Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Breakpoint Menu and Debug Menu in the Decompiler Context Menu #2260

Merged
Merged
Show file tree
Hide file tree
Changes from 6 commits
Commits
Show all changes
22 commits
Select commit Hold shift + click to select a range
0a945a8
Add option for breakpoints
NirmalManoj Jun 23, 2020
3100872
add debug menu
NirmalManoj Jun 22, 2020
bf05fa8
some suggested changes
NirmalManoj Jun 23, 2020
bb1e8db
make function to set shortcut context
NirmalManoj Jun 23, 2020
c08975d
renamed shortcut context setting function
NirmalManoj Jun 23, 2020
7663e97
replaced foreach, remove an unnecessary function
NirmalManoj Jun 23, 2020
c4a067e
formatted
NirmalManoj Jun 24, 2020
beff827
Implement logic for handling multiple breakpoints in a line
NirmalManoj Jun 25, 2020
fa7832c
suggested changes and complete formatting
NirmalManoj Jun 27, 2020
ac773e7
changed logic for adding/editing advanced offsets
NirmalManoj Jun 27, 2020
5e2f94b
breakpoints in line menu
NirmalManoj Jun 27, 2020
a85a9ab
suggested change
NirmalManoj Jun 27, 2020
cfcdb90
use RAddressString
NirmalManoj Jun 27, 2020
c9f6b45
use addAction() for creating and adding actions to breakpointsInLineMenu
NirmalManoj Jun 27, 2020
7e607f8
connect with breakpointsChanged
NirmalManoj Jun 27, 2020
1d5ef96
removed addAction() with lambda
NirmalManoj Jun 27, 2020
78f4361
made breakpointsInLineMenu a context sensitive submenu of breakpointMenu
NirmalManoj Jun 28, 2020
7928275
setupBreakpointsInLineMenu() in aboutToShowSlot
NirmalManoj Jun 28, 2020
88283b1
fixed the problem arised due to the connection with breakpointsChanged
NirmalManoj Jun 28, 2020
d7d78d2
made some functions private + formatted
NirmalManoj Jun 28, 2020
4f766c0
tried to fix memory leak associated with breakpointsInLineMenu
NirmalManoj Jun 28, 2020
7eee2e6
tried to fix potential memory leak with breakpointsInLineMenu
NirmalManoj Jun 29, 2020
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Jump to
Jump to file
Failed to load files.
Diff view
Diff view
105 changes: 103 additions & 2 deletions src/menus/DecompilerContextMenu.cpp
@@ -1,6 +1,7 @@
#include "DecompilerContextMenu.h"
#include "dialogs/preferences/PreferencesDialog.h"
#include "MainWindow.h"
#include "dialogs/BreakpointsDialog.h"

#include <QtCore>
#include <QShortcut>
Expand All @@ -13,11 +14,20 @@ DecompilerContextMenu::DecompilerContextMenu(QWidget *parent, MainWindow *mainWi
: QMenu(parent),
offset(0),
mainWindow(mainWindow),
actionCopy(tr("Copy"), this)
actionCopy(tr("Copy"), this),
actionAddBreakpoint(tr("Add/remove breakpoint"), this),
actionAdvancedBreakpoint(tr("Advanced breakpoint"), this),
actionContinueUntil(tr("Continue until line"), this),
actionSetPC(tr("Set PC"), this)
{
setActionCopy();
addSeparator();

addBreakpointMenu();
addDebugMenu();

setShortcutContextInActions(this);

connect(this, &DecompilerContextMenu::aboutToShow,
this, &DecompilerContextMenu::aboutToShowSlot);
}
Expand All @@ -38,8 +48,30 @@ void DecompilerContextMenu::setCanCopy(bool enabled)
actionCopy.setVisible(enabled);
}

void DecompilerContextMenu::setShortcutContextInActions(QMenu *menu)
{
for(QAction *action: menu->actions()){
if(action->isSeparator()){
//Do nothing
}else if(action->menu()){
setShortcutContextInActions(action->menu());
}else{
action->setShortcutContext(Qt::WidgetWithChildrenShortcut);
}
}
}

void DecompilerContextMenu::aboutToShowSlot()
{
// Only show debug options if we are currently debugging
debugMenu->menuAction()->setVisible(Core()->currentlyDebugging);
bool hasBreakpoint = Core()->breakpointIndexAt(offset) > -1;
actionAddBreakpoint.setText(hasBreakpoint ?
tr("Remove breakpoint") : tr("Add breakpoint"));
actionAdvancedBreakpoint.setText(hasBreakpoint ?
tr("Edit breakpoint") : tr("Advanced breakpoint"));
QString progCounterName = Core()->getRegisterName("PC").toUpper();
actionSetPC.setText(tr("Set %1 here").arg(progCounterName));
}

// Set up actions
Expand All @@ -48,7 +80,28 @@ void DecompilerContextMenu::setActionCopy(){
connect(&actionCopy, &QAction::triggered, this, &DecompilerContextMenu::actionCopyTriggered);
addAction(&actionCopy);
actionCopy.setShortcut(QKeySequence::Copy);
actionCopy.setShortcutContext(Qt::WidgetWithChildrenShortcut);
}

