在lldb python中打印结构数组 [英] printing struct array in lldb python

查看:266
本文介绍了在lldb python中打印结构数组的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

在此处关注问题:

在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,但是前两个项目中的数据已损坏.

>>> 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试图为您的目的提供一些帮助.它与帮助内容一致,内容为:

指针根据指向的内容而有所不同.如果指针 指向简单类型,索引为零的孩子 是唯一可用的子级值,除非Composite_allowed 为true,在这种情况下,指针将用作数组 并可以使用正数或 负指标. 如果指针指向聚合类型 (数组,类,联合,结构),则指针是 透明地跳过,任何子级都将成为索引 聚合类型中的子值.例如,如果 我们有一个'Point'类型,并且我们的SBValue包含一个 指向"Point"类型的指针,则索引为零的子元素为 'x'成员,索引1的孩子将是'y'成员 (索引为零的孩子将不是"Point"实例).

实际上,buffers.GetChildAtIndex(2,0,1)应该返回了无值".为allow-synthetic参数传递1或传递1都应关闭这种偷看行为.无论哪种情况,这都是错误,请通过 http://bugreporter.apple.com 提交.. >

同时,您应该能够通过手动遍历数组并使用"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屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