forked from qt-creator/qt-creator
debugger: implement basic support for gdb's 'return' command
Returning a value is not yet supported.
This commit is contained in:
@@ -154,6 +154,7 @@ struct DebuggerManagerActions
|
|||||||
QAction *runToFunctionAction;
|
QAction *runToFunctionAction;
|
||||||
QAction *jumpToLineAction1; // in the Debug menu
|
QAction *jumpToLineAction1; // in the Debug menu
|
||||||
QAction *jumpToLineAction2; // in the text editor context menu
|
QAction *jumpToLineAction2; // in the text editor context menu
|
||||||
|
QAction *returnFromFunctionAction;
|
||||||
QAction *nextAction;
|
QAction *nextAction;
|
||||||
QAction *snapshotAction;
|
QAction *snapshotAction;
|
||||||
QAction *watchAction1; // in the Debug menu
|
QAction *watchAction1; // in the Debug menu
|
||||||
|
|||||||
@@ -53,9 +53,11 @@ const char * const C_GDBDEBUGGER = "Gdb Debugger";
|
|||||||
const char * const GDBRUNNING = "Gdb.Running";
|
const char * const GDBRUNNING = "Gdb.Running";
|
||||||
|
|
||||||
const char * const DEBUGGER_COMMON_SETTINGS_ID = "A.Common";
|
const char * const DEBUGGER_COMMON_SETTINGS_ID = "A.Common";
|
||||||
const char * const DEBUGGER_COMMON_SETTINGS_NAME = QT_TRANSLATE_NOOP("Debugger", "Common");
|
const char * const DEBUGGER_COMMON_SETTINGS_NAME =
|
||||||
|
QT_TRANSLATE_NOOP("Debugger", "Common");
|
||||||
const char * const DEBUGGER_SETTINGS_CATEGORY = "O.Debugger";
|
const char * const DEBUGGER_SETTINGS_CATEGORY = "O.Debugger";
|
||||||
const char * const DEBUGGER_SETTINGS_TR_CATEGORY = QT_TRANSLATE_NOOP("Debugger", "Debugger");
|
const char * const DEBUGGER_SETTINGS_TR_CATEGORY =
|
||||||
|
QT_TRANSLATE_NOOP("Debugger", "Debugger");
|
||||||
|
|
||||||
namespace Internal {
|
namespace Internal {
|
||||||
enum { debug = 0 };
|
enum { debug = 0 };
|
||||||
@@ -65,9 +67,10 @@ namespace Internal {
|
|||||||
const char * const LD_PRELOAD_ENV_VAR = "LD_PRELOAD";
|
const char * const LD_PRELOAD_ENV_VAR = "LD_PRELOAD";
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
}
|
} // namespace Internal
|
||||||
} // namespace Constants
|
} // namespace Constants
|
||||||
|
|
||||||
|
|
||||||
enum DebuggerState
|
enum DebuggerState
|
||||||
{
|
{
|
||||||
DebuggerNotReady, // Debugger not started
|
DebuggerNotReady, // Debugger not started
|
||||||
@@ -121,6 +124,7 @@ enum DebuggerCapabilities
|
|||||||
ReloadModuleCapability = 0x80,
|
ReloadModuleCapability = 0x80,
|
||||||
ReloadModuleSymbolsCapability = 0x100,
|
ReloadModuleSymbolsCapability = 0x100,
|
||||||
BreakOnThrowAndCatchCapability = 0x200,
|
BreakOnThrowAndCatchCapability = 0x200,
|
||||||
|
ReturnFromFunctionCapability = 0x400,
|
||||||
};
|
};
|
||||||
|
|
||||||
enum LogChannel
|
enum LogChannel
|
||||||
|
|||||||
@@ -485,7 +485,11 @@ void DebuggerManager::init()
|
|||||||
d->m_actions.runToLineAction1 = new QAction(tr("Run to Line"), this);
|
d->m_actions.runToLineAction1 = new QAction(tr("Run to Line"), this);
|
||||||
d->m_actions.runToLineAction2 = new QAction(tr("Run to Line"), this);
|
d->m_actions.runToLineAction2 = new QAction(tr("Run to Line"), this);
|
||||||
|
|
||||||
d->m_actions.runToFunctionAction = new QAction(tr("Run to Outermost Function"), this);
|
d->m_actions.runToFunctionAction =
|
||||||
|
new QAction(tr("Run to Outermost Function"), this);
|
||||||
|
|
||||||
|
d->m_actions.returnFromFunctionAction =
|
||||||
|
new QAction(tr("Immediately Return From Inner Function"), this);
|
||||||
|
|
||||||
d->m_actions.jumpToLineAction1 = new QAction(tr("Jump to Line"), this);
|
d->m_actions.jumpToLineAction1 = new QAction(tr("Jump to Line"), this);
|
||||||
d->m_actions.jumpToLineAction2 = new QAction(tr("Jump to Line"), this);
|
d->m_actions.jumpToLineAction2 = new QAction(tr("Jump to Line"), this);
|
||||||
@@ -524,6 +528,8 @@ void DebuggerManager::init()
|
|||||||
this, SLOT(jumpToLineExec()));
|
this, SLOT(jumpToLineExec()));
|
||||||
connect(d->m_actions.jumpToLineAction2, SIGNAL(triggered()),
|
connect(d->m_actions.jumpToLineAction2, SIGNAL(triggered()),
|
||||||
this, SLOT(jumpToLineExec()));
|
this, SLOT(jumpToLineExec()));
|
||||||
|
connect(d->m_actions.returnFromFunctionAction, SIGNAL(triggered()),
|
||||||
|
this, SLOT(returnExec()));
|
||||||
connect(d->m_actions.watchAction1, SIGNAL(triggered()),
|
connect(d->m_actions.watchAction1, SIGNAL(triggered()),
|
||||||
this, SLOT(addToWatchWindow()));
|
this, SLOT(addToWatchWindow()));
|
||||||
connect(d->m_actions.watchAction2, SIGNAL(triggered()),
|
connect(d->m_actions.watchAction2, SIGNAL(triggered()),
|
||||||
@@ -1185,6 +1191,13 @@ void DebuggerManager::nextExec()
|
|||||||
d->m_engine->nextExec();
|
d->m_engine->nextExec();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void DebuggerManager::returnExec()
|
||||||
|
{
|
||||||
|
QTC_ASSERT(d->m_engine, return);
|
||||||
|
resetLocation();
|
||||||
|
d->m_engine->returnExec();
|
||||||
|
}
|
||||||
|
|
||||||
void DebuggerManager::watchPoint()
|
void DebuggerManager::watchPoint()
|
||||||
{
|
{
|
||||||
if (QAction *action = qobject_cast<QAction *>(sender()))
|
if (QAction *action = qobject_cast<QAction *>(sender()))
|
||||||
@@ -1742,8 +1755,8 @@ void DebuggerManager::setState(DebuggerState state, bool forced)
|
|||||||
d->m_actions.watchAction1->setEnabled(true);
|
d->m_actions.watchAction1->setEnabled(true);
|
||||||
d->m_actions.watchAction2->setEnabled(true);
|
d->m_actions.watchAction2->setEnabled(true);
|
||||||
d->m_actions.breakAction->setEnabled(true);
|
d->m_actions.breakAction->setEnabled(true);
|
||||||
d->m_actions.snapshotAction->setEnabled(
|
d->m_actions.snapshotAction->
|
||||||
stopped && (engineCapabilities & SnapshotCapability));
|
setEnabled(stopped && (engineCapabilities & SnapshotCapability));
|
||||||
|
|
||||||
const bool interruptIsExit = !running;
|
const bool interruptIsExit = !running;
|
||||||
if (interruptIsExit) {
|
if (interruptIsExit) {
|
||||||
@@ -1762,6 +1775,8 @@ void DebuggerManager::setState(DebuggerState state, bool forced)
|
|||||||
d->m_actions.runToLineAction1->setEnabled(stopped);
|
d->m_actions.runToLineAction1->setEnabled(stopped);
|
||||||
d->m_actions.runToLineAction2->setEnabled(stopped);
|
d->m_actions.runToLineAction2->setEnabled(stopped);
|
||||||
d->m_actions.runToFunctionAction->setEnabled(stopped);
|
d->m_actions.runToFunctionAction->setEnabled(stopped);
|
||||||
|
d->m_actions.returnFromFunctionAction->
|
||||||
|
setEnabled(stopped && (engineCapabilities & ReturnFromFunctionCapability));
|
||||||
|
|
||||||
const bool canJump = stopped && (engineCapabilities & JumpToLineCapability);
|
const bool canJump = stopped && (engineCapabilities & JumpToLineCapability);
|
||||||
d->m_actions.jumpToLineAction1->setEnabled(canJump);
|
d->m_actions.jumpToLineAction1->setEnabled(canJump);
|
||||||
|
|||||||
@@ -235,6 +235,7 @@ public slots:
|
|||||||
void stepOutExec();
|
void stepOutExec();
|
||||||
void nextExec();
|
void nextExec();
|
||||||
void continueExec();
|
void continueExec();
|
||||||
|
void returnExec();
|
||||||
void detachDebugger();
|
void detachDebugger();
|
||||||
void makeSnapshot();
|
void makeSnapshot();
|
||||||
|
|
||||||
|
|||||||
@@ -119,6 +119,7 @@ const char * const RUN_TO_LINE2 = "Debugger.RunToLine2";
|
|||||||
const char * const RUN_TO_FUNCTION = "Debugger.RunToFunction";
|
const char * const RUN_TO_FUNCTION = "Debugger.RunToFunction";
|
||||||
const char * const JUMP_TO_LINE1 = "Debugger.JumpToLine1";
|
const char * const JUMP_TO_LINE1 = "Debugger.JumpToLine1";
|
||||||
const char * const JUMP_TO_LINE2 = "Debugger.JumpToLine2";
|
const char * const JUMP_TO_LINE2 = "Debugger.JumpToLine2";
|
||||||
|
const char * const RETURN_FROM_FUNCTION = "Debugger.ReturnFromFunction";
|
||||||
const char * const SNAPSHOT = "Debugger.Snapshot";
|
const char * const SNAPSHOT = "Debugger.Snapshot";
|
||||||
const char * const TOGGLE_BREAK = "Debugger.ToggleBreak";
|
const char * const TOGGLE_BREAK = "Debugger.ToggleBreak";
|
||||||
const char * const BREAK_BY_FUNCTION = "Debugger.BreakByFunction";
|
const char * const BREAK_BY_FUNCTION = "Debugger.BreakByFunction";
|
||||||
@@ -799,6 +800,10 @@ bool DebuggerPlugin::initialize(const QStringList &arguments, QString *errorMess
|
|||||||
Constants::JUMP_TO_LINE1, debuggercontext);
|
Constants::JUMP_TO_LINE1, debuggercontext);
|
||||||
mdebug->addAction(cmd);
|
mdebug->addAction(cmd);
|
||||||
|
|
||||||
|
cmd = am->registerAction(actions.returnFromFunctionAction,
|
||||||
|
Constants::RETURN_FROM_FUNCTION, debuggercontext);
|
||||||
|
mdebug->addAction(cmd);
|
||||||
|
|
||||||
#ifdef USE_REVERSE_DEBUGGING
|
#ifdef USE_REVERSE_DEBUGGING
|
||||||
cmd = am->registerAction(actions.reverseDirectionAction,
|
cmd = am->registerAction(actions.reverseDirectionAction,
|
||||||
Constants::REVERSE, debuggercontext);
|
Constants::REVERSE, debuggercontext);
|
||||||
|
|||||||
@@ -1711,7 +1711,8 @@ unsigned GdbEngine::debuggerCapabilities() const
|
|||||||
| AutoDerefPointersCapability | DisassemblerCapability
|
| AutoDerefPointersCapability | DisassemblerCapability
|
||||||
| RegisterCapability | ShowMemoryCapability
|
| RegisterCapability | ShowMemoryCapability
|
||||||
| JumpToLineCapability | ReloadModuleCapability
|
| JumpToLineCapability | ReloadModuleCapability
|
||||||
| ReloadModuleSymbolsCapability | BreakOnThrowAndCatchCapability;
|
| ReloadModuleSymbolsCapability | BreakOnThrowAndCatchCapability
|
||||||
|
| ReturnFromFunctionCapability;
|
||||||
}
|
}
|
||||||
|
|
||||||
void GdbEngine::continueInferiorInternal()
|
void GdbEngine::continueInferiorInternal()
|
||||||
@@ -1902,6 +1903,21 @@ void GdbEngine::jumpToLineExec(const QString &fileName, int lineNumber)
|
|||||||
#endif
|
#endif
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void GdbEngine::returnExec()
|
||||||
|
{
|
||||||
|
QTC_ASSERT(state() == InferiorStopped, qDebug() << state());
|
||||||
|
setTokenBarrier();
|
||||||
|
setState(InferiorRunningRequested);
|
||||||
|
showStatusMessage(tr("Immediate return from function requested..."), 5000);
|
||||||
|
postCommand("-exec-finish", RunRequest, CB(handleExecReturn));
|
||||||
|
}
|
||||||
|
|
||||||
|
void GdbEngine::handleExecReturn(const GdbResponse &response)
|
||||||
|
{
|
||||||
|
if (response.resultClass == GdbResultDone) {
|
||||||
|
updateAll();
|
||||||
|
}
|
||||||
|
}
|
||||||
/*!
|
/*!
|
||||||
\fn void GdbEngine::setTokenBarrier()
|
\fn void GdbEngine::setTokenBarrier()
|
||||||
\brief Discard the results of all pending watch-updating commands.
|
\brief Discard the results of all pending watch-updating commands.
|
||||||
|
|||||||
@@ -296,10 +296,12 @@ private: ////////// Inferior Management //////////
|
|||||||
virtual void runToFunctionExec(const QString &functionName);
|
virtual void runToFunctionExec(const QString &functionName);
|
||||||
// void handleExecRunToFunction(const GdbResponse &response);
|
// void handleExecRunToFunction(const GdbResponse &response);
|
||||||
virtual void jumpToLineExec(const QString &fileName, int lineNumber);
|
virtual void jumpToLineExec(const QString &fileName, int lineNumber);
|
||||||
|
virtual void returnExec();
|
||||||
|
|
||||||
void handleExecContinue(const GdbResponse &response);
|
void handleExecContinue(const GdbResponse &response);
|
||||||
void handleExecStep(const GdbResponse &response);
|
void handleExecStep(const GdbResponse &response);
|
||||||
void handleExecNext(const GdbResponse &response);
|
void handleExecNext(const GdbResponse &response);
|
||||||
|
void handleExecReturn(const GdbResponse &response);
|
||||||
|
|
||||||
qint64 inferiorPid() const { return m_manager->inferiorPid(); }
|
qint64 inferiorPid() const { return m_manager->inferiorPid(); }
|
||||||
void handleInferiorPidChanged(qint64 pid) { manager()->notifyInferiorPidChanged(pid); }
|
void handleInferiorPidChanged(qint64 pid) { manager()->notifyInferiorPidChanged(pid); }
|
||||||
|
|||||||
@@ -82,6 +82,7 @@ public:
|
|||||||
virtual void nextExec() = 0;
|
virtual void nextExec() = 0;
|
||||||
virtual void stepIExec() = 0;
|
virtual void stepIExec() = 0;
|
||||||
virtual void nextIExec() = 0;
|
virtual void nextIExec() = 0;
|
||||||
|
virtual void returnExec() {}
|
||||||
|
|
||||||
virtual void continueInferior() = 0;
|
virtual void continueInferior() = 0;
|
||||||
virtual void interruptInferior() = 0;
|
virtual void interruptInferior() = 0;
|
||||||
|
|||||||
Reference in New Issue
Block a user