From cd3b6c7b234712487ebe80f3db16fc5041acd936 Mon Sep 17 00:00:00 2001 From: Friedemann Kleint Date: Tue, 18 Jan 2011 15:28:55 +0100 Subject: 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. --- src/libs/qtcreatorcdbext/extensioncontext.h | 2 +- src/libs/qtcreatorcdbext/qtcreatorcdbextension.cpp | 7 +++++++ src/plugins/debugger/cdb/cdbengine.cpp | 20 +++++++++++++++++--- 3 files changed, 25 insertions(+), 4 deletions(-) (limited to 'src') diff --git a/src/libs/qtcreatorcdbext/extensioncontext.h b/src/libs/qtcreatorcdbext/extensioncontext.h index 27a3f76b22..5c7baad436 100644 --- a/src/libs/qtcreatorcdbext/extensioncontext.h +++ b/src/libs/qtcreatorcdbext/extensioncontext.h @@ -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 m_control; std::auto_ptr m_symbolGroup; diff --git a/src/libs/qtcreatorcdbext/qtcreatorcdbextension.cpp b/src/libs/qtcreatorcdbext/qtcreatorcdbextension.cpp index ef3fd00ec0..785efdcc8e 100644 --- a/src/libs/qtcreatorcdbext/qtcreatorcdbextension.cpp +++ b/src/libs/qtcreatorcdbext/qtcreatorcdbextension.cpp @@ -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(); diff --git a/src/plugins/debugger/cdb/cdbengine.cpp b/src/plugins/debugger/cdb/cdbengine.cpp index d6d8440035..8ad1c17f48 100644 --- a/src/plugins/debugger/cdb/cdbengine.cpp +++ b/src/plugins/debugger/cdb/cdbengine.cpp @@ -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 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; -- cgit v1.2.1