https://github.com/labath updated https://github.com/llvm/llvm-project/pull/145017
>From c4923f70478b5274e114642841fd9d3683b67d39 Mon Sep 17 00:00:00 2001 From: Pavel Labath <pa...@labath.sk> Date: Fri, 20 Jun 2025 10:29:23 +0200 Subject: [PATCH] [lldb] Use Socket::CreatePair for launching debugserver This lets get rid of platform-specific code in ProcessGDBRemote and use the same code path (module differences in socket types) everywhere. It also unlocks further cleanups in the debugserver launching code. --- .../Process/gdb-remote/ProcessGDBRemote.cpp | 145 +++++++----------- 1 file changed, 55 insertions(+), 90 deletions(-) diff --git a/lldb/source/Plugins/Process/gdb-remote/ProcessGDBRemote.cpp b/lldb/source/Plugins/Process/gdb-remote/ProcessGDBRemote.cpp index f18bdd5175f2e..4e3569a5e7987 100644 --- a/lldb/source/Plugins/Process/gdb-remote/ProcessGDBRemote.cpp +++ b/lldb/source/Plugins/Process/gdb-remote/ProcessGDBRemote.cpp @@ -3447,115 +3447,80 @@ ProcessGDBRemote::EstablishConnectionIfNeeded(const ProcessInfo &process_info) { } return error; } -#if !defined(_WIN32) -#define USE_SOCKETPAIR_FOR_LOCAL_CONNECTION 1 -#endif - -#ifdef USE_SOCKETPAIR_FOR_LOCAL_CONNECTION -static bool SetCloexecFlag(int fd) { -#if defined(FD_CLOEXEC) - int flags = ::fcntl(fd, F_GETFD); - if (flags == -1) - return false; - return (::fcntl(fd, F_SETFD, flags | FD_CLOEXEC) == 0); -#else - return false; -#endif -} -#endif Status ProcessGDBRemote::LaunchAndConnectToDebugserver( const ProcessInfo &process_info) { using namespace std::placeholders; // For _1, _2, etc. - Status error; - if (m_debugserver_pid == LLDB_INVALID_PROCESS_ID) { - // If we locate debugserver, keep that located version around - static FileSpec g_debugserver_file_spec; + if (m_debugserver_pid != LLDB_INVALID_PROCESS_ID) + return Status(); - ProcessLaunchInfo debugserver_launch_info; - // Make debugserver run in its own session so signals generated by special - // terminal key sequences (^C) don't affect debugserver. - debugserver_launch_info.SetLaunchInSeparateProcessGroup(true); + ProcessLaunchInfo debugserver_launch_info; + // Make debugserver run in its own session so signals generated by special + // terminal key sequences (^C) don't affect debugserver. + debugserver_launch_info.SetLaunchInSeparateProcessGroup(true); - const std::weak_ptr<ProcessGDBRemote> this_wp = - std::static_pointer_cast<ProcessGDBRemote>(shared_from_this()); - debugserver_launch_info.SetMonitorProcessCallback( - std::bind(MonitorDebugserverProcess, this_wp, _1, _2, _3)); - debugserver_launch_info.SetUserID(process_info.GetUserID()); + const std::weak_ptr<ProcessGDBRemote> this_wp = + std::static_pointer_cast<ProcessGDBRemote>(shared_from_this()); + debugserver_launch_info.SetMonitorProcessCallback( + std::bind(MonitorDebugserverProcess, this_wp, _1, _2, _3)); + debugserver_launch_info.SetUserID(process_info.GetUserID()); #if defined(__APPLE__) - // On macOS 11, we need to support x86_64 applications translated to - // arm64. We check whether a binary is translated and spawn the correct - // debugserver accordingly. - int mib[] = { CTL_KERN, KERN_PROC, KERN_PROC_PID, - static_cast<int>(process_info.GetProcessID()) }; - struct kinfo_proc processInfo; - size_t bufsize = sizeof(processInfo); - if (sysctl(mib, (unsigned)(sizeof(mib)/sizeof(int)), &processInfo, - &bufsize, NULL, 0) == 0 && bufsize > 0) { - if (processInfo.kp_proc.p_flag & P_TRANSLATED) { - FileSpec rosetta_debugserver("/Library/Apple/usr/libexec/oah/debugserver"); - debugserver_launch_info.SetExecutableFile(rosetta_debugserver, false); - } + // On macOS 11, we need to support x86_64 applications translated to + // arm64. We check whether a binary is translated and spawn the correct + // debugserver accordingly. + int mib[] = {CTL_KERN, KERN_PROC, KERN_PROC_PID, + static_cast<int>(process_info.GetProcessID())}; + struct kinfo_proc processInfo; + size_t bufsize = sizeof(processInfo); + if (sysctl(mib, (unsigned)(sizeof(mib) / sizeof(int)), &processInfo, &bufsize, + NULL, 0) == 0 && + bufsize > 0) { + if (processInfo.kp_proc.p_flag & P_TRANSLATED) { + FileSpec rosetta_debugserver( + "/Library/Apple/usr/libexec/oah/debugserver"); + debugserver_launch_info.SetExecutableFile(rosetta_debugserver, false); } + } #endif - shared_fd_t communication_fd = SharedSocket::kInvalidFD; -#ifdef USE_SOCKETPAIR_FOR_LOCAL_CONNECTION - // Use a socketpair on non-Windows systems for security and performance - // reasons. - int sockets[2]; /* the pair of socket descriptors */ - if (socketpair(AF_UNIX, SOCK_STREAM, 0, sockets) == -1) { - error = Status::FromErrno(); - return error; - } + llvm::Expected<Socket::Pair> socket_pair = Socket::CreatePair(); + if (!socket_pair) + return Status::FromError(socket_pair.takeError()); - int our_socket = sockets[0]; - int gdb_socket = sockets[1]; - auto cleanup_our = llvm::make_scope_exit([&]() { close(our_socket); }); - auto cleanup_gdb = llvm::make_scope_exit([&]() { close(gdb_socket); }); + Status error; + SharedSocket shared_socket(socket_pair->first.get(), error); + if (error.Fail()) + return error; - // Don't let any child processes inherit our communication socket - SetCloexecFlag(our_socket); - communication_fd = gdb_socket; -#endif + error = m_gdb_comm.StartDebugserverProcess( + nullptr, GetTarget().GetPlatform().get(), debugserver_launch_info, + nullptr, nullptr, shared_socket.GetSendableFD()); - error = m_gdb_comm.StartDebugserverProcess( - nullptr, GetTarget().GetPlatform().get(), debugserver_launch_info, - nullptr, nullptr, communication_fd); + if (error.Fail()) { + Log *log = GetLog(GDBRLog::Process); - if (error.Success()) - m_debugserver_pid = debugserver_launch_info.GetProcessID(); - else - m_debugserver_pid = LLDB_INVALID_PROCESS_ID; - - if (m_debugserver_pid != LLDB_INVALID_PROCESS_ID) { -#ifdef USE_SOCKETPAIR_FOR_LOCAL_CONNECTION - // Our process spawned correctly, we can now set our connection to use - // our end of the socket pair - cleanup_our.release(); - m_gdb_comm.SetConnection( - std::make_unique<ConnectionFileDescriptor>(our_socket, true)); -#endif - StartAsyncThread(); - } + LLDB_LOGF(log, "failed to start debugserver process: %s", + error.AsCString()); + return error; + } - if (error.Fail()) { - Log *log = GetLog(GDBRLog::Process); + m_debugserver_pid = debugserver_launch_info.GetProcessID(); + shared_socket.CompleteSending(m_debugserver_pid); - LLDB_LOGF(log, "failed to start debugserver process: %s", - error.AsCString()); - return error; - } + // Our process spawned correctly, we can now set our connection to use + // our end of the socket pair + m_gdb_comm.SetConnection(std::make_unique<ConnectionFileDescriptor>( + socket_pair->second.release())); + StartAsyncThread(); - if (m_gdb_comm.IsConnected()) { - // Finish the connection process by doing the handshake without - // connecting (send NULL URL) - error = ConnectToDebugserver(""); - } else { - error = Status::FromErrorString("connection failed"); - } + if (m_gdb_comm.IsConnected()) { + // Finish the connection process by doing the handshake without + // connecting (send NULL URL) + error = ConnectToDebugserver(""); + } else { + error = Status::FromErrorString("connection failed"); } return error; } _______________________________________________ lldb-commits mailing list lldb-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/lldb-commits