Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Set debugger breakpoint at end of a function without return

I am debugging method f() that has no return in it.

class A(object):      def __init__(self):         self.X = []      def f(self):                     for i in range(10):             self.X.append(i) 

I need to see how this method modifies variable X right after it is called. To do that, I insert a return at the end of the method, and set the breakpoint there:

enter image description here

That way, as soon as the method reaches its return, I can see the value of my variable X.


This does the job, but I am pretty sure there is a better way. Editing a method or function every time I need to debug it seems silly.

Question:
Is there a different way (e.g. an option in the debugger) to set a breakpoint at the end of a method that does not have a return?

(Note that setting a breakpoint at the function call and using Step Over would not display X when mouseovering, since the function is called from a different module.)

like image 946
user Avatar asked Apr 29 '15 08:04

user


People also ask

How do you Debug a break point?

To set a breakpoint in source code, click in the far left margin next to a line of code. You can also select the line and press F9, select Debug > Toggle Breakpoint, or right-click and select Breakpoint > Insert breakpoint. The breakpoint appears as a red dot in the left margin.

Does a breakpoint stop before or after the line?

(See section Stack frames, for a description of stack frames.) Set a breakpoint at line linenum in the current source file. The current source file is the last file whose source text was printed. The breakpoint will stop your program just before it executes any of the code on that line.

What is conditional breakpoint in debugger?

Conditional breakpoints allow you to break inside a code block when a defined expression evaluates to true. Conditional breakpoints highlight as orange instead of blue. Add a conditional breakpoint by right clicking a line number, selecting Add Conditional Breakpoint , and entering an expression.


2 Answers

You can add a conditional breakpoint on the last line and set the condition to be something that occurs only in the last iteration.

In this instance the condition is very easy since it's just i == 9, but it may be a lot more complex depending on your loop condition so sometimes adding a statement at the end will be the easier solution.

Conditional breakpoint in IntelliJ IDEA

That screenshot is from IntelliJ IDEA and your screenshot looks like it's from the same IDE, so just right-click the breakpoint to show the dialog and enter your condition.

If you're using some other IDE I'm sure there is capability to make a breakpoint conditional.

Update:

There is no support for breaking at the end of a method in the Python debugger, only at the start of a method:

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

With a lineno argument, set a break there in the current file. With a function argument, set a break at the first executable statement within that function. The line number may be prefixed with a filename and a colon, to specify a breakpoint in another file (probably one that hasn't been loaded yet). The file is searched on sys.path. Note that each breakpoint is assigned a number to which all the other breakpoint commands refer.

If a second argument is present, it is an expression which must evaluate to true before the breakpoint is honored.

Without argument, list all breaks, including for each breakpoint, the number of times that breakpoint has been hit, the current ignore count, and the associated condition if any.

like image 151
Raniz Avatar answered Oct 25 '22 03:10

Raniz


Your IDE is hiding what's under the hood. That is, something like

import pdb 

is prepended to your script and

pdb.set_trace() 

is inserted before the line onto which your placed your breakpoint. From what you say I deduce that PyCharm does not like placing breakpoints on empty lines. However pdb.set_trace() can perfectly be placed at the end of a method.

So you could insert those yourself (or write a macro) and run python -m pdb to start debugging.

(Edit) example

import pdb  class A(object):      def __init__(self):         self.X = []      def f(self):         for i in range(10):             self.X.append(i)         pdb.set_trace()  if __name__ == '__main__':     a = A()     a.f() 

Debug with

$ python -m pdb test.py  > /dev/test.py(1)<module>() ----> 1 import pdb       2        3 class A(object):  ipdb> cont --Return-- > /dev/test.py(11)f()->None -> pdb.set_trace() (Pdb) self.X [0, 1, 2, 3, 4, 5, 6, 7, 8, 9] (Pdb) 

ipdb can be used instead of pdb.

like image 25
Hugues Fontenelle Avatar answered Oct 25 '22 05:10

Hugues Fontenelle