Skip to content
Snippets Groups Projects
Commit 7fa7ec98 authored by Friedemann Kleint's avatar Friedemann Kleint
Browse files

Debugger[New CDB]: Do not add begin twice for QList<Large>.

Factor out some utilities for hashes.
parent 6723f92a
No related branches found
No related tags found
No related merge requests found
...@@ -36,15 +36,19 @@ ...@@ -36,15 +36,19 @@
typedef AbstractSymbolGroupNode::AbstractSymbolGroupNodePtrVector AbstractSymbolGroupNodePtrVector; typedef AbstractSymbolGroupNode::AbstractSymbolGroupNodePtrVector AbstractSymbolGroupNodePtrVector;
// Return size of container or -1 // Read a pointer array from debuggee memory (ULONG64/32 according pointer size)
int containerSize(KnownType kt, SymbolGroupNode *n, const SymbolGroupValueContext &ctx) static void *readPointerArray(ULONG64 address, unsigned count, const SymbolGroupValueContext &ctx)
{ {
QTC_TRACE_IN const unsigned pointerSize = SymbolGroupValue::pointerSize();
if ((kt & KT_ContainerType) == 0) const ULONG allocSize = pointerSize * count;
return -1; ULONG bytesRead = 0;
const int ct = containerSize(kt, SymbolGroupValue(n, ctx)); void *data = new unsigned char[allocSize];
QTC_TRACE_OUT const HRESULT hr = ctx.dataspaces->ReadVirtual(address, data, allocSize, &bytesRead);
return ct; if (FAILED(hr) || bytesRead != allocSize) {
delete [] data;
return 0;
}
return data;
} }
// Return size from an STL vector (last/first iterators). // Return size from an STL vector (last/first iterators).
...@@ -70,6 +74,17 @@ static inline int msvcStdVectorSize(const SymbolGroupValue &v) ...@@ -70,6 +74,17 @@ static inline int msvcStdVectorSize(const SymbolGroupValue &v)
return -1; return -1;
} }
// Return size of container or -1
int containerSize(KnownType kt, SymbolGroupNode *n, const SymbolGroupValueContext &ctx)
{
QTC_TRACE_IN
if ((kt & KT_ContainerType) == 0)
return -1;
const int ct = containerSize(kt, SymbolGroupValue(n, ctx));
QTC_TRACE_OUT
return ct;
}
// Determine size of containers // Determine size of containers
int containerSize(KnownType kt, const SymbolGroupValue &v) int containerSize(KnownType kt, const SymbolGroupValue &v)
{ {
...@@ -95,6 +110,10 @@ int containerSize(KnownType kt, const SymbolGroupValue &v) ...@@ -95,6 +110,10 @@ int containerSize(KnownType kt, const SymbolGroupValue &v)
if (const SymbolGroupValue sizeV = v["d"]["size"]) if (const SymbolGroupValue sizeV = v["d"]["size"])
return sizeV.intValue(); return sizeV.intValue();
break; break;
case KT_QMultiHash:
if (const SymbolGroupValue qHash = v[unsigned(0)])
return containerSize(KT_QHash, qHash);
break;
case KT_QQueue: case KT_QQueue:
if (const SymbolGroupValue qList= v[unsigned(0)]) if (const SymbolGroupValue qList= v[unsigned(0)])
return containerSize(KT_QList, qList); return containerSize(KT_QList, qList);
...@@ -202,9 +221,21 @@ static inline AbstractSymbolGroupNodePtrVector qLinkedListChildList(SymbolGroupN ...@@ -202,9 +221,21 @@ static inline AbstractSymbolGroupNodePtrVector qLinkedListChildList(SymbolGroupN
return AbstractSymbolGroupNodePtrVector(); return AbstractSymbolGroupNodePtrVector();
} }
// Symbol Name/(Expression) of a pointed-to instance ('Foo' at 0x10') ==> '*(Foo *)0x10'
static inline std::string pointedToSymbolName(ULONG64 address, const std::string &type)
{
std::ostringstream str;
str << "*(" << type;
if (!endsWith(type, '*'))
str << ' ';
str << "*)" << std::showbase << std::hex << address;
return str.str();
}
/* Helper for array-type containers: /* Helper for array-type containers:
* Add a series of "*(innertype *)0x (address + n * size)" fake child symbols. * Add a series of "*(innertype *)0x (address + n * size)" fake child symbols.
* for a function generating a sequence of addresses. */ * for a function generating a sequence of addresses. */
template <class AddressFunc> template <class AddressFunc>
AbstractSymbolGroupNodePtrVector arrayChildList(SymbolGroup *sg, AddressFunc addressFunc, AbstractSymbolGroupNodePtrVector arrayChildList(SymbolGroup *sg, AddressFunc addressFunc,
const std::string &innerType, int count) const std::string &innerType, int count)
...@@ -215,12 +246,8 @@ AbstractSymbolGroupNodePtrVector arrayChildList(SymbolGroup *sg, AddressFunc add ...@@ -215,12 +246,8 @@ AbstractSymbolGroupNodePtrVector arrayChildList(SymbolGroup *sg, AddressFunc add
std::string errorMessage; std::string errorMessage;
rc.reserve(count); rc.reserve(count);
for (int i = 0; i < count; i++) { for (int i = 0; i < count; i++) {
std::ostringstream str; const std::string name = pointedToSymbolName(addressFunc(), innerType);
str << "*(" << innerType; if (SymbolGroupNode *child = sg->addSymbol(name, std::string(), &errorMessage)) {
if (!endsWith(innerType, '*'))
str << ' ';
str << "*)" << std::showbase << std::hex << addressFunc();
if (SymbolGroupNode *child = sg->addSymbol(str.str(), std::string(), &errorMessage)) {
rc.push_back(ReferenceSymbolGroupNode::createArrayNode(i, child)); rc.push_back(ReferenceSymbolGroupNode::createArrayNode(i, child));
} else { } else {
break; break;
...@@ -352,26 +379,30 @@ static inline AbstractSymbolGroupNodePtrVector ...@@ -352,26 +379,30 @@ static inline AbstractSymbolGroupNodePtrVector
} }
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**)'
const ULONG allocSize = pointerSize * count; if (void *data = readPointerArray(arrayAddress, count, v.context())) {
ULONG bytesRead = 0; // Generate sequence of addresses from pointer array
void *data = new unsigned char[pointerSize * count]; const AbstractSymbolGroupNodePtrVector rc = pointerSize == 8 ?
const HRESULT hr = v.context().dataspaces->ReadVirtual(arrayAddress + begin * pointerSize, data, allocSize, &bytesRead); arrayChildList(v.node()->symbolGroup(), AddressArraySequence<ULONG64>(reinterpret_cast<const ULONG64 *>(data)), innerType, count) :
if (FAILED(hr) || bytesRead != allocSize) { arrayChildList(v.node()->symbolGroup(), AddressArraySequence<ULONG32>(reinterpret_cast<const ULONG32 *>(data)), innerType, count);
delete [] data; delete [] data;
return AbstractSymbolGroupNodePtrVector(); return rc;
} }
// Generate sequence of addresses from pointer array return AbstractSymbolGroupNodePtrVector();
const AbstractSymbolGroupNodePtrVector rc = pointerSize == 8 ?
arrayChildList(v.node()->symbolGroup(), AddressArraySequence<ULONG64>(reinterpret_cast<const ULONG64 *>(data)), innerType, count) :
arrayChildList(v.node()->symbolGroup(), AddressArraySequence<ULONG32>(reinterpret_cast<const ULONG32 *>(data)), innerType, count);
delete [] data;
return rc;
} }
return arrayChildList(v.node()->symbolGroup(), return arrayChildList(v.node()->symbolGroup(),
AddressSequence(arrayAddress, pointerSize), AddressSequence(arrayAddress, pointerSize),
innerType, count); innerType, count);
} }
static inline AbstractSymbolGroupNodePtrVector
qHashChildList(const SymbolGroupValue &, int count)
{
AbstractSymbolGroupNodePtrVector rc;
if (!count)
return rc;
return rc;
}
AbstractSymbolGroupNodePtrVector containerChildren(SymbolGroupNode *node, int type, AbstractSymbolGroupNodePtrVector containerChildren(SymbolGroupNode *node, int type,
int size, const SymbolGroupValueContext &ctx) int size, const SymbolGroupValueContext &ctx)
{ {
...@@ -396,6 +427,16 @@ AbstractSymbolGroupNodePtrVector containerChildren(SymbolGroupNode *node, int ty ...@@ -396,6 +427,16 @@ AbstractSymbolGroupNodePtrVector containerChildren(SymbolGroupNode *node, int ty
if (const SymbolGroupValue qVector = SymbolGroupValue(node, ctx)[unsigned(0)]) if (const SymbolGroupValue qVector = SymbolGroupValue(node, ctx)[unsigned(0)])
return qVectorChildList(qVector.node(), size, ctx); return qVectorChildList(qVector.node(), size, ctx);
break; break;
case KT_QHash:
return qHashChildList(SymbolGroupValue(node, ctx), size);
case KT_QMultiMap:
if (const SymbolGroupValue hash = SymbolGroupValue(node, ctx)[unsigned(0)])
return qHashChildList(hash, size);
break;
case KT_QSet:
if (const SymbolGroupValue qHash = SymbolGroupValue(node, ctx)["q_hash"])
return qHashChildList(qHash, size);
break;
case KT_QStringList: case KT_QStringList:
if (const SymbolGroupValue qList = SymbolGroupValue(node, ctx)[unsigned(0)]) if (const SymbolGroupValue qList = SymbolGroupValue(node, ctx)[unsigned(0)])
return qListChildList(qList, size); return qListChildList(qList, size);
......
...@@ -138,8 +138,9 @@ enum KnownType ...@@ -138,8 +138,9 @@ enum KnownType
KT_QQueue = KT_Qt_Type + KT_ContainerType + 6, KT_QQueue = KT_Qt_Type + KT_ContainerType + 6,
KT_QSet = KT_Qt_Type + KT_ContainerType + 7, KT_QSet = KT_Qt_Type + KT_ContainerType + 7,
KT_QHash = KT_Qt_Type + KT_ContainerType + 8, KT_QHash = KT_Qt_Type + KT_ContainerType + 8,
KT_QMap = KT_Qt_Type + KT_ContainerType + 9, KT_QMultiHash = KT_Qt_Type + KT_ContainerType + 9,
KT_QMultiMap = KT_Qt_Type + KT_ContainerType + 10, KT_QMap = KT_Qt_Type + KT_ContainerType + 10,
KT_QMultiMap = KT_Qt_Type + KT_ContainerType + 11,
// STL // STL
KT_StdString = KT_STL_Type + 1, KT_StdString = KT_STL_Type + 1,
KT_StdWString = KT_STL_Type + 2, KT_StdWString = KT_STL_Type + 2,
......
...@@ -456,6 +456,10 @@ static KnownType knownTypeHelper(const std::string &type, std::string::size_type ...@@ -456,6 +456,10 @@ static KnownType knownTypeHelper(const std::string &type, std::string::size_type
if (!type.compare(qPos, 9, "QMultiMap")) if (!type.compare(qPos, 9, "QMultiMap"))
return KT_QMultiMap; return KT_QMultiMap;
break; break;
case 10:
if (!type.compare(qPos, 10, "QMultiHash"))
return KT_QMultiHash;
break;
case 11: case 11:
if (!type.compare(qPos, 11, "QLinkedList")) if (!type.compare(qPos, 11, "QLinkedList"))
return KT_QLinkedList; return KT_QLinkedList;
......
0% Loading or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment