summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorhjk <hjk@theqtcompany.com>2016-07-13 14:17:18 +0200
committerhjk <hjk@qt.io>2016-07-13 15:57:37 +0000
commita12420c9954c62401f14ddddbfb309526d25ed84 (patch)
tree2c73b5ef99d8ddf29a085ae2c0b0120b7efb2bfe
parent56d786a49217bf6644c89f56abcd108ef87287a4 (diff)
downloadqt-creator-a12420c9954c62401f14ddddbfb309526d25ed84.tar.gz
Debugger: Improve QMetaObject dumper
Change-Id: I690e95f5f4651331f6b2407636253770a9bb92a0 Reviewed-by: Alexandru Croitor <alexandru.croitor@qt.io> Reviewed-by: hjk <hjk@qt.io>
-rw-r--r--share/qtcreator/debugger/dumper.py196
-rw-r--r--share/qtcreator/debugger/qttypes.py90
2 files changed, 164 insertions, 122 deletions
diff --git a/share/qtcreator/debugger/dumper.py b/share/qtcreator/debugger/dumper.py
index a305dbec7c..bda932b80b 100644
--- a/share/qtcreator/debugger/dumper.py
+++ b/share/qtcreator/debugger/dumper.py
@@ -1409,16 +1409,8 @@ class DumperBase:
# This is called is when a QObject derived class is expanded
def putQObjectGuts(self, qobject, smo):
- intSize = self.intSize()
ptrSize = self.ptrSize()
- # dd = value["d_ptr"]["d"] is just behind the vtable.
dd = self.extractPointer(qobject, offset=ptrSize)
- isQt5 = self.qtVersion() >= 0x50000
-
- extraDataOffset = 5 * ptrSize + 8 if isQt5 else 6 * ptrSize + 8
- extraData = self.extractPointer(dd + extraDataOffset)
- #with SubItem(self, "[extradata]"):
- # self.putValue("0x%x" % toInteger(extraData))
# Parent and children.
try:
@@ -1428,51 +1420,161 @@ class DumperBase:
except:
pass
- with SubItem(self, "[properties]"):
- propertyCount = 0
- usesVector = self.qtVersion() >= 0x50700
+ # dd = value["d_ptr"]["d"] is just behind the vtable.
+ isQt5 = self.qtVersion() >= 0x50000
+ extraDataOffset = 5 * ptrSize + 8 if isQt5 else 6 * ptrSize + 8
+ extraData = self.extractPointer(dd + extraDataOffset)
+ self.putQObjectGutsHelper(extraData, dd, smo)
+
+
+ def putQObjectGutsHelper(self, extraData, dd, smo):
+ intSize = self.intSize()
+ ptrSize = self.ptrSize()
+ data = smo["d"]["data"]
+ #warn("DATA: %s" % data)
+
+ def metaString(offset):
+ ddata = self.extractPointer(data)
+ sd = self.extractPointer(smo["d"]["stringdata"])
+
+ metaObjectVersion = self.extractInt(ddata)
+ if metaObjectVersion >= 7: # Qt 5.
+ byteArrayDataType = self.lookupType(self.qtNamespace() + "QByteArrayData")
+ byteArrayDataSize = byteArrayDataType.sizeof
+ literal = sd + offset * byteArrayDataSize
+ ldata, lsize, lalloc = self.byteArrayDataHelper(literal)
+ return self.extractBlob(ldata, lsize).toString()
+ else: # Qt 4.
+ ldata = sd + offset
+ return self.extractCString(ldata).decode("utf8")
+
+ def walker(base):
+ ptr = toInteger(base)
+ while True:
+ yield self.extractInt(ptr)
+ ptr += intSize
+
+ def put1(name, p):
+ x = p.next()
+ with SubItem(self, name):
+ self.putValue(x)
+ self.putType("uint")
+ self.putNumChild(0)
+ return x
+
+ def put2(name, p):
+ xy = (p.next(), p.next())
+ with SubItem(self, name):
+ self.putValue("%s %s" % xy)
+ self.putType("uint")
+ self.putNumChild(0)
+ return xy[0]
+
+ def putt(name, value):
+ with SubItem(self, name):
+ self.putValue(value)
+ self.putType(" ")
+ self.putNumChild(0)
+
+ with SubItem(self, "[raw]"):
+ self.putEmptyValue()
+ self.putNumChild(1)
if self.isExpanded():
- propertyNames = self.staticQObjectPropertyNames(smo)
- propertyCount = len(propertyNames) # Doesn't include dynamic properties.
+ self.put('sortable="0"')
+ p = walker(data)
+
with Children(self):
- # Static properties.
- for i in range(propertyCount):
- name = propertyNames[i]
- self.putCallItem(str(name), qobject, "property", '"' + name + '"')
-
- # Dynamic properties.
- if extraData:
- byteArrayType = self.lookupQtType("QByteArray")
- variantType = self.lookupQtType("QVariant")
- names = self.listChildrenGenerator(extraData + ptrSize, byteArrayType)
- if usesVector:
- values = self.vectorChildrenGenerator(extraData + 2 * ptrSize, variantType)
- else:
- values = self.listChildrenGenerator(extraData + 2 * ptrSize, variantType)
- for (k, v) in zip(names, values):
- with SubItem(self, propertyCount):
- self.put('key="%s",' % self.encodeByteArray(k))
- self.put('keyencoded="latin1",')
- self.putItem(v)
- propertyCount += 1
- self.putItemCount(propertyCount)
- else:
- # We need a handle to [x] for the user to expand the item
- # before we know whether there are actual children. Counting
- # them is too expensive.
- self.putNumChild(1)
- self.putSpecialValue("minimumitemcount", 0)
+ put1("revision", p)
+ put1("classname", p)
+ put2("classinfo", p)
+ methodCount = put2("methods", p)
+ put2("properties", p)
+ put2("enums/sets", p)
+ put2("constructors", p)
+ put1("flags", p)
+ signalCount = put1("signalCount", p)
+
+ if extraData:
+ with SubItem(self, "[extraData]"):
+ self.putValue("0x%x" % toInteger(extraData))
+ self.putType("void *")
+ self.putNumChild(0)
+
+ with SubItem(self, "[properties]"):
+ propertyCount = 0
+ usesVector = self.qtVersion() >= 0x50700
+ if self.isExpanded():
+ propertyNames = self.staticQObjectPropertyNames(smo)
+ propertyCount = len(propertyNames) # Doesn't include dynamic properties.
+ with Children(self):
+ # Static properties.
+ for i in range(propertyCount):
+ name = propertyNames[i]
+ self.putCallItem(str(name), qobject, "property", '"' + name + '"')
+
+ # Dynamic properties.
+ if extraData:
+ byteArrayType = self.lookupQtType("QByteArray")
+ variantType = self.lookupQtType("QVariant")
+ names = self.listChildrenGenerator(extraData + ptrSize, byteArrayType)
+ if usesVector:
+ values = self.vectorChildrenGenerator(extraData + 2 * ptrSize, variantType)
+ else:
+ values = self.listChildrenGenerator(extraData + 2 * ptrSize, variantType)
+ for (k, v) in zip(names, values):
+ with SubItem(self, propertyCount):
+ self.put('key="%s",' % self.encodeByteArray(k))
+ self.put('keyencoded="latin1",')
+ self.putItem(v)
+ propertyCount += 1
+ self.putItemCount(propertyCount)
+ else:
+ # We need a handle to [x] for the user to expand the item
+ # before we know whether there are actual children. Counting
+ # them is too expensive.
+ self.putNumChild(1)
+ self.putSpecialValue("minimumitemcount", 0)
+
+ #with SubItem(self, "[methods]"):
+ # methodCount = self.staticQObjectMethodCount(smo)
+ # self.putItemCount(methodCount)
+ # if self.isExpanded():
+ # methodNames = self.staticQObjectMethodNames(smo)
+ # with Children(self):
+ # for i in range(methodCount):
+ # k = methodNames[i]
+ # with SubItem(self, k):
+ # self.putEmptyValue()
+ #
with SubItem(self, "[methods]"):
methodCount = self.staticQObjectMethodCount(smo)
self.putItemCount(methodCount)
if self.isExpanded():
- methodNames = self.staticQObjectMethodNames(smo)
with Children(self):
+ p = walker(toInteger(data) + 14 * 4)
for i in range(methodCount):
- k = methodNames[i]
- with SubItem(self, k):
- self.putEmptyValue()
+ t = (p.next(), p.next(), p.next(), p.next(), p.next())
+ name = metaString(t[0])
+ with SubItem(self, "[%s]" % i):
+ self.putValue(name)
+ self.putType(" ")
+ self.putNumChild(1)
+ with Children(self):
+ putt("name", name)
+ putt("nameindex", t[0])
+ flags = t[4]
+ if flags == 0x06:
+ putt("type", "signal")
+ elif flags == 0x0a:
+ putt("type", "slot")
+ elif flags == 0x0a:
+ putt("type", "invokable")
+ putt("argc", t[1])
+ putt("parameter", t[2])
+ putt("tag", t[3])
+ putt("flags", t[4])
+
with SubItem(self, "[signals]"):
signalCount = self.staticQObjectSignalCount(smo)
@@ -1485,16 +1587,16 @@ class DumperBase:
k = signalNames[i]
with SubItem(self, k):
self.putEmptyValue()
- self.putQObjectConnections(qobject)
+ if dd:
+ self.putQObjectConnections(dd)
- def putQObjectConnections(self, qobject):
+ def putQObjectConnections(self, dd):
with SubItem(self, "[connections]"):
ptrSize = self.ptrSize()
self.putNoType()
ns = self.qtNamespace()
privateTypeName = ns + "QObjectPrivate"
privateType = self.lookupType(privateTypeName)
- dd = qobject["d_ptr"]["d"]
d_ptr = dd.cast(privateType.pointer()).dereference()
connections = d_ptr["connectionLists"]
if self.isNull(connections):
diff --git a/share/qtcreator/debugger/qttypes.py b/share/qtcreator/debugger/qttypes.py
index bc112de7fb..4e50a191c5 100644
--- a/share/qtcreator/debugger/qttypes.py
+++ b/share/qtcreator/debugger/qttypes.py
@@ -1121,82 +1121,22 @@ def qdump__QMetaObject(d, value):
dd = value["d"]
d.putSubItem("d", dd)
data = d.extractPointer(dd["data"])
-
- propertyNames = d.staticQObjectPropertyNames(value)
- propertyIndex = 0
- for propertyName in propertyNames:
- with SubItem(d, "property_%s" % propertyIndex):
- d.putValue(propertyName)
- propertyIndex += 1
-
- #byteArrayDataType = d.lookupType(d.qtNamespace() + "QByteArrayData")
- #byteArrayDataSize = byteArrayDataType.sizeof
- #sd = d.extractPointer(dd["stringdata"])
- #stringdata, size, alloc = d.byteArrayDataHelper(sd)
-
- #propertyCount = d.extractInt(data + 24)
- #propertyData = d.extractInt(data + 28)
-
- ## This is the 'data' member in the qt_meta_stringdata_qobject__*_t struct
- #d.putIntItem("_byteArrayDataSize", byteArrayDataSize)
- #d.putAddressItem("_data", data)
- #d.putAddressItem("_sd_", stringdata)
- #with SubItem(d, "_sd"):
- # d.putValue(d.readMemory(stringdata, size), "latin1")
- #with SubItem(d, "_cn"):
- # d.putValue(d.readMemory(stringdata + d.extractInt(data + 4), size), "latin1")
-
- #for i in range(propertyCount):
- # with SubItem(d, "property_%s" % i):
- # x = data + (propertyData + 3 * i) * 4
- # literal = sd + d.extractInt(x) * byteArrayDataSize
- # ldata, lsize, lalloc = d.byteArrayDataHelper(literal)
- # d.putValue(d.readMemory(ldata, lsize), "latin1")
-
- # d.putNumChild(1)
- # if d.isExpanded():
- # with Children(d):
- # if d.isExpanded():
- # d.putAddressItem("_literal", literal)
- # d.putIntItem("__data", ldata)
- # d.putIntItem("__size", lsize)
- # d.putIntItem("__alloc", lalloc)
- # d.putIntItem("name", d.extractInt(x))
- # d.putIntItem("type", d.extractInt(x + 4))
- # d.putIntItem("flags", d.extractInt(x + 8))
-
- methodCount = d.extractInt(data + 16)
- methodData = d.extractInt(data + 20)
- for i in range(methodCount):
- with SubItem(d, "method_%s" % i):
- x = data + (methodData + 5 * i) * 4
- #d.putEmptyValue()
- d.putValue(d.readCString(stringdata + d.extractInt(x)))
- d.putNumChild(1)
- if d.isExpanded():
- with Children(d):
- if d.isExpanded():
- d.putIntItem("name", d.extractInt(x))
- d.putIntItem("argc", d.extractInt(x + 4))
- d.putIntItem("argv", d.extractInt(x + 8))
- d.putIntItem("type", d.extractInt(x + 12))
- d.putIntItem("flags", d.extractInt(x + 16))
-
+ d.putQObjectGutsHelper(0, 0, value)
d.putSubItem("stringData", dd["stringdata"])
- d.putIntItem("revision", d.extractInt(data))
- d.putIntItem("className", d.extractInt(data + 4))
- d.putIntItem("classInfoCount", d.extractInt(data + 8))
- d.putIntItem("className", d.extractInt(data + 12))
- d.putIntItem("methodCount", d.extractInt(data + 16))
- d.putIntItem("methodData", d.extractInt(data + 20))
- d.putIntItem("propertyCount", d.extractInt(data + 24))
- d.putIntItem("propertyData", d.extractInt(data + 28))
- d.putIntItem("enumeratorCount", d.extractInt(data + 32))
- d.putIntItem("enumeratorData", d.extractInt(data + 36))
- d.putIntItem("constructorCount", d.extractInt(data + 40))
- d.putIntItem("constructorData", d.extractInt(data + 44))
- d.putIntItem("flags", d.extractInt(data + 48))
- d.putIntItem("signalCount", d.extractInt(data + 52))
+ #d.putIntItem("revision", d.extractInt(data))
+ #d.putIntItem("className", d.extractInt(data + 4))
+ #d.putIntItem("classInfoCount", d.extractInt(data + 8))
+ #d.putIntItem("className", d.extractInt(data + 12))
+ #d.putIntItem("methodCount", d.extractInt(data + 16))
+ #d.putIntItem("methodData", d.extractInt(data + 20))
+ #d.putIntItem("propertyCount", d.extractInt(data + 24))
+ #d.putIntItem("propertyData", d.extractInt(data + 28))
+ #d.putIntItem("enumeratorCount", d.extractInt(data + 32))
+ #d.putIntItem("enumeratorData", d.extractInt(data + 36))
+ #d.putIntItem("constructorCount", d.extractInt(data + 40))
+ #d.putIntItem("constructorData", d.extractInt(data + 44))
+ #d.putIntItem("flags", d.extractInt(data + 48))
+ #d.putIntItem("signalCount", d.extractInt(data + 52))
def _qdump__QObject(d, value):
d.putQObjectNameValue(value)