bug 985566 - add some pretty printers to .gdbinit r=froydnj r=glandium
authorTrevor Saunders <trev.saunders@gmail.com>
Wed, 19 Mar 2014 13:53:16 -0400
changeset 300260 c993782dbd5218c72c653b53482daea1be9b4c5c
parent 300259 48034e1448f251b3186567c11c71577772030d3a
child 300261 7f15db5b8c9eea2bac2c57b7c6d938b91753357a
push id19512
push usercbook@mozilla.com
push dateFri, 03 Jun 2016 10:40:46 +0000
treeherderfx-team@0ef7cc6b42c7 [default view] [failures only]
perfherder[talos] [build metrics] [platform microbench] (compared to previous push)
reviewersfroydnj, glandium
bugs985566
milestone49.0a1
bug 985566 - add some pretty printers to .gdbinit r=froydnj r=glandium
.gdbinit
.gdbinit_python
build/.gdbinit_python.in
build/moz.build
python/gdbpp/gdbpp/__init__.py
python/gdbpp/gdbpp/owningthread.py
python/gdbpp/gdbpp/smartptr.py
python/gdbpp/gdbpp/string.py
python/gdbpp/gdbpp/tarray.py
--- a/.gdbinit
+++ b/.gdbinit
@@ -174,8 +174,10 @@ end
 
 def js
   call DumpJSStack()
 end
 
 def ft
   call $arg0->DumpFrameTree()
 end
