项目中遇到了一个多线程的问题,系统总是莫名其妙的崩溃,而且bug不可重现,后来发现是接收到某些信号的问题,于是乎就加入了信号处理函数,想获得是什么地方触发了这个信号,因为感觉多线程调试比较麻烦,于是就想到了使用利用__builtin_return_address来获得函数运行栈的方法。
直接上测试代码:
| #include #include #include
#define MAX_LEVEL 4 void sigfunc(int signo) { printf("%s(0): %p\n", __func__, __builtin_return_address(0)); printf("%s(1): %p\n", __func__, __builtin_return_address(1)); printf("%s(2): %p\n", __func__, __builtin_return_address(2)); printf("%s(3): %p\n", __func__, __builtin_return_address(3)); printf("%s(4): %p\n", __func__, __builtin_return_address(4)); exit(1); }
int b() { printf("%s(0): %p\n", __func__, __builtin_return_address(0)); while(1) { sleep(1); } }
int a(int temp) { temp += 1; printf("%s(0): %p\n", __func__, __builtin_return_address(0));
b();
return temp; }
int main() { signal(SIGINT, sigfunc); a(123);
return 0; }
|
运行结果:
wangyao@wangyao-laptop:~/Test$ ./a.out
a(0): 0x8048554
b(0): 0x804851e
sigfunc(0): 0xb7eef420
sigfunc(1): 0x80484f2
sigfunc(2): 0x804851e
sigfunc(3): 0x8048554
sigfunc(4): 0xb7da2450
我们已经拿到了程序运行轨迹中的逻辑地址,下面的就是在gdb里面l一下那些地址就可以了:
wangyao@wangyao-laptop:~/Test$ gdb -q a.out
(gdb) l *0x804851e
0x804851e is in a (t_return.c:37).
32 temp += 1;
33 printf("%s(0): %p\n", __func__, __builtin_return_address(0));
34
35 b();
36
37 return temp;38 }
39
40 int main()
41 {
(gdb) q
这样就已经找到了程序运行的轨迹,如果使用一些ELF处理的库直接解析符号表的话,也可以不用gdb来做,直接通过得到的逻辑地址进行定位;-)
参考:
http://blog.csdn.net/celestialwy/archive/2006/10/23/1346155.aspx
阅读(7320) | 评论(0) | 转发(1) |