Skip to content

Commit

Permalink
Turn the break reason into an enum, fix some minor issues
Browse files Browse the repository at this point in the history
  • Loading branch information
hrydgard committed Feb 19, 2025
1 parent 25cc2ba commit 5e98430
Show file tree
Hide file tree
Showing 21 changed files with 115 additions and 58 deletions.
58 changes: 45 additions & 13 deletions Core/Core.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -50,15 +50,15 @@ static std::mutex g_stepMutex;
struct CPUStepCommand {
CPUStepType type;
int stepSize;
const char *reason;
BreakReason reason;
u32 relatedAddr;
bool empty() const {
return type == CPUStepType::None;
}
void clear() {
type = CPUStepType::None;
stepSize = 0;
reason = "";
reason = BreakReason::None;
relatedAddr = 0;
}
};
Expand All @@ -80,13 +80,47 @@ volatile bool coreStatePending = false;

static bool powerSaving = false;
static bool g_breakAfterFrame = false;
static std::string g_breakReason;
static BreakReason g_breakReason = BreakReason::None;

static MIPSExceptionInfo g_exceptionInfo;

// This is called on EmuThread before RunLoop.
static bool Core_ProcessStepping(MIPSDebugInterface *cpu);

BreakReason Core_BreakReason() {
return g_breakReason;
}

const char *BreakReasonToString(BreakReason reason) {
switch (reason) {
case BreakReason::None: return "None";
case BreakReason::DebugBreak: return "cpu.debugbreak";
case BreakReason::DebugStep: return "cpu.stepping";
case BreakReason::DebugStepInto: return "cpu.stepInto";
case BreakReason::UIFocus: return "ui.lost_focus";
case BreakReason::AfterFrame: return "frame.after";
case BreakReason::MemoryException: return "memory.exception";
case BreakReason::CpuException: return "cpu.exception";
case BreakReason::BreakInstruction: return "cpu.breakInstruction";
case BreakReason::SavestateLoad: return "savestate.load";
case BreakReason::SavestateSave: return "savestate.save";
case BreakReason::SavestateRewind: return "savestate.rewind";
case BreakReason::SavestateCrash: return "savestate.crash";
case BreakReason::MemoryBreakpoint: return "memory.breakpoint";
case BreakReason::CpuBreakpoint: return "cpu.breakpoint";
case BreakReason::BreakpointUpdate: return "cpu.breakpoint.update";
case BreakReason::MemoryAccess: return "memory.access"; // ???
case BreakReason::JitBranchDebug: return "jit.branchdebug";
case BreakReason::RABreak: return "ra.break";
case BreakReason::BreakOnBoot: return "ui.boot";
case BreakReason::AddBreakpoint: return "cpu.breakpoint.add";
case BreakReason::FrameAdvance: return "ui.frameAdvance";
case BreakReason::UIPause: return "ui.pause";
case BreakReason::HLEDebugBreak: return "hle.step";
default: return "Unknown";
}
}

