zoukankan      html  css  js  c++  java
  • 使用Backtrace函数打印调用栈 Debug居家必备

    glibc提供了backtrace这个库函数,可以用来打印call stack。比如我们可以在程序中注册常见的一些signal,比如SIGSEGMENT, SIGPIPE,然后在这些信号的回调函数中,利用backtrace打印出call stack,这样debug就非常的方便。 
    backtrace的使用很简单,使用man手册中的Example代码即可,例如:
     
     1 #include <execinfo.h>   
     2 #include <stdio.h>
     3 #include <string.h>
     4 #include <stdlib.h>
     5 #include <errno.h>
     6 
     7 #define SIZE        100
     8 
     9 void dump_stack()
    10 {
    11     int btnum = 0;
    12     void *btbuf[SIZE];
    13     char **btstrings = NULL;
    14     int i;
    15 
    16     /* Get backtrace */
    17     btnum = backtrace(btbuf, SIZE);
    18     btstrings = backtrace_symbols(btbuf, btnum);
    19     if (btstrings == NULL) {
    20         printf("Backtrace failed: %d:%s\n", errno, strerror(errno));
    21     } else {
    22         printf("Backtraces, total %d items\n", btnum);
    23         for (i = 0; i < btnum; i++)
    24             printf("%s\n", btstrings[i]);
    25 
    26         free(btstrings);
    27     }
    28 }
    29 
    30 void start_working()
    31 {
    32     printf("Start working...\n");
    33     dump_stack();
    34 }
    35 
    36 int main()
    37 {
    38     printf("Start backtracing...\n");
    39     start_working();
    40     return 0;
    41 }
    首先用backtrace,最多生成100层的call stack。然后用backtrace_symbols将backtrace返回的一堆地址翻译成函数名称。backtrace的返回值是具体生成了多少层的call stack,填充的btbuf是一个void *的数组,里面每个element都是一个void *,其实就是一个地址。 
    backtrace_symbols生成的字符串都是malloc出来的,但是不要最后一个一个的free,因为backtrace_symbols是根据backtrace给出的call stack层数,一次性的malloc出来一块内存来存放结果字符串的,所以,像上面代码一样,只需要在最后,free backtrace_symbols的返回指针就OK了。这一点backtrace的manual中也是特别提到的。
     
    此外需要注意的是,使用backtrace来获取调用栈信息,在编译的时候需要加入:-rdynamic,这个option是传递给linker的,linker会将symbol放到.dydym table中,这样backtrace_symbols才能获取到地址对应的symbol。所以即使是使用了-g来编译程序,如果不使用-rdynamic的话,backtrace_symbols也找不到地址对应的symbol。这是backtrace系列函数的一个缺陷。不过有了地址也算是一个很大帮助了,毕竟可以使用gdb来找到对应的symbol。
  • 相关阅读:
    有关C#中List排序的总结
    配置jdk1.8.0_77
    New Day
    HDU 4288 Coder 线段树
    AOJ 169 找零钱 DP OR 母函数
    HDU 3954 Level up 线段树
    HDU 3016 Man Down 线段树+简单DP
    HDU 4027 Can you answer these queries? 线段树
    HDU 3333 Turing Tree 树状数组 离线查询
    POJ 2464 Brownie Points II 树状数组+扫描线
  • 原文地址:https://www.cnblogs.com/super119/p/1901468.html
Copyright © 2011-2022 走看看