GDB漂亮打印机:打印的阵列时的大小由父结构已知

问题描述:

我在C一个结构++是这样的:GDB漂亮打印机:打印的阵列时的大小由父结构已知

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> 

这是通过从DataBlockPrinterchildren()方法返回的迭代器的第一个结果返回db["size"],然后从db["hb"]["data"]下一个size结果完成。

我也尝试使用一个单独的打印机HeapBlocks,但问题有一个HeapBlock不知道它到底有多大:存储在父(DataBlock),所以HeapBlock打印机也不会知道何时停止迭代。

当它作为DataBlock的一部分在这里打印时,是否可以将size字段获取到HeapBlock美丽的打印机?

不幸的是,没有内置的方法来做到这一点。我相信在gdb bugzilla中存在一个bug。

可能会用黑客做到这一点:在DataBlock打印机中,在散列表中记录HeapBlock的地址和大小。然后HeapBlock打印机可以查看这个。当然,这个问题变成了决定如何使缓存无效的问题之一。 Offhand我想不出一个好办法:-(但也许没关系,只要不使它失效就可以了,当DataBlock打印机被销毁时,你可能会失效; gdb并不能保证它可以正常工作,但它可能没问题实践。

+0

好像组合https://sourceware.org/bugzilla/show_bug.cgi?id=12806和https://sourceware.org/bugzilla/ show_bug.cgi?ID = 16436? – Inductiveload 2015-03-09 16:09:43

我发现一个其他的方式

#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'