forked from qt-creator/qt-creator
Debugger: Adjust to latest field changes
Change-Id: Ic4b3c8f0670a0d58e3d762ff0765862709901d2a Reviewed-by: Christian Stenger <christian.stenger@qt.io>
This commit is contained in:
@@ -131,36 +131,35 @@ class Dumper(DumperBase):
|
||||
tdata.lbitsize = nativeType.bitsize()
|
||||
tdata.code = code
|
||||
self.registerType(typeId, tdata) # Prevent recursion in fields.
|
||||
tdata.lfields = self.listFields(nativeType, self.Type(self, typeId))
|
||||
if code == TypeCodeStruct:
|
||||
tdata.lfields = lambda value : \
|
||||
self.listFields(nativeType, value)
|
||||
tdata.lalignment = lambda : \
|
||||
self.nativeStructAlignment(nativeType)
|
||||
tdata.templateArguments = self.listTemplateParameters(nativeType)
|
||||
self.registerType(typeId, tdata) # Fix up fields and template args
|
||||
return self.Type(self, typeId)
|
||||
|
||||
def listFields(self, nativeType, parentType):
|
||||
fields = []
|
||||
def listFields(self, nativeType, value):
|
||||
if value.address() is None or value.address() == 0:
|
||||
raise Exception("")
|
||||
nativeValue = cdbext.createValue(value.address(), nativeType)
|
||||
index = 0
|
||||
nativeMember = nativeValue.childFromIndex(index)
|
||||
while nativeMember is not None:
|
||||
yield self.fromNativeValue(nativeMember)
|
||||
index += 1
|
||||
nativeMember = nativeValue.childFromIndex(index)
|
||||
|
||||
if not nativeType.code() == TypeCodeStruct:
|
||||
return fields
|
||||
|
||||
nativeIndex = 0
|
||||
nativeFields = nativeType.fields()
|
||||
for nativeField in nativeFields:
|
||||
field = self.Field(self)
|
||||
fieldType = nativeField.type().unqualified()
|
||||
if fieldType is None:
|
||||
fieldType = FakeVoidType('void', self)
|
||||
field.ltype = self.fromNativeType(fieldType)
|
||||
field.parentType = parentType
|
||||
field.name = nativeField.name()
|
||||
field.isBaseClass = False
|
||||
field.lbitpos = nativeField.bitpos()
|
||||
field.lbitsize = nativeField.bitsize()
|
||||
field.nativeIndex = nativeIndex
|
||||
#warn("FIELD RESULT: %s" % field)
|
||||
fields.append(field)
|
||||
nativeIndex += 1
|
||||
|
||||
return fields
|
||||
def nativeStructAlignment(self, nativeType):
|
||||
#warn("NATIVE ALIGN FOR %s" % nativeType.name)
|
||||
def handleItem(nativeFieldType, align):
|
||||
a = self.fromNativeType(nativeFieldType).alignment()
|
||||
return a if a > align else align
|
||||
align = 1
|
||||
for f in nativeType.fields():
|
||||
align = handleItem(f.type(), align)
|
||||
return align
|
||||
|
||||
def listTemplateParameters(self, nativeType):
|
||||
targs = []
|
||||
|
@@ -27,6 +27,7 @@
|
||||
|
||||
#include "extensioncontext.h"
|
||||
#include "symbolgroup.h"
|
||||
#include "symbolgroupvalue.h"
|
||||
|
||||
#include "pyfield.h"
|
||||
#include "pystdoutredirect.h"
|
||||
@@ -106,6 +107,57 @@ static PyObject *cdbext_readRawMemory(PyObject *, PyObject *args)
|
||||
return ret;
|
||||
}
|
||||
|
||||
static PyObject *cdbext_createValue(PyObject *, PyObject *args)
|
||||
{
|
||||
ULONG64 address = 0;
|
||||
Type *type = 0;
|
||||
if (!PyArg_ParseTuple(args, "KO", &address, &type))
|
||||
Py_RETURN_NONE;
|
||||
|
||||
if (debugPyCdbextModule) {
|
||||
DebugPrint() << "Create Value address: 0x" << std::hex << address
|
||||
<< " type name: " << getTypeName(type->m_module, type->m_typeId);
|
||||
}
|
||||
|
||||
ExtensionCommandContext *extCmdCtx = ExtensionCommandContext::instance();
|
||||
CIDebugSymbols *symbols = extCmdCtx->symbols();
|
||||
|
||||
ULONG frame;
|
||||
if (FAILED(symbols->GetCurrentScopeFrameIndex(&frame)))
|
||||
Py_RETURN_NONE;
|
||||
|
||||
std::string errorMessage;
|
||||
LocalsSymbolGroup *lsg = ExtensionContext::instance().symbolGroup(
|
||||
symbols, extCmdCtx->threadId(), int(frame), &errorMessage);
|
||||
if (!lsg)
|
||||
Py_RETURN_NONE;
|
||||
|
||||
CIDebugSymbolGroup *dsg = lsg->debugSymbolGroup();
|
||||
ULONG numberOfSymbols = 0;
|
||||
dsg->GetNumberSymbols(&numberOfSymbols);
|
||||
ULONG index = 0;
|
||||
for (;index < numberOfSymbols; ++index) {
|
||||
ULONG64 offset;
|
||||
dsg->GetSymbolOffset(index, &offset);
|
||||
if (offset == address) {
|
||||
DEBUG_SYMBOL_PARAMETERS params;
|
||||
if (SUCCEEDED(dsg->GetSymbolParameters(index, 1, ¶ms))) {
|
||||
if (params.TypeId == type->m_typeId && params.Module == type->m_module)
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (index >= numberOfSymbols) {
|
||||
index = DEBUG_ANY_ID;
|
||||
const std::string name = SymbolGroupValue::pointedToSymbolName(
|
||||
address, getTypeName(type->m_module, type->m_typeId));
|
||||
if (FAILED(dsg->AddSymbol(name.c_str(), &index)))
|
||||
Py_RETURN_NONE;
|
||||
}
|
||||
return createValue(index, dsg);
|
||||
}
|
||||
|
||||
static PyMethodDef cdbextMethods[] = {
|
||||
{"parseAndEvaluate", cdbext_parseAndEvaluate, METH_VARARGS,
|
||||
"Returns value of expression or None if the expression can not be resolved"},
|
||||
@@ -117,6 +169,8 @@ static PyMethodDef cdbextMethods[] = {
|
||||
"Returns the size of a pointer"},
|
||||
{"readRawMemory", cdbext_readRawMemory, METH_VARARGS,
|
||||
"Read a block of data from the virtual address space"},
|
||||
{"createValue", cdbext_createValue, METH_VARARGS,
|
||||
"Creates a value with the given type at the given address"},
|
||||
{NULL, NULL, 0,
|
||||
NULL} /* Sentinel */
|
||||
};
|
||||
|
Reference in New Issue
Block a user