【发布时间】:2019-07-30 19:15:51
【问题描述】:
我使用 GDB 来了解 CPython 如何执行 test.py 源文件,我想在 CPython 开始执行时停止它我感兴趣的操作码。
操作系统: Ubuntu 18.04.2 LTS
调试器: GNU gdb (Ubuntu 8.1-0ubuntu3) 8.1.0.20180409-git
第一个问题 - 许多 CPython 的 .py 自己的文件在我的 test.py 轮到它之前执行,所以我不能只在 _PyEval_EvalFrameDefault 处中断 - 其中有很多,所以我应该将我的文件与其他文件区分开来。
第二个问题 - 我不能设置像“当文件名等于test.py”这样的条件,因为文件名不是一个简单的@ 987654325@字符串,它是CPython的Unicode对象,所以标准的GDB字符串函数不能用于比较。
此时,我将在test.py 源代码的所需行处中断执行的下一个技巧:
比如我有源文件:
x = ['a', 'b', 'c']
# I want to set the breakpoint at this line.
for e in x:
print(e)
我将二进制左移运算符添加到代码中:
x = ['a', 'b', 'c']
# Added for breakpoint
a = 12
b = 2 << a
for e in x:
print(e)
然后,通过这个 GDB 命令在Python/ceval.c 文件中跟踪BINARY_LSHIFT 操作码的执行:
break ceval.c:1327
我选择了BINARY_LSHIFT 操作码,因为它很少在代码中使用。因此,我可以快速到达.py 文件的所需部分——它在我的test.py 之前执行的所有其他.py 模块中发生一次。
我看起来更直接地做同样的事情,所以 问题:
- 我可以捕捉到
test.py开始执行的那一刻吗?我应该提一下,test.py文件名出现在不同阶段:解析、编译、执行。因此,在任何阶段都可以中断 CPython 执行也是一件好事。 - 我可以指定
test.py的行,我想在哪里中断?.c文件很容易,但对于.py文件则不然。
【问题讨论】: