Files
qt-creator/share/qtcreator/gdbmacros/gdbmacros.py

2241 lines
79 KiB
Python

#Note: Keep name-type-value-numchild-extra order
#######################################################################
#
# Dumper Implementations
#
#######################################################################
from __future__ import with_statement
def qdump__QAtomicInt(d, item):
d.putValue(item.value["_q_value"])
d.putNumChild(0)
def qdump__QBasicAtomicInt(d, item):
d.putValue(item.value["_q_value"])
d.putNumChild(0)
def qdump__QBasicAtomicPointer(d, item):
innerType = templateArgument(item.value.type.unqualified(), 0)
d.putType(item.value.type)
p = cleanAddress(item.value["_q_value"])
d.putValue(p)
d.putPointerValue(item.value.address)
d.putNumChild(p)
if d.isExpanded(item):
with Children(d):
d.putItem(item.value["_q_value"])
def qdump__QByteArray(d, item):
d.putByteArrayValue(item.value)
d_ptr = item.value['d'].dereference()
size = d_ptr['size']
d.putNumChild(size)
if d.isExpanded(item):
innerType = lookupType("char")
with Children(d, [size, 1000], innerType):
data = d_ptr['data']
p = gdb.Value(data.cast(innerType.pointer()))
for i in d.childRange():
d.putSubItem(Item(p.dereference(), item.iname, i))
p += 1
def qdump__QChar(d, item):
ucs = int(item.value["ucs"])
d.putValue("'%c' (%d)" % (printableChar(ucs), ucs))
d.putNumChild(0)
def qdump__QAbstractItemModel(d, item):
# Create a default-constructed QModelIndex on the stack.
ri = makeValue(d.ns + "QModelIndex", "-1, -1, 0, 0")
this_ = makeExpression(item.value)
ri_ = makeExpression(ri)
try:
rowCount = int(parseAndEvaluate("%s.rowCount(%s)" % (this_, ri_)))
columnCount = int(parseAndEvaluate("%s.columnCount(%s)" % (this_, ri_)))
except:
d.putPlainChildren(item)
return
d.putValue("%d x %d" % (rowCount, columnCount))
d.putNumChild(rowCount * columnCount)
if d.isExpanded(item):
with Children(d, rowCount * columnCount, ri.type):
i = 0
for row in xrange(rowCount):
for column in xrange(columnCount):
with SubItem(d):
d.putField("iname", "%s.%d" % (item.iname, i))
d.putName("[%s, %s]" % (row, column))
mi = parseAndEvaluate("%s.index(%d,%d,%s)"
% (this_, row, column, ri_))
#warn("MI: %s " % mi)
#name = "[%d,%d]" % (row, column)
#d.putValue("%s" % mi)
d.putItem(Item(mi, item.iname, i))
i = i + 1
#warn("MI: %s " % mi)
#d.putName("[%d,%d]" % (row, column))
#d.putValue("%s" % mi)
#d.putNumChild(0)
#d.putType(mi.type)
#gdb.execute("call free($ri)")
def qdump__QModelIndex(d, item):
r = item.value["r"]
c = item.value["c"]
p = item.value["p"]
m = item.value["m"]
mm = m.dereference()
mm = mm.cast(mm.type.unqualified())
mi = makeValue(d.ns + "QModelIndex", "%s,%s,%s,%s" % (r, c, p, m))
mm_ = makeExpression(mm)
mi_ = makeExpression(mi)
try:
rowCount = int(parseAndEvaluate("%s.rowCount(%s)" % (mm_, mi_)))
columnCount = int(parseAndEvaluate("%s.columnCount(%s)" % (mm_, mi_)))
except:
d.putPlainChildren(item)
return
try:
# Access DisplayRole as value
value = parseAndEvaluate("%s.data(%s, 0)" % (mm_, mi_))
v = value["d"]["data"]["ptr"]
d.putStringValue(makeValue(d.ns + 'QString', v))
except:
d.putValue("(invalid)")
if r >= 0 and c >= 0 and not isNull(m):
d.putNumChild(rowCount * columnCount)
if d.isExpanded(item):
with Children(d):
i = 0
for row in xrange(rowCount):
for column in xrange(columnCount):
with SubItem(d):
d.putField("iname", "%s.%d" % (item.iname, i))
d.putName("[%s, %s]" % (row, column))
mi2 = parseAndEvaluate("%s.index(%d,%d,%s)"
% (mm_, row, column, mi_))
d.putItem(Item(mi2, item.iname, i))
i = i + 1
#d.putCallItem("parent", item, "parent")
#with SubItem(d):
# d.putName("model")
# d.putValue(m)
# d.putType(d.ns + "QAbstractItemModel*")
# d.putNumChild(1)
else:
d.putValue("(invalid)")
d.putNumChild(0)
if d.isExpanded(item):
with Children(d):
pass
#gdb.execute("call free($mi)")
def qdump__QDate(d, item):
if int(item.value["jd"]) == 0:
d.putValue("(null)")
d.putNumChild(0)
return
qt = d.ns + "Qt::"
d.putStringValue(call(item.value, "toString", qt + "TextDate"))
d.putNumChild(1)
if d.isExpanded(item):
# FIXME: This improperly uses complex return values.
with Children(d, 4):
d.putCallItem("toString", item, "toString", qt + "TextDate")
d.putCallItem("(ISO)", item, "toString", qt + "ISODate")
d.putCallItem("(SystemLocale)", item, "toString",
qt + "SystemLocaleDate")
d.putCallItem("(Locale)", item, "toString", qt + "LocaleDate")
def qdump__QTime(d, item):
if int(item.value["mds"]) == -1:
d.putValue("(null)")
d.putNumChild(0)
return
qt = d.ns + "Qt::"
d.putStringValue(call(item.value, "toString", qt + "TextDate"))
d.putNumChild(1)
if d.isExpanded(item):
# FIXME: This improperly uses complex return values.
with Children(d, 8):
d.putCallItem("toString", item, "toString", qt + "TextDate")
d.putCallItem("(ISO)", item, "toString", qt + "ISODate")
d.putCallItem("(SystemLocale)", item, "toString",
qt + "SystemLocaleDate")
d.putCallItem("(Locale)", item, "toString", qt + "LocaleDate")
d.putCallItem("toUTC", item, "toTimeSpec", qt + "UTC")
def qdump__QDateTime(d, item):
try:
# Fails without debug info.
if int(item.value["d"]["d"].dereference()["time"]["mds"]) == -1:
d.putValue("(null)")
d.putNumChild(0)
return
except:
d.putPlainChildren(item)
return
qt = d.ns + "Qt::"
d.putStringValue(call(item.value, "toString", qt + "TextDate"))
d.putNumChild(1)
if d.isExpanded(item):
# FIXME: This improperly uses complex return values.
with Children(d, 8):
d.putCallItem("toTime_t", item, "toTime_t")
d.putCallItem("toString", item, "toString", qt + "TextDate")
d.putCallItem("(ISO)", item, "toString", qt + "ISODate")
d.putCallItem("(SystemLocale)", item, "toString", qt + "SystemLocaleDate")
d.putCallItem("(Locale)", item, "toString", qt + "LocaleDate")
d.putCallItem("toUTC", item, "toTimeSpec", qt + "UTC")
d.putCallItem("toLocalTime", item, "toTimeSpec", qt + "LocalTime")
def qdump__QDir(d, item):
d.putStringValue(item.value["d_ptr"]["d"].dereference()["path"])
d.putNumChild(2)
if d.isExpanded(item):
with Children(d, 2):
d.putCallItem("absolutePath", item, "absolutePath")
d.putCallItem("canonicalPath", item, "canonicalPath")
def qdump__QFile(d, item):
ptype = lookupType(d.ns + "QFilePrivate")
d_ptr = item.value["d_ptr"]["d"].dereference()
d.putStringValue(d_ptr.cast(ptype)["fileName"])
d.putNumChild(1)
if d.isExpanded(item):
with Children(d, 1):
d.putCallItem("exists", item, "exists()")
def qdump__QFileInfo(d, item):
try:
d.putStringValue(item.value["d_ptr"]["d"].dereference()["fileName"])
except:
d.putPlainChildren(item)
return
d.putNumChild(3)
if d.isExpanded(item):
with Children(d, 10, lookupType(d.ns + "QString")):
d.putCallItem("absolutePath", item, "absolutePath")
d.putCallItem("absoluteFilePath", item, "absoluteFilePath")
d.putCallItem("canonicalPath", item, "canonicalPath")
d.putCallItem("canonicalFilePath", item, "canonicalFilePath")
d.putCallItem("completeBaseName", item, "completeBaseName")
d.putCallItem("completeSuffix", item, "completeSuffix")
d.putCallItem("baseName", item, "baseName")
if False:
#ifdef Q_OS_MACX
d.putCallItem("isBundle", item, "isBundle")
d.putCallItem("bundleName", item, "bundleName")
d.putCallItem("fileName", item, "fileName")
d.putCallItem("filePath", item, "filePath")
# Crashes gdb (archer-tromey-python, at dad6b53fe)
#d.putCallItem("group", item, "group")
#d.putCallItem("owner", item, "owner")
d.putCallItem("path", item, "path")
d.putCallItem("groupid", item, "groupId")
d.putCallItem("ownerid", item, "ownerId")
#QFile::Permissions permissions () const
perms = call(item.value, "permissions")
if perms is None:
d.putValue("<not available>")
else:
with SubItem(d):
d.putName("permissions")
d.putValue(" ")
d.putType(d.ns + "QFile::Permissions")
d.putNumChild(10)
if d.isExpandedIName(item.iname + ".permissions"):
with Children(d, 10):
perms = perms['i']
d.putBoolItem("ReadOwner", perms & 0x4000)
d.putBoolItem("WriteOwner", perms & 0x2000)
d.putBoolItem("ExeOwner", perms & 0x1000)
d.putBoolItem("ReadUser", perms & 0x0400)
d.putBoolItem("WriteUser", perms & 0x0200)
d.putBoolItem("ExeUser", perms & 0x0100)
d.putBoolItem("ReadGroup", perms & 0x0040)
d.putBoolItem("WriteGroup", perms & 0x0020)
d.putBoolItem("ExeGroup", perms & 0x0010)
d.putBoolItem("ReadOther", perms & 0x0004)
d.putBoolItem("WriteOther", perms & 0x0002)
d.putBoolItem("ExeOther", perms & 0x0001)
#QDir absoluteDir () const
#QDir dir () const
d.putCallItem("caching", item, "caching")
d.putCallItem("exists", item, "exists")
d.putCallItem("isAbsolute", item, "isAbsolute")
d.putCallItem("isDir", item, "isDir")
d.putCallItem("isExecutable", item, "isExecutable")
d.putCallItem("isFile", item, "isFile")
d.putCallItem("isHidden", item, "isHidden")
d.putCallItem("isReadable", item, "isReadable")
d.putCallItem("isRelative", item, "isRelative")
d.putCallItem("isRoot", item, "isRoot")
d.putCallItem("isSymLink", item, "isSymLink")
d.putCallItem("isWritable", item, "isWritable")
d.putCallItem("created", item, "created")
d.putCallItem("lastModified", item, "lastModified")
d.putCallItem("lastRead", item, "lastRead")
def qdump__QFixed(d, item):
v = int(item.value["val"])
d.putValue("%s/64 = %s" % (v, v/64.0))
d.putNumChild(0)
# Stock gdb 7.2 seems to have a problem with types here:
#
# echo -e "namespace N { struct S { enum E { zero, one, two }; }; }\n"\
# "int main() { N::S::E x = N::S::one;\n return x; }" >> main.cpp
# g++ -g main.cpp
# gdb-7.2 -ex 'file a.out' -ex 'b main' -ex 'run' -ex 'step' \
# -ex 'ptype N::S::E' -ex 'python print gdb.lookup_type("N::S::E")' -ex 'q'
# gdb-7.1 -ex 'file a.out' -ex 'b main' -ex 'run' -ex 'step' \
# -ex 'ptype N::S::E' -ex 'python print gdb.lookup_type("N::S::E")' -ex 'q'
# gdb-cvs -ex 'file a.out' -ex 'b main' -ex 'run' -ex 'step' \
# -ex 'ptype N::S::E' -ex 'python print gdb.lookup_type("N::S::E")' -ex 'q'
#
# gives as of 2010-11-02
#
# type = enum N::S::E {N::S::zero, N::S::one, N::S::two} \n
# Traceback (most recent call last): File "<string>", line 1,
# in <module> RuntimeError: No type named N::S::E.
# type = enum N::S::E {N::S::zero, N::S::one, N::S::two} \n N::S::E
# type = enum N::S::E {N::S::zero, N::S::one, N::S::two} \n N::S::E
#
# i.e. there's something broken in stock 7.2 that is was ok in 7.1 and is ok later.
def qdump__QFlags(d, item):
i = item.value["i"]
try:
enumType = templateArgument(item.value.type.unqualified(), 0)
d.putValue("%s (%s)" % (i.cast(enumType), i))
except:
d.putValue("%s" % i)
d.putNumChild(0)
def qdump__QHash(d, item):
def hashDataFirstNode(value):
value = value.cast(hashDataType)
bucket = value["buckets"]
e = value.cast(hashNodeType)
for n in xrange(value["numBuckets"] - 1, -1, -1):
n = n - 1
if n < 0:
break
if bucket.dereference() != e:
return bucket.dereference()
bucket = bucket + 1
return e;
def hashDataNextNode(node):
next = node["next"]
if next["next"]:
return next
d = node.cast(hashDataType.pointer()).dereference()
numBuckets = d["numBuckets"]
start = (node["h"] % numBuckets) + 1
bucket = d["buckets"] + start
for n in xrange(numBuckets - start):
if bucket.dereference() != next:
return bucket.dereference()
bucket += 1
return node
keyType = templateArgument(item.value.type, 0)
valueType = templateArgument(item.value.type, 1)
d_ptr = item.value["d"]
e_ptr = item.value["e"]
size = d_ptr["size"]
hashDataType = d_ptr.type
hashNodeType = e_ptr.type
check(0 <= size and size <= 100 * 1000 * 1000)
checkRef(d_ptr["ref"])
d.putItemCount(size)
d.putNumChild(size)
if d.isExpanded(item):
isSimpleKey = isSimpleType(keyType)
isSimpleValue = isSimpleType(valueType)
node = hashDataFirstNode(item.value)
innerType = e_ptr.dereference().type
inner = select(isSimpleKey and isSimpleValue, valueType, innerType)
with Children(d, [size, 1000], inner):
for i in d.childRange():
it = node.dereference().cast(innerType)
with SubItem(d):
key = it["key"]
value = it["value"]
if isSimpleKey and isSimpleValue:
d.putName(key)
d.putItem(Item(value, item.iname, i))
d.putType(valueType)
else:
d.putItem(Item(it, item.iname, i))
node = hashDataNextNode(node)
def qdump__QHashNode(d, item):
keyType = templateArgument(item.value.type, 0)
valueType = templateArgument(item.value.type, 1)
key = item.value["key"]
value = item.value["value"]
if isSimpleType(keyType) and isSimpleType(valueType):
d.putItem(Item(value, "data", item.iname))
else:
d.putValue(" ")
d.putNumChild(2)
if d.isExpanded(item):
with Children(d):
with SubItem(d):
d.putName("key")
d.putItem(Item(key, item.iname, "key"))
with SubItem(d):
d.putName("value")
d.putItem(Item(value, item.iname, "value"))
def qdump__QHostAddress(d, item):
data = item.value["d"]["d"].dereference()
d.putStringValue(data["ipString"])
d.putNumChild(1)
if d.isExpanded(item):
with Children(d):
d.putFields(Item(data, item.iname))
def qdump__QList(d, item):
d_ptr = item.value["d"]
begin = d_ptr["begin"]
end = d_ptr["end"]
array = d_ptr["array"]
check(begin >= 0 and end >= 0 and end <= 1000 * 1000 * 1000)
size = end - begin
check(size >= 0)
#if n > 0:
# checkAccess(&list.front())
# checkAccess(&list.back())
checkRef(d_ptr["ref"])
# Additional checks on pointer arrays.
innerType = templateArgument(item.value.type, 0)
innerTypeIsPointer = innerType.code == gdb.TYPE_CODE_PTR \
and str(innerType.target().unqualified()) != "char"
if innerTypeIsPointer:
p = gdb.Value(array).cast(innerType.pointer()) + begin
checkPointerRange(p, qmin(size, 100))
d.putItemCount(size)
d.putNumChild(size)
if d.isExpanded(item):
innerSize = innerType.sizeof
# The exact condition here is:
# QTypeInfo<T>::isLarge || QTypeInfo<T>::isStatic
# but this data is available neither in the compiled binary nor
# in the frontend.
# So as first approximation only do the 'isLarge' check:
isInternal = innerSize <= d_ptr.type.sizeof and d.isMovableType(innerType)
dummyType = lookupType("void").pointer().pointer()
innerTypePointer = innerType.pointer()
p = gdb.Value(array).cast(dummyType) + begin
if innerTypeIsPointer:
inner = innerType.target()
else:
inner = innerType
# about 0.5s / 1000 items
with Children(d, [size, 2000], inner):
for i in d.childRange():
if isInternal:
pp = p.cast(innerTypePointer).dereference();
d.putSubItem(Item(pp, item.iname, i))
else:
pp = p.cast(innerTypePointer.pointer()).dereference()
d.putSubItem(Item(pp, item.iname, i))
p += 1
def qform__QImage():
return "Normal,Displayed"
def qdump__QImage(d, item):
try:
painters = item.value["painters"]
except:
d.putPlainChildren(item)
return
check(0 <= painters and painters < 1000)
d_ptr = item.value["d"]
if isNull(d_ptr):
d.putValue("(null)")
else:
checkRef(d_ptr["ref"])
d.putValue("(%dx%d)" % (d_ptr["width"], d_ptr["height"]))
bits = d_ptr["data"]
nbytes = d_ptr["nbytes"]
d.putNumChild(0)
#d.putNumChild(1)
if d.isExpanded(item):
with Children(d):
with SubItem(d):
d.putName("data")
d.putType(" ");
d.putNumChild(0)
d.putValue("size: %s bytes" % nbytes);
format = d.itemFormat(item)
if format == 1:
d.putDisplay(StopDisplay)
elif format == 2:
if False:
# Take four bytes at a time, this is critical for performance.
# In fact, even four at a time is too slow beyond 100x100 or so.
d.putField("editformat", 1) # Magic marker for direct "QImage" data.
d.put('%s="' % name)
d.put("%08x" % int(d_ptr["width"]))
d.put("%08x" % int(d_ptr["height"]))
d.put("%08x" % int(d_ptr["format"]))
p = bits.cast(lookupType("unsigned int").pointer())
for i in xrange(nbytes / 4):
d.put("%08x" % int(p.dereference()))
p += 1
d.put('",')
else:
# Write to an external file. Much faster ;-(
file = tempfile.mkstemp(prefix="gdbpy_")
filename = file[1].replace("\\", "\\\\")
p = bits.cast(lookupType("unsigned char").pointer())
gdb.execute("dump binary memory %s %s %s" %
(filename, cleanAddress(p), cleanAddress(p + nbytes)))
d.putDisplay(DisplayImage, " %d %d %d %s"
% (d_ptr["width"], d_ptr["height"], d_ptr["format"], filename))
def qdump__QLinkedList(d, item):
d_ptr = item.value["d"]
e_ptr = item.value["e"]
n = d_ptr["size"]
check(0 <= n and n <= 100*1000*1000)
checkRef(d_ptr["ref"])
d.putItemCount(n)
d.putNumChild(n)
if d.isExpanded(item):
innerType = templateArgument(item.value.type, 0)
with Children(d, [n, 1000], innerType):
p = e_ptr["n"]
for i in d.childRange():
d.putSubItem(Item(p["t"], item.iname, i))
p = p["n"]
def qdump__QLocale(d, item):
d.putStringValue(call(item.value, "name"))
d.putNumChild(0)
return
# FIXME: Poke back for variants.
if d.isExpanded(item):
with Children(d, 1, lookupType(d.ns + "QChar"), 0):
d.putCallItem("country", item, "country")
d.putCallItem("language", item, "language")
d.putCallItem("measurementSystem", item, "measurementSystem")
d.putCallItem("numberOptions", item, "numberOptions")
d.putCallItem("timeFormat_(short)", item,
"timeFormat", d.ns + "QLocale::ShortFormat")
d.putCallItem("timeFormat_(long)", item,
"timeFormat", d.ns + "QLocale::LongFormat")
d.putCallItem("decimalPoint", item, "decimalPoint")
d.putCallItem("exponential", item, "exponential")
d.putCallItem("percent", item, "percent")
d.putCallItem("zeroDigit", item, "zeroDigit")
d.putCallItem("groupSeparator", item, "groupSeparator")
d.putCallItem("negativeSign", item, "negativeSign")
def qdump__QMapNode(d, item):
d.putValue(" ")
d.putNumChild(2)
if d.isExpanded(item):
with Children(d, 2):
with SubItem(d):
d.putName("key")
d.putItem(Item(item.value["key"], item.iname, "name"))
with SubItem(d):
d.putName("value")
d.putItem(Item(item.value["value"], item.iname, "value"))
def qdumpHelper__QMap(d, item, forceLong):
d_ptr = item.value["d"].dereference()
e_ptr = item.value["e"].dereference()
n = d_ptr["size"]
check(0 <= n and n <= 100*1000*1000)
checkRef(d_ptr["ref"])
d.putItemCount(n)
d.putNumChild(n)
if d.isExpanded(item):
if n > 1000:
n = 1000
keyType = templateArgument(item.value.type, 0)
valueType = templateArgument(item.value.type, 1)
isSimpleKey = isSimpleType(keyType)
isSimpleValue = isSimpleType(valueType)
it = e_ptr["forward"].dereference()
# QMapPayloadNode is QMapNode except for the 'forward' member, so
# its size is most likely the offset of the 'forward' member therein.
# Or possibly 2 * sizeof(void *)
nodeType = lookupType(d.ns + "QMapNode<%s, %s>" % (keyType, valueType))
payloadSize = nodeType.sizeof - 2 * lookupType("void").pointer().sizeof
charPtr = lookupType("char").pointer()
innerType = select(isSimpleKey and isSimpleValue, valueType, nodeType)
with Children(d, n, innerType):
for i in xrange(n):
itd = it.dereference()
base = it.cast(charPtr) - payloadSize
node = base.cast(nodeType.pointer()).dereference()
with SubItem(d):
key = node["key"]
value = node["value"]
#if isSimpleType(item.value.type):
# or isStringType(d, item.value.type):
if isSimpleKey and isSimpleValue:
#d.putType(valueType)
if forceLong:
d.putName("[%s] %s" % (i, key))
else:
d.putName(key)
d.putItem(Item(value, item.iname, i))
else:
d.putItem(Item(node, item.iname, i))
it = it.dereference()["forward"].dereference()
def qdump__QMap(d, item):
qdumpHelper__QMap(d, item, False)
def qdump__QMultiMap(d, item):
qdumpHelper__QMap(d, item, True)
def extractCString(table, offset):
result = ""
while True:
d = table[offset]
if d == 0:
break
result += "%c" % d
offset += 1
return result
def qdump__QObject(d, item):
#warn("OBJECT: %s " % item.value)
try:
privateTypeName = str(item.value.type) + "Private"
privateType = lookupType(privateTypeName)
if privateType is None:
privateTypeName = d.ns + "QObjectPrivate"
privateType = lookupType(privateTypeName)
staticMetaObject = item.value["staticMetaObject"]
d_ptr = item.value["d_ptr"]["d"].cast(privateType.pointer()).dereference()
#warn("D_PTR: %s " % d_ptr)
objectName = d_ptr["objectName"]
except:
d.putPlainChildren(item)
return
#warn("SMO: %s " % staticMetaObject)
#warn("SMO DATA: %s " % staticMetaObject["d"]["stringdata"])
superData = staticMetaObject["d"]["superdata"]
#warn("SUPERDATA: %s" % superData)
#while not isNull(superData):
# superData = superData.dereference()["d"]["superdata"]
# warn("SUPERDATA: %s" % superData)
if privateType is None:
d.putNumChild(4)
#d.putValue(cleanAddress(item.value.address))
if d.isExpanded(item):
with Children(d):
d.putFields(item)
return
#warn("OBJECTNAME: %s " % objectName)
#warn("D_PTR: %s " % d_ptr)
mo = d_ptr["metaObject"]
if isNull(mo):
mo = staticMetaObject
#warn("MO: %s " % mo)
#warn("MO.D: %s " % mo["d"])
metaData = mo["d"]["data"]
metaStringData = mo["d"]["stringdata"]
#extradata = mo["d"]["extradata"] # Capitalization!
#warn("METADATA: %s " % metaData)
#warn("STRINGDATA: %s " % metaStringData)
#warn("TYPE: %s " % item.value.type)
#warn("INAME: %s " % item.iname)
#d.putValue("")
d.putStringValue(objectName)
#QSignalMapper::staticMetaObject
#checkRef(d_ptr["ref"])
d.putNumChild(4)
if d.isExpanded(item):
with Children(d):
# Local data
if privateTypeName != d.ns + "QObjectPrivate":
if not privateType is None:
with SubItem(d):
d.putName("data")
d.putValue(" ")
d.putType(" ")
d.putNumChild(1)
iname = item.iname + ".data"
if d.isExpandedIName(iname):
with Children(d):
child = Item(d_ptr, iname)
d.putFields(child, False)
d.putFields(item)
# Parent and children.
if stripClassTag(str(item.value.type)) == d.ns + "QObject":
d.putSubItem(Item(d_ptr["parent"], item.iname, "parent", "parent"))
d.putSubItem(Item(d_ptr["children"], item.iname, "children", "children"))
# Properties.
with SubItem(d):
# Prolog
extraData = d_ptr["extraData"] # Capitalization!
if isNull(extraData):
dynamicPropertyCount = 0
else:
extraDataType = lookupType(
d.ns + "QObjectPrivate::ExtraData").pointer()
extraData = extraData.cast(extraDataType)
ed = extraData.dereference()
names = ed["propertyNames"]
values = ed["propertyValues"]
#userData = ed["userData"]
namesBegin = names["d"]["begin"]
namesEnd = names["d"]["end"]
namesArray = names["d"]["array"]
dynamicPropertyCount = namesEnd - namesBegin
#staticPropertyCount = call(mo, "propertyCount")
staticPropertyCount = metaData[6]
#warn("PROPERTY COUNT: %s" % staticPropertyCount)
propertyCount = staticPropertyCount + dynamicPropertyCount
d.putName("properties")
d.putType(" ")
d.putItemCount(propertyCount)
d.putNumChild(propertyCount)
if d.isExpandedIName(item.iname + ".properties"):
# FIXME: Make this global. Don't leak.
variant = "'%sQVariant'" % d.ns
# Avoid malloc symbol clash with QVector
gdb.execute("set $d = (%s*)calloc(sizeof(%s), 1)"
% (variant, variant))
gdb.execute("set $d.d.is_shared = 0")
with Children(d, [propertyCount, 500]):
# Dynamic properties.
if dynamicPropertyCount != 0:
dummyType = lookupType("void").pointer().pointer()
namesType = lookupType(d.ns + "QByteArray")
valuesBegin = values["d"]["begin"]
valuesEnd = values["d"]["end"]
valuesArray = values["d"]["array"]
valuesType = lookupType(d.ns + "QVariant")
p = namesArray.cast(dummyType) + namesBegin
q = valuesArray.cast(dummyType) + valuesBegin
for i in xrange(dynamicPropertyCount):
with SubItem(d):
pp = p.cast(namesType.pointer()).dereference();
d.putField("key", encodeByteArray(pp))
d.putField("keyencoded", Hex2EncodedLatin1)
qq = q.cast(valuesType.pointer().pointer())
qq = qq.dereference();
d.putField("addr", cleanAddress(qq))
d.putField("exp", "*(%s*)%s"
% (variant, cleanAddress(qq)))
name = "%s.properties.%d" % (item.iname, i)
t = qdump__QVariant(d, Item(qq, name))
# Override the "QVariant (foo)" output
d.putType(t, d.currentTypePriority + 1)
p += 1
q += 1
# Static properties.
propertyData = metaData[7]
for i in xrange(staticPropertyCount):
with NoAddress(d):
with SubItem(d):
offset = propertyData + 3 * i
propertyName = extractCString(metaStringData,
metaData[offset])
propertyType = extractCString(metaStringData,
metaData[offset + 1])
d.putName(propertyName)
#flags = metaData[offset + 2]
#warn("FLAGS: %s " % flags)
#warn("PROPERTY: %s %s " % (propertyType, propertyName))
# #exp = '((\'%sQObject\'*)%s)->property("%s")' \
# % (d.ns, item.value.address, propertyName)
#exp = '"((\'%sQObject\'*)%s)"' %
#(d.ns, item.value.address,)
#warn("EXPRESSION: %s" % exp)
value = call(item.value, "property",
str(cleanAddress(metaStringData + metaData[offset])))
value1 = value["d"]
#warn(" CODE: %s" % value1["type"])
# Type 1 and 2 are bool and int.
# Try to save a few cycles in this case:
if int(value1["type"]) > 2:
# Poke back value
gdb.execute("set $d.d.data.ull = %s"
% value1["data"]["ull"])
gdb.execute("set $d.d.type = %s"
% value1["type"])
gdb.execute("set $d.d.is_null = %s"
% value1["is_null"])
value = parseAndEvaluate("$d").dereference()
val, inner, innert = qdumpHelper__QVariant(d, value)
if len(inner):
# Build-in types.
d.putType(inner)
name = "%s.properties.%d" \
% (item.iname, i + dynamicPropertyCount)
d.putItem(Item(val, item.iname + ".properties",
propertyName, propertyName))
else:
# User types.
# func = "typeToName(('%sQVariant::Type')%d)"
# % (d.ns, variantType)
# type = str(call(item.value, func))
# type = type[type.find('"') + 1 : type.rfind('"')]
# type = type.replace("Q", d.ns + "Q") # HACK!
# data = call(item.value, "constData")
# tdata = data.cast(lookupType(type).pointer())
# .dereference()
# d.putValue("(%s)" % tdata.type)
# d.putType(tdata.type)
# d.putNumChild(1)
# if d.isExpanded(item):
# with Children(d):
# d.putSubItem(Item(tdata, item.iname,
# "data", "data"))
warn("FIXME: CUSTOM QOBJECT PROPERTY: %s %s"
% (propertyType, innert))
d.putType(propertyType)
d.putValue("...")
d.putNumChild(0)
# Connections.
with SubItem(d):
d.putName("connections")
d.putType(" ")
connections = d_ptr["connectionLists"]
connectionListCount = 0
if not isNull(connections):
connectionListCount = connections["d"]["size"]
d.putItemCount(connectionListCount, 0)
d.putNumChild(connectionListCount)
if d.isExpandedIName(item.iname + ".connections"):
with Children(d):
vectorType = connections.type.target().fields()[0].type
innerType = templateArgument(vectorType, 0)
# Should check: innerType == ns::QObjectPrivate::ConnectionList
p = gdb.Value(connections["p"]["array"]).cast(innerType.pointer())
pp = 0
for i in xrange(connectionListCount):
first = p.dereference()["first"]
while not isNull(first):
d.putSubItem(Item(first.dereference(),
item.iname + ".connections", pp))
first = first["next"]
# We need to enforce some upper limit.
pp += 1
if pp > 1000:
break
p += 1
# Signals
signalCount = metaData[13]
with SubItem(d):
d.putName("signals")
d.putItemCount(signalCount)
d.putType(" ")
d.putNumChild(signalCount)
if signalCount:
# FIXME: empty type does not work for childtype
#d.putField("childtype", ".")
d.putField("childnumchild", "0")
if d.isExpandedIName(item.iname + ".signals"):
with Children(d):
for signal in xrange(signalCount):
with SubItem(d):
offset = metaData[14 + 5 * signal]
d.putField("iname", "%s.signals.%d"
% (item.iname, signal))
d.putName("signal %d" % signal)
d.putType(" ")
d.putValue(extractCString(metaStringData, offset))
d.putNumChild(0) # FIXME: List the connections here.
# Slots
with SubItem(d):
slotCount = metaData[4] - signalCount
d.putName("slots")
d.putItemCount(slotCount)
d.putType(" ")
d.putNumChild(slotCount)
if slotCount:
#d.putField("childtype", ".")
d.putField("childnumchild", "0")
if d.isExpandedIName(item.iname + ".slots"):
with Children(d):
for slot in xrange(slotCount):
with SubItem(d):
offset = metaData[14 + 5 * (signalCount + slot)]
d.putField("iname", "%s.slots.%d" % (item.iname, slot))
d.putName("slot %d" % slot)
d.putType(" ")
d.putValue(extractCString(metaStringData, offset))
d.putNumChild(0) # FIXME: List the connections here.
# Active connection
with SubItem(d):
d.putName("currentSender")
d.putType(" ")
sender = d_ptr["currentSender"]
d.putValue(cleanAddress(sender))
if isNull(sender):
d.putNumChild(0)
else:
d.putNumChild(1)
iname = item.iname + ".currentSender"
if d.isExpandedIName(iname):
with Children(d):
# Sending object
d.putSubItem(Item(sender["sender"], iname, "object", "object"))
# Signal in sending object
with SubItem(d):
d.putName("signal")
d.putValue(sender["signal"])
d.putType(" ");
d.putNumChild(0)
# QObject
# static const uint qt_meta_data_QObject[] = {
# int revision;
# int className;
# int classInfoCount, classInfoData;
# int methodCount, methodData;
# int propertyCount, propertyData;
# int enumeratorCount, enumeratorData;
# int constructorCount, constructorData; //since revision 2
# int flags; //since revision 3
# int signalCount; //since revision 4
# // content:
# 4, // revision
# 0, // classname
# 0, 0, // classinfo
# 4, 14, // methods
# 1, 34, // properties
# 0, 0, // enums/sets
# 2, 37, // constructors
# 0, // flags
# 2, // signalCount
# /* 14 */
# // signals: signature, parameters, type, tag, flags
# 9, 8, 8, 8, 0x05,
# 29, 8, 8, 8, 0x25,
# /* 24 */
# // slots: signature, parameters, type, tag, flags
# 41, 8, 8, 8, 0x0a,
# 55, 8, 8, 8, 0x08,
# /* 34 */
# // properties: name, type, flags
# 90, 82, 0x0a095103,
# /* 37 */
# // constructors: signature, parameters, type, tag, flags
# 108, 101, 8, 8, 0x0e,
# 126, 8, 8, 8, 0x2e,
# 0 // eod
# };
# static const char qt_meta_stringdata_QObject[] = {
# "QObject\0\0destroyed(QObject*)\0destroyed()\0"
# "deleteLater()\0_q_reregisterTimers(void*)\0"
# "QString\0objectName\0parent\0QObject(QObject*)\0"
# "QObject()\0"
# };
# QSignalMapper
# static const uint qt_meta_data_QSignalMapper[] = {
# // content:
# 4, // revision
# 0, // classname
# 0, 0, // classinfo
# 7, 14, // methods
# 0, 0, // properties
# 0, 0, // enums/sets
# 0, 0, // constructors
# 0, // flags
# 4, // signalCount
# // signals: signature, parameters, type, tag, flags
# 15, 14, 14, 14, 0x05,
# 27, 14, 14, 14, 0x05,
# 43, 14, 14, 14, 0x05,
# 60, 14, 14, 14, 0x05,
# // slots: signature, parameters, type, tag, flags
# 77, 14, 14, 14, 0x0a,
# 90, 83, 14, 14, 0x0a,
# 104, 14, 14, 14, 0x08,
# 0 // eod
# };
# static const char qt_meta_stringdata_QSignalMapper[] = {
# "QSignalMapper\0\0mapped(int)\0mapped(QString)\0"
# "mapped(QWidget*)\0mapped(QObject*)\0"
# "map()\0sender\0map(QObject*)\0"
# "_q_senderDestroyed()\0"
# };
# const QMetaObject QSignalMapper::staticMetaObject = {
# { &QObject::staticMetaObject, qt_meta_stringdata_QSignalMapper,
# qt_meta_data_QSignalMapper, 0 }
# };
# static const char *sizePolicyEnumValue(QSizePolicy::Policy p)
# {
# switch (p) {
# case QSizePolicy::Fixed:
# return "Fixed"
# case QSizePolicy::Minimum:
# return "Minimum"
# case QSizePolicy::Maximum:
# return "Maximum"
# case QSizePolicy::Preferred:
# return "Preferred"
# case QSizePolicy::Expanding:
# return "Expanding"
# case QSizePolicy::MinimumExpanding:
# return "MinimumExpanding"
# case QSizePolicy::Ignored:
# break
# }
# return "Ignored"
# }
#
# static QString sizePolicyValue(const QSizePolicy &sp)
# {
# QString rc
# QTextStream str(&rc)
# // Display as in Designer
# str << '[' << sizePolicyEnumValue(sp.horizontalPolicy())
# << ", " << sizePolicyEnumValue(sp.verticalPolicy())
# << ", " << sp.horizontalStretch() << ", " << sp.verticalStretch() << ']'
# return rc
# }
# #endif
#
# // Meta enumeration helpers
# static inline void dumpMetaEnumType(QDumper &d, const QMetaEnum &me)
# {
# QByteArray type = me.scope()
# if !type.isEmpty())
# type += "::"
# type += me.name()
# d.putField("type", type.constData())
# }
#
# static inline void dumpMetaEnumValue(QDumper &d, const QMetaProperty &mop,
# int value)
# {
#
# const QMetaEnum me = mop.enumerator()
# dumpMetaEnumType(d, me)
# if const char *enumValue = me.valueToKey(value)) {
# d.putValue(enumValue)
# } else {
# d.putValue(value)
# }
# d.putField("numchild", 0)
# }
#
# static inline void dumpMetaFlagValue(QDumper &d, const QMetaProperty &mop,
# int value)
# {
# const QMetaEnum me = mop.enumerator()
# dumpMetaEnumType(d, me)
# const QByteArray flagsValue = me.valueToKeys(value)
# if flagsValue.isEmpty():
# d.putValue(value)
# else:
# d.putValue(flagsValue.constData())
# d.putNumChild(0)
# }
def qdump__QPixmap(d, item):
painters = item.value["painters"]
check(0 <= painters and painters < 1000)
d_ptr = item.value["data"]["d"]
if isNull(d_ptr):
d.putValue("(null)")
else:
checkRef(d_ptr["ref"])
d.putValue("(%dx%d)" % (d_ptr["w"], d_ptr["h"]))
d.putNumChild(0)
def qdump__QPoint(d, item):
x = item.value["xp"]
y = item.value["yp"]
# should not be needed, but sometimes yield myns::QVariant::Private::Data::qreal
x = x.cast(x.type.strip_typedefs())
y = y.cast(y.type.strip_typedefs())
d.putValue("(%s, %s)" % (x, y))
d.putNumChild(2)
if d.isExpanded(item):
with Children(d, 2, x.type.strip_typedefs()):
d.putSubItem(Item(x, None, None, "x"))
d.putSubItem(Item(y, None, None, "y"))
def qdump__QPointF(d, item):
qdump__QPoint(d, item)
def qdump__QRect(d, item):
def pp(l): return select(l >= 0, "+%s" % l, l)
x1 = item.value["x1"]
y1 = item.value["y1"]
x2 = item.value["x2"]
y2 = item.value["y2"]
w = x2 - x1 + 1
h = y2 - y1 + 1
d.putValue("%sx%s%s%s" % (w, h, pp(x1), pp(y1)))
d.putNumChild(4)
if d.isExpanded(item):
with Children(d, 4, x1.type.strip_typedefs()):
d.putSubItem(Item(x1, None, None, "x1"))
d.putSubItem(Item(y1, None, None, "y1"))
d.putSubItem(Item(x2, None, None, "x2"))
d.putSubItem(Item(y2, None, None, "y2"))
def qdump__QRectF(d, item):
def pp(l): return select(l >= 0, "+%s" % l, l)
x = item.value["xp"]
y = item.value["yp"]
w = item.value["w"]
h = item.value["h"]
# FIXME: workaround, see QPoint
x = x.cast(x.type.strip_typedefs())
y = y.cast(y.type.strip_typedefs())
w = w.cast(w.type.strip_typedefs())
h = h.cast(h.type.strip_typedefs())
d.putValue("%sx%s%s%s" % (w, h, pp(x), pp(y)))
d.putNumChild(4)
if d.isExpanded(item):
with Children(d, 4, x.type.strip_typedefs()):
d.putSubItem(Item(x, None, None, "x"))
d.putSubItem(Item(y, None, None, "y"))
d.putSubItem(Item(w, None, None, "w"))
d.putSubItem(Item(h, None, None, "h"))
def qdump__QRegion(d, item):
p = item.value["d"].dereference()["qt_rgn"]
if isNull(p):
d.putValue("<empty>")
d.putNumChild(0)
else:
try:
# Fails without debug info.
n = int(p.dereference()["numRects"])
d.putItemCount(n)
d.putNumChild(n)
if d.isExpanded(item):
with Children(d):
d.putFields(Item(p.dereference(), item.iname))
except:
d.putValue(p)
d.putPlainChildren(item)
# qt_rgn might be 0
# gdb.parse_and_eval("region")["d"].dereference()["qt_rgn"].dereference()
def qdump__QScopedPointer(d, item):
d.putType(d.currentType, d.currentTypePriority + 1)
d.putItem(Item(item.value["d"], item.iname, None, None))
def qdump__QSet(d, item):
def hashDataFirstNode(value):
value = value.cast(hashDataType)
bucket = value["buckets"]
e = value.cast(hashNodeType)
for n in xrange(value["numBuckets"] - 1, -1, -1):
n = n - 1
if n < 0:
break
if bucket.dereference() != e:
return bucket.dereference()
bucket = bucket + 1
return e;
def hashDataNextNode(node):
next = node["next"]
if next["next"]:
return next
d = node.cast(hashDataType.pointer()).dereference()
numBuckets = d["numBuckets"]
start = (node["h"] % numBuckets) + 1
bucket = d["buckets"] + start
for n in xrange(numBuckets - start):
if bucket.dereference() != next:
return bucket.dereference()
bucket += 1
return node
keyType = templateArgument(item.value.type, 0)
d_ptr = item.value["q_hash"]["d"]
e_ptr = item.value["q_hash"]["e"]
size = d_ptr["size"]
hashDataType = d_ptr.type
hashNodeType = e_ptr.type
check(0 <= size and size <= 100 * 1000 * 1000)
checkRef(d_ptr["ref"])
d.putItemCount(size)
d.putNumChild(size)
if d.isExpanded(item):
isSimpleKey = isSimpleType(keyType)
node = hashDataFirstNode(item.value)
innerType = e_ptr.dereference().type
with Children(d, [size, 1000], keyType):
for i in xrange(size):
it = node.dereference().cast(innerType)
with SubItem(d):
key = it["key"]
if isSimpleKey:
d.putType(keyType)
d.putItem(Item(key, None, None))
else:
d.putItem(Item(key, item.iname, i))
node = hashDataNextNode(node)
def qdump__QSharedData(d, item):
d.putValue("ref: %s" % item.value["ref"]["_q_value"])
d.putNumChild(0)
def qdump__QSharedDataPointer(d, item):
d_ptr = item.value["d"]
if isNull(d_ptr):
d.putValue("(null)")
d.putNumChild(0)
else:
# This replaces the pointer by the pointee, making the
# pointer transparent.
try:
innerType = templateArgument(item.value.type, 0)
except:
d.putValue(d_ptr)
d.putPlainChildren(item)
return
value = gdb.Value(d_ptr.cast(innerType.pointer()))
d.putType(d.currentType, d.currentTypePriority + 1)
d.putItem(Item(value.dereference(), item.iname, None))
def qdump__QSharedPointer(d, item):
qdump__QWeakPointer(d, item)
def qdump__QSize(d, item):
w = item.value["wd"]
h = item.value["ht"]
d.putValue("(%s, %s)" % (w, h))
d.putNumChild(2)
if d.isExpanded(item):
with Children(d, 2, w.type):
d.putSubItem(Item(w, item.iname, "w", "w"))
d.putSubItem(Item(h, item.iname, "h", "h"))
def qdump__QSizeF(d, item):
qdump__QSize(d, item)
def qdump__QStack(d, item):
qdump__QVector(d, item)
def qdump__QStandardItem(d, item):
d.putType(d.currentType, d.currentTypePriority + 1)
try:
d.putItem(Item(item.value["d_ptr"], item.iname, None, None))
except:
d.putPlainChildren(item)
def qform__QString():
return "Inline,Separate Window"
def qdump__QString(d, item):
d.putStringValue(item.value)
d.putNumChild(0)
format = d.itemFormat(item)
if format == 1:
d.putDisplay(StopDisplay)
elif format == 2:
d.putField("editformat", 2)
str = encodeString(item.value)
d.putField("editvalue", str)
def qdump__QStringList(d, item):
d_ptr = item.value['d']
begin = d_ptr['begin']
end = d_ptr['end']
size = end - begin
check(size >= 0)
check(size <= 10 * 1000 * 1000)
# checkAccess(&list.front())
# checkAccess(&list.back())
checkRef(d_ptr["ref"])
d.putItemCount(size)
d.putNumChild(size)
if d.isExpanded(item):
innerType = lookupType(d.ns + "QString")
ptr = gdb.Value(d_ptr["array"]).cast(innerType.pointer())
ptr += d_ptr["begin"]
with Children(d, [size, 1000], innerType):
for i in d.childRange():
d.putSubItem(Item(ptr.dereference(), item.iname, i))
ptr += 1
def qdump__QTemporaryFile(d, item):
qdump__QFile(d, item)
def qdump__QTextCodec(d, item):
value = call(item.value, "name")
d.putValue(encodeByteArray(value), 6)
d.putNumChild(2)
if d.isExpanded(item):
with Children(d):
d.putCallItem("name", item, "name")
d.putCallItem("mibEnum", item, "mibEnum")
def qdump__QTextCursor(d, item):
dd = item.value["d"]["d"]
if isNull(dd):
d.putValue("(invalid)")
d.putNumChild(0)
else:
try:
p = dd.dereference()
d.putValue(p["position"])
except:
d.putPlainChildren(item)
return
d.putNumChild(1)
if d.isExpanded(item):
with Children(d):
d.putIntItem("position", p["position"])
d.putIntItem("anchor", p["anchor"])
d.putCallItem("selected", item, "selectedText")
def qdump__QTextDocument(d, item):
d.putValue(" ")
d.putNumChild(1)
if d.isExpanded(item):
with Children(d):
d.putCallItem("blockCount", item, "blockCount")
d.putCallItem("characterCount", item, "characterCount")
d.putCallItem("lineCount", item, "lineCount")
d.putCallItem("revision", item, "revision")
d.putCallItem("toPlainText", item, "toPlainText")
def qdump__QUrl(d, item):
try:
data = item.value["d"].dereference()
d.putStringValue(data["encodedOriginal"])
except:
d.putPlainChildren(item)
return
d.putNumChild(1)
if d.isExpanded(item):
with Children(d):
d.putFields(Item(data, item.iname))
def qdumpHelper__QVariant(d, value):
data = value["d"]["data"]
variantType = int(value["d"]["type"])
#warn("VARIANT TYPE: %s : " % variantType)
val = None
inner = ""
innert = ""
if variantType == 0: # QVariant::Invalid
d.putValue("(invalid)")
d.putNumChild(0)
elif variantType == 1: # QVariant::Bool
d.putValue(select(data["b"], "true", "false"))
d.putNumChild(0)
inner = "bool"
elif variantType == 2: # QVariant::Int
d.putValue(data["i"])
d.putNumChild(0)
inner = "int"
elif variantType == 3: # uint
d.putValue(data["u"])
d.putNumChild(0)
inner = "uint"
elif variantType == 4: # qlonglong
d.putValue(data["ll"])
d.putNumChild(0)
inner = "qlonglong"
elif variantType == 5: # qulonglong
d.putValue(data["ull"])
d.putNumChild(0)
inner = "qulonglong"
elif variantType == 6: # QVariant::Double
value = data["d"]
d.putValue(data["d"])
d.putNumChild(0)
inner = "double"
elif variantType == 7: # QVariant::QChar
inner = d.ns + "QChar"
elif variantType == 8: # QVariant::VariantMap
inner = d.ns + "QMap<" + d.ns + "QString, " + d.ns + "QVariant>"
innert = d.ns + "QVariantMap"
elif variantType == 9: # QVariant::VariantList
inner = d.ns + "QList<" + d.ns + "QVariant>"
innert = d.ns + "QVariantList"
elif variantType == 10: # QVariant::String
inner = d.ns + "QString"
elif variantType == 11: # QVariant::StringList
inner = d.ns + "QStringList"
elif variantType == 12: # QVariant::ByteArray
inner = d.ns + "QByteArray"
elif variantType == 13: # QVariant::BitArray
inner = d.ns + "QBitArray"
elif variantType == 14: # QVariant::Date
inner = d.ns + "QDate"
elif variantType == 15: # QVariant::Time
inner = d.ns + "QTime"
elif variantType == 16: # QVariant::DateTime
inner = d.ns + "QDateTime"
elif variantType == 17: # QVariant::Url
inner = d.ns + "QUrl"
elif variantType == 18: # QVariant::Locale
inner = d.ns + "QLocale"
elif variantType == 19: # QVariant::Rect
inner = d.ns + "QRect"
elif variantType == 20: # QVariant::RectF
inner = d.ns + "QRectF"
elif variantType == 21: # QVariant::Size
inner = d.ns + "QSize"
elif variantType == 22: # QVariant::SizeF
inner = d.ns + "QSizeF"
elif variantType == 23: # QVariant::Line
inner = d.ns + "QLine"
elif variantType == 24: # QVariant::LineF
inner = d.ns + "QLineF"
elif variantType == 25: # QVariant::Point
inner = d.ns + "QPoint"
elif variantType == 26: # QVariant::PointF
inner = d.ns + "QPointF"
elif variantType == 27: # QVariant::RegExp
inner = d.ns + "QRegExp"
elif variantType == 28: # QVariant::VariantHash
inner = d.ns + "QHash<" + d.ns + "QString, " + d.ns + "QVariant>"
innert = d.ns + "QVariantHash"
elif variantType == 64: # QVariant::Font
inner = d.ns + "QFont"
elif variantType == 65: # QVariant::Pixmap
inner = d.ns + "QPixmap"
elif variantType == 66: # QVariant::Brush
inner = d.ns + "QBrush"
elif variantType == 67: # QVariant::Color
inner = d.ns + "QColor"
elif variantType == 68: # QVariant::Palette
inner = d.ns + "QPalette"
elif variantType == 69: # QVariant::Icon
inner = d.ns + "QIcon"
elif variantType == 70: # QVariant::Image
inner = d.ns + "QImage"
elif variantType == 71: # QVariant::Polygon and PointArray
inner = d.ns + "QPolygon"
elif variantType == 72: # QVariant::Region
inner = d.ns + "QRegion"
elif variantType == 73: # QVariant::Bitmap
inner = d.ns + "QBitmap"
elif variantType == 74: # QVariant::Cursor
inner = d.ns + "QCursor"
elif variantType == 75: # QVariant::SizePolicy
inner = d.ns + "QSizePolicy"
elif variantType == 76: # QVariant::KeySequence
inner = d.ns + "QKeySequence"
elif variantType == 77: # QVariant::Pen
inner = d.ns + "QPen"
elif variantType == 78: # QVariant::TextLength
inner = d.ns + "QTextLength"
elif variantType == 79: # QVariant::TextFormat
inner = d.ns + "QTextFormat"
elif variantType == 81: # QVariant::Transform
inner = d.ns + "QTransform"
elif variantType == 82: # QVariant::Matrix4x4
inner = d.ns + "QMatrix4x4"
elif variantType == 83: # QVariant::Vector2D
inner = d.ns + "QVector2D"
elif variantType == 84: # QVariant::Vector3D
inner = d.ns + "QVector3D"
elif variantType == 85: # QVariant::Vector4D
inner = d.ns + "QVector4D"
elif variantType == 86: # QVariant::Quadernion
inner = d.ns + "QQuadernion"
if len(inner):
innerType = lookupType(inner)
sizePD = lookupType(d.ns + 'QVariant::Private::Data').sizeof
if innerType.sizeof > sizePD:
sizePS = lookupType(d.ns + 'QVariant::PrivateShared').sizeof
val = (sizePS + data.cast(lookupType('char').pointer())) \
.cast(innerType.pointer()).dereference()
else:
val = data.cast(innerType)
if len(innert) == 0:
innert = inner
return val, inner, innert
def qdump__QVariant(d, item):
val, inner, innert = qdumpHelper__QVariant(d, item.value)
#warn("VARIANT DATA: '%s' '%s' '%s': " % (val, inner, innert))
if len(inner):
innerType = lookupType(inner)
# FIXME: Why "shared"?
if innerType.sizeof > item.value["d"]["data"].type.sizeof:
v = item.value["d"]["data"]["shared"]["ptr"] \
.cast(innerType.pointer()).dereference()
else:
v = item.value["d"]["data"].cast(innerType)
d.putValue(" ", None, -99)
d.putItem(Item(v, item.iname))
d.putType("%sQVariant (%s)" % (d.ns, innert), d.currentTypePriority + 1)
return innert
# User types.
d_member = item.value["d"]
type = str(call(item.value, "typeToName",
"('%sQVariant::Type')%d" % (d.ns, d_member["type"])))
type = type[type.find('"') + 1 : type.rfind('"')]
type = type.replace("Q", d.ns + "Q") # HACK!
type = type.replace("uint", "unsigned int") # HACK!
type = type.replace("COMMA", ",") # HACK!
#warn("TYPE: %s" % type)
data = call(item.value, "constData")
#warn("DATA: %s" % data)
d.putValue(" ", None, -99)
d.putType("%sQVariant (%s)" % (d.ns, type))
d.putNumChild(1)
tdata = data.cast(lookupType(type).pointer()).dereference()
if d.isExpanded(item):
with Children(d):
#warn("TDATA: %s" % tdata)
with NoAddress(d):
d.putSubItem(Item(tdata, item.iname, "data", "data"))
return tdata.type
def qdump__QVector(d, item):
d_ptr = item.value["d"]
p_ptr = item.value["p"]
alloc = d_ptr["alloc"]
size = d_ptr["size"]
check(0 <= size and size <= alloc and alloc <= 1000 * 1000 * 1000)
checkRef(d_ptr["ref"])
innerType = templateArgument(item.value.type, 0)
d.putItemCount(size)
d.putNumChild(size)
if d.isExpanded(item):
p = gdb.Value(p_ptr["array"]).cast(innerType.pointer())
charPtr = lookupType("char").pointer()
d.putField("size", size)
d.putField("addrbase", cleanAddress(p))
d.putField("addrstep", (p+1).cast(charPtr) - p.cast(charPtr))
with Children(d, [size, 2000], innerType):
for i in d.childRange():
d.putSubItem(Item(p.dereference(), item.iname, i))
p += 1
def qdump__QWeakPointer(d, item):
d_ptr = item.value["d"]
value = item.value["value"]
if isNull(d_ptr) and isNull(value):
d.putValue("(null)")
d.putNumChild(0)
return
if isNull(d_ptr) or isNull(value):
d.putValue("<invalid>")
d.putNumChild(0)
return
weakref = d_ptr["weakref"]["_q_value"]
strongref = d_ptr["strongref"]["_q_value"]
check(int(strongref) >= -1)
check(int(strongref) <= int(weakref))
check(int(weakref) <= 10*1000*1000)
innerType = templateArgument(item.value.type, 0)
if isSimpleType(value.dereference().type):
d.putItem(Item(value.dereference(), item.iname, None))
else:
d.putValue("")
d.putNumChild(3)
if d.isExpanded(item):
with Children(d, 3):
d.putSubItem(Item(value.dereference(), item.iname, "data", "data"))
d.putIntItem("weakref", weakref)
d.putIntItem("strongref", strongref)
#######################################################################
#
# Standard Library dumper
#
#######################################################################
def qdump__std__deque(d, item):
impl = item.value["_M_impl"]
start = impl["_M_start"]
size = impl["_M_finish"]["_M_cur"] - start["_M_cur"]
check(0 <= size and size <= 1000 * 1000 * 1000)
d.putItemCount(size)
d.putNumChild(size)
if d.isExpanded(item):
innerType = templateArgument(item.value.type, 0)
innerSize = innerType.sizeof
bufsize = select(innerSize < 512, 512 / innerSize, 1)
with Children(d, [size, 2000], innerType):
pcur = start["_M_cur"]
pfirst = start["_M_first"]
plast = start["_M_last"]
pnode = start["_M_node"]
for i in d.childRange():
d.putSubItem(Item(pcur.dereference(), item.iname, i))
pcur += 1
if pcur == plast:
newnode = pnode + 1
pnode = newnode
pfirst = newnode.dereference()
plast = pfirst + bufsize
pcur = pfirst
def qdump__std__list(d, item):
impl = item.value["_M_impl"]
node = impl["_M_node"]
head = node.address
size = 0
p = node["_M_next"]
while p != head and size <= 1001:
size += 1
p = p["_M_next"]
d.putItemCount(size, 1000)
d.putNumChild(size)
if d.isExpanded(item):
p = node["_M_next"]
innerType = templateArgument(item.value.type, 0)
with Children(d, [size, 1000], innerType):
for i in d.childRange():
innerPointer = innerType.pointer()
value = (p + 1).cast(innerPointer).dereference()
d.putSubItem(Item(value, item.iname, i))
p = p["_M_next"]
def qdump__std__map(d, item):
impl = item.value["_M_t"]["_M_impl"]
size = impl["_M_node_count"]
check(0 <= size and size <= 100*1000*1000)
d.putItemCount(size)
d.putNumChild(size)
if d.isExpanded(item):
keyType = templateArgument(item.value.type, 0)
valueType = templateArgument(item.value.type, 1)
pairType = templateArgument(templateArgument(item.value.type, 3), 0)
isSimpleKey = isSimpleType(keyType)
isSimpleValue = isSimpleType(valueType)
innerType = select(isSimpleKey and isSimpleValue, valueType, pairType)
pairPointer = pairType.pointer()
node = impl["_M_header"]["_M_left"]
with Children(d, [size, 1000], select(size > 0, innerType, pairType),
select(isSimpleKey and isSimpleValue, None, 2)):
for i in d.childRange():
pair = (node + 1).cast(pairPointer).dereference()
with SubItem(d):
if isSimpleKey and isSimpleValue:
d.putName(str(pair["first"]))
d.putItem(Item(pair["second"], item.iname, i))
else:
d.putValue(" ")
if d.isExpandedIName("%s.%d" % (item.iname, i)):
with Children(d, 2, None):
iname = "%s.%d" % (item.iname, i)
keyItem = Item(pair["first"], iname, "first", "first")
valueItem = Item(pair["second"], iname, "second", "second")
d.putSubItem(keyItem)
d.putSubItem(valueItem)
if isNull(node["_M_right"]):
parent = node["_M_parent"]
while node == parent["_M_right"]:
node = parent
parent = parent["_M_parent"]
if node["_M_right"] != parent:
node = parent
else:
node = node["_M_right"]
while not isNull(node["_M_left"]):
node = node["_M_left"]
def qdump__std__set(d, item):
impl = item.value["_M_t"]["_M_impl"]
size = impl["_M_node_count"]
check(0 <= size and size <= 100*1000*1000)
d.putItemCount(size)
d.putNumChild(size)
if d.isExpanded(item):
valueType = templateArgument(item.value.type, 0)
node = impl["_M_header"]["_M_left"]
with Children(d, [size, 1000], valueType):
for i in d.childRange():
element = (node + 1).cast(valueType.pointer()).dereference()
d.putSubItem(Item(element, item.iname, i))
if isNull(node["_M_right"]):
parent = node["_M_parent"]
while node == parent["_M_right"]:
node = parent
parent = parent["_M_parent"]
if node["_M_right"] != parent:
node = parent
else:
node = node["_M_right"]
while not isNull(node["_M_left"]):
node = node["_M_left"]
def qdump__std__stack(d, item):
data = item.value["c"]
qdump__std__deque(d, Item(data, item.iname))
def qdump__std__string(d, item):
data = item.value["_M_dataplus"]["_M_p"]
baseType = item.value.type.unqualified().strip_typedefs()
if baseType.code == gdb.TYPE_CODE_REF:
baseType = baseType.target().unqualified().strip_typedefs()
# We might encounter 'std::string' or 'std::basic_string<>'
# or even 'std::locale::string' on MinGW due to some type lookup glitch.
if str(baseType) == 'std::string' or str(baseType) == 'std::locale::string':
charType = lookupType("char")
elif str(baseType) == 'std::wstring':
charType = lookupType("wchar_t")
else:
charType = templateArgument(baseType, 0)
repType = lookupType("%s::_Rep" % baseType).pointer()
rep = (data.cast(repType) - 1).dereference()
size = rep['_M_length']
alloc = rep['_M_capacity']
check(rep['_M_refcount'] >= -1) # Can be -1 accoring to docs.
check(0 <= size and size <= alloc and alloc <= 100*1000*1000)
p = gdb.Value(data.cast(charType.pointer()))
s = ""
# Override "std::basic_string<...>
if str(charType) == "char":
d.putType("std::string", 1)
elif str(charType) == "wchar_t":
d.putType("std::wstring", 1)
n = qmin(size, 1000)
if charType.sizeof == 1:
format = "%02x"
for i in xrange(size):
s += format % int(p.dereference())
p += 1
d.putValue(s, Hex2EncodedLatin1)
d.putNumChild(0)
elif charType.sizeof == 2:
format = "%02x%02x"
for i in xrange(size):
val = int(p.dereference())
s += format % (val % 256, val / 256)
p += 1
d.putValue(s, Hex4EncodedLittleEndian)
else:
# FIXME: This is not always a proper solution.
format = "%02x%02x%02x%02x"
for i in xrange(size):
val = int(p.dereference())
hi = val / 65536
lo = val % 65536
s += format % (lo % 256, lo / 256, hi % 256, hi / 256)
p += 1
d.putValue(s, Hex8EncodedLittleEndian)
d.putNumChild(0)
def qdump__std__vector(d, item):
impl = item.value["_M_impl"]
type = templateArgument(item.value.type, 0)
alloc = impl["_M_end_of_storage"]
isBool = str(type) == 'bool'
if isBool:
start = impl["_M_start"]["_M_p"]
finish = impl["_M_finish"]["_M_p"]
# FIXME: 32 is sizeof(unsigned long) * CHAR_BIT
storagesize = 32
size = (finish - start) * storagesize
size += impl["_M_finish"]["_M_offset"]
size -= impl["_M_start"]["_M_offset"]
else:
start = impl["_M_start"]
finish = impl["_M_finish"]
size = finish - start
check(0 <= size and size <= 1000 * 1000 * 1000)
check(finish <= alloc)
checkPointer(start)
checkPointer(finish)
checkPointer(alloc)
d.putItemCount(size)
d.putNumChild(size)
if d.isExpanded(item):
if isBool:
with Children(d, [size, 10000], type):
for i in d.childRange():
q = start + i / storagesize
data = (q.dereference() >> (i % storagesize)) & 1
d.putBoolItem(str(i), select(data, "true", "false"))
else:
with Children(d, [size, 10000], type):
p = start
for i in d.childRange():
d.putSubItem(Item(p.dereference(), item.iname, i))
p += 1
def qdump__string(d, item):
qdump__std__string(d, item)
def qdump__std__wstring(d, item):
qdump__std__string(d, item)
def qdump__std__basic_string(d, item):
qdump__std__string(d, item)
def qdump__wstring(d, item):
qdump__std__string(d, item)
def qdump____gnu_cxx__hash_set(d, item):
ht = item.value["_M_ht"]
size = ht["_M_num_elements"]
check(0 <= size and size <= 1000 * 1000 * 1000)
d.putItemCount(size)
d.putNumChild(size)
type = templateArgument(item.value.type, 0)
d.putType("__gnu__cxx::hash_set<%s>" % type)
if d.isExpanded(item):
with Children(d, [size, 1000], type):
buckets = ht["_M_buckets"]["_M_impl"]
bucketStart = buckets["_M_start"]
bucketFinish = buckets["_M_finish"]
p = bucketStart
itemCount = 0
for i in xrange(bucketFinish - bucketStart):
if not isNull(p.dereference()):
cur = p.dereference()
while not isNull(cur):
with SubItem(d):
d.putValue(cur["_M_val"])
cur = cur["_M_next"]
itemCount += 1
p = p + 1
#######################################################################
#
# Boost dumper
#
#######################################################################
def qdump__boost__optional(d, item):
if item.value["m_initialized"] == False:
d.putValue("<uninitialized>")
d.putNumChild(0)
else:
d.putType(item.value.type, d.currentTypePriority + 1)
type = templateArgument(item.value.type, 0)
storage = item.value["m_storage"]
if type.code == gdb.TYPE_CODE_REF:
value = storage.cast(type.target().pointer()).dereference()
else:
value = storage.cast(type)
d.putItem(Item(value, item.iname))
#######################################################################
#
# Symbian
#
#######################################################################
def encodeSymbianString(base, size):
s = ""
for i in xrange(size):
val = int(base[i])
if val == 9:
s += "5c007400" # \t
else:
s += "%02x%02x" % (val % 256, val / 256)
return s
def qdump__TBuf(d, item):
size = item.value["iLength"] & 0xffff
base = item.value["iBuf"]
max = numericTemplateArgument(item.value.type, 0)
check(0 <= size and size <= max)
d.putNumChild(0)
d.putValue(encodeSymbianString(base, size), Hex4EncodedLittleEndian)
def qdump__TLitC(d, item):
size = item.value["iTypeLength"] & 0xffff
base = item.value["iBuf"]
max = numericTemplateArgument(item.value.type, 0)
check(0 <= size and size <= max)
d.putNumChild(0)
d.putValue(encodeSymbianString(base, size), Hex4EncodedLittleEndian)
#######################################################################
#
# SSE
#
#######################################################################
def qform____m128():
return "As Floats,As Doubles"
def qdump____m128(d, item):
d.putValue(" ")
d.putNumChild(1)
if d.isExpanded(item):
format = d.itemFormat(item)
if format == 2: # As Double
innerType = lookupType("double")
count = 2
else: # Default, As float
innerType = lookupType("float")
count = 4
p = item.value.address.cast(innerType.pointer())
with Children(d, count, innerType):
for i in xrange(count):
d.putSubItem(Item(p.dereference(), item.iname))
p += 1
#######################################################################
#
# Webkit
#
#######################################################################
def jstagAsString(tag):
# enum { Int32Tag = 0xffffffff };
# enum { CellTag = 0xfffffffe };
# enum { TrueTag = 0xfffffffd };
# enum { FalseTag = 0xfffffffc };
# enum { NullTag = 0xfffffffb };
# enum { UndefinedTag = 0xfffffffa };
# enum { EmptyValueTag = 0xfffffff9 };
# enum { DeletedValueTag = 0xfffffff8 };
if tag == -1:
return "Int32"
if tag == -2:
return "Cell"
if tag == -3:
return "True"
if tag == -4:
return "Null"
if tag == -5:
return "Undefined"
if tag == -6:
return "Empty"
if tag == -7:
return "Deleted"
return "Unknown"
def qdump__QTJSC__JSValue(d, item):
d.putValue(" ")
d.putNumChild(1)
if d.isExpanded(item):
with Children(d):
tag = item.value["u"]["asBits"]["tag"]
payload = item.value["u"]["asBits"]["payload"]
#d.putIntItem("tag", tag)
with SubItem(d):
d.putName("tag")
d.putValue(jstagAsString(long(tag)))
d.putType(" ")
d.putNumChild(0)
d.putIntItem("payload", long(payload))
d.putFields(Item(item.value["u"], item.iname))
if tag == -2:
cellType = lookupType("QTJSC::JSCell").pointer()
d.putSubItem(Item(payload.cast(cellType), item.iname, "cell", "cell"))
try:
# FIXME: This might not always be a variant.
delegateType = lookupType(d.ns + "QScript::QVariantDelegate").pointer()
delegate = scriptObject["d"]["delegate"].cast(delegateType)
#d.putSubItem(Item(delegate, item.iname, "delegate", "delegate"))
variant = delegate["m_value"]
d.putSubItem(Item(variant, item.iname, "variant", "variant"))
except:
pass
def qdump__QScriptValue(d, item):
# structure:
# engine QScriptEnginePrivate
# jscValue QTJSC::JSValue
# next QScriptValuePrivate *
# numberValue 5.5987310416280426e-270 myns::qsreal
# prev QScriptValuePrivate *
# ref QBasicAtomicInt
# stringValue QString
# type QScriptValuePrivate::Type: { JavaScriptCore, Number, String }
#d.putValue(" ")
dd = item.value["d_ptr"]["d"]
if isNull(dd):
d.putValue("(invalid)")
d.putNumChild(0)
return
if long(dd["type"]) == 1: # Number
d.putValue(dd["numberValue"])
d.putType("%sQScriptValue (Number)" % d.ns)
d.putNumChild(0)
return
if long(dd["type"]) == 2: # String
d.putStringValue(dd["stringValue"])
d.putType("%sQScriptValue (String)" % d.ns)
return
d.putType("%sQScriptValue (JSCoreValue)" % d.ns)
x = dd["jscValue"]["u"]
tag = x["asBits"]["tag"]
payload = x["asBits"]["payload"]
#isValid = long(x["asBits"]["tag"]) != -6 # Empty
#isCell = long(x["asBits"]["tag"]) == -2
#warn("IS CELL: %s " % isCell)
#isObject = False
#className = "UNKNOWN NAME"
#if isCell:
# # isCell() && asCell()->isObject();
# # in cell: m_structure->typeInfo().type() == ObjectType;
# cellType = lookupType("QTJSC::JSCell").pointer()
# cell = payload.cast(cellType).dereference()
# dtype = "NO DYNAMIC TYPE"
# try:
# dtype = cell.dynamic_type
# except:
# pass
# warn("DYNAMIC TYPE: %s" % dtype)
# warn("STATUC %s" % cell.type)
# type = cell["m_structure"]["m_typeInfo"]["m_type"]
# isObject = long(type) == 7 # ObjectType;
# className = "UNKNOWN NAME"
#warn("IS OBJECT: %s " % isObject)
#inline bool JSCell::inherits(const ClassInfo* info) const
#for (const ClassInfo* ci = classInfo(); ci; ci = ci->parentClass) {
# if (ci == info)
# return true;
#return false;
try:
# This might already fail for "native" payloads.
scriptObjectType = lookupType(d.ns + "QScriptObject").pointer()
scriptObject = payload.cast(scriptObjectType)
# FIXME: This might not always be a variant.
delegateType = lookupType(d.ns + "QScript::QVariantDelegate").pointer()
delegate = scriptObject["d"]["delegate"].cast(delegateType)
#d.putSubItem(Item(delegate, item.iname, "delegate", "delegate"))
variant = delegate["m_value"]
#d.putSubItem(Item(variant, item.iname, "variant", "variant"))
t = qdump__QVariant(d, Item(variant, "variant"))
# Override the "QVariant (foo)" output
d.putType("%sQScriptValue (%s)" % (d.ns, t), d.currentTypePriority + 1)
if t != "JSCoreValue":
return
except:
pass
# This is a "native" JSCore type for e.g. QDateTime.
d.putValue("<native>")
d.putNumChild(1)
if d.isExpanded(item):
with Children(d):
d.putSubItem(Item(dd["jscValue"], item.iname, "jscValue", "jscValue"))
#######################################################################
#
# Display Test
#
#######################################################################
if False:
# FIXME: Make that work
def qdump__Color(d, item):
v = item.value
d.putValue("(%s, %s, %s; %s)" % (v["r"], v["g"], v["b"], v["a"]))
if d.isExpanded(item):
with Children(d):
d.putSubItem(Item(v["r"], item.iname, "0", "r"))
d.putSubItem(Item(v["g"], item.iname, "1", "g"))
d.putSubItem(Item(v["b"], item.iname, "2", "b"))
d.putSubItem(Item(v["a"], item.iname, "3", "a"))
def qdump__Color_(d, item):
v = item.value
d.putValue("(%s, %s, %s; %s)" % (v["r"], v["g"], v["b"], v["a"]))
if d.isExpanded(item):
with Children(d):
with SubItem(d):
d.putField("iname", item.iname + ".0")
d.putItem(Item(v["r"], item.iname, "0", "r"))
with SubItem(d):
d.putField("iname", item.iname + ".1")
d.putItem(Item(v["g"], item.iname, "1", "g"))
with SubItem(d):
d.putField("iname", item.iname + ".2")
d.putItem(Item(v["b"], item.iname, "2", "b"))
with SubItem(d):
d.putField("iname", item.iname + ".3")
d.putItem(Item(v["a"], item.iname, "3", "a"))
def qdump__Function(d, item):
min = item.value["min"]
max = item.value["max"]
var = extractByteArray(item.value["var"])
f = extractByteArray(item.value["f"])
d.putValue("%s, %s=%f..%f" % (f, var, min, max))
d.putNumChild(0)
d.putField("typeformats", "Normal,Displayed");
format = d.itemFormat(item)
if format == 0:
d.putDisplay(StopDisplay)
elif format == 1:
input = "plot [%s=%f:%f] %s" % (var, min, max, f)
d.putDisplay(DisplayProcess, input, "gnuplot")