在 lldb python 中打印结构数组
printing struct array in lldb python
这里的问题如下: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
的数组,我应该能够通过 buffers.GetChildAtIndex
函数访问每个 Buffer
,但是数据是前 2 项已损坏。
>>> 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]
?
我做错了什么?
GetChildAtIndex 正努力为您提供一些 over-helpful 帮助。与帮助一致,上面写着:
指针因指向的内容而异。如果指针
指向一个简单类型,索引为零的 child
是唯一可用的 child 值,除非 synthetic_allowed
为真,在这种情况下指针将用作数组
并且可以使用正或创建 'synthetic' child 值
负指标。 如果指针指向聚合类型
(一个数组,class,union,struct),那么指针是
透明地跳过,任何 children 都将成为索引
聚合类型中的 child 个值。 例如,如果
我们有一个 'Point' 类型,我们有一个 SBValue 包含
指向 'Point' 类型的指针,那么索引零处的 child 将是
'x' 成员,索引 1 处的 child 将成为 'y' 成员
(索引零处的 child 不会是 'Point' 实例)。
所以真的,buffers.GetChildAtIndex(2,0,1) 应该返回 "No Value"。无论是那个还是为 allow-synthetic 参数传递 1 都应该关闭此 peek-through 行为。无论哪种情况,这都是一个错误,请将其归档为 http://bugreporter.apple.com。
与此同时,您应该能够通过手动遍历数组并使用“SBTarget.CreateValueFromAddress 来创建值来获得相同的效果。首先使用 [=33= 获取数组的地址](); 通过获取缓冲区的类型、获取其 Pointee 类型并在其上调用 GetByteSize 来确定缓冲区的大小。然后只需将地址增加大小计数次即可创建所有值。
这里的问题如下: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
的数组,我应该能够通过 buffers.GetChildAtIndex
函数访问每个 Buffer
,但是数据是前 2 项已损坏。
>>> 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]
?
我做错了什么?
GetChildAtIndex 正努力为您提供一些 over-helpful 帮助。与帮助一致,上面写着:
指针因指向的内容而异。如果指针 指向一个简单类型,索引为零的 child 是唯一可用的 child 值,除非 synthetic_allowed 为真,在这种情况下指针将用作数组 并且可以使用正或创建 'synthetic' child 值 负指标。 如果指针指向聚合类型 (一个数组,class,union,struct),那么指针是 透明地跳过,任何 children 都将成为索引 聚合类型中的 child 个值。 例如,如果 我们有一个 'Point' 类型,我们有一个 SBValue 包含 指向 'Point' 类型的指针,那么索引零处的 child 将是 'x' 成员,索引 1 处的 child 将成为 'y' 成员 (索引零处的 child 不会是 'Point' 实例)。
所以真的,buffers.GetChildAtIndex(2,0,1) 应该返回 "No Value"。无论是那个还是为 allow-synthetic 参数传递 1 都应该关闭此 peek-through 行为。无论哪种情况,这都是一个错误,请将其归档为 http://bugreporter.apple.com。
与此同时,您应该能够通过手动遍历数组并使用“SBTarget.CreateValueFromAddress 来创建值来获得相同的效果。首先使用 [=33= 获取数组的地址](); 通过获取缓冲区的类型、获取其 Pointee 类型并在其上调用 GetByteSize 来确定缓冲区的大小。然后只需将地址增加大小计数次即可创建所有值。