Debugger: Use symbol tag to determine type code

Change-Id: I49a2a0f3e1ff65accb0d2e04fbd9352ce3f63f2c
Reviewed-by: Christian Stenger <christian.stenger@qt.io>
This commit is contained in:
David Schulz
2017-02-27 14:04:32 +01:00
parent 327341b917
commit edacb7d383
5 changed files with 98 additions and 21 deletions

View File

@@ -149,10 +149,18 @@ class Dumper(DumperBase):
code = nativeType.code()
if code == TypeCodePointer:
return self.createPointerType(self.lookupType(nativeType.targetName(), nativeType.moduleId()))
if nativeType.name().startswith('<function>'):
code = TypeCodeFunction
else:
targetType = self.lookupType(nativeType.targetName(), nativeType.moduleId())
return self.createPointerType(targetType)
if code == TypeCodeArray:
return self.createArrayType(self.lookupType(nativeType.targetName(), nativeType.moduleId()), nativeType.arrayElements())
if nativeType.name().startswith('__fptr()'):
code = TypeCodeStruct
else:
targetType = self.lookupType(nativeType.targetName(), nativeType.moduleId())
return self.createArrayType(targetType, nativeType.arrayElements())
tdata = self.TypeData(self)
tdata.name = nativeType.name()

View File

@@ -27,9 +27,19 @@
#include "extensioncontext.h"
#include "pycdbextmodule.h"
#include "pyvalue.h"
#include "stringutils.h"
#include "symbolgroupvalue.h"
#include <Windows.h>
#ifndef _NO_CVCONST_H
#define _NO_CVCONST_H
#include <dbghelp.h>
#undef _NO_CVCONST_H
#else
#include <dbghelp.h>
#endif
constexpr bool debugPyType = false;
constexpr bool debuggingTypeEnabled() { return debugPyType || debugPyCdbextModule; }
@@ -202,10 +212,11 @@ static std::string getModuleName(ULONG64 module)
return std::string();
}
PyType::PyType(ULONG64 module, unsigned long typeId, const std::string &name)
PyType::PyType(ULONG64 module, unsigned long typeId, const std::string &name, int tag)
: m_module(module)
, m_typeId(typeId)
, m_resolved(true)
, m_tag(tag)
{
m_name = SymbolGroupValue::stripClassPrefixes(name);
if (m_name.compare(0, 6, "union ") == 0)
@@ -257,19 +268,44 @@ int PyType::code() const
{
if (!m_resolved)
return TypeCodeUnresolvable;
const std::string &typeName = name();
if (typeName.empty())
return TypeCodeUnresolvable;
if (isPointerType(typeName))
return TypeCodePointer;
if (isArrayType(typeName))
return TypeCodeArray;
if (typeName.find("<function>") != std::string::npos)
return TypeCodeFunction;
if (isIntegralType(typeName))
return TypeCodeIntegral;
if (isFloatType(typeName))
return TypeCodeFloat;
if (m_tag < 0) {
// try to parse typeName
const std::string &typeName = name();
if (typeName.empty())
return TypeCodeUnresolvable;
if (isPointerType(typeName))
return TypeCodePointer;
if (isArrayType(typeName))
return TypeCodeArray;
if (typeName.find("<function>") == 0)
return TypeCodeFunction;
if (isIntegralType(typeName))
return TypeCodeIntegral;
if (isFloatType(typeName))
return TypeCodeFloat;
IDebugSymbolGroup2 *sg = 0;
if (FAILED(ExtensionCommandContext::instance()->symbols()->CreateSymbolGroup2(&sg)))
return TypeCodeStruct;
const std::string helperValueName = SymbolGroupValue::pointedToSymbolName(0, name(true));
ULONG index = DEBUG_ANY_ID;
if (SUCCEEDED(sg->AddSymbol(helperValueName.c_str(), &index)))
m_tag = PyValue(index, sg).tag();
sg->Release();
}
switch (m_tag) {
case SymTagUDT: return TypeCodeStruct;
case SymTagEnum: return TypeCodeEnum;
case SymTagTypedef: return TypeCodeTypedef;
case SymTagFunctionType: return TypeCodeFunction;
case SymTagPointerType: return TypeCodePointer;
case SymTagArrayType: return TypeCodeArray;
case SymTagBaseType: return isIntegralType(name()) ? TypeCodeIntegral : TypeCodeFloat;
default: break;
}
return TypeCodeStruct;
}

View File

@@ -36,7 +36,8 @@ class PyType
{
public:
PyType() = default;
PyType(ULONG64 module, unsigned long typeId, const std::string &name = std::string());
PyType(ULONG64 module, unsigned long typeId,
const std::string &name = std::string(), int tag = -1);
PyType(const PyType &other) = default;
std::string name(bool withModule = false) const;
@@ -75,6 +76,7 @@ private:
ULONG64 m_module = 0;
bool m_resolved = false;
mutable std::string m_name;
mutable int m_tag = -1;
};
struct TypePythonObject

View File

@@ -85,12 +85,13 @@ PyType PyValue::type()
return PyType();
ULONG size = 0;
m_symbolGroup->GetSymbolTypeName(m_index, NULL, 0, &size);
std::string typeName;
if (size != 0) {
std::string typeName(size - 1, '\0');
if (SUCCEEDED(m_symbolGroup->GetSymbolTypeName(m_index, &typeName[0], size, NULL)))
return PyType(params.Module, params.TypeId, typeName);
typeName = std::string(size - 1, '\0');
if (FAILED(m_symbolGroup->GetSymbolTypeName(m_index, &typeName[0], size, NULL)))
typeName.clear();
}
return PyType(params.Module, params.TypeId);
return PyType(params.Module, params.TypeId, typeName, tag());
}
ULONG64 PyValue::bitsize()
@@ -188,6 +189,16 @@ int PyValue::isValid()
return m_symbolGroup != nullptr;
}
int PyValue::tag()
{
if (!m_symbolGroup)
return -1;
DEBUG_SYMBOL_ENTRY info;
if (FAILED(m_symbolGroup->GetSymbolEntryInformation(m_index, &info)))
return -1;
return info.Tag;
}
PyValue PyValue::childFromName(const std::string &name)
{
const ULONG endIndex = m_index + childCount();
@@ -301,6 +312,23 @@ PyValue PyValue::createValue(ULONG64 address, const PyType &type)
return PyValue(index, symbolGroup);
}
int PyValue::tag(const std::string &typeName)
{
CIDebugSymbols *symbols = ExtensionCommandContext::instance()->symbols();
IDebugSymbolGroup2 *sg = 0;
if (FAILED(symbols->CreateSymbolGroup2(&sg)))
return -1;
int tag = -1;
const std::string name = SymbolGroupValue::pointedToSymbolName(0, typeName);
ULONG index = DEBUG_ANY_ID;
if (SUCCEEDED(sg->AddSymbol(name.c_str(), &index)))
tag = PyValue(index, sg).tag();
sg->Release();
return tag;
}
// Python interface implementation
namespace PyValueInterface {

View File

@@ -49,12 +49,15 @@ public:
std::string nativeDebuggerValue();
int isValid();
int tag();
PyValue childFromName(const std::string &name);
PyValue childFromField(const PyField &field);
PyValue childFromIndex(int index);
static PyValue createValue(ULONG64 address, const PyType &type);
static int tag(const std::string &typeName);
private:
static void indicesMoved(CIDebugSymbolGroup *symbolGroup, ULONG start, ULONG delta);