2017-09-28 11 views
1

私は、Linux PCカーネルバージョン4.4.14で動作するマルチスレッドアプリケーションを開発しています。私はセグメンテーション違反を引き起こすいくつかの致命的なエラーを追跡したい。 SIGSEGVにリンクされたシグナルハンドラをセットアップして、クラッシュを引き起こしているスレッドのPID番号を取得しようとしました。ハンドラ関数のコードは以下の通りです:シグナルSIGSEGV sigactionを使用してキャッチ

void sighandler(int signum, siginfo_t *siginfo, void *context) 
{ 
    // get pid of sender, 
    pid_t sender_pid = siginfo->si_pid; 
    printf("Process %d got signal %d SEG FAULT !!!\n", (int)sender_pid, signum); 
    fflush(stdout); 
    sleep(1); 
    printf("Stdout Flushed %d got signal %d SEG FAULT !!!\n", sender_pid, signum); 
    trappola.sa_flags = 0; 
    trappola.sa_handler = SIG_DFL; 
    sigaction(signum, &trappola, NULL); 
    kill(getpid(), signum); 
    exit(-1); 
} 

と(メインで)私が使用してsighandler機能をリンク:

struct sigaction trappola; 
memset(&trappola, 0x00, sizeof(trappola)); 

trappola.sa_flags = SA_SIGINFO; 
trappola.sa_sigaction = sighandler; 
sigaction(SIGSEGV, &trappola, NULL); 

ハンドラが動作しているが、私はのPIDを取得することはできませんよ障害を引き起こすスレッド。 printf:

printf("Process %d got signal %d SEG FAULT !!!\n", (int)sender_pid, signum); 

必ずしも意味のないsender_pidと異なる番号を表示してください。 問題のスレッドのPIDを取得できないのはなぜですか?

どこが間違っていますか?問題のスレッドのPIDをハンドラ関数でどのように取得できますか?

ありがとうございました。

よろしくお願いいたします。 (アドレスsiginfo->si_addrで)SIGSEGVを引き起こすスレッドが信号を受信し、同じスレッドであるため

マルコBisio

答えて

0

siginfo->si_pidは意味がありません。

the signal(7) manpageを見る

信号が生成(したがってペンディング)することができるプロセスの全体 (例えば、キル(2)を使用して送信された場合)として、または特定のスレッド(例えば、 ため 特定の機械語命令を実行する 結果として生成され、このようなSIGSEGVやSIGFPEなどの特定の信号、スレッドは(...)を向けられているが

+0

は、あなたの答えをありがとうございました。う患者がスレッドを投げているsigsegvはハンドラ内の信号を受信するものと同じではないようです。つまり、main()はハンドラをインストールし、pthread_create ....を使ってスレッドを実行します。その後スレッドは独自のPID番号を持ちます。私はsiginfo-> si_pidを使ってハンドラからそのpid番号を読み取ることができると予想しました。 ありがとうございました Marco Bisio – mrcbis

+0

@mrcbisあなたは何があなたのものになっているか教えてください。これは同じスレッドではありません。デバッガ( 'gdb')を使うと、segfaultの原因を知ることができます。 – xhienne

関連する問題