forked from qt-creator/qt-creator
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:
@@ -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,
|
||||||
|
|||||||
@@ -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;
|
||||||
|
|||||||
Reference in New Issue
Block a user