Debugger: Drop support for backends relying on Python 2

The last discussion of the topic was 18 months ago, and already back
then it seemed not widely used anymore. See
https://lists.qt-project.org/pipermail/qt-creator/2020-February/008382.html

Change-Id: I48c879ce918b7351b1120bd70892deb0330637f5
Reviewed-by: Alexandru Croitor <alexandru.croitor@qt.io>
Reviewed-by: Orgad Shaneh <orgads@gmail.com>
Reviewed-by: Eike Ziller <eike.ziller@qt.io>
Reviewed-by: Cristian Adam <cristian.adam@qt.io>
This commit is contained in:
hjk
2021-08-24 10:46:34 +02:00
parent d5e0567f78
commit 43bcf91121
3 changed files with 35 additions and 63 deletions

View File

@@ -46,12 +46,6 @@ except:
pass pass
if sys.version_info[0] >= 3:
toInteger = int
else:
toInteger = long
class ReportItem(): class ReportItem():
""" """
Helper structure to keep temporary 'best' information about a value Helper structure to keep temporary 'best' information about a value
@@ -517,7 +511,7 @@ class DumperBase():
item = item[:-1] item = item[:-1]
if item.endswith('u'): if item.endswith('u'):
item = item[:-1] item = item[:-1]
val = toInteger(item) val = int(item)
if val > 0x80000000: if val > 0x80000000:
val -= 0x100000000 val -= 0x100000000
res.append(val) res.append(val)
@@ -529,9 +523,6 @@ class DumperBase():
# Hex decoding operating on str, return str. # Hex decoding operating on str, return str.
@staticmethod @staticmethod
def hexdecode(s, encoding='utf8'): 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) return bytes.fromhex(s).decode(encoding)
# Hex encoding operating on str or bytes, return str. # Hex encoding operating on str or bytes, return str.
@@ -539,10 +530,6 @@ class DumperBase():
def hexencode(s): def hexencode(s):
if s is None: if s is None:
s = '' s = ''
if sys.version_info[0] == 2:
if isinstance(s, buffer):
return bytes(s).encode('hex')
return s.encode('hex')
if isinstance(s, str): if isinstance(s, str):
s = s.encode('utf8') s = s.encode('utf8')
return base64.b16encode(s).decode('utf8') return base64.b16encode(s).decode('utf8')
@@ -898,7 +885,7 @@ class DumperBase():
self.check(ref < 1000000) self.check(ref < 1000000)
def checkIntType(self, thing): def checkIntType(self, thing):
if not self.isInt(thing): if not isinstance(thing, int):
raise RuntimeError('Expected an integral value, got %s' % type(thing)) raise RuntimeError('Expected an integral value, got %s' % type(thing))
def readToFirstZero(self, base, tsize, maximum): def readToFirstZero(self, base, tsize, maximum):
@@ -1037,8 +1024,7 @@ class DumperBase():
def putType(self, typish, priority=0): def putType(self, typish, priority=0):
# Higher priority values override lower ones. # Higher priority values override lower ones.
if priority >= self.currentType.priority: if priority >= self.currentType.priority:
types = (str) if sys.version_info[0] >= 3 else (str, unicode) if isinstance(typish, str):
if isinstance(typish, types):
self.currentType.value = typish self.currentType.value = typish
else: else:
self.currentType.value = typish.name self.currentType.value = typish.name
@@ -1152,7 +1138,7 @@ class DumperBase():
def cleanAddress(self, addr): def cleanAddress(self, addr):
if addr is None: if addr is None:
return '<no address>' return '<no address>'
return '0x%x' % toInteger(hex(addr), 16) return '0x%x' % int(hex(addr), 16)
def stripNamespaceFromType(self, typeName): def stripNamespaceFromType(self, typeName):
ns = self.qtNamespace() ns = self.qtNamespace()
@@ -1722,7 +1708,7 @@ class DumperBase():
def split(self, pattern, value): def split(self, pattern, value):
if isinstance(value, self.Value): if isinstance(value, self.Value):
return value.split(pattern) return value.split(pattern)
if self.isInt(value): if isinstance(value, int):
val = self.Value(self) val = self.Value(self)
val.laddress = value val.laddress = value
return val.split(pattern) return val.split(pattern)
@@ -1787,12 +1773,12 @@ class DumperBase():
stringdataOffset = ptrSize stringdataOffset = ptrSize
if self.isWindowsTarget() and self.qtVersion() >= 0x060000: if self.isWindowsTarget() and self.qtVersion() >= 0x060000:
stringdataOffset += ptrSize # indirect super data member stringdataOffset += ptrSize # indirect super data member
stringdata = self.extractPointer(toInteger(metaObjectPtr) + stringdataOffset) stringdata = self.extractPointer(int(metaObjectPtr) + stringdataOffset)
def unpackString(base, size): def unpackString(base, size):
try: try:
s = struct.unpack_from('%ds' % size, self.readRawMemory(base, size))[0] s = struct.unpack_from('%ds' % size, self.readRawMemory(base, size))[0]
return s if sys.version_info[0] == 2 else s.decode('utf8') return s.decode('utf8')
except: except:
return '<not available>' return '<not available>'
@@ -1802,7 +1788,7 @@ class DumperBase():
if revision >= 7: # Qt 5. if revision >= 7: # Qt 5.
byteArrayDataSize = 24 if ptrSize == 8 else 16 byteArrayDataSize = 24 if ptrSize == 8 else 16
literal = stringdata + toInteger(index) * byteArrayDataSize literal = stringdata + int(index) * byteArrayDataSize
base, size, _ = self.qArrayDataHelper(literal) base, size, _ = self.qArrayDataHelper(literal)
return unpackString(base, size) return unpackString(base, size)
@@ -2338,7 +2324,7 @@ class DumperBase():
return self.extractSomething(value, 'b', 8) return self.extractSomething(value, 'b', 8)
def extractSomething(self, value, pattern, bitsize): def extractSomething(self, value, pattern, bitsize):
if self.isInt(value): if isinstance(value, int):
val = self.Value(self) val = self.Value(self)
val.laddress = value val.laddress = value
return val.extractSomething(pattern, bitsize) return val.extractSomething(pattern, bitsize)
@@ -2535,13 +2521,10 @@ class DumperBase():
return msg return msg
def reloadDumpers(self, args): def reloadDumpers(self, args):
import importlib
for mod in self.dumpermodules: for mod in self.dumpermodules:
m = sys.modules[mod] m = sys.modules[mod]
if sys.version_info[0] >= 3: importlib.reload(m)
import importlib
importlib.reload(m)
else:
reload(m)
self.setupDumpers(args) self.setupDumpers(args)
def loadDumpers(self, args): def loadDumpers(self, args):
@@ -2725,12 +2708,9 @@ class DumperBase():
def extractInterpreterStack(self): def extractInterpreterStack(self):
return self.sendInterpreterRequest('backtrace', {'limit': 10}) return self.sendInterpreterRequest('backtrace', {'limit': 10})
def isInt(self, thing): def isInt(self, thing): # Unused since 6.0
if isinstance(thing, int): if isinstance(thing, int):
return True return True
if sys.version_info[0] == 2:
if isinstance(thing, long):
return True
return False return False
def putItems(self, count, generator, maxNumChild=10000): def putItems(self, count, generator, maxNumChild=10000):
@@ -2963,7 +2943,7 @@ class DumperBase():
return self._type return self._type
def check(self): def check(self):
if self.laddress is not None and not self.dumper.isInt(self.laddress): if self.laddress is not None and not isinstance(self.laddress, int):
raise RuntimeError('INCONSISTENT ADDRESS: %s' % type(self.laddress)) raise RuntimeError('INCONSISTENT ADDRESS: %s' % type(self.laddress))
if self.type is not None and not isinstance(self.type, self.dumper.Type): if self.type is not None and not isinstance(self.type, self.dumper.Type):
raise RuntimeError('INCONSISTENT TYPE: %s' % type(self.type)) raise RuntimeError('INCONSISTENT TYPE: %s' % type(self.type))
@@ -2995,8 +2975,6 @@ class DumperBase():
if simple is not None: if simple is not None:
return str(simple) return str(simple)
#if self.ldata is not None: #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') # return self.ldata.encode('hex')
if self.laddress is not None: if self.laddress is not None:
return 'value of type %s at address 0x%x' % (self.type.name, self.laddress) return 'value of type %s at address 0x%x' % (self.type.name, self.laddress)
@@ -3138,7 +3116,7 @@ class DumperBase():
return res return res
elif isinstance(index, self.dumper.Field): elif isinstance(index, self.dumper.Field):
field = index field = index
elif self.dumper.isInt(index): elif isinstance(index, int):
if self.type.code == TypeCode.Array: if self.type.code == TypeCode.Array:
addr = self.laddress + int(index) * self.type.ltarget.size() addr = self.laddress + int(index) * self.type.ltarget.size()
return self.dumper.createValue(addr, self.type.ltarget) return self.dumper.createValue(addr, self.type.ltarget)
@@ -3201,10 +3179,7 @@ class DumperBase():
lbyte = ldata[i] lbyte = ldata[i]
else: else:
lbyte = ldata[fieldOffset + fieldSize - 1 - i] lbyte = ldata[fieldOffset + fieldSize - 1 - i]
if sys.version_info[0] >= 3: data += lbyte
data += lbyte
else:
data += ord(lbyte)
data = data >> fieldBitpos data = data >> fieldBitpos
data = data & ((1 << fieldBitsize) - 1) data = data & ((1 << fieldBitsize) - 1)
val.lvalue = data val.lvalue = data
@@ -3263,7 +3238,7 @@ class DumperBase():
def __add__(self, other): def __add__(self, other):
self.check() self.check()
if self.dumper.isInt(other): if isinstance(other, int):
stripped = self.type.stripTypedefs() stripped = self.type.stripTypedefs()
if stripped.code == TypeCode.Pointer: if stripped.code == TypeCode.Pointer:
address = self.pointer() + stripped.dereference().size() * other address = self.pointer() + stripped.dereference().size() * other
@@ -3337,10 +3312,7 @@ class DumperBase():
def zeroExtend(self, data, size): def zeroExtend(self, data, size):
ext = '\0' * (size - len(data)) ext = '\0' * (size - len(data))
if sys.version_info[0] == 3: pad = bytes(ext, encoding='latin1')
pad = bytes(ext, encoding='latin1')
else:
pad = bytes(ext)
return pad + data if self.dumper.isBigEndian else data + pad return pad + data if self.dumper.isBigEndian else data + pad
def cast(self, typish): def cast(self, typish):
@@ -3434,7 +3406,7 @@ class DumperBase():
return tuple(map(structFixer, fields, result)) return tuple(map(structFixer, fields, result))
def checkPointer(self, p, align=1): def checkPointer(self, p, align=1):
ptr = p if self.isInt(p) else p.pointer() ptr = p if isinstance(p, int) else p.pointer()
self.readRawMemory(ptr, 1) self.readRawMemory(ptr, 1)
def type(self, typeId): def type(self, typeId):
@@ -3550,7 +3522,7 @@ class DumperBase():
% (tdata.name, tdata.lbitsize, tdata.code) % (tdata.name, tdata.lbitsize, tdata.code)
def __getitem__(self, index): def __getitem__(self, index):
if self.dumper.isInt(index): if isinstance(index, int):
return self.templateArgument(index) return self.templateArgument(index)
raise RuntimeError('CANNOT INDEX TYPE') raise RuntimeError('CANNOT INDEX TYPE')
@@ -3743,7 +3715,7 @@ class DumperBase():
return 'I' if self.ptrSize() == 4 else 'Q' return 'I' if self.ptrSize() == 4 else 'Q'
def toPointerData(self, address): def toPointerData(self, address):
if not self.isInt(address): if not isinstance(address, int):
raise RuntimeError('wrong') raise RuntimeError('wrong')
return bytes(struct.pack(self.packCode + self.ptrCode(), address)) return bytes(struct.pack(self.packCode + self.ptrCode(), address))
@@ -3754,7 +3726,7 @@ class DumperBase():
if not isinstance(targetTypish, self.Type) and not isinstance(targetTypish, str): if not isinstance(targetTypish, self.Type) and not isinstance(targetTypish, str):
raise RuntimeError('Expected type in createPointerValue(), got %s' raise RuntimeError('Expected type in createPointerValue(), got %s'
% type(targetTypish)) % type(targetTypish))
if not self.isInt(targetAddress): if not isinstance(targetAddress, int):
raise RuntimeError('Expected integral address value in createPointerValue(), got %s' raise RuntimeError('Expected integral address value in createPointerValue(), got %s'
% type(targetTypish)) % type(targetTypish))
val = self.Value(self) val = self.Value(self)
@@ -3769,7 +3741,7 @@ class DumperBase():
if not isinstance(targetType, self.Type): if not isinstance(targetType, self.Type):
raise RuntimeError('Expected type in createReferenceValue(), got %s' raise RuntimeError('Expected type in createReferenceValue(), got %s'
% type(targetType)) % type(targetType))
if not self.isInt(targetAddress): if not isinstance(targetAddress, int):
raise RuntimeError('Expected integral address value in createReferenceValue(), got %s' raise RuntimeError('Expected integral address value in createReferenceValue(), got %s'
% type(targetType)) % type(targetType))
val = self.Value(self) val = self.Value(self)
@@ -3953,7 +3925,7 @@ class DumperBase():
def createValue(self, datish, typish): def createValue(self, datish, typish):
val = self.Value(self) val = self.Value(self)
val._type = self.createType(typish) val._type = self.createType(typish)
if self.isInt(datish): # Used as address. if isinstance(datish, int): # Used as address.
#DumperBase.warn('CREATING %s AT 0x%x' % (val.type.name, datish)) #DumperBase.warn('CREATING %s AT 0x%x' % (val.type.name, datish))
val.laddress = datish val.laddress = datish
if self.useDynamicType: if self.useDynamicType:

