Debugger: Adjust to latest field changes

Change-Id: Ic4b3c8f0670a0d58e3d762ff0765862709901d2a
Reviewed-by: Christian Stenger <christian.stenger@qt.io>
This commit is contained in:
David Schulz
2016-11-03 15:34:37 +01:00
parent bf133156ee
commit 8736565c14
2 changed files with 78 additions and 25 deletions

View File

@@ -131,36 +131,35 @@ class Dumper(DumperBase):
tdata.lbitsize = nativeType.bitsize() tdata.lbitsize = nativeType.bitsize()
tdata.code = code tdata.code = code
self.registerType(typeId, tdata) # Prevent recursion in fields. 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) tdata.templateArguments = self.listTemplateParameters(nativeType)
self.registerType(typeId, tdata) # Fix up fields and template args self.registerType(typeId, tdata) # Fix up fields and template args
return self.Type(self, typeId) return self.Type(self, typeId)
def listFields(self, nativeType, parentType): def listFields(self, nativeType, value):
fields = [] 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: def nativeStructAlignment(self, nativeType):
return fields #warn("NATIVE ALIGN FOR %s" % nativeType.name)
def handleItem(nativeFieldType, align):
nativeIndex = 0 a = self.fromNativeType(nativeFieldType).alignment()
nativeFields = nativeType.fields() return a if a > align else align
for nativeField in nativeFields: align = 1
field = self.Field(self) for f in nativeType.fields():
fieldType = nativeField.type().unqualified() align = handleItem(f.type(), align)
if fieldType is None: return align
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 listTemplateParameters(self, nativeType): def listTemplateParameters(self, nativeType):
targs = [] targs = []

View File

@@ -27,6 +27,7 @@
#include "extensioncontext.h" #include "extensioncontext.h"
#include "symbolgroup.h" #include "symbolgroup.h"
#include "symbolgroupvalue.h"
#include "pyfield.h" #include "pyfield.h"
#include "pystdoutredirect.h" #include "pystdoutredirect.h"
@@ -106,6 +107,57 @@ static PyObject *cdbext_readRawMemory(PyObject *, PyObject *args)
return ret; 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, &params))) {
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[] = { static PyMethodDef cdbextMethods[] = {
{"parseAndEvaluate", cdbext_parseAndEvaluate, METH_VARARGS, {"parseAndEvaluate", cdbext_parseAndEvaluate, METH_VARARGS,
"Returns value of expression or None if the expression can not be resolved"}, "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"}, "Returns the size of a pointer"},
{"readRawMemory", cdbext_readRawMemory, METH_VARARGS, {"readRawMemory", cdbext_readRawMemory, METH_VARARGS,
"Read a block of data from the virtual address space"}, "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, NULL, 0,
NULL} /* Sentinel */ NULL} /* Sentinel */
}; };