Commit 9aa75a7f authored by hjk's avatar hjk
Browse files

debugger: cache results of gdb.lookup_type

parent 0862afe3
......@@ -90,12 +90,50 @@ def isGoodGdb():
# and gdb.VERSION != "6.8.50.20090630-cvs"
return 'parse_and_eval' in __builtin__.dir(gdb)
typeCache = {}
def lookupType(typestring):
type = typeCache.get(typestring)
#warn("LOOKUP 1: %s -> %s" % (typestring, type))
if type is None:
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("enum "):
ts = ts[5:]
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
return type
def cleanAddress(addr):
if addr is None:
return "<no address>"
# We cannot use str(addr) as it yields rubbish for char pointers
# that might trigger Unicode encoding errors.
return addr.cast(gdb.lookup_type("void").pointer())
return addr.cast(lookupType("void").pointer())
# Workaround for gdb < 7.1
def numericTemplateArgument(type, position):
......@@ -535,7 +573,7 @@ def checkRef(ref):
check(count < 1000000) # assume there aren't a million references to any object
#def couldBePointer(p, align):
# type = gdb.lookup_type("unsigned int")
# type = lookupType("unsigned int")
# ptr = gdb.Value(p).cast(type)
# d = int(str(ptr))
# warn("CHECKING : %s %d " % (p, ((d & 3) == 0 and (d > 1000 or d == 0))))
......@@ -559,7 +597,7 @@ def isNull(p):
# for invalid char *, as their "contents" is being examined
#s = str(p)
#return s == "0x0" or s.startswith("0x0 ")
return p.cast(gdb.lookup_type("void").pointer()) == 0
return p.cast(lookupType("void").pointer()) == 0
movableTypes = set([
"QBrush", "QBitArray", "QByteArray",
......@@ -648,7 +686,7 @@ def findFirstZero(p, max):
def extractCharArray(p, maxsize):
t = gdb.lookup_type("unsigned char").pointer()
t = lookupType("unsigned char").pointer()
p = p.cast(t)
i = findFirstZero(p, maxsize)
limit = select(i < 0, maxsize, i)
......@@ -673,7 +711,7 @@ def extractByteArray(value):
return extractCharArray(data, 100)
def encodeCharArray(p, maxsize, size = -1):
t = gdb.lookup_type("unsigned char").pointer()
t = lookupType("unsigned char").pointer()
p = p.cast(t)
if size == -1:
i = findFirstZero(p, maxsize)
......@@ -689,7 +727,7 @@ def encodeCharArray(p, maxsize, size = -1):
return s
def encodeChar2Array(p, maxsize):
t = gdb.lookup_type("unsigned short").pointer()
t = lookupType("unsigned short").pointer()
p = p.cast(t)
i = findFirstZero(p, maxsize)
limit = select(i < 0, maxsize, i)
......@@ -702,7 +740,7 @@ def encodeChar2Array(p, maxsize):
return s
def encodeChar4Array(p, maxsize):
t = gdb.lookup_type("unsigned int").pointer()
t = lookupType("unsigned int").pointer()
p = p.cast(t)
i = findFirstZero(p, maxsize)
limit = select(i < 0, maxsize, i)
......@@ -1087,7 +1125,7 @@ class Dumper:
def putPointerValue(self, value):
# Use a lower priority
self.putValue("0x%x" % value.dereference().cast(
gdb.lookup_type("unsigned long")), None, -1)
lookupType("unsigned long")), None, -1)
def putStringValue(self, value):
if value is None:
......@@ -1370,7 +1408,7 @@ class Dumper:
if self.isExpanded(item):
if value.type.code == gdb.TYPE_CODE_ARRAY:
baseptr = value.cast(value.type.target().pointer())
charptr = gdb.lookup_type("unsigned char").pointer()
charptr = lookupType("unsigned char").pointer()
addr1 = (baseptr+1).cast(charptr)
addr0 = baseptr.cast(charptr)
self.putField("addrbase" % cleanAddress(addr0))
......
......@@ -27,7 +27,7 @@ def qdump__QByteArray(d, item):
d.putNumChild(size)
if d.isExpanded(item):
innerType = gdb.lookup_type("char")
innerType = lookupType("char")
with Children(d, [size, 1000], innerType):
data = d_ptr['data']
p = gdb.Value(data.cast(innerType.pointer()))
......@@ -57,7 +57,7 @@ def qdump__QAbstractItem(d, item):
d.putNumChild(rowCount * columnCount)
if d.isExpanded(item):
with Children(d):
innerType = gdb.lookup_type(d.ns + "QAbstractItem")
innerType = lookupType(d.ns + "QAbstractItem")
for row in xrange(rowCount):
for column in xrange(columnCount):
with SubItem(d):
......@@ -202,7 +202,7 @@ def qdump__QFileInfo(d, item):
d.putStringValue(call(item.value, "filePath()"))
d.putNumChild(3)
if d.isExpanded(item):
with Children(d, 10, gdb.lookup_type(d.ns + "QString")):
with Children(d, 10, lookupType(d.ns + "QString")):
d.putCallItem("absolutePath", item, "absolutePath()")
d.putCallItem("absoluteFilePath", item, "absoluteFilePath()")
d.putCallItem("canonicalPath", item, "canonicalPath()")
......@@ -397,7 +397,7 @@ def qdump__QList(d, item):
# in the frontend.
# So as first approximation only do the 'isLarge' check:
isInternal = innerSize <= d_ptr.type.sizeof and d.isMovableType(innerType)
dummyType = gdb.lookup_type("void").pointer().pointer()
dummyType = lookupType("void").pointer().pointer()
innerTypePointer = innerType.pointer()
p = gdb.Value(array).cast(dummyType) + begin
if innerTypeIsPointer:
......@@ -449,7 +449,7 @@ def qdump__QImage(d, item):
d.put("%08x" % int(d_ptr["width"]))
d.put("%08x" % int(d_ptr["height"]))
d.put("%08x" % int(d_ptr["format"]))
p = bits.cast(gdb.lookup_type("unsigned int").pointer())
p = bits.cast(lookupType("unsigned int").pointer())
for i in xrange(nbytes / 4):
d.put("%08x" % int(p.dereference()))
p += 1
......@@ -458,7 +458,7 @@ def qdump__QImage(d, item):
# Write to an external file. Much faster ;-(
file = tempfile.mkstemp(prefix="gdbpy_")
filename = file[1].replace("\\", "\\\\")
p = bits.cast(gdb.lookup_type("unsigned char").pointer())
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"
......@@ -485,7 +485,7 @@ def qdump__QLocale(d, item):
d.putStringValue(call(item.value, "name()"))
d.putNumChild(8)
if d.isExpanded(item):
with Children(d, 1, gdb.lookup_type(d.ns + "QChar"), 0):
with Children(d, 1, lookupType(d.ns + "QChar"), 0):
d.putCallItem("country", item, "country()")
d.putCallItem("language", item, "language()")
d.putCallItem("measurementSystem", item, "measurementSystem()")
......@@ -539,9 +539,9 @@ def qdump__QMap(d, item):
# 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 = gdb.lookup_type(d.ns + "QMapNode<%s, %s>" % (keyType, valueType))
payloadSize = nodeType.sizeof - 2 * gdb.lookup_type("void").pointer().sizeof
charPtr = gdb.lookup_type("char").pointer()
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)
......@@ -592,7 +592,7 @@ def qdump__QObject(d, item):
# superData = superData.dereference()["d"]["superdata"]
# warn("SUPERDATA: %s" % superData)
privateType = gdb.lookup_type(d.ns + "QObjectPrivate").pointer()
privateType = lookupType(d.ns + "QObjectPrivate").pointer()
d_ptr = item.value["d_ptr"]["d"].cast(privateType).dereference()
#warn("D_PTR: %s " % d_ptr)
objectName = d_ptr["objectName"]
......@@ -662,7 +662,7 @@ def qdump__QObject(d, item):
# type = type[type.find('"') + 1 : type.rfind('"')]
# type = type.replace("Q", d.ns + "Q") # HACK!
# data = call(item.value, "constData()")
# tdata = data.cast(gdb.lookup_type(type).pointer()).dereference()
# tdata = data.cast(lookupType(type).pointer()).dereference()
# d.putValue("(%s)" % tdata.type)
# d.putType(tdata.type)
# d.putNumChild(1)
......@@ -1420,7 +1420,7 @@ def qdump__QStringList(d, item):
d.putItemCount(size)
d.putNumChild(size)
if d.isExpanded(item):
innerType = gdb.lookup_type(d.ns + "QString")
innerType = lookupType(d.ns + "QString")
ptr = gdb.Value(d_ptr["array"]).cast(innerType.pointer())
ptr += d_ptr["begin"]
with Children(d, [size, 1000], innerType):
......@@ -1580,11 +1580,11 @@ def qdumpHelper__QVariant(d, value):
inner = d.ns + "QQuadernion"
if len(inner):
innerType = gdb.lookup_type(inner)
sizePD = gdb.lookup_type(d.ns + 'QVariant::Private::Data').sizeof
innerType = lookupType(inner)
sizePD = lookupType(d.ns + 'QVariant::Private::Data').sizeof
if innerType.sizeof > sizePD:
sizePS = gdb.lookup_type(d.ns + 'QVariant::PrivateShared').sizeof
val = (sizePS + data.cast(gdb.lookup_type('char').pointer())) \
sizePS = lookupType(d.ns + 'QVariant::PrivateShared').sizeof
val = (sizePS + data.cast(lookupType('char').pointer())) \
.cast(innerType.pointer()).dereference()
else:
val = data.cast(innerType)
......@@ -1600,7 +1600,7 @@ def qdump__QVariant(d, item):
#warn("VARIANT DATA: '%s' '%s' '%s': " % (val, inner, innert))
if len(inner):
innerType = gdb.lookup_type(inner)
innerType = lookupType(inner)
# FIXME: Why "shared"?
if innerType.sizeof > item.value["d"]["data"].type.sizeof:
v = item.value["d"]["data"]["shared"]["ptr"] \
......@@ -1617,7 +1617,7 @@ def qdump__QVariant(d, item):
type = type[type.find('"') + 1 : type.rfind('"')]
type = type.replace("Q", d.ns + "Q") # HACK!
data = call(item.value, "constData()")
tdata = data.cast(gdb.lookup_type(type).pointer()).dereference()
tdata = data.cast(lookupType(type).pointer()).dereference()
d.putType("%sQVariant (%s)" % (d.ns, tdata.type))
d.putNumChild(1)
if d.isExpanded(item):
......@@ -1812,7 +1812,7 @@ def qdump__std__string(d, item):
data = item.value["_M_dataplus"]["_M_p"]
baseType = item.value.type.unqualified().strip_typedefs()
charType = baseType.template_argument(0)
repType = gdb.lookup_type("%s::_Rep" % baseType).pointer()
repType = lookupType("%s::_Rep" % baseType).pointer()
rep = (data.cast(repType) - 1).dereference()
size = rep['_M_length']
alloc = rep['_M_capacity']
......
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