[Lldb-commits] [lldb] [lldb] Have lldb-server assign ports to children in platform mode (PR #88845)

Anthony Ha via lldb-commits lldb-commits at lists.llvm.org
Fri May 3 11:55:42 PDT 2024


https://github.com/Awfa updated https://github.com/llvm/llvm-project/pull/88845

>From 3d75f42b5f61ea126001919491aa09ebd15ba9f8 Mon Sep 17 00:00:00 2001
From: Anthony Ha <antha at microsoft.com>
Date: Mon, 15 Apr 2024 19:36:34 +0000
Subject: [PATCH 1/4] [lldb] Have lldb-server assign ports to children in
 platform mode

---
 lldb/tools/lldb-server/lldb-platform.cpp | 41 ++++++++++++++++--------
 1 file changed, 28 insertions(+), 13 deletions(-)

diff --git a/lldb/tools/lldb-server/lldb-platform.cpp b/lldb/tools/lldb-server/lldb-platform.cpp
index 3e126584eb25b4..384709ba79b656 100644
--- a/lldb/tools/lldb-server/lldb-platform.cpp
+++ b/lldb/tools/lldb-server/lldb-platform.cpp
@@ -282,17 +282,10 @@ int main_platform(int argc, char *argv[]) {
     }
   }
 
