繁体   English   中英

在 lldb python 中打印结构数组

[英]printing struct array in lldb python

遵循此处的问题: 编写 Python 脚本以在 lldb 中打印出一组 recs

我希望能够为 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]和 up 项没问题。

为什么print buffers.GetChildAtIndex(1,0,1)指向buffers[0].count item 而不是buffers[1]

我究竟做错了什么?

GetChildAtIndex 试图在这里为您的目的提供一点帮助。 它与帮助一致,它说:

指针因指向的内容而异。 如果指针指向简单类型,则索引为零处的子值是唯一可用的子值,除非synthetic_allowed 为真,在这种情况下,指针将用作数组并可以使用正或负索引创建“合成”子值. 如果指针指向聚合类型(数组、类、联合、结构),则透明地跳过指针对象,并且任何子项都将成为聚合类型中子值的索引。 例如,如果我们有一个 'Point' 类型并且我们有一个 SBValue 包含一个指向 'Point' 类型的指针,那么位于索引 0 的子节点将是 'x' 成员,位于索引 1 的子节点将是 ' y' 成员(索引为零的子项不会是 'Point' 实例)。

所以实际上,buffers.GetChildAtIndex(2,0,1) 应该返回“No Value”。 无论是那个还是为 allow-synthetic 参数传递 1 都应该关闭这种窥视行为。 无论哪种情况,这都是一个错误,请将其提交到http://bugreporter.apple.com

同时,您应该能够通过手动遍历数组并使用“SBTarget.CreateValueFromAddress 创建值来获得相同的效果。首先使用 buffers.GetAddress(); 获取数组的地址;以及缓冲区的大小通过获取缓冲区的类型,获取其 Pointee 类型并在其上调用 GetByteSize。然后将地址增加大小计数倍以创建所有值。

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM