Commit 780c8283 authored by hjk's avatar hjk

Debugger: Adjust QList dumpers to LLDB needs

Change-Id: I01071510d422176b632bcaf93e009ad5056ea777
Reviewed-by: default avatarhjk <hjk121@nokiamail.com>
parent a5e0ab13
......@@ -25,14 +25,12 @@ gdbLoaded = True
def warn(message):
print "XXX: %s\n" % message.encode("latin1")
def valueAddressAsInt(value):
return long(value.address)
def pointerAsInt(value):
return long(value)
def directBaseClass(typeobj, index = 0):
# FIXME: Check it's really a base.
return typeobj.fields()[index]
def asInt(value):
return int(value)
def createPointerValue(context, address, pointeeType):
return gdb.Value(address).cast(pointeeType.pointer())
def savePrint(output):
try:
......@@ -471,9 +469,6 @@ def childAt(value, index):
# them transparently.
return value
def addressOf(value):
return gdb.Value(value.address).cast(value.type.pointer())
#gdb.Value.child = impl_Value_child
......@@ -1589,6 +1584,9 @@ class Dumper:
def voidPtrSize(self):
return self.voidPtrType().sizeof
def addressOf(self, value):
return long(value.address)
def put(self, value):
self.output.append(value)
......@@ -1624,7 +1622,7 @@ class Dumper:
self.putNumChild(0)
self.currentValue = None
def putBetterType(self, type, priority = 0):
def putBetterType(self, type):
self.currentType = str(type)
self.currentTypePriority = self.currentTypePriority + 1
......
......@@ -95,14 +95,11 @@ qqEditable = {}
# This keeps canonical forms of the typenames, without array indices etc.
qqStripForFormat = {}
def valueAddressAsInt(value):
return value.AddressOf().GetValueAsUnsigned()
def templateArgument(typeobj, index):
return typeobj.GetTemplateArgumentType(index)
def pointerAsInt(value):
return value.GetValueAsUnsigned()
def templateArgument(type, index):
return type.GetTemplateArgumentType(index)
def directBaseClass(typeobj, index = 0):
return typeobj.GetDirectBaseClassAtIndex(index)
def stripForFormat(typeName):
global qqStripForFormat
......@@ -268,22 +265,32 @@ def checkRef(ref):
check(count >= minimum)
check(count < 1000000)
def createPointerValue(context, address, pointeeType):
addr = int(address) & 0xFFFFFFFFFFFFFFFF
return context.CreateValueFromAddress(None, addr, pointeeType).AddressOf()
def impl_SBValue__add__(self, offset):
if self.GetType().IsPointerType():
address = self.GetValueAsUnsigned() + offset.GetValueAsSigned()
if isinstance(offset, int) or isinstance(offset, long):
pass
else:
offset = offset.GetValueAsSigned()
itemsize = self.GetType().GetDereferencedType().GetByteSize()
address = self.GetValueAsUnsigned() + offset * itemsize
address = address & 0xFFFFFFFFFFFFFFFF # Force unsigned
return self.CreateValueFromAddress(None, address, self.GetType())
return createPointerValue(self, address, self.GetType().GetPointeeType())
raise RuntimeError("SBValue.__add__ not implemented: %s" % self.GetType())
return NotImplemented
def impl_SBValue__sub__(self, other):
if self.GetType().IsPointerType():
if isinstance(other, int):
return self.GetChildAtIndex(-other, lldb.eNoDynamicValues, True).AddressOf()
if isinstance(other, int) or isinstance(other, long):
address = self.GetValueAsUnsigned() - offset.GetValueAsSigned()
address = address & 0xFFFFFFFFFFFFFFFF # Force unsigned
return self.CreateValueFromAddress(None, address, self.GetType())
if other.GetType().IsPointerType():
itemsize = self.GetType().GetDereferencedType().GetByteSize()
return (int(self) - int(other)) / itemsize
return impl_SBValue__add__(self, -int(other))
raise RuntimeError("SBValue.__sub__ not implemented: %s" % self.GetType())
return NotImplemented
......@@ -294,7 +301,8 @@ def impl_SBValue__le__(self, other):
return NotImplemented
def impl_SBValue__int__(self):
return int(self.GetValue(), 0)
return self.GetValueAsSigned()
#return int(self.GetValue(), 0)
def impl_SBValue__long__(self):
return int(self.GetValue(), 0)
......@@ -310,9 +318,6 @@ def impl_SBValue__getitem__(self, name):
def childAt(value, index):
return value.GetChildAtIndex(index)
def addressOf(value):
return value.address_of
lldb.SBValue.__add__ = impl_SBValue__add__
lldb.SBValue.__sub__ = impl_SBValue__sub__
lldb.SBValue.__le__ = impl_SBValue__le__
......@@ -547,6 +552,9 @@ class Dumper:
self.sizetType_ = self.lookupType('size_t')
return self.sizetType_
def addressOf(self, value):
return int(value.GetLoadAddress())
def handleCommand(self, command):
result = lldb.SBCommandReturnObject()
self.debugger.GetCommandInterpreter().HandleCommand(command, result)
......@@ -757,14 +765,23 @@ class Dumper:
self.currentType = str(type)
self.currentTypePriority = priority
def putBetterType(self, type, priority = 0):
def putBetterType(self, type):
try:
self.currentType = type.GetName()
except:
self.currentType = str(type)
self.currentTypePriority = self.currentTypePriority + 1
def readRawMemory(self, base, size):
error = lldb.SBError()
contents = self.process.ReadMemory(base.GetLoadAddress(), size, error)
#warn("BASE: %s " % base)
#warn("SIZE: %s " % size)
base = int(base) & 0xFFFFFFFFFFFFFFFF
size = int(size) & 0xFFFFFFFF
#warn("BASEX: %s " % base)
#warn("SIZEX: %s " % size)
contents = self.process.ReadMemory(base, size, error)
return binascii.hexlify(contents)
def computeLimit(self, size, limit):
......
......@@ -67,14 +67,15 @@ def qdump__QBasicAtomicPointer(d, value):
d.putItem(value["_q_value"])
def qByteArrayData(d, value):
private = value['d']
private = value['d'].dereference()
checkRef(private['ref'])
size = int(private['size'])
alloc = int(private['alloc'])
try:
# Qt 5. Will fail on Qt 4 due to the missing 'offset' member.
offset = private['offset']
data = private.cast(d.charPtrType()) + offset
offset = int(private['offset'])
addr = d.addressOf(private) + offset
data = createPointerValue(value, addr, d.charType())
return data, size, alloc
except:
# Qt 4:
......@@ -597,22 +598,17 @@ def qdump__QHostAddress(d, value):
d.putFields(data)
def qdump__QList(d, value):
d_ptr = childAt(value, 0)["d"].dereference()
begin = int(d_ptr["begin"])
end = int(d_ptr["end"])
array = addressOf(d_ptr["array"])
dptr = childAt(value, 0)["d"]
private = dptr.dereference()
begin = int(private["begin"])
end = int(private["end"])
array = private["array"]
check(begin >= 0 and end >= 0 and end <= 1000 * 1000 * 1000)
size = end - begin
check(size >= 0)
checkRef(d_ptr["ref"])
checkRef(private["ref"])
# Additional checks on pointer arrays.
innerType = templateArgument(value.type, 0)
innerTypeIsPointer = innerType.code == PointerCode \
and str(innerType.target().unqualified()) != "char"
if innerTypeIsPointer:
p = array.cast(innerType.pointer()) + begin
checkPointerRange(p, min(size, 100))
d.putItemCount(size)
d.putNumChild(size)
......@@ -623,20 +619,24 @@ def qdump__QList(d, value):
# but this data is available neither in the compiled binary nor
# in the frontend.
# So as first approximation only do the 'isLarge' check:
isInternal = innerSize <= d_ptr.type.sizeof and d.isMovableType(innerType)
innerTypePointer = innerType.pointer()
p = array.cast(d.charPtrType().pointer()) + begin
if innerTypeIsPointer:
inner = innerType.target()
stepSize = dptr.type.sizeof
isInternal = innerSize <= stepSize and d.isMovableType(innerType)
addr = d.addressOf(array) + begin * stepSize
if isInternal:
if innerSize == stepSize:
p = createPointerValue(value, addr, innerType)
d.putArrayData(innerType, p, size)
else:
inner = innerType
# about 0.5s / 1000 items
with Children(d, size, maxNumChild=2000, childType=inner):
with Children(d, size, childType=innerType):
for i in d.childRange():
if isInternal:
d.putSubItem(i, p.cast(innerTypePointer).dereference())
p = createPointerValue(value, addr + i * stepSize, innerType)
d.putSubItem(i, p.dereference())
else:
d.putSubItem(i, p.cast(innerTypePointer.pointer()).dereference())
p = createPointerValue(value, addr, innerType.pointer())
# about 0.5s / 1000 items
with Children(d, size, maxNumChild=2000, childType=innerType):
for i in d.childRange():
d.putSubItem(i, p.dereference().dereference())
p += 1
def qform__QImage():
......@@ -1585,19 +1585,9 @@ def qdump__QStringRef(d, value):
def qdump__QStringList(d, value):
d_ptr = value['d']
begin = d_ptr['begin']
end = d_ptr['end']
size = end - begin
check(size >= 0)
check(size <= 10 * 1000 * 1000)
checkRef(d_ptr["ref"])
d.putItemCount(size)
d.putNumChild(size)
if d.isExpanded():
innerType = d.lookupType(d.ns + "QString")
innerTypePP = innerType.pointer().pointer()
d.putArrayData(innerType, d_ptr["array"].cast(innerTypePP) + begin, size, 0)
listType = directBaseClass(value.type).type
qdump__QList(d, value.cast(listType))
d.putBetterType(value.type)
def qdump__QTemporaryFile(d, value):
......@@ -2199,7 +2189,7 @@ def qdump__std__string(d, value):
sizePtr = data.cast(d.sizetType().pointer())
size = int(sizePtr[-3])
alloc = int(sizePtr[-2])
refcount = int(sizePtr[-1]) & 0xffffffff
refcount = int(sizePtr[-1])
check(refcount >= -1) # Can be -1 accoring to docs.
check(0 <= size and size <= alloc and alloc <= 100*1000*1000)
......
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