Debugger: Initial implementation of conditional breakpoints

Expression class to store compiled expressions and associated variable list.

Co-authored-by:  TryTwo <taolas@gmail.com>
This commit is contained in:
smurf3tte
2020-12-16 15:40:20 -08:00
committed by TryTwo
parent 9ca1c0f533
commit 7842f9a715
17 changed files with 1240 additions and 36 deletions

View File

@ -15,6 +15,7 @@
#include "Core/ConfigManager.h"
#include "Core/Core.h"
#include "Core/PowerPC/BreakPoints.h"
#include "Core/PowerPC/Expression.h"
#include "Core/PowerPC/PPCSymbolDB.h"
#include "Core/PowerPC/PowerPC.h"
@ -86,7 +87,7 @@ void BreakpointWidget::CreateWidgets()
m_table = new QTableWidget;
m_table->setTabKeyNavigation(false);
m_table->setContentsMargins(0, 0, 0, 0);
m_table->setColumnCount(5);
m_table->setColumnCount(6);
m_table->setSelectionMode(QAbstractItemView::SingleSelection);
m_table->setSelectionBehavior(QAbstractItemView::SelectRows);
m_table->setEditTriggers(QAbstractItemView::NoEditTriggers);
@ -160,7 +161,7 @@ void BreakpointWidget::Update()
m_table->clear();
m_table->setHorizontalHeaderLabels(
{tr("Active"), tr("Type"), tr("Function"), tr("Address"), tr("Flags")});
{tr("Active"), tr("Type"), tr("Function"), tr("Address"), tr("Flags"), tr("Condition")});
int i = 0;
m_table->setRowCount(i);
@ -203,6 +204,13 @@ void BreakpointWidget::Update()
m_table->setItem(i, 4, create_item(flags));
QString condition;
if (bp.condition)
condition = QString::fromStdString(bp.condition->GetText());
m_table->setItem(i, 5, create_item(condition));
i++;
}
@ -387,12 +395,15 @@ void BreakpointWidget::OnContextMenu()
void BreakpointWidget::AddBP(u32 addr)
{
AddBP(addr, false, true, true);
AddBP(addr, false, true, true, {});
}
void BreakpointWidget::AddBP(u32 addr, bool temp, bool break_on_hit, bool log_on_hit)
void BreakpointWidget::AddBP(u32 addr, bool temp, bool break_on_hit, bool log_on_hit,
const QString& condition)
{
PowerPC::breakpoints.Add(addr, temp, break_on_hit, log_on_hit);
PowerPC::breakpoints.Add(
addr, temp, break_on_hit, log_on_hit,
!condition.isEmpty() ? Expression::TryParse(condition.toUtf8().constData()) : std::nullopt);
emit BreakpointsChanged();
Update();

View File

@ -21,7 +21,7 @@ public:
~BreakpointWidget();
void AddBP(u32 addr);
void AddBP(u32 addr, bool temp, bool break_on_hit, bool log_on_hit);
void AddBP(u32 addr, bool temp, bool break_on_hit, bool log_on_hit, const QString& condition);
void AddAddressMBP(u32 addr, bool on_read = true, bool on_write = true, bool do_log = true,
bool do_break = true);
void AddRangedMBP(u32 from, u32 to, bool do_read = true, bool do_write = true, bool do_log = true,

View File

@ -14,6 +14,7 @@
#include <QRadioButton>
#include <QVBoxLayout>
#include "Core/PowerPC/Expression.h"
#include "DolphinQt/Debugger/BreakpointWidget.h"
#include "DolphinQt/QtUtils/ModalMessageBox.h"
@ -40,11 +41,14 @@ void NewBreakpointDialog::CreateWidgets()
type_group->addButton(m_instruction_bp);
m_instruction_box = new QGroupBox;
m_instruction_address = new QLineEdit;
m_instruction_condition = new QLineEdit;
auto* instruction_layout = new QHBoxLayout;
auto* instruction_layout = new QGridLayout;
m_instruction_box->setLayout(instruction_layout);
instruction_layout->addWidget(new QLabel(tr("Address:")));
instruction_layout->addWidget(m_instruction_address);
instruction_layout->addWidget(new QLabel(tr("Address:")), 0, 0);
instruction_layout->addWidget(m_instruction_address, 0, 1);
instruction_layout->addWidget(new QLabel(tr("Condition:")), 1, 0);
instruction_layout->addWidget(m_instruction_condition, 1, 1);
// Memory BP
m_memory_bp = new QRadioButton(tr("Memory Breakpoint"));
@ -174,7 +178,15 @@ void NewBreakpointDialog::accept()
return;
}
m_parent->AddBP(address, false, do_break, do_log);
const QString condition = m_instruction_condition->text().trimmed();
if (!condition.isEmpty() && !Expression::TryParse(condition.toUtf8().constData()))
{
invalid_input(tr("Condition"));
return;
}
m_parent->AddBP(address, false, do_break, do_log, condition);
}
else
{

View File

@ -34,6 +34,7 @@ private:
QRadioButton* m_instruction_bp;
QGroupBox* m_instruction_box;
QLineEdit* m_instruction_address;
QLineEdit* m_instruction_condition;
// Memory BPs
QRadioButton* m_memory_bp;