Commit bb8aed62 authored by hjk's avatar hjk
Browse files

debugger: make type lookup more robust

... by stripping out 'const', 'volatile', 'struct' and 'class'.
parent 77cf419d
...@@ -92,12 +92,45 @@ typeCache = {} ...@@ -92,12 +92,45 @@ typeCache = {}
def lookupType(typestring): def lookupType(typestring):
type = typeCache.get(typestring) type = typeCache.get(typestring)
#warn("LOOKUP: %s -> %s" % (typestring, type)) #warn("LOOKUP 1: %s -> %s" % (typestring, type))
if type is None: if type is None:
type = gdb.lookup_type(typestring) ts = typestring
while True:
#WARN("ts: '%s'" % ts)
if ts.startswith("class "):
ts = ts[6:]
elif ts.startswith("struct "):
ts = ts[7:]
elif ts.startswith("const "):
ts = ts[6:]
elif ts.startswith("volatile "):
ts = ts[9:]
elif ts.startswith("const "):
ts = ts[6:]
elif ts.startswith("volatile "):
ts = ts[9:]
elif ts.endswith("const"):
ts = ts[-5:]
elif ts.endswith("volatile"):
ts = ts[-8:]
else:
break
try:
#warn("LOOKING UP '%s'" % ts)
type = gdb.lookup_type(ts)
except:
# Can throw "RuntimeError: No type named class Foo."
#warn("LOOKING UP '%s' FAILED" % ts)
pass
#warn(" RESULT: '%s'" % type)
#if not type is None:
# warn(" FIELDS: '%s'" % type.fields())
typeCache[typestring] = type typeCache[typestring] = type
return type return type
def cleanType(type):
return lookupType(str(type))
def cleanAddress(addr): def cleanAddress(addr):
if addr is None: if addr is None:
return "<no address>" return "<no address>"
...@@ -595,6 +628,10 @@ def stripClassTag(type): ...@@ -595,6 +628,10 @@ def stripClassTag(type):
return type[6:] return type[6:]
elif type.startswith("struct "): elif type.startswith("struct "):
return type[7:] return type[7:]
elif type.startswith("const "):
return type[6:]
elif type.startswith("volatile "):
return type[9:]
return type return type
def checkPointerRange(p, n): def checkPointerRange(p, n):
...@@ -755,12 +792,27 @@ def encodeString(value): ...@@ -755,12 +792,27 @@ def encodeString(value):
p += 1 p += 1
return s return s
def stripTypedefs(typeobj): def stripTypedefs(type):
type = typeobj type = type.unqualified()
while type.code == gdb.TYPE_CODE_TYPEDEF: while type.code == gdb.TYPE_CODE_TYPEDEF:
type = type.strip_typedefs().unqualified() type = type.strip_typedefs().unqualified()
return type return type
def extractFields(type):
# Insufficient, see http://sourceware.org/bugzilla/show_bug.cgi?id=10953:
#fields = value.type.fields()
# Insufficient, see http://sourceware.org/bugzilla/show_bug.cgi?id=11777:
#fields = stripTypedefs(value.type).fields()
# This seems to work.
#warn("TYPE 0: %s" % type)
type = stripTypedefs(type)
#warn("TYPE 1: %s" % type)
type = lookupType(str(type))
#warn("TYPE 2: %s" % type)
fields = type.fields()
#warn("FIELDS: %s" % fields)
return fields
####################################################################### #######################################################################
# #
# Item # Item
...@@ -1296,17 +1348,26 @@ class Dumper: ...@@ -1296,17 +1348,26 @@ class Dumper:
elif typedefStrippedType.code == gdb.TYPE_CODE_PTR: elif typedefStrippedType.code == gdb.TYPE_CODE_PTR:
#warn("POINTER: %s" % format) warn("POINTER: %s" % format)
isHandled = False isHandled = False
target = stripTypedefs(type.target()) target = stripTypedefs(type.target())
if (not isHandled) and isNull(value):
warn("NULL POINTER")
self.putType(item.value.type)
self.putValue("0x0")
self.putNumChild(0)
isHandled = True
if (not isHandled) and target.code == gdb.TYPE_CODE_VOID: if (not isHandled) and target.code == gdb.TYPE_CODE_VOID:
warn("VOID POINTER: %s" % format)
self.putType(item.value.type) self.putType(item.value.type)
self.putValue(str(value)) self.putValue(str(value))
self.putNumChild(0) self.putNumChild(0)
isHandled = True isHandled = True
if (not isHandled) and (not format is None): if (not isHandled) and (not format is None):
warn("SPECIAL FORMAT POINTER: %s" % format)
self.putAddress(value.address) self.putAddress(value.address)
self.putType(item.value.type) self.putType(item.value.type)
isHandled = True isHandled = True
...@@ -1328,10 +1389,8 @@ class Dumper: ...@@ -1328,10 +1389,8 @@ class Dumper:
self.putValue(encodeChar4Array(value, 100), Hex8EncodedBigEndian) self.putValue(encodeChar4Array(value, 100), Hex8EncodedBigEndian)
self.putNumChild(0) self.putNumChild(0)
if (not isHandled): if (not isHandled) and (str(typedefStrippedType)
anonStrippedType = str(typedefStrippedType) \ .replace("(anonymous namespace)", "").find("(") != -1):
.replace("(anonymous namespace)", "")
if anonStrippedType.find("(") != -1:
# A function pointer. # A function pointer.
self.putValue(str(item.value)) self.putValue(str(item.value))
self.putAddress(value.address) self.putAddress(value.address)
...@@ -1339,25 +1398,12 @@ class Dumper: ...@@ -1339,25 +1398,12 @@ class Dumper:
self.putNumChild(0) self.putNumChild(0)
isHandled = True isHandled = True
if (not isHandled) and self.useFancy:
if isNull(value):
self.putValue("0x0")
self.putType(item.value.type)
self.putNumChild(0)
isHandled = True
if (not isHandled):
self.putType(item.value.type)
self.putValue(str(value))
self.putNumChild(0)
isHandled = True
#warn("AUTODEREF: %s" % self.autoDerefPointers) #warn("AUTODEREF: %s" % self.autoDerefPointers)
#warn("IS HANDLED: %s" % isHandled) #warn("IS HANDLED: %s" % isHandled)
#warn("RES: %s" % (self.autoDerefPointers and not isHandled)) #warn("RES: %s" % (self.autoDerefPointers and not isHandled))
if (not isHandled) and (self.autoDerefPointers or name == "this"): if (not isHandled) and (self.autoDerefPointers or name == "this"):
## Generic pointer type. ## Generic pointer type.
#warn("GENERIC AUTODEREF POINTER: %s" % value.address) warn("GENERIC AUTODEREF POINTER: %s" % value.address)
innerType = item.value.type.target() innerType = item.value.type.target()
self.putType(innerType) self.putType(innerType)
savedCurrentChildType = self.currentChildType savedCurrentChildType = self.currentChildType
...@@ -1392,21 +1438,11 @@ class Dumper: ...@@ -1392,21 +1438,11 @@ class Dumper:
self.listAnonymous(item, "#%d" % self.anonNumber, type) self.listAnonymous(item, "#%d" % self.anonNumber, type)
else: else:
#warn("GENERIC STRUCT: %s" % item.value.type) warn("GENERIC STRUCT: %s" % item.value.type)
#warn("INAME: %s " % item.iname) #warn("INAME: %s " % item.iname)
#warn("INAMES: %s " % self.expandedINames) #warn("INAMES: %s " % self.expandedINames)
#warn("EXPANDED: %s " % (item.iname in self.expandedINames)) #warn("EXPANDED: %s " % (item.iname in self.expandedINames))
fields = extractFields(type)
# Insufficient, see http://sourceware.org/bugzilla/show_bug.cgi?id=10953
#fields = value.type.fields()
# Insufficient, see http://sourceware.org/bugzilla/show_bug.cgi?id=11777
#fields = stripTypedefs(value.type).fields()
# This seems to work.
type = stripTypedefs(type)
type = lookupType(str(type))
fields = type.fields()
self.putType(item.value.type) self.putType(item.value.type)
try: try:
...@@ -1444,9 +1480,7 @@ class Dumper: ...@@ -1444,9 +1480,7 @@ class Dumper:
def putFields(self, item, innerType = None): def putFields(self, item, innerType = None):
value = item.value value = item.value
type = stripTypedefs(value.type) type = stripTypedefs(value.type)
# http://sourceware.org/bugzilla/show_bug.cgi?id=11777 fields = extractFields(type)
type = lookupType(str(type))
fields = stripTypedefs(type).fields()
baseNumber = 0 baseNumber = 0
for field in fields: for field in fields:
#warn("FIELD: %s" % field) #warn("FIELD: %s" % field)
......
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