diff --git a/src/core/CMakeLists.txt b/src/core/CMakeLists.txt
index e370fd225..66de33799 100644
--- a/src/core/CMakeLists.txt
+++ b/src/core/CMakeLists.txt
@@ -135,8 +135,6 @@ add_library(core STATIC
     frontend/framebuffer_layout.cpp
     frontend/framebuffer_layout.h
     frontend/input.h
-    gdbstub/gdbstub.cpp
-    gdbstub/gdbstub.h
     hardware_interrupt_manager.cpp
     hardware_interrupt_manager.h
     hle/ipc.h
diff --git a/src/core/arm/dynarmic/arm_dynarmic_64.cpp b/src/core/arm/dynarmic/arm_dynarmic_64.cpp
index 9f170a224..5c2060d78 100644
--- a/src/core/arm/dynarmic/arm_dynarmic_64.cpp
+++ b/src/core/arm/dynarmic/arm_dynarmic_64.cpp
@@ -14,7 +14,6 @@
 #include "core/arm/dynarmic/arm_exclusive_monitor.h"
 #include "core/core.h"
 #include "core/core_timing.h"
-#include "core/gdbstub/gdbstub.h"
 #include "core/hardware_properties.h"
 #include "core/hle/kernel/process.h"
 #include "core/hle/kernel/scheduler.h"
@@ -96,16 +95,6 @@ public:
         case Dynarmic::A64::Exception::Yield:
             return;
         case Dynarmic::A64::Exception::Breakpoint:
-            if (GDBStub::IsServerEnabled()) {
-                parent.jit->HaltExecution();
-                parent.SetPC(pc);
-                Kernel::Thread* const thread = parent.system.CurrentScheduler().GetCurrentThread();
-                parent.SaveContext(thread->GetContext64());
-                GDBStub::Break();
-                GDBStub::SendTrap(thread, 5);
-                return;
-            }
-            [[fallthrough]];
         default:
             ASSERT_MSG(false, "ExceptionRaised(exception = {}, pc = {:08X}, code = {:08X})",
                        static_cast<std::size_t>(exception), pc, MemoryReadCode(pc));
diff --git a/src/core/core.cpp b/src/core/core.cpp
index 7ca3652af..f4bbc9ec3 100644
--- a/src/core/core.cpp
+++ b/src/core/core.cpp
@@ -25,7 +25,6 @@
 #include "core/file_sys/sdmc_factory.h"
 #include "core/file_sys/vfs_concat.h"
 #include "core/file_sys/vfs_real.h"
-#include "core/gdbstub/gdbstub.h"
 #include "core/hardware_interrupt_manager.h"
 #include "core/hle/kernel/client_port.h"
 #include "core/hle/kernel/kernel.h"
@@ -186,11 +185,8 @@ struct System::Impl {
         }
 
         service_manager = std::make_shared<Service::SM::ServiceManager>(kernel);
-
         services = std::make_unique<Service::Services>(service_manager, system);
-        GDBStub::DeferStart();
-
-        interrupt_manager = std::make_unique<Core::Hardware::InterruptManager>(system);
+        interrupt_manager = std::make_unique<Hardware::InterruptManager>(system);
 
         // Initialize time manager, which must happen after kernel is created
         time_manager.Initialize();
@@ -297,7 +293,6 @@ struct System::Impl {
         }
 
         // Shutdown emulation session
-        GDBStub::Shutdown();
         services.reset();
         service_manager.reset();
         cheat_engine.reset();
diff --git a/src/core/cpu_manager.cpp b/src/core/cpu_manager.cpp
index 100e90d82..eeeb6e8df 100644
--- a/src/core/cpu_manager.cpp
+++ b/src/core/cpu_manager.cpp
@@ -10,7 +10,6 @@
 #include "core/core.h"
 #include "core/core_timing.h"
 #include "core/cpu_manager.h"
-#include "core/gdbstub/gdbstub.h"
 #include "core/hle/kernel/kernel.h"
 #include "core/hle/kernel/physical_core.h"
 #include "core/hle/kernel/scheduler.h"
diff --git a/src/core/gdbstub/gdbstub.cpp b/src/core/gdbstub/gdbstub.cpp
deleted file mode 100644
index 97ee65464..000000000
--- a/src/core/gdbstub/gdbstub.cpp
+++ /dev/null
@@ -1,1397 +0,0 @@
-// Copyright 2013 Dolphin Emulator Project
-// Licensed under GPLv2+
-// Refer to the license.txt file included.
-
-// Originally written by Sven Peter <sven@fail0verflow.com> for anergistic.
-
-#include <algorithm>
-#include <atomic>
-#include <climits>
-#include <csignal>
-#include <cstdarg>
-#include <cstdio>
-#include <cstring>
-#include <map>
-#include <numeric>
-#include <fcntl.h>
-
-#ifdef _WIN32
-#include <winsock2.h>
-// winsock2.h needs to be included first to prevent winsock.h being included by other includes
-#include <io.h>
-#include <iphlpapi.h>
-#include <ws2tcpip.h>
-#define SHUT_RDWR 2
-#else
-#include <netinet/in.h>
-#include <sys/select.h>
-#include <sys/socket.h>
-#include <sys/un.h>
-#include <unistd.h>
-#endif
-
-#include "common/logging/log.h"
-#include "common/string_util.h"
-#include "common/swap.h"
-#include "core/arm/arm_interface.h"
-#include "core/core.h"
-#include "core/gdbstub/gdbstub.h"
-#include "core/hle/kernel/memory/page_table.h"
-#include "core/hle/kernel/process.h"
-#include "core/hle/kernel/scheduler.h"
-#include "core/loader/loader.h"
-#include "core/memory.h"
-
-namespace GDBStub {
-namespace {
-constexpr int GDB_BUFFER_SIZE = 10000;
-
-constexpr char GDB_STUB_START = '$';
-constexpr char GDB_STUB_END = '#';
-constexpr char GDB_STUB_ACK = '+';
-constexpr char GDB_STUB_NACK = '-';
-
-#ifndef SIGTRAP
-constexpr u32 SIGTRAP = 5;
-#endif
-
-#ifndef SIGTERM
-constexpr u32 SIGTERM = 15;
-#endif
-
-#ifndef MSG_WAITALL
-constexpr u32 MSG_WAITALL = 8;
-#endif
-
-constexpr u32 LR_REGISTER = 30;
-constexpr u32 SP_REGISTER = 31;
-constexpr u32 PC_REGISTER = 32;
-constexpr u32 PSTATE_REGISTER = 33;
-constexpr u32 UC_ARM64_REG_Q0 = 34;
-constexpr u32 FPCR_REGISTER = 66;
-
-// For sample XML files see the GDB source /gdb/features
-// GDB also wants the l character at the start
-// This XML defines what the registers are for this specific ARM device
-constexpr char target_xml[] =
-    R"(l<?xml version="1.0"?>
-<!DOCTYPE target SYSTEM "gdb-target.dtd">
-<target version="1.0">
-  <feature name="org.gnu.gdb.aarch64.core">
-    <reg name="x0" bitsize="64"/>
-    <reg name="x1" bitsize="64"/>
-    <reg name="x2" bitsize="64"/>
-    <reg name="x3" bitsize="64"/>
-    <reg name="x4" bitsize="64"/>
-    <reg name="x5" bitsize="64"/>
-    <reg name="x6" bitsize="64"/>
-    <reg name="x7" bitsize="64"/>
-    <reg name="x8" bitsize="64"/>
-    <reg name="x9" bitsize="64"/>
-    <reg name="x10" bitsize="64"/>
-    <reg name="x11" bitsize="64"/>
-    <reg name="x12" bitsize="64"/>
-    <reg name="x13" bitsize="64"/>
-    <reg name="x14" bitsize="64"/>
-    <reg name="x15" bitsize="64"/>
-    <reg name="x16" bitsize="64"/>
-    <reg name="x17" bitsize="64"/>
-    <reg name="x18" bitsize="64"/>
-    <reg name="x19" bitsize="64"/>
-    <reg name="x20" bitsize="64"/>
-    <reg name="x21" bitsize="64"/>
-    <reg name="x22" bitsize="64"/>
-    <reg name="x23" bitsize="64"/>
-    <reg name="x24" bitsize="64"/>
-    <reg name="x25" bitsize="64"/>
-    <reg name="x26" bitsize="64"/>
-    <reg name="x27" bitsize="64"/>
-    <reg name="x28" bitsize="64"/>
-    <reg name="x29" bitsize="64"/>
-    <reg name="x30" bitsize="64"/>
-    <reg name="sp" bitsize="64" type="data_ptr"/>
-
-    <reg name="pc" bitsize="64" type="code_ptr"/>
-
-    <flags id="pstate_flags" size="4">
-      <field name="SP" start="0" end="0"/>
-      <field name="" start="1" end="1"/>
-      <field name="EL" start="2" end="3"/>
-      <field name="nRW" start="4" end="4"/>
-      <field name="" start="5" end="5"/>
-      <field name="F" start="6" end="6"/>
-      <field name="I" start="7" end="7"/>
-      <field name="A" start="8" end="8"/>
-      <field name="D" start="9" end="9"/>
-
-      <field name="IL" start="20" end="20"/>
-      <field name="SS" start="21" end="21"/>
-
-      <field name="V" start="28" end="28"/>
-      <field name="C" start="29" end="29"/>
-      <field name="Z" start="30" end="30"/>
-      <field name="N" start="31" end="31"/>
-    </flags>
-    <reg name="pstate" bitsize="32" type="pstate_flags"/>
-  </feature>
-  <feature name="org.gnu.gdb.aarch64.fpu">
-  </feature>
-</target>
-)";
-
-int gdbserver_socket = -1;
-bool defer_start = false;
-
-u8 command_buffer[GDB_BUFFER_SIZE];
-u32 command_length;
-
-u32 latest_signal = 0;
-bool memory_break = false;
-
-Kernel::Thread* current_thread = nullptr;
-u32 current_core = 0;
-
-// Binding to a port within the reserved ports range (0-1023) requires root permissions,
-// so default to a port outside of that range.
-u16 gdbstub_port = 24689;
-
-bool halt_loop = true;
-bool step_loop = false;
-bool send_trap = false;
-
-// If set to false, the server will never be started and no
-// gdbstub-related functions will be executed.
-std::atomic<bool> server_enabled(false);
-
-#ifdef _WIN32
-WSADATA InitData;
-#endif
-
-struct Breakpoint {
-    bool active;
-    VAddr addr;
-    u64 len;
-    std::array<u8, 4> inst;
-};
-
-using BreakpointMap = std::map<VAddr, Breakpoint>;
-BreakpointMap breakpoints_execute;
-BreakpointMap breakpoints_read;
-BreakpointMap breakpoints_write;
-
-struct Module {
-    std::string name;
-    VAddr beg;
-    VAddr end;
-};
-
-std::vector<Module> modules;
-} // Anonymous namespace
-
-void RegisterModule(std::string name, VAddr beg, VAddr end, bool add_elf_ext) {
-    Module module;
-    if (add_elf_ext) {
-        Common::SplitPath(name, nullptr, &module.name, nullptr);
-        module.name += ".elf";
-    } else {
-        module.name = std::move(name);
-    }
-    module.beg = beg;
-    module.end = end;
-    modules.push_back(std::move(module));
-}
-
-static Kernel::Thread* FindThreadById(s64 id) {
-    const auto& threads = Core::System::GetInstance().GlobalScheduler().GetThreadList();
-    for (auto& thread : threads) {
-        if (thread->GetThreadID() == static_cast<u64>(id)) {
-            current_core = thread->GetProcessorID();
-            return thread.get();
-        }
-    }
-    return nullptr;
-}
-
-static u64 RegRead(std::size_t id, Kernel::Thread* thread = nullptr) {
-    if (!thread) {
-        return 0;
-    }
-
-    const auto& thread_context = thread->GetContext64();
-
-    if (id < SP_REGISTER) {
-        return thread_context.cpu_registers[id];
-    } else if (id == SP_REGISTER) {
-        return thread_context.sp;
-    } else if (id == PC_REGISTER) {
-        return thread_context.pc;
-    } else if (id == PSTATE_REGISTER) {
-        return thread_context.pstate;
-    } else if (id > PSTATE_REGISTER && id < FPCR_REGISTER) {
-        return thread_context.vector_registers[id - UC_ARM64_REG_Q0][0];
-    } else {
-        return 0;
-    }
-}
-
-static void RegWrite(std::size_t id, u64 val, Kernel::Thread* thread = nullptr) {
-    if (!thread) {
-        return;
-    }
-
-    auto& thread_context = thread->GetContext64();
-
-    if (id < SP_REGISTER) {
-        thread_context.cpu_registers[id] = val;
-    } else if (id == SP_REGISTER) {
-        thread_context.sp = val;
-    } else if (id == PC_REGISTER) {
-        thread_context.pc = val;
-    } else if (id == PSTATE_REGISTER) {
-        thread_context.pstate = static_cast<u32>(val);
-    } else if (id > PSTATE_REGISTER && id < FPCR_REGISTER) {
-        thread_context.vector_registers[id - (PSTATE_REGISTER + 1)][0] = val;
-    }
-}
-
-static u128 FpuRead(std::size_t id, Kernel::Thread* thread = nullptr) {
-    if (!thread) {
-        return u128{0};
-    }
-
-    auto& thread_context = thread->GetContext64();
-
-    if (id >= UC_ARM64_REG_Q0 && id < FPCR_REGISTER) {
-        return thread_context.vector_registers[id - UC_ARM64_REG_Q0];
-    } else if (id == FPCR_REGISTER) {
-        return u128{thread_context.fpcr, 0};
-    } else {
-        return u128{0};
-    }
-}
-
-static void FpuWrite(std::size_t id, u128 val, Kernel::Thread* thread = nullptr) {
-    if (!thread) {
-        return;
-    }
-
-    auto& thread_context = thread->GetContext64();
-
-    if (id >= UC_ARM64_REG_Q0 && id < FPCR_REGISTER) {
-        thread_context.vector_registers[id - UC_ARM64_REG_Q0] = val;
-    } else if (id == FPCR_REGISTER) {
-        thread_context.fpcr = static_cast<u32>(val[0]);
-    }
-}
-
-/**
- * Turns hex string character into the equivalent byte.
- *
- * @param hex Input hex character to be turned into byte.
- */
-static u8 HexCharToValue(u8 hex) {
-    if (hex >= '0' && hex <= '9') {
-        return static_cast<u8>(hex - '0');
-    } else if (hex >= 'a' && hex <= 'f') {
-        return static_cast<u8>(hex - 'a' + 0xA);
-    } else if (hex >= 'A' && hex <= 'F') {
-        return static_cast<u8>(hex - 'A' + 0xA);
-    }
-
-    LOG_ERROR(Debug_GDBStub, "Invalid nibble: {} ({:02X})", hex, hex);
-    return 0;
-}
-
-/**
- * Turn nibble of byte into hex string character.
- *
- * @param n Nibble to be turned into hex character.
- */
-static u8 NibbleToHex(u8 n) {
-    n &= 0xF;
-    if (n < 0xA) {
-        return static_cast<u8>('0' + n);
-    } else {
-        return static_cast<u8>('a' + n - 0xA);
-    }
-}
-
-/**
- * Converts input hex string characters into an array of equivalent of u8 bytes.
- *
- * @param src Pointer to array of output hex string characters.
- * @param len Length of src array.
- */
-static u32 HexToInt(const u8* src, std::size_t len) {
-    u32 output = 0;
-    while (len-- > 0) {
-        output = (output << 4) | HexCharToValue(src[0]);
-        src++;
-    }
-    return output;
-}
-
-/**
- * Converts input hex string characters into an array of equivalent of u8 bytes.
- *
- * @param src Pointer to array of output hex string characters.
- * @param len Length of src array.
- */
-static u64 HexToLong(const u8* src, std::size_t len) {
-    u64 output = 0;
-    while (len-- > 0) {
-        output = (output << 4) | HexCharToValue(src[0]);
-        src++;
-    }
-    return output;
-}
-
-/**
- * Converts input array of u8 bytes into their equivalent hex string characters.
- *
- * @param dest Pointer to buffer to store output hex string characters.
- * @param src Pointer to array of u8 bytes.
- * @param len Length of src array.
- */
-static void MemToGdbHex(u8* dest, const u8* src, std::size_t len) {
-    while (len-- > 0) {
-        const u8 tmp = *src++;
-        *dest++ = NibbleToHex(static_cast<u8>(tmp >> 4));
-        *dest++ = NibbleToHex(tmp);
-    }
-}
-
-/**
- * Converts input gdb-formatted hex string characters into an array of equivalent of u8 bytes.
- *
- * @param dest Pointer to buffer to store u8 bytes.
- * @param src Pointer to array of output hex string characters.
- * @param len Length of src array.
- */
-static void GdbHexToMem(u8* dest, const u8* src, std::size_t len) {
-    while (len-- > 0) {
-        *dest++ = static_cast<u8>((HexCharToValue(src[0]) << 4) | HexCharToValue(src[1]));
-        src += 2;
-    }
-}
-
-/**
- * Convert a u32 into a gdb-formatted hex string.
- *
- * @param dest Pointer to buffer to store output hex string characters.
- * @param v    Value to convert.
- */
-static void IntToGdbHex(u8* dest, u32 v) {
-    for (int i = 0; i < 8; i += 2) {
-        dest[i + 1] = NibbleToHex(static_cast<u8>(v >> (4 * i)));
-        dest[i] = NibbleToHex(static_cast<u8>(v >> (4 * (i + 1))));
-    }
-}
-
-/**
- * Convert a u64 into a gdb-formatted hex string.
- *
- * @param dest Pointer to buffer to store output hex string characters.
- * @param v    Value to convert.
- */
-static void LongToGdbHex(u8* dest, u64 v) {
-    for (int i = 0; i < 16; i += 2) {
-        dest[i + 1] = NibbleToHex(static_cast<u8>(v >> (4 * i)));
-        dest[i] = NibbleToHex(static_cast<u8>(v >> (4 * (i + 1))));
-    }
-}
-
-/**
- * Convert a gdb-formatted hex string into a u32.
- *
- * @param src Pointer to hex string.
- */
-static u32 GdbHexToInt(const u8* src) {
-    u32 output = 0;
-
-    for (int i = 0; i < 8; i += 2) {
-        output = (output << 4) | HexCharToValue(src[7 - i - 1]);
-        output = (output << 4) | HexCharToValue(src[7 - i]);
-    }
-
-    return output;
-}
-
-/**
- * Convert a gdb-formatted hex string into a u64.
- *
- * @param src Pointer to hex string.
- */
-static u64 GdbHexToLong(const u8* src) {
-    u64 output = 0;
-
-    for (int i = 0; i < 16; i += 2) {
-        output = (output << 4) | HexCharToValue(src[15 - i - 1]);
-        output = (output << 4) | HexCharToValue(src[15 - i]);
-    }
-
-    return output;
-}
-
-/**
- * Convert a gdb-formatted hex string into a u128.
- *
- * @param src Pointer to hex string.
- */
-static u128 GdbHexToU128(const u8* src) {
-    u128 output;
-
-    for (int i = 0; i < 16; i += 2) {
-        output[0] = (output[0] << 4) | HexCharToValue(src[15 - i - 1]);
-        output[0] = (output[0] << 4) | HexCharToValue(src[15 - i]);
-    }
-
-    for (int i = 0; i < 16; i += 2) {
-        output[1] = (output[1] << 4) | HexCharToValue(src[16 + 15 - i - 1]);
-        output[1] = (output[1] << 4) | HexCharToValue(src[16 + 15 - i]);
-    }
-
-    return output;
-}
-
-/// Read a byte from the gdb client.
-static u8 ReadByte() {
-    u8 c;
-    std::size_t received_size = recv(gdbserver_socket, reinterpret_cast<char*>(&c), 1, MSG_WAITALL);
-    if (received_size != 1) {
-        LOG_ERROR(Debug_GDBStub, "recv failed: {}", received_size);
-        Shutdown();
-    }
-
-    return c;
-}
-
-/// Calculate the checksum of the current command buffer.
-static u8 CalculateChecksum(const u8* buffer, std::size_t length) {
-    return static_cast<u8>(std::accumulate(buffer, buffer + length, u8{0},
-                                           [](u8 lhs, u8 rhs) { return u8(lhs + rhs); }));
-}
-
-/**
- * Get the map of breakpoints for a given breakpoint type.
- *
- * @param type Type of breakpoint map.
- */
-static BreakpointMap& GetBreakpointMap(BreakpointType type) {
-    switch (type) {
-    case BreakpointType::Execute:
-        return breakpoints_execute;
-    case BreakpointType::Read:
-        return breakpoints_read;
-    case BreakpointType::Write:
-        return breakpoints_write;
-    default:
-        return breakpoints_read;
-    }
-}
-
-/**
- * Remove the breakpoint from the given address of the specified type.
- *
- * @param type Type of breakpoint.
- * @param addr Address of breakpoint.
- */
-static void RemoveBreakpoint(BreakpointType type, VAddr addr) {
-    BreakpointMap& p = GetBreakpointMap(type);
-
-    const auto bp = p.find(addr);
-    if (bp == p.end()) {
-        return;
-    }
-
-    LOG_DEBUG(Debug_GDBStub, "gdb: removed a breakpoint: {:016X} bytes at {:016X} of type {}",
-              bp->second.len, bp->second.addr, static_cast<int>(type));
-
-    if (type == BreakpointType::Execute) {
-        auto& system = Core::System::GetInstance();
-        system.Memory().WriteBlock(bp->second.addr, bp->second.inst.data(), bp->second.inst.size());
-        system.InvalidateCpuInstructionCaches();
-    }
-    p.erase(addr);
-}
-
-BreakpointAddress GetNextBreakpointFromAddress(VAddr addr, BreakpointType type) {
-    const BreakpointMap& p = GetBreakpointMap(type);
-    const auto next_breakpoint = p.lower_bound(addr);
-    BreakpointAddress breakpoint;
-
-    if (next_breakpoint != p.end()) {
-        breakpoint.address = next_breakpoint->first;
-        breakpoint.type = type;
-    } else {
-        breakpoint.address = 0;
-        breakpoint.type = BreakpointType::None;
-    }
-
-    return breakpoint;
-}
-
-bool CheckBreakpoint(VAddr addr, BreakpointType type) {
-    if (!IsConnected()) {
-        return false;
-    }
-
-    const BreakpointMap& p = GetBreakpointMap(type);
-    const auto bp = p.find(addr);
-
-    if (bp == p.end()) {
-        return false;
-    }
-
-    u64 len = bp->second.len;
-
-    // IDA Pro defaults to 4-byte breakpoints for all non-hardware breakpoints
-    // no matter if it's a 4-byte or 2-byte instruction. When you execute a
-    // Thumb instruction with a 4-byte breakpoint set, it will set a breakpoint on
-    // two instructions instead of the single instruction you placed the breakpoint
-    // on. So, as a way to make sure that execution breakpoints are only breaking
-    // on the instruction that was specified, set the length of an execution
-    // breakpoint to 1. This should be fine since the CPU should never begin executing
-    // an instruction anywhere except the beginning of the instruction.
-    if (type == BreakpointType::Execute) {
-        len = 1;
-    }
-
-    if (bp->second.active && (addr >= bp->second.addr && addr < bp->second.addr + len)) {
-        LOG_DEBUG(Debug_GDBStub,
-                  "Found breakpoint type {} @ {:016X}, range: {:016X}"
-                  " - {:016X} ({:X} bytes)",
-                  static_cast<int>(type), addr, bp->second.addr, bp->second.addr + len, len);
-        return true;
-    }
-
-    return false;
-}
-
-/**
- * Send packet to gdb client.
- *
- * @param packet Packet to be sent to client.
- */
-static void SendPacket(const char packet) {
-    std::size_t sent_size = send(gdbserver_socket, &packet, 1, 0);
-    if (sent_size != 1) {
-        LOG_ERROR(Debug_GDBStub, "send failed");
-    }
-}
-
-/**
- * Send reply to gdb client.
- *
- * @param reply Reply to be sent to client.
- */
-static void SendReply(const char* reply) {
-    if (!IsConnected()) {
-        return;
-    }
-
-    LOG_DEBUG(Debug_GDBStub, "Reply: {}", reply);
-
-    memset(command_buffer, 0, sizeof(command_buffer));
-
-    command_length = static_cast<u32>(strlen(reply));
-    if (command_length + 4 > sizeof(command_buffer)) {
-        LOG_ERROR(Debug_GDBStub, "command_buffer overflow in SendReply");
-        return;
-    }
-
-    memcpy(command_buffer + 1, reply, command_length);
-
-    const u8 checksum = CalculateChecksum(command_buffer, command_length + 1);
-    command_buffer[0] = GDB_STUB_START;
-    command_buffer[command_length + 1] = GDB_STUB_END;
-    command_buffer[command_length + 2] = NibbleToHex(static_cast<u8>(checksum >> 4));
-    command_buffer[command_length + 3] = NibbleToHex(checksum);
-
-    u8* ptr = command_buffer;
-    u32 left = command_length + 4;
-    while (left > 0) {
-        const auto sent_size = send(gdbserver_socket, reinterpret_cast<char*>(ptr), left, 0);
-        if (sent_size < 0) {
-            LOG_ERROR(Debug_GDBStub, "gdb: send failed");
-            return Shutdown();
-        }
-
-        left -= static_cast<u32>(sent_size);
-        ptr += sent_size;
-    }
-}
-
-/// Handle query command from gdb client.
-static void HandleQuery() {
-    LOG_DEBUG(Debug_GDBStub, "gdb: query '{}'", command_buffer + 1);
-
-    const char* query = reinterpret_cast<const char*>(command_buffer + 1);
-
-    if (strcmp(query, "TStatus") == 0) {
-        SendReply("T0");
-    } else if (strncmp(query, "Supported", strlen("Supported")) == 0) {
-        // PacketSize needs to be large enough for target xml
-        std::string buffer = "PacketSize=2000;qXfer:features:read+;qXfer:threads:read+";
-        if (!modules.empty()) {
-            buffer += ";qXfer:libraries:read+";
-        }
-        SendReply(buffer.c_str());
-    } else if (strncmp(query, "Xfer:features:read:target.xml:",
-                       strlen("Xfer:features:read:target.xml:")) == 0) {
-        SendReply(target_xml);
-    } else if (strncmp(query, "Offsets", strlen("Offsets")) == 0) {
-        const VAddr base_address =
-            Core::System::GetInstance().CurrentProcess()->PageTable().GetCodeRegionStart();
-        std::string buffer = fmt::format("TextSeg={:0x}", base_address);
-        SendReply(buffer.c_str());
-    } else if (strncmp(query, "fThreadInfo", strlen("fThreadInfo")) == 0) {
-        std::string val = "m";
-        const auto& threads = Core::System::GetInstance().GlobalScheduler().GetThreadList();
-        for (const auto& thread : threads) {
-            val += fmt::format("{:x},", thread->GetThreadID());
-        }
-        val.pop_back();
-        SendReply(val.c_str());
-    } else if (strncmp(query, "sThreadInfo", strlen("sThreadInfo")) == 0) {
-        SendReply("l");
-    } else if (strncmp(query, "Xfer:threads:read", strlen("Xfer:threads:read")) == 0) {
-        std::string buffer;
-        buffer += "l<?xml version=\"1.0\"?>";
-        buffer += "<threads>";
-        const auto& threads = Core::System::GetInstance().GlobalScheduler().GetThreadList();
-        for (const auto& thread : threads) {
-            buffer +=
-                fmt::format(R"*(<thread id="{:x}" core="{:d}" name="Thread {:x}"></thread>)*",
-                            thread->GetThreadID(), thread->GetProcessorID(), thread->GetThreadID());
-        }
-        buffer += "</threads>";
-        SendReply(buffer.c_str());
-    } else if (strncmp(query, "Xfer:libraries:read", strlen("Xfer:libraries:read")) == 0) {
-        std::string buffer;
-        buffer += "l<?xml version=\"1.0\"?>";
-        buffer += "<library-list>";
-        for (const auto& module : modules) {
-            buffer +=
-                fmt::format(R"*("<library name = "{}"><segment address = "0x{:x}"/></library>)*",
-                            module.name, module.beg);
-        }
-        buffer += "</library-list>";
-        SendReply(buffer.c_str());
-    } else {
-        SendReply("");
-    }
-}
-
-/// Handle set thread command from gdb client.
-static void HandleSetThread() {
-    int thread_id = -1;
-    if (command_buffer[2] != '-') {
-        thread_id = static_cast<int>(HexToInt(command_buffer + 2, command_length - 2));
-    }
-    if (thread_id >= 1) {
-        current_thread = FindThreadById(thread_id);
-    }
-    if (!current_thread) {
-        thread_id = 1;
-        current_thread = FindThreadById(thread_id);
-    }
-    if (current_thread) {
-        SendReply("OK");
-        return;
-    }
-    SendReply("E01");
-}
-
-/// Handle thread alive command from gdb client.
-static void HandleThreadAlive() {
-    int thread_id = static_cast<int>(HexToInt(command_buffer + 1, command_length - 1));
-    if (thread_id == 0) {
-        thread_id = 1;
-    }
-    if (FindThreadById(thread_id)) {
-        SendReply("OK");
-        return;
-    }
-    SendReply("E01");
-}
-
-/**
- * Send signal packet to client.
- *
- * @param signal Signal to be sent to client.
- */
-static void SendSignal(Kernel::Thread* thread, u32 signal, bool full = true) {
-    if (gdbserver_socket == -1) {
-        return;
-    }
-
-    latest_signal = signal;
-
-    if (!thread) {
-        full = false;
-    }
-
-    std::string buffer;
-    if (full) {
-        buffer = fmt::format("T{:02x}{:02x}:{:016x};{:02x}:{:016x};{:02x}:{:016x}", latest_signal,
-                             PC_REGISTER, Common::swap64(RegRead(PC_REGISTER, thread)), SP_REGISTER,
-                             Common::swap64(RegRead(SP_REGISTER, thread)), LR_REGISTER,
-                             Common::swap64(RegRead(LR_REGISTER, thread)));
-    } else {
-        buffer = fmt::format("T{:02x}", latest_signal);
-    }
-
-    if (thread) {
-        buffer += fmt::format(";thread:{:x};", thread->GetThreadID());
-    }
-
-    SendReply(buffer.c_str());
-}
-
-/// Read command from gdb client.
-static void ReadCommand() {
-    command_length = 0;
-    memset(command_buffer, 0, sizeof(command_buffer));
-
-    u8 c = ReadByte();
-    if (c == '+') {
-        // ignore ack
-        return;
-    } else if (c == 0x03) {
-        LOG_INFO(Debug_GDBStub, "gdb: found break command");
-        halt_loop = true;
-        SendSignal(current_thread, SIGTRAP);
-        return;
-    } else if (c != GDB_STUB_START) {
-        LOG_DEBUG(Debug_GDBStub, "gdb: read invalid byte {:02X}", c);
-        return;
-    }
-
-    while ((c = ReadByte()) != GDB_STUB_END) {
-        if (command_length >= sizeof(command_buffer)) {
-            LOG_ERROR(Debug_GDBStub, "gdb: command_buffer overflow");
-            SendPacket(GDB_STUB_NACK);
-            return;
-        }
-        command_buffer[command_length++] = c;
-    }
-
-    auto checksum_received = static_cast<u32>(HexCharToValue(ReadByte()) << 4);
-    checksum_received |= static_cast<u32>(HexCharToValue(ReadByte()));
-
-    const u32 checksum_calculated = CalculateChecksum(command_buffer, command_length);
-
-    if (checksum_received != checksum_calculated) {
-        LOG_ERROR(Debug_GDBStub,
-                  "gdb: invalid checksum: calculated {:02X} and read {:02X} for ${}# (length: {})",
-                  checksum_calculated, checksum_received, command_buffer, command_length);
-
-        command_length = 0;
-
-        SendPacket(GDB_STUB_NACK);
-        return;
-    }
-
-    SendPacket(GDB_STUB_ACK);
-}
-
-/// Check if there is data to be read from the gdb client.
-static bool IsDataAvailable() {
-    if (!IsConnected()) {
-        return false;
-    }
-
-    fd_set fd_socket;
-
-    FD_ZERO(&fd_socket);
-    FD_SET(static_cast<u32>(gdbserver_socket), &fd_socket);
-
-    struct timeval t;
-    t.tv_sec = 0;
-    t.tv_usec = 0;
-
-    if (select(gdbserver_socket + 1, &fd_socket, nullptr, nullptr, &t) < 0) {
-        LOG_ERROR(Debug_GDBStub, "select failed");
-        return false;
-    }
-
-    return FD_ISSET(gdbserver_socket, &fd_socket) != 0;
-}
-
-/// Send requested register to gdb client.
-static void ReadRegister() {
-    static u8 reply[64];
-    memset(reply, 0, sizeof(reply));
-
-    u32 id = HexCharToValue(command_buffer[1]);
-    if (command_buffer[2] != '\0') {
-        id <<= 4;
-        id |= HexCharToValue(command_buffer[2]);
-    }
-
-    if (id <= SP_REGISTER) {
-        LongToGdbHex(reply, RegRead(id, current_thread));
-    } else if (id == PC_REGISTER) {
-        LongToGdbHex(reply, RegRead(id, current_thread));
-    } else if (id == PSTATE_REGISTER) {
-        IntToGdbHex(reply, static_cast<u32>(RegRead(id, current_thread)));
-    } else if (id >= UC_ARM64_REG_Q0 && id < FPCR_REGISTER) {
-        u128 r = FpuRead(id, current_thread);
-        LongToGdbHex(reply, r[0]);
-        LongToGdbHex(reply + 16, r[1]);
-    } else if (id == FPCR_REGISTER) {
-        u128 r = FpuRead(id, current_thread);
-        IntToGdbHex(reply, static_cast<u32>(r[0]));
-    } else if (id == FPCR_REGISTER + 1) {
-        u128 r = FpuRead(id, current_thread);
-        IntToGdbHex(reply, static_cast<u32>(r[0] >> 32));
-    }
-
-    SendReply(reinterpret_cast<char*>(reply));
-}
-
-/// Send all registers to the gdb client.
-static void ReadRegisters() {
-    static u8 buffer[GDB_BUFFER_SIZE - 4];
-    memset(buffer, 0, sizeof(buffer));
-
-    u8* bufptr = buffer;
-
-    for (u32 reg = 0; reg <= SP_REGISTER; reg++) {
-        LongToGdbHex(bufptr + reg * 16, RegRead(reg, current_thread));
-    }
-
-    bufptr += 32 * 16;
-
-    LongToGdbHex(bufptr, RegRead(PC_REGISTER, current_thread));
-
-    bufptr += 16;
-
-    IntToGdbHex(bufptr, static_cast<u32>(RegRead(PSTATE_REGISTER, current_thread)));
-
-    bufptr += 8;
-
-    u128 r;
-
-    for (u32 reg = UC_ARM64_REG_Q0; reg < FPCR_REGISTER; reg++) {
-        r = FpuRead(reg, current_thread);
-        LongToGdbHex(bufptr + reg * 32, r[0]);
-        LongToGdbHex(bufptr + reg * 32 + 16, r[1]);
-    }
-
-    bufptr += 32 * 32;
-
-    r = FpuRead(FPCR_REGISTER, current_thread);
-    IntToGdbHex(bufptr, static_cast<u32>(r[0]));
-
-    bufptr += 8;
-
-    SendReply(reinterpret_cast<char*>(buffer));
-}
-
-/// Modify data of register specified by gdb client.
-static void WriteRegister() {
-    const u8* buffer_ptr = command_buffer + 3;
-
-    u32 id = HexCharToValue(command_buffer[1]);
-    if (command_buffer[2] != '=') {
-        ++buffer_ptr;
-        id <<= 4;
-        id |= HexCharToValue(command_buffer[2]);
-    }
-
-    if (id <= SP_REGISTER) {
-        RegWrite(id, GdbHexToLong(buffer_ptr), current_thread);
-    } else if (id == PC_REGISTER) {
-        RegWrite(id, GdbHexToLong(buffer_ptr), current_thread);
-    } else if (id == PSTATE_REGISTER) {
-        RegWrite(id, GdbHexToInt(buffer_ptr), current_thread);
-    } else if (id >= UC_ARM64_REG_Q0 && id < FPCR_REGISTER) {
-        FpuWrite(id, GdbHexToU128(buffer_ptr), current_thread);
-    } else if (id == FPCR_REGISTER) {
-    } else if (id == FPCR_REGISTER + 1) {
-    }
-
-    // Update ARM context, skipping scheduler - no running threads at this point
-    Core::System::GetInstance()
-        .ArmInterface(current_core)
-        .LoadContext(current_thread->GetContext64());
-
-    SendReply("OK");
-}
-
-/// Modify all registers with data received from the client.
-static void WriteRegisters() {
-    const u8* buffer_ptr = command_buffer + 1;
-
-    if (command_buffer[0] != 'G')
-        return SendReply("E01");
-
-    for (u32 i = 0, reg = 0; reg <= FPCR_REGISTER; i++, reg++) {
-        if (reg <= SP_REGISTER) {
-            RegWrite(reg, GdbHexToLong(buffer_ptr + i * 16), current_thread);
-        } else if (reg == PC_REGISTER) {
-            RegWrite(PC_REGISTER, GdbHexToLong(buffer_ptr + i * 16), current_thread);
-        } else if (reg == PSTATE_REGISTER) {
-            RegWrite(PSTATE_REGISTER, GdbHexToInt(buffer_ptr + i * 16), current_thread);
-        } else if (reg >= UC_ARM64_REG_Q0 && reg < FPCR_REGISTER) {
-            RegWrite(reg, GdbHexToLong(buffer_ptr + i * 16), current_thread);
-        } else if (reg == FPCR_REGISTER) {
-            RegWrite(FPCR_REGISTER, GdbHexToLong(buffer_ptr + i * 16), current_thread);
-        } else if (reg == FPCR_REGISTER + 1) {
-            RegWrite(FPCR_REGISTER, GdbHexToLong(buffer_ptr + i * 16), current_thread);
-        }
-    }
-
-    // Update ARM context, skipping scheduler - no running threads at this point
-    Core::System::GetInstance()
-        .ArmInterface(current_core)
-        .LoadContext(current_thread->GetContext64());
-
-    SendReply("OK");
-}
-
-/// Read location in memory specified by gdb client.
-static void ReadMemory() {
-    static u8 reply[GDB_BUFFER_SIZE - 4];
-
-    auto start_offset = command_buffer + 1;
-    const auto addr_pos = std::find(start_offset, command_buffer + command_length, ',');
-    const VAddr addr = HexToLong(start_offset, static_cast<u64>(addr_pos - start_offset));
-
-    start_offset = addr_pos + 1;
-    const u64 len =
-        HexToLong(start_offset, static_cast<u64>((command_buffer + command_length) - start_offset));
-
-    LOG_DEBUG(Debug_GDBStub, "gdb: addr: {:016X} len: {:016X}", addr, len);
-
-    if (len * 2 > sizeof(reply)) {
-        SendReply("E01");
-    }
-
-    auto& memory = Core::System::GetInstance().Memory();
-    if (!memory.IsValidVirtualAddress(addr)) {
-        return SendReply("E00");
-    }
-
-    std::vector<u8> data(len);
-    memory.ReadBlock(addr, data.data(), len);
-
-    MemToGdbHex(reply, data.data(), len);
-    reply[len * 2] = '\0';
-    SendReply(reinterpret_cast<char*>(reply));
-}
-
-/// Modify location in memory with data received from the gdb client.
-static void WriteMemory() {
-    auto start_offset = command_buffer + 1;
-    const auto addr_pos = std::find(start_offset, command_buffer + command_length, ',');
-    const VAddr addr = HexToLong(start_offset, static_cast<u64>(addr_pos - start_offset));
-
-    start_offset = addr_pos + 1;
-    const auto len_pos = std::find(start_offset, command_buffer + command_length, ':');
-    const u64 len = HexToLong(start_offset, static_cast<u64>(len_pos - start_offset));
-
-    auto& system = Core::System::GetInstance();
-    auto& memory = system.Memory();
-    if (!memory.IsValidVirtualAddress(addr)) {
-        return SendReply("E00");
-    }
-
-    std::vector<u8> data(len);
-    GdbHexToMem(data.data(), len_pos + 1, len);
-    memory.WriteBlock(addr, data.data(), len);
-    system.InvalidateCpuInstructionCaches();
-    SendReply("OK");
-}
-
-void Break(bool is_memory_break) {
-    send_trap = true;
-
-    memory_break = is_memory_break;
-}
-
-/// Tell the CPU that it should perform a single step.
-static void Step() {
-    if (command_length > 1) {
-        RegWrite(PC_REGISTER, GdbHexToLong(command_buffer + 1), current_thread);
-        // Update ARM context, skipping scheduler - no running threads at this point
-        Core::System::GetInstance()
-            .ArmInterface(current_core)
-            .LoadContext(current_thread->GetContext64());
-    }
-    step_loop = true;
-    halt_loop = true;
-    send_trap = true;
-    Core::System::GetInstance().InvalidateCpuInstructionCaches();
-}
-
-/// Tell the CPU if we hit a memory breakpoint.
-bool IsMemoryBreak() {
-    if (!IsConnected()) {
-        return false;
-    }
-
-    return memory_break;
-}
-
-/// Tell the CPU to continue executing.
-static void Continue() {
-    memory_break = false;
-    step_loop = false;
-    halt_loop = false;
-    Core::System::GetInstance().InvalidateCpuInstructionCaches();
-}
-
-/**
- * Commit breakpoint to list of breakpoints.
- *
- * @param type Type of breakpoint.
- * @param addr Address of breakpoint.
- * @param len Length of breakpoint.
- */
-static bool CommitBreakpoint(BreakpointType type, VAddr addr, u64 len) {
-    BreakpointMap& p = GetBreakpointMap(type);
-
-    Breakpoint breakpoint;
-    breakpoint.active = true;
-    breakpoint.addr = addr;
-    breakpoint.len = len;
-
-    auto& system = Core::System::GetInstance();
-    auto& memory = system.Memory();
-    memory.ReadBlock(addr, breakpoint.inst.data(), breakpoint.inst.size());
-
-    static constexpr std::array<u8, 4> btrap{0x00, 0x7d, 0x20, 0xd4};
-    if (type == BreakpointType::Execute) {
-        memory.WriteBlock(addr, btrap.data(), btrap.size());
-        system.InvalidateCpuInstructionCaches();
-    }
-    p.insert({addr, breakpoint});
-
-    LOG_DEBUG(Debug_GDBStub, "gdb: added {} breakpoint: {:016X} bytes at {:016X}",
-              static_cast<int>(type), breakpoint.len, breakpoint.addr);
-
-    return true;
-}
-
-/// Handle add breakpoint command from gdb client.
-static void AddBreakpoint() {
-    BreakpointType type;
-
-    u8 type_id = HexCharToValue(command_buffer[1]);
-    switch (type_id) {
-    case 0:
-    case 1:
-        type = BreakpointType::Execute;
-        break;
-    case 2:
-        type = BreakpointType::Write;
-        break;
-    case 3:
-        type = BreakpointType::Read;
-        break;
-    case 4:
-        type = BreakpointType::Access;
-        break;
-    default:
-        return SendReply("E01");
-    }
-
-    auto start_offset = command_buffer + 3;
-    auto addr_pos = std::find(start_offset, command_buffer + command_length, ',');
-    VAddr addr = HexToLong(start_offset, static_cast<u64>(addr_pos - start_offset));
-
-    start_offset = addr_pos + 1;
-    u64 len =
-        HexToLong(start_offset, static_cast<u64>((command_buffer + command_length) - start_offset));
-
-    if (type == BreakpointType::Access) {
-        // Access is made up of Read and Write types, so add both breakpoints
-        type = BreakpointType::Read;
-
-        if (!CommitBreakpoint(type, addr, len)) {
-            return SendReply("E02");
-        }
-
-        type = BreakpointType::Write;
-    }
-
-    if (!CommitBreakpoint(type, addr, len)) {
-        return SendReply("E02");
-    }
-
-    SendReply("OK");
-}
-
-/// Handle remove breakpoint command from gdb client.
-static void RemoveBreakpoint() {
-    BreakpointType type;
-
-    u8 type_id = HexCharToValue(command_buffer[1]);
-    switch (type_id) {
-    case 0:
-    case 1:
-        type = BreakpointType::Execute;
-        break;
-    case 2:
-        type = BreakpointType::Write;
-        break;
-    case 3:
-        type = BreakpointType::Read;
-        break;
-    case 4:
-        type = BreakpointType::Access;
-        break;
-    default:
-        return SendReply("E01");
-    }
-
-    auto start_offset = command_buffer + 3;
-    auto addr_pos = std::find(start_offset, command_buffer + command_length, ',');
-    VAddr addr = HexToLong(start_offset, static_cast<u64>(addr_pos - start_offset));
-
-    if (type == BreakpointType::Access) {
-        // Access is made up of Read and Write types, so add both breakpoints
-        type = BreakpointType::Read;
-        RemoveBreakpoint(type, addr);
-
-        type = BreakpointType::Write;
-    }
-
-    RemoveBreakpoint(type, addr);
-    SendReply("OK");
-}
-
-void HandlePacket() {
-    if (!IsConnected()) {
-        if (defer_start) {
-            ToggleServer(true);
-        }
-        return;
-    }
-
-    if (!IsDataAvailable()) {
-        return;
-    }
-
-    ReadCommand();
-    if (command_length == 0) {
-        return;
-    }
-
-    LOG_DEBUG(Debug_GDBStub, "Packet: {}", command_buffer);
-
-    switch (command_buffer[0]) {
-    case 'q':
-        HandleQuery();
-        break;
-    case 'H':
-        HandleSetThread();
-        break;
-    case '?':
-        SendSignal(current_thread, latest_signal);
-        break;
-    case 'k':
-        Shutdown();
-        LOG_INFO(Debug_GDBStub, "killed by gdb");
-        return;
-    case 'g':
-        ReadRegisters();
-        break;
-    case 'G':
-        WriteRegisters();
-        break;
-    case 'p':
-        ReadRegister();
-        break;
-    case 'P':
-        WriteRegister();
-        break;
-    case 'm':
-        ReadMemory();
-        break;
-    case 'M':
-        WriteMemory();
-        break;
-    case 's':
-        Step();
-        return;
-    case 'C':
-    case 'c':
-        Continue();
-        return;
-    case 'z':
-        RemoveBreakpoint();
-        break;
-    case 'Z':
-        AddBreakpoint();
-        break;
-    case 'T':
-        HandleThreadAlive();
-        break;
-    default:
-        SendReply("");
-        break;
-    }
-}
-
-void SetServerPort(u16 port) {
-    gdbstub_port = port;
-}
-
-void ToggleServer(bool status) {
-    if (status) {
-        server_enabled = status;
-
-        // Start server
-        if (!IsConnected() && Core::System::GetInstance().IsPoweredOn()) {
-            Init();
-        }
-    } else {
-        // Stop server
-        if (IsConnected()) {
-            Shutdown();
-        }
-
-        server_enabled = status;
-    }
-}
-
-void DeferStart() {
-    defer_start = true;
-}
-
-static void Init(u16 port) {
-    if (!server_enabled) {
-        // Set the halt loop to false in case the user enabled the gdbstub mid-execution.
-        // This way the CPU can still execute normally.
-        halt_loop = false;
-        step_loop = false;
-        return;
-    }
-
-    // Setup initial gdbstub status
-    halt_loop = true;
-    step_loop = false;
-
-    breakpoints_execute.clear();
-    breakpoints_read.clear();
-    breakpoints_write.clear();
-
-    modules.clear();
-
-    // Start gdb server
-    LOG_INFO(Debug_GDBStub, "Starting GDB server on port {}...", port);
-
-    sockaddr_in saddr_server = {};
-    saddr_server.sin_family = AF_INET;
-    saddr_server.sin_port = htons(port);
-    saddr_server.sin_addr.s_addr = INADDR_ANY;
-
-#ifdef _WIN32
-    WSAStartup(MAKEWORD(2, 2), &InitData);
-#endif
-
-    int tmpsock = static_cast<int>(socket(PF_INET, SOCK_STREAM, 0));
-    if (tmpsock == -1) {
-        LOG_ERROR(Debug_GDBStub, "Failed to create gdb socket");
-    }
-
-    // Set socket to SO_REUSEADDR so it can always bind on the same port
-    int reuse_enabled = 1;
-    if (setsockopt(tmpsock, SOL_SOCKET, SO_REUSEADDR, (const char*)&reuse_enabled,
-                   sizeof(reuse_enabled)) < 0) {
-        LOG_ERROR(Debug_GDBStub, "Failed to set gdb socket option");
-    }
-
-    const sockaddr* server_addr = reinterpret_cast<const sockaddr*>(&saddr_server);
-    socklen_t server_addrlen = sizeof(saddr_server);
-    if (bind(tmpsock, server_addr, server_addrlen) < 0) {
-        LOG_ERROR(Debug_GDBStub, "Failed to bind gdb socket");
-    }
-
-    if (listen(tmpsock, 1) < 0) {
-        LOG_ERROR(Debug_GDBStub, "Failed to listen to gdb socket");
-    }
-
-    // Wait for gdb to connect
-    LOG_INFO(Debug_GDBStub, "Waiting for gdb to connect...");
-    sockaddr_in saddr_client;
-    sockaddr* client_addr = reinterpret_cast<sockaddr*>(&saddr_client);
-    socklen_t client_addrlen = sizeof(saddr_client);
-    gdbserver_socket = static_cast<int>(accept(tmpsock, client_addr, &client_addrlen));
-    if (gdbserver_socket < 0) {
-        // In the case that we couldn't start the server for whatever reason, just start CPU
-        // execution like normal.
-        halt_loop = false;
-        step_loop = false;
-
-        LOG_ERROR(Debug_GDBStub, "Failed to accept gdb client");
-    } else {
-        LOG_INFO(Debug_GDBStub, "Client connected.");
-        saddr_client.sin_addr.s_addr = ntohl(saddr_client.sin_addr.s_addr);
-    }
-
-    // Clean up temporary socket if it's still alive at this point.
-    if (tmpsock != -1) {
-        shutdown(tmpsock, SHUT_RDWR);
-    }
-}
-
-void Init() {
-    Init(gdbstub_port);
-}
-
-void Shutdown() {
-    if (!server_enabled) {
-        return;
-    }
-    defer_start = false;
-
-    LOG_INFO(Debug_GDBStub, "Stopping GDB ...");
-    if (gdbserver_socket != -1) {
-        shutdown(gdbserver_socket, SHUT_RDWR);
-        gdbserver_socket = -1;
-    }
-
-#ifdef _WIN32
-    WSACleanup();
-#endif
-
-    LOG_INFO(Debug_GDBStub, "GDB stopped.");
-}
-
-bool IsServerEnabled() {
-    return server_enabled;
-}
-
-bool IsConnected() {
-    return IsServerEnabled() && gdbserver_socket != -1;
-}
-
-bool GetCpuHaltFlag() {
-    return halt_loop;
-}
-
-bool GetCpuStepFlag() {
-    return step_loop;
-}
-
-void SetCpuStepFlag(bool is_step) {
-    step_loop = is_step;
-}
-
-void SendTrap(Kernel::Thread* thread, int trap) {
-    if (!send_trap) {
-        return;
-    }
-
-    current_thread = thread;
-    SendSignal(thread, trap);
-
-    halt_loop = true;
-    send_trap = false;
-}
-}; // namespace GDBStub
diff --git a/src/core/gdbstub/gdbstub.h b/src/core/gdbstub/gdbstub.h
deleted file mode 100644
index 8fe3c320b..000000000
--- a/src/core/gdbstub/gdbstub.h
+++ /dev/null
@@ -1,114 +0,0 @@
-// Copyright 2013 Dolphin Emulator Project
-// Licensed under GPLv2+
-// Refer to the license.txt file included.
-
-// Originally written by Sven Peter <sven@fail0verflow.com> for anergistic.
-
-#pragma once
-
-#include <string>
-#include "common/common_types.h"
-#include "core/hle/kernel/thread.h"
-
-namespace GDBStub {
-
-/// Breakpoint Method
-enum class BreakpointType {
-    None,    ///< None
-    Execute, ///< Execution Breakpoint
-    Read,    ///< Read Breakpoint
-    Write,   ///< Write Breakpoint
-    Access   ///< Access (R/W) Breakpoint
-};
-
-struct BreakpointAddress {
-    VAddr address;
-    BreakpointType type;
-};
-
-/**
- * Set the port the gdbstub should use to listen for connections.
- *
- * @param port Port to listen for connection
- */
-void SetServerPort(u16 port);
-
-/**
- * Starts or stops the server if possible.
- *
- * @param status Set the server to enabled or disabled.
- */
-void ToggleServer(bool status);
-
-/// Start the gdbstub server.
-void Init();
-
-/**
- * Defer initialization of the gdbstub to the first packet processing functions.
- * This avoids a case where the gdbstub thread is frozen after initialization
- * and fails to respond in time to packets.
- */
-void DeferStart();
-
-/// Stop gdbstub server.
-void Shutdown();
-
-/// Checks if the gdbstub server is enabled.
-bool IsServerEnabled();
-
-/// Returns true if there is an active socket connection.
-bool IsConnected();
-
-/// Register module.
-void RegisterModule(std::string name, VAddr beg, VAddr end, bool add_elf_ext = true);
-
-/**
- * Signal to the gdbstub server that it should halt CPU execution.
- *
- * @param is_memory_break If true, the break resulted from a memory breakpoint.
- */
-void Break(bool is_memory_break = false);
-
-/// Determine if there was a memory breakpoint.
-bool IsMemoryBreak();
-
-/// Read and handle packet from gdb client.
-void HandlePacket();
-
-/**
- * Get the nearest breakpoint of the specified type at the given address.
- *
- * @param addr Address to search from.
- * @param type Type of breakpoint.
- */
-BreakpointAddress GetNextBreakpointFromAddress(VAddr addr, GDBStub::BreakpointType type);
-
-/**
- * Check if a breakpoint of the specified type exists at the given address.
- *
- * @param addr Address of breakpoint.
- * @param type Type of breakpoint.
- */
-bool CheckBreakpoint(VAddr addr, GDBStub::BreakpointType type);
-
-/// If set to true, the CPU will halt at the beginning of the next CPU loop.
-bool GetCpuHaltFlag();
-
-/// If set to true and the CPU is halted, the CPU will step one instruction.
-bool GetCpuStepFlag();
-
-/**
- * When set to true, the CPU will step one instruction when the CPU is halted next.
- *
- * @param is_step
- */
-void SetCpuStepFlag(bool is_step);
-
-/**
- * Send trap signal from thread back to the gdbstub server.
- *
- * @param thread Sending thread.
- * @param trap Trap no.
- */
-void SendTrap(Kernel::Thread* thread, int trap);
-} // namespace GDBStub
diff --git a/src/core/loader/deconstructed_rom_directory.cpp b/src/core/loader/deconstructed_rom_directory.cpp
index 2002dc4f2..79ebf11de 100644
--- a/src/core/loader/deconstructed_rom_directory.cpp
+++ b/src/core/loader/deconstructed_rom_directory.cpp
@@ -12,7 +12,6 @@
 #include "core/file_sys/control_metadata.h"
 #include "core/file_sys/patch_manager.h"
 #include "core/file_sys/romfs_factory.h"
