It is always nice to have the ability to log a proper call stack backtrace when doing things like signal handling, C++ exception handling, or simply debug logging. Bonus points if the C++ backtraces are demangled. This is how I get backtraces and C++ demangling to work for me when developing with GCC:
Everything you need to get access to the call stack from C/C++ is made available through #include <execinfo.h>, and passing in -rdynamic to your GCC compiler. From a code perspective, there are two function calls you need to make: the first will return some void* pointers, while the second will take those pointers and give you back the symbolic names and offsets:
The "do something here" is the trick. At this point, ptr is now an array of text strings. You can access them as ptr[0], ptr[1], etc. What they look like somewhat depends on whether or not you're using C or C++. Here is the output from the example compiled with gcc:
Here is that same example compile with g++:
If you're working with gcc, then your work is done; you can take the text pointers and parse them, display them, or simply log them as you see fit.
But if you're working with g++ then all you have at this point is the mangled names. It takes a little bit more work to demangle the call stack.
C++ of course mangles all symbols. If you're not already familiar with how mangling works, please refer to Wikipedia as a starting point.
Luckily for us, there is a function that will take a g++ mangled name, and return to us the full prototype including namespace or class if applicable. When combined with the backtrace, this can be a useful feature.
Though this is a trivial example, take the backtrace obtained in the example above, and note this line:
...we can extract the mangled function name _Z16displayBacktracev. To demangle this, we'd call the following code:
The mangled name _Z16displayBacktracev is demangled as expected to displayBacktrace().
It is important to note that demangledName is a malloc()'d buffer, so remember to free it. Also note the text strings returned from backtrace_symbols() cannot be used directly as input to abi::__cxa_demangle(). You'll need to parse each backtrace line to extract just the mangled name.
Combine backtrace with C++ demangling, and you've got a powerful tool to use when you need to log where in the code something happened.