|  |  | @ -119,9 +119,11 @@ void trace(String* string) { | 
			
		
	
		
			
				
					|  |  |  | 
 | 
			
		
	
		
			
				
					|  |  |  |         // the names as provided by 'backtrace_symbols' are mangled for some reason.
 | 
			
		
	
		
			
				
					|  |  |  |         // we have to demangle them, using this weird api
 | 
			
		
	
		
			
				
					|  |  |  |         // example mangled name (wrapped in double quotes):
 | 
			
		
	
		
			
				
					|  |  |  |         // "2   shard_tracy                         0x00000001032d5618 _ZL17drawSettingsPanelv + 904"
 | 
			
		
	
		
			
				
					|  |  |  |         char buffer[1024]; | 
			
		
	
		
			
				
					|  |  |  |         const char* mangledNameBegin = String::firstCharOccurence(traces[i], '_'); | 
			
		
	
		
			
				
					|  |  |  |         const char* mangledNameEnd = String::lastCharOccurence(traces[i], '+'); | 
			
		
	
		
			
				
					|  |  |  |         const char* mangledNameBegin = String::lastCharOccurence(traces[i], '_'); | 
			
		
	
		
			
				
					|  |  |  |         const char* mangledNameEnd = String::lastCharOccurence(traces[i], '+'); // it actually ends one char before.
 | 
			
		
	
		
			
				
					|  |  |  | 
 | 
			
		
	
		
			
				
					|  |  |  |         if (mangledNameBegin == null || mangledNameEnd == null) { | 
			
		
	
		
			
				
					|  |  |  |             // we can't demangle this name for some reason, just copy the mangled name to the buffer
 | 
			
		
	
	
		
			
				
					|  |  | @ -138,8 +140,9 @@ void trace(String* string) { | 
			
		
	
		
			
				
					|  |  |  |         s32 status = -1; | 
			
		
	
		
			
				
					|  |  |  |         char* trace = abi::__cxa_demangle(buffer, null, null, &status); | 
			
		
	
		
			
				
					|  |  |  |         if (trace == null) { | 
			
		
	
		
			
				
					|  |  |  |             println("warning: failed to demangle name: %s", traces[i]); | 
			
		
	
		
			
				
					|  |  |  |             continue; | 
			
		
	
		
			
				
					|  |  |  |             println("warning: failed to demangle name: %s, exit status of attempt: %d", traces[i], status); | 
			
		
	
		
			
				
					|  |  |  |             // just write back the original trace, un-demangled.
 | 
			
		
	
		
			
				
					|  |  |  |             trace = traces[i]; | 
			
		
	
		
			
				
					|  |  |  |         } | 
			
		
	
		
			
				
					|  |  |  | 
 | 
			
		
	
		
			
				
					|  |  |  |         if (string == null) { | 
			
		
	
	
		
			
				
					|  |  | @ -225,7 +228,7 @@ static void writeMinidump(EXCEPTION_POINTERS* pep) { | 
			
		
	
		
			
				
					|  |  |  | 
 | 
			
		
	
		
			
				
					|  |  |  | // for fatal errors which may occur at runtime, even on a release binary.
 | 
			
		
	
		
			
				
					|  |  |  | // if a fatal error should not occur at runtime on a release binary, consider preferring 'massert'
 | 
			
		
	
		
			
				
					|  |  |  | // it's unclear when you should use asserts vs. die actually. idk man
 | 
			
		
	
		
			
				
					|  |  |  | // it's unclear when you should use asserts vs. die actually. idk man, they kinda do the same thing right now
 | 
			
		
	
		
			
				
					|  |  |  | void die(const char* format, ...) { | 
			
		
	
		
			
				
					|  |  |  |     ULE_TYPES_H_FTAG; | 
			
		
	
		
			
				
					|  |  |  |     if (format == null) { | 
			
		
	
	
		
			
				
					|  |  | @ -258,7 +261,7 @@ void die(const char* format, ...) { | 
			
		
	
		
			
				
					|  |  |  | 
 | 
			
		
	
		
			
				
					|  |  |  |     } else { | 
			
		
	
		
			
				
					|  |  |  |         String string = String128f(""); | 
			
		
	
		
			
				
					|  |  |  |         string.setfv(format, args); | 
			
		
	
		
			
				
					|  |  |  |         string.appendfv(format, args); | 
			
		
	
		
			
				
					|  |  |  |         string.append("\n"); | 
			
		
	
		
			
				
					|  |  |  |         trace(&string); | 
			
		
	
		
			
				
					|  |  |  | 
 | 
			
		
	
	
		
			
				
					|  |  | 
 |