-#include "core/gdbstub/gdbstub.h"
 #include "core/hle/kernel/kernel.h"
 #include "core/hle/kernel/memory/page_table.h"
 #include "core/hle/kernel/process.h"
@@ -180,8 +179,6 @@ AppLoader_DeconstructedRomDirectory::LoadResult AppLoader_DeconstructedRomDirect
         next_load_addr = *tentative_next_load_addr;
         modules.insert_or_assign(load_addr, module);
         LOG_DEBUG(Loader, "loaded module {} @ 0x{:X}", module, load_addr);
-        // Register module with GDBStub
-        GDBStub::RegisterModule(module, load_addr, next_load_addr - 1, false);
     }
 
     // Find the RomFS by searching for a ".romfs" file in this directory
diff --git a/src/core/loader/kip.cpp b/src/core/loader/kip.cpp
index 2a905d3e4..e162c4ff0 100644
--- a/src/core/loader/kip.cpp
+++ b/src/core/loader/kip.cpp
@@ -5,7 +5,6 @@
 #include <cstring>
 #include "core/file_sys/kernel_executable.h"
 #include "core/file_sys/program_metadata.h"
-#include "core/gdbstub/gdbstub.h"
 #include "core/hle/kernel/code_set.h"
 #include "core/hle/kernel/memory/page_table.h"
 #include "core/hle/kernel/process.h"
