使用sys.settrace()调试Python脚本时避开外层exec()包装追踪
自定义Python调试器:过滤exec()外层上下文,只追踪输入文件代码
问题背景
我正在用sys.settrace()构建自定义Python调试器,用来检查和记录执行事件。脚本接收一个.py输入文件作为参数,核心执行代码如下:
code_str = wrap_input(INPUT_PATH) x = compile(code_str, INPUT_PATH, 'exec') sys.settrace(tracer) exec(x) sys.settrace(None)
现在的问题是,追踪器会同时捕获两类事件:
- 输入文件的实际业务代码
- 外层
exec()的包装上下文
简化的日志示例如下:
A call encountered in <module>() at line number 0 Line 1 → {'code_str': ..., 'x': <code object <module> at ...>} Line 5 → {'code_str': ..., 'x': <code object <module> at ...>, 'foo': <function foo at ...>} // File starts here A call encountered in foo() at line number 1 Line 2 → {} Line 3 → {'x': 5} A return encountered in foo() at line number 3 // File ends here A return encountered in <module>() at line number 5
我只需要追踪输入文件内部的实际执行逻辑,不想处理外层包装的事件。
已尝试的过滤方法
我试过通过栈帧的文件名过滤:
if frame.f_code.co_filename != INPUT_PATH: return None
但奇怪的是,哪怕是初始exec()调用期间,frame.f_code.co_filename始终等于INPUT_PATH,这个过滤器根本区分不开外层exec()上下文和输入文件的真实代码。
核心问题
怎么在追踪输入文件代码的同时,避开外层exec()逻辑的追踪?换句话说,如何判断当前追踪的是用户输入文件里的实际代码(比如里面定义的函数),而不是外层的包装调用?
可行解决方案
修改追踪器函数,通过栈帧深度过滤:
def tracer(frame, event, arg=None): depth = 0 current_frame = frame while current_frame: depth += 1 current_frame = current_frame.f_back if depth > 3: # 这里编写你的事件处理逻辑 return tracer return None
内容的提问来源于stack exchange,提问作者dheb
相关产品推荐
相关产品推荐

