[Lldb-commits] [lldb] [lldb] Set SO_NOSIGPIPE on platforms that support it (PR #198044)

Alex Langford via lldb-commits lldb-commits at lists.llvm.org
Fri May 22 15:17:55 PDT 2026


https://github.com/bulbazord updated https://github.com/llvm/llvm-project/pull/198044

>From 1552d70c76a17ae084ba4e8c9c26bf5ba37d025f Mon Sep 17 00:00:00 2001
From: Alex Langford <alangford at apple.com>
Date: Fri, 15 May 2026 16:22:23 -0700
Subject: [PATCH 1/3] [lldb] Set SO_NOSIGPIPE on platforms that support it

On macOS, I've seen instances where debugserver goes down very quickly
after it starts up (less than 100ms). Normally, LLDB is able to detect
when debugserver goes down and report it without bringing down the
entire debug session. However that's not happening here. My best guess
is that debugserver is going down before LLDB is ready to react to it.

To mitigate this scenario, adopt SO_NOSIGPIPE. Note that this mostly
matters for tools that embed liblldb. The LLDB driver ignores all
SIGPIPEs.

rdar://173516461
---
 lldb/source/Host/common/Socket.cpp      |  6 ++++++
 lldb/source/Host/posix/DomainSocket.cpp | 10 ++++++++++
 2 files changed, 16 insertions(+)

diff --git a/lldb/source/Host/common/Socket.cpp b/lldb/source/Host/common/Socket.cpp
index d2f954b9d5c8a..58497e4c8de8d 100644
--- a/lldb/source/Host/common/Socket.cpp
+++ b/lldb/source/Host/common/Socket.cpp
@@ -444,6 +444,12 @@ NativeSocket Socket::CreateSocket(const int domain, const int type,
   if (sock == kInvalidSocketValue)
     SetLastError(error);
 
+#if defined(SO_NOSIGPIPE)
+  if (Socket::SetOption(sock, SOL_SOCKET, SO_NOSIGPIPE, 1) == -1)
+    LLDB_LOG(GetLog(LLDBLog::Host), "failed to set SO_NOSIGPIPE on fd {0}: {1}",
+             sock, llvm::sys::StrError());
+#endif
+
   return sock;
 }
 
diff --git a/lldb/source/Host/posix/DomainSocket.cpp b/lldb/source/Host/posix/DomainSocket.cpp
index c0f6ffe626e9e..4f08c372d43cf 100644
--- a/lldb/source/Host/posix/DomainSocket.cpp
+++ b/lldb/source/Host/posix/DomainSocket.cpp
@@ -95,6 +95,16 @@ llvm::Expected<DomainSocket::Pair> DomainSocket::CreatePair() {
   }
 #endif
 
+#if defined(SO_NOSIGPIPE)
+  Log *log = GetLog(LLDBLog::Host);
+  if (Socket::SetOption(sockets[0], SOL_SOCKET, SO_NOSIGPIPE, 1) == -1)
+    LLDB_LOG(log, "failed to set NO_SIGPIPE on fd {0}: {1}", sockets[0],
+             llvm::sys::StrError());
+  if (Socket::SetOption(sockets[1], SOL_SOCKET, SO_NOSIGPIPE, 1) == -1)
+    LLDB_LOG(log, "failed to set NO_SIGPIPE on fd {0}: {1}", sockets[1],
+             llvm::sys::StrError());
+#endif
+
   return Pair(std::unique_ptr<DomainSocket>(
                   new DomainSocket(ProtocolUnixDomain, sockets[0],
                                    /*should_close=*/true)),

>From 5a2feeeafd932c4de986535e1079bc68f82eeba9 Mon Sep 17 00:00:00 2001
From: Alex Langford <alangford at apple.com>
Date: Thu, 21 May 2026 16:10:15 -0700
Subject: [PATCH 2/3] Add unittest

---
 lldb/unittests/Host/SocketTest.cpp | 33 ++++++++++++++++++++++++++++++
 1 file changed, 33 insertions(+)

diff --git a/lldb/unittests/Host/SocketTest.cpp b/lldb/unittests/Host/SocketTest.cpp
index 3a95708283a84..45dcce83ca0a7 100644
--- a/lldb/unittests/Host/SocketTest.cpp
+++ b/lldb/unittests/Host/SocketTest.cpp
@@ -11,10 +11,15 @@
 #include "lldb/Host/Config.h"
 #include "lldb/Host/MainLoop.h"
 #include "lldb/Utility/UriParser.h"
+#include "llvm/ADT/ScopeExit.h"
 #include "llvm/Testing/Support/Error.h"
 #include "gmock/gmock.h"
 #include "gtest/gtest.h"
 #include <chrono>
+#if LLDB_ENABLE_POSIX
+#include <cerrno>
+#include <csignal>
+#endif
 #if __linux__
 #include <lldb/Host/linux/AbstractSocket.h>
 #endif
@@ -446,6 +451,34 @@ TEST_F(SocketTest, AbstractSocketFromBoundNativeSocket) {
 }
 #endif
 
+#if LLDB_ENABLE_POSIX
+TEST_F(SocketTest, DontReceiveSIGPIPE) {
+  static volatile std::sig_atomic_t sigpipe_received;
+  sigpipe_received = 0;
+
+  struct sigaction new_action = {};
+  struct sigaction old_action = {};
+  new_action.sa_handler = [](int) { sigpipe_received = 1; };
+  sigemptyset(&new_action.sa_mask);
+  ASSERT_EQ(0, sigaction(SIGPIPE, &new_action, &old_action));
+  llvm::scope_exit restore_sigpipe(
+      [&] { sigaction(SIGPIPE, &old_action, nullptr); });
+
+  auto pair = Socket::CreatePair();
+  ASSERT_THAT_EXPECTED(pair, llvm::Succeeded());
+  Socket &reader = *pair->first;
+  Socket &writer = *pair->second;
+
+  ASSERT_THAT_ERROR(reader.Close().takeError(), llvm::Succeeded());
+
+  size_t num_bytes = 1;
+  Status err = writer.Write("x", num_bytes);
+  EXPECT_TRUE(err.Fail());
+  EXPECT_EQ(EPIPE, static_cast<int>(err.GetError()));
+  EXPECT_EQ(0, sigpipe_received);
+}
+#endif
+
 INSTANTIATE_TEST_SUITE_P(
     SocketTests, SocketTest,
     testing::Values(SocketTestParams{/*is_ipv6=*/false,

>From d61aeb1dfec2cc7a9cb4017954af4d84b42493b6 Mon Sep 17 00:00:00 2001
From: Alex Langford <alangford at apple.com>
Date: Fri, 22 May 2026 15:17:36 -0700
Subject: [PATCH 3/3] Linux support

---
 lldb/source/Host/common/Socket.cpp | 6 +++++-
 1 file changed, 5 insertions(+), 1 deletion(-)

diff --git a/lldb/source/Host/common/Socket.cpp b/lldb/source/Host/common/Socket.cpp
index 58497e4c8de8d..810d63fc0390d 100644
--- a/lldb/source/Host/common/Socket.cpp
+++ b/lldb/source/Host/common/Socket.cpp
@@ -404,7 +404,11 @@ int Socket::SetOption(NativeSocket sockfd, int level, int option_name,
 }
 
 ssize_t Socket::Send(const void *buf, const size_t num_bytes) {
-  return ::send(m_socket, static_cast<const char *>(buf), num_bytes, 0);
+  int flags = 0;
+#if defined(MSG_NOSIGNAL)
+  flags |= MSG_NOSIGNAL;
+#endif
+  return ::send(m_socket, static_cast<const char *>(buf), num_bytes, flags);
 }
 
 void Socket::SetLastError(Status &error) {



More information about the lldb-commits mailing list