void DecompilerContextMenu::setActionAddBreakpoint()
{
connect(&actionAddBreakpoint, &QAction::triggered, this, &DecompilerContextMenu::actionAddBreakpointTriggered);
actionAddBreakpoint.setShortcuts({Qt::Key_F2, Qt::CTRL + Qt::Key_B});
}

void DecompilerContextMenu::setActionAdvancedBreakpoint()
{
connect(&actionAdvancedBreakpoint, &QAction::triggered, this, &DecompilerContextMenu::actionAdvancedBreakpointTriggered);
actionAdvancedBreakpoint.setShortcut({Qt::CTRL + Qt::Key_F2});
}

void DecompilerContextMenu::setActionContinueUntil()
{
connect(&actionContinueUntil, &QAction::triggered, this, &DecompilerContextMenu::actionContinueUntilTriggered);
}

void DecompilerContextMenu::setActionSetPC()
{
connect(&actionSetPC, &QAction::triggered, this, &DecompilerContextMenu::actionSetPCTriggered);
}

// Set up action responses
Expand All @@ -57,3 +110,51 @@ void DecompilerContextMenu::actionCopyTriggered()
{
emit copy();
}

void DecompilerContextMenu::actionAddBreakpointTriggered()
{
Core()->toggleBreakpoint(offset);
karliss marked this conversation as resolved.
Show resolved Hide resolved
}

void DecompilerContextMenu::actionAdvancedBreakpointTriggered()
{
int index = Core()->breakpointIndexAt(offset);
if (index >= 0) {
BreakpointsDialog::editBreakpoint(Core()->getBreakpointAt(offset), this);
} else {
BreakpointsDialog::createNewBreakpoint(offset, this);
}
}

void DecompilerContextMenu::actionContinueUntilTriggered()
{
Core()->continueUntilDebug(RAddressString(offset));
}

void DecompilerContextMenu::actionSetPCTriggered()
{
QString progCounterName = Core()->getRegisterName("PC");
Core()->setRegister(progCounterName, RAddressString(offset).toUpper());
}

// Set up menus

void DecompilerContextMenu::addBreakpointMenu()
{
breakpointMenu = addMenu(tr("Breakpoint"));

setActionAddBreakpoint();
breakpointMenu->addAction(&actionAddBreakpoint);
setActionAdvancedBreakpoint();
breakpointMenu->addAction(&actionAdvancedBreakpoint);
}

void DecompilerContextMenu::addDebugMenu()
{
debugMenu = addMenu(tr("Debug"));

setActionContinueUntil();
debugMenu->addAction(&actionContinueUntil);
setActionSetPC();
debugMenu->addAction(&actionSetPC);
}
28 changes: 26 additions & 2 deletions src/menus/DecompilerContextMenu.h
Expand Up @@ -12,7 +12,7 @@ class DecompilerContextMenu : public QMenu
public:
DecompilerContextMenu(QWidget *parent, MainWindow *mainWindow);
~DecompilerContextMenu();

signals:
void copy();

Expand All @@ -24,18 +24,42 @@ private slots:
void aboutToShowSlot();

void actionCopyTriggered();

void actionAddBreakpointTriggered();
void actionAdvancedBreakpointTriggered();

void actionContinueUntilTriggered();
void actionSetPCTriggered();

private:
QKeySequence getCopySequence() const;
void setShortcutContextInActions(QMenu *menu);

RVA offset;
MainWindow *mainWindow;

QAction actionCopy;
QAction *copySeparator;

QMenu *breakpointMenu;
QAction actionAddBreakpoint;
QAction actionAdvancedBreakpoint;

QMenu *debugMenu;
QAction actionContinueUntil;
QAction actionSetPC;

// Set actions
void setActionCopy();

void setActionAddBreakpoint();
void setActionAdvancedBreakpoint();

void setActionContinueUntil();
void setActionSetPC();

// Add Menus
void addBreakpointMenu();
void addDebugMenu();
// I left out the following part from RAnnotatedCode. Probably, we will be returning/passing annotations
// from/to the function getThingUsedHere() and updateTargetMenuActions(). This block of comment will get removed in
// future PRs.
Expand Down
3 changes: 1 addition & 2 deletions src/widgets/DecompilerWidget.cpp
Expand Up @@ -147,8 +147,7 @@ static ut64 offsetForPosition(RAnnotatedCode &codeDecompiled, size_t pos)
void *annotationi;
r_vector_foreach(&codeDecompiled.annotations, annotationi) {
RCodeAnnotation *annotation = (RCodeAnnotation *)annotationi;
if (annotation->type != R_CODE_ANNOTATION_TYPE_OFFSET || annotation->start > pos
|| annotation->end <= pos) {
if (annotation->type != R_CODE_ANNOTATION_TYPE_OFFSET || annotation->start > pos) {
karliss marked this conversation as resolved.
Show resolved Hide resolved
continue;
}
if (closestPos != SIZE_MAX && closestPos >= annotation->start) {
Expand Down