forked from qt-creator/qt-creator
Debugger: Improve QMetaObject dumper
Change-Id: I690e95f5f4651331f6b2407636253770a9bb92a0 Reviewed-by: Alexandru Croitor <alexandru.croitor@qt.io> Reviewed-by: hjk <hjk@qt.io>
This commit is contained in:
@@ -1409,16 +1409,8 @@ class DumperBase:
|
|||||||
|
|
||||||
# This is called is when a QObject derived class is expanded
|
# This is called is when a QObject derived class is expanded
|
||||||
def putQObjectGuts(self, qobject, smo):
|
def putQObjectGuts(self, qobject, smo):
|
||||||
intSize = self.intSize()
|
|
||||||
ptrSize = self.ptrSize()
|
ptrSize = self.ptrSize()
|
||||||
# dd = value["d_ptr"]["d"] is just behind the vtable.
|
|
||||||
dd = self.extractPointer(qobject, offset=ptrSize)
|
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.
|
# Parent and children.
|
||||||
try:
|
try:
|
||||||
@@ -1428,51 +1420,161 @@ class DumperBase:
|
|||||||
except:
|
except:
|
||||||
pass
|
pass
|
||||||
|
|
||||||
with SubItem(self, "[properties]"):
|
# dd = value["d_ptr"]["d"] is just behind the vtable.
|
||||||
propertyCount = 0
|
isQt5 = self.qtVersion() >= 0x50000
|
||||||
usesVector = self.qtVersion() >= 0x50700
|
extraDataOffset = 5 * ptrSize + 8 if isQt5 else 6 * ptrSize + 8
|
||||||
if self.isExpanded():
|
extraData = self.extractPointer(dd + extraDataOffset)
|
||||||
propertyNames = self.staticQObjectPropertyNames(smo)
|
self.putQObjectGutsHelper(extraData, dd, 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:
|
def putQObjectGutsHelper(self, extraData, dd, smo):
|
||||||
byteArrayType = self.lookupQtType("QByteArray")
|
intSize = self.intSize()
|
||||||
variantType = self.lookupQtType("QVariant")
|
ptrSize = self.ptrSize()
|
||||||
names = self.listChildrenGenerator(extraData + ptrSize, byteArrayType)
|
data = smo["d"]["data"]
|
||||||
if usesVector:
|
#warn("DATA: %s" % data)
|
||||||
values = self.vectorChildrenGenerator(extraData + 2 * ptrSize, variantType)
|
|
||||||
else:
|
def metaString(offset):
|
||||||
values = self.listChildrenGenerator(extraData + 2 * ptrSize, variantType)
|
ddata = self.extractPointer(data)
|
||||||
for (k, v) in zip(names, values):
|
sd = self.extractPointer(smo["d"]["stringdata"])
|
||||||
with SubItem(self, propertyCount):
|
|
||||||
self.put('key="%s",' % self.encodeByteArray(k))
|
metaObjectVersion = self.extractInt(ddata)
|
||||||
self.put('keyencoded="latin1",')
|
if metaObjectVersion >= 7: # Qt 5.
|
||||||
self.putItem(v)
|
byteArrayDataType = self.lookupType(self.qtNamespace() + "QByteArrayData")
|
||||||
propertyCount += 1
|
byteArrayDataSize = byteArrayDataType.sizeof
|
||||||
self.putItemCount(propertyCount)
|
literal = sd + offset * byteArrayDataSize
|
||||||
else:
|
ldata, lsize, lalloc = self.byteArrayDataHelper(literal)
|
||||||
# We need a handle to [x] for the user to expand the item
|
return self.extractBlob(ldata, lsize).toString()
|
||||||
# before we know whether there are actual children. Counting
|
else: # Qt 4.
|
||||||
# them is too expensive.
|
ldata = sd + offset
|
||||||
self.putNumChild(1)
|
return self.extractCString(ldata).decode("utf8")
|
||||||
self.putSpecialValue("minimumitemcount", 0)
|
|
||||||
|
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():
|
||||||
|
self.put('sortable="0"')
|
||||||
|
p = walker(data)
|
||||||
|
|
||||||
|
with Children(self):
|
||||||
|
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]"):
|
with SubItem(self, "[methods]"):
|
||||||
methodCount = self.staticQObjectMethodCount(smo)
|
methodCount = self.staticQObjectMethodCount(smo)
|
||||||
self.putItemCount(methodCount)
|
self.putItemCount(methodCount)
|
||||||
if self.isExpanded():
|
if self.isExpanded():
|
||||||
methodNames = self.staticQObjectMethodNames(smo)
|
|
||||||
with Children(self):
|
with Children(self):
|
||||||
|
p = walker(toInteger(data) + 14 * 4)
|
||||||
for i in range(methodCount):
|
for i in range(methodCount):
|
||||||
k = methodNames[i]
|
t = (p.next(), p.next(), p.next(), p.next(), p.next())
|
||||||
with SubItem(self, k):
|
name = metaString(t[0])
|
||||||
self.putEmptyValue()
|
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]"):
|
with SubItem(self, "[signals]"):
|
||||||
signalCount = self.staticQObjectSignalCount(smo)
|
signalCount = self.staticQObjectSignalCount(smo)
|
||||||
@@ -1485,16 +1587,16 @@ class DumperBase:
|
|||||||
k = signalNames[i]
|
k = signalNames[i]
|
||||||
with SubItem(self, k):
|
with SubItem(self, k):
|
||||||
self.putEmptyValue()
|
self.putEmptyValue()
|
||||||
self.putQObjectConnections(qobject)
|
if dd:
|
||||||
|
self.putQObjectConnections(dd)
|
||||||
|
|
||||||
def putQObjectConnections(self, qobject):
|
def putQObjectConnections(self, dd):
|
||||||
with SubItem(self, "[connections]"):
|
with SubItem(self, "[connections]"):
|
||||||
ptrSize = self.ptrSize()
|
ptrSize = self.ptrSize()
|
||||||
self.putNoType()
|
self.putNoType()
|
||||||
ns = self.qtNamespace()
|
ns = self.qtNamespace()
|
||||||
privateTypeName = ns + "QObjectPrivate"
|
privateTypeName = ns + "QObjectPrivate"
|
||||||
privateType = self.lookupType(privateTypeName)
|
privateType = self.lookupType(privateTypeName)
|
||||||
dd = qobject["d_ptr"]["d"]
|
|
||||||
d_ptr = dd.cast(privateType.pointer()).dereference()
|
d_ptr = dd.cast(privateType.pointer()).dereference()
|
||||||
connections = d_ptr["connectionLists"]
|
connections = d_ptr["connectionLists"]
|
||||||
if self.isNull(connections):
|
if self.isNull(connections):
|
||||||
|
@@ -1121,82 +1121,22 @@ def qdump__QMetaObject(d, value):
|
|||||||
dd = value["d"]
|
dd = value["d"]
|
||||||
d.putSubItem("d", dd)
|
d.putSubItem("d", dd)
|
||||||
data = d.extractPointer(dd["data"])
|
data = d.extractPointer(dd["data"])
|
||||||
|
d.putQObjectGutsHelper(0, 0, value)
|
||||||
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.putSubItem("stringData", dd["stringdata"])
|
d.putSubItem("stringData", dd["stringdata"])
|
||||||
d.putIntItem("revision", d.extractInt(data))
|
#d.putIntItem("revision", d.extractInt(data))
|
||||||
d.putIntItem("className", d.extractInt(data + 4))
|
#d.putIntItem("className", d.extractInt(data + 4))
|
||||||
d.putIntItem("classInfoCount", d.extractInt(data + 8))
|
#d.putIntItem("classInfoCount", d.extractInt(data + 8))
|
||||||
d.putIntItem("className", d.extractInt(data + 12))
|
#d.putIntItem("className", d.extractInt(data + 12))
|
||||||
d.putIntItem("methodCount", d.extractInt(data + 16))
|
#d.putIntItem("methodCount", d.extractInt(data + 16))
|
||||||
d.putIntItem("methodData", d.extractInt(data + 20))
|
#d.putIntItem("methodData", d.extractInt(data + 20))
|
||||||
d.putIntItem("propertyCount", d.extractInt(data + 24))
|
#d.putIntItem("propertyCount", d.extractInt(data + 24))
|
||||||
d.putIntItem("propertyData", d.extractInt(data + 28))
|
#d.putIntItem("propertyData", d.extractInt(data + 28))
|
||||||
d.putIntItem("enumeratorCount", d.extractInt(data + 32))
|
#d.putIntItem("enumeratorCount", d.extractInt(data + 32))
|
||||||
d.putIntItem("enumeratorData", d.extractInt(data + 36))
|
#d.putIntItem("enumeratorData", d.extractInt(data + 36))
|
||||||
d.putIntItem("constructorCount", d.extractInt(data + 40))
|
#d.putIntItem("constructorCount", d.extractInt(data + 40))
|
||||||
d.putIntItem("constructorData", d.extractInt(data + 44))
|
#d.putIntItem("constructorData", d.extractInt(data + 44))
|
||||||
d.putIntItem("flags", d.extractInt(data + 48))
|
#d.putIntItem("flags", d.extractInt(data + 48))
|
||||||
d.putIntItem("signalCount", d.extractInt(data + 52))
|
#d.putIntItem("signalCount", d.extractInt(data + 52))
|
||||||
|
|
||||||
def _qdump__QObject(d, value):
|
def _qdump__QObject(d, value):
|
||||||
d.putQObjectNameValue(value)
|
d.putQObjectNameValue(value)
|
||||||
|
Reference in New Issue
Block a user