11

予期しない例外を発生させる関数があるとします。その関数を ipdb でラップします。

def boom(x, y):
    try:
        x / y
    except Exception as e:
        import ipdb; ipdb.set_trace()

def main():
    x = 2
    y = 0
    boom(x, y)

if __name__ == '__main__':
    main()

スタックを上に移動して、x と y の値を確認できます。

$ python crash.py 
> /tmp/crash.py(6)boom()
      5     except Exception as e:
----> 6         import ipdb; ipdb.set_trace()
      7 

ipdb> u
> /tmp/crash.py(11)main()
     10     y = 0
---> 11     boom(x, y)
     12 

ipdb> p y
0

ただし、デバッグするときは、デバッガーを最上位に置きたいだけです。

def boom(x, y):
    x / y

def main():
    x = 2
    y = 0
    boom(x, y)

if __name__ == '__main__':
    try:
        main()
    except Exception as e:
        import ipdb; ipdb.set_trace()

トレースバックを表示できますが、呼び出された関数内の変数を表示できません:

$ python crash.py 
> /tmp/crash.py(14)<module>()
     12         main()
     13     except Exception as e:
---> 14         import ipdb; ipdb.set_trace()

ipdb> !import traceback; traceback.print_exc(e)
Traceback (most recent call last):
  File "crash.py", line 12, in <module>
    main()
  File "crash.py", line 8, in main
    boom(x, y)
  File "crash.py", line 3, in boom
    x / y
ZeroDivisionError: integer division or modulo by zero
ipdb> d # I want to see what value x and y had!
*** Newest frame

例外オブジェクトには、例外が発生したときのスタックへの参照がまだ残っていることは明らかです。スタックが巻き戻されたにもかかわらず、ここxにアクセスできますか?y

4

3 に答える 3

1

コンテキストマネージャーを使用することもできます

with ipdb.launch_ipdb_on_exception():
    main()

を使用した使いやすいラッパーipdb.post_mortemです。

于 2019-08-02T15:52:01.443 に答える