forked from qt-creator/qt-creator
Revert "Debugger: Drop support for backends relying on Python 2"
This reverts commit 43bcf91121
.
GDB coming with MinGW shipped by Qt (e.g. 5.15 official) are still Python2 based.
Change-Id: Iad658de7a242345cc7f6081f26f0238071668a06
Reviewed-by: Denis Shienkov <denis.shienkov@gmail.com>
Reviewed-by: Alexandru Croitor <alexandru.croitor@qt.io>
Reviewed-by: Eike Ziller <eike.ziller@qt.io>
Reviewed-by: hjk <hjk@qt.io>
This commit is contained in:
@@ -46,6 +46,12 @@ except:
|
||||
pass
|
||||
|
||||
|
||||
if sys.version_info[0] >= 3:
|
||||
toInteger = int
|
||||
else:
|
||||
toInteger = long
|
||||
|
||||
|
||||
class ReportItem():
|
||||
"""
|
||||
Helper structure to keep temporary 'best' information about a value
|
||||
@@ -511,7 +517,7 @@ class DumperBase():
|
||||
item = item[:-1]
|
||||
if item.endswith('u'):
|
||||
item = item[:-1]
|
||||
val = int(item)
|
||||
val = toInteger(item)
|
||||
if val > 0x80000000:
|
||||
val -= 0x100000000
|
||||
res.append(val)
|
||||
@@ -523,6 +529,9 @@ class DumperBase():
|
||||
# Hex decoding operating on str, return str.
|
||||
@staticmethod
|
||||
def hexdecode(s, encoding='utf8'):
|
||||
if sys.version_info[0] == 2:
|
||||
# For python2 we need an extra str() call to return str instead of unicode
|
||||
return str(s.decode('hex').decode(encoding))
|
||||
return bytes.fromhex(s).decode(encoding)
|
||||
|
||||
# Hex encoding operating on str or bytes, return str.
|
||||
@@ -530,6 +539,10 @@ class DumperBase():
|
||||
def hexencode(s):
|
||||
if s is None:
|
||||
s = ''
|
||||
if sys.version_info[0] == 2:
|
||||
if isinstance(s, buffer):
|
||||
return bytes(s).encode('hex')
|
||||
return s.encode('hex')
|
||||
if isinstance(s, str):
|
||||
s = s.encode('utf8')
|
||||
return base64.b16encode(s).decode('utf8')
|
||||
@@ -885,7 +898,7 @@ class DumperBase():
|
||||
self.check(ref < 1000000)
|
||||
|
||||
def checkIntType(self, thing):
|
||||
if not isinstance(thing, int):
|
||||
if not self.isInt(thing):
|
||||
raise RuntimeError('Expected an integral value, got %s' % type(thing))
|
||||
|
||||
def readToFirstZero(self, base, tsize, maximum):
|
||||
@@ -1024,7 +1037,8 @@ class DumperBase():
|
||||
def putType(self, typish, priority=0):
|
||||
# Higher priority values override lower ones.
|
||||
if priority >= self.currentType.priority:
|
||||
if isinstance(typish, str):
|
||||
types = (str) if sys.version_info[0] >= 3 else (str, unicode)
|
||||
if isinstance(typish, types):
|
||||
self.currentType.value = typish
|
||||
else:
|
||||
self.currentType.value = typish.name
|
||||
@@ -1138,7 +1152,7 @@ class DumperBase():
|
||||
def cleanAddress(self, addr):
|
||||
if addr is None:
|
||||
return '<no address>'
|
||||
return '0x%x' % int(hex(addr), 16)
|
||||
return '0x%x' % toInteger(hex(addr), 16)
|
||||
|
||||
def stripNamespaceFromType(self, typeName):
|
||||
ns = self.qtNamespace()
|
||||
@@ -1708,7 +1722,7 @@ class DumperBase():
|
||||
def split(self, pattern, value):
|
||||
if isinstance(value, self.Value):
|
||||
return value.split(pattern)
|
||||
if isinstance(value, int):
|
||||
if self.isInt(value):
|
||||
val = self.Value(self)
|
||||
val.laddress = value
|
||||
return val.split(pattern)
|
||||
@@ -1773,12 +1787,12 @@ class DumperBase():
|
||||
stringdataOffset = ptrSize
|
||||
if self.isWindowsTarget() and self.qtVersion() >= 0x060000:
|
||||
stringdataOffset += ptrSize # indirect super data member
|
||||
stringdata = self.extractPointer(int(metaObjectPtr) + stringdataOffset)
|
||||
stringdata = self.extractPointer(toInteger(metaObjectPtr) + stringdataOffset)
|
||||
|
||||
def unpackString(base, size):
|
||||
try:
|
||||
s = struct.unpack_from('%ds' % size, self.readRawMemory(base, size))[0]
|
||||
return s.decode('utf8')
|
||||
return s if sys.version_info[0] == 2 else s.decode('utf8')
|
||||
except:
|
||||
return '<not available>'
|
||||
|
||||
@@ -1788,7 +1802,7 @@ class DumperBase():
|
||||
|
||||
if revision >= 7: # Qt 5.
|
||||
byteArrayDataSize = 24 if ptrSize == 8 else 16
|
||||
literal = stringdata + int(index) * byteArrayDataSize
|
||||
literal = stringdata + toInteger(index) * byteArrayDataSize
|
||||
base, size, _ = self.qArrayDataHelper(literal)
|
||||
return unpackString(base, size)
|
||||
|
||||
@@ -2324,7 +2338,7 @@ class DumperBase():
|
||||
return self.extractSomething(value, 'b', 8)
|
||||
|
||||
def extractSomething(self, value, pattern, bitsize):
|
||||
if isinstance(value, int):
|
||||
if self.isInt(value):
|
||||
val = self.Value(self)
|
||||
val.laddress = value
|
||||
return val.extractSomething(pattern, bitsize)
|
||||
@@ -2521,10 +2535,13 @@ class DumperBase():
|
||||
return msg
|
||||
|
||||
def reloadDumpers(self, args):
|
||||
import importlib
|
||||
for mod in self.dumpermodules:
|
||||
m = sys.modules[mod]
|
||||
importlib.reload(m)
|
||||
if sys.version_info[0] >= 3:
|
||||
import importlib
|
||||
importlib.reload(m)
|
||||
else:
|
||||
reload(m)
|
||||
self.setupDumpers(args)
|
||||
|
||||
def loadDumpers(self, args):
|
||||
@@ -2708,9 +2725,12 @@ class DumperBase():
|
||||
def extractInterpreterStack(self):
|
||||
return self.sendInterpreterRequest('backtrace', {'limit': 10})
|
||||
|
||||
def isInt(self, thing): # Unused since 6.0
|
||||
def isInt(self, thing):
|
||||
if isinstance(thing, int):
|
||||
return True
|
||||
if sys.version_info[0] == 2:
|
||||
if isinstance(thing, long):
|
||||
return True
|
||||
return False
|
||||
|
||||
def putItems(self, count, generator, maxNumChild=10000):
|
||||
@@ -2943,7 +2963,7 @@ class DumperBase():
|
||||
return self._type
|
||||
|
||||
def check(self):
|
||||
if self.laddress is not None and not isinstance(self.laddress, int):
|
||||
if self.laddress is not None and not self.dumper.isInt(self.laddress):
|
||||
raise RuntimeError('INCONSISTENT ADDRESS: %s' % type(self.laddress))
|
||||
if self.type is not None and not isinstance(self.type, self.dumper.Type):
|
||||
raise RuntimeError('INCONSISTENT TYPE: %s' % type(self.type))
|
||||
@@ -2975,6 +2995,8 @@ class DumperBase():
|
||||
if simple is not None:
|
||||
return str(simple)
|
||||
#if self.ldata is not None:
|
||||
# if sys.version_info[0] == 2 and isinstance(self.ldata, buffer):
|
||||
# return bytes(self.ldata).encode('hex')
|
||||
# return self.ldata.encode('hex')
|
||||
if self.laddress is not None:
|
||||
return 'value of type %s at address 0x%x' % (self.type.name, self.laddress)
|
||||
@@ -3116,7 +3138,7 @@ class DumperBase():
|
||||
return res
|
||||
elif isinstance(index, self.dumper.Field):
|
||||
field = index
|
||||
elif isinstance(index, int):
|
||||
elif self.dumper.isInt(index):
|
||||
if self.type.code == TypeCode.Array:
|
||||
addr = self.laddress + int(index) * self.type.ltarget.size()
|
||||
return self.dumper.createValue(addr, self.type.ltarget)
|
||||
@@ -3179,7 +3201,10 @@ class DumperBase():
|
||||
lbyte = ldata[i]
|
||||
else:
|
||||
lbyte = ldata[fieldOffset + fieldSize - 1 - i]
|
||||
data += lbyte
|
||||
if sys.version_info[0] >= 3:
|
||||
data += lbyte
|
||||
else:
|
||||
data += ord(lbyte)
|
||||
data = data >> fieldBitpos
|
||||
data = data & ((1 << fieldBitsize) - 1)
|
||||
val.lvalue = data
|
||||
@@ -3238,7 +3263,7 @@ class DumperBase():
|
||||
|
||||
def __add__(self, other):
|
||||
self.check()
|
||||
if isinstance(other, int):
|
||||
if self.dumper.isInt(other):
|
||||
stripped = self.type.stripTypedefs()
|
||||
if stripped.code == TypeCode.Pointer:
|
||||
address = self.pointer() + stripped.dereference().size() * other
|
||||
@@ -3312,7 +3337,10 @@ class DumperBase():
|
||||
|
||||
def zeroExtend(self, data, size):
|
||||
ext = '\0' * (size - len(data))
|
||||
pad = bytes(ext, encoding='latin1')
|
||||
if sys.version_info[0] == 3:
|
||||
pad = bytes(ext, encoding='latin1')
|
||||
else:
|
||||
pad = bytes(ext)
|
||||
return pad + data if self.dumper.isBigEndian else data + pad
|
||||
|
||||
def cast(self, typish):
|
||||
@@ -3406,7 +3434,7 @@ class DumperBase():
|
||||
return tuple(map(structFixer, fields, result))
|
||||
|
||||
def checkPointer(self, p, align=1):
|
||||
ptr = p if isinstance(p, int) else p.pointer()
|
||||
ptr = p if self.isInt(p) else p.pointer()
|
||||
self.readRawMemory(ptr, 1)
|
||||
|
||||
def type(self, typeId):
|
||||
@@ -3522,7 +3550,7 @@ class DumperBase():
|
||||
% (tdata.name, tdata.lbitsize, tdata.code)
|
||||
|
||||
def __getitem__(self, index):
|
||||
if isinstance(index, int):
|
||||
if self.dumper.isInt(index):
|
||||
return self.templateArgument(index)
|
||||
raise RuntimeError('CANNOT INDEX TYPE')
|
||||
|
||||
@@ -3715,7 +3743,7 @@ class DumperBase():
|
||||
return 'I' if self.ptrSize() == 4 else 'Q'
|
||||
|
||||
def toPointerData(self, address):
|
||||
if not isinstance(address, int):
|
||||
if not self.isInt(address):
|
||||
raise RuntimeError('wrong')
|
||||
return bytes(struct.pack(self.packCode + self.ptrCode(), address))
|
||||
|
||||
@@ -3726,7 +3754,7 @@ class DumperBase():
|
||||
if not isinstance(targetTypish, self.Type) and not isinstance(targetTypish, str):
|
||||
raise RuntimeError('Expected type in createPointerValue(), got %s'
|
||||
% type(targetTypish))
|
||||
if not isinstance(targetAddress, int):
|
||||
if not self.isInt(targetAddress):
|
||||
raise RuntimeError('Expected integral address value in createPointerValue(), got %s'
|
||||
% type(targetTypish))
|
||||
val = self.Value(self)
|
||||
@@ -3741,7 +3769,7 @@ class DumperBase():
|
||||
if not isinstance(targetType, self.Type):
|
||||
raise RuntimeError('Expected type in createReferenceValue(), got %s'
|
||||
% type(targetType))
|
||||
if not isinstance(targetAddress, int):
|
||||
if not self.isInt(targetAddress):
|
||||
raise RuntimeError('Expected integral address value in createReferenceValue(), got %s'
|
||||
% type(targetType))
|
||||
val = self.Value(self)
|
||||
@@ -3925,7 +3953,7 @@ class DumperBase():
|
||||
def createValue(self, datish, typish):
|
||||
val = self.Value(self)
|
||||
val._type = self.createType(typish)
|
||||
if isinstance(datish, int): # Used as address.
|
||||
if self.isInt(datish): # Used as address.
|
||||
#DumperBase.warn('CREATING %s AT 0x%x' % (val.type.name, datish))
|
||||
val.laddress = datish
|
||||
if self.useDynamicType:
|
||||
|
@@ -36,7 +36,7 @@ import sys
|
||||
import struct
|
||||
import tempfile
|
||||
|
||||
from dumper import DumperBase, Children, TopLevelItem
|
||||
from dumper import DumperBase, Children, toInteger, TopLevelItem
|
||||
from utils import TypeCode
|
||||
from gdbtracepoint import *
|
||||
|
||||
@@ -259,7 +259,7 @@ class Dumper(DumperBase):
|
||||
code = nativeType.code
|
||||
if code == gdb.TYPE_CODE_REF:
|
||||
targetType = self.fromNativeType(nativeType.target().unqualified())
|
||||
val = self.createReferenceValue(int(nativeValue.address), targetType)
|
||||
val = self.createReferenceValue(toInteger(nativeValue.address), targetType)
|
||||
val.nativeValue = nativeValue
|
||||
#DumperBase.warn('CREATED REF: %s' % val)
|
||||
return val
|
||||
@@ -269,7 +269,7 @@ class Dumper(DumperBase):
|
||||
except:
|
||||
nativeTargetValue = None
|
||||
targetType = self.fromNativeType(nativeType.target().unqualified())
|
||||
val = self.createPointerValue(int(nativeValue), targetType)
|
||||
val = self.createPointerValue(toInteger(nativeValue), targetType)
|
||||
# The nativeValue is needed in case of multiple inheritance, see
|
||||
# QTCREATORBUG-17823. Using it triggers nativeValueDereferencePointer()
|
||||
# later which
|
||||
@@ -277,7 +277,7 @@ class Dumper(DumperBase):
|
||||
val.nativeValue = nativeValue
|
||||
#DumperBase.warn('CREATED PTR 1: %s' % val)
|
||||
if nativeValue.address is not None:
|
||||
val.laddress = int(nativeValue.address)
|
||||
val.laddress = toInteger(nativeValue.address)
|
||||
#DumperBase.warn('CREATED PTR 2: %s' % val)
|
||||
return val
|
||||
if code == gdb.TYPE_CODE_TYPEDEF:
|
||||
@@ -300,7 +300,7 @@ class Dumper(DumperBase):
|
||||
|
||||
val.nativeValue = nativeValue
|
||||
if nativeValue.address is not None:
|
||||
val.laddress = int(nativeValue.address)
|
||||
val.laddress = toInteger(nativeValue.address)
|
||||
else:
|
||||
size = nativeType.sizeof
|
||||
chars = self.lookupNativeType('unsigned char')
|
||||
@@ -834,7 +834,7 @@ class Dumper(DumperBase):
|
||||
#DumperBase.warn('EXP: %s' % exp)
|
||||
res = gdb.parse_and_eval(exp)
|
||||
#DumperBase.warn('RES: %s' % res)
|
||||
return int(res)
|
||||
return toInteger(res)
|
||||
|
||||
def releaseValue(self, address):
|
||||
gdb.parse_and_eval('free(0x%x)' % address)
|
||||
@@ -874,12 +874,12 @@ class Dumper(DumperBase):
|
||||
return 0
|
||||
try:
|
||||
# Older GDB ~7.4 don't have gdb.Symbol.value()
|
||||
return int(symbol.value().address)
|
||||
return toInteger(symbol.value().address)
|
||||
except:
|
||||
pass
|
||||
|
||||
address = gdb.parse_and_eval("&'%s'" % symbolName)
|
||||
return int(address)
|
||||
return toInteger(address)
|
||||
|
||||
def isArmArchitecture(self):
|
||||
return 'arm' in gdb.TARGET_CONFIG.lower()
|
||||
@@ -1059,7 +1059,7 @@ class Dumper(DumperBase):
|
||||
|
||||
def findSymbol(self, symbolName):
|
||||
try:
|
||||
return int(gdb.parse_and_eval("(size_t)&'%s'" % symbolName))
|
||||
return toInteger(gdb.parse_and_eval("(size_t)&'%s'" % symbolName))
|
||||
except:
|
||||
return 0
|
||||
|
||||
@@ -1371,7 +1371,7 @@ class Dumper(DumperBase):
|
||||
if typeobj.code == gdb.TYPE_CODE_PTR:
|
||||
dereftype = typeobj.target().unqualified()
|
||||
if dereftype.name == needle:
|
||||
addr = int(value)
|
||||
addr = toInteger(value)
|
||||
res = None
|
||||
for pat in pats:
|
||||
try:
|
||||
|
@@ -26,7 +26,7 @@
|
||||
import platform
|
||||
import struct
|
||||
import re
|
||||
from dumper import Children, SubItem, UnnamedSubItem, DumperBase
|
||||
from dumper import Children, SubItem, UnnamedSubItem, toInteger, DumperBase
|
||||
from utils import DisplayFormat, TypeCode
|
||||
|
||||
|
||||
@@ -3106,7 +3106,7 @@ def qdumpHelper_QJsonValue(d, data, base, pv):
|
||||
if t == 2:
|
||||
d.putType('QJsonValue (Number)')
|
||||
if latinOrIntValue:
|
||||
w = int(v)
|
||||
w = toInteger(v)
|
||||
if w >= 0x4000000:
|
||||
w -= 0x8000000
|
||||
d.putValue(w)
|
||||
|
Reference in New Issue
Block a user