forked from qt-creator/qt-creator
Debugger: Move some global variables to the Dumper class
Change-Id: I5c8fd8a48f27ac70e6e39f645d64dcd788752e73 Reviewed-by: hjk <hjk121@nokiamail.com>
This commit is contained in:
@@ -41,44 +41,6 @@ else:
|
||||
verbosity = 0
|
||||
verbosity = 1
|
||||
|
||||
qqStringCutOff = 10000
|
||||
|
||||
# This is a cache mapping from 'type name' to 'display alternatives'.
|
||||
qqFormats = {}
|
||||
|
||||
# This is a cache of all known dumpers.
|
||||
qqDumpers = {}
|
||||
|
||||
# This is a cache of all dumpers that support writing.
|
||||
qqEditable = {}
|
||||
|
||||
# This is an approximation of the Qt Version found
|
||||
qqVersion = None
|
||||
|
||||
# This keeps canonical forms of the typenames, without array indices etc.
|
||||
qqStripForFormat = {}
|
||||
|
||||
def stripForFormat(typeName):
|
||||
global qqStripForFormat
|
||||
if typeName in qqStripForFormat:
|
||||
return qqStripForFormat[typeName]
|
||||
stripped = ""
|
||||
inArray = 0
|
||||
for c in stripClassTag(typeName):
|
||||
if c == '<':
|
||||
break
|
||||
if c == ' ':
|
||||
continue
|
||||
if c == '[':
|
||||
inArray += 1
|
||||
elif c == ']':
|
||||
inArray -= 1
|
||||
if inArray and ord(c) >= 48 and ord(c) <= 57:
|
||||
continue
|
||||
stripped += c
|
||||
qqStripForFormat[typeName] = stripped
|
||||
return stripped
|
||||
|
||||
def hasPlot():
|
||||
fileName = "/usr/bin/gnuplot"
|
||||
return os.path.isfile(fileName) and os.access(fileName, os.X_OK)
|
||||
@@ -261,6 +223,44 @@ class DumperBase:
|
||||
self.isGdb = False
|
||||
self.isLldb = False
|
||||
|
||||
# Later set, or not set:
|
||||
# cachedQtVersion
|
||||
self.stringCutOff = 10000
|
||||
|
||||
# This is a cache mapping from 'type name' to 'display alternatives'.
|
||||
self.qqFormats = {}
|
||||
|
||||
# This is a cache of all known dumpers.
|
||||
self.qqDumpers = {}
|
||||
|
||||
# This is a cache of all dumpers that support writing.
|
||||
self.qqEditable = {}
|
||||
|
||||
# This keeps canonical forms of the typenames, without array indices etc.
|
||||
self.cachedFormats = {}
|
||||
|
||||
|
||||
def stripForFormat(self, typeName):
|
||||
if typeName in self.cachedFormats:
|
||||
return self.cachedFormats[typeName]
|
||||
stripped = ""
|
||||
inArray = 0
|
||||
for c in stripClassTag(typeName):
|
||||
if c == '<':
|
||||
break
|
||||
if c == ' ':
|
||||
continue
|
||||
if c == '[':
|
||||
inArray += 1
|
||||
elif c == ']':
|
||||
inArray -= 1
|
||||
if inArray and ord(c) >= 48 and ord(c) <= 57:
|
||||
continue
|
||||
stripped += c
|
||||
self.cachedFormats[typeName] = stripped
|
||||
return stripped
|
||||
|
||||
|
||||
def is32bit(self):
|
||||
return self.ptrSize() == 4
|
||||
|
||||
@@ -268,7 +268,7 @@ class DumperBase:
|
||||
if limit is None:
|
||||
return size
|
||||
if limit == 0:
|
||||
return min(size, qqStringCutOff)
|
||||
return min(size, self.stringCutOff)
|
||||
return min(size, limit)
|
||||
|
||||
def byteArrayDataHelper(self, addr):
|
||||
@@ -372,10 +372,11 @@ class DumperBase:
|
||||
return self.putValue(self.encodeString(value), Hex4EncodedLittleEndian)
|
||||
|
||||
def putMapName(self, value):
|
||||
if str(value.type) == self.ns + "QString":
|
||||
ns = self.qtNamespace()
|
||||
if str(value.type) == ns + "QString":
|
||||
self.put('key="%s",' % self.encodeString(value))
|
||||
self.put('keyencoded="%s",' % Hex4EncodedLittleEndian)
|
||||
elif str(value.type) == self.ns + "QByteArray":
|
||||
elif str(value.type) == ns + "QByteArray":
|
||||
self.put('key="%s",' % self.encodeByteArray(value))
|
||||
self.put('keyencoded="%s",' % Hex2EncodedLatin1)
|
||||
else:
|
||||
@@ -416,9 +417,9 @@ class DumperBase:
|
||||
def encodeCArray(self, p, innerType, suffix):
|
||||
t = self.lookupType(innerType)
|
||||
p = p.cast(t.pointer())
|
||||
limit = self.findFirstZero(p, qqStringCutOff)
|
||||
limit = self.findFirstZero(p, self.stringCutOff)
|
||||
s = self.readMemory(p, limit * t.sizeof)
|
||||
if limit > qqStringCutOff:
|
||||
if limit > self.stringCutOff:
|
||||
s += suffix
|
||||
return s
|
||||
|
||||
@@ -503,6 +504,14 @@ class DumperBase:
|
||||
|
||||
return type == "QStringList" and self.qtVersion() >= 0x050000
|
||||
|
||||
def currentItemFormat(self, type = None):
|
||||
format = self.formats.get(self.currentIName)
|
||||
if format is None:
|
||||
if type is None:
|
||||
type = self.currentType
|
||||
needle = self.stripForFormat(str(type))
|
||||
format = self.typeformats.get(needle)
|
||||
return format
|
||||
|
||||
def cleanAddress(addr):
|
||||
if addr is None:
|
||||
|
@@ -298,57 +298,9 @@ class ScanStackCommand(gdb.Command):
|
||||
|
||||
ScanStackCommand()
|
||||
|
||||
def registerDumper(funcname, function):
|
||||
global qqDumpers, qqFormats, qqEditable
|
||||
try:
|
||||
#warn("FUNCTION: %s " % funcname)
|
||||
#funcname = function.func_name
|
||||
if funcname.startswith("qdump__"):
|
||||
type = funcname[7:]
|
||||
qqDumpers[type] = function
|
||||
qqFormats[type] = qqFormats.get(type, "")
|
||||
elif funcname.startswith("qform__"):
|
||||
type = funcname[7:]
|
||||
formats = ""
|
||||
try:
|
||||
formats = function()
|
||||
except:
|
||||
pass
|
||||
qqFormats[type] = formats
|
||||
elif funcname.startswith("qedit__"):
|
||||
type = funcname[7:]
|
||||
try:
|
||||
qqEditable[type] = function
|
||||
except:
|
||||
pass
|
||||
except:
|
||||
pass
|
||||
|
||||
def bbsetup(args = ''):
|
||||
global qqDumpers, qqFormats, qqEditable, typeCache
|
||||
qqDumpers = {}
|
||||
qqFormats = {}
|
||||
qqEditable = {}
|
||||
typeCache = {}
|
||||
module = sys.modules[__name__]
|
||||
|
||||
#warn("KEYS: %s " % module.__dict__.keys())
|
||||
for name in module.__dict__.keys():
|
||||
#warn("KEY: %s " % name)
|
||||
#warn("FUNCT: %s " % module.__dict__[name])
|
||||
registerDumper(name, module.__dict__[name])
|
||||
|
||||
result = "dumpers=["
|
||||
#qqNs = qtNamespace() # This is too early
|
||||
for key, value in qqFormats.items():
|
||||
if key in qqEditable:
|
||||
result += '{type="%s",formats="%s",editable="true"},' % (key, value)
|
||||
else:
|
||||
result += '{type="%s",formats="%s"},' % (key, value)
|
||||
result += ']'
|
||||
#result += ',namespace="%s"' % qqNs
|
||||
print(result)
|
||||
return result
|
||||
print(theDumper.bbsetup())
|
||||
|
||||
registerCommand("bbsetup", bbsetup)
|
||||
|
||||
@@ -377,18 +329,8 @@ class PlainDumper:
|
||||
for child in children:
|
||||
d.putSubItem(child[0], child[1])
|
||||
|
||||
def importPlainDumper(printer):
|
||||
global qqDumpers, qqFormats
|
||||
name = printer.name.replace("::", "__")
|
||||
qqDumpers[name] = PlainDumper(printer)
|
||||
qqFormats[name] = ""
|
||||
|
||||
def importPlainDumpers(args):
|
||||
return
|
||||
for obj in gdb.objfiles():
|
||||
for printers in obj.pretty_printers + gdb.pretty_printers:
|
||||
for printer in printers.subprinters:
|
||||
importPlainDumper(printer)
|
||||
theDumper.importPlainDumpers()
|
||||
|
||||
registerCommand("importPlainDumpers", importPlainDumpers)
|
||||
|
||||
@@ -651,27 +593,6 @@ def value(expr):
|
||||
Value = gdb.Value
|
||||
|
||||
|
||||
qqNs = None
|
||||
|
||||
def qtNamespace():
|
||||
# FIXME: This only works when call from inside a Qt function frame.
|
||||
global qqNs
|
||||
if not qqNs is None:
|
||||
return qqNs
|
||||
try:
|
||||
str = gdb.execute("ptype QString::Null", to_string=True)
|
||||
# The result looks like:
|
||||
# "type = const struct myns::QString::Null {"
|
||||
# " <no data fields>"
|
||||
# "}"
|
||||
pos1 = str.find("struct") + 7
|
||||
pos2 = str.find("QString::Null")
|
||||
if pos1 > -1 and pos2 > -1:
|
||||
qqNs = str[pos1:pos2]
|
||||
return qqNs
|
||||
return ""
|
||||
except:
|
||||
return ""
|
||||
|
||||
def stripTypedefs(type):
|
||||
type = type.unqualified()
|
||||
@@ -698,23 +619,8 @@ class LocalItem:
|
||||
#######################################################################
|
||||
|
||||
def bbedit(args):
|
||||
global qqEditable
|
||||
(type, expr, value) = args.split(",")
|
||||
type = b16decode(type)
|
||||
ns = qtNamespace()
|
||||
if type.startswith(ns):
|
||||
type = type[len(ns):]
|
||||
type = type.replace("::", "__")
|
||||
pos = type.find('<')
|
||||
if pos != -1:
|
||||
type = type[0:pos]
|
||||
expr = b16decode(expr)
|
||||
value = b16decode(value)
|
||||
#warn("EDIT: %s %s %s %s: " % (pos, type, expr, value))
|
||||
if qqEditable.has_key(type):
|
||||
qqEditable[type](expr, value)
|
||||
else:
|
||||
gdb.execute("set (%s)=%s" % (expr, value))
|
||||
#(type, expr, value) = args.split(",")
|
||||
theDumper.bbedit(args.split(","))
|
||||
|
||||
registerCommand("bbedit", bbedit)
|
||||
|
||||
@@ -781,7 +687,9 @@ class Dumper(DumperBase):
|
||||
# These values will be kept between calls to 'run'.
|
||||
self.isGdb = True
|
||||
self.childEventAddress = None
|
||||
self.cachedQtVersion = None
|
||||
|
||||
# Later set, or not set:
|
||||
#self.cachedQtVersion
|
||||
|
||||
def run(self, args):
|
||||
self.output = []
|
||||
@@ -841,9 +749,7 @@ class Dumper(DumperBase):
|
||||
self.partialUpdate = "partial" in options
|
||||
self.tooltipOnly = "tooltiponly" in options
|
||||
self.noLocals = "nolocals" in options
|
||||
self.ns = qtNamespace()
|
||||
|
||||
#warn("NAMESPACE: '%s'" % self.ns)
|
||||
#warn("NAMESPACE: '%s'" % self.qtNamespace())
|
||||
#warn("VARIABLES: %s" % varList)
|
||||
#warn("EXPANDED INAMES: %s" % self.expandedINames)
|
||||
#warn("WATCHERS: %s" % watchers)
|
||||
@@ -1209,10 +1115,14 @@ class Dumper(DumperBase):
|
||||
def selectedInferior(self):
|
||||
try:
|
||||
# gdb.Inferior is new in gdb 7.2
|
||||
return gdb.selected_inferior()
|
||||
self.cachedInferior = gdb.selected_inferior()
|
||||
except:
|
||||
# Pre gdb 7.4. Right now we don't have more than one inferior anyway.
|
||||
return gdb.inferiors()[0]
|
||||
self.cachedInferior = gdb.inferiors()[0]
|
||||
|
||||
# Memoize result.
|
||||
self.selectedInferior = lambda: self.cachedInferior
|
||||
return self.cachedInferior
|
||||
|
||||
def readRawMemory(self, addr, size):
|
||||
mem = self.selectedInferior().read_memory(addr, size)
|
||||
@@ -1289,16 +1199,20 @@ class Dumper(DumperBase):
|
||||
return xrange(min(toInteger(self.currentMaxNumChild), toInteger(self.currentNumChild)))
|
||||
|
||||
def qtVersion(self):
|
||||
if self.cachedQtVersion is None:
|
||||
try:
|
||||
self.cachedQtVersion = extractQtVersion()
|
||||
except:
|
||||
try:
|
||||
self.cachedQtVersion = extractQtVersion()
|
||||
# This will fail on Qt 5
|
||||
gdb.execute("ptype QString::shared_empty", to_string=True)
|
||||
self.cachedQtVersion = 0x040800
|
||||
except:
|
||||
try:
|
||||
# This will fail on Qt 5
|
||||
gdb.execute("ptype QString::shared_empty", to_string=True)
|
||||
self.cachedQtVersion = 0x040800
|
||||
except:
|
||||
self.cachedQtVersion = 0x050000
|
||||
#self.cachedQtVersion = 0x050000
|
||||
# Assume Qt 5 until we have a definitive answer.
|
||||
return 0x050000
|
||||
|
||||
# Memoize good results.
|
||||
self.qtVersion = lambda: self.cachedQtVersion
|
||||
return self.cachedQtVersion
|
||||
|
||||
# Convenience function.
|
||||
@@ -1390,8 +1304,9 @@ class Dumper(DumperBase):
|
||||
|
||||
def stripNamespaceFromType(self, typeName):
|
||||
type = stripClassTag(typeName)
|
||||
if len(self.ns) > 0 and type.startswith(self.ns):
|
||||
type = type[len(self.ns):]
|
||||
ns = self.qtNamespace()
|
||||
if len(ns) > 0 and type.startswith(ns):
|
||||
type = type[len(ns):]
|
||||
pos = type.find("<")
|
||||
# FIXME: make it recognize foo<A>::bar<B>::iterator?
|
||||
while pos != -1:
|
||||
@@ -1425,12 +1340,6 @@ class Dumper(DumperBase):
|
||||
self.putType(type)
|
||||
self.putNumChild(0)
|
||||
|
||||
def currentItemFormat(self):
|
||||
format = self.formats.get(self.currentIName)
|
||||
if format is None:
|
||||
format = self.typeformats.get(stripForFormat(str(self.currentType)))
|
||||
return format
|
||||
|
||||
def putSubItem(self, component, value, tryDynamic=True):
|
||||
with SubItem(self, component):
|
||||
self.putItem(value, tryDynamic)
|
||||
@@ -1563,8 +1472,6 @@ class Dumper(DumperBase):
|
||||
self.putNumChild(0)
|
||||
return
|
||||
|
||||
global qqDumpers, qqFormats
|
||||
|
||||
type = value.type.unqualified()
|
||||
typeName = str(type)
|
||||
tryDynamic &= self.useDynamicType
|
||||
@@ -1653,9 +1560,9 @@ class Dumper(DumperBase):
|
||||
return
|
||||
|
||||
if type.code == TypedefCode:
|
||||
if typeName in qqDumpers:
|
||||
if typeName in self.qqDumpers:
|
||||
self.putType(typeName)
|
||||
qqDumpers[typeName](self, value)
|
||||
self.qqDumpers[typeName](self, value)
|
||||
return
|
||||
|
||||
type = stripTypedefs(type)
|
||||
@@ -1708,9 +1615,7 @@ class Dumper(DumperBase):
|
||||
|
||||
innerType = type.target()
|
||||
innerTypeName = str(innerType.unqualified())
|
||||
format = self.formats.get(self.currentIName)
|
||||
if format is None:
|
||||
format = self.typeformats.get(stripForFormat(str(type)))
|
||||
format = self.currentItemFormat(type)
|
||||
|
||||
if innerType.code == VoidCode:
|
||||
#warn("VOID POINTER: %s" % format)
|
||||
@@ -1868,9 +1773,7 @@ class Dumper(DumperBase):
|
||||
self.putItem(expensiveDowncast(value), False)
|
||||
return
|
||||
|
||||
format = self.formats.get(self.currentIName)
|
||||
if format is None:
|
||||
format = self.typeformats.get(stripForFormat(typeName))
|
||||
format = self.currentItemFormat(typeName)
|
||||
|
||||
if self.useFancy and (format is None or format >= 1):
|
||||
self.putType(typeName)
|
||||
@@ -1890,9 +1793,9 @@ class Dumper(DumperBase):
|
||||
return
|
||||
|
||||
#warn(" STRIPPED: %s" % nsStrippedType)
|
||||
#warn(" DUMPERS: %s" % qqDumpers)
|
||||
#warn(" DUMPERS: %s" % (nsStrippedType in qqDumpers))
|
||||
dumper = qqDumpers.get(nsStrippedType, None)
|
||||
#warn(" DUMPERS: %s" % self.qqDumpers)
|
||||
#warn(" DUMPERS: %s" % (nsStrippedType in self.qqDumpers))
|
||||
dumper = self.qqDumpers.get(nsStrippedType, None)
|
||||
if not dumper is None:
|
||||
if tryDynamic:
|
||||
dumper(self, expensiveDowncast(value))
|
||||
@@ -2031,10 +1934,57 @@ class Dumper(DumperBase):
|
||||
with Children(self, 1):
|
||||
self.listAnonymous(value, name, field.type)
|
||||
|
||||
def registerDumper(self, funcname, function):
|
||||
try:
|
||||
#warn("FUNCTION: %s " % funcname)
|
||||
#funcname = function.func_name
|
||||
if funcname.startswith("qdump__"):
|
||||
type = funcname[7:]
|
||||
self.qqDumpers[type] = function
|
||||
self.qqFormats[type] = self.qqFormats.get(type, "")
|
||||
elif funcname.startswith("qform__"):
|
||||
type = funcname[7:]
|
||||
formats = ""
|
||||
try:
|
||||
formats = function()
|
||||
except:
|
||||
pass
|
||||
self.qqFormats[type] = formats
|
||||
elif funcname.startswith("qedit__"):
|
||||
type = funcname[7:]
|
||||
try:
|
||||
self.qqEditable[type] = function
|
||||
except:
|
||||
pass
|
||||
except:
|
||||
pass
|
||||
|
||||
def bbsetup(self):
|
||||
self.qqDumpers = {}
|
||||
self.qqFormats = {}
|
||||
self.qqEditable = {}
|
||||
self.typeCache = {}
|
||||
module = sys.modules[__name__]
|
||||
|
||||
#warn("KEYS: %s " % module.__dict__.keys())
|
||||
for name in module.__dict__.keys():
|
||||
#warn("KEY: %s " % name)
|
||||
#warn("FUNCT: %s " % module.__dict__[name])
|
||||
self.registerDumper(name, module.__dict__[name])
|
||||
|
||||
result = "dumpers=["
|
||||
for key, value in self.qqFormats.items():
|
||||
if key in self.qqEditable:
|
||||
result += '{type="%s",formats="%s",editable="true"},' % (key, value)
|
||||
else:
|
||||
result += '{type="%s",formats="%s"},' % (key, value)
|
||||
result += ']'
|
||||
return result
|
||||
|
||||
def threadname(self, maximalStackDepth):
|
||||
e = gdb.selected_frame()
|
||||
ns = qtNamespace()
|
||||
out = ""
|
||||
ns = self.qtNamespace()
|
||||
while True:
|
||||
maximalStackDepth -= 1
|
||||
if maximalStackDepth < 0:
|
||||
@@ -2087,6 +2037,54 @@ class Dumper(DumperBase):
|
||||
return out + ']'
|
||||
|
||||
|
||||
def importPlainDumper(self, printer):
|
||||
name = printer.name.replace("::", "__")
|
||||
self.qqDumpers[name] = PlainDumper(printer)
|
||||
self.qqFormats[name] = ""
|
||||
|
||||
def importPlainDumpers(self):
|
||||
for obj in gdb.objfiles():
|
||||
for printers in obj.pretty_printers + gdb.pretty_printers:
|
||||
for printer in printers.subprinters:
|
||||
self.importPlainDumper(printer)
|
||||
|
||||
def qtNamespace(self):
|
||||
# FIXME: This only works when call from inside a Qt function frame.
|
||||
namespace = ""
|
||||
try:
|
||||
str = gdb.execute("ptype QString::Null", to_string=True)
|
||||
# The result looks like:
|
||||
# "type = const struct myns::QString::Null {"
|
||||
# " <no data fields>"
|
||||
# "}"
|
||||
pos1 = str.find("struct") + 7
|
||||
pos2 = str.find("QString::Null")
|
||||
if pos1 > -1 and pos2 > -1:
|
||||
namespace = str[pos1:pos2]
|
||||
self.cachedQtNamespace = namespace
|
||||
self.ns = lambda: self.cachedQtNamespace
|
||||
except:
|
||||
pass
|
||||
|
||||
return namespace
|
||||
|
||||
def bbedit(self, type, expr, value):
|
||||
type = b16decode(type)
|
||||
ns = self.qtNamespace()
|
||||
if type.startswith(ns):
|
||||
type = type[len(ns):]
|
||||
type = type.replace("::", "__")
|
||||
pos = type.find('<')
|
||||
if pos != -1:
|
||||
type = type[0:pos]
|
||||
expr = b16decode(expr)
|
||||
value = b16decode(value)
|
||||
#warn("EDIT: %s %s %s %s: " % (pos, type, expr, value))
|
||||
if self.qqEditable.has_key(type):
|
||||
self.qqEditable[type](expr, value)
|
||||
else:
|
||||
gdb.execute("set (%s)=%s" % (expr, value))
|
||||
|
||||
|
||||
# Global instance.
|
||||
theDumper = Dumper()
|
||||
|
@@ -78,27 +78,6 @@ import lldb
|
||||
|
||||
qqWatchpointOffset = 10000
|
||||
|
||||
def registerDumper(function):
|
||||
if hasattr(function, 'func_name'):
|
||||
funcname = function.func_name
|
||||
if funcname.startswith("qdump__"):
|
||||
type = funcname[7:]
|
||||
qqDumpers[type] = function
|
||||
qqFormats[type] = qqFormats.get(type, "")
|
||||
elif funcname.startswith("qform__"):
|
||||
type = funcname[7:]
|
||||
formats = ""
|
||||
try:
|
||||
formats = function()
|
||||
except:
|
||||
pass
|
||||
qqFormats[type] = formats
|
||||
elif funcname.startswith("qedit__"):
|
||||
type = funcname[7:]
|
||||
try:
|
||||
qqEditable[type] = function
|
||||
except:
|
||||
pass
|
||||
|
||||
def warn(message):
|
||||
print('\n\nWARNING="%s",\n' % message.encode("latin1").replace('"', "'"))
|
||||
@@ -293,7 +272,6 @@ class Dumper(DumperBase):
|
||||
self.expandedINames = {}
|
||||
self.passExceptions = True
|
||||
self.useLldbDumpers = False
|
||||
self.ns = ""
|
||||
self.autoDerefPointers = True
|
||||
self.useDynamicType = True
|
||||
self.useFancy = True
|
||||
@@ -449,10 +427,7 @@ class Dumper(DumperBase):
|
||||
return typeobj.GetTypeClass() in (lldb.eTypeClassStruct, lldb.eTypeClassClass)
|
||||
|
||||
def qtVersion(self):
|
||||
global qqVersion
|
||||
if not qqVersion is None:
|
||||
return qqVersion
|
||||
qqVersion = 0x0
|
||||
self.cachedQtVersion = 0x0
|
||||
coreExpression = re.compile(r"(lib)?Qt5?Core")
|
||||
for n in range(0, self.target.GetNumModules()):
|
||||
module = self.target.GetModuleAtIndex(n)
|
||||
@@ -461,10 +436,13 @@ class Dumper(DumperBase):
|
||||
reverseVersion.reverse()
|
||||
shift = 0
|
||||
for v in reverseVersion:
|
||||
qqVersion += v << shift
|
||||
self.cachedQtVersion += v << shift
|
||||
shift += 8
|
||||
break
|
||||
return qqVersion
|
||||
|
||||
# Memoize good results.
|
||||
self.qtVersion = lambda: self.cachedQtVersion
|
||||
return self.cachedQtVersion
|
||||
|
||||
def intSize(self):
|
||||
return 4
|
||||
@@ -536,12 +514,6 @@ class Dumper(DumperBase):
|
||||
def putField(self, name, value):
|
||||
self.put('%s="%s",' % (name, value))
|
||||
|
||||
def currentItemFormat(self):
|
||||
format = self.formats.get(self.currentIName)
|
||||
if format is None:
|
||||
format = self.typeformats.get(stripForFormat(str(self.currentType)))
|
||||
return format
|
||||
|
||||
def isMovableType(self, type):
|
||||
if type.GetTypeClass() in (lldb.eTypeClassBuiltin, lldb.eTypeClassPointer):
|
||||
return True
|
||||
@@ -845,11 +817,16 @@ class Dumper(DumperBase):
|
||||
self.currentValuePriority = priority
|
||||
self.currentValueEncoding = encoding
|
||||
|
||||
def qtNamespace(self):
|
||||
# FIXME
|
||||
return ""
|
||||
|
||||
def stripNamespaceFromType(self, typeName):
|
||||
#type = stripClassTag(typeName)
|
||||
type = typeName
|
||||
#if len(self.ns) > 0 and type.startswith(self.ns):
|
||||
# type = type[len(self.ns):]
|
||||
#ns = qtNamespace()
|
||||
#if len(ns) > 0 and type.startswith(ns):
|
||||
# type = type[len(ns):]
|
||||
pos = type.find("<")
|
||||
# FIXME: make it recognize foo<A>::bar<B>::iterator?
|
||||
while pos != -1:
|
||||
@@ -912,10 +889,10 @@ class Dumper(DumperBase):
|
||||
|
||||
# Typedefs
|
||||
if typeClass == lldb.eTypeClassTypedef:
|
||||
if typeName in qqDumpers:
|
||||
if typeName in self.qqDumpers:
|
||||
self.putType(typeName)
|
||||
self.context = value
|
||||
qqDumpers[typeName](self, value)
|
||||
self.qqDumpers[typeName](self, value)
|
||||
return
|
||||
realType = value.GetType()
|
||||
if hasattr(realType, 'GetCanonicalType'):
|
||||
@@ -970,9 +947,7 @@ class Dumper(DumperBase):
|
||||
innerType = value.GetType().GetPointeeType().unqualified()
|
||||
innerTypeName = str(innerType)
|
||||
|
||||
format = self.formats.get(self.currentIName)
|
||||
if format is None:
|
||||
format = self.typeformats.get(stripForFormat(str(type)))
|
||||
format = self.currentItemFormat(type)
|
||||
|
||||
if innerTypeName == "void":
|
||||
warn("VOID POINTER: %s" % format)
|
||||
@@ -1130,11 +1105,11 @@ class Dumper(DumperBase):
|
||||
if self.useFancy:
|
||||
stripped = self.stripNamespaceFromType(typeName).replace("::", "__")
|
||||
#warn("STRIPPED: %s" % stripped)
|
||||
#warn("DUMPABLE: %s" % (stripped in qqDumpers))
|
||||
if stripped in qqDumpers:
|
||||
#warn("DUMPABLE: %s" % (stripped in self.qqDumpers))
|
||||
if stripped in self.qqDumpers:
|
||||
self.putType(typeName)
|
||||
self.context = value
|
||||
qqDumpers[stripped](self, value)
|
||||
self.qqDumpers[stripped](self, value)
|
||||
return
|
||||
|
||||
# Normal value
|
||||
@@ -1634,13 +1609,34 @@ class Dumper(DumperBase):
|
||||
self.reportError(error)
|
||||
self.reportVariables()
|
||||
|
||||
def registerDumper(self, function):
|
||||
if hasattr(function, 'func_name'):
|
||||
funcname = function.func_name
|
||||
if funcname.startswith("qdump__"):
|
||||
type = funcname[7:]
|
||||
self.qqDumpers[type] = function
|
||||
self.qqFormats[type] = self.qqFormats.get(type, "")
|
||||
elif funcname.startswith("qform__"):
|
||||
type = funcname[7:]
|
||||
formats = ""
|
||||
try:
|
||||
formats = function()
|
||||
except:
|
||||
pass
|
||||
self.qqFormats[type] = formats
|
||||
elif funcname.startswith("qedit__"):
|
||||
type = funcname[7:]
|
||||
try:
|
||||
self.qqEditable[type] = function
|
||||
except:
|
||||
pass
|
||||
|
||||
def importDumpers(self, _ = None):
|
||||
result = lldb.SBCommandReturnObject()
|
||||
interpreter = self.debugger.GetCommandInterpreter()
|
||||
global qqDumpers, qqFormats, qqEditable
|
||||
items = globals()
|
||||
for key in items:
|
||||
registerDumper(items[key])
|
||||
self.registerDumper(items[key])
|
||||
|
||||
def execute(self, args):
|
||||
getattr(self, args['cmd'])(args)
|
||||
|
@@ -94,7 +94,7 @@ def qdump__QAbstractItemModel(d, value):
|
||||
#format == 2:
|
||||
# Create a default-constructed QModelIndex on the stack.
|
||||
try:
|
||||
ri = d.makeValue(d.ns + "QModelIndex", "-1, -1, 0, 0")
|
||||
ri = d.makeValue(d.qtNamespace() + "QModelIndex", "-1, -1, 0, 0")
|
||||
this_ = d.makeExpression(value)
|
||||
ri_ = d.makeExpression(ri)
|
||||
rowCount = int(d.parseAndEvaluate("%s.rowCount(%s)" % (this_, ri_)))
|
||||
@@ -147,8 +147,9 @@ def qdump__QModelIndex(d, value):
|
||||
|
||||
mm = m.dereference()
|
||||
mm = mm.cast(mm.type.unqualified())
|
||||
ns = d.qtNamespace()
|
||||
try:
|
||||
mi = d.makeValue(d.ns + "QModelIndex", "%s,%s,%s,%s" % (r, c, p, m))
|
||||
mi = d.makeValue(ns + "QModelIndex", "%s,%s,%s,%s" % (r, c, p, m))
|
||||
mm_ = d.makeExpression(mm)
|
||||
mi_ = d.makeExpression(mi)
|
||||
rowCount = int(d.parseAndEvaluate("%s.rowCount(%s)" % (mm_, mi_)))
|
||||
@@ -162,7 +163,7 @@ def qdump__QModelIndex(d, value):
|
||||
# Access DisplayRole as value
|
||||
val = d.parseAndEvaluate("%s.data(%s, 0)" % (mm_, mi_))
|
||||
v = val["d"]["data"]["ptr"]
|
||||
d.putStringValue(d.makeValue(d.ns + 'QString', v))
|
||||
d.putStringValue(d.makeValue(ns + 'QString', v))
|
||||
except:
|
||||
d.putValue("(invalid)")
|
||||
|
||||
@@ -181,7 +182,7 @@ def qdump__QModelIndex(d, value):
|
||||
#d.putCallItem("parent", val, "parent")
|
||||
#with SubItem(d, "model"):
|
||||
# d.putValue(m)
|
||||
# d.putType(d.ns + "QAbstractItemModel*")
|
||||
# d.putType(ns + "QAbstractItemModel*")
|
||||
# d.putNumChild(1)
|
||||
#gdb.execute("call free($mi)")
|
||||
|
||||
@@ -192,7 +193,7 @@ def qdump__QDate(d, value):
|
||||
d.putValue(jd, JulianDate)
|
||||
d.putNumChild(1)
|
||||
if d.isExpanded():
|
||||
qt = d.ns + "Qt::"
|
||||
qt = d.qtNamespace() + "Qt::"
|
||||
if d.isLldb:
|
||||
qt += "DateFormat::" # FIXME: Bug?...
|
||||
# FIXME: This improperly uses complex return values.
|
||||
@@ -213,8 +214,9 @@ def qdump__QTime(d, value):
|
||||
d.putValue(mds, MillisecondsSinceMidnight)
|
||||
d.putNumChild(1)
|
||||
if d.isExpanded():
|
||||
qtdate = d.ns + "Qt::"
|
||||
qttime = d.ns + "Qt::"
|
||||
ns = d.qtNamespace()
|
||||
qtdate = ns + "Qt::"
|
||||
qttime = ns + "Qt::"
|
||||
if d.isLldb:
|
||||
qtdate += "DateFormat::" # FIXME: Bug?...
|
||||
# FIXME: This improperly uses complex return values.
|
||||
@@ -267,8 +269,8 @@ def qdump__QDateTime(d, value):
|
||||
if d.isExpanded():
|
||||
# FIXME: This improperly uses complex return values.
|
||||
with Children(d):
|
||||
qtdate = d.ns + "Qt::"
|
||||
qttime = d.ns + "Qt::"
|
||||
qtdate = d.qtNamespace() + "Qt::"
|
||||
qttime = qtdate
|
||||
if d.isLldb:
|
||||
qtdate += "DateFormat::" # FIXME: Bug?...
|
||||
qttime += "TimeSpec::" # FIXME: Bug?...
|
||||
@@ -320,24 +322,25 @@ def qdump__QDir(d, value):
|
||||
d.putStringValueByAddress(privAddress + dirEntryOffset)
|
||||
if d.isExpanded():
|
||||
with Children(d):
|
||||
ns = d.qtNamespace()
|
||||
d.call(value, "count") # Fill cache.
|
||||
#d.putCallItem("absolutePath", value, "absolutePath")
|
||||
#d.putCallItem("canonicalPath", value, "canonicalPath")
|
||||
with SubItem(d, "absolutePath"):
|
||||
typ = d.lookupType(d.ns + "QString")
|
||||
typ = d.lookupType(ns + "QString")
|
||||
d.putItem(d.createValue(privAddress + absoluteDirEntryOffset, typ))
|
||||
with SubItem(d, "entryInfoList"):
|
||||
typ = d.lookupType(d.ns + "QList<" + d.ns + "QFileInfo>")
|
||||
typ = d.lookupType(ns + "QList<" + ns + "QFileInfo>")
|
||||
d.putItem(d.createValue(privAddress + fileInfosOffset, typ))
|
||||
with SubItem(d, "entryList"):
|
||||
typ = d.lookupType(d.ns + "QStringList")
|
||||
typ = d.lookupType(ns + "QStringList")
|
||||
d.putItem(d.createValue(privAddress + filesOffset, typ))
|
||||
|
||||
|
||||
def qdump__QFile(d, value):
|
||||
try:
|
||||
# Try using debug info first.
|
||||
ptype = d.lookupType(d.ns + "QFilePrivate").pointer()
|
||||
ptype = d.lookupType(d.qtNamespace() + "QFilePrivate").pointer()
|
||||
d_ptr = value["d_ptr"]["d"]
|
||||
fileNameAddress = d.addressOf(d_ptr.cast(ptype).dereference()["fileName"])
|
||||
d.putNumChild(1)
|
||||
@@ -370,7 +373,8 @@ def qdump__QFileInfo(d, value):
|
||||
d.putStringValueByAddress(filePathAddress)
|
||||
d.putNumChild(1)
|
||||
if d.isExpanded():
|
||||
with Children(d, childType=d.lookupType(d.ns + "QString")):
|
||||
ns = d.qtNamespace()
|
||||
with Children(d, childType=d.lookupType(ns + "QString")):
|
||||
d.putCallItem("absolutePath", value, "absolutePath")
|
||||
d.putCallItem("absoluteFilePath", value, "absoluteFilePath")
|
||||
d.putCallItem("canonicalPath", value, "canonicalPath")
|
||||
@@ -399,7 +403,7 @@ def qdump__QFileInfo(d, value):
|
||||
else:
|
||||
with SubItem(d, "permissions"):
|
||||
d.putEmptyValue()
|
||||
d.putType(d.ns + "QFile::Permissions")
|
||||
d.putType(ns + "QFile::Permissions")
|
||||
d.putNumChild(10)
|
||||
if d.isExpanded():
|
||||
with Children(d, 10):
|
||||
@@ -793,7 +797,7 @@ def qdump__QLocale(d, value):
|
||||
#global qqLocalesCount
|
||||
#if qqLocalesCount is None:
|
||||
# #try:
|
||||
# qqLocalesCount = int(value(d.ns + 'locale_data_size'))
|
||||
# qqLocalesCount = int(value(ns + 'locale_data_size'))
|
||||
# #except:
|
||||
# qqLocalesCount = 438
|
||||
#try:
|
||||
@@ -810,15 +814,16 @@ def qdump__QLocale(d, value):
|
||||
return
|
||||
# FIXME: Poke back for variants.
|
||||
if d.isExpanded():
|
||||
with Children(d, childType=d.lookupType(d.ns + "QChar"), childNumChild=0):
|
||||
ns = d.qtNamespace()
|
||||
with Children(d, childType=d.lookupType(ns + "QChar"), childNumChild=0):
|
||||
d.putCallItem("country", value, "country")
|
||||
d.putCallItem("language", value, "language")
|
||||
d.putCallItem("measurementSystem", value, "measurementSystem")
|
||||
d.putCallItem("numberOptions", value, "numberOptions")
|
||||
d.putCallItem("timeFormat_(short)", value,
|
||||
"timeFormat", d.ns + "QLocale::ShortFormat")
|
||||
"timeFormat", ns + "QLocale::ShortFormat")
|
||||
d.putCallItem("timeFormat_(long)", value,
|
||||
"timeFormat", d.ns + "QLocale::LongFormat")
|
||||
"timeFormat", ns + "QLocale::LongFormat")
|
||||
d.putCallItem("decimalPoint", value, "decimalPoint")
|
||||
d.putCallItem("exponential", value, "exponential")
|
||||
d.putCallItem("percent", value, "percent")
|
||||
@@ -858,7 +863,7 @@ def qdumpHelper__Qt4_QMap(d, value, forceLong):
|
||||
# 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 = d.lookupType(d.ns + "QMapNode<%s,%s>" % (keyType, valueType))
|
||||
nodeType = d.lookupType(d.qtNamespace() + "QMapNode<%s,%s>" % (keyType, valueType))
|
||||
nodePointerType = nodeType.pointer()
|
||||
payloadSize = nodeType.sizeof - 2 * nodePointerType.sizeof
|
||||
|
||||
@@ -976,9 +981,10 @@ def extractCString(table, offset):
|
||||
|
||||
def qdump__QObject(d, value):
|
||||
d.putQObjectNameValue(value)
|
||||
ns = d.qtNamespace()
|
||||
|
||||
try:
|
||||
privateTypeName = d.ns + "QObjectPrivate"
|
||||
privateTypeName = ns + "QObjectPrivate"
|
||||
privateType = d.lookupType(privateTypeName)
|
||||
staticMetaObject = value["staticMetaObject"]
|
||||
except:
|
||||
@@ -1030,7 +1036,7 @@ def qdump__QObject(d, value):
|
||||
with Children(d):
|
||||
|
||||
# Local data.
|
||||
if privateTypeName != d.ns + "QObjectPrivate":
|
||||
if privateTypeName != ns + "QObjectPrivate":
|
||||
if not privateType is None:
|
||||
with SubItem(d, "data"):
|
||||
d.putEmptyValue()
|
||||
@@ -1043,7 +1049,7 @@ def qdump__QObject(d, value):
|
||||
|
||||
d.putFields(value)
|
||||
# Parent and children.
|
||||
if stripClassTag(str(value.type)) == d.ns + "QObject":
|
||||
if stripClassTag(str(value.type)) == ns + "QObject":
|
||||
d.putSubItem("parent", d_ptr["parent"])
|
||||
d.putSubItem("children", d_ptr["children"])
|
||||
|
||||
@@ -1055,7 +1061,7 @@ def qdump__QObject(d, value):
|
||||
dynamicPropertyCount = 0
|
||||
else:
|
||||
extraDataType = d.lookupType(
|
||||
d.ns + "QObjectPrivate::ExtraData").pointer()
|
||||
ns + "QObjectPrivate::ExtraData").pointer()
|
||||
extraData = extraData.cast(extraDataType)
|
||||
ed = extraData.dereference()
|
||||
names = ed["propertyNames"]
|
||||
@@ -1077,7 +1083,7 @@ def qdump__QObject(d, value):
|
||||
|
||||
if d.isExpanded():
|
||||
# FIXME: Make this global. Don't leak.
|
||||
variant = "'%sQVariant'" % d.ns
|
||||
variant = "'%sQVariant'" % ns
|
||||
# Avoid malloc symbol clash with QVector
|
||||
gdb.execute("set $d = (%s*)calloc(sizeof(%s), 1)"
|
||||
% (variant, variant))
|
||||
@@ -1087,11 +1093,11 @@ def qdump__QObject(d, value):
|
||||
# Dynamic properties.
|
||||
if dynamicPropertyCount != 0:
|
||||
dummyType = d.voidPtrType().pointer()
|
||||
namesType = d.lookupType(d.ns + "QByteArray")
|
||||
namesType = d.lookupType(ns + "QByteArray")
|
||||
valuesBegin = values["d"]["begin"]
|
||||
valuesEnd = values["d"]["end"]
|
||||
valuesArray = values["d"]["array"]
|
||||
valuesType = d.lookupType(d.ns + "QVariant")
|
||||
valuesType = d.lookupType(ns + "QVariant")
|
||||
p = namesArray.cast(dummyType) + namesBegin
|
||||
q = valuesArray.cast(dummyType) + valuesBegin
|
||||
for i in xrange(dynamicPropertyCount):
|
||||
@@ -1124,9 +1130,9 @@ def qdump__QObject(d, value):
|
||||
#warn("FLAGS: %s " % flags)
|
||||
#warn("PROPERTY: %s %s " % (propertyType, propertyName))
|
||||
# #exp = '((\'%sQObject\'*)%s)->property("%s")' \
|
||||
# % (d.ns, value.address, propertyName)
|
||||
# % (ns, value.address, propertyName)
|
||||
#exp = '"((\'%sQObject\'*)%s)"' %
|
||||
#(d.ns, value.address,)
|
||||
#(ns, value.address,)
|
||||
#warn("EXPRESSION: %s" % exp)
|
||||
prop = d.call(value, "property",
|
||||
str(cleanAddress(metaStringData + metaData[offset])))
|
||||
@@ -1150,10 +1156,10 @@ def qdump__QObject(d, value):
|
||||
else:
|
||||
# User types.
|
||||
# func = "typeToName(('%sQVariant::Type')%d)"
|
||||
# % (d.ns, variantType)
|
||||
# % (ns, variantType)
|
||||
# type = str(d.call(value, func))
|
||||
# type = type[type.find('"') + 1 : type.rfind('"')]
|
||||
# type = type.replace("Q", d.ns + "Q") # HACK!
|
||||
# type = type.replace("Q", ns + "Q") # HACK!
|
||||
# data = d.call(value, "constData")
|
||||
# tdata = data.cast(d.lookupType(type).pointer())
|
||||
# .dereference()
|
||||
@@ -1465,15 +1471,16 @@ def qdump__QRegExp(d, value):
|
||||
# - QStringList captures (+3ptr +2enum +1bool +3pad?)
|
||||
# FIXME: Remove need to call. Needed to warm up cache.
|
||||
d.call(value, "capturedTexts") # create cache
|
||||
ns = d.qtNamespace()
|
||||
with SubItem(d, "syntax"):
|
||||
# value["priv"]["engineKey"["capturedCache"]
|
||||
address = engineKeyAddress + d.ptrSize()
|
||||
typ = d.lookupType(d.ns + "QRegExp::PatternSyntax")
|
||||
typ = d.lookupType(ns + "QRegExp::PatternSyntax")
|
||||
d.putItem(d.createValue(address, typ))
|
||||
with SubItem(d, "captures"):
|
||||
# value["priv"]["capturedCache"]
|
||||
address = privAddress + 3 * d.ptrSize() + 12
|
||||
typ = d.lookupType(d.ns + "QStringList")
|
||||
typ = d.lookupType(ns + "QStringList")
|
||||
d.putItem(d.createValue(address, typ))
|
||||
|
||||
|
||||
@@ -1496,7 +1503,8 @@ def qdump__QRegion(d, value):
|
||||
if d.isExpanded():
|
||||
with Children(d):
|
||||
v = d.ptrSize()
|
||||
rectType = d.lookupType(d.ns + "QRect")
|
||||
ns = d.qtNamespace()
|
||||
rectType = d.lookupType(ns + "QRect")
|
||||
d.putIntItem("numRects", n)
|
||||
d.putSubItem("extents", d.createValue(pp + 2 * v, rectType))
|
||||
d.putSubItem("innerRect", d.createValue(pp + 2 * v + rectType.sizeof, rectType))
|
||||
@@ -1504,12 +1512,12 @@ def qdump__QRegion(d, value):
|
||||
# FIXME
|
||||
try:
|
||||
# Can fail if QVector<QRect> debuginfo is missing.
|
||||
vectType = d.lookupType("%sQVector<%sQRect>" % (d.ns, d.ns))
|
||||
vectType = d.lookupType("%sQVector<%sQRect>" % (ns, ns))
|
||||
d.putSubItem("rects", d.createValue(pp + v, vectType))
|
||||
except:
|
||||
with SubItem(d, "rects"):
|
||||
d.putItemCount(n)
|
||||
d.putType("%sQVector<%sQRect>" % (d.ns, d.ns))
|
||||
d.putType("%sQVector<%sQRect>" % (ns, ns))
|
||||
d.putNumChild(0)
|
||||
|
||||
|
||||
@@ -1761,7 +1769,7 @@ def qdump__QUrl(d, value):
|
||||
d.putValue(url, Hex4EncodedLittleEndian)
|
||||
d.putNumChild(8)
|
||||
if d.isExpanded():
|
||||
stringType = d.lookupType(d.ns + "QString")
|
||||
stringType = d.lookupType(d.qtNamespace() + "QString")
|
||||
with Children(d):
|
||||
d.putIntItem("port", port)
|
||||
d.putGenericItem("scheme", stringType, scheme, Hex4EncodedLittleEndian)
|
||||
@@ -1774,12 +1782,12 @@ def qdump__QUrl(d, value):
|
||||
|
||||
def qdumpHelper_QVariant_0(d, data):
|
||||
# QVariant::Invalid
|
||||
d.putBetterType("%sQVariant (invalid)" % d.ns)
|
||||
d.putBetterType("%sQVariant (invalid)" % d.qtNamespace())
|
||||
d.putValue("(invalid)")
|
||||
|
||||
def qdumpHelper_QVariant_1(d, data):
|
||||
# QVariant::Bool
|
||||
d.putBetterType("%sQVariant (bool)" % d.ns)
|
||||
d.putBetterType("%sQVariant (bool)" % d.qtNamespace())
|
||||
if int(data["b"]):
|
||||
d.putValue("true")
|
||||
else:
|
||||
@@ -1787,27 +1795,27 @@ def qdumpHelper_QVariant_1(d, data):
|
||||
|
||||
def qdumpHelper_QVariant_2(d, data):
|
||||
# QVariant::Int
|
||||
d.putBetterType("%sQVariant (int)" % d.ns)
|
||||
d.putBetterType("%sQVariant (int)" % d.qtNamespace())
|
||||
d.putValue(int(data["i"]))
|
||||
|
||||
def qdumpHelper_QVariant_3(d, data):
|
||||
# uint
|
||||
d.putBetterType("%sQVariant (uint)" % d.ns)
|
||||
d.putBetterType("%sQVariant (uint)" % d.qtNamespace())
|
||||
d.putValue(int(data["u"]))
|
||||
|
||||
def qdumpHelper_QVariant_4(d, data):
|
||||
# qlonglong
|
||||
d.putBetterType("%sQVariant (qlonglong)" % d.ns)
|
||||
d.putBetterType("%sQVariant (qlonglong)" % d.qtNamespace())
|
||||
d.putValue(int(data["ll"]))
|
||||
|
||||
def qdumpHelper_QVariant_5(d, data):
|
||||
# qulonglong
|
||||
d.putBetterType("%sQVariant (qulonglong)" % d.ns)
|
||||
d.putBetterType("%sQVariant (qulonglong)" % d.qtNamespace())
|
||||
d.putValue(int(data["ull"]))
|
||||
|
||||
def qdumpHelper_QVariant_6(d, data):
|
||||
# QVariant::Double
|
||||
d.putBetterType("%sQVariant (double)" % d.ns)
|
||||
d.putBetterType("%sQVariant (double)" % d.qtNamespace())
|
||||
d.putValue(float(data["d"]))
|
||||
|
||||
qdumpHelper_QVariants_A = [
|
||||
@@ -1893,7 +1901,7 @@ def qdumpHelper__QVariant(d, value):
|
||||
else:
|
||||
innert = qdumpHelper_QVariants_C[variantType - 64]
|
||||
|
||||
inner = d.ns + innert
|
||||
inner = d.qtNamespace() + innert
|
||||
|
||||
innerType = d.lookupType(inner)
|
||||
sizePD = 8 # sizeof(QVariant::Private::Data)
|
||||
@@ -1908,7 +1916,7 @@ def qdumpHelper__QVariant(d, value):
|
||||
|
||||
d.putEmptyValue(-99)
|
||||
d.putItem(val)
|
||||
d.putBetterType("%sQVariant (%s)" % (d.ns, innert))
|
||||
d.putBetterType("%sQVariant (%s)" % (d.qtNamespace(), innert))
|
||||
|
||||
return (None, innert, True)
|
||||
|
||||
@@ -1922,14 +1930,15 @@ def qdump__QVariant(d, value):
|
||||
# User types.
|
||||
d_ptr = value["d"]
|
||||
typeCode = int(d_ptr["type"])
|
||||
ns = d.qtNamespace()
|
||||
try:
|
||||
exp = "((const char *(*)(int))%sQMetaType::typeName)(%d)" % (d.ns, typeCode)
|
||||
exp = "((const char *(*)(int))%sQMetaType::typeName)(%d)" % (ns, typeCode)
|
||||
type = str(d.parseAndEvaluate(exp))
|
||||
except:
|
||||
exp = "%sQMetaType::typeName(%d)" % (d.ns, typeCode)
|
||||
exp = "%sQMetaType::typeName(%d)" % (ns, typeCode)
|
||||
type = str(d.parseAndEvaluate(exp))
|
||||
type = type[type.find('"') + 1 : type.rfind('"')]
|
||||
type = type.replace("Q", d.ns + "Q") # HACK!
|
||||
type = type.replace("Q", ns + "Q") # HACK!
|
||||
type = type.replace("uint", "unsigned int") # HACK!
|
||||
type = type.replace("COMMA", ",") # HACK!
|
||||
type = type.replace(" ,", ",") # Lldb
|
||||
@@ -1937,7 +1946,7 @@ def qdump__QVariant(d, value):
|
||||
data = d.call(value, "constData")
|
||||
#warn("DATA: %s" % data)
|
||||
d.putEmptyValue(-99)
|
||||
d.putType("%sQVariant (%s)" % (d.ns, type))
|
||||
d.putType("%sQVariant (%s)" % (ns, type))
|
||||
d.putNumChild(1)
|
||||
tdata = data.cast(d.lookupType(type).pointer()).dereference()
|
||||
if d.isExpanded():
|
||||
@@ -2075,7 +2084,7 @@ def qdump__QTJSC__JSValue(d, value):
|
||||
|
||||
try:
|
||||
# FIXME: This might not always be a variant.
|
||||
delegateType = d.lookupType(d.ns + "QScript::QVariantDelegate").pointer()
|
||||
delegateType = d.lookupType(d.qtNamespace() + "QScript::QVariantDelegate").pointer()
|
||||
delegate = scriptObject["d"]["delegate"].cast(delegateType)
|
||||
#d.putSubItem("delegate", delegate)
|
||||
variant = delegate["m_value"]
|
||||
@@ -2096,21 +2105,22 @@ def qdump__QScriptValue(d, value):
|
||||
# type QScriptValuePrivate::Type: { JavaScriptCore, Number, String }
|
||||
#d.putEmptyValue()
|
||||
dd = value["d_ptr"]["d"]
|
||||
ns = d.qtNamespace()
|
||||
if d.isNull(dd):
|
||||
d.putValue("(invalid)")
|
||||
d.putNumChild(0)
|
||||
return
|
||||
if int(dd["type"]) == 1: # Number
|
||||
d.putValue(dd["numberValue"])
|
||||
d.putType("%sQScriptValue (Number)" % d.ns)
|
||||
d.putType("%sQScriptValue (Number)" % ns)
|
||||
d.putNumChild(0)
|
||||
return
|
||||
if int(dd["type"]) == 2: # String
|
||||
d.putStringValue(dd["stringValue"])
|
||||
d.putType("%sQScriptValue (String)" % d.ns)
|
||||
d.putType("%sQScriptValue (String)" % ns)
|
||||
return
|
||||
|
||||
d.putType("%sQScriptValue (JSCoreValue)" % d.ns)
|
||||
d.putType("%sQScriptValue (JSCoreValue)" % ns)
|
||||
x = dd["jscValue"]["u"]
|
||||
tag = x["asBits"]["tag"]
|
||||
payload = x["asBits"]["payload"]
|
||||
@@ -2144,11 +2154,11 @@ def qdump__QScriptValue(d, value):
|
||||
|
||||
try:
|
||||
# This might already fail for "native" payloads.
|
||||
scriptObjectType = d.lookupType(d.ns + "QScriptObject").pointer()
|
||||
scriptObjectType = d.lookupType(ns + "QScriptObject").pointer()
|
||||
scriptObject = payload.cast(scriptObjectType)
|
||||
|
||||
# FIXME: This might not always be a variant.
|
||||
delegateType = d.lookupType(d.ns + "QScript::QVariantDelegate").pointer()
|
||||
delegateType = d.lookupType(ns + "QScript::QVariantDelegate").pointer()
|
||||
delegate = scriptObject["d"]["delegate"].cast(delegateType)
|
||||
#d.putSubItem("delegate", delegate)
|
||||
|
||||
@@ -2156,7 +2166,7 @@ def qdump__QScriptValue(d, value):
|
||||
#d.putSubItem("variant", variant)
|
||||
t = qdump__QVariant(d, variant)
|
||||
# Override the "QVariant (foo)" output
|
||||
d.putBetterType("%sQScriptValue (%s)" % (d.ns, t))
|
||||
d.putBetterType("%sQScriptValue (%s)" % (ns, t))
|
||||
if t != "JSCoreValue":
|
||||
return
|
||||
except:
|
||||
|
@@ -321,7 +321,7 @@ def qdump__std__stringHelper1(d, value, charSize):
|
||||
qdump_stringHelper(d, sizePtr, size * charSize, charSize)
|
||||
|
||||
def qdump_stringHelper(d, data, size, charSize):
|
||||
cutoff = min(size, qqStringCutOff)
|
||||
cutoff = min(size, d.stringCutOff)
|
||||
mem = d.readMemory(data, cutoff)
|
||||
if charSize == 1:
|
||||
encodingType = Hex2EncodedLatin1
|
||||
|
@@ -910,7 +910,7 @@ void tst_Dumpers::dumper()
|
||||
"python from gdbbridge import *\n"
|
||||
"run " + nograb + "\n"
|
||||
"up\n"
|
||||
"python print('@%sS@%s@' % ('N', qtNamespace()))\n"
|
||||
"python print('@%sS@%s@' % ('N', theDumper.qtNamespace()))\n"
|
||||
"bb options:fancy,autoderef,dyntype,pe vars: expanded:" + expanded + " typeformats:\n";
|
||||
} else {
|
||||
cmds += "run\n";
|
||||
|
Reference in New Issue
Block a user