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。

转载于:https://www.cnblogs.com/super119/archive/2010/12/09/1901468.html

使用Backtrace函数打印调用栈 - Debug居家必备相关推荐

  1. php 打印函数调用栈,利用backtrace和backtrace_symbols函数打印调用栈信息

    本帖最后由 kylin_try 于 2017-2-6 08:41 编辑 在头文件"execinfo.h"中声明了三个函数用于获取当前线程的函数调用堆栈. #include int ...

  2. backtrace打印调用栈

    目录 1.backtrace打印调用栈 2.addr2line 1.backtrace打印调用栈 https://blog.csdn.net/hejinjing_tom_com/article/det ...

  3. Android-Hal-C++打印调用栈

    Android-Hal-C++打印调用栈 debuggerd是android的一个daemon进程,负责在进程出错异常时,将进程的运行时信息给dump出来供分析. debuggerd的core dum ...

  4. linux 函数中打印调用栈

    一.内核中 To print the stack contents and a backtrace to the kernel log, use the #include <linux/kern ...

  5. 【译】理解Javascript函数执行—调用栈、事件循环、任务等

    原文作者:Gaurav Pandvia 原文链接:medium.com/@gaurav.pan- 文中部分链接可能需要梯子. 欢迎批评指正. 现如今,web开发者(我们更喜欢被叫做前端工程师)用一门脚 ...

  6. java打印堆栈信息linux,在C/C++程序里打印调用栈信息(转载)

    原文出处  http://blog.csdn.net/yetyongjin/article/details/7759144 以下不能windows + mingw下执行.  windows下参考 ht ...

  7. 「译」理解Javascript函数执行—调用栈、事件循环、任务等

    现如今,web开发者(我们更喜欢被叫做前端工程师)用一门脚本语言就能做任何事情,从提供浏览器中的交互,到开发电脑游戏.桌面工具.跨平台移动应用,甚至可以在服务端部署(如最流行的Node.js)来连结任 ...

  8. [译]深入理解JavaScript函数执行—调用栈,事件循环和任务等

    Web 开发者,或者前端工程师(我们更喜欢别人这么称呼)现如今几乎能做所有的工作,从扮演一个浏览器内部交互性的角色,到制作电脑游戏.桌面控件.跨平台手机应用,甚至还可以把它写在服务器端(最流行的是no ...

  9. C语言获取程序崩溃信号,打印调用栈backtrace、backtrace_symbols、addr2line

    源程序 #include <stdio.h> #include <stdlib.h> #include <signal.h> #include <execin ...

最新文章

  1. TeaPot 用webgl画茶壶(3) 环境纹理和skybox
  2. thinkphp3.2独立分组的建立
  3. 计算机教室布线施工方案,最新计算机教室施工方案.docx
  4. ruby+watir 安装
  5. python计算时差
  6. python opendr_《网络工程师的Python之路》出书了!
  7. 如何从官网直接下载iTunes?
  8. R语言基础数据操作fBasics
  9. 小程序模板平台怎么选?
  10. 用canvas绘制三角形
  11. 2.企业发放的奖金根据利润提成。
  12. 好莱坞明星识别-第六周
  13. front-matter参数的解释与设置
  14. .net5 查询Access数据库数据
  15. 开局签到满级剑术天赋(三)
  16. mysql优化手段——潭州学院
  17. springboot windows下WORD文档转PDF
  18. 交友盲盒小程序版本 全开源版本kxdao首发(已更新)
  19. 让windows 2008 也netmeeting
  20. Jenkins 邮件模板配置

热门文章

  1. Cloudstreams: 云间整合的下一个挑战
  2. ARM Neon 列子 - Vector Add
  3. 嵌入式linux通过DHCP自动获取IP地址实现
  4. Waveform Audio 驱动(Wavedev2)之:WAV 驱动解析
  5. louvain算法python_复杂网络任务6:Louvain社区发现算法的原理、细节和实现,作业,六,以及...
  6. 检测到目标url存在框架注入漏洞_HOST注入攻击剖析
  7. python 接口测试 url_Python 接口测试之接口请求方法封装
  8. linux 引导程序修复工具,linux 引导修复工具
  9. php取json子对象属性,php中输出json对象的值(实现方法)
  10. python 运行当前目录下的所有文件