Commit e1760131 authored by hjk's avatar hjk

Debugger: Move some global variables to the Dumper class

Change-Id: I5c8fd8a48f27ac70e6e39f645d64dcd788752e73
Reviewed-by: default avatarhjk <hjk121@nokiamail.com>
parent f9ff6303
......@@ -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:
......
This diff is collapsed.
......@@ -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)
......
This diff is collapsed.
......@@ -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";
......
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