mirror of
https://github.com/dolphin-emu/dolphin.git
synced 2025-07-30 01:29:42 -06:00
Expand conditional breakpoints to memory breakpoints
This commit is contained in:
@ -335,7 +335,7 @@ void PPCDebugInterface::ToggleMemCheck(u32 address, bool read, bool write, bool
|
||||
MemCheck.log_on_hit = log;
|
||||
MemCheck.break_on_hit = true;
|
||||
|
||||
PowerPC::memchecks.Add(MemCheck);
|
||||
PowerPC::memchecks.Add(std::move(MemCheck));
|
||||
}
|
||||
else
|
||||
{
|
||||
|
@ -83,7 +83,6 @@ void BreakPoints::AddFromStrings(const TBreakPointsStr& bp_strings)
|
||||
|
||||
if (iss.peek() == '$')
|
||||
iss.ignore();
|
||||
|
||||
iss >> std::hex >> bp.address;
|
||||
iss >> flags;
|
||||
bp.is_enabled = flags.find('n') != flags.npos;
|
||||
@ -203,11 +202,21 @@ MemChecks::TMemChecksStr MemChecks::GetStrings() const
|
||||
{
|
||||
std::ostringstream ss;
|
||||
ss.imbue(std::locale::classic());
|
||||
ss << fmt::format("${:08x} {:08x} ", mc.start_address, mc.end_address);
|
||||
if (mc.is_enabled)
|
||||
ss << 'n';
|
||||
if (mc.is_break_on_read)
|
||||
ss << 'r';
|
||||
if (mc.is_break_on_write)
|
||||
ss << 'w';
|
||||
if (mc.log_on_hit)
|
||||
ss << 'l';
|
||||
if (mc.break_on_hit)
|
||||
ss << 'b';
|
||||
if (mc.condition)
|
||||
ss << "c " << mc.condition->GetText();
|
||||
|
||||
ss << std::hex << mc.start_address << " " << mc.end_address << " " << (mc.is_enabled ? "n" : "")
|
||||
<< (mc.is_break_on_read ? "r" : "") << (mc.is_break_on_write ? "w" : "")
|
||||
<< (mc.log_on_hit ? "l" : "") << (mc.break_on_hit ? "b" : "");
|
||||
mc_strings.push_back(ss.str());
|
||||
mc_strings.emplace_back(ss.str());
|
||||
}
|
||||
|
||||
return mc_strings;
|
||||
@ -221,6 +230,9 @@ void MemChecks::AddFromStrings(const TMemChecksStr& mc_strings)
|
||||
std::istringstream iss(mc_string);
|
||||
iss.imbue(std::locale::classic());
|
||||
|
||||
if (iss.peek() == '$')
|
||||
iss.ignore();
|
||||
|
||||
std::string flags;
|
||||
iss >> std::hex >> mc.start_address >> mc.end_address >> flags;
|
||||
|
||||
@ -230,12 +242,19 @@ void MemChecks::AddFromStrings(const TMemChecksStr& mc_strings)
|
||||
mc.is_break_on_write = flags.find('w') != 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)
|
||||
{
|
||||
iss >> std::ws;
|
||||
std::string condition;
|
||||
std::getline(iss, condition);
|
||||
mc.condition = Expression::TryParse(condition);
|
||||
}
|
||||
|
||||
Add(mc);
|
||||
Add(std::move(mc));
|
||||
}
|
||||
}
|
||||
|
||||
void MemChecks::Add(const TMemCheck& memory_check)
|
||||
void MemChecks::Add(TMemCheck memory_check)
|
||||
{
|
||||
bool had_any = HasAny();
|
||||
Core::RunAsCPUThread([&] {
|
||||
@ -254,7 +273,7 @@ void MemChecks::Add(const TMemCheck& memory_check)
|
||||
}
|
||||
else
|
||||
{
|
||||
m_mem_checks.push_back(memory_check);
|
||||
m_mem_checks.emplace_back(std::move(memory_check));
|
||||
}
|
||||
// If this is the first one, clear the JIT cache so it can switch to
|
||||
// watchpoint-compatible code.
|
||||
@ -338,7 +357,8 @@ bool TMemCheck::Action(Common::DebugInterface* debug_interface, u64 value, u32 a
|
||||
if (!is_enabled)
|
||||
return false;
|
||||
|
||||
if ((write && is_break_on_write) || (!write && is_break_on_read))
|
||||
if (((write && is_break_on_write) || (!write && is_break_on_read)) &&
|
||||
EvaluateCondition(this->condition))
|
||||
{
|
||||
if (log_on_hit)
|
||||
{
|
||||
|
@ -42,6 +42,8 @@ struct TMemCheck
|
||||
|
||||
u32 num_hits = 0;
|
||||
|
||||
std::optional<Expression> condition;
|
||||
|
||||
// returns whether to break
|
||||
bool Action(Common::DebugInterface* debug_interface, u64 value, u32 addr, bool write, size_t size,
|
||||
u32 pc);
|
||||
@ -93,7 +95,7 @@ public:
|
||||
TMemChecksStr GetStrings() const;
|
||||
void AddFromStrings(const TMemChecksStr& mc_strings);
|
||||
|
||||
void Add(const TMemCheck& memory_check);
|
||||
void Add(TMemCheck memory_check);
|
||||
|
||||
bool ToggleBreakPoint(u32 address);
|
||||
|
||||
|
@ -865,7 +865,7 @@ static bool AddBreakpoint(BreakpointType type, u32 addr, u32 len)
|
||||
new_memcheck.break_on_hit = true;
|
||||
new_memcheck.log_on_hit = false;
|
||||
new_memcheck.is_enabled = true;
|
||||
PowerPC::memchecks.Add(new_memcheck);
|
||||
PowerPC::memchecks.Add(std::move(new_memcheck));
|
||||
INFO_LOG_FMT(GDB_STUB, "gdb: added {} memcheck: {:08x} bytes at {:08x}", static_cast<int>(type),
|
||||
len, addr);
|
||||
}
|
||||
|
Reference in New Issue
Block a user