Skip to content

Commit c4923f7

Browse files
committed
[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.
1 parent 092ef1d commit c4923f7

File tree

1 file changed

+55
-90
lines changed

1 file changed

+55
-90
lines changed

lldb/source/Plugins/Process/gdb-remote/ProcessGDBRemote.cpp

Lines changed: 55 additions & 90 deletions
Original file line numberDiff line numberDiff line change
@@ -3447,115 +3447,80 @@ ProcessGDBRemote::EstablishConnectionIfNeeded(const ProcessInfo &process_info) {
34473447
}
34483448
return error;
34493449
}
3450-
#if !defined(_WIN32)
3451-
#define USE_SOCKETPAIR_FOR_LOCAL_CONNECTION 1
3452-
#endif
3453-
3454-
#ifdef USE_SOCKETPAIR_FOR_LOCAL_CONNECTION
3455-
static bool SetCloexecFlag(int fd) {
3456-
#if defined(FD_CLOEXEC)
3457-
int flags = ::fcntl(fd, F_GETFD);
3458-
if (flags == -1)
3459-
return false;
3460-
return (::fcntl(fd, F_SETFD, flags | FD_CLOEXEC) == 0);
3461-
#else
3462-
return false;
3463-
#endif
3464-
}
3465-
#endif
34663450

