Debugger[New CDB]: Fix QList.

- Account for POD types in largeStatic-Check
- Avoid dumping empty children list (move handling to visitor)
- Verbose facility.
This commit is contained in:
Friedemann Kleint
2011-01-05 16:50:26 +01:00
parent 10cb3af03c
commit 29ad8a4561
6 changed files with 57 additions and 26 deletions

View File

@@ -687,6 +687,8 @@ static inline AbstractSymbolGroupNodePtrVector
return AbstractSymbolGroupNodePtrVector(); return AbstractSymbolGroupNodePtrVector();
const std::string innerType = fixInnerType(innerTypes.front(), v.context()); const std::string innerType = fixInnerType(innerTypes.front(), v.context());
const unsigned innerTypeSize = SymbolGroupValue::sizeOf(innerType.c_str()); const unsigned innerTypeSize = SymbolGroupValue::sizeOf(innerType.c_str());
if (debugVector)
DebugPrint() << "QList " << v.name() << " inner type " << innerType << ' ' << innerTypeSize;
if (!innerTypeSize) if (!innerTypeSize)
return AbstractSymbolGroupNodePtrVector(); return AbstractSymbolGroupNodePtrVector();
/* QList<> is: /* QList<> is:
@@ -704,11 +706,13 @@ static inline AbstractSymbolGroupNodePtrVector
innerType, count); innerType, count);
// Check condition for large||static. // Check condition for large||static.
bool isLargeOrStatic = innerTypeSize > pointerSize; bool isLargeOrStatic = innerTypeSize > pointerSize;
if (!isLargeOrStatic) { if (!isLargeOrStatic && !SymbolGroupValue::isPointerType(innerType)) {
const KnownType kt = knownType(innerType, false); // inner type, no 'class ' prefix. 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; isLargeOrStatic = true;
} }
if (debugVector)
DebugPrint() << "isLargeOrStatic " << isLargeOrStatic;
if (isLargeOrStatic) { if (isLargeOrStatic) {
// Retrieve the pointer array ourselves to avoid having to evaluate '*(class foo**)' // Retrieve the pointer array ourselves to avoid having to evaluate '*(class foo**)'
if (void *data = readPointerArray(arrayAddress, count, v.context())) { if (void *data = readPointerArray(arrayAddress, count, v.context())) {

View File

@@ -109,8 +109,9 @@ static const CommandDescription commandDescriptions[] = {
"-c complex dumpers"}, "-c complex dumpers"},
{"locals", {"locals",
"Prints local variables of symbol group in GDBMI or debug format", "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" "-h human-readable ouput\n"
"-v increase verboseness of dumping\n"
"-d debug output\n" "-d debug output\n"
"-f debug_filter\n" "-f debug_filter\n"
"-c complex dumpers\n" "-c complex dumpers\n"
@@ -304,6 +305,7 @@ static std::string commmandLocals(ExtensionCommandContext &exc,PCSTR args, int *
StringVector expandedInames; StringVector expandedInames;
StringVector uninitializedInames; StringVector uninitializedInames;
DumpParameters parameters; DumpParameters parameters;
SymbolGroupValue::verbose = 0;
// Parse away options // Parse away options
while (!tokens.empty() && tokens.front().size() == 2 && tokens.front().at(0) == '-') { while (!tokens.empty() && tokens.front().size() == 2 && tokens.front().at(0) == '-') {
const char option = tokens.front().at(1); const char option = tokens.front().at(1);
@@ -334,6 +336,10 @@ static std::string commmandLocals(ExtensionCommandContext &exc,PCSTR args, int *
debugFilter = tokens.front(); debugFilter = tokens.front();
tokens.pop_front(); tokens.pop_front();
break; break;
case 'v':
SymbolGroupValue::verbose++;
tokens.pop_front();
break;
case 'e': case 'e':
if (tokens.empty()) { if (tokens.empty()) {
*errorMessage = singleLineUsage(commandDescriptions[CmdLocals]); *errorMessage = singleLineUsage(commandDescriptions[CmdLocals]);

View File

@@ -811,13 +811,13 @@ std::wstring SymbolGroupNode::simpleDumpValue(const SymbolGroupValueContext &ctx
return symbolGroupFixedValue(); 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) 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, int SymbolGroupNode::dumpNode(std::ostream &str,
const std::string &aName, const std::string &aName,
const std::string &aFullIName, const std::string &aFullIName,
const DumpParameters &dumpParameters, const DumpParameters &dumpParameters,
@@ -867,8 +867,8 @@ void SymbolGroupNode::dumpNode(std::ostream &str,
if (childCountGuess != 0) if (childCountGuess != 0)
valueEditable = false; valueEditable = false;
str << ",valueenabled=\"" << (valueEnabled ? "true" : "false") << '"' str << ",valueenabled=\"" << (valueEnabled ? "true" : "false") << '"'
<< ",valueeditable=\"" << (valueEditable ? "true" : "false") << '"' << ",valueeditable=\"" << (valueEditable ? "true" : "false") << '"';
<< ",numchild=\"" << childCountGuess << '"'; return childCountGuess;
} }
void SymbolGroupNode::debug(std::ostream &str, void SymbolGroupNode::debug(std::ostream &str,
@@ -1080,11 +1080,11 @@ ReferenceSymbolGroupNode *ReferenceSymbolGroupNode::createArrayNode(int index,
return new ReferenceSymbolGroupNode(nameIname.first, nameIname.second, referencedNode); 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) const DumpParameters &p, const SymbolGroupValueContext &ctx)
{ {
// Let the referenced node dump with our iname/name // 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, 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); 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 &) const DumpParameters &, const SymbolGroupValueContext &)
{ {
SymbolGroupNode::dumpBasicData(str, name(), visitingFullIname); SymbolGroupNode::dumpBasicData(str, name(), visitingFullIname);
if (m_address) if (m_address)
str << ",addr=\"0x" << std::hex << m_address << '"'; str << ",addr=\"0x" << std::hex << m_address << '"';
str << ",type=\"" << m_type << "\",valueencoded=\"0\",value=\"\",valueenabled=\"false\"" 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, void MapNodeSymbolGroupNode::debug(std::ostream &os, const std::string &visitingFullIname,
@@ -1216,7 +1217,10 @@ SymbolGroupNodeVisitor::VisitResult
indentStream(m_os, depth * 2); indentStream(m_os, depth * 2);
} }
m_os << '{'; 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 if (m_visitChildren) { // open children array
m_os << ",children=["; m_os << ",children=[";
} else { // No children, close array. } else { // No children, close array.

View File

@@ -118,8 +118,8 @@ public:
const std::string &visitingParentIname, const std::string &visitingParentIname,
unsigned child, unsigned depth); unsigned child, unsigned depth);
// I/O: GDBMI dump for Visitors // I/O: GDBMI dump for Visitors, return child count
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) = 0; const DumpParameters &p, const SymbolGroupValueContext &ctx) = 0;
// I/O: debug output for Visitors // I/O: debug output for Visitors
virtual void debug(std::ostream &os, const std::string &visitingFullIname, virtual void debug(std::ostream &os, const std::string &visitingFullIname,
@@ -217,10 +217,10 @@ public:
SymbolGroup *symbolGroup() const { return m_symbolGroup; } SymbolGroup *symbolGroup() const { return m_symbolGroup; }
// I/O: Gdbmi dump for Visitors // 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); const DumpParameters &p, const SymbolGroupValueContext &ctx);
// Dumper functionality for reference nodes. // Dumper functionality for reference nodes, returns child count guess
void dumpNode(std::ostream &str, const std::string &aName, const std::string &aFullIName, int dumpNode(std::ostream &str, const std::string &aName, const std::string &aFullIName,
const DumpParameters &p, const SymbolGroupValueContext &ctx); const DumpParameters &p, const SymbolGroupValueContext &ctx);
// I/O: debug for Visitors // I/O: debug for Visitors
@@ -281,7 +281,7 @@ public:
static ReferenceSymbolGroupNode *createArrayNode(int index, static ReferenceSymbolGroupNode *createArrayNode(int index,
SymbolGroupNode *referencedNode); 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); const DumpParameters &p, const SymbolGroupValueContext &ctx);
virtual void debug(std::ostream &os, const std::string &visitingFullIname, virtual void debug(std::ostream &os, const std::string &visitingFullIname,
unsigned verbosity, unsigned depth) const; unsigned verbosity, unsigned depth) const;
@@ -311,7 +311,7 @@ public:
create(int i, ULONG64 address /* = 0 */, const std::string &type, create(int i, ULONG64 address /* = 0 */, const std::string &type,
SymbolGroupNode *key, SymbolGroupNode *value); 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); const DumpParameters &p, const SymbolGroupValueContext &ctx);
virtual void debug(std::ostream &os, const std::string &visitingFullIname, virtual void debug(std::ostream &os, const std::string &visitingFullIname,
unsigned verbosity, unsigned depth) const; unsigned verbosity, unsigned depth) const;

