我在C ++中有一个像这样的结构:
struct HeapBlock {
char* data;
}
struct DataBlock {
int size;
HeapBlock hb;
}
这些是框架的一部分,还有其他几个成员,助手等等,但这些是重要的部分。我想在Python GDB漂亮的打印机中显示这个:
NAME TYPE VALUE
DataBlock: DataBlock "Size 2000 @ 0x445343"
|--->size int 2000
|--->data HeapBlock {...}
|--->[0] char 0x34
|--->[1] char 0x45
....
<more values>
到目前为止,我未能将HeapBlock显示为一个单独的孩子。我成功地滥用了一个迭代器来生成:
NAME TYPE VALUE
DataBlock: DataBlock
|--->size int 2000
|--->[0] char 0x34
|--->[1] char 0x45
....
<more values>
这是通过从db["size"]
的{{1}}方法返回的迭代器返回第一个结果中的DataBlockPrinter
,然后从children()
返回db["hb"]["data"]
来完成的。 1}}结果。
我还尝试为size
使用单独的打印机,但问题是HeapBlocks
不知道它有多大:它存储在父(HeapBlock
中}),因此DataBlock
打印机也不知道何时停止迭代。
当HeapBlock
漂亮的打印机作为size
的一部分打印出来时,是否可以将HeapBlock
字段输入?
答案 0 :(得分:1)
我找到了另一种方式
#convert to vector
class DataBlock:
def iter(self):
p=self.v['p']
emtp=p.type.target().unqualified().strip_typedefs()
pv=emtp.vector(self.cnt-1).pointer()#convert to vector,the actual type is char (*) __attribute__ (vector_size(self.cnt)))
yield('p',p.cast(pv))
#We register this type
def regCls(v):
if str(v.type).find(") __attribute__ ((vector_size")>0:
return _py_vector(v)
def regMyPP():gdb.pretty_printers.append(regCls)
#Then parse this type out
class _py_vector:
def __init__(self,v):self.v=v
def tp(self):
s=str(self.v.type)
return gdb.lookup_type(s[:s.find('(')-1]).pointer()#eg.char
def sz(self):
s=str(self.v.type)
st=s.find('vector_size(')+12
ed=s.find(')',st)
return int(s[st:ed])#Get it's size
def to_string(self): return self.v.cast(self.tp()).lazy_string(length=self.sz())
def display_hint(self): return 'string'
答案 1 :(得分:0)
不幸的是,没有内置的方法可以做到这一点。我相信在gdb bugzilla中有一个关于它的bug。
有可能通过黑客攻击:在DataBlock
打印机中,在哈希表中记录HeapBlock
的地址和大小。然后HeapBlock
打印机可以查看这个。当然,问题就变成了决定如何使缓存无效的问题。我不能想到一个好的方法:-(但也许它可以简单地使它无效。你可能会尝试在DataBlock
打印机被销毁时失效; gdb没有做到这一点保证这会有效,但在实践中可能没问题。