我需要在我的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(); 清理(); ... }
答案 0 :(得分:3)
你想在SIGSEGV之后进行清理(即严重错误)......我发现这有点奇怪,因为,1)如果你正在调试应用程序,你应该保留所有内容,以便存储在核心文件中,这样你就可以准确确定发生了什么,2)如果你有一个客户的发布申请(让我们说)好......它不应该是SIGSEGV :)(不管怎样我的问题,只是说..)
关于主题,
我认为你可以尝试阻止所有线程中的SIGSEGV,除了你试图进行清理的线程;这应该使os将信号传递给该特定线程。我能想到的其他解决方案是setjmp()/ longjmp()(虽然没有测试过任何这些)。
小心一旦你的程序得到一个SEGV,你就处于不稳定的状态(即你的清理也可能会失败,并产生另一个SEGV等),所以你应该考虑使用核心崩溃。
答案 1 :(得分:2)
在遇到SIGSEGV后,可靠无法运行任何代码。你有时可能会逃避它,但你不能相信你的程序在事后按预期工作。例如,如果您因为堆损坏而有SIGSEGV,那么如果您的第三方lib正在清理任何内存,您将遇到问题。
为了获得一个可靠的解决方案,我会想一想你是否真的需要运行那个清理代码,或者是否有另一种方法来处理这种情况(检查下次启动时是否有不正常的关机,......)。
答案 2 :(得分:1)
我认为你不应该尝试运行任何清理内存状态的东西,特别是将其写入光盘,就像成功一样,你会导致数据损坏。
如果可能的话,记录一些状态信息可能有助于调试,但你不应该依赖它。
相反,程序应该在记录状态信息之后返回默认处理程序(和转储核心等),或者调用_exit并退出而不进行任何清理。
如果您需要在崩溃后重新开始清理工作,请在下次启动时执行此操作。