forked from qt-creator/qt-creator
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:
@@ -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())) {
|
||||||
|
|||||||
@@ -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]);
|
||||||
|
|||||||
@@ -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.
|
||||||
|
|||||||
@@ -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;
|
||||||
|
|||||||
@@ -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;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -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;
|
||||||
|
|||||||
Reference in New Issue
Block a user