|
EDA365欢迎您登录!
您需要 登录 才可以下载或查看,没有帐号?注册
x
一般察看函数运行时堆栈的方法是使用GDB(bt命令)之类的外部调试器,但是,有些时候为了分析程序的BUG,(主要针对长时间运行程序的分析),在程序出错时打印出函数的调用堆栈是非常有用的。. S+ c$ {5 {' H# l' W
在glibc头文件"execinfo.h"中声明了三个函数用于获取当前线程的函数调用堆栈。
1 O4 f3 B, Q7 a" B. c; Z1 U5 u2 m) }3 ?8 E7 Q7 L ~1 N
int backtrace(void **buffer,int size) 0 c7 |& l+ `; E. |2 p3 A6 J: P
- }" P8 R% g3 C8 K) |: O
该函数用于获取当前线程的调用堆栈,获取的信息将会被存放在buffer中,它是一个指针列表。参数 size 用来指定buffer中可以保存多少个void* 元素。函数返回值是实际获取的指针个数,最大不超过size大小
2 ^( z0 t) _( ]1 P+ S3 T8 R4 \7 b5 E V/ |+ g
在buffer中的指针实际是从堆栈中获取的返回地址,每一个堆栈框架有一个返回地址2 k3 e* v( U3 t `
" }4 C: D! c7 n) I9 A; G' w注意:某些编译器的优化选项对获取正确的调用堆栈有干扰,另外内联函数没有堆栈框架;删除框架指针也会导致无法正确解析堆栈内容
: T2 X6 s$ I9 S0 S# V& B4 _char ** backtrace_symbols (void *const *buffer, int size) 6 x5 {0 R6 U) e
! w& m. k: l! o; _. }% S$ q% j
backtrace_symbols将从backtrace函数获取的信息转化为一个字符串数组. 参数buffer应该是从backtrace函数获取的指针数组,size是该数组中的元素个数(backtrace的返回值) a: {0 m# R& Y0 x% b6 D
1 b" k; d) ]" X9 J8 y. v函数返回值是一个指向字符串数组的指针,它的大小同buffer相同.每个字符串包含了一个相对于buffer中对应元素的可打印信息.它包括函数名,函数的偏移地址,和实际的返回地址/ T- m. V/ l, K2 x
* R8 {5 N% c$ T$ t4 q4 u
( @6 _ i/ n+ W- T% S4 v# C* L
|
|