Commit fdde69a5 authored by hjk's avatar hjk

Debugger: Add dumper for various QJson* classes

Needed to debug the QmlDebugger.

Change-Id: Ia0b50dac2146fcc81990b78eb8de30c8e763bba2
Reviewed-by: default avatarChristian Stenger <christian.stenger@theqtcompany.com>
parent 98c31cfc
......@@ -751,6 +751,12 @@ class Dumper(DumperBase):
def extractUInt(self, addr):
return struct.unpack("I", self.readRawMemory(addr, 4))[0]
def extractShort(self, addr):
return struct.unpack("h", self.readRawMemory(addr, 2))[0]
def extractUShort(self, addr):
return struct.unpack("H", self.readRawMemory(addr, 2))[0]
def extractByte(self, addr):
return struct.unpack("b", self.readRawMemory(addr, 1))[0]
......
......@@ -505,6 +505,16 @@ class Dumper(DumperBase):
def addressOf(self, value):
return int(value.GetLoadAddress())
def extractUShort(self, address):
error = lldb.SBError()
return int(self.process.ReadUnsignedFromMemory(address, 2, error))
def extractShort(self, address):
i = self.extractUInt(address)
if i >= 0x8000:
i -= 0x10000
return i
def extractUInt(self, address):
error = lldb.SBError()
return int(self.process.ReadUnsignedFromMemory(address, 4, error))
......
......@@ -2499,3 +2499,200 @@ def qdump__QQmlAccessorProperties__Properties(d, value):
d.putItemCount(size)
if d.isExpanded():
d.putArrayData(value["properties"], size)
#
# QJson
#
def qdumpHelper_qle_cutBits(value, offset, length):
return (value >> offset) & ((1 << length) - 1)
def qdump__QJsonPrivate__qle_bitfield(d, value):
offset = d.numericTemplateArgument(value.type, 0)
length = d.numericTemplateArgument(value.type, 1)
val = toInteger(value["val"])
d.putValue("%s" % qdumpHelper_qle_cutBits(val, offset, length))
d.putNumChild(0)
def qdumpHelper_qle_signedbitfield_value(d, value):
offset = d.numericTemplateArgument(value.type, 0)
length = d.numericTemplateArgument(value.type, 1)
val = toInteger(value["val"])
val = (val >> offset) & ((1 << length) - 1)
if val >= (1 << (length - 1)):
val -= (1 << (length - 1))
return val
def qdump__QJsonPrivate__qle_signedbitfield(d, value):
d.putValue("%s" % qdumpHelper_qle_signedbitfield_value(d, value))
d.putNumChild(0)
def qdump__QJsonPrivate__q_littleendian(d, value):
d.putValue("%s" % toInteger(value["val"]))
d.putNumChild(0)
def qdumpHelper__QJsonValue(d, data, base, pv):
"""
Parameters are the parameters to the
QJsonValue(QJsonPrivate::Data *data, QJsonPrivate::Base *base,
const QJsonPrivate::Value& pv)
constructor. We "inline" the construction here.
data is passed as pointer integer
base is passed as pointer integer
pv is passed as 32 bit integer.
"""
t = qdumpHelper_qle_cutBits(pv, 0, 3)
v = qdumpHelper_qle_cutBits(pv, 5, 27)
latinOrIntValue = qdumpHelper_qle_cutBits(pv, 3, 1)
if t == 0:
d.putType("QJsonValue (Null)")
d.putValue("Null")
d.putNumChild(0)
return
if t == 1:
d.putType("QJsonValue (Bool)")
d.putValue("true" if v else "false")
d.putNumChild(0)
return
if t == 2:
d.putType("QJsonValue (Number)")
if latinOrIntValue:
d.putValue(v)
else:
data = base + v;
d.putValue(d.extractBlob(data, 8).extractDouble())
d.putNumChild(0)
return
if t == 3:
d.putType("QJsonValue (String)")
data = base + v;
if latinOrIntValue:
length = d.extractUShort(data)
d.putValue(d.readMemory(data + 2, length), Hex2EncodedLatin1)
else:
length = d.extractUInt(data)
d.putValue(d.readMemory(data + 4, length * 2), Hex4EncodedLittleEndian)
d.putNumChild(1)
return
if t == 4:
d.putType("QJsonValue (Array)")
qdumpHelper__QJsonArray(d, data, base + v)
return
if t == 5:
d.putType("QJsonValue (Object)")
qdumpHelper__QJsonObject(d, data, base + v)
d.putNumChild(0)
def qdumpHelper__QJsonArray(d, data, array):
"""
Parameters are the parameters to the
QJsonArray(QJsonPrivate::Data *data, QJsonPrivate::Array *array)
constructor. We "inline" the construction here.
array is passed as integer pointer to the QJsonPrivate::Base object.
"""
if d.isNull(data):
n = 0
else:
# The 'length' part of the _dummy member:
n = qdumpHelper_qle_cutBits(d.extractUInt(array + 4), 1, 31)
d.putItemCount(n)
d.putNumChild(1)
if d.isExpanded():
with Children(d):
table = array + d.extractUInt(array + 8)
for i in range(n):
with SubItem(d, i):
qdumpHelper__QJsonValue(d, data, array, d.extractUInt(table + 4 * i))
def qdumpHelper__QJsonObject(d, data, obj):
"""
Parameters are the parameters to the
QJsonObject(QJsonPrivate::Data *data, QJsonPrivate::Object *object);
constructor. We "inline" the construction here.
obj is passed as integer pointer to the QJsonPrivate::Base object.
"""
if d.isNull(data):
n = 0
else:
# The 'length' part of the _dummy member:
n = qdumpHelper_qle_cutBits(d.extractUInt(obj + 4), 1, 31)
d.putItemCount(n)
d.putNumChild(1)
if d.isExpanded():
with Children(d):
table = obj + d.extractUInt(obj + 8)
for i in range(n):
with SubItem(d, i):
entryPtr = table + 4 * i # entryAt(i)
entryStart = obj + d.extractUInt(entryPtr) # Entry::value
keyStart = entryStart + 4 # sizeof(QJsonPrivate::Entry) == 4
val = d.extractInt(entryStart)
key = d.extractInt(keyStart)
isLatinKey = qdumpHelper_qle_cutBits(val, 4, 1)
if isLatinKey:
keyLength = d.extractUShort(keyStart)
d.put('key="%s",' % d.readMemory(keyStart + 2, keyLength))
d.put('keyencoded="%s",' % Hex2EncodedLatin1)
else:
keyLength = d.extractUInt(keyStart)
d.put('key="%s",' % d.readMemory(keyStart + 4, keyLength))
d.put('keyencoded="%s",' % Hex4EncodedLittleEndian)
qdumpHelper__QJsonValue(d, data, obj, val)
def qdump__QJsonValue(d, value):
t = toInteger(value["t"])
if t == 0:
d.putType("QJsonValue (Null)")
d.putValue("Null")
d.putNumChild(0)
return
if t == 1:
d.putType("QJsonValue (Bool)")
v = toInteger(value["b"])
d.putValue("true" if v else "false")
return
if t == 2:
d.putType("QJsonValue (Number)")
d.putValue(value["dbl"])
return
if t == 3:
d.putType("QJsonValue (String)")
d.putStringValueByAddress(toInteger(value["stringData"]))
d.putNumChild(0)
return
if t == 4:
d.putType("QJsonValue (Array)")
qdumpHelper__QJsonArray(d, toInteger(value["d"]), toInteger(value["base"]))
return
if t == 5:
d.putType("QJsonValue (Object)")
qdumpHelper__QJsonObject(d, toInteger(value["d"]), toInteger(value["base"]))
return
d.putType("QJsonValue (Undefined)")
d.putEmptyValue()
d.putNumChild(0)
def qdump__QJsonArray(d, value):
qdumpHelper__QJsonArray(d, toInteger(value["d"]), toInteger(value["a"]))
def qdump__QJsonObject(d, value):
qdumpHelper__QJsonObject(d, toInteger(value["d"]), toInteger(value["o"]))
......@@ -5806,6 +5806,63 @@ void tst_Dumpers::dumper_data()
+ GuiProfile()
+ Check("pol", "<5 items>", "@QPolygonF")
+ Check("p", "<5 items>", "@QGraphicsPolygonItem");
QTest::newRow("QJson")
<< Data("#include <QJsonObject>\n"
"#include <QJsonArray>\n"
"#include <QJsonValue>\n"
"#include <QVariantMap>\n",
"QJsonObject ob = QJsonObject::fromVariantMap({\n"
" {\"a\", 1},\n"
" {\"bb\", 2},\n"
" {\"ccc\", \"hallo\"},\n"
" {\"s\", \"ssss\"}\n"
"});\n"
"ob.insert(QLatin1String(\"d\"), QJsonObject::fromVariantMap({{\"ddd\", 1234}}));\n"
"\n"
"QJsonArray a;\n"
"a.append(QJsonValue(1));\n"
"a.append(QJsonValue(\"asd\"));\n"
"a.append(QJsonValue(QString::fromLatin1(\"cdfer\")));\n"
"a.append(QJsonValue(1.4));\n"
"a.append(QJsonValue(true));\n"
"a.append(ob);\n"
"\n"
"QJsonArray b;\n"
"b.append(QJsonValue(1));\n"
"b.append(a);\n"
"b.append(QJsonValue(2));\n"
"\n"
"unused(&ob,&b,&a);\n")
+ Cxx11Profile()
+ Check("a", "<6 items>", "@QJsonArray")
+ Check("a.0", "[0]", "1", "QJsonValue (Number)")
+ Check("a.1", "[1]", "\"asd\"", "QJsonValue (String)")
+ Check("a.2", "[2]", "\"cdfer\"", "QJsonValue (String)")
+ Check("a.3", "[3]", "1.4", "QJsonValue (Number)")
+ Check("a.4", "[4]", "true", "QJsonValue (Bool)")
+ Check("a.5", "[5]", "<5 items>", "QJsonValue (Object)")
+ Check("a.5.0", "\"a\"", "1", "QJsonValue (Number)")
+ Check("a.5.1", "\"bb\"", "2", "QJsonValue (Number)")
+ Check("a.5.2", "\"ccc\"", "\"hallo\"", "QJsonValue (String)")
+ Check("a.5.3", "\"d\"", "<1 items>", "QJsonValue (Object)")
+ Check("a.5.4", "\"s\"", "\"ssss\"", "QJsonValue (String)")
+ Check("b", "b", "<3 items>" , "@QJsonArray")
+ Check("b.0", "[0]", "1", "QJsonValue (Number)")
+ Check("b.1", "[1]", "<6 items>", "QJsonValue (Array)")
+ Check("b.1.0", "[0]", "1", "QJsonValue (Number)")
+ Check("b.1.1", "[1]", "\"asd\"", "QJsonValue (String)")
+ Check("b.1.2", "[2]", "\"cdfer\"", "QJsonValue (String)")
+ Check("b.1.3", "[3]", "1.4", "QJsonValue (Number)")
+ Check("b.1.4", "[4]", "true", "QJsonValue (Bool)")
+ Check("b.1.5", "[5]", "<5 items>", "QJsonValue (Object)")
+ Check("b.2", "[2]", "2", "QJsonValue (Number)")
+ Check("ob", "ob", "<5 items>", "@QJsonObject")
+ Check("ob.0", "\"a\"", "1", "QJsonValue (Number)")
+ Check("ob.1", "\"bb\"", "2", "QJsonValue (Number)")
+ Check("ob.2", "\"ccc\"", "\"hallo\"", "QJsonValue (String)")
+ Check("ob.3", "\"d\"", "<1 items>", "QJsonValue (Object)")
+ Check("ob.4", "\"s\"", "\"ssss\"", "QJsonValue (String)");
}
int main(int argc, char *argv[])
......
Markdown is supported
0% or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment