在此处提出问题:Writing a Python script to print out an array of recs in lldb
我希望能够在lldb中为给定结构的数组创建类型摘要。问题是我无法通过python-lldb正确访问数组。有些数据不正确。
我在C中有以下测试代码:
#include <stdio.h>
#include <stdlib.h>
struct Buffer
{
struct Buffer* next;
struct Buffer* prev;
};
struct Base
{
struct Buffer* buffers;
int count;
};
void fill(struct Buffer* buf, int count)
{
for (int i = 0; i < count; ++i)
{
struct Buffer t = {(void*)0xdeadbeef,(void*)i};
buf[i] = t;
}
}
void foo(struct Base* base)
{
printf("break here\n");
}
int main(int argc, char** argv)
{
int c = 20;
void* buf = malloc(sizeof (struct Buffer) * c);
struct Base base = {.buffers = buf, .count = c};
fill(base.buffers, base.count);
foo(&base);
return 0;
}
在lldb:
(lldb) b foo
(lldb) r
(lldb) script
>>> debugger=lldb.debugger
>>> target=debugger.GetSelectedTarget()
>>> frame=lldb.frame
>>> base=frame.FindVariable('base')
>>> buffers=base.GetChildMemberWithName('buffers')
现在,buffers
应指向struct Buffer
数组,我应该能够通过Buffer
函数访问每个buffers.GetChildAtIndex
,但数据已损坏前两项。
>>> print buffers.GetChildAtIndex(0,0,1)
(Buffer *) next = 0x00000000deadbeef
>>> print buffers.GetChildAtIndex(1,0,1)
(Buffer *) prev = 0x0000000000000000
>>> print buffers.GetChildAtIndex(2,0,1)
(Buffer) [2] = {
next = 0x00000000deadbeef
prev = 0x0000000000000002
}
只有buffers[2]
及以上项目可以。
为什么print buffers.GetChildAtIndex(1,0,1)
指向buffers[0].count
项而不是buffers[1]
?
我做错了什么?
答案 0 :(得分:1)
GetChildAtIndex试图在这里对你的目的有点过分帮助。这符合帮助,其中说:
指针根据指向的不同而不同。如果指针 指向一个简单类型,索引为零的子项 是唯一可用的子值,除非synthetic_allowed 是的,在这种情况下,指针将用作数组 并且可以使用positive或者创建'合成'子值 负面指数。 如果指针指向聚合类型 (数组,类,联合,结构),然后是指针 透明地跳过,任何孩子都将成为索引 聚合类型中的子值。例如,如果 我们有一个'Point'类型,我们有一个包含a的SBValue 指向'Point'类型的指针,那么索引为零的子节点将是 'x'成员,索引1处的子将成为'y'成员 (索引为零的子节点不是'Point'实例)。
所以真的,buffers.GetChildAtIndex(2,0,1)应该返回“No Value”。对于allow-synthetic参数,或者传递1应该关闭这个偷看行为。在任何一种情况下,这都是一个错误,请用http://bugreporter.apple.com提交。
与此同时,您应该能够通过手动遍历数组并使用“SBTarget.CreateValueFromAddress来创建值来获得相同的效果。首先使用buffers.GetAddress()获取数组的地址;以及通过获取缓冲区类型获取缓冲区的大小,获取其Pointee类型并调用GetByteSize。然后只需将地址增加大小计数次数即可创建所有值。