summaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
authorFriedemann Kleint <Friedemann.Kleint@nokia.com>2011-01-18 15:28:55 +0100
committerFriedemann Kleint <Friedemann.Kleint@nokia.com>2011-01-18 15:34:58 +0100
commitcd3b6c7b234712487ebe80f3db16fc5041acd936 (patch)
treedaa9a2ac2820c3347cc409f84b382daa4777b451 /src
parentf0a54abf6b4bbd71bd9a5148f3ebabda6df438fa (diff)
downloadqt-creator-cd3b6c7b234712487ebe80f3db16fc5041acd936.tar.gz
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.
Diffstat (limited to 'src')
-rw-r--r--src/libs/qtcreatorcdbext/extensioncontext.h2
-rw-r--r--src/libs/qtcreatorcdbext/qtcreatorcdbextension.cpp7
-rw-r--r--src/plugins/debugger/cdb/cdbengine.cpp20
3 files changed, 25 insertions, 4 deletions
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<CIDebugControl> m_control;
std::auto_ptr<LocalsSymbolGroup> 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<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;