Debugger: Update subtree if partial variable is requested

Instead of dumping the complete locals just dump the subtree
with the partial variable.

Change-Id: Ieac5f62efd87144bbea7a6a559d8be8d48d9084e
Reviewed-by: Christian Stenger <christian.stenger@qt.io>
This commit is contained in:
David Schulz
2016-12-08 15:51:49 +01:00
parent b352082a45
commit 16b44c80f6
3 changed files with 40 additions and 12 deletions

View File

@@ -267,11 +267,9 @@ class Dumper(DumperBase):
self.anonNumber = 0
variables = []
for val in cdbext.listOfLocals():
self.currentContextValue = val
name = val.name()
for val in cdbext.listOfLocals(self.partialVariable):
value = self.fromNativeValue(val)
value.name = name
value.name = val.name()
variables.append(value)
self.handleLocals(variables)

View File

@@ -105,18 +105,47 @@ static PyObject *cdbext_lookupType(PyObject *, PyObject *args) // -> Type
return lookupType(type);
}
static PyObject *cdbext_listOfLocals(PyObject *, PyObject *) // -> [ Value ]
static PyObject *cdbext_listOfLocals(PyObject *, PyObject *args) // -> [ Value ]
{
char *partialVariablesC;
if (!PyArg_ParseTuple(args, "s", &partialVariablesC))
Py_RETURN_NONE;
const std::string partialVariable(partialVariablesC);
IDebugSymbolGroup2 *symbolGroup = nullptr;
auto locals = PyList_New(0);
IDebugSymbolGroup2 *sg;
CIDebugSymbols *symbols = ExtensionCommandContext::instance()->symbols();
if (FAILED(symbols->GetScopeSymbolGroup2(DEBUG_SCOPE_GROUP_ALL, NULL, &sg)))
return locals;
if (partialVariable.empty()) {
symbolGroup = currentSymbolGroup.create();
if (symbolGroup == nullptr)
return locals;
} else {
symbolGroup = currentSymbolGroup.get();
if (symbolGroup == nullptr)
return locals;
ULONG scopeEnd;
if (FAILED(symbolGroup->GetNumberSymbols(&scopeEnd)))
return locals;
std::vector<std::string> inameTokens;
split(partialVariable, '.', std::back_inserter(inameTokens));
auto currentPartialIname = inameTokens.begin();
++currentPartialIname; // skip "local" part
ULONG symbolGroupIndex = 0;
for (;symbolGroupIndex < scopeEnd; ++symbolGroupIndex) {
if (getSymbolName(symbolGroup, symbolGroupIndex) == *currentPartialIname) {
PyList_Append(locals, createValue(symbolGroupIndex, symbolGroup));
return locals;
}
}
}
ULONG symbolCount;
if (FAILED(sg->GetNumberSymbols(&symbolCount)))
if (FAILED(symbolGroup->GetNumberSymbols(&symbolCount)))
return locals;
for (ULONG index = 0; index < symbolCount; ++index)
PyList_Append(locals, createValue(index, sg));
PyList_Append(locals, createValue(index, symbolGroup));
return locals;
}
@@ -196,7 +225,7 @@ static PyMethodDef cdbextMethods[] = {
"Returns value of expression or None if the expression can not be resolved"},
{"lookupType", cdbext_lookupType, METH_VARARGS,
"Returns type object or None if the type can not be resolved"},
{"listOfLocals", cdbext_listOfLocals, METH_NOARGS,
{"listOfLocals", cdbext_listOfLocals, METH_VARARGS,
"Returns list of values that are currently in scope"},
{"pointerSize", cdbext_pointerSize, METH_NOARGS,
"Returns the size of a pointer"},

View File

@@ -41,3 +41,4 @@ struct Value
PyTypeObject *value_pytype();
void initValue(Value *value);
PyObject *createValue(ULONG index, CIDebugSymbolGroup *symbolGroup);
std::string getSymbolName(CIDebugSymbolGroup *sg, ULONG index);