Commit bb380a00 authored by Friedemann Kleint's avatar Friedemann Kleint
Browse files

CDB extension: Also look for QV4::ExecutionEngine for the QML stack



The struct has been renamed from QV4::ExecutionContext to
QV4::ExecutionEngine in Qt 5.7.

Task-number: QTCREATORBUG-17097
Change-Id: If9685d039d3d1f9caf369ec847ac6705747ae9f7
Reviewed-by: David Schulz's avatarDavid Schulz <david.schulz@qt.io>
parent 24281353
......@@ -202,14 +202,22 @@ static std::string findModule(CIDebugSymbols *syms,
}
// Try to find a JS execution context passed as parameter in a complete stack dump (kp)
static ULONG64 jsExecutionContextFromStackTrace(const std::wstring &stack)
{
// Search for "QV4::ExecutionContext * - varying variable names - 0x...[,)]"
const wchar_t needle[] = L"struct QV4::ExecutionContext * "; // .. varying variable names .. 0x...
const std::string::size_type varPos = stack.find(needle);
if (varPos == std::string::npos)
static ULONG64 jsExecutionEngineFromStackTrace(const std::wstring &stack)
{
// Search for "QV4::ExecutionEngine * - varying variable names - 0x...[,)]"
const wchar_t needle[] = L"struct QV4::ExecutionEngine * "; // Qt 5.7 onwards
std::string::size_type varEnd = std::string::npos;
std::string::size_type varPos = stack.find(needle);
if (varPos != std::string::npos) {
varEnd = varPos + sizeof(needle) / sizeof(wchar_t) - 1;
} else {
const wchar_t needle56[] = L"struct QV4::ExecutionContext * "; // up to Qt 5.6
varPos = stack.find(needle56);
if (varPos != std::string::npos)
varEnd = varPos + sizeof(needle56) / sizeof(wchar_t) - 1;
}
if (varEnd == std::string::npos)
return 0;
const std::string::size_type varEnd = varPos + sizeof(needle) / sizeof(wchar_t) - 1;
std::string::size_type numPos = stack.find(L"0x", varEnd);
if (numPos == std::string::npos || numPos > (varEnd + 20))
return 0;
......@@ -227,10 +235,10 @@ static ULONG64 jsExecutionContextFromStackTrace(const std::wstring &stack)
return str.fail() ? 0 : result;
}
// Try to find address of jsExecutionContext by looking at the
// Try to find address of jsExecutionEngine by looking at the
// stack trace in case QML is loaded.
ULONG64 ExtensionContext::jsExecutionContext(ExtensionCommandContext &exc,
std::string *errorMessage)
ULONG64 ExtensionContext::jsExecutionEngine(ExtensionCommandContext &exc,
std::string *errorMessage)
{
const QtInfo &qtInfo = QtInfo::get(SymbolGroupValueContext(exc.dataSpaces(), exc.symbols()));
......@@ -241,7 +249,7 @@ ULONG64 ExtensionContext::jsExecutionContext(ExtensionCommandContext &exc,
*errorMessage = "QML not loaded";
return 0;
}
// Retrieve full stack (costly) and try to find a JS execution context passed as parameter
// Retrieve full stack (costly) and try to find a JS execution engine passed as parameter
startRecordingOutput();
StateNotificationBlocker blocker(this);
const HRESULT hr = m_control->Execute(DEBUG_OUTCTL_ALL_CLIENTS, "kp", DEBUG_EXECUTE_ECHO);
......@@ -255,9 +263,9 @@ ULONG64 ExtensionContext::jsExecutionContext(ExtensionCommandContext &exc,
*errorMessage = "Unable to obtain stack (output redirection in place?)";
return 0;
}
const ULONG64 result = jsExecutionContextFromStackTrace(fullStackTrace);
const ULONG64 result = jsExecutionEngineFromStackTrace(fullStackTrace);
if (!result)
*errorMessage = "JS ExecutionContext address not found in stack";
*errorMessage = "JS ExecutionEngine address not found in stack";
return result;
}
......
......@@ -115,7 +115,7 @@ public:
const Parameters &parameters() const { return m_parameters; }
Parameters &parameters() { return m_parameters; }
ULONG64 jsExecutionContext(ExtensionCommandContext &exc, std::string *errorMessage);
ULONG64 jsExecutionEngine(ExtensionCommandContext &exc, std::string *errorMessage);
bool stateNotification() const { return m_stateNotification; }
void setStateNotification(bool s) { m_stateNotification = s; }
......
......@@ -1091,7 +1091,7 @@ extern "C" HRESULT CALLBACK qmlstack(CIDebugClient *client, PCSTR argsIn)
int token = 0;
bool humanReadable = false;
ULONG64 jsExecutionContext = 0;
ULONG64 jsExecutionEngine = 0;
std::string stackDump;
do {
......@@ -1101,16 +1101,16 @@ extern "C" HRESULT CALLBACK qmlstack(CIDebugClient *client, PCSTR argsIn)
tokens.pop_front();
}
if (!tokens.empty()) {
if (!integerFromString(tokens.front(), &jsExecutionContext)) {
if (!integerFromString(tokens.front(), &jsExecutionEngine)) {
errorMessage = "Invalid address " + tokens.front();
break;
}
tokens.pop_front();
}
ExtensionCommandContext exc(client);
if (!jsExecutionContext) { // Try to find execution context unless it was given.
jsExecutionContext = ExtensionContext::instance().jsExecutionContext(exc, &errorMessage);
if (!jsExecutionContext)
if (!jsExecutionEngine) { // Try to find execution engine unless it was given.
jsExecutionEngine = ExtensionContext::instance().jsExecutionEngine(exc, &errorMessage);
if (!jsExecutionEngine)
break;
}
// call function to get stack trace. Call with exceptions handled right from
......@@ -1118,7 +1118,7 @@ extern "C" HRESULT CALLBACK qmlstack(CIDebugClient *client, PCSTR argsIn)
std::ostringstream callStr;
const QtInfo &qtInfo = QtInfo::get(SymbolGroupValueContext(exc.dataSpaces(), exc.symbols()));
callStr << qtInfo.prependQtModule("qt_v4StackTrace(", QtInfo::Qml) << std::showbase << std::hex
<< jsExecutionContext << std::dec << std::noshowbase << ')';
<< jsExecutionEngine << std::dec << std::noshowbase << ')';
std::wstring wOutput;
if (!ExtensionContext::instance().call(callStr.str(), ExtensionContext::CallWithExceptionsHandled, &wOutput, &errorMessage))
break;
......
Markdown is supported
0% or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment