利用backtrace跟踪程序的调用堆栈
2014-04-24 15:31
447 查看
通过backtrace()函数可以获得当前的程序堆栈地址. 提供一个指针数组, backtrace()函数会把调用堆栈的地址填到里面.#include <execinfo.h>int backtrace(void **buffer, int size);
为了跟踪动态库, 需要给gcc添加-rdynamic参数. 另外, 为了看到函数名, 行号等调试信息, 还要添加-g参数.-rdynamic参数的涵义: This instructs the linker to add all symbols, not only used ones, to the dynamic symbol table. This option is needed for some uses of dlopen or to allow obtaining backtraces from within a program
backtrace_symbols()可以将堆栈地址转换成可读的信息用于打印, 但不是很具体, 无法显示出函数名和行号, 通过binutils的addr2line可以做到这一点. 调用方式为: addr2line -Cif -e 文件名 地址
对于动态库中的函数, 文件名是动态库的. backtrace给出的堆栈地址是经过map的, 因此需要将映射后的地址还原. 映射的基地址可通过读取/proc/self/maps得到.
对于程序运行环境没有addr2line工具的情况, 如嵌入式平台, 可以打印出地址, 在PC上用交叉工具链的addr2line工具分析.
对于一些系统或第三方没有加-g编译的so库, addr2line可能看不到函数名和行号的信息, 这时使用dladdr()函数可看到一些导出函数的函数名. dladdr()要使用backtrace()获得的原始地址, 不是还原后的.
通过sigaction()注册一些系统信号的处理回调, 如SIGSEGV, 可以在Segmentation fault时打印程序堆栈.
由于C++的符号是经过name mangling, 为了显示的友好性, 可先做demangle.
++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++[01] 0x7ffbda2dd5ca 0x5ca func: function_so_static, file: /data/callstack/test_so.c L7, module: /data/callstack/libtest.so[02] 0x7ffbda2dd5da 0x5da func: function_so, file: /data/callstack/test_so.c L13, module: /data/callstack/libtest.so[03] 0x401c5e 0x401c5e func: function_callso, file: /data/callstack/test.c L19, module: /data/callstack/callstack[04] 0x401d12 0x401d12 func: main, file: /data/callstack/test.c L44, module: /data/callstack/callstack[05] 0x7ffbd9f3e76d 0x2176d func: __libc_start_main, file: unknown, module: /lib/x86_64-linux-gnu/libc.so.6[06] 0x400f59 0x400f59 func: _start, file: unknown, module: /data/callstack/callstack++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
代码下载地址:https://github.com/thinkphoebe/callstack.git
参考:http://blog.csdn.net/littlefang/article/details/17654419http://blog.bigpixel.ro/2010/09/stack-unwinding-stack-trace-with-gcc/
来自为知笔记(Wiz)
为了跟踪动态库, 需要给gcc添加-rdynamic参数. 另外, 为了看到函数名, 行号等调试信息, 还要添加-g参数.-rdynamic参数的涵义: This instructs the linker to add all symbols, not only used ones, to the dynamic symbol table. This option is needed for some uses of dlopen or to allow obtaining backtraces from within a program
backtrace_symbols()可以将堆栈地址转换成可读的信息用于打印, 但不是很具体, 无法显示出函数名和行号, 通过binutils的addr2line可以做到这一点. 调用方式为: addr2line -Cif -e 文件名 地址
对于动态库中的函数, 文件名是动态库的. backtrace给出的堆栈地址是经过map的, 因此需要将映射后的地址还原. 映射的基地址可通过读取/proc/self/maps得到.
对于程序运行环境没有addr2line工具的情况, 如嵌入式平台, 可以打印出地址, 在PC上用交叉工具链的addr2line工具分析.
对于一些系统或第三方没有加-g编译的so库, addr2line可能看不到函数名和行号的信息, 这时使用dladdr()函数可看到一些导出函数的函数名. dladdr()要使用backtrace()获得的原始地址, 不是还原后的.
通过sigaction()注册一些系统信号的处理回调, 如SIGSEGV, 可以在Segmentation fault时打印程序堆栈.
由于C++的符号是经过name mangling, 为了显示的友好性, 可先做demangle.
++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++[01] 0x7ffbda2dd5ca 0x5ca func: function_so_static, file: /data/callstack/test_so.c L7, module: /data/callstack/libtest.so[02] 0x7ffbda2dd5da 0x5da func: function_so, file: /data/callstack/test_so.c L13, module: /data/callstack/libtest.so[03] 0x401c5e 0x401c5e func: function_callso, file: /data/callstack/test.c L19, module: /data/callstack/callstack[04] 0x401d12 0x401d12 func: main, file: /data/callstack/test.c L44, module: /data/callstack/callstack[05] 0x7ffbd9f3e76d 0x2176d func: __libc_start_main, file: unknown, module: /lib/x86_64-linux-gnu/libc.so.6[06] 0x400f59 0x400f59 func: _start, file: unknown, module: /data/callstack/callstack++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
代码下载地址:https://github.com/thinkphoebe/callstack.git
参考:http://blog.csdn.net/littlefang/article/details/17654419http://blog.bigpixel.ro/2010/09/stack-unwinding-stack-trace-with-gcc/
来自为知笔记(Wiz)
附件列表
相关文章推荐
- 利用ftrace跟踪内核static tracepoint——实例writeback event
- linux中追踪函数backtrace调用堆栈
- 利用strace ltrace或truss跟踪程序的系统调用
- 利用ftrace跟踪内核static tracepoint——实例writeback event
- 利用ftrace跟踪内核static tracepoint——实例writeback event
- 获取iOS任意线程调用堆栈(五)完整实现:BSBacktraceLogger
- pstack跟踪程序调用堆栈
- 利用backtrace列出当前函数调用关系
- 利用backtrace解决程序coredump
- Firefox中利用javascript调用本地程序
- Firefox中利用javascript调用本地程序
- 【程序27】利用递归函数调用方式,将所输入的5个字符,以相反顺序打印出来
- Linux程序异常退出打印调用堆栈
- 什么是堆栈追踪(StackTrace)?如何利用StackTrace对程序进行调试?
- arm-eabi-addr2line工具跟踪Android调用堆栈
- Linux下利用backtrace追踪函数调用堆栈以及定位段错误
- Linux下利用backtrace追踪函数调用堆栈以及定位段错误
- Win32程序函数调用时堆栈变化情况分析
- 使用arm-eabi-addr2line, ndk-stack工具跟踪Android调用堆栈
- 利用MSCRM4.0 Trace功能跟踪详细错误信息