aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorDavid Schulz <david.schulz@qt.io>2016-08-30 13:46:23 +0200
committerDavid Schulz <david.schulz@qt.io>2016-09-15 07:27:27 +0000
commit6b112c1b04d3fbed65492a2a05e2c34f71c6bc8d (patch)
tree60837108d5cccc08e399ec5f767345e9e900c1ea
parent21dc290360f80b007d36545f18b316f8236d659e (diff)
Cdb: Introduce SymbolGroupChildInfo
Holds the offset and type of a symbol ancestor. This information is cached and used to collect data directly via offset instead of expanding known symbols. Change-Id: I0c08f6911dfbb6016c4bb12cb6325be873c6000a Reviewed-by: Christian Stenger <christian.stenger@qt.io>
-rw-r--r--src/libs/qtcreatorcdbext/symbolgroupvalue.cpp109
-rw-r--r--src/libs/qtcreatorcdbext/symbolgroupvalue.h17
2 files changed, 126 insertions, 0 deletions
diff --git a/src/libs/qtcreatorcdbext/symbolgroupvalue.cpp b/src/libs/qtcreatorcdbext/symbolgroupvalue.cpp
index 131685b103..5d7147f373 100644
--- a/src/libs/qtcreatorcdbext/symbolgroupvalue.cpp
+++ b/src/libs/qtcreatorcdbext/symbolgroupvalue.cpp
@@ -40,9 +40,14 @@
#include <algorithm>
#include <limits>
#include <ctype.h>
+#include <unordered_map>
typedef std::vector<int>::size_type VectorIndexType;
+typedef std::unordered_map<std::string, SymbolAncestorInfo> AncestorInfos;
+
+static std::unordered_map<std::string, AncestorInfos> typeAncestorInfos;
+
/*!
\class SymbolGroupValueContext
\brief The SymbolGroupValueContext class passes all IDebug interfaces
@@ -129,6 +134,93 @@ SymbolGroupValue SymbolGroupValue::operator[](unsigned index) const
return SymbolGroupValue(m_errorMessage);
}
+SymbolGroupValue SymbolGroupValue::addSymbolForAncestor(const std::string &ancestorName) const
+{
+ const SymbolAncestorInfo info = infoOfAncestor(ancestorName);
+ if (info.isValid()) {
+ const ULONG64 base = isPointerType(type()) ? pointerValue() : address();
+ const std::string &pointerToType =
+ pointedToSymbolName(base + info.offset, stripClassPrefixes(info.type));
+ if (SymbolGroupNode *ancestorNode =
+ node()->symbolGroup()->addSymbol(module(), pointerToType, "", "", &std::string())) {
+ return SymbolGroupValue(ancestorNode, m_context);
+ }
+ }
+ if (isValid() && SymbolGroupValue::verbose) { // Do not report subsequent errors
+ DebugPrint dp;
+ dp << this->name() << "::addSymbolForAncestor(\"" << ancestorName << "\") failed. ";
+ formatNodeError(m_node, dp);
+ }
+ return SymbolGroupValue(m_errorMessage);
+}
+
+int SymbolGroupValue::readIntegerFromAncestor(const std::string &name, int defaultValue) const
+{
+ return readPODFromAncestor<int>(name, defaultValue);
+}
+
+LONG64 SymbolGroupValue::offsetOfAncestor(const std::string &name) const
+{
+ return infoOfAncestor(name).offset;
+}
+
+ULONG64 SymbolGroupValue::addressOfAncestor(const std::string &name) const
+{
+ const ULONG64 base = isPointerType(type()) ? pointerValue() : address();
+ LONG64 offset = offsetOfAncestor(name);
+ return offset >= 0 ? base + ULONG64(offset) : 0;
+}
+
+std::string SymbolGroupValue::typeOfAncestor(const std::string &name) const
+{
+ return infoOfAncestor(name).type;
+}
+
+SymbolAncestorInfo SymbolGroupValue::infoOfAncestor(const std::string &name) const
+{
+ const std::string &typeName = type();
+ AncestorInfos &offsets = typeAncestorInfos[typeName];
+ auto offsetIt = offsets.find(name);
+ if (offsetIt != offsets.end())
+ return offsetIt->second;
+
+ SymbolAncestorInfo info;
+ if (!ensureExpanded())
+ return info;
+
+ if (AbstractSymbolGroupNode *abstractChildNode = m_node->childByIName(name.c_str())) {
+ if (SymbolGroupNode *childNode = abstractChildNode->asSymbolGroupNode()) {
+ SymbolGroupValue child(childNode, m_context);
+ ULONG64 childAddress = child.address();
+ if (childAddress == 0)
+ return info;
+ const ULONG64 base = isPointerType(typeName) ? pointerValue() : address();
+ info.offset = LONG64(childAddress - base);
+ info.type = child.type();
+ }
+ }
+
+ if (!info.isValid()) {
+ // Search recursively for ancestor
+ for (AbstractSymbolGroupNode *abstractChildNode : m_node->children()) {
+ if (SymbolGroupNode *childNode = abstractChildNode->asSymbolGroupNode()) {
+ SymbolGroupValue child(childNode, m_context);
+ if (isPointerType(child.type()))
+ continue;
+ info = child.infoOfAncestor(name);
+ if (info.isValid()) {
+ info.offset += offsetOfAncestor(child.name());
+ break;
+ }
+ }
+ }
+ }
+
+ if (info.isValid())
+ offsets[name] = info;
+ return info;
+}
+
unsigned SymbolGroupValue::childCount() const
{
if (ensureExpanded())
@@ -254,12 +346,29 @@ template<class POD>
return rc;
}
+template<class POD>
+POD SymbolGroupValue::readPODFromAncestor(const std::string &name, POD defaultValue) const
+{
+ ULONG64 address = addressOfAncestor(name.c_str());
+ if (address == 0)
+ return defaultValue;
+ return readPODFromMemory<POD>(m_context.dataspaces, address, sizeof(POD), defaultValue, 0);
+}
+
ULONG64 SymbolGroupValue::readPointerValue(CIDebugDataSpaces *ds, ULONG64 address,
std::string *errorMessage /* = 0 */)
{
return readPODFromMemory<ULONG64>(ds, address, SymbolGroupValue::pointerSize(), 0, errorMessage);
}
+ULONG64 SymbolGroupValue::readPointerValueFromAncestor(const std::string &name) const
+{
+ ULONG64 address = addressOfAncestor(name.c_str());
+ if (address == 0)
+ return 0;
+ return readPointerValue(m_context.dataspaces, address);
+}
+
ULONG64 SymbolGroupValue::readUnsignedValue(CIDebugDataSpaces *ds,
ULONG64 address, ULONG debuggeeTypeSize,
ULONG64 defaultValue,
diff --git a/src/libs/qtcreatorcdbext/symbolgroupvalue.h b/src/libs/qtcreatorcdbext/symbolgroupvalue.h
index 87e6c9a109..d14ee0e3dd 100644
--- a/src/libs/qtcreatorcdbext/symbolgroupvalue.h
+++ b/src/libs/qtcreatorcdbext/symbolgroupvalue.h
@@ -46,6 +46,13 @@ struct SymbolGroupValueContext
CIDebugSymbols *symbols = nullptr;
};
+struct SymbolAncestorInfo
+{
+ bool isValid() const { return offset >= 0 && !type.empty(); }
+ std::string type;
+ LONG64 offset = -1;
+};
+
class SymbolGroupValue
{
explicit SymbolGroupValue(const std::string &parentError);
@@ -80,6 +87,15 @@ public:
std::wstring value() const;
unsigned size() const;
+ //offset based access to ancestors
+ SymbolGroupValue addSymbolForAncestor(const std::string &ancestorName) const;
+ ULONG64 readPointerValueFromAncestor(const std::string &name) const;
+ int readIntegerFromAncestor(const std::string &name, int defaultValue = -1) const;
+ LONG64 offsetOfAncestor(const std::string &name) const;
+ ULONG64 addressOfAncestor(const std::string &name) const;
+ std::string typeOfAncestor(const std::string &childName) const;
+ SymbolAncestorInfo infoOfAncestor(const std::string &name) const;
+
SymbolGroupNode *node() const { return m_node; }
SymbolGroupValueContext context() const { return m_context; }
@@ -170,6 +186,7 @@ public:
private:
bool ensureExpanded() const;
SymbolGroupValue typeCastedValue(ULONG64 address, const char *type) const;
+ template<class POD> POD readPODFromAncestor(const std::string &name, POD defaultValue) const;
SymbolGroupNode *m_node = 0;
SymbolGroupValueContext m_context;