diff options
author | hjk <hjk@theqtcompany.com> | 2016-07-13 14:17:18 +0200 |
---|---|---|
committer | hjk <hjk@qt.io> | 2016-07-13 15:57:37 +0000 |
commit | a12420c9954c62401f14ddddbfb309526d25ed84 (patch) | |
tree | 2c73b5ef99d8ddf29a085ae2c0b0120b7efb2bfe | |
parent | 56d786a49217bf6644c89f56abcd108ef87287a4 (diff) | |
download | qt-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.py | 196 | ||||
-rw-r--r-- | share/qtcreator/debugger/qttypes.py | 90 |
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) |