How to get a backtrace with GCC

| Comments (1) | Software
Occasionally programmers want to get a backtrace (the set of function calls that the program is currently in: A calls B, which calls C, which calls D, etc.) This is particularly useful for writing various kinds of instrumentation like memory checkers, profiling tools, etc. This is straightforward with a debugger, but that's not really convenient if there are a lot of events you want to get backtraces for. It's also possible to do this nonportably: if you know the way the compiler lays out the stack, you can grovel through memory and dig out the stack trace yourself, but that's a pain and requires reading a lot of documentation about the memory layout, so people typically don't bother.

Conveniently, if the program was compiled with GCC there's a much easier way. GCC has a builtin primitive that lets you get the frame pointer or return pointer address of any function in the call stack (documentation here.) Obviously, this is just the address, but you can then use dladdr() to extract the name of the function. Put together, you've got a backtrace. Note that this only gives you the function name and (with some work) the offset into the function. You'd need to grovel through the symbol table or something to actually figure out what line of source you were on. Still, that's information you didn't have before and is enough for a lot of purposes.

On FreeBSD, there's actually a library in ports called libexecinfo, which implements this trick. That's where I learned about it. Glibc also includes this as a native facility. I assume it works like this, but haven't bothered to examine the source.


Mac OS also have backtrace() and friends.

Leave a comment