Attaching to a running gevent monkey patched process [PyCharm 2018.1]


I'm on PyCharm 2018.1 and I am trying to debug a local process that utilizes monkey patching by Gevent. I have enabled Gevent support in the IDE, however I still cannot attach. Whenever I try to attach to the process, I get the following stack, at which point pydevd in PyCharm exits with code 0.

Traceback (most recent call last):
File "/path/lib/python3.6/site-packages/pycharm-debug-py3k.egg/_pydevd_bundle/", line 539, in start_client
s.connect((host, port))
File "/path/lib/python3.6/site-packages/gevent/", line 290, in connect
r = getaddrinfo(address[0], address[1],
File "/path/lib/python3.6/site-packages/gevent/", line 288, in getaddrinfo
return get_hub().resolver.getaddrinfo(host, port, family, type, proto, flags)
File "/path/lib/python3.6/site-packages/gevent/", line 65, in getaddrinfo
return self.pool.apply(_socket.getaddrinfo, args, kwargs)
File "/path/lib/python3.6/site-packages/gevent/", line 325, in apply
return self.spawn(func, *args, **kwds).get()
File "/path/lib/python3.6/site-packages/gevent/", line 382, in get
self._wait_core(timeout, ())
File "/path/lib/python3.6/site-packages/gevent/", line 106, in _wait_core
result = self.hub.switch()
File "/path/lib/python3.6/site-packages/gevent/", line 629, in switch
File "/path/lib/python3.6/site-packages/gevent/", line 633, in switch_out
raise BlockingSwitchOutError('Impossible to call blocking function in the event loop callback')
gevent.hub.BlockingSwitchOutError: Impossible to call blocking function in the event loop callback

I saw this bug thread, but it pertains to remote debugging. In my case I have a local process to attach to.

Surprisingly, adding these 3 lines right before monkey.patch_all() does allow me to attach the debugger, although the process a little weird: when a breakpoint is hit, all gevent loops pause.

import os
os.environ["GEVENT_SUPPORT"] = "True"
import pydevd

I do have "Suspend=Thread" instead of All set. I am not sure why all threads pause - that does not seem like expected behavior.


Is there a more reasonable way to work around all of this without requiring very specific imports, or pausing all threads? I would have thought Gevent Support being set in the IDE would work fine.

Comment actions Permalink

Hi! PyCharm's debugger can't work with gevent process which has already been pached, that's why adding 

os.environ["GEVENT_SUPPORT"] = "True"

is necessary before monkey patching. 
Could you please share a code sample, where your error appears?

Comment actions Permalink

Hi Elizabeth!

That makes sense then as I am attaching to an already running process that I invoked from a console. Unfortunately I am not sure how much effort it would be to craft a code sample as the code I am working with is not trivial. The short of it is it's a simple Python HTTP API being served by the reference WSGI implementation for local testing with some gevent-based asynchronous loops. However, since I am running outside of PyCharm, by the time I am trying to attach the process has already been monkey-patched.

So do I need that "import pydevd" statement there as well? What is the most concise way to allow post-monkey-patching attachment?

Comment actions Permalink

Follow-up: it appears I may have answered my own question. I went digging for usages of that environ variable and ended up here:

def protect_libraries_from_patching():
In this function we delete some modules from `sys.modules` dictionary and import them again inside
`_pydev_saved_modules` in order to save their original copies there. After that we can use these
saved modules within the debugger to protect them from patching by external libraries (e.g. gevent).
# Truncated


That's a pretty nifty trick. Looks like this gets called when pydevd is imported, which makes the import necessary. 


Please sign in to leave a comment.