问题
I'm trying to debug a Python program using pdb. The program could be like this:
def main():
a = 1
print(b)
c = 2
d = 3
Apparently, print(b) is a typo which should be print(a) but it is not important and I can fix it with the text editor but I want to bypass this error and continue debugging.
I tried jump, like jump 4(assuming "c=2" is line 4) but I was given error "Jump failed: f_lineno can only be set by a line trace function", which means I need to give a line trace function when I'm programming.
So, is there a way to deal with this problem, or is there some other way to bypass the error line when using pdb?
回答1:
I'm not sure, but this may be a bug that was fixed in Mar 2018, so you may need to (patch, upgrade, reinstall?) your Python.
回答2:
TLDR: this is pdb's post-mortem mode in which jumping is not supposed to work. But it's still very useful.
I reproduce it with python 3.8.2 as *** Jump failed: can only jump from a 'line' trace event
by running the script "under pdb" like so: python3 -m pdb -c c script.py
and trying to jump to another line in pdb prompt which then appears.
What's happened: an unhandled exception, in this case NameError: name 'b' is not defined
caused python to stop interpreting the script; pdb intercepted this situation and entered its post-mortem mode.
As Almar Klein nicely put it in his blog post,
Post-mortem debugging refers to the concept of entering debug mode after something has broken. There is no setting of breakpoints involved, so it's very quick and you can inspect the full stack trace, making it an effective way of tracing errors.
Although jump
, next
, return
won't work in post-mortem, bt
, up
, down
, ll
and pp
, along with the possibility to import modules and run arbitrary python code directly in the pdb's interactive shell can be very effective ways to get the root cause. In our simple example the root cause of the NameError
is shown immediately upon a quick ll
: pdb prefixes the offending line of code with >>
.
Had we not passed -c c
(meaning continue
), pdb would have shown its prompt and paused before the first line of your program is interpreted, so you'd have a chance to step through the whole program or set a breakpoint before or at the offending line, and jump over it, never entering the post-mortem.
Even in post-mortem, you can prepare a breakpoint anywhere in the program, e.g. break 2
for line 2, and say c
or continue
so pdb will finish post-mortem, reload the file, and restart the program with the updated set of breakpoints.
Another way to deal with it is to manually write import pdb; pdb.set_trace()
in suspicious places in your code - or since python 3.7, simply breakpoint()
, and run the python program normally (not "under" pdb anymore) which allows then to jump
, next
, return
etc, as well as everything else - when or if the breakpoint is reached.
If your Python program is started through behave
:
- make sure to run it with
--no-capture
whenever using pdb or similar debuggers (whether post-mortem mode or not), to avoid problems with behave's stdin/stdout capturing making pdb unresponsive and/or its prompt invisible. - also, if you want to use the pdb post-mortem mode:
in environment.py
:
def after_step(context, step): # pylint: disable=unused-argument
if step.status == 'failed':
import pdb
pdb.post_mortem(step.exc_traceback)
来源:https://stackoverflow.com/questions/53347730/pdb-bypass-error-jump-failed-can-only-jump-from-a-line-trace-event