34673451
Status ProcessGDBRemote::LaunchAndConnectToDebugserver(
34683452
const ProcessInfo &process_info) {
34693453
using namespace std::placeholders; // For _1, _2, etc.
34703454

3471-
Status error;
3472-
if (m_debugserver_pid == LLDB_INVALID_PROCESS_ID) {
3473-
// If we locate debugserver, keep that located version around
3474-
static FileSpec g_debugserver_file_spec;
3455+
if (m_debugserver_pid != LLDB_INVALID_PROCESS_ID)
3456+
return Status();
34753457

3476-
ProcessLaunchInfo debugserver_launch_info;
3477-
// Make debugserver run in its own session so signals generated by special
3478-
// terminal key sequences (^C) don't affect debugserver.
3479-
debugserver_launch_info.SetLaunchInSeparateProcessGroup(true);
3458+
ProcessLaunchInfo debugserver_launch_info;
3459+
// Make debugserver run in its own session so signals generated by special
3460+
// terminal key sequences (^C) don't affect debugserver.
3461+
debugserver_launch_info.SetLaunchInSeparateProcessGroup(true);
34803462

3481-
const std::weak_ptr<ProcessGDBRemote> this_wp =
3482-
std::static_pointer_cast<ProcessGDBRemote>(shared_from_this());
3483-
debugserver_launch_info.SetMonitorProcessCallback(
3484-
std::bind(MonitorDebugserverProcess, this_wp, _1, _2, _3));
3485-
debugserver_launch_info.SetUserID(process_info.GetUserID());
3463+
const std::weak_ptr<ProcessGDBRemote> this_wp =
3464+
std::static_pointer_cast<ProcessGDBRemote>(shared_from_this());
3465+
debugserver_launch_info.SetMonitorProcessCallback(
3466+
std::bind(MonitorDebugserverProcess, this_wp, _1, _2, _3));
3467+
debugserver_launch_info.SetUserID(process_info.GetUserID());
34863468

34873469
#if defined(__APPLE__)
3488-
// On macOS 11, we need to support x86_64 applications translated to
3489-
// arm64. We check whether a binary is translated and spawn the correct
3490-
// debugserver accordingly.
3491-
int mib[] = { CTL_KERN, KERN_PROC, KERN_PROC_PID,
3492-
static_cast<int>(process_info.GetProcessID()) };
3493-
struct kinfo_proc processInfo;
3494-
size_t bufsize = sizeof(processInfo);
3495-
if (sysctl(mib, (unsigned)(sizeof(mib)/sizeof(int)), &processInfo,
3496-
&bufsize, NULL, 0) == 0 && bufsize > 0) {
3497-
if (processInfo.kp_proc.p_flag & P_TRANSLATED) {
3498-
FileSpec rosetta_debugserver("/Library/Apple/usr/libexec/oah/debugserver");
3499-
debugserver_launch_info.SetExecutableFile(rosetta_debugserver, false);
3500-
}
3470+
// On macOS 11, we need to support x86_64 applications translated to
3471+
// arm64. We check whether a binary is translated and spawn the correct
3472+
// debugserver accordingly.
3473+
int mib[] = {CTL_KERN, KERN_PROC, KERN_PROC_PID,
3474+
static_cast<int>(process_info.GetProcessID())};
3475+
struct kinfo_proc processInfo;
3476+
size_t bufsize = sizeof(processInfo);
3477+
if (sysctl(mib, (unsigned)(sizeof(mib) / sizeof(int)), &processInfo, &bufsize,
3478+
NULL, 0) == 0 &&
3479+
bufsize > 0) {
3480+
if (processInfo.kp_proc.p_flag & P_TRANSLATED) {
3481+
FileSpec rosetta_debugserver(
3482+
"/Library/Apple/usr/libexec/oah/debugserver");
3483+
debugserver_launch_info.SetExecutableFile(rosetta_debugserver, false);
35013484
}
3485+
}
35023486
#endif
35033487

3504-
shared_fd_t communication_fd = SharedSocket::kInvalidFD;
3505-
#ifdef USE_SOCKETPAIR_FOR_LOCAL_CONNECTION
3506-
// Use a socketpair on non-Windows systems for security and performance
3507-
// reasons.
3508-
int sockets[2]; /* the pair of socket descriptors */
3509-
if (socketpair(AF_UNIX, SOCK_STREAM, 0, sockets) == -1) {
3510-
error = Status::FromErrno();
3511-
return error;
3512-
}
3488+
llvm::Expected<Socket::Pair> socket_pair = Socket::CreatePair();
3489+
if (!socket_pair)
3490+
return Status::FromError(socket_pair.takeError());
35133491

3514-
int our_socket = sockets[0];
3515-
int gdb_socket = sockets[1];
3516-
auto cleanup_our = llvm::make_scope_exit([&]() { close(our_socket); });
3517-
auto cleanup_gdb = llvm::make_scope_exit([&]() { close(gdb_socket); });
3492+
Status error;
3493+
SharedSocket shared_socket(socket_pair->first.get(), error);
3494+
if (error.Fail())
3495+
return error;
35183496

3519-
// Don't let any child processes inherit our communication socket
3520-
SetCloexecFlag(our_socket);
3521-
communication_fd = gdb_socket;
3522-
#endif
3497+
error = m_gdb_comm.StartDebugserverProcess(
3498+
nullptr, GetTarget().GetPlatform().get(), debugserver_launch_info,
3499+
nullptr, nullptr, shared_socket.GetSendableFD());
35233500

3524-
error = m_gdb_comm.StartDebugserverProcess(
3525-
nullptr, GetTarget().GetPlatform().get(), debugserver_launch_info,
3526-
nullptr, nullptr, communication_fd);
3501+
if (error.Fail()) {
3502+
Log *log = GetLog(GDBRLog::Process);
35273503

3528-
if (error.Success())
3529-
m_debugserver_pid = debugserver_launch_info.GetProcessID();
3530-
else
3531-
m_debugserver_pid = LLDB_INVALID_PROCESS_ID;
3532-
3533-
if (m_debugserver_pid != LLDB_INVALID_PROCESS_ID) {
3534-
#ifdef USE_SOCKETPAIR_FOR_LOCAL_CONNECTION
3535-
// Our process spawned correctly, we can now set our connection to use
3536-
// our end of the socket pair
3537-
cleanup_our.release();
3538-
m_gdb_comm.SetConnection(
3539-
std::make_unique<ConnectionFileDescriptor>(our_socket, true));
3540-
#endif
3541-
StartAsyncThread();
3542-
}
3504+
LLDB_LOGF(log, "failed to start debugserver process: %s",
3505+
error.AsCString());
3506+
return error;
3507+
}
35433508

3544-
if (error.Fail()) {
3545-
Log *log = GetLog(GDBRLog::Process);
3509+
m_debugserver_pid = debugserver_launch_info.GetProcessID();
3510+
shared_socket.CompleteSending(m_debugserver_pid);
35463511

3547-
LLDB_LOGF(log, "failed to start debugserver process: %s",
3548-
error.AsCString());
3549-
return error;
3550-
}
3512+
// Our process spawned correctly, we can now set our connection to use
3513+
// our end of the socket pair
3514+
m_gdb_comm.SetConnection(std::make_unique<ConnectionFileDescriptor>(
3515+
socket_pair->second.release()));
3516+
StartAsyncThread();
35513517

3552-
if (m_gdb_comm.IsConnected()) {
3553-
// Finish the connection process by doing the handshake without
3554-
// connecting (send NULL URL)
3555-
error = ConnectToDebugserver("");
3556-
} else {
3557-
error = Status::FromErrorString("connection failed");
3558-
}
3518+
if (m_gdb_comm.IsConnected()) {
3519+
// Finish the connection process by doing the handshake without
3520+
// connecting (send NULL URL)
3521+
error = ConnectToDebugserver("");
3522+
} else {
3523+
error = Status::FromErrorString("connection failed");
35593524
}
35603525
return error;
35613526
}

0 commit comments

Comments
 (0)