From 38036eb1c8633d151c721992e085e1aca5658f9d Mon Sep 17 00:00:00 2001
From: "Gauvain \"GovanifY\" Roussel-Tarbouriech" <gauvain@govanify.com>
Date: Sun, 23 Feb 2020 21:33:49 +0100
Subject: [PATCH 1/2] gdbstub: Ensure gdbstub doesn't drop packets crucial to
 initialization

---
 src/core/core.cpp            | 2 +-
 src/core/gdbstub/gdbstub.cpp | 9 ++++++++-
 src/core/gdbstub/gdbstub.h   | 7 +++++++
 3 files changed, 16 insertions(+), 2 deletions(-)

diff --git a/src/core/core.cpp b/src/core/core.cpp
index 218508126..d1bc9340d 100644
--- a/src/core/core.cpp
+++ b/src/core/core.cpp
@@ -166,7 +166,7 @@ struct System::Impl {
         service_manager = std::make_shared<Service::SM::ServiceManager>();
 
         Service::Init(service_manager, system);
-        GDBStub::Init();
+        GDBStub::DeferStart();
 
         renderer = VideoCore::CreateRenderer(emu_window, system);
         if (!renderer->Init()) {
diff --git a/src/core/gdbstub/gdbstub.cpp b/src/core/gdbstub/gdbstub.cpp
index e8d8871a7..6ee4df6b5 100644
--- a/src/core/gdbstub/gdbstub.cpp
+++ b/src/core/gdbstub/gdbstub.cpp
@@ -141,6 +141,7 @@ constexpr char target_xml[] =
 )";
 
 int gdbserver_socket = -1;
+bool defer_start = false;
 
 u8 command_buffer[GDB_BUFFER_SIZE];
 u32 command_length;
@@ -1165,7 +1166,8 @@ static void RemoveBreakpoint() {
 }
 
 void HandlePacket() {
-    if (!IsConnected()) {
+    if (!IsConnected() && defer_start) {
+        ToggleServer(true);
         return;
     }
 
@@ -1256,6 +1258,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.
@@ -1341,6 +1347,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 5a36524b2..8fe3c320b 100644
--- a/src/core/gdbstub/gdbstub.h
+++ b/src/core/gdbstub/gdbstub.h
@@ -43,6 +43,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();
 

From eae2ed6b07054a7cb9eca1bc930f4bb9f973a329 Mon Sep 17 00:00:00 2001
From: "Gauvain \"GovanifY\" Roussel-Tarbouriech" <gauvain@govanify.com>
Date: Mon, 24 Feb 2020 14:30:24 +0100
Subject: [PATCH 2/2] gdbstub: small logic bug fix with defer_start

---
 src/core/gdbstub/gdbstub.cpp | 6 ++++--
 1 file changed, 4 insertions(+), 2 deletions(-)

diff --git a/src/core/gdbstub/gdbstub.cpp b/src/core/gdbstub/gdbstub.cpp
index 6ee4df6b5..6d15aeed9 100644
--- a/src/core/gdbstub/gdbstub.cpp
+++ b/src/core/gdbstub/gdbstub.cpp
@@ -1166,8 +1166,10 @@ static void RemoveBreakpoint() {
 }
 
 void HandlePacket() {
-    if (!IsConnected() && defer_start) {
-        ToggleServer(true);
+    if (!IsConnected()) {
+        if (defer_start) {
+            ToggleServer(true);
+        }
         return;
     }