[历史归档]本文原发布于 cstriker1407.info 个人博客,内容为历史存档,仅供参考。
发布时间:2019-03-20| 标题:backtrace和addr2line简单介绍|分类:编程 / 操作系统 / linux |标签:C&&C++·addr2line·backtrace
backtrace和addr2line简单介绍
参考
【 https://www.cnblogs.com/listenerln/p/6382272.html 】
【 https://www.cnblogs.com/muahao/p/7610645.html 】
【 http://116.62.110.235/blog/linux-addr2line/ 】
有时候我们想要打印程序运行堆栈来便于调试,我们可以使用backtrace API来实现,同时使用addr2line来帮助定位到具体函数。
backtrace的详细介绍可以参考man手册或者在线搜索下。这里就笔记下最简单的使用方式:
//prog.c#include<execinfo.h>#include<stdio.h>#include<stdlib.h>#include<unistd.h>#defineBT_BUF_SIZE100voidmyfunc3(void){intj,nptrs;void*buffer[BT_BUF_SIZE];char**strings;nptrs=backtrace(buffer,BT_BUF_SIZE);printf("backtrace()returned%d addresses ",nptrs);/* The call backtrace_symbols_fd(buffer, nptrs, STDOUT_FILENO) would produce similar output to the following: */strings=backtrace_symbols(buffer,nptrs);if(strings==NULL){perror("backtrace_symbols");exit(EXIT_FAILURE);}for(j=0;j<nptrs;j++)printf("%s ",strings);free(strings);}staticvoid/* "static" means don't export the symbol... */myfunc2(void){myfunc3();}voidmyfunc(intncalls){if(ncalls>1)myfunc(ncalls-1);elsemyfunc2();}intmain(intargc,char*argv[]){if(argc!=2){fprintf(stderr,"%s num-calls ",argv[0]);exit(EXIT_FAILURE);}myfunc(atoi(argv[1]));exit(EXIT_SUCCESS);}如何使用:
$ gcc-rdynamic-gprog.c-oprog $ ./prog5backtrace()returned10addresses ./prog(myfunc3+0x2e)[0x5628807eeb78]./prog(+0xc4a)[0x5628807eec4a]./prog(myfunc+0x25)[0x5628807eec72]./prog(myfunc+0x1e)[0x5628807eec6b]./prog(myfunc+0x1e)[0x5628807eec6b]./prog(myfunc+0x1e)[0x5628807eec6b]./prog(myfunc+0x1e)[0x5628807eec6b]./prog(main+0x5b)[0x5628807eecd0]/lib/x86_64-linux-gnu/libc.so.6(__libc_start_main+0xe7)[0x7fce2564db97]./prog(_start+0x2a)[0x5628807eea6a]$ addr2line-eprog-fpa0xc6b 0x0000000000000c6b: myfunc 于 /prog.c:44几点说明:
1 prog.c来源于man手册
2 编译需要加上 -rdynamic -g 命令
3 addr2line有时无法识别绝对地址,需要用相对地址来查询