Demangling C++ Names
March 26th, 2008 by Joe RanieriRuntimeException.stack is one of the most useful things to be added to REALbasic. However, we can make it a bit better by demangling any C++ function names that might be in the stack trace.
Function CPPDemangle(name as string) As string //! Demangles a C++ function name. Returns an empty string on failure. //! Only works on Mac OS X. #if targetMacOS declare function __cxa_demangle lib "/usr/lib/libstdc++.6.dylib" ( name as CString, _ outBuffer as ptr, outLength as ptr, byref outState as integer ) as CString declare sub free lib "System" ( value as CString ) const kStateSuccess = 0 dim state as integer dim demangledString as CString = __cxa_demangle( name, nil, nil, state ) if state = kStateSuccess then // create our RB string, then free the string demangle gave us dim result as string = demangledString free( demangledString ) return result end if #endif End Function
Then you can apply this function to the exception’s stack like so:
Function GetErrorStack(err as RuntimeException) As string() //! Gets the stack trace for our exception. This differs from //! RuntimeException.stack in that it demangles C++ names. // this can crash in some cases, giving us a completely useless crash log // <rb-feedback://keeqghwg>, hopefully this will be fixed someday... dim stack() as string = err.stack dim cleanedStack() as string // the order of RB's "for each" isn't defined <rb-feedback://hdcdbgfi>, so we have // to use a normal loop for i as integer = 0 to stack.ubound dim name as string = stack( i ) dim demangledName as string = cppDemangle( name ) if demangledName <> "" then cleanedStack.append( demangledName ) else cleanedStack.append( name ) end if next return cleanedStack End Function
So, instead of seeing “__ZN14RuntimeListbox7GetTextE15getTextSelectorll” in an exception trace, you will see “RuntimeListbox::GetText(getTextSelector, long, long)“. Much, much easier on the eyes.