From 29ad8a456101b593ae491afe58a38cbb223e9fa6 Mon Sep 17 00:00:00 2001 From: Friedemann Kleint Date: Wed, 5 Jan 2011 16:50:26 +0100 Subject: [PATCH] Debugger[New CDB]: Fix QList. - Account for POD types in largeStatic-Check - Avoid dumping empty children list (move handling to visitor) - Verbose facility. --- src/libs/qtcreatorcdbext/containers.cpp | 8 +++-- .../qtcreatorcdbext/qtcreatorcdbextension.cpp | 8 ++++- src/libs/qtcreatorcdbext/symbolgroupnode.cpp | 32 +++++++++++-------- src/libs/qtcreatorcdbext/symbolgroupnode.h | 16 +++++----- src/libs/qtcreatorcdbext/symbolgroupvalue.cpp | 17 +++++++++- src/libs/qtcreatorcdbext/symbolgroupvalue.h | 2 ++ 6 files changed, 57 insertions(+), 26 deletions(-) diff --git a/src/libs/qtcreatorcdbext/containers.cpp b/src/libs/qtcreatorcdbext/containers.cpp index 9e28cf0aa45..63f8d2ce545 100644 --- a/src/libs/qtcreatorcdbext/containers.cpp +++ b/src/libs/qtcreatorcdbext/containers.cpp @@ -687,6 +687,8 @@ static inline AbstractSymbolGroupNodePtrVector return AbstractSymbolGroupNodePtrVector(); const std::string innerType = fixInnerType(innerTypes.front(), v.context()); const unsigned innerTypeSize = SymbolGroupValue::sizeOf(innerType.c_str()); + if (debugVector) + DebugPrint() << "QList " << v.name() << " inner type " << innerType << ' ' << innerTypeSize; if (!innerTypeSize) return AbstractSymbolGroupNodePtrVector(); /* QList<> is: @@ -704,11 +706,13 @@ static inline AbstractSymbolGroupNodePtrVector innerType, count); // Check condition for large||static. bool isLargeOrStatic = innerTypeSize > pointerSize; - if (!isLargeOrStatic) { + if (!isLargeOrStatic && !SymbolGroupValue::isPointerType(innerType)) { const KnownType kt = knownType(innerType, false); // inner type, no 'class ' prefix. - if (kt != KT_Unknown && !(knownType(innerType, false) & (KT_Qt_PrimitiveType|KT_Qt_MovableType))) + if (kt != KT_Unknown && !(kt & (KT_POD_Type|KT_Qt_PrimitiveType|KT_Qt_MovableType))) isLargeOrStatic = true; } + if (debugVector) + DebugPrint() << "isLargeOrStatic " << isLargeOrStatic; if (isLargeOrStatic) { // Retrieve the pointer array ourselves to avoid having to evaluate '*(class foo**)' if (void *data = readPointerArray(arrayAddress, count, v.context())) { diff --git a/src/libs/qtcreatorcdbext/qtcreatorcdbextension.cpp b/src/libs/qtcreatorcdbext/qtcreatorcdbextension.cpp index 96a96d88020..68647605ed4 100644 --- a/src/libs/qtcreatorcdbext/qtcreatorcdbextension.cpp +++ b/src/libs/qtcreatorcdbext/qtcreatorcdbextension.cpp @@ -109,8 +109,9 @@ static const CommandDescription commandDescriptions[] = { "-c complex dumpers"}, {"locals", "Prints local variables of symbol group in GDBMI or debug format", - "[-t token] [T formats] [-I formats] [-f debugfilter] [-c] [-h] [-d] [-e expand-list] [-u uninitialized-list]\n [iname]\n" + "[-t token] [-v] [T formats] [-I formats] [-f debugfilter] [-c] [-h] [-d] [-e expand-list] [-u uninitialized-list]\n [iname]\n" "-h human-readable ouput\n" + "-v increase verboseness of dumping\n" "-d debug output\n" "-f debug_filter\n" "-c complex dumpers\n" @@ -304,6 +305,7 @@ static std::string commmandLocals(ExtensionCommandContext &exc,PCSTR args, int * StringVector expandedInames; StringVector uninitializedInames; DumpParameters parameters; + SymbolGroupValue::verbose = 0; // Parse away options while (!tokens.empty() && tokens.front().size() == 2 && tokens.front().at(0) == '-') { const char option = tokens.front().at(1); @@ -334,6 +336,10 @@ static std::string commmandLocals(ExtensionCommandContext &exc,PCSTR args, int * debugFilter = tokens.front(); tokens.pop_front(); break; + case 'v': + SymbolGroupValue::verbose++; + tokens.pop_front(); + break; case 'e': if (tokens.empty()) { *errorMessage = singleLineUsage(commandDescriptions[CmdLocals]); diff --git a/src/libs/qtcreatorcdbext/symbolgroupnode.cpp b/src/libs/qtcreatorcdbext/symbolgroupnode.cpp index f17d2f7682e..dc52ade5e35 100644 --- a/src/libs/qtcreatorcdbext/symbolgroupnode.cpp +++ b/src/libs/qtcreatorcdbext/symbolgroupnode.cpp @@ -811,17 +811,17 @@ std::wstring SymbolGroupNode::simpleDumpValue(const SymbolGroupValueContext &ctx return symbolGroupFixedValue(); } -void SymbolGroupNode::dump(std::ostream &str, const std::string &visitingFullIname, +int SymbolGroupNode::dump(std::ostream &str, const std::string &visitingFullIname, const DumpParameters &p, const SymbolGroupValueContext &ctx) { - dumpNode(str, name(), visitingFullIname, p, ctx); + return dumpNode(str, name(), visitingFullIname, p, ctx); } -void SymbolGroupNode::dumpNode(std::ostream &str, - const std::string &aName, - const std::string &aFullIName, - const DumpParameters &dumpParameters, - const SymbolGroupValueContext &ctx) +int SymbolGroupNode::dumpNode(std::ostream &str, + const std::string &aName, + const std::string &aFullIName, + const DumpParameters &dumpParameters, + const SymbolGroupValueContext &ctx) { const std::string t = type(); SymbolGroupNode::dumpBasicData(str, aName, aFullIName, t, aFullIName); @@ -867,8 +867,8 @@ void SymbolGroupNode::dumpNode(std::ostream &str, if (childCountGuess != 0) valueEditable = false; str << ",valueenabled=\"" << (valueEnabled ? "true" : "false") << '"' - << ",valueeditable=\"" << (valueEditable ? "true" : "false") << '"' - << ",numchild=\"" << childCountGuess << '"'; + << ",valueeditable=\"" << (valueEditable ? "true" : "false") << '"'; + return childCountGuess; } void SymbolGroupNode::debug(std::ostream &str, @@ -1080,11 +1080,11 @@ ReferenceSymbolGroupNode *ReferenceSymbolGroupNode::createArrayNode(int index, return new ReferenceSymbolGroupNode(nameIname.first, nameIname.second, referencedNode); } -void ReferenceSymbolGroupNode::dump(std::ostream &str, const std::string &visitingFullIname, +int ReferenceSymbolGroupNode::dump(std::ostream &str, const std::string &visitingFullIname, const DumpParameters &p, const SymbolGroupValueContext &ctx) { // Let the referenced node dump with our iname/name - m_referencedNode->dumpNode(str, name(), visitingFullIname, p, ctx); + return m_referencedNode->dumpNode(str, name(), visitingFullIname, p, ctx); } void ReferenceSymbolGroupNode::debug(std::ostream &str, const std::string &visitingFullIname, @@ -1121,14 +1121,15 @@ MapNodeSymbolGroupNode return new MapNodeSymbolGroupNode(nameIname.first, nameIname.second, address, type, keyRN, valueRN); } -void MapNodeSymbolGroupNode::dump(std::ostream &str, const std::string &visitingFullIname, +int MapNodeSymbolGroupNode::dump(std::ostream &str, const std::string &visitingFullIname, const DumpParameters &, const SymbolGroupValueContext &) { SymbolGroupNode::dumpBasicData(str, name(), visitingFullIname); if (m_address) str << ",addr=\"0x" << std::hex << m_address << '"'; str << ",type=\"" << m_type << "\",valueencoded=\"0\",value=\"\",valueenabled=\"false\"" - ",valueeditable=\"false\",numchild=\"2\""; + ",valueeditable=\"false\""; + return 2; } void MapNodeSymbolGroupNode::debug(std::ostream &os, const std::string &visitingFullIname, @@ -1216,7 +1217,10 @@ SymbolGroupNodeVisitor::VisitResult indentStream(m_os, depth * 2); } m_os << '{'; - node->dump(m_os, fullIname, m_parameters, m_context); + const int childCount = node->dump(m_os, fullIname, m_parameters, m_context); + m_os << ",numchild=\"" << childCount << '"'; + if (!childCount) + m_visitChildren = false; if (m_visitChildren) { // open children array m_os << ",children=["; } else { // No children, close array. diff --git a/src/libs/qtcreatorcdbext/symbolgroupnode.h b/src/libs/qtcreatorcdbext/symbolgroupnode.h index 1c019333d21..be4da87dbb3 100644 --- a/src/libs/qtcreatorcdbext/symbolgroupnode.h +++ b/src/libs/qtcreatorcdbext/symbolgroupnode.h @@ -118,9 +118,9 @@ public: const std::string &visitingParentIname, unsigned child, unsigned depth); - // I/O: GDBMI dump for Visitors - virtual void dump(std::ostream &str, const std::string &visitingFullIname, - const DumpParameters &p, const SymbolGroupValueContext &ctx) = 0; + // I/O: GDBMI dump for Visitors, return child count + virtual int dump(std::ostream &str, const std::string &visitingFullIname, + const DumpParameters &p, const SymbolGroupValueContext &ctx) = 0; // I/O: debug output for Visitors virtual void debug(std::ostream &os, const std::string &visitingFullIname, unsigned verbosity, unsigned depth) const; @@ -217,10 +217,10 @@ public: SymbolGroup *symbolGroup() const { return m_symbolGroup; } // I/O: Gdbmi dump for Visitors - virtual void dump(std::ostream &str, const std::string &fullIname, + virtual int dump(std::ostream &str, const std::string &fullIname, const DumpParameters &p, const SymbolGroupValueContext &ctx); - // Dumper functionality for reference nodes. - void dumpNode(std::ostream &str, const std::string &aName, const std::string &aFullIName, + // Dumper functionality for reference nodes, returns child count guess + int dumpNode(std::ostream &str, const std::string &aName, const std::string &aFullIName, const DumpParameters &p, const SymbolGroupValueContext &ctx); // I/O: debug for Visitors @@ -281,7 +281,7 @@ public: static ReferenceSymbolGroupNode *createArrayNode(int index, SymbolGroupNode *referencedNode); - virtual void dump(std::ostream &str, const std::string &visitingFullIname, + virtual int dump(std::ostream &str, const std::string &visitingFullIname, const DumpParameters &p, const SymbolGroupValueContext &ctx); virtual void debug(std::ostream &os, const std::string &visitingFullIname, unsigned verbosity, unsigned depth) const; @@ -311,7 +311,7 @@ public: create(int i, ULONG64 address /* = 0 */, const std::string &type, SymbolGroupNode *key, SymbolGroupNode *value); - virtual void dump(std::ostream &str, const std::string &visitingFullIname, + virtual int dump(std::ostream &str, const std::string &visitingFullIname, const DumpParameters &p, const SymbolGroupValueContext &ctx); virtual void debug(std::ostream &os, const std::string &visitingFullIname, unsigned verbosity, unsigned depth) const; diff --git a/src/libs/qtcreatorcdbext/symbolgroupvalue.cpp b/src/libs/qtcreatorcdbext/symbolgroupvalue.cpp index 73e6f5c94e7..15f59f4e9e9 100644 --- a/src/libs/qtcreatorcdbext/symbolgroupvalue.cpp +++ b/src/libs/qtcreatorcdbext/symbolgroupvalue.cpp @@ -39,6 +39,8 @@ #include #include +unsigned SymbolGroupValue::verbose = 0; + SymbolGroupValue::SymbolGroupValue(const std::string &parentError) : m_node(0), m_errorMessage(parentError) { @@ -50,8 +52,11 @@ SymbolGroupValue::SymbolGroupValue(SymbolGroupNode *node, const SymbolGroupValueContext &ctx) : m_node(node), m_context(ctx) { - if (m_node && !m_node->isMemoryAccessible()) // Invalid if no value + if (m_node && !m_node->isMemoryAccessible()) { // Invalid if no value m_node = 0; + if (SymbolGroupValue::verbose) + DebugPrint() << name() << " memory access error"; + } } SymbolGroupValue::SymbolGroupValue() : @@ -70,6 +75,8 @@ SymbolGroupValue SymbolGroupValue::operator[](unsigned index) const if (index < m_node->children().size()) if (SymbolGroupNode *n = m_node->childAt(index)->asSymbolGroupNode()) return SymbolGroupValue(n, m_context); + if (SymbolGroupValue::verbose) + DebugPrint() << this->name() << "::operator[" << index << "](const char*) fails"; return SymbolGroupValue(m_errorMessage); } @@ -87,6 +94,8 @@ bool SymbolGroupValue::ensureExpanded() const m_node->addFlags(SymbolGroupNode::ExpandedByDumper); return true; } + if (SymbolGroupValue::verbose) + DebugPrint() << "Expand failure of '" << name() << "': " << m_errorMessage; return false; } @@ -96,6 +105,8 @@ SymbolGroupValue SymbolGroupValue::operator[](const char *name) const if (AbstractSymbolGroupNode *child = m_node->childByIName(name)) if (SymbolGroupNode *n = child->asSymbolGroupNode()) return SymbolGroupValue(n, m_context); + if (SymbolGroupValue::verbose) + DebugPrint() << this->name() << "::operator[](" << name << ") fails for " << name; return SymbolGroupValue(m_errorMessage); } @@ -143,6 +154,8 @@ int SymbolGroupValue::intValue(int defaultValue) const if (integerFromString(wStringToString(v), &rc)) return rc; } + if (SymbolGroupValue::verbose) + DebugPrint() << name() << "::intValue() fails"; return defaultValue; } @@ -153,6 +166,8 @@ ULONG64 SymbolGroupValue::pointerValue(ULONG64 defaultValue) const if (integerFromString(wStringToString(value()), &rc)) return rc; } + if (SymbolGroupValue::verbose) + DebugPrint() << name() << "::pointerValue() fails"; return defaultValue; } diff --git a/src/libs/qtcreatorcdbext/symbolgroupvalue.h b/src/libs/qtcreatorcdbext/symbolgroupvalue.h index 9a0ea67536f..28c8ddb99c5 100644 --- a/src/libs/qtcreatorcdbext/symbolgroupvalue.h +++ b/src/libs/qtcreatorcdbext/symbolgroupvalue.h @@ -119,6 +119,8 @@ public: // get the inner types: "QMap" -> "int", "double" static std::vector innerTypesOf(const std::string &t); + static unsigned verbose; + private: bool ensureExpanded() const; SymbolGroupValue typeCastedValue(ULONG64 address, const char *type) const;