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
|
||||
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
|
||||
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 + '"')
|
||||
# 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)
|
||||
|
||||
# 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)
|
||||
|
||||
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():
|
||||
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]"):
|
||||
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):
|
||||
|
@@ -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)
|
||||
|
Reference in New Issue
Block a user