Python 2如何调试exec块注入的代码



该项目是pywebsocket,以单机模式运行。

处理程序从文件中读取,并通过exec <code-block-in-string> in global_dic运行。然后通过global_dic[<function-name>]挂接处理程序代码。当请求URL时,将通过资源处理程序映射调用处理程序函数。

如何对exec块中处理程序中的代码进行单步执行?具体来说,你是如何在PyCharm中做到这一点的?还是在其他工具中?

或者更一般地说,如何调试exec块中的代码?

对于特定的代码,处理程序由函数_source_handler_file()读入并来源于mod_pywebsocket/dispatch.py,如(实际打开和读取是在调用此函数之前,但只是将其放在下面解释逻辑):

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

然后_HandlerSuite的实例由主循环保存在映射中,并由主循环用于调用基于URL资源的处理程序。

gbin回答后更新:

基于gbin的示例,代码应该是这样的:

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

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)?

在执行execfile()时,代码将在PyCharm中停止。

但是,当它调用注入的处理程序myhandler()时,我希望它在注入的代码块内的print(88)上停止。这个问题还没有解决。

为了解决后半部分的问题,可能的解决方案是将代码拉入Python系统的导入模块记录中。也许可以使用__import__。但这会污染名称空间。有更好的方法吗?或者有没有一种方法可以导入但仍然保持名称空间的隔离?

再次更新:

今天,我用execfile("...", blob)启动了相同的代码,它很简单。它在注入的处理程序函数上停止。不知道为什么前几天不起作用。

如果可以更改/override/monkeypatchdispatch.py,则可以在python 3:下使用execfile()或exec(compile(…))

如果您有其他.py文件:

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

py2:下

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

仅供参考py3:

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

现在,如果你在other.py中设置了一个断点,pycharm就会停止!

最新更新