forked from qt-creator/qt-creator
Debugger: Paddle back on the (non-)auto detection of Qt versions
It looks like there are Qt-using scenarios without easy way to have the right Qt version in the kit, Among the frequent cases where we need to distinguish Qt versions in the dumpers are the Qt5/6 container layout differences which can in some cases be detected from the currently dumped value. Use that now as the primary distinction and fall back to the previous expensive peeking only if that is needed. This also postpones any Qt version related activity until a real Qt type is encountered, i.e. does not impact non-Qt scenarios. Task-number: QTCREATORBUG-31033 Change-Id: I67b6e34c42994ad9f6e8ec8698b430b55327cf0c Reviewed-by: hjk <hjk@qt.io> Reviewed-by: David Schulz <david.schulz@qt.io> Reviewed-by: Christian Stenger <christian.stenger@qt.io>
This commit is contained in:
@@ -76,7 +76,9 @@ class Dumper(DumperBase):
|
|||||||
self.outputLock = threading.Lock()
|
self.outputLock = threading.Lock()
|
||||||
self.isCdb = True
|
self.isCdb = True
|
||||||
|
|
||||||
#FIXME
|
#FIXME
|
||||||
|
def register_known_qt_types(self):
|
||||||
|
DumperBase.register_known_qt_types(self)
|
||||||
typeid = self.typeid_for_string('@QVariantMap')
|
typeid = self.typeid_for_string('@QVariantMap')
|
||||||
del self.type_code_cache[typeid]
|
del self.type_code_cache[typeid]
|
||||||
del self.type_target_cache[typeid]
|
del self.type_target_cache[typeid]
|
||||||
|
@@ -172,8 +172,6 @@ class DumperBase():
|
|||||||
self.qtCustomEventFunc = 0
|
self.qtCustomEventFunc = 0
|
||||||
self.qtCustomEventPltFunc = 0
|
self.qtCustomEventPltFunc = 0
|
||||||
self.qtPropertyFunc = 0
|
self.qtPropertyFunc = 0
|
||||||
self.qtversion = None
|
|
||||||
self.qtns = None
|
|
||||||
self.passExceptions = False
|
self.passExceptions = False
|
||||||
self.isTesting = False
|
self.isTesting = False
|
||||||
self.qtLoaded = False
|
self.qtLoaded = False
|
||||||
@@ -189,6 +187,11 @@ class DumperBase():
|
|||||||
|
|
||||||
self.dumpermodules = []
|
self.dumpermodules = []
|
||||||
|
|
||||||
|
# These are sticky for the session
|
||||||
|
self.qtversion = None
|
||||||
|
self.qtversionAtLeast6 = None
|
||||||
|
self.qtnamespace = None
|
||||||
|
|
||||||
self.init_type_cache()
|
self.init_type_cache()
|
||||||
|
|
||||||
try:
|
try:
|
||||||
@@ -211,7 +214,7 @@ class DumperBase():
|
|||||||
self.currentPrintsAddress = True
|
self.currentPrintsAddress = True
|
||||||
self.currentChildType = None
|
self.currentChildType = None
|
||||||
self.currentChildNumChild = None
|
self.currentChildNumChild = None
|
||||||
self.register_known_types()
|
self.register_known_simple_types()
|
||||||
|
|
||||||
def setVariableFetchingOptions(self, args):
|
def setVariableFetchingOptions(self, args):
|
||||||
self.last_args = args
|
self.last_args = args
|
||||||
@@ -233,9 +236,16 @@ class DumperBase():
|
|||||||
self.useTimeStamps = int(args.get('timestamps', '0'))
|
self.useTimeStamps = int(args.get('timestamps', '0'))
|
||||||
self.partialVariable = args.get('partialvar', '')
|
self.partialVariable = args.get('partialvar', '')
|
||||||
self.uninitialized = args.get('uninitialized', [])
|
self.uninitialized = args.get('uninitialized', [])
|
||||||
self.qtversion = args.get('qtversion', 0x060602)
|
|
||||||
self.qtnamespace = args.get('qtnamespace', '')
|
|
||||||
self.uninitialized = list(map(lambda x: self.hexdecode(x), self.uninitialized))
|
self.uninitialized = list(map(lambda x: self.hexdecode(x), self.uninitialized))
|
||||||
|
|
||||||
|
if self.qtversion is None:
|
||||||
|
self.qtversion = args.get('qtversion', None)
|
||||||
|
if self.qtversion == 0:
|
||||||
|
self.qtversion = None
|
||||||
|
if self.qtnamespace is None:
|
||||||
|
self.qtnamespace = args.get('qtnamespace', None)
|
||||||
|
|
||||||
#self.warn('NAMESPACE: "%s"' % self.qtNamespace())
|
#self.warn('NAMESPACE: "%s"' % self.qtNamespace())
|
||||||
#self.warn('EXPANDED INAMES: %s' % self.expandedINames)
|
#self.warn('EXPANDED INAMES: %s' % self.expandedINames)
|
||||||
#self.warn('WATCHERS: %s' % self.watchers)
|
#self.warn('WATCHERS: %s' % self.watchers)
|
||||||
@@ -256,11 +266,50 @@ class DumperBase():
|
|||||||
args['partialvar'] = ''
|
args['partialvar'] = ''
|
||||||
self.fetchVariables(args)
|
self.fetchVariables(args)
|
||||||
|
|
||||||
|
def extractQtVersion(self):
|
||||||
|
# can be overridden in bridges
|
||||||
|
pass
|
||||||
|
|
||||||
def qtVersion(self):
|
def qtVersion(self):
|
||||||
return self.qtversion
|
if self.qtversion:
|
||||||
|
return self.qtversion
|
||||||
|
|
||||||
|
#self.warn("ACCESSING UNKNOWN QT VERSION")
|
||||||
|
self.qtversion = self.extractQtVersion()
|
||||||
|
if self.qtversion:
|
||||||
|
return self.qtversion
|
||||||
|
|
||||||
|
#self.warn("EXTRACTING QT VERSION FAILED. GUESSING NOW.")
|
||||||
|
if self.qtversionAtLeast6 is None or self.qtversionAtLeast6 is True:
|
||||||
|
return 0x060602
|
||||||
|
return 0x050f00
|
||||||
|
|
||||||
|
def qtVersionAtLeast(self, version):
|
||||||
|
# A hack to cover most of the changes from Qt 5 to 6
|
||||||
|
if version == 0x60000 and self.qtversionAtLeast6 is not None:
|
||||||
|
return self.qtversionAtLeast6
|
||||||
|
if version == 0x50000: # FIXME: This drops unknown 4.x for now
|
||||||
|
return True
|
||||||
|
return self.qtVersion() >= version
|
||||||
|
|
||||||
|
def qtVersionPing(self, typeid, size_for_qt5=-1):
|
||||||
|
# To be called from places where the type size is sufficient
|
||||||
|
# to distinguish Qt 5.x and 6.x
|
||||||
|
if size_for_qt5 == -1:
|
||||||
|
size_for_qt5 = self.ptrSize()
|
||||||
|
test_size = self.type_size(typeid)
|
||||||
|
self.setQtVersionAtLeast6(test_size > size_for_qt5)
|
||||||
|
|
||||||
|
def setQtVersionAtLeast6(self, is6):
|
||||||
|
if self.qtversionAtLeast6 is None:
|
||||||
|
#self.warn("SETTING Qt VERSION AT LEAST 6 TO %s" % is6)
|
||||||
|
self.qtversionAtLeast6 = is6
|
||||||
|
self.register_known_qt_types()
|
||||||
|
#else:
|
||||||
|
# self.warn("QT VERSION ALREADY KNOWN")
|
||||||
|
|
||||||
def qtNamespace(self):
|
def qtNamespace(self):
|
||||||
return self.qtnamespace
|
return '' if self.qtnamespace is None else self.qtnamespace
|
||||||
|
|
||||||
def resetPerStepCaches(self):
|
def resetPerStepCaches(self):
|
||||||
self.perStepCache = {}
|
self.perStepCache = {}
|
||||||
@@ -494,8 +543,13 @@ class DumperBase():
|
|||||||
def register_struct(self, name, p5=0, p6=0, s=0, qobject_based=False):
|
def register_struct(self, name, p5=0, p6=0, s=0, qobject_based=False):
|
||||||
# p5 = n -> n * ptrsize for Qt 5
|
# p5 = n -> n * ptrsize for Qt 5
|
||||||
# p6 = n -> n * ptrsize for Qt 6
|
# p6 = n -> n * ptrsize for Qt 6
|
||||||
#if self.qtVersion() >= 0x060000: # FIXME: Qt 5, ptrSize()
|
if self.qtversionAtLeast6 is None:
|
||||||
size = 8 * p6 + s
|
self.warn("TOO EARLY TO GUESS QT VERSION")
|
||||||
|
size = 8 * p6 + s
|
||||||
|
elif self.qtversionAtLeast6 is True:
|
||||||
|
size = 8 * p6 + s
|
||||||
|
else:
|
||||||
|
size = 8 * p5 + s
|
||||||
typeid = self.typeid_for_string(name)
|
typeid = self.typeid_for_string(name)
|
||||||
self.type_code_cache[typeid] = TypeCode.Struct
|
self.type_code_cache[typeid] = TypeCode.Struct
|
||||||
self.type_size_cache[typeid] = size
|
self.type_size_cache[typeid] = size
|
||||||
@@ -503,7 +557,7 @@ class DumperBase():
|
|||||||
self.type_alignment_cache[typeid] = 8
|
self.type_alignment_cache[typeid] = 8
|
||||||
return typeid
|
return typeid
|
||||||
|
|
||||||
def register_known_types(self):
|
def register_known_simple_types(self):
|
||||||
typeid = 0
|
typeid = 0
|
||||||
self.typeid_cache[''] = typeid
|
self.typeid_cache[''] = typeid
|
||||||
self.type_code_cache[typeid] = TypeCode.Void
|
self.type_code_cache[typeid] = TypeCode.Void
|
||||||
@@ -563,6 +617,8 @@ class DumperBase():
|
|||||||
|
|
||||||
self.register_enum('@Qt::ItemDataRole', 4)
|
self.register_enum('@Qt::ItemDataRole', 4)
|
||||||
|
|
||||||
|
def register_known_qt_types(self):
|
||||||
|
#self.warn("REGISTERING KNOWN QT TYPES NOW")
|
||||||
self.register_struct('@QObject', p5=2, p6=2, qobject_based=True)
|
self.register_struct('@QObject', p5=2, p6=2, qobject_based=True)
|
||||||
self.register_struct('@QObjectPrivate', p5=10, p6=10) # FIXME: Not exact
|
self.register_struct('@QObjectPrivate', p5=10, p6=10) # FIXME: Not exact
|
||||||
|
|
||||||
@@ -711,9 +767,9 @@ class DumperBase():
|
|||||||
return limit
|
return limit
|
||||||
|
|
||||||
def vectorData(self, value):
|
def vectorData(self, value):
|
||||||
if self.qtVersion() >= 0x060000:
|
if self.qtVersionAtLeast(0x060000):
|
||||||
data, length, alloc = self.qArrayData(value)
|
data, length, alloc = self.qArrayData(value)
|
||||||
elif self.qtVersion() >= 0x050000:
|
elif self.qtVersionAtLeast(0x050000):
|
||||||
vector_data_ptr = self.extractPointer(value)
|
vector_data_ptr = self.extractPointer(value)
|
||||||
if self.ptrSize() == 4:
|
if self.ptrSize() == 4:
|
||||||
(ref, length, alloc, offset) = self.split('IIIp', vector_data_ptr)
|
(ref, length, alloc, offset) = self.split('IIIp', vector_data_ptr)
|
||||||
@@ -729,7 +785,7 @@ class DumperBase():
|
|||||||
return data, length
|
return data, length
|
||||||
|
|
||||||
def qArrayData(self, value):
|
def qArrayData(self, value):
|
||||||
if self.qtVersion() >= 0x60000:
|
if self.qtVersionAtLeast(0x60000):
|
||||||
dd, data, length = self.split('ppp', value)
|
dd, data, length = self.split('ppp', value)
|
||||||
if dd:
|
if dd:
|
||||||
_, _, alloc = self.split('iip', dd)
|
_, _, alloc = self.split('iip', dd)
|
||||||
@@ -740,7 +796,7 @@ class DumperBase():
|
|||||||
|
|
||||||
def qArrayDataHelper(self, array_data_ptr):
|
def qArrayDataHelper(self, array_data_ptr):
|
||||||
# array_data_ptr is what is e.g. stored in a QByteArray's d_ptr.
|
# array_data_ptr is what is e.g. stored in a QByteArray's d_ptr.
|
||||||
if self.qtVersion() >= 0x050000:
|
if self.qtVersionAtLeast(0x050000):
|
||||||
# QTypedArray:
|
# QTypedArray:
|
||||||
# - QtPrivate::RefCount ref
|
# - QtPrivate::RefCount ref
|
||||||
# - int length
|
# - int length
|
||||||
@@ -753,7 +809,7 @@ class DumperBase():
|
|||||||
data = data & 0xffffffff
|
data = data & 0xffffffff
|
||||||
else:
|
else:
|
||||||
data = data & 0xffffffffffffffff
|
data = data & 0xffffffffffffffff
|
||||||
elif self.qtVersion() >= 0x040000:
|
elif self.qtVersionAtLeast(0x040000):
|
||||||
# Data:
|
# Data:
|
||||||
# - QBasicAtomicInt ref;
|
# - QBasicAtomicInt ref;
|
||||||
# - int alloc, length;
|
# - int alloc, length;
|
||||||
@@ -1597,7 +1653,7 @@ class DumperBase():
|
|||||||
|
|
||||||
intSize = 4
|
intSize = 4
|
||||||
ptrSize = self.ptrSize()
|
ptrSize = self.ptrSize()
|
||||||
if self.qtVersion() >= 0x060000:
|
if self.qtVersionAtLeast(0x060000):
|
||||||
# Size of QObjectData: 9 pointer + 2 int
|
# Size of QObjectData: 9 pointer + 2 int
|
||||||
# - vtable
|
# - vtable
|
||||||
# - QObject *q_ptr;
|
# - QObject *q_ptr;
|
||||||
@@ -1618,7 +1674,7 @@ class DumperBase():
|
|||||||
# - QList<QPointer<QObject> > eventFilters;
|
# - QList<QPointer<QObject> > eventFilters;
|
||||||
# - QString objectName
|
# - QString objectName
|
||||||
objectNameAddress = extra + 12 * ptrSize
|
objectNameAddress = extra + 12 * ptrSize
|
||||||
elif self.qtVersion() >= 0x050000:
|
elif self.qtVersionAtLeast(0x050000):
|
||||||
# Size of QObjectData: 5 pointer + 2 int
|
# Size of QObjectData: 5 pointer + 2 int
|
||||||
# - vtable
|
# - vtable
|
||||||
# - QObject *q_ptr;
|
# - QObject *q_ptr;
|
||||||
@@ -1811,7 +1867,7 @@ class DumperBase():
|
|||||||
# a Q_OBJECT SMO has a non-null superdata (unless it's QObject itself),
|
# a Q_OBJECT SMO has a non-null superdata (unless it's QObject itself),
|
||||||
# a Q_GADGET SMO has a null superdata (hopefully)
|
# a Q_GADGET SMO has a null superdata (hopefully)
|
||||||
if result and not isQObjectProper:
|
if result and not isQObjectProper:
|
||||||
if self.qtVersion() >= 0x60000 and self.isWindowsTarget():
|
if self.qtVersionAtLeast(0x60000) and self.isWindowsTarget():
|
||||||
(direct, indirect) = self.split('pp', result)
|
(direct, indirect) = self.split('pp', result)
|
||||||
# since Qt 6 there is an additional indirect super data getter on windows
|
# since Qt 6 there is an additional indirect super data getter on windows
|
||||||
if direct == 0 and indirect == 0:
|
if direct == 0 and indirect == 0:
|
||||||
@@ -1895,14 +1951,14 @@ class DumperBase():
|
|||||||
return result
|
return result
|
||||||
|
|
||||||
def listData(self, value, check=True):
|
def listData(self, value, check=True):
|
||||||
if self.qtVersion() >= 0x60000:
|
if self.qtVersionAtLeast(0x60000):
|
||||||
dd, data, size = self.split('ppi', value)
|
dd, data, size = self.split('ppi', value)
|
||||||
return data, size
|
return data, size
|
||||||
|
|
||||||
base = self.extractPointer(value)
|
base = self.extractPointer(value)
|
||||||
(ref, alloc, begin, end) = self.split('IIII', base)
|
(ref, alloc, begin, end) = self.split('IIII', base)
|
||||||
array = base + 16
|
array = base + 16
|
||||||
if self.qtVersion() < 0x50000:
|
if not self.qtVersionAtLeast(0x50000):
|
||||||
array += self.ptrSize()
|
array += self.ptrSize()
|
||||||
size = end - begin
|
size = end - begin
|
||||||
|
|
||||||
@@ -1941,7 +1997,7 @@ class DumperBase():
|
|||||||
def metaString(self, metaObjectPtr, index, revision):
|
def metaString(self, metaObjectPtr, index, revision):
|
||||||
ptrSize = self.ptrSize()
|
ptrSize = self.ptrSize()
|
||||||
stringdataOffset = ptrSize
|
stringdataOffset = ptrSize
|
||||||
if self.isWindowsTarget() and self.qtVersion() >= 0x060000:
|
if self.isWindowsTarget() and self.qtVersionAtLeast(0x060000):
|
||||||
stringdataOffset += ptrSize # indirect super data member
|
stringdataOffset += ptrSize # indirect super data member
|
||||||
stringdata = self.extract_pointer_at_address(int(metaObjectPtr) + stringdataOffset)
|
stringdata = self.extract_pointer_at_address(int(metaObjectPtr) + stringdataOffset)
|
||||||
|
|
||||||
@@ -1970,19 +2026,19 @@ class DumperBase():
|
|||||||
self.putField('sortgroup', sortorder)
|
self.putField('sortgroup', sortorder)
|
||||||
|
|
||||||
def putQMetaStuff(self, value, origType):
|
def putQMetaStuff(self, value, origType):
|
||||||
if self.qtVersion() >= 0x060000:
|
if self.qtVersionAtLeast(0x060000):
|
||||||
metaObjectPtr, handle = value.split('pp')
|
metaObjectPtr, handle = value.split('pp')
|
||||||
else:
|
else:
|
||||||
metaObjectPtr, handle = value.split('pI')
|
metaObjectPtr, handle = value.split('pI')
|
||||||
if metaObjectPtr != 0:
|
if metaObjectPtr != 0:
|
||||||
if self.qtVersion() >= 0x060000:
|
if self.qtVersionAtLeast(0x060000):
|
||||||
if handle == 0:
|
if handle == 0:
|
||||||
self.putEmptyValue()
|
self.putEmptyValue()
|
||||||
return
|
return
|
||||||
revision = 9
|
revision = 9
|
||||||
name, alias, flags, keyCount, data = self.split('IIIII', handle)
|
name, alias, flags, keyCount, data = self.split('IIIII', handle)
|
||||||
index = name
|
index = name
|
||||||
elif self.qtVersion() >= 0x050000:
|
elif self.qtVersionAtLeast(0x050000):
|
||||||
revision = 7
|
revision = 7
|
||||||
dataPtr = self.extract_pointer_at_address(metaObjectPtr + 2 * self.ptrSize())
|
dataPtr = self.extract_pointer_at_address(metaObjectPtr + 2 * self.ptrSize())
|
||||||
index = self.extractInt(dataPtr + 4 * handle)
|
index = self.extractInt(dataPtr + 4 * handle)
|
||||||
@@ -2024,7 +2080,7 @@ class DumperBase():
|
|||||||
|
|
||||||
def extractDataPtr(someMetaObjectPtr):
|
def extractDataPtr(someMetaObjectPtr):
|
||||||
# dataPtr = metaObjectPtr['d']['data']
|
# dataPtr = metaObjectPtr['d']['data']
|
||||||
if self.qtVersion() >= 0x60000 and self.isWindowsTarget():
|
if self.qtVersionAtLeast(0x60000) and self.isWindowsTarget():
|
||||||
offset = 3
|
offset = 3
|
||||||
else:
|
else:
|
||||||
offset = 2
|
offset = 2
|
||||||
@@ -2054,13 +2110,13 @@ class DumperBase():
|
|||||||
extraData = 0
|
extraData = 0
|
||||||
if qobjectPtr:
|
if qobjectPtr:
|
||||||
dd = self.extract_pointer_at_address(qobjectPtr + ptrSize)
|
dd = self.extract_pointer_at_address(qobjectPtr + ptrSize)
|
||||||
if self.qtVersion() >= 0x60000:
|
if self.qtVersionAtLeast(0x60000):
|
||||||
(dvtablePtr, qptr, parent, children, bindingStorageData, bindingStatus,
|
(dvtablePtr, qptr, parent, children, bindingStorageData, bindingStatus,
|
||||||
flags, postedEvents, dynMetaObjectPtr, # Up to here QObjectData.
|
flags, postedEvents, dynMetaObjectPtr, # Up to here QObjectData.
|
||||||
extraData, threadDataPtr, connectionListsPtr,
|
extraData, threadDataPtr, connectionListsPtr,
|
||||||
sendersPtr, currentSenderPtr) \
|
sendersPtr, currentSenderPtr) \
|
||||||
= self.split('pp{@QObject*}{@QList<@QObject *>}ppIIp' + 'ppppp', dd)
|
= self.split('pp{@QObject*}{@QList<@QObject *>}ppIIp' + 'ppppp', dd)
|
||||||
elif self.qtVersion() >= 0x50000:
|
elif self.qtVersionAtLeast(0x50000):
|
||||||
(dvtablePtr, qptr, parent, children, flags, postedEvents,
|
(dvtablePtr, qptr, parent, children, flags, postedEvents,
|
||||||
dynMetaObjectPtr, # Up to here QObjectData.
|
dynMetaObjectPtr, # Up to here QObjectData.
|
||||||
extraData, threadDataPtr, connectionListsPtr,
|
extraData, threadDataPtr, connectionListsPtr,
|
||||||
@@ -2186,7 +2242,7 @@ typename))
|
|||||||
with Children(self):
|
with Children(self):
|
||||||
# Static properties.
|
# Static properties.
|
||||||
for i in range(propertyCount):
|
for i in range(propertyCount):
|
||||||
if self.qtVersion() >= 0x60000:
|
if self.qtVersionAtLeast(0x60000):
|
||||||
t = self.split('IIIII', dataPtr + properties * 4 + 20 * i)
|
t = self.split('IIIII', dataPtr + properties * 4 + 20 * i)
|
||||||
else:
|
else:
|
||||||
t = self.split('III', dataPtr + properties * 4 + 12 * i)
|
t = self.split('III', dataPtr + properties * 4 + 12 * i)
|
||||||
@@ -2239,18 +2295,18 @@ typename))
|
|||||||
data += inner_size
|
data += inner_size
|
||||||
|
|
||||||
variant_typeid = self.cheap_typeid_from_name('@QVariant')
|
variant_typeid = self.cheap_typeid_from_name('@QVariant')
|
||||||
if self.qtVersion() >= 0x60000:
|
if self.qtVersionAtLeast(0x60000):
|
||||||
values = vectorGenerator(extraData + 3 * ptrSize, variant_typeid)
|
values = vectorGenerator(extraData + 3 * ptrSize, variant_typeid)
|
||||||
elif self.qtVersion() >= 0x50600:
|
elif self.qtVersionAtLeast(0x50600):
|
||||||
values = vectorGenerator(extraData + 2 * ptrSize, variant_typeid)
|
values = vectorGenerator(extraData + 2 * ptrSize, variant_typeid)
|
||||||
elif self.qtVersion() >= 0x50000:
|
elif self.qtVersionAtLeast(0x50000):
|
||||||
values = list5Generator(extraData + 2 * ptrSize, variant_typeid)
|
values = list5Generator(extraData + 2 * ptrSize, variant_typeid)
|
||||||
else:
|
else:
|
||||||
variantptr_typeid = self.cheap_typeid_from_name('@QVariant')
|
variantptr_typeid = self.cheap_typeid_from_name('@QVariant')
|
||||||
values = list5Generator(extraData + 2 * ptrSize, variantptr_typeid)
|
values = list5Generator(extraData + 2 * ptrSize, variantptr_typeid)
|
||||||
|
|
||||||
bytearray_typeid = self.cheap_typeid_from_name('@QByteArray')
|
bytearray_typeid = self.cheap_typeid_from_name('@QByteArray')
|
||||||
if self.qtVersion() >= 0x60000:
|
if self.qtVersionAtLeast(0x60000):
|
||||||
names = list6Generator(extraData, bytearray_typeid)
|
names = list6Generator(extraData, bytearray_typeid)
|
||||||
else:
|
else:
|
||||||
names = list5Generator(extraData + ptrSize, bytearray_typeid)
|
names = list5Generator(extraData + ptrSize, bytearray_typeid)
|
||||||
@@ -3427,9 +3483,9 @@ typename))
|
|||||||
):
|
):
|
||||||
return True
|
return True
|
||||||
if strippedName == 'QStringList':
|
if strippedName == 'QStringList':
|
||||||
return self.dumper.qtVersion() >= 0x050000
|
return self.dumper.qtVersionAtLeast(0x050000)
|
||||||
if strippedName == 'QList':
|
if strippedName == 'QList':
|
||||||
return self.dumper.qtVersion() >= 0x050600
|
return self.dumper.qtVersionAtLeast(0x050600)
|
||||||
return False
|
return False
|
||||||
|
|
||||||
class Field:
|
class Field:
|
||||||
@@ -3550,7 +3606,7 @@ typename))
|
|||||||
if typename.startswith('QList<') or typename.startswith('QVector<'):
|
if typename.startswith('QList<') or typename.startswith('QVector<'):
|
||||||
typeid = self.typeid_for_string(typename)
|
typeid = self.typeid_for_string(typename)
|
||||||
if typeid:
|
if typeid:
|
||||||
size = 3 * self.ptrSize() if self.qtVersion() >= 0x060000 else self.ptrSize()
|
size = 3 * self.ptrSize() if self.qtVersionAtLeast(0x060000) else self.ptrSize()
|
||||||
self.type_code_cache[typeid] = TypeCode.Struct
|
self.type_code_cache[typeid] = TypeCode.Struct
|
||||||
self.type_size_cache[typeid] = size
|
self.type_size_cache[typeid] = size
|
||||||
return typeid
|
return typeid
|
||||||
|
@@ -874,6 +874,36 @@ class Dumper(DumperBase):
|
|||||||
except:
|
except:
|
||||||
return '0x%x' % address
|
return '0x%x' % address
|
||||||
|
|
||||||
|
def qtVersionString(self):
|
||||||
|
try:
|
||||||
|
return str(gdb.lookup_symbol('qVersion')[0].value()())
|
||||||
|
except:
|
||||||
|
pass
|
||||||
|
try:
|
||||||
|
ns = self.qtNamespace()
|
||||||
|
return str(gdb.parse_and_eval("((const char*(*)())'%sqVersion')()" % ns))
|
||||||
|
except:
|
||||||
|
pass
|
||||||
|
return None
|
||||||
|
|
||||||
|
def extractQtVersion(self):
|
||||||
|
try:
|
||||||
|
# Only available with Qt 5.3+
|
||||||
|
return int(str(gdb.parse_and_eval('((void**)&qtHookData)[2]')), 16)
|
||||||
|
except:
|
||||||
|
pass
|
||||||
|
|
||||||
|
try:
|
||||||
|
version = self.qtVersionString()
|
||||||
|
(major, minor, patch) = version[version.find('"') + 1:version.rfind('"')].split('.')
|
||||||
|
qtversion = 0x10000 * int(major) + 0x100 * int(minor) + int(patch)
|
||||||
|
self.qtVersion = lambda: qtversion
|
||||||
|
return qtversion
|
||||||
|
except:
|
||||||
|
# Use fallback until we have a better answer.
|
||||||
|
return None
|
||||||
|
|
||||||
|
|
||||||
def createSpecialBreakpoints(self, args):
|
def createSpecialBreakpoints(self, args):
|
||||||
self.specialBreakpoints = []
|
self.specialBreakpoints = []
|
||||||
|
|
||||||
|
@@ -783,6 +783,54 @@ class Dumper(DumperBase):
|
|||||||
|
|
||||||
self.fetchInternalFunctions = lambda: None
|
self.fetchInternalFunctions = lambda: None
|
||||||
|
|
||||||
|
def extractQtVersion(self):
|
||||||
|
for func in self.target.FindFunctions('qVersion'):
|
||||||
|
name = func.GetSymbol().GetName()
|
||||||
|
if name == None:
|
||||||
|
continue
|
||||||
|
if name.endswith('()'):
|
||||||
|
name = name[:-2]
|
||||||
|
if name.count(':') > 2:
|
||||||
|
continue
|
||||||
|
|
||||||
|
#qtNamespace = name[:name.find('qVersion')]
|
||||||
|
#self.qtNamespace = lambda: qtNamespace
|
||||||
|
|
||||||
|
options = lldb.SBExpressionOptions()
|
||||||
|
res = self.target.EvaluateExpression(name + '()', options)
|
||||||
|
|
||||||
|
if not res.IsValid() or not res.GetType().IsPointerType():
|
||||||
|
exp = '((const char*())%s)()' % name
|
||||||
|
res = self.target.EvaluateExpression(exp, options)
|
||||||
|
|
||||||
|
if not res.IsValid() or not res.GetType().IsPointerType():
|
||||||
|
exp = '((const char*())_Z8qVersionv)()'
|
||||||
|
res = self.target.EvaluateExpression(exp, options)
|
||||||
|
|
||||||
|
if not res.IsValid() or not res.GetType().IsPointerType():
|
||||||
|
continue
|
||||||
|
|
||||||
|
version = str(res)
|
||||||
|
if version.count('.') != 2:
|
||||||
|
continue
|
||||||
|
|
||||||
|
version.replace("'", '"') # Both seem possible
|
||||||
|
version = version[version.find('"') + 1:version.rfind('"')]
|
||||||
|
|
||||||
|
(major, minor, patch) = version.split('.')
|
||||||
|
qtVersion = 0x10000 * int(major) + 0x100 * int(minor) + int(patch)
|
||||||
|
return qtVersion
|
||||||
|
|
||||||
|
try:
|
||||||
|
versionValue = self.target.EvaluateExpression('qtHookData[2]').GetNonSyntheticValue()
|
||||||
|
if versionValue.IsValid():
|
||||||
|
return versionValue.unsigned
|
||||||
|
except:
|
||||||
|
pass
|
||||||
|
|
||||||
|
return None
|
||||||
|
|
||||||
|
|
||||||
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)
|
||||||
|
@@ -33,7 +33,8 @@ def qedit__QByteArray(d, value, data):
|
|||||||
|
|
||||||
|
|
||||||
def qdump__QByteArray(d, value):
|
def qdump__QByteArray(d, value):
|
||||||
if d.qtVersion() >= 0x60000:
|
d.qtVersionPing(value.typeid)
|
||||||
|
if d.qtVersionAtLeast(0x060000):
|
||||||
dd, data, length = value.split('ppi')
|
dd, data, length = value.split('ppi')
|
||||||
if dd:
|
if dd:
|
||||||
_, _, alloc = d.split('iii', dd)
|
_, _, alloc = d.split('iii', dd)
|
||||||
@@ -76,7 +77,8 @@ def qdump__QByteArray(d, value):
|
|||||||
|
|
||||||
|
|
||||||
def qdump__QBitArray(d, value):
|
def qdump__QBitArray(d, value):
|
||||||
if d.qtVersion() >= 0x60000:
|
d.qtVersionPing(value.typeid)
|
||||||
|
if d.qtVersionAtLeast(0x060000):
|
||||||
_, data, basize = value.split('ppi')
|
_, data, basize = value.split('ppi')
|
||||||
else:
|
else:
|
||||||
data, basize, _ = d.qArrayData(value['d'])
|
data, basize, _ = d.qArrayData(value['d'])
|
||||||
@@ -232,13 +234,13 @@ def qdump__QStandardItem(d, value):
|
|||||||
#d.createType('@QStandardItem*')
|
#d.createType('@QStandardItem*')
|
||||||
|
|
||||||
vtable, dptr = value.split('pp')
|
vtable, dptr = value.split('pp')
|
||||||
if d.qtVersion() >= 0x060000:
|
if d.qtVersionAtLeast(0x060000):
|
||||||
model, parent, values, children, rows, cols, item = \
|
model, parent, values, children, rows, cols, item = \
|
||||||
d.split('pp{@QList<@QStandardItemData>}{@QList<@QStandardItem *>}IIp', dptr)
|
d.split('pp{@QList<@QStandardItemData>}{@QList<@QStandardItem *>}IIp', dptr)
|
||||||
else:
|
else:
|
||||||
# There used to be a virtual destructor that got removed in
|
# There used to be a virtual destructor that got removed in
|
||||||
# 88b6abcebf29b455438 on Apr 18 17:01:22 2017
|
# 88b6abcebf29b455438 on Apr 18 17:01:22 2017
|
||||||
if d.qtVersion() < 0x050900 and not d.isMsvcTarget():
|
if not d.qtVersionAtLeast(0x050900) and not d.isMsvcTarget():
|
||||||
dptr += d.ptrSize();
|
dptr += d.ptrSize();
|
||||||
model, parent, values, children, rows, cols, item = \
|
model, parent, values, children, rows, cols, item = \
|
||||||
d.split('pp{@QVector<@QStandardItemData>}{@QVector<@QStandardItem *>}IIp', dptr)
|
d.split('pp{@QVector<@QStandardItemData>}{@QVector<@QStandardItem *>}IIp', dptr)
|
||||||
@@ -266,7 +268,7 @@ def qdump__QDate(d, value):
|
|||||||
d.enumExpression('DateFormat', 'TextDate'))
|
d.enumExpression('DateFormat', 'TextDate'))
|
||||||
d.putCallItem('(ISO)', '@QString', value, 'toString',
|
d.putCallItem('(ISO)', '@QString', value, 'toString',
|
||||||
d.enumExpression('DateFormat', 'ISODate'))
|
d.enumExpression('DateFormat', 'ISODate'))
|
||||||
if d.qtVersion() < 0x060000:
|
if not d.qtVersionAtLeast(0x060000):
|
||||||
d.putCallItem('(SystemLocale)', '@QString', value, 'toString',
|
d.putCallItem('(SystemLocale)', '@QString', value, 'toString',
|
||||||
d.enumExpression('DateFormat', 'SystemLocaleDate'))
|
d.enumExpression('DateFormat', 'SystemLocaleDate'))
|
||||||
d.putCallItem('(Locale)', '@QString', value, 'toString',
|
d.putCallItem('(Locale)', '@QString', value, 'toString',
|
||||||
@@ -286,7 +288,7 @@ def qdump__QTime(d, value):
|
|||||||
d.enumExpression('DateFormat', 'TextDate'))
|
d.enumExpression('DateFormat', 'TextDate'))
|
||||||
d.putCallItem('(ISO)', '@QString', value, 'toString',
|
d.putCallItem('(ISO)', '@QString', value, 'toString',
|
||||||
d.enumExpression('DateFormat', 'ISODate'))
|
d.enumExpression('DateFormat', 'ISODate'))
|
||||||
if d.canCallLocale() and d.qtVersion() < 0x060000:
|
if d.canCallLocale() and not d.qtVersionAtLeast(0x060000):
|
||||||
d.putCallItem('(SystemLocale)', '@QString', value, 'toString',
|
d.putCallItem('(SystemLocale)', '@QString', value, 'toString',
|
||||||
d.enumExpression('DateFormat', 'SystemLocaleDate'))
|
d.enumExpression('DateFormat', 'SystemLocaleDate'))
|
||||||
d.putCallItem('(Locale)', '@QString', value, 'toString',
|
d.putCallItem('(Locale)', '@QString', value, 'toString',
|
||||||
@@ -305,13 +307,12 @@ def qdump__QTimeZone(d, value):
|
|||||||
|
|
||||||
|
|
||||||
def qdump__QDateTime(d, value):
|
def qdump__QDateTime(d, value):
|
||||||
qtVersion = d.qtVersion()
|
|
||||||
isValid = False
|
isValid = False
|
||||||
# This relies on the Qt4/Qt5 internal structure layout:
|
# This relies on the Qt4/Qt5 internal structure layout:
|
||||||
# {sharedref(4), ...
|
# {sharedref(4), ...
|
||||||
base = d.extractPointer(value)
|
base = d.extractPointer(value)
|
||||||
is32bit = d.ptrSize() == 4
|
is32bit = d.ptrSize() == 4
|
||||||
if qtVersion >= 0x050200:
|
if qtVersionAtLeast(0x050200):
|
||||||
tiVersion = d.qtTypeInfoVersion()
|
tiVersion = d.qtTypeInfoVersion()
|
||||||
#DumperBase.warn('TI VERSION: %s' % tiVersion)
|
#DumperBase.warn('TI VERSION: %s' % tiVersion)
|
||||||
if tiVersion is None:
|
if tiVersion is None:
|
||||||
@@ -384,9 +385,9 @@ def qdump__QDateTime(d, value):
|
|||||||
# - [QTime time;]
|
# - [QTime time;]
|
||||||
# - - uint mds;
|
# - - uint mds;
|
||||||
# - Spec spec;
|
# - Spec spec;
|
||||||
dateSize = 8 if qtVersion >= 0x050000 else 4 # Qt5: qint64, Qt4 uint
|
dateSize = 8 if qtVersionAtLeast(0x050000) else 4 # Qt5: qint64, Qt4 uint
|
||||||
# 4 byte padding after 4 byte QAtomicInt if we are on 64 bit and QDate is 64 bit
|
# 4 byte padding after 4 byte QAtomicInt if we are on 64 bit and QDate is 64 bit
|
||||||
refPlusPadding = 8 if qtVersion >= 0x050000 and d.ptrSize() == 8 else 4
|
refPlusPadding = 8 if qtVersionAtLeast(0x050000) and d.ptrSize() == 8 else 4
|
||||||
dateBase = base + refPlusPadding
|
dateBase = base + refPlusPadding
|
||||||
timeBase = dateBase + dateSize
|
timeBase = dateBase + dateSize
|
||||||
mds = d.extractInt(timeBase)
|
mds = d.extractInt(timeBase)
|
||||||
@@ -410,7 +411,7 @@ def qdump__QDateTime(d, value):
|
|||||||
d.enumExpression('DateFormat', 'ISODate'))
|
d.enumExpression('DateFormat', 'ISODate'))
|
||||||
d.putCallItem('toUTC', '@QDateTime', value, 'toTimeSpec',
|
d.putCallItem('toUTC', '@QDateTime', value, 'toTimeSpec',
|
||||||
d.enumExpression('TimeSpec', 'UTC'))
|
d.enumExpression('TimeSpec', 'UTC'))
|
||||||
if d.qtVersion() < 0x060000:
|
if not d.qtVersionAtLeast(0x060000):
|
||||||
d.putCallItem('(SystemLocale)', '@QString', value, 'toString',
|
d.putCallItem('(SystemLocale)', '@QString', value, 'toString',
|
||||||
d.enumExpression('DateFormat', 'SystemLocaleDate'))
|
d.enumExpression('DateFormat', 'SystemLocaleDate'))
|
||||||
d.putCallItem('(Locale)', '@QString', value, 'toString',
|
d.putCallItem('(Locale)', '@QString', value, 'toString',
|
||||||
@@ -756,7 +757,6 @@ def qdump__QFile(d, value):
|
|||||||
def qdump__QFileInfo(d, value):
|
def qdump__QFileInfo(d, value):
|
||||||
privAddress = d.extractPointer(value)
|
privAddress = d.extractPointer(value)
|
||||||
#bit32 = d.ptrSize() == 4
|
#bit32 = d.ptrSize() == 4
|
||||||
#qt5 = d.qtVersion() >= 0x050000
|
|
||||||
#try:
|
#try:
|
||||||
# d.putStringValue(value['d_ptr']['d'].dereference()['fileNames'][3])
|
# d.putStringValue(value['d_ptr']['d'].dereference()['fileNames'][3])
|
||||||
#except:
|
#except:
|
||||||
@@ -876,7 +876,7 @@ def qdump__QVariantHash(d, value):
|
|||||||
|
|
||||||
|
|
||||||
def qdumpHelper_QHash(d, value, keyType, valueType):
|
def qdumpHelper_QHash(d, value, keyType, valueType):
|
||||||
if d.qtVersion() >= 0x60000:
|
if d.qtVersionAtLeast(0x060000):
|
||||||
qdumpHelper_QHash_6(d, value, keyType, valueType)
|
qdumpHelper_QHash_6(d, value, keyType, valueType)
|
||||||
else:
|
else:
|
||||||
qdumpHelper_QHash_5(d, value, keyType, valueType)
|
qdumpHelper_QHash_5(d, value, keyType, valueType)
|
||||||
@@ -918,7 +918,7 @@ def qdumpHelper_QHash_5(d, value, keyType, valueType):
|
|||||||
|
|
||||||
d.putItemCount(size)
|
d.putItemCount(size)
|
||||||
if d.isExpanded():
|
if d.isExpanded():
|
||||||
isShort = d.qtVersion() < 0x050000 and keyType.name == 'int'
|
isShort = not d.qtVersionAtLeast(0x050000) and keyType.name == 'int'
|
||||||
with Children(d, size):
|
with Children(d, size):
|
||||||
node = hashDataFirstNode()
|
node = hashDataFirstNode()
|
||||||
for i in d.childRange():
|
for i in d.childRange():
|
||||||
@@ -994,7 +994,7 @@ def qHashIteratorHelper(d, value):
|
|||||||
if d.isExpanded():
|
if d.isExpanded():
|
||||||
with Children(d):
|
with Children(d):
|
||||||
node = d.extractPointer(value)
|
node = d.extractPointer(value)
|
||||||
isShort = d.qtVersion() < 0x050000 and keyType.name == 'int'
|
isShort = not d.qtVersionAtLeast(0x050000) and keyType.name == 'int'
|
||||||
if isShort:
|
if isShort:
|
||||||
typeCode = 'P{%s}@{%s}' % (keyType.name, valueType.name)
|
typeCode = 'P{%s}@{%s}' % (keyType.name, valueType.name)
|
||||||
(pnext, key, padding2, val) = d.split(typeCode, node)
|
(pnext, key, padding2, val) = d.split(typeCode, node)
|
||||||
@@ -1015,9 +1015,8 @@ def qdump__QHash__iterator(d, value):
|
|||||||
|
|
||||||
def qdump__QHostAddress(d, value):
|
def qdump__QHostAddress(d, value):
|
||||||
dd = d.extractPointer(value)
|
dd = d.extractPointer(value)
|
||||||
qtVersion = d.qtVersion()
|
|
||||||
tiVersion = d.qtTypeInfoVersion()
|
tiVersion = d.qtTypeInfoVersion()
|
||||||
#DumperBase.warn('QT: %x, TI: %s' % (qtVersion, tiVersion))
|
#DumperBase.warn('QT: %x, TI: %s' % (d.qtVersion(), tiVersion))
|
||||||
mayNeedParse = True
|
mayNeedParse = True
|
||||||
if tiVersion is not None:
|
if tiVersion is not None:
|
||||||
if tiVersion >= 16:
|
if tiVersion >= 16:
|
||||||
@@ -1032,14 +1031,14 @@ def qdump__QHostAddress(d, value):
|
|||||||
else:
|
else:
|
||||||
(ipString, scopeId, a4, pad, a6, protocol, isParsed) \
|
(ipString, scopeId, a4, pad, a6, protocol, isParsed) \
|
||||||
= d.split('{@QString}{@QString}{@quint32}I16sI{bool}', dd)
|
= d.split('{@QString}{@QString}{@quint32}I16sI{bool}', dd)
|
||||||
elif qtVersion >= 0x050600: # 5.6.0 at f3aabb42
|
elif qtVersionAtLeast(0x050600): # 5.6.0 at f3aabb42
|
||||||
if d.ptrSize() == 8 or d.isWindowsTarget():
|
if d.ptrSize() == 8 or d.isWindowsTarget():
|
||||||
(ipString, scopeId, a4, pad, a6, protocol, isParsed) \
|
(ipString, scopeId, a4, pad, a6, protocol, isParsed) \
|
||||||
= d.split('{@QString}{@QString}{@quint32}I16sI{bool}', dd)
|
= d.split('{@QString}{@QString}{@quint32}I16sI{bool}', dd)
|
||||||
else:
|
else:
|
||||||
(ipString, scopeId, a4, a6, protocol, isParsed) \
|
(ipString, scopeId, a4, a6, protocol, isParsed) \
|
||||||
= d.split('{@QString}{@QString}{@quint32}16sI{bool}', dd)
|
= d.split('{@QString}{@QString}{@quint32}16sI{bool}', dd)
|
||||||
elif qtVersion >= 0x050000: # 5.2.0 at 62feb088
|
elif qtVersionAtLeast(0x050000): # 5.2.0 at 62feb088
|
||||||
(ipString, scopeId, a4, a6, protocol, isParsed) \
|
(ipString, scopeId, a4, a6, protocol, isParsed) \
|
||||||
= d.split('{@QString}{@QString}{@quint32}16sI{bool}', dd)
|
= d.split('{@QString}{@QString}{@quint32}16sI{bool}', dd)
|
||||||
else: # 4.8.7 at b05d05f
|
else: # 4.8.7 at b05d05f
|
||||||
@@ -1104,7 +1103,8 @@ def qdumpHelper_QList(d, value, inner_typish):
|
|||||||
data, size = d.listData(value, check=True)
|
data, size = d.listData(value, check=True)
|
||||||
d.putItemCount(size)
|
d.putItemCount(size)
|
||||||
|
|
||||||
if d.qtVersion() >= 0x60000:
|
d.qtVersionPing(value.typeid)
|
||||||
|
if d.qtVersionAtLeast(0x060000):
|
||||||
d.putPlotData(data, size, innerType)
|
d.putPlotData(data, size, innerType)
|
||||||
return
|
return
|
||||||
|
|
||||||
@@ -1145,9 +1145,9 @@ def qform__QImage():
|
|||||||
|
|
||||||
|
|
||||||
def qdump__QImage(d, value):
|
def qdump__QImage(d, value):
|
||||||
if d.qtVersion() >= 0x060000:
|
if d.qtVersionAtLeast(0x060000):
|
||||||
vtbl, painters, image_data = value.split('ppp')
|
vtbl, painters, image_data = value.split('ppp')
|
||||||
elif d.qtVersion() >= 0x050000:
|
elif d.qtVersionAtLeast(0x050000):
|
||||||
vtbl, painters, reserved, image_data = value.split('pppp')
|
vtbl, painters, reserved, image_data = value.split('pppp')
|
||||||
else:
|
else:
|
||||||
vtbl, painters, image_data = value.split('ppp')
|
vtbl, painters, image_data = value.split('ppp')
|
||||||
@@ -1161,12 +1161,12 @@ def qdump__QImage(d, value):
|
|||||||
|
|
||||||
d.putExpandable()
|
d.putExpandable()
|
||||||
if d.isExpanded():
|
if d.isExpanded():
|
||||||
if d.qtVersion() < 0x060000:
|
if d.qtVersionAtLeast(0x060000):
|
||||||
(ref, width, height, depth, nbytes, pad, devicePixelRatio, colorTable,
|
|
||||||
bits, iformat) = d.split('iiiii@dppi', image_data)
|
|
||||||
else:
|
|
||||||
(ref, width, height, depth, nbytes, pad, devicePixelRatio, _, _, _,
|
(ref, width, height, depth, nbytes, pad, devicePixelRatio, _, _, _,
|
||||||
bits, iformat) = d.split('iiiii@dppppi', image_data)
|
bits, iformat) = d.split('iiiii@dppppi', image_data)
|
||||||
|
else:
|
||||||
|
(ref, width, height, depth, nbytes, pad, devicePixelRatio, colorTable,
|
||||||
|
bits, iformat) = d.split('iiiii@dppi', image_data)
|
||||||
with Children(d):
|
with Children(d):
|
||||||
d.putIntItem('width', width)
|
d.putIntItem('width', width)
|
||||||
d.putIntItem('height', height)
|
d.putIntItem('height', height)
|
||||||
@@ -1222,8 +1222,7 @@ def qdump__QLocale(d, value):
|
|||||||
# index = int(value['d']['d']['m_data']...)
|
# index = int(value['d']['d']['m_data']...)
|
||||||
#d.check(index >= 0)
|
#d.check(index >= 0)
|
||||||
#d.check(index <= qqLocalesCount)
|
#d.check(index <= qqLocalesCount)
|
||||||
qtVersion = d.qtVersion()
|
if not d.qtVersionAtLeast(0x50000):
|
||||||
if qtVersion < 0x50000:
|
|
||||||
d.putStringValue(d.call('const char *', value, 'name'))
|
d.putStringValue(d.call('const char *', value, 'name'))
|
||||||
d.putPlainChildren(value)
|
d.putPlainChildren(value)
|
||||||
return
|
return
|
||||||
@@ -1240,7 +1239,7 @@ def qdump__QLocale(d, value):
|
|||||||
|
|
||||||
prefix = ns + 'QLocale::'
|
prefix = ns + 'QLocale::'
|
||||||
try:
|
try:
|
||||||
if qtVersion >= 0x060700:
|
if qtVersionAtLeast(0x060700):
|
||||||
res = d.call('const char *', value, 'name', prefix + 'TagSeparator::Underscore')
|
res = d.call('const char *', value, 'name', prefix + 'TagSeparator::Underscore')
|
||||||
else:
|
else:
|
||||||
res = d.call('const char *', value, 'name')
|
res = d.call('const char *', value, 'name')
|
||||||
@@ -1347,9 +1346,9 @@ def qdump__QMap(d, value):
|
|||||||
|
|
||||||
|
|
||||||
def qdumpHelper_QMap(d, value, keyType, valueType):
|
def qdumpHelper_QMap(d, value, keyType, valueType):
|
||||||
if d.qtVersion() >= 0x60000:
|
if d.qtVersionAtLeast(0x060000):
|
||||||
qdumpHelper_Qt6_QMap(d, value, keyType, valueType)
|
qdumpHelper_Qt6_QMap(d, value, keyType, valueType)
|
||||||
elif d.qtVersion() >= 0x50000:
|
elif d.qtVersionAtLeast(0x50000):
|
||||||
qdumpHelper_Qt5_QMap(d, value, keyType, valueType)
|
qdumpHelper_Qt5_QMap(d, value, keyType, valueType)
|
||||||
else:
|
else:
|
||||||
qdumpHelper_Qt4_QMap(d, value, keyType, valueType)
|
qdumpHelper_Qt4_QMap(d, value, keyType, valueType)
|
||||||
@@ -1369,7 +1368,7 @@ def qdumpHelper_Qt6_QMultiMap(d, value, keyType, valueType):
|
|||||||
d.putBetterType('@QMultiMap<%s, %s>' % (keyType.name, valueType.name))
|
d.putBetterType('@QMultiMap<%s, %s>' % (keyType.name, valueType.name))
|
||||||
|
|
||||||
def qdump__QMultiMap(d, value):
|
def qdump__QMultiMap(d, value):
|
||||||
if d.qtVersion() >= 0x60000:
|
if d.qtVersionAtLeast(0x060000):
|
||||||
qdumpHelper_Qt6_QMultiMap(d, value, value.type[0], value.type[1])
|
qdumpHelper_Qt6_QMultiMap(d, value, value.type[0], value.type[1])
|
||||||
else:
|
else:
|
||||||
qdump__QMap(d, value)
|
qdump__QMap(d, value)
|
||||||
@@ -1449,9 +1448,9 @@ def qdump__QProcEnvKey(d, value):
|
|||||||
|
|
||||||
|
|
||||||
def qdump__QPixmap(d, value):
|
def qdump__QPixmap(d, value):
|
||||||
if d.qtVersion() >= 0x060000:
|
if d.qtVersionAtLeast(0x060000):
|
||||||
vtbl, painters, data = value.split('ppp')
|
vtbl, painters, data = value.split('ppp')
|
||||||
elif d.qtVersion() >= 0x050000:
|
elif d.qtVersionAtLeast(0x050000):
|
||||||
vtbl, painters, reserved, data = s = d.split('pppp', value)
|
vtbl, painters, reserved, data = s = d.split('pppp', value)
|
||||||
else:
|
else:
|
||||||
vtbl, painters, data = value.split('ppp')
|
vtbl, painters, data = value.split('ppp')
|
||||||
@@ -1518,15 +1517,15 @@ def qdump__QRegion(d, value):
|
|||||||
if d_ptr == 0:
|
if d_ptr == 0:
|
||||||
d.putSpecialValue('empty')
|
d.putSpecialValue('empty')
|
||||||
else:
|
else:
|
||||||
if d.qtVersion() >= 0x060000:
|
if d.qtVersionAtLeast(0x060000):
|
||||||
ref, _, rgn = d.split('i@p', d_ptr)
|
ref, _, rgn = d.split('i@p', d_ptr)
|
||||||
numRects, innerArea, rects, extents, innerRect = \
|
numRects, innerArea, rects, extents, innerRect = \
|
||||||
d.split('ii{@QList<@QRect>}{@QRect}{@QRect}', rgn)
|
d.split('ii{@QList<@QRect>}{@QRect}{@QRect}', rgn)
|
||||||
elif d.qtVersion() >= 0x050400: # Padding removed in ee324e4ed
|
elif d.qtVersionAtLeast(0x050400): # Padding removed in ee324e4ed
|
||||||
ref, _, rgn = d.split('i@p', d_ptr)
|
ref, _, rgn = d.split('i@p', d_ptr)
|
||||||
numRects, innerArea, rects, extents, innerRect = \
|
numRects, innerArea, rects, extents, innerRect = \
|
||||||
d.split('ii{@QVector<@QRect>}{@QRect}{@QRect}', rgn)
|
d.split('ii{@QVector<@QRect>}{@QRect}{@QRect}', rgn)
|
||||||
elif d.qtVersion() >= 0x050000:
|
elif d.qtVersionAtLeast(0x050000):
|
||||||
ref, _, rgn = d.split('i@p', d_ptr)
|
ref, _, rgn = d.split('i@p', d_ptr)
|
||||||
numRects, _, rects, extents, innerRect, innerArea = \
|
numRects, _, rects, extents, innerRect, innerArea = \
|
||||||
d.split('i@{@QVector<@QRect>}{@QRect}{@QRect}i', rgn)
|
d.split('i@{@QVector<@QRect>}{@QRect}{@QRect}i', rgn)
|
||||||
@@ -1564,7 +1563,7 @@ def qdump__QScopedPointer(d, value):
|
|||||||
|
|
||||||
|
|
||||||
def qdump__QSet(d, value):
|
def qdump__QSet(d, value):
|
||||||
if d.qtVersion() >= 0x060000:
|
if d.qtVersionAtLeast(0x060000):
|
||||||
qdumpHelper_QSet6(d, value)
|
qdumpHelper_QSet6(d, value)
|
||||||
else:
|
else:
|
||||||
qdumpHelper_QSet45(d, value)
|
qdumpHelper_QSet45(d, value)
|
||||||
@@ -1637,7 +1636,7 @@ def qdumpHelper_QSet45(d, value):
|
|||||||
d.putItemCount(length)
|
d.putItemCount(length)
|
||||||
if d.isExpanded():
|
if d.isExpanded():
|
||||||
keyType = value.type[0]
|
keyType = value.type[0]
|
||||||
isShort = d.qtVersion() < 0x050000 and keyType.name == 'int'
|
isShort = not d.qtVersionAtLeast(0x050000) and keyType.name == 'int'
|
||||||
with Children(d, length, childType=keyType):
|
with Children(d, length, childType=keyType):
|
||||||
node = hashDataFirstNode()
|
node = hashDataFirstNode()
|
||||||
for i in d.childRange():
|
for i in d.childRange():
|
||||||
@@ -1714,7 +1713,7 @@ def qform__QStack():
|
|||||||
|
|
||||||
|
|
||||||
def qdump__QStack(d, value):
|
def qdump__QStack(d, value):
|
||||||
if d.qtVersion() >= 0x60000:
|
if d.qtVersionVersionAtLeast(0x060000):
|
||||||
qdump__QList(d, value)
|
qdump__QList(d, value)
|
||||||
else:
|
else:
|
||||||
qdump__QVector(d, value)
|
qdump__QVector(d, value)
|
||||||
@@ -1734,7 +1733,7 @@ def qdump__QPolygon(d, value):
|
|||||||
|
|
||||||
def qdump__QGraphicsPolygonItem(d, value):
|
def qdump__QGraphicsPolygonItem(d, value):
|
||||||
(vtbl, dptr) = value.split('pp')
|
(vtbl, dptr) = value.split('pp')
|
||||||
if d.qtVersion() >= 0x060000:
|
if d.qtVersionAtLeast(0x060000):
|
||||||
if d.ptrSize() == 8:
|
if d.ptrSize() == 8:
|
||||||
offset = 424 # sizeof(QGraphicsPolygonItemPrivate), the base
|
offset = 424 # sizeof(QGraphicsPolygonItemPrivate), the base
|
||||||
else:
|
else:
|
||||||
@@ -1764,6 +1763,7 @@ def qform__QString():
|
|||||||
|
|
||||||
|
|
||||||
def qdump__QString(d, value):
|
def qdump__QString(d, value):
|
||||||
|
d.qtVersionPing(value.typeid)
|
||||||
d.putStringValue(value)
|
d.putStringValue(value)
|
||||||
data, length, _ = d.stringData(value)
|
data, length, _ = d.stringData(value)
|
||||||
displayFormat = d.currentItemFormat()
|
displayFormat = d.currentItemFormat()
|
||||||
@@ -1924,7 +1924,7 @@ def qdump__QUrl(d, value):
|
|||||||
d.putValue('<invalid>')
|
d.putValue('<invalid>')
|
||||||
return
|
return
|
||||||
|
|
||||||
if d.qtVersion() < 0x050000:
|
if not d.qtVersionAtLeast(0x050000):
|
||||||
d.call('void', value, 'port') # Warm up internal cache.
|
d.call('void', value, 'port') # Warm up internal cache.
|
||||||
d.call('void', value, 'path')
|
d.call('void', value, 'path')
|
||||||
st = '{@QString}'
|
st = '{@QString}'
|
||||||
@@ -2154,7 +2154,8 @@ qdumpHelper_QVariants_F = [
|
|||||||
|
|
||||||
|
|
||||||
def qdump__QVariant(d, value):
|
def qdump__QVariant(d, value):
|
||||||
if d.qtVersion() >= 0x060000:
|
d.qtVersionPing(value.typeid, 2 * d.ptrSize())
|
||||||
|
if d.qtVersionAtLeast(0x060000):
|
||||||
qdumpHelper__QVariant6(d, value)
|
qdumpHelper__QVariant6(d, value)
|
||||||
else:
|
else:
|
||||||
qdumpHelper__QVariant45(d, value)
|
qdumpHelper__QVariant45(d, value)
|
||||||
@@ -2208,12 +2209,12 @@ def qdumpHelper__QVariant45(d, value):
|
|||||||
return None
|
return None
|
||||||
|
|
||||||
# Extended Core type (Qt 5)
|
# Extended Core type (Qt 5)
|
||||||
if variantType >= 31 and variantType <= 38 and d.qtVersion() >= 0x050000:
|
if variantType >= 31 and variantType <= 38 and d.qtVersionAtLeast(0x050000):
|
||||||
qdumpHelper_QVariants_D[variantType - 31](d, value)
|
qdumpHelper_QVariants_D[variantType - 31](d, value)
|
||||||
return None
|
return None
|
||||||
|
|
||||||
# Extended Core type (Qt 4)
|
# Extended Core type (Qt 4)
|
||||||
if variantType >= 128 and variantType <= 135 and d.qtVersion() < 0x050000:
|
if variantType >= 128 and variantType <= 135 and not d.qtVersionAtLeast(0x050000):
|
||||||
if variantType == 128:
|
if variantType == 128:
|
||||||
d.putBetterType('@QVariant (void *)')
|
d.putBetterType('@QVariant (void *)')
|
||||||
d.putValue('0x%x' % value.extractPointer())
|
d.putValue('0x%x' % value.extractPointer())
|
||||||
@@ -2234,7 +2235,7 @@ def qdumpHelper__QVariant45(d, value):
|
|||||||
innert = qdumpHelper_QVariants_B[variantType - 7]
|
innert = qdumpHelper_QVariants_B[variantType - 7]
|
||||||
elif variantType <= 74:
|
elif variantType <= 74:
|
||||||
innert = qdumpHelper_QVariants_E[variantType - 64]
|
innert = qdumpHelper_QVariants_E[variantType - 64]
|
||||||
elif d.qtVersion() < 0x050000:
|
elif not d.qtVersionAtLeast(0x050000):
|
||||||
innert = qdumpHelper_QVariants_F[variantType - 76]
|
innert = qdumpHelper_QVariants_F[variantType - 76]
|
||||||
else:
|
else:
|
||||||
innert = qdumpHelper_QVariants_F[variantType - 75]
|
innert = qdumpHelper_QVariants_F[variantType - 75]
|
||||||
@@ -2308,7 +2309,8 @@ def qform__QVector():
|
|||||||
|
|
||||||
|
|
||||||
def qdump__QVector(d, value):
|
def qdump__QVector(d, value):
|
||||||
if d.qtVersion() >= 0x060000:
|
d.qtVersionPing(value.typeid)
|
||||||
|
if d.qtVersionAtLeast(0x060000):
|
||||||
data, length = d.listData(value)
|
data, length = d.listData(value)
|
||||||
d.putItemCount(length)
|
d.putItemCount(length)
|
||||||
d.putPlotData(data, length, value.type.target()[0])
|
d.putPlotData(data, length, value.type.target()[0])
|
||||||
@@ -2330,7 +2332,7 @@ if False:
|
|||||||
|
|
||||||
|
|
||||||
def qdump__QVarLengthArray(d, value):
|
def qdump__QVarLengthArray(d, value):
|
||||||
if d.qtVersion() >= 0x060000:
|
if d.qtVersionAtLeast(0x060000):
|
||||||
cap, length, data = value.split('QQp')
|
cap, length, data = value.split('QQp')
|
||||||
else:
|
else:
|
||||||
cap, length, data = value.split('iip')
|
cap, length, data = value.split('iip')
|
||||||
@@ -2366,7 +2368,7 @@ def qdump_QWeakPointerHelper(d, value, isWeak, innerType=None):
|
|||||||
d.putValue('<invalid>')
|
d.putValue('<invalid>')
|
||||||
return
|
return
|
||||||
|
|
||||||
if d.qtVersion() >= 0x050000:
|
if d.qtVersionAtLeast(0x050000):
|
||||||
(weakref, strongref) = d.split('ii', d_ptr)
|
(weakref, strongref) = d.split('ii', d_ptr)
|
||||||
else:
|
else:
|
||||||
(vptr, weakref, strongref) = d.split('pii', d_ptr)
|
(vptr, weakref, strongref) = d.split('pii', d_ptr)
|
||||||
@@ -2872,7 +2874,7 @@ def qdump__QJSValue(d, value):
|
|||||||
if d.ptrSize() == 4:
|
if d.ptrSize() == 4:
|
||||||
qdump_32__QJSValue(d, value)
|
qdump_32__QJSValue(d, value)
|
||||||
else:
|
else:
|
||||||
if d.qtVersion() >= 0x60000:
|
if d.qtVersionAtLeast(0x060000):
|
||||||
qdump_64__QJSValue_6(d, value)
|
qdump_64__QJSValue_6(d, value)
|
||||||
else:
|
else:
|
||||||
qdump_64__QJSValue_5(d, value)
|
qdump_64__QJSValue_5(d, value)
|
||||||
@@ -2906,7 +2908,7 @@ def qdump_64__QJSValue_6(d, value):
|
|||||||
if dd == 0:
|
if dd == 0:
|
||||||
d.putValue('(undefined)')
|
d.putValue('(undefined)')
|
||||||
d.putType(value.type.name + ' (undefined)')
|
d.putType(value.type.name + ' (undefined)')
|
||||||
if d.qtVersion() < 0x60500:
|
if not d.qtVersionAtLeast(0x60500):
|
||||||
typ = dd >> 47
|
typ = dd >> 47
|
||||||
if typ == 5:
|
if typ == 5:
|
||||||
d.putValue('(null)')
|
d.putValue('(null)')
|
||||||
@@ -3326,7 +3328,7 @@ def qdumpHelper_QJsonObject(d, data, obj):
|
|||||||
def qdump__QJsonValue(d, value):
|
def qdump__QJsonValue(d, value):
|
||||||
(data, dd, t) = value.split('QpI')
|
(data, dd, t) = value.split('QpI')
|
||||||
|
|
||||||
if d.qtVersion() >= 0x050f00:
|
if d.qtVersionAtLeast(0x050f00):
|
||||||
value = d.createProxyValue((data, dd, t, False), 'QCborValue_proxy')
|
value = d.createProxyValue((data, dd, t, False), 'QCborValue_proxy')
|
||||||
d.putItem(value)
|
d.putItem(value)
|
||||||
return
|
return
|
||||||
@@ -3361,13 +3363,13 @@ def qdump__QJsonValue(d, value):
|
|||||||
|
|
||||||
|
|
||||||
def qdump__QJsonArray(d, value):
|
def qdump__QJsonArray(d, value):
|
||||||
if d.qtVersion() >= 0x060000:
|
if d.qtVersionAtLeast(0x060000):
|
||||||
dptr = d.extractPointer(value)
|
dptr = d.extractPointer(value)
|
||||||
if not dptr:
|
if not dptr:
|
||||||
d.putItemCount(0)
|
d.putItemCount(0)
|
||||||
else:
|
else:
|
||||||
qdumpHelper_QCbor_array(d, dptr, False)
|
qdumpHelper_QCbor_array(d, dptr, False)
|
||||||
elif d.qtVersion() >= 0x050f00:
|
elif d.qtVersionAtLeast(0x050f00):
|
||||||
_, container_ptr = value.split('pp')
|
_, container_ptr = value.split('pp')
|
||||||
qdumpHelper_QCbor_array(d, container_ptr, False)
|
qdumpHelper_QCbor_array(d, container_ptr, False)
|
||||||
else:
|
else:
|
||||||
@@ -3375,13 +3377,13 @@ def qdump__QJsonArray(d, value):
|
|||||||
|
|
||||||
|
|
||||||
def qdump__QJsonObject(d, value):
|
def qdump__QJsonObject(d, value):
|
||||||
if d.qtVersion() >= 0x060000:
|
if d.qtVersionAtLeast(0x060000):
|
||||||
dptr = d.extractPointer(value)
|
dptr = d.extractPointer(value)
|
||||||
if not dptr:
|
if not dptr:
|
||||||
d.putItemCount(0)
|
d.putItemCount(0)
|
||||||
else:
|
else:
|
||||||
qdumpHelper_QCbor_map(d, dptr, False)
|
qdumpHelper_QCbor_map(d, dptr, False)
|
||||||
elif d.qtVersion() >= 0x050f00:
|
elif d.qtVersionAtLeast(0x050f00):
|
||||||
_, container_ptr = value.split('pp')
|
_, container_ptr = value.split('pp')
|
||||||
qdumpHelper_QCbor_map(d, container_ptr, False)
|
qdumpHelper_QCbor_map(d, container_ptr, False)
|
||||||
else:
|
else:
|
||||||
@@ -3456,15 +3458,15 @@ def qdump__qfloat16(d, value):
|
|||||||
def qdumpHelper_QCbor_string(d, container_ptr, element_index, is_bytes):
|
def qdumpHelper_QCbor_string(d, container_ptr, element_index, is_bytes):
|
||||||
# d.split('i@{@QByteArray::size_type}pp', container_ptr) doesn't work with CDB,
|
# d.split('i@{@QByteArray::size_type}pp', container_ptr) doesn't work with CDB,
|
||||||
# so be explicit:
|
# so be explicit:
|
||||||
data_pos = container_ptr + (2 * d.ptrSize() if d.qtVersion() >= 0x060000 else 8)
|
data_pos = container_ptr + (2 * d.ptrSize() if d.qtVersionAtLeast(0x060000) else 8)
|
||||||
elements_pos = data_pos + (3 * d.ptrSize() if d.qtVersion() >= 0x060000 else d.ptrSize())
|
elements_pos = data_pos + (3 * d.ptrSize() if d.qtVersionAtLeast(0x060000) else d.ptrSize())
|
||||||
elements_data_ptr, elements_size = d.vectorData(elements_pos)
|
elements_data_ptr, elements_size = d.vectorData(elements_pos)
|
||||||
element_at_n_addr = elements_data_ptr + element_index * 16 # sizeof(QtCbor::Element) == 16
|
element_at_n_addr = elements_data_ptr + element_index * 16 # sizeof(QtCbor::Element) == 16
|
||||||
element_value, _, element_flags = d.split('qII', element_at_n_addr)
|
element_value, _, element_flags = d.split('qII', element_at_n_addr)
|
||||||
enc = 'latin1' if is_bytes or (element_flags & 8) else 'utf16'
|
enc = 'latin1' if is_bytes or (element_flags & 8) else 'utf16'
|
||||||
bytedata, _, _ = d.qArrayData(data_pos)
|
bytedata, _, _ = d.qArrayData(data_pos)
|
||||||
bytedata += element_value
|
bytedata += element_value
|
||||||
if d.qtVersion() >= 0x060000:
|
if d.qtVersionAtLeast(0x060000):
|
||||||
bytedata_len = d.extractInt64(bytedata)
|
bytedata_len = d.extractInt64(bytedata)
|
||||||
bytedata_data = bytedata + 8
|
bytedata_data = bytedata + 8
|
||||||
else:
|
else:
|
||||||
@@ -3493,8 +3495,8 @@ def qdumpHelper_QCbor_array(d, container_ptr, is_cbor):
|
|||||||
return
|
return
|
||||||
# d.split('i@{@QByteArray::size_type}pp', container_ptr) doesn't work with CDB,
|
# d.split('i@{@QByteArray::size_type}pp', container_ptr) doesn't work with CDB,
|
||||||
# so be explicit:
|
# so be explicit:
|
||||||
data_pos = container_ptr + (2 * d.ptrSize() if d.qtVersion() >= 0x060000 else 8)
|
data_pos = container_ptr + (2 * d.ptrSize() if d.qtVersionAtLeast(0x060000) else 8)
|
||||||
elements_pos = data_pos + (3 * d.ptrSize() if d.qtVersion() >= 0x060000 else d.ptrSize())
|
elements_pos = data_pos + (3 * d.ptrSize() if d.qtVersionAtLeast(0x060000) else d.ptrSize())
|
||||||
elements_data_ptr, elements_size = d.vectorData(elements_pos)
|
elements_data_ptr, elements_size = d.vectorData(elements_pos)
|
||||||
d.putItemCount(elements_size)
|
d.putItemCount(elements_size)
|
||||||
if d.isExpanded():
|
if d.isExpanded():
|
||||||
@@ -3515,8 +3517,8 @@ def qdumpHelper_QCbor_map(d, container_ptr, is_cbor):
|
|||||||
return
|
return
|
||||||
# d.split('i@{@QByteArray::size_type}pp', container_ptr) doesn't work with CDB,
|
# d.split('i@{@QByteArray::size_type}pp', container_ptr) doesn't work with CDB,
|
||||||
# so be explicit:
|
# so be explicit:
|
||||||
data_pos = container_ptr + (2 * d.ptrSize() if d.qtVersion() >= 0x060000 else 8)
|
data_pos = container_ptr + (2 * d.ptrSize() if d.qtVersionAtLeast(0x060000) else 8)
|
||||||
elements_pos = data_pos + (3 * d.ptrSize() if d.qtVersion() >= 0x060000 else d.ptrSize())
|
elements_pos = data_pos + (3 * d.ptrSize() if d.qtVersionAtLeast(0x060000) else d.ptrSize())
|
||||||
elements_data_ptr, elements_size = d.vectorData(elements_pos)
|
elements_data_ptr, elements_size = d.vectorData(elements_pos)
|
||||||
elements_size = int(elements_size / 2)
|
elements_size = int(elements_size / 2)
|
||||||
d.putItemCount(elements_size)
|
d.putItemCount(elements_size)
|
||||||
|
Reference in New Issue
Block a user