void Core_SetGraphicsContext(GraphicsContext *ctx) {
PSP_CoreParameter().graphicsContext = ctx;
}
Expand Down Expand Up @@ -170,6 +204,7 @@ void Core_RunLoopUntil(u64 globalticks) {
mipsr4k.RunLoopUntil(globalticks);
if (g_breakAfterFrame && coreState == CORE_NEXTFRAME) {
g_breakAfterFrame = false;
g_breakReason = BreakReason::AfterFrame;
coreState = CORE_STEPPING_CPU;
}
break; // Will loop around to go to RUNNING_GE or NEXTFRAME, which will exit.
Expand Down Expand Up @@ -376,7 +411,7 @@ static bool Core_ProcessStepping(MIPSDebugInterface *cpu) {
}

// Free-threaded (hm, possibly except tracing).
void Core_Break(const char *reason, u32 relatedAddress) {
void Core_Break(BreakReason reason, u32 relatedAddress) {
if (coreState != CORE_RUNNING_CPU) {
ERROR_LOG(Log::CPU, "Core_Break only works in the CORE_RUNNING_CPU state");
return;
Expand Down Expand Up @@ -405,16 +440,12 @@ void Core_Break(const char *reason, u32 relatedAddress) {
g_cpuStepCommand.reason = reason;
g_cpuStepCommand.relatedAddr = relatedAddress;
steppingCounter++;
_assert_msg_(reason != nullptr, "No reason specified for break");
_assert_msg_(reason != BreakReason::None, "No reason specified for break");
Core_UpdateState(CORE_STEPPING_CPU);
}
System_Notify(SystemNotification::DEBUG_MODE_CHANGE);
}

const std::string &Core_BreakReason() {
return g_breakReason;
}

// Free-threaded (or at least should be)
void Core_Resume() {
// If the current PC is on a breakpoint, the user doesn't want to do nothing.
Expand All @@ -431,6 +462,7 @@ void Core_Resume() {
// Clear the exception if we resume.
Core_ResetException();
coreState = CORE_RUNNING_CPU;
g_breakReason = BreakReason::None;
System_Notify(SystemNotification::DEBUG_MODE_CHANGE);
}

Expand Down Expand Up @@ -523,7 +555,7 @@ void Core_MemoryException(u32 address, u32 accessSize, u32 pc, MemoryExceptionTy
e.accessSize = accessSize;
e.stackTrace = stackTrace;
e.pc = pc;
Core_Break("memory.exception", address);
Core_Break(BreakReason::MemoryException, address);
}
}

Expand Down Expand Up @@ -551,7 +583,7 @@ void Core_MemoryExceptionInfo(u32 address, u32 accessSize, u32 pc, MemoryExcepti
e.accessSize = accessSize;
e.stackTrace = stackTrace;
e.pc = pc;
Core_Break("memory.exception", address);
Core_Break(BreakReason::MemoryException, address);
}
}

Expand All @@ -570,7 +602,7 @@ void Core_ExecException(u32 address, u32 pc, ExecExceptionType type) {
e.pc = pc;
// This just records the closest value that could be useful as reference.
e.ra = currentMIPS->r[MIPS_REG_RA];
Core_Break("cpu.exception", address);
Core_Break(BreakReason::CpuException, address);
}

void Core_BreakException(u32 pc) {
Expand All @@ -583,7 +615,7 @@ void Core_BreakException(u32 pc) {
e.pc = pc;

if (!g_Config.bIgnoreBadMemAccess) {
Core_Break("cpu.breakInstruction", currentMIPS->pc);
Core_Break(BreakReason::BreakInstruction, currentMIPS->pc);
}
}

Expand Down
35 changes: 32 additions & 3 deletions Core/Core.h
Original file line number Diff line number Diff line change
Expand Up @@ -44,13 +44,42 @@ enum class CPUStepType {
Frame,
};

// Must be set when breaking.
enum class BreakReason {
None,
DebugBreak,
DebugStep,
DebugStepInto,
UIFocus,
AfterFrame,
MemoryException,
CpuException,
BreakInstruction,
SavestateLoad,
SavestateSave,
SavestateRewind,
SavestateCrash,
MemoryBreakpoint,
CpuBreakpoint,
BreakpointUpdate,
MemoryAccess, // ???
JitBranchDebug,
BreakOnBoot,
RABreak,
AddBreakpoint,
FrameAdvance,
UIPause,
HLEDebugBreak,
};
const char *BreakReasonToString(BreakReason reason);

// Async, called from gui
void Core_Break(const char *reason, u32 relatedAddress = 0);
void Core_Break(BreakReason reason, u32 relatedAddress = 0);

// Resumes execution. Works both when stepping the CPU and the GE.
void Core_Resume();

const std::string &Core_BreakReason();
BreakReason Core_BreakReason();

// This should be called externally.
// Can fail if another step type was requested this frame.
Expand All @@ -62,7 +91,7 @@ void Core_SwitchToGe(); // Switches from CPU emulation to GE display list execu
// Changes every time we enter stepping.
int Core_GetSteppingCounter();
struct SteppingReason {
const char *reason = nullptr;
BreakReason reason;
u32 relatedAddress = 0;
};
SteppingReason Core_GetSteppingReason();
Expand Down
2 changes: 1 addition & 1 deletion Core/CoreTiming.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -147,7 +147,7 @@ int RegisterEvent(const char *name, TimedCallback callback) {

void AntiCrashCallback(u64 userdata, int cyclesLate) {
ERROR_LOG(Log::SaveState, "Savestate broken: an unregistered event was called.");
Core_Break("savestate.crash", 0);
Core_Break(BreakReason::SavestateCrash, 0);
}

void RestoreRegisterEvent(int &event_type, const char *name, TimedCallback callback) {
Expand Down
6 changes: 3 additions & 3 deletions Core/Debugger/Breakpoints.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -64,7 +64,7 @@ BreakAction MemCheck::Action(u32 addr, bool write, int size, u32 pc, const char
// Conditions have always already been checked if we get here.
Log(addr, write, size, pc, reason);
if ((result & BREAK_ACTION_PAUSE) && coreState != CORE_POWERUP) {
Core_Break("memory.breakpoint", start);
Core_Break(BreakReason::MemoryBreakpoint, start);
}

return result;
Expand Down Expand Up @@ -316,7 +316,7 @@ BreakAction BreakpointManager::ExecBreakPoint(u32 addr) {
}
}
if ((info.result & BREAK_ACTION_PAUSE) && coreState != CORE_POWERUP) {
Core_Break("cpu.breakpoint", info.addr);
Core_Break(BreakReason::CpuBreakpoint, info.addr);
}

return info.result;
Expand Down Expand Up @@ -624,7 +624,7 @@ void BreakpointManager::Update(u32 addr) {
if (MIPSComp::jit && addr != -1) {
bool resume = false;
if (Core_IsStepping() == false) {
Core_Break("cpu.breakpoint.update", addr);
Core_Break(BreakReason::BreakpointUpdate, addr);
Core_WaitInactive();
resume = true;
}
Expand Down
2 changes: 1 addition & 1 deletion Core/Debugger/WebSocket/CPUCoreSubscriber.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -72,7 +72,7 @@ void WebSocketCPUStepping(DebuggerRequest &req) {
return req.Fail("CPU not started");
}
if (!Core_IsStepping() && Core_IsActive()) {
Core_Break("cpu.stepping", 0);
Core_Break(BreakReason::DebugStep, 0);
}
}

Expand Down
2 changes: 1 addition & 1 deletion Core/Debugger/WebSocket/MemorySubscriber.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -64,7 +64,7 @@ static AutoDisabledReplacements LockMemoryAndCPU(uint32_t addr, bool keepReplace
if (Core_IsStepping()) {
result.wasStepping = true;
} else {
Core_Break("memory.access", addr);
Core_Break(BreakReason::MemoryAccess, addr);
Core_WaitInactive();
}

Expand Down
4 changes: 2 additions & 2 deletions Core/Debugger/WebSocket/SteppingBroadcaster.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -33,8 +33,8 @@ struct CPUSteppingEvent {
j.writeUint("pc", currentMIPS->pc);
// A double ought to be good enough for a 156 day debug session.
j.writeFloat("ticks", CoreTiming::GetTicks());
if (reason_.reason) {
j.writeString("reason", reason_.reason);
if (reason_.reason != BreakReason::None) {
j.writeString("reason", BreakReasonToString(reason_.reason));
j.writeUint("relatedAddress", reason_.relatedAddress);
}
j.end();
Expand Down
2 changes: 1 addition & 1 deletion Core/Debugger/WebSocket/SteppingSubscriber.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -91,7 +91,7 @@ void WebSocketSteppingState::Into(DebuggerRequest &req) {
if (!currentDebugMIPS->isAlive())
return req.Fail("CPU not started");
if (!Core_IsStepping()) {
Core_Break("cpu.stepInto", 0);
Core_Break(BreakReason::DebugStepInto, 0);
return;
}

Expand Down
2 changes: 1 addition & 1 deletion Core/HLE/HLE.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -404,7 +404,7 @@ static bool hleExecuteDebugBreak(const HLEFunction *func) {
}

INFO_LOG(Log::CPU, "Broke after syscall: %s", func->name);
Core_Break("hle.step", g_syscallPC);
Core_Break(BreakReason::HLEDebugBreak, g_syscallPC);
return true;
}

Expand Down
2 changes: 1 addition & 1 deletion Core/MIPS/MIPSTables.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -1003,7 +1003,7 @@ static void RunUntilWithChecks(u64 globalTicks) {
if (hasBPs && g_breakpoints.IsAddressBreakPoint(curMips->pc) && g_breakpoints.CheckSkipFirst() != curMips->pc) {
auto cond = g_breakpoints.GetBreakPointCondition(currentMIPS->pc);
if (!cond || cond->Evaluate()) {
Core_Break("cpu.breakpoint", curMips->pc);
Core_Break(BreakReason::CpuBreakpoint, curMips->pc);
if (g_breakpoints.IsTempBreakPoint(curMips->pc))
g_breakpoints.RemoveBreakPoint(curMips->pc);
break;
Expand Down
2 changes: 1 addition & 1 deletion Core/MIPS/x86/CompBranch.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -109,7 +109,7 @@ static void JitBranchLogMismatch(MIPSOpcode op, u32 pc)
char temp[256];
MIPSDisAsm(op, pc, temp, sizeof(temp), true);
ERROR_LOG(Log::JIT, "Bad jump: %s - int:%08x jit:%08x", temp, currentMIPS->intBranchExit, currentMIPS->jitBranchExit);
Core_Break("jit.branchdebug", pc);
Core_Break(BreakReason::JitBranchDebug, pc);
}

void Jit::BranchLog(MIPSOpcode op)
Expand Down
2 changes: 1 addition & 1 deletion Core/RetroAchievements.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -545,7 +545,7 @@ static void raintegration_event_handler(const rc_client_raintegration_event_t *e
break;
case RC_CLIENT_RAINTEGRATION_EVENT_PAUSE:
// The toolkit has hit a breakpoint and wants to pause the emulator. Do so.
Core_Break("ra_breakpoint");
Core_Break(BreakReason::RABreak);
break;
case RC_CLIENT_RAINTEGRATION_EVENT_HARDCORE_CHANGED:
// Hardcore mode has been changed (either directly by the user, or disabled through the use of the tools).
Expand Down
6 changes: 3 additions & 3 deletions Core/SaveState.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -432,7 +432,7 @@ double g_lastSaveTime = -1.0;

rewindStates.NotifyState();
if (coreState == CoreState::CORE_RUNTIME_ERROR)
Core_Break("savestate.load", 0);
Core_Break(BreakReason::SavestateLoad, 0);
Enqueue(Operation(SAVESTATE_LOAD, filename, slot, callback, cbUserData));
}

Expand All @@ -444,7 +444,7 @@ double g_lastSaveTime = -1.0;

rewindStates.NotifyState();
if (coreState == CoreState::CORE_RUNTIME_ERROR)
Core_Break("savestate.save", 0);
Core_Break(BreakReason::SavestateSave, 0);
Enqueue(Operation(SAVESTATE_SAVE, filename, slot, callback, cbUserData));
}

Expand All @@ -459,7 +459,7 @@ double g_lastSaveTime = -1.0;
return;
}
if (coreState == CoreState::CORE_RUNTIME_ERROR)
Core_Break("savestate.rewind", 0);
Core_Break(BreakReason::SavestateRewind, 0);
Enqueue(Operation(SAVESTATE_REWIND, Path(), -1, callback, cbUserData));
}

Expand Down
11 changes: 5 additions & 6 deletions UI/EmuScreen.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -120,10 +120,9 @@ static void __EmuScreenVblank()
{
auto sy = GetI18NCategory(I18NCat::SYSTEM);

if (frameStep_ && lastNumFlips != gpuStats.numFlips)
{
if (frameStep_ && lastNumFlips != gpuStats.numFlips) {
frameStep_ = false;
Core_Break("ui.frameAdvance", 0);
Core_Break(BreakReason::FrameAdvance, 0);
lastNumFlips = gpuStats.numFlips;
}
#ifndef MOBILE_DEVICE
Expand Down Expand Up @@ -772,10 +771,10 @@ void EmuScreen::onVKey(int virtualKeyCode, bool down) {
case VIRTKEY_PAUSE_NO_MENU:
if (down && !NetworkWarnUserIfOnlineAndCantSpeed()) {
// We re-use debug break/resume to implement pause/resume without a menu.
if (coreState == CORE_STEPPING_CPU) {
if (coreState == CORE_STEPPING_CPU) { // should we check reason?
Core_Resume();
} else {
Core_Break("user-pause");
Core_Break(BreakReason::UIPause);
}
}
break;
Expand Down Expand Up @@ -1586,7 +1585,7 @@ ScreenRenderFlags EmuScreen::render(ScreenRenderMode mode) {
Core_Resume();
} else if (!frameStep_) {
lastNumFlips = gpuStats.numFlips;
Core_Break("ui.frameAdvance", 0);
Core_Break(BreakReason::FrameAdvance, 0);
}
}
}
Expand Down
Loading

0 comments on commit 5e98430

Please sign in to comment.