2011-07-12 108 views
4

在我的main()的開始,我有:爲什麼信號不會被捕獲?

signal(SIGTERM, SIGTERM_handler); 

SIGTERM_handler是:

void SIGTERM_handler(int signum) { 

    NSLog(@"Caught signal: [%d]. Cleaning up ...",signum); 
    //cleanup(); 
    NSLog(@"Done cleaning up. Exiting ..."); 
    exit(EXIT_FAILURE); 
} 

那些線從來沒有印刷。當我在處理程序中設置斷點時,它們從不被擊中。我不會在任何地方撥打sigaction()。 GDB設置爲通過我關心的信號(handle SIGTERM SIGINT pass stop printhandle SIGTERM SIGINT pass nostop print)。即使是默認的信號處理程序也不起作用 - 向程序發送SIGINT(爲此我沒有指定處理程序)也什麼都不做。

這可能是什麼原因造成的?

+0

有沒有可能日誌文件緩衝區沒有被刷新? –

+0

如何在gdb中運行時將信號發送給您的進程?我會建議嘗試其他信號之一(比如殺死-1或殺死-2) – KevinDTimm

+0

我發送的信號包括'kill -2','kill -15'和其他信號。我知道這是行得通的,因爲如果我轉而做「處理...停止」,那麼GDB確實停止並說我的程序收到了一個信號;它仍然不會觸發處理程序。 –

回答

2

肖恩,所以你使用CZMQ,每當你做一個zctx_new()時,它將信號轉移到自己的目的。我的建議是,如果可能讓CZMQ做它的事情,並使用它提供的機制來捕獲中斷,這些機制是全局zctx_interrupted變量,並且在任何阻塞的ZMQ調用中,都會返回一個空返回值和EINTR錯誤代碼。

5

我不知道目標C,但我確實有信號處理經驗,所以我會回答,因爲如果POSIX和C.

調用沒有被記錄爲「異步信號安全」中的任何功能信號處理程序是一種風險,應該避免。當調用信號處理程序時,您不能對堆棧或其他狀態做出任何假設。當您的信號處理程序被調用時,堆棧甚至可能會被「丟棄」(在創建或銷燬幀的過程中)。當您的信號處理程序被調用時,您的庫可能有不一致的狀態。

聲明一個在你的事件循環中被檢查的易失標誌(int),以查看它是否已經改變。信號處理程序應該只設置該標誌並返回,沒有別的。 (除非您的平臺使用SVR4類型的信號,在這種情況下,您還需要在信號處理程序中重新安裝信號處理程序。)

響應信號的日誌消息和其他活動應該通過任何代碼完成檢查標誌並處理該標誌暗示的事件。

您看到的症狀可能不是由於信號處理程序中的庫調用(我的錢會誠實地在gdb交互中),但我絕對建議將所有庫調用從信號處理程序中取出。

0

你在調試器中運行這個嗎?從GDB發佈的內部和外部,我遇到了在iOS平臺上處理信號的問題。我認爲OSX中會出現同樣的問題。這已經很長時間了,我不能給你具體的東西

相關問題