簡體   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