From a7319f382db7c4dd5b1cef47f0d4421deadfc769 Mon Sep 17 00:00:00 2001 From: Friedemann Kleint Date: Fri, 17 Dec 2010 15:34:18 +0100 Subject: [PATCH] Debugger[New CDB]: Add std::deque. --- src/libs/qtcreatorcdbext/containers.cpp | 94 ++++++++++++++++++++++++ src/plugins/debugger/cdb2/cdbengine2.cpp | 5 +- 2 files changed, 98 insertions(+), 1 deletion(-) diff --git a/src/libs/qtcreatorcdbext/containers.cpp b/src/libs/qtcreatorcdbext/containers.cpp index e8e25fe50bd..2893cdfcd75 100644 --- a/src/libs/qtcreatorcdbext/containers.cpp +++ b/src/libs/qtcreatorcdbext/containers.cpp @@ -33,6 +33,7 @@ #include "stringutils.h" #include +#include typedef AbstractSymbolGroupNode::AbstractSymbolGroupNodePtrVector AbstractSymbolGroupNodePtrVector; typedef std::vector SymbolGroupValueVector; @@ -53,6 +54,24 @@ static void *readPointerArray(ULONG64 address, unsigned count, const SymbolGroup return data; } +template +inline void dumpHexArray(std::ostream &os, const UInt *a, int count) +{ + os << std::showbase << std::hex; + std::copy(a, a + count, std::ostream_iterator(os, ", ")); + os << std::noshowbase << std::dec; +} + +static inline void dump32bitPointerArray(std::ostream &os, const void *a, int count) +{ + dumpHexArray(os, reinterpret_cast(a), count); +} + +static inline void dump64bitPointerArray(std::ostream &os, const void *a, int count) +{ + dumpHexArray(os, reinterpret_cast(a), count); +} + // Return size from an STL vector (last/first iterators). static inline int msvcStdVectorSize(const SymbolGroupValue &v) { @@ -304,6 +323,75 @@ static inline AbstractSymbolGroupNodePtrVector return AbstractSymbolGroupNodePtrVector(); } +// Helper for std::deque<>: From the array of deque blocks, read out the values. +template +AbstractSymbolGroupNodePtrVector + stdDequeChildrenHelper(SymbolGroup *sg, + const AddressType *blockArray, ULONG64 blockArraySize, + const std::string &innerType, ULONG64 innerTypeSize, + ULONG64 startOffset, ULONG64 dequeSize, int count) +{ + AbstractSymbolGroupNodePtrVector rc; + rc.reserve(count); + std::string errorMessage; + // Determine block number and offset in the block array T[][dequeSize] + // and create symbol by address. + for (int i = 0; i < count; i++) { + // see -header: std::deque::iterator::operator* + const ULONG64 offset = startOffset + i; + ULONG64 block = offset / dequeSize; + if (block >= blockArraySize) + block -= blockArraySize; + const ULONG64 blockOffset = offset % dequeSize; + const ULONG64 address = blockArray[block] + innerTypeSize * blockOffset; + if (SymbolGroupNode *n = sg->addSymbol(pointedToSymbolName(address, innerType), std::string(), &errorMessage)) { + rc.push_back(ReferenceSymbolGroupNode::createArrayNode(i, n)); + } else { + return AbstractSymbolGroupNodePtrVector(); + } + } + return rc; +} + +// std::deque<> +static inline AbstractSymbolGroupNodePtrVector + stdDequeChildList(const SymbolGroupValue &v, int count) +{ + if (!count) + return AbstractSymbolGroupNodePtrVector(); + const SymbolGroupValue base = v[unsigned(0)]; + if (!base) + return AbstractSymbolGroupNodePtrVector(); + const ULONG64 arrayAddress = base["_Map"].pointerValue(); + const int startOffset = base["_Myoff"].intValue(); + const int mapSize = base["_Mapsize"].intValue(); + if (!arrayAddress || startOffset < 0 || mapSize <= 0) + return AbstractSymbolGroupNodePtrVector(); + const std::vector innerTypes = v.innerTypes(); + if (innerTypes.empty()) + return AbstractSymbolGroupNodePtrVector(); + // Get the deque size (block size) which is an unavailable static member + // (cf for the actual expression). + const unsigned innerTypeSize = SymbolGroupValue::sizeOf(innerTypes.front().c_str()); + if (!innerTypeSize) + return AbstractSymbolGroupNodePtrVector(); + const int dequeSize = innerTypeSize <= 1 ? 16 : innerTypeSize <= 2 ? + 8 : innerTypeSize <= 4 ? 4 : innerTypeSize <= 8 ? 2 : 1; + // Read out map array (pointing to the blocks) + void *mapArray = readPointerArray(arrayAddress, mapSize, v.context()); + if (!mapArray) + return AbstractSymbolGroupNodePtrVector(); + const AbstractSymbolGroupNodePtrVector rc = SymbolGroupValue::pointerSize() == 8 ? + stdDequeChildrenHelper(v.node()->symbolGroup(), + reinterpret_cast(mapArray), mapSize, + innerTypes.front(), innerTypeSize, startOffset, dequeSize, count) : + stdDequeChildrenHelper(v.node()->symbolGroup(), + reinterpret_cast(mapArray), mapSize, + innerTypes.front(), innerTypeSize, startOffset, dequeSize, count); + delete [] mapArray; + return rc; +} + // QVector static inline AbstractSymbolGroupNodePtrVector qVectorChildList(SymbolGroupNode *n, int count, const SymbolGroupValueContext &ctx) @@ -583,6 +671,12 @@ AbstractSymbolGroupNodePtrVector containerChildren(SymbolGroupNode *node, int ty break; case KT_StdList: return stdListChildList(node, size , ctx); + case KT_StdDeque: + return stdDequeChildList(SymbolGroupValue(node, ctx), size); + case KT_StdStack: + if (const SymbolGroupValue deque = SymbolGroupValue(node, ctx)[unsigned(0)]) + return stdDequeChildList(deque, size); + break; } return AbstractSymbolGroupNodePtrVector(); } diff --git a/src/plugins/debugger/cdb2/cdbengine2.cpp b/src/plugins/debugger/cdb2/cdbengine2.cpp index 0b92f5527c1..2050f05e9b8 100644 --- a/src/plugins/debugger/cdb2/cdbengine2.cpp +++ b/src/plugins/debugger/cdb2/cdbengine2.cpp @@ -1058,7 +1058,10 @@ void CdbEngine::handleDisassembler(const CdbBuiltinCommandPtr &command) void CdbEngine::fetchMemory(Debugger::Internal::MemoryAgent *agent, QObject *editor, quint64 addr, quint64 length) { - QTC_ASSERT(m_accessible, return;) + if (!m_accessible) { + qWarning("Internal error: Attempt to read memory from inaccessible session: %s", Q_FUNC_INFO); + return; + } if (debug) qDebug("CdbEngine::fetchMemory %llu bytes from 0x%llx", length, addr);