OSDN Git Service

Debugger[New CDB]: Fix QList.
authorFriedemann Kleint <Friedemann.Kleint@nokia.com>
Wed, 5 Jan 2011 15:50:26 +0000 (16:50 +0100)
committerFriedemann Kleint <Friedemann.Kleint@nokia.com>
Wed, 5 Jan 2011 15:52:30 +0000 (16:52 +0100)
- Account for POD types in largeStatic-Check
- Avoid dumping empty children list (move handling to visitor)
- Verbose facility.

src/libs/qtcreatorcdbext/containers.cpp
src/libs/qtcreatorcdbext/qtcreatorcdbextension.cpp
src/libs/qtcreatorcdbext/symbolgroupnode.cpp
src/libs/qtcreatorcdbext/symbolgroupnode.h
src/libs/qtcreatorcdbext/symbolgroupvalue.cpp
src/libs/qtcreatorcdbext/symbolgroupvalue.h

index 9e28cf0..63f8d2c 100644 (file)
@@ -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()))  {
index 96a96d8..6864760 100644 (file)
@@ -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<frame-number> [iname]\n"
+ "[-t token] [-v] [T formats] [-I formats] [-f debugfilter] [-c] [-h] [-d] [-e expand-list] [-u uninitialized-list]\n<frame-number> [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]);
index f17d2f7..dc52ade 100644 (file)
@@ -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.
index 1c01933..be4da87 100644 (file)
@@ -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;
index 73e6f5c..15f59f4 100644 (file)
@@ -39,6 +39,8 @@
 #include <iomanip>
 #include <algorithm>
 
+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;
 }
 
index 9a0ea67..28c8ddb 100644 (file)
@@ -119,6 +119,8 @@ public:
     // get the inner types: "QMap<int, double>" -> "int", "double"
     static std::vector<std::string> innerTypesOf(const std::string &t);
 
+    static unsigned verbose;
+
 private:
     bool ensureExpanded() const;
     SymbolGroupValue typeCastedValue(ULONG64 address, const char *type) const;