forked from qt-creator/qt-creator
debugger: cache results of gdb.lookup_type
This commit is contained in:
@@ -88,12 +88,22 @@ def isGoodGdb():
|
|||||||
# and gdb.VERSION != "6.8.50.20090630-cvs"
|
# and gdb.VERSION != "6.8.50.20090630-cvs"
|
||||||
return 'parse_and_eval' in __builtin__.dir(gdb)
|
return 'parse_and_eval' in __builtin__.dir(gdb)
|
||||||
|
|
||||||
|
typeCache = {}
|
||||||
|
|
||||||
|
def lookupType(typestring):
|
||||||
|
type = typeCache.get(typestring)
|
||||||
|
#warn("LOOKUP: %s -> %s" % (typestring, type))
|
||||||
|
if type is None:
|
||||||
|
type = gdb.lookup_type(typestring)
|
||||||
|
typeCache[typestring] = type
|
||||||
|
return type
|
||||||
|
|
||||||
def cleanAddress(addr):
|
def cleanAddress(addr):
|
||||||
if addr is None:
|
if addr is None:
|
||||||
return "<no address>"
|
return "<no address>"
|
||||||
# We cannot use str(addr) as it yields rubbish for char pointers
|
# We cannot use str(addr) as it yields rubbish for char pointers
|
||||||
# that might trigger Unicode encoding errors.
|
# 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
|
# Workaround for gdb < 7.1
|
||||||
def numericTemplateArgument(type, position):
|
def numericTemplateArgument(type, position):
|
||||||
@@ -535,7 +545,7 @@ def checkRef(ref):
|
|||||||
check(count < 1000000) # assume there aren't a million references to any object
|
check(count < 1000000) # assume there aren't a million references to any object
|
||||||
|
|
||||||
#def couldBePointer(p, align):
|
#def couldBePointer(p, align):
|
||||||
# type = gdb.lookup_type("unsigned int")
|
# type = lookupType("unsigned int")
|
||||||
# ptr = gdb.Value(p).cast(type)
|
# ptr = gdb.Value(p).cast(type)
|
||||||
# d = int(str(ptr))
|
# d = int(str(ptr))
|
||||||
# warn("CHECKING : %s %d " % (p, ((d & 3) == 0 and (d > 1000 or d == 0))))
|
# warn("CHECKING : %s %d " % (p, ((d & 3) == 0 and (d > 1000 or d == 0))))
|
||||||
@@ -559,7 +569,7 @@ def isNull(p):
|
|||||||
# for invalid char *, as their "contents" is being examined
|
# for invalid char *, as their "contents" is being examined
|
||||||
#s = str(p)
|
#s = str(p)
|
||||||
#return s == "0x0" or s.startswith("0x0 ")
|
#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([
|
movableTypes = set([
|
||||||
"QBrush", "QBitArray", "QByteArray",
|
"QBrush", "QBitArray", "QByteArray",
|
||||||
@@ -648,7 +658,7 @@ def findFirstZero(p, max):
|
|||||||
|
|
||||||
|
|
||||||
def extractCharArray(p, maxsize):
|
def extractCharArray(p, maxsize):
|
||||||
t = gdb.lookup_type("unsigned char").pointer()
|
t = lookupType("unsigned char").pointer()
|
||||||
p = p.cast(t)
|
p = p.cast(t)
|
||||||
i = findFirstZero(p, maxsize)
|
i = findFirstZero(p, maxsize)
|
||||||
limit = select(i < 0, maxsize, i)
|
limit = select(i < 0, maxsize, i)
|
||||||
@@ -673,7 +683,7 @@ def extractByteArray(value):
|
|||||||
return extractCharArray(data, 100)
|
return extractCharArray(data, 100)
|
||||||
|
|
||||||
def encodeCharArray(p, maxsize, size = -1):
|
def encodeCharArray(p, maxsize, size = -1):
|
||||||
t = gdb.lookup_type("unsigned char").pointer()
|
t = lookupType("unsigned char").pointer()
|
||||||
p = p.cast(t)
|
p = p.cast(t)
|
||||||
if size == -1:
|
if size == -1:
|
||||||
i = findFirstZero(p, maxsize)
|
i = findFirstZero(p, maxsize)
|
||||||
@@ -689,7 +699,7 @@ def encodeCharArray(p, maxsize, size = -1):
|
|||||||
return s
|
return s
|
||||||
|
|
||||||
def encodeChar2Array(p, maxsize):
|
def encodeChar2Array(p, maxsize):
|
||||||
t = gdb.lookup_type("unsigned short").pointer()
|
t = lookupType("unsigned short").pointer()
|
||||||
p = p.cast(t)
|
p = p.cast(t)
|
||||||
i = findFirstZero(p, maxsize)
|
i = findFirstZero(p, maxsize)
|
||||||
limit = select(i < 0, maxsize, i)
|
limit = select(i < 0, maxsize, i)
|
||||||
@@ -702,7 +712,7 @@ def encodeChar2Array(p, maxsize):
|
|||||||
return s
|
return s
|
||||||
|
|
||||||
def encodeChar4Array(p, maxsize):
|
def encodeChar4Array(p, maxsize):
|
||||||
t = gdb.lookup_type("unsigned int").pointer()
|
t = lookupType("unsigned int").pointer()
|
||||||
p = p.cast(t)
|
p = p.cast(t)
|
||||||
i = findFirstZero(p, maxsize)
|
i = findFirstZero(p, maxsize)
|
||||||
limit = select(i < 0, maxsize, i)
|
limit = select(i < 0, maxsize, i)
|
||||||
@@ -774,7 +784,7 @@ class FrameCommand(gdb.Command):
|
|||||||
super(FrameCommand, self).__init__("bb", gdb.COMMAND_OBSCURE)
|
super(FrameCommand, self).__init__("bb", gdb.COMMAND_OBSCURE)
|
||||||
|
|
||||||
def invoke(self, args, from_tty):
|
def invoke(self, args, from_tty):
|
||||||
if True:
|
if False:
|
||||||
bb(args)
|
bb(args)
|
||||||
else:
|
else:
|
||||||
import cProfile
|
import cProfile
|
||||||
@@ -1097,7 +1107,7 @@ class Dumper:
|
|||||||
def putPointerValue(self, value):
|
def putPointerValue(self, value):
|
||||||
# Use a lower priority
|
# Use a lower priority
|
||||||
self.putValue("0x%x" % value.dereference().cast(
|
self.putValue("0x%x" % value.dereference().cast(
|
||||||
gdb.lookup_type("unsigned long")), None, -1)
|
lookupType("unsigned long")), None, -1)
|
||||||
|
|
||||||
def putStringValue(self, value):
|
def putStringValue(self, value):
|
||||||
if value is None:
|
if value is None:
|
||||||
@@ -1381,7 +1391,7 @@ class Dumper:
|
|||||||
if self.isExpanded(item):
|
if self.isExpanded(item):
|
||||||
if value.type.code == gdb.TYPE_CODE_ARRAY:
|
if value.type.code == gdb.TYPE_CODE_ARRAY:
|
||||||
baseptr = value.cast(value.type.target().pointer())
|
baseptr = value.cast(value.type.target().pointer())
|
||||||
charptr = gdb.lookup_type("unsigned char").pointer()
|
charptr = lookupType("unsigned char").pointer()
|
||||||
addr1 = (baseptr+1).cast(charptr)
|
addr1 = (baseptr+1).cast(charptr)
|
||||||
addr0 = baseptr.cast(charptr)
|
addr0 = baseptr.cast(charptr)
|
||||||
self.putField("addrbase", cleanAddress(addr0))
|
self.putField("addrbase", cleanAddress(addr0))
|
||||||
|
@@ -27,7 +27,7 @@ def qdump__QByteArray(d, item):
|
|||||||
d.putNumChild(size)
|
d.putNumChild(size)
|
||||||
|
|
||||||
if d.isExpanded(item):
|
if d.isExpanded(item):
|
||||||
innerType = gdb.lookup_type("char")
|
innerType = lookupType("char")
|
||||||
with Children(d, [size, 1000], innerType):
|
with Children(d, [size, 1000], innerType):
|
||||||
data = d_ptr['data']
|
data = d_ptr['data']
|
||||||
p = gdb.Value(data.cast(innerType.pointer()))
|
p = gdb.Value(data.cast(innerType.pointer()))
|
||||||
@@ -57,7 +57,7 @@ def qdump__QAbstractItem(d, item):
|
|||||||
d.putNumChild(rowCount * columnCount)
|
d.putNumChild(rowCount * columnCount)
|
||||||
if d.isExpanded(item):
|
if d.isExpanded(item):
|
||||||
with Children(d):
|
with Children(d):
|
||||||
innerType = gdb.lookup_type(d.ns + "QAbstractItem")
|
innerType = lookupType(d.ns + "QAbstractItem")
|
||||||
for row in xrange(rowCount):
|
for row in xrange(rowCount):
|
||||||
for column in xrange(columnCount):
|
for column in xrange(columnCount):
|
||||||
with SubItem(d):
|
with SubItem(d):
|
||||||
@@ -202,7 +202,7 @@ def qdump__QFileInfo(d, item):
|
|||||||
d.putStringValue(call(item.value, "filePath()"))
|
d.putStringValue(call(item.value, "filePath()"))
|
||||||
d.putNumChild(3)
|
d.putNumChild(3)
|
||||||
if d.isExpanded(item):
|
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("absolutePath", item, "absolutePath()")
|
||||||
d.putCallItem("absoluteFilePath", item, "absoluteFilePath()")
|
d.putCallItem("absoluteFilePath", item, "absoluteFilePath()")
|
||||||
d.putCallItem("canonicalPath", item, "canonicalPath()")
|
d.putCallItem("canonicalPath", item, "canonicalPath()")
|
||||||
@@ -406,7 +406,7 @@ def qdump__QList(d, item):
|
|||||||
# in the frontend.
|
# in the frontend.
|
||||||
# So as first approximation only do the 'isLarge' check:
|
# So as first approximation only do the 'isLarge' check:
|
||||||
isInternal = innerSize <= d_ptr.type.sizeof and d.isMovableType(innerType)
|
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()
|
innerTypePointer = innerType.pointer()
|
||||||
p = gdb.Value(array).cast(dummyType) + begin
|
p = gdb.Value(array).cast(dummyType) + begin
|
||||||
if innerTypeIsPointer:
|
if innerTypeIsPointer:
|
||||||
@@ -458,7 +458,7 @@ def qdump__QImage(d, item):
|
|||||||
d.put("%08x" % int(d_ptr["width"]))
|
d.put("%08x" % int(d_ptr["width"]))
|
||||||
d.put("%08x" % int(d_ptr["height"]))
|
d.put("%08x" % int(d_ptr["height"]))
|
||||||
d.put("%08x" % int(d_ptr["format"]))
|
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):
|
for i in xrange(nbytes / 4):
|
||||||
d.put("%08x" % int(p.dereference()))
|
d.put("%08x" % int(p.dereference()))
|
||||||
p += 1
|
p += 1
|
||||||
@@ -467,7 +467,7 @@ def qdump__QImage(d, item):
|
|||||||
# Write to an external file. Much faster ;-(
|
# Write to an external file. Much faster ;-(
|
||||||
file = tempfile.mkstemp(prefix="gdbpy_")
|
file = tempfile.mkstemp(prefix="gdbpy_")
|
||||||
filename = file[1].replace("\\", "\\\\")
|
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" %
|
gdb.execute("dump binary memory %s %s %s" %
|
||||||
(filename, cleanAddress(p), cleanAddress(p + nbytes)))
|
(filename, cleanAddress(p), cleanAddress(p + nbytes)))
|
||||||
d.putDisplay(DisplayImage, " %d %d %d %s"
|
d.putDisplay(DisplayImage, " %d %d %d %s"
|
||||||
@@ -494,7 +494,7 @@ def qdump__QLocale(d, item):
|
|||||||
d.putStringValue(call(item.value, "name()"))
|
d.putStringValue(call(item.value, "name()"))
|
||||||
d.putNumChild(8)
|
d.putNumChild(8)
|
||||||
if d.isExpanded(item):
|
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("country", item, "country()")
|
||||||
d.putCallItem("language", item, "language()")
|
d.putCallItem("language", item, "language()")
|
||||||
d.putCallItem("measurementSystem", item, "measurementSystem()")
|
d.putCallItem("measurementSystem", item, "measurementSystem()")
|
||||||
@@ -548,9 +548,9 @@ def qdump__QMap(d, item):
|
|||||||
# QMapPayloadNode is QMapNode except for the 'forward' member, so
|
# QMapPayloadNode is QMapNode except for the 'forward' member, so
|
||||||
# its size is most likely the offset of the 'forward' member therein.
|
# its size is most likely the offset of the 'forward' member therein.
|
||||||
# Or possibly 2 * sizeof(void *)
|
# Or possibly 2 * sizeof(void *)
|
||||||
nodeType = gdb.lookup_type(d.ns + "QMapNode<%s, %s>" % (keyType, valueType))
|
nodeType = lookupType(d.ns + "QMapNode<%s, %s>" % (keyType, valueType))
|
||||||
payloadSize = nodeType.sizeof - 2 * gdb.lookup_type("void").pointer().sizeof
|
payloadSize = nodeType.sizeof - 2 * lookupType("void").pointer().sizeof
|
||||||
charPtr = gdb.lookup_type("char").pointer()
|
charPtr = lookupType("char").pointer()
|
||||||
|
|
||||||
innerType = select(isSimpleKey and isSimpleValue, valueType, nodeType)
|
innerType = select(isSimpleKey and isSimpleValue, valueType, nodeType)
|
||||||
|
|
||||||
@@ -601,7 +601,7 @@ def qdump__QObject(d, item):
|
|||||||
# superData = superData.dereference()["d"]["superdata"]
|
# superData = superData.dereference()["d"]["superdata"]
|
||||||
# warn("SUPERDATA: %s" % 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()
|
d_ptr = item.value["d_ptr"]["d"].cast(privateType).dereference()
|
||||||
#warn("D_PTR: %s " % d_ptr)
|
#warn("D_PTR: %s " % d_ptr)
|
||||||
objectName = d_ptr["objectName"]
|
objectName = d_ptr["objectName"]
|
||||||
@@ -638,7 +638,7 @@ def qdump__QObject(d, item):
|
|||||||
if isNull(extraData):
|
if isNull(extraData):
|
||||||
dynamicPropertyCount = 0
|
dynamicPropertyCount = 0
|
||||||
else:
|
else:
|
||||||
extraDataType = gdb.lookup_type(
|
extraDataType = lookupType(
|
||||||
d.ns + "QObjectPrivate::ExtraData").pointer()
|
d.ns + "QObjectPrivate::ExtraData").pointer()
|
||||||
extraData = extraData.cast(extraDataType)
|
extraData = extraData.cast(extraDataType)
|
||||||
ed = extraData.dereference()
|
ed = extraData.dereference()
|
||||||
@@ -664,12 +664,12 @@ def qdump__QObject(d, item):
|
|||||||
if d.isExpandedIName(item.iname + ".properties"):
|
if d.isExpandedIName(item.iname + ".properties"):
|
||||||
with Children(d, [propertyCount, 500]):
|
with Children(d, [propertyCount, 500]):
|
||||||
# Dynamic properties.
|
# Dynamic properties.
|
||||||
dummyType = gdb.lookup_type("void").pointer().pointer()
|
dummyType = lookupType("void").pointer().pointer()
|
||||||
namesType = gdb.lookup_type(d.ns + "QByteArray")
|
namesType = lookupType(d.ns + "QByteArray")
|
||||||
valuesBegin = values["d"]["begin"]
|
valuesBegin = values["d"]["begin"]
|
||||||
valuesEnd = values["d"]["end"]
|
valuesEnd = values["d"]["end"]
|
||||||
valuesArray = values["d"]["array"]
|
valuesArray = values["d"]["array"]
|
||||||
valuesType = gdb.lookup_type(d.ns + "QVariant")
|
valuesType = lookupType(d.ns + "QVariant")
|
||||||
p = namesArray.cast(dummyType) + namesBegin
|
p = namesArray.cast(dummyType) + namesBegin
|
||||||
q = valuesArray.cast(dummyType) + valuesBegin
|
q = valuesArray.cast(dummyType) + valuesBegin
|
||||||
for i in xrange(dynamicPropertyCount):
|
for i in xrange(dynamicPropertyCount):
|
||||||
@@ -720,7 +720,7 @@ def qdump__QObject(d, item):
|
|||||||
# type = type[type.find('"') + 1 : type.rfind('"')]
|
# type = type[type.find('"') + 1 : type.rfind('"')]
|
||||||
# type = type.replace("Q", d.ns + "Q") # HACK!
|
# type = type.replace("Q", d.ns + "Q") # HACK!
|
||||||
# data = call(item.value, "constData()")
|
# 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.putValue("(%s)" % tdata.type)
|
||||||
# d.putType(tdata.type)
|
# d.putType(tdata.type)
|
||||||
# d.putNumChild(1)
|
# d.putNumChild(1)
|
||||||
@@ -1485,7 +1485,7 @@ def qdump__QStringList(d, item):
|
|||||||
d.putItemCount(size)
|
d.putItemCount(size)
|
||||||
d.putNumChild(size)
|
d.putNumChild(size)
|
||||||
if d.isExpanded(item):
|
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 = gdb.Value(d_ptr["array"]).cast(innerType.pointer())
|
||||||
ptr += d_ptr["begin"]
|
ptr += d_ptr["begin"]
|
||||||
with Children(d, [size, 1000], innerType):
|
with Children(d, [size, 1000], innerType):
|
||||||
@@ -1645,11 +1645,11 @@ def qdumpHelper__QVariant(d, value):
|
|||||||
inner = d.ns + "QQuadernion"
|
inner = d.ns + "QQuadernion"
|
||||||
|
|
||||||
if len(inner):
|
if len(inner):
|
||||||
innerType = gdb.lookup_type(inner)
|
innerType = lookupType(inner)
|
||||||
sizePD = gdb.lookup_type(d.ns + 'QVariant::Private::Data').sizeof
|
sizePD = lookupType(d.ns + 'QVariant::Private::Data').sizeof
|
||||||
if innerType.sizeof > sizePD:
|
if innerType.sizeof > sizePD:
|
||||||
sizePS = gdb.lookup_type(d.ns + 'QVariant::PrivateShared').sizeof
|
sizePS = lookupType(d.ns + 'QVariant::PrivateShared').sizeof
|
||||||
val = (sizePS + data.cast(gdb.lookup_type('char').pointer())) \
|
val = (sizePS + data.cast(lookupType('char').pointer())) \
|
||||||
.cast(innerType.pointer()).dereference()
|
.cast(innerType.pointer()).dereference()
|
||||||
else:
|
else:
|
||||||
val = data.cast(innerType)
|
val = data.cast(innerType)
|
||||||
@@ -1665,7 +1665,7 @@ def qdump__QVariant(d, item):
|
|||||||
#warn("VARIANT DATA: '%s' '%s' '%s': " % (val, inner, innert))
|
#warn("VARIANT DATA: '%s' '%s' '%s': " % (val, inner, innert))
|
||||||
|
|
||||||
if len(inner):
|
if len(inner):
|
||||||
innerType = gdb.lookup_type(inner)
|
innerType = lookupType(inner)
|
||||||
# FIXME: Why "shared"?
|
# FIXME: Why "shared"?
|
||||||
if innerType.sizeof > item.value["d"]["data"].type.sizeof:
|
if innerType.sizeof > item.value["d"]["data"].type.sizeof:
|
||||||
v = item.value["d"]["data"]["shared"]["ptr"] \
|
v = item.value["d"]["data"]["shared"]["ptr"] \
|
||||||
@@ -1683,7 +1683,7 @@ def qdump__QVariant(d, item):
|
|||||||
type = type[type.find('"') + 1 : type.rfind('"')]
|
type = type[type.find('"') + 1 : type.rfind('"')]
|
||||||
type = type.replace("Q", d.ns + "Q") # HACK!
|
type = type.replace("Q", d.ns + "Q") # HACK!
|
||||||
data = call(item.value, "constData()")
|
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.putType("%sQVariant (%s)" % (d.ns, tdata.type))
|
||||||
d.putNumChild(1)
|
d.putNumChild(1)
|
||||||
if d.isExpanded(item):
|
if d.isExpanded(item):
|
||||||
@@ -1879,7 +1879,7 @@ def qdump__std__string(d, item):
|
|||||||
data = item.value["_M_dataplus"]["_M_p"]
|
data = item.value["_M_dataplus"]["_M_p"]
|
||||||
baseType = item.value.type.unqualified().strip_typedefs()
|
baseType = item.value.type.unqualified().strip_typedefs()
|
||||||
charType = baseType.template_argument(0)
|
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()
|
rep = (data.cast(repType) - 1).dereference()
|
||||||
size = rep['_M_length']
|
size = rep['_M_length']
|
||||||
alloc = rep['_M_capacity']
|
alloc = rep['_M_capacity']
|
||||||
|
Reference in New Issue
Block a user