View File

@@ -39,6 +39,8 @@
#include <iomanip> #include <iomanip>
#include <algorithm> #include <algorithm>
unsigned SymbolGroupValue::verbose = 0;
SymbolGroupValue::SymbolGroupValue(const std::string &parentError) : SymbolGroupValue::SymbolGroupValue(const std::string &parentError) :
m_node(0), m_errorMessage(parentError) m_node(0), m_errorMessage(parentError)
{ {
@@ -50,8 +52,11 @@ SymbolGroupValue::SymbolGroupValue(SymbolGroupNode *node,
const SymbolGroupValueContext &ctx) : const SymbolGroupValueContext &ctx) :
m_node(node), m_context(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; m_node = 0;
if (SymbolGroupValue::verbose)
DebugPrint() << name() << " memory access error";
}
} }
SymbolGroupValue::SymbolGroupValue() : SymbolGroupValue::SymbolGroupValue() :
@@ -70,6 +75,8 @@ SymbolGroupValue SymbolGroupValue::operator[](unsigned index) const
if (index < m_node->children().size()) if (index < m_node->children().size())
if (SymbolGroupNode *n = m_node->childAt(index)->asSymbolGroupNode()) if (SymbolGroupNode *n = m_node->childAt(index)->asSymbolGroupNode())
return SymbolGroupValue(n, m_context); return SymbolGroupValue(n, m_context);
if (SymbolGroupValue::verbose)
DebugPrint() << this->name() << "::operator[" << index << "](const char*) fails";
return SymbolGroupValue(m_errorMessage); return SymbolGroupValue(m_errorMessage);
} }
@@ -87,6 +94,8 @@ bool SymbolGroupValue::ensureExpanded() const
m_node->addFlags(SymbolGroupNode::ExpandedByDumper); m_node->addFlags(SymbolGroupNode::ExpandedByDumper);
return true; return true;
} }
if (SymbolGroupValue::verbose)
DebugPrint() << "Expand failure of '" << name() << "': " << m_errorMessage;
return false; return false;
} }
@@ -96,6 +105,8 @@ SymbolGroupValue SymbolGroupValue::operator[](const char *name) const
if (AbstractSymbolGroupNode *child = m_node->childByIName(name)) if (AbstractSymbolGroupNode *child = m_node->childByIName(name))
if (SymbolGroupNode *n = child->asSymbolGroupNode()) if (SymbolGroupNode *n = child->asSymbolGroupNode())
return SymbolGroupValue(n, m_context); return SymbolGroupValue(n, m_context);
if (SymbolGroupValue::verbose)
DebugPrint() << this->name() << "::operator[](" << name << ") fails for " << name;
return SymbolGroupValue(m_errorMessage); return SymbolGroupValue(m_errorMessage);
} }
@@ -143,6 +154,8 @@ int SymbolGroupValue::intValue(int defaultValue) const
if (integerFromString(wStringToString(v), &rc)) if (integerFromString(wStringToString(v), &rc))
return rc; return rc;
} }
if (SymbolGroupValue::verbose)
DebugPrint() << name() << "::intValue() fails";
return defaultValue; return defaultValue;
} }
@@ -153,6 +166,8 @@ ULONG64 SymbolGroupValue::pointerValue(ULONG64 defaultValue) const
if (integerFromString(wStringToString(value()), &rc)) if (integerFromString(wStringToString(value()), &rc))
return rc; return rc;
} }
if (SymbolGroupValue::verbose)
DebugPrint() << name() << "::pointerValue() fails";
return defaultValue; return defaultValue;
} }

View File

@@ -119,6 +119,8 @@ public:
// get the inner types: "QMap<int, double>" -> "int", "double" // get the inner types: "QMap<int, double>" -> "int", "double"
static std::vector<std::string> innerTypesOf(const std::string &t); static std::vector<std::string> innerTypesOf(const std::string &t);
static unsigned verbose;
private: private:
bool ensureExpanded() const; bool ensureExpanded() const;
SymbolGroupValue typeCastedValue(ULONG64 address, const char *type) const; SymbolGroupValue typeCastedValue(ULONG64 address, const char *type) const;