diff --git a/share/qtcreator/gdbmacros/dumper.py b/share/qtcreator/gdbmacros/dumper.py index 780588f91d7..ed9853af18d 100644 --- a/share/qtcreator/gdbmacros/dumper.py +++ b/share/qtcreator/gdbmacros/dumper.py @@ -1766,6 +1766,7 @@ class Dumper: Item(item.value.dereference(), item.iname, None, None)) self.currentChildType = savedCurrentChildType self.putPointerValue(value.address) + self.put('origaddr="%s",' % value) return # Fall back to plain pointer printing. diff --git a/src/plugins/debugger/watchdata.cpp b/src/plugins/debugger/watchdata.cpp index c807f86606b..705e54b6025 100644 --- a/src/plugins/debugger/watchdata.cpp +++ b/src/plugins/debugger/watchdata.cpp @@ -145,6 +145,7 @@ WatchData::WatchData() : state(InitialState), editformat(0), address(0), + origAddress(0), size(0), bitpos(0), bitsize(0), @@ -309,6 +310,11 @@ QString WatchData::toString() const str << "addr=\"0x" << address << doubleQuoteComma; str.setIntegerBase(10); } + if (origAddress) { + str.setIntegerBase(16); + str << "origaddr=\"0x" << origAddress << doubleQuoteComma; + str.setIntegerBase(10); + } if (!exp.isEmpty()) str << "exp=\"" << exp << doubleQuoteComma; @@ -372,6 +378,9 @@ QString WatchData::toToolTip() const formatToolTipRow(str, tr("Value"), val); formatToolTipRow(str, tr("Object Address"), QString::fromAscii(hexAddress())); + if (origAddress) + formatToolTipRow(str, tr("Original Address"), + QString::fromAscii(hexOrigAddress())); if (size) formatToolTipRow(str, tr("Size"), QString::number(size)); @@ -415,6 +424,11 @@ QByteArray WatchData::hexAddress() const return address ? (QByteArray("0x") + QByteArray::number(address, 16)) : QByteArray(); } +QByteArray WatchData::hexOrigAddress() const +{ + return origAddress ? (QByteArray("0x") + QByteArray::number(origAddress, 16)) : QByteArray(); +} + } // namespace Internal } // namespace Debugger diff --git a/src/plugins/debugger/watchdata.h b/src/plugins/debugger/watchdata.h index f62d73c3826..d8e835fffb5 100644 --- a/src/plugins/debugger/watchdata.h +++ b/src/plugins/debugger/watchdata.h @@ -113,6 +113,7 @@ public: quint64 coreAddress() const; QByteArray hexAddress() const; + QByteArray hexOrigAddress() const; public: quint64 id; // Token for the engine for internal mapping @@ -128,6 +129,7 @@ public: QByteArray type; // Type for further processing QString displayedType;// Displayed type (optional) quint64 address; // Displayed address + quint64 origAddress; // Original address for dereferenced pointers uint size; // Size uint bitpos; // Position within bit fields uint bitsize; // Size in case of bit fields diff --git a/src/plugins/debugger/watchhandler.cpp b/src/plugins/debugger/watchhandler.cpp index a232b098439..fd7bd5afbb6 100644 --- a/src/plugins/debugger/watchhandler.cpp +++ b/src/plugins/debugger/watchhandler.cpp @@ -641,6 +641,10 @@ QVariant WatchModel::data(const QModelIndex &idx, int role) const case 1: result = removeInitialNamespace(truncateValue( formattedValue(data, itemFormat(data))), ns); + if (data.origAddress) { + result += QLatin1String(" @"); + result += QString::fromLatin1(data.hexOrigAddress()); + } break; case 2: result = removeNamespaces(displayType(data), ns); @@ -692,16 +696,16 @@ QVariant WatchModel::data(const QModelIndex &idx, int role) const return m_handler->m_expandedINames.contains(data.iname); case LocalsTypeFormatListRole: { - if (isIntType(data.type) && data.type != "bool") - return QStringList() << tr("decimal") << tr("hexadecimal") - << tr("binary") << tr("octal"); - if (data.type.endsWith('*')) + if (data.origAddress || data.type.endsWith('*')) return QStringList() << tr("Raw pointer") << tr("Latin1 string") << tr("UTF8 string") << tr("UTF16 string") << tr("UCS4 string"); + if (isIntType(data.type) && data.type != "bool") + return QStringList() << tr("decimal") << tr("hexadecimal") + << tr("binary") << tr("octal"); // Hack: Compensate for namespaces. QString type = data.type; int pos = type.indexOf("::Q"); diff --git a/src/plugins/debugger/watchutils.cpp b/src/plugins/debugger/watchutils.cpp index 0c784b0f082..1788ba5b5d0 100644 --- a/src/plugins/debugger/watchutils.cpp +++ b/src/plugins/debugger/watchutils.cpp @@ -1349,6 +1349,11 @@ void setWatchDataAddress(WatchData &data, const GdbMi &mi) setWatchDataAddressHelper(data, mi.data()); } +void setWatchDataOrigAddress(WatchData &data, const GdbMi &mi) +{ + data.origAddress = mi.data().toULongLong(0, 16); +} + void setWatchDataSize(WatchData &data, const GdbMi &mi) { if (mi.isValid()) { @@ -1418,6 +1423,7 @@ void parseWatchData(const QSet &expandedINames, setWatchDataValue(data, item); setWatchDataAddress(data, item.findChild("addr")); + setWatchDataOrigAddress(data, item.findChild("origaddr")); setWatchDataSize(data, item.findChild("size")); setWatchDataExpression(data, item.findChild("exp")); setWatchDataValueEnabled(data, item.findChild("valueenabled")); diff --git a/tests/manual/gdbdebugger/simple/simple_gdbtest_app.cpp b/tests/manual/gdbdebugger/simple/simple_gdbtest_app.cpp index b32d1e29a2f..6ed5ffa52d3 100644 --- a/tests/manual/gdbdebugger/simple/simple_gdbtest_app.cpp +++ b/tests/manual/gdbdebugger/simple/simple_gdbtest_app.cpp @@ -2559,6 +2559,7 @@ void testMPI() int main(int argc, char *argv[]) { + int *x = new int(32); testQXmlAttributes(); testQRegExp(); testInlineBreakpoints();