2012-01-12 102 views
9

我在程序中註冊了一個信號處理程序。在收到不需要的信號(SIGABRT)後,我在信號處理程序中調用'exit(-1)'來退出該過程。但正如少數會議上注意到的那樣,它調用exit(),但未能終止進程。可以退出()無法終止進程?

該問題是隨機生成的,我強烈懷疑執行exit()。

是否有任何原因或情況可導致exit()無法終止進程。

謝謝。

+1

我當然建議你尋找另一個導致bug的原因,而不是像'exit'這樣的函數。幾乎總是,當您認爲編譯器或標準庫等存在錯誤時,導致錯誤是您自己的錯誤。 – Shahbaz 2012-01-12 10:24:27

+3

@Shahbaz:Mandar並不是在詢問執行過程中的錯誤,或者暗示存在錯誤。問題是'exit'是否被指定爲總是終止程序,答案是否定的(特別是如果從信號處理程序中調用)。 – 2012-01-12 11:10:49

+0

爲什麼不把SIGABRT的處理程序設置爲exit()?無論您在信號處理程序中做了什麼其他事情,都可以在atexit()調用中執行。 – 2012-01-12 17:24:29

回答

13

你是否從信號處理程序調用exit()

man 7 signal,部分異步信號安全功能你可以看到所有被保障的功能從信號處理函數調用時的工作:

的信號處理函數必須非常小心,因爲處理其他地方可能會中斷 程序執行中的某些任意點。 POSIX具有「安全功能」的概念。如果 信號中斷不安全函數的執行,並且處理程序調用不安全函數,那麼程序的行爲是未定義的。

POSIX.1-2004(又稱POSIX.1-2001技術勘誤2)要求 保證實現下面的功能可以被安全地調用一個訊號處理器中:

那裏你可以見功能_Exit(),_exit()abort(),但特別不是exit()。所以你不應該從信號處理程序調用它。

令人討厭的是,即使您從信號處理程序(printf()任何?)調用不安全的函數,它也會在大多數情況下工作......但並非總是如此。

+1

從信號處理程序調用異步信號不安全函數*完全合法*除非信號中斷另一個異步信號不安全函數。這就解釋了它「大部分時間」工作的原因,但這也意味着如果您注意確保信號處理程序不能中斷不安全的情況,則即使在正確的,健壯的代碼中,也可以在信號處理程序中使用異步信號不安全的函數函數(例如,在大部分時間保留信號並且在執行純算術或像文件描述符IO和'select'這樣的異步信號安全庫調用時解除阻塞信號)。 – 2012-01-12 13:41:44

+0

@R ..當然你是對的。但在實踐中很難確保,除非在特殊情況下。我個人覺得更方便,只是爲了避免不安全的功能。 – rodrigo 2012-01-12 13:47:48

+1

另請參閱:http://pubs.opengroup.org/onlinepubs/009695399/functions/xsh_chap02_04.html – 2012-01-12 17:22:06

3

是的,有一些情況下,如:

出口()函數首先請)由atexit對(註冊的所有功能,在其註冊的相反的順序,不同之處在於一個函數被調用在任何之前已經註冊過的已經被調用的函數之後。每個功能在註冊時都被調用多次。如果在調用任何此類函數期間調用longjmp()函數來終止對已註冊函數的調用,則行爲未定義。

如果通過對atexit()的調用註冊的函數未能返回,則不應調用其餘的註冊函數,並且不應完成其餘的exit()處理。如果不止一次調用exit(),則行爲是未定義的。

請參閱exit上的POSIX頁面。

有關更多信息,請在遇到問題時附加一個調試器並查看調用堆棧。

相關問題