summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--lldb/include/lldb/Host/Host.h16
-rw-r--r--lldb/include/lldb/Host/posix/ProcessLauncherPosix.h24
-rw-r--r--lldb/source/Host/CMakeLists.txt6
-rw-r--r--lldb/source/Host/common/Host.cpp355
-rw-r--r--lldb/source/Host/macosx/Host.mm299
-rw-r--r--lldb/source/Host/posix/ProcessLauncherPosix.cpp34
-rw-r--r--lldb/unittests/tools/lldb-server/tests/TestClient.cpp1
7 files changed, 302 insertions, 433 deletions
diff --git a/lldb/include/lldb/Host/Host.h b/lldb/include/lldb/Host/Host.h
index c474dccab5d..83e6d850cf1 100644
--- a/lldb/include/lldb/Host/Host.h
+++ b/lldb/include/lldb/Host/Host.h
@@ -184,22 +184,6 @@ public:
static bool GetProcessInfo(lldb::pid_t pid, ProcessInstanceInfo &proc_info);
-#if (defined(__APPLE__) || defined(__linux__) || defined(__FreeBSD__) || \
- defined(__GLIBC__) || defined(__NetBSD__) || defined(__OpenBSD__)) && \
- !defined(__ANDROID__)
-
- static short GetPosixspawnFlags(const ProcessLaunchInfo &launch_info);
-
- static Status LaunchProcessPosixSpawn(const char *exe_path,
- const ProcessLaunchInfo &launch_info,
- lldb::pid_t &pid);
-
- static bool AddPosixSpawnFileAction(void *file_actions,
- const FileAction *info, Log *log,
- Status &error);
-
-#endif
-
static const lldb::UnixSignalsSP &GetUnixSignals();
static Status LaunchProcess(ProcessLaunchInfo &launch_info);
diff --git a/lldb/include/lldb/Host/posix/ProcessLauncherPosix.h b/lldb/include/lldb/Host/posix/ProcessLauncherPosix.h
deleted file mode 100644
index 4800c406604..00000000000
--- a/lldb/include/lldb/Host/posix/ProcessLauncherPosix.h
+++ /dev/null
@@ -1,24 +0,0 @@
-//===-- ProcessLauncherPosix.h ----------------------------------*- C++ -*-===//
-//
-// The LLVM Compiler Infrastructure
-//
-// This file is distributed under the University of Illinois Open Source
-// License. See LICENSE.TXT for details.
-//
-//===----------------------------------------------------------------------===//
-
-#ifndef lldb_Host_posix_ProcessLauncherPosix_h_
-#define lldb_Host_posix_ProcessLauncherPosix_h_
-
-#include "lldb/Host/ProcessLauncher.h"
-
-namespace lldb_private {
-
-class ProcessLauncherPosix : public ProcessLauncher {
-public:
- HostProcess LaunchProcess(const ProcessLaunchInfo &launch_info,
- Status &error) override;
-};
-}
-
-#endif
diff --git a/lldb/source/Host/CMakeLists.txt b/lldb/source/Host/CMakeLists.txt
index 2a73c30f852..b9079ce26a2 100644
--- a/lldb/source/Host/CMakeLists.txt
+++ b/lldb/source/Host/CMakeLists.txt
@@ -90,12 +90,6 @@ else()
posix/ProcessLauncherPosixFork.cpp
)
- if (NOT (CMAKE_SYSTEM_NAME MATCHES "Android"))
- add_host_subdirectory(posix
- posix/ProcessLauncherPosix.cpp
- )
- endif()
-
if (CMAKE_SYSTEM_NAME MATCHES "Darwin")
include_directories(SYSTEM ${LIBXML2_INCLUDE_DIR})
add_host_subdirectory(macosx
diff --git a/lldb/source/Host/common/Host.cpp b/lldb/source/Host/common/Host.cpp
index d78961e5bff..a2204a07bc6 100644
--- a/lldb/source/Host/common/Host.cpp
+++ b/lldb/source/Host/common/Host.cpp
@@ -73,10 +73,8 @@
#if defined(_WIN32)
#include "lldb/Host/windows/ProcessLauncherWindows.h"
-#elif defined(__linux__) || defined(__NetBSD__)
-#include "lldb/Host/posix/ProcessLauncherPosixFork.h"
#else
-#include "lldb/Host/posix/ProcessLauncherPosix.h"
+#include "lldb/Host/posix/ProcessLauncherPosixFork.h"
#endif
#if defined(__APPLE__)
@@ -602,359 +600,14 @@ Status Host::RunShellCommand(const Args &args, const FileSpec &working_dir,
return error;
}
-// LaunchProcessPosixSpawn for Apple, Linux, FreeBSD, NetBSD and other GLIBC
-// systems
-
-#if defined(__APPLE__) || defined(__linux__) || defined(__FreeBSD__) || \
- defined(__GLIBC__) || defined(__NetBSD__)
-#if !defined(__ANDROID__)
-// this method needs to be visible to macosx/Host.cpp and
-// common/Host.cpp.
-
-short Host::GetPosixspawnFlags(const ProcessLaunchInfo &launch_info) {
- short flags = POSIX_SPAWN_SETSIGDEF | POSIX_SPAWN_SETSIGMASK;
-
-#if defined(__APPLE__)
- if (launch_info.GetFlags().Test(eLaunchFlagExec))
- flags |= POSIX_SPAWN_SETEXEC; // Darwin specific posix_spawn flag
-
- if (launch_info.GetFlags().Test(eLaunchFlagDebug))
- flags |= POSIX_SPAWN_START_SUSPENDED; // Darwin specific posix_spawn flag
-
- if (launch_info.GetFlags().Test(eLaunchFlagDisableASLR))
- flags |= _POSIX_SPAWN_DISABLE_ASLR; // Darwin specific posix_spawn flag
-
- if (launch_info.GetLaunchInSeparateProcessGroup())
- flags |= POSIX_SPAWN_SETPGROUP;
-
-#ifdef POSIX_SPAWN_CLOEXEC_DEFAULT
-#if defined(__APPLE__) && (defined(__x86_64__) || defined(__i386__))
- static LazyBool g_use_close_on_exec_flag = eLazyBoolCalculate;
- if (g_use_close_on_exec_flag == eLazyBoolCalculate) {
- g_use_close_on_exec_flag = eLazyBoolNo;
-
- uint32_t major, minor, update;
- if (HostInfo::GetOSVersion(major, minor, update)) {
- // Kernel panic if we use the POSIX_SPAWN_CLOEXEC_DEFAULT on 10.7 or
- // earlier
- if (major > 10 || (major == 10 && minor > 7)) {
- // Only enable for 10.8 and later OS versions
- g_use_close_on_exec_flag = eLazyBoolYes;
- }
- }
- }
-#else
- static LazyBool g_use_close_on_exec_flag = eLazyBoolYes;
-#endif
- // Close all files exception those with file actions if this is supported.
- if (g_use_close_on_exec_flag == eLazyBoolYes)
- flags |= POSIX_SPAWN_CLOEXEC_DEFAULT;
-#endif
-#endif // #if defined (__APPLE__)
- return flags;
-}
-
-Status Host::LaunchProcessPosixSpawn(const char *exe_path,
- const ProcessLaunchInfo &launch_info,
- lldb::pid_t &pid) {
- Status error;
- Log *log(lldb_private::GetLogIfAllCategoriesSet(LIBLLDB_LOG_HOST |
- LIBLLDB_LOG_PROCESS));
-
- posix_spawnattr_t attr;
- error.SetError(::posix_spawnattr_init(&attr), eErrorTypePOSIX);
-
- if (error.Fail()) {
- LLDB_LOG(log, "error: {0}, ::posix_spawnattr_init ( &attr )", error);
- return error;
- }
-
- // Make a quick class that will cleanup the posix spawn attributes in case
- // we return in the middle of this function.
- lldb_utility::CleanUp<posix_spawnattr_t *, int> posix_spawnattr_cleanup(
- &attr, posix_spawnattr_destroy);
-
- sigset_t no_signals;
- sigset_t all_signals;
- sigemptyset(&no_signals);
- sigfillset(&all_signals);
- ::posix_spawnattr_setsigmask(&attr, &no_signals);
-#if defined(__linux__) || defined(__FreeBSD__) || defined(__NetBSD__)
- ::posix_spawnattr_setsigdefault(&attr, &no_signals);
-#else
- ::posix_spawnattr_setsigdefault(&attr, &all_signals);
-#endif
-
- short flags = GetPosixspawnFlags(launch_info);
-
- error.SetError(::posix_spawnattr_setflags(&attr, flags), eErrorTypePOSIX);
- if (error.Fail()) {
- LLDB_LOG(log,
- "error: {0}, ::posix_spawnattr_setflags ( &attr, flags={1:x} )",
- error, flags);
- return error;
- }
-
-// posix_spawnattr_setbinpref_np appears to be an Apple extension per:
-// http://www.unix.com/man-page/OSX/3/posix_spawnattr_setbinpref_np/
-#if defined(__APPLE__) && !defined(__arm__)
-
- // Don't set the binpref if a shell was provided. After all, that's only
- // going to affect what version of the shell
- // is launched, not what fork of the binary is launched. We insert "arch
- // --arch <ARCH> as part of the shell invocation
- // to do that job on OSX.
-
- if (launch_info.GetShell() == nullptr) {
- // We don't need to do this for ARM, and we really shouldn't now that we
- // have multiple CPU subtypes and no posix_spawnattr call that allows us
- // to set which CPU subtype to launch...
- const ArchSpec &arch_spec = launch_info.GetArchitecture();
- cpu_type_t cpu = arch_spec.GetMachOCPUType();
- cpu_type_t sub = arch_spec.GetMachOCPUSubType();
- if (cpu != 0 && cpu != static_cast<cpu_type_t>(UINT32_MAX) &&
- cpu != static_cast<cpu_type_t>(LLDB_INVALID_CPUTYPE) &&
- !(cpu == 0x01000007 && sub == 8)) // If haswell is specified, don't try
- // to set the CPU type or we will fail
- {
- size_t ocount = 0;
- error.SetError(::posix_spawnattr_setbinpref_np(&attr, 1, &cpu, &ocount),
- eErrorTypePOSIX);
- if (error.Fail())
- LLDB_LOG(log, "error: {0}, ::posix_spawnattr_setbinpref_np ( &attr, 1, "
- "cpu_type = {1:x}, count => {2} )",
- error, cpu, ocount);
-
- if (error.Fail() || ocount != 1)
- return error;
- }
- }
-
-#endif
-
- const char *tmp_argv[2];
- char *const *argv = const_cast<char *const *>(
- launch_info.GetArguments().GetConstArgumentVector());
- char *const *envp = const_cast<char *const *>(
- launch_info.GetEnvironmentEntries().GetConstArgumentVector());
- if (argv == NULL) {
- // posix_spawn gets very unhappy if it doesn't have at least the program
- // name in argv[0]. One of the side affects I have noticed is the
- // environment
- // variables don't make it into the child process if "argv == NULL"!!!
- tmp_argv[0] = exe_path;
- tmp_argv[1] = NULL;
- argv = const_cast<char *const *>(tmp_argv);
- }
-
+// The functions below implement process launching for non-Apple-based platforms
#if !defined(__APPLE__)
- // manage the working directory
- char current_dir[PATH_MAX];
- current_dir[0] = '\0';
-#endif
-
- FileSpec working_dir{launch_info.GetWorkingDirectory()};
- if (working_dir) {
-#if defined(__APPLE__)
- // Set the working directory on this thread only
- if (__pthread_chdir(working_dir.GetCString()) < 0) {
- if (errno == ENOENT) {
- error.SetErrorStringWithFormat("No such file or directory: %s",
- working_dir.GetCString());
- } else if (errno == ENOTDIR) {
- error.SetErrorStringWithFormat("Path doesn't name a directory: %s",
- working_dir.GetCString());
- } else {
- error.SetErrorStringWithFormat("An unknown error occurred when "
- "changing directory for process "
- "execution.");
- }
- return error;
- }
-#else
- if (::getcwd(current_dir, sizeof(current_dir)) == NULL) {
- error.SetError(errno, eErrorTypePOSIX);
- LLDB_LOG(log, "error: {0}, unable to save the current directory", error);
- return error;
- }
-
- if (::chdir(working_dir.GetCString()) == -1) {
- error.SetError(errno, eErrorTypePOSIX);
- LLDB_LOG(log, "error: {0}, unable to change working directory to {1}",
- error, working_dir);
- return error;
- }
-#endif
- }
-
- ::pid_t result_pid = LLDB_INVALID_PROCESS_ID;
- const size_t num_file_actions = launch_info.GetNumFileActions();
- if (num_file_actions > 0) {
- posix_spawn_file_actions_t file_actions;
- error.SetError(::posix_spawn_file_actions_init(&file_actions),
- eErrorTypePOSIX);
- if (error.Fail()) {
- LLDB_LOG(log,
- "error: {0}, ::posix_spawn_file_actions_init ( &file_actions )",
- error);
- return error;
- }
-
- // Make a quick class that will cleanup the posix spawn attributes in case
- // we return in the middle of this function.
- lldb_utility::CleanUp<posix_spawn_file_actions_t *, int>
- posix_spawn_file_actions_cleanup(&file_actions,
- posix_spawn_file_actions_destroy);
-
- for (size_t i = 0; i < num_file_actions; ++i) {
- const FileAction *launch_file_action =
- launch_info.GetFileActionAtIndex(i);
- if (launch_file_action) {
- if (!AddPosixSpawnFileAction(&file_actions, launch_file_action, log,
- error))
- return error;
- }
- }
-
- error.SetError(
- ::posix_spawnp(&result_pid, exe_path, &file_actions, &attr, argv, envp),
- eErrorTypePOSIX);
-
- if (error.Fail()) {
- LLDB_LOG(log, "error: {0}, ::posix_spawnp(pid => {1}, path = '{2}', "
- "file_actions = {3}, "
- "attr = {4}, argv = {5}, envp = {6} )",
- error, result_pid, exe_path, &file_actions, &attr, argv, envp);
- if (log) {
- for (int ii = 0; argv[ii]; ++ii)
- LLDB_LOG(log, "argv[{0}] = '{1}'", ii, argv[ii]);
- }
- }
-
- } else {
- error.SetError(
- ::posix_spawnp(&result_pid, exe_path, NULL, &attr, argv, envp),
- eErrorTypePOSIX);
-
- if (error.Fail()) {
- LLDB_LOG(log, "error: {0}, ::posix_spawnp ( pid => {1}, path = '{2}', "
- "file_actions = NULL, attr = {3}, argv = {4}, envp = {5} )",
- error, result_pid, exe_path, &attr, argv, envp);
- if (log) {
- for (int ii = 0; argv[ii]; ++ii)
- LLDB_LOG(log, "argv[{0}] = '{1}'", ii, argv[ii]);
- }
- }
- }
- pid = result_pid;
-
- if (working_dir) {
-#if defined(__APPLE__)
- // No more thread specific current working directory
- __pthread_fchdir(-1);
-#else
- if (::chdir(current_dir) == -1 && error.Success()) {
- error.SetError(errno, eErrorTypePOSIX);
- LLDB_LOG(log,
- "error: {0}, unable to change current directory back to {1}",
- error, current_dir);
- }
-#endif
- }
-
- return error;
-}
-
-bool Host::AddPosixSpawnFileAction(void *_file_actions, const FileAction *info,
- Log *log, Status &error) {
- if (info == NULL)
- return false;
-
- posix_spawn_file_actions_t *file_actions =
- reinterpret_cast<posix_spawn_file_actions_t *>(_file_actions);
-
- switch (info->GetAction()) {
- case FileAction::eFileActionNone:
- error.Clear();
- break;
-
- case FileAction::eFileActionClose:
- if (info->GetFD() == -1)
- error.SetErrorString(
- "invalid fd for posix_spawn_file_actions_addclose(...)");
- else {
- error.SetError(
- ::posix_spawn_file_actions_addclose(file_actions, info->GetFD()),
- eErrorTypePOSIX);
- if (error.Fail())
- LLDB_LOG(log, "error: {0}, posix_spawn_file_actions_addclose "
- "(action={1}, fd={2})",
- error, file_actions, info->GetFD());
- }
- break;
-
- case FileAction::eFileActionDuplicate:
- if (info->GetFD() == -1)
- error.SetErrorString(
- "invalid fd for posix_spawn_file_actions_adddup2(...)");
- else if (info->GetActionArgument() == -1)
- error.SetErrorString(
- "invalid duplicate fd for posix_spawn_file_actions_adddup2(...)");
- else {
- error.SetError(
- ::posix_spawn_file_actions_adddup2(file_actions, info->GetFD(),
- info->GetActionArgument()),
- eErrorTypePOSIX);
- if (error.Fail())
- LLDB_LOG(log, "error: {0}, posix_spawn_file_actions_adddup2 "
- "(action={1}, fd={2}, dup_fd={3})",
- error, file_actions, info->GetFD(), info->GetActionArgument());
- }
- break;
-
- case FileAction::eFileActionOpen:
- if (info->GetFD() == -1)
- error.SetErrorString(
- "invalid fd in posix_spawn_file_actions_addopen(...)");
- else {
- int oflag = info->GetActionArgument();
-
- mode_t mode = 0;
-
- if (oflag & O_CREAT)
- mode = 0640;
-
- error.SetError(::posix_spawn_file_actions_addopen(
- file_actions, info->GetFD(),
- info->GetPath().str().c_str(), oflag, mode),
- eErrorTypePOSIX);
- if (error.Fail())
- LLDB_LOG(
- log, "error: {0}, posix_spawn_file_actions_addopen (action={1}, "
- "fd={2}, path='{3}', oflag={4}, mode={5})",
- error, file_actions, info->GetFD(), info->GetPath(), oflag, mode);
- }
- break;
- }
- return error.Success();
-}
-#endif // !defined(__ANDROID__)
-#endif // defined (__APPLE__) || defined (__linux__) || defined (__FreeBSD__) ||
- // defined (__GLIBC__) || defined(__NetBSD__)
-
-#if defined(__linux__) || defined(__FreeBSD__) || defined(__GLIBC__) || \
- defined(__NetBSD__) || defined(_WIN32)
-// The functions below implement process launching via posix_spawn() for Linux,
-// FreeBSD and NetBSD.
-
Status Host::LaunchProcess(ProcessLaunchInfo &launch_info) {
std::unique_ptr<ProcessLauncher> delegate_launcher;
#if defined(_WIN32)
delegate_launcher.reset(new ProcessLauncherWindows());
-#elif defined(__linux__) || defined(__NetBSD__)
- delegate_launcher.reset(new ProcessLauncherPosixFork());
#else
- delegate_launcher.reset(new ProcessLauncherPosix());
+ delegate_launcher.reset(new ProcessLauncherPosixFork());
#endif
MonitoringProcessLauncher launcher(std::move(delegate_launcher));
@@ -968,7 +621,7 @@ Status Host::LaunchProcess(ProcessLaunchInfo &launch_info) {
return error;
}
-#endif // defined(__linux__) || defined(__FreeBSD__) || defined(__NetBSD__)
+#endif // !defined(__APPLE__)
#ifndef _WIN32
void Host::Kill(lldb::pid_t pid, int signo) { ::kill(pid, signo); }
diff --git a/lldb/source/Host/macosx/Host.mm b/lldb/source/Host/macosx/Host.mm
index be205f95386..919b35624e6 100644
--- a/lldb/source/Host/macosx/Host.mm
+++ b/lldb/source/Host/macosx/Host.mm
@@ -1024,6 +1024,47 @@ static Status getXPCAuthorization(ProcessLaunchInfo &launch_info) {
}
#endif
+static short GetPosixspawnFlags(const ProcessLaunchInfo &launch_info) {
+ short flags = POSIX_SPAWN_SETSIGDEF | POSIX_SPAWN_SETSIGMASK;
+
+ if (launch_info.GetFlags().Test(eLaunchFlagExec))
+ flags |= POSIX_SPAWN_SETEXEC; // Darwin specific posix_spawn flag
+
+ if (launch_info.GetFlags().Test(eLaunchFlagDebug))
+ flags |= POSIX_SPAWN_START_SUSPENDED; // Darwin specific posix_spawn flag
+
+ if (launch_info.GetFlags().Test(eLaunchFlagDisableASLR))
+ flags |= _POSIX_SPAWN_DISABLE_ASLR; // Darwin specific posix_spawn flag
+
+ if (launch_info.GetLaunchInSeparateProcessGroup())
+ flags |= POSIX_SPAWN_SETPGROUP;
+
+#ifdef POSIX_SPAWN_CLOEXEC_DEFAULT
+#if defined(__x86_64__) || defined(__i386__)
+ static LazyBool g_use_close_on_exec_flag = eLazyBoolCalculate;
+ if (g_use_close_on_exec_flag == eLazyBoolCalculate) {
+ g_use_close_on_exec_flag = eLazyBoolNo;
+
+ uint32_t major, minor, update;
+ if (HostInfo::GetOSVersion(major, minor, update)) {
+ // Kernel panic if we use the POSIX_SPAWN_CLOEXEC_DEFAULT on 10.7 or
+ // earlier
+ if (major > 10 || (major == 10 && minor > 7)) {
+ // Only enable for 10.8 and later OS versions
+ g_use_close_on_exec_flag = eLazyBoolYes;
+ }
+ }
+ }
+#else
+ static LazyBool g_use_close_on_exec_flag = eLazyBoolYes;
+#endif // defined(__x86_64__) || defined(__i386__)
+ // Close all files exception those with file actions if this is supported.
+ if (g_use_close_on_exec_flag == eLazyBoolYes)
+ flags |= POSIX_SPAWN_CLOEXEC_DEFAULT;
+#endif // ifdef POSIX_SPAWN_CLOEXEC_DEFAULT
+ return flags;
+}
+
static Status LaunchProcessXPC(const char *exe_path,
ProcessLaunchInfo &launch_info,
lldb::pid_t &pid) {
@@ -1107,7 +1148,7 @@ static Status LaunchProcessXPC(const char *exe_path,
xpc_dictionary_set_int64(message, LauncherXPCServiceCPUTypeKey,
launch_info.GetArchitecture().GetMachOCPUType());
xpc_dictionary_set_int64(message, LauncherXPCServicePosixspawnFlagsKey,
- Host::GetPosixspawnFlags(launch_info));
+ GetPosixspawnFlags(launch_info));
const FileAction *file_action = launch_info.GetFileActionForFD(STDIN_FILENO);
if (file_action && !file_action->GetPath().empty()) {
xpc_dictionary_set_string(message, LauncherXPCServiceStdInPathKeyKey,
@@ -1161,6 +1202,262 @@ static Status LaunchProcessXPC(const char *exe_path,
#endif
}
+static bool AddPosixSpawnFileAction(void *_file_actions, const FileAction *info,
+ Log *log, Status &error) {
+ if (info == NULL)
+ return false;
+
+ posix_spawn_file_actions_t *file_actions =
+ reinterpret_cast<posix_spawn_file_actions_t *>(_file_actions);
+
+ switch (info->GetAction()) {
+ case FileAction::eFileActionNone:
+ error.Clear();
+ break;
+
+ case FileAction::eFileActionClose:
+ if (info->GetFD() == -1)
+ error.SetErrorString(
+ "invalid fd for posix_spawn_file_actions_addclose(...)");
+ else {
+ error.SetError(
+ ::posix_spawn_file_actions_addclose(file_actions, info->GetFD()),
+ eErrorTypePOSIX);
+ if (error.Fail())
+ LLDB_LOG(log,
+ "error: {0}, posix_spawn_file_actions_addclose "
+ "(action={1}, fd={2})",
+ error, file_actions, info->GetFD());
+ }
+ break;
+
+ case FileAction::eFileActionDuplicate:
+ if (info->GetFD() == -1)
+ error.SetErrorString(
+ "invalid fd for posix_spawn_file_actions_adddup2(...)");
+ else if (info->GetActionArgument() == -1)
+ error.SetErrorString(
+ "invalid duplicate fd for posix_spawn_file_actions_adddup2(...)");
+ else {
+ error.SetError(
+ ::posix_spawn_file_actions_adddup2(file_actions, info->GetFD(),
+ info->GetActionArgument()),
+ eErrorTypePOSIX);
+ if (error.Fail())
+ LLDB_LOG(log,
+ "error: {0}, posix_spawn_file_actions_adddup2 "
+ "(action={1}, fd={2}, dup_fd={3})",
+ error, file_actions, info->GetFD(), info->GetActionArgument());
+ }
+ break;
+
+ case FileAction::eFileActionOpen:
+ if (info->GetFD() == -1)
+ error.SetErrorString(
+ "invalid fd in posix_spawn_file_actions_addopen(...)");
+ else {
+ int oflag = info->GetActionArgument();
+
+ mode_t mode = 0;
+
+ if (oflag & O_CREAT)
+ mode = 0640;
+
+ error.SetError(::posix_spawn_file_actions_addopen(
+ file_actions, info->GetFD(),
+ info->GetPath().str().c_str(), oflag, mode),
+ eErrorTypePOSIX);
+ if (error.Fail())
+ LLDB_LOG(log,
+ "error: {0}, posix_spawn_file_actions_addopen (action={1}, "
+ "fd={2}, path='{3}', oflag={4}, mode={5})",
+ error, file_actions, info->GetFD(), info->GetPath(), oflag,
+ mode);
+ }
+ break;
+ }
+ return error.Success();
+}
+
+static Status LaunchProcessPosixSpawn(const char *exe_path,
+ const ProcessLaunchInfo &launch_info,
+ lldb::pid_t &pid) {
+ Status error;
+ Log *log(lldb_private::GetLogIfAllCategoriesSet(LIBLLDB_LOG_HOST |
+ LIBLLDB_LOG_PROCESS));
+
+ posix_spawnattr_t attr;
+ error.SetError(::posix_spawnattr_init(&attr), eErrorTypePOSIX);
+
+ if (error.Fail()) {
+ LLDB_LOG(log, "error: {0}, ::posix_spawnattr_init ( &attr )", error);
+ return error;
+ }
+
+ // Make a quick class that will cleanup the posix spawn attributes in case
+ // we return in the middle of this function.
+ lldb_utility::CleanUp<posix_spawnattr_t *, int> posix_spawnattr_cleanup(
+ &attr, posix_spawnattr_destroy);
+
+ sigset_t no_signals;
+ sigset_t all_signals;
+ sigemptyset(&no_signals);
+ sigfillset(&all_signals);
+ ::posix_spawnattr_setsigmask(&attr, &no_signals);
+ ::posix_spawnattr_setsigdefault(&attr, &all_signals);
+
+ short flags = GetPosixspawnFlags(launch_info);
+
+ error.SetError(::posix_spawnattr_setflags(&attr, flags), eErrorTypePOSIX);
+ if (error.Fail()) {
+ LLDB_LOG(log,
+ "error: {0}, ::posix_spawnattr_setflags ( &attr, flags={1:x} )",
+ error, flags);
+ return error;
+ }
+
+// posix_spawnattr_setbinpref_np appears to be an Apple extension per:
+// http://www.unix.com/man-page/OSX/3/posix_spawnattr_setbinpref_np/
+#if !defined(__arm__)
+
+ // Don't set the binpref if a shell was provided. After all, that's only
+ // going to affect what version of the shell
+ // is launched, not what fork of the binary is launched. We insert "arch
+ // --arch <ARCH> as part of the shell invocation
+ // to do that job on OSX.
+
+ if (launch_info.GetShell() == nullptr) {
+ // We don't need to do this for ARM, and we really shouldn't now that we
+ // have multiple CPU subtypes and no posix_spawnattr call that allows us
+ // to set which CPU subtype to launch...
+ const ArchSpec &arch_spec = launch_info.GetArchitecture();
+ cpu_type_t cpu = arch_spec.GetMachOCPUType();
+ cpu_type_t sub = arch_spec.GetMachOCPUSubType();
+ if (cpu != 0 && cpu != static_cast<cpu_type_t>(UINT32_MAX) &&
+ cpu != static_cast<cpu_type_t>(LLDB_INVALID_CPUTYPE) &&
+ !(cpu == 0x01000007 && sub == 8)) // If haswell is specified, don't try
+ // to set the CPU type or we will fail
+ {
+ size_t ocount = 0;
+ error.SetError(::posix_spawnattr_setbinpref_np(&attr, 1, &cpu, &ocount),
+ eErrorTypePOSIX);
+ if (error.Fail())
+ LLDB_LOG(log,
+ "error: {0}, ::posix_spawnattr_setbinpref_np ( &attr, 1, "
+ "cpu_type = {1:x}, count => {2} )",
+ error, cpu, ocount);
+
+ if (error.Fail() || ocount != 1)
+ return error;
+ }
+ }
+#endif // !defined(__arm__)
+
+ const char *tmp_argv[2];
+ char *const *argv = const_cast<char *const *>(
+ launch_info.GetArguments().GetConstArgumentVector());
+ char *const *envp = const_cast<char *const *>(
+ launch_info.GetEnvironmentEntries().GetConstArgumentVector());
+ if (argv == NULL) {
+ // posix_spawn gets very unhappy if it doesn't have at least the program
+ // name in argv[0]. One of the side affects I have noticed is the
+ // environment
+ // variables don't make it into the child process if "argv == NULL"!!!
+ tmp_argv[0] = exe_path;
+ tmp_argv[1] = NULL;
+ argv = const_cast<char *const *>(tmp_argv);
+ }
+
+ FileSpec working_dir{launch_info.GetWorkingDirectory()};
+ if (working_dir) {
+ // Set the working directory on this thread only
+ if (__pthread_chdir(working_dir.GetCString()) < 0) {
+ if (errno == ENOENT) {
+ error.SetErrorStringWithFormat("No such file or directory: %s",
+ working_dir.GetCString());
+ } else if (errno == ENOTDIR) {
+ error.SetErrorStringWithFormat("Path doesn't name a directory: %s",
+ working_dir.GetCString());
+ } else {
+ error.SetErrorStringWithFormat("An unknown error occurred when "
+ "changing directory for process "
+ "execution.");
+ }
+ return error;
+ }
+ }
+
+ ::pid_t result_pid = LLDB_INVALID_PROCESS_ID;
+ const size_t num_file_actions = launch_info.GetNumFileActions();
+ if (num_file_actions > 0) {
+ posix_spawn_file_actions_t file_actions;
+ error.SetError(::posix_spawn_file_actions_init(&file_actions),
+ eErrorTypePOSIX);
+ if (error.Fail()) {
+ LLDB_LOG(log,
+ "error: {0}, ::posix_spawn_file_actions_init ( &file_actions )",
+ error);
+ return error;
+ }
+
+ // Make a quick class that will cleanup the posix spawn attributes in case
+ // we return in the middle of this function.
+ lldb_utility::CleanUp<posix_spawn_file_actions_t *, int>
+ posix_spawn_file_actions_cleanup(&file_actions,
+ posix_spawn_file_actions_destroy);
+
+ for (size_t i = 0; i < num_file_actions; ++i) {
+ const FileAction *launch_file_action =
+ launch_info.GetFileActionAtIndex(i);
+ if (launch_file_action) {
+ if (!AddPosixSpawnFileAction(&file_actions, launch_file_action, log,
+ error))
+ return error;
+ }
+ }
+
+ error.SetError(
+ ::posix_spawnp(&result_pid, exe_path, &file_actions, &attr, argv, envp),
+ eErrorTypePOSIX);
+
+ if (error.Fail()) {
+ LLDB_LOG(log,
+ "error: {0}, ::posix_spawnp(pid => {1}, path = '{2}', "
+ "file_actions = {3}, "
+ "attr = {4}, argv = {5}, envp = {6} )",
+ error, result_pid, exe_path, &file_actions, &attr, argv, envp);
+ if (log) {
+ for (int ii = 0; argv[ii]; ++ii)
+ LLDB_LOG(log, "argv[{0}] = '{1}'", ii, argv[ii]);
+ }
+ }
+
+ } else {
+ error.SetError(
+ ::posix_spawnp(&result_pid, exe_path, NULL, &attr, argv, envp),
+ eErrorTypePOSIX);
+
+ if (error.Fail()) {
+ LLDB_LOG(log,
+ "error: {0}, ::posix_spawnp ( pid => {1}, path = '{2}', "
+ "file_actions = NULL, attr = {3}, argv = {4}, envp = {5} )",
+ error, result_pid, exe_path, &attr, argv, envp);
+ if (log) {
+ for (int ii = 0; argv[ii]; ++ii)
+ LLDB_LOG(log, "argv[{0}] = '{1}'", ii, argv[ii]);
+ }
+ }
+ }
+ pid = result_pid;
+
+ if (working_dir) {
+ // No more thread specific current working directory
+ __pthread_fchdir(-1);
+ }
+
+ return error;
+}
+
static bool ShouldLaunchUsingXPC(ProcessLaunchInfo &launch_info) {
bool result = false;
diff --git a/lldb/source/Host/posix/ProcessLauncherPosix.cpp b/lldb/source/Host/posix/ProcessLauncherPosix.cpp
deleted file mode 100644
index 6d07be1eec6..00000000000
--- a/lldb/source/Host/posix/ProcessLauncherPosix.cpp
+++ /dev/null
@@ -1,34 +0,0 @@
-//===-- ProcessLauncherPosix.cpp --------------------------------*- C++ -*-===//
-//
-// The LLVM Compiler Infrastructure
-//
-// This file is distributed under the University of Illinois Open Source
-// License. See LICENSE.TXT for details.
-//
-//===----------------------------------------------------------------------===//
-
-#include "lldb/Host/posix/ProcessLauncherPosix.h"
-#include "lldb/Host/Host.h"
-#include "lldb/Host/HostProcess.h"
-
-#include "lldb/Target/ProcessLaunchInfo.h"
-
-#include <limits.h>
-
-using namespace lldb;
-using namespace lldb_private;
-
-HostProcess
-ProcessLauncherPosix::LaunchProcess(const ProcessLaunchInfo &launch_info,
- Status &error) {
- lldb::pid_t pid;
- char exe_path[PATH_MAX];
-
- launch_info.GetExecutableFile().GetPath(exe_path, sizeof(exe_path));
-
- // TODO(zturner): Move the code from LaunchProcessPosixSpawn to here, and make
- // MacOSX re-use this
- // ProcessLauncher when it wants a posix_spawn launch.
- error = Host::LaunchProcessPosixSpawn(exe_path, launch_info, pid);
- return HostProcess(pid);
-}
diff --git a/lldb/unittests/tools/lldb-server/tests/TestClient.cpp b/lldb/unittests/tools/lldb-server/tests/TestClient.cpp
index 540d7979055..9553ddd65fa 100644
--- a/lldb/unittests/tools/lldb-server/tests/TestClient.cpp
+++ b/lldb/unittests/tools/lldb-server/tests/TestClient.cpp
@@ -12,7 +12,6 @@
#include "lldb/Host/HostInfo.h"
#include "lldb/Host/common/TCPSocket.h"
#include "lldb/Host/posix/ConnectionFileDescriptorPosix.h"
-#include "lldb/Host/posix/ProcessLauncherPosix.h"
#include "lldb/Interpreter/Args.h"
#include "lldb/Target/ProcessLaunchInfo.h"
#include "llvm/ADT/StringExtras.h"
OpenPOWER on IntegriCloud