diff --git a/share/qtcreator/gdbmacros/dumper.py b/share/qtcreator/gdbmacros/dumper.py index 2f283006ce2..1bee0ed2c60 100644 --- a/share/qtcreator/gdbmacros/dumper.py +++ b/share/qtcreator/gdbmacros/dumper.py @@ -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 "" # 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)) diff --git a/share/qtcreator/gdbmacros/gdbmacros.py b/share/qtcreator/gdbmacros/gdbmacros.py index cdf16c66ab6..c1f74a77c3d 100644 --- a/share/qtcreator/gdbmacros/gdbmacros.py +++ b/share/qtcreator/gdbmacros/gdbmacros.py @@ -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']