24

I was exploring the boost::stacktrace by trying a simple example to print the call stack of a recursive function.

#include "boost/stacktrace.hpp"

int factorial(int x){
    if (x < 2) {
        std::cout << boost::stacktrace::stacktrace();
        return 1;
    }
    return x * factorial(x - 1);
}

int main(int ac, char *av[]) {
    std::cout << factorial(4);
}

However the output of the code does not include any information about the function name and line number:

 0# 0x000055A6F6B57C0F in /home/user/myapp
 1# 0x000055A6F6B57C42 in /home/user/myapp
 2# 0x000055A6F6B57C42 in /home/user/myapp
 3# 0x000055A6F6B57C42 in /home/user/myapp
 4# 0x000055A6F6B57C9D in /home/user/myapp
 5# __libc_start_main in /lib/x86_64-linux-gnu/libc.so.6
 6# 0x000055A6F6B57AEA in /home/user/myapp

This is in contrast with the sample output from the boost website: (copied from https://www.boost.org/doc/libs/1_68_0/doc/html/stacktrace/getting_started.html#stacktrace.getting_started.how_to_print_current_call_stack)

0# bar(int) at /path/to/source/file.cpp:70
1# bar(int) at /path/to/source/file.cpp:70
2# bar(int) at /path/to/source/file.cpp:70
3# bar(int) at /path/to/source/file.cpp:70
4# main at /path/to/main.cpp:93
5# __libc_start_main in /lib/x86_64-linux-gnu/libc.so.6
6# _start

Why don't I see the source line numbers and function names in the stack-trace output?

I have enabled debugging information in my project-level CMakeList.txt:

set(CMAKE_BUILD_TYPE Debug)

I can also see the symbols are present when demangling the binary file:

nm -an myapp | c++filt | grep factorial

0000000000000f40 t _GLOBAL__sub_I__Z9factoriali
00000000000010f0 T factorial(int)
motam79
  • 3,542
  • 5
  • 34
  • 60

4 Answers4

16

You need to do a few things (this is for Linux):

  1. Make sure that debug info is enabled: e.g., -g

  2. Link against libdl: -ldl

  3. Define one of the necessary macros (to get line numbers): e.g., -DBOOST_STACKTRACE_USE_ADDR2LINE

All this info is provided here:

https://www.boost.org/doc/libs/1_69_0/doc/html/stacktrace/configuration_and_build.html

jordi
  • 336
  • 4
  • 7
  • Does boost stacktrace use dynsym or symtab section? I ask because backtrace_symbols uses dynsym which we don't fill. – Desperado17 Jun 02 '20 at 08:14
16

I do not have enough reputation to comment, so I'll extend jordi's answer here:

  1. Make sure that debug info is enabled: e.g., -g

  2. Link against libdl: -ldl

  3. Define one of the necessary macros (to get line numbers): e.g., -DBOOST_STACKTRACE_USE_ADDR2LINE

  4. Compile and link with -no-pie and -fno-pie options.

Pavel Bazika
  • 356
  • 4
  • 8
4

This is what worked for me, I am compiling with g++ :

  • Compile with -g -ggdb -no-pie -fno-pie -rdynamic
  • define macro -DBOOST_STACKTRACE_USE_ADDR2LINE
  • Link against libdl -libl and -no-pie -fno-pie

Edit : in my case rdynamic was the missing bit to allow me to have unmagled function names and line numbers

  • As most of the information in this answer is repeating earlier answers, it would help to highlight the options you added, especially if you could explain why you made the additions. – Chad Barth Jan 17 '22 at 23:07
  • 1
    Fair enough, -rdynamic was the key in my case. – Geoffrey Merck Jan 19 '22 at 06:33
  • 1
    To set -rdynamic using cmake add the line `set_property(TARGET your_target PROPERTY ENABLE_EXPORTS ON)` – Andrew H Sep 16 '22 at 18:26
4

This worked for me:

g++ -g backtrace.cpp -o bb -lboost_stacktrace_backtrace -D BOOST_STACKTRACE_LINK

-D BOOST_STACKTRACE_LINK was the missing option that solved the problem for me.

Jacob Burckhardt
  • 391
  • 1
  • 2
  • 10