From b5284a5b31ac1aae1f30514fd5cee049d5b16414 Mon Sep 17 00:00:00 2001 From: Trevor Saunders Date: Wed, 19 Mar 2014 13:53:16 -0400 Subject: [PATCH] bug 985566 - add some pretty printers to .gdbinit r=froydnj r=glandium --- .gdbinit | 2 ++ .gdbinit_python | 5 ++++ build/.gdbinit_python.in | 6 +++++ build/moz.build | 2 ++ python/gdbpp/gdbpp/__init__.py | 26 +++++++++++++++++++ python/gdbpp/gdbpp/owningthread.py | 24 ++++++++++++++++++ python/gdbpp/gdbpp/smartptr.py | 40 ++++++++++++++++++++++++++++++ python/gdbpp/gdbpp/string.py | 19 ++++++++++++++ python/gdbpp/gdbpp/tarray.py | 27 ++++++++++++++++++++ 9 files changed, 151 insertions(+) create mode 100644 .gdbinit_python create mode 100644 build/.gdbinit_python.in create mode 100644 python/gdbpp/gdbpp/__init__.py create mode 100644 python/gdbpp/gdbpp/owningthread.py create mode 100644 python/gdbpp/gdbpp/smartptr.py create mode 100644 python/gdbpp/gdbpp/string.py create mode 100644 python/gdbpp/gdbpp/tarray.py diff --git a/.gdbinit b/.gdbinit index 698b3bc622421..2f2dba9b46834 100644 --- a/.gdbinit +++ b/.gdbinit @@ -179,3 +179,5 @@ end def ft call $arg0->DumpFrameTree() end + +source .gdbinit_python diff --git a/.gdbinit_python b/.gdbinit_python new file mode 100644 index 0000000000000..9ad12bd2ac630 --- /dev/null +++ b/.gdbinit_python @@ -0,0 +1,5 @@ +python +import sys +sys.path.append('python/gdbpp/') +import gdbpp +end diff --git a/build/.gdbinit_python.in b/build/.gdbinit_python.in new file mode 100644 index 0000000000000..54c5c2db8d703 --- /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 diff --git a/build/moz.build b/build/moz.build index 13bf0a3ca6b59..3917186514b60 100644 --- a/build/moz.build +++ b/build/moz.build @@ -60,6 +60,8 @@ if CONFIG['MOZ_DMD']: # 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']: diff --git a/python/gdbpp/gdbpp/__init__.py b/python/gdbpp/gdbpp/__init__.py new file mode 100644 index 0000000000000..456cfefafad83 --- /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) diff --git a/python/gdbpp/gdbpp/owningthread.py b/python/gdbpp/gdbpp/owningthread.py new file mode 100644 index 0000000000000..c1a97e0aca392 --- /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 diff --git a/python/gdbpp/gdbpp/smartptr.py b/python/gdbpp/gdbpp/smartptr.py new file mode 100644 index 0000000000000..2352c913a6c61 --- /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$') +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)) diff --git a/python/gdbpp/gdbpp/string.py b/python/gdbpp/gdbpp/string.py new file mode 100644 index 0000000000000..aed21171b8185 --- /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' diff --git a/python/gdbpp/gdbpp/tarray.py b/python/gdbpp/gdbpp/tarray.py new file mode 100644 index 0000000000000..a894f93681121 --- /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'