17

I have a program written in C that runs on Linux, MacOS and Windows. Is there a way I can call a function and generate a stack trace? This would be super-useful for me. Ideally I'd like to do it on all three platforms, but Linux is the most important. (Windows is being compiled via mingw.)

Thanks.

Felix Kling
  • 795,719
  • 175
  • 1,089
  • 1,143
vy32
  • 28,461
  • 37
  • 122
  • 246

3 Answers3

8

For example, in GCC and the GNU libc C library, you can use backtrace().

As @slugonamission suggests, Windows offers CaptureStackBackTrace() - thanks!

Other platforms may offer similar features.

(This is obviously a platform-dependent question.)

(On a related note, there also exist self-disassembly libraries.)

Kerrek SB
  • 464,522
  • 92
  • 875
  • 1,084
  • For Windows, this old post may help: [POST](http://stackoverflow.com/questions/5693192/win32-backtrace-from-c-code) – slugonamission Nov 07 '11 at 01:12
  • Here's a [similar backtrace suggestion](http://stackoverflow.com/a/4983533/487992) that includes reference to [addr2line](http://linux.die.net/man/1/addr2line) program to translate offsets to file names and line numbers. – JohnMudd Mar 09 '15 at 15:48
6

I'm using this code to generate debug stack traces. It uses libunwind to get the stacktrace and libdwfl to read debug information.

It produces nice Java-like stack traces, with function names and source locations. eg.:

at c(stack_trace.c:95)
at b(stack_trace.c:100)
at a(stack_trace.c:105)
at main(stack_trace.c:110)

libunwind should work on Windows and Mac, but libdwfl is Linux and ELF specific.

Piotr Praszmo
  • 17,928
  • 1
  • 57
  • 65
  • 1
    Thanks. I downloaded libunwind and it did not compile on my Mac. – vy32 Nov 07 '11 at 20:06
  • 1
    @vy32 you are right. It turns out they are both Linux specific. – Piotr Praszmo Nov 07 '11 at 20:36
  • Can we generate backtrace using libunwind when the program crash? – Pritesh Acharya Sep 05 '13 at 04:57
  • @PriteshAcharya [Just print the stacktrace in SIGSEGV signal handler](https://gist.github.com/banthar/6452707). Be careful with this code though. It's riddled with undefined behavior. – Piotr Praszmo Sep 05 '13 at 16:41
  • yea. I don't wanna get a new SIGSEGV inside the SIGSEGV handler. :D – Pritesh Acharya Sep 06 '13 at 05:08
  • i couldn't install libdwfl. it doesn't come up with elfutils. I'm using debian system. – Pritesh Acharya Sep 06 '13 at 05:26
  • I've been searching for a relatively straightforward way to get a stack trace with files and line numbers like this for hours and this is the first and only answer I've found. Thanks! – andrewrk Jul 31 '15 at 06:10
  • I agree, this works quite well. However, for some functions, if I call `debugInfo(out,(void*)(ip-4))` the function name is wrong and it would be correct calling `debugInfo(out,(void*)(ip))`. I've verified the behavior and it's consistent also with `addr2line`. I suspect I'm missing some basics about program counter arithmetics, does anyone has a clue why this is happening? – Avio Nov 30 '16 at 16:47
  • @Avio UNW_REG_IP points to instruction to which function will return. We want the instruction where the function was called. Without that offset you will get wrong line numbers. `-4` is wrong as some call instructions take less than that. Try `-1` instead. – Piotr Praszmo Nov 30 '16 at 21:37
  • @Banthar thanks for the suggestion, but it was my fault. I forgot to remove the `-O3` during building, so from a certain "depth" on I was missing some function call (probably inlined) and from there on line numbers were wrong. I've made a few trials with `-O0` and both -4 and -1 produce the same results. I'm still missing something about program counter arithmetics, but now at least it's working :) – Avio Dec 01 '16 at 10:41
3

Ian Lance Taylor's libbacktrace does this. It handles stack unwinding and provides support for DWARF debugging symbols.

https://github.com/ianlancetaylor/libbacktrace

As of October 2020, libbacktrace supports ELF, PE/COFF, Mach-O, and XCOFF executables with DWARF debugging information. In other words, it supports GNU/Linux, *BSD, macOS, Windows, and AIX. The library is written to make it straightforward to add support for other object file and debugging formats.

Jens A. Koch
  • 39,862
  • 13
  • 113
  • 141
Erwan Legrand
  • 4,148
  • 26
  • 26