25

Sounds like I'm missing something extremely simple, I'm trying to set a breakpoint in my python code using:

if(some condition):
        pdb.set_trace()

My error in the code comes after a large number of iterations..difficult to debug using print etc. I am able to print stuff when the condition hits but I would like to set brk-pt.

--EDIT--

Actual code:

import pdb
if (node_num == 16):
    print node_num
    pdb.set_trace()
sanjay
  • 647
  • 1
  • 6
  • 14
  • Yes what you do should work, if you have some sort of counter that you can access in that scope you can simply `if count > limit:` and then execution will flow into the block, hit the `set_trace` and execution will pause there. – metatoaster Aug 12 '14 at 22:56
  • I just tried something really easy: if(condition): print "" pdb.set_trace() ########## print shows up but not the breakpoint!! – sanjay Aug 12 '14 at 22:58
  • Have you imported pdb? Try `import pdb;pdb.set_trace()`. – metatoaster Aug 12 '14 at 23:00
  • Yes, I'm able to use pdb.set_trace() outside of an if condition...yes, pdb imported – sanjay Aug 12 '14 at 23:02
  • Can you update your question with the complete code with the start of the loop, both the print statement and calling of `pdb.set_trace()`? – metatoaster Aug 12 '14 at 23:05
  • Does that help? the code is too big to post here – sanjay Aug 12 '14 at 23:12

3 Answers3

54

I see you found your solution Sanjay. But for those who arrived here looking for a means to set a conditional breakpoint with pdb read on:

Instead of hard coding conditions such as if node_num == 16:, run pdb in interactive mode. Sample code:

import pdb

for node_num in range(50):
  do_something(node_num)
...

In the shell start the script in debug mode using -m pdb:

[rick@rolled ~]$ python -m pdb abc.py
> /home/dcadm/abc.py(1)<module>()
-> import pdb
(Pdb) l
  1  -> import pdb
  2
  3     for node_num in range(50) :
  4       foo = 2**node_num
[EOF]
(Pdb) b 4, node_num > 4
Breakpoint 1 at /home/dcadm/abc.py:4
(Pdb) c
> /home/dcadm/abc.py(4)<module>()
-> foo = 2**node_num
(Pdb) node_num 
5
(Pdb)

The pdb shell command b 4, node_num > 4 breaks at line 4 when node_num is greater than 4.

Nathaniel Jones
  • 939
  • 1
  • 14
  • 25
mcchiz
  • 742
  • 6
  • 11
15

To actually use conditional breakpoints in pdb, you can do the following:

b(reak) [([filename:]lineno | function) [, condition]]

https://docs.python.org/3/library/pdb.html#pdbcommand-break

Eg I'm running some test code that iterates over django views. I want to break only when the particular view I'm interested in is reached:

b C:\Users\powlo\project\tests\TestCase.py:350, view.view_name == 'app.views.export'

powlo
  • 2,538
  • 3
  • 28
  • 38
2

I am not sure as to why your code isn't working, but what you can do is on your local machine, create a new file for your minimum example to see if you can do what you want to do

import pdb

for node_num in range(50):
    if node_num == 16:
        print(node_num)
        pdb.set_trace()

Now running it:

16
> /tmp/tmp.py(3)<module>()
-> for node_num in range(50):
(Pdb) p node_num
16

As you can see this worked as intended with this trivial example, it's up to you to figure out how to adapt this to your code, and/or figure out what else did you do to your code/environment that prevented that prompt from showing up.

Alternatively, if you have a function that is dying in an exception and you want to know the exact line that caused it, you should use post_mortem instead. Wrap the problematic section of code with this

try:
    problem_function()
except Exception:  # or the specific exception type thrown
    pdb.post_mortem()
    raise

What post_mortem would do is dump a break point right at the point where the exception happened (specifically in that stack frame), and so this allows all values to be inspected and then let you continue execution. However I also put a raise at the end to allow the exception to continue as normal, and this is intended as execution doesn't normally from where it die but just pause at that exception handling block due to the post_mortem call. Might as well just give up after inspecting what went wrong.

metatoaster
  • 17,419
  • 5
  • 55
  • 66
  • @metatoaster..thanks a lot for your responses, I tried a lot of different ways to debug this issue but in the end it looks like I was exceeding the maximum recursion depth This is solved by adding: sys.setrecursionlimit(10000) That was the reason I was not able to set a breakpoint..I initially thought it had something to do with my compiler but when I re-verified the compiler etc I found out that this was the problem It just never occurred to me that I should google the max recursion thing – sanjay Aug 13 '14 at 18:30
  • Sorry about the delay, because of the suspected compiler fault, I moved my code to a different server where I had privileges – sanjay Aug 13 '14 at 18:33
  • I have started using python only since the last week (generally use perl, c++, c etc)...this is surely the strangest error I have seen... – sanjay Aug 13 '14 at 18:45
  • @sanjay Oh, yeah, if you told me about the actual exception I would have told you to do something else. Just edited the answer here to reflect this. – metatoaster Aug 13 '14 at 21:33
  • 1
    Oh yeah, also this is not strange as it seems. Python does not have tail recursion by default hence this limit is to guard against stack overflows - http://stackoverflow.com/questions/3323001/maximum-recursion-depth – metatoaster Aug 13 '14 at 21:41