personal web log written by izabeera and dryobates

python pdb debugging

Navigating in Pdb

by dryobates

I often see programmers, even experienced, that tediously press "n" and "s" few hundreds of times, one after another, only to skip some for loop or get into state where loop is executed n-th time in pdb. Here is a little tip how to do it smarter.

Conditions

What I often see is debugging some loop with code like below:

System Message: WARNING/2 (<string>, line 6)

Cannot analyze code. Pygments package not found.

.. code-block:: python

   for i in range(100):
        import pdb; pdb.set_trace()
        print i
        ...

I wrote earlier how to cope with above problem and get debugger started only once. But often we want to stop execution when some condition is met. It would be a lot of typing if you would like to stop execution when "i == 98". Better solution is to put a breakpoint with condition:

System Message: WARNING/2 (<string>, line 19)

Cannot analyze code. Pygments package not found.

.. code-block:: python

   import pdb; pdb.set_trace()
   for i in range(100):
        print i
        ...


System Message: WARNING/2 (<string>, line 27)

Cannot analyze code. Pygments package not found.

.. code-block:: python

    -> for i in range(100):
    (Pdb) l
      1         import pdb; pdb.set_trace()
      2  ->     for i in range(100):
      3             print i
      ...
    (Pdb) b 3, i == 98
    Breakpoint 1 at some_file.py:3
    (Pdb) c
    0
    1
    ...
    96
    97
    > some_file.py(3)<module>()
    -> print i
    (Pdb) p i
    98
    (Pdb)


With above code execution will be stopped only when "i == 98".

Sometimes execution path is quite complex and putting set_trace just before loop isn't good choice. If you know filename and line number you can forget about set_trace and editing any file. Just run program with pdb and place breakpoint in file and line you want it:

System Message: WARNING/2 (<string>, line 57)

Cannot analyze code. Pygments package not found.

.. code-block:: python

   python -m pdb some_file.py
   (Pdb) b some_file.py:2, i == 98
   Breakpoint 1 at some_file.py:2
   (Pdb) c


Aliases

Sometimes condition isn't easy to express with simple math. There are times when you have to print some more complex variable and decide yourself if you should skip another loop or not. In such cases you often put simple breakpoint inside a loop and type:

System Message: WARNING/2 (<string>, line 73)

Cannot analyze code. Pygments package not found.

.. code-block:: python

   (Pdb) p i
   0
   (Pdb) c
   > some_file.py(2)<module>()
   -> print i
   (Pdb) p i
   1
   (Pdb) c
   > some_file.py(2)<module>()
   -> print i
   (Pdb) p i
   2
   (Pdb) c
   > some_file.py(2)<module>()
   -> print i
   ...

And so one. Print, continue, print, continue... If you end up with such repetitive task it's time for aliases:

System Message: WARNING/2 (<string>, line 95)

Cannot analyze code. Pygments package not found.

.. code-block:: python

   (Pdb) alias cp c ;; p i
   (Pdb) cp
   > some_file.py(2)<module>()
   -> print i
   0
   (Pdb) cp
   > some_file.py(2)<module>()
   -> print i
   1
   (Pdb) cp
   > some_file.py(2)<module>()
   -> print i
   2
   ...

Alias definition has simple, yet powerful syntax. You can pass parameters to aliases or define them ahead in ".pdbrc" file. All of that you can find in documentation [1] What you won't find in documentation is ";;" trick. Placing double semicolon while defining alias allows to stream multiple commands as seen above.

More elastic alias that could be placed in ".pdbrc" could be:

System Message: WARNING/2 (<string>, line 120)

Cannot analyze code. Pygments package not found.

.. code-block:: python

   (Pdb) alias cp c ;; p %1
   (Pdb) cp i
   > some_file.py(2)<module>()
   -> print i
   0
   ...

[1]pdb's Documentation https://docs.python.org/2/library/pdb.html
dryobates
dryobates
Jakub Stolarski. Software engineer. I work professionally as programmer since 2005. Speeding up software development with Test Driven Development, task automation and optimization for performance are things that focus my mind from my early career up to now. If you ask me for my religion: Python, Vim and FreeBSD are my trinity ;) Email: jakub@stolarscy.com

Archive