forked from qt-creator/qt-creator
Debugger: Prepare delayed type creation for DumperBase.Values
Change-Id: I283bcdec178e0a860bef71753cd29cc283a58391 Reviewed-by: David Schulz <david.schulz@qt.io> Reviewed-by: Christian Stenger <christian.stenger@qt.io>
This commit is contained in:
@@ -106,10 +106,10 @@ class Dumper(DumperBase):
|
|||||||
self.check(isinstance(nativeValue, cdbext.Value))
|
self.check(isinstance(nativeValue, cdbext.Value))
|
||||||
val = self.Value(self)
|
val = self.Value(self)
|
||||||
val.name = nativeValue.name()
|
val.name = nativeValue.name()
|
||||||
val.type = self.fromNativeType(nativeValue.type())
|
val._type = self.fromNativeType(nativeValue.type())
|
||||||
# There is no cdb api for the size of bitfields.
|
# There is no cdb api for the size of bitfields.
|
||||||
# Workaround this issue by parsing the native debugger text for integral types.
|
# Workaround this issue by parsing the native debugger text for integral types.
|
||||||
if val.type.code == TypeCode.Integral:
|
if val._type.code == TypeCode.Integral:
|
||||||
try:
|
try:
|
||||||
integerString = nativeValue.nativeDebuggerValue()
|
integerString = nativeValue.nativeDebuggerValue()
|
||||||
except UnicodeDecodeError:
|
except UnicodeDecodeError:
|
||||||
@@ -128,16 +128,16 @@ class Dumper(DumperBase):
|
|||||||
base = 16
|
base = 16
|
||||||
else:
|
else:
|
||||||
base = 10
|
base = 10
|
||||||
signed = not val.type.name.startswith('unsigned')
|
signed = not val._type.name.startswith('unsigned')
|
||||||
try:
|
try:
|
||||||
val.ldata = int(integerString, base).to_bytes(val.type.size(),
|
val.ldata = int(integerString, base).to_bytes(val._type.size(),
|
||||||
byteorder='little', signed=signed)
|
byteorder='little', signed=signed)
|
||||||
except:
|
except:
|
||||||
# read raw memory in case the integerString can not be interpreted
|
# read raw memory in case the integerString can not be interpreted
|
||||||
pass
|
pass
|
||||||
if val.type.code == TypeCode.Enum:
|
if val._type.code == TypeCode.Enum:
|
||||||
val.ldisplay = self.enumValue(nativeValue)
|
val.ldisplay = self.enumValue(nativeValue)
|
||||||
val.isBaseClass = val.name == val.type.name
|
val.isBaseClass = val.name == val._type.name
|
||||||
val.nativeValue = nativeValue
|
val.nativeValue = nativeValue
|
||||||
val.laddress = nativeValue.address()
|
val.laddress = nativeValue.address()
|
||||||
return val
|
return val
|
||||||
@@ -408,10 +408,10 @@ class Dumper(DumperBase):
|
|||||||
nativeType = self.lookupNativeType(typeName, module)
|
nativeType = self.lookupNativeType(typeName, module)
|
||||||
if nativeType is None:
|
if nativeType is None:
|
||||||
return None
|
return None
|
||||||
type = self.fromNativeType(nativeType)
|
_type = self.fromNativeType(nativeType)
|
||||||
if type.name != typeName:
|
if _type.name != typeName:
|
||||||
self.registerType(typeName, type.typeData())
|
self.registerType(typeName, _type.typeData())
|
||||||
return type
|
return _type
|
||||||
return self.Type(self, typeName)
|
return self.Type(self, typeName)
|
||||||
|
|
||||||
def lookupNativeType(self, name, module=0):
|
def lookupNativeType(self, name, module=0):
|
||||||
@@ -509,7 +509,7 @@ class Dumper(DumperBase):
|
|||||||
else:
|
else:
|
||||||
val = self.Value(self)
|
val = self.Value(self)
|
||||||
val.laddress = value.pointer()
|
val.laddress = value.pointer()
|
||||||
val.type = value.type.dereference()
|
val._type = value.type.dereference()
|
||||||
|
|
||||||
return val
|
return val
|
||||||
|
|
||||||
|
@@ -752,7 +752,7 @@ class DumperBase():
|
|||||||
buf = bytearray(struct.pack('i', ival))
|
buf = bytearray(struct.pack('i', ival))
|
||||||
val = self.Value(self)
|
val = self.Value(self)
|
||||||
val.ldata = bytes(buf)
|
val.ldata = bytes(buf)
|
||||||
val.type = self.createType(typish)
|
val._type = self.createType(typish)
|
||||||
with SubItem(self, name):
|
with SubItem(self, name):
|
||||||
self.putItem(val)
|
self.putItem(val)
|
||||||
|
|
||||||
@@ -2907,7 +2907,7 @@ class DumperBase():
|
|||||||
def __init__(self, dumper):
|
def __init__(self, dumper):
|
||||||
self.dumper = dumper
|
self.dumper = dumper
|
||||||
self.name = None
|
self.name = None
|
||||||
self.type = None
|
self._type = None
|
||||||
self.ldata = None # Target address in case of references and pointers.
|
self.ldata = None # Target address in case of references and pointers.
|
||||||
self.laddress = None # Own address.
|
self.laddress = None # Own address.
|
||||||
self.lvalue = None
|
self.lvalue = None
|
||||||
@@ -2924,7 +2924,7 @@ class DumperBase():
|
|||||||
val = self.dumper.Value(self.dumper)
|
val = self.dumper.Value(self.dumper)
|
||||||
val.dumper = self.dumper
|
val.dumper = self.dumper
|
||||||
val.name = self.name
|
val.name = self.name
|
||||||
val.type = self.type
|
val._type = self._type
|
||||||
val.ldata = self.ldata
|
val.ldata = self.ldata
|
||||||
val.laddress = self.laddress
|
val.laddress = self.laddress
|
||||||
val.lIsInScope = self.lIsInScope
|
val.lIsInScope = self.lIsInScope
|
||||||
@@ -2936,6 +2936,12 @@ class DumperBase():
|
|||||||
val.nativeValue = self.nativeValue
|
val.nativeValue = self.nativeValue
|
||||||
return val
|
return val
|
||||||
|
|
||||||
|
@property
|
||||||
|
def type(self):
|
||||||
|
if self._type is None and self.nativeValue is not None:
|
||||||
|
self._type = self.dumper.nativeValueType(self.nativeValue)
|
||||||
|
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 self.dumper.isInt(self.laddress):
|
||||||
raise RuntimeError('INCONSISTENT ADDRESS: %s' % type(self.laddress))
|
raise RuntimeError('INCONSISTENT ADDRESS: %s' % type(self.laddress))
|
||||||
@@ -3150,7 +3156,7 @@ class DumperBase():
|
|||||||
val = self.dumper.Value(self.dumper)
|
val = self.dumper.Value(self.dumper)
|
||||||
val.name = field.name
|
val.name = field.name
|
||||||
val.isBaseClass = field.isBase
|
val.isBaseClass = field.isBase
|
||||||
val.type = field.fieldType()
|
val._type = field.fieldType()
|
||||||
|
|
||||||
if field.isArtificial:
|
if field.isArtificial:
|
||||||
if self.laddress is not None:
|
if self.laddress is not None:
|
||||||
@@ -3244,7 +3250,7 @@ class DumperBase():
|
|||||||
val = self.dumper.Value(self.dumper)
|
val = self.dumper.Value(self.dumper)
|
||||||
val.laddress = None
|
val.laddress = None
|
||||||
val.ldata = bytes(struct.pack(self.dumper.packCode + 'Q', address))
|
val.ldata = bytes(struct.pack(self.dumper.packCode + 'Q', address))
|
||||||
val.type = self.type
|
val._type = self._type
|
||||||
return val
|
return val
|
||||||
raise RuntimeError('BAD DATA TO ADD TO: %s %s' % (self.type, other))
|
raise RuntimeError('BAD DATA TO ADD TO: %s %s' % (self.type, other))
|
||||||
|
|
||||||
@@ -3267,17 +3273,17 @@ class DumperBase():
|
|||||||
val.laddress = self.pointer()
|
val.laddress = self.pointer()
|
||||||
if val.laddress is None and self.laddress is not None:
|
if val.laddress is None and self.laddress is not None:
|
||||||
val.laddress = self.laddress
|
val.laddress = self.laddress
|
||||||
val.type = self.type.dereference()
|
val._type = self.type.dereference()
|
||||||
if self.dumper.useDynamicType:
|
if self.dumper.useDynamicType:
|
||||||
val.type = self.dumper.nativeDynamicType(val.laddress, val.type)
|
val._type = self.dumper.nativeDynamicType(val.laddress, val.type)
|
||||||
else:
|
else:
|
||||||
val = self.dumper.nativeValueDereferenceReference(self)
|
val = self.dumper.nativeValueDereferenceReference(self)
|
||||||
elif self.type.code == TypeCode.Pointer:
|
elif self.type.code == TypeCode.Pointer:
|
||||||
if self.nativeValue is None:
|
if self.nativeValue is None:
|
||||||
val.laddress = self.pointer()
|
val.laddress = self.pointer()
|
||||||
val.type = self.type.dereference()
|
val._type = self.type.dereference()
|
||||||
if self.dumper.useDynamicType:
|
if self.dumper.useDynamicType:
|
||||||
val.type = self.dumper.nativeDynamicType(val.laddress, val.type)
|
val._type = self.dumper.nativeDynamicType(val.laddress, val.type)
|
||||||
else:
|
else:
|
||||||
val = self.dumper.nativeValueDereferencePointer(self)
|
val = self.dumper.nativeValueDereferencePointer(self)
|
||||||
else:
|
else:
|
||||||
@@ -3286,7 +3292,7 @@ class DumperBase():
|
|||||||
#DumperBase.warn("DEREFERENCING TO: %s" % val)
|
#DumperBase.warn("DEREFERENCING TO: %s" % val)
|
||||||
#dynTypeName = val.type.dynamicTypeName(val.laddress)
|
#dynTypeName = val.type.dynamicTypeName(val.laddress)
|
||||||
#if dynTypeName is not None:
|
#if dynTypeName is not None:
|
||||||
# val.type = self.dumper.createType(dynTypeName)
|
# val._type = self.dumper.createType(dynTypeName)
|
||||||
return val
|
return val
|
||||||
|
|
||||||
def detypedef(self):
|
def detypedef(self):
|
||||||
@@ -3294,7 +3300,7 @@ class DumperBase():
|
|||||||
if self.type.code != TypeCode.Typedef:
|
if self.type.code != TypeCode.Typedef:
|
||||||
raise RuntimeError("WRONG")
|
raise RuntimeError("WRONG")
|
||||||
val = self.copy()
|
val = self.copy()
|
||||||
val.type = self.type.ltarget
|
val._type = self.type.ltarget
|
||||||
#DumperBase.warn("DETYPEDEF FROM: %s" % self)
|
#DumperBase.warn("DETYPEDEF FROM: %s" % self)
|
||||||
#DumperBase.warn("DETYPEDEF TO: %s" % val)
|
#DumperBase.warn("DETYPEDEF TO: %s" % val)
|
||||||
return val
|
return val
|
||||||
@@ -3323,7 +3329,7 @@ class DumperBase():
|
|||||||
val.laddress = self.laddress
|
val.laddress = self.laddress
|
||||||
val.lbitsize = self.lbitsize
|
val.lbitsize = self.lbitsize
|
||||||
val.ldata = self.ldata
|
val.ldata = self.ldata
|
||||||
val.type = self.dumper.createType(typish)
|
val._type = self.dumper.createType(typish)
|
||||||
return val
|
return val
|
||||||
|
|
||||||
def address(self):
|
def address(self):
|
||||||
@@ -3736,7 +3742,7 @@ class DumperBase():
|
|||||||
targetType = self.createType(targetTypish)
|
targetType = self.createType(targetTypish)
|
||||||
if self.useDynamicType:
|
if self.useDynamicType:
|
||||||
targetType = targetType.dynamicType(targetAddress)
|
targetType = targetType.dynamicType(targetAddress)
|
||||||
val.type = self.createPointerType(targetType)
|
val._type = self.createPointerType(targetType)
|
||||||
return val
|
return val
|
||||||
|
|
||||||
def createReferenceValue(self, targetAddress, targetType):
|
def createReferenceValue(self, targetAddress, targetType):
|
||||||
@@ -3750,7 +3756,7 @@ class DumperBase():
|
|||||||
val.ldata = self.toPointerData(targetAddress)
|
val.ldata = self.toPointerData(targetAddress)
|
||||||
if self.useDynamicType:
|
if self.useDynamicType:
|
||||||
targetType = targetType.dynamicType(targetAddress)
|
targetType = targetType.dynamicType(targetAddress)
|
||||||
val.type = self.createReferenceType(targetType)
|
val._type = self.createReferenceType(targetType)
|
||||||
return val
|
return val
|
||||||
|
|
||||||
def createPointerType(self, targetType):
|
def createPointerType(self, targetType):
|
||||||
@@ -3926,12 +3932,12 @@ 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 self.isInt(datish): # 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:
|
||||||
val.type = val.type.dynamicType(datish)
|
val._type = val.type.dynamicType(datish)
|
||||||
return val
|
return val
|
||||||
if isinstance(datish, bytes):
|
if isinstance(datish, bytes):
|
||||||
#DumperBase.warn('CREATING %s WITH DATA %s' % (val.type.name, self.hexencode(datish)))
|
#DumperBase.warn('CREATING %s WITH DATA %s' % (val.type.name, self.hexencode(datish)))
|
||||||
@@ -3947,7 +3953,7 @@ class DumperBase():
|
|||||||
tdata.code = TypeCode.Struct
|
tdata.code = TypeCode.Struct
|
||||||
self.registerType(type_name, tdata)
|
self.registerType(type_name, tdata)
|
||||||
val = self.Value(self)
|
val = self.Value(self)
|
||||||
val.type = self.Type(self, type_name)
|
val._type = self.Type(self, type_name)
|
||||||
val.ldata = proxy_data
|
val.ldata = proxy_data
|
||||||
return val
|
return val
|
||||||
|
|
||||||
|
@@ -236,6 +236,9 @@ class Dumper(DumperBase):
|
|||||||
pass
|
pass
|
||||||
return self.fromNativeValue(val)
|
return self.fromNativeValue(val)
|
||||||
|
|
||||||
|
def nativeValueType(self, nativeValue):
|
||||||
|
return self.fromNativeType(nativeValue.type)
|
||||||
|
|
||||||
def fromNativeValue(self, nativeValue):
|
def fromNativeValue(self, nativeValue):
|
||||||
#DumperBase.warn('FROM NATIVE VALUE: %s' % nativeValue)
|
#DumperBase.warn('FROM NATIVE VALUE: %s' % nativeValue)
|
||||||
self.check(isinstance(nativeValue, gdb.Value))
|
self.check(isinstance(nativeValue, gdb.Value))
|
||||||
@@ -297,7 +300,7 @@ class Dumper(DumperBase):
|
|||||||
pass
|
pass
|
||||||
val.ldata = bytes(buf)
|
val.ldata = bytes(buf)
|
||||||
|
|
||||||
val.type = self.fromNativeType(nativeType)
|
val._type = self.fromNativeType(nativeType)
|
||||||
val.lIsInScope = not nativeValue.is_optimized_out
|
val.lIsInScope = not nativeValue.is_optimized_out
|
||||||
code = nativeType.code
|
code = nativeType.code
|
||||||
if code == gdb.TYPE_CODE_ENUM:
|
if code == gdb.TYPE_CODE_ENUM:
|
||||||
@@ -496,7 +499,7 @@ class Dumper(DumperBase):
|
|||||||
if nativeMember is None:
|
if nativeMember is None:
|
||||||
val = self.Value(self)
|
val = self.Value(self)
|
||||||
val.name = fieldName
|
val.name = fieldName
|
||||||
val.type = self.fromNativeType(nativeField.type)
|
val._type = self.fromNativeType(nativeField.type)
|
||||||
val.lIsInScope = False
|
val.lIsInScope = False
|
||||||
return val
|
return val
|
||||||
val = self.fromNativeValue(nativeMember)
|
val = self.fromNativeValue(nativeMember)
|
||||||
@@ -505,7 +508,7 @@ class Dumper(DumperBase):
|
|||||||
val.lvalue = int(nativeMember)
|
val.lvalue = int(nativeMember)
|
||||||
val.laddress = None
|
val.laddress = None
|
||||||
fieldType = self.fromNativeType(nativeFieldType)
|
fieldType = self.fromNativeType(nativeFieldType)
|
||||||
val.type = self.createBitfieldType(fieldType, nativeField.bitsize)
|
val._type = self.createBitfieldType(fieldType, nativeField.bitsize)
|
||||||
val.isBaseClass = nativeField.is_base_class
|
val.isBaseClass = nativeField.is_base_class
|
||||||
val.name = fieldName
|
val.name = fieldName
|
||||||
return val
|
return val
|
||||||
|
@@ -196,7 +196,7 @@ class Dumper(DumperBase):
|
|||||||
if hasattr(nativeTargetType, 'GetCanonicalType'):
|
if hasattr(nativeTargetType, 'GetCanonicalType'):
|
||||||
nativeTargetType = nativeTargetType.GetCanonicalType()
|
nativeTargetType = nativeTargetType.GetCanonicalType()
|
||||||
val = self.fromNativeValue(nativeValue.Cast(nativeTargetType))
|
val = self.fromNativeValue(nativeValue.Cast(nativeTargetType))
|
||||||
val.type = self.fromNativeType(nativeType)
|
val._type = self.fromNativeType(nativeType)
|
||||||
#DumperBase.warn('CREATED TYPEDEF: %s' % val)
|
#DumperBase.warn('CREATED TYPEDEF: %s' % val)
|
||||||
else:
|
else:
|
||||||
val = self.Value(self)
|
val = self.Value(self)
|
||||||
@@ -215,7 +215,7 @@ class Dumper(DumperBase):
|
|||||||
except:
|
except:
|
||||||
pass
|
pass
|
||||||
|
|
||||||
val.type = self.fromNativeType(nativeType)
|
val._type = self.fromNativeType(nativeType)
|
||||||
|
|
||||||
if code == lldb.eTypeClassEnumeration:
|
if code == lldb.eTypeClassEnumeration:
|
||||||
intval = nativeValue.GetValueAsSigned()
|
intval = nativeValue.GetValueAsSigned()
|
||||||
@@ -331,7 +331,7 @@ class Dumper(DumperBase):
|
|||||||
if fieldType.GetNumberOfDirectBaseClasses() == 0:
|
if fieldType.GetNumberOfDirectBaseClasses() == 0:
|
||||||
member = self.Value(self)
|
member = self.Value(self)
|
||||||
fieldName = fieldObj.GetName()
|
fieldName = fieldObj.GetName()
|
||||||
member.type = self.fromNativeType(fieldType)
|
member._type = self.fromNativeType(fieldType)
|
||||||
member.name = fieldName
|
member.name = fieldName
|
||||||
member.fields = []
|
member.fields = []
|
||||||
if False:
|
if False:
|
||||||
|
Reference in New Issue
Block a user