通过 sys.set_trace 访问 Python 解释器的数据栈
Accessing Python intepreter's data stack through sys.set_trace
我正在使用 sys.set_trace(..)
对 python 代码执行字节码分析。
更具体地说,我设置了一个跟踪器函数,每次执行字节码时都会触发。
对于我的分析,我需要获取带有操作码 "STORE_ATTR"
的字节码将在其上存储值的对象。
例如。我有这个字节码:
Instruction(opname='STORE_ATTR', opcode=95, arg=9, argval='pos', argrepr='pos', offset=188, starts_line=None, is_jump_target=False)
看到这个,解释器将尝试从数据栈中弹出顶部元素,以便在其中存储一个值。
我也有办法访问该对象吗?是否有一个 API 像 TOP() 函数,我可以从跟踪器中调用它并获取堆栈的最高值当前正在执行的帧?
遗憾的是,此类信息无法通过 Python 访问,但您可以使用 C API 访问。这里的另一个问题是,这在很大程度上取决于您拥有的 Python 版本。以下适用于 Python 3.8.5
,但稍作修改也适用于其他版本。
相当于 PyEval_SetTrace
has access to the f_stacktop
field of PyFrameObject
class. This field is used by TOP()
在 ceval.c
。
您还可以验证 f_stacktop
没有暴露给 Python frame
class here.
您可以在此处查看访问当前帧的 TOS 的代码示例:
int tracefunc(PyObject *obj, PyFrameObject *frame, int what, PyObject *arg) {
[...]
PyObject **stack_pointer = frame->f_stacktop;
PyObject *tos = stack_pointer[-1];
[...]
}
我正在使用 sys.set_trace(..)
对 python 代码执行字节码分析。
更具体地说,我设置了一个跟踪器函数,每次执行字节码时都会触发。
对于我的分析,我需要获取带有操作码 "STORE_ATTR"
的字节码将在其上存储值的对象。
例如。我有这个字节码:
Instruction(opname='STORE_ATTR', opcode=95, arg=9, argval='pos', argrepr='pos', offset=188, starts_line=None, is_jump_target=False)
看到这个,解释器将尝试从数据栈中弹出顶部元素,以便在其中存储一个值。 我也有办法访问该对象吗?是否有一个 API 像 TOP() 函数,我可以从跟踪器中调用它并获取堆栈的最高值当前正在执行的帧?
遗憾的是,此类信息无法通过 Python 访问,但您可以使用 C API 访问。这里的另一个问题是,这在很大程度上取决于您拥有的 Python 版本。以下适用于 Python 3.8.5
,但稍作修改也适用于其他版本。
相当于 PyEval_SetTrace
has access to the f_stacktop
field of PyFrameObject
class. This field is used by TOP()
在 ceval.c
。
您还可以验证 f_stacktop
没有暴露给 Python frame
class here.
您可以在此处查看访问当前帧的 TOS 的代码示例:
int tracefunc(PyObject *obj, PyFrameObject *frame, int what, PyObject *arg) {
[...]
PyObject **stack_pointer = frame->f_stacktop;
PyObject *tos = stack_pointer[-1];
[...]
}