【问题标题】:Is it possible to terminate only the one thread on receiving a SIGSEGV?是否可以在接收到 SIGSEGV 时仅终止一个线程?
【发布时间】:2011-09-03 05:05:49
【问题描述】:

我有一个启动多个线程的应用程序。 我正在使用信号处理程序来捕获信号。

我不希望我的应用程序在SIGSEGV 上退出;我只想终止产生信号的线程,并在其他线程中继续整个应用程序的流程。 有可能吗?

【问题讨论】:

  • @asveikau 它是服务器应用程序,我将在 SIGGEV 上发送警报,但我不想因为一个线程崩溃而影响其他线程。是不是和c++中的异常处理不一样?
  • 如果您想与崩溃隔离,请使用多个进程,而不是线程。如果错误代码与服务器的其余部分位于相同的地址空间中,它很可能会使您的进程的其余部分处于错误状态。更不用说你应该编写你的服务器,使其不会首先崩溃.....
  • 投反对票有什么理由吗?我才知道,这是不好的做法。但是我不应该在这个网站上清除我的疑问吗?
  • 不,它与 C++ 中的异常处理不同。看这里讨论pthread_sigmask():linuxjournal.com/article/2121
  • 什么是SIGGEV?你的意思是SIGSEGV

标签: c signal-handling


【解决方案1】:

如果出现SIGSEGV,则表明您的程序已经调用了未定义的行为,即整个程序的状态为未定义/不确定/无效。在实践中,您可能能够恢复并继续跑步,但不能保证,这可能很危险。

正如 asveikau 所提到的,您可以将 longjmp 退出信号处理程序并尝试进行清理,但如果崩溃发生在 mallocfreeprintf 中间,这可能会造成更严重的混乱,或任何修改全局数据或与其他线程共享的数据或将在longjmp 目标的清理代码中访问的数据的状态的函数。状态可能已损坏/不一致,和/或锁可能被持有并永久不可释放。

如果你能确保这不会发生——例如,如果行为不端的线程从不调用任何异步信号不安全函数——那么从信号处理程序中调用 longjmp 可能是安全的,然后调用 pthread_exit

另一种方法可能是永久冻结信号处理程序中的线程,方法是将所有信号添加到SIGSEGVsa_mask,然后在信号处理程序中写入for (;;) pause();。这是 100%“安全”的,但如果崩溃线程持有任何锁,则可能会使进程处于死锁状态。这可能比将损坏状态暴露给其他线程并进一步破坏您的数据到地狱“更糟糕”......

【讨论】:

  • 我在最初的评论中确实提到了longjmp,但我删除了这个建议。无论好坏,这可能不是他要问的,而且可能会比他开始时引起更多的混乱。
猜你喜欢
  • 2019-06-06
  • 1970-01-01
  • 1970-01-01
  • 2012-04-29
  • 2021-06-08
  • 2012-01-22
  • 2011-06-07
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多