From 319b38398e0d990f88db34dc562c73ce847cf910 Mon Sep 17 00:00:00 2001 From: Pavel Labath Date: Mon, 19 Jun 2017 12:26:22 +0000 Subject: Delete ProcessLauncherPosix Summary: ProcessLauncherPosix was using posix_spawn for launching the process, but this function is not available on all platforms we support, and even where it was avaialable, it did not support the full range of options we require for launching (most importantly, launching in stop-on-entry mode). For these reasons, the set of ifdefs around these functions has grown untractably large, and we were forced to implement our own launcher from more basic primitives anyway (ProcessLauncherPosixFork -- used on Linux, Android, and NetBSD). Therefore, I remove this class, and move the relevant parts of the code to the darwin-specific Host.mm file. This is the platform that code was originally written for anyway, and it's the only platform where this implementation makes sense (e.g. the lack of the "thread-specific working directory" concept makes these functions racy on all other platforms). This allows us to remove a lot of ifdefs and simplify the code. Effectively, the only change this introduces is that FreeBSD will now use the fork-based launcher instead of posix_spawnp. That sholdn't be a problem as this approach works at least on one other BSD-based system already. Reviewers: krytarowski, emaste, jingham Subscribers: srhines, mgorny, lldb-commits Differential Revision: https://reviews.llvm.org/D34236 llvm-svn: 305686 --- lldb/source/Host/common/Host.cpp | 355 +-------------------------------------- 1 file changed, 4 insertions(+), 351 deletions(-) (limited to 'lldb/source/Host/common/Host.cpp') 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_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 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(UINT32_MAX) && - cpu != static_cast(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( - launch_info.GetArguments().GetConstArgumentVector()); - char *const *envp = const_cast( - 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(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_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(_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 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); } -- cgit v1.2.3