python / cpython

The Python programming language
https://www.python.org/
Other
60.83k stars 29.36k forks source link

Add advanced debugging examples to pdb documentation #119579

Open Delengowski opened 1 month ago

Delengowski commented 1 month ago

Documentation

With gh-90095 being closed out by #116660, I believe a section on Advanced Usage of the pdb module would be beneficial. While the current documentation for pdb does discuss the use of .pdbrc file, it does not provide many examples of what is capable, these capabilities are mostly inferred. In fact a googling of ".pdbrc python" provides a few SO posts 1 2 asking how to set commands in .pdbrc with no real explanation. Additionally I only find 2 real webpages 3 4 that discuss at length the use of .pdbrc and it is mostly for defining aliases.

This Advanced Usage section would demonstrate how to set breakpoints and issue commands to those breakpoints from within the .pdbrc file as an alternative to placing inline breakpoint() and print() calls for debugging purposes.

gaogaotiantian commented 1 month ago

So there's a difference between a documentation and a tutorial. We need to keep a balance so that the user is not swamped reading all the details and examples.

.pdbrc is very straightforward (after the fix):

executed as if it had been typed at the debugger prompt

That's it. Basically anything contradicts this would be considered a bug. It can't replace breakpoint() because that's how the debugger is brought up (unless you are talking about using python -m pdb + breakpoint() which is a bit weird, you should use break command instead).

.pdbrc file is not intended to be used as a file to input your pdb commands for a very specific program to debug. It is some "config" file to set up your pdb as you'd like for all debugging scenarios. Think of that as a .profile file, you won't add very specific commands like cd ~/program or code . into it - that's something that would change every time you use your terminal.

However, it's okay if you do not want to type the commands repeatedly and put them in the .pdbrc file, and the rule is pretty simple - whatever you want to type when the debugger is brought up for the first time, put them in the .pdbrc file.

Delengowski commented 1 month ago

That's it. Basically anything contradicts this would be considered a bug. It can't replace breakpoint() because that's how the debugger is brought up (unless you are talking about using python -m pdb + breakpoint() which is a bit weird, you should use break command instead).

I think this is where the misunderstanding is stemming from.

I'm suggesting something which show cases the ability to start a python program with python -m pdb with a .pdbrc that will place breakpoints with b <path to file>:<line number> (or optionally with a condition). Which then further shows how with your bug fix, can issue commands when that breakpoint is hit.

I'm suggesting this as an advanced technique, to the alternative of inserting breakpoint() into the example program (which I did for many years).

For example I have a script located at /tmp/example.py

from itertools import product

x_axis = range(6)
y_axis = range(6)

for x,y in product(x_axis, y_axis):
    ...

Let's say I want to print the multiplication of x and y when they're equal, for nothing but debugging purposes. For a long time I would change example.py like this

from itertools import product

x_axis = range(6)
y_axis = range(6)

for x,y in product(x_axis, y_axis):
    if x == y:
        print(x*y)

With your bug fix for issuing commands I can now do in /tmp/.pdbrc

b /tmp/example.py:7, (x == y)
commands 1
print(x*y)
continue

Without having to change the content of /tmp/example.py at all by simply doing python -m pdb example.py from within /tmp

I find this very powerful and not clear from the docs at all. I do not find it clear that you can even use .pdbrc to issue breakpoints like this at all.

Before your bugfix, I could still sort of do this. Using .pdbrc I could add a breakpoint to b /tmp/example.py:7, (x == y) but would have to type out the following manually in pdb repl.

commands 1
print(x*y)
continue

I do think this is an extremely useful and under documented feature of pdb. Which is not a reflection of your changes, but something I believe has been like this for a long time.

Perhaps not directly in pdb documentation and under a different section, a howto?

Delengowski commented 1 month ago

.pdbrc file is not intended to be used as a file to input your pdb commands for a very specific program to debug. It is some "config" file to set up your pdb as you'd like for all debugging scenarios. Think of that as a .profile file, you won't add very specific commands like cd ~/program or code . into it - that's something that would change every time you use your terminal.

I disagree with you here, merely by the fact that you can have a .pdbrc in both a specific directory and/or your home area. With both being executed. I've done this pdb for years and do it with gdb through .gdbinit also.

I much prefer issuing breakpoints (and now commands thanks to you) through .pdbrc rather than changing the source code. Its why I was so happy and thankful for your PR and backport to 3.11/3.12

gaogaotiantian commented 1 month ago

Like I said, it's definitely okay (and supported) to use .pdbrc as some start-up script to debug a specific program. I have no objection against that. I'm also very glad that the bug fix made your life easier when debugging :)

Maybe we can add some section to elaborate the possibility to use .pdbrc as debugging scripts so you don't have to type commands in the REPL every time. My concern is still the same - we need a balance here. Almost all the debugging commands can use some elaboration to show some "techniques" for debugging, but we only document them to the point of how they work, not how can you use them to do better debugging.

I probably need some input from other core devs about this idea.