CdbExt: Make max array size configurable.

Change-Id: I1bbf028e94160701726afc6cad1f4f529287a451
Reviewed-by: Friedemann Kleint <Friedemann.Kleint@digia.com>
This commit is contained in:
David Schulz
2014-03-11 08:26:54 +01:00
parent f5d97d48f8
commit 64c4779244
5 changed files with 38 additions and 31 deletions

View File

@@ -31,6 +31,7 @@
#include "symbolgroupvalue.h" #include "symbolgroupvalue.h"
#include "symbolgroup.h" #include "symbolgroup.h"
#include "stringutils.h" #include "stringutils.h"
#include "extensioncontext.h"
#include <functional> #include <functional>
#include <iterator> #include <iterator>
@@ -225,13 +226,13 @@ int containerSize(KnownType kt, const SymbolGroupValue &v)
* and the next link */ * and the next link */
template <class ValueFunction, class NextFunction> template <class ValueFunction, class NextFunction>
AbstractSymbolGroupNodePtrVector linkedListChildList(SymbolGroupValue headNode, AbstractSymbolGroupNodePtrVector linkedListChildList(SymbolGroupValue headNode,
int count, unsigned count,
ValueFunction valueFunc, ValueFunction valueFunc,
NextFunction nextFunc) NextFunction nextFunc)
{ {
AbstractSymbolGroupNodePtrVector rc; AbstractSymbolGroupNodePtrVector rc;
rc.reserve(count); rc.reserve(count);
for (int i =0; i < count && headNode; i++) { for (unsigned i = 0; i < count && headNode; i++) {
if (const SymbolGroupValue value = valueFunc(headNode)) { if (const SymbolGroupValue value = valueFunc(headNode)) {
rc.push_back(ReferenceSymbolGroupNode::createArrayNode(i, value.node())); rc.push_back(ReferenceSymbolGroupNode::createArrayNode(i, value.node()));
headNode = nextFunc(headNode); headNode = nextFunc(headNode);
@@ -254,7 +255,7 @@ private:
}; };
// std::list<T>: Skip dummy head node and then a linked list of "_Next", "_Myval". // std::list<T>: Skip dummy head node and then a linked list of "_Next", "_Myval".
static inline AbstractSymbolGroupNodePtrVector stdListChildList(SymbolGroupNode *n, int count, static inline AbstractSymbolGroupNodePtrVector stdListChildList(SymbolGroupNode *n, unsigned count,
const SymbolGroupValueContext &ctx) const SymbolGroupValueContext &ctx)
{ {
if (!count) if (!count)
@@ -267,13 +268,13 @@ static inline AbstractSymbolGroupNodePtrVector stdListChildList(SymbolGroupNode
return AbstractSymbolGroupNodePtrVector(); return AbstractSymbolGroupNodePtrVector();
} }
static inline AbstractSymbolGroupNodePtrVector stdArrayChildList(SymbolGroupNode *n, int count, static inline AbstractSymbolGroupNodePtrVector stdArrayChildList(SymbolGroupNode *n, unsigned count,
const SymbolGroupValueContext &ctx) const SymbolGroupValueContext &ctx)
{ {
AbstractSymbolGroupNodePtrVector rc; AbstractSymbolGroupNodePtrVector rc;
if (SymbolGroupValue elems = SymbolGroupValue(n, ctx)["_Elems"]) { if (SymbolGroupValue elems = SymbolGroupValue(n, ctx)["_Elems"]) {
rc.reserve(count); rc.reserve(count);
for (int i = 0; i < count; ++i) { for (unsigned i = 0; i < count; ++i) {
if (const SymbolGroupValue value = elems[i]) if (const SymbolGroupValue value = elems[i])
rc.push_back(ReferenceSymbolGroupNode::createArrayNode(i, value.node())); rc.push_back(ReferenceSymbolGroupNode::createArrayNode(i, value.node()));
else else
@@ -284,8 +285,8 @@ static inline AbstractSymbolGroupNodePtrVector stdArrayChildList(SymbolGroupNode
} }
// QLinkedList<T>: Dummy head node and then a linked list of "n", "t". // QLinkedList<T>: Dummy head node and then a linked list of "n", "t".
static inline AbstractSymbolGroupNodePtrVector qLinkedListChildList(SymbolGroupNode *n, int count, static inline AbstractSymbolGroupNodePtrVector qLinkedListChildList(
const SymbolGroupValueContext &ctx) SymbolGroupNode *n, unsigned count, const SymbolGroupValueContext &ctx)
{ {
if (count) if (count)
if (const SymbolGroupValue head = SymbolGroupValue(n, ctx)["e"]["n"]) if (const SymbolGroupValue head = SymbolGroupValue(n, ctx)["e"]["n"])
@@ -301,14 +302,14 @@ template <class AddressFunc>
AbstractSymbolGroupNodePtrVector arrayChildList(SymbolGroup *sg, AddressFunc addressFunc, AbstractSymbolGroupNodePtrVector arrayChildList(SymbolGroup *sg, AddressFunc addressFunc,
const std::string &module, const std::string &module,
const std::string &innerType, const std::string &innerType,
int count) unsigned count)
{ {
AbstractSymbolGroupNodePtrVector rc; AbstractSymbolGroupNodePtrVector rc;
if (!count) if (!count)
return rc; return rc;
std::string errorMessage; std::string errorMessage;
rc.reserve(count); rc.reserve(count);
for (int i = 0; i < count; i++) { for (unsigned i = 0; i < count; i++) {
const std::string name = SymbolGroupValue::pointedToSymbolName(addressFunc(), innerType); const std::string name = SymbolGroupValue::pointedToSymbolName(addressFunc(), innerType);
if (SymbolGroupNode *child = sg->addSymbol(module, name, std::string(), &errorMessage)) { if (SymbolGroupNode *child = sg->addSymbol(module, name, std::string(), &errorMessage)) {
rc.push_back(ReferenceSymbolGroupNode::createArrayNode(i, child)); rc.push_back(ReferenceSymbolGroupNode::createArrayNode(i, child));
@@ -344,7 +345,7 @@ private:
static inline AbstractSymbolGroupNodePtrVector static inline AbstractSymbolGroupNodePtrVector
arrayChildList(SymbolGroup *sg, ULONG64 address, const std::string &module, arrayChildList(SymbolGroup *sg, ULONG64 address, const std::string &module,
const std::string &innerType, int count) const std::string &innerType, unsigned count)
{ {
if (const unsigned innerTypeSize = SymbolGroupValue::sizeOf(innerType.c_str())) if (const unsigned innerTypeSize = SymbolGroupValue::sizeOf(innerType.c_str()))
return arrayChildList(sg, AddressSequence(address, innerTypeSize), return arrayChildList(sg, AddressSequence(address, innerTypeSize),
@@ -354,7 +355,7 @@ static inline AbstractSymbolGroupNodePtrVector
// std::vector<T> // std::vector<T>
static inline AbstractSymbolGroupNodePtrVector static inline AbstractSymbolGroupNodePtrVector
stdVectorChildList(SymbolGroupNode *n, int count, const SymbolGroupValueContext &ctx) stdVectorChildList(SymbolGroupNode *n, unsigned count, const SymbolGroupValueContext &ctx)
{ {
if (!count) if (!count)
return AbstractSymbolGroupNodePtrVector(); return AbstractSymbolGroupNodePtrVector();
@@ -382,14 +383,14 @@ AbstractSymbolGroupNodePtrVector
const AddressType *blockArray, ULONG64 blockArraySize, const AddressType *blockArray, ULONG64 blockArraySize,
const std::string &module, const std::string &module,
const std::string &innerType, ULONG64 innerTypeSize, const std::string &innerType, ULONG64 innerTypeSize,
ULONG64 startOffset, ULONG64 dequeSize, int count) ULONG64 startOffset, ULONG64 dequeSize, unsigned count)
{ {
AbstractSymbolGroupNodePtrVector rc; AbstractSymbolGroupNodePtrVector rc;
rc.reserve(count); rc.reserve(count);
std::string errorMessage; std::string errorMessage;
// Determine block number and offset in the block array T[][dequeSize] // Determine block number and offset in the block array T[][dequeSize]
// and create symbol by address. // and create symbol by address.
for (int i = 0; i < count; i++) { for (unsigned i = 0; i < count; i++) {
// see <deque>-header: std::deque<T>::iterator::operator* // see <deque>-header: std::deque<T>::iterator::operator*
const ULONG64 offset = startOffset + i; const ULONG64 offset = startOffset + i;
ULONG64 block = offset / dequeSize; ULONG64 block = offset / dequeSize;
@@ -407,7 +408,7 @@ AbstractSymbolGroupNodePtrVector
// std::deque<> // std::deque<>
static inline AbstractSymbolGroupNodePtrVector static inline AbstractSymbolGroupNodePtrVector
stdDequeChildList(const SymbolGroupValue &dequeIn, int count) stdDequeChildList(const SymbolGroupValue &dequeIn, unsigned count)
{ {
if (!count) if (!count)
return AbstractSymbolGroupNodePtrVector(); return AbstractSymbolGroupNodePtrVector();
@@ -618,29 +619,29 @@ static inline SymbolGroupValueVector
// std::set<>: Children directly contained in list // std::set<>: Children directly contained in list
static inline AbstractSymbolGroupNodePtrVector static inline AbstractSymbolGroupNodePtrVector
stdSetChildList(const SymbolGroupValue &set, int count) stdSetChildList(const SymbolGroupValue &set, unsigned count)
{ {
const SymbolGroupValueVector children = stdTreeChildList(set, count); const SymbolGroupValueVector children = stdTreeChildList(set, count);
if (int(children.size()) != count) if (int(children.size()) != count)
return AbstractSymbolGroupNodePtrVector(); return AbstractSymbolGroupNodePtrVector();
AbstractSymbolGroupNodePtrVector rc; AbstractSymbolGroupNodePtrVector rc;
rc.reserve(count); rc.reserve(count);
for (int i = 0; i < count; i++) for (unsigned i = 0; i < count; i++)
rc.push_back(ReferenceSymbolGroupNode::createArrayNode(i, children.at(i).node())); rc.push_back(ReferenceSymbolGroupNode::createArrayNode(i, children.at(i).node()));
return rc; return rc;
} }
// std::map<K,V>: A list of std::pair<K,V> (derived from std::pair_base<K,V>) // std::map<K,V>: A list of std::pair<K,V> (derived from std::pair_base<K,V>)
static inline AbstractSymbolGroupNodePtrVector static inline AbstractSymbolGroupNodePtrVector
stdMapChildList(const SymbolGroupValue &map, int count) stdMapChildList(const SymbolGroupValue &map, unsigned count)
{ {
const SymbolGroupValueVector children = stdTreeChildList(map[unsigned(0)], count); const SymbolGroupValueVector children = stdTreeChildList(map[unsigned(0)], count);
if (int(children.size()) != count) if (children.size() != count)
return AbstractSymbolGroupNodePtrVector(); return AbstractSymbolGroupNodePtrVector();
AbstractSymbolGroupNodePtrVector rc; AbstractSymbolGroupNodePtrVector rc;
rc.reserve(count); rc.reserve(count);
const std::string firstName = "first"; const std::string firstName = "first";
for (int i = 0; i < count; i++) { for (unsigned i = 0; i < count; i++) {
// MSVC2010 (only) has a std::pair_base class. // MSVC2010 (only) has a std::pair_base class.
const SymbolGroupValue key = SymbolGroupValue::findMember(children.at(i), firstName); const SymbolGroupValue key = SymbolGroupValue::findMember(children.at(i), firstName);
const SymbolGroupValue pairBase = key.parent(); const SymbolGroupValue pairBase = key.parent();
@@ -658,7 +659,7 @@ static inline AbstractSymbolGroupNodePtrVector
// QVector<T> // QVector<T>
static inline AbstractSymbolGroupNodePtrVector static inline AbstractSymbolGroupNodePtrVector
qVectorChildList(SymbolGroupNode *n, int count, const SymbolGroupValueContext &ctx) qVectorChildList(SymbolGroupNode *n, unsigned count, const SymbolGroupValueContext &ctx)
{ {
if (!count) if (!count)
return AbstractSymbolGroupNodePtrVector(); return AbstractSymbolGroupNodePtrVector();
@@ -706,7 +707,7 @@ private:
// QList<>. // QList<>.
static inline AbstractSymbolGroupNodePtrVector static inline AbstractSymbolGroupNodePtrVector
qListChildList(const SymbolGroupValue &v, int count) qListChildList(const SymbolGroupValue &v, unsigned count)
{ {
// QList<T>: d/array is declared as array of void *[]. Dereference first // QList<T>: d/array is declared as array of void *[]. Dereference first
// element to obtain address. // element to obtain address.
@@ -898,7 +899,7 @@ SymbolGroupValueVector qHashNodes(const SymbolGroupValue &v,
// QSet<>: Contains a 'QHash<key, QHashDummyValue>' as member 'q_hash'. // QSet<>: Contains a 'QHash<key, QHashDummyValue>' as member 'q_hash'.
// Just dump the keys as an array. // Just dump the keys as an array.
static inline AbstractSymbolGroupNodePtrVector static inline AbstractSymbolGroupNodePtrVector
qSetChildList(const SymbolGroupValue &v, int count) qSetChildList(const SymbolGroupValue &v, unsigned count)
{ {
const SymbolGroupValue qHash = v["q_hash"]; const SymbolGroupValue qHash = v["q_hash"];
AbstractSymbolGroupNodePtrVector rc; AbstractSymbolGroupNodePtrVector rc;
@@ -908,7 +909,7 @@ static inline AbstractSymbolGroupNodePtrVector
if (nodes.size() != VectorIndexType(count)) if (nodes.size() != VectorIndexType(count))
return rc; return rc;
rc.reserve(count); rc.reserve(count);
for (int i = 0; i < count; i++) { for (unsigned i = 0; i < count; i++) {
if (const SymbolGroupValue key = nodes.at(i)["key"]) if (const SymbolGroupValue key = nodes.at(i)["key"])
rc.push_back(ReferenceSymbolGroupNode::createArrayNode(i, key.node())); rc.push_back(ReferenceSymbolGroupNode::createArrayNode(i, key.node()));
else else
@@ -919,7 +920,7 @@ static inline AbstractSymbolGroupNodePtrVector
// QHash<>: Add with fake map nodes. // QHash<>: Add with fake map nodes.
static inline AbstractSymbolGroupNodePtrVector static inline AbstractSymbolGroupNodePtrVector
qHashChildList(const SymbolGroupValue &v, int count) qHashChildList(const SymbolGroupValue &v, unsigned count)
{ {
AbstractSymbolGroupNodePtrVector rc; AbstractSymbolGroupNodePtrVector rc;
if (!count) if (!count)
@@ -928,7 +929,7 @@ static inline AbstractSymbolGroupNodePtrVector
if (nodes.size() != count) if (nodes.size() != count)
return rc; return rc;
rc.reserve(count); rc.reserve(count);
for (int i = 0; i < count; i++) { for (unsigned i = 0; i < count; i++) {
const SymbolGroupValue &mapNode = nodes.at(i); const SymbolGroupValue &mapNode = nodes.at(i);
const SymbolGroupValue key = mapNode["key"]; const SymbolGroupValue key = mapNode["key"];
const SymbolGroupValue value = mapNode["value"]; const SymbolGroupValue value = mapNode["value"];
@@ -1090,7 +1091,7 @@ static inline AbstractSymbolGroupNodePtrVector
/*! Determine children of containers \ingroup qtcreatorcdbext */ /*! Determine children of containers \ingroup qtcreatorcdbext */
AbstractSymbolGroupNodePtrVector containerChildren(SymbolGroupNode *node, int type, AbstractSymbolGroupNodePtrVector containerChildren(SymbolGroupNode *node, int type,
int size, const SymbolGroupValueContext &ctx) unsigned size, const SymbolGroupValueContext &ctx)
{ {
if (SymbolGroupValue::verbose) { if (SymbolGroupValue::verbose) {
DebugPrint dp; DebugPrint dp;
@@ -1102,8 +1103,9 @@ AbstractSymbolGroupNodePtrVector containerChildren(SymbolGroupNode *node, int ty
} }
if (!size) if (!size)
return AbstractSymbolGroupNodePtrVector(); return AbstractSymbolGroupNodePtrVector();
if (size > 100) const unsigned maxArraySize = ExtensionContext::instance().parameters().maxArraySize;
size = 100; if (size > maxArraySize)
size = maxArraySize;
switch (type) { switch (type) {
case KT_QVector: case KT_QVector:
return qVectorChildList(node, size, ctx); return qVectorChildList(node, size, ctx);

View File

@@ -47,7 +47,7 @@ int containerSize(KnownType kt, SymbolGroupNode *n, const SymbolGroupValueContex
/* Create a list of children of containers. */ /* Create a list of children of containers. */
std::vector<AbstractSymbolGroupNode *> containerChildren(SymbolGroupNode *node, std::vector<AbstractSymbolGroupNode *> containerChildren(SymbolGroupNode *node,
int type, int type,
int size, unsigned size,
const SymbolGroupValueContext &ctx); const SymbolGroupValueContext &ctx);
#endif // CONTAINERS_H #endif // CONTAINERS_H

View File

@@ -50,7 +50,7 @@ const char *ExtensionContext::breakPointStopReasonC = "breakpoint";
\ingroup qtcreatorcdbext \ingroup qtcreatorcdbext
*/ */
Parameters::Parameters() : maxStringLength(10000), maxStackDepth(1000) Parameters::Parameters() : maxStringLength(10000), maxArraySize(100) ,maxStackDepth(1000)
{ {
} }

View File

@@ -48,6 +48,7 @@ public:
Parameters(); Parameters();
unsigned maxStringLength; unsigned maxStringLength;
unsigned maxArraySize;
unsigned maxStackDepth; unsigned maxStackDepth;
}; };

View File

@@ -174,7 +174,8 @@ static const CommandDescription commandDescriptions[] = {
{"widgetat","Return address of widget at position","<x> <y>"}, {"widgetat","Return address of widget at position","<x> <y>"},
{"breakpoints","List breakpoints with modules","[-h] [-v]"}, {"breakpoints","List breakpoints with modules","[-h] [-v]"},
{"test","Testing command","-T type | -w watch-expression"}, {"test","Testing command","-T type | -w watch-expression"},
{"setparameter","Set parameter","maxStringLength=value maxStackDepth=value stateNotification=1,0"} {"setparameter","Set parameter",
"maxStringLength=value maxArraySize=value maxStackDepth=value stateNotification=1,0"}
}; };
typedef std::vector<std::string> StringVector; typedef std::vector<std::string> StringVector;
@@ -912,6 +913,9 @@ extern "C" HRESULT CALLBACK setparameter(CIDebugClient *, PCSTR args)
if (!token.compare(0, equalsPos, "maxStringLength")) { if (!token.compare(0, equalsPos, "maxStringLength")) {
if (integerFromString(value, &ExtensionContext::instance().parameters().maxStringLength)) if (integerFromString(value, &ExtensionContext::instance().parameters().maxStringLength))
++success; ++success;
} else if (!token.compare(0, equalsPos, "maxArraySize")) {
if (integerFromString(value, &ExtensionContext::instance().parameters().maxArraySize))
++success;
} else if (!token.compare(0, equalsPos, "maxStackDepth")) { } else if (!token.compare(0, equalsPos, "maxStackDepth")) {
if (integerFromString(value, &ExtensionContext::instance().parameters().maxStackDepth)) if (integerFromString(value, &ExtensionContext::instance().parameters().maxStackDepth))
++success; ++success;