diff --git a/src/ARM.cpp b/src/ARM.cpp index b7b703da..c115d728 100644 --- a/src/ARM.cpp +++ b/src/ARM.cpp @@ -123,6 +123,7 @@ ARM::ARM(u32 num, bool jit, std::optional gdb, melonDS::NDS& nds) : ) GdbStub.Init(); IsSingleStep = false; + BreakOnError = gdb->BreakOnError; #endif } @@ -545,6 +546,16 @@ void ARMv5::PrefetchAbort() { Log(LogLevel::Warn, "ARM9: prefetch abort (%08X)\n", R[15]); +#ifdef GDBSTUB_ENABLED + Gdb::StubState s = GdbStub.Poll(); + if (BreakOnError && s != Gdb::StubState::NoConn) + { + BreakReq = true; + GdbCheckB(); + return; + } +#endif + u32 oldcpsr = CPSR; CPSR &= ~0xBF; CPSR |= 0x97; @@ -568,6 +579,16 @@ void ARMv5::DataAbort() { Log(LogLevel::Warn, "ARM9: data abort (%08X)\n", R[15]); +#ifdef GDBSTUB_ENABLED + Gdb::StubState s = GdbStub.Poll(); + if (BreakOnError && s != Gdb::StubState::NoConn) + { + BreakReq = true; + GdbCheckB(); + return; + } +#endif + u32 oldcpsr = CPSR; CPSR &= ~0xBF; CPSR |= 0x97; diff --git a/src/ARM.h b/src/ARM.h index b652e74d..ecb3bd51 100644 --- a/src/ARM.h +++ b/src/ARM.h @@ -206,6 +206,7 @@ protected: bool IsSingleStep; bool BreakReq; bool BreakOnStartup; + bool BreakOnError; u16 Port; public: diff --git a/src/Args.h b/src/Args.h index 2c405e29..da52117c 100644 --- a/src/Args.h +++ b/src/Args.h @@ -79,6 +79,7 @@ struct GDBArgs u16 PortARM9 = 0; bool ARM7BreakOnStartup = false; bool ARM9BreakOnStartup = false; + bool BreakOnError = false; }; /// Arguments to pass into the NDS constructor. diff --git a/src/frontend/qt_sdl/Config.cpp b/src/frontend/qt_sdl/Config.cpp index 02be5b65..95e4a6b4 100644 --- a/src/frontend/qt_sdl/Config.cpp +++ b/src/frontend/qt_sdl/Config.cpp @@ -310,6 +310,7 @@ LegacyEntry LegacyFile[] = #ifdef GDBSTUB_ENABLED {"GdbEnabled", 1, "Gdb.Enabled", false}, + {"GdbBreakOnError", 1, "Gdb.BreakOnError", true}, {"GdbPortARM7", 0, "Gdb.ARM7.Port", true}, {"GdbPortARM9", 0, "Gdb.ARM9.Port", true}, {"GdbARM7BreakOnStartup", 1, "Gdb.ARM7.BreakOnStartup", true}, diff --git a/src/frontend/qt_sdl/EmuInstance.cpp b/src/frontend/qt_sdl/EmuInstance.cpp index 2ac3f42d..7a74c6be 100644 --- a/src/frontend/qt_sdl/EmuInstance.cpp +++ b/src/frontend/qt_sdl/EmuInstance.cpp @@ -1285,6 +1285,7 @@ bool EmuInstance::updateConsole(UpdateConsoleNDSArgs&& _ndsargs, UpdateConsoleGB static_cast(gdbopt.GetInt("ARM9.Port")), gdbopt.GetBool("ARM7.BreakOnStartup"), gdbopt.GetBool("ARM9.BreakOnStartup"), + gdbopt.GetBool("BreakOnError") }; auto gdbargs = gdbopt.GetBool("Enabled") ? std::make_optional(_gdbargs) : std::nullopt; #else diff --git a/src/frontend/qt_sdl/EmuSettingsDialog.cpp b/src/frontend/qt_sdl/EmuSettingsDialog.cpp index b37f7118..6c7e90a7 100644 --- a/src/frontend/qt_sdl/EmuSettingsDialog.cpp +++ b/src/frontend/qt_sdl/EmuSettingsDialog.cpp @@ -96,6 +96,7 @@ EmuSettingsDialog::EmuSettingsDialog(QWidget* parent) : QDialog(parent), ui(new #ifdef GDBSTUB_ENABLED ui->cbGdbEnabled->setChecked(instcfg.GetBool("Gdb.Enabled")); + ui->cbGdbBreakOnError->setChecked(instcfg.GetBool("Gdb.BreakOnError")); ui->intGdbPortA7->setValue(instcfg.GetInt("Gdb.ARM7.Port")); ui->intGdbPortA9->setValue(instcfg.GetInt("Gdb.ARM9.Port")); ui->cbGdbBOSA7->setChecked(instcfg.GetBool("Gdb.ARM7.BreakOnStartup")); @@ -294,6 +295,7 @@ void EmuSettingsDialog::done(int r) #endif #ifdef GDBSTUB_ENABLED instcfg.SetBool("Gdb.Enabled", ui->cbGdbEnabled->isChecked()); + instcfg.SetBool("Gdb.BreakOnError", ui->cbGdbBreakOnError->isChecked()); instcfg.SetInt("Gdb.ARM7.Port", ui->intGdbPortA7->value()); instcfg.SetInt("Gdb.ARM9.Port", ui->intGdbPortA9->value()); instcfg.SetBool("Gdb.ARM7.BreakOnStartup", ui->cbGdbBOSA7->isChecked()); diff --git a/src/frontend/qt_sdl/EmuSettingsDialog.ui b/src/frontend/qt_sdl/EmuSettingsDialog.ui index 2746e1da..1b123f67 100644 --- a/src/frontend/qt_sdl/EmuSettingsDialog.ui +++ b/src/frontend/qt_sdl/EmuSettingsDialog.ui @@ -607,14 +607,21 @@ - + + + + Break on data error + + + + Note: melonDS must be restarted in order for these changes to have effect - + Note: GDB stub cannot be used together with the JIT recompiler