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