[LLVMdev] Demangling question

Talin viridia at gmail.com
Thu Sep 4 20:35:47 PDT 2008


So I got tired of LLVM's PrintStackTrace() function only being able to 
print mangled C++ names. I went ahead and wrote a demangler (shown 
below), however there's one slight problem, which is that the output of 
backtrace_symbols appears to be different on different platforms. In 
order to use the cxxabi demangler, you need to provide it with the 
portion of each line that contains the mangled name, and strip all of 
the other items on that line. In the case of OS X, the mangled symbol is 
delimited by whitespace, however on some platforms it appears that the 
mangled name is surrounded by parentheses.

I guess what could be done is to just write a version of the line 
stripper per platform. I'd start by only supporting the platforms I have 
access to, and letting other people contribute the parsing code for 
their platform.

    #if HAVE_CXXABI_H
    #include <cxxabi.h>
    #endif

    /// ....

    static void PrintStackTrace(int skipFrames) {
    #ifdef HAVE_BACKTRACE
      // Use backtrace() to output a backtrace on Linux systems with glibc.
      int depth = backtrace(stackTrace,
          static_cast<int>(arrayLengthOf(StackTrace)));

    #ifdef HAVE_CXXABI_H
      if (char ** symbols = backtrace_symbols(StackTrace, depth)) {
       
        // Name buffer used to contain demangling result.
        size_t sz = 256;
        char * buffer = (char *)malloc(sz);

        for (int i = 0; i < depth; ++i) {
          // Skip this frame, and possibly the assert machinery as well.
          if (i >= skipFrames) {
            char * symbol = symbols[i];
            // TODO: This is a very cheesy way to extract the symbol name,
            // need to come up with something that will work on various
    platforms.
            // fprintf(outstream, "%s\n", symbol);
            char * begin = strchr(symbol, '_');
            char * demangled_name = NULL;
            if (begin) {
              char * end = strchr(begin, ' ');
              if (end) {
                *end = 0;
                int status;
                demangled_name = abi::__cxa_demangle(begin, buffer, &sz,
    &status);
              }
            }
         
            if (demangled_name != NULL) {
              fprintf(outstream, "%s\n", demangled_name);
           
              // Result may be a realloc of input buffer.
              buffer = demangled_name;
            }
          }
        }

        free(symbols);
        free(buffer);
      }
    #else
      backtrace_symbols_fd(StackTrace, depth, STDERR_FILENO);
    #endif
    #endif
    }


Oh, and one other thing I haven't figured out is how to add a test for 
<cxxabi.h> into LLVM's configure script.

In any case, if someone wants to work on this feel free to use this 
code, I've been too busy lately to make a patch.

-- Talin




More information about the llvm-dev mailing list