Is there a way to examine the last exception when in pdb/before entering pdb? (Using python 2.7.5).
Immediately (yes, I enter no other commands at all) after an exception being raised in my code, I do sys.exc_info()
; this just results in (None, None, None)
. At this point, I can do pdb.pm()
, and pdb starts at the point that the exception is raised.
I'd like to be able to examine this exception object (it is not stored in a variable before being raised).
There is nothing obviously helpful in http://docs.python.org/2/library/pdb.html or http://docs.python.org/2/library/sys.html
Edit: I know about set_trace
. I'd like to examine the exception before I modify the code.
Is this what you are looking for?
import pdb
try:
1/0
except Exception as err:
pdb.set_trace()
% test.py
--Return--
> /home/unutbu/pybin/test.py(8)<module>()->None
-> pdb.set_trace()
(Pdb) err
ZeroDivisionError('integer division or modulo by zero',)
(Pdb) quit
If you do not want to modify the code where the exception originates, you could instead redefine sys.excepthook
:
import pdb
import sys
def excepthook(type, value, traceback):
pdb.set_trace()
sys.excepthook = excepthook
1/0
% test.py
--Return--
> /home/unutbu/pybin/test.py(7)excepthook()->None
-> pdb.set_trace()
(Pdb) type
<type 'exceptions.ZeroDivisionError'>
(Pdb) value
ZeroDivisionError('integer division or modulo by zero',)
(Pdb) traceback
<traceback object at 0xb774f52c>
(Pdb)
You can retrieve the latest exception in pdb/ipdb via:
__exception__
The above is actually a tuple of the (exception, message).
You can use sys.last_value
:
>>> no_such_var
Traceback (most recent call last):
File "<stdin>", line 1, in <module>
NameError: name 'no_such_var' is not defined
>>> import sys
>>> sys.last_value
NameError("name 'no_such_var' is not defined",)
>>> sys.last_value.args
("name 'no_such_var' is not defined",)
>>> no_such_var
Traceback (most recent call last):
File "<stdin>", line 1, in <module>
NameError: name 'no_such_var' is not defined
>>> import pdb, sys
>>> pdb.set_trace()
--Return--
> <stdin>(1)<module>()->None
(Pdb) sys.last_value
NameError("name 'no_such_var' is not defined",)
NOTE: This solution is not perfect. The value is set when an exception is not handled and the interpreter prints an error message and a stack traceback. For example, if the exception is caught using try .. except ..
, sys.last_value
is not set.
You can run the script through pdb
via python -m pdb -c continue script.py
. It will enter post-mortem debugging on an uncaught exception and drop you in the pdb interface. Here you can examine sys.exc_info()
in order to get the exception. For example:
$ echo "1 / 0" > script.py
$ python -m pdb -c continue script.py
Traceback (most recent call last):
[...]
File "/tmp/script.py", line 1, in <module>
1 / 0
ZeroDivisionError: division by zero
Uncaught exception. Entering post mortem debugging
Running 'cont' or 'step' will restart the program
> /tmp/script.py(1)<module>()
-> 1 / 0
(Pdb) !import sys
(Pdb) p sys.exc_info()
(<class 'ZeroDivisionError'>, ZeroDivisionError('division by zero'), <traceback object at 0x7f3adcf09148>)
(Pdb) interact
*interactive*
>>> import sys
>>> sys.exc_info()
(<class 'ZeroDivisionError'>, ZeroDivisionError('division by zero'), <traceback object at 0x7f3adcf09148>)
I bumped into this post, but none of the answers did what I needed, which was to repeat all of the error information (including the traceback) that was spewed before the pdb.pm()
step in the question. Here's what worked for me in the end:
Add the following lines to your .pdbrc file:
import sys
import traceback
alias rethrow traceback.print_exception(sys.last_type, sys.last_value, sys.last_traceback)
Now, next time you're in a pdb environment, you can just type rethrow
, and it will repeat all the error information from before you had typed pdb.pm()
.
The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.