故障期间的backtrace()函数(SIGSEGV)信号处理程序

时间:2011-08-15 19:11:42

标签: c linux stack-trace

我已阅读(see here)在Linux下的故障信号处理程序(例如处理SIGSEGV)期间使用backtrace()打印堆栈跟踪的“常见做法”是:< / p>

1从未记录的EIP结构中获取指令指针(RIPsigcontext)。

2用指令指针替换堆栈跟踪中的第2帧,因为第一帧是信号处理程序,第2帧应该在libc代码的sigaction范围内,已覆盖故障发生的原始帧。

3从新更换的第二帧开始打印回溯。

在我的测试中(在x86_64 2.6内核上),实际上发生故障的原始帧存在于第3帧中由backtrace()给出的堆栈跟踪中 - 第一个是信号处理程序,第二个是libc信号处理代码。

内核信号处理的这种变化是否记录在某个可供我参考的地方?

在我看来,结果是你可以避免从指令指针替换任何帧,并从第3帧开始打印backtrace()的堆栈跟踪,但我想确认这是已知行为和正确的方法。

1 个答案:

答案 0 :(得分:5)

这是一个有趣的尝试,但它不是真正的便携式,可能永远不会100%可靠。所以,按照你说的方式实现它,如果它适用于你的平台,并包含一些小的单元测试,以便你立即知道你将来使用的某个系统是否工作方式不同。毕竟,当调用此代码时,您已经搞砸了,所以尽可能做到最好,然后继续前进。

可以同时使用或代替您的方案使用的完全不同的替代方法是编写一个脚本,以便在程序转储核心时由Linux调用。然后,此脚本可以在核心文件上以批处理模式运行gdb以获取回溯并向您发送电子邮件或其他任何内容。