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

Debugger[CDB]: Switch to thread 0 after DebugBreak().

Do not show artificial thread that is created by
DebugBreak() as it causes a switch to disassembly.
Forcibly discard the symbol group for each locals
update as the lazy creation mechanism does not trigger
on thread changes back and forth involving assembly,
which causes the symbol group to become stale.
parent f0a54abf
......@@ -90,6 +90,7 @@ public:
// Return symbol group for frame (cached as long as frame/thread do not change).
LocalsSymbolGroup *symbolGroup(CIDebugSymbols *symbols, ULONG threadId, int frame, std::string *errorMessage);
int symbolGroupFrame() const;
void discardSymbolGroup();
WatchesSymbolGroup *watchesSymbolGroup(CIDebugSymbols *symbols, std::string *errorMessage);
WatchesSymbolGroup *watchesSymbolGroup() const; // Do not create.
......@@ -105,7 +106,6 @@ public:
private:
bool isInitialized() const;
void discardSymbolGroup();
IInterfacePointer<CIDebugControl> m_control;
std::auto_ptr<LocalsSymbolGroup> m_symbolGroup;
......
......@@ -125,6 +125,7 @@ static const CommandDescription commandDescriptions[] = {
"-u uninitialized-list Comma-separated list of uninitialized inames\n"
"-I formatmap map of 'hex-encoded-iname=typecode'\n"
"-T formatmap map of 'hex-encoded-type-name=typecode'\n"
"-D Discard existing symbol group\n"
"-W Synchronize watch items (-w)\n"
"-w iname expression Watch item"},
{"watches",
......@@ -403,6 +404,7 @@ static std::string commmandLocals(ExtensionCommandContext &commandExtCtx,PCSTR a
StringVector uninitializedInames;
InameExpressionMap watcherInameExpressionMap;
bool watchSynchronization = false;
bool discardSymbolGroup = false;
// Parse away options
for (bool optionLeft = true; optionLeft && !tokens.empty(); ) {
switch (parameters.parseOption(&tokens)) {
......@@ -446,6 +448,9 @@ static std::string commmandLocals(ExtensionCommandContext &commandExtCtx,PCSTR a
case 'W':
watchSynchronization = true;
break;
case 'D':
discardSymbolGroup = true;
break;
} // case option
}
break;
......@@ -466,6 +471,8 @@ static std::string commmandLocals(ExtensionCommandContext &commandExtCtx,PCSTR a
iname = tokens.front();
const SymbolGroupValueContext dumpContext(commandExtCtx.dataSpaces(), commandExtCtx.symbols());
if (discardSymbolGroup)
extCtx.discardSymbolGroup();
SymbolGroup * const symGroup = extCtx.symbolGroup(commandExtCtx.symbols(), commandExtCtx.threadId(), frame, errorMessage);
if (!symGroup)
return std::string();
......
......@@ -1111,9 +1111,13 @@ void CdbEngine::updateLocals()
watchHandler()->endCycle();
return;
}
// Watchers: Initial expand, get uninitialized and query
/* Watchers: Forcibly discard old symbol group as switching from
* thread 0/frame 0 -> thread 1/assembly -> thread 0/frame 0 will otherwise re-use it
* and cause errors as it seems to go 'stale' when switching threads.
* Initial expand, get uninitialized and query */
QByteArray arguments;
ByteArrayInputStream str(arguments);
str << "-D";
// Pre-expand
const QSet<QByteArray> expanded = watchHandler()->expandedINames();
if (!expanded.isEmpty()) {
......@@ -1428,7 +1432,9 @@ enum StopActionFlags
StopShowExceptionMessageBox = 0x4,
// Notify stop or just continue
StopNotifyStop = 0x8,
StopIgnoreContinue = 0x10
StopIgnoreContinue = 0x10,
// Hit on break in artificial stop thread (created by DebugBreak()).
StopInArtificialThread = 0x20
};
unsigned CdbEngine::examineStopReason(const QByteArray &messageIn,
......@@ -1483,8 +1489,12 @@ unsigned CdbEngine::examineStopReason(const QByteArray &messageIn,
}
}
if (isDebuggerWinException(exception.exceptionCode)) {
unsigned rc = StopReportStatusMessage|StopNotifyStop;
// Detect interruption by DebugBreak() and force a switch to thread 0.
if (exception.function == "ntdll!DbgBreakPoint")
rc |= StopInArtificialThread;
*message = msgInterrupted();
return StopReportStatusMessage|StopNotifyStop;
return rc;
}
#endif
*exceptionBoxMessage = msgStoppedByException(description, QString::number(threadId));
......@@ -1561,6 +1571,10 @@ void CdbEngine::handleSessionIdle(const QByteArray &messageBA)
notifyInferiorSpontaneousStop();
}
// Start sequence to get all relevant data.
if (stopFlags & StopInArtificialThread) {
showMessage(tr("Switching to main thread..."), LogMisc);
postCommand("~0 s", 0);
}
unsigned sequence = CommandListStack|CommandListThreads;
if (debuggerCore()->isDockVisible(QLatin1String(Constants::DOCKWIDGET_REGISTER)))
sequence |= CommandListRegisters;
......
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