简体   繁体   中英

Python 2 How to debug code injected by the exec block

The project is pywebsocket , running in standalong mode.

Handlers are read in from files and run through exec <code-block-in-string> in global_dic . The handler code then is hooked through global_dic[<function-name>] . When a URL is requested, a handler function will be called through a resource-handler map.

How can the code in handlers in the exec block be stepped over? Specifically how do you do it in PyCharm? Or in other tools?

Or more generally how do you debug code in a exec block?

For the specific code, the handlers are read in and sourced in mod_pywebsocket/dispatch.py by function _source_handler_file() , like (actually open and read are before calling this function but just put it here below to explain the logic):

global_dic = {}
handler_definition = open(handler_definition_filepath).read()
exec handler_definition in global_dic
handler = global_dic[handler_name]
return _HandlerSuite(handler)

Then the instance of _HandlerSuite is kept by the main loop in a map, and is used by the main loop to call a handler based on the URL resource.

Update after gbin's answer:

The code should look like, based on gbin's example:

print(3)
toto = 5
def my_handler_func():
    print(88)

Under py2:

execfile('other.py', blob)       # this works perfectly
print("blob %s" % blob['toto'])  # 
myhandler = blob['my_handler_func']
myhandler()                      # how to make this stop on print(88)?

The code would stop in PyCharm on executing execfile() .

But when it calls the injected handler myhandler() , I'd like it to stop on print(88) inside the injected code block. This is not solved yet.

To solve the 2nd half of the questions, probably a solution is to pull the code into the imported-module record of the Python system. Maybe by using __import__ . But that would pollute the name space. Is there a better way? Or is there a way to import but still keep the name spaces isolated?

Update again:

Today I fired the same code with execfile("...", blob) it simply worked. It stopped on the injected handler function. Not sure why it did not work the other day.

If you can change/override/monkeypatch dispatch.py, you can use execfile() or exec(compile(...)) under python 3:

If you have a other.py file:

print(1)
print(2)
print(3)
toto = 5

Under py2:

execfile('other.py', blob)
print("blob %s" % blob['toto'])

Just FYI under py3:

code_block = compile(open('other.py').read(), 'other.py', 'exec')
blob = {}
exec(code_block, blob)
print("blob %s" % blob['toto'])

Now if you put a breakpoint in other.py, pycharm will stop on it !

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM