diff --git a/src/plugins/debugger/commonoptionspage.ui b/src/plugins/debugger/commonoptionspage.ui
index c7cbc68b28d..821c930252d 100644
--- a/src/plugins/debugger/commonoptionspage.ui
+++ b/src/plugins/debugger/commonoptionspage.ui
@@ -55,6 +55,16 @@
+ -
+
+
+ Enable reverse debugging
+
+
+
+ -
+
+
-
-
diff --git a/src/plugins/debugger/debuggeractions.cpp b/src/plugins/debugger/debuggeractions.cpp
index e6358718bde..568e922c2d6 100644
--- a/src/plugins/debugger/debuggeractions.cpp
+++ b/src/plugins/debugger/debuggeractions.cpp
@@ -294,6 +294,12 @@ DebuggerSettings *DebuggerSettings::instance()
item->setCheckable(true);
instance->insertItem(SkipKnownFrames, item);
+ item = new SavedAction(instance);
+ item->setSettingsKey(debugModeGroup, QLatin1String("EnableReverseDebugging"));
+ item->setText(tr("Enable reverse debugging"));
+ item->setCheckable(true);
+ instance->insertItem(EnableReverseDebugging, item);
+
item = new SavedAction(instance);
item->setSettingsKey(debugModeGroup, QLatin1String("AllPluginBreakpoints"));
item->setDefaultValue(true);
diff --git a/src/plugins/debugger/debuggeractions.h b/src/plugins/debugger/debuggeractions.h
index a45a60e32b3..b65981957bf 100644
--- a/src/plugins/debugger/debuggeractions.h
+++ b/src/plugins/debugger/debuggeractions.h
@@ -112,6 +112,7 @@ enum DebuggerActionCode
// Running
SkipKnownFrames,
+ EnableReverseDebugging,
// Breakpoints
SynchronizeBreakpoints,
diff --git a/src/plugins/debugger/debuggerconstants.h b/src/plugins/debugger/debuggerconstants.h
index 119b6afe2a0..720df8aca6f 100644
--- a/src/plugins/debugger/debuggerconstants.h
+++ b/src/plugins/debugger/debuggerconstants.h
@@ -47,6 +47,7 @@ const char * const STEPOUT = "Debugger.StepOut";
const char * const NEXT = "Debugger.NextLine";
const char * const STEPI = "Debugger.StepInstruction";
const char * const NEXTI = "Debugger.NextInstruction";
+const char * const REVERSE = "Debugger.ReverseDirection";
const char * const M_DEBUG_VIEWS = "Debugger.Menu.View.Debug";
diff --git a/src/plugins/debugger/debuggermanager.cpp b/src/plugins/debugger/debuggermanager.cpp
index 6768c63d025..b2a19fe8b1e 100644
--- a/src/plugins/debugger/debuggermanager.cpp
+++ b/src/plugins/debugger/debuggermanager.cpp
@@ -411,6 +411,12 @@ void DebuggerManager::init()
m_watchAction = new QAction(this);
m_watchAction->setText(tr("Add to Watch Window"));
+ m_reverseDirectionAction = new QAction(this);
+ m_reverseDirectionAction->setText(tr("Reverse Direction"));
+ m_reverseDirectionAction->setCheckable(true);
+ m_reverseDirectionAction->setChecked(false);
+ //m_reverseDirectionAction->setIcon(QIcon(":/debugger/images/debugger_stepoverproc_small.png"));
+
// For usuage hints oin focus{In,Out}
connect(m_continueAction, SIGNAL(triggered()),
this, SLOT(continueExec()));
@@ -1504,6 +1510,11 @@ void DebuggerManager::reloadFullStack()
m_engine->reloadFullStack();
}
+bool DebuggerManager::isReverseDebugging() const
+{
+ return m_reverseDirectionAction->isChecked();
+}
+
//////////////////////////////////////////////////////////////////////
//
diff --git a/src/plugins/debugger/debuggermanager.h b/src/plugins/debugger/debuggermanager.h
index c28b8d45ffd..00b339cda87 100644
--- a/src/plugins/debugger/debuggermanager.h
+++ b/src/plugins/debugger/debuggermanager.h
@@ -220,6 +220,7 @@ private:
virtual bool qtDumperLibraryEnabled() const = 0;
virtual QString qtDumperLibraryName() const = 0;
virtual void showQtDumperLibraryWarning(const QString &details = QString()) = 0;
+ virtual bool isReverseDebugging() const = 0;
virtual qint64 inferiorPid() const = 0;
@@ -288,6 +289,7 @@ public slots:
void nextIExec();
void continueExec();
void detachDebugger();
+ void reverseDirection();
void addToWatchWindow();
void updateWatchModel();
@@ -358,6 +360,7 @@ private:
virtual bool qtDumperLibraryEnabled() const;
virtual QString qtDumperLibraryName() const;
virtual void showQtDumperLibraryWarning(const QString &details = QString());
+ virtual bool isReverseDebugging() const;
//
// internal implementation
@@ -461,6 +464,7 @@ private:
QAction *m_sepAction;
QAction *m_stepIAction;
QAction *m_nextIAction;
+ QAction *m_reverseDirectionAction;
QWidget *m_breakWindow;
QWidget *m_disassemblerWindow;
diff --git a/src/plugins/debugger/debuggerplugin.cpp b/src/plugins/debugger/debuggerplugin.cpp
index 250a065f736..09f61b81e4b 100644
--- a/src/plugins/debugger/debuggerplugin.cpp
+++ b/src/plugins/debugger/debuggerplugin.cpp
@@ -120,6 +120,7 @@ const char * const STEPOUT_KEY = "Shift+F7";
const char * const NEXT_KEY = "F6";
const char * const STEPI_KEY = "Shift+F9";
const char * const NEXTI_KEY = "Shift+F6";
+const char * const REVERSE_KEY = "";
const char * const RUN_TO_LINE_KEY = "Shift+F8";
const char * const RUN_TO_FUNCTION_KEY = "Ctrl+F6";
const char * const JUMP_TO_LINE_KEY = "Alt+D,Alt+L";
@@ -135,6 +136,7 @@ const char * const STEPOUT_KEY = "Shift+F11";
const char * const NEXT_KEY = "F10";
const char * const STEPI_KEY = "";
const char * const NEXTI_KEY = "";
+const char * const REVERSE_KEY = "F12";
const char * const RUN_TO_LINE_KEY = "";
const char * const RUN_TO_FUNCTION_KEY = "";
const char * const JUMP_TO_LINE_KEY = "";
@@ -284,7 +286,9 @@ QWidget *CommonOptionsPage::createPage(QWidget *parent)
m_ui.checkBoxSkipKnownFrames);
m_group.insert(theDebuggerAction(UseToolTips),
m_ui.checkBoxUseToolTips);
- m_group.insert(theDebuggerAction(MaximalStackDepth),
+ m_group.insert(theDebuggerAction(EnableReverseDebugging),
+ m_ui.checkBoxEnableReverseDebugging);
+ m_group.insert(theDebuggerAction(MaximalStackDepth),
m_ui.spinBoxMaximalStackDepth);
return w;
@@ -671,6 +675,11 @@ bool DebuggerPlugin::initialize(const QStringList &arguments, QString *errorMess
Constants::JUMP_TO_LINE, debuggercontext);
mdebug->addAction(cmd);
+ cmd = am->registerAction(m_manager->m_reverseDirectionAction,
+ Constants::REVERSE, debuggercontext);
+ cmd->setDefaultKeySequence(QKeySequence(Constants::REVERSE_KEY));
+ mdebug->addAction(cmd);
+
sep = new QAction(this);
sep->setSeparator(true);
cmd = am->registerAction(sep, QLatin1String("Debugger.Sep3"), globalcontext);
@@ -816,6 +825,8 @@ bool DebuggerPlugin::initialize(const QStringList &arguments, QString *errorMess
debugToolBar->addAction(am->command(Constants::STEPI)->action());
debugToolBar->addAction(am->command(Constants::NEXTI)->action());
debugToolBar->addSeparator();
+ debugToolBar->addAction(am->command(Constants::REVERSE)->action());
+ debugToolBar->addSeparator();
debugToolBar->addWidget(new QLabel(tr("Threads:")));
QComboBox *threadBox = new QComboBox;
diff --git a/src/plugins/debugger/gdb/gdbengine.cpp b/src/plugins/debugger/gdb/gdbengine.cpp
index a3eb6f0c7e4..8f578bfead8 100644
--- a/src/plugins/debugger/gdb/gdbengine.cpp
+++ b/src/plugins/debugger/gdb/gdbengine.cpp
@@ -928,6 +928,10 @@ void GdbEngine::handleAqcuiredInferior()
if (theDebuggerBoolSetting(ListSourceFiles))
reloadSourceFiles();
+ // Reverse debugging. FIXME: Should only be used when available.
+ if (theDebuggerBoolSetting(EnableReverseDebugging))
+ postCommand(_("target record"));
+
tryLoadDebuggingHelpers();
#ifndef Q_OS_MAC
@@ -1664,14 +1668,20 @@ void GdbEngine::stepExec()
{
setTokenBarrier();
qq->notifyInferiorRunningRequested();
- postCommand(_("-exec-step"), CB(handleExecRun));
+ if (qq->isReverseDebugging())
+ postCommand(_("reverse-step"), CB(handleExecRun));
+ else
+ postCommand(_("-exec-step"), CB(handleExecRun));
}
void GdbEngine::stepIExec()
{
setTokenBarrier();
qq->notifyInferiorRunningRequested();
- postCommand(_("-exec-step-instruction"), CB(handleExecRun));
+ if (qq->isReverseDebugging())
+ postCommand(_("reverse-stepi"), CB(handleExecRun));
+ else
+ postCommand(_("-exec-step-instruction"), CB(handleExecRun));
}
void GdbEngine::stepOutExec()
@@ -1685,14 +1695,20 @@ void GdbEngine::nextExec()
{
setTokenBarrier();
qq->notifyInferiorRunningRequested();
- postCommand(_("-exec-next"), CB(handleExecRun));
+ if (qq->isReverseDebugging())
+ postCommand(_("reverse-next"), CB(handleExecRun));
+ else
+ postCommand(_("-exec-next"), CB(handleExecRun));
}
void GdbEngine::nextIExec()
{
setTokenBarrier();
qq->notifyInferiorRunningRequested();
- postCommand(_("-exec-next-instruction"), CB(handleExecRun));
+ if (qq->isReverseDebugging())
+ postCommand(_("reverse-nexti"), CB(handleExecRun));
+ else
+ postCommand(_("exec-next-instruction"), CB(handleExecRun));
}
void GdbEngine::runToLineExec(const QString &fileName, int lineNumber)
diff --git a/tests/manual/gdbdebugger/simple/app.cpp b/tests/manual/gdbdebugger/simple/app.cpp
index 12adff1b833..ae4569ad504 100644
--- a/tests/manual/gdbdebugger/simple/app.cpp
+++ b/tests/manual/gdbdebugger/simple/app.cpp
@@ -945,6 +945,13 @@ void testQVectorOfQList()
Q_UNUSED(pv);
}
+
+void testNoArgumentName(int i, int, int k)
+{
+ i = 1;
+ k = 2;
+}
+
void foo() {}
void foo(int) {}
void foo(QList) {}
@@ -1082,6 +1089,8 @@ int main(int argc, char *argv[])
QString hallo = "hallo";
QStringList list;
list << "aaa" << "bbb" << "cc";
+
+ testNoArgumentName(1, 2, 3);
testIO();
testHidden();
testArray();