シェル(具体的には、fish
)がバックグラウンドプロセスに信号を送信する問題をデバッグしようとしています。プロセスが受信しているシグナルを認識できるようにしたいのですが。
理想的には、次のようなプログラムを実行したいと思います。
$ log_signals > signals.txt &
次に、受信した信号を出力に書き込みます。しかし、そのようなプログラムがすぐに存在するとは思いません。
入力信号をトラップして検査する最も簡単な方法は何ですか。できれば自分のプログラムを作成する必要はありません。
(私はLinuxではなくOS Xを実行しているので、可能であれば、プラットフォームにとらわれない答えを選びたいと思います。)
Stéphane はこの情報を comment として投稿しましたが、この情報は既存の回答よりも有用であることがわかったため、コメントを回答として再投稿しています。
Linuxの場合のみ:デフォルトでstrace
はシグナルを出力するため、-e
フラグを使用してすべてのシステムコールを無音にし、シグナルをより明確にすることができます。
strace -e 'trace=!all' cmd
私の場合、実行しているデーモンを強制終了しているプロセスを特定しようとしたため、次のような出力が得られました。
[hendrenj@underling02 ~]$ strace -p 171869 -e 'trace=!all'
Process 171869 attached
--- SIGTERM {si_signo=SIGTERM, si_code=SI_USER, si_pid=151513, si_uid=1000} ---
+++ killed by SIGTERM +++
ここで、PID 171869に接続し、そのプロセスがPID 151513のプロセスによってSIGTERMに送信されたことを確認できます。
詳細については、 このブログ投稿 をチェックしてください。これは、auditd
(SELinuxを使用しているディストリビューションを使用している場合はSELinuxに付属していると思います)またはstap
(strace
の場合)などのツールを示唆しています。十分に強力ではありません。
これを行うには、gdb
を使用できます。
_gdb --batch -ex 'handle all print' -ex 'handle all nostop' -ex 'handle all pass' -ex 'run' cat
_はGDBの下でcatを実行し、すべての信号を出力し、プログラムに渡して実行を停止しません。
GDBは代わりにバックグラウンドに移行しようとするため、バックグラウンドプログラムに対してこれを行うのはより困難です。 _cat &
_で開始し、別のウィンドウでデバッガをアタッチするほうがよい場合があります:gdb -ex 'handle all print' -ex 'handle all nostop' -ex 'handle all pass' -ex 'c' (pgrep cat)[1]
。 _q[ENTER]
_を3回押してすべてのスパッを通過すると、cat
の実行を見ることができます。