pretty-print.py 4.0 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167
  1. import gdb.printing
  2. import re
  3. def create_iter(item, end, idx):
  4. return vectorPrinter._iterator(item, end, idx)
  5. class vectorPrinter:
  6. class _iterator:
  7. def __init__(self, item, end, idx):
  8. self.item = item
  9. self.end = end
  10. self.size = self.end - self.item
  11. self.idx = idx
  12. def __iter__(self):
  13. return self
  14. def __next__(self):
  15. if self.item >= self.end:
  16. raise StopIteration
  17. key = '[%d]' % self.idx
  18. iter = self.item.dereference()
  19. self.item += 1
  20. self.idx += 1
  21. return key, iter
  22. def __init__(self, val):
  23. self.val = val
  24. def to_string(self):
  25. return "vector of size %d, capacity %d" % (self.val['m_size'], self.val['m_capacity'])
  26. def display_hint(self):
  27. return 'array'
  28. def children(self):
  29. return self._iterator(self.val['m_arr'], self.val['m_arr'] + self.val['m_size'], 0)
  30. def _leftmost(node):
  31. ret = node
  32. while ret['left'] != 0:
  33. ret = ret['left'].dereference()
  34. return ret
  35. def _next(node):
  36. if node['right']:
  37. return _leftmost(node['right'].dereference())
  38. else:
  39. if node['parent'] == 0:
  40. return None
  41. parent = node['parent'].dereference()
  42. if parent['left'] == node.address:
  43. return parent
  44. ret = node
  45. while True:
  46. ret = ret['parent'].dereference()
  47. if ret['parent'] == 0:
  48. return None
  49. if ret['parent'].dereference()['left'] == ret.address:
  50. break
  51. return ret['parent'].dereference()
  52. class mapPrinter:
  53. def __init__(self, val):
  54. self.val = val
  55. def to_string(self):
  56. return "types::map"
  57. def display_hint(self):
  58. return 'array'
  59. def children(self):
  60. yield '[root]', self.val['root']
  61. if self.val['root'] == 0:
  62. return
  63. nd = _leftmost(self.val['root'].dereference())
  64. i = 0
  65. while True:
  66. yield "[%d]" % i, nd['v']
  67. nd = _next(nd)
  68. i += 1
  69. if nd == None:
  70. break
  71. class stringPrinter:
  72. def __init__(self, val):
  73. self.val = val
  74. def to_string(self):
  75. return self.val['m_arr']
  76. def children(self):
  77. yield 'str', self.val['m_arr']
  78. if self.val['m_arr'] == 0:
  79. return
  80. yield 'length', self.val['m_size'] - 1
  81. ptr = self.val['m_arr']
  82. i = 0
  83. while ptr.dereference() != 0:
  84. yield '[%d]' % i, ptr.dereference()
  85. ptr += 1
  86. i += 1
  87. yield '[%d]' % i, 0
  88. class listPrinter:
  89. def __init__(self, val):
  90. self.val = val
  91. def to_string(self):
  92. return "list of size %d" % (self.val['head'].reinterpret_cast(gdb.lookup_type("size_t").pointer()) + 2).dereference()
  93. def display_hint(self):
  94. return 'array'
  95. def children(self):
  96. head = self.val['head']
  97. end = self.val['tail']
  98. yield '[head]', head
  99. yield '[tail]', end
  100. if head == 0 or end == 0:
  101. return
  102. node = head['next']
  103. idx = 0
  104. while node != end:
  105. yield '[%d]' % idx, node['value']
  106. idx += 1
  107. node = node['next']
  108. def build_pretty_printer(val):
  109. type = val.type
  110. if type.code == gdb.TYPE_CODE_REF:
  111. type = type.target()
  112. if type.code == gdb.TYPE_CODE_PTR:
  113. type = type.target()
  114. type = type.unqualified().strip_typedefs()
  115. typename = type.tag
  116. if typename == None:
  117. return None
  118. if re.compile(r"^types::list<.*?>$").match(typename):
  119. return listPrinter(val)
  120. if re.compile(r"^types::vector<.*?>$").match(typename):
  121. return vectorPrinter(val)
  122. if re.compile(r"^types::string<.*?>$").match(typename):
  123. return stringPrinter(val)
  124. if re.compile(r"^types::map<.*?>$").match(typename):
  125. return mapPrinter(val)
  126. return None
  127. gdb.pretty_printers.append(build_pretty_printer)