printers.py 53 KB

12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364656667686970717273747576777879808182838485868788899091929394959697989910010110210310410510610710810911011111211311411511611711811912012112212312412512612712812913013113213313413513613713813914014114214314414514614714814915015115215315415515615715815916016116216316416516616716816917017117217317417517617717817918018118218318418518618718818919019119219319419519619719819920020120220320420520620720820921021121221321421521621721821922022122222322422522622722822923023123223323423523623723823924024124224324424524624724824925025125225325425525625725825926026126226326426526626726826927027127227327427527627727827928028128228328428528628728828929029129229329429529629729829930030130230330430530630730830931031131231331431531631731831932032132232332432532632732832933033133233333433533633733833934034134234334434534634734834935035135235335435535635735835936036136236336436536636736836937037137237337437537637737837938038138238338438538638738838939039139239339439539639739839940040140240340440540640740840941041141241341441541641741841942042142242342442542642742842943043143243343443543643743843944044144244344444544644744844945045145245345445545645745845946046146246346446546646746846947047147247347447547647747847948048148248348448548648748848949049149249349449549649749849950050150250350450550650750850951051151251351451551651751851952052152252352452552652752852953053153253353453553653753853954054154254354454554654754854955055155255355455555655755855956056156256356456556656756856957057157257357457557657757857958058158258358458558658758858959059159259359459559659759859960060160260360460560660760860961061161261361461561661761861962062162262362462562662762862963063163263363463563663763863964064164264364464564664764864965065165265365465565665765865966066166266366466566666766866967067167267367467567667767867968068168268368468568668768868969069169269369469569669769869970070170270370470570670770870971071171271371471571671771871972072172272372472572672772872973073173273373473573673773873974074174274374474574674774874975075175275375475575675775875976076176276376476576676776876977077177277377477577677777877978078178278378478578678778878979079179279379479579679779879980080180280380480580680780880981081181281381481581681781881982082182282382482582682782882983083183283383483583683783883984084184284384484584684784884985085185285385485585685785885986086186286386486586686786886987087187287387487587687787887988088188288388488588688788888989089189289389489589689789889990090190290390490590690790890991091191291391491591691791891992092192292392492592692792892993093193293393493593693793893994094194294394494594694794894995095195295395495595695795895996096196296396496596696796896997097197297397497597697797897998098198298398498598698798898999099199299399499599699799899910001001100210031004100510061007100810091010101110121013101410151016101710181019102010211022102310241025102610271028102910301031103210331034103510361037103810391040104110421043104410451046104710481049105010511052105310541055105610571058105910601061106210631064106510661067106810691070107110721073107410751076107710781079108010811082108310841085108610871088108910901091109210931094109510961097109810991100110111021103110411051106110711081109111011111112111311141115111611171118111911201121112211231124112511261127112811291130113111321133113411351136113711381139114011411142114311441145114611471148114911501151115211531154115511561157115811591160116111621163116411651166116711681169117011711172117311741175117611771178117911801181118211831184118511861187118811891190119111921193119411951196119711981199120012011202120312041205120612071208120912101211121212131214121512161217121812191220122112221223122412251226122712281229123012311232123312341235123612371238123912401241124212431244124512461247124812491250125112521253125412551256125712581259126012611262126312641265126612671268126912701271127212731274127512761277127812791280128112821283128412851286128712881289129012911292129312941295129612971298129913001301130213031304130513061307130813091310131113121313131413151316131713181319132013211322132313241325132613271328132913301331133213331334133513361337133813391340134113421343134413451346134713481349135013511352135313541355135613571358135913601361136213631364136513661367136813691370137113721373137413751376137713781379138013811382138313841385138613871388138913901391139213931394139513961397139813991400140114021403140414051406140714081409141014111412141314141415141614171418141914201421142214231424142514261427142814291430143114321433143414351436143714381439144014411442144314441445144614471448144914501451145214531454145514561457145814591460146114621463146414651466
  1. # Pretty-printers for libstdc++.
  2. # Copyright (C) 2008-2015 Free Software Foundation, Inc.
  3. # This program is free software; you can redistribute it and/or modify
  4. # it under the terms of the GNU General Public License as published by
  5. # the Free Software Foundation; either version 3 of the License, or
  6. # (at your option) any later version.
  7. #
  8. # This program is distributed in the hope that it will be useful,
  9. # but WITHOUT ANY WARRANTY; without even the implied warranty of
  10. # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
  11. # GNU General Public License for more details.
  12. #
  13. # You should have received a copy of the GNU General Public License
  14. # along with this program. If not, see <http://www.gnu.org/licenses/>.
  15. import gdb
  16. import itertools
  17. import re
  18. import sys
  19. ### Python 2 + Python 3 compatibility code
  20. # Resources about compatibility:
  21. #
  22. # * <http://pythonhosted.org/six/>: Documentation of the "six" module
  23. # FIXME: The handling of e.g. std::basic_string (at least on char)
  24. # probably needs updating to work with Python 3's new string rules.
  25. #
  26. # In particular, Python 3 has a separate type (called byte) for
  27. # bytestrings, and a special b"" syntax for the byte literals; the old
  28. # str() type has been redefined to always store Unicode text.
  29. #
  30. # We probably can't do much about this until this GDB PR is addressed:
  31. # <https://sourceware.org/bugzilla/show_bug.cgi?id=17138>
  32. if sys.version_info[0] > 2:
  33. ### Python 3 stuff
  34. Iterator = object
  35. # Python 3 folds these into the normal functions.
  36. imap = map
  37. izip = zip
  38. # Also, int subsumes long
  39. long = int
  40. else:
  41. ### Python 2 stuff
  42. class Iterator:
  43. """Compatibility mixin for iterators
  44. Instead of writing next() methods for iterators, write
  45. __next__() methods and use this mixin to make them work in
  46. Python 2 as well as Python 3.
  47. Idea stolen from the "six" documentation:
  48. <http://pythonhosted.org/six/#six.Iterator>
  49. """
  50. def next(self):
  51. return self.__next__()
  52. # In Python 2, we still need these from itertools
  53. from itertools import imap, izip
  54. # Try to use the new-style pretty-printing if available.
  55. _use_gdb_pp = True
  56. try:
  57. import gdb.printing
  58. except ImportError:
  59. _use_gdb_pp = False
  60. # Try to install type-printers.
  61. _use_type_printing = False
  62. try:
  63. import gdb.types
  64. if hasattr(gdb.types, 'TypePrinter'):
  65. _use_type_printing = True
  66. except ImportError:
  67. pass
  68. # Starting with the type ORIG, search for the member type NAME. This
  69. # handles searching upward through superclasses. This is needed to
  70. # work around http://sourceware.org/bugzilla/show_bug.cgi?id=13615.
  71. def find_type(orig, name):
  72. typ = orig.strip_typedefs()
  73. while True:
  74. # Use typ.name here instead of str(typ) to discard any const,etc.
  75. # qualifiers. PR 67440.
  76. search = typ.name + '::' + name
  77. try:
  78. return gdb.lookup_type(search)
  79. except RuntimeError:
  80. pass
  81. # The type was not found, so try the superclass. We only need
  82. # to check the first superclass, so we don't bother with
  83. # anything fancier here.
  84. field = typ.fields()[0]
  85. if not field.is_base_class:
  86. raise ValueError("Cannot find type %s::%s" % (str(orig), name))
  87. typ = field.type
  88. class SharedPointerPrinter:
  89. "Print a shared_ptr or weak_ptr"
  90. def __init__ (self, typename, val):
  91. self.typename = typename
  92. self.val = val
  93. def to_string (self):
  94. state = 'empty'
  95. refcounts = self.val['_M_refcount']['_M_pi']
  96. if refcounts != 0:
  97. usecount = refcounts['_M_use_count']
  98. weakcount = refcounts['_M_weak_count']
  99. if usecount == 0:
  100. state = 'expired, weak %d' % weakcount
  101. else:
  102. state = 'count %d, weak %d' % (usecount, weakcount - 1)
  103. return '%s (%s) %s' % (self.typename, state, self.val['_M_ptr'])
  104. class UniquePointerPrinter:
  105. "Print a unique_ptr"
  106. def __init__ (self, typename, val):
  107. self.val = val
  108. def to_string (self):
  109. v = self.val['_M_t']['_M_head_impl']
  110. return ('std::unique_ptr<%s> containing %s' % (str(v.type.target()),
  111. str(v)))
  112. class StdListPrinter:
  113. "Print a std::list"
  114. class _iterator(Iterator):
  115. def __init__(self, nodetype, head):
  116. self.nodetype = nodetype
  117. self.base = head['_M_next']
  118. self.head = head.address
  119. self.count = 0
  120. def __iter__(self):
  121. return self
  122. def __next__(self):
  123. if self.base == self.head:
  124. raise StopIteration
  125. elt = self.base.cast(self.nodetype).dereference()
  126. self.base = elt['_M_next']
  127. count = self.count
  128. self.count = self.count + 1
  129. return ('[%d]' % count, elt['_M_data'])
  130. def __init__(self, typename, val):
  131. self.typename = typename
  132. self.val = val
  133. def children(self):
  134. nodetype = find_type(self.val.type, '_Node')
  135. nodetype = nodetype.strip_typedefs().pointer()
  136. return self._iterator(nodetype, self.val['_M_impl']['_M_node'])
  137. def to_string(self):
  138. if self.val['_M_impl']['_M_node'].address == self.val['_M_impl']['_M_node']['_M_next']:
  139. return 'empty %s' % (self.typename)
  140. return '%s' % (self.typename)
  141. class StdListIteratorPrinter:
  142. "Print std::list::iterator"
  143. def __init__(self, typename, val):
  144. self.val = val
  145. self.typename = typename
  146. def to_string(self):
  147. nodetype = find_type(self.val.type, '_Node')
  148. nodetype = nodetype.strip_typedefs().pointer()
  149. return self.val['_M_node'].cast(nodetype).dereference()['_M_data']
  150. class StdSlistPrinter:
  151. "Print a __gnu_cxx::slist"
  152. class _iterator(Iterator):
  153. def __init__(self, nodetype, head):
  154. self.nodetype = nodetype
  155. self.base = head['_M_head']['_M_next']
  156. self.count = 0
  157. def __iter__(self):
  158. return self
  159. def __next__(self):
  160. if self.base == 0:
  161. raise StopIteration
  162. elt = self.base.cast(self.nodetype).dereference()
  163. self.base = elt['_M_next']
  164. count = self.count
  165. self.count = self.count + 1
  166. return ('[%d]' % count, elt['_M_data'])
  167. def __init__(self, typename, val):
  168. self.val = val
  169. def children(self):
  170. nodetype = find_type(self.val.type, '_Node')
  171. nodetype = nodetype.strip_typedefs().pointer()
  172. return self._iterator(nodetype, self.val)
  173. def to_string(self):
  174. if self.val['_M_head']['_M_next'] == 0:
  175. return 'empty __gnu_cxx::slist'
  176. return '__gnu_cxx::slist'
  177. class StdSlistIteratorPrinter:
  178. "Print __gnu_cxx::slist::iterator"
  179. def __init__(self, typename, val):
  180. self.val = val
  181. def to_string(self):
  182. nodetype = find_type(self.val.type, '_Node')
  183. nodetype = nodetype.strip_typedefs().pointer()
  184. return self.val['_M_node'].cast(nodetype).dereference()['_M_data']
  185. class StdVectorPrinter:
  186. "Print a std::vector"
  187. class _iterator(Iterator):
  188. def __init__ (self, start, finish, bitvec):
  189. self.bitvec = bitvec
  190. if bitvec:
  191. self.item = start['_M_p']
  192. self.so = start['_M_offset']
  193. self.finish = finish['_M_p']
  194. self.fo = finish['_M_offset']
  195. itype = self.item.dereference().type
  196. self.isize = 8 * itype.sizeof
  197. else:
  198. self.item = start
  199. self.finish = finish
  200. self.count = 0
  201. def __iter__(self):
  202. return self
  203. def __next__(self):
  204. count = self.count
  205. self.count = self.count + 1
  206. if self.bitvec:
  207. if self.item == self.finish and self.so >= self.fo:
  208. raise StopIteration
  209. elt = self.item.dereference()
  210. if elt & (1 << self.so):
  211. obit = 1
  212. else:
  213. obit = 0
  214. self.so = self.so + 1
  215. if self.so >= self.isize:
  216. self.item = self.item + 1
  217. self.so = 0
  218. return ('[%d]' % count, obit)
  219. else:
  220. if self.item == self.finish:
  221. raise StopIteration
  222. elt = self.item.dereference()
  223. self.item = self.item + 1
  224. return ('[%d]' % count, elt)
  225. def __init__(self, typename, val):
  226. self.typename = typename
  227. self.val = val
  228. self.is_bool = val.type.template_argument(0).code == gdb.TYPE_CODE_BOOL
  229. def children(self):
  230. return self._iterator(self.val['_M_impl']['_M_start'],
  231. self.val['_M_impl']['_M_finish'],
  232. self.is_bool)
  233. def to_string(self):
  234. start = self.val['_M_impl']['_M_start']
  235. finish = self.val['_M_impl']['_M_finish']
  236. end = self.val['_M_impl']['_M_end_of_storage']
  237. if self.is_bool:
  238. start = self.val['_M_impl']['_M_start']['_M_p']
  239. so = self.val['_M_impl']['_M_start']['_M_offset']
  240. finish = self.val['_M_impl']['_M_finish']['_M_p']
  241. fo = self.val['_M_impl']['_M_finish']['_M_offset']
  242. itype = start.dereference().type
  243. bl = 8 * itype.sizeof
  244. length = (bl - so) + bl * ((finish - start) - 1) + fo
  245. capacity = bl * (end - start)
  246. return ('%s<bool> of length %d, capacity %d'
  247. % (self.typename, int (length), int (capacity)))
  248. else:
  249. return ('%s of length %d, capacity %d'
  250. % (self.typename, int (finish - start), int (end - start)))
  251. def display_hint(self):
  252. return 'array'
  253. class StdVectorIteratorPrinter:
  254. "Print std::vector::iterator"
  255. def __init__(self, typename, val):
  256. self.val = val
  257. def to_string(self):
  258. return self.val['_M_current'].dereference()
  259. class StdTuplePrinter:
  260. "Print a std::tuple"
  261. class _iterator(Iterator):
  262. def __init__ (self, head):
  263. self.head = head
  264. # Set the base class as the initial head of the
  265. # tuple.
  266. nodes = self.head.type.fields ()
  267. if len (nodes) == 1:
  268. # Set the actual head to the first pair.
  269. self.head = self.head.cast (nodes[0].type)
  270. elif len (nodes) != 0:
  271. raise ValueError("Top of tuple tree does not consist of a single node.")
  272. self.count = 0
  273. def __iter__ (self):
  274. return self
  275. def __next__ (self):
  276. # Check for further recursions in the inheritance tree.
  277. # For a GCC 5+ tuple self.head is None after visiting all nodes:
  278. if not self.head:
  279. raise StopIteration
  280. nodes = self.head.type.fields ()
  281. # For a GCC 4.x tuple there is a final node with no fields:
  282. if len (nodes) == 0:
  283. raise StopIteration
  284. # Check that this iteration has an expected structure.
  285. if len (nodes) > 2:
  286. raise ValueError("Cannot parse more than 2 nodes in a tuple tree.")
  287. if len (nodes) == 1:
  288. # This is the last node of a GCC 5+ std::tuple.
  289. impl = self.head.cast (nodes[0].type)
  290. self.head = None
  291. else:
  292. # Either a node before the last node, or the last node of
  293. # a GCC 4.x tuple (which has an empty parent).
  294. # - Left node is the next recursion parent.
  295. # - Right node is the actual class contained in the tuple.
  296. # Process right node.
  297. impl = self.head.cast (nodes[1].type)
  298. # Process left node and set it as head.
  299. self.head = self.head.cast (nodes[0].type)
  300. self.count = self.count + 1
  301. # Finally, check the implementation. If it is
  302. # wrapped in _M_head_impl return that, otherwise return
  303. # the value "as is".
  304. fields = impl.type.fields ()
  305. if len (fields) < 1 or fields[0].name != "_M_head_impl":
  306. return ('[%d]' % self.count, impl)
  307. else:
  308. return ('[%d]' % self.count, impl['_M_head_impl'])
  309. def __init__ (self, typename, val):
  310. self.typename = typename
  311. self.val = val;
  312. def children (self):
  313. return self._iterator (self.val)
  314. def to_string (self):
  315. if len (self.val.type.fields ()) == 0:
  316. return 'empty %s' % (self.typename)
  317. return '%s containing' % (self.typename)
  318. class StdStackOrQueuePrinter:
  319. "Print a std::stack or std::queue"
  320. def __init__ (self, typename, val):
  321. self.typename = typename
  322. self.visualizer = gdb.default_visualizer(val['c'])
  323. def children (self):
  324. return self.visualizer.children()
  325. def to_string (self):
  326. return '%s wrapping: %s' % (self.typename,
  327. self.visualizer.to_string())
  328. def display_hint (self):
  329. if hasattr (self.visualizer, 'display_hint'):
  330. return self.visualizer.display_hint ()
  331. return None
  332. class RbtreeIterator(Iterator):
  333. def __init__(self, rbtree):
  334. self.size = rbtree['_M_t']['_M_impl']['_M_node_count']
  335. self.node = rbtree['_M_t']['_M_impl']['_M_header']['_M_left']
  336. self.count = 0
  337. def __iter__(self):
  338. return self
  339. def __len__(self):
  340. return int (self.size)
  341. def __next__(self):
  342. if self.count == self.size:
  343. raise StopIteration
  344. result = self.node
  345. self.count = self.count + 1
  346. if self.count < self.size:
  347. # Compute the next node.
  348. node = self.node
  349. if node.dereference()['_M_right']:
  350. node = node.dereference()['_M_right']
  351. while node.dereference()['_M_left']:
  352. node = node.dereference()['_M_left']
  353. else:
  354. parent = node.dereference()['_M_parent']
  355. while node == parent.dereference()['_M_right']:
  356. node = parent
  357. parent = parent.dereference()['_M_parent']
  358. if node.dereference()['_M_right'] != parent:
  359. node = parent
  360. self.node = node
  361. return result
  362. def get_value_from_Rb_tree_node(node):
  363. """Returns the value held in an _Rb_tree_node<_Val>"""
  364. try:
  365. member = node.type.fields()[1].name
  366. if member == '_M_value_field':
  367. # C++03 implementation, node contains the value as a member
  368. return node['_M_value_field']
  369. elif member == '_M_storage':
  370. # C++11 implementation, node stores value in __aligned_buffer
  371. p = node['_M_storage']['_M_storage'].address
  372. p = p.cast(node.type.template_argument(0).pointer())
  373. return p.dereference()
  374. except:
  375. pass
  376. raise ValueError("Unsupported implementation for %s" % str(node.type))
  377. # This is a pretty printer for std::_Rb_tree_iterator (which is
  378. # std::map::iterator), and has nothing to do with the RbtreeIterator
  379. # class above.
  380. class StdRbtreeIteratorPrinter:
  381. "Print std::map::iterator"
  382. def __init__ (self, typename, val):
  383. self.val = val
  384. valtype = self.val.type.template_argument(0).strip_typedefs()
  385. nodetype = gdb.lookup_type('std::_Rb_tree_node<' + str(valtype) + '>')
  386. self.link_type = nodetype.strip_typedefs().pointer()
  387. def to_string (self):
  388. node = self.val['_M_node'].cast(self.link_type).dereference()
  389. return get_value_from_Rb_tree_node(node)
  390. class StdDebugIteratorPrinter:
  391. "Print a debug enabled version of an iterator"
  392. def __init__ (self, typename, val):
  393. self.val = val
  394. # Just strip away the encapsulating __gnu_debug::_Safe_iterator
  395. # and return the wrapped iterator value.
  396. def to_string (self):
  397. itype = self.val.type.template_argument(0)
  398. return self.val.cast(itype)
  399. class StdMapPrinter:
  400. "Print a std::map or std::multimap"
  401. # Turn an RbtreeIterator into a pretty-print iterator.
  402. class _iter(Iterator):
  403. def __init__(self, rbiter, type):
  404. self.rbiter = rbiter
  405. self.count = 0
  406. self.type = type
  407. def __iter__(self):
  408. return self
  409. def __next__(self):
  410. if self.count % 2 == 0:
  411. n = next(self.rbiter)
  412. n = n.cast(self.type).dereference()
  413. n = get_value_from_Rb_tree_node(n)
  414. self.pair = n
  415. item = n['first']
  416. else:
  417. item = self.pair['second']
  418. result = ('[%d]' % self.count, item)
  419. self.count = self.count + 1
  420. return result
  421. def __init__ (self, typename, val):
  422. self.typename = typename
  423. self.val = val
  424. def to_string (self):
  425. return '%s with %d elements' % (self.typename,
  426. len (RbtreeIterator (self.val)))
  427. def children (self):
  428. rep_type = find_type(self.val.type, '_Rep_type')
  429. node = find_type(rep_type, '_Link_type')
  430. node = node.strip_typedefs()
  431. return self._iter (RbtreeIterator (self.val), node)
  432. def display_hint (self):
  433. return 'map'
  434. class StdSetPrinter:
  435. "Print a std::set or std::multiset"
  436. # Turn an RbtreeIterator into a pretty-print iterator.
  437. class _iter(Iterator):
  438. def __init__(self, rbiter, type):
  439. self.rbiter = rbiter
  440. self.count = 0
  441. self.type = type
  442. def __iter__(self):
  443. return self
  444. def __next__(self):
  445. item = next(self.rbiter)
  446. item = item.cast(self.type).dereference()
  447. item = get_value_from_Rb_tree_node(item)
  448. # FIXME: this is weird ... what to do?
  449. # Maybe a 'set' display hint?
  450. result = ('[%d]' % self.count, item)
  451. self.count = self.count + 1
  452. return result
  453. def __init__ (self, typename, val):
  454. self.typename = typename
  455. self.val = val
  456. def to_string (self):
  457. return '%s with %d elements' % (self.typename,
  458. len (RbtreeIterator (self.val)))
  459. def children (self):
  460. rep_type = find_type(self.val.type, '_Rep_type')
  461. node = find_type(rep_type, '_Link_type')
  462. node = node.strip_typedefs()
  463. return self._iter (RbtreeIterator (self.val), node)
  464. class StdBitsetPrinter:
  465. "Print a std::bitset"
  466. def __init__(self, typename, val):
  467. self.typename = typename
  468. self.val = val
  469. def to_string (self):
  470. # If template_argument handled values, we could print the
  471. # size. Or we could use a regexp on the type.
  472. return '%s' % (self.typename)
  473. def children (self):
  474. words = self.val['_M_w']
  475. wtype = words.type
  476. # The _M_w member can be either an unsigned long, or an
  477. # array. This depends on the template specialization used.
  478. # If it is a single long, convert to a single element list.
  479. if wtype.code == gdb.TYPE_CODE_ARRAY:
  480. tsize = wtype.target ().sizeof
  481. else:
  482. words = [words]
  483. tsize = wtype.sizeof
  484. nwords = wtype.sizeof / tsize
  485. result = []
  486. byte = 0
  487. while byte < nwords:
  488. w = words[byte]
  489. bit = 0
  490. while w != 0:
  491. if (w & 1) != 0:
  492. # Another spot where we could use 'set'?
  493. result.append(('[%d]' % (byte * tsize * 8 + bit), 1))
  494. bit = bit + 1
  495. w = w >> 1
  496. byte = byte + 1
  497. return result
  498. class StdDequePrinter:
  499. "Print a std::deque"
  500. class _iter(Iterator):
  501. def __init__(self, node, start, end, last, buffer_size):
  502. self.node = node
  503. self.p = start
  504. self.end = end
  505. self.last = last
  506. self.buffer_size = buffer_size
  507. self.count = 0
  508. def __iter__(self):
  509. return self
  510. def __next__(self):
  511. if self.p == self.last:
  512. raise StopIteration
  513. result = ('[%d]' % self.count, self.p.dereference())
  514. self.count = self.count + 1
  515. # Advance the 'cur' pointer.
  516. self.p = self.p + 1
  517. if self.p == self.end:
  518. # If we got to the end of this bucket, move to the
  519. # next bucket.
  520. self.node = self.node + 1
  521. self.p = self.node[0]
  522. self.end = self.p + self.buffer_size
  523. return result
  524. def __init__(self, typename, val):
  525. self.typename = typename
  526. self.val = val
  527. self.elttype = val.type.template_argument(0)
  528. size = self.elttype.sizeof
  529. if size < 512:
  530. self.buffer_size = int (512 / size)
  531. else:
  532. self.buffer_size = 1
  533. def to_string(self):
  534. start = self.val['_M_impl']['_M_start']
  535. end = self.val['_M_impl']['_M_finish']
  536. delta_n = end['_M_node'] - start['_M_node'] - 1
  537. delta_s = start['_M_last'] - start['_M_cur']
  538. delta_e = end['_M_cur'] - end['_M_first']
  539. size = self.buffer_size * delta_n + delta_s + delta_e
  540. return '%s with %d elements' % (self.typename, long (size))
  541. def children(self):
  542. start = self.val['_M_impl']['_M_start']
  543. end = self.val['_M_impl']['_M_finish']
  544. return self._iter(start['_M_node'], start['_M_cur'], start['_M_last'],
  545. end['_M_cur'], self.buffer_size)
  546. def display_hint (self):
  547. return 'array'
  548. class StdDequeIteratorPrinter:
  549. "Print std::deque::iterator"
  550. def __init__(self, typename, val):
  551. self.val = val
  552. def to_string(self):
  553. return self.val['_M_cur'].dereference()
  554. class StdStringPrinter:
  555. "Print a std::basic_string of some kind"
  556. def __init__(self, typename, val):
  557. self.val = val
  558. self.new_string = typename.find("::__cxx11::basic_string") != -1
  559. def to_string(self):
  560. # Make sure &string works, too.
  561. type = self.val.type
  562. if type.code == gdb.TYPE_CODE_REF:
  563. type = type.target ()
  564. # Calculate the length of the string so that to_string returns
  565. # the string according to length, not according to first null
  566. # encountered.
  567. ptr = self.val ['_M_dataplus']['_M_p']
  568. if self.new_string:
  569. length = self.val['_M_string_length']
  570. # https://sourceware.org/bugzilla/show_bug.cgi?id=17728
  571. ptr = ptr.cast(ptr.type.strip_typedefs())
  572. else:
  573. realtype = type.unqualified ().strip_typedefs ()
  574. reptype = gdb.lookup_type (str (realtype) + '::_Rep').pointer ()
  575. header = ptr.cast(reptype) - 1
  576. length = header.dereference ()['_M_length']
  577. if hasattr(ptr, "lazy_string"):
  578. return ptr.lazy_string (length = length)
  579. return ptr.string (length = length)
  580. def display_hint (self):
  581. return 'string'
  582. class Tr1HashtableIterator(Iterator):
  583. def __init__ (self, hash):
  584. self.buckets = hash['_M_buckets']
  585. self.bucket = 0
  586. self.bucket_count = hash['_M_bucket_count']
  587. self.node_type = find_type(hash.type, '_Node').pointer()
  588. self.node = 0
  589. while self.bucket != self.bucket_count:
  590. self.node = self.buckets[self.bucket]
  591. if self.node:
  592. break
  593. self.bucket = self.bucket + 1
  594. def __iter__ (self):
  595. return self
  596. def __next__ (self):
  597. if self.node == 0:
  598. raise StopIteration
  599. node = self.node.cast(self.node_type)
  600. result = node.dereference()['_M_v']
  601. self.node = node.dereference()['_M_next'];
  602. if self.node == 0:
  603. self.bucket = self.bucket + 1
  604. while self.bucket != self.bucket_count:
  605. self.node = self.buckets[self.bucket]
  606. if self.node:
  607. break
  608. self.bucket = self.bucket + 1
  609. return result
  610. class StdHashtableIterator(Iterator):
  611. def __init__(self, hash):
  612. self.node = hash['_M_before_begin']['_M_nxt']
  613. self.node_type = find_type(hash.type, '__node_type').pointer()
  614. def __iter__(self):
  615. return self
  616. def __next__(self):
  617. if self.node == 0:
  618. raise StopIteration
  619. elt = self.node.cast(self.node_type).dereference()
  620. self.node = elt['_M_nxt']
  621. valptr = elt['_M_storage'].address
  622. valptr = valptr.cast(elt.type.template_argument(0).pointer())
  623. return valptr.dereference()
  624. class Tr1UnorderedSetPrinter:
  625. "Print a tr1::unordered_set"
  626. def __init__ (self, typename, val):
  627. self.typename = typename
  628. self.val = val
  629. def hashtable (self):
  630. if self.typename.startswith('std::tr1'):
  631. return self.val
  632. return self.val['_M_h']
  633. def to_string (self):
  634. return '%s with %d elements' % (self.typename, self.hashtable()['_M_element_count'])
  635. @staticmethod
  636. def format_count (i):
  637. return '[%d]' % i
  638. def children (self):
  639. counter = imap (self.format_count, itertools.count())
  640. if self.typename.startswith('std::tr1'):
  641. return izip (counter, Tr1HashtableIterator (self.hashtable()))
  642. return izip (counter, StdHashtableIterator (self.hashtable()))
  643. class Tr1UnorderedMapPrinter:
  644. "Print a tr1::unordered_map"
  645. def __init__ (self, typename, val):
  646. self.typename = typename
  647. self.val = val
  648. def hashtable (self):
  649. if self.typename.startswith('std::tr1'):
  650. return self.val
  651. return self.val['_M_h']
  652. def to_string (self):
  653. return '%s with %d elements' % (self.typename, self.hashtable()['_M_element_count'])
  654. @staticmethod
  655. def flatten (list):
  656. for elt in list:
  657. for i in elt:
  658. yield i
  659. @staticmethod
  660. def format_one (elt):
  661. return (elt['first'], elt['second'])
  662. @staticmethod
  663. def format_count (i):
  664. return '[%d]' % i
  665. def children (self):
  666. counter = imap (self.format_count, itertools.count())
  667. # Map over the hash table and flatten the result.
  668. if self.typename.startswith('std::tr1'):
  669. data = self.flatten (imap (self.format_one, Tr1HashtableIterator (self.hashtable())))
  670. # Zip the two iterators together.
  671. return izip (counter, data)
  672. data = self.flatten (imap (self.format_one, StdHashtableIterator (self.hashtable())))
  673. # Zip the two iterators together.
  674. return izip (counter, data)
  675. def display_hint (self):
  676. return 'map'
  677. class StdForwardListPrinter:
  678. "Print a std::forward_list"
  679. class _iterator(Iterator):
  680. def __init__(self, nodetype, head):
  681. self.nodetype = nodetype
  682. self.base = head['_M_next']
  683. self.count = 0
  684. def __iter__(self):
  685. return self
  686. def __next__(self):
  687. if self.base == 0:
  688. raise StopIteration
  689. elt = self.base.cast(self.nodetype).dereference()
  690. self.base = elt['_M_next']
  691. count = self.count
  692. self.count = self.count + 1
  693. valptr = elt['_M_storage'].address
  694. valptr = valptr.cast(elt.type.template_argument(0).pointer())
  695. return ('[%d]' % count, valptr.dereference())
  696. def __init__(self, typename, val):
  697. self.val = val
  698. self.typename = typename
  699. def children(self):
  700. nodetype = find_type(self.val.type, '_Node')
  701. nodetype = nodetype.strip_typedefs().pointer()
  702. return self._iterator(nodetype, self.val['_M_impl']['_M_head'])
  703. def to_string(self):
  704. if self.val['_M_impl']['_M_head']['_M_next'] == 0:
  705. return 'empty %s' % (self.typename)
  706. return '%s' % (self.typename)
  707. class SingleObjContainerPrinter(object):
  708. "Base class for printers of containers of single objects"
  709. def __init__ (self, val, viz):
  710. self.contained_value = val
  711. self.visualizer = viz
  712. def _recognize(self, type):
  713. """Return TYPE as a string after applying type printers"""
  714. global _use_type_printing
  715. if not _use_type_printing:
  716. return str(type)
  717. return gdb.types.apply_type_recognizers(gdb.types.get_type_recognizers(),
  718. type) or str(type)
  719. class _contained(Iterator):
  720. def __init__ (self, val):
  721. self.val = val
  722. def __iter__ (self):
  723. return self
  724. def __next__(self):
  725. if self.val is None:
  726. raise StopIteration
  727. retval = self.val
  728. self.val = None
  729. return ('[contained value]', retval)
  730. def children (self):
  731. if self.contained_value is None:
  732. return self._contained (None)
  733. if hasattr (self.visualizer, 'children'):
  734. return self.visualizer.children ()
  735. return self._contained (self.contained_value)
  736. def display_hint (self):
  737. # if contained value is a map we want to display in the same way
  738. if hasattr (self.visualizer, 'children') and hasattr (self.visualizer, 'display_hint'):
  739. return self.visualizer.display_hint ()
  740. return None
  741. class StdExpAnyPrinter(SingleObjContainerPrinter):
  742. "Print a std::experimental::any"
  743. def __init__ (self, typename, val):
  744. self.typename = 'std::experimental::any'
  745. self.val = val
  746. self.contained_type = None
  747. contained_value = None
  748. visualizer = None
  749. mgr = self.val['_M_manager']
  750. if mgr != 0:
  751. func = gdb.block_for_pc(int(mgr.cast(gdb.lookup_type('intptr_t'))))
  752. if not func:
  753. raise ValueError("Invalid function pointer in std::experimental::any")
  754. rx = r"""({0}::_Manager_\w+<.*>)::_S_manage\({0}::_Op, {0} const\*, {0}::_Arg\*\)""".format(typename)
  755. m = re.match(rx, func.function.name)
  756. if not m:
  757. raise ValueError("Unknown manager function in std::experimental::any")
  758. # FIXME need to expand 'std::string' so that gdb.lookup_type works
  759. mgrname = re.sub("std::string(?!\w)", str(gdb.lookup_type('std::string').strip_typedefs()), m.group(1))
  760. mgrtype = gdb.lookup_type(mgrname)
  761. self.contained_type = mgrtype.template_argument(0)
  762. valptr = None
  763. if '::_Manager_internal' in mgrname:
  764. valptr = self.val['_M_storage']['_M_buffer'].address
  765. elif '::_Manager_external' in mgrname:
  766. valptr = self.val['_M_storage']['_M_ptr']
  767. elif '::_Manager_alloc' in mgrname:
  768. datatype = gdb.lookup_type(mgrname + '::_Data')
  769. valptr = self.val['_M_storage']['_M_ptr'].cast(datatype.pointer())
  770. valptr = valptr.dereference()['_M_data'].address
  771. else:
  772. raise ValueError("Unknown manager function in std::experimental::any")
  773. contained_value = valptr.cast(self.contained_type.pointer()).dereference()
  774. visualizer = gdb.default_visualizer(contained_value)
  775. super(StdExpAnyPrinter, self).__init__ (contained_value, visualizer)
  776. def to_string (self):
  777. if self.contained_type is None:
  778. return '%s [no contained value]' % self.typename
  779. desc = "%s containing " % self.typename
  780. if hasattr (self.visualizer, 'children'):
  781. return desc + self.visualizer.to_string ()
  782. valtype = self._recognize (self.contained_type)
  783. return desc + valtype
  784. class StdExpOptionalPrinter(SingleObjContainerPrinter):
  785. "Print a std::experimental::optional"
  786. def __init__ (self, typename, val):
  787. valtype = self._recognize (val.type.template_argument(0))
  788. self.typename = "std::experimental::optional<%s>" % valtype
  789. self.val = val
  790. contained_value = val['_M_payload'] if self.val['_M_engaged'] else None
  791. visualizer = gdb.default_visualizer (val['_M_payload'])
  792. super (StdExpOptionalPrinter, self).__init__ (contained_value, visualizer)
  793. def to_string (self):
  794. if self.contained_value is None:
  795. return self.typename + " [no contained value]"
  796. if hasattr (self.visualizer, 'children'):
  797. return self.typename + " containing " + self.visualizer.to_string ()
  798. return self.typename
  799. class StdExpStringViewPrinter:
  800. "Print a std::experimental::basic_string_view"
  801. def __init__ (self, typename, val):
  802. self.val = val
  803. def to_string (self):
  804. ptr = self.val['_M_str']
  805. len = self.val['_M_len']
  806. if hasattr (ptr, "lazy_string"):
  807. return ptr.lazy_string (length = len)
  808. return ptr.string (length = len)
  809. def display_hint (self):
  810. return 'string'
  811. class StdExpPathPrinter:
  812. "Print a std::experimental::filesystem::path"
  813. def __init__ (self, typename, val):
  814. self.val = val
  815. start = self.val['_M_cmpts']['_M_impl']['_M_start']
  816. finish = self.val['_M_cmpts']['_M_impl']['_M_finish']
  817. self.num_cmpts = int (finish - start)
  818. def _path_type(self):
  819. t = str(self.val['_M_type'])
  820. if t[-9:] == '_Root_dir':
  821. return "root-directory"
  822. if t[-10:] == '_Root_name':
  823. return "root-name"
  824. return None
  825. def to_string (self):
  826. path = "%s" % self.val ['_M_pathname']
  827. if self.num_cmpts == 0:
  828. t = self._path_type()
  829. if t:
  830. path = '%s [%s]' % (path, t)
  831. return "filesystem::path %s" % path
  832. class _iterator(Iterator):
  833. def __init__(self, cmpts):
  834. self.item = cmpts['_M_impl']['_M_start']
  835. self.finish = cmpts['_M_impl']['_M_finish']
  836. self.count = 0
  837. def __iter__(self):
  838. return self
  839. def __next__(self):
  840. if self.item == self.finish:
  841. raise StopIteration
  842. item = self.item.dereference()
  843. count = self.count
  844. self.count = self.count + 1
  845. self.item = self.item + 1
  846. path = item['_M_pathname']
  847. t = StdExpPathPrinter(item.type.name, item)._path_type()
  848. if not t:
  849. t = count
  850. return ('[%s]' % t, path)
  851. def children(self):
  852. return self._iterator(self.val['_M_cmpts'])
  853. # A "regular expression" printer which conforms to the
  854. # "SubPrettyPrinter" protocol from gdb.printing.
  855. class RxPrinter(object):
  856. def __init__(self, name, function):
  857. super(RxPrinter, self).__init__()
  858. self.name = name
  859. self.function = function
  860. self.enabled = True
  861. def invoke(self, value):
  862. if not self.enabled:
  863. return None
  864. if value.type.code == gdb.TYPE_CODE_REF:
  865. if hasattr(gdb.Value,"referenced_value"):
  866. value = value.referenced_value()
  867. return self.function(self.name, value)
  868. # A pretty-printer that conforms to the "PrettyPrinter" protocol from
  869. # gdb.printing. It can also be used directly as an old-style printer.
  870. class Printer(object):
  871. def __init__(self, name):
  872. super(Printer, self).__init__()
  873. self.name = name
  874. self.subprinters = []
  875. self.lookup = {}
  876. self.enabled = True
  877. self.compiled_rx = re.compile('^([a-zA-Z0-9_:]+)(<.*>)?$')
  878. def add(self, name, function):
  879. # A small sanity check.
  880. # FIXME
  881. if not self.compiled_rx.match(name):
  882. raise ValueError('libstdc++ programming error: "%s" does not match' % name)
  883. printer = RxPrinter(name, function)
  884. self.subprinters.append(printer)
  885. self.lookup[name] = printer
  886. # Add a name using _GLIBCXX_BEGIN_NAMESPACE_VERSION.
  887. def add_version(self, base, name, function):
  888. self.add(base + name, function)
  889. self.add(base + '__7::' + name, function)
  890. # Add a name using _GLIBCXX_BEGIN_NAMESPACE_CONTAINER.
  891. def add_container(self, base, name, function):
  892. self.add_version(base, name, function)
  893. self.add_version(base + '__cxx1998::', name, function)
  894. @staticmethod
  895. def get_basic_type(type):
  896. # If it points to a reference, get the reference.
  897. if type.code == gdb.TYPE_CODE_REF:
  898. type = type.target ()
  899. # Get the unqualified type, stripped of typedefs.
  900. type = type.unqualified ().strip_typedefs ()
  901. return type.tag
  902. def __call__(self, val):
  903. typename = self.get_basic_type(val.type)
  904. if not typename:
  905. return None
  906. # All the types we match are template types, so we can use a
  907. # dictionary.
  908. match = self.compiled_rx.match(typename)
  909. if not match:
  910. return None
  911. basename = match.group(1)
  912. if val.type.code == gdb.TYPE_CODE_REF:
  913. if hasattr(gdb.Value,"referenced_value"):
  914. val = val.referenced_value()
  915. if basename in self.lookup:
  916. return self.lookup[basename].invoke(val)
  917. # Cannot find a pretty printer. Return None.
  918. return None
  919. libstdcxx_printer = None
  920. class TemplateTypePrinter(object):
  921. r"""A type printer for class templates.
  922. Recognizes type names that match a regular expression.
  923. Replaces them with a formatted string which can use replacement field
  924. {N} to refer to the \N subgroup of the regex match.
  925. Type printers are recusively applied to the subgroups.
  926. This allows recognizing e.g. "std::vector<(.*), std::allocator<\\1> >"
  927. and replacing it with "std::vector<{1}>", omitting the template argument
  928. that uses the default type.
  929. """
  930. def __init__(self, name, pattern, subst):
  931. self.name = name
  932. self.pattern = re.compile(pattern)
  933. self.subst = subst
  934. self.enabled = True
  935. class _recognizer(object):
  936. def __init__(self, pattern, subst):
  937. self.pattern = pattern
  938. self.subst = subst
  939. self.type_obj = None
  940. def recognize(self, type_obj):
  941. if type_obj.tag is None:
  942. return None
  943. m = self.pattern.match(type_obj.tag)
  944. if m:
  945. subs = list(m.groups())
  946. for i, sub in enumerate(subs):
  947. if ('{%d}' % (i+1)) in self.subst:
  948. # apply recognizers to subgroup
  949. rep = gdb.types.apply_type_recognizers(
  950. gdb.types.get_type_recognizers(),
  951. gdb.lookup_type(sub))
  952. if rep:
  953. subs[i] = rep
  954. subs = [None] + subs
  955. return self.subst.format(*subs)
  956. return None
  957. def instantiate(self):
  958. return self._recognizer(self.pattern, self.subst)
  959. def add_one_template_type_printer(obj, name, match, subst):
  960. printer = TemplateTypePrinter(name, '^std::' + match + '$', 'std::' + subst)
  961. gdb.types.register_type_printer(obj, printer)
  962. class FilteringTypePrinter(object):
  963. def __init__(self, match, name):
  964. self.match = match
  965. self.name = name
  966. self.enabled = True
  967. class _recognizer(object):
  968. def __init__(self, match, name):
  969. self.match = match
  970. self.name = name
  971. self.type_obj = None
  972. def recognize(self, type_obj):
  973. if type_obj.tag is None:
  974. return None
  975. if self.type_obj is None:
  976. if not self.match in type_obj.tag:
  977. # Filter didn't match.
  978. return None
  979. try:
  980. self.type_obj = gdb.lookup_type(self.name).strip_typedefs()
  981. except:
  982. pass
  983. if self.type_obj == type_obj:
  984. return self.name
  985. return None
  986. def instantiate(self):
  987. return self._recognizer(self.match, self.name)
  988. def add_one_type_printer(obj, match, name):
  989. printer = FilteringTypePrinter(match, 'std::' + name)
  990. gdb.types.register_type_printer(obj, printer)
  991. def register_type_printers(obj):
  992. global _use_type_printing
  993. if not _use_type_printing:
  994. return
  995. for pfx in ('', 'w'):
  996. add_one_type_printer(obj, 'basic_string', pfx + 'string')
  997. add_one_type_printer(obj, 'basic_ios', pfx + 'ios')
  998. add_one_type_printer(obj, 'basic_streambuf', pfx + 'streambuf')
  999. add_one_type_printer(obj, 'basic_istream', pfx + 'istream')
  1000. add_one_type_printer(obj, 'basic_ostream', pfx + 'ostream')
  1001. add_one_type_printer(obj, 'basic_iostream', pfx + 'iostream')
  1002. add_one_type_printer(obj, 'basic_stringbuf', pfx + 'stringbuf')
  1003. add_one_type_printer(obj, 'basic_istringstream',
  1004. pfx + 'istringstream')
  1005. add_one_type_printer(obj, 'basic_ostringstream',
  1006. pfx + 'ostringstream')
  1007. add_one_type_printer(obj, 'basic_stringstream',
  1008. pfx + 'stringstream')
  1009. add_one_type_printer(obj, 'basic_filebuf', pfx + 'filebuf')
  1010. add_one_type_printer(obj, 'basic_ifstream', pfx + 'ifstream')
  1011. add_one_type_printer(obj, 'basic_ofstream', pfx + 'ofstream')
  1012. add_one_type_printer(obj, 'basic_fstream', pfx + 'fstream')
  1013. add_one_type_printer(obj, 'basic_regex', pfx + 'regex')
  1014. add_one_type_printer(obj, 'sub_match', pfx + 'csub_match')
  1015. add_one_type_printer(obj, 'sub_match', pfx + 'ssub_match')
  1016. add_one_type_printer(obj, 'match_results', pfx + 'cmatch')
  1017. add_one_type_printer(obj, 'match_results', pfx + 'smatch')
  1018. add_one_type_printer(obj, 'regex_iterator', pfx + 'cregex_iterator')
  1019. add_one_type_printer(obj, 'regex_iterator', pfx + 'sregex_iterator')
  1020. add_one_type_printer(obj, 'regex_token_iterator',
  1021. pfx + 'cregex_token_iterator')
  1022. add_one_type_printer(obj, 'regex_token_iterator',
  1023. pfx + 'sregex_token_iterator')
  1024. # Note that we can't have a printer for std::wstreampos, because
  1025. # it shares the same underlying type as std::streampos.
  1026. add_one_type_printer(obj, 'fpos', 'streampos')
  1027. add_one_type_printer(obj, 'basic_string', 'u16string')
  1028. add_one_type_printer(obj, 'basic_string', 'u32string')
  1029. for dur in ('nanoseconds', 'microseconds', 'milliseconds',
  1030. 'seconds', 'minutes', 'hours'):
  1031. add_one_type_printer(obj, 'duration', dur)
  1032. add_one_type_printer(obj, 'linear_congruential_engine', 'minstd_rand0')
  1033. add_one_type_printer(obj, 'linear_congruential_engine', 'minstd_rand')
  1034. add_one_type_printer(obj, 'mersenne_twister_engine', 'mt19937')
  1035. add_one_type_printer(obj, 'mersenne_twister_engine', 'mt19937_64')
  1036. add_one_type_printer(obj, 'subtract_with_carry_engine', 'ranlux24_base')
  1037. add_one_type_printer(obj, 'subtract_with_carry_engine', 'ranlux48_base')
  1038. add_one_type_printer(obj, 'discard_block_engine', 'ranlux24')
  1039. add_one_type_printer(obj, 'discard_block_engine', 'ranlux48')
  1040. add_one_type_printer(obj, 'shuffle_order_engine', 'knuth_b')
  1041. # Do not show defaulted template arguments in class templates
  1042. add_one_template_type_printer(obj, 'unique_ptr<T>',
  1043. 'unique_ptr<(.*), std::default_delete<\\1 ?> >',
  1044. 'unique_ptr<{1}>')
  1045. add_one_template_type_printer(obj, 'deque<T>',
  1046. 'deque<(.*), std::allocator<\\1 ?> >',
  1047. 'deque<{1}>')
  1048. add_one_template_type_printer(obj, 'forward_list<T>',
  1049. 'forward_list<(.*), std::allocator<\\1 ?> >',
  1050. 'forward_list<{1}>')
  1051. add_one_template_type_printer(obj, 'list<T>',
  1052. 'list<(.*), std::allocator<\\1 ?> >',
  1053. 'list<{1}>')
  1054. add_one_template_type_printer(obj, 'vector<T>',
  1055. 'vector<(.*), std::allocator<\\1 ?> >',
  1056. 'vector<{1}>')
  1057. add_one_template_type_printer(obj, 'map<Key, T>',
  1058. 'map<(.*), (.*), std::less<\\1 ?>, std::allocator<std::pair<\\1 const, \\2 ?> > >',
  1059. 'map<{1}, {2}>')
  1060. add_one_template_type_printer(obj, 'multimap<Key, T>',
  1061. 'multimap<(.*), (.*), std::less<\\1 ?>, std::allocator<std::pair<\\1 const, \\2 ?> > >',
  1062. 'multimap<{1}, {2}>')
  1063. add_one_template_type_printer(obj, 'set<T>',
  1064. 'set<(.*), std::less<\\1 ?>, std::allocator<\\1 ?> >',
  1065. 'set<{1}>')
  1066. add_one_template_type_printer(obj, 'multiset<T>',
  1067. 'multiset<(.*), std::less<\\1 ?>, std::allocator<\\1 ?> >',
  1068. 'multiset<{1}>')
  1069. add_one_template_type_printer(obj, 'unordered_map<Key, T>',
  1070. 'unordered_map<(.*), (.*), std::hash<\\1 ?>, std::equal_to<\\1 ?>, std::allocator<std::pair<\\1 const, \\2 ?> > >',
  1071. 'unordered_map<{1}, {2}>')
  1072. add_one_template_type_printer(obj, 'unordered_multimap<Key, T>',
  1073. 'unordered_multimap<(.*), (.*), std::hash<\\1 ?>, std::equal_to<\\1 ?>, std::allocator<std::pair<\\1 const, \\2 ?> > >',
  1074. 'unordered_multimap<{1}, {2}>')
  1075. add_one_template_type_printer(obj, 'unordered_set<T>',
  1076. 'unordered_set<(.*), std::hash<\\1 ?>, std::equal_to<\\1 ?>, std::allocator<\\1 ?> >',
  1077. 'unordered_set<{1}>')
  1078. add_one_template_type_printer(obj, 'unordered_multiset<T>',
  1079. 'unordered_multiset<(.*), std::hash<\\1 ?>, std::equal_to<\\1 ?>, std::allocator<\\1 ?> >',
  1080. 'unordered_multiset<{1}>')
  1081. # strip the "fundamentals_v1" inline namespace from these types
  1082. add_one_template_type_printer(obj, 'optional<T>',
  1083. 'experimental::fundamentals_v1::optional<(.*)>',
  1084. 'experimental::optional<\\1>')
  1085. add_one_template_type_printer(obj, 'basic_string_view<C>',
  1086. 'experimental::fundamentals_v1::basic_string_view<(.*), std::char_traits<\\1> >',
  1087. 'experimental::basic_string_view<\\1>')
  1088. def register_libstdcxx_printers (obj):
  1089. "Register libstdc++ pretty-printers with objfile Obj."
  1090. global _use_gdb_pp
  1091. global libstdcxx_printer
  1092. if _use_gdb_pp:
  1093. gdb.printing.register_pretty_printer(obj, libstdcxx_printer)
  1094. else:
  1095. if obj is None:
  1096. obj = gdb
  1097. obj.pretty_printers.append(libstdcxx_printer)
  1098. register_type_printers(obj)
  1099. def build_libstdcxx_dictionary ():
  1100. global libstdcxx_printer
  1101. libstdcxx_printer = Printer("libstdc++-v6")
  1102. # For _GLIBCXX_BEGIN_NAMESPACE_VERSION.
  1103. vers = '(__7::)?'
  1104. # For _GLIBCXX_BEGIN_NAMESPACE_CONTAINER.
  1105. container = '(__cxx1998::' + vers + ')?'
  1106. # libstdc++ objects requiring pretty-printing.
  1107. # In order from:
  1108. # http://gcc.gnu.org/onlinedocs/libstdc++/latest-doxygen/a01847.html
  1109. libstdcxx_printer.add_version('std::', 'basic_string', StdStringPrinter)
  1110. libstdcxx_printer.add_version('std::', '__cxx11::basic_string', StdStringPrinter)
  1111. libstdcxx_printer.add_container('std::', 'bitset', StdBitsetPrinter)
  1112. libstdcxx_printer.add_container('std::', 'deque', StdDequePrinter)
  1113. libstdcxx_printer.add_container('std::', 'list', StdListPrinter)
  1114. libstdcxx_printer.add_container('std::', 'map', StdMapPrinter)
  1115. libstdcxx_printer.add_container('std::', 'multimap', StdMapPrinter)
  1116. libstdcxx_printer.add_container('std::', 'multiset', StdSetPrinter)
  1117. libstdcxx_printer.add_version('std::', 'priority_queue',
  1118. StdStackOrQueuePrinter)
  1119. libstdcxx_printer.add_version('std::', 'queue', StdStackOrQueuePrinter)
  1120. libstdcxx_printer.add_version('std::', 'tuple', StdTuplePrinter)
  1121. libstdcxx_printer.add_container('std::', 'set', StdSetPrinter)
  1122. libstdcxx_printer.add_version('std::', 'stack', StdStackOrQueuePrinter)
  1123. libstdcxx_printer.add_version('std::', 'unique_ptr', UniquePointerPrinter)
  1124. libstdcxx_printer.add_container('std::', 'vector', StdVectorPrinter)
  1125. # vector<bool>
  1126. # Printer registrations for classes compiled with -D_GLIBCXX_DEBUG.
  1127. libstdcxx_printer.add('std::__debug::bitset', StdBitsetPrinter)
  1128. libstdcxx_printer.add('std::__debug::deque', StdDequePrinter)
  1129. libstdcxx_printer.add('std::__debug::list', StdListPrinter)
  1130. libstdcxx_printer.add('std::__debug::map', StdMapPrinter)
  1131. libstdcxx_printer.add('std::__debug::multimap', StdMapPrinter)
  1132. libstdcxx_printer.add('std::__debug::multiset', StdSetPrinter)
  1133. libstdcxx_printer.add('std::__debug::priority_queue',
  1134. StdStackOrQueuePrinter)
  1135. libstdcxx_printer.add('std::__debug::queue', StdStackOrQueuePrinter)
  1136. libstdcxx_printer.add('std::__debug::set', StdSetPrinter)
  1137. libstdcxx_printer.add('std::__debug::stack', StdStackOrQueuePrinter)
  1138. libstdcxx_printer.add('std::__debug::unique_ptr', UniquePointerPrinter)
  1139. libstdcxx_printer.add('std::__debug::vector', StdVectorPrinter)
  1140. # These are the TR1 and C++0x printers.
  1141. # For array - the default GDB pretty-printer seems reasonable.
  1142. libstdcxx_printer.add_version('std::', 'shared_ptr', SharedPointerPrinter)
  1143. libstdcxx_printer.add_version('std::', 'weak_ptr', SharedPointerPrinter)
  1144. libstdcxx_printer.add_container('std::', 'unordered_map',
  1145. Tr1UnorderedMapPrinter)
  1146. libstdcxx_printer.add_container('std::', 'unordered_set',
  1147. Tr1UnorderedSetPrinter)
  1148. libstdcxx_printer.add_container('std::', 'unordered_multimap',
  1149. Tr1UnorderedMapPrinter)
  1150. libstdcxx_printer.add_container('std::', 'unordered_multiset',
  1151. Tr1UnorderedSetPrinter)
  1152. libstdcxx_printer.add_container('std::', 'forward_list',
  1153. StdForwardListPrinter)
  1154. libstdcxx_printer.add_version('std::tr1::', 'shared_ptr', SharedPointerPrinter)
  1155. libstdcxx_printer.add_version('std::tr1::', 'weak_ptr', SharedPointerPrinter)
  1156. libstdcxx_printer.add_version('std::tr1::', 'unordered_map',
  1157. Tr1UnorderedMapPrinter)
  1158. libstdcxx_printer.add_version('std::tr1::', 'unordered_set',
  1159. Tr1UnorderedSetPrinter)
  1160. libstdcxx_printer.add_version('std::tr1::', 'unordered_multimap',
  1161. Tr1UnorderedMapPrinter)
  1162. libstdcxx_printer.add_version('std::tr1::', 'unordered_multiset',
  1163. Tr1UnorderedSetPrinter)
  1164. # These are the C++0x printer registrations for -D_GLIBCXX_DEBUG cases.
  1165. # The tr1 namespace printers do not seem to have any debug
  1166. # equivalents, so do no register them.
  1167. libstdcxx_printer.add('std::__debug::unordered_map',
  1168. Tr1UnorderedMapPrinter)
  1169. libstdcxx_printer.add('std::__debug::unordered_set',
  1170. Tr1UnorderedSetPrinter)
  1171. libstdcxx_printer.add('std::__debug::unordered_multimap',
  1172. Tr1UnorderedMapPrinter)
  1173. libstdcxx_printer.add('std::__debug::unordered_multiset',
  1174. Tr1UnorderedSetPrinter)
  1175. libstdcxx_printer.add('std::__debug::forward_list',
  1176. StdForwardListPrinter)
  1177. # Library Fundamentals TS components
  1178. libstdcxx_printer.add_version('std::experimental::fundamentals_v1::',
  1179. 'any', StdExpAnyPrinter)
  1180. libstdcxx_printer.add_version('std::experimental::fundamentals_v1::',
  1181. 'optional', StdExpOptionalPrinter)
  1182. libstdcxx_printer.add_version('std::experimental::fundamentals_v1::',
  1183. 'basic_string_view', StdExpStringViewPrinter)
  1184. # Filesystem TS components
  1185. libstdcxx_printer.add_version('std::experimental::filesystem::v1::',
  1186. 'path', StdExpPathPrinter)
  1187. libstdcxx_printer.add_version('std::experimental::filesystem::v1::__cxx11::',
  1188. 'path', StdExpPathPrinter)
  1189. # Extensions.
  1190. libstdcxx_printer.add_version('__gnu_cxx::', 'slist', StdSlistPrinter)
  1191. if True:
  1192. # These shouldn't be necessary, if GDB "print *i" worked.
  1193. # But it often doesn't, so here they are.
  1194. libstdcxx_printer.add_container('std::', '_List_iterator',
  1195. StdListIteratorPrinter)
  1196. libstdcxx_printer.add_container('std::', '_List_const_iterator',
  1197. StdListIteratorPrinter)
  1198. libstdcxx_printer.add_version('std::', '_Rb_tree_iterator',
  1199. StdRbtreeIteratorPrinter)
  1200. libstdcxx_printer.add_version('std::', '_Rb_tree_const_iterator',
  1201. StdRbtreeIteratorPrinter)
  1202. libstdcxx_printer.add_container('std::', '_Deque_iterator',
  1203. StdDequeIteratorPrinter)
  1204. libstdcxx_printer.add_container('std::', '_Deque_const_iterator',
  1205. StdDequeIteratorPrinter)
  1206. libstdcxx_printer.add_version('__gnu_cxx::', '__normal_iterator',
  1207. StdVectorIteratorPrinter)
  1208. libstdcxx_printer.add_version('__gnu_cxx::', '_Slist_iterator',
  1209. StdSlistIteratorPrinter)
  1210. # Debug (compiled with -D_GLIBCXX_DEBUG) printer
  1211. # registrations. The Rb_tree debug iterator when unwrapped
  1212. # from the encapsulating __gnu_debug::_Safe_iterator does not
  1213. # have the __norm namespace. Just use the existing printer
  1214. # registration for that.
  1215. libstdcxx_printer.add('__gnu_debug::_Safe_iterator',
  1216. StdDebugIteratorPrinter)
  1217. libstdcxx_printer.add('std::__norm::_List_iterator',
  1218. StdListIteratorPrinter)
  1219. libstdcxx_printer.add('std::__norm::_List_const_iterator',
  1220. StdListIteratorPrinter)
  1221. libstdcxx_printer.add('std::__norm::_Deque_const_iterator',
  1222. StdDequeIteratorPrinter)
  1223. libstdcxx_printer.add('std::__norm::_Deque_iterator',
  1224. StdDequeIteratorPrinter)
  1225. build_libstdcxx_dictionary ()