Python 如何获取内部值作为gdb pretty print的数组使用?

Python 如何获取内部值作为gdb pretty print的数组使用?,python,gdb,pretty-print,Python,Gdb,Pretty Print,我为InnerStruct编写了一个漂亮的打印机,它将数组显示为2个元素,并且正确地显示了值。我还为TestStruct2开了一个玩笑,但是我不知道如何使TestStruct包含与InnerStruct相同的内容。我不知道如何从gdb/python访问array.nestedVariables。我该如何编写它,以便TestStruct提供与InnerStruct相同的结果 来源 struct InnerStruct { int buffer[100]; int len; }; s

我为InnerStruct编写了一个漂亮的打印机,它将数组显示为2个元素,并且正确地显示了值。我还为TestStruct2开了一个玩笑,但是我不知道如何使TestStruct包含与InnerStruct相同的内容。我不知道如何从gdb/python访问array.nestedVariables。我该如何编写它,以便TestStruct提供与InnerStruct相同的结果

来源

struct InnerStruct
{
    int buffer[100];
    int len;
};
struct TestStruct
{
    InnerStruct array;
};
struct TestStruct2
{
    InnerStruct array;
};

int main() {
    TestStruct s;
    s.array.buffer[0] = 5;
    s.array.buffer[1] = 8;
    s.array.len=2;
    TestStruct2 s2;
    s2.array.buffer[0] = 5;
    s2.array.buffer[1] = 8;
    s2.array.len=2;
    return 0;
}
格德比尼特先生

python

pp = gdb.printing.RegexpCollectionPrettyPrinter("pp")

class InnerStructPrinter:
    "Print a InnerStruct"

    class _iterator:
        def __init__ (self, start, finish):
            self.item = start
            self.finish = finish
            self.count = 0

        def __iter__ (self):
            return self

        def __next__ (self):
            count = self.count
            self.count = self.count + 1
            if self.item == self.finish:
                raise StopIteration
            elt = self.item.dereference()
            self.item = self.item + 1
            return ('[%d]' % count, elt)

        def next (self):
            return self.__next__()

    def __init__ (self, val):
        self.val = val

    def children (self):
        start = self.val['buffer'][0].address
        return self._iterator(start, start + self.val['len'])

    def to_string (self):
        len = self.val['len']
        return '%s of length %d' % (self.val.type, len)

    def display_hint (self):
        return 'array'

pp.add_printer('InnerStruct', '^InnerStruct$', InnerStructPrinter)

class TestStruct2Printer:
    "Print a TestStruct2"

    def __init__ (self, val):
        self.val = val

    def to_string (self):
        return "Array of"

    def children(self):
        yield ('0', 'fake')
        yield ('1', 'val')

    def display_hint (self):
        return 'array'

pp.add_printer('TestStruct2', '^TestStruct2$', TestStruct2Printer)

gdb.printing.register_pretty_printer(gdb.current_objfile(), pp)
end

我看不出有什么理由认为增加这一点是不够的

类TestStructPrinter(InnerStructPrinter):
定义初始值(self,val):
super().uuu init_uuu(val['array']))
pp.add_打印机('TestStruct','^TestStruct$',TestStructPrinter)
换句话说,子字段仅作为
val['field']['subfield']
访问。子类化有点像黑客,但你明白了

示例会话:

(gdb)显示版本
GNU gdb(Debian 9.2-1)9.2
版权所有(C)2020免费软件基金会。
[…]
(gdb)python打印(sys.version)
3.8.6(默认,2020年9月25日09:36:53)
[GCC 10.2.0]
(gdb)打印
$1=长度为2={5,8}的内部结构
(gdb)打印s数组
$2=长度为2={5,8}的内部结构

不过,这似乎是一件相当愚蠢的事情:调试器应该帮助您区分类型。通过使
TestStruct
InnerStruct
打印出相同的内容,它会误导用户认为使用的是一种类型而不是另一种类型,并让他们尝试访问,比如说,
s.buffer
而不是
s.array.buffer

您能添加一下结果的信息吗,您希望它看起来如何?什么是array.nestedVariables?我在代码中的任何地方都看不到
nestedVariables
。@ssbssa我希望TestStruct看起来与InnerStruct完全相同。gdbinit可以完美地工作,但我的问题是让TestStruct看起来像它。我不知道如何从成员中提取变量以重新创建it@ks1322我的意思不是字面上的“嵌套变量”。我是指变量中的变量。对于InnerStruct,我可以很好地访问缓冲区和长度,但是对于TestStruct,要使它看起来一样,我必须获得array.buffer/array.length,我完全不知道如何访问这些变量。我明天实际尝试时必须给您回复,但是
val['field']['subfield']
实际工作吗?我发誓我试过不止一次这让我很烦恼,我试过了。出了点问题。只有那4行吗?因为在中添加它会使
.gdbinit
中断,并且不会加载任何漂亮的打印机。不,您将它放在
python
命令和终止它的
end
命令之间。(当然,在超类之后)我想这是一个粘贴问题。它似乎起作用了,
val['field']['subfield']
我发誓我已经试过了。早上,我会尝试把这个应用到我真正的课堂上,看看它是否有效,如果我有任何后续问题,我会告诉你。我可能会接受,因为它确实有效(
val['field']['subfield']
)。认可的。我知道了如何使地图打印得漂亮,这样我的gdbinit问题就都解决了,这就足够了。泰