forked from qt-creator/qt-creator
Debugger: Rework display length limitation systems
There are two values now, one to limit an entry in the L&E view (default 100) and a hard upper limit (at 1 mio). If displayed values are elided, the true length is shown in addition. Change-Id: I180b70446c18e258c164e5af75b88d4c8b6c53f2 Reviewed-by: hjk <hjk121@nokiamail.com>
This commit is contained in:
@@ -71,6 +71,19 @@ except:
|
|||||||
return "Normal"
|
return "Normal"
|
||||||
|
|
||||||
|
|
||||||
|
class ReportItem:
|
||||||
|
"""
|
||||||
|
Helper structure to keep temporary "best" information about a value
|
||||||
|
or a type scheduled to be reported. This might get overridden be
|
||||||
|
subsequent better guesses during a putItem() run.
|
||||||
|
"""
|
||||||
|
def __init__(self):
|
||||||
|
self.value = None
|
||||||
|
self.priority = -100
|
||||||
|
self.encoding = None
|
||||||
|
self.elided = 0
|
||||||
|
|
||||||
|
|
||||||
class Blob(object):
|
class Blob(object):
|
||||||
"""
|
"""
|
||||||
Helper structure to keep a blob of bytes, possibly
|
Helper structure to keep a blob of bytes, possibly
|
||||||
@@ -310,6 +323,7 @@ class DumperBase:
|
|||||||
# Later set, or not set:
|
# Later set, or not set:
|
||||||
# cachedQtVersion
|
# cachedQtVersion
|
||||||
self.stringCutOff = 10000
|
self.stringCutOff = 10000
|
||||||
|
self.displayStringLimit = 100
|
||||||
|
|
||||||
# This is a cache mapping from 'type name' to 'display alternatives'.
|
# This is a cache mapping from 'type name' to 'display alternatives'.
|
||||||
self.qqFormats = {}
|
self.qqFormats = {}
|
||||||
@@ -375,12 +389,11 @@ class DumperBase:
|
|||||||
# assume no Qt 3 support by default
|
# assume no Qt 3 support by default
|
||||||
return False
|
return False
|
||||||
|
|
||||||
|
# Clamps size to limit.
|
||||||
def computeLimit(self, size, limit):
|
def computeLimit(self, size, limit):
|
||||||
if limit is None:
|
if limit is None or size <= limit:
|
||||||
return size
|
return 0, size
|
||||||
if limit == 0:
|
return size, limit
|
||||||
return min(size, self.stringCutOff)
|
|
||||||
return min(size, limit)
|
|
||||||
|
|
||||||
def vectorDataHelper(self, addr):
|
def vectorDataHelper(self, addr):
|
||||||
if self.qtVersion() >= 0x050000:
|
if self.qtVersion() >= 0x050000:
|
||||||
@@ -419,53 +432,50 @@ class DumperBase:
|
|||||||
return data, size, alloc
|
return data, size, alloc
|
||||||
|
|
||||||
# addr is the begin of a QByteArrayData structure
|
# addr is the begin of a QByteArrayData structure
|
||||||
def encodeStringHelper(self, addr, limit = 0):
|
def encodeStringHelper(self, addr, limit):
|
||||||
# Should not happen, but we get it with LLDB as result
|
# Should not happen, but we get it with LLDB as result
|
||||||
# of inferior calls
|
# of inferior calls
|
||||||
if addr == 0:
|
if addr == 0:
|
||||||
return ""
|
return 0, ""
|
||||||
data, size, alloc = self.byteArrayDataHelper(addr)
|
data, size, alloc = self.byteArrayDataHelper(addr)
|
||||||
if alloc != 0:
|
if alloc != 0:
|
||||||
self.check(0 <= size and size <= alloc and alloc <= 100*1000*1000)
|
self.check(0 <= size and size <= alloc and alloc <= 100*1000*1000)
|
||||||
limit = self.computeLimit(size, limit)
|
elided, shown = self.computeLimit(size, limit)
|
||||||
s = self.readMemory(data, 2 * limit)
|
return elided, self.readMemory(data, 2 * shown)
|
||||||
if limit < size:
|
|
||||||
s += "2e002e002e00"
|
|
||||||
return s
|
|
||||||
|
|
||||||
def encodeByteArrayHelper(self, addr, limit = None):
|
def encodeByteArrayHelper(self, addr, limit):
|
||||||
data, size, alloc = self.byteArrayDataHelper(addr)
|
data, size, alloc = self.byteArrayDataHelper(addr)
|
||||||
if alloc != 0:
|
if alloc != 0:
|
||||||
self.check(0 <= size and size <= alloc and alloc <= 100*1000*1000)
|
self.check(0 <= size and size <= alloc and alloc <= 100*1000*1000)
|
||||||
limit = self.computeLimit(size, limit)
|
elided, shown = self.computeLimit(size, limit)
|
||||||
s = self.readMemory(data, limit)
|
return elided, self.readMemory(data, shown)
|
||||||
if limit < size:
|
|
||||||
s += "2e2e2e"
|
|
||||||
return s
|
|
||||||
|
|
||||||
def readMemory(self, addr, size):
|
def readMemory(self, addr, size):
|
||||||
data = self.extractBlob(addr, size).toBytes()
|
data = self.extractBlob(addr, size).toBytes()
|
||||||
return self.hexencode(data)
|
return self.hexencode(data)
|
||||||
|
|
||||||
def encodeByteArray(self, value, limit = 0):
|
def encodeByteArray(self, value, limit = 0):
|
||||||
return self.encodeByteArrayHelper(self.extractPointer(value), limit)
|
elided, data = self.encodeByteArrayHelper(self.extractPointer(value), limit)
|
||||||
|
return data
|
||||||
|
|
||||||
def byteArrayData(self, value):
|
def byteArrayData(self, value):
|
||||||
return self.byteArrayDataHelper(self.extractPointer(value))
|
return self.byteArrayDataHelper(self.extractPointer(value))
|
||||||
|
|
||||||
def putByteArrayValue(self, value):
|
def putByteArrayValue(self, value):
|
||||||
return self.putValue(self.encodeByteArray(value, self.stringCutOff), Hex2EncodedLatin1)
|
elided, data = self.encodeByteArrayHelper(self.extractPointer(value), self.displayStringLimit)
|
||||||
|
self.putValue(data, Hex2EncodedLatin1, elided=elided)
|
||||||
|
|
||||||
def putByteArrayValueByAddress(self, addr):
|
def putByteArrayValueByAddress(self, addr):
|
||||||
self.putValue(self.encodeByteArrayHelper(self.extractPointer(addr)),
|
elided, data = self.encodeByteArrayHelper(addr, self.displayStringLimit)
|
||||||
Hex2EncodedLatin1)
|
self.putValue(data, Hex2EncodedLatin1, elided=elided)
|
||||||
|
|
||||||
def putStringValueByAddress(self, addr):
|
def putStringValueByAddress(self, addr):
|
||||||
self.putValue(self.encodeStringHelper(self.extractPointer(addr)),
|
elided, data = self.encodeStringHelper(self.extractPointer(addr), self.displayStringLimit)
|
||||||
Hex4EncodedLittleEndian)
|
self.putValue(data, Hex4EncodedLittleEndian, elided=elided)
|
||||||
|
|
||||||
def encodeString(self, value, limit = 0):
|
def encodeString(self, value, limit = 0):
|
||||||
return self.encodeStringHelper(self.extractPointer(value), limit)
|
elided, data = self.encodeStringHelper(self.extractPointer(value), limit)
|
||||||
|
return data
|
||||||
|
|
||||||
def stringData(self, value):
|
def stringData(self, value):
|
||||||
return self.byteArrayDataHelper(self.extractPointer(value))
|
return self.byteArrayDataHelper(self.extractPointer(value))
|
||||||
@@ -499,7 +509,8 @@ class DumperBase:
|
|||||||
return inner.strip()
|
return inner.strip()
|
||||||
|
|
||||||
def putStringValue(self, value):
|
def putStringValue(self, value):
|
||||||
return self.putValue(self.encodeString(value, self.stringCutOff), Hex4EncodedLittleEndian)
|
elided, data = self.encodeStringHelper(self.extractPointer(value), self.displayStringLimit)
|
||||||
|
self.putValue(data, Hex4EncodedLittleEndian, elided=elided)
|
||||||
|
|
||||||
def putAddressItem(self, name, value, type = ""):
|
def putAddressItem(self, name, value, type = ""):
|
||||||
with SubItem(self, name):
|
with SubItem(self, name):
|
||||||
@@ -619,27 +630,16 @@ class DumperBase:
|
|||||||
def findFirstZero(self, p, maximum):
|
def findFirstZero(self, p, maximum):
|
||||||
for i in xrange(maximum):
|
for i in xrange(maximum):
|
||||||
if int(p.dereference()) == 0:
|
if int(p.dereference()) == 0:
|
||||||
return i
|
return 0, i
|
||||||
p = p + 1
|
p = p + 1
|
||||||
return maximum + 1
|
# Real end is unknown.
|
||||||
|
return -1, maximum
|
||||||
|
|
||||||
def encodeCArray(self, p, innerType, suffix):
|
def encodeCArray(self, p, innerType, limit):
|
||||||
t = self.lookupType(innerType)
|
t = self.lookupType(innerType)
|
||||||
p = p.cast(t.pointer())
|
p = p.cast(t.pointer())
|
||||||
limit = self.findFirstZero(p, self.stringCutOff)
|
elided, shown = self.findFirstZero(p, limit)
|
||||||
s = self.readMemory(p, limit * t.sizeof)
|
return elided, self.readMemory(p, shown * t.sizeof)
|
||||||
if limit > self.stringCutOff:
|
|
||||||
s += suffix
|
|
||||||
return s
|
|
||||||
|
|
||||||
def encodeCharArray(self, p):
|
|
||||||
return self.encodeCArray(p, "unsigned char", "2e2e2e")
|
|
||||||
|
|
||||||
def encodeChar2Array(self, p):
|
|
||||||
return self.encodeCArray(p, "unsigned short", "2e002e002e00")
|
|
||||||
|
|
||||||
def encodeChar4Array(self, p):
|
|
||||||
return self.encodeCArray(p, "unsigned int", "2e0000002e0000002e000000")
|
|
||||||
|
|
||||||
def putItemCount(self, count, maximum = 1000000000):
|
def putItemCount(self, count, maximum = 1000000000):
|
||||||
# This needs to override the default value, so don't use 'put' directly.
|
# This needs to override the default value, so don't use 'put' directly.
|
||||||
@@ -654,26 +654,34 @@ class DumperBase:
|
|||||||
|
|
||||||
def putType(self, type, priority = 0):
|
def putType(self, type, priority = 0):
|
||||||
# Higher priority values override lower ones.
|
# Higher priority values override lower ones.
|
||||||
if priority >= self.currentTypePriority:
|
if priority >= self.currentType.priority:
|
||||||
self.currentType = str(type)
|
self.currentType.value = str(type)
|
||||||
self.currentTypePriority = priority
|
self.currentType.priority = priority
|
||||||
|
|
||||||
def putValue(self, value, encoding = None, priority = 0):
|
def putValue(self, value, encoding = None, priority = 0, elided = None):
|
||||||
# Higher priority values override lower ones.
|
# Higher priority values override lower ones.
|
||||||
if priority >= self.currentValuePriority:
|
# elided = 0 indicates all data is available in value,
|
||||||
self.currentValue = value
|
# otherwise it's the true length.
|
||||||
self.currentValuePriority = priority
|
if priority >= self.currentValue.priority:
|
||||||
self.currentValueEncoding = encoding
|
self.currentValue.value = value
|
||||||
|
self.currentValue.priority = priority
|
||||||
|
self.currentValue.encoding = encoding
|
||||||
|
self.currentValue.elided = elided
|
||||||
|
|
||||||
def putEmptyValue(self, priority = -10):
|
def putEmptyValue(self, priority = -10):
|
||||||
if priority >= self.currentValuePriority:
|
if priority >= self.currentValue.priority:
|
||||||
self.currentValue = ""
|
self.currentValue.value = ""
|
||||||
self.currentValuePriority = priority
|
self.currentValue.priority = priority
|
||||||
self.currentValueEncoding = None
|
self.currentValue.encoding = None
|
||||||
|
self.currentValue.elided = None
|
||||||
|
|
||||||
def putName(self, name):
|
def putName(self, name):
|
||||||
self.put('name="%s",' % name)
|
self.put('name="%s",' % name)
|
||||||
|
|
||||||
|
def putBetterType(self, type):
|
||||||
|
self.currentType.value = str(type)
|
||||||
|
self.currentType.priority += 1
|
||||||
|
|
||||||
def putNoType(self):
|
def putNoType(self):
|
||||||
# FIXME: replace with something that does not need special handling
|
# FIXME: replace with something that does not need special handling
|
||||||
# in SubItem.__exit__().
|
# in SubItem.__exit__().
|
||||||
@@ -682,7 +690,7 @@ class DumperBase:
|
|||||||
def putInaccessible(self):
|
def putInaccessible(self):
|
||||||
#self.putBetterType(" ")
|
#self.putBetterType(" ")
|
||||||
self.putNumChild(0)
|
self.putNumChild(0)
|
||||||
self.currentValue = None
|
self.currentValue.value = None
|
||||||
|
|
||||||
def putNamedSubItem(self, component, value, name):
|
def putNamedSubItem(self, component, value, name):
|
||||||
with SubItem(self, component):
|
with SubItem(self, component):
|
||||||
@@ -805,7 +813,8 @@ class DumperBase:
|
|||||||
if format == None and innerTypeName == "char":
|
if format == None and innerTypeName == "char":
|
||||||
# Use Latin1 as default for char *.
|
# Use Latin1 as default for char *.
|
||||||
self.putType(typeName)
|
self.putType(typeName)
|
||||||
self.putValue(self.encodeCharArray(value), Hex2EncodedLatin1)
|
(elided, data) = self.encodeCArray(value, "unsigned char", self.displayStringLimit)
|
||||||
|
self.putValue(data, Hex2EncodedLatin1, elided=elided)
|
||||||
self.putNumChild(0)
|
self.putNumChild(0)
|
||||||
return
|
return
|
||||||
|
|
||||||
@@ -823,35 +832,40 @@ class DumperBase:
|
|||||||
if format == Latin1StringFormat:
|
if format == Latin1StringFormat:
|
||||||
# Explicitly requested Latin1 formatting.
|
# Explicitly requested Latin1 formatting.
|
||||||
self.putType(typeName)
|
self.putType(typeName)
|
||||||
self.putValue(self.encodeCharArray(value), Hex2EncodedLatin1)
|
(elided, data) = self.encodeCArray(value, "unsigned char", self.displayStringLimit)
|
||||||
|
self.putValue(data, Hex2EncodedLatin1, elided=elided)
|
||||||
self.putNumChild(0)
|
self.putNumChild(0)
|
||||||
return
|
return
|
||||||
|
|
||||||
if format == Utf8StringFormat:
|
if format == Utf8StringFormat:
|
||||||
# Explicitly requested UTF-8 formatting.
|
# Explicitly requested UTF-8 formatting.
|
||||||
self.putType(typeName)
|
self.putType(typeName)
|
||||||
self.putValue(self.encodeCharArray(value), Hex2EncodedUtf8)
|
(elided, data) = self.encodeCArray(value, "unsigned char", self.displayStringLimit)
|
||||||
|
self.putValue(data, Hex2EncodedUtf8, elided=elided)
|
||||||
self.putNumChild(0)
|
self.putNumChild(0)
|
||||||
return
|
return
|
||||||
|
|
||||||
if format == Local8BitStringFormat:
|
if format == Local8BitStringFormat:
|
||||||
# Explicitly requested local 8 bit formatting.
|
# Explicitly requested local 8 bit formatting.
|
||||||
self.putType(typeName)
|
self.putType(typeName)
|
||||||
self.putValue(self.encodeCharArray(value), Hex2EncodedLocal8Bit)
|
(elided, data) = self.encodeCArray(value, "unsigned char", self.displayStringLimit)
|
||||||
|
self.putValue(data, Hex2EncodedLocal8Bit, elided=elided)
|
||||||
self.putNumChild(0)
|
self.putNumChild(0)
|
||||||
return
|
return
|
||||||
|
|
||||||
if format == Utf16StringFormat:
|
if format == Utf16StringFormat:
|
||||||
# Explicitly requested UTF-16 formatting.
|
# Explicitly requested UTF-16 formatting.
|
||||||
self.putType(typeName)
|
self.putType(typeName)
|
||||||
self.putValue(self.encodeChar2Array(value), Hex4EncodedLittleEndian)
|
(elided, data) = self.encodeCArray(value, "unsigned short", self.displayStringLimit)
|
||||||
|
self.putValue(data, Hex4EncodedLittleEndian, elided=elided)
|
||||||
self.putNumChild(0)
|
self.putNumChild(0)
|
||||||
return
|
return
|
||||||
|
|
||||||
if format == Ucs4StringFormat:
|
if format == Ucs4StringFormat:
|
||||||
# Explicitly requested UCS-4 formatting.
|
# Explicitly requested UCS-4 formatting.
|
||||||
self.putType(typeName)
|
self.putType(typeName)
|
||||||
self.putValue(self.encodeChar4Array(value), Hex8EncodedLittleEndian)
|
(elided, data) = self.encodeCArray(value, "unsigned int", self.displayStringLimit)
|
||||||
|
self.putValue(data, Hex8EncodedLittleEndian, elided=elided)
|
||||||
self.putNumChild(0)
|
self.putNumChild(0)
|
||||||
return
|
return
|
||||||
|
|
||||||
@@ -1226,7 +1240,7 @@ class DumperBase:
|
|||||||
format = self.formats.get(self.currentIName)
|
format = self.formats.get(self.currentIName)
|
||||||
if format is None:
|
if format is None:
|
||||||
if type is None:
|
if type is None:
|
||||||
type = self.currentType
|
type = self.currentType.value
|
||||||
needle = self.stripForFormat(str(type))
|
needle = self.stripForFormat(str(type))
|
||||||
format = self.typeformats.get(needle)
|
format = self.typeformats.get(needle)
|
||||||
return format
|
return format
|
||||||
@@ -1256,8 +1270,8 @@ class DumperBase:
|
|||||||
if not hasPlot():
|
if not hasPlot():
|
||||||
return
|
return
|
||||||
if not self.isSimpleType(typeobj):
|
if not self.isSimpleType(typeobj):
|
||||||
#self.putValue(self.currentValue + " (not plottable)")
|
#self.putValue(self.currentValue.value + " (not plottable)")
|
||||||
self.putValue(self.currentValue)
|
self.putValue(self.currentValue.value)
|
||||||
self.putField("plottable", "0")
|
self.putField("plottable", "0")
|
||||||
return
|
return
|
||||||
global gnuplotPipe
|
global gnuplotPipe
|
||||||
@@ -1435,8 +1449,8 @@ class DumperBase:
|
|||||||
value = self.parseAndEvaluate(exp)
|
value = self.parseAndEvaluate(exp)
|
||||||
self.putItem(value)
|
self.putItem(value)
|
||||||
except RuntimeError:
|
except RuntimeError:
|
||||||
self.currentType = " "
|
self.currentType.value = " "
|
||||||
self.currentValue = "<no such value>"
|
self.currentValue.value = "<no such value>"
|
||||||
self.currentChildNumChild = -1
|
self.currentChildNumChild = -1
|
||||||
self.currentNumChild = 0
|
self.currentNumChild = 0
|
||||||
self.putNumChild(0)
|
self.putNumChild(0)
|
||||||
|
|||||||
@@ -367,11 +367,8 @@ class Dumper(DumperBase):
|
|||||||
self.currentChildNumChild = -1
|
self.currentChildNumChild = -1
|
||||||
self.currentMaxNumChild = -1
|
self.currentMaxNumChild = -1
|
||||||
self.currentNumChild = -1
|
self.currentNumChild = -1
|
||||||
self.currentValue = None
|
self.currentValue = ReportItem()
|
||||||
self.currentValuePriority = -100
|
self.currentType = ReportItem()
|
||||||
self.currentValueEncoding = None
|
|
||||||
self.currentType = None
|
|
||||||
self.currentTypePriority = -100
|
|
||||||
self.currentAddress = None
|
self.currentAddress = None
|
||||||
self.typeformats = {}
|
self.typeformats = {}
|
||||||
self.formats = {}
|
self.formats = {}
|
||||||
@@ -402,6 +399,8 @@ class Dumper(DumperBase):
|
|||||||
self.expandedINames = set(arg[pos:].split(","))
|
self.expandedINames = set(arg[pos:].split(","))
|
||||||
elif arg.startswith("stringcutoff:"):
|
elif arg.startswith("stringcutoff:"):
|
||||||
self.stringCutOff = int(arg[pos:])
|
self.stringCutOff = int(arg[pos:])
|
||||||
|
elif arg.startswith("displaystringlimit:"):
|
||||||
|
self.displayStringLimit = int(arg[pos:])
|
||||||
elif arg.startswith("typeformats:"):
|
elif arg.startswith("typeformats:"):
|
||||||
for f in arg[pos:].split(","):
|
for f in arg[pos:].split(","):
|
||||||
pos = f.find("=")
|
pos = f.find("=")
|
||||||
@@ -525,39 +524,39 @@ class Dumper(DumperBase):
|
|||||||
self.put('name="%s",' % item.name)
|
self.put('name="%s",' % item.name)
|
||||||
item.savedIName = self.currentIName
|
item.savedIName = self.currentIName
|
||||||
item.savedValue = self.currentValue
|
item.savedValue = self.currentValue
|
||||||
item.savedValuePriority = self.currentValuePriority
|
|
||||||
item.savedValueEncoding = self.currentValueEncoding
|
|
||||||
item.savedType = self.currentType
|
item.savedType = self.currentType
|
||||||
item.savedTypePriority = self.currentTypePriority
|
|
||||||
item.savedCurrentAddress = self.currentAddress
|
item.savedCurrentAddress = self.currentAddress
|
||||||
self.currentIName = item.iname
|
self.currentIName = item.iname
|
||||||
self.currentValuePriority = -100
|
self.currentValue = ReportItem();
|
||||||
self.currentValueEncoding = None
|
self.currentType = ReportItem();
|
||||||
self.currentType = ""
|
|
||||||
self.currentTypePriority = -100
|
|
||||||
self.currentAddress = None
|
self.currentAddress = None
|
||||||
|
|
||||||
def exitSubItem(self, item, exType, exValue, exTraceBack):
|
def exitSubItem(self, item, exType, exValue, exTraceBack):
|
||||||
#warn(" CURRENT VALUE: %s %s %s" % (self.currentValue,
|
#warn("CURRENT VALUE: %s: %s %s %s %s" % (
|
||||||
# self.currentValueEncoding, self.currentValuePriority))
|
# self.currentIName,
|
||||||
|
# self.currentValue.value,
|
||||||
|
# self.currentValue.elided,
|
||||||
|
# self.currentValue.encoding,
|
||||||
|
# self.currentValue.priority))
|
||||||
if not exType is None:
|
if not exType is None:
|
||||||
if self.passExceptions:
|
if self.passExceptions:
|
||||||
showException("SUBITEM", exType, exValue, exTraceBack)
|
showException("SUBITEM", exType, exValue, exTraceBack)
|
||||||
self.putNumChild(0)
|
self.putNumChild(0)
|
||||||
self.putValue("<not accessible>")
|
self.putValue("<not accessible>")
|
||||||
try:
|
try:
|
||||||
#warn("TYPE VALUE: %s" % self.currentValue)
|
#warn("CURRENT TYPE: %s" % self.currentType.value)
|
||||||
typeName = stripClassTag(self.currentType)
|
typeName = stripClassTag(self.currentType.value)
|
||||||
#warn("TYPE: '%s' DEFAULT: '%s' % (typeName, self.currentChildType))
|
|
||||||
|
|
||||||
if len(typeName) > 0 and typeName != self.currentChildType:
|
if len(typeName) > 0 and typeName != self.currentChildType:
|
||||||
self.put('type="%s",' % typeName) # str(type.unqualified()) ?
|
self.put('type="%s",' % typeName) # str(type.unqualified()) ?
|
||||||
if self.currentValue is None:
|
if self.currentValue.value is None:
|
||||||
self.put('value="<not accessible>",numchild="0",')
|
self.put('value="<not accessible>",numchild="0",')
|
||||||
else:
|
else:
|
||||||
if not self.currentValueEncoding is None:
|
if not self.currentValue.encoding is None:
|
||||||
self.put('valueencoded="%d",' % self.currentValueEncoding)
|
self.put('valueencoded="%d",' % self.currentValue.encoding)
|
||||||
self.put('value="%s",' % self.currentValue)
|
if self.currentValue.elided:
|
||||||
|
self.put('valueelided="%d",' % self.currentValue.elided)
|
||||||
|
self.put('value="%s",' % self.currentValue.value)
|
||||||
except:
|
except:
|
||||||
pass
|
pass
|
||||||
if not self.currentAddress is None:
|
if not self.currentAddress is None:
|
||||||
@@ -565,10 +564,7 @@ class Dumper(DumperBase):
|
|||||||
self.put('},')
|
self.put('},')
|
||||||
self.currentIName = item.savedIName
|
self.currentIName = item.savedIName
|
||||||
self.currentValue = item.savedValue
|
self.currentValue = item.savedValue
|
||||||
self.currentValuePriority = item.savedValuePriority
|
|
||||||
self.currentValueEncoding = item.savedValueEncoding
|
|
||||||
self.currentType = item.savedType
|
self.currentType = item.savedType
|
||||||
self.currentTypePriority = item.savedTypePriority
|
|
||||||
self.currentAddress = item.savedCurrentAddress
|
self.currentAddress = item.savedCurrentAddress
|
||||||
return True
|
return True
|
||||||
|
|
||||||
@@ -888,10 +884,6 @@ class Dumper(DumperBase):
|
|||||||
self.isQt3Support = lambda: self.cachedIsQt3Suport
|
self.isQt3Support = lambda: self.cachedIsQt3Suport
|
||||||
return self.cachedIsQt3Suport
|
return self.cachedIsQt3Suport
|
||||||
|
|
||||||
def putBetterType(self, type):
|
|
||||||
self.currentType = str(type)
|
|
||||||
self.currentTypePriority = self.currentTypePriority + 1
|
|
||||||
|
|
||||||
def putAddress(self, addr):
|
def putAddress(self, addr):
|
||||||
if self.currentPrintsAddress:
|
if self.currentPrintsAddress:
|
||||||
try:
|
try:
|
||||||
|
|||||||
@@ -261,11 +261,8 @@ class Dumper(DumperBase):
|
|||||||
self.typeformats = {}
|
self.typeformats = {}
|
||||||
|
|
||||||
self.currentIName = None
|
self.currentIName = None
|
||||||
self.currentValuePriority = -100
|
self.currentValue = ReportItem()
|
||||||
self.currentValueEncoding = None
|
self.currentType = ReportItem()
|
||||||
self.currentType = ""
|
|
||||||
self.currentTypePriority = -100
|
|
||||||
self.currentValue = None
|
|
||||||
self.currentNumChild = None
|
self.currentNumChild = None
|
||||||
self.currentMaxNumChild = None
|
self.currentMaxNumChild = None
|
||||||
self.currentPrintsAddress = None
|
self.currentPrintsAddress = None
|
||||||
@@ -310,15 +307,10 @@ class Dumper(DumperBase):
|
|||||||
self.put('name="%s",' % item.name)
|
self.put('name="%s",' % item.name)
|
||||||
item.savedIName = self.currentIName
|
item.savedIName = self.currentIName
|
||||||
item.savedValue = self.currentValue
|
item.savedValue = self.currentValue
|
||||||
item.savedValuePriority = self.currentValuePriority
|
|
||||||
item.savedValueEncoding = self.currentValueEncoding
|
|
||||||
item.savedType = self.currentType
|
item.savedType = self.currentType
|
||||||
item.savedTypePriority = self.currentTypePriority
|
|
||||||
self.currentIName = item.iname
|
self.currentIName = item.iname
|
||||||
self.currentValuePriority = -100
|
self.currentValue = ReportItem()
|
||||||
self.currentValueEncoding = None
|
self.currentType = ReportItem()
|
||||||
self.currentType = ""
|
|
||||||
self.currentTypePriority = -100
|
|
||||||
|
|
||||||
def exitSubItem(self, item, exType, exValue, exTraceBack):
|
def exitSubItem(self, item, exType, exValue, exTraceBack):
|
||||||
if not exType is None:
|
if not exType is None:
|
||||||
@@ -327,24 +319,23 @@ class Dumper(DumperBase):
|
|||||||
self.putNumChild(0)
|
self.putNumChild(0)
|
||||||
self.putValue("<not accessible>")
|
self.putValue("<not accessible>")
|
||||||
try:
|
try:
|
||||||
typeName = self.currentType
|
typeName = self.currentType.value
|
||||||
if len(typeName) > 0 and typeName != self.currentChildType:
|
if len(typeName) > 0 and typeName != self.currentChildType:
|
||||||
self.put('type="%s",' % typeName) # str(type.unqualified()) ?
|
self.put('type="%s",' % typeName) # str(type.unqualified()) ?
|
||||||
if self.currentValue is None:
|
if self.currentValue.value is None:
|
||||||
self.put('value="<not accessible>",numchild="0",')
|
self.put('value="<not accessible>",numchild="0",')
|
||||||
else:
|
else:
|
||||||
if not self.currentValueEncoding is None:
|
if not self.currentValue.encoding is None:
|
||||||
self.put('valueencoded="%s",' % self.currentValueEncoding)
|
self.put('valueencoded="%s",' % self.currentValue.encoding)
|
||||||
self.put('value="%s",' % self.currentValue)
|
if self.currentValue.elided:
|
||||||
|
self.put('valueelided="%s",' % self.currentValue.elided)
|
||||||
|
self.put('value="%s",' % self.currentValue.value)
|
||||||
except:
|
except:
|
||||||
pass
|
pass
|
||||||
self.put('},')
|
self.put('},')
|
||||||
self.currentIName = item.savedIName
|
self.currentIName = item.savedIName
|
||||||
self.currentValue = item.savedValue
|
self.currentValue = item.savedValue
|
||||||
self.currentValuePriority = item.savedValuePriority
|
|
||||||
self.currentValueEncoding = item.savedValueEncoding
|
|
||||||
self.currentType = item.savedType
|
self.currentType = item.savedType
|
||||||
self.currentTypePriority = item.savedTypePriority
|
|
||||||
return True
|
return True
|
||||||
|
|
||||||
def isSimpleType(self, typeobj):
|
def isSimpleType(self, typeobj):
|
||||||
@@ -856,14 +847,6 @@ class Dumper(DumperBase):
|
|||||||
def reportStackTop(self):
|
def reportStackTop(self):
|
||||||
self.report('stack-top={}')
|
self.report('stack-top={}')
|
||||||
|
|
||||||
def putBetterType(self, type):
|
|
||||||
try:
|
|
||||||
self.currentType = type.GetName()
|
|
||||||
except:
|
|
||||||
self.currentType = str(type)
|
|
||||||
self.currentTypePriority = self.currentTypePriority + 1
|
|
||||||
#warn("BETTER TYPE: %s PRIORITY: %s" % (type, self.currentTypePriority))
|
|
||||||
|
|
||||||
def extractBlob(self, base, size):
|
def extractBlob(self, base, size):
|
||||||
if size == 0:
|
if size == 0:
|
||||||
return Blob("")
|
return Blob("")
|
||||||
|
|||||||
@@ -274,7 +274,7 @@ def qdump__QDateTime(d, value):
|
|||||||
tz = ""
|
tz = ""
|
||||||
else:
|
else:
|
||||||
idBase = tzp + 2 * d.ptrSize() # [QSharedData] + [vptr]
|
idBase = tzp + 2 * d.ptrSize() # [QSharedData] + [vptr]
|
||||||
tz = d.encodeByteArrayHelper(d.extractPointer(idBase))
|
tz = d.encodeByteArrayHelper(d.extractPointer(idBase), limit=100)
|
||||||
d.putValue("%s/%s/%s/%s/%s" % (msecs, spec, offset, tz, status),
|
d.putValue("%s/%s/%s/%s/%s" % (msecs, spec, offset, tz, status),
|
||||||
DateTimeInternal)
|
DateTimeInternal)
|
||||||
else:
|
else:
|
||||||
@@ -705,7 +705,7 @@ def qdump__QHostAddress(d, value):
|
|||||||
ipStringAddress = privAddress + (0 if isQt5 else 24)
|
ipStringAddress = privAddress + (0 if isQt5 else 24)
|
||||||
isParsedAddress = privAddress + 24 + 2 * sizeofQString
|
isParsedAddress = privAddress + 24 + 2 * sizeofQString
|
||||||
# value.d.d->ipString
|
# value.d.d->ipString
|
||||||
ipString = d.encodeStringHelper(d.extractPointer(ipStringAddress))
|
ipString = d.encodeStringHelper(d.extractPointer(ipStringAddress), limit=100)
|
||||||
if d.extractByte(isParsedAddress) and len(ipString) > 0:
|
if d.extractByte(isParsedAddress) and len(ipString) > 0:
|
||||||
d.putValue(ipString, Hex4EncodedLittleEndian)
|
d.putValue(ipString, Hex4EncodedLittleEndian)
|
||||||
else:
|
else:
|
||||||
@@ -720,7 +720,7 @@ def qdump__QHostAddress(d, value):
|
|||||||
data = d.readMemory(privAddress + a6Offset, 16)
|
data = d.readMemory(privAddress + a6Offset, 16)
|
||||||
address = ':'.join("%x" % int(data[i:i+4], 16) for i in xrange(0, 32, 4))
|
address = ':'.join("%x" % int(data[i:i+4], 16) for i in xrange(0, 32, 4))
|
||||||
scopeId = privAddress + sizeofQString + (0 if isQt5 else 24)
|
scopeId = privAddress + sizeofQString + (0 if isQt5 else 24)
|
||||||
scopeId = d.encodeStringHelper(d.extractPointer(scopeId))
|
scopeId = d.encodeStringHelper(d.extractPointer(scopeId), limit=100)
|
||||||
d.putValue("%s%%%s" % (address, scopeId), IPv6AddressAndHexScopeId)
|
d.putValue("%s%%%s" % (address, scopeId), IPv6AddressAndHexScopeId)
|
||||||
elif proto == 0:
|
elif proto == 0:
|
||||||
# value.d.d->a
|
# value.d.d->a
|
||||||
@@ -1730,7 +1730,7 @@ def qdump__QString(d, value):
|
|||||||
d.putDisplay(StopDisplay)
|
d.putDisplay(StopDisplay)
|
||||||
elif format == 2:
|
elif format == 2:
|
||||||
d.putField("editformat", DisplayUtf16String)
|
d.putField("editformat", DisplayUtf16String)
|
||||||
d.putField("editvalue", d.encodeString(value))
|
d.putField("editvalue", d.encodeString(value, limit=None))
|
||||||
|
|
||||||
|
|
||||||
def qdump__QStringRef(d, value):
|
def qdump__QStringRef(d, value):
|
||||||
@@ -1759,7 +1759,7 @@ def qdump__QTemporaryFile(d, value):
|
|||||||
|
|
||||||
def qdump__QTextCodec(d, value):
|
def qdump__QTextCodec(d, value):
|
||||||
name = d.call(value, "name")
|
name = d.call(value, "name")
|
||||||
d.putValue(d.encodeByteArray(d, name), 6)
|
d.putValue(d.encodeByteArray(name, limit=100), 6)
|
||||||
d.putNumChild(2)
|
d.putNumChild(2)
|
||||||
if d.isExpanded():
|
if d.isExpanded():
|
||||||
with Children(d):
|
with Children(d):
|
||||||
@@ -1843,13 +1843,13 @@ def qdump__QUrl(d, value):
|
|||||||
d.putValue("<invalid>")
|
d.putValue("<invalid>")
|
||||||
return
|
return
|
||||||
schemeAddr = privAddress + 2 * d.intSize()
|
schemeAddr = privAddress + 2 * d.intSize()
|
||||||
scheme = d.encodeStringHelper(d.extractPointer(schemeAddr))
|
scheme = d.encodeStringHelper(d.extractPointer(schemeAddr), limit=1000)
|
||||||
userName = d.encodeStringHelper(d.extractPointer(schemeAddr + 1 * d.ptrSize()))
|
userName = d.encodeStringHelper(d.extractPointer(schemeAddr + 1 * d.ptrSize()), limit=100)
|
||||||
password = d.encodeStringHelper(d.extractPointer(schemeAddr + 2 * d.ptrSize()))
|
password = d.encodeStringHelper(d.extractPointer(schemeAddr + 2 * d.ptrSize()), limit=100)
|
||||||
host = d.encodeStringHelper(d.extractPointer(schemeAddr + 3 * d.ptrSize()))
|
host = d.encodeStringHelper(d.extractPointer(schemeAddr + 3 * d.ptrSize()), limit=100)
|
||||||
path = d.encodeStringHelper(d.extractPointer(schemeAddr + 4 * d.ptrSize()))
|
path = d.encodeStringHelper(d.extractPointer(schemeAddr + 4 * d.ptrSize()), limit=1000)
|
||||||
query = d.encodeStringHelper(d.extractPointer(schemeAddr + 5 * d.ptrSize()))
|
query = d.encodeStringHelper(d.extractPointer(schemeAddr + 5 * d.ptrSize()), limit=10000)
|
||||||
fragment = d.encodeStringHelper(d.extractPointer(schemeAddr + 6 * d.ptrSize()))
|
fragment = d.encodeStringHelper(d.extractPointer(schemeAddr + 6 * d.ptrSize()), limit=10000)
|
||||||
port = d.extractInt(d.extractPointer(value) + d.intSize())
|
port = d.extractInt(d.extractPointer(value) + d.intSize())
|
||||||
|
|
||||||
url = scheme
|
url = scheme
|
||||||
|
|||||||
@@ -418,10 +418,8 @@ def qdump__std__stringHelper1__QNX(d, value, charSize):
|
|||||||
qdump_stringHelper(d, sizePtr, size * charSize, charSize)
|
qdump_stringHelper(d, sizePtr, size * charSize, charSize)
|
||||||
|
|
||||||
def qdump_stringHelper(d, data, size, charSize):
|
def qdump_stringHelper(d, data, size, charSize):
|
||||||
cutoff = min(size, d.stringCutOff)
|
elided, shown = d.computeLimit(size, d.displayStringLimit)
|
||||||
mem = d.readMemory(data, cutoff)
|
mem = d.readMemory(data, shown)
|
||||||
if size > d.stringCutOff:
|
|
||||||
mem += "2e2e2e"
|
|
||||||
if charSize == 1:
|
if charSize == 1:
|
||||||
encodingType = Hex2EncodedLatin1
|
encodingType = Hex2EncodedLatin1
|
||||||
displayType = DisplayLatin1String
|
displayType = DisplayLatin1String
|
||||||
@@ -433,7 +431,7 @@ def qdump_stringHelper(d, data, size, charSize):
|
|||||||
displayType = DisplayUtf16String
|
displayType = DisplayUtf16String
|
||||||
|
|
||||||
d.putNumChild(0)
|
d.putNumChild(0)
|
||||||
d.putValue(mem, encodingType)
|
d.putValue(mem, encodingType, elided=elided)
|
||||||
|
|
||||||
format = d.currentItemFormat()
|
format = d.currentItemFormat()
|
||||||
if format == 1:
|
if format == 1:
|
||||||
|
|||||||
@@ -121,6 +121,14 @@ CommonOptionsPageWidget::CommonOptionsPageWidget
|
|||||||
spinBoxMaximalStringLength->setSingleStep(1000);
|
spinBoxMaximalStringLength->setSingleStep(1000);
|
||||||
spinBoxMaximalStringLength->setValue(10000);
|
spinBoxMaximalStringLength->setValue(10000);
|
||||||
|
|
||||||
|
labelDisplayStringLimit = new QLabel(tr("Display string limit:"), behaviorBox);
|
||||||
|
|
||||||
|
spinBoxDisplayStringLimit = new QSpinBox(behaviorBox);
|
||||||
|
spinBoxDisplayStringLimit->setSpecialValueText(tr("<unlimited>"));
|
||||||
|
spinBoxDisplayStringLimit->setMaximum(10000);
|
||||||
|
spinBoxDisplayStringLimit->setSingleStep(10);
|
||||||
|
spinBoxDisplayStringLimit->setValue(100);
|
||||||
|
|
||||||
sourcesMappingWidget = new DebuggerSourcePathMappingWidget(this);
|
sourcesMappingWidget = new DebuggerSourcePathMappingWidget(this);
|
||||||
|
|
||||||
QHBoxLayout *horizontalLayout = new QHBoxLayout();
|
QHBoxLayout *horizontalLayout = new QHBoxLayout();
|
||||||
@@ -128,6 +136,11 @@ CommonOptionsPageWidget::CommonOptionsPageWidget
|
|||||||
horizontalLayout->addWidget(spinBoxMaximalStackDepth);
|
horizontalLayout->addWidget(spinBoxMaximalStackDepth);
|
||||||
horizontalLayout->addStretch();
|
horizontalLayout->addStretch();
|
||||||
|
|
||||||
|
QHBoxLayout *horizontalLayout1 = new QHBoxLayout();
|
||||||
|
horizontalLayout1->addWidget(labelDisplayStringLimit);
|
||||||
|
horizontalLayout1->addWidget(spinBoxDisplayStringLimit);
|
||||||
|
horizontalLayout1->addStretch();
|
||||||
|
|
||||||
QHBoxLayout *horizontalLayout2 = new QHBoxLayout();
|
QHBoxLayout *horizontalLayout2 = new QHBoxLayout();
|
||||||
horizontalLayout2->addWidget(labelMaximalStringLength);
|
horizontalLayout2->addWidget(labelMaximalStringLength);
|
||||||
horizontalLayout2->addWidget(spinBoxMaximalStringLength);
|
horizontalLayout2->addWidget(spinBoxMaximalStringLength);
|
||||||
@@ -148,7 +161,8 @@ CommonOptionsPageWidget::CommonOptionsPageWidget
|
|||||||
gridLayout->addWidget(checkBoxShowQmlObjectTree, 3, 1, 1, 1);
|
gridLayout->addWidget(checkBoxShowQmlObjectTree, 3, 1, 1, 1);
|
||||||
gridLayout->addWidget(checkBoxKeepEditorStationaryWhileStepping, 4, 1, 1, 1);
|
gridLayout->addWidget(checkBoxKeepEditorStationaryWhileStepping, 4, 1, 1, 1);
|
||||||
gridLayout->addWidget(checkBoxRegisterForPostMortem, 5, 1, 1, 1);
|
gridLayout->addWidget(checkBoxRegisterForPostMortem, 5, 1, 1, 1);
|
||||||
gridLayout->addLayout(horizontalLayout2, 6, 1, 1, 2);
|
gridLayout->addLayout(horizontalLayout1, 6, 1, 1, 2);
|
||||||
|
gridLayout->addLayout(horizontalLayout2, 7, 1, 1, 2);
|
||||||
|
|
||||||
QVBoxLayout *verticalLayout = new QVBoxLayout(this);
|
QVBoxLayout *verticalLayout = new QVBoxLayout(this);
|
||||||
verticalLayout->addWidget(behaviorBox);
|
verticalLayout->addWidget(behaviorBox);
|
||||||
@@ -193,6 +207,7 @@ CommonOptionsPageWidget::CommonOptionsPageWidget
|
|||||||
m_group->insert(dc->action(UseAddressInStackView), 0);
|
m_group->insert(dc->action(UseAddressInStackView), 0);
|
||||||
m_group->insert(dc->action(AlwaysAdjustStackColumnWidths), 0);
|
m_group->insert(dc->action(AlwaysAdjustStackColumnWidths), 0);
|
||||||
m_group->insert(dc->action(MaximalStackDepth), spinBoxMaximalStackDepth);
|
m_group->insert(dc->action(MaximalStackDepth), spinBoxMaximalStackDepth);
|
||||||
|
m_group->insert(dc->action(DisplayStringLimit), spinBoxDisplayStringLimit);
|
||||||
m_group->insert(dc->action(MaximalStringLength), spinBoxMaximalStringLength);
|
m_group->insert(dc->action(MaximalStringLength), spinBoxMaximalStringLength);
|
||||||
m_group->insert(dc->action(ShowStdNamespace), 0);
|
m_group->insert(dc->action(ShowStdNamespace), 0);
|
||||||
m_group->insert(dc->action(ShowQtNamespace), 0);
|
m_group->insert(dc->action(ShowQtNamespace), 0);
|
||||||
|
|||||||
@@ -77,9 +77,11 @@ private:
|
|||||||
QCheckBox *checkBoxWarnOnReleaseBuilds;
|
QCheckBox *checkBoxWarnOnReleaseBuilds;
|
||||||
QCheckBox *checkBoxKeepEditorStationaryWhileStepping;
|
QCheckBox *checkBoxKeepEditorStationaryWhileStepping;
|
||||||
QLabel *labelMaximalStackDepth;
|
QLabel *labelMaximalStackDepth;
|
||||||
|
QLabel *labelDisplayStringLimit;
|
||||||
QLabel *labelMaximalStringLength;
|
QLabel *labelMaximalStringLength;
|
||||||
QSpinBox *spinBoxMaximalStackDepth;
|
QSpinBox *spinBoxMaximalStackDepth;
|
||||||
QSpinBox *spinBoxMaximalStringLength;
|
QSpinBox *spinBoxMaximalStringLength;
|
||||||
|
QSpinBox *spinBoxDisplayStringLimit;
|
||||||
|
|
||||||
DebuggerSourcePathMappingWidget *sourcesMappingWidget;
|
DebuggerSourcePathMappingWidget *sourcesMappingWidget;
|
||||||
const QSharedPointer<Utils::SavedActionSet> m_group;
|
const QSharedPointer<Utils::SavedActionSet> m_group;
|
||||||
|
|||||||
@@ -631,8 +631,18 @@ DebuggerSettings::DebuggerSettings()
|
|||||||
item->setDefaultValue(20);
|
item->setDefaultValue(20);
|
||||||
insertItem(MaximalStackDepth, item);
|
insertItem(MaximalStackDepth, item);
|
||||||
|
|
||||||
|
item = new SavedAction(this);
|
||||||
|
item->setSettingsKey(debugModeGroup, QLatin1String("DisplayStringLimit"));
|
||||||
|
item->setToolTip(tr("The maximal length of string entries in the "
|
||||||
|
"Locals and Expressions pane. Longer than that are cut off "
|
||||||
|
"and displayed with an ellipsis attached."));
|
||||||
|
item->setDefaultValue(100);
|
||||||
|
insertItem(DisplayStringLimit, item);
|
||||||
|
|
||||||
item = new SavedAction(this);
|
item = new SavedAction(this);
|
||||||
item->setSettingsKey(debugModeGroup, QLatin1String("MaximalStringLength"));
|
item->setSettingsKey(debugModeGroup, QLatin1String("MaximalStringLength"));
|
||||||
|
item->setToolTip(tr("The maximal length for strings in separated windows. "
|
||||||
|
"Longer strings are cut off and displayed with an ellipsis attached."));
|
||||||
item->setDefaultValue(10000);
|
item->setDefaultValue(10000);
|
||||||
insertItem(MaximalStringLength, item);
|
insertItem(MaximalStringLength, item);
|
||||||
|
|
||||||
|
|||||||
@@ -148,6 +148,7 @@ enum DebuggerActionCode
|
|||||||
AutoDerefPointers,
|
AutoDerefPointers,
|
||||||
AlwaysAdjustLocalsColumnWidths,
|
AlwaysAdjustLocalsColumnWidths,
|
||||||
MaximalStringLength,
|
MaximalStringLength,
|
||||||
|
DisplayStringLimit,
|
||||||
|
|
||||||
// Source List
|
// Source List
|
||||||
ListSourceFiles,
|
ListSourceFiles,
|
||||||
|
|||||||
@@ -219,7 +219,6 @@ QDataStream &operator<<(QDataStream &stream, const WatchData &wd)
|
|||||||
stream << wd.value;
|
stream << wd.value;
|
||||||
stream << wd.editvalue;
|
stream << wd.editvalue;
|
||||||
stream << wd.editformat;
|
stream << wd.editformat;
|
||||||
stream << wd.valuetooltip;
|
|
||||||
stream << wd.typeFormats;
|
stream << wd.typeFormats;
|
||||||
stream << wd.type;
|
stream << wd.type;
|
||||||
stream << wd.displayedType;
|
stream << wd.displayedType;
|
||||||
@@ -243,7 +242,6 @@ QDataStream &operator>>(QDataStream &stream, WatchData &wd)
|
|||||||
stream >> wd.value;
|
stream >> wd.value;
|
||||||
stream >> wd.editvalue;
|
stream >> wd.editvalue;
|
||||||
stream >> wd.editformat;
|
stream >> wd.editformat;
|
||||||
stream >> wd.valuetooltip;
|
|
||||||
stream >> wd.typeFormats;
|
stream >> wd.typeFormats;
|
||||||
stream >> wd.type;
|
stream >> wd.type;
|
||||||
stream >> wd.displayedType;
|
stream >> wd.displayedType;
|
||||||
|
|||||||
@@ -4841,7 +4841,10 @@ void GdbEngine::updateLocalsPython(const UpdateParameters ¶ms)
|
|||||||
expanded += "formats:" + handler->individualFormatRequests();
|
expanded += "formats:" + handler->individualFormatRequests();
|
||||||
|
|
||||||
QByteArray cutOff = " stringcutoff:"
|
QByteArray cutOff = " stringcutoff:"
|
||||||
+ debuggerCore()->action(MaximalStringLength)->value().toByteArray();
|
+ debuggerCore()->action(MaximalStringLength)->value().toByteArray()
|
||||||
|
+ " displaystringlimit:"
|
||||||
|
+ debuggerCore()->action(DisplayStringLimit)->value().toByteArray();
|
||||||
|
|
||||||
|
|
||||||
QByteArray watchers;
|
QByteArray watchers;
|
||||||
const QString fileName = stackHandler()->currentFrame().file;
|
const QString fileName = stackHandler()->currentFrame().file;
|
||||||
|
|||||||
@@ -126,6 +126,7 @@ WatchData::WatchData() :
|
|||||||
size(0),
|
size(0),
|
||||||
bitpos(0),
|
bitpos(0),
|
||||||
bitsize(0),
|
bitsize(0),
|
||||||
|
elided(0),
|
||||||
hasChildren(false),
|
hasChildren(false),
|
||||||
valueEnabled(true),
|
valueEnabled(true),
|
||||||
valueEditable(true),
|
valueEditable(true),
|
||||||
@@ -142,12 +143,12 @@ bool WatchData::isEqual(const WatchData &other) const
|
|||||||
&& name == other.name
|
&& name == other.name
|
||||||
&& value == other.value
|
&& value == other.value
|
||||||
&& editvalue == other.editvalue
|
&& editvalue == other.editvalue
|
||||||
&& valuetooltip == other.valuetooltip
|
|
||||||
&& type == other.type
|
&& type == other.type
|
||||||
&& displayedType == other.displayedType
|
&& displayedType == other.displayedType
|
||||||
&& variable == other.variable
|
&& variable == other.variable
|
||||||
&& address == other.address
|
&& address == other.address
|
||||||
&& size == other.size
|
&& size == other.size
|
||||||
|
&& elided == other.elided
|
||||||
&& hasChildren == other.hasChildren
|
&& hasChildren == other.hasChildren
|
||||||
&& valueEnabled == other.valueEnabled
|
&& valueEnabled == other.valueEnabled
|
||||||
&& valueEditable == other.valueEditable
|
&& valueEditable == other.valueEditable
|
||||||
@@ -312,6 +313,9 @@ QString WatchData::toString() const
|
|||||||
if (isValueKnown() && !value.isEmpty())
|
if (isValueKnown() && !value.isEmpty())
|
||||||
str << "value=\"" << value << doubleQuoteComma;
|
str << "value=\"" << value << doubleQuoteComma;
|
||||||
|
|
||||||
|
if (elided)
|
||||||
|
str << "valueelided=\"" << elided << doubleQuoteComma;
|
||||||
|
|
||||||
if (!editvalue.isEmpty())
|
if (!editvalue.isEmpty())
|
||||||
str << "editvalue=\"<...>\",";
|
str << "editvalue=\"<...>\",";
|
||||||
// str << "editvalue=\"" << editvalue << doubleQuoteComma;
|
// str << "editvalue=\"" << editvalue << doubleQuoteComma;
|
||||||
@@ -382,7 +386,7 @@ QString WatchData::toToolTip() const
|
|||||||
formatToolTipRow(str, tr("Internal Type"), QLatin1String(type));
|
formatToolTipRow(str, tr("Internal Type"), QLatin1String(type));
|
||||||
if (!displayedType.isEmpty())
|
if (!displayedType.isEmpty())
|
||||||
formatToolTipRow(str, tr("Displayed Type"), displayedType);
|
formatToolTipRow(str, tr("Displayed Type"), displayedType);
|
||||||
QString val = valuetooltip.isEmpty() ? value : valuetooltip;
|
QString val = value;
|
||||||
// Automatically display hex value for unsigned integers.
|
// Automatically display hex value for unsigned integers.
|
||||||
if (!val.isEmpty() && val.at(0).isDigit() && isIntType(type)) {
|
if (!val.isEmpty() && val.at(0).isDigit() && isIntType(type)) {
|
||||||
bool ok;
|
bool ok;
|
||||||
@@ -458,13 +462,6 @@ void WatchData::updateValue(const GdbMi &item)
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void setWatchDataValueToolTip(WatchData &data, const GdbMi &mi,
|
|
||||||
int encoding)
|
|
||||||
{
|
|
||||||
if (mi.isValid())
|
|
||||||
data.valuetooltip = decodeData(mi.data(), encoding);
|
|
||||||
}
|
|
||||||
|
|
||||||
void WatchData::updateChildCount(const GdbMi &mi)
|
void WatchData::updateChildCount(const GdbMi &mi)
|
||||||
{
|
{
|
||||||
if (mi.isValid())
|
if (mi.isValid())
|
||||||
@@ -629,6 +626,10 @@ void parseWatchData(const QSet<QByteArray> &expandedINames,
|
|||||||
if (mi.isValid())
|
if (mi.isValid())
|
||||||
data.typeFormats = QString::fromUtf8(mi.data());
|
data.typeFormats = QString::fromUtf8(mi.data());
|
||||||
|
|
||||||
|
mi = item["valueelided"];
|
||||||
|
if (mi.isValid())
|
||||||
|
data.elided = mi.toInt();
|
||||||
|
|
||||||
mi = item["bitpos"];
|
mi = item["bitpos"];
|
||||||
if (mi.isValid())
|
if (mi.isValid())
|
||||||
data.bitpos = mi.toInt();
|
data.bitpos = mi.toInt();
|
||||||
|
|||||||
@@ -126,7 +126,6 @@ public:
|
|||||||
QString value; // Displayed value
|
QString value; // Displayed value
|
||||||
QByteArray editvalue; // Displayed value
|
QByteArray editvalue; // Displayed value
|
||||||
qint32 editformat; // Format of displayed value
|
qint32 editformat; // Format of displayed value
|
||||||
QString valuetooltip; // Tooltip in value column
|
|
||||||
QString typeFormats; // Selection of formats of displayed value
|
QString typeFormats; // Selection of formats of displayed value
|
||||||
QByteArray type; // Type for further processing
|
QByteArray type; // Type for further processing
|
||||||
QString displayedType;// Displayed type (optional)
|
QString displayedType;// Displayed type (optional)
|
||||||
@@ -135,6 +134,7 @@ public:
|
|||||||
uint size; // Size
|
uint size; // Size
|
||||||
uint bitpos; // Position within bit fields
|
uint bitpos; // Position within bit fields
|
||||||
uint bitsize; // Size in case of bit fields
|
uint bitsize; // Size in case of bit fields
|
||||||
|
int elided; // Full size if value was cut off, -1 if cut on unknown size, 0 otherwise
|
||||||
bool hasChildren;
|
bool hasChildren;
|
||||||
bool valueEnabled; // Value will be enabled or not
|
bool valueEnabled; // Value will be enabled or not
|
||||||
bool valueEditable; // Value will be editable
|
bool valueEditable; // Value will be editable
|
||||||
|
|||||||
@@ -695,6 +695,14 @@ QString WatchModel::formattedValue(const WatchData &data) const
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (data.elided) {
|
||||||
|
QString v = value;
|
||||||
|
v.chop(1);
|
||||||
|
QString len = data.elided > 0 ? QString::number(data.elided)
|
||||||
|
: QLatin1String("unknown length");
|
||||||
|
return v + QLatin1String("\"... (") + len + QLatin1Char(')');
|
||||||
|
}
|
||||||
|
|
||||||
return translate(value);
|
return translate(value);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
Reference in New Issue
Block a user