gevent 提供了一个后门server,可以用来debug正在运行的进程,官方文档是这样描述的
The BackdoorServer provides a REPL inside a running process. As long as the process is monkey-patched, the BackdoorServer can coexist with other elements of the process.
 
下面这个例子是从stackoverflow 上看到的,这里自己实践一下
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 import json from gevent import pywsgi from gevent import monkey from gevent import event from gevent.backdoor import BackdoorServer import time monkey.patch_all() a = "foo" def build_response(response):     return json.dumps(response) def start_process(environ, start_response):     '''     {"content": {"code": 0, "req_id": "20160420154445000"}, "res": "ok", "err_code": 0}     '''     risk_id = 0     response = dict()     response = {         'err_code': 0,         'res': 'ok',         'content': dict()     }     status = '200 OK'     response_headers = [('Content-type', 'text/html'), ('Connection', 'close')]     start_response(status, response_headers)     return build_response(response) def main():     stop_event = event.Event()     servers = [BackdoorServer(('127.0.0.1', 5001),                               banner="Hello from gevent backdoor!",                               locals={'foo': "From defined scope!"}), pywsgi.WSGIServer(('127.0.0.1', 5002),                                                                                         start_process, ), ]     for server in servers:         if not server.started:             server.start()     stop_event.wait()     for server in servers:         if server.started:             server.stop() if __name__ == '__main__':     main() 
 
将这个python文件run起来,然后执行telnet 127.0.0.1 5001就可以链接到上面的进程中去
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 #   telnet 127.0.0.1 5001> >> import greenlet, inspect#  获取当前协程> >> greenlet.getcurrent()     <_Greenlet_stdreplace at 0x10bd40448: _handle_and_close_when_done(<bound method BackdoorServer.handle of <BackdoorSe, <bound method StreamServer.do_close of <BackdoorSe, (<gevent._socket3.socket object, fd=8, family=2, t)> #  获取当前协程的父协程,看到是hub,这其实是gevent的调度协程> >> greenlet.getcurrent().parent  <Hub '' at 0x10bcdd6d8 select default pending=0 ref=2 resolver=<gevent.resolver_thread.Resolver at 0x10bd167f0 pool=<ThreadPool at 0x10bd169b0 0/1/10 hub=<Hub at 0x10bcdd6d8 thread_ident=0x140736039191424>>> threadpool=<ThreadPool at 0x10bd169b0 0/1/10 hub=<Hub at 0x10bcdd6d8 thread_ident=0x140736039191424>> thread_ident=0x7fffa99f8380> #  再网上走一层,这里就到了我们运行main的协程> >> inspect.getouterframes(greenlet.getcurrent().parent.parent.gr_frame)[FrameInfo(frame=<frame object at 0x7faecf476e48>, filename='xxxxxxxxxx', lineno=100, function='main', code_context=['    stop_event.wait()\n'], index=0), FrameInfo(frame=<frame object at 0x7faecf41ea78>, filename='xxxxxxxxxxx', lineno=107, function='<module>', code_context=['    main()\n'], index=0)] > >> inspect.getouterframes(greenlet.getcurrent().parent.parent.gr_frame)[1][0]<frame object at 0x7faecf41ea78> #  通过inspect可以获取变量a的值,这样就可以debug当前的进程了> >> inspect.getargvalues(inspect.getouterframes(greenlet.getcurrent().parent.parent.gr_frame)[1][0]).locals['a']'foo'