41

例外を受け取った後にsegfaultsするPythonプログラムをデバッグしていKeyboardInterruptます。これは通常Ctrl+C、シェルから押すことによって行われます。SIGINT特定のコード変更でバグが修正されたかどうかをテストするために、起動後ランダムにプログラムに送信される小さなシェルスクリプトを用意しました。私が抱えている問題は、Ctrl+C送信が信号の送信とはプログラムに異なる影響を及ぼしSIGINT、バグが発生しないように見えることです。そのため、2つのアクションの違いは何でしょうか。

このプログラムはキーボードアクションをまったくキャッチせず、いくつかのスレッド/プロセスを含むPythonプログラムです。シグナルハンドラーをインストールせず(Pythonはインストールしますが)、をstty -a提供しintr = ^Cます。すべてのサブプロセス/スレッドに送信し、プライマリプロセスにのみ送信する可能性があると思いますが、それは私の疑いの範囲ですCtrl+CSIGINTkill -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
4

2 に答える 2

35

^CSIGINTフォアグラウンドプロセスグループ内のすべてのプロセスにを送信します。で同等のことを行うにはkill、シグナルをプロセスグループに送信する必要があります(OSレベルの概念)。

kill -SIGINT -<pid>

またはジョブに(シェルレベルの概念、パイプラインはで終了しました&):

kill -SIGINT %
于 2011-12-06T20:30:45.823 に答える
8

ここで説明されているように

Pythonは、デフォルトで少数のシグナルハンドラーをインストールします。SIGPIPEは無視され(したがって、パイプとソケットの書き込みエラーは通常のPython例外として報告されます)、SIGINTはKeyboardInterrupt例外に変換されます。これらはすべてオーバーライドできます。

したがって、SIGINTを送信する場合とCtrl+を送信する場合の動作は同じである必要がありcます。

ただし、KeyboardInterruptコードのどこかに、

try:
   ...
except:   # notice the lack of exception class
   pass

これにより、KeyboardInterrupt例外が「食べられ」ます。

于 2011-12-06T11:16:56.390 に答える