From 6595e1d443a793d67a33ad10dddbebf15f149c7f Mon Sep 17 00:00:00 2001 From: Friedemann Kleint Date: Fri, 16 Mar 2012 11:57:46 +0100 Subject: [PATCH] Adapt CDB debug helpers to pending container changes. - Adapt QByteArray, QString, QVector. - Disable QMap for Qt 5. Change-Id: I113d546fc69165b504ce4998b3bf7ac9c44130fb Reviewed-by: hjk --- src/libs/qtcreatorcdbext/containers.cpp | 37 ++++++++++++++++--- src/libs/qtcreatorcdbext/symbolgroupvalue.cpp | 22 ++++++----- 2 files changed, 44 insertions(+), 15 deletions(-) diff --git a/src/libs/qtcreatorcdbext/containers.cpp b/src/libs/qtcreatorcdbext/containers.cpp index a676346f62a..2dfa6246fa3 100644 --- a/src/libs/qtcreatorcdbext/containers.cpp +++ b/src/libs/qtcreatorcdbext/containers.cpp @@ -151,11 +151,19 @@ int containerSize(KnownType kt, const SymbolGroupValue &v) break; case KT_QLinkedList: case KT_QHash: - case KT_QMap: - case KT_QVector: if (const SymbolGroupValue sizeV = v["d"]["size"]) return sizeV.intValue(); break; + case KT_QMap: + case KT_QVector: { + // Inheritance from QVectorTypedData, QMapData<> in Qt 5. + const SymbolGroupValue sizeV = + QtInfo::get(v.context()).version >= 5 ? + v["d"][unsigned(0)]["size"] : v["d"]["size"]; + if (sizeV) + return sizeV.intValue(); + } + break; case KT_QMultiHash: if (const SymbolGroupValue qHash = v[unsigned(0)]) return containerSize(KT_QHash, qHash); @@ -646,16 +654,33 @@ static inline AbstractSymbolGroupNodePtrVector static inline AbstractSymbolGroupNodePtrVector qVectorChildList(SymbolGroupNode *n, int count, const SymbolGroupValueContext &ctx) { - if (count) { - // QVector: p/array is declared as array of T. Dereference first + if (!count) + return AbstractSymbolGroupNodePtrVector(); + const SymbolGroupValue vec(n, ctx); + const int qtVersion = QtInfo::get(vec.context()).version; + if (qtVersion < 5) { + // Qt 4: QVector: p/array is declared as array of T. Dereference first // element to obtain address. - const SymbolGroupValue vec(n, ctx); if (const SymbolGroupValue firstElementV = vec["p"]["array"][unsigned(0)]) { if (const ULONG64 arrayAddress = firstElementV.address()) { const std::string fixedInnerType = fixInnerType(firstElementV.type(), vec); return arrayChildList(n->symbolGroup(), arrayAddress, n->module(), fixedInnerType, count); } } + return AbstractSymbolGroupNodePtrVector(); + } + // Qt 5: Data are located in a pool behind 'd' (similar to QString, + // QByteArray). + const SymbolGroupValue dV = vec["d"][unsigned(0)]; + const SymbolGroupValue offsetV = dV["offset"]; + if (!dV || !offsetV) + return AbstractSymbolGroupNodePtrVector(); + const ULONG64 arrayAddress = dV.address() + offsetV.intValue(); + std::vector innerTypes = SymbolGroupValue::innerTypesOf(vec.type()); + if (arrayAddress && !innerTypes.empty()) { + return arrayChildList(n->symbolGroup(), arrayAddress, n->module(), + fixInnerType(innerTypes.front(), vec), + count); } return AbstractSymbolGroupNodePtrVector(); } @@ -939,6 +964,8 @@ static inline AbstractSymbolGroupNodePtrVector if (!count) return AbstractSymbolGroupNodePtrVector(); + if (QtInfo::get(v.context()).version >= 5) // ### fixme: Qt 5 map is a rb tree. + return AbstractSymbolGroupNodePtrVector(); // Get node type: 'class namespace::QMap' // ->'QtCored4!namespace::QMapNode' // Note: Any types QMapNode<> will not be found without modules! diff --git a/src/libs/qtcreatorcdbext/symbolgroupvalue.cpp b/src/libs/qtcreatorcdbext/symbolgroupvalue.cpp index 011b4c17c96..10f948cfa8d 100644 --- a/src/libs/qtcreatorcdbext/symbolgroupvalue.cpp +++ b/src/libs/qtcreatorcdbext/symbolgroupvalue.cpp @@ -1414,7 +1414,8 @@ struct QtStringAddressData /* Helper to determine the location and size of the data of * QStrings/QByteArrays for versions 4,5. In Qt 4, 'd' has a 'data' * pointer. In Qt 5, the d-elements and the data are in a storage pool - * and the data are at an offset behind the d-structures. */ + * and the data are at an offset behind the d-structures (QString, + * QByteArray, QVector). */ QtStringAddressData readQtStringAddressData(const SymbolGroupValue &dV, int qtMajorVersion) { @@ -1431,15 +1432,13 @@ QtStringAddressData readQtStringAddressData(const SymbolGroupValue &dV, } else { // Qt 5: Memory pool after the data element. const SymbolGroupValue offsetV = dV["offset"]; - const SymbolGroupValue arrayV = dV["d"]; - if (!offsetV || !arrayV) + if (!offsetV) return QtStringAddressData(); - int offset = offsetV.intValue(); - if (arrayV.type().find("short") != std::string::npos) - offset /= sizeof(short); // QString: offset is in short[]. - result.address = arrayV.address() - + SymbolGroupValue::pointerDiffSize() - + offset; + // Take the address for QTypeArrayData of QByteArray, else + // pointer value of D-pointer. + const ULONG64 baseAddress = SymbolGroupValue::isPointerType(dV.type()) ? + dV.pointerValue() : dV.address(); + result.address = baseAddress + offsetV.intValue(); } return result; } @@ -1578,7 +1577,10 @@ static inline bool dumpQByteArray(const SymbolGroupValue &v, std::wostream &str) char *memory; unsigned fullSize; unsigned size; - if (!readQt5StringData(dV, qtInfo.version, false, 10240, &fullSize, &size, &memory)) + const SymbolGroupValue typeArrayV = dV[unsigned(0)]; + if (!typeArrayV) + return false; + if (!readQt5StringData(typeArrayV, qtInfo.version, false, 10240, &fullSize, &size, &memory)) return false; if (size) { // Emulate CDB's behavior of replacing unprintable characters