Commit 71c3d097 authored by hjk's avatar hjk

debugger: try make custom dumpers more "user friendly"

Introduce Dumper.put{Value,Name,StringValue,ByteArrayValue} functions.
No need for explicit specification of valueencoding in user code.
parent 4bac4969
...@@ -123,6 +123,44 @@ def qtNamespace(): ...@@ -123,6 +123,44 @@ def qtNamespace():
except RuntimeError: except RuntimeError:
return "" return ""
def encodeByteArray(value):
d_ptr = value['d'].dereference()
data = d_ptr['data']
size = d_ptr['size']
alloc = d_ptr['alloc']
check(0 <= size and size <= alloc and alloc <= 100*1000*1000)
check(d_ptr["ref"]["_q_value"] > 0)
if size > 0:
checkAccess(data, 4)
checkAccess(data + size) == 0
innerType = gdb.lookup_type("char")
p = gdb.Value(data.cast(innerType.pointer()))
s = ""
for i in xrange(0, size):
s += "%02x" % int(p.dereference())
p += 1
return s
def encodeString(value):
d_ptr = value['d'].dereference()
data = d_ptr['data']
size = d_ptr['size']
alloc = d_ptr['alloc']
check(0 <= size and size <= alloc and alloc <= 100*1000*1000)
if size > 0:
checkAccess(data, 4)
checkAccess(data + size * 2) == 0
check(d_ptr["ref"]["_q_value"] > 0)
p = gdb.Value(d_ptr["data"])
s = ""
for i in xrange(0, size):
val = int(p.dereference())
s += "%02x" % (val % 256)
s += "%02x" % (val / 256)
p += 1
return s
####################################################################### #######################################################################
# #
# Item # Item
...@@ -347,6 +385,26 @@ class Dumper: ...@@ -347,6 +385,26 @@ class Dumper:
if int(numchild) != int(self.childNumChilds[-1]): if int(numchild) != int(self.childNumChilds[-1]):
self.putField("numchild", numchild) self.putField("numchild", numchild)
def putValue(self, value, encoding = None):
if not encoding is None:
self.putField("valueencoded", encoding)
self.putField("value", value)
def putStringValue(self, value):
str = encodeString(value)
self.putCommaIfNeeded()
self.put('valueencoded="%d",value="%s"' % (7, str))
def putByteArrayValue(self, value):
str = encodeByteArray(value)
self.putCommaIfNeeded()
self.put('valueencoded="%d",value="%s"' % (6, str))
def putName(self, name):
self.putCommaIfNeeded()
self.put('name="%s"' % name)
def isExpanded(self, item): def isExpanded(self, item):
#warn("IS EXPANDED: %s in %s" % (item.iname, self.expandedINames)) #warn("IS EXPANDED: %s in %s" % (item.iname, self.expandedINames))
if item.iname is None: if item.iname is None:
...@@ -383,16 +441,16 @@ class Dumper: ...@@ -383,16 +441,16 @@ class Dumper:
def putIntItem(self, name, value): def putIntItem(self, name, value):
self.beginHash() self.beginHash()
self.putField("name", name) self.putName(name)
self.putField("value", value) self.putValue(value)
self.putType("int") self.putType("int")
self.putNumChild(0) self.putNumChild(0)
self.endHash() self.endHash()
def putBoolItem(self, name, value): def putBoolItem(self, name, value):
self.beginHash() self.beginHash()
self.putField("name", name) self.putName(name)
self.putField("value", value) self.putValue(value)
self.putType("bool") self.putType("bool")
self.putNumChild(0) self.putNumChild(0)
self.endHash() self.endHash()
...@@ -402,9 +460,9 @@ class Dumper: ...@@ -402,9 +460,9 @@ class Dumper:
self.safeoutput += self.output self.safeoutput += self.output
self.output = "" self.output = ""
def dumpInnerValueHelper(self, item, field = "value"): def dumpInnerValueHelper(self, item):
if isSimpleType(item.value.type): if isSimpleType(item.value.type):
self.safePutItemHelper(item, field) self.safePutItemHelper(item)
def safePutItemHelper(self, item): def safePutItemHelper(self, item):
self.pushOutput() self.pushOutput()
...@@ -429,10 +487,10 @@ class Dumper: ...@@ -429,10 +487,10 @@ class Dumper:
#warn("Exception.") #warn("Exception.")
#for line in tb: #for line in tb:
# warn("%s" % line) # warn("%s" % line)
self.putField("name", item.name) self.putName(item.name)
self.putField("value", "<invalid>") self.putValue("<invalid>")
self.putField("type", str(item.value.type)) self.putType(str(item.value.type))
self.putField("numchild", "0") self.putNumChild(0)
#if self.isExpanded(item): #if self.isExpanded(item):
self.beginChildren() self.beginChildren()
self.endChildren() self.endChildren()
...@@ -459,16 +517,16 @@ class Dumper: ...@@ -459,16 +517,16 @@ class Dumper:
self.putItemOrPointerHelper( self.putItemOrPointerHelper(
Item(item.value.dereference(), item.iname, None, None)) Item(item.value.dereference(), item.iname, None, None))
else: else:
self.putField("value", "(null)") self.putValue("(null)")
self.putField("numchild", "0") self.putNumChild(0)
else: else:
self.safePutItemHelper(item) self.safePutItemHelper(item)
def putItemHelper(self, item, field = "value"): def putItemHelper(self, item):
name = getattr(item, "name", None) name = getattr(item, "name", None)
if not name is None: if not name is None:
self.putField("name", name) self.putName(name)
self.putType(item.value.type) self.putType(item.value.type)
# FIXME: Gui shows references stripped? # FIXME: Gui shows references stripped?
...@@ -494,16 +552,15 @@ class Dumper: ...@@ -494,16 +552,15 @@ class Dumper:
#warn(" DUMPERS: %s" % (strippedType in self.dumpers)) #warn(" DUMPERS: %s" % (strippedType in self.dumpers))
if isSimpleType(type): if isSimpleType(type):
self.putField(field, value) self.putValue(value)
if field == "value": self.putNumChild(0)
self.putNumChild(0)
elif strippedType in self.dumpers: elif strippedType in self.dumpers:
self.dumpers[strippedType](self, item) self.dumpers[strippedType](self, item)
elif type.code == gdb.TYPE_CODE_ENUM: elif type.code == gdb.TYPE_CODE_ENUM:
#warn("GENERIC ENUM: %s" % value) #warn("GENERIC ENUM: %s" % value)
self.putField(field, value) self.putValue(value)
self.putNumChild(0) self.putNumChild(0)
...@@ -511,7 +568,7 @@ class Dumper: ...@@ -511,7 +568,7 @@ class Dumper:
isHandled = False isHandled = False
#warn("GENERIC POINTER: %s" % value) #warn("GENERIC POINTER: %s" % value)
if isNull(value): if isNull(value):
self.putField(field, "0x0") self.putValue("0x0")
self.putNumChild(0) self.putNumChild(0)
isHandled = True isHandled = True
...@@ -524,8 +581,8 @@ class Dumper: ...@@ -524,8 +581,8 @@ class Dumper:
for i in xrange(0, 10): for i in xrange(0, 10):
if p.dereference() == 0: if p.dereference() == 0:
# Found terminating NUL # Found terminating NUL
self.putField("%sencoded" % field, "6") self.putField("valueencoded", "6")
self.put(',%s="' % field) self.put(',value="')
p = value p = value
for j in xrange(0, i): for j in xrange(0, i):
self.put('%02x' % int(p.dereference())) self.put('%02x' % int(p.dereference()))
...@@ -539,11 +596,17 @@ class Dumper: ...@@ -539,11 +596,17 @@ class Dumper:
if not isHandled: if not isHandled:
# Generic pointer type. # Generic pointer type.
#warn("GENERIC POINTER: %s" % value) #warn("GENERIC POINTER: %s" % value)
self.putField(field, str(value.address))
if self.isExpanded(item): if self.isExpanded(item):
#warn("GENERIC POINTER: %s" % item.value.type.target())
self.put(',')
# Temporary change to target type.
self.childTypes.append(
stripClassTag(str(item.value.type.target())))
self.putItemOrPointerHelper( self.putItemOrPointerHelper(
Item(item.value.dereference(), item.iname, None, None)) Item(item.value.dereference(), item.iname, None, None))
self.childTypes.pop()
else: else:
self.putValue(str(value.address))
self.putNumChild(1) self.putNumChild(1)
else: else:
...@@ -556,7 +619,7 @@ class Dumper: ...@@ -556,7 +619,7 @@ class Dumper:
#fields = value.type.fields() #fields = value.type.fields()
fields = value.type.strip_typedefs().fields() fields = value.type.strip_typedefs().fields()
self.putField("value", "{...}") self.putValue("{...}")
if False: if False:
numfields = 0 numfields = 0
...@@ -607,9 +670,8 @@ class Dumper: ...@@ -607,9 +670,8 @@ class Dumper:
child.name = "<anon>" child.name = "<anon>"
self.beginHash() self.beginHash()
#d.putField("iname", child.iname) #d.putField("iname", child.iname)
#d.putField("name", child.name) #d.putName(child.name)
#d.putType(child.value.type) #d.putType(child.value.type)
self.safePutItemHelper(child) self.safePutItemHelper(child)
self.endHash() self.endHash()
self.endChildren() self.endChildren()
This diff is collapsed.
...@@ -1924,19 +1924,19 @@ void tst_Gdb::dump_QObject() ...@@ -1924,19 +1924,19 @@ void tst_Gdb::dump_QObject()
"value='0x0',numchild='0'}," "value='0x0',numchild='0'},"
"{name='children',type='-'," // NS"QObject{Data,}::QObjectList'," "{name='children',type='-'," // NS"QObject{Data,}::QObjectList',"
"value='<0 items>',numchild='0',children=[]}," "value='<0 items>',numchild='0',children=[]},"
"{name='properties',value='<1 items>',type='',numchild='1',children=[" "{name='properties',value='<1 items>',type=' ',numchild='1',children=["
"{name='objectName',type='"NS"QString',valueencoded='7'," "{name='objectName',type='"NS"QString',valueencoded='7',"
"value='41006e0020004f0062006a00650063007400',numchild='0'}]}," "value='41006e0020004f0062006a00650063007400',numchild='0'}]},"
"{name='connections',value='<0 items>',type='',numchild='0'," "{name='connections',value='<0 items>',type=' ',numchild='0',"
"children=[]}," "children=[]},"
"{name='signals',value='<2 items>',type='',numchild='2'," "{name='signals',value='<2 items>',type=' ',numchild='2',"
"childnumchild='0',children=[" "childnumchild='0',children=["
"{name='signal 0',type='',value='destroyed(QObject*)'}," "{name='signal 0',type=' ',value='destroyed(QObject*)'},"
"{name='signal 1',type='',value='destroyed()'}]}," "{name='signal 1',type=' ',value='destroyed()'}]},"
"{name='slots',value='<2 items>',type='',numchild='2'," "{name='slots',value='<2 items>',type=' ',numchild='2',"
"childnumchild='0',children=[" "childnumchild='0',children=["
"{name='slot 0',type='',value='deleteLater()'}," "{name='slot 0',type=' ',value='deleteLater()'},"
"{name='slot 1',type='',value='_q_reregisterTimers(void*)'}]}]}", "{name='slot 1',type=' ',value='_q_reregisterTimers(void*)'}]}]}",
"local.ob" "local.ob"
",local.ob.children" ",local.ob.children"
",local.ob.properties" ",local.ob.properties"
......
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