forked from qt-creator/qt-creator
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 <david.schulz@qt.io>
This commit is contained in:
@@ -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)
|
// Try to find a JS execution context passed as parameter in a complete stack dump (kp)
|
||||||
static ULONG64 jsExecutionContextFromStackTrace(const std::wstring &stack)
|
static ULONG64 jsExecutionEngineFromStackTrace(const std::wstring &stack)
|
||||||
{
|
{
|
||||||
// Search for "QV4::ExecutionContext * - varying variable names - 0x...[,)]"
|
// Search for "QV4::ExecutionEngine * - varying variable names - 0x...[,)]"
|
||||||
const wchar_t needle[] = L"struct QV4::ExecutionContext * "; // .. varying variable names .. 0x...
|
const wchar_t needle[] = L"struct QV4::ExecutionEngine * "; // Qt 5.7 onwards
|
||||||
const std::string::size_type varPos = stack.find(needle);
|
std::string::size_type varEnd = std::string::npos;
|
||||||
if (varPos == 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;
|
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);
|
std::string::size_type numPos = stack.find(L"0x", varEnd);
|
||||||
if (numPos == std::string::npos || numPos > (varEnd + 20))
|
if (numPos == std::string::npos || numPos > (varEnd + 20))
|
||||||
return 0;
|
return 0;
|
||||||
@@ -227,10 +235,10 @@ static ULONG64 jsExecutionContextFromStackTrace(const std::wstring &stack)
|
|||||||
return str.fail() ? 0 : result;
|
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.
|
// stack trace in case QML is loaded.
|
||||||
ULONG64 ExtensionContext::jsExecutionContext(ExtensionCommandContext &exc,
|
ULONG64 ExtensionContext::jsExecutionEngine(ExtensionCommandContext &exc,
|
||||||
std::string *errorMessage)
|
std::string *errorMessage)
|
||||||
{
|
{
|
||||||
|
|
||||||
const QtInfo &qtInfo = QtInfo::get(SymbolGroupValueContext(exc.dataSpaces(), exc.symbols()));
|
const QtInfo &qtInfo = QtInfo::get(SymbolGroupValueContext(exc.dataSpaces(), exc.symbols()));
|
||||||
@@ -241,7 +249,7 @@ ULONG64 ExtensionContext::jsExecutionContext(ExtensionCommandContext &exc,
|
|||||||
*errorMessage = "QML not loaded";
|
*errorMessage = "QML not loaded";
|
||||||
return 0;
|
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();
|
startRecordingOutput();
|
||||||
StateNotificationBlocker blocker(this);
|
StateNotificationBlocker blocker(this);
|
||||||
const HRESULT hr = m_control->Execute(DEBUG_OUTCTL_ALL_CLIENTS, "kp", DEBUG_EXECUTE_ECHO);
|
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?)";
|
*errorMessage = "Unable to obtain stack (output redirection in place?)";
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
const ULONG64 result = jsExecutionContextFromStackTrace(fullStackTrace);
|
const ULONG64 result = jsExecutionEngineFromStackTrace(fullStackTrace);
|
||||||
if (!result)
|
if (!result)
|
||||||
*errorMessage = "JS ExecutionContext address not found in stack";
|
*errorMessage = "JS ExecutionEngine address not found in stack";
|
||||||
return result;
|
return result;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@@ -115,7 +115,7 @@ public:
|
|||||||
const Parameters ¶meters() const { return m_parameters; }
|
const Parameters ¶meters() const { return m_parameters; }
|
||||||
Parameters ¶meters() { return m_parameters; }
|
Parameters ¶meters() { return m_parameters; }
|
||||||
|
|
||||||
ULONG64 jsExecutionContext(ExtensionCommandContext &exc, std::string *errorMessage);
|
ULONG64 jsExecutionEngine(ExtensionCommandContext &exc, std::string *errorMessage);
|
||||||
|
|
||||||
bool stateNotification() const { return m_stateNotification; }
|
bool stateNotification() const { return m_stateNotification; }
|
||||||
void setStateNotification(bool s) { m_stateNotification = s; }
|
void setStateNotification(bool s) { m_stateNotification = s; }
|
||||||
|
@@ -1091,7 +1091,7 @@ extern "C" HRESULT CALLBACK qmlstack(CIDebugClient *client, PCSTR argsIn)
|
|||||||
|
|
||||||
int token = 0;
|
int token = 0;
|
||||||
bool humanReadable = false;
|
bool humanReadable = false;
|
||||||
ULONG64 jsExecutionContext = 0;
|
ULONG64 jsExecutionEngine = 0;
|
||||||
std::string stackDump;
|
std::string stackDump;
|
||||||
|
|
||||||
do {
|
do {
|
||||||
@@ -1101,16 +1101,16 @@ extern "C" HRESULT CALLBACK qmlstack(CIDebugClient *client, PCSTR argsIn)
|
|||||||
tokens.pop_front();
|
tokens.pop_front();
|
||||||
}
|
}
|
||||||
if (!tokens.empty()) {
|
if (!tokens.empty()) {
|
||||||
if (!integerFromString(tokens.front(), &jsExecutionContext)) {
|
if (!integerFromString(tokens.front(), &jsExecutionEngine)) {
|
||||||
errorMessage = "Invalid address " + tokens.front();
|
errorMessage = "Invalid address " + tokens.front();
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
tokens.pop_front();
|
tokens.pop_front();
|
||||||
}
|
}
|
||||||
ExtensionCommandContext exc(client);
|
ExtensionCommandContext exc(client);
|
||||||
if (!jsExecutionContext) { // Try to find execution context unless it was given.
|
if (!jsExecutionEngine) { // Try to find execution engine unless it was given.
|
||||||
jsExecutionContext = ExtensionContext::instance().jsExecutionContext(exc, &errorMessage);
|
jsExecutionEngine = ExtensionContext::instance().jsExecutionEngine(exc, &errorMessage);
|
||||||
if (!jsExecutionContext)
|
if (!jsExecutionEngine)
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
// call function to get stack trace. Call with exceptions handled right from
|
// 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;
|
std::ostringstream callStr;
|
||||||
const QtInfo &qtInfo = QtInfo::get(SymbolGroupValueContext(exc.dataSpaces(), exc.symbols()));
|
const QtInfo &qtInfo = QtInfo::get(SymbolGroupValueContext(exc.dataSpaces(), exc.symbols()));
|
||||||
callStr << qtInfo.prependQtModule("qt_v4StackTrace(", QtInfo::Qml) << std::showbase << std::hex
|
callStr << qtInfo.prependQtModule("qt_v4StackTrace(", QtInfo::Qml) << std::showbase << std::hex
|
||||||
<< jsExecutionContext << std::dec << std::noshowbase << ')';
|
<< jsExecutionEngine << std::dec << std::noshowbase << ')';
|
||||||
std::wstring wOutput;
|
std::wstring wOutput;
|
||||||
if (!ExtensionContext::instance().call(callStr.str(), ExtensionContext::CallWithExceptionsHandled, &wOutput, &errorMessage))
|
if (!ExtensionContext::instance().call(callStr.str(), ExtensionContext::CallWithExceptionsHandled, &wOutput, &errorMessage))
|
||||||
break;
|
break;
|
||||||
|
Reference in New Issue
Block a user