どの信号がプロセスに送信されるかを検出する最も簡単な方法は何ですか?

どの信号がプロセスに送信されるかを検出する最も簡単な方法は何ですか?

fish私のシェルで(特に)バックグラウンドプロセスにシグナルを送信する問題をデバッグしようとしています。プロセスがどの信号を受信して​​いるかを識別できるようにしたいです。

理想的には、次のことを行うプログラムが必要です。

$ log_signals > signals.txt &

その後、受信した信号が出力に書き込まれます。しかし、まだそのようなプログラムはないようです。

可能であれば、独自のプログラムを書かずに着信信号をキャプチャしてチェックする最も簡単な方法は何ですか?

(私はLinuxではなくOS Xを実行しているので、可能であればプラットフォームに依存しない答えを好みます。)

答え1

~からスティーブンこの情報を次のように投稿してください。コメントしかし、この情報は既存の回答よりも役に立つと思い、コメントを回答として再公開しています。

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(System Tap)などを使用することをお勧めします。strace

答え2

trapいくつかの依存関係を持つのではなく、コマンドを直接接続して信号を検出できることに気づきました。以下のスクリプトは、信号にいくつかの「トラップ」を設定し(関連信号が入ったときに関数を実行します)、信号を終了コードとして出力します。必要に応じて、出口をコンソール出力に変更できます。

#!/bin/sh

trap cleanup_1 1 # SIGHUP
trap cleanup_2 2 # SIGINT
trap cleanup_3 3 # SIGQUIT
trap cleanup_6 6 # SIGABRT
trap cleanup_15 15 # SIGTERM

cleanup_1()
{
  exit 1
}

cleanup_2()
{
  exit 2
}

cleanup_3()
{
  exit 3
}

cleanup_6()
{
  exit 6
}

cleanup_15()
{
  exit 15
}

echo "Started"
cat

答え3

gdbこれを行うには、次の方法を使用できます。

gdb --batch -ex 'handle all print' -ex 'handle all nostop' -ex 'handle all pass' -ex 'run' catGDBで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実行を見ることができます。

答え4

strace -o logfile -e signal=all cmdline

関連情報