Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How to continue to the next loop iteration in Python PDB?

Given this sample code:

import pdb

for i in range(10):
  pdb.set_trace()
  print(str(i))

When I get the prompt from PDB, how can I skip an iteration of the loop, with the continue loop control statement, when it's also used by PDB, to continue code execution?

like image 293
Andor Avatar asked Feb 09 '15 16:02

Andor


People also ask

How do you go to the next line in pdb?

The difference between n (next) and s (step) is where pdb stops. Use n (next) to continue execution until the next line and stay within the current function, i.e. not stop in a foreign function if one is called. Think of next as “staying local” or “step over”.

What is the difference between the step and the next commands in pdb?

Continue execution until the next line in the current function is reached or it returns. (The difference between next and step is that step stops inside a called function, while next executes called functions at (nearly) full speed, only stopping at the next line in the current function.)

How do you step into a function in pdb?

To break into the pdb debugger, you need to call import pdb; pdb. set_trace() inside your function. In the above code, one function calls another.

How do I break out of pdb?

Whenever you want to leave the pdb console, type the command quit or exit . If you would like to explicitly restart a program at any place within the program, you can do so with the command run .


2 Answers

You cannot use continue because new statements in the debugger need to be complete and valid without any other context; continue must be given inside a loop construct when being compiled. As such using !continue (with the ! to prevent pdb from interpreting the command) cannot be used even if the debugger is processing a loop construct.

You can use the j[ump] command, provided you have a later statement to jump to. If your loop is empty after the statements you wanted to jump over, you can only 'rewind':

$ bin/python test.py
> /.../test.py(5)<module>()
-> print(str(i))
(Pdb) l
  1     import pdb
  2     
  3     for i in range(10):
  4         pdb.set_trace()
  5  ->     print(str(i))
  6     
[EOF]
(Pdb) j 3
> /.../test.py(3)<module>()
-> for i in range(10):

j 3 jumped to line 3, not skipping anything; line 3 will be re-executed including setting up the range(). You could jump to line 4, but then the for loop doesn't advance.

You'd need to add another statement at the end of the loop to jump to for Python to continue from. That statement can be a print() or a pass or anything else that doesn't have to alter your state. You could even use continue as the last statement. I used i:

for i in range(10):
    pdb.set_trace()
    print(str(i))
    i  # only here to jump to.

Demo:

$ bin/python test.py
> /.../test.py(5)<module>()
-> print(str(i))
(Pdb) l
  1     import pdb
  2     
  3     for i in range(10):
  4         pdb.set_trace()
  5  ->     print(str(i))
  6         i  # only here to jump to.
  7     
[EOF]
(Pdb) j 6
> /.../test.py(6)<module>()
-> i  # only here to jump to.
(Pdb) c
> /.../test.py(4)<module>()
-> pdb.set_trace()
(Pdb) s
> /.../test.py(5)<module>()
-> print(str(i))
(Pdb) j 6
> /.../test.py(6)<module>()
-> i  # only here to jump to.
(Pdb) i
1
(Pdb) c
> /.../test.py(4)<module>()
-> pdb.set_trace()
(Pdb) s
> /.../test.py(5)<module>()
-> print(str(i))
(Pdb) j 6
> /.../test.py(6)<module>()
-> i  # only here to jump to.
(Pdb) i
2

From Debugger Commands:

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.

like image 136
Martijn Pieters Avatar answered Oct 14 '22 06:10

Martijn Pieters


Sounds like a strange thing to want to do. You should be able to use the jump command though. You'll probably need to add a pass statement at the end of your for loop so you can jump to the end of the loop. If you're not sure of the line numbers of your code then you can use ll to find out the line numbers of your loop.

> c:\run.py(5)<module>()
-> print(i)
(Pdb) ll
  1     import pdb
  2     
  3     for i in range(10):
  4         pdb.set_trace()
  5  ->     print(i)
  6         pass
(Pdb) j 6
> c:\run.py(6)<module>()
-> pass
(Pdb) c
> c:\python\run.py(4)<module>()
-> pdb.set_trace()
(Pdb) c
1
> c:\python\run.py(5)<module>()
-> print(i)

It's worth noting that jumping to the for line will restart the loop.

like image 43
Dunes Avatar answered Oct 14 '22 06:10

Dunes