forked from qt-creator/qt-creator
Debugger: evaluate expression before assigning when using python dumper
Fixes: QTCREATORBUG-23711 Change-Id: Ic386b3e4bdd948e74f52116248de1b33a35fe03a Reviewed-by: hjk <hjk@qt.io> Reviewed-by: Christian Stenger <christian.stenger@qt.io>
This commit is contained in:
@@ -160,7 +160,7 @@ static const CommandDescription commandDescriptions[] = {
|
|||||||
{"assign","Assigns a value to a variable in current symbol group.",
|
{"assign","Assigns a value to a variable in current symbol group.",
|
||||||
"[-t token] [-h] <iname=value>\n"
|
"[-t token] [-h] <iname=value>\n"
|
||||||
"-h Data are hex-encoded, binary data\n"
|
"-h Data are hex-encoded, binary data\n"
|
||||||
"-u Data are hex-encoded, UTF16 data"
|
"-e iname is an hex-encoded expression to be evaluated "
|
||||||
},
|
},
|
||||||
{"threads","Lists threads in GDBMI format.","[-t token]"},
|
{"threads","Lists threads in GDBMI format.","[-t token]"},
|
||||||
{"registers","Lists registers in GDBMI format","[-t token]"},
|
{"registers","Lists registers in GDBMI format","[-t token]"},
|
||||||
@@ -819,57 +819,77 @@ extern "C" HRESULT CALLBACK assign(CIDebugClient *client, PCSTR argsIn)
|
|||||||
ExtensionCommandContext exc(client);
|
ExtensionCommandContext exc(client);
|
||||||
|
|
||||||
std::string errorMessage;
|
std::string errorMessage;
|
||||||
bool success = false;
|
|
||||||
bool encoded = false;
|
bool encoded = false;
|
||||||
|
bool evaluateExpression = false;
|
||||||
int token = 0;
|
int token = 0;
|
||||||
do {
|
StringList tokens = commandTokens<StringList>(argsIn, &token);
|
||||||
StringList tokens = commandTokens<StringList>(argsIn, &token);
|
while (!tokens.empty()) {
|
||||||
if (tokens.empty()) {
|
|
||||||
errorMessage = singleLineUsage(commandDescriptions[CmdAssign]);
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (tokens.front() == "-h") {
|
if (tokens.front() == "-h") {
|
||||||
encoded = true;
|
encoded = true;
|
||||||
tokens.pop_front();
|
tokens.pop_front();
|
||||||
|
continue;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (tokens.empty()) {
|
if (tokens.front() == "-e") {
|
||||||
errorMessage = singleLineUsage(commandDescriptions[CmdAssign]);
|
evaluateExpression = true;
|
||||||
break;
|
tokens.pop_front();
|
||||||
|
continue;
|
||||||
}
|
}
|
||||||
|
break;
|
||||||
|
};
|
||||||
|
|
||||||
// Parse 'assign locals.x=5'
|
// Parse 'assign locals.x=5'
|
||||||
const std::string::size_type equalsPos = tokens.front().find('=');
|
const std::string::size_type equalsPos = tokens.empty() ? std::string::npos
|
||||||
if (equalsPos == std::string::npos) {
|
: tokens.front().find('=');
|
||||||
errorMessage = singleLineUsage(commandDescriptions[CmdAssign]);
|
if (equalsPos == std::string::npos) {
|
||||||
break;
|
errorMessage = singleLineUsage(commandDescriptions[CmdAssign]);
|
||||||
}
|
} else {
|
||||||
const std::string iname = tokens.front().substr(0, equalsPos);
|
std::string iname = tokens.front().substr(0, equalsPos);
|
||||||
const std::string value = tokens.front().substr(equalsPos + 1, tokens.front().size() - equalsPos - 1);
|
const std::string value = tokens.front().substr(equalsPos + 1,
|
||||||
// get the symbolgroup
|
tokens.front().size() - equalsPos - 1);
|
||||||
int currentFrame = ExtensionContext::instance().symbolGroupFrame();
|
SymbolGroup *symGroup = nullptr;
|
||||||
if (currentFrame < 0) {
|
if (evaluateExpression) {
|
||||||
CIDebugControl *control = ExtensionCommandContext::instance()->control();
|
WatchesSymbolGroup *watchesSymGroup
|
||||||
DEBUG_STACK_FRAME frame;
|
= ExtensionContext::instance().watchesSymbolGroup(exc.symbols(), &errorMessage);
|
||||||
if (FAILED(control->GetStackTrace(0, 0, 0, &frame, 1, NULL))) {
|
std::string tempAssignIname = "watch.tmpassign";
|
||||||
errorMessage = "No current frame.";
|
if (watchesSymGroup) {
|
||||||
break;
|
if (watchesSymGroup->addWatch(exc.symbols(),
|
||||||
|
tempAssignIname,
|
||||||
|
stringFromHex(iname),
|
||||||
|
&errorMessage)) {
|
||||||
|
iname = tempAssignIname;
|
||||||
|
symGroup = watchesSymGroup;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
// get the symbolgroup
|
||||||
|
int currentFrame = ExtensionContext::instance().symbolGroupFrame();
|
||||||
|
if (currentFrame < 0) {
|
||||||
|
CIDebugControl *control = ExtensionCommandContext::instance()->control();
|
||||||
|
DEBUG_STACK_FRAME frame;
|
||||||
|
if (FAILED(control->GetStackTrace(0, 0, 0, &frame, 1, NULL)))
|
||||||
|
errorMessage = "No current frame.";
|
||||||
|
else
|
||||||
|
currentFrame = frame.FrameNumber;
|
||||||
|
}
|
||||||
|
if (currentFrame >= 0) {
|
||||||
|
symGroup = ExtensionContext::instance().symbolGroup(exc.symbols(),
|
||||||
|
exc.threadId(),
|
||||||
|
currentFrame,
|
||||||
|
&errorMessage);
|
||||||
}
|
}
|
||||||
currentFrame = frame.FrameNumber;
|
|
||||||
}
|
}
|
||||||
SymbolGroup *symGroup = ExtensionContext::instance().symbolGroup(exc.symbols(), exc.threadId(), currentFrame, &errorMessage);
|
if (symGroup
|
||||||
if (!symGroup)
|
&& symGroup->assign(iname,
|
||||||
break;
|
encoded ? stringFromHex(value) : value,
|
||||||
success = symGroup->assign(iname, encoded ? stringFromHex(value) : value,
|
SymbolGroupValueContext(exc.dataSpaces(), exc.symbols()),
|
||||||
SymbolGroupValueContext(exc.dataSpaces(), exc.symbols()),
|
&errorMessage)) {
|
||||||
&errorMessage);
|
ExtensionContext::instance().report('R', token, 0, "assign", "Ok");
|
||||||
} while (false);
|
return S_OK;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
if (success)
|
ExtensionContext::instance().report('N', token, 0, "assign", errorMessage.c_str());
|
||||||
ExtensionContext::instance().report('R', token, 0, "assign", "Ok");
|
|
||||||
else
|
|
||||||
ExtensionContext::instance().report('N', token, 0, "assign", errorMessage.c_str());
|
|
||||||
return S_OK;
|
return S_OK;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@@ -929,8 +929,15 @@ void CdbEngine::assignValueInDebugger(WatchItem *w, const QString &expr, const Q
|
|||||||
qWarning("Internal error: assignValueInDebugger: Invalid state or no stack frame.");
|
qWarning("Internal error: assignValueInDebugger: Invalid state or no stack frame.");
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
runCommand({m_extensionCommandPrefix + "assign -h " + w->iname + '=' + toHex(value.toString()),
|
if (m_pythonVersion > 0x030000 && w->isWatcher()) {
|
||||||
NoFlags});
|
runCommand({m_extensionCommandPrefix + "assign -h -e " + toHex(w->expression()) + '='
|
||||||
|
+ toHex(value.toString()),
|
||||||
|
NoFlags});
|
||||||
|
} else {
|
||||||
|
runCommand({m_extensionCommandPrefix + "assign -h " + w->iname + '=' + toHex(value.toString()),
|
||||||
|
NoFlags});
|
||||||
|
}
|
||||||
|
|
||||||
// Update all locals in case we change a union or something pointed to
|
// Update all locals in case we change a union or something pointed to
|
||||||
// that affects other variables, too.
|
// that affects other variables, too.
|
||||||
updateLocals();
|
updateLocals();
|
||||||
|
Reference in New Issue
Block a user