2012-01-26 20 views
5

我的問題是:確定一個功能是異步信號安全的(可以稱爲信號處理器中)

  1. 有沒有辦法最終確定的函數是異步信號安全的,如果你沒有獲得其實施?
  2. 如果不是,有沒有一種方法可以測試函數是否足夠支持異步信號以從信號處理程序調用?

如果您讀取signal()或sigaction()的手冊頁,會得到一個異步信號安全函數列表(可在信號處理函數內安全調用的函數)。不過,我認爲這份清單並不詳盡。例如,在下頁http://linux.die.net/man/7/signal,所述異步信號安全功能標題下,顯示如下:

POSIX.1-2004(也稱爲POSIX.1-2001技術勘誤2)需要一個實施保證可以在信號處理程序內安全地調用以下功能:

然後它繼續列出上面手冊頁中列出的常規異步信號安全功能。當我讀到它時,它說「它需要」,而不是「這些是唯一的」。

例如,this site表示back_trace_symbols_fd()是異步信號安全的。該函數獲取的是來自dladdr()的數據,並且它不像使用back_trace_symbols()那樣使用malloc(),所以它看起來可能是安全的。另外,我做了一些測試,並且dladdr()的輸出結構包含char *變量,但是這些變量在運行時不是malloc。它們指向的char字符串在運行時即使在調用dladdr()之前也存在。

任何想法或想法,可以指向我在正確的方向表示讚賞。

+2

不要忘記對你的問題投票有用的答案,或接受對你的每個問題最有用的答案。如果您不確定,請查看[常見問題](http://stackoverflow.com/faq),特別是[如何在此處提問?](http://stackoverflow.com/faq#howtoask) –

回答

4

如果您無法訪問函數的實現,可以查看手冊頁。如果手冊頁沒有說它是異步安全的,並且POSIX標準沒有說它是異步安全的,唯一安全的結論是「它不是異步安全的」(加上「不要使用它」 )。

沒有100%可靠的方法來測試函數是否是異步安全的。請記住,測試只能顯示錯誤的存在,而不是它們的缺失(Dijkstra)。事實上,你沒有設法將功能癢癢的測試行爲可能只是意味着你的測試是不夠的(但放心,你不能冒犯的重要客戶會立即和意外地設計一個毀滅性的有效測試,證明該函數幾乎在您發佈具有錯誤假設的代碼時就不是異步安全的)。

+0

This方法相當令人沮喪,因爲例如'strlen'和'memcpy'不能保證異步信號的安全。但你只需要忍受它 - 你永遠不知道什麼時候一些明亮的火花會發明一個真正不可重入的令人難以置信的優化'memcpy'。無論如何,C標準說庫函數通常不能從信號處理程序中調用(異步信號 - 不安全只是說它不能從處理程序調用一個恰好中斷另一個不安全函數的信號,但這是一個棘手的事情,以實際獲得任何優勢)。 –

+0

@SteveJessop strlen()未在sigaction()的手冊頁中定義爲async-signal-safe,但可以實現自己的異步信號安全版本。它所做的就是計算非NULL字符,當你到達NULL時返回該值。 – Roberto

+0

@JonathanLeffler你知道爲什麼有些手冊頁指定了線程安全性和信號安全性,而另一些則沒有?我猜我應該按照我自己的操作系統的手冊頁。一些手冊頁指定了一個屬性(5)函數(不知道它是否是一個函數),它指定了所有這些和更多。你知道如何訪問?請參見示例手冊頁:http://compute.cnr.berkeley.edu/cgi-bin/man-cgi?dladdr+3 – Roberto

0

你希望在信號處理程序中實現什麼?你應該考慮它是否適合它。這可能是最好的按照手冊頁的建議:

In general, signal handlers should do little more 
than set a flag; most other actions are not safe. 
+1

你可以在信號處理程序中做更多的事情。你只需要小心。看看這個例子:http://code.google.com/p/plcrashreporter/ – Roberto