mirror of
https://github.com/hrydgard/ppsspp.git
synced 2026-09-06 04:35:29 +02:00
Add BreakpointManager::ChangeBreakPointAddress, use it from the ImDebugger
ChangeBreakPointAddress() moves the breakpoint keeping its action, condition and log format, invalidates both ends, refuses to land on an existing breakpoint, and resets the hit count since it belonged to the old address. The edit form now works on a copy of the address and commits on deactivation rather than per keystroke, so typing one address doesn't churn through every prefix of it. The breakpoint edit form assigned straight to bp.addr and then invalidated the icache at "bp.addr - 4, 8" - which by then is the *new* address - need both. Also clear the selection after Delete in both edit forms - the reference into the vector is dangling from that point on. Harmless today, but only because nothing happens to touch it below. Covered by a new Breakpoints unit test (verified to fail without the duplicate check and the hit reset). Co-Authored-By: Claude Opus 5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01GZq8ZtJmFY7bkX5FVkr3P9
This commit is contained in:
co-authored by
Claude Opus 5
parent
d4500d9353
commit
0c510ca62e
@@ -1149,23 +1149,27 @@ static void DrawBreakpointsView(MIPSDebugInterface *mipsDebug, ImConfig &cfg) {
|
||||
// Add edit form for breakpoints
|
||||
if (ImGui::BeginChild("bp_edit")) {
|
||||
auto &bp = bps[cfg.selectedBreakpoint];
|
||||
bool changed = false;
|
||||
ImGui::TextUnformatted("Edit breakpoint");
|
||||
if (ImGui::CheckboxFlags("Enabled", (int *)&bp.action, (int)BREAK_ACTION_PAUSE)) {
|
||||
changed = true;
|
||||
}
|
||||
if (ImGui::CheckboxFlags("Log", (int *)&bp.action, (int)BREAK_ACTION_LOG)) {
|
||||
changed = true;
|
||||
}
|
||||
if (ImGui::InputScalar("Address", ImGuiDataType_U32, &bp.addr, nullptr, nullptr, "%08x", ImGuiInputTextFlags_CharsHexadecimal)) {
|
||||
changed = true;
|
||||
}
|
||||
if (changed) {
|
||||
// This is a bit hacky, we should probably add a utility function in the breakpoint manager.
|
||||
currentMIPS->InvalidateICacheRangeDeferred(bp.addr - 4, 8);
|
||||
// No cache invalidation needed for these two: the JIT emits its call for any address
|
||||
// that has a breakpoint at all, and the action bits are read live in
|
||||
// ExecBreakPoint(). Only the set of addresses affects generated code.
|
||||
ImGui::CheckboxFlags("Enabled", (int *)&bp.action, (int)BREAK_ACTION_PAUSE);
|
||||
ImGui::CheckboxFlags("Log", (int *)&bp.action, (int)BREAK_ACTION_LOG);
|
||||
|
||||
// Moving a breakpoint isn't just an assignment to bp.addr - the compiled code at
|
||||
// both the old and the new address has to be invalidated, and landing on top of an
|
||||
// existing breakpoint has to be refused. Edit a copy and let the manager do it.
|
||||
// Committing on deactivation rather than per keystroke also avoids doing all that
|
||||
// for each of the intermediate addresses you pass through while typing one.
|
||||
u32 addr = bp.addr;
|
||||
ImGui::InputScalar("Address", ImGuiDataType_U32, &addr, nullptr, nullptr, "%08x", ImGuiInputTextFlags_CharsHexadecimal);
|
||||
if (ImGui::IsItemDeactivatedAfterEdit()) {
|
||||
g_breakpoints.ChangeBreakPointAddress(bp.addr, addr);
|
||||
}
|
||||
if (ImGui::Button("Delete")) {
|
||||
g_breakpoints.RemoveBreakPoint(bp.addr);
|
||||
// bp (and bps) are dangling from here on - don't touch them again this frame.
|
||||
cfg.selectedBreakpoint = -1;
|
||||
}
|
||||
ImGui::EndChild();
|
||||
}
|
||||
@@ -1212,12 +1216,14 @@ static void DrawBreakpointsView(MIPSDebugInterface *mipsDebug, ImConfig &cfg) {
|
||||
if (ImGui::InputScalar("End", ImGuiDataType_U32, &mc.end, NULL, NULL, "%08x", ImGuiInputTextFlags_CharsHexadecimal)) {
|
||||
changed = true;
|
||||
}
|
||||
if (ImGui::Button("Delete")) {
|
||||
g_breakpoints.RemoveMemCheck(mcs[cfg.selectedMemCheck].start, mcs[cfg.selectedMemCheck].end);
|
||||
}
|
||||
if (changed) {
|
||||
g_breakpoints.NotifyChangedMemchecks();
|
||||
}
|
||||
if (ImGui::Button("Delete")) {
|
||||
g_breakpoints.RemoveMemCheck(mc.start, mc.end);
|
||||
// mc (and mcs) are dangling from here on - don't touch them again this frame.
|
||||
cfg.selectedMemCheck = -1;
|
||||
}
|
||||
ImGui::EndChild();
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user