mirror of
https://github.com/rizinorg/cutter.git
synced 2025-01-31 16:47:26 +00:00
Add initial reverse debugging support
This commit is contained in:
parent
ac8c0e4175
commit
89a5b03484
@ -1902,6 +1902,35 @@ void CutterCore::continueDebug()
|
|||||||
debugTask->startTask();
|
debugTask->startTask();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void CutterCore::continueBackDebug()
|
||||||
|
{
|
||||||
|
if (!currentlyDebugging) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (currentlyEmulating) {
|
||||||
|
if (!asyncCmdEsil("aecb", debugTask)) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
if (!asyncCmd("dcb", debugTask)) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
emit debugTaskStateChanged();
|
||||||
|
|
||||||
|
connect(debugTask.data(), &R2Task::finished, this, [this] () {
|
||||||
|
debugTask.clear();
|
||||||
|
syncAndSeekProgramCounter();
|
||||||
|
emit registersChanged();
|
||||||
|
emit stackChanged();
|
||||||
|
emit refreshCodeViews();
|
||||||
|
emit debugTaskStateChanged();
|
||||||
|
});
|
||||||
|
|
||||||
|
debugTask->startTask();
|
||||||
|
}
|
||||||
|
|
||||||
void CutterCore::continueUntilDebug(QString offset)
|
void CutterCore::continueUntilDebug(QString offset)
|
||||||
{
|
{
|
||||||
if (!currentlyDebugging) {
|
if (!currentlyDebugging) {
|
||||||
@ -2055,6 +2084,32 @@ void CutterCore::stepOutDebug()
|
|||||||
debugTask->startTask();
|
debugTask->startTask();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void CutterCore::stepBackDebug()
|
||||||
|
{
|
||||||
|
if (!currentlyDebugging) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (currentlyEmulating) {
|
||||||
|
if (!asyncCmdEsil("aesb", debugTask)) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
if (!asyncCmd("dsb", debugTask)) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
emit debugTaskStateChanged();
|
||||||
|
|
||||||
|
connect(debugTask.data(), &R2Task::finished, this, [this] () {
|
||||||
|
debugTask.clear();
|
||||||
|
syncAndSeekProgramCounter();
|
||||||
|
emit debugTaskStateChanged();
|
||||||
|
});
|
||||||
|
|
||||||
|
debugTask->startTask();
|
||||||
|
}
|
||||||
|
|
||||||
QStringList CutterCore::getDebugPlugins()
|
QStringList CutterCore::getDebugPlugins()
|
||||||
{
|
{
|
||||||
QStringList plugins;
|
QStringList plugins;
|
||||||
@ -2080,6 +2135,41 @@ void CutterCore::setDebugPlugin(QString plugin)
|
|||||||
setConfig("dbg.backend", plugin);
|
setConfig("dbg.backend", plugin);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void CutterCore::addTraceSession()
|
||||||
|
{
|
||||||
|
if (!currentlyDebugging) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (currentlyEmulating) {
|
||||||
|
if (!asyncCmdEsil("aets+", debugTask)) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
if (!asyncCmd("dts+", debugTask)) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
emit debugTaskStateChanged();
|
||||||
|
|
||||||
|
connect(debugTask.data(), &R2Task::finished, this, [this] () {
|
||||||
|
if (debugTaskDialog) {
|
||||||
|
delete debugTaskDialog;
|
||||||
|
}
|
||||||
|
debugTask.clear();
|
||||||
|
|
||||||
|
emit debugTaskStateChanged();
|
||||||
|
});
|
||||||
|
|
||||||
|
debugTaskDialog = new R2TaskDialog(debugTask);
|
||||||
|
debugTaskDialog->setBreakOnClose(true);
|
||||||
|
debugTaskDialog->setAttribute(Qt::WA_DeleteOnClose);
|
||||||
|
debugTaskDialog->setDesc(tr("Creating debug tracepoint..."));
|
||||||
|
debugTaskDialog->show();
|
||||||
|
|
||||||
|
debugTask->startTask();
|
||||||
|
}
|
||||||
|
|
||||||
void CutterCore::toggleBreakpoint(RVA addr)
|
void CutterCore::toggleBreakpoint(RVA addr)
|
||||||
{
|
{
|
||||||
cmdRaw(QString("dbs %1").arg(addr));
|
cmdRaw(QString("dbs %1").arg(addr));
|
||||||
|
@ -394,12 +394,15 @@ public:
|
|||||||
void suspendDebug();
|
void suspendDebug();
|
||||||
void syncAndSeekProgramCounter();
|
void syncAndSeekProgramCounter();
|
||||||
void continueDebug();
|
void continueDebug();
|
||||||
|
void continueBackDebug();
|
||||||
void continueUntilCall();
|
void continueUntilCall();
|
||||||
void continueUntilSyscall();
|
void continueUntilSyscall();
|
||||||
void continueUntilDebug(QString offset);
|
void continueUntilDebug(QString offset);
|
||||||
void stepDebug();
|
void stepDebug();
|
||||||
void stepOverDebug();
|
void stepOverDebug();
|
||||||
void stepOutDebug();
|
void stepOutDebug();
|
||||||
|
void stepBackDebug();
|
||||||
|
void addTraceSession();
|
||||||
|
|
||||||
void addBreakpoint(const BreakpointDescription &config);
|
void addBreakpoint(const BreakpointDescription &config);
|
||||||
void updateBreakpoint(int index, const BreakpointDescription &config);
|
void updateBreakpoint(int index, const BreakpointDescription &config);
|
||||||
|
@ -294,10 +294,14 @@ void MainWindow::initToolBar()
|
|||||||
ui->menuDebug->addAction(debugActions->actionStep);
|
ui->menuDebug->addAction(debugActions->actionStep);
|
||||||
ui->menuDebug->addAction(debugActions->actionStepOver);
|
ui->menuDebug->addAction(debugActions->actionStepOver);
|
||||||
ui->menuDebug->addAction(debugActions->actionStepOut);
|
ui->menuDebug->addAction(debugActions->actionStepOut);
|
||||||
|
ui->menuDebug->addAction(debugActions->actionStepBack);
|
||||||
ui->menuDebug->addSeparator();
|
ui->menuDebug->addSeparator();
|
||||||
ui->menuDebug->addAction(debugActions->actionContinue);
|
ui->menuDebug->addAction(debugActions->actionContinue);
|
||||||
ui->menuDebug->addAction(debugActions->actionContinueUntilCall);
|
ui->menuDebug->addAction(debugActions->actionContinueUntilCall);
|
||||||
ui->menuDebug->addAction(debugActions->actionContinueUntilSyscall);
|
ui->menuDebug->addAction(debugActions->actionContinueUntilSyscall);
|
||||||
|
ui->menuDebug->addAction(debugActions->actionContinueBack);
|
||||||
|
ui->menuDebug->addSeparator();
|
||||||
|
ui->menuDebug->addAction(debugActions->actionAddTraceSession);
|
||||||
|
|
||||||
// Sepparator between undo/redo and goto lineEdit
|
// Sepparator between undo/redo and goto lineEdit
|
||||||
QWidget *spacer4 = new QWidget();
|
QWidget *spacer4 = new QWidget();
|
||||||
|
@ -33,6 +33,7 @@
|
|||||||
<file>img/icons/light/continue_until_call.svg</file>
|
<file>img/icons/light/continue_until_call.svg</file>
|
||||||
<file>img/icons/continue_until_syscall.svg</file>
|
<file>img/icons/continue_until_syscall.svg</file>
|
||||||
<file>img/icons/light/continue_until_syscall.svg</file>
|
<file>img/icons/light/continue_until_syscall.svg</file>
|
||||||
|
<file>img/icons/reverse_continue.svg</file>
|
||||||
<file>img/icons/detach_debugger.svg</file>
|
<file>img/icons/detach_debugger.svg</file>
|
||||||
<file>img/icons/light/step_into.svg</file>
|
<file>img/icons/light/step_into.svg</file>
|
||||||
<file>img/icons/step_into.svg</file>
|
<file>img/icons/step_into.svg</file>
|
||||||
@ -40,6 +41,8 @@
|
|||||||
<file>img/icons/step_over.svg</file>
|
<file>img/icons/step_over.svg</file>
|
||||||
<file>img/icons/step_out.svg</file>
|
<file>img/icons/step_out.svg</file>
|
||||||
<file>img/icons/light/step_out.svg</file>
|
<file>img/icons/light/step_out.svg</file>
|
||||||
|
<file>img/icons/reverse_step.svg</file>
|
||||||
|
<file>img/icons/record_trace.svg</file>
|
||||||
<file>img/icons/cloud.svg</file>
|
<file>img/icons/cloud.svg</file>
|
||||||
<file>img/icons/down.svg</file>
|
<file>img/icons/down.svg</file>
|
||||||
<file>img/icons/down_white.svg</file>
|
<file>img/icons/down_white.svg</file>
|
||||||
|
@ -24,6 +24,9 @@ DebugActions::DebugActions(QToolBar *toolBar, MainWindow *main) :
|
|||||||
QIcon startEmulIcon = QIcon(":/img/icons/play_light_emul.svg");
|
QIcon startEmulIcon = QIcon(":/img/icons/play_light_emul.svg");
|
||||||
QIcon startAttachIcon = QIcon(":/img/icons/play_light_attach.svg");
|
QIcon startAttachIcon = QIcon(":/img/icons/play_light_attach.svg");
|
||||||
QIcon startRemoteIcon = QIcon(":/img/icons/play_light_remote.svg");
|
QIcon startRemoteIcon = QIcon(":/img/icons/play_light_remote.svg");
|
||||||
|
QIcon continueBackIcon = QIcon(":/img/icons/reverse_continue.svg");
|
||||||
|
QIcon stepBackIcon = QIcon(":/img/icons/reverse_step.svg");
|
||||||
|
QIcon addTraceSessionIcon = QIcon(":/img/icons/record_trace.svg");
|
||||||
stopIcon = QIcon(":/img/icons/media-stop_light.svg");
|
stopIcon = QIcon(":/img/icons/media-stop_light.svg");
|
||||||
restartIcon = QIcon(":/img/icons/spin_light.svg");
|
restartIcon = QIcon(":/img/icons/spin_light.svg");
|
||||||
detachIcon = QIcon(":/img/icons/detach_debugger.svg");
|
detachIcon = QIcon(":/img/icons/detach_debugger.svg");
|
||||||
@ -41,9 +44,12 @@ DebugActions::DebugActions(QToolBar *toolBar, MainWindow *main) :
|
|||||||
QString continueUMLabel = tr("Continue until main");
|
QString continueUMLabel = tr("Continue until main");
|
||||||
QString continueUCLabel = tr("Continue until call");
|
QString continueUCLabel = tr("Continue until call");
|
||||||
QString continueUSLabel = tr("Continue until syscall");
|
QString continueUSLabel = tr("Continue until syscall");
|
||||||
|
QString continueBackLabel = tr("Continue backwards");
|
||||||
QString stepLabel = tr("Step");
|
QString stepLabel = tr("Step");
|
||||||
QString stepOverLabel = tr("Step over");
|
QString stepOverLabel = tr("Step over");
|
||||||
QString stepOutLabel = tr("Step out");
|
QString stepOutLabel = tr("Step out");
|
||||||
|
QString stepBackLabel = tr("Step backwards");
|
||||||
|
QString addTraceSessionLabel = tr("Add trace session");
|
||||||
suspendLabel = tr("Suspend the process");
|
suspendLabel = tr("Suspend the process");
|
||||||
continueLabel = tr("Continue");
|
continueLabel = tr("Continue");
|
||||||
restartDebugLabel = tr("Restart program");
|
restartDebugLabel = tr("Restart program");
|
||||||
@ -61,12 +67,17 @@ DebugActions::DebugActions(QToolBar *toolBar, MainWindow *main) :
|
|||||||
actionContinueUntilMain = new QAction(continueUMLabel, this);
|
actionContinueUntilMain = new QAction(continueUMLabel, this);
|
||||||
actionContinueUntilCall = new QAction(continueUCLabel, this);
|
actionContinueUntilCall = new QAction(continueUCLabel, this);
|
||||||
actionContinueUntilSyscall = new QAction(continueUSLabel, this);
|
actionContinueUntilSyscall = new QAction(continueUSLabel, this);
|
||||||
|
actionContinueBack = new QAction(continueBackIcon, continueBackLabel, this);
|
||||||
|
actionContinueBack->setShortcut(QKeySequence(Qt::CTRL + Qt::Key_F5));
|
||||||
actionStep = new QAction(stepLabel, this);
|
actionStep = new QAction(stepLabel, this);
|
||||||
actionStep->setShortcut(QKeySequence(Qt::Key_F7));
|
actionStep->setShortcut(QKeySequence(Qt::Key_F7));
|
||||||
actionStepOver = new QAction(stepOverLabel, this);
|
actionStepOver = new QAction(stepOverLabel, this);
|
||||||
actionStepOver->setShortcut(QKeySequence(Qt::Key_F8));
|
actionStepOver->setShortcut(QKeySequence(Qt::Key_F8));
|
||||||
actionStepOut = new QAction(stepOutLabel, this);
|
actionStepOut = new QAction(stepOutLabel, this);
|
||||||
actionStepOut->setShortcut(QKeySequence(Qt::CTRL + Qt::Key_F8));
|
actionStepOut->setShortcut(QKeySequence(Qt::CTRL + Qt::Key_F8));
|
||||||
|
actionStepBack = new QAction(stepBackIcon, stepBackLabel, this);
|
||||||
|
actionStepBack->setShortcut(QKeySequence(Qt::CTRL + Qt::Key_F7));
|
||||||
|
actionAddTraceSession = new QAction(addTraceSessionIcon, addTraceSessionLabel, this);
|
||||||
|
|
||||||
QToolButton *startButton = new QToolButton;
|
QToolButton *startButton = new QToolButton;
|
||||||
startButton->setPopupMode(QToolButton::MenuButtonPopup);
|
startButton->setPopupMode(QToolButton::MenuButtonPopup);
|
||||||
@ -100,16 +111,22 @@ DebugActions::DebugActions(QToolBar *toolBar, MainWindow *main) :
|
|||||||
toolBar->addAction(actionStepOver);
|
toolBar->addAction(actionStepOver);
|
||||||
toolBar->addAction(actionStep);
|
toolBar->addAction(actionStep);
|
||||||
toolBar->addAction(actionStepOut);
|
toolBar->addAction(actionStepOut);
|
||||||
|
toolBar->addAction(actionStepBack);
|
||||||
|
toolBar->addAction(actionContinueBack);
|
||||||
|
toolBar->addAction(actionAddTraceSession);
|
||||||
|
|
||||||
allActions = {actionStop, actionAllContinues, actionContinue, actionContinueUntilCall, actionContinueUntilMain, actionContinueUntilSyscall, actionStep, actionStepOut, actionStepOver};
|
allActions = {actionStop, actionAllContinues, actionContinue, actionContinueUntilCall,
|
||||||
// hide allactions
|
actionContinueUntilMain, actionContinueUntilSyscall, actionStep, actionStepOut,
|
||||||
|
actionStepOver, actionContinueBack, actionStepBack, actionAddTraceSession};
|
||||||
|
|
||||||
|
// Hide all actions
|
||||||
setAllActionsVisible(false);
|
setAllActionsVisible(false);
|
||||||
|
|
||||||
// Toggle all buttons except restart, suspend(=continue) and stop since those are
|
// Toggle all buttons except restart, suspend(=continue) and stop since those are
|
||||||
// necessary to avoid staying stuck
|
// necessary to avoid staying stuck
|
||||||
toggleActions = {actionStepOver, actionStep, actionStepOut, actionContinueUntilMain,
|
toggleActions = {actionStepOver, actionStep, actionStepOut, actionContinueUntilMain,
|
||||||
actionContinueUntilCall, actionContinueUntilSyscall
|
actionContinueUntilCall, actionContinueUntilSyscall, actionStepBack,
|
||||||
};
|
actionContinueBack, actionAddTraceSession};
|
||||||
toggleConnectionActions = {actionAttach, actionStartRemote};
|
toggleConnectionActions = {actionAttach, actionStartRemote};
|
||||||
|
|
||||||
connect(Core(), &CutterCore::debugProcessFinished, this, [ = ](int pid) {
|
connect(Core(), &CutterCore::debugProcessFinished, this, [ = ](int pid) {
|
||||||
|
@ -26,11 +26,14 @@ public:
|
|||||||
QAction *actionContinueUntilMain;
|
QAction *actionContinueUntilMain;
|
||||||
QAction *actionContinueUntilCall;
|
QAction *actionContinueUntilCall;
|
||||||
QAction *actionContinueUntilSyscall;
|
QAction *actionContinueUntilSyscall;
|
||||||
|
QAction *actionContinueBack;
|
||||||
QAction *actionStep;
|
QAction *actionStep;
|
||||||
QAction *actionStepOver;
|
QAction *actionStepOver;
|
||||||
QAction *actionStepOut;
|
QAction *actionStepOut;
|
||||||
|
QAction *actionStepBack;
|
||||||
QAction *actionStop;
|
QAction *actionStop;
|
||||||
QAction *actionAllContinues;
|
QAction *actionAllContinues;
|
||||||
|
QAction *actionAddTraceSession;
|
||||||
|
|
||||||
// Continue/suspend and start/restart interchange during runtime
|
// Continue/suspend and start/restart interchange during runtime
|
||||||
QIcon continueIcon;
|
QIcon continueIcon;
|
||||||
|
Loading…
Reference in New Issue
Block a user