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>
This commit is contained in:
David Schulz
2016-08-30 13:46:23 +02:00
parent 21dc290360
commit 6b112c1b04
2 changed files with 126 additions and 0 deletions

View File

@@ -40,9 +40,14 @@
#include <algorithm> #include <algorithm>
#include <limits> #include <limits>
#include <ctype.h> #include <ctype.h>
#include <unordered_map>
typedef std::vector<int>::size_type VectorIndexType; 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 \class SymbolGroupValueContext
\brief The SymbolGroupValueContext class passes all IDebug interfaces \brief The SymbolGroupValueContext class passes all IDebug interfaces
@@ -129,6 +134,93 @@ SymbolGroupValue SymbolGroupValue::operator[](unsigned index) const
return SymbolGroupValue(m_errorMessage); 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 unsigned SymbolGroupValue::childCount() const
{ {
if (ensureExpanded()) if (ensureExpanded())
@@ -254,12 +346,29 @@ template<class POD>
return rc; 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, ULONG64 SymbolGroupValue::readPointerValue(CIDebugDataSpaces *ds, ULONG64 address,
std::string *errorMessage /* = 0 */) std::string *errorMessage /* = 0 */)
{ {
return readPODFromMemory<ULONG64>(ds, address, SymbolGroupValue::pointerSize(), 0, errorMessage); 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 SymbolGroupValue::readUnsignedValue(CIDebugDataSpaces *ds,
ULONG64 address, ULONG debuggeeTypeSize, ULONG64 address, ULONG debuggeeTypeSize,
ULONG64 defaultValue, ULONG64 defaultValue,

View File

@@ -46,6 +46,13 @@ struct SymbolGroupValueContext
CIDebugSymbols *symbols = nullptr; CIDebugSymbols *symbols = nullptr;
}; };
struct SymbolAncestorInfo
{
bool isValid() const { return offset >= 0 && !type.empty(); }
std::string type;
LONG64 offset = -1;
};
class SymbolGroupValue class SymbolGroupValue
{ {
explicit SymbolGroupValue(const std::string &parentError); explicit SymbolGroupValue(const std::string &parentError);
@@ -80,6 +87,15 @@ public:
std::wstring value() const; std::wstring value() const;
unsigned size() 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; } SymbolGroupNode *node() const { return m_node; }
SymbolGroupValueContext context() const { return m_context; } SymbolGroupValueContext context() const { return m_context; }
@@ -170,6 +186,7 @@ public:
private: private:
bool ensureExpanded() const; bool ensureExpanded() const;
SymbolGroupValue typeCastedValue(ULONG64 address, const char *type) 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; SymbolGroupNode *m_node = 0;
SymbolGroupValueContext m_context; SymbolGroupValueContext m_context;