私はKeyboardInterrupt
例外を受け取った後にsegfaultするPythonプログラムをデバッグしています。これは通常、 Ctrl+C シェルから。特定のコード変更でバグが修正されたかどうかをテストするために、起動後にランダムにSIGINT
をプログラムに送信する小さなシェルスクリプトを用意しました。私が抱えている問題は、 Ctrl+C シグナルSIGINT
を送信する場合とはプログラムの効果が異なるようで、バグが発生することはないため、2つのアクションの違いは何なのかと思います。
プログラムはキーボードアクションをまったくキャッチせず、pythonいくつかのスレッド/プロセスを含むプログラムです。シグナルハンドラーをインストールしません(Python =します)、そしてstty -a
はintr = ^C
を与えます。 Ctrl+CSIGINT
はすべてのサブプロセス/スレッドに送信されますが、kill -INT
はプライマリプロセスにのみ送信されますが、これは私の疑いです。
以下は、kill -INT
を送信するシェルスクリプトです。
wait
while :; do
seconds="$(python -c 'import random; print random.random()*4')"
./mandos --debug --configdir=confdir \
--statedir=statedir --no-restore --no-dbus &
pid=$!
{ sleep $seconds; kill -INT $pid; } &
fg %./mandos
status=$?
if [ $status -gt 1 ]; then
echo "Failed exit $status after $seconds seconds"
break
fi
wait
done
^C
は、フォアグラウンドプロセスグループのすべてのプロセスにSIGINT
を送信します。 kill
で同等のことを行うには、プロセスグループに信号を送信する必要があります(OSレベルの概念)。
kill -SIGINT -<pid>
または仕事(シェルレベルの概念、パイプラインは&
):
kill -SIGINT %
として ここで説明 :
Pythonはデフォルトで少数のシグナルハンドラーをインストールします:SIGPIPEは無視されます(パイプとソケットの書き込みエラーは通常のPython例外として報告されます)。SIGINTはKeyboardInterrupt例外に変換されます。すべてのこれらは上書きできます。
そのため、SIGINTの送信と Ctrl + c。
ただし、KeyboardInterrupt
に注意する必要があります。コードのどこかに
try:
...
except: # notice the lack of exception class
pass
これは、KeyboardInterrupt例外を「食べます」。