2012-01-19 15 views
5

私はSIGABRTシグナルのハンドラを設定した後、abort()をコールしますが、ハンドラはトリガされず、プログラムは中止されます。なぜですか?SIGABRTシグナルの処理方法は?

#include <iostream> 
#include <csignal> 
using namespace std; 
void Triger(int x) 
{ 
    cout << "Function triger" << endl; 
} 

int main() 
{ 
    signal(SIGABRT, Triger); 
    abort(); 
    cin.ignore(); 
    return 0; 
} 

プログラムの出力は:あなたがハンドラに注意を払うだろうSIGABRTabort()のハンドラを置き換えることができますが

enter image description here

+0

作品を期待どおりには、メッセージが表示されますここには、「」が含まれています。どのプラットフォーム? –

+0

MSVC++ 2010のWindows 7 x64(ビジュアルスタジオにcstdlibを含める必要はありません) – codekiddy

+1

シグナルハンドラが 'longjmp'をしない限り、プログラムを中止する必要があります。その前にメッセージを出力したい場合は、 'std :: cout'をフラッシュする(または' std :: cerr'に書き込む)ことができます。 –

答えて

11

他の人は言ったように、あなたはabort()を戻せず、実行を正常に続けることができません。しかし、あなたができることは、try catchと同様の構造で中止を呼び出すかもしれないコードを保護することです。コードの実行は中断されますが、残りのプログラムは続行できます。ここではデモです:

#include <csetjmp> 
#include <csignal> 
#include <cstdlib> 
#include <iostream> 

jmp_buf env; 

void on_sigabrt (int signum) 
{ 
    longjmp (env, 1); 
} 

void try_and_catch_abort (void (*func)(void)) 
{ 
    if (setjmp (env) == 0) { 
    signal(SIGABRT, &on_sigabrt); 
    (*func)(); 
    } 
    else { 
    std::cout << "aborted\n"; 
    } 
}  

void do_stuff_aborted() 
{ 
    std::cout << "step 1\n"; 
    abort(); 
    std::cout << "step 2\n"; 
} 

void do_stuff() 
{ 
    std::cout << "step 1\n"; 
    std::cout << "step 2\n"; 
}  

int main() 
{ 
    try_and_catch_abort (&do_stuff_aborted); 
    try_and_catch_abort (&do_stuff); 
} 
+0

この回答は未完成のようです。注意: ? – stanm

6

、アボートは、シグナルハンドラが戻らない場合にのみ禁止されます。 C99の関連引用符は7.20.4.1段落2にあります。

シグナルのSIGABRTが捕捉され、シグナルハンドラが戻らない限り、アボート機能が異常終了します。 ...

シグナルハンドラが戻り、プログラムがアボートします。

+0

上記のtry_and_catch_abortは、リリースされたコードではなく、デバッグモードでのみ動作すると言っていますか? – Michele

2

あなたはそれらの症状を取得するあなたはデバッグビルドを持っている場合、それはデバッグブレークを設定するので、(窓およびVisual Studio-で、私は2012年のバージョンでテストしています)、ポップアップデバッグダイアログをIE 、abort()のデバッグ実装で)。 あなたはそのメッセージ「機能triger」

を得る「無視する」選ぶ場合は、リリースビルドを行う場合は、デバッグポップアップダイアログを得ることはありませんし、完全に

関連する問題