在 Linux 中处理 SIGSEGV?
我需要在我的 Linux 应用程序中处理 SIGSEGV。原因是在生成核心转储之前必须进行一些清理(3-partry lib)。更重要的是,清理必须在调用线程的上下文中执行,不能在信号处理程序中执行。 因此,我计划在信号处理程序中将控制权传递给调用线程,在清理完成后,然后使用 raise(SIGSEGV) 生成核心转储。
真正的问题似乎 signal_handler 无法将控制传递给调用线程,无论我使用 post_sem 还是其他一些。 有什么想法可以处理这个案子吗?是否可以劫持 SIGSEGV,然后在 SIGSEGV 处理程序中返回到另一个线程来执行一些清理?
信号(SIGSEGV,signal_handler);
信号处理程序() { ... post_sem(); ... }
调用线程() { wait_sem(); 清理(); ... }
I need handle the SIGSEGV in my Linux app. The reason is some clean up(3-partry lib) must be done before generate core-dump. What is more, the clean up must be performed in the context of calling thread, cannot do in signal handler.
So I plan in signal handler to pass the control to the calling thread, after the clean up finished, then use raise(SIGSEGV) to generate the core-dump.
The real problem seems the signal_handler cannot pass the control to calling thread, no matter I use post_sem or some others.
Any idea to handle this case? Possbile to hijack the SIGSEGV, then in SIGSEGV hander return to another thread to perform some clean up?
signal(SIGSEGV, signal_handler);
signal_handler()
{
...
post_sem();
...
}
calling thread()
{
wait_sem();
clean_up();
...
}
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(3)
您想在 SIGSEGV (即严重错误)后进行清理...我觉得这有点奇怪,因为,1)如果您正在调试应用程序,您应该将所有内容完好无损地存储在核心文件中,以便您可以准确地识别发生了什么2)如果您有一个客户的发布应用程序(比方说)...它不应该 SIGSEGV :)(无论如何不是我的问题,只是说..)
就主题而言,
我认为您可以尝试阻止 SIGSEGV除了您尝试进行清理的线程之外的所有线程;这应该使操作系统将信号传递给该特定线程。我能想到的其他解决方案是类似于 setjmp() / longjmp() 的方法(但尚未测试其中任何一个)。
请注意,一旦您的程序获得了 SEGV,您的基础就会不稳定(即您的清理也可能会失败并生成另一个 SEGV 等),因此您应该考虑仅因核心而崩溃。
You want to cleanup after a SIGSEGV (i.e. serious error)... I find this a little weird because, 1) if you were debugging the application you should leave everything intact to be stored in the core file so you can accurately identify what happened and 2) if you have a release application for a customer (let's say) well...it shouldn't SIGSEGV :) (not my problem anyway, just saying..)
On topic,
I think you could try to block SIGSEGV in all threads except the one in which you are trying to do the cleanup; this should make the os deliver the signal to that specific thread. Other solution I could think of is something along the lines of setjmp() / longjmp() (haven't tested any of these though).
Be careful that once your program got a SEGV, you're on shaky ground (i.e. your cleanup might fail as well and generate another SEGV etc etc) so you should consider just crashing with a core.
在遇到 SIGSEGV 后,不可能可靠运行任何代码。有时您可能会侥幸逃脱,但您不能相信您的程序随后会按预期工作。例如,如果您由于堆损坏而出现 SIGSEGV,那么当您的第 3 方库正在清理任何内存时,您将会遇到问题。
为了获得可靠的解决方案,我会考虑您是否确实需要运行该清理代码,或者是否有其他方法来处理这种情况(检查下次启动时是否有不干净的关闭,...)。
Its not possible to reliable run any code after you have encountered a SIGSEGV. You might get away with it sometimes but you can't trust your program to work as intended afterwards. If for example you have a SIGSEGV because of a corrupted heap you will have problems if your 3rd party lib is cleaning up any memory.
To get a reliable solution i would think about if you really need to run that cleanup code or if there is another way to handle the situation (check for an unclean shutdown on the next startup, ...).
我认为您不应该尝试运行任何清理内存状态的操作,尤其是将其写入光盘,就好像成功一样,您会导致数据损坏。
如果可能的话,记录一些状态信息可能有助于调试,但您不应该依赖这种能力。
相反,程序应该在记录状态信息后,返回到默认处理程序(并转储核心等),或者调用 _exit 并退出而不进行任何清理。
如果您需要执行清理工作以在崩溃后重新启动,请在下次启动时执行此操作。
I think you should not try to run anything which cleans up in-memory state, especially writing it to disc, as if successful, you make cause data corruption.
Recording some state information, if possible, may aid debugging, but you should not rely on being able to.
Instead, the program should, after logging state information, either return to the default handler (and dump core etc), or call _exit and quit without any cleanup whatsoever.
If you need to do cleanup work to start again after a crash, do it on the next startup instead.