pudb icon indicating copy to clipboard operation
pudb copied to clipboard

Jump command

Open asmeurer opened this issue 9 years ago • 11 comments

When researching the bug for https://github.com/inducer/pudb/pull/90, I read in the docs:

f_lineno is the current line number of the frame — writing to this from within a trace function jumps to the given line (only for the bottom-most frame). A debugger can implement a Jump command (aka Set Next Statement) by writing to f_lineno.

I'm probably the last person to learn about this, but it seems like a useful thing to implement. j is already taken as down, but J is free. It's probably easy to implement, at least assuming the error reporting is good for bad jumps.

asmeurer avatar Jan 07 '15 19:01 asmeurer

I wouldn't turn this down if there were a patch, although IMO it's not exactly mind-blowing in terms of debugging usefulness. Or maybe I'm just not imaginative enough.

inducer avatar Jan 07 '15 23:01 inducer

Yeah, uh, I also am not really sure if it would be useful for debugging. Being able to inject arbitrary code into the frame would be useful, but this is not quite that.

I suppose if you wanted to skip a block of code for some reason, maybe. If I ever find myself wanting this, I'll make a note of it.

asmeurer avatar Jan 08 '15 01:01 asmeurer

Can you also jump back to a specific line in a file you're debugging, like:

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.

It should be noted that not all jumps are allowed – for instance it is not possible to jump into the middle of a for loop or out of a finally clause.

flowersw avatar Sep 06 '17 20:09 flowersw

Hi, this would be very useful if the loop is compute-intensive to run, and one only wants to test it for a few before jumping out to test the subsequent code.

w-hc avatar Jul 27 '18 22:07 w-hc

This is straightforward to implement, but I can't figure out how to make the jump command stop on the line it is jumping too, like t. It works in pdb so I know it should be possible.

Here is what I have

diff --git a/pudb/debugger.py b/pudb/debugger.py
index 28a06b5..5f9328e 100644
--- a/pudb/debugger.py
+++ b/pudb/debugger.py
@@ -206,6 +206,9 @@ class Debugger(bdb.Bdb):
                     break
                 frame = frame.f_back
 
+    def set_jump(self, frame, line):
+        frame.f_lineno = line
+
     def set_trace(self, frame=None, as_breakpoint=None, paused=True):
         """Start debugging from `frame`.
 
@@ -1161,6 +1164,48 @@ class DebuggerUI(FrameVarInfoKeeper):
                     self.debugger.set_continue()
                     end()
 
+
+        def jump_to_cursor(w, size, key):
+            if self.debugger.post_mortem:
+                self.message("Post-mortem mode: Can't modify state.")
+            else:
+                sline, pos = self.source.get_focus()
+                lineno = pos+1
+
+                bp_source_identifier = \
+                        self.source_code_provider.get_breakpoint_source_identifier()
+
+                if bp_source_identifier is None:
+                    self.message(
+                        "Cannot jump here--"
+                        "source code does not correspond to a file location. "
+                        "(perhaps this is generated code)")
+
+                from pudb.lowlevel import get_breakpoint_invalid_reason
+                invalid_reason = get_breakpoint_invalid_reason(
+                        bp_source_identifier, lineno)
+
+                if invalid_reason is not None:
+                    self.message(
+                        "Cannot jump to the line you indicated, "
+                        "for the following reason:\n\n"
+                        + invalid_reason)
+                else:
+                    err = self.debugger.set_break(
+                         bp_source_identifier, pos+1, temporary=True)
+                    if err:
+                        self.message("Error dealing with jump:\n" + err)
+
+                    try:
+                        self.debugger.set_jump(
+                            self.debugger.curframe, pos+1)
+                    except ValueError as e:
+                        self.message("""\
+Error with jump. Note that jumping only works on the topmost stack frame.
+(The error was: %s)""" % (e.args[0],))
+
+                    end()
+
         def move_home(w, size, key):
             self.source.set_focus(0)
 
@@ -1188,6 +1233,7 @@ class DebuggerUI(FrameVarInfoKeeper):
                 lineno = min(max(0, int(lineno_edit.value())-1), len(self.source)-1)
                 self.source.set_focus(lineno)
 
+
         def move_down(w, size, key):
             w.keypress(size, "down")
 
@@ -1419,6 +1465,7 @@ class DebuggerUI(FrameVarInfoKeeper):
         self.source_sigwrap.listen("r", finish)
         self.source_sigwrap.listen("c", cont)
         self.source_sigwrap.listen("t", run_to_cursor)
+        self.source_sigwrap.listen("J", jump_to_cursor)
 
         self.source_sigwrap.listen("j", move_down)
         self.source_sigwrap.listen("k", move_up)

asmeurer avatar Jul 28 '18 00:07 asmeurer

Work in progress PR if someone wants to pick it up https://github.com/inducer/pudb/pull/306

asmeurer avatar Jul 28 '18 00:07 asmeurer

This is very useful for cases like when the process requires some complex and compute-expensive initialization before staritng the code I actually want to debug. Then, if I skipped over certain function call but then decided that I wanted to step into it instead, I have to re-start the whole process instead of just using Jump command.

MarSoft avatar Mar 17 '19 20:03 MarSoft

I find this useful when a function returns an unexpected value. I can conditionally break on the line after the function call when the value is returned, then back the current statement up and re-call the function to see what happened. Very excited to see work on this has started.

j8spencer avatar Apr 18 '19 01:04 j8spencer

My teammate just had a need for this feature now.

cool-RR avatar Aug 15 '19 12:08 cool-RR

This is a feature I would use a lot in the ways suggested above.

FGrose avatar Dec 21 '22 21:12 FGrose

Managed to fix the issue in my PR https://github.com/inducer/pudb/pull/306. It's ready to be reviewed.

asmeurer avatar Dec 22 '22 22:12 asmeurer