[Lldb-commits] [lldb] r305686 - Delete ProcessLauncherPosix

Pavel Labath via lldb-commits lldb-commits at lists.llvm.org
Mon Jun 19 05:26:22 PDT 2017


Author: labath
Date: Mon Jun 19 07:26:22 2017
New Revision: 305686

URL: http://llvm.org/viewvc/llvm-project?rev=305686&view=rev
Log:
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

Removed:
    lldb/trunk/include/lldb/Host/posix/ProcessLauncherPosix.h
    lldb/trunk/source/Host/posix/ProcessLauncherPosix.cpp
Modified:
    lldb/trunk/include/lldb/Host/Host.h
    lldb/trunk/source/Host/CMakeLists.txt
    lldb/trunk/source/Host/common/Host.cpp
    lldb/trunk/source/Host/macosx/Host.mm
    lldb/trunk/unittests/tools/lldb-server/tests/TestClient.cpp

Modified: lldb/trunk/include/lldb/Host/Host.h
URL: http://llvm.org/viewvc/llvm-project/lldb/trunk/include/lldb/Host/Host.h?rev=305686&r1=305685&r2=305686&view=diff
==============================================================================
--- lldb/trunk/include/lldb/Host/Host.h (original)
+++ lldb/trunk/include/lldb/Host/Host.h Mon Jun 19 07:26:22 2017
@@ -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);

Removed: lldb/trunk/include/lldb/Host/posix/ProcessLauncherPosix.h
URL: http://llvm.org/viewvc/llvm-project/lldb/trunk/include/lldb/Host/posix/ProcessLauncherPosix.h?rev=305685&view=auto
==============================================================================
--- lldb/trunk/include/lldb/Host/posix/ProcessLauncherPosix.h (original)
+++ lldb/trunk/include/lldb/Host/posix/ProcessLauncherPosix.h (removed)
@@ -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

Modified: lldb/trunk/source/Host/CMakeLists.txt
URL: http://llvm.org/viewvc/llvm-project/lldb/trunk/source/Host/CMakeLists.txt?rev=305686&r1=305685&r2=305686&view=diff
==============================================================================
--- lldb/trunk/source/Host/CMakeLists.txt (original)
+++ lldb/trunk/source/Host/CMakeLists.txt Mon Jun 19 07:26:22 2017
@@ -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

Modified: lldb/trunk/source/Host/common/Host.cpp
URL: http://llvm.org/viewvc/llvm-project/lldb/trunk/source/Host/common/Host.cpp?rev=305686&r1=305685&r2=305686&view=diff
==============================================================================
--- lldb/trunk/source/Host/common/Host.cpp (original)
+++ lldb/trunk/source/Host/common/Host.cpp Mon Jun 19 07:26:22 2017
@@ -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
   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(ProcessLaunch
 
   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); }

Modified: lldb/trunk/source/Host/macosx/Host.mm
URL: http://llvm.org/viewvc/llvm-project/lldb/trunk/source/Host/macosx/Host.mm?rev=305686&r1=305685&r2=305686&view=diff
==============================================================================
--- lldb/trunk/source/Host/macosx/Host.mm (original)
+++ lldb/trunk/source/Host/macosx/Host.mm Mon Jun 19 07:26:22 2017
@@ -1024,6 +1024,47 @@ static Status getXPCAuthorization(Proces
 }
 #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 cha
   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 cha
 #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;
 

Removed: lldb/trunk/source/Host/posix/ProcessLauncherPosix.cpp
URL: http://llvm.org/viewvc/llvm-project/lldb/trunk/source/Host/posix/ProcessLauncherPosix.cpp?rev=305685&view=auto
==============================================================================
--- lldb/trunk/source/Host/posix/ProcessLauncherPosix.cpp (original)
+++ lldb/trunk/source/Host/posix/ProcessLauncherPosix.cpp (removed)
@@ -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);
-}

Modified: lldb/trunk/unittests/tools/lldb-server/tests/TestClient.cpp
URL: http://llvm.org/viewvc/llvm-project/lldb/trunk/unittests/tools/lldb-server/tests/TestClient.cpp?rev=305686&r1=305685&r2=305686&view=diff
==============================================================================
--- lldb/trunk/unittests/tools/lldb-server/tests/TestClient.cpp (original)
+++ lldb/trunk/unittests/tools/lldb-server/tests/TestClient.cpp Mon Jun 19 07:26:22 2017
@@ -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"




More information about the lldb-commits mailing list