[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
Thu May 2 17:37:10 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/3] [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/3] 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/3] 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;



More information about the lldb-commits mailing list