New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
A way to un-breakpoint a set_trace() line #90
Conversation
I agree. |
👍 Good idea. |
Thoughts on a GUI for this? I was thinking that whenever a set_trace() is called, it could be added to the breakpoint section (with some kind of indicator that it's not a real breakpoint), and then one could "delete" it from there. It would also highlight the line in the code, probably using a different but similar color to the breakpoint color (falling bak to the breakpoint color if it's not in the theme). Would it be too confusing to use the same key 'b' to handle this? It doesn't make sense to have a breakpoint on a set_trace line, so there shouldn't be ambiguity. |
I'm OK even treating it as a "regular" breakpoint with no visual distinction. Since it's impractical to scan the entire source for |
I agree: when the set_trace is first hit, make it appear just as any other breakpoint. Then the 'b' command can toggle it off. That sounds great. |
Yes, source code analysis is far outside the scope of PuDB. |
Another technical question: should anything be saved to the breakpoints file if a |
Agree with your initial reaction. |
For now, set_trace() is ignored after the first time it is called. What remains to do is to implement this in the GUI so that set_trace can be skipped or not dynamically by the user.
OK, using some dark magic, I've converted this issue into a pull request. For now, all I've implemented is the part that lets you skip set_trace, to show that it works. Right now, it just skips after the first time it is called. What remains to be implemented is linking this in with the GUI. Comments on if I'm going about this the right way are appreciated. |
I should add: Perhaps use code objects and line numbers as hash keys. Also, forgot to say thank you for taking a stab at this. |
All that remains to do is to show this in the UI.
Unfortunately, I'm not sure how to make it highlight initially, because I'm not sure how to communicate that information from the debugger to the UI.
This only works if it is the first time set_trace() has been called in the file. Further set_trace() calls are not highlighted.
Yeah, I figured out a lot more after I pushed that, but I wrote it on an airplane, and just now got to push it. See the commit messages. There is just one thing that doesn't work. |
So there are two issues
import pudb
def main():
for i in range(10):
pudb.set_trace()
print('test')
for i in range(5):
pudb.set_trace()
print('test2')
main() If you run this code, it will stop at the first So it is being marked as a breakpoint. The issue is that screen is not being redrawn. I couldn't figure out how to communicate this information to the GUI from
|
(I've split out the issue about improving the breakpoints view.) |
OK, so I'll do that separately. I feel like even adding But the first issue is still a blocker. How can I make the UI refresh when set_trace() is called? |
I tried the new That doesn't exactly solve my problem, though, but I wanted to see if it would work. |
|
This required redrawing the source lines in set_trace(). I'm not sure if this is the best way to do this, but it seems to work.
OK, I got bored on the plane today and decided to finish this up. Take a look if my method of resetting the UI is correct (my most recent commit). As far as I know, this is ready to be reviewed and merged. Basic behavior (in case you forgot): when |
If I Ctrl-C in the middle of execution with your patch applied, there's a spurious (and confusing) breakpoint shown in the source. (Easy to reproduce with |
That was easy enough to fix, but there seems to be another issue that comes up when there is a normal breakpoint in the same file. I'm still working on that. |
The breakpoints list is used internally by bdb, and adding "fake" set_trace breakpoints to it leads to an inconsistent state inside of bdb where two lists of breakpoints are not equal to one another, causing it to crash. Since set_trace "breakpoints" are not real breakpoints, there is no need for bdb to know about them.
OK, I fixed that bug, again on an airplane (this time with some pretty hard-core non-PuDB debugging). Lesson learned: be careful with |
In b979fc5, something is still amiss. Here's a reproducer:
|
Forgot to say: Thanks for your work on this! |
Doesn't reproduce for me. Does it actually break at the spurious breakpoint? |
By the way, I noticed that the fake breakpoints are a little off because normal breakpoints stop on the line itself, but set_trace stops on the line after. But I think the fix here is to actually go in and make the set_trace breakpoints color differently. |
Oh I think I might be seeing what you are seeing now. It only seems to happen in Python 2. Except for me the spurious breakpoint is on line 34 (right below the |
Actually, I think the thing I described is the source of the problem. It thinks the line number is the line after the set_trace (which could be any line depending on the flow of the code). Any thoughts on how to fix this? |
And why is it Python 2 only? Did Python 3 change the behavior of |
Searching around, I found some vaguely similar things in the Python issue tracker, like http://bugs.python.org/issue17697#msg186637. But I haven't dug deep enough to know if they are the same, or how to fix this issue. Again, if you have any thoughts, I'd love to hear them. |
Hmm, now I can only seem to reproduce it in Python 3. |
This fixes an issue, noted in inducer#90, where f_lineno would be reported incorrectly, causing lines to be spuriously reported as breakpoints. See also https://bugs.python.org/issue17697#msg186637 for a description of the problem.
OK, I have applied the patch from https://bugs.python.org/issue16482, which was mentioned in https://bugs.python.org/issue17697 to fix the problem, and it seems to work (and based on my understanding of the problem, it seems like it should work). It looks like this is a workaround for a bug in the interpreter itself, where line numbers can be reported incorrectly on frames with traces set on them when the global trace is removed. The workaround, as I understand it, is to remove the traces when continuing so that the line numbers get reported correctly. As such this probably deserves some testing. Everything seems to work in my limited testing. I can definitely reproduce your issue and this latest commit fixes it. Also see https://bitbucket.org/xdegaye/pdb-clone/commits/123d1b6db6649f4b54712db321865fda55395488, which looks like it goes even further than my patch to toward working around this issue (see also the current code). I'm unclear why this fix would be necessary for anything other than At any rate, please test this. To my knowledge, it should be ready to go (again). |
In my limited testing, this seems to do the trick. This whole 'disable set_trace' thing is pretty slick, I like it. Ready to go in as far as I am concerned. |
OK, let's do it. |
A way to un-breakpoint a set_trace() line
Cool, thanks! |
This sounds kind of odd, let me explain. I usually enter the debugger with an explicit call to set_trace(). Often, once I've hit that line a few times, I no longer need to stop there, but I don't want to restart the process.
Just as I can manually turn a regular line into a breakpoint with the 'b' command, I would love a way to turn a set_trace() line back into a regular, non-breaking line. The set_trace function would still be called of course, but could examine the calling line to see if it had been marked as non-breaking, and continue.