簡體   English   中英

信號處理

[英]signal handling

我只是在Mac OS X中玩信號。

為什么在我的信號處理程序完成后,以下代碼不會產生SIGSEGV的默認行為? 在Linux下,代碼工作正常。

#include <stdio.h>
#include <signal.h>
#include <stdlib.h>

void err_crash();

void my_signal_handler (int signal)
{
    fprintf(stderr, "signal == %i\n", signal);
    fflush(stderr);
    err_crash();
}

void err_crash()
{
    static int count= 0;
    if (count)
        signal(SIGSEGV, SIG_DFL);       /* break recursion loop if we recursed */
    count++;

    // one of the two should really crash ;)
    ((void)(*((int volatile *)NULL)));
    *((int *)NULL) = 42;

    abort();                            /* in case we're not crashed yet... */
}

int main ()
{
    signal(SIGSEGV, my_signal_handler);
    err_crash();
    return 0;
}

編輯:我得到的輸出如下:

bonecrusher:devel sw$ g++ signal_problems.cpp -o foo
bonecrusher:devel sw$ ./foo 
signal == 11
^C
bonecrusher:devel sw$

問題是我希望程序在signal == 11的輸出之后終止,但它永遠發生,我必須打斷它。

這實際上讓我大腦凍結了幾分鍾,而且在這個時代,人們不應該使用signal()的原因只會在我身上變得更強。

首先,從signal()的手冊頁

signal()的行為在UNIX版本中各不相同,並且在不同版本的Linux上也有不同的歷史變化。 避免使用:改為使用sigaction(2)。

進一步向下:

  • 如果處置設置為函數,則首先將處置重置為SIG_DFL,或者阻止信號(參見下面的可移植性),然后使用參數signum調用處理程序。 如果處理程序的調用導致信號被阻塞,則在從處理程序返回時信號被解除阻塞。

在原來的Unix系統中,被安裝的處理程序時,配置被復位為SIG_DFL, 阻斷的相同類型的輸入信號,然后將其跑處理函數。 System V提供了這個,而linux內核也是如此。

這意味着,一旦代碼在linux系統上運行,一旦調用第二個異常,它將直接退出。

現在到了有趣的部分。 BSD試圖改善這種行為。 再次從手冊頁:

在BSD上,當調用信號處理程序時,信號處理不會被重置,並且在處理程序執行時阻止信號的其他實例被傳遞。

由於mac osx部分基於BSD,一旦代碼在mac osx上運行,一旦調用第二個異常,它將處於掛起狀態並等待第一個異常的處理程序退出。 但既然你永遠不會退出,那你就陷入了僵局。

這就是為什么一個人應該使用sigaction()而不是signal()

現在來一些提示:

處理程序應該簡短,並快速返回。 如果您正在執行計算並調用其他函數,那么您可能做錯了。 信號不能替代事件驅動的框架。

調用非異步安全的函數很糟糕。 考慮如果在調用fprintf期間發生異常會發生什么,並且在處理程序內部再次調用fprintf 信號處理程序和程序數據都可能被破壞,因為它們在流本身上運行。

更多閱讀: “信號處理程序”中的“Do”和“Do not”

根據POSIX

如果在阻塞時生成任何SIGFPE,SIGILL,SIGSEGV或SIGBUS信號,則結果是未定義的,除非信號由kill()函數, sigqueue()函數或raise()函數生成。

因為SIGSEGV在SIGSEGV信號處理程序中被阻塞,所以在這種情況下結果是未定義的,並且任何行為都是有效的。 如果您不希望它被阻止,您可以使用帶有SA_NODEFER標志的sigaction()安裝信號處理程序,或使用sigprocmask()來取消阻塞信號處理程序中的信號。

在調試器中運行它並單步執行您希望崩潰的指令。

無法保證寫入無效地址必須創建分段錯誤。 也許Mac OS X會為您映射這些地址,而您正在覆蓋一些良性的東西。

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM