如何在gdb中读取带有_插槽的python对象的属性

如何在gdb中读取带有_插槽的python对象的属性,python,gdb,Python,Gdb,我有一个Python进程的核心转储,我正试图检查它。特别是,我对特定的Decimal实例的值感兴趣 我已经将Python扩展加载到gdb,特别是我正在使用。这在gdb中提供了对Python语言状态的某种程度的检查。值得注意的是,检查基于为下级流程中的对象重新创建“代理对象”,这些代理对象是通过复制被检查对象的\uuu dict\uuu创建的 不幸的是,具有\uuuuuu插槽的类的实例没有\uuuuu dict\uuuuu,因此返回None,因此Decimal实例的属性似乎不需要一些努力就无法检查

我有一个Python进程的核心转储,我正试图检查它。特别是,我对特定的
Decimal
实例的值感兴趣

我已经将Python扩展加载到gdb,特别是我正在使用。这在gdb中提供了对Python语言状态的某种程度的检查。值得注意的是,检查基于为下级流程中的对象重新创建“代理对象”,这些代理对象是通过复制被检查对象的
\uuu dict\uuu
创建的

不幸的是,具有
\uuuuuu插槽的类的实例没有
\uuuuu dict\uuuuu
,因此返回None,因此
Decimal
实例的属性似乎不需要一些努力就无法检查

此外,由于这是一个核心转储,而不是一个实时进程,所以我不能简单地调用。似乎我唯一的选择是在gdb中手动遍历结构,直到得到值为止


如何完成这种手动检查?

从一些要检查的值开始。对于本例,我们将查看
self.\u int
。首先获取
self
的地址,并将其保存到方便变量中:

(gdb) py-locals
self = <Decimal at remote 0x7f2d6cbc0280>
[...]
(gdb) set $self = (PyObject*)0x7f2d6cbc0280
(gdb) p $self->ob_type->tp_dict
$5 = {[...] '_int': <member_descriptor at remote 0x7f2d8e527320>, [...]}
(gdb) set $int = (PyMemberDescrObject *)0x7f2d8e527320
时隙属性存储在与对象指针的某个偏移量(
$self
)处,我们可以这样获得该偏移量:

(gdb) p *$int->d_member
$9 = {name = 0x7f2d931d3774 "_int", type = 16, offset = 24, flags = 0, doc = 0x0}
要解释该值,我们还必须注意类型。的实现显示了如何根据类型强制转换值,我们可以看到上面的类型16对应于
T\u OBJECT\u EX
。现在,我们将描述符中的
偏移量
添加到
$self
,适当地转换它,并打印结果:

(gdb) p *(PyObject**)((char *)$self+24)
$14 = '600'
你有了它:
self.\u int
'600'