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.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 = []
|
||||||
|
@@ -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, ¶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[] = {
|
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 */
|
||||||
};
|
};
|
||||||
|
Reference in New Issue
Block a user