View File

@@ -36,7 +36,7 @@ import sys
import struct import struct
import tempfile import tempfile
from dumper import DumperBase, Children, toInteger, TopLevelItem from dumper import DumperBase, Children, TopLevelItem
from utils import TypeCode from utils import TypeCode
from gdbtracepoint import * from gdbtracepoint import *
@@ -259,7 +259,7 @@ class Dumper(DumperBase):
code = nativeType.code code = nativeType.code
if code == gdb.TYPE_CODE_REF: if code == gdb.TYPE_CODE_REF:
targetType = self.fromNativeType(nativeType.target().unqualified()) targetType = self.fromNativeType(nativeType.target().unqualified())
val = self.createReferenceValue(toInteger(nativeValue.address), targetType) val = self.createReferenceValue(int(nativeValue.address), targetType)
val.nativeValue = nativeValue val.nativeValue = nativeValue
#DumperBase.warn('CREATED REF: %s' % val) #DumperBase.warn('CREATED REF: %s' % val)
return val return val
@@ -269,7 +269,7 @@ class Dumper(DumperBase):
except: except:
nativeTargetValue = None nativeTargetValue = None
targetType = self.fromNativeType(nativeType.target().unqualified()) targetType = self.fromNativeType(nativeType.target().unqualified())
val = self.createPointerValue(toInteger(nativeValue), targetType) val = self.createPointerValue(int(nativeValue), targetType)
# The nativeValue is needed in case of multiple inheritance, see # The nativeValue is needed in case of multiple inheritance, see
# QTCREATORBUG-17823. Using it triggers nativeValueDereferencePointer() # QTCREATORBUG-17823. Using it triggers nativeValueDereferencePointer()
# later which # later which
@@ -277,7 +277,7 @@ class Dumper(DumperBase):
val.nativeValue = nativeValue val.nativeValue = nativeValue
#DumperBase.warn('CREATED PTR 1: %s' % val) #DumperBase.warn('CREATED PTR 1: %s' % val)
if nativeValue.address is not None: if nativeValue.address is not None:
val.laddress = toInteger(nativeValue.address) val.laddress = int(nativeValue.address)
#DumperBase.warn('CREATED PTR 2: %s' % val) #DumperBase.warn('CREATED PTR 2: %s' % val)
return val return val
if code == gdb.TYPE_CODE_TYPEDEF: if code == gdb.TYPE_CODE_TYPEDEF:
@@ -300,7 +300,7 @@ class Dumper(DumperBase):
val.nativeValue = nativeValue val.nativeValue = nativeValue
if nativeValue.address is not None: if nativeValue.address is not None:
val.laddress = toInteger(nativeValue.address) val.laddress = int(nativeValue.address)
else: else:
size = nativeType.sizeof size = nativeType.sizeof
chars = self.lookupNativeType('unsigned char') chars = self.lookupNativeType('unsigned char')
@@ -834,7 +834,7 @@ class Dumper(DumperBase):
#DumperBase.warn('EXP: %s' % exp) #DumperBase.warn('EXP: %s' % exp)
res = gdb.parse_and_eval(exp) res = gdb.parse_and_eval(exp)
#DumperBase.warn('RES: %s' % res) #DumperBase.warn('RES: %s' % res)
return toInteger(res) return int(res)
def releaseValue(self, address): def releaseValue(self, address):
gdb.parse_and_eval('free(0x%x)' % address) gdb.parse_and_eval('free(0x%x)' % address)
@@ -874,12 +874,12 @@ class Dumper(DumperBase):
return 0 return 0
try: try:
# Older GDB ~7.4 don't have gdb.Symbol.value() # Older GDB ~7.4 don't have gdb.Symbol.value()
return toInteger(symbol.value().address) return int(symbol.value().address)
except: except:
pass pass
address = gdb.parse_and_eval("&'%s'" % symbolName) address = gdb.parse_and_eval("&'%s'" % symbolName)
return toInteger(address) return int(address)
def isArmArchitecture(self): def isArmArchitecture(self):
return 'arm' in gdb.TARGET_CONFIG.lower() return 'arm' in gdb.TARGET_CONFIG.lower()
@@ -1059,7 +1059,7 @@ class Dumper(DumperBase):
def findSymbol(self, symbolName): def findSymbol(self, symbolName):
try: try:
return toInteger(gdb.parse_and_eval("(size_t)&'%s'" % symbolName)) return int(gdb.parse_and_eval("(size_t)&'%s'" % symbolName))
except: except:
return 0 return 0
@@ -1371,7 +1371,7 @@ class Dumper(DumperBase):
if typeobj.code == gdb.TYPE_CODE_PTR: if typeobj.code == gdb.TYPE_CODE_PTR:
dereftype = typeobj.target().unqualified() dereftype = typeobj.target().unqualified()
if dereftype.name == needle: if dereftype.name == needle:
addr = toInteger(value) addr = int(value)
res = None res = None
for pat in pats: for pat in pats:
try: try:

View File

@@ -26,7 +26,7 @@
import platform import platform
import struct import struct
import re import re
from dumper import Children, SubItem, UnnamedSubItem, toInteger, DumperBase from dumper import Children, SubItem, UnnamedSubItem, DumperBase
from utils import DisplayFormat, TypeCode from utils import DisplayFormat, TypeCode
@@ -3106,7 +3106,7 @@ def qdumpHelper_QJsonValue(d, data, base, pv):
if t == 2: if t == 2:
d.putType('QJsonValue (Number)') d.putType('QJsonValue (Number)')
if latinOrIntValue: if latinOrIntValue:
w = toInteger(v) w = int(v)
if w >= 0x4000000: if w >= 0x4000000:
w -= 0x8000000 w -= 0x8000000
d.putValue(w) d.putValue(w)