首页 诗词 字典 板报 句子 名言 友答 励志 学校 网站地图
当前位置: 首页 > 教程频道 > 操作系统 > UNIXLINUX >

Linux下多线程程序崩溃时怎么提取出所有线程的函数调用栈

2012-02-24 
Linux下多线程程序崩溃时如何提取出所有线程的函数调用栈尝试过三种方法都不凑效1.libc 中的backtrace函数

Linux下多线程程序崩溃时如何提取出所有线程的函数调用栈
尝试过三种方法都不凑效
1.libc 中的backtrace函数
2.内联汇编,提取出ebp寄存器的值再回溯出函数调用栈(会有兼容性问题,x86下试过可以,一移植到其他平台就用不了,本人菜鸟,汇编不熟)
3.gcc 内建的两个函数 
Built-in Function: void * __builtin_return_address (unsigned int level)

Built-in Function: void * __builtin_frame_address (unsigned int level) 


这些都是只能提取出当前线程的调用栈信息

望各位大虾赐教,感激不尽 


ps: 是通过signal监听异常信号,要在回调函数中把堆栈信息提取出来

  目前我只能发100分的贴

[解决办法]
突然想到一个,你用gdb调试,用backtrace命令看看。就算不能查看所有线程的栈,但是对程序崩溃的原因调查应该有所帮助吧!
[解决办法]
atexit + backtrace试试。
[解决办法]

探讨
尝试过三种方法都不凑效
1.libc 中的backtrace函数
2.内联汇编,提取出ebp寄存器的值再回溯出函数调用栈(会有兼容性问题,x86下试过可以,一移植到其他平台就用不了,本人菜鸟,汇编不熟)
3.gcc 内建的两个函数
Built-in Function: void * __builtin_return_address (unsigned int level)

Buil……

[解决办法]
我觉得可能是线程处理信号的问题。

linux的线程是轻量级进程,线程有自己的信号处理表,继承于父进程。而内核发送信号的单位是进程级别的,不向所有的线程发信号。

参考一下这个文章:
http://www.ibm.com/developerworks/cn/linux/kernel/l-thread/
[解决办法]
两个问题:

1、你确定捕捉信号的那个位置是在创建线程之前还是之后?

2、你可以考虑把所有线程记录下来,用pthread_kill给所有线程发送一个消息(比如USR1)。在USR1中独立用backtrace打印调用栈。
[解决办法]
gdb下用thread apply all bt这个命令不行么?
[解决办法]
看下下面的页面,或许有帮助
http://www.2cto.com/kf/201107/97270.html
[解决办法]
A backtrace is the series of currently active function calls for the program.
-----------------------------------------

以上是man手册里的一句话,我的理解是:

1)如果用backtrace函数记录堆栈信息,应当在每个需要记录堆栈信息的函数体内运行这个函数(这时堆栈正常);

2)当异常发生时,比如楼主说的Test2()函数内除零,只有在Test2函数上下文环境没有被破坏时,
backtrace才能正常运行,如果在信号处理函数里运行backtrace时,之前的上下文可能已经不存在了;
因为信号处理函数注册后,在内核发出异常信号后被程序捕捉执行,这时信号处理函数内的backtrace读取的是这个时刻的上下文环境;

3)信号处理函数是进程中所有线程共享的,任何一个线程改变了信号处理函数,都影响其它线程;
与硬件故障或计时器超时相关信号被发送到引起该事件的线程中去;
其它信号则被发送到任意一个线程,在Linux中,就是当前进程的第一个线程;

我是菜鸟,一点拙见,欢迎批评指正;

热点排行