Pdb перейти к кадру в исключении в рамках исключения - PullRequest
0 голосов
/ 29 августа 2018

Я отлаживаю программу с именем a.py, используя pdb

def f(x) :
    x / x

def g(x) :
    try :
        f(x)
    except Exception as e :
        assert 0

g(0)

Когда я запускаю программу, используя python3 -m pdb a.py, программа останавливается на строке assert 0, и я получаю следующую информацию об ошибке:

Traceback (most recent call last):
  File "/tmp/a.py", line 6, in g
    f(x)
  File "/tmp/a.py", line 2, in f
    x / x
ZeroDivisionError: division by zero

During handling of the above exception, another exception occurred:

Traceback (most recent call last):
  File "/usr/lib64/python3.6/pdb.py", line 1667, in main
    pdb._runscript(mainpyfile)
  File "/usr/lib64/python3.6/pdb.py", line 1548, in _runscript
    self.run(statement)
  File "/usr/lib64/python3.6/bdb.py", line 434, in run
    exec(cmd, globals, locals)
  File "<string>", line 1, in <module>
  File "/tmp/a.py", line 11, in <module>
    g(0)
  File "/tmp/a.py", line 9, in g
    assert 0
AssertionError

и стек (показывается с помощью команды bt):

(Pdb) bt
  /usr/lib64/python3.6/pdb.py(1667)main()
-> pdb._runscript(mainpyfile)
  /usr/lib64/python3.6/pdb.py(1548)_runscript()
-> self.run(statement)
  /usr/lib64/python3.6/bdb.py(434)run()
-> exec(cmd, globals, locals)
  <string>(1)<module>()->None
  /tmp/a.py(11)<module>()->None
-> g(0)
> /tmp/a.py(9)g()
-> assert 0
(Pdb) 

Проблема в том, что я не могу перейти к функции f для отладки x / x, просто используя up и down, потому что мой стек заканчивается на функции g.

Как мне отладить такие исключения в пределах исключений? А как насчет исключений внутри исключений в исключениях ...?

Ответы [ 2 ]

0 голосов
/ 30 августа 2018

На самом деле повторно вызывает исключение (вариант 3 в wholevinski s answer ) решает мою проблему, так как она не требует, чтобы я изменил функцию f. Вот код:

'''Option 3'''
def f(x) :
    x -= 1
    x / x

def g(x) :
    try :
        for i in range(x, 0, -1) :
            print(f(i))
    except Exception as e :
        raise e

g(10)

Вывод Pdb из стека:

(Pdb) bt
  /usr/lib64/python3.6/pdb.py(1667)main()
-> pdb._runscript(mainpyfile)
  /usr/lib64/python3.6/pdb.py(1548)_runscript()
-> self.run(statement)
  /usr/lib64/python3.6/bdb.py(434)run()
-> exec(cmd, globals, locals)
  <string>(1)<module>()->None
  /tmp/a.py(13)<module>()->None
-> g(10)
  /tmp/a.py(11)g()
-> raise e
  /tmp/a.py(9)g()
-> print(f(i))
> /tmp/a.py(4)f()
-> x / x
(Pdb) 
0 голосов
/ 30 августа 2018

Как я понимаю, у вас есть несколько вариантов. Вы можете переместить ваш try-except в f(x), распечатать описательную ошибку в вашем g() try-except и перейти в pdb, или повторно вызвать ваше исключение после регистрации вашего дружеского сообщения об ошибке. Я не фанат полагаться на необработанные исключения для отладки (вариант 3), поэтому вот как выглядят варианты 1 и 2:

'''Option 1'''
def f(x) :
    try:
        x / x
    except Exception as e:
        print('An error occurred, entering pdb shell')
        import pdb; pdb.set_trace()

def g(x) :
    f(x)

g(0)

Выход:

$ python throw.py 
An error occurred, entering pdb shell
--Return--
> /home/wholevinski/so_test/throw.py(6)f()->None
-> import pdb; pdb.set_trace()
(Pdb) x
0

или

'''Option 2'''
def f(x):
    x / x

def g(x):
    try:
        f(x)
    except Exception as e:
        print('f({}) raised with error "{}". Entering pdb shell.'.format(x, str(e)))
        import pdb; pdb.set_trace()

g(0)

Выход:

$ python throw.py 
f(0) raised with error division by zero. Entering pdb shell.
--Return--
> /home/wholevinski/so_test/throw.py(9)g()->None
-> import pdb; pdb.set_trace()
(Pdb) x
...