Debugging asyncio code in PyCharm causes absolutely crazy unrepeatable errors - python

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

Related

Overlooking AttributeError exceptions in Python using VS Code debugger

I have a massive loop that I am trying to debug in VS Code and running my python app in.
I keep hitting this AttributeError and it pauses the debugger which I DON'T want it to do. I want to bypass it and let it finish (which it does without debugger running).
The error:
Exception has occurred: AttributeError (note: full exception trace is shown but execution is paused at: )
I really don't want to hit F5 a billion times as I am trying to get to near the end of my program to see whatcertain variables in my Panda's DataFrame are. Is this possible?

How to halt a Python script - only if it is being debugged

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.

How to retry before an exception with Eclipse/PyDev

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.

Python Debugging : Find where an exception is raised, go into debug mode?

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.

Can I put break points on background threads in Python?

I'm using the PyDev for Eclipse plugin, and I'm trying to set a break point in some code that gets run in a background thread. The break point never gets hit even though the code is executing. Here's a small example:
import thread
def go(count):
print 'count is %d.' % count # set break point here
print 'calling from main thread:'
go(13)
print 'calling from bg thread:'
thread.start_new_thread(go, (23,))
raw_input('press enter to quit.')
The break point in that example gets hit when it's called on the main thread, but not when it's called from a background thread. Is there anything I can do, or is that a limitation of the PyDev debugger?
Update
Thanks for the work arounds. I submitted a PyDev feature request, and it has been completed. It should be released with version 1.6.0. Thanks, PyDev team!
The problem is that there's no API in the thread module to know when a thread starts.
What you can do in your example is set the debugger trace function yourself (as Alex pointed) as in the code below (if you're not in the remote debugger, the pydevd.connected = True is currently required -- I'll change pydev so that this is not needed anymore). You may want to add a try..except ImportError for the pydevd import (which will fail if you're not running in the debugger)
def go(count):
import pydevd
pydevd.connected = True
pydevd.settrace(suspend=False)
print 'count is %d.' % count # set break point here
Now, on a second thought, I think that pydev can replace the start_new_thread method in the thread module providing its own function which will setup the debugger and later call the original function (just did that and it seems to be working, so, if you use the nightly that will be available in some hours, which will become the future 1.6.0, it should be working without doing anything special).
The underlying issue is with sys.settrace, the low-level Python function used to perform all tracing and debugging -- as the docs say,
The function is thread-specific; for a
debugger to support multiple threads,
it must be registered using settrace()
for each thread being debugged.
I believe that when you set a breakpoint in PyDev, the resulting settrace call is always happening on the main thread (I have not looked at PyDev recently so they may have added some way to work around that, but I don't recall any from the time when I did look).
A workaround you might implement yourself is, in your main thread after the breakpoint has been set, to use sys.gettrace to get PyDev's trace function, save it in a global variable, and make sure in all threads of interest to call sys.settrace with that global variable as the argument -- a tad cumbersome (more so for threads that already exist at the time the breakpoint is set!), but I can't think of any simpler alternative.
On this question, I found a way to start the command-line debugger:
import pdb; pdb.set_trace()
It's not as easy to use as the Eclipse debugger, but it's better than nothing.
For me this worked according to one of Fabio's posts, after setting the trace with setTrace("000.000.000.000") # where 0's are the IP of your computer running Eclipse/PyDev
threading.settrace(pydevd.GetGlobalDebugger().trace_dispatch)

Categories

Resources