繁体   English   中英

如何正确终止信号处理程序中的线程?

[英]How to properly terminate a thread in a signal handler?

我想为SIGSEGV,SIGILL和可能的其他一些信号设置信号处理程序,而不是终止整个过程,而只是终止有问题的线程,并可能在某个地方设置一个标志,以便监视线程可以投诉并启动另一个线程。 我不确定是否有安全的方法可以做到这一点。 Pthreads似乎提供了退出当前线程以及取消另一个线程的功能,但是它们可能会调用一堆退出处理程序。 即使它们不是,似乎在许多情况下它们也不是异步信号安全的,尽管这些情况是可以避免的。 我可以调用一个较低级别的函数来破坏线程吗? 假设我以异步信号安全的方式修改了自己的数据结构,并且不获取互斥体,是否存在仅通过终止于SIGSEGV的线程就可以使pthread /其他全局数据结构处于不一致状态? 我想到了malloc,但是除非libc有问题,否则malloc本身不应该SIGSEGV / SIGILL。 我意识到POSIX在这里非常保守,不能做任何保证。 只要有一种方法可以在实践中做到,我就很高兴。 顺便说一句,不能选择分叉。

如果是SIGSEGV / SIGILL / SIGILL 如果发生在您自己的代码中 ,则信号处理程序将不会在异步信号上下文中运行(从根本上来说,这是一个同步信号,但是如果它发生在标准库函数中,则仍将是AS上下文),因此您可以从合法地调用pthread_exit信号处理程序。 但是,仍有一些问题使这种做法令人怀疑:

  • SIGSEGV / SIGILL 除非您通过raisekillpthread_killsigqueue等生成行为,否则在定义了行为的程序中绝不会发生这种情况(在某些特殊情况下,它们将是异步信号)。 否则,它们表示程序具有未定义的行为 如果程序调用了未定义的行为,则所有选择均关闭。 UB没有隔离到特定线程或特定时间序列。 如果程序具有UB,则其整个输出/行为将毫无意义。

  • 如果程序的状态被破坏(例如,由于free -after- free ,使用无效指针,缓冲区溢出等),则第一次故障访问很有可能发生在标准库的一部分内(例如,在malloc ),而不是比您的代码中。 在这种情况下,信号处理程序在AS安全的上下文中运行,并且无法调用pthread_exit 当然该程序已经有了UB(请参阅以上几点),但是即使您假装这不是问题,您仍然会遇到麻烦。

如果您的程序遇到此类崩溃,则需要找到原因并加以解决,而不是尝试使用信号处理程序对其进行修补。 Valgrind是你的朋友。 如果那是不可能的,那么最好的选择是将崩溃的代码隔离到单独的进程中,在该进程中,您可以推断出它们异步崩溃时会发生什么,而不是让崩溃的代码处于同一进程中(其中,有关代码行为的任何进一步的推理都是无效的)一旦您知道它崩溃了)。

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM