【发布时间】:2018-02-01 22:55:06
【问题描述】:
我的应用使用 SIGSEGV(Segmentation Violation)信号处理程序(在 sigaction() 注册)。
当我的应用程序访问 NULL 指针时,我的 SIGSEGV 处理程序获得一个控制,打印(到控制台并记录)违规线程的堆栈跟踪,并调用导致核心转储(崩溃转储)的默认信号处理程序一代。因此,当测试人员报告崩溃时,我很快会在日志中看到有问题的线程堆栈跟踪(没有分析核心转储)。
但是在 堆栈溢出 的情况下,我的信号处理程序未启动,应用程序崩溃(带有静默日志)。在分析核心转储时,我(或我的同事)发现崩溃发生在正确代码的中间。理解堆栈溢出是崩溃的原因需要很长时间。所以我希望在日志中至少有一条消息“堆栈溢出”(以防堆栈溢出)。
在阅读SIGALTSTACK(2) 手册页(注意部分)时,我意识到我的信号处理程序是在有问题的线程的堆栈上调用的,这就是为什么在堆栈溢出的情况下无法调用信号处理程序(没有堆栈以调用信号处理程序)。 但是,可以在备用堆栈上运行信号处理程序。这将让我的信号处理程序记录消息“堆栈溢出”。
但是手册页让我认为,如果我将 SIGSEGV 处理程序切换为使用备用堆栈,则处理程序将始终在备用堆栈上执行,并且将无法记录 NULL 指针的违规线程堆栈跟踪-访问案例。
因此问题是:“如何使 SIGSEGV 处理程序在备用堆栈上启动仅适用于堆栈溢出情况(以及在当前活动堆栈上适用于所有其他情况)?”
要获取堆栈跟踪,我使用以下调用:backtrace()、backtrace_symbols()、abi::__cxa_demangle()。
【问题讨论】:
-
在“正常”
sigsegv的情况下如何获取堆栈跟踪? -
@user58697,我已经更新了问题,见底线。