GDB pretty-printer: печать массива, когда размер известен родительской структуре

У меня есть структура в 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"] в первом результате от итератора, возвращенного DataBlockPrinter"s children() метод, а затем из db["hb"]["data"] для следующего size Результаты.

Я также пытался использовать отдельный принтер для HeapBlocksНо проблема в том, что HeapBlock понятия не имеет, насколько он велик: что хранится в родительском (DataBlock), Итак HeapBlock принтер также не знает, когда прекратить итерации.

Можно ли получить size поле к HeapBlock красивый принтер, когда он печатается как часть DataBlock Вот?

2 ответа

Я нашел другой способ

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

К сожалению, нет встроенного способа сделать это. Я считаю, что в gdb bugzilla есть открытая ошибка.

Это может быть возможно сделать с помощью взлома: в DataBlock принтер, запишите адрес и размер HeapBlock в хеш-таблице. Тогда HeapBlock Принтер может посмотреть это. Конечно, тогда возникает проблема с решением о том, как сделать кэш недействительным. Не совсем удачно придумать хороший способ:-(Но, может быть, это нормально - просто не лишать его законной силы. Вы можете попробовать сделать его недействительным, когда DataBlock принтер уничтожен; GDB не гарантирует, что это будет работать, но на практике это может быть нормально.

Другие вопросы по тегам