forked from qt-creator/qt-creator
Debugger: Fix char * display with LLDB
Change-Id: I2d0989bd3581f3b61eb975d58bc1c9e119e27d89 Reviewed-by: hjk <hjk121@nokiamail.com>
This commit is contained in:
@@ -391,6 +391,31 @@ class DumperBase:
|
|||||||
self.check(count >= minimum)
|
self.check(count >= minimum)
|
||||||
self.check(count < 1000000)
|
self.check(count < 1000000)
|
||||||
|
|
||||||
|
def findFirstZero(self, p, maximum):
|
||||||
|
for i in xrange(maximum):
|
||||||
|
if int(p.dereference()) == 0:
|
||||||
|
return i
|
||||||
|
p = p + 1
|
||||||
|
return maximum + 1
|
||||||
|
|
||||||
|
def encodeCArray(self, p, innerType, suffix):
|
||||||
|
t = self.lookupType(innerType)
|
||||||
|
p = p.cast(t.pointer())
|
||||||
|
limit = self.findFirstZero(p, qqStringCutOff)
|
||||||
|
s = self.readMemory(p, limit * t.sizeof)
|
||||||
|
if limit > qqStringCutOff:
|
||||||
|
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 putQObjectNameValue(self, value):
|
def putQObjectNameValue(self, value):
|
||||||
try:
|
try:
|
||||||
intSize = self.intSize()
|
intSize = self.intSize()
|
||||||
|
|||||||
@@ -1123,7 +1123,7 @@ class Dumper(DumperBase):
|
|||||||
#return s == "0x0" or s.startswith("0x0 ")
|
#return s == "0x0" or s.startswith("0x0 ")
|
||||||
#try:
|
#try:
|
||||||
# # Can fail with: "RuntimeError: Cannot access memory at address 0x5"
|
# # Can fail with: "RuntimeError: Cannot access memory at address 0x5"
|
||||||
# return p.cast(lookupType("void").pointer()) == 0
|
# return p.cast(self.lookupType("void").pointer()) == 0
|
||||||
#except:
|
#except:
|
||||||
# return False
|
# return False
|
||||||
try:
|
try:
|
||||||
@@ -1365,7 +1365,7 @@ class Dumper(DumperBase):
|
|||||||
self.putEmptyValue(-1)
|
self.putEmptyValue(-1)
|
||||||
else:
|
else:
|
||||||
self.putValue("0x%x" % value.cast(
|
self.putValue("0x%x" % value.cast(
|
||||||
lookupType("unsigned long")), None, -1)
|
self.lookupType("unsigned long")), None, -1)
|
||||||
|
|
||||||
def putDisplay(self, format, value = None, cmd = None):
|
def putDisplay(self, format, value = None, cmd = None):
|
||||||
self.put('editformat="%s",' % format)
|
self.put('editformat="%s",' % format)
|
||||||
@@ -1546,31 +1546,6 @@ class Dumper(DumperBase):
|
|||||||
for i in self.childRange():
|
for i in self.childRange():
|
||||||
self.putSubItem(i, (base + i).dereference())
|
self.putSubItem(i, (base + i).dereference())
|
||||||
|
|
||||||
def findFirstZero(self, p, maximum):
|
|
||||||
for i in xrange(maximum):
|
|
||||||
if p.dereference() == 0:
|
|
||||||
return i
|
|
||||||
p = p + 1
|
|
||||||
return maximum + 1
|
|
||||||
|
|
||||||
def encodeCArray(self, p, innerType, suffix):
|
|
||||||
t = lookupType(innerType)
|
|
||||||
p = p.cast(t.pointer())
|
|
||||||
limit = self.findFirstZero(p, qqStringCutOff)
|
|
||||||
s = self.readMemory(p, limit * t.sizeof)
|
|
||||||
if limit > qqStringCutOff:
|
|
||||||
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 putCallItem(self, name, value, func, *args):
|
def putCallItem(self, name, value, func, *args):
|
||||||
result = self.call2(value, func, args)
|
result = self.call2(value, func, args)
|
||||||
with SubItem(self, name):
|
with SubItem(self, name):
|
||||||
@@ -1846,7 +1821,7 @@ class Dumper(DumperBase):
|
|||||||
#self.putAddress(value.address)
|
#self.putAddress(value.address)
|
||||||
self.putField("bbb", "1")
|
self.putField("bbb", "1")
|
||||||
#self.putPointerValue(value)
|
#self.putPointerValue(value)
|
||||||
self.putValue("0x%x" % value.cast(lookupType("unsigned long")))
|
self.putValue("0x%x" % value.cast(self.lookupType("unsigned long")))
|
||||||
self.putField("ccc", "1")
|
self.putField("ccc", "1")
|
||||||
self.putNumChild(1)
|
self.putNumChild(1)
|
||||||
if self.currentIName in self.expandedINames:
|
if self.currentIName in self.expandedINames:
|
||||||
@@ -2079,7 +2054,7 @@ def threadname(arg):
|
|||||||
or e.name() == "_ZN14QThreadPrivate5startEPv@4":
|
or e.name() == "_ZN14QThreadPrivate5startEPv@4":
|
||||||
try:
|
try:
|
||||||
thrptr = e.read_var("thr").dereference()
|
thrptr = e.read_var("thr").dereference()
|
||||||
obtype = lookupType(ns + "QObjectPrivate").pointer()
|
obtype = d.lookupType(ns + "QObjectPrivate").pointer()
|
||||||
d_ptr = thrptr["d_ptr"]["d"].cast(obtype).dereference()
|
d_ptr = thrptr["d_ptr"]["d"].cast(obtype).dereference()
|
||||||
try:
|
try:
|
||||||
objectName = d_ptr["objectName"]
|
objectName = d_ptr["objectName"]
|
||||||
|
|||||||
@@ -939,30 +939,169 @@ class Dumper(DumperBase):
|
|||||||
self.putNumChild(0)
|
self.putNumChild(0)
|
||||||
return
|
return
|
||||||
|
|
||||||
if self.autoDerefPointers:
|
try:
|
||||||
innerType = value.GetType().GetPointeeType().unqualified()
|
value.dereference()
|
||||||
self.putType(innerType)
|
except:
|
||||||
savedCurrentChildType = self.currentChildType
|
# Failure to dereference a pointer should at least
|
||||||
self.currentChildType = str(innerType)
|
# show the value of a pointer.
|
||||||
inner = value.Dereference()
|
self.putValue(cleanAddress(value))
|
||||||
if inner.IsValid():
|
self.putType(typeName)
|
||||||
self.putItem(inner)
|
self.putNumChild(0)
|
||||||
|
return
|
||||||
|
|
||||||
|
type = value.GetType()
|
||||||
|
innerType = value.GetType().GetPointeeType().unqualified()
|
||||||
|
innerTypeName = str(innerType)
|
||||||
|
|
||||||
|
format = self.formats.get(self.currentIName)
|
||||||
|
if format is None:
|
||||||
|
format = self.typeformats.get(stripForFormat(str(type)))
|
||||||
|
|
||||||
|
if innerTypeName == "void":
|
||||||
|
warn("VOID POINTER: %s" % format)
|
||||||
|
self.putType(typeName)
|
||||||
|
self.putValue(str(value))
|
||||||
|
self.putNumChild(0)
|
||||||
|
return
|
||||||
|
|
||||||
|
if format == None and innerTypeName == "char":
|
||||||
|
# Use Latin1 as default for char *.
|
||||||
|
self.putType(typeName)
|
||||||
|
self.putValue(self.encodeCharArray(value), Hex2EncodedLatin1)
|
||||||
|
self.putNumChild(0)
|
||||||
|
return
|
||||||
|
|
||||||
|
if format == 0:
|
||||||
|
# Explicitly requested bald pointer.
|
||||||
|
self.putType(typeName)
|
||||||
|
self.putPointerValue(value)
|
||||||
|
self.putNumChild(1)
|
||||||
|
if self.currentIName in self.expandedINames:
|
||||||
|
with Children(self):
|
||||||
|
with SubItem(self, '*'):
|
||||||
|
self.putItem(value.dereference())
|
||||||
|
return
|
||||||
|
|
||||||
|
if format == 1:
|
||||||
|
# Explicitly requested Latin1 formatting.
|
||||||
|
self.putType(typeName)
|
||||||
|
self.putValue(self.encodeCharArray(value), Hex2EncodedLatin1)
|
||||||
|
self.putNumChild(0)
|
||||||
|
return
|
||||||
|
|
||||||
|
if format == 2:
|
||||||
|
# Explicitly requested UTF-8 formatting.
|
||||||
|
self.putType(typeName)
|
||||||
|
self.putValue(self.encodeCharArray(value), Hex2EncodedUtf8)
|
||||||
|
self.putNumChild(0)
|
||||||
|
return
|
||||||
|
|
||||||
|
if format == 3:
|
||||||
|
# Explicitly requested local 8 bit formatting.
|
||||||
|
self.putType(typeName)
|
||||||
|
self.putValue(self.encodeCharArray(value), Hex2EncodedLocal8Bit)
|
||||||
|
self.putNumChild(0)
|
||||||
|
return
|
||||||
|
|
||||||
|
if format == 4:
|
||||||
|
# Explicitly requested UTF-16 formatting.
|
||||||
|
self.putType(typeName)
|
||||||
|
self.putValue(self.encodeChar2Array(value), Hex4EncodedLittleEndian)
|
||||||
|
self.putNumChild(0)
|
||||||
|
return
|
||||||
|
|
||||||
|
if format == 5:
|
||||||
|
# Explicitly requested UCS-4 formatting.
|
||||||
|
self.putType(typeName)
|
||||||
|
self.putValue(self.encodeChar4Array(value), Hex8EncodedLittleEndian)
|
||||||
|
self.putNumChild(0)
|
||||||
|
return
|
||||||
|
|
||||||
|
if format == 6:
|
||||||
|
# Explicitly requested formatting as array of 10 items.
|
||||||
|
self.putType(typeName)
|
||||||
|
self.putItemCount(10)
|
||||||
|
self.putNumChild(10)
|
||||||
|
self.putArrayData(innerType, value, 10)
|
||||||
|
return
|
||||||
|
|
||||||
|
if format == 7:
|
||||||
|
# Explicitly requested formatting as array of 1000 items.
|
||||||
|
self.putType(typeName)
|
||||||
|
self.putItemCount(1000)
|
||||||
|
self.putNumChild(1000)
|
||||||
|
self.putArrayData(innerType, value, 1000)
|
||||||
|
return
|
||||||
|
|
||||||
|
#if innerType.code == MethodCode or innerType.code == FunctionCode:
|
||||||
|
# # A function pointer with format None.
|
||||||
|
# self.putValue(str(value))
|
||||||
|
# self.putType(typeName)
|
||||||
|
# self.putNumChild(0)
|
||||||
|
# return
|
||||||
|
|
||||||
|
#warn("AUTODEREF: %s" % self.autoDerefPointers)
|
||||||
|
#warn("INAME: %s" % self.currentIName)
|
||||||
|
if self.autoDerefPointers or self.currentIName.endswith('.this'):
|
||||||
|
## Generic pointer type with format None
|
||||||
|
#warn("GENERIC AUTODEREF POINTER: %s AT %s TO %s"
|
||||||
|
# % (type, value.address, innerTypeName))
|
||||||
|
# Never dereference char types.
|
||||||
|
if innerTypeName != "char" \
|
||||||
|
and innerTypeName != "signed char" \
|
||||||
|
and innerTypeName != "unsigned char" \
|
||||||
|
and innerTypeName != "wchar_t":
|
||||||
|
self.putType(innerType)
|
||||||
|
savedCurrentChildType = self.currentChildType
|
||||||
|
self.currentChildType = stripClassTag(innerTypeName)
|
||||||
|
self.putItem(value.dereference())
|
||||||
self.currentChildType = savedCurrentChildType
|
self.currentChildType = savedCurrentChildType
|
||||||
|
#self.putPointerValue(value)
|
||||||
self.put('origaddr="%s",' % value.address)
|
self.put('origaddr="%s",' % value.address)
|
||||||
return
|
return
|
||||||
|
|
||||||
else:
|
# Fall back to plain pointer printing.
|
||||||
numchild = value.GetNumChildren()
|
#warn("GENERIC PLAIN POINTER: %s" % value.type)
|
||||||
self.put('iname="%s",' % self.currentIName)
|
#warn("ADDR PLAIN POINTER: %s" % value.address)
|
||||||
self.putType(typeName)
|
#self.putType(typeName)
|
||||||
self.putValue('0x%x' % value.GetValueAsUnsigned())
|
#self.putField("aaa", "1")
|
||||||
self.put('numchild="1",')
|
##self.put('addr="0x%x",' % toInteger(value.address))
|
||||||
self.put('addr="0x%x",' % value.GetLoadAddress())
|
##self.putAddress(value.address)
|
||||||
if self.currentIName in self.expandedINames:
|
#self.putField("bbb", "1")
|
||||||
with Children(self):
|
##self.putPointerValue(value)
|
||||||
child = value.Dereference()
|
#self.putValue("0x%x" % value.cast(self.lookupType("unsigned long")))
|
||||||
with SubItem(self, child):
|
#self.putField("ccc", "1")
|
||||||
self.putItem(child)
|
#self.putNumChild(1)
|
||||||
|
#if self.currentIName in self.expandedINames:
|
||||||
|
# with Children(self):
|
||||||
|
# with SubItem(self, "*"):
|
||||||
|
# self.putItem(value.dereference())
|
||||||
|
#return
|
||||||
|
|
||||||
|
#if self.autoDerefPointers:
|
||||||
|
# self.putType(innerType)
|
||||||
|
# savedCurrentChildType = self.currentChildType
|
||||||
|
# self.currentChildType = str(innerType)
|
||||||
|
# inner = value.Dereference()
|
||||||
|
# if inner.IsValid():
|
||||||
|
# self.putItem(inner)
|
||||||
|
# self.currentChildType = savedCurrentChildType
|
||||||
|
# self.put('origaddr="%s",' % value.address)
|
||||||
|
# return
|
||||||
|
#
|
||||||
|
# else:
|
||||||
|
|
||||||
|
numchild = value.GetNumChildren()
|
||||||
|
self.put('iname="%s",' % self.currentIName)
|
||||||
|
self.putType(typeName)
|
||||||
|
self.putValue('0x%x' % value.GetValueAsUnsigned())
|
||||||
|
self.put('numchild="1",')
|
||||||
|
self.put('addr="0x%x",' % value.GetLoadAddress())
|
||||||
|
if self.currentIName in self.expandedINames:
|
||||||
|
with Children(self):
|
||||||
|
child = value.Dereference()
|
||||||
|
with SubItem(self, child):
|
||||||
|
self.putItem(child)
|
||||||
|
|
||||||
|
|
||||||
#warn("VALUE: %s" % value)
|
#warn("VALUE: %s" % value)
|
||||||
|
|||||||
Reference in New Issue
Block a user