@@ -91,8 +90,6 @@ AppLoader::LoadResult AppLoader_KIP::Load(Kernel::Process& process,
     program_image.resize(PageAlignSize(kip->GetBSSOffset()) + kip->GetBSSSize());
     codeset.DataSegment().size += kip->GetBSSSize();
 
-    GDBStub::RegisterModule(kip->GetName(), base_address, base_address + program_image.size());
-
     codeset.memory = std::move(program_image);
     process.LoadModule(std::move(codeset), base_address);
 
diff --git a/src/core/loader/nro.cpp b/src/core/loader/nro.cpp
index 5f4b3104b..ccf8cc153 100644
--- a/src/core/loader/nro.cpp
+++ b/src/core/loader/nro.cpp
@@ -14,10 +14,10 @@
 #include "core/file_sys/control_metadata.h"
 #include "core/file_sys/romfs_factory.h"
 #include "core/file_sys/vfs_offset.h"
-#include "core/gdbstub/gdbstub.h"
 #include "core/hle/kernel/code_set.h"
 #include "core/hle/kernel/memory/page_table.h"
 #include "core/hle/kernel/process.h"
+#include "core/hle/kernel/thread.h"
 #include "core/hle/service/filesystem/filesystem.h"
 #include "core/loader/nro.h"
 #include "core/loader/nso.h"
@@ -197,10 +197,6 @@ static bool LoadNroImpl(Kernel::Process& process, const std::vector<u8>& data,
     codeset.memory = std::move(program_image);
     process.LoadModule(std::move(codeset), process.PageTable().GetCodeRegionStart());
 
-    // Register module with GDBStub
-    GDBStub::RegisterModule(name, process.PageTable().GetCodeRegionStart(),
-                            process.PageTable().GetCodeRegionEnd());
-
     return true;
 }
 
diff --git a/src/core/loader/nso.cpp b/src/core/loader/nso.cpp
index aa85c1a29..95b6f339a 100644
--- a/src/core/loader/nso.cpp
+++ b/src/core/loader/nso.cpp
@@ -14,10 +14,10 @@
 #include "common/swap.h"
 #include "core/core.h"
 #include "core/file_sys/patch_manager.h"
-#include "core/gdbstub/gdbstub.h"
 #include "core/hle/kernel/code_set.h"
 #include "core/hle/kernel/memory/page_table.h"
 #include "core/hle/kernel/process.h"
+#include "core/hle/kernel/thread.h"
 #include "core/loader/nso.h"
 #include "core/memory.h"
 #include "core/settings.h"
@@ -159,9 +159,6 @@ std::optional<VAddr> AppLoader_NSO::LoadModule(Kernel::Process& process, Core::S
     codeset.memory = std::move(program_image);
     process.LoadModule(std::move(codeset), load_base);
 
-    // Register module with GDBStub
-    GDBStub::RegisterModule(file.GetName(), load_base, load_base);
-
     return load_base + image_size;
 }
 
diff --git a/src/core/settings.cpp b/src/core/settings.cpp
index aadbc3932..e9997a263 100644
--- a/src/core/settings.cpp
+++ b/src/core/settings.cpp
@@ -4,9 +4,10 @@
 
 #include <string_view>
 
+#include "common/assert.h"
 #include "common/file_util.h"
+#include "common/logging/log.h"
 #include "core/core.h"
-#include "core/gdbstub/gdbstub.h"
 #include "core/hle/service/hid/hid.h"
 #include "core/settings.h"
 #include "video_core/renderer_base.h"
@@ -31,13 +32,9 @@ std::string GetTimeZoneString() {
     return timezones[time_zone_index];
 }
 
-void Apply() {
-    GDBStub::SetServerPort(values.gdbstub_port);
-    GDBStub::ToggleServer(values.use_gdbstub);
-
-    auto& system_instance = Core::System::GetInstance();
-    if (system_instance.IsPoweredOn()) {
-        system_instance.Renderer().RefreshBaseSettings();
+void Apply(Core::System& system) {
+    if (system.IsPoweredOn()) {
+        system.Renderer().RefreshBaseSettings();
     }
 
     Service::HID::ReloadInputDevices();
@@ -106,9 +103,9 @@ float Volume() {
     return values.volume.GetValue();
 }
 
-void RestoreGlobalState() {
+void RestoreGlobalState(bool is_powered_on) {
     // If a game is running, DO NOT restore the global settings state
-    if (Core::System::GetInstance().IsPoweredOn()) {
+    if (is_powered_on) {
         return;
     }
 
diff --git a/src/core/settings.h b/src/core/settings.h
index 1143aba5d..3df611d5b 100644
--- a/src/core/settings.h
+++ b/src/core/settings.h
@@ -14,6 +14,10 @@
 #include "common/common_types.h"
 #include "input_common/settings.h"
 
+namespace Core {
+class System;
+}
+
 namespace Settings {
 
 enum class RendererBackend {
@@ -247,11 +251,11 @@ float Volume();
 
 std::string GetTimeZoneString();
 
-void Apply();
+void Apply(Core::System& system);
 void LogSettings();
 
 // Restore the global state of all applicable settings in the Values struct
-void RestoreGlobalState();
+void RestoreGlobalState(bool is_powered_on);
 
 // Fixes settings that are known to cause issues with the emulator
 void Sanitize();
diff --git a/src/yuzu/configuration/config.cpp b/src/yuzu/configuration/config.cpp
index 3c423a271..8be9e93c3 100644
--- a/src/yuzu/configuration/config.cpp
+++ b/src/yuzu/configuration/config.cpp
@@ -7,6 +7,7 @@
 #include <QSettings>
 #include "common/common_paths.h"
 #include "common/file_util.h"
+#include "core/core.h"
 #include "core/hle/service/acc/profile_manager.h"
 #include "core/hle/service/hid/controllers/npad.h"
 #include "input_common/main.h"
@@ -1598,7 +1599,7 @@ void Config::Reload() {
     Settings::Sanitize();
     // To apply default value changes
     SaveValues();
-    Settings::Apply();
+    Settings::Apply(Core::System::GetInstance());
 }
 
 void Config::Save() {
diff --git a/src/yuzu/configuration/configure_dialog.cpp b/src/yuzu/configuration/configure_dialog.cpp
index 5041e0bf8..b33f8437a 100644
--- a/src/yuzu/configuration/configure_dialog.cpp
+++ b/src/yuzu/configuration/configure_dialog.cpp
@@ -5,6 +5,7 @@
 #include <QHash>
 #include <QListWidgetItem>
 #include <QSignalBlocker>
+#include "core/core.h"
 #include "core/settings.h"
 #include "ui_configure.h"
 #include "yuzu/configuration/config.h"
@@ -54,7 +55,7 @@ void ConfigureDialog::ApplyConfiguration() {
     ui->debugTab->ApplyConfiguration();
     ui->webTab->ApplyConfiguration();
     ui->serviceTab->ApplyConfiguration();
-    Settings::Apply();
+    Settings::Apply(Core::System::GetInstance());
     Settings::LogSettings();
 }
 
diff --git a/src/yuzu/configuration/configure_per_game.cpp b/src/yuzu/configuration/configure_per_game.cpp
index 8eac3bd9d..f598513df 100644
--- a/src/yuzu/configuration/configure_per_game.cpp
+++ b/src/yuzu/configuration/configure_per_game.cpp
@@ -57,7 +57,7 @@ void ConfigurePerGame::ApplyConfiguration() {
     ui->graphicsAdvancedTab->ApplyConfiguration();
     ui->audioTab->ApplyConfiguration();
 
-    Settings::Apply();
+    Settings::Apply(Core::System::GetInstance());
     Settings::LogSettings();
 
     game_config->Save();
diff --git a/src/yuzu/configuration/configure_profile_manager.cpp b/src/yuzu/configuration/configure_profile_manager.cpp
index 6334c4c50..13d9a4757 100644
--- a/src/yuzu/configuration/configure_profile_manager.cpp
+++ b/src/yuzu/configuration/configure_profile_manager.cpp
@@ -180,7 +180,7 @@ void ConfigureProfileManager::ApplyConfiguration() {
         return;
     }
 
-    Settings::Apply();
+    Settings::Apply(Core::System::GetInstance());
 }
 
 void ConfigureProfileManager::SelectUser(const QModelIndex& index) {
diff --git a/src/yuzu/configuration/configure_system.cpp b/src/yuzu/configuration/configure_system.cpp
index 59a58d92c..6cf2032da 100644
--- a/src/yuzu/configuration/configure_system.cpp
+++ b/src/yuzu/configuration/configure_system.cpp
@@ -105,16 +105,18 @@ void ConfigureSystem::SetConfiguration() {
 void ConfigureSystem::ReadSystemSettings() {}
 
 void ConfigureSystem::ApplyConfiguration() {
-    // Allow setting custom RTC even if system is powered on, to allow in-game time to be fast
-    // forwared
+    auto& system = Core::System::GetInstance();
+
+    // Allow setting custom RTC even if system is powered on,
+    // to allow in-game time to be fast forwarded
     if (Settings::values.custom_rtc.UsingGlobal()) {
         if (ui->custom_rtc_checkbox->isChecked()) {
             Settings::values.custom_rtc.SetValue(
                 std::chrono::seconds(ui->custom_rtc_edit->dateTime().toSecsSinceEpoch()));
-            if (Core::System::GetInstance().IsPoweredOn()) {
+            if (system.IsPoweredOn()) {
                 const s64 posix_time{Settings::values.custom_rtc.GetValue()->count() +
                                      Service::Time::TimeManager::GetExternalTimeZoneOffset()};
-                Core::System::GetInstance().GetTimeManager().UpdateLocalSystemClockTime(posix_time);
+                system.GetTimeManager().UpdateLocalSystemClockTime(posix_time);
             }
         } else {
             Settings::values.custom_rtc.SetValue(std::nullopt);
@@ -197,7 +199,7 @@ void ConfigureSystem::ApplyConfiguration() {
         }
     }
 
-    Settings::Apply();
+    Settings::Apply(system);
 }
 
 void ConfigureSystem::RefreshConsoleID() {
diff --git a/src/yuzu/configuration/configure_ui.cpp b/src/yuzu/configuration/configure_ui.cpp
index dbe3f78c8..aed876008 100644
--- a/src/yuzu/configuration/configure_ui.cpp
+++ b/src/yuzu/configuration/configure_ui.cpp
@@ -9,6 +9,7 @@
 #include <QDirIterator>
 #include "common/common_types.h"
 #include "common/file_util.h"
+#include "core/core.h"
 #include "core/settings.h"
 #include "ui_configure_ui.h"
 #include "yuzu/configuration/configure_ui.h"
@@ -84,7 +85,7 @@ void ConfigureUi::ApplyConfiguration() {
     UISettings::values.enable_screenshot_save_as = ui->enable_screenshot_save_as->isChecked();
     Common::FS::GetUserPath(Common::FS::UserPath::ScreenshotsDir,
                             ui->screenshot_path_edit->text().toStdString());
-    Settings::Apply();
+    Settings::Apply(Core::System::GetInstance());
 }
 
 void ConfigureUi::RequestGameListUpdate() {
diff --git a/src/yuzu/main.cpp b/src/yuzu/main.cpp
index 07fa85741..871ff4ae4 100644
--- a/src/yuzu/main.cpp
+++ b/src/yuzu/main.cpp
@@ -172,7 +172,7 @@ void GMainWindow::ShowTelemetryCallout() {
            "<br/><br/>Would you like to share your usage data with us?");
     if (QMessageBox::question(this, tr("Telemetry"), telemetry_message) != QMessageBox::Yes) {
         Settings::values.enable_telemetry = false;
-        Settings::Apply();
+        Settings::Apply(Core::System::GetInstance());
     }
 }
 
@@ -302,7 +302,7 @@ void GMainWindow::ControllerSelectorReconfigureControllers(
     emit ControllerSelectorReconfigureFinished();
 
     // Don't forget to apply settings.
-    Settings::Apply();
+    Settings::Apply(Core::System::GetInstance());
     config->Save();
 
     UpdateStatusButtons();
@@ -571,11 +571,11 @@ void GMainWindow::InitializeWidgets() {
         if (emulation_running) {
             return;
         }
-        bool is_async = !Settings::values.use_asynchronous_gpu_emulation.GetValue() ||
-                        Settings::values.use_multi_core.GetValue();
+        const bool is_async = !Settings::values.use_asynchronous_gpu_emulation.GetValue() ||
+                              Settings::values.use_multi_core.GetValue();
         Settings::values.use_asynchronous_gpu_emulation.SetValue(is_async);
         async_status_button->setChecked(Settings::values.use_asynchronous_gpu_emulation.GetValue());
-        Settings::Apply();
+        Settings::Apply(Core::System::GetInstance());
     });
     async_status_button->setText(tr("ASYNC"));
     async_status_button->setCheckable(true);
@@ -590,12 +590,12 @@ void GMainWindow::InitializeWidgets() {
             return;
         }
         Settings::values.use_multi_core.SetValue(!Settings::values.use_multi_core.GetValue());
-        bool is_async = Settings::values.use_asynchronous_gpu_emulation.GetValue() ||
-                        Settings::values.use_multi_core.GetValue();
+        const bool is_async = Settings::values.use_asynchronous_gpu_emulation.GetValue() ||
+                              Settings::values.use_multi_core.GetValue();
         Settings::values.use_asynchronous_gpu_emulation.SetValue(is_async);
         async_status_button->setChecked(Settings::values.use_asynchronous_gpu_emulation.GetValue());
         multicore_status_button->setChecked(Settings::values.use_multi_core.GetValue());
-        Settings::Apply();
+        Settings::Apply(Core::System::GetInstance());
     });
     multicore_status_button->setText(tr("MULTICORE"));
     multicore_status_button->setCheckable(true);
@@ -630,7 +630,7 @@ void GMainWindow::InitializeWidgets() {
             Settings::values.renderer_backend.SetValue(Settings::RendererBackend::OpenGL);
         }
 
-        Settings::Apply();
+        Settings::Apply(Core::System::GetInstance());
     });
 #endif // HAS_VULKAN
     statusBar()->insertPermanentWidget(0, renderer_status_button);
@@ -2130,14 +2130,14 @@ void GMainWindow::OnPauseGame() {
 }
 
 void GMainWindow::OnStopGame() {
-    Core::System& system{Core::System::GetInstance()};
+    auto& system{Core::System::GetInstance()};
     if (system.GetExitLock() && !ConfirmForceLockedExit()) {
         return;
     }
 
     ShutdownGame();
 
-    Settings::RestoreGlobalState();
+    Settings::RestoreGlobalState(system.IsPoweredOn());
     UpdateStatusButtons();
 }
 
@@ -2312,10 +2312,11 @@ void GMainWindow::OnConfigurePerGame() {
 
 void GMainWindow::OpenPerGameConfiguration(u64 title_id, const std::string& file_name) {
     const auto v_file = Core::GetGameFileFromPath(vfs, file_name);
+    const auto& system = Core::System::GetInstance();
 
     ConfigurePerGame dialog(this, title_id);
     dialog.LoadFromFile(v_file);
-    auto result = dialog.exec();
+    const auto result = dialog.exec();
     if (result == QDialog::Accepted) {
         dialog.ApplyConfiguration();
 
@@ -2325,13 +2326,14 @@ void GMainWindow::OpenPerGameConfiguration(u64 title_id, const std::string& file
         }
 
         // Do not cause the global config to write local settings into the config file
-        Settings::RestoreGlobalState();
+        const bool is_powered_on = system.IsPoweredOn();
+        Settings::RestoreGlobalState(is_powered_on);
 
-        if (!Core::System::GetInstance().IsPoweredOn()) {
+        if (!is_powered_on) {
             config->Save();
         }
     } else {
-        Settings::RestoreGlobalState();
+        Settings::RestoreGlobalState(system.IsPoweredOn());
     }
 }
 
@@ -2602,7 +2604,7 @@ void GMainWindow::OnCoreError(Core::System::ResultStatus result, std::string det
         if (emu_thread) {
             ShutdownGame();
 
-            Settings::RestoreGlobalState();
+            Settings::RestoreGlobalState(Core::System::GetInstance().IsPoweredOn());
             UpdateStatusButtons();
         }
     } else {
@@ -2774,7 +2776,7 @@ void GMainWindow::closeEvent(QCloseEvent* event) {
     if (emu_thread != nullptr) {
         ShutdownGame();
 
-        Settings::RestoreGlobalState();
+        Settings::RestoreGlobalState(Core::System::GetInstance().IsPoweredOn());
         UpdateStatusButtons();
     }
 
diff --git a/src/yuzu_cmd/yuzu.cpp b/src/yuzu_cmd/yuzu.cpp
index ba6e89249..c2efe1ee6 100644
--- a/src/yuzu_cmd/yuzu.cpp
+++ b/src/yuzu_cmd/yuzu.cpp
@@ -25,7 +25,6 @@
 #include "core/crypto/key_manager.h"
 #include "core/file_sys/registered_cache.h"
 #include "core/file_sys/vfs_real.h"
-#include "core/gdbstub/gdbstub.h"
 #include "core/hle/kernel/process.h"
 #include "core/hle/service/filesystem/filesystem.h"
 #include "core/loader/loader.h"
@@ -174,13 +173,13 @@ int main(int argc, char** argv) {
         return -1;
     }
 
+    auto& system{Core::System::GetInstance()};
+    InputCommon::InputSubsystem input_subsystem;
+
     // Apply the command line arguments
     Settings::values.gdbstub_port = gdb_port;
     Settings::values.use_gdbstub = use_gdbstub;
-    Settings::Apply();
-
-    Core::System& system{Core::System::GetInstance()};
-    InputCommon::InputSubsystem input_subsystem;
+    Settings::Apply(system);
 
     std::unique_ptr<EmuWindow_SDL2> emu_window;
     switch (Settings::values.renderer_backend.GetValue()) {
diff --git a/src/yuzu_tester/yuzu.cpp b/src/yuzu_tester/yuzu.cpp
index ea94a6537..50bd7ae41 100644
--- a/src/yuzu_tester/yuzu.cpp
+++ b/src/yuzu_tester/yuzu.cpp
@@ -160,10 +160,12 @@ int main(int argc, char** argv) {
         return -1;
     }
 
-    Settings::values.use_gdbstub = false;
-    Settings::Apply();
+    Core::System& system{Core::System::GetInstance()};
 
-    std::unique_ptr<EmuWindow_SDL2_Hide> emu_window{std::make_unique<EmuWindow_SDL2_Hide>()};
+    Settings::values.use_gdbstub = false;
+    Settings::Apply(system);
+
+    const auto emu_window{std::make_unique<EmuWindow_SDL2_Hide>()};
 
     bool finished = false;
     int return_value = 0;
@@ -212,7 +214,6 @@ int main(int argc, char** argv) {
             return_value = -1;
     };
 
-    Core::System& system{Core::System::GetInstance()};
     system.SetContentProvider(std::make_unique<FileSys::ContentProviderUnion>());
     system.SetFilesystem(std::make_shared<FileSys::RealVfsFilesystem>());
     system.GetFileSystemController().CreateFactories(*system.GetFilesystem());