-  do {
-    GDBRemoteCommunicationServerPlatform platform(
-        acceptor_up->GetSocketProtocol(), acceptor_up->GetSocketScheme());
-
-    if (port_offset > 0)
-      platform.SetPortOffset(port_offset);
-
-    if (!gdbserver_portmap.empty()) {
-      platform.SetPortMap(std::move(gdbserver_portmap));
-    }
+  GDBRemoteCommunicationServerPlatform platform(
+      acceptor_up->GetSocketProtocol(), acceptor_up->GetSocketScheme());
 
+  do {
     const bool children_inherit_accept_socket = true;
     Connection *conn = nullptr;
     error = acceptor_up->Accept(children_inherit_accept_socket, conn);
@@ -301,13 +294,31 @@ int main_platform(int argc, char *argv[]) {
       exit(socket_error);
     }
     printf("Connection established.\n");
+
+    std::optional<uint16_t> port = 0;
     if (g_server) {
       // Collect child zombie processes.
 #if !defined(_WIN32)
-      while (waitpid(-1, nullptr, WNOHANG) > 0)
-        ;
+      auto waitResult = waitpid(-1, nullptr, WNOHANG);
+      while (waitResult > 0) {
+        // waitResult is the child pid
+        gdbserver_portmap.FreePortForProcess(waitResult);
+        waitResult = waitpid(-1, nullptr, WNOHANG);
+      }
 #endif
-      if (fork()) {
+      llvm::Expected<uint16_t> available_port =
+          gdbserver_portmap.GetNextAvailablePort();
+      if (available_port)
+        port = *available_port;
+
+      else {
+        fprintf(stderr, "no available port for connection - dropping...\n");
+        delete conn;
+        continue;
+      }
+      auto childPid = fork();
+      if (childPid) {
+        gdbserver_portmap.AssociatePortWithProcess(*available_port, childPid);
         // Parent doesn't need a connection to the lldb client
         delete conn;
 
@@ -324,6 +335,10 @@ int main_platform(int argc, char *argv[]) {
       // connections while a connection is active.
       acceptor_up.reset();
     }
+
+    GDBRemoteCommunicationServerPlatform::PortMap portmap_for_child;
+    portmap_for_child.AllowPort(*port);
+    platform.SetPortMap(std::move(portmap_for_child));
     platform.SetConnection(std::unique_ptr<Connection>(conn));
 
     if (platform.IsConnected()) {

>From 27782fb03b3705e9ff4a5b3cc0d17c8448919be9 Mon Sep 17 00:00:00 2001
From: Anthony Ha <antha at microsoft.com>
Date: Wed, 17 Apr 2024 00:46:58 +0000
Subject: [PATCH 2/4] amend! [lldb] Have lldb-server assign ports to children
 in platform mode

[lldb] Have lldb-server assign ports to children in platform mode
---
 lldb/tools/lldb-server/lldb-platform.cpp | 24 ++++++++++++++----------
 1 file changed, 14 insertions(+), 10 deletions(-)

diff --git a/lldb/tools/lldb-server/lldb-platform.cpp b/lldb/tools/lldb-server/lldb-platform.cpp
index 384709ba79b656..ff91a3318cf0d5 100644
--- a/lldb/tools/lldb-server/lldb-platform.cpp
+++ b/lldb/tools/lldb-server/lldb-platform.cpp
@@ -295,27 +295,31 @@ int main_platform(int argc, char *argv[]) {
     }
     printf("Connection established.\n");
 
-    std::optional<uint16_t> port = 0;
     if (g_server) {
       // Collect child zombie processes.
 #if !defined(_WIN32)
-      auto waitResult = waitpid(-1, nullptr, WNOHANG);
-      while (waitResult > 0) {
+      ::pid_t waitResult;
+      while ((waitResult = waitpid(-1, nullptr, WNOHANG)) > 0) {
         // waitResult is the child pid
         gdbserver_portmap.FreePortForProcess(waitResult);
-        waitResult = waitpid(-1, nullptr, WNOHANG);
       }
 #endif
+      // TODO: Clean up portmap for Windows when children die
+
+      // After collecting zombie ports, get the next available
+      GDBRemoteCommunicationServerPlatform::PortMap portmap_for_child;
       llvm::Expected<uint16_t> available_port =
           gdbserver_portmap.GetNextAvailablePort();
       if (available_port)
-        port = *available_port;
-
+        portmap_for_child.AllowPort(*available_port);
       else {
-        fprintf(stderr, "no available port for connection - dropping...\n");
+        fprintf(stderr,
+                "no available gdbserver port for connection - dropping...\n");
         delete conn;
         continue;
       }
+      platform.SetPortMap(std::move(portmap_for_child));
+
       auto childPid = fork();
       if (childPid) {
         gdbserver_portmap.AssociatePortWithProcess(*available_port, childPid);
@@ -334,11 +338,11 @@ int main_platform(int argc, char *argv[]) {
       // If not running as a server, this process will not accept
       // connections while a connection is active.
       acceptor_up.reset();
+
+      // When not running in server mode, use all available ports
+      platform.SetPortMap(std::move(gdbserver_portmap));
     }
 
-    GDBRemoteCommunicationServerPlatform::PortMap portmap_for_child;
-    portmap_for_child.AllowPort(*port);
-    platform.SetPortMap(std::move(portmap_for_child));
     platform.SetConnection(std::unique_ptr<Connection>(conn));
 
     if (platform.IsConnected()) {

>From 5c3cfb5ad34f8a8f5470d2647a55873ee2981ecf Mon Sep 17 00:00:00 2001
From: Anthony Ha <antha at microsoft.com>
Date: Fri, 3 May 2024 00:36:03 +0000
Subject: [PATCH 3/4] amend! [lldb] Have lldb-server assign ports to children
 in platform mode

[lldb] Have lldb-server assign ports to children in platform mode
---
 lldb/tools/lldb-server/lldb-platform.cpp | 4 ++++
 1 file changed, 4 insertions(+)

diff --git a/lldb/tools/lldb-server/lldb-platform.cpp b/lldb/tools/lldb-server/lldb-platform.cpp
index ff91a3318cf0d5..cfd0a3797d810a 100644
--- a/lldb/tools/lldb-server/lldb-platform.cpp
+++ b/lldb/tools/lldb-server/lldb-platform.cpp
@@ -284,6 +284,8 @@ int main_platform(int argc, char *argv[]) {
 
   GDBRemoteCommunicationServerPlatform platform(
       acceptor_up->GetSocketProtocol(), acceptor_up->GetSocketScheme());
+  if (port_offset > 0)
+    platform.SetPortOffset(port_offset);
 
   do {
     const bool children_inherit_accept_socket = true;
@@ -305,6 +307,7 @@ int main_platform(int argc, char *argv[]) {
       }
 #endif
       // TODO: Clean up portmap for Windows when children die
+      // See https://github.com/llvm/llvm-project/issues/90923
 
       // After collecting zombie ports, get the next available
       GDBRemoteCommunicationServerPlatform::PortMap portmap_for_child;
@@ -313,6 +316,7 @@ int main_platform(int argc, char *argv[]) {
       if (available_port)
         portmap_for_child.AllowPort(*available_port);
       else {
+        llvm::consumeError(available_port.takeError());
         fprintf(stderr,
                 "no available gdbserver port for connection - dropping...\n");
         delete conn;

>From 3f53d68a632aa2f8e908927a14fb331a1fc4ba66 Mon Sep 17 00:00:00 2001
From: Anthony Ha <antha at microsoft.com>
Date: Fri, 3 May 2024 18:20:19 +0000
Subject: [PATCH 4/4] amend! [lldb] Have lldb-server assign ports to children
 in platform mode

[lldb] Have lldb-server assign ports to children in platform mode
---
 lldb/docs/use/qemu-testing.rst | 3 ++-
 1 file changed, 2 insertions(+), 1 deletion(-)

diff --git a/lldb/docs/use/qemu-testing.rst b/lldb/docs/use/qemu-testing.rst
index 6e282141864cc1..51a30b11717a87 100644
--- a/lldb/docs/use/qemu-testing.rst
+++ b/lldb/docs/use/qemu-testing.rst
@@ -172,6 +172,7 @@ forwarded for this to work.
 
 .. note::
   These options are used to create a "port map" within ``lldb-server``.
-  Unfortunately this map is not shared across all the processes it may create,
+  Unfortunately this map is not cleaned up on Windows on connection close,
   and across a few uses you may run out of valid ports. To work around this,
   restart the platform every so often, especially after running a set of tests.
+  This is tracked here: https://github.com/llvm/llvm-project/issues/90923



More information about the lldb-commits mailing list