【问题标题】:backtrace() function during fault (SIGSEGV) signal handler故障(SIGSEGV)信号处理程序期间的回溯()函数
【发布时间】:2011-08-15 19:11:41
【问题描述】:

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

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

2 将堆栈跟踪中的第二帧替换为指令指针,因为第一帧是信号处理程序,并且第二帧应该在sigaction 代码中的libc 内,它已经覆盖了原来的发生故障的帧。

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

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

内核信号处理的这种变化是否记录在您可以参考的地方?

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

【问题讨论】:

    标签: c linux stack-trace


    【解决方案1】:

    这是一件有趣的事情,但它并不是真正的便携,而且可能永远不会 100% 可靠。因此,只需按照您所说的方式实现它,如果它在您的平台上有效,并为其包含一些小单元测试,以便您立即知道您将来使用的某些系统是否以相同的方式工作。毕竟,当这段代码被调用时,你已经搞砸了,所以尽你所能继续前进吧。

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

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2019-08-24
      • 2013-09-09
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2018-05-29
      相关资源
      最近更新 更多