Is it possible to step backwards in pdb?
Asked Answered
F

4

74

After I hit n to evaluate a line, I want to go back and then hit s to step into that function if it failed. Is this possible?

The docs say:

j(ump) lineno Set the next line that will be executed. Only available in the bottom-most frame. This lets you jump back and execute code again, or jump forward to skip code that you don’t want to run.

Flipflop answered 22/9, 2014 at 11:26 Comment(6)
Nope. PDB cannot turn back time.Thanatopsis
@MartijnPieters see my edit, the docs say you can jump back to a line, so it's not possible to do this or jump back to the previous line somehow?Flipflop
Jumping back to a function that failed and restoring the state which caused failure are two different things.Cerumen
Note the caveat on that term. Code from the bottom most frame can be manipulated and run out of context, which is what jump does. No time reversal is taking place. If you jump to execute a function that raises an exception, the exception is not un-raised.Thanatopsis
There exists timetravelpdb (announced here and here, see also PyPi) but its only documentation is in a Youtube video (!) and I haven't yet bothered to install it.Natty
I'm analyzing a code using pydb and ddd, I tried usineg jump command and it works. In my case performing the function twice has no problem so in situations like this, this jump command helps!Jules
E
67

The GNU debugger, gdb: It is extremely slow, as it undoes single machine instruction at a time.

The Python debugger, pdb: The jump command takes you backwards in the code, but does not reverse the state of the program.

For Python, the extended python debugger prototype, epdb, was created for this reason. Here is the thesis and here is the program and the code.

I used epdb as a starting point to create a live reverse debugger as part of my MSc degree. The thesis is available online: Combining reverse debugging and live programming towards visual thinking in computer programming. In chapter 1 and 2 I also cover most of the historical approaches to reverse debugging.

Ennis answered 9/11, 2014 at 12:45 Comment(4)
The thesis looks really good! I haven't read it in detail, but as you are an expert: what do you think of the solutions mentioned at this question so far? Your epdb vs timetravelpdb vs revdb in PyPy?Natty
@Natty Not sure which thesis you are referring to, Patrick Sabin's earlier epdb thesis, or my later thesis, both linked to above. Haven't followed reverse debugging developments for over 2 years so not sure. After quick glance: timetravelpdb seems very similar to epdb, but has less features, e.g. epdb manages not just program state but external/environment state (to some degree), to ensure determinism. Revdb uses a record-replay approach, also doesn't seem to manage external state. Both record-replay and snapshotting (my preference) approaches have merits, as explained in my thesis.Ennis
Are there any doc or tutorial for epdb?Breadroot
@Breadroot I am also interested in tutorial for epdbPinite
D
12

PyPy has started to implement RevDB, which supports reverse debugging.

It is (as of Feb 2017) still at an alpha stage, only supports Python 2.7, only works on Linux or OS X, and requires you to build Python yourself from a special revision. It's also very slow and uses a lot of RAM. To quote the Bitbucket page:

Note that the log file typically grows at a rate of 1-2 MB per second. Assuming size is not a problem, the limiting factor are:

  • Replaying time. If your recorded execution took more than a few minutes, replaying will be painfully slow. It sometimes needs to go over the whole log several times in a single session. If the bug occurs randomly but rarely, you should run recording for a few minutes, then kill the process and try again, repeatedly until you get the crash.
  • RAM usage for replaying. The RAM requirements are 10 or 15 times larger for replaying than for recording. If that is too much, you can try with a lower value for MAX_SUBPROCESSES in _revdb/process.py, but it will always be several times larger.

Details are on the PyPy blog and installation and usage instructions are on the RevDB bitbucket page.

Dillydally answered 21/2, 2017 at 8:58 Comment(0)
M
11

Reverse debugging (returning to previously recorded application state or backwards single-stepping debugging) is generally an assembly or C level debugger feature. E.g. gdb can do it:

https://sourceware.org/gdb/wiki/ReverseDebug

Bidirectional (or reverse) debugging

Reverse debugging is utterly complex, and may have performance penalty of 50.000x. It also requires extensive support from the debugging tools. Python virtual machine does not provide the reverse debugging support.

If you are interactively evaluation Python code I suggest trying IPython Notebook which provide HTML-based interactive Python shells. You can easily write your code and mix and match the order. There is no pdb debugging support, though. There is ipdb which provides better history and search facilities for entered debugging commands, but it doesn't do direct backwards jumps either as far as I know.

Meraree answered 22/9, 2014 at 12:6 Comment(0)
B
3

Though you may not be able to reverse the code execution in time, the next best thing pdb has are the stack frame jumps.

Use w to see where you're in the stack frame (bottom is the newest), and u(p) or d(own) to traverse up the stackframe to access the frame where the function call stepped you into the current frame.

Batson answered 9/3, 2022 at 21:14 Comment(0)

© 2022 - 2024 — McMap. All rights reserved.