forked from qt-creator/qt-creator
debugger: rework error handling in python dumpers
This commit is contained in:
@@ -137,6 +137,131 @@ def catchCliOutput(command):
|
||||
return lines
|
||||
|
||||
|
||||
def showException(msg, exType, exValue, exTraceback):
|
||||
warn("**** CAUGHT EXCEPTION: %s ****" % msg)
|
||||
try:
|
||||
import traceback
|
||||
for line in traceback.format_exception(exType, exValue, exTraceback):
|
||||
warn("%s" % line)
|
||||
except:
|
||||
pass
|
||||
|
||||
|
||||
class OutputSafer:
|
||||
def __init__(self, d, pre = "", post = ""):
|
||||
self.d = d
|
||||
self.pre = pre
|
||||
self.post = post
|
||||
|
||||
def __enter__(self):
|
||||
self.d.put(self.pre)
|
||||
self.savedOutput = self.d.output
|
||||
self.d.output = ""
|
||||
|
||||
def __exit__(self, exType, exValue, exTraceBack):
|
||||
self.d.put(self.post)
|
||||
if self.d.passExceptions and not exType is None:
|
||||
showException("OUTPUTSAFER", exType, exValue, exTraceBack)
|
||||
self.d.output = self.savedOutput
|
||||
else:
|
||||
self.d.output = self.savedOutput + self.d.output
|
||||
return False
|
||||
|
||||
|
||||
class SubItem:
|
||||
def __init__(self, d):
|
||||
self.d = d
|
||||
|
||||
def __enter__(self):
|
||||
self.d.put('{')
|
||||
self.savedValue = self.d.currentValue
|
||||
self.savedValuePriority = self.d.currentValuePriority
|
||||
self.savedValueEncoding = self.d.currentValueEncoding
|
||||
self.savedType = self.d.currentType
|
||||
self.savedTypePriority = self.d.currentTypePriority
|
||||
self.d.currentValue = ""
|
||||
self.d.currentValuePriority = 0
|
||||
self.d.currentValueEncoding = None
|
||||
self.d.currentType = ""
|
||||
self.d.currentTypePriority = 0
|
||||
|
||||
def __exit__(self, exType, exValue, exTraceBack):
|
||||
#warn(" CURRENT VALUE: %s %s %s" % (self.d.currentValue,
|
||||
# self.d.currentValueEncoding, self.d.currentValuePriority))
|
||||
if self.d.passExceptions and not exType is None:
|
||||
showException("SUBITEM", exType, exValue, exTraceBack)
|
||||
if not self.d.currentValueEncoding is None:
|
||||
self.d.putField("valueencoded", self.d.currentValueEncoding)
|
||||
if not self.d.currentValue is None:
|
||||
self.d.putField("value", self.d.currentValue)
|
||||
#warn("TYPE CURRENT: %s" % self.d.currentType)
|
||||
type = stripClassTag(str(self.d.currentType))
|
||||
#warn("TYPE: '%s' DEFAULT: '%s'" % (type, self.d.currentChildType))
|
||||
if len(type) > 0 and type != self.d.currentChildType:
|
||||
self.d.put('type="%s",' % type) # str(type.unqualified()) ?
|
||||
self.d.put('},')
|
||||
self.d.currentValue = self.savedValue
|
||||
self.d.currentValuePriority = self.savedValuePriority
|
||||
self.d.currentValueEncoding = self.savedValueEncoding
|
||||
self.d.currentType = self.savedType
|
||||
self.d.currentTypePriority = self.savedTypePriority
|
||||
return True
|
||||
|
||||
|
||||
class Children:
|
||||
def __init__(self, d, numChild = 1, childType = None, childNumChild = None):
|
||||
self.d = d
|
||||
self.numChild = numChild
|
||||
self.childType = childType
|
||||
self.childNumChild = childNumChild
|
||||
#warn("CHILDREN: %s %s %s" % (numChild, childType, childNumChild))
|
||||
|
||||
def __enter__(self):
|
||||
childType = ""
|
||||
childNumChild = -1
|
||||
if type(self.numChild) is list:
|
||||
numChild = self.numChild[0]
|
||||
maxNumChild = self.numChild[1]
|
||||
else:
|
||||
numChild = self.numChild
|
||||
maxNumChild = self.numChild
|
||||
if numChild == 0:
|
||||
self.childType = None
|
||||
if not self.childType is None:
|
||||
childType = stripClassTag(str(self.childType))
|
||||
self.d.put('childtype="%s",' % childType)
|
||||
if isSimpleType(self.childType) or isStringType(self.d, self.childType):
|
||||
self.d.put('childnumchild="0",')
|
||||
childNumChild = 0
|
||||
elif self.childType.code == gdb.TYPE_CODE_PTR:
|
||||
self.d.put('childnumchild="1",')
|
||||
childNumChild = 1
|
||||
if not self.childNumChild is None:
|
||||
self.d.put('childnumchild="%s",' % self.childNumChild)
|
||||
childNumChild = self.childNumChild
|
||||
self.savedChildType = self.d.currentChildType
|
||||
self.savedChildNumChild = self.d.currentChildNumChild
|
||||
self.savedNumChilds = self.d.currentNumChilds
|
||||
self.savedMaxNumChilds = self.d.currentNumChilds
|
||||
self.d.currentChildType = childType
|
||||
self.d.currentChildNumChild = childNumChild
|
||||
self.d.currentNumChilds = numChild
|
||||
self.d.currentMaxNumChilds = maxNumChild
|
||||
self.d.put("children=[")
|
||||
|
||||
def __exit__(self, exType, exValue, exTraceBack):
|
||||
if self.d.passExceptions and not exType is None:
|
||||
showException("CHILDREN", exType, exValue, exTraceBack)
|
||||
if self.d.currentMaxNumChilds < self.d.currentNumChilds:
|
||||
self.d.putEllipsis();
|
||||
self.d.currentChildType = self.savedChildType
|
||||
self.d.currentChildNumChild = self.savedChildNumChild
|
||||
self.d.currentNumChilds = self.savedNumChilds
|
||||
self.d.currentMaxNumChilds = self.savedMaxNumChilds
|
||||
self.d.put('],')
|
||||
return True
|
||||
|
||||
|
||||
class Breakpoint:
|
||||
def __init__(self):
|
||||
self.number = None
|
||||
@@ -345,7 +470,7 @@ def listOfLocals(varList):
|
||||
# like 'Warning: can't find linker symbol for virtual table for
|
||||
# `std::less<char const*>' value\n\nwarning: found
|
||||
# `myns::QHashData::shared_null' instead [...]
|
||||
# that break subsequent parsing. Chicken out and take the
|
||||
# that break subsequent parsing. Chicken out and take the
|
||||
# next "usable" line.
|
||||
continue
|
||||
items.append(item)
|
||||
@@ -447,6 +572,8 @@ movableTypes = set([
|
||||
def stripClassTag(type):
|
||||
if type.startswith("class "):
|
||||
return type[6:]
|
||||
elif type.startswith("struct "):
|
||||
return type[7:]
|
||||
return type
|
||||
|
||||
def checkPointerRange(p, n):
|
||||
@@ -461,7 +588,11 @@ def call(value, func):
|
||||
type = "'" + type + "'"
|
||||
exp = "((%s*)%s)->%s" % (type, value.address, func)
|
||||
#warn("CALL: %s" % exp)
|
||||
result = parseAndEvaluate(exp)
|
||||
result = None
|
||||
try:
|
||||
result = parseAndEvaluate(exp)
|
||||
except:
|
||||
pass
|
||||
#warn(" -> %s" % result)
|
||||
return result
|
||||
|
||||
@@ -684,6 +815,7 @@ class FrameCommand(gdb.Command):
|
||||
# Locals
|
||||
#
|
||||
for item in listOfLocals(varList):
|
||||
with OutputSafer(d, "", ""):
|
||||
d.anonNumber = -1
|
||||
#warn("ITEM NAME %s: " % item.name)
|
||||
try:
|
||||
@@ -695,14 +827,13 @@ class FrameCommand(gdb.Command):
|
||||
pass
|
||||
except:
|
||||
# Locals with failing memory access.
|
||||
d.beginHash()
|
||||
d.put('iname="%s",' % item.iname)
|
||||
d.put('name="%s",' % item.name)
|
||||
d.put('addr="<not accessible>",')
|
||||
d.put('value="<not accessible>",')
|
||||
d.put('type="%s",' % item.value.type)
|
||||
d.put('numchild="0"');
|
||||
d.endHash()
|
||||
with SubItem(d):
|
||||
d.put('iname="%s",' % item.iname)
|
||||
d.put('name="%s",' % item.name)
|
||||
d.put('addr="<not accessible>",')
|
||||
d.put('value="<not accessible>",')
|
||||
d.put('type="%s",' % item.value.type)
|
||||
d.put('numchild="0"');
|
||||
continue
|
||||
|
||||
type = item.value.type
|
||||
@@ -717,74 +848,56 @@ class FrameCommand(gdb.Command):
|
||||
p += 1
|
||||
n += 1
|
||||
|
||||
d.beginHash()
|
||||
d.put('iname="%s",' % item.iname)
|
||||
d.putName(item.name)
|
||||
d.putItemCount(select(n <= 100, n, "> 100"))
|
||||
d.putType(type)
|
||||
d.putNumChild(n)
|
||||
if d.isExpanded(item):
|
||||
p = item.value
|
||||
d.beginChildren(n)
|
||||
for i in xrange(n):
|
||||
value = p.dereference()
|
||||
d.putItem(Item(value, item.iname, i, None))
|
||||
p += 1
|
||||
if n > 100:
|
||||
d.putEllipsis()
|
||||
d.endChildren()
|
||||
d.endHash()
|
||||
with SubItem(d):
|
||||
d.put('iname="%s",' % item.iname)
|
||||
d.putName(item.name)
|
||||
d.putItemCount(select(n <= 100, n, "> 100"))
|
||||
d.putType(type)
|
||||
d.putNumChild(n)
|
||||
if d.isExpanded(item):
|
||||
p = item.value
|
||||
with Children(d, n):
|
||||
for i in xrange(n):
|
||||
value = p.dereference()
|
||||
d.putItem(Item(value, item.iname, i, None))
|
||||
p += 1
|
||||
if n > 100:
|
||||
d.putEllipsis()
|
||||
|
||||
else:
|
||||
# A "normal" local variable or parameter.
|
||||
try:
|
||||
addr = cleanAddress(item.value.address)
|
||||
d.beginHash()
|
||||
d.put('iname="%s",' % item.iname)
|
||||
d.put('addr="%s",' % addr)
|
||||
d.safePutItemHelper(item)
|
||||
d.endHash()
|
||||
with SubItem(d):
|
||||
d.put('iname="%s",' % item.iname)
|
||||
d.put('addr="%s",' % addr)
|
||||
d.putItemHelper(item)
|
||||
except AttributeError:
|
||||
# Thrown by cleanAddress with message "'NoneType' object
|
||||
# has no attribute 'cast'" for optimized-out values.
|
||||
d.beginHash()
|
||||
d.put('iname="%s",' % item.iname)
|
||||
d.put('name="%s",' % item.name)
|
||||
d.put('addr="<optimized out>",')
|
||||
d.put('value="<optimized out>",')
|
||||
d.put('type="%s"' % item.value.type)
|
||||
d.endHash()
|
||||
|
||||
d.pushOutput()
|
||||
locals = d.safeoutput
|
||||
|
||||
with SubItem(d):
|
||||
d.put('iname="%s",' % item.iname)
|
||||
d.put('name="%s",' % item.name)
|
||||
d.put('addr="<optimized out>",')
|
||||
d.put('value="<optimized out>",')
|
||||
d.put('type="%s"' % item.value.type)
|
||||
|
||||
#
|
||||
# Watchers
|
||||
#
|
||||
d.safeoutput = ""
|
||||
if len(watchers) > 0:
|
||||
for watcher in watchers.split("##"):
|
||||
(exp, iname) = watcher.split("#")
|
||||
self.handleWatch(d, exp, iname)
|
||||
d.pushOutput()
|
||||
watchers = d.safeoutput
|
||||
|
||||
sep = ""
|
||||
if len(locals) and len(watchers):
|
||||
sep = ","
|
||||
with OutputSafer(d, ",", ""):
|
||||
if len(watchers) > 0:
|
||||
for watcher in watchers.split("##"):
|
||||
(exp, iname) = watcher.split("#")
|
||||
self.handleWatch(d, exp, iname)
|
||||
|
||||
#
|
||||
# Breakpoints
|
||||
#
|
||||
#breakpoints = ""
|
||||
#d.safeoutput = ""
|
||||
#listOfBreakpoints(d)
|
||||
#d.pushOutput()
|
||||
#breakpoints = d.safeoutput
|
||||
|
||||
#print('data=[' + locals + sep + watchers + '],bkpts=[' + breakpoints + ']\n')
|
||||
print('data=[' + locals + sep + watchers + ']\n')
|
||||
print('data=[' + d.output + ']')
|
||||
|
||||
|
||||
def handleWatch(self, d, exp, iname):
|
||||
@@ -793,49 +906,46 @@ class FrameCommand(gdb.Command):
|
||||
#warn("HANDLING WATCH %s, INAME: '%s'" % (exp, iname))
|
||||
if exp.startswith("[") and exp.endswith("]"):
|
||||
#warn("EVAL: EXP: %s" % exp)
|
||||
d.beginHash()
|
||||
with SubItem(d):
|
||||
d.putField("iname", iname)
|
||||
d.putField("name", escapedExp)
|
||||
d.putField("exp", escapedExp)
|
||||
try:
|
||||
list = eval(exp)
|
||||
d.putValue("")
|
||||
d.putType(" ")
|
||||
d.putNumChild(len(list))
|
||||
# This is a list of expressions to evaluate
|
||||
with Children(d, len(list)):
|
||||
itemNumber = 0
|
||||
for item in list:
|
||||
self.handleWatch(d, item, "%s.%d" % (iname, itemNumber))
|
||||
itemNumber += 1
|
||||
except RuntimeError, error:
|
||||
warn("EVAL: ERROR CAUGHT %s" % error)
|
||||
d.putValue("<syntax error>")
|
||||
d.putType(" ")
|
||||
d.putNumChild(0)
|
||||
with Children(d, 0):
|
||||
pass
|
||||
return
|
||||
|
||||
with SubItem(d):
|
||||
d.putField("iname", iname)
|
||||
d.putField("name", escapedExp)
|
||||
d.putField("exp", escapedExp)
|
||||
try:
|
||||
list = eval(exp)
|
||||
d.putValue("")
|
||||
d.putType(" ")
|
||||
d.putNumChild(len(list))
|
||||
# This is a list of expressions to evaluate
|
||||
d.beginChildren(len(list))
|
||||
itemNumber = 0
|
||||
for item in list:
|
||||
self.handleWatch(d, item, "%s.%d" % (iname, itemNumber))
|
||||
itemNumber += 1
|
||||
d.endChildren()
|
||||
except RuntimeError, error:
|
||||
warn("EVAL: ERROR CAUGHT %s" % error)
|
||||
d.putValue("<syntax error>")
|
||||
d.putType(" ")
|
||||
d.putNumChild(0)
|
||||
d.beginChildren(0)
|
||||
d.endChildren()
|
||||
d.endHash()
|
||||
return
|
||||
|
||||
d.beginHash()
|
||||
d.putField("iname", iname)
|
||||
d.putField("name", escapedExp)
|
||||
d.putField("exp", escapedExp)
|
||||
handled = False
|
||||
if exp == "<Edit>" or len(exp) == 0:
|
||||
d.put('value=" ",type=" ",numchild="0",')
|
||||
else:
|
||||
try:
|
||||
value = parseAndEvaluate(exp)
|
||||
item = Item(value, iname, None, None)
|
||||
if not value is None:
|
||||
d.putAddress(value.address)
|
||||
d.putItemHelper(item)
|
||||
except RuntimeError:
|
||||
d.put('value="<invalid>",type="<unknown>",numchild="0",')
|
||||
d.endHash()
|
||||
handled = False
|
||||
if exp == "<Edit>" or len(exp) == 0:
|
||||
d.put('value=" ",type=" ",numchild="0",')
|
||||
else:
|
||||
try:
|
||||
value = parseAndEvaluate(exp)
|
||||
item = Item(value, iname, None, None)
|
||||
if not value is None:
|
||||
d.putAddress(value.address)
|
||||
d.putItemHelper(item)
|
||||
except RuntimeError:
|
||||
d.put('value="<invalid>",type="<unknown>",numchild="0",')
|
||||
|
||||
|
||||
FrameCommand()
|
||||
@@ -882,11 +992,15 @@ SalCommand()
|
||||
class Dumper:
|
||||
def __init__(self):
|
||||
self.output = ""
|
||||
self.safeoutput = ""
|
||||
self.childTypes = [""]
|
||||
self.childNumChilds = [-1]
|
||||
self.maxNumChilds = [-1]
|
||||
self.numChilds = [-1]
|
||||
self.currentChildType = ""
|
||||
self.currentChildNumChild = -1
|
||||
self.currentMaxNumChilds = -1
|
||||
self.currentNumChilds = -1
|
||||
self.currentValue = None
|
||||
self.currentValuePriority = -100
|
||||
self.currentValueEncoding = None
|
||||
self.currentType = None
|
||||
self.currentTypePriority = -100
|
||||
|
||||
def put(self, value):
|
||||
self.output += value
|
||||
@@ -894,60 +1008,14 @@ class Dumper:
|
||||
def putField(self, name, value):
|
||||
self.put('%s="%s",' % (name, value))
|
||||
|
||||
def beginHash(self):
|
||||
self.put('{')
|
||||
|
||||
def endHash(self):
|
||||
self.put('},')
|
||||
|
||||
def beginItem(self, name):
|
||||
self.put('%s="' % name)
|
||||
|
||||
def endItem(self):
|
||||
self.put('",')
|
||||
|
||||
def beginChildren(self, numChild_ = 1, childType_ = None, childNumChild_ = None):
|
||||
childType = ""
|
||||
childNumChild = -1
|
||||
if type(numChild_) is list:
|
||||
numChild = numChild_[0]
|
||||
maxNumChild = numChild_[1]
|
||||
else:
|
||||
numChild = numChild_
|
||||
maxNumChild = numChild_
|
||||
if numChild == 0:
|
||||
childType_ = None
|
||||
if not childType_ is None:
|
||||
childType = stripClassTag(str(childType_))
|
||||
self.put('childtype="%s",' % childType)
|
||||
if isSimpleType(childType_) or isStringType(self, childType_):
|
||||
self.put('childnumchild="0",')
|
||||
childNumChild = 0
|
||||
elif childType_.code == gdb.TYPE_CODE_PTR:
|
||||
self.put('childnumchild="1",')
|
||||
childNumChild = 1
|
||||
if not childNumChild_ is None:
|
||||
self.put('childnumchild="%s",' % childNumChild_)
|
||||
childNumChild = childNumChild_
|
||||
self.childTypes.append(childType)
|
||||
self.childNumChilds.append(childNumChild)
|
||||
self.numChilds.append(numChild)
|
||||
self.maxNumChilds.append(maxNumChild)
|
||||
#warn("BEGIN: %s" % self.childTypes)
|
||||
self.put("children=[")
|
||||
|
||||
def endChildren(self):
|
||||
#warn("END: %s" % self.childTypes)
|
||||
numChild = self.numChilds.pop()
|
||||
maxNumChild = self.maxNumChilds.pop()
|
||||
if maxNumChild < numChild:
|
||||
self.putEllipsis();
|
||||
self.childTypes.pop()
|
||||
self.childNumChilds.pop()
|
||||
self.put('],')
|
||||
|
||||
def childRange(self):
|
||||
return xrange(qmin(self.maxNumChilds[-1], self.numChilds[-1]))
|
||||
return xrange(qmin(self.currentMaxNumChilds, self.currentNumChilds))
|
||||
|
||||
# convenience
|
||||
def putItemCount(self, count):
|
||||
@@ -956,28 +1024,30 @@ class Dumper:
|
||||
def putEllipsis(self):
|
||||
self.put('{name="<incomplete>",value="",type="",numchild="0"},')
|
||||
|
||||
def putType(self, type):
|
||||
#warn("TYPES: '%s' '%s'" % (type, self.childTypes))
|
||||
#warn(" EQUAL 2: %s " % (str(type) == self.childTypes[-1]))
|
||||
type = stripClassTag(str(type))
|
||||
if len(type) > 0 and type != self.childTypes[-1]:
|
||||
self.put('type="%s",' % type) # str(type.unqualified()) ?
|
||||
def putType(self, type, priority = 0):
|
||||
# higher priority values override lower ones
|
||||
if priority >= self.currentTypePriority:
|
||||
self.currentType = type
|
||||
self.currentTypePriority = priority
|
||||
|
||||
def putAddress(self, addr):
|
||||
self.put('addr="%s",' % cleanAddress(addr))
|
||||
|
||||
def putNumChild(self, numchild):
|
||||
#warn("NUM CHILD: '%s' '%s'" % (numchild, self.childNumChilds[-1]))
|
||||
if numchild != self.childNumChilds[-1]:
|
||||
#warn("NUM CHILD: '%s' '%s'" % (numchild, self.currentChildNumChild))
|
||||
if numchild != self.currentChildNumChild:
|
||||
self.put('numchild="%s",' % numchild)
|
||||
|
||||
def putValue(self, value, encoding = None):
|
||||
if not encoding is None:
|
||||
self.putField("valueencoded", encoding)
|
||||
self.putField("value", value)
|
||||
def putValue(self, value, encoding = None, priority = 0):
|
||||
# higher priority values override lower ones
|
||||
if priority >= self.currentValuePriority:
|
||||
self.currentValue = value
|
||||
self.currentValuePriority = priority
|
||||
self.currentValueEncoding = encoding
|
||||
|
||||
def putPointerValue(self, value):
|
||||
self.putValue("0x%x" % value.dereference().cast(
|
||||
# Use a lower priority
|
||||
self.putField("value2", "0x%x" % value.dereference().cast(
|
||||
gdb.lookup_type("unsigned long")))
|
||||
|
||||
def putStringValue(self, value):
|
||||
@@ -1014,11 +1084,6 @@ class Dumper:
|
||||
def isExpandedIName(self, iname):
|
||||
return iname in self.expandedINames
|
||||
|
||||
def unputField(self, name):
|
||||
pos = self.output.rfind(",")
|
||||
if self.output[pos + 1:].startswith(name):
|
||||
self.output = self.output[0:pos]
|
||||
|
||||
def stripNamespaceFromType(self, typeobj):
|
||||
# This breaks for dumpers type names containing '__star'.
|
||||
# But this should not happen as identifiers containing two
|
||||
@@ -1044,29 +1109,18 @@ class Dumper:
|
||||
return self.stripNamespaceFromType(type) in movableTypes
|
||||
|
||||
def putIntItem(self, name, value):
|
||||
self.beginHash()
|
||||
self.putName(name)
|
||||
self.putValue(value)
|
||||
self.putType("int")
|
||||
self.putNumChild(0)
|
||||
self.endHash()
|
||||
with SubItem(self):
|
||||
self.putName(name)
|
||||
self.putValue(value)
|
||||
self.putType("int")
|
||||
self.putNumChild(0)
|
||||
|
||||
def putBoolItem(self, name, value):
|
||||
self.beginHash()
|
||||
self.putName(name)
|
||||
self.putValue(value)
|
||||
self.putType("bool")
|
||||
self.putNumChild(0)
|
||||
self.endHash()
|
||||
|
||||
def pushOutput(self):
|
||||
#warn("PUSH OUTPUT: %s " % self.output)
|
||||
self.safeoutput += self.output
|
||||
self.output = ""
|
||||
|
||||
def dumpInnerValueHelper(self, item):
|
||||
if isSimpleType(item.value.type):
|
||||
self.safePutItemHelper(item)
|
||||
with SubItem(self):
|
||||
self.putName(name)
|
||||
self.putValue(value)
|
||||
self.putType("bool")
|
||||
self.putNumChild(0)
|
||||
|
||||
def itemFormat(self, item):
|
||||
format = self.formats.get(str(cleanAddress(item.value.address)))
|
||||
@@ -1074,58 +1128,13 @@ class Dumper:
|
||||
format = self.typeformats.get(stripClassTag(str(item.value.type)))
|
||||
return format
|
||||
|
||||
def safePutItem(self, item):
|
||||
self.beginHash()
|
||||
self.safePutItemHelper(item)
|
||||
self.endHash()
|
||||
|
||||
def safePutItemHelper(self, item):
|
||||
self.pushOutput()
|
||||
# This is only used at the top level to ensure continuation
|
||||
# after failures due to uninitialized or corrupted data.
|
||||
if self.passExceptions:
|
||||
# for debugging reasons propagate errors.
|
||||
def putItem(self, item):
|
||||
with SubItem(self):
|
||||
self.putItemHelper(item)
|
||||
|
||||
else:
|
||||
try:
|
||||
self.putItemHelper(item)
|
||||
|
||||
except RuntimeError:
|
||||
self.output = ""
|
||||
# FIXME: Only catch debugger related exceptions
|
||||
#exType, exValue, exTraceback = sys.exc_info()
|
||||
#tb = traceback.format_exception(exType, exValue, exTraceback)
|
||||
#warn("Exception: %s" % ex.message)
|
||||
# DeprecationWarning: BaseException.message
|
||||
# has been deprecated
|
||||
#warn("Exception.")
|
||||
#for line in tb:
|
||||
# warn("%s" % line)
|
||||
self.putName(item.name)
|
||||
try:
|
||||
d.putAddress(item.value.address)
|
||||
except:
|
||||
pass
|
||||
self.putValue("<invalid>")
|
||||
self.putType(str(item.value.type))
|
||||
self.putNumChild(0)
|
||||
#if self.isExpanded(item):
|
||||
self.beginChildren()
|
||||
self.endChildren()
|
||||
self.pushOutput()
|
||||
|
||||
def putItem(self, item):
|
||||
self.beginHash()
|
||||
self.safePutItemHelper(item)
|
||||
self.endHash()
|
||||
|
||||
def putCallItem(self, name, item, func):
|
||||
try:
|
||||
result = call(item.value, func)
|
||||
self.safePutItem(Item(result, item.iname, name, name))
|
||||
except:
|
||||
self.safePutItem(Item(None, item.iname))
|
||||
result = call(item.value, func)
|
||||
self.putItem(Item(result, item.iname, name, name))
|
||||
|
||||
def putItemHelper(self, item):
|
||||
name = getattr(item, "name", None)
|
||||
@@ -1194,7 +1203,6 @@ class Dumper:
|
||||
format = self.itemFormat(item)
|
||||
|
||||
if not format is None:
|
||||
#warn("FORMAT %s" % format)
|
||||
self.putAddress(value.address)
|
||||
self.putType(item.value.type)
|
||||
self.putNumChild(0)
|
||||
@@ -1256,11 +1264,11 @@ class Dumper:
|
||||
#warn("GENERIC AUTODEREF POINTER: %s" % value.address)
|
||||
innerType = item.value.type.target()
|
||||
self.putType(innerType)
|
||||
self.childTypes.append(
|
||||
stripClassTag(str(innerType)))
|
||||
savedCurrentChildType = self.currentChildType
|
||||
self.currentChildType = stripClassTag(str(innerType))
|
||||
self.putItemHelper(
|
||||
Item(item.value.dereference(), item.iname, None, None))
|
||||
self.childTypes.pop()
|
||||
self.currentChildType = savedCurrentChildType
|
||||
self.putPointerValue(value.address)
|
||||
isHandled = True
|
||||
|
||||
@@ -1271,10 +1279,9 @@ class Dumper:
|
||||
self.putAddress(value.address)
|
||||
self.putNumChild(1)
|
||||
if self.isExpanded(item):
|
||||
self.beginChildren()
|
||||
self.putItem(
|
||||
Item(item.value.dereference(), item.iname, "*", "*"))
|
||||
self.endChildren()
|
||||
with Children(self):
|
||||
self.putItem(
|
||||
Item(item.value.dereference(), item.iname, "*", "*"))
|
||||
self.putPointerValue(value.address)
|
||||
|
||||
elif str(type).startswith("<anon"):
|
||||
@@ -1283,9 +1290,8 @@ class Dumper:
|
||||
self.putType(item.value.type)
|
||||
self.putValue("{...}")
|
||||
self.anonNumber += 1
|
||||
self.beginChildren(1)
|
||||
self.listAnonymous(item, "#%d" % self.anonNumber, type)
|
||||
self.endChildren()
|
||||
with Children(self, 1):
|
||||
self.listAnonymous(item, "#%d" % self.anonNumber, type)
|
||||
|
||||
else:
|
||||
#warn("GENERIC STRUCT: %s" % item.value.type)
|
||||
@@ -1326,56 +1332,53 @@ class Dumper:
|
||||
innerType = None
|
||||
if len(fields) == 1 and fields[0].name is None:
|
||||
innerType = value.type.target()
|
||||
self.beginChildren(1, innerType)
|
||||
with Children(self, 1, innerType):
|
||||
|
||||
baseNumber = 0
|
||||
for field in fields:
|
||||
#warn("FIELD: %s" % field)
|
||||
#warn(" BITSIZE: %s" % field.bitsize)
|
||||
#warn(" ARTIFICIAL: %s" % field.artificial)
|
||||
bitpos = getattr(field, "bitpos", None)
|
||||
if bitpos is None: # FIXME: Is check correct?
|
||||
continue # A static class member(?).
|
||||
baseNumber = 0
|
||||
for field in fields:
|
||||
#warn("FIELD: %s" % field)
|
||||
#warn(" BITSIZE: %s" % field.bitsize)
|
||||
#warn(" ARTIFICIAL: %s" % field.artificial)
|
||||
bitpos = getattr(field, "bitpos", None)
|
||||
if bitpos is None: # FIXME: Is check correct?
|
||||
continue # A static class member(?).
|
||||
|
||||
if field.name is None:
|
||||
innerType = value.type.target()
|
||||
p = value.cast(innerType.pointer())
|
||||
for i in xrange(value.type.sizeof / innerType.sizeof):
|
||||
self.putItem(Item(p.dereference(), item.iname, i, None))
|
||||
p = p + 1
|
||||
continue
|
||||
if field.name is None:
|
||||
innerType = value.type.target()
|
||||
p = value.cast(innerType.pointer())
|
||||
for i in xrange(value.type.sizeof / innerType.sizeof):
|
||||
self.putItem(Item(p.dereference(), item.iname, i, None))
|
||||
p = p + 1
|
||||
continue
|
||||
|
||||
# Ignore vtable pointers for virtual inheritance.
|
||||
if field.name.startswith("_vptr."):
|
||||
continue
|
||||
# Ignore vtable pointers for virtual inheritance.
|
||||
if field.name.startswith("_vptr."):
|
||||
continue
|
||||
|
||||
#warn("FIELD NAME: %s" % field.name)
|
||||
#warn("FIELD TYPE: %s" % field.type)
|
||||
if field.name == stripClassTag(str(field.type)):
|
||||
# Field is base type. We cannot use field.name as part
|
||||
# of the iname as it might contain spaces and other
|
||||
# strange characters.
|
||||
child = Item(value.cast(field.type),
|
||||
item.iname, "@%d" % baseNumber, field.name)
|
||||
baseNumber += 1
|
||||
self.beginHash()
|
||||
self.putField("iname", child.iname)
|
||||
self.safePutItemHelper(child)
|
||||
self.endHash()
|
||||
elif len(field.name) == 0:
|
||||
# Anonymous union. We need a dummy name to distinguish
|
||||
# multiple anonymous unions in the struct.
|
||||
self.anonNumber += 1
|
||||
self.listAnonymous(item, "#%d" % self.anonNumber, field.type)
|
||||
else:
|
||||
# Named field.
|
||||
self.beginHash()
|
||||
child = Item(value[field.name],
|
||||
item.iname, field.name, field.name)
|
||||
self.safePutItemHelper(child)
|
||||
self.endHash()
|
||||
|
||||
self.endChildren()
|
||||
#warn("FIELD NAME: %s" % field.name)
|
||||
#warn("FIELD TYPE: %s" % field.type)
|
||||
if field.name == stripClassTag(str(field.type)):
|
||||
# Field is base type. We cannot use field.name as part
|
||||
# of the iname as it might contain spaces and other
|
||||
# strange characters.
|
||||
child = Item(value.cast(field.type),
|
||||
item.iname, "@%d" % baseNumber, field.name)
|
||||
baseNumber += 1
|
||||
with SubItem(self):
|
||||
self.putField("iname", child.iname)
|
||||
self.putItemHelper(child)
|
||||
elif len(field.name) == 0:
|
||||
# Anonymous union. We need a dummy name to distinguish
|
||||
# multiple anonymous unions in the struct.
|
||||
self.anonNumber += 1
|
||||
self.listAnonymous(item, "#%d" % self.anonNumber,
|
||||
field.type)
|
||||
else:
|
||||
# Named field.
|
||||
with SubItem(self):
|
||||
child = Item(value[field.name],
|
||||
item.iname, field.name, field.name)
|
||||
self.putItemHelper(child)
|
||||
|
||||
def listAnonymous(self, item, name, type):
|
||||
for field in type.fields():
|
||||
@@ -1383,28 +1386,25 @@ class Dumper:
|
||||
if len(field.name) > 0:
|
||||
value = item.value[field.name]
|
||||
child = Item(value, item.iname, field.name, field.name)
|
||||
self.beginHash()
|
||||
self.putAddress(value.address)
|
||||
self.putItemHelper(child)
|
||||
self.endHash();
|
||||
with SubItem(self):
|
||||
self.putAddress(value.address)
|
||||
self.putItemHelper(child)
|
||||
else:
|
||||
# Further nested.
|
||||
self.anonNumber += 1
|
||||
name = "#%d" % self.anonNumber
|
||||
iname = "%s.%s" % (item.iname, name)
|
||||
child = Item(item.value, iname, None, name)
|
||||
self.beginHash()
|
||||
self.putField("name", name)
|
||||
self.putField("value", " ")
|
||||
if str(field.type).endswith("<anonymous union>"):
|
||||
self.putField("type", "<anonymous union>")
|
||||
elif str(field.type).endswith("<anonymous struct>"):
|
||||
self.putField("type", "<anonymous struct>")
|
||||
else:
|
||||
self.putField("type", field.type)
|
||||
self.beginChildren(1)
|
||||
self.listAnonymous(child, name, field.type)
|
||||
self.endChildren()
|
||||
self.endHash()
|
||||
with SubItem(self):
|
||||
self.putField("name", name)
|
||||
self.putField("value", " ")
|
||||
if str(field.type).endswith("<anonymous union>"):
|
||||
self.putField("type", "<anonymous union>")
|
||||
elif str(field.type).endswith("<anonymous struct>"):
|
||||
self.putField("type", "<anonymous struct>")
|
||||
else:
|
||||
self.putField("type", field.type)
|
||||
with Children(self, 1):
|
||||
self.listAnonymous(child, name, field.type)
|
||||
|
||||
|
||||
|
||||
File diff suppressed because it is too large
Load Diff
Reference in New Issue
Block a user