1. ホーム
  2. パイソン

[解決済み】実行中のPythonアプリケーションのスタックトレースを表示させる。

2022-03-25 05:42:30

質問

Pythonのアプリケーションが時々動かなくなるのですが、原因がわかりません。

Pythonインタプリタにシグナルを送り、実行中のコードを正確に表示させる方法はありますか?

スタックトレースのようなものでしょうか?

関連する質問

解決方法は?

このような状況、つまり、あるプロセスが長い間実行されているが、時々不明で再現性のない理由でスタックするような場合に使用するモジュールがあるんだ。 これは少し厄介で、unix上でしか動作しません(シグナルが必要です)。

import code, traceback, signal

def debug(sig, frame):
    """Interrupt running process, and provide a python prompt for
    interactive debugging."""
    d={'_frame':frame}         # Allow access to frame object.
    d.update(frame.f_globals)  # Unless shadowed by global
    d.update(frame.f_locals)

    i = code.InteractiveConsole(d)
    message  = "Signal received : entering python shell.\nTraceback:\n"
    message += ''.join(traceback.format_stack(frame))
    i.interact(message)

def listen():
    signal.signal(signal.SIGUSR1, debug)  # Register handler

使い方は、プログラムの起動時に listen() 関数を呼び出して (site.py に記述して、すべての python プログラムに使わせることもできます)、実行させるだけです。 どの時点でも、killやpythonを使用して、プロセスにSIGUSR1シグナルを送信します。

    os.kill(pid, signal.SIGUSR1)

これにより、プログラムは現在いる地点で Python コンソールにブレークし、スタックトレースを表示し、変数を操作することができます。 実行を続けるには control-d (EOF) を使ってください (ただし、シグナルを送った時点でおそらくすべての I/O などに割り込むことになるので、完全に非侵入型ではないことに注意してください)。

同じことをする別のスクリプトがありますが、こちらはパイプを通して実行中のプロセスと通信します(バックグラウンドのプロセスなどをデバッグできるようにするためです)。 ここに載せるにはちょっと大きいですが、このスクリプトを パイソン料理本レシピ .