Debugger: Import GDB pretty printers for new objfiles

Previously, if enabled in the configuration, system
GDB pretty printers were loaded only once for all
objfiles present at the point in time when the loading
happened, which meant that GDB pretty printers for
objfiles loaded later were not taken into account
and thus unavailable if they were defined in the
corresponding autoload scripts for the objfiles.

In order to make use of those as well, remember whether
loading of system GDB pretty printer is enabled, and if so,
evaluate the pretty printers set at the new objfiles
in the handler for GDB's new_objfile event.

Extract the functionality for handling one objfile's
pretty_printers to a separate function
'importPlainDumpersForObj' to avoid code duplication.

Note: For this to actually work, it is required that the
objfile passed to the registered GDB new_objfile handler
actually has the pretty printers set at this stage.
This was only recently implemented on GDB side, in
GDB commit 2c473def12b08100e6b56261f01112db7f6aeab5
("gdb: do autoload before notifying Python side in
new_objfile event", 2021-04-27, [1]).
Therefore, this currently only works with the current
development version of GDB built from its git master
branch, not with any already released GDB versions.
(When older GDB versions are used, this will just behave
as it used to, and the corresponding GDB pretty-printers
will not be used.)

[1] https://sourceware.org/git/?p=binutils-gdb.git;a=commitdiff;h=2c473def12b08100e6b56261f01112db7f6aeab5

Fixes: QTCREATORBUG-25339
Change-Id: Ibc0ab16fbb75184fa199c0709bfc73954f04c193
Reviewed-by: hjk <hjk@qt.io>
This commit is contained in:
Michael Weghorn
2021-05-04 15:01:15 +02:00
parent 23fb4449f1
commit fd9ca07a11

View File

@@ -177,12 +177,14 @@ class PlainDumper():
def importPlainDumpers(args):
if args == 'off':
theDumper.usePlainDumpers = False
try:
gdb.execute('disable pretty-printer .* .*')
except:
# Might occur in non-ASCII directories
DumperBase.warn('COULD NOT DISABLE PRETTY PRINTERS')
else:
theDumper.usePlainDumpers = True
theDumper.importPlainDumpers()
@@ -219,6 +221,9 @@ class Dumper(DumperBase):
def __init__(self):
DumperBase.__init__(self)
# whether to load plain dumpers for objfiles
self.usePlainDumpers = False
# These values will be kept between calls to 'fetchVariables'.
self.isGdb = True
self.typeCache = {}
@@ -1033,11 +1038,14 @@ class Dumper(DumperBase):
self.qqDumpers[name] = PlainDumper(printer)
self.qqFormats[name] = ''
def importPlainDumpersForObj(self, obj):
for printers in obj.pretty_printers + gdb.pretty_printers:
for printer in printers.subprinters:
self.importPlainDumper(printer)
def importPlainDumpers(self):
for obj in gdb.objfiles():
for printers in obj.pretty_printers + gdb.pretty_printers:
for printer in printers.subprinters:
self.importPlainDumper(printer)
self.importPlainDumpersForObj(obj)
def qtNamespace(self):
# This function is replaced by handleQtCoreLoaded()
@@ -1060,6 +1068,9 @@ class Dumper(DumperBase):
self.addDebugLibs(objfile)
self.handleQtCoreLoaded(objfile)
if self.usePlainDumpers:
self.importPlainDumpersForObj(objfile)
def addDebugLibs(self, objfile):
# The directory where separate debug symbols are searched for
# is "/usr/lib/debug".