From c6931ac76dfe95806913cfff1d690641cda7583a Mon Sep 17 00:00:00 2001 From: PabloMK7 Date: Mon, 4 May 2026 14:53:34 +0200 Subject: [PATCH] gdb: Add cmake toggle to enable GDB stub --- CMakeLists.txt | 3 ++- docker/azahar-room/Dockerfile | 1 + src/android/app/build.gradle.kts | 3 ++- src/android/app/src/main/jni/default_ini.h | 6 ++---- .../configuration/configure_debug.cpp | 6 +++++- src/citra_qt/configuration/configure_debug.ui | 2 +- src/core/CMakeLists.txt | 14 ++++++++++---- src/core/arm/dynarmic/arm_dynarmic.cpp | 13 +++++++++++-- .../arm/dyncom/arm_dyncom_interpreter.cpp | 8 ++++++-- src/core/arm/skyeye_common/armstate.cpp | 5 +++++ src/core/arm/skyeye_common/armstate.h | 10 ++++++++++ src/core/core.cpp | 10 ++++++++++ src/core/gdbstub/gdbstub.cpp | 9 ++++----- src/core/gdbstub/gdbstub.h | 4 ++++ src/core/gdbstub/hio.cpp | 4 ++++ src/core/gdbstub/hio.h | 4 ++++ src/core/hle/kernel/process.cpp | 6 ++++++ src/core/hle/kernel/svc.cpp | 4 ++++ src/core/hle/kernel/thread.cpp | 5 +++++ src/core/memory.cpp | 19 ++++++++++++++++++- 20 files changed, 114 insertions(+), 22 deletions(-) diff --git a/CMakeLists.txt b/CMakeLists.txt index 3d58cc70d..d98994384 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -99,7 +99,7 @@ endif() # Track which options were explicitly set by the user (for libretro conflict detection) set(_LIBRETRO_INCOMPATIBLE_OPTIONS - ENABLE_SDL2 ENABLE_QT ENABLE_WEB_SERVICE ENABLE_SCRIPTING + ENABLE_SDL2 ENABLE_QT ENABLE_WEB_SERVICE ENABLE_SCRIPTING ENABLE_GDBSTUB ENABLE_OPENAL ENABLE_ROOM ENABLE_ROOM_STANDALONE ENABLE_CUBEB ENABLE_LIBUSB) set(_USER_SET_OPTIONS "") foreach(_opt IN LISTS _LIBRETRO_INCOMPATIBLE_OPTIONS) @@ -122,6 +122,7 @@ CMAKE_DEPENDENT_OPTION(ENABLE_ROOM_STANDALONE "Enable generating a standalone de option(ENABLE_WEB_SERVICE "Enable web services (telemetry, etc.)" ON) option(ENABLE_SCRIPTING "Enable RPC server for scripting" ON) +option(ENABLE_GDBSTUB "Enable GDB stub for emulated applications" ON) CMAKE_DEPENDENT_OPTION(ENABLE_CUBEB "Enables the cubeb audio backend" ON "NOT IOS" OFF) option(ENABLE_OPENAL "Enables the OpenAL audio backend" ON) diff --git a/docker/azahar-room/Dockerfile b/docker/azahar-room/Dockerfile index c47896dd9..9a5f07820 100644 --- a/docker/azahar-room/Dockerfile +++ b/docker/azahar-room/Dockerfile @@ -9,6 +9,7 @@ COPY . /var/azahar-src RUN mkdir builddir && cd builddir && \ cmake /var/azahar-src -G Ninja \ -DENABLE_QT=OFF \ + -DENABLE_GDBSTUB=OFF \ -DENABLE_TESTS=OFF \ -DENABLE_ROOM=ON \ -DENABLE_ROOM_STANDALONE=ON \ diff --git a/src/android/app/build.gradle.kts b/src/android/app/build.gradle.kts index 733656c0e..2ee844985 100644 --- a/src/android/app/build.gradle.kts +++ b/src/android/app/build.gradle.kts @@ -79,7 +79,8 @@ android { "-DENABLE_QT=0", // Don't use QT "-DENABLE_SDL2=0", // Don't use SDL "-DANDROID_ARM_NEON=true", // cryptopp requires Neon to work - "-DANDROID_SUPPORT_FLEXIBLE_PAGE_SIZES=ON" // Support Android 15 16KiB page sizes + "-DANDROID_SUPPORT_FLEXIBLE_PAGE_SIZES=ON", // Support Android 15 16KiB page sizes + "-DENABLE_GDBSTUB=OFF", // Disable GDB stub ) } } diff --git a/src/android/app/src/main/jni/default_ini.h b/src/android/app/src/main/jni/default_ini.h index 2a70a060a..bfe406d77 100644 --- a/src/android/app/src/main/jni/default_ini.h +++ b/src/android/app/src/main/jni/default_ini.h @@ -37,6 +37,8 @@ constexpr std::array android_config_omitted_keys = { Keys::audio_bitrate, Keys::last_artic_base_addr, // On Android, this value is stored as a "preference" Keys::break_on_unmapped_memory_access, // Does nothing as the error is ignored + Keys::use_gdbstub, // GDB functionality disabled by deafult on Android + Keys::gdbstub_port, }; // clang-format off @@ -532,10 +534,6 @@ static const char* android_config_default_file_content = (BOOST_HANA_STRING(R"( # 0 (default): Off, 1: On )") DECLARE_KEY(renderer_debug) BOOST_HANA_STRING(R"( -# Port for listening to GDB connections. -)") DECLARE_KEY(use_gdbstub) BOOST_HANA_STRING(R"( -)") DECLARE_KEY(gdbstub_port) BOOST_HANA_STRING(R"( - # Flush log output on every message # Immediately commits the debug log to file. Use this if Azahar crashes and the log output is being cut. )") DECLARE_KEY(instant_debug_log) BOOST_HANA_STRING(R"( diff --git a/src/citra_qt/configuration/configure_debug.cpp b/src/citra_qt/configuration/configure_debug.cpp index 313df5d36..a1e26e456 100644 --- a/src/citra_qt/configuration/configure_debug.cpp +++ b/src/citra_qt/configuration/configure_debug.cpp @@ -100,6 +100,10 @@ ConfigureDebug::ConfigureDebug(bool is_powered_on_, QWidget* parent) ui->clock_speed_label->setVisible(Settings::IsConfiguringGlobal()); ui->clock_speed_combo->setVisible(!Settings::IsConfiguringGlobal()); +#ifndef ENABLE_GDBSTUB + ui->gdb_groupbox->setVisible(false); +#endif + SetupPerGameUI(); } @@ -198,7 +202,7 @@ void ConfigureDebug::SetupPerGameUI() { ConfigurationShared::SetHighlight(ui->clock_speed_widget, index == 1); }); - ui->groupBox->setVisible(false); + ui->gdb_groupbox->setVisible(false); ui->groupBox_2->setVisible(false); ui->enable_rpc_server->setVisible(false); ui->toggle_unique_data_console_type->setVisible(false); diff --git a/src/citra_qt/configuration/configure_debug.ui b/src/citra_qt/configuration/configure_debug.ui index 1a470fb6f..d9c833949 100644 --- a/src/citra_qt/configuration/configure_debug.ui +++ b/src/citra_qt/configuration/configure_debug.ui @@ -17,7 +17,7 @@ - + GDB diff --git a/src/core/CMakeLists.txt b/src/core/CMakeLists.txt index ec7a45bfe..e3f8e5275 100644 --- a/src/core/CMakeLists.txt +++ b/src/core/CMakeLists.txt @@ -126,10 +126,6 @@ add_library(citra_core STATIC frontend/image_interface.cpp frontend/image_interface.h frontend/input.h - gdbstub/gdbstub.cpp - gdbstub/gdbstub.h - gdbstub/hio.cpp - gdbstub/hio.h hle/applets/applet.cpp hle/applets/applet.h hle/applets/erreula.cpp @@ -529,6 +525,16 @@ if (ENABLE_SCRIPTING) ) endif() +if (ENABLE_GDBSTUB) + target_compile_definitions(citra_core PUBLIC -DENABLE_GDBSTUB) + target_sources(citra_core PRIVATE + gdbstub/gdbstub.cpp + gdbstub/gdbstub.h + gdbstub/hio.cpp + gdbstub/hio.h + ) +endif() + if ("x86_64" IN_LIST ARCHITECTURE OR "arm64" IN_LIST ARCHITECTURE) target_sources(citra_core PRIVATE arm/dynarmic/arm_dynarmic.cpp diff --git a/src/core/arm/dynarmic/arm_dynarmic.cpp b/src/core/arm/dynarmic/arm_dynarmic.cpp index 002c5488d..503092889 100644 --- a/src/core/arm/dynarmic/arm_dynarmic.cpp +++ b/src/core/arm/dynarmic/arm_dynarmic.cpp @@ -14,7 +14,9 @@ #include "core/arm/dynarmic/arm_tick_counts.h" #include "core/core.h" #include "core/core_timing.h" +#ifdef ENABLE_GDBSTUB #include "core/gdbstub/gdbstub.h" +#endif #include "core/hle/kernel/svc.h" #include "core/memory.h" @@ -106,11 +108,13 @@ public: case Dynarmic::A32::Exception::NoExecuteFault: break; case Dynarmic::A32::Exception::Breakpoint: +#ifdef ENABLE_GDBSTUB if (GDBStub::IsConnected()) { parent.SetPC(pc); parent.ServeBreak(SIGTRAP); return; } +#endif break; case Dynarmic::A32::Exception::SendEvent: case Dynarmic::A32::Exception::SendEventLocal: @@ -124,9 +128,12 @@ public: } parent.SetPC(pc); +#ifdef ENABLE_GDBSTUB if (GDBStub::IsConnected()) { parent.ServeBreak(SIGILL); - } else { + } else +#endif + { std::string error; for (int i = 0; i < 16; i++) { error += fmt::format("r{:02d} = {:08X}\n", i, parent.GetReg(i)); @@ -328,8 +335,10 @@ void ARM_Dynarmic::SetPageTable(const std::shared_ptr& page_t jits.emplace(current_page_table, std::move(new_jit)); } -void ARM_Dynarmic::ServeBreak(int signal) { +void ARM_Dynarmic::ServeBreak([[maybe_unused]] int signal) { +#ifdef ENABLE_GDBSTUB GDBStub::Break(signal); +#endif } std::unique_ptr ARM_Dynarmic::MakeJit() { diff --git a/src/core/arm/dyncom/arm_dyncom_interpreter.cpp b/src/core/arm/dyncom/arm_dyncom_interpreter.cpp index 794197590..af30fdad3 100644 --- a/src/core/arm/dyncom/arm_dyncom_interpreter.cpp +++ b/src/core/arm/dyncom/arm_dyncom_interpreter.cpp @@ -23,7 +23,9 @@ #include "core/arm/skyeye_common/vfp/vfp.h" #include "core/core.h" #include "core/core_timing.h" +#ifdef ENABLE_GDBSTUB #include "core/gdbstub/gdbstub.h" +#endif #include "core/hle/kernel/svc.h" #include "core/memory.h" @@ -922,9 +924,11 @@ MICROPROFILE_DEFINE(DynCom_Execute, "DynCom", "Execute", MP_RGB(255, 0, 0)); unsigned InterpreterMainLoop(ARMul_State* cpu) { MICROPROFILE_SCOPE(DynCom_Execute); +#ifdef ENABLE_GDBSTUB /// Nearest upcoming GDB code execution breakpoint, relative to the last dispatch's address. GDBStub::BreakpointAddress breakpoint_data; breakpoint_data.type = GDBStub::BreakpointType::None; +#endif #undef RM #undef RS @@ -952,7 +956,7 @@ unsigned InterpreterMainLoop(ARMul_State* cpu) { #define INC_PC(l) ptr += sizeof(arm_inst) + l #define INC_PC_STUB ptr += sizeof(arm_inst) -#ifdef ANDROID +#ifndef ENABLE_GDBSTUB #define GDB_BP_CHECK #else #define GDB_BP_CHECK \ @@ -1653,7 +1657,7 @@ DISPATCH: { goto END; } -#ifndef ANDROID +#ifdef ENABLE_GDBSTUB // Find breakpoint if one exists within the block if (GDBStub::IsConnected()) { breakpoint_data = diff --git a/src/core/arm/skyeye_common/armstate.cpp b/src/core/arm/skyeye_common/armstate.cpp index d7349b59a..9ff89c5a7 100644 --- a/src/core/arm/skyeye_common/armstate.cpp +++ b/src/core/arm/skyeye_common/armstate.cpp @@ -9,6 +9,9 @@ #include "core/arm/skyeye_common/armstate.h" #include "core/arm/skyeye_common/vfp/vfp.h" #include "core/core.h" +#ifdef ENABLE_GDBSTUB +#include "core/gdbstub/gdbstub.h" +#endif #include "core/memory.h" #ifndef SIGTRAP @@ -580,6 +583,7 @@ void ARMul_State::WriteCP15Register(u32 value, u32 crn, u32 opcode_1, u32 crm, u } void ARMul_State::ServeBreak() { +#ifdef ENABLE_GDBSTUB if (!GDBStub::IsServerEnabled()) { return; } @@ -592,4 +596,5 @@ void ARMul_State::ServeBreak() { last_bkpt_hit = false; GDBStub::Break(SIGTRAP); } +#endif } diff --git a/src/core/arm/skyeye_common/armstate.h b/src/core/arm/skyeye_common/armstate.h index f36c46c07..925881304 100644 --- a/src/core/arm/skyeye_common/armstate.h +++ b/src/core/arm/skyeye_common/armstate.h @@ -1,3 +1,7 @@ +// Copyright Citra Emulator Project / Azahar Emulator Project +// Licensed under GPLv2 or any later version +// Refer to the license.txt file included. + /* armdefs.h -- ARMulator common definitions: ARM6 Instruction Emulator. Copyright (C) 1994 Advanced RISC Machines Ltd. @@ -21,7 +25,9 @@ #include #include "common/common_types.h" #include "core/arm/skyeye_common/arm_regformat.h" +#ifdef ENABLE_GDBSTUB #include "core/gdbstub/gdbstub.h" +#endif namespace Core { class System; @@ -199,10 +205,12 @@ public: return TFlag ? 2 : 4; } +#ifdef ENABLE_GDBSTUB void RecordBreak(GDBStub::BreakpointAddress bkpt) { last_bkpt = bkpt; last_bkpt_hit = true; } +#endif void ServeBreak(); @@ -267,6 +275,8 @@ private: u32 exclusive_tag; // The address for which the local monitor is in exclusive access mode bool exclusive_state; +#ifdef ENABLE_GDBSTUB GDBStub::BreakpointAddress last_bkpt{}; bool last_bkpt_hit = false; +#endif }; diff --git a/src/core/core.cpp b/src/core/core.cpp index d0a6fc313..28af9f4f0 100644 --- a/src/core/core.cpp +++ b/src/core/core.cpp @@ -26,7 +26,9 @@ #include "core/dumping/backend.h" #include "core/file_sys/ncch_container.h" #include "core/frontend/image_interface.h" +#ifdef ENABLE_GDBSTUB #include "core/gdbstub/gdbstub.h" +#endif #include "core/global.h" #include "core/hle/kernel/ipc_debugger/recorder.h" #include "core/hle/kernel/kernel.h" @@ -83,6 +85,7 @@ System::ResultStatus System::RunLoop(bool tight_loop) { return ResultStatus::ErrorNotInitialized; } +#ifdef ENABLE_GDBSTUB if (GDBStub::IsServerEnabled()) { // The break flag is only set if GDB is connected, // we can do clearing here safely. If it is ever @@ -92,6 +95,7 @@ System::ResultStatus System::RunLoop(bool tight_loop) { } GDBStub::HandlePacket(*this); } +#endif Signal signal{Signal::None}; u32 param{}; @@ -561,7 +565,9 @@ System::ResultStatus System::Init(Frontend::EmuWindow& emu_window, app_loader->ReadProgramId(loading_title_id); HW::AES::InitKeys(); Service::Init(*this, loading_title_id, lle_modules, !app_loader->DoingInitialSetup()); +#ifdef ENABLE_GDBSTUB GDBStub::DeferStart(); +#endif if (!registered_image_interface) { registered_image_interface = std::make_shared(); @@ -686,7 +692,9 @@ void System::Shutdown(bool is_deserializing) { gpu.reset(); if (!is_deserializing) { lle_modules.clear(); +#ifdef ENABLE_GDBSTUB GDBStub::Shutdown(); +#endif perf_stats.reset(); app_loader.reset(); } @@ -749,8 +757,10 @@ void System::Reset() { } void System::ApplySettings() { +#ifdef ENABLE_GDBSTUB GDBStub::SetServerPort(Settings::values.gdbstub_port.GetValue()); GDBStub::ToggleServer(Settings::values.use_gdbstub.GetValue()); +#endif if (gpu) { #ifndef ANDROID diff --git a/src/core/gdbstub/gdbstub.cpp b/src/core/gdbstub/gdbstub.cpp index 9189c3a69..017677606 100644 --- a/src/core/gdbstub/gdbstub.cpp +++ b/src/core/gdbstub/gdbstub.cpp @@ -43,10 +43,12 @@ #include "core/loader/loader.h" #include "core/memory.h" -#pragma optimize("", off) +#ifndef ENABLE_GDBSTUB +#error "File was compiled with GDB stub support disabled" +#endif // Uncomment to log all GDB traffic -#define PRINT_GDB_TRAFFIC +// #define PRINT_GDB_TRAFFIC namespace GDBStub { namespace { @@ -1700,9 +1702,6 @@ static void Init(u16 port) { } SetNonBlock(accept_socket, true); - - // Wait for gdb to connect - LOG_INFO(Debug_GDBStub, "Waiting for gdb to connect...\n"); } void Init() { diff --git a/src/core/gdbstub/gdbstub.h b/src/core/gdbstub/gdbstub.h index fec95d5aa..0fd3c7c00 100644 --- a/src/core/gdbstub/gdbstub.h +++ b/src/core/gdbstub/gdbstub.h @@ -14,6 +14,10 @@ #include "common/common_types.h" #include "core/hle/kernel/thread.h" +#ifndef ENABLE_GDBSTUB +#error "File was included with GDB stub support disabled" +#endif + namespace Core { class System; } diff --git a/src/core/gdbstub/hio.cpp b/src/core/gdbstub/hio.cpp index 2d6c8058a..8a8a7adc6 100644 --- a/src/core/gdbstub/hio.cpp +++ b/src/core/gdbstub/hio.cpp @@ -9,6 +9,10 @@ #include "core/gdbstub/gdbstub.h" #include "core/gdbstub/hio.h" +#ifndef ENABLE_GDBSTUB +#error "File was compiled with GDB stub support disabled" +#endif + #ifndef SIGTRAP constexpr u32 SIGTRAP = 5; #endif diff --git a/src/core/gdbstub/hio.h b/src/core/gdbstub/hio.h index 5fe366bb4..066bef55a 100644 --- a/src/core/gdbstub/hio.h +++ b/src/core/gdbstub/hio.h @@ -6,6 +6,10 @@ #include "common/common_types.h" +#ifndef ENABLE_GDBSTUB +#error "File was included with GDB stub support disabled" +#endif + namespace Core { class System; } diff --git a/src/core/hle/kernel/process.cpp b/src/core/hle/kernel/process.cpp index 32d9a46cd..b895a1f13 100644 --- a/src/core/hle/kernel/process.cpp +++ b/src/core/hle/kernel/process.cpp @@ -16,7 +16,9 @@ #include "common/logging/log.h" #include "common/serialization/boost_vector.hpp" #include "core/core.h" +#ifdef ENABLE_GDBSTUB #include "core/gdbstub/gdbstub.h" +#endif #include "core/hle/kernel/errors.h" #include "core/hle/kernel/memory.h" #include "core/hle/kernel/process.h" @@ -265,16 +267,20 @@ void Process::Run(s32 main_thread_priority, u32 stack_size) { // Pause process at start if flag enabled and we are not a sysmodule if (Core::System::GetInstance().GetDebugNextProcessFlag() && resource_limit->GetCategory() != Kernel::ResourceLimitCategory::Other) { +#ifdef ENABLE_GDBSTUB if (GDBStub::IsServerEnabled()) { LOG_INFO(Loader, "Pausing process {} at start", process_id); SetDebugBreak(true); } +#endif Core::System::GetInstance().ClearDebugNextProcessFlag(); } } void Process::Exit() { +#ifdef ENABLE_GDBSTUB GDBStub::OnProcessExit(process_id); +#endif auto plgldr = Service::PLGLDR::GetService(Core::System::GetInstance()); if (plgldr) { diff --git a/src/core/hle/kernel/svc.cpp b/src/core/hle/kernel/svc.cpp index a02e91427..7392de779 100644 --- a/src/core/hle/kernel/svc.cpp +++ b/src/core/hle/kernel/svc.cpp @@ -14,7 +14,9 @@ #include "core/arm/arm_interface.h" #include "core/core.h" #include "core/core_timing.h" +#ifdef ENABLE_GDBSTUB #include "core/gdbstub/hio.h" +#endif #include "core/hle/kernel/address_arbiter.h" #include "core/hle/kernel/client_port.h" #include "core/hle/kernel/client_session.h" @@ -1171,7 +1173,9 @@ void SVC::OutputDebugString(VAddr address, s32 len) { } if (len == 0) { +#ifdef ENABLE_GDBSTUB GDBStub::SetHioRequest(system, kernel.GetCurrentProcess().get(), address); +#endif return; } diff --git a/src/core/hle/kernel/thread.cpp b/src/core/hle/kernel/thread.cpp index 73fced736..5f982c9e6 100644 --- a/src/core/hle/kernel/thread.cpp +++ b/src/core/hle/kernel/thread.cpp @@ -17,6 +17,9 @@ #include "core/arm/arm_interface.h" #include "core/arm/skyeye_common/armstate.h" #include "core/core.h" +#ifdef ENABLE_GDBSTUB +#include "core/gdbstub/gdbstub.h" +#endif #include "core/hle/kernel/errors.h" #include "core/hle/kernel/kernel.h" #include "core/hle/kernel/mutex.h" @@ -135,7 +138,9 @@ void Thread::Stop() { process->resource_limit->Release(ResourceLimitType::Thread, 1); } +#ifdef ENABLE_GDBSTUB GDBStub::OnThreadExit(thread_id); +#endif } void ThreadManager::SwitchContext(Thread* new_thread) { diff --git a/src/core/memory.cpp b/src/core/memory.cpp index 47416ab87..d96e8651f 100644 --- a/src/core/memory.cpp +++ b/src/core/memory.cpp @@ -17,7 +17,9 @@ #include "common/swap.h" #include "core/arm/arm_interface.h" #include "core/core.h" +#ifdef ENABLE_GDBSTUB #include "core/gdbstub/gdbstub.h" +#endif #include "core/global.h" #include "core/hle/kernel/process.h" #include "core/hle/service/plgldr/plgldr.h" @@ -569,9 +571,12 @@ T MemorySystem::UnmappedAccess(const VAddr vaddr, const T value, bool read) { const std::string value_str = read ? std::string("") : fmt::format(" 0x{:08X}", value); const std::string message = fmt::format("unmapped {}{}{} @ 0x{:08X} at PC 0x{:08X}", mode, sizeof(T) * 8, value_str, vaddr, impl->GetPC()); +#ifdef ENABLE_GDBSTUB if (GDBStub::IsConnected()) { GDBStub::Break(SIGSEGV); - } else if (Settings::values.break_on_unmapped_memory_access) { + } else +#endif + if (Settings::values.break_on_unmapped_memory_access) { impl->system.SetStatus(Core::System::ResultStatus::ErrorMemoryExceptionRaised, message.c_str()); } @@ -621,9 +626,11 @@ T MemorySystem::Read(const std::shared_ptr& page_table, const VAddr v T value; std::memcpy(&value, it->second.memory.GetPtr() + (vaddr & CITRA_PAGE_MASK), sizeof(T)); +#ifdef ENABLE_GDBSTUB if (GDBStub::CheckBreakpoint(vaddr, sizeof(T), GDBStub::BreakpointType::Read)) { GDBStub::Break(SIGTRAP); } +#endif return value; } @@ -640,9 +647,11 @@ T MemorySystem::Read(const std::shared_ptr& page_table, const VAddr v T value; std::memcpy(&value, GetPointerForRasterizerCache(vaddr), sizeof(T)); +#ifdef ENABLE_GDBSTUB if (GDBStub::CheckBreakpoint(vaddr, sizeof(T), GDBStub::BreakpointType::Read)) { GDBStub::Break(SIGTRAP); } +#endif return value; } @@ -695,9 +704,11 @@ void MemorySystem::Write(const std::shared_ptr& page_table, const VAd std::memcpy(it->second.memory.GetPtr() + (vaddr & CITRA_PAGE_MASK), &data, sizeof(T)); +#ifdef ENABLE_GDBSTUB if (GDBStub::CheckBreakpoint(vaddr, sizeof(T), GDBStub::BreakpointType::Write)) { GDBStub::Break(SIGTRAP); } +#endif break; } @@ -710,9 +721,11 @@ void MemorySystem::Write(const std::shared_ptr& page_table, const VAd RasterizerFlushVirtualRegion(vaddr, sizeof(T), FlushMode::Invalidate); std::memcpy(GetPointerForRasterizerCache(vaddr), &data, sizeof(T)); +#ifdef ENABLE_GDBSTUB if (GDBStub::CheckBreakpoint(vaddr, sizeof(T), GDBStub::BreakpointType::Write)) { GDBStub::Break(SIGTRAP); } +#endif break; } @@ -749,9 +762,11 @@ bool MemorySystem::WriteExclusive(const VAddr vaddr, const T data, const T expec bool ret = Common::AtomicCompareAndSwap(volatile_pointer, data, expected); +#ifdef ENABLE_GDBSTUB if (GDBStub::CheckBreakpoint(vaddr, sizeof(T), GDBStub::BreakpointType::Write)) { GDBStub::Break(SIGTRAP); } +#endif return ret; } @@ -766,9 +781,11 @@ bool MemorySystem::WriteExclusive(const VAddr vaddr, const T data, const T expec const auto volatile_pointer = reinterpret_cast(GetPointerForRasterizerCache(vaddr).GetPtr()); +#ifdef ENABLE_GDBSTUB if (GDBStub::CheckBreakpoint(vaddr, sizeof(T), GDBStub::BreakpointType::Write)) { GDBStub::Break(SIGTRAP); } +#endif return Common::AtomicCompareAndSwap(volatile_pointer, data, expected); }