在Linux中处理SIGSEGV?

时间:2010-06-10 06:48:05

标签: linux handler signals sigsegv

我需要在我的Linux应用程序中处理SIGSEGV。原因是在生成核心转储之前必须进行一些清理(3-partry lib)。更重要的是,清理必须在调用线程的上下文中执行,不能在信号处理程序中执行。   所以我计划在信号处理程序中将控制传递给调用线程,在清理完成后,然后使用raise(SIGSEGV)生成核心转储。

真正的问题似乎是signal_handler无法将控制传递给调用线程,无论我使用post_sem还是其他一些。  有没有办法处理这个案子? Possbile劫持SIGSEGV,然后在SIGSEGV hander返回另一个线程执行一些清理工作?

信号(SIGSEGV,signal_handler);

signal_handler() { ...  post_sem(); ... }

调用thread() {   wait_sem();   清理(​​);   ... }

3 个答案:

答案 0 :(得分:3)

你想在SIGSEGV之后进行清理(即严重错误)......我发现这有点奇怪,因为,1)如果你正在调试应用程序,你应该保留所有内容,以便存储在核心文件中,这样你就可以准确确定发生了什么,2)如果你有一个客户的发布申请(让我们说)好......它不应该是SIGSEGV :)(不管怎样我的问题,只是说..)

关于主题,

我认为你可以尝试阻止所有线程中的SIGSEGV,除了你试图进行清理的线程;这应该使os将信号传递给该特定线程。我能想到的其他解决方案是setjmp()/ longjmp()(虽然没有测试过任何这些)。

小心一旦你的程序得到一个SEGV,你就处于不稳定的状态(即你的清理也可能会失败,并产生另一个SEGV等),所以你应该考虑使用核心崩溃。

答案 1 :(得分:2)

在遇到SIGSEGV后,可靠无法运行任何代码。你有时可能会逃避它,但你不能相信你的程序在事后按预期工作。例如,如果您因为堆损坏而有SIGSEGV,那么如果您的第三方lib正在清理任何内存,您将遇到问题。

为了获得一个可靠的解决方案,我会想一想你是否真的需要运行那个清理代码,或者是否有另一种方法来处理这种情况(检查下次启动时是否有不正常的关机,......)。

答案 2 :(得分:1)

我认为你不应该尝试运行任何清理内存状态的东西,特别是将其写入光盘,就像成功一样,你会导致数据损坏。

如果可能的话,记录一些状态信息可能有助于调试,但你不应该依赖它。

相反,程序应该在记录状态信息之后返回默认处理程序(和转储核心等),或者调用_exit并退出而不进行任何清理。

如果您需要在崩溃后重新开始清理工作,请在下次启动时执行此操作。