10

私は Linux シグナルの初心者です。助けてください。次のコードは、Linux 2.6 gcc で実行するとコア ダンプを取得します。

$ ./a.out
浮動小数点例外 (コアダンプ)

質問:
1. プロセス シグナル マスクがインストールされているため、40 行目で生成された「SIGFPGE」はvolatile int z = x/y;ブロックされるべきではありませんか?
2. ブロックされていない場合、シグナル ハンドラがインストールされているため、コア ダンプの代わりに「SIGFPE」がシグナル ハンドラによってキャプチャされるべきではありませんか?
3. 行 40 をコメントアウトし、代わりにvolatile int z = x/y;行 42 を使用すると、すべてが期待どおりに機能します。raise(SIGFPE);ここで x/0 と raise SIGFPE の違いは何ですか?

コードは次のとおりです。

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

    void sig_handler(int signum)
    {
       printf("sig_handler() received signal %d\n", signum);
    }


    int main(int argc, char * argv[])
    {

       // setup signal mask, block all signals
       sigset_t set;
       sigfillset(&set);

       if(sigprocmask(SIG_BLOCK, &set, NULL)<0)
       {
          perror("failed to set sigmask");
          return -1;
       }

       // install signal handler for SIGFPE
       struct sigaction act;
       act.sa_handler = sig_handler;
       act.sa_mask = set;
       act.sa_flags = 0;
       if(sigaction( SIGFPE, &act, NULL)<0)
       {
          perror("sigaction failed");
          exit(-1);
       }

       volatile int x =1;
       volatile int y =0;
       volatile int z = x/y; //line 40

       //raise(SIGFPE); //line 42

       printf("point 1000\n");

       return 0;
    }
4

2 に答える 2

4

シグナルがブロックされている間にハードウェア トラップによって引き起こされた SIGFPE は、未定義の動作を引き起こします。

ブロックされている間に SIGFPE、SIGILL、SIGSEGV、または SIGBUS シグナルのいずれかが生成された場合、シグナルが kill() 関数、sigqueue() 関数、または raise() 関数によって生成された場合を除き、結果は未定義です。

(sigprocmask仕様より)

于 2011-07-08T18:46:55.457 に答える