aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorFriedemann Kleint <Friedemann.Kleint@nokia.com>2009-11-10 10:40:24 +0100
committercon <qtc-committer@nokia.com>2009-11-10 14:00:22 +0100
commited855cbbbcf1673709c769d4193ff78fbc958db0 (patch)
tree65ffc6157e5fde7a3154d66355563d14d690588d
parent7dc7b0c6438c8e22cfe724c555693f8beee40a65 (diff)
Cdb: Fix step out.
Use debugger's 'gu' command instead of temporary breakpoint as a workaround until it is properly supported by the SetExecutionStatus() API. Reviewed-by: hjk Task-number: QTCREATORBUG-240 (cherry picked from commit 5acac101a6cdbc9a304fe9eaf9a2eeb42d3a6201)
-rw-r--r--src/plugins/debugger/cdb/cdbdebugengine.cpp65
-rw-r--r--src/plugins/debugger/cdb/cdbdebugengine.h1
2 files changed, 23 insertions, 43 deletions
diff --git a/src/plugins/debugger/cdb/cdbdebugengine.cpp b/src/plugins/debugger/cdb/cdbdebugengine.cpp
index 6c307af0c5a..08c552dab8b 100644
--- a/src/plugins/debugger/cdb/cdbdebugengine.cpp
+++ b/src/plugins/debugger/cdb/cdbdebugengine.cpp
@@ -1034,9 +1034,16 @@ static inline QString msgStepFailed(unsigned long executionStatus, int threadId,
return QString::fromLatin1("Thread %1: Unable to step into: %2").arg(threadId).arg(why);
}
-// Step with DEBUG_STATUS_STEP_OVER ('p'-command) or
+// Step out has to be done via executing 'gu'. TODO: Remove once it is
+// accessible via normal API for SetExecutionStatus().
+
+enum { CdbExtendedExecutionStatusStepOut = 7452347 };
+
+// Step with DEBUG_STATUS_STEP_OVER ('p'-command),
// DEBUG_STATUS_STEP_INTO ('t'-trace-command) or
+// CdbExtendedExecutionStatusStepOut ("gu"-command)
// its reverse equivalents in the case of single threads.
+
bool CdbDebugEngine::step(unsigned long executionStatus)
{
if (debugCDBExecution)
@@ -1068,7 +1075,7 @@ bool CdbDebugEngine::step(unsigned long executionStatus)
m_d->setCodeLevel(); // Step by instruction or source line
setState(InferiorRunningRequested, Q_FUNC_INFO, __LINE__);
bool success = false;
- if (sameThread) { // Step event-triggering thread, use fast API
+ if (sameThread && executionStatus != CdbExtendedExecutionStatusStepOut) { // Step event-triggering thread, use fast API
const HRESULT hr = m_d->m_cif.debugControl->SetExecutionStatus(executionStatus);
success = SUCCEEDED(hr);
if (!success)
@@ -1077,8 +1084,18 @@ bool CdbDebugEngine::step(unsigned long executionStatus)
// Need to use a command to explicitly specify the current thread
QString command;
QTextStream str(&command);
- str << '~' << m_d->m_currentThreadId << ' '
- << (executionStatus == DEBUG_STATUS_STEP_OVER ? 'p' : 't');
+ str << '~' << m_d->m_currentThreadId << ' ';
+ switch (executionStatus) {
+ case DEBUG_STATUS_STEP_OVER:
+ str << 'p';
+ break;
+ case DEBUG_STATUS_STEP_INTO:
+ str << 't';
+ break;
+ case CdbExtendedExecutionStatusStepOut:
+ str << "gu";
+ break;
+ }
manager()->showDebuggerOutput(tr("Stepping %1").arg(command));
const HRESULT hr = m_d->m_cif.debugControl->Execute(DEBUG_OUTCTL_THIS_CLIENT, command.toLatin1().constData(), DEBUG_EXECUTE_ECHO);
success = SUCCEEDED(hr);
@@ -1121,44 +1138,8 @@ void CdbDebugEngine::nextIExec()
void CdbDebugEngine::stepOutExec()
{
- if (debugCDBExecution)
- qDebug() << "stepOutExec";
- // emulate gdb 'exec-finish' (exec until return of current function)
- // by running up to address of the above stack frame (mostly works).
- const StackHandler* sh = manager()->stackHandler();
- const int idx = sh->currentIndex() + 1;
- const QList<StackFrame> stackframes = sh->frames();
- if (idx < 0 || idx >= stackframes.size()) {
- warning(QString::fromLatin1("Cannot step out of stack frame %1.").arg(idx));
- return;
- }
- // Set a temporary breakpoint and continue
- const StackFrame& frame = stackframes.at(idx);
- bool success = false;
- QString errorMessage;
- do {
- const ULONG64 address = frame.address.toULongLong(&success, 16);
- if (!success) {
- errorMessage = QLatin1String("Cannot obtain address from stack frame");
- break;
- }
- manager()->showDebuggerOutput(LogMisc, tr("Running to 0x%1...").arg(address, 0, 16));
- IDebugBreakpoint2* pBP;
- HRESULT hr = m_d->m_cif.debugControl->AddBreakpoint2(DEBUG_BREAKPOINT_CODE, DEBUG_ANY_ID, &pBP);
- if (FAILED(hr) || !pBP) {
- errorMessage = QString::fromLatin1("Cannot create temporary breakpoint: %1").arg(msgDebugEngineComResult(hr));
- break;
- }
-
- pBP->SetOffset(address);
- pBP->AddFlags(DEBUG_BREAKPOINT_ENABLED);
- pBP->AddFlags(DEBUG_BREAKPOINT_ONE_SHOT);
- if (!m_d->continueInferior(&errorMessage))
- break;
- success = true;
- } while (false);
- if (!success)
- warning(msgFunctionFailed(Q_FUNC_INFO, errorMessage));
+ if (!manager()->isReverseDebugging())
+ step(CdbExtendedExecutionStatusStepOut);
}
void CdbDebugEngine::continueInferior()
diff --git a/src/plugins/debugger/cdb/cdbdebugengine.h b/src/plugins/debugger/cdb/cdbdebugengine.h
index c96a0205961..077faf4e14f 100644
--- a/src/plugins/debugger/cdb/cdbdebugengine.h
+++ b/src/plugins/debugger/cdb/cdbdebugengine.h
@@ -120,7 +120,6 @@ private:
void startWatchTimer();
void killWatchTimer();
void processTerminated(unsigned long exitCode);
- bool executeDebuggerCommand(const QString &command, QString *errorMessage);
bool evaluateExpression(const QString &expression, QString *value, QString *type, QString *errorMessage);
void evaluateWatcher(WatchData *wd);
QString editorToolTip(const QString &exp, const QString &function);