diff --git a/src/core/core.cpp b/src/core/core.cpp
index cd1799e42..401fff01b 100644
--- a/src/core/core.cpp
+++ b/src/core/core.cpp
@@ -306,7 +306,7 @@ System::ResultStatus System::Init(Frontend::EmuWindow& emu_window, u32 system_mo
 
     HW::Init(*memory);
     Service::Init(*this);
-    GDBStub::Init();
+    GDBStub::DeferStart();
 
     VideoCore::ResultStatus result = VideoCore::Init(emu_window, *memory);
     if (result != VideoCore::ResultStatus::Success) {
diff --git a/src/core/gdbstub/gdbstub.cpp b/src/core/gdbstub/gdbstub.cpp
index a7ed44aff..bf15f1011 100644
--- a/src/core/gdbstub/gdbstub.cpp
+++ b/src/core/gdbstub/gdbstub.cpp
@@ -121,6 +121,7 @@ constexpr char target_xml[] =
 )";
 
 int gdbserver_socket = -1;
+bool defer_start = false;
 
 u8 command_buffer[GDB_BUFFER_SIZE];
 u32 command_length;
@@ -1042,7 +1043,8 @@ static void RemoveBreakpoint() {
 }
 
 void HandlePacket() {
-    if (!IsConnected()) {
+    if (!IsConnected() && defer_start) {
+        ToggleServer(true);
         return;
     }
 
@@ -1133,6 +1135,10 @@ void ToggleServer(bool 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.
@@ -1216,6 +1222,7 @@ void Shutdown() {
     if (!server_enabled) {
         return;
     }
+    defer_start = false;
 
     LOG_INFO(Debug_GDBStub, "Stopping GDB ...");
     if (gdbserver_socket != -1) {
diff --git a/src/core/gdbstub/gdbstub.h b/src/core/gdbstub/gdbstub.h
index 131b3f823..b878b7957 100644
--- a/src/core/gdbstub/gdbstub.h
+++ b/src/core/gdbstub/gdbstub.h
@@ -42,6 +42,13 @@ 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();