forked from qt-creator/qt-creator
Debugger: Use symbol tag to determine type code
Change-Id: I49a2a0f3e1ff65accb0d2e04fbd9352ce3f63f2c Reviewed-by: Christian Stenger <christian.stenger@qt.io>
This commit is contained in:
@@ -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()
|
||||
|
@@ -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;
|
||||
}
|
||||
|
||||
|
@@ -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
|
||||
|
@@ -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 {
|
||||
|
@@ -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);
|
||||
|
||||
|
Reference in New Issue
Block a user