gdb を使用してデバッグした場合とそうでない場合で、動作が異なる単純な C プログラムがあります。プログラムは次のとおりです。
#include <stdio.h>
#include <signal.h>
int main() {
kill(getpid(), SIGFPE);
printf("I'm happy.\n");
return 0;
}
単独で実行すると、次の非常に奇妙な結果が得られます。
ezyang@javelin:~$ ./mini 私は満足しています。 ezyang@javelin:~$ echo $? 0
エラーなし!これは、シグナルが発せられていないということではありません。
ezyang@javelin:~$ strace -e signal ./mini 殺す (31950、SIGFPE) = 0 --- SIGFPE (浮動小数点例外) @ 0 (0) --- 私は満足しています
GDB では、状況が異なります。
ezyang@javelin:~/Dev/ghc-build-sandbox/libraries/unix/tests/libposix$ gdb ./mini GNU gdb (GDB) 7.5.91.20130417-cvs-ubuntu Copyright (C) 2013 Free Software Foundation, Inc. ライセンス GPLv3+: GNU GPL バージョン 3 以降 これはフリー ソフトウェアです。自由に変更して再配布してください。 法律で許可されている範囲で、保証はありません。「コピーを表示」と入力します 詳細については、「保証を表示する」を参照してください。 この GDB は「x86_64-linux-gnu」として構成されました。 バグ報告の手順については、次を参照してください。 ... /srv/code/ghc-build-sandbox/libraries/unix/tests/libposix/mini からシンボルを読み取り中...(デバッグ シンボルが見つかりません)...完了。 (gdb) r プログラムの開始: /srv/code/ghc-build-sandbox/libraries/unix/tests/libposix/mini 警告: 0x7ffff7ffa000 に追加されたシンボル ファイル システム提供の DSO に読み込み可能なセクションが見つかりません プログラムは、シグナル SIGFPE、算術例外を受け取りました。 kill () の 0x00007ffff7a49317 at ../sysdeps/unix/syscall-template.S:81 81 ../sysdeps/unix/syscall-template.S: そのようなファイルまたはディレクトリはありません。 (gdb)c つづく。 プログラムはシグナル SIGFPE、算術例外で終了しました。 プログラムはもう存在しません。
GDBに停止しないように依頼しても違いはありません
(gdb) SIGFPE nostop を処理する シグナル ストップ プリント プログラムへのパス 説明 SIGFPE いいえ はい はい 算術例外 (gdb) r プログラムの開始: /srv/code/ghc-build-sandbox/libraries/unix/tests/libposix/mini 警告: 0x7ffff7ffa000 に追加されたシンボル ファイル システム提供の DSO に読み込み可能なセクションが見つかりません プログラムは、シグナル SIGFPE、算術例外を受け取りました。 プログラムはシグナル SIGFPE、算術例外で終了しました。 プログラムはもう存在しません。
どうしたの?!1 つには、SIGFPE がプログラムを強制終了しないのはなぜですか。次に、GDB の動作が異なるのはなぜですか?
アップデート。考えられることの 1 つは、子プロセスが親プロセスのシグナル マスクを継承していることです。 しかし、このトランスクリプトに見られるように、明らかにそうではありません。 この分析は正しくありませんでした。以下を参照してください。
ezyang@javelin:~$ トラップ - SIGFPE ezyang@javelin:~$ ./mini 私は満足しています。
更新 2.私の友人は、trap が親プロセスではなく、シェル自体によって設定されたシグナルのみを報告することを指摘しています。そこで、すべての親の無視マスクを追跡したところ、見よ、rxvt-unicode には SIGFPE がマスクされていました。友人は、rxvt-unicode を使用して実行可能ファイルを実行すると、再現できることを確認しました。