Commit dbc474ef authored by hjk's avatar hjk

Debugger: Speed up Qt namespace extraction with GDB

Change-Id: Ic2a1296828d5aceb6c0aae0edbd165e3d0e86741
Reviewed-by: default avatarhjk <hjk121@nokiamail.com>
parent 712d6df4
......@@ -409,11 +409,13 @@ class Dumper(DumperBase):
self.useDynamicType = "dyntype" in options
self.useFancy = "fancy" in options
self.forceQtNamespace = "forcens" in options
self.passExceptions = "pe" in options
#self.passExceptions = True
self.autoDerefPointers = "autoderef" in options
self.partialUpdate = "partial" in options
self.tooltipOnly = "tooltiponly" in options
self.fallbackQtVersion = 0x50200
#warn("NAMESPACE: '%s'" % self.qtNamespace())
#warn("VARIABLES: %s" % varList)
#warn("EXPANDED INAMES: %s" % self.expandedINames)
......@@ -495,6 +497,9 @@ class Dumper(DumperBase):
self.output.append(']')
self.typesToReport = {}
if "forcens" in options:
self.qtNamepaceToRport = self.qtNamespace()
if self.qtNamespaceToReport:
self.output.append(',qtnamespace="%s"' % self.qtNamespaceToReport)
self.qtNamespaceToReport = None
......@@ -912,14 +917,8 @@ class Dumper(DumperBase):
(major, minor, patch) = version[version.find('"')+1:version.rfind('"')].split('.')
self.cachedQtVersion = 0x10000 * int(major) + 0x100 * int(minor) + int(patch)
except:
try:
# This will fail on Qt 5
gdb.execute("ptype QString::shared_null", to_string=True)
return 0x040800
except:
#self.cachedQtVersion = 0x050000
# Assume Qt 5.3 until we have a definitive answer.
return 0x050300
# Use fallback until we have a better answer.
return self.fallbackQtVersion
# Memoize good results.
self.qtVersion = lambda: self.cachedQtVersion
......@@ -1546,29 +1545,32 @@ class Dumper(DumperBase):
self.importPlainDumper(printer)
def qtNamespace(self):
# FIXME: This only works when call from inside a Qt function frame.
namespace = ""
# This only works when called from a valid frame.
try:
cand = "QArrayData::shared_null"
symbol = gdb.lookup_symbol(cand)[0]
if symbol:
ns = symbol.name[:-len(cand)]
self.qtNamespaceToReport = ns
self.qtNamespace = lambda: ns
return ns
except:
pass
try:
out = gdb.execute("ptype QString::Null", to_string=True)
# The result looks like:
# "type = const struct myns::QString::Null {"
# " <no data fields>"
# "}"
pos1 = out.find("struct") + 7
pos2 = out.find("QString::Null")
if pos1 > -1 and pos2 > -1:
namespace = out[pos1:pos2]
# Doesn't work
#gdb.write('=qt-namespace-detected,ns="%s"' % namespace)
self.qtNamespaceToReport = namespace
self.cachedQtNamespace = namespace
self.qtNamespace = lambda: self.cachedQtNamespace
# This is Qt, but not 5.x.
cand = "QByteArray::shared_null"
symbol = gdb.lookup_symbol(cand)[0]
if symbol:
ns = symbol.name[:-len(cand)]
self.qtNamespaceToReport = ns
self.qtNamespace = lambda: ns
self.fallbackQtVersion = 0x40800
return ns
except:
pass
return namespace
return ""
def bbedit(self, args):
(typeName, expr, data) = args.split(',')
......
......@@ -1081,8 +1081,7 @@ void tst_Dumpers::dumper()
"python sys.path.append('" + uninstalledData + "')\n"
"python from gdbbridge import *\n"
"run " + nograb + "\n"
"python print('@%sS@%s@' % ('N', theDumper.qtNamespace()))\n"
"bb options:fancy,autoderef,dyntype,pe vars: expanded:" + expanded + " typeformats:\n";
"bb options:fancy,forcens,autoderef,dyntype,pe vars: expanded:" + expanded + " typeformats:\n";
cmds += "quit\n";
......@@ -1150,20 +1149,14 @@ void tst_Dumpers::dumper()
if (m_debuggerEngine == GdbEngine) {
int posDataStart = output.indexOf("data=");
QVERIFY(posDataStart != -1);
int posDataEnd = output.indexOf(",typeinfo", posDataStart);
QVERIFY(posDataEnd != -1);
contents = output.mid(posDataStart, posDataEnd - posDataStart);
contents = output.mid(posDataStart);
contents.replace("\\\"", "\"");
int posNameSpaceStart = output.indexOf("@NS@");
QVERIFY(posNameSpaceStart != -1);
posNameSpaceStart += sizeof("@NS@") - 1;
int posNameSpaceEnd = output.indexOf("@", posNameSpaceStart);
QVERIFY(posNameSpaceEnd != -1);
context.nameSpace = output.mid(posNameSpaceStart, posNameSpaceEnd - posNameSpaceStart);
GdbMi actualx;
actualx.fromStringMultiple(contents);
context.nameSpace = actualx["qtnamespace"].data();
//qDebug() << "FOUND NS: " << context.nameSpace;
if (context.nameSpace == "::")
context.nameSpace.clear();
contents.replace("\\\"", "\"");
} else if (m_debuggerEngine == LldbEngine) {
//qDebug() << "GOT OUTPUT: " << output;
int pos = output.indexOf("data=[{");
......@@ -1198,6 +1191,7 @@ void tst_Dumpers::dumper()
GdbMi actual;
actual.fromString(contents);
WatchData local;
local.iname = "local";
......
Markdown is supported
0% or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment