Commit e1f8ed73 authored by hjk's avatar hjk
Browse files

Debugger: Sort out the 'address' vs 'origaddr' fields



Now 'address' always refers to the address of the object or
field mentioned in a WatchItem whereas 'origaddr' is
optionally used for the address of the pointer (not its
value) pointing to the object/field in case of "autoderef"
pointers.

Change-Id: I718eb13e6147dafca016c85db6c8b31c631cc764
Reviewed-by: default avatarhjk <hjk121@nokiamail.com>
parent 48951d16
......@@ -379,11 +379,13 @@ class SubItem:
self.savedValueEncoding = self.d.currentValueEncoding
self.savedType = self.d.currentType
self.savedTypePriority = self.d.currentTypePriority
self.savedCurrentAddress = self.d.currentAddress
self.d.currentIName = self.iname
self.d.currentValuePriority = -100
self.d.currentValueEncoding = None
self.d.currentType = ""
self.d.currentTypePriority = -100
self.d.currentAddress = None
def __exit__(self, exType, exValue, exTraceBack):
#warn(" CURRENT VALUE: %s %s %s" % (self.d.currentValue,
......@@ -408,6 +410,8 @@ class SubItem:
self.d.put('value="%s",' % self.d.currentValue)
except:
pass
if not self.d.currentAddress is None:
self.d.put(self.d.currentAddress)
self.d.put('},')
self.d.currentIName = self.savedIName
self.d.currentValue = self.savedValue
......@@ -415,6 +419,7 @@ class SubItem:
self.d.currentValueEncoding = self.savedValueEncoding
self.d.currentType = self.savedType
self.d.currentTypePriority = self.savedTypePriority
self.d.currentAddress = self.savedCurrentAddress
return True
class TopLevelItem(SubItem):
......@@ -992,6 +997,7 @@ class Dumper:
self.currentValueEncoding = None
self.currentType = None
self.currentTypePriority = -100
self.currentAddress = None
self.typeformats = {}
self.formats = {}
self.useDynamicType = True
......@@ -1240,7 +1246,8 @@ class Dumper:
if self.currentPrintsAddress:
try:
# addr can be "None", long(None) fails.
self.put('addr="0x%x",' % long(addr))
#self.put('addr="0x%x",' % long(addr))
self.currentAddress = 'addr="0x%x",' % long(addr)
except:
pass
......@@ -1249,6 +1256,12 @@ class Dumper:
if numchild != self.currentChildNumChild:
self.put('numchild="%s",' % numchild)
def putEmptyValue(self, priority = -10):
if priority >= self.currentValuePriority:
self.currentValue = ""
self.currentValuePriority = priority
self.currentValueEncoding = None
def putValue(self, value, encoding = None, priority = 0):
# Higher priority values override lower ones.
if priority >= self.currentValuePriority:
......@@ -1259,9 +1272,9 @@ class Dumper:
def putPointerValue(self, value):
# Use a lower priority
if value is None:
self.putValue(" ", None, -1)
self.putEmptyValue(-1)
else:
self.putValue("0x%x" % value.dereference().cast(
self.putValue("0x%x" % value.cast(
lookupType("unsigned long")), None, -1)
def putStringValue(self, value, priority = 0):
......@@ -1327,7 +1340,6 @@ class Dumper:
def putIntItem(self, name, value):
with SubItem(self, name):
self.putValue(value)
self.putAddress(value.address)
self.putType("int")
self.putNumChild(0)
......@@ -1434,6 +1446,8 @@ class Dumper:
typeName = str(type)
tryDynamic &= self.useDynamicType
lookupType(typeName) # Fill type cache
if tryDynamic:
self.putAddress(value.address)
# FIXME: Gui shows references stripped?
#warn(" ")
......@@ -1480,7 +1494,6 @@ class Dumper:
return
if type.code == IntCode or type.code == CharCode:
self.putAddress(value.address)
self.putType(typeName)
if value.is_optimized_out:
self.putValue("<optimized out>")
......@@ -1490,7 +1503,6 @@ class Dumper:
return
if type.code == FloatCode or type.code == BoolCode:
self.putAddress(value.address)
self.putType(typeName)
if value.is_optimized_out:
self.putValue("<optimized out>")
......@@ -1500,7 +1512,6 @@ class Dumper:
return
if type.code == EnumCode:
self.putAddress(value.address)
self.putType(typeName)
if value.is_optimized_out:
self.putValue("<optimized out>")
......@@ -1510,7 +1521,6 @@ class Dumper:
return
if type.code == ComplexCode:
self.putAddress(value.address)
self.putType(typeName)
if value.is_optimized_out:
self.putValue("<optimized out>")
......@@ -1527,7 +1537,7 @@ class Dumper:
type = stripTypedefs(type)
# The cast can destroy the address?
self.putAddress(value.address)
#self.putAddress(value.address)
# Workaround for http://sourceware.org/bugzilla/show_bug.cgi?id=13380
if type.code == ArrayCode:
value = parseAndEvaluate("{%s}%s" % (type, value.address))
......@@ -1568,7 +1578,6 @@ class Dumper:
if isNull(value):
#warn("NULL POINTER")
self.putAddress(value.address)
self.putType(typeName)
self.putValue("0x0")
self.putNumChild(0)
......@@ -1585,12 +1594,10 @@ class Dumper:
self.putType(typeName)
self.putValue(str(value))
self.putNumChild(0)
self.putAddress(value.address)
return
if format == None and innerTypeName == "char":
# Use Latin1 as default for char *.
self.putAddress(value.address)
self.putType(typeName)
self.putValue(encodeCharArray(value), Hex2EncodedLatin1)
self.putNumChild(0)
......@@ -1598,20 +1605,17 @@ class Dumper:
if format == 0:
# Explicitly requested bald pointer.
self.putAddress(value.address)
self.putType(typeName)
self.putPointerValue(value.address)
self.putPointerValue(value)
self.putNumChild(1)
if self.currentIName in self.expandedINames:
with Children(self):
with SubItem(self, '*'):
self.putItem(value.dereference())
#self.putAddress(value)
return
if format == 1:
# Explicitly requested Latin1 formatting.
self.putAddress(value.address)
self.putType(typeName)
self.putValue(encodeCharArray(value), Hex2EncodedLatin1)
self.putNumChild(0)
......@@ -1619,7 +1623,6 @@ class Dumper:
if format == 2:
# Explicitly requested UTF-8 formatting.
self.putAddress(value.address)
self.putType(typeName)
self.putValue(encodeCharArray(value), Hex2EncodedUtf8)
self.putNumChild(0)
......@@ -1627,7 +1630,6 @@ class Dumper:
if format == 3:
# Explicitly requested local 8 bit formatting.
self.putAddress(value.address)
self.putType(typeName)
self.putValue(encodeCharArray(value), Hex2EncodedLocal8Bit)
self.putNumChild(0)
......@@ -1635,7 +1637,6 @@ class Dumper:
if format == 4:
# Explicitly requested UTF-16 formatting.
self.putAddress(value.address)
self.putType(typeName)
self.putValue(encodeChar2Array(value), Hex4EncodedLittleEndian)
self.putNumChild(0)
......@@ -1643,7 +1644,6 @@ class Dumper:
if format == 5:
# Explicitly requested UCS-4 formatting.
self.putAddress(value.address)
self.putType(typeName)
self.putValue(encodeChar4Array(value), Hex8EncodedLittleEndian)
self.putNumChild(0)
......@@ -1652,7 +1652,6 @@ class Dumper:
if innerType.code == MethodCode or innerType.code == FunctionCode:
# A function pointer with format None.
self.putValue(str(value))
self.putAddress(value.address)
self.putType(typeName)
self.putNumChild(0)
return
......@@ -1673,20 +1672,26 @@ class Dumper:
self.currentChildType = stripClassTag(innerTypeName)
self.putItem(value.dereference())
self.currentChildType = savedCurrentChildType
self.putPointerValue(value.address)
self.put('origaddr="%s",' % cleanAddress(value.address))
#self.putPointerValue(value)
self.put('origaddr="%s",' % value.address)
return
# Fall back to plain pointer printing.
#warn("GENERIC PLAIN POINTER: %s" % value.type)
warn("GENERIC PLAIN POINTER: %s" % value.type)
warn("ADDR PLAIN POINTER: %s" % value.address)
self.putType(typeName)
self.putAddress(value.address)
self.putField("aaa", "1")
#self.put('addr="0x%x",' % long(value.address))
#self.putAddress(value.address)
self.putField("bbb", "1")
#self.putPointerValue(value)
self.putValue("0x%x" % value.cast(lookupType("unsigned long")))
self.putField("ccc", "1")
self.putNumChild(1)
if self.currentIName in self.expandedINames:
with Children(self):
with SubItem(self, "*"):
self.putItem(value.dereference())
self.putPointerValue(value.address)
return
if type.code == MethodPointerCode \
......@@ -1694,7 +1699,6 @@ class Dumper:
or type.code == FunctionCode \
or type.code == MemberPointerCode:
self.putType(typeName)
self.putAddress(value.address)
self.putValue(value)
self.putNumChild(0)
return
......@@ -1723,7 +1727,6 @@ class Dumper:
format = self.typeformats.get(stripForFormat(typeName))
if self.useFancy and (format is None or format >= 1):
self.putAddress(value.address)
self.putType(typeName)
nsStrippedType = self.stripNamespaceFromType(typeName)\
......@@ -1755,7 +1758,6 @@ class Dumper:
n = value["length"]
base = value["ptr"]
self.putType(typeName)
self.putAddress(value.address)
self.putItemCount(n)
if self.isExpanded():
self.putArrayData(base.type.target(), base, n)
......@@ -1771,8 +1773,7 @@ class Dumper:
self.tryPutObjectNameValue(value) # Is this too expensive?
self.putType(typeName)
self.putAddress(value.address)
self.putValue("{...}")
self.putEmptyValue()
if False:
numfields = 0
......@@ -1792,9 +1793,8 @@ class Dumper:
self.putFields(value)
def putPlainChildren(self, value):
self.putValue(" ", None, -99)
self.putEmptyValue(-99)
self.putNumChild(1)
self.putAddress(value.address)
if self.currentIName in self.expandedINames:
with Children(self):
self.putFields(value)
......@@ -1899,7 +1899,6 @@ class Dumper:
#warn("FIELD NAME: %s" % field.name)
if len(field.name) > 0:
with SubItem(self, field.name):
#self.putAddress(value.address)
self.putItem(value[field.name])
else:
# Further nested.
......@@ -1909,7 +1908,7 @@ class Dumper:
#child = SameItem(item.value, iname)
with SubItem(self, name):
self.put('name="%s",' % name)
self.putValue(" ")
self.putEmptyValue()
fieldTypeName = str(field.type)
if fieldTypeName.endswith("<anonymous union>"):
self.putType("<anonymous union>")
......
......@@ -140,7 +140,7 @@ def qdump__QModelIndex(d, value):
rowCount = int(parseAndEvaluate("%s.rowCount(%s)" % (mm_, mi_)))
columnCount = int(parseAndEvaluate("%s.columnCount(%s)" % (mm_, mi_)))
except:
d.putValue(" ")
d.putEmptyValue()
d.putPlainChildren(value)
return
......@@ -309,7 +309,7 @@ def qdump__QFileInfo(d, value):
d.putValue("<not available>")
else:
with SubItem(d, "permissions"):
d.putValue(" ")
d.putEmptyValue()
d.putType(d.ns + "QFile::Permissions")
d.putNumChild(10)
if d.isExpanded():
......@@ -472,7 +472,7 @@ def qdump__QHashNode(d, value):
# d.putName(key)
# d.putValue(val)
#else:
d.putValue(" ")
d.putEmptyValue()
d.putNumChild(2)
if d.isExpanded():
......@@ -487,7 +487,7 @@ def qHashIteratorHelper(d, value):
keyType = templateArgument(hashType, 0)
valueType = templateArgument(hashType, 1)
d.putNumChild(1)
d.putValue(" ")
d.putEmptyValue()
if d.isExpanded():
with Children(d):
typeName = "%sQHash<%s,%s>::Node" % (d.ns, keyType, valueType)
......@@ -675,7 +675,7 @@ def qdump__QLocale(d, value):
def qdump__QMapNode(d, value):
d.putValue(" ")
d.putEmptyValue()
d.putNumChild(2)
if d.isExpanded():
with Children(d):
......@@ -870,7 +870,7 @@ def qdump__QObject(d, value):
#warn("STRINGDATA: %s " % metaStringData)
#warn("TYPE: %s " % value.type)
#warn("INAME: %s " % d.currentIName())
#d.putValue("")
#d.putEmptyValue()
#QSignalMapper::staticMetaObject
#checkRef(d_ptr["ref"])
d.putNumChild(4)
......@@ -881,7 +881,7 @@ def qdump__QObject(d, value):
if privateTypeName != d.ns + "QObjectPrivate":
if not privateType is None:
with SubItem(d, "data"):
d.putValue(" ")
d.putEmptyValue()
d.putNoType()
d.putNumChild(1)
if d.isExpanded():
......@@ -1560,7 +1560,7 @@ def qdump__QTextCursor(d, value):
def qdump__QTextDocument(d, value):
d.putValue(" ")
d.putEmptyValue()
d.putNumChild(1)
if d.isExpanded():
with Children(d):
......@@ -1755,7 +1755,7 @@ def qdump__QVariant(d, value):
v = d_data["shared"]["ptr"].cast(innerType.pointer()).dereference()
else:
v = d_data.cast(innerType)
d.putValue(" ", None, -99)
d.putEmptyValue(-99)
d.putItem(v)
d.putBetterType("%sQVariant (%s)" % (d.ns, innert))
return innert
......@@ -1770,7 +1770,7 @@ def qdump__QVariant(d, value):
warn("TYPE: %s" % type)
data = call(value, "constData")
warn("DATA: %s" % data)
d.putValue(" ", None, -99)
d.putEmptyValue(-99)
d.putType("%sQVariant (%s)" % (d.ns, type))
d.putNumChild(1)
tdata = data.cast(lookupType(type).pointer()).dereference()
......@@ -1840,7 +1840,7 @@ def qdump__QWeakPointer(d, value):
d.putNumChild(3)
d.putItem(val.dereference())
else:
d.putValue("")
d.putEmptyValue()
d.putNumChild(3)
if d.isExpanded():
......@@ -1865,7 +1865,7 @@ def qdump____c_style_array__(d, value):
type = value.type.unqualified()
targetType = type.target()
typeName = str(type)
d.putAddress(value.address)
#d.putAddress(value.address)
d.putType(typeName)
d.putNumChild(1)
format = d.currentItemFormat()
......@@ -2018,7 +2018,7 @@ def qdump__std__map(d, value):
d.putMapName(pair["first"])
d.putItem(pair["second"])
else:
d.putValue(" ")
d.putEmptyValue()
if d.isExpanded():
with Children(d, 2):
d.putSubItem("first", pair["first"])
......@@ -2040,7 +2040,7 @@ def stdTreeIteratorHelper(d, value):
pnode = value["_M_node"]
node = pnode.dereference()
d.putNumChild(1)
d.putValue(" ")
d.putEmptyValue()
if d.isExpanded():
dataType = templateArgument(value.type, 0)
nodeType = lookupType("std::_Rb_tree_node<%s>" % dataType)
......@@ -2053,7 +2053,7 @@ def stdTreeIteratorHelper(d, value):
d.putSubItem("value", data)
with SubItem(d, "node"):
d.putNumChild(1)
d.putValue(" ")
d.putEmptyValue()
d.putType(" ")
if d.isExpanded():
with Children(d):
......@@ -2153,7 +2153,7 @@ def qdump__std__string(d, value):
encodingType = Hex8EncodedLittleEndian
displayType = DisplayUtf16String
d.putAddress(value.address)
#d.putAddress(value.address)
d.putNumChild(0)
d.putValue(mem, encodingType)
......@@ -2358,7 +2358,7 @@ def qdump__boost__shared_ptr(d, value):
d.putNumChild(3)
d.putItem(val)
else:
d.putValue("")
d.putEmptyValue()
d.putNumChild(3)
if d.isExpanded():
......@@ -2394,7 +2394,7 @@ def qform____m128():
return "As Floats,As Doubles"
def qdump____m128(d, value):
d.putValue(" ")
d.putEmptyValue()
d.putNumChild(1)
if d.isExpanded():
format = d.currentItemFormat()
......@@ -2439,7 +2439,7 @@ def jstagAsString(tag):
def qdump__QTJSC__JSValue(d, value):
d.putValue(" ")
d.putEmptyValue()
d.putNumChild(1)
if d.isExpanded():
with Children(d):
......@@ -2479,7 +2479,7 @@ def qdump__QScriptValue(d, value):
# ref QBasicAtomicInt
# stringValue QString
# type QScriptValuePrivate::Type: { JavaScriptCore, Number, String }
#d.putValue(" ")
#d.putEmptyValue()
dd = value["d_ptr"]["d"]
if isNull(dd):
d.putValue("(invalid)")
......@@ -2714,13 +2714,12 @@ def qdump_Array(d, value):
n = value["length"]
p = value["ptr"]
t = cleanDType(value.type)[7:]
d.putAddress(value.address)
d.putType("%s[%d]" % (t, n))
if t == "char":
d.putValue(encodeCharArray(p, 100), Hex2EncodedLocal8Bit)
d.putNumChild(0)
else:
d.putValue(" ")
d.putEmptyValue()
d.putNumChild(n)
innerType = p.type
if d.isExpanded():
......@@ -2736,9 +2735,8 @@ def qdump_AArray(d, value):
# member of type void *. Not much that can be done here.
p = value["ptr"]
t = cleanDType(value.type)[8:]
d.putAddress(value.address)
d.putType("%s]" % t.replace("_", "["))
d.putValue(" ")
d.putEmptyValue()
d.putNumChild(1)
if d.isExpanded():
with Children(d, 1):
......@@ -2814,7 +2812,7 @@ if False:
if d.isExpanded():
with Children(d):
with SubItem(d, "tree"):
d.putValue(" ")
d.putEmptyValue()
d.putNoType()
d.putNumChild(1)
if d.isExpanded():
......@@ -2822,7 +2820,7 @@ if False:
for i in xrange(count):
d.putSubItem(Item(entries[i], iname))
with SubItem(d, "data"):
d.putValue(" ")
d.putEmptyValue()
d.putNoType()
d.putNumChild(1)
if d.isExpanded():
......
......@@ -1090,19 +1090,15 @@ int SymbolGroupNode::dumpNode(std::ostream &str,
std::wstring value = simpleDumpValue(ctx);
if (addr) {
ULONG64 referencedAddr = 0;
// Determine referenced address of pointers?
str << std::hex << std::showbase << ",addr=\"" << addr << '"';
if (!value.compare(0, 2u, L"0x")) {
std::wistringstream str(value.substr(2u, value.size() - 2u));
str >> std::hex >> referencedAddr;
// Determine referenced address of pointers?
ULONG64 referencedAddr = 0;
std::wistringstream istr(value.substr(2u, value.size() - 2u));
istr >> std::hex >> referencedAddr;
if (referencedAddr)
str << ",origaddr=\"" << referencedAddr << '"';
}
// Emulate gdb's behaviour of returning the referenced address
// for pointers.
str << std::hex << std::showbase;
if (referencedAddr)
str << ",addr=\"" << referencedAddr << "\",origaddr=\"" << addr << '"';
else
str << ",addr=\"" << addr << '"';
str << std::noshowbase << std::dec;
}
const ULONG s = size();
......
......@@ -76,13 +76,12 @@ enum ModelRoles
LocalsTypeFormatListRole,
LocalsTypeFormatRole, // Used to communicate alternative formats to the view
LocalsIndividualFormatRole,
LocalsAddressRole, // Memory address of variable as quint64
LocalsReferencingAddressRole, // Address referencing for 'Automatically dereferenced pointer'
LocalsObjectAddressRole, // Memory address of variable as quint64
LocalsSizeRole, // Size of variable as quint
LocalsRawValueRole, // Unformatted value as string
LocalsPointerValueRole, // Pointer value (address) as quint64
LocalsIsWatchpointAtAddressRole,
LocalsIsWatchpointAtPointerValueRole,
LocalsPointerAddressRole, // Address of (undereferenced) pointer as quint64
LocalsIsWatchpointAtObjectAddressRole,
LocalsIsWatchpointAtPointerAddressRole,
// Snapshots
SnapshotCapabilityRole
......
......@@ -1404,7 +1404,7 @@ void GdbEngine::handleVarListChildrenHelperClassic(const GdbMi &item,
data.variable = name;
data.updateType(item.findChild("type"));
data.updateValue(item);
data.updateAddress(item.findChild("addr"), GdbMi());
data.updateAddress(item.findChild("addr"));
data.setHasChildren(false);
insertData(data);
} else if (parent.iname.endsWith('.')) {
......@@ -1428,7 +1428,7 @@ void GdbEngine::handleVarListChildrenHelperClassic(const GdbMi &item,
data.sortId = sortId;
data.updateType(item.findChild("type"));
data.updateValue(item);
data.updateAddress(item.findChild("addr"), GdbMi());
data.updateAddress(item.findChild("addr"));
data.updateChildCount(item.findChild("numchild"));
if (!watchHandler()->isExpandedIName(data.iname))
data.setChildrenUnneeded();
......
......@@ -123,7 +123,7 @@ WatchData::WatchData() :
state(InitialState),
editformat(0),
address(0),
referencingAddress(0),
origaddr(0),
size(0),
bitpos(0),
bitsize(0),
......@@ -213,11 +213,6 @@ void WatchData::setValue(const QString &value0)
setValueUnneeded();
}
void WatchData::setValueToolTip(const QString &tooltip)
{
valuetooltip = tooltip;
}
enum GuessChildrenResult { HasChildren, HasNoChildren, HasPossiblyChildren };
static GuessChildrenResult guessChildren(const QByteArray &type)
......@@ -271,11 +266,6 @@ void WatchData::setType(const QByteArray &str, bool guessChildrenFromType)
}
}
void WatchData::updateAddress(const quint64 &a)
{
address = a;
}
void WatchData::setHexAddress(const QByteArray &a)
{
bool ok;
......@@ -307,9 +297,9 @@ QString WatchData::toString() const
str << "addr=\"0x" << address << doubleQuoteComma;
str.setIntegerBase(10);
}
if (referencingAddress) {
if (origaddr) {