A similar question
When developing some Windows desktop stuff in Delphi, I had a habit of inserting
asm(int 3);.
If a debugger is running, that acts like a breakpoint. If no debugger is running, it does nothing (NOOP).
I would like to do something similar for my Python scripts. Is there some Python function like HaltDebugger()? Cross platform, of course.
[Update] I am looking for something that will work with PyCharm
This is the most portable solution. A more difficult one is sketched below for PyCharm.
Kind of depends on the debugger, but if you use pdb (which would be cross platform), the docs state:
The typical usage to break into the debugger from a running program is
to insert
import pdb; pdb.set_trace()
you want this to be conditional, so you can paste at each breakpoint:
try: pdb.set_trace()
except NameError: pass
and when you want to debug just import pdb at the top. If it must be one line you cannot use duck typing. Instead:
if 'pdb' in globals(): pdb.set_trace()
PyCharm only
Assuming you insist on not marking debugging lines with the mouse this might work:
Using exception breakpoints:
PyCharm provides exception breakpoints for Python, Django, and
JavaScript.
Exception breakpoints are triggered when the specified exception is
thrown. Unlike the line breakpoints, which require specific source
references, exception breakpoints apply globally to the exception
condition, rather than to a particular code reference.
Depending on the type of processing an exception, the debugging can
break when a process terminates with an exception, or as soon as an
exception occurs.
You could:
Create a custom exception in your project, DebugException
Set the exception breakpoint as per the link above. Make sure it is set to trigger immediately, not when program exits.
Finally,
paste
try: raise DebugException()
Exception: pass
wherever you want to break. This seems like a lot of trouble to not double click with your mouse to mark a breakpoint.
Related
In my project that based on asyncio and asyncio tcp connections that debugs with PyCharm debugger I got very and very very absurd errors.
If I put breakpoint on code after running, the breakpoint never fires.
But breakpoints fires if breakpoint has been put before starting program.
But in some cases the firing on breakpoints causes strange errors (if paused on breakpoint and resumed).
The next exceptions I remarked:
TypeError: 'coroutine' object not callable
SystemError: unknown opcode
First exception is very rare. Can be raised in any place on code and unrepeatable.
Second exception I remarked the first time recently. This is repeatable in my code. The function where I put breakpoint is function in async task (asyncio.Task). I can't repeat from scratch. But I think the type of exception (unknown opcode??? O_O) should make you think.
Besides! The exception vanished if I change the code: for example I added the a = 0 line. Exception not raised after. The deleting a = 0 will return this exception again.
Is this error of kind of esoteric errors?
I think the PyCharm debugger conflicts with asnycio.
Or maybe I doing something wrong?
Unknown opcode can be any line of code in the function where breakpoint put. Repeats in specific places in code.
This exception also can be at line, but also inside another function. Very rare and unreproducible
which version of python you use? There is new debugger for python3.6 based on inserting opcodes before starting process. You can find some more info in this repo https://github.com/Elizaveta239/frame-eval
Is there a way to set a dynamic breakpoint***, suspend on exception, in pdb?
***dynamic in the sense of not tied to any line number
In pycharm (pydev), this is possible and is a nice feature, but often times, I have to use pdb due to limitations of the pycharm debugger (no jump functionality and/or the machine doesn't have pycharm).
You're looking for postmortem mode:
try:
code_that_may_raise_exception()
except Exception:
import pdb; pdb.post_mortem()
This will break on exception and drop you into a debugger right where it is being raised from
I am using Eclipse + PyDev, although I can break on exception using PyDev->Manage Exception Breakpoints, I am unable to continue the execution after the exception.
What I would like to be able to do is to set the next statement before the exception so I can run a few commands in the console window and continue execution. If I use Eclipse -> Run -> Set Next Statement before the exception, the editor will show the next statement being where I set it but then when resuming the execution, the program will be terminated.
Can this be done ?
Unfortunately no, this is a Python restriction on setting the next line to be executed: it can't set the next statement after an exception is thrown (it can't even go to a different block -- i.e.: if you're inside a try..except, you can't set the next statement to be out of that block).
You could in theory take a look at Python itself as it's open source and see how it handles that and make it more generic to handle your situation, but apart from that, what you want is not doable.
Is there a command in the Python debugger (pdb) that says something like "run until the next exception is raised?"
Seems an obvious requirement but can't seem to find it.
Update : To be clear, my problem is an exception which is being caught and turned into an inadequate message in a log file. And I can't find where the exception is raised.
I figured that if I could go into trace mode and say "run until an exception is thrown" that would be the most straightforward way of finding it. I don't think post-mortem will work here.
Execute your script as follows:
python -m pdb myscript.py
Press c and Enter.
When an uncaught exception is raised you program will stop running and fall back to the pdb debug prompt.
Can you search the code in the failing script for the text of the message that is logged (I realize that this may be difficult if the string is generated in a complex way). If you can find the point where the message is generated/logged then you can set an appropriate break point to troubleshoot the problem.
Unfortunately, AFAIK Python pdb debugging does not offer the capability that is present in some other languages to say, for example, break when Exception is raised.
as an alternative to using pdb, I would have a use for the Python continue statement in interactive mode, after control-C during a script invocation with python -i. that way, say at a raw_input('continue->') prompt in my script, I could break out, inspect/modify things, and go right back to the raw_input prompt (or whatever code caused an exception) with a continue command. the break command outside of a loop could also be repurposed for symmetry, but I'd have less use for that. before submitting a PEP for this, I'd like some feedback from the Python community.
it might be possible to do something similar just using a PYTHONSTARTUP script and the inspect module, but if so I haven't figured it out yet.
ctrl-C raised a KeyboardInterrupt exception in your script. Since you didn't catch that exception, the program terminated. Only then the interactive prompt appears.
You can't continue because your program is already over. The fact that you pressed Ctrl-C just raised an exception, the program didn't pause at that exact place. It continued execution, up to the last line, and finished.
There's no way to know where you want to continue to. For that you need a real debugger.