在lldb python中打印结构数组 [英] printing struct array in lldb python
问题描述
在此处关注问题: 在lldb中: 现在, 只有 为什么 我在做什么错了? GetChildAtIndex试图为您的目的提供一些帮助.它与帮助内容一致,内容为: 指针根据指向的内容而有所不同.如果指针
指向简单类型,索引为零的孩子
是唯一可用的子级值,除非Composite_allowed
为true,在这种情况下,指针将用作数组
并可以使用正数或
负指标. 如果指针指向聚合类型
(数组,类,联合,结构),则指针是
透明地跳过,任何子级都将成为索引
聚合类型中的子值.例如,如果
我们有一个'Point'类型,并且我们的SBValue包含一个
指向"Point"类型的指针,则索引为零的子元素为
'x'成员,索引1的孩子将是'y'成员
(索引为零的孩子将不是"Point"实例). 实际上,buffers.GetChildAtIndex(2,0,1)应该返回了无值".为allow-synthetic参数传递1或传递1都应关闭这种偷看行为.无论哪种情况,这都是错误,请通过 http://bugreporter.apple.com 提交.(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
,但是前两个项目中的数据已损坏. >>> 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]
?
同时,您应该能够通过手动遍历数组并使用"SBTarget.CreateValueFromAddress创建值"来获得相同的效果.首先使用buffers.GetAddress()获取数组的地址,然后通过获取缓冲区的类型,获取其Pointee类型并在其中调用GetByteSize来获取缓冲区的大小,然后将地址增加大小计数时间即可创建所有值.
Following the question here: Writing a Python script to print out an array of recs in lldb
I would like to be able to create a type summary for an array of a given struct in lldb. Problem is that I am not able to access array correctly through python-lldb. Some data is incorrect.
I have the following test code in 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;
}
In 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')
Now, buffers
should point to array of struct Buffer
and I should be able to access each and every Buffer
via the buffers.GetChildAtIndex
function, but the data is corrupted in the first 2 items.
>>> 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
}
Only the buffers[2]
and up items are ok.
Why does print buffers.GetChildAtIndex(1,0,1)
points to buffers[0].count
item instead of buffers[1]
?
What am I doing wrong?
GetChildAtIndex is trying to be a little over-helpful for your purposes here. It is in accord with the help, which says:
Pointers differ depending on what they point to. If the pointer points to a simple type, the child at index zero is the only child value available, unless synthetic_allowed is true, in which case the pointer will be used as an array and can create 'synthetic' child values using positive or negative indexes. If the pointer points to an aggregate type (an array, class, union, struct), then the pointee is transparently skipped and any children are going to be the indexes of the child values within the aggregate type. For example if we have a 'Point' type and we have a SBValue that contains a pointer to a 'Point' type, then the child at index zero will be the 'x' member, and the child at index 1 will be the 'y' member (the child at index zero won't be a 'Point' instance).
So really, buffers.GetChildAtIndex(2,0,1) should have returned "No Value". Either that or passing 1 for the allow-synthetic argument should turn off this peek-through behavior. In either case, this is a bug, please file it with http://bugreporter.apple.com.
In the mean time you should be able to get the same effect by walking your array by hand and using "SBTarget.CreateValueFromAddress to create the values. Start by getting the address of the array with buffers.GetAddress(); and the size of Buffers by getting the type of buffers, getting its Pointee type & calling GetByteSize on that. Then just increment the address by the size count times to create all the values.
这篇关于在lldb python中打印结构数组的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!