Commit 9db98dc5 authored by hjk's avatar hjk

Debugger: Move some common code back to qttypes.py

Change-Id: I2306277ec39d6149c376bde584c51551a780877d
Reviewed-by: default avatarhjk <hjk121@nokiamail.com>
parent 4f282282
......@@ -14,7 +14,7 @@ import traceback
cdbLoaded = False
lldbLoaded = False
gdbLoaded = False
gdbLoaded = True
#######################################################################
#
......@@ -25,6 +25,15 @@ gdbLoaded = False
def warn(message):
print "XXX: %s\n" % message.encode("latin1")
def valueAddressAsInt(value):
return long(value.address)
def pointerAsInt(value):
return long(value)
def asInt(value):
return int(value)
def savePrint(output):
try:
print(output)
......@@ -226,7 +235,7 @@ def readRawMemory(base, size):
pass
s = ""
t = lookupType("unsigned char").pointer()
base = base.cast(t)
base = gdb.Value(base).cast(t)
for i in xrange(size):
s += "%02x" % int(base.dereference())
base += 1
......@@ -1192,19 +1201,6 @@ def encodeChar2Array(p):
def encodeChar4Array(p):
return encodeCArray(p, "unsigned int", "2e0000002e0000002e000000")
def qByteArrayData(value):
private = value['d']
checkRef(private['ref'])
try:
# Qt 5. Will fail on Qt 4 due to the missing 'offset' member.
offset = private['offset']
charPointerType = lookupType('char *')
data = private.cast(charPointerType) + private['offset']
return data, int(private['size']), int(private['alloc'])
except:
# Qt 4:
return private['data'], int(private['size']), int(private['alloc'])
def computeLimit(size, limit):
if limit is None:
return size
......@@ -1212,49 +1208,6 @@ def computeLimit(size, limit):
return min(size, qqStringCutOff)
return min(size, limit)
def encodeByteArray(value, limit = None):
data, size, alloc = qByteArrayData(value)
if alloc != 0:
check(0 <= size and size <= alloc and alloc <= 100*1000*1000)
limit = computeLimit(size, limit)
s = readRawMemory(data, limit)
if limit < size:
s += "2e2e2e"
return s
def qStringData(value):
private = value['d']
checkRef(private['ref'])
try:
# Qt 5. Will fail on Qt 4 due to the missing 'offset' member.
offset = private['offset']
ushortPointerType = lookupType('ushort *')
data = private.cast(ushortPointerType) + offset / 2
return data, int(private['size']), int(private['alloc'])
except:
# Qt 4.
return private['data'], int(private['size']), int(private['alloc'])
def encodeString(value, limit = 0):
data, size, alloc = qStringData(value)
if alloc != 0:
check(0 <= size and size <= alloc and alloc <= 100*1000*1000)
limit = computeLimit(size, limit)
s = readRawMemory(data, 2 * limit)
if limit < size:
s += "2e002e002e00"
return s
def encodeByteArray(value, limit = None):
data, size, alloc = qByteArrayData(value)
if alloc != 0:
check(0 <= size and size <= alloc and alloc <= 100*1000*1000)
limit = computeLimit(size, limit)
s = readRawMemory(data, limit)
if limit < size:
s += "2e2e2e"
return s
def stripTypedefs(type):
type = type.unqualified()
while type.code == TypedefCode:
......@@ -1399,6 +1352,13 @@ class Dumper:
self.useDynamicType = True
self.expandedINames = {}
self.charType_ = None
self.intType_ = None
self.sizetType_ = None
self.charPtrType_ = None
self.voidType_ = None
self.voidPtrType_ = None
def __init__(self, args):
self.defaultInit()
......@@ -1552,6 +1512,8 @@ class Dumper:
#print('data=[' + locals + sep + watchers + ']\n')
def lookupType(self, typeName):
return lookupType(typeName)
def handleWatch(self, exp, iname):
exp = str(exp)
......@@ -1599,6 +1561,33 @@ class Dumper:
self.currentNumChild = 0
self.putNumChild(0)
def intType(self):
if self.intType_ is None:
self.intType_ = self.lookupType('int')
return self.intType_
def charType(self):
if self.charType_ is None:
self.charType_ = self.lookupType('char')
return self.charType_
def sizetType(self):
if self.sizetType_ is None:
self.sizetType_ = self.lookupType('size_t')
return self.sizetType_
def charPtrType(self):
if self.charPtrType_ is None:
self.charPtrType_ = self.lookupType('char*')
return self.charPtrType_
def voidPtrType(self):
if self.voidPtrType_ is None:
self.voidType_ = self.lookupType('void*')
return self.voidPtrType_
def voidPtrSize(self):
return self.voidPtrType().sizeof
def put(self, value):
self.output.append(value)
......@@ -1674,11 +1663,6 @@ class Dumper:
self.putValue("0x%x" % value.cast(
lookupType("unsigned long")), None, -1)
def putStringValue(self, value, priority = 0):
if not value is None:
str = encodeString(value)
self.putValue(str, Hex4EncodedLittleEndian, priority)
def putDisplay(self, format, value = None, cmd = None):
self.put('editformat="%s",' % format)
if cmd is None:
......@@ -1687,9 +1671,13 @@ class Dumper:
else:
self.put('editvalue="%s|%s",' % (cmd, value))
def putByteArrayValue(self, value):
str = encodeByteArray(value)
self.putValue(str, Hex2EncodedLatin1)
def computeLimit(self, size, limit):
if limit is None:
return size
if limit == 0:
#return min(size, qqStringCutOff)
return min(size, 100)
return min(size, limit)
def putName(self, name):
self.put('name="%s",' % name)
......@@ -1700,7 +1688,7 @@ class Dumper:
self.put('key="%s",' % encodeString(value))
self.put('keyencoded="%s",' % Hex4EncodedLittleEndian)
elif str(value.type) == ns + "QByteArray":
self.put('key="%s",' % encodeByteArray(value))
self.put('key="%s",' % self.encodeByteArray(value))
self.put('keyencoded="%s",' % Hex2EncodedLatin1)
else:
self.put('name="%s",' % value)
......@@ -1770,7 +1758,7 @@ class Dumper:
self.put('addrstep="0x%x",' % long(typeobj.sizeof))
self.put('arrayencoding="%s",' % simpleEncoding(typeobj))
self.put('arraydata="')
self.put(readRawMemory(base, size))
self.put(self.readRawMemory(base, size))
self.put('",')
return True
......@@ -1817,8 +1805,8 @@ class Dumper:
def putArrayData(self, type, base, n,
childNumChild = None, maxNumChild = 10000):
base = base.cast(type.pointer())
if not self.tryPutArrayContents(type, base, n):
base = base.cast(type.pointer())
with Children(self, n, type, childNumChild, maxNumChild,
base, type.sizeof):
for i in self.childRange():
......@@ -2200,7 +2188,7 @@ class Dumper:
if not isNull(p):
objectName = p.dereference()["objectName"]
if not objectName is None:
data, size, alloc = qStringData(objectName)
data, size, alloc = qStringData(self, objectName)
if size > 0:
str = readRawMemory(data, 2 * size)
self.putValue(str, Hex4EncodedLittleEndian, 1)
......@@ -2211,18 +2199,8 @@ class Dumper:
return readRawMemory(base, size)
def putFields(self, value, dumpBase = True):
fields = extractFields(value)
# FIXME: Merge into this function.
if gdbLoaded:
self.putFieldsGdb(fields, value, dumpBase)
return
for field in fields:
with SubItem(self, field.name):
self.putItem(field)
fields = extractFields(value)
def putFieldsGdb(self, fields, value, dumpBase):
#warn("TYPE: %s" % type)
#warn("FIELDS: %s" % fields)
baseNumber = 0
......@@ -2377,7 +2355,6 @@ def qmlb(args):
return bp
registerCommand("qmlb", qmlb)
gdbLoaded = True
currentDir = os.path.dirname(os.path.abspath(inspect.getfile(inspect.currentframe())))
execfile(os.path.join(currentDir, "qttypes.py"))
......
......@@ -68,14 +68,6 @@ DisplayUtf8String \
= range(7)
def lookupType(name):
if name == "int":
return intType
if name == "size_t":
return sizeTType
if name == "char":
return charType
if name == "char *":
return charPtrType
return None
def isSimpleType(typeobj):
......@@ -89,7 +81,7 @@ def isSimpleType(typeobj):
#
#######################################################################
qqStringCutOff = 1000
qqStringCutOff = 10000
# This is a cache mapping from 'type name' to 'display alternatives'.
qqFormats = {}
......@@ -103,6 +95,12 @@ qqEditable = {}
# This keeps canonical forms of the typenames, without array indices etc.
qqStripForFormat = {}
def valueAddressAsInt(value):
return value.AddressOf().GetValueAsUnsigned()
def pointerAsInt(value):
return value.GetValueAsUnsigned()
def templateArgument(type, index):
return type.GetTemplateArgumentType(index)
......@@ -162,30 +160,6 @@ def showException(msg, exType, exValue, exTraceback):
def registerCommand(name, func):
pass
def qByteArrayData(value):
private = value['d']
checkRef(private['ref'])
try:
# Qt 5. Will fail on Qt 4 due to the missing 'offset' member.
offset = private['offset']
data = int(private) + int(offset)
return data, int(private['size']), int(private['alloc'])
except:
# Qt 4:
return private['data'], int(private['size']), int(private['alloc'])
def qStringData(value):
private = value['d']
checkRef(private['ref'])
try:
# Qt 5. Will fail on Qt 4 due to the missing 'offset' member.
offset = private['offset']
data = int(private) + int(offset)
return data, int(private['size'].GetValue()), int(private['alloc'])
except:
# Qt 4.
return private['data'], int(private['size']), int(private['alloc'])
def currentFrame():
currentThread = self.process.GetThreadAtIndex(0)
return currentThread.GetFrameAtIndex(0)
......@@ -296,7 +270,9 @@ def checkRef(ref):
def impl_SBValue__add__(self, offset):
if self.GetType().IsPointerType():
return self.GetChildAtIndex(int(offset), lldb.eNoDynamicValues, True).AddressOf()
address = self.GetValueAsUnsigned() + offset.GetValueAsSigned()
address = address & 0xFFFFFFFFFFFFFFFF # Force unsigned
return self.CreateValueFromAddress(None, address, self.GetType())
raise RuntimeError("SBValue.__add__ not implemented: %s" % self.GetType())
return NotImplemented
......@@ -320,13 +296,15 @@ def impl_SBValue__le__(self, other):
def impl_SBValue__int__(self):
return int(self.GetValue(), 0)
def impl_SBValue__long__(self):
return int(self.GetValue(), 0)
def impl_SBValue__getitem__(self, name):
if self.GetType().IsPointerType() and isinstance(name, int):
innertype = self.Dereference().GetType()
address = self.GetValueAsUnsigned() + name * innertype.GetByteSize()
return self.CreateValueFromAddress("xx", address, innertype)
#return self.GetChildAtIndex(int(offset))
#return self.GetChildAtIndex(int(offset), lldb.eNoDynamicValues, True)
address = address & 0xFFFFFFFFFFFFFFFF # Force unsigned
return self.CreateValueFromAddress(None, address, innertype)
return self.GetChildMemberWithName(name)
def childAt(value, index):
......@@ -504,7 +482,7 @@ class SubItem:
self.d.currentTypePriority = self.savedTypePriority
return True
class Debugger:
class Dumper:
def __init__(self):
self.debugger = lldb.SBDebugger.Create()
#self.debugger.SetLoggingCallback(loggingCallback)
......@@ -536,6 +514,38 @@ class Debugger:
self.currentChildType = None
self.currentChildNumChild = None
self.charType_ = None
self.intType_ = None
self.sizetType_ = None
self.charPtrType_ = None
self.voidType_ = None
def intType(self):
if self.intType_ is None:
self.intType_ = self.target.GetModuleAtIndex(0).FindFirstType('int')
return self.intType_
def charType(self):
if self.charType_ is None:
self.charType_ = self.target.GetModuleAtIndex(0).FindFirstType('char')
return self.charType_
def charPtrType(self):
if self.charPtrType_ is None:
self.charPtrType_ = self.charType().GetPointerType()
return self.charPtrType_
def voidPtrType(self):
return self.charPtrType() # FIXME
def voidPtrSize(self):
return self.charPtrType().GetByteSize()
def sizetType(self):
if self.sizetType_ is None:
self.sizetType_ = self.lookupType('size_t')
return self.sizetType_
def handleCommand(self, command):
result = lldb.SBCommandReturnObject()
self.debugger.GetCommandInterpreter().HandleCommand(command, result)
......@@ -594,11 +604,11 @@ class Debugger:
return False
size = n * typeobj.sizeof
self.put('childtype="%s",' % typeobj)
self.put('addrbase="0x%x",' % long(base))
self.put('addrstep="0x%x",' % long(typeobj.sizeof))
self.put('addrbase="0x%x",' % int(base))
self.put('addrstep="%d",' % typeobj.sizeof)
self.put('arrayencoding="%s",' % simpleEncoding(typeobj))
self.put('arraydata="')
self.put(self.readRawMemory(long(base), size))
self.put(self.readRawMemory(base, size))
self.put('",')
return True
......@@ -750,14 +760,10 @@ class Debugger:
self.currentType = str(type)
self.currentTypePriority = self.currentTypePriority + 1
def putStringValue(self, value, priority = 0):
if not value is None:
str = self.encodeString(value)
self.putValue(str, Hex4EncodedLittleEndian, priority)
def readRawMemory(self, base, size):
error = lldb.SBError()
contents = self.process.ReadMemory(int(base), size, error)
contents = self.process.ReadMemory(base.GetLoadAddress(), size, error)
return binascii.hexlify(contents)
def computeLimit(self, size, limit):
......@@ -768,26 +774,6 @@ class Debugger:
return min(size, 100)
return min(size, limit)
def encodeString(self, value, limit = 0):
data, size, alloc = qStringData(value)
if alloc != 0:
check(0 <= size and size <= alloc and alloc <= 100*1000*1000)
limit = self.computeLimit(size, limit)
s = self.readRawMemory(data, 2 * limit)
if limit < size:
s += "2e002e002e00"
return s
def encodeByteArray(self, value, limit = None):
data, size, alloc = qByteArrayData(value)
if alloc != 0:
check(0 <= size and size <= alloc and alloc <= 100*1000*1000)
limit = self.computeLimit(size, limit)
s = self.readRawMemory(data, limit)
if limit < size:
s += "2e2e2e"
return s
def putValue(self, value, encoding = None, priority = 0):
# Higher priority values override lower ones.
if priority >= self.currentValuePriority:
......@@ -795,10 +781,6 @@ class Debugger:
self.currentValuePriority = priority
self.currentValueEncoding = encoding
def putByteArrayValue(self, value):
str = self.encodeByteArray(value)
self.putValue(str, Hex2EncodedLatin1)
def stripNamespaceFromType(self, typeName):
#type = stripClassTag(typeName)
type = typeName
......@@ -901,13 +883,6 @@ class Debugger:
self.report('')
def reportData(self, _ = None):
# Hack.
global charPtrType, charType, intType, sizeTType
intType = self.target.GetModuleAtIndex(0).FindFirstType('int')
sizeTType = self.target.GetModuleAtIndex(0).FindFirstType('size_t')
charType = self.target.GetModuleAtIndex(0).FindFirstType('char')
charPtrType = charType.GetPointerType()
self.reportRegisters()
if self.process is None:
self.report('process="none"')
......@@ -1251,7 +1226,7 @@ execfile(os.path.join(currentDir, "qttypes.py"))
def doit():
db = Debugger()
db = Dumper()
db.report('state="enginesetupok"')
while True:
......@@ -1266,7 +1241,7 @@ def doit():
def testit():
db = Debugger()
db = Dumper()
error = lldb.SBError()
db.target = db.debugger.CreateTarget(sys.argv[2], None, None, True, error)
......
This diff is collapsed.
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