Linux 信号处理程序(segv)无法在设备崩溃前完成

Linux 信号处理程序(segv)无法在设备崩溃前完成,linux,segmentation-fault,signals,Linux,Segmentation Fault,Signals,我安装了一个处理程序(比如crashHandler()),它具有一些文件输出功能。它是一个linux线程,使用crashHandler()注册SIGSEGV。需要写入文件,因为它将堆栈跟踪存储到持久存储。 它在大多数情况下都有效。但在特定场景中,函数(crashHandler())会部分执行该函数(我可以看到日志),然后设备重新启动。有人能帮我解决这个问题吗?这里要问的第一个问题是为什么设备会重新启动。通常,普通应用程序崩溃不会导致内核级或硬件级重新启动。最有可能的情况是,您在崩溃处理程序完成之

我安装了一个处理程序(比如crashHandler()),它具有一些文件输出功能。它是一个linux线程,使用crashHandler()注册SIGSEGV。需要写入文件,因为它将堆栈跟踪存储到持久存储。

它在大多数情况下都有效。但在特定场景中,函数(crashHandler())会部分执行该函数(我可以看到日志),然后设备重新启动。有人能帮我解决这个问题吗?

这里要问的第一个问题是为什么设备会重新启动。通常,普通应用程序崩溃不会导致内核级或硬件级重新启动。最有可能的情况是,您在崩溃处理程序完成之前点击了一个看门狗计时器(在这种情况下,您应该延长看门狗超时时间-但不要从崩溃处理程序中重置计时器,因为这样会使崩溃处理程序本身出现问题,从而阻止重新启动),或者这是pid 1,它在SIGSEGV处理程序中崩溃,由于pid 1(初始化)死亡而导致内核死机


如果是后者,您需要更加小心在崩溃处理程序中执行的操作。记住,你刚才撞车了。你知道内存是损坏的,但你不知道它是如何损坏的。它可能以影响崩溃处理程序本身的方式损坏-例如,如果损坏堆元数据,则可能无法分配内存,而这次不会真正崩溃。您应该将在该处理程序中执行的操作保持在最低限度,特别是,避免调用任何未被记录为存在的库函数,并避免使用任何复杂的(包含指针的)数据结构或动态分配的内存。为了实现最高级别的安全性,请将自己限制为只执行fork()和exec()的另一个进程,该进程将使用调试器API(
ptrace()
/proc/$PID/mem
)来执行内存转储或您可能需要的任何其他操作。

非常感谢您对各种可能性的详细解释。我收集到的信息是,由于crashhandler()正在被执行,很可能是看门狗计时器启动了。如果是,我如何增加它?我还想确认,如果pid 1死亡发生,我看不出crashhandler有任何被呼叫的机会。这是正确的吗?推论:如何处理SIGSEGV,以便为以后的调试保留堆栈跟踪(持久化)?请注意,在这种情况下,内核转储不是一个选项,因为空间非常有限。