Commit d40ee224 authored by hjk's avatar hjk
Browse files

Debugger: Handle extraction of data from temporary SBValue



Change-Id: I5d79b59e971933fef8ef94c20333035188d33a57
Reviewed-by: default avatarhjk <hjk121@nokiamail.com>
parent e6e80866
......@@ -118,9 +118,6 @@ class Blob(object):
def extractFloat(self, offset = 0):
return struct.unpack_from("f", self.data, offset)[0]
def extractPointer(self, offset = 0):
return struct.unpack_from("P", self.data, offset)[0]
#
# Gnuplot based display for array-like structures.
#
......@@ -383,7 +380,7 @@ class DumperBase:
# - qptrdiff offset
size = self.extractInt(addr + 4)
alloc = self.extractInt(addr + 8) & 0x7ffffff
data = addr + self.dereference(addr + 8 + self.ptrSize())
data = addr + self.extractPointer(addr + 8 + self.ptrSize())
if self.ptrSize() == 4:
data = data & 0xffffffff
else:
......@@ -396,7 +393,7 @@ class DumperBase:
# - char *data;
alloc = self.extractInt(addr + 4)
size = self.extractInt(addr + 8)
data = self.dereference(addr + 8 + self.ptrSize())
data = self.extractPointer(addr + 8 + self.ptrSize())
return data, size, alloc
# addr is the begin of a QByteArrayData structure
......@@ -429,27 +426,27 @@ class DumperBase:
return self.hexencode(data)
def encodeByteArray(self, value):
return self.encodeByteArrayHelper(self.dereferenceValue(value))
return self.encodeByteArrayHelper(self.extractPointer(value))
def byteArrayData(self, value):
return self.byteArrayDataHelper(self.dereferenceValue(value))
return self.byteArrayDataHelper(self.extractPointer(value))
def putByteArrayValue(self, value):
return self.putValue(self.encodeByteArray(value), Hex2EncodedLatin1)
def putByteArrayValueByAddress(self, addr):
self.putValue(self.encodeByteArrayHelper(self.dereference(addr)),
self.putValue(self.encodeByteArrayHelper(self.extractPointer(addr)),
Hex2EncodedLatin1)
def putStringValueByAddress(self, addr):
self.putValue(self.encodeStringHelper(self.dereference(addr)),
self.putValue(self.encodeStringHelper(self.extractPointer(addr)),
Hex4EncodedLittleEndian)
def encodeString(self, value):
return self.encodeStringHelper(self.dereferenceValue(value))
return self.encodeStringHelper(self.extractPointer(value))
def stringData(self, value):
return self.byteArrayDataHelper(self.dereferenceValue(value))
return self.byteArrayDataHelper(self.extractPointer(value))
def extractTemplateArgument(self, typename, position):
level = 0
......@@ -859,7 +856,7 @@ class DumperBase:
intSize = self.intSize()
ptrSize = self.ptrSize()
# dd = value["d_ptr"]["d"] is just behind the vtable.
dd = self.dereference(self.addressOf(value) + ptrSize)
dd = self.extractPointer(value, offset=ptrSize)
if self.qtVersion() < 0x050000:
# Size of QObjectData: 5 pointer + 2 int
......@@ -915,8 +912,8 @@ class DumperBase:
def staticQObjectPropertyNames(self, metaobject):
properties = []
dd = metaobject["d"]
data = self.dereferenceValue(dd["data"])
sd = self.dereferenceValue(dd["stringdata"])
data = self.extractPointer(dd["data"])
sd = self.extractPointer(dd["stringdata"])
metaObjectVersion = self.extractInt(data)
propertyCount = self.extractInt(data + 24)
......@@ -1027,6 +1024,18 @@ class DumperBase:
base += 1
f.write("e\n")
def extractPointer(self, thing, offset = 0):
if isinstance(thing, int):
bytes = self.extractBlob(thing, self.ptrSize()).toBytes()
elif sys.version_info[0] == 2 and isinstance(thing, long):
bytes = self.extractBlob(thing, self.ptrSize()).toBytes()
elif isinstance(thing, Blob):
bytes = blob.toBytes()
else:
# Assume it's a (backend specific) Value.
bytes = self.toBlob(thing).toBytes()
code = "I" if self.ptrSize() == 4 else "Q"
return struct.unpack_from(code, bytes, offset)[0]
# Some "Enums"
......
......@@ -947,15 +947,6 @@ class Dumper(DumperBase):
mem.tobytes()
return mem
# FIXME: The commented out versions do not work with
# a Python 3 based GDB due to the bug addressed in
# https://sourceware.org/ml/gdb-patches/2013-09/msg00571.html
def dereference(self, addr):
#return long(gdb.Value(addr).cast(self.voidPtrType().pointer()).dereference())
ptrSize = self.ptrSize()
code = "I" if ptrSize == 4 else "Q"
return struct.unpack(code, self.readRawMemory(addr, ptrSize))[0]
def extractInt64(self, addr):
return struct.unpack("q", self.readRawMemory(addr, 8))[0]
......@@ -965,11 +956,6 @@ class Dumper(DumperBase):
def extractByte(self, addr):
return struct.unpack("b", self.readRawMemory(addr, 1))[0]
# Do not use value.address here as this might not have one,
# i.e. be the result of an inferior call
def dereferenceValue(self, value):
return toInteger(value.cast(self.voidPtrType()))
def extractStaticMetaObjectHelper(self, typeobj):
"""
Checks whether type has a Q_OBJECT macro.
......
......@@ -541,12 +541,6 @@ class Dumper(DumperBase):
def addressOf(self, value):
return int(value.GetLoadAddress())
def dereferenceValue(self, value):
return long(value.Cast(self.voidPtrType()))
def dereference(self, address):
return long(self.createValue(address, self.voidPtrType()))
def extractInt(self, address):
return int(self.createValue(address, self.intType()))
......
......@@ -230,7 +230,7 @@ def qdump__QTime(d, value):
def qdump__QTimeZone(d, value):
base = d.dereferenceValue(value)
base = d.extractPointer(value)
if base == 0:
d.putValue("(null)")
d.putNumChild(0)
......@@ -245,7 +245,7 @@ def qdump__QDateTime(d, value):
isValid = False
# This relies on the Qt4/Qt5 internal structure layout:
# {sharedref(4), ...
base = d.dereferenceValue(value)
base = d.extractPointer(value)
if qtVersion >= 0x050200:
dateBase = base + d.ptrSize() # Only QAtomicInt, but will be padded.
# qint64 m_msecs
......@@ -312,7 +312,7 @@ def qdump__QDateTime(d, value):
def qdump__QDir(d, value):
d.putNumChild(1)
privAddress = d.dereferenceValue(value)
privAddress = d.extractPointer(value)
bit32 = d.is32bit()
qt5 = d.qtVersion() >= 0x050000
......@@ -415,7 +415,7 @@ def qdump__QFile(d, value):
def qdump__QFileInfo(d, value):
privAddress = d.dereferenceValue(value)
privAddress = d.extractPointer(value)
#bit32 = d.is32bit()
#qt5 = d.qtVersion() >= 0x050000
#try:
......@@ -676,7 +676,7 @@ def qdump__QHostAddress(d, value):
# protocol (2*ptrSize + 20)
# bool isParsed (2*ptrSize + 24)
privAddress = d.dereferenceValue(value)
privAddress = d.extractPointer(value)
isQt5 = d.qtVersion() >= 0x050000
sizeofQString = d.ptrSize()
ipStringAddress = privAddress + (0 if isQt5 else 24)
......@@ -841,7 +841,7 @@ def qdump__QImage(d, value):
def qdump__QLinkedList(d, value):
dd = d.dereferenceValue(value)
dd = d.extractPointer(value)
ptrSize = d.ptrSize()
n = d.extractInt(dd + 4 + 2 * ptrSize);
ref = d.extractInt(dd + 2 * ptrSize);
......@@ -1058,7 +1058,7 @@ def qdump__QMetaObject(d, value):
with Children(d):
dd = value["d"]
d.putSubItem("d", dd)
data = d.dereferenceValue(dd["data"])
data = d.extractPointer(dd["data"])
propertyNames = d.staticQObjectPropertyNames(value)
propertyIndex = 0
......@@ -1069,7 +1069,7 @@ def qdump__QMetaObject(d, value):
#byteArrayDataType = d.lookupType(d.qtNamespace() + "QByteArrayData")
#byteArrayDataSize = byteArrayDataType.sizeof
#sd = d.dereferenceValue(dd["stringdata"])
#sd = d.extractPointer(dd["stringdata"])
#stringdata, size, alloc = d.byteArrayDataHelper(sd)
#propertyCount = d.extractInt(data + 24)
......@@ -1552,7 +1552,7 @@ def qdump__QRectF(d, value):
def qdump__QRegExp(d, value):
# value.priv.engineKey.pattern
privAddress = d.dereferenceValue(value)
privAddress = d.extractPointer(value)
engineKeyAddress = privAddress + d.ptrSize()
patternAddress = engineKeyAddress
d.putStringValueByAddress(patternAddress)
......@@ -1595,7 +1595,7 @@ def qdump__QRegion(d, value):
# QRect extents;
# QRect innerRect;
# int innerArea;
pp = d.dereferenceValue(p)
pp = d.extractPointer(p)
n = d.extractInt(pp)
d.putItemCount(n)
d.putNumChild(n)
......@@ -1792,7 +1792,7 @@ def qdump__QTextCodec(d, value):
def qdump__QTextCursor(d, value):
privAddress = d.dereferenceValue(value)
privAddress = d.extractPointer(value)
if privAddress == 0:
d.putValue("(invalid)")
d.putNumChild(0)
......@@ -1822,7 +1822,7 @@ def qdump__QTextDocument(d, value):
def qdump__QUrl(d, value):
if d.qtVersion() < 0x050000:
privAddress = d.dereferenceValue(value)
privAddress = d.extractPointer(value)
if not privAddress:
# d == 0 if QUrl was constructed with default constructor
d.putValue("<invalid>")
......@@ -1854,7 +1854,7 @@ def qdump__QUrl(d, value):
# - QString path;
# - QString query;
# - QString fragment;
privAddress = d.dereferenceValue(value)
privAddress = d.extractPointer(value)
if not privAddress:
# d == 0 if QUrl was constructed with default constructor
d.putValue("<invalid>")
......@@ -1867,7 +1867,7 @@ def qdump__QUrl(d, value):
path = d.encodeStringHelper(d.dereference(schemeAddr + 4 * d.ptrSize()))
query = d.encodeStringHelper(d.dereference(schemeAddr + 5 * d.ptrSize()))
fragment = d.encodeStringHelper(d.dereference(schemeAddr + 6 * d.ptrSize()))
port = d.extractInt(d.dereferenceValue(value) + d.intSize())
port = d.extractInt(d.extractPointer(value) + d.intSize())
url = scheme
url += "3a002f002f00"
......@@ -1967,7 +1967,7 @@ qdumpHelper_QVariants_B = [
def qdumpHelper_QVariant_31(d, blob):
# QVariant::VoidStar
d.putBetterType("%sQVariant (void *)" % d.qtNamespace())
d.putValue("0x%x" % blob.extractPointer())
d.putValue("0x%x" % d.extractPointer(blob))
def qdumpHelper_QVariant_32(d, blob):
# QVariant::Long
......
......@@ -764,7 +764,7 @@ def qdump__std____1__vector(d, value):
innerType = d.templateArgument(value.type, 0)
if d.isLldb and d.childAt(value, 0).type == innerType:
# That's old lldb automatically formatting
begin = d.dereferenceValue(value)
begin = d.extractPointer(value)
size = value.GetNumChildren()
else:
# Normal case
......
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