mirror of
https://github.com/dolphin-emu/dolphin.git
synced 2025-12-16 04:09:39 +00:00
Compare commits
2 Commits
183ef986b2
...
52a7b51b3b
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
52a7b51b3b | ||
|
|
476234f001 |
@ -10,11 +10,13 @@
|
||||
#include <string>
|
||||
#include <vector>
|
||||
|
||||
#include "Common/Assert.h"
|
||||
#include "Common/BitSet.h"
|
||||
#include "Common/CommonTypes.h"
|
||||
#include "Common/Logging/Log.h"
|
||||
#include "Core/Core.h"
|
||||
#include "Core/Debugger/DebugInterface.h"
|
||||
#include "Core/Debugger/Debugger_SymbolMap.h"
|
||||
#include "Core/PowerPC/Expression.h"
|
||||
#include "Core/PowerPC/JitInterface.h"
|
||||
#include "Core/PowerPC/MMU.h"
|
||||
@ -72,6 +74,8 @@ BreakPoints::TBreakPointsStr BreakPoints::GetStrings() const
|
||||
ss << "l";
|
||||
if (bp.break_on_hit)
|
||||
ss << "b";
|
||||
if (bp.log_call_stack)
|
||||
ss << "s";
|
||||
if (bp.condition)
|
||||
ss << "c " << bp.condition->GetText();
|
||||
bp_strings.emplace_back(ss.str());
|
||||
@ -96,6 +100,7 @@ void BreakPoints::AddFromStrings(const TBreakPointsStr& bp_strings)
|
||||
bp.is_enabled = flags.find('n') != flags.npos;
|
||||
bp.log_on_hit = flags.find('l') != flags.npos;
|
||||
bp.break_on_hit = flags.find('b') != flags.npos;
|
||||
bp.log_call_stack = flags.find('s') != flags.npos;
|
||||
if (flags.find('c') != std::string::npos)
|
||||
{
|
||||
iss >> std::ws;
|
||||
@ -119,10 +124,10 @@ void BreakPoints::Add(TBreakPoint bp)
|
||||
|
||||
void BreakPoints::Add(u32 address)
|
||||
{
|
||||
BreakPoints::Add(address, true, false, std::nullopt);
|
||||
BreakPoints::Add(address, true, false, false, std::nullopt);
|
||||
}
|
||||
|
||||
void BreakPoints::Add(u32 address, bool break_on_hit, bool log_on_hit,
|
||||
void BreakPoints::Add(u32 address, bool break_on_hit, bool log_on_hit, bool log_call_stack,
|
||||
std::optional<Expression> condition)
|
||||
{
|
||||
// Check for existing breakpoint, and overwrite with new info.
|
||||
@ -133,6 +138,7 @@ void BreakPoints::Add(u32 address, bool break_on_hit, bool log_on_hit,
|
||||
bp.is_enabled = true;
|
||||
bp.break_on_hit = break_on_hit;
|
||||
bp.log_on_hit = log_on_hit;
|
||||
bp.log_call_stack = log_call_stack;
|
||||
bp.address = address;
|
||||
bp.condition = std::move(condition);
|
||||
|
||||
@ -241,6 +247,8 @@ MemChecks::TMemChecksStr MemChecks::GetStrings() const
|
||||
ss << 'l';
|
||||
if (mc.break_on_hit)
|
||||
ss << 'b';
|
||||
if (mc.log_call_stack)
|
||||
ss << 's';
|
||||
if (mc.condition)
|
||||
ss << "c " << mc.condition->GetText();
|
||||
|
||||
@ -271,6 +279,7 @@ void MemChecks::AddFromStrings(const TMemChecksStr& mc_strings)
|
||||
mc.is_enabled = flags.find('n') != flags.npos;
|
||||
mc.is_break_on_read = flags.find('r') != flags.npos;
|
||||
mc.is_break_on_write = flags.find('w') != flags.npos;
|
||||
mc.log_call_stack = flags.find('s') != flags.npos;
|
||||
mc.log_on_hit = flags.find('l') != flags.npos;
|
||||
mc.break_on_hit = flags.find('b') != flags.npos;
|
||||
if (flags.find('c') != std::string::npos)
|
||||
@ -421,6 +430,14 @@ bool TMemCheck::Action(Core::System& system, u64 value, u32 addr, bool write, si
|
||||
NOTICE_LOG_FMT(MEMMAP, "MBP {:08x} ({}) {}{} {:x} at {:08x} ({})", pc,
|
||||
ppc_symbol_db.GetDescription(pc), write ? "Write" : "Read", size * 8, value,
|
||||
addr, ppc_symbol_db.GetDescription(addr));
|
||||
|
||||
if (log_call_stack)
|
||||
{
|
||||
ASSERT(Core::IsCPUThread());
|
||||
Core::CPUThreadGuard guard(system);
|
||||
Dolphin_Debugger::PrintCallstack(guard, Common::Log::LogType::MEMMAP,
|
||||
Common::Log::LogLevel::LNOTICE);
|
||||
}
|
||||
}
|
||||
if (break_on_hit)
|
||||
return true;
|
||||
|
||||
@ -23,6 +23,7 @@ struct TBreakPoint
|
||||
bool is_enabled = false;
|
||||
bool log_on_hit = false;
|
||||
bool break_on_hit = false;
|
||||
bool log_call_stack = false;
|
||||
std::optional<Expression> condition;
|
||||
};
|
||||
|
||||
@ -40,6 +41,8 @@ struct TMemCheck
|
||||
bool log_on_hit = false;
|
||||
bool break_on_hit = false;
|
||||
|
||||
bool log_call_stack = false;
|
||||
|
||||
u32 num_hits = 0;
|
||||
|
||||
std::optional<Expression> condition;
|
||||
@ -74,7 +77,8 @@ public:
|
||||
const TBreakPoint* GetRegularBreakpoint(u32 address) const;
|
||||
|
||||
// Add BreakPoint. If one already exists on the same address, replace it.
|
||||
void Add(u32 address, bool break_on_hit, bool log_on_hit, std::optional<Expression> condition);
|
||||
void Add(u32 address, bool break_on_hit, bool log_on_hit, bool log_call_stack,
|
||||
std::optional<Expression> condition);
|
||||
void Add(u32 address);
|
||||
void Add(TBreakPoint bp);
|
||||
// Add temporary breakpoint (e.g., Step Over, Run to Here)
|
||||
|
||||
@ -20,6 +20,7 @@
|
||||
#include "Core/Config/MainSettings.h"
|
||||
#include "Core/Core.h"
|
||||
#include "Core/CoreTiming.h"
|
||||
#include "Core/Debugger/Debugger_SymbolMap.h"
|
||||
#include "Core/HW/CPU.h"
|
||||
#include "Core/HW/SystemTimers.h"
|
||||
#include "Core/Host.h"
|
||||
@ -641,6 +642,15 @@ bool PowerPCManager::CheckBreakPoints()
|
||||
m_ppc_state.gpr[4], m_ppc_state.gpr[5], m_ppc_state.gpr[6], m_ppc_state.gpr[7],
|
||||
m_ppc_state.gpr[8], m_ppc_state.gpr[9], m_ppc_state.gpr[10], m_ppc_state.gpr[11],
|
||||
m_ppc_state.gpr[12], LR(m_ppc_state));
|
||||
|
||||
if (bp->log_call_stack)
|
||||
{
|
||||
auto& system = Core::System::GetInstance();
|
||||
ASSERT(Core::IsCPUThread());
|
||||
Core::CPUThreadGuard guard(system);
|
||||
Dolphin_Debugger::PrintCallstack(guard, Common::Log::LogType::MEMMAP,
|
||||
Common::Log::LogLevel::LNOTICE);
|
||||
}
|
||||
}
|
||||
if (bp->break_on_hit)
|
||||
return true;
|
||||
|
||||
@ -1159,7 +1159,7 @@ void BranchWatchDialog::SetBreakpoints(bool break_on_hit, bool log_on_hit) const
|
||||
for (const QModelIndex& index : m_index_list_temp)
|
||||
{
|
||||
const u32 address = m_table_proxy->data(index, UserRole::ClickRole).value<u32>();
|
||||
breakpoints.Add(address, break_on_hit, log_on_hit, {});
|
||||
breakpoints.Add(address, break_on_hit, log_on_hit, false, {});
|
||||
}
|
||||
emit Host::GetInstance()->PPCBreakpointsChanged();
|
||||
}
|
||||
|
||||
@ -47,6 +47,8 @@ BreakpointDialog::BreakpointDialog(BreakpointWidget* parent, const TBreakPoint*
|
||||
m_do_log->setChecked(!breakpoint->break_on_hit && breakpoint->log_on_hit);
|
||||
m_do_log_and_break->setChecked(breakpoint->break_on_hit && breakpoint->log_on_hit);
|
||||
|
||||
m_call_stack_checkbox->setChecked(breakpoint->log_call_stack);
|
||||
|
||||
OnBPTypeChanged();
|
||||
OnAddressTypeChanged();
|
||||
}
|
||||
@ -81,6 +83,8 @@ BreakpointDialog::BreakpointDialog(BreakpointWidget* parent, const TMemCheck* me
|
||||
m_do_log->setChecked(!memcheck->break_on_hit && memcheck->log_on_hit);
|
||||
m_do_log_and_break->setChecked(memcheck->break_on_hit && memcheck->log_on_hit);
|
||||
|
||||
m_call_stack_checkbox->setChecked(memcheck->log_call_stack);
|
||||
|
||||
OnBPTypeChanged();
|
||||
OnAddressTypeChanged();
|
||||
}
|
||||
@ -175,6 +179,11 @@ void BreakpointDialog::CreateWidgets()
|
||||
conditional_layout->addWidget(new QLabel(tr("Condition:")));
|
||||
conditional_layout->addWidget(m_conditional);
|
||||
|
||||
// add a checkbox to support printing call stacks on membps
|
||||
QHBoxLayout* call_stack_layout = new QHBoxLayout;
|
||||
m_call_stack_checkbox = new QCheckBox(tr("Log Call Stack"));
|
||||
call_stack_layout->addWidget(m_call_stack_checkbox);
|
||||
|
||||
auto* action_layout = new QHBoxLayout;
|
||||
action_layout->addWidget(m_do_log);
|
||||
action_layout->addWidget(m_do_break);
|
||||
@ -183,6 +192,7 @@ void BreakpointDialog::CreateWidgets()
|
||||
auto* action_vlayout = new QVBoxLayout;
|
||||
action_vlayout->addLayout(conditional_layout);
|
||||
action_vlayout->addLayout(action_layout);
|
||||
action_vlayout->addLayout(call_stack_layout);
|
||||
|
||||
action_box->setLayout(action_vlayout);
|
||||
|
||||
@ -263,6 +273,7 @@ void BreakpointDialog::accept()
|
||||
// Actions
|
||||
bool do_log = m_do_log->isChecked() || m_do_log_and_break->isChecked();
|
||||
bool do_break = m_do_break->isChecked() || m_do_log_and_break->isChecked();
|
||||
bool log_call_stack = m_call_stack_checkbox->isChecked();
|
||||
|
||||
bool good;
|
||||
|
||||
@ -286,7 +297,7 @@ void BreakpointDialog::accept()
|
||||
return;
|
||||
}
|
||||
|
||||
m_parent->AddBP(address, do_break, do_log, condition);
|
||||
m_parent->AddBP(address, do_break, do_log, log_call_stack, condition);
|
||||
}
|
||||
else
|
||||
{
|
||||
@ -307,11 +318,12 @@ void BreakpointDialog::accept()
|
||||
return;
|
||||
}
|
||||
|
||||
m_parent->AddRangedMBP(from, to, on_read, on_write, do_log, do_break, condition);
|
||||
m_parent->AddRangedMBP(from, to, on_read, on_write, do_log, do_break, log_call_stack,
|
||||
condition);
|
||||
}
|
||||
else
|
||||
{
|
||||
m_parent->AddAddressMBP(from, on_read, on_write, do_log, do_break, condition);
|
||||
m_parent->AddAddressMBP(from, on_read, on_write, do_log, do_break, log_call_stack, condition);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@ -66,6 +66,8 @@ private:
|
||||
QRadioButton* m_do_break;
|
||||
QRadioButton* m_do_log_and_break;
|
||||
|
||||
QCheckBox* m_call_stack_checkbox;
|
||||
|
||||
QLineEdit* m_conditional;
|
||||
QPushButton* m_cond_help_btn;
|
||||
|
||||
|
||||
@ -597,13 +597,14 @@ void BreakpointWidget::OnItemChanged(QTableWidgetItem* item)
|
||||
|
||||
void BreakpointWidget::AddBP(u32 addr)
|
||||
{
|
||||
AddBP(addr, true, true, {});
|
||||
AddBP(addr, true, true, false, {});
|
||||
}
|
||||
|
||||
void BreakpointWidget::AddBP(u32 addr, bool break_on_hit, bool log_on_hit, const QString& condition)
|
||||
void BreakpointWidget::AddBP(u32 addr, bool break_on_hit, bool log_on_hit, bool log_call_stack,
|
||||
const QString& condition)
|
||||
{
|
||||
m_system.GetPowerPC().GetBreakPoints().Add(
|
||||
addr, break_on_hit, log_on_hit,
|
||||
addr, break_on_hit, log_on_hit, log_call_stack,
|
||||
!condition.isEmpty() ? Expression::TryParse(condition.toUtf8().constData()) : std::nullopt);
|
||||
|
||||
emit Host::GetInstance()->PPCBreakpointsChanged();
|
||||
@ -644,7 +645,7 @@ void BreakpointWidget::EditBreakpoint(u32 address, int edit, std::optional<QStri
|
||||
}
|
||||
|
||||
void BreakpointWidget::AddAddressMBP(u32 addr, bool on_read, bool on_write, bool do_log,
|
||||
bool do_break, const QString& condition)
|
||||
bool do_break, bool log_call_stack, const QString& condition)
|
||||
{
|
||||
TMemCheck check;
|
||||
|
||||
@ -655,6 +656,7 @@ void BreakpointWidget::AddAddressMBP(u32 addr, bool on_read, bool on_write, bool
|
||||
check.is_break_on_write = on_write;
|
||||
check.log_on_hit = do_log;
|
||||
check.break_on_hit = do_break;
|
||||
check.log_call_stack = log_call_stack;
|
||||
check.condition =
|
||||
!condition.isEmpty() ? Expression::TryParse(condition.toUtf8().constData()) : std::nullopt;
|
||||
{
|
||||
@ -666,7 +668,7 @@ void BreakpointWidget::AddAddressMBP(u32 addr, bool on_read, bool on_write, bool
|
||||
}
|
||||
|
||||
void BreakpointWidget::AddRangedMBP(u32 from, u32 to, bool on_read, bool on_write, bool do_log,
|
||||
bool do_break, const QString& condition)
|
||||
bool do_break, bool log_call_stack, const QString& condition)
|
||||
{
|
||||
TMemCheck check;
|
||||
|
||||
@ -677,6 +679,7 @@ void BreakpointWidget::AddRangedMBP(u32 from, u32 to, bool on_read, bool on_writ
|
||||
check.is_break_on_write = on_write;
|
||||
check.log_on_hit = do_log;
|
||||
check.break_on_hit = do_break;
|
||||
check.log_call_stack = log_call_stack;
|
||||
check.condition =
|
||||
!condition.isEmpty() ? Expression::TryParse(condition.toUtf8().constData()) : std::nullopt;
|
||||
{
|
||||
|
||||
@ -34,11 +34,14 @@ public:
|
||||
~BreakpointWidget() override;
|
||||
|
||||
void AddBP(u32 addr);
|
||||
void AddBP(u32 addr, bool break_on_hit, bool log_on_hit, const QString& condition);
|
||||
void AddBP(u32 addr, bool break_on_hit, bool log_on_hit, bool log_call_stack,
|
||||
const QString& condition);
|
||||
void AddAddressMBP(u32 addr, bool on_read = true, bool on_write = true, bool do_log = true,
|
||||
bool do_break = true, const QString& condition = {});
|
||||
bool do_break = true, bool log_call_stack = false,
|
||||
const QString& condition = {});
|
||||
void AddRangedMBP(u32 from, u32 to, bool do_read = true, bool do_write = true, bool do_log = true,
|
||||
bool do_break = true, const QString& condition = {});
|
||||
bool do_break = true, bool log_call_stack = false,
|
||||
const QString& condition = {});
|
||||
void UpdateButtonsEnabled();
|
||||
void Update();
|
||||
|
||||
|
||||
Loading…
Reference in New Issue
Block a user