Search code examples
c++c++11raspberry-pi

Raspberry Pi optimized backtrace()


Is there any Raspberry Pi optimized/specific backtrace() implementation? I'm using standard backtrace() code but looking forward for more detailed output from my_backtrace function.

void my_backtrace(){
     void *stack[10];
     int n = backtrace(stack, 10);
     std::cout << "Last  frames==" << n << std::endl;
     backtrace_symbols_fd(stack, n, STDOUT_FILENO);
}

Solution

  • //--There is list of options:
    //a) backtrace in combination with abi::__cxa_demangle
    //b) GDB
    //c) [libunwind][1], [http://www.nongnu.org/libunwind/docs.html] 
    //d) libbfd-dev 
    //e) [backward-cpp][1], [https://github.com/bombela/backward-cpp]
    //f) [libbacktrace][1], [https://github.com/ErwanLegrand/libbacktrace]
    //-----------------------------------------------
    #include <execinfo.h>
    #include <iostream>
    #include <sys/types.h>
    #include <unistd.h>
    #include <sstream>
    #include <sys/wait.h>
    //-----------------------------------------------
    //Based on GDB
    //-----------------------------------------------
    void print_trace_gdb() {
        char pid_buf[30];
        sprintf(pid_buf, "%d", getpid());
        char name_buf[512];
        name_buf[readlink("/proc/self/exe", name_buf, 511)]=0;
    
        int child_pid = fork();
        if (!child_pid) {           
            dup2(2,1); // redirect output to stderr
            fprintf(stdout,"stack trace for %s pid=%s\n",name_buf, pid_buf);
            execlp("gdb", "gdb", "--batch", "-n", "-ex", "thread", "-ex", "bt", name_buf, pid_buf, NULL);
            //if gdb failed to start
            abort();
        } else {
            waitpid(child_pid,NULL,0);
        }
     }
    
    //-----------------------------------------------
     void rec_function(int ii)
     {
         if ( ii == 0 ) {std::cout << "int value==" << ii << "\n";}
         else {rec_function(--ii);}
         print_trace_gdb();
     }
    
     //-----------------------------------------------
     int main()
    {
       int jj=1;
       std::cout << "\n---begin test-----\n";
       std::cout << "int value==" << jj << "\n";
       rec_function(jj);
       std::cout << "---end test-----\n";
    }
    

    Output from this code is

    ---begin test-----
    int value==1
    int value==0
    stack trace for /opt/cpp/linux_backtrace_gdb pid=4181
    0x00007f878b5ca4ca in waitpid () from /lib/x86_64-linux-gnu/libc.so.6
    [Current thread is 1 (process 4181)]
    #0  0x00007f878b5ca4ca in waitpid () from /lib/x86_64-linux-gnu/libc.so.6
    #1  0x0000000000400e69 in print_trace_gdb () at linux_backtrace_gdb.cpp:25
    #2  0x0000000000400ed2 in rec_function (ii=0) at linux_backtrace_gdb.cpp:34
    #3  0x0000000000400ecd in rec_function (ii=0) at linux_backtrace_gdb.cpp:33
    #4  0x0000000000400f29 in main () at linux_backtrace_gdb.cpp:43
    stack trace for /opt/cpp/linux_backtrace_gdb pid=4181
    0x00007f878b5ca4ca in waitpid () from /lib/x86_64-linux-gnu/libc.so.6
    [Current thread is 1 (process 4181)]
    #0  0x00007f878b5ca4ca in waitpid () from /lib/x86_64-linux-gnu/libc.so.6
    #1  0x0000000000400e69 in print_trace_gdb () at linux_backtrace_gdb.cpp:25
    #2  0x0000000000400ed2 in rec_function (ii=0) at linux_backtrace_gdb.cpp:34
    #3  0x0000000000400f29 in main () at linux_backtrace_gdb.cpp:43
    ---end test-----