2012-04-20 6 views
0

私はctrl-cシグナルのシグナルハンドラを使用しています。アプリケーションを終了する代わりにctrl-cシグナルが生成されるたびに、何らかのアクションを実行します。ctrl-cのシグナルハンドラを使用する - 無限ループの助けが必要

while(1)ループ(任意のエラー条件)によってアプリケーションがハングアップした場合、その場合にのみアプリケーションを終了することができますか?

例:

void handle() 
{ 
    /*do some action*/ 
    ---- 
    ---- 
    --- 

    if (while(1) detected) 
    { 
    exit(0); 
    } 
} 


main() 
{ 
    struct sigaction myhandle; 
    myhandle.sa_handler = handle; 
    sigemptyset(&myhandle.sa_mask); 
    myhandle.sa_flags = 0; 
    sigaction(SIGINT, &myhandle, NULL); 

    while(1); 
} 

おかげ

+0

1)シグナルハンドラの宣言/定義/シグネチャが間違っている、 'void handle(int signum);' 2 ''参照2 'siglongjmp' – wildplasser

答えて

0

その非常に難しいあなたはCtrl-Cのような信号を受信する前に、あなたのコードが偶然の無限ループにあったかどうかを見つけるために。ヒューリスティックなアプローチをいくつか提案することができます。十分に長いサイズの変数、好ましくはグローバルunsigned long long intを持ち、この変数をループ内で増分し続け、ループの繰り返しごとに無限ループに入る可能性があると考えてください。シグナルを受け取ったら、シグナルハンドラ内のこの変数の値がしきい値MAX_NUMBER_OF_ITERATIONSであることを確認します。変数がユーザー定義のしきい値を超えている場合は、無限ループを宣言し、exitを続行するだけです。これらlines-

#define MAX_NUMBER_OF_ITERATIONS 100000000 

unsigned long long checkForEndlessLoop=0; 
bool overflow; 

void sigHandler (int signum) 
{ 
    signal(sig, SIG_IGN); // Ignore it so that another Ctrl-C doesn't appear any soon 
    if (overflow || (checkForEndlessLoop > MAX_NUMBER_OF_ITERATIONS)) 
    { 
     //Something's fishy in the loop. 
     exit(0); 
    } 
    else 
    { 
     signal(SIGINT, sigHandler); 
    } 
} 

int main() 
{ 
    signal(SIGINT, sigHandler); 

    for (checkForEndlessLoop=0; SOME_SLOPPY_CONDITION;) 
    { 
     //Some processing here 
     if (++checkForEndlessLoop == 0) 
      overflow=true; 
    } 

    checkForEndlessLoop=0; 

    while (SOME_SLOPPY_CONDITION) 
    { 
     //Some processing here 
     if (++checkForEndlessLoop == 0) 
      overflow=true; 
    } 

} 

、あるいは単純に

何かが、同じようにすぐに故障した状態が検出されたとして、障害のあるループの外にSIG_IGNbreakを使用してSIGINT無視され、エラーメッセージをプリントアウトし、出口!

+0

2)siglongjmp 3)コンパイラがその値をキャッシュするのを避けるために、「volatile」を使用します。 – wildplasser

関連する問題