Debugger: Provider Qt version externally to bridges

Extracting within the bridges is expensive.

Change-Id: Icf69db4b112230cc23e331abc0b3eb0de1323f46
Reviewed-by: <github-actions-qt-creator@cristianadam.eu>
Reviewed-by: Christian Stenger <christian.stenger@qt.io>
Reviewed-by: David Schulz <david.schulz@qt.io>
This commit is contained in:
hjk
2024-04-26 13:48:06 +02:00
parent bee7cdfd1e
commit 6aab6f61b5
9 changed files with 88 additions and 181 deletions

View File

@@ -768,80 +768,7 @@ class Dumper(DumperBase):
symbol = funcs[0].GetSymbol()
self.qtPropertyFunc = symbol.GetStartAddress().GetLoadAddress(self.target)
def fetchQtVersionAndNamespace(self):
for func in self.target.FindFunctions('qVersion'):
name = func.GetSymbol().GetName()
if name == None:
continue
if name.endswith('()'):
name = name[:-2]
if name.count(':') > 2:
continue
qtNamespace = name[:name.find('qVersion')]
self.qtNamespace = lambda: qtNamespace
options = lldb.SBExpressionOptions()
res = self.target.EvaluateExpression(name + '()', options)
if not res.IsValid() or not res.GetType().IsPointerType():
exp = '((const char*())%s)()' % name
res = self.target.EvaluateExpression(exp, options)
if not res.IsValid() or not res.GetType().IsPointerType():
exp = '((const char*())_Z8qVersionv)()'
res = self.target.EvaluateExpression(exp, options)
if not res.IsValid() or not res.GetType().IsPointerType():
continue
version = str(res)
if version.count('.') != 2:
continue
version.replace("'", '"') # Both seem possible
version = version[version.find('"') + 1:version.rfind('"')]
(major, minor, patch) = version.split('.')
qtVersion = 0x10000 * int(major) + 0x100 * int(minor) + int(patch)
self.qtVersion = lambda: qtVersion
return (qtNamespace, qtVersion)
try:
versionValue = self.target.EvaluateExpression('qtHookData[2]').GetNonSyntheticValue()
if versionValue.IsValid():
return ('', versionValue.unsigned)
except:
pass
return ('', self.fallbackQtVersion)
def qtVersionAndNamespace(self):
qtVersionAndNamespace = None
try:
qtVersionAndNamespace = self.fetchQtVersionAndNamespace()
self.report("Detected Qt Version: 0x%0x (namespace='%s')" %
(qtVersionAndNamespace[1], qtVersionAndNamespace[0] or "no namespace"))
except Exception as e:
DumperBase.warn('[lldb] Error detecting Qt version: %s' % e)
try:
self.fetchInternalFunctions()
self.report('Found function QObject::property: 0x%0x' % self.qtPropertyFunc)
self.report('Found function QObject::customEvent: 0x%0x' % self.qtCustomEventFunc)
except Exception as e:
DumperBase.warn('[lldb] Error fetching internal Qt functions: %s' % e)
# Cache version information by overriding this function.
self.qtVersionAndNamespace = lambda: qtVersionAndNamespace
return qtVersionAndNamespace
def qtNamespace(self):
return self.qtVersionAndNamespace()[0]
def qtVersion(self):
return self.qtVersionAndNamespace()[1]
self.fetchInternalFunctions = lambda: None
def handleCommand(self, command):
result = lldb.SBCommandReturnObject()
@@ -1360,6 +1287,9 @@ class Dumper(DumperBase):
self.setVariableFetchingOptions(args)
self.qtLoaded = True # FIXME: Do that elsewhere
# Reset certain caches whenever a step over / into / continue
# happens.
# FIXME: Caches are currently also cleared if currently