+
+source .gdbinit_python
new file mode 100644
--- /dev/null
+++ b/.gdbinit_python
@@ -0,0 +1,5 @@
+python
+import sys
+sys.path.append('python/gdbpp/')
+import gdbpp
+end
new file mode 100644
--- /dev/null
+++ b/build/.gdbinit_python.in
@@ -0,0 +1,6 @@
+#filter substitution
+python
+import sys
+sys.path.append('@topsrcdir@/python/gdbpp')
+import gdbpp
+end
--- a/build/moz.build
+++ b/build/moz.build
@@ -55,16 +55,18 @@ if CONFIG['ENABLE_TESTS'] or CONFIG['MOZ
         FINAL_TARGET_FILES += ['/tools/rb/fix_linux_stack.py']
 
 if CONFIG['MOZ_DMD']:
     FINAL_TARGET_FILES += ['/memory/replace/dmd/dmd.py']
 
 # Put a useful .gdbinit in the bin directory, to be picked up automatically
 # by GDB when we debug executables there.
 FINAL_TARGET_FILES += ['/.gdbinit']
+FINAL_TARGET_PP_FILES += ['.gdbinit_python.in']
+OBJDIR_FILES += ['!/dist/bin/.gdbinit_python']
 
 # Install the clang-cl runtime library for ASAN next to the binaries we produce.
 if CONFIG['MOZ_ASAN'] and CONFIG['CLANG_CL']:
     FINAL_TARGET_FILES += ['%' + CONFIG['MOZ_CLANG_RT_ASAN_LIB_PATH']]
 
 if CONFIG['MOZ_APP_BASENAME']:
     FINAL_TARGET_PP_FILES += ['application.ini']
     if CONFIG['MOZ_WIDGET_TOOLKIT'] != 'android' and CONFIG['MOZ_UPDATER']:
new file mode 100644
--- /dev/null
+++ b/python/gdbpp/gdbpp/__init__.py
@@ -0,0 +1,26 @@
+# -*- Mode: python; c-basic-offset: 4; indent-tabs-mode: nil; tab-width: 40 -*-
+# vim: set filetype=python:
+# This Source Code Form is subject to the terms of the Mozilla Public
+# License, v. 2.0. If a copy of the MPL was not distributed with this
+# file, You can obtain one at http://mozilla.org/MPL/2.0/.
+
+import gdb
+import gdb.printing
+
+class GeckoPrettyPrinter(object):
+    pp = gdb.printing.RegexpCollectionPrettyPrinter('GeckoPrettyPrinters')
+
+    def __init__(self, name, regexp):
+        self.name = name
+        self.regexp = regexp
+
+    def __call__(self, wrapped):
+        GeckoPrettyPrinter.pp.add_printer(self.name, self.regexp, wrapped)
+        return wrapped
+
+import gdbpp.owningthread
+import gdbpp.smartptr
+import gdbpp.string
+import gdbpp.tarray
+
+gdb.printing.register_pretty_printer(None, GeckoPrettyPrinter.pp)
new file mode 100644
--- /dev/null
+++ b/python/gdbpp/gdbpp/owningthread.py
@@ -0,0 +1,24 @@
+# -*- Mode: python; c-basic-offset: 4; indent-tabs-mode: nil; tab-width: 40 -*-
+# vim: set filetype=python:
+# This Source Code Form is subject to the terms of the Mozilla Public
+# License, v. 2.0. If a copy of the MPL was not distributed with this
+# file, You can obtain one at http://mozilla.org/MPL/2.0/.
+
+import gdb
+from gdbpp import GeckoPrettyPrinter
+
+@GeckoPrettyPrinter('nsAutoOwningThread', '^nsAutoOwningThread$')
+class owning_thread_printer(object):
+    def __init__(self, value):
+        self.value = value
+
+    def to_string(self):
+        prthread_type = gdb.lookup_type('PRThread').pointer()
+        prthread = self.value['mThread'].cast(prthread_type)
+        name = prthread['name']
+
+        # if the thread doesn't have a name try to get its thread id (might not
+        # work on !linux)
+        name = prthread['tid']
+
+        return name if name else '(PRThread *) %s' % prthread
new file mode 100644
--- /dev/null
+++ b/python/gdbpp/gdbpp/smartptr.py
@@ -0,0 +1,40 @@
+# -*- Mode: python; c-basic-offset: 4; indent-tabs-mode: nil; tab-width: 40 -*-
+# vim: set filetype=python:
+# This Source Code Form is subject to the terms of the Mozilla Public
+# License, v. 2.0. If a copy of the MPL was not distributed with this
+# file, You can obtain one at http://mozilla.org/MPL/2.0/.
+
+import gdb
+from gdbpp import GeckoPrettyPrinter
+
+@GeckoPrettyPrinter('nsWeakPtr', '^nsCOMPtr<nsIWeakReference>$')
+class weak_ptr_printer(object):
+    def __init__(self, value):
+        self.value = value
+
+    def to_string(self):
+        proxy = self.value['mRawPtr']
+        if not proxy:
+            return '[(%s) 0x0]' % proxy.type
+
+        ref_type = proxy.dynamic_type
+        weak_ptr = proxy.cast(ref_type).dereference()['mReferent']
+        if not weak_ptr:
+            return '[(%s) %s]' % (weak_ptr.type, weak_ptr)
+
+        return '[(%s) %s]' % (weak_ptr.dynamic_type, weak_ptr)
+
+@GeckoPrettyPrinter('nsAutoPtr', 'nsAutoPtr<.*>')
+@GeckoPrettyPrinter('nsCOMPtr', 'nsCOMPtr<.*>')
+@GeckoPrettyPrinter('RefPtr', 'RefPtr<.*>')
+class smartptr_printer(object):
+    def __init__(self, value):
+        self.value = value['mRawPtr']
+
+    def to_string(self):
+        if not self.value:
+            type_name = str(self.value.type)
+        else:
+            type_name = str(self.value.dereference().dynamic_type.pointer())
+
+        return '[(%s) %s]' % (type_name, str(self.value))
new file mode 100644
--- /dev/null
+++ b/python/gdbpp/gdbpp/string.py
@@ -0,0 +1,19 @@
+# -*- Mode: python; c-basic-offset: 4; indent-tabs-mode: nil; tab-width: 40 -*-
+# vim: set filetype=python:
+# This Source Code Form is subject to the terms of the Mozilla Public
+# License, v. 2.0. If a copy of the MPL was not distributed with this
+# file, You can obtain one at http://mozilla.org/MPL/2.0/.
+
+import gdb
+from gdbpp import GeckoPrettyPrinter
+
+@GeckoPrettyPrinter('nsString', '^ns.*String$')
+class string_printer(object):
+    def __init__(self, value):
+        self.value = value
+
+    def to_string(self):
+        return self.value['mData']
+
+    def display_hint(self):
+        return 'string'
new file mode 100644
--- /dev/null
+++ b/python/gdbpp/gdbpp/tarray.py
@@ -0,0 +1,27 @@
+# -*- Mode: python; c-basic-offset: 4; indent-tabs-mode: nil; tab-width: 40 -*-
+# vim: set filetype=python:
+# This Source Code Form is subject to the terms of the Mozilla Public
+# License, v. 2.0. If a copy of the MPL was not distributed with this
+# file, You can obtain one at http://mozilla.org/MPL/2.0/.
+
+import gdb
+import itertools
+from gdbpp import GeckoPrettyPrinter
+
+@GeckoPrettyPrinter('TArray', '.*TArray<.*>$')
+class tarray_printer(object):
+    def __init__(self, value):
+        self.value = value
+        self.elem_type = value.type.template_argument(0)
+
+    def children(self):
+        length = self.value['mHdr'].dereference()['mLength']
+        data = self.value['mHdr'] + 1
+        elements = data.cast(self.elem_type.pointer())
+        return (('%d' % i, (elements + i).dereference()) for i in range(0, int(length)))
+
+    def to_string(self):
+        return str(self.value.type)
+
+    def display_hint(self):
+        return 'array'