I would like to print call stack with more information like in gdb.
This is what I have so far.
void to_print_callstack()
{
void *buffer[100];
int n = backtrace(buffer,10);
char **str = backtrace_symbols(buffer, n);
for (int i = 0; i < n; i++)
{
printf("%d: %s\n", i, str[i]);
}
}
When it runs, I get something as below.
0: ./test-prog() [0x4466bf]
1: ./test-prog() [0x445e1d]
2: ./test-prog() [0x443fd5]
3: ./test-prog() [0x439a99]
4: ./test-prog() [0x43302f]
5: ./test-prog() [0x4322c9]
6: ./test-prog() [0x4320cd]
7: ./test-prog() [0x43e76b]
8: /lib/libc.so.6(__libc_start_main+0xfd) [0x7fc4de7d8c4d]
9: ./test-prog() [0x431569]
It is hard to read. With function names, it would be much better. Thanks a lot for the tip.
Disclaimer: The following is mostly for Linux using GCC or Clang with libstdc++, you might need different ways on other systems.
The most important thing is to add
-rdynamic
to the command line when linking. I don't know if this is required on all systems, but for me, this actually turned all those addresses into symbols.Now that you get some information, you probably want to demangle the symbols. You start with a stand-alone function to demangle any symbol:
And now for the real thing. I don't know if the format of the output from
backtrace_symbols
is specified, but the following works quite well for me:(I had to adapt my code slightly since I'm not using
std::cout
, so there might be some little quirks there - check the code if it works for you and if not and you need help fixing it, let me know).