[Lldb-commits] [lldb] r199856 - Unify OS X/POSIX/Linux Host spawn support.

Todd Fiala tfiala at google.com
Wed Jan 22 16:52:29 PST 2014


Author: tfiala
Date: Wed Jan 22 18:52:28 2014
New Revision: 199856

URL: http://llvm.org/viewvc/llvm-project?rev=199856&view=rev
Log:
Unify OS X/POSIX/Linux Host spawn support.

This fixes a bug under Linux where spawning a process via
Host::LaunchProcess was disabling all blockable signals on the
launched process.  This caused strange behavior when attempting
to kill the lldb-gdbserver process, as the child generally would
not die unless killed with a non-blockable signal (e.g. 'kill -9').

This change moves several functions out of macosx/Host.mm into
common/Host.cpp.  In addition, two functions that needed to work
across common/Host.cpp and macosx/Host.mm were moved into the Host.h
header file.

Modified:
    lldb/trunk/include/lldb/Host/Host.h
    lldb/trunk/source/Host/common/Host.cpp
    lldb/trunk/source/Host/macosx/Host.mm

Modified: lldb/trunk/include/lldb/Host/Host.h
URL: http://llvm.org/viewvc/llvm-project/lldb/trunk/include/lldb/Host/Host.h?rev=199856&r1=199855&r2=199856&view=diff
==============================================================================
--- lldb/trunk/include/lldb/Host/Host.h (original)
+++ lldb/trunk/include/lldb/Host/Host.h Wed Jan 22 18:52:28 2014
@@ -476,7 +476,15 @@ public:
 
     static bool
     GetProcessInfo (lldb::pid_t pid, ProcessInstanceInfo &proc_info);
-    
+
+#if defined (__APPLE__) || defined (__linux__) || defined (__FreeBSD__) || defined (__GLIBC__)
+    static short
+    GetPosixspawnFlags (ProcessLaunchInfo &launch_info);
+
+    static Error
+    LaunchProcessPosixSpawn (const char *exe_path, ProcessLaunchInfo &launch_info, ::pid_t &pid);
+#endif
+
     static lldb::pid_t
     LaunchApplication (const FileSpec &app_file_spec);
 

Modified: lldb/trunk/source/Host/common/Host.cpp
URL: http://llvm.org/viewvc/llvm-project/lldb/trunk/source/Host/common/Host.cpp?rev=199856&r1=199855&r2=199856&view=diff
==============================================================================
--- lldb/trunk/source/Host/common/Host.cpp (original)
+++ lldb/trunk/source/Host/common/Host.cpp Wed Jan 22 18:52:28 2014
@@ -38,7 +38,7 @@
 #include <AvailabilityMacros.h>
 #endif
 
-#if defined (__linux__) || defined (__FreeBSD__) || defined (__FreeBSD_kernel__)
+#if defined (__linux__) || defined (__FreeBSD__) || defined (__FreeBSD_kernel__) || defined (__APPLE__)
 #include <spawn.h>
 #include <sys/wait.h>
 #include <sys/syscall.h>
@@ -69,6 +69,18 @@
 #include "llvm/Support/Host.h"
 #include "llvm/Support/raw_ostream.h"
 
+#if defined (__APPLE__)
+#ifndef _POSIX_SPAWN_DISABLE_ASLR
+#define _POSIX_SPAWN_DISABLE_ASLR       0x0100
+#endif
+
+extern "C"
+{
+    int __pthread_chdir(const char *path);
+    int __pthread_fchdir (int fildes);
+}
+
+#endif
 
 using namespace lldb;
 using namespace lldb_private;
@@ -1637,24 +1649,73 @@ Host::RunShellCommand (const char *comma
     return error;
 }
 
-#if defined(__linux__) || defined(__FreeBSD__) || defined(__GLIBC__)
-// The functions below implement process launching via posix_spawn() for Linux
-// and FreeBSD.
 
-// The posix_spawn() and posix_spawnp() functions first appeared in FreeBSD 8.0,
-static Error
-LaunchProcessPosixSpawn (const char *exe_path, ProcessLaunchInfo &launch_info, ::pid_t &pid)
+// LaunchProcessPosixSpawn for Apple, Linux, FreeBSD and other GLIBC
+// systems
+
+#if defined (__APPLE__) || defined (__linux__) || defined (__FreeBSD__) || defined (__GLIBC__)
+
+// this method needs to be visible to macosx/Host.cpp and
+// common/Host.cpp.
+
+short
+Host::GetPosixspawnFlags (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 (Host::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;
+}
+
+Error
+Host::LaunchProcessPosixSpawn (const char *exe_path, ProcessLaunchInfo &launch_info, ::pid_t &pid)
 {
     Error error;
     Log *log(lldb_private::GetLogIfAllCategoriesSet (LIBLLDB_LOG_HOST | LIBLLDB_LOG_PROCESS));
 
-    assert(exe_path);
-    assert(!launch_info.GetFlags().Test (eLaunchFlagDebug));
-
     posix_spawnattr_t attr;
-
     error.SetError( ::posix_spawnattr_init (&attr), eErrorTypePOSIX);
-    error.LogIfError(log, "::posix_spawnattr_init ( &attr )");
+
+    if (error.Fail() || log)
+        error.PutToLog(log, "::posix_spawnattr_init ( &attr )");
     if (error.Fail())
         return error;
 
@@ -1666,52 +1727,82 @@ LaunchProcessPosixSpawn (const char *exe
     sigset_t all_signals;
     sigemptyset (&no_signals);
     sigfillset (&all_signals);
-    ::posix_spawnattr_setsigmask(&attr, &all_signals);
+    ::posix_spawnattr_setsigmask(&attr, &no_signals);
+#if defined (__linux__)
     ::posix_spawnattr_setsigdefault(&attr, &no_signals);
+#else
+    ::posix_spawnattr_setsigdefault(&attr, &all_signals);
+#endif
 
-    short flags = POSIX_SPAWN_SETSIGDEF | POSIX_SPAWN_SETSIGMASK;
+    short flags = GetPosixspawnFlags(launch_info);
 
     error.SetError( ::posix_spawnattr_setflags (&attr, flags), eErrorTypePOSIX);
-    error.LogIfError(log, "::posix_spawnattr_setflags ( &attr, flags=0x%8.8x )", flags);
+    if (error.Fail() || log)
+        error.PutToLog(log, "::posix_spawnattr_setflags ( &attr, flags=0x%8.8x )", flags);
     if (error.Fail())
         return error;
 
-    const size_t num_file_actions = launch_info.GetNumFileActions ();
-    posix_spawn_file_actions_t file_actions, *file_action_ptr = NULL;
-    // 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_action_ptr, NULL, posix_spawn_file_actions_destroy);
+    // 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__)
+
+    // 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 != UINT32_MAX &&
+        cpu != 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() || log)
+            error.PutToLog(log, "::posix_spawnattr_setbinpref_np ( &attr, 1, cpu_type = 0x%8.8x, count => %llu )", cpu, (uint64_t)ocount);
 
-    if (num_file_actions > 0)
-    {
-        error.SetError( ::posix_spawn_file_actions_init (&file_actions), eErrorTypePOSIX);
-        error.LogIfError(log, "::posix_spawn_file_actions_init ( &file_actions )");
-        if (error.Fail())
+        if (error.Fail() || ocount != 1)
             return error;
+    }
 
-        file_action_ptr = &file_actions;
-        posix_spawn_file_actions_cleanup.set(file_action_ptr);
+#endif
 
-        for (size_t i = 0; i < num_file_actions; ++i)
-        {
-            const ProcessLaunchInfo::FileAction *launch_file_action = launch_info.GetFileActionAtIndex(i);
-            if (launch_file_action &&
-                !ProcessLaunchInfo::FileAction::AddPosixSpawnFileAction (&file_actions,
-                                                                         launch_file_action,
-                                                                         log,
-                                                                         error))
-                return error;
-        }
+    const char *tmp_argv[2];
+    char * const *argv = (char * const*)launch_info.GetArguments().GetConstArgumentVector();
+    char * const *envp = (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 = (char * const*)tmp_argv;
     }
 
-    // Change working directory if neccessary.
+#if !defined (__APPLE__)
+    // manage the working directory
     char current_dir[PATH_MAX];
     current_dir[0] = '\0';
+#endif
 
     const char *working_dir = launch_info.GetWorkingDirectory();
-    if (working_dir != NULL)
+    if (working_dir)
     {
+#if defined (__APPLE__)
+        // Set the working directory on this thread only
+        if (__pthread_chdir (working_dir) < 0) {
+            if (errno == ENOENT) {
+                error.SetErrorStringWithFormat("No such file or directory: %s", working_dir);
+            } else if (errno == ENOTDIR) {
+                error.SetErrorStringWithFormat("Path doesn't name a directory: %s", working_dir);
+            } 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);
@@ -1725,45 +1816,111 @@ LaunchProcessPosixSpawn (const char *exe
             error.LogIfError(log, "unable to change working directory to %s", working_dir);
             return error;
         }
+#endif
     }
 
-    const char *tmp_argv[2];
-    char * const *argv = (char * const*)launch_info.GetArguments().GetConstArgumentVector();
-    char * const *envp = (char * const*)launch_info.GetEnvironmentEntries().GetConstArgumentVector();
+    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() || log)
+            error.PutToLog(log, "::posix_spawn_file_actions_init ( &file_actions )");
+        if (error.Fail())
+            return error;
 
-    // Prepare minimal argument list if we didn't get it from the launch_info structure.
-    // We must pass argv into posix_spawnp and it must contain at least two items -
-    // pointer to an executable and NULL.
-    if (argv == NULL)
+        // 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 ProcessLaunchInfo::FileAction *launch_file_action = launch_info.GetFileActionAtIndex(i);
+            if (launch_file_action)
+            {
+                if (!ProcessLaunchInfo::FileAction::AddPosixSpawnFileAction (&file_actions,
+                                                                             launch_file_action,
+                                                                             log,
+                                                                             error))
+                    return error;
+            }
+        }
+
+        error.SetError (::posix_spawnp (&pid,
+                                        exe_path,
+                                        &file_actions,
+                                        &attr,
+                                        argv,
+                                        envp),
+                        eErrorTypePOSIX);
+
+        if (error.Fail() || log)
+        {
+            error.PutToLog(log, "::posix_spawnp ( pid => %i, path = '%s', file_actions = %p, attr = %p, argv = %p, envp = %p )",
+                           pid,
+                           exe_path,
+                           &file_actions,
+                           &attr,
+                           argv,
+                           envp);
+            if (log)
+            {
+                for (int ii=0; argv[ii]; ++ii)
+                    log->Printf("argv[%i] = '%s'", ii, argv[ii]);
+            }
+        }
+
+    }
+    else
     {
-        tmp_argv[0] = exe_path;
-        tmp_argv[1] = NULL;
-        argv = (char * const*)tmp_argv;
+        error.SetError (::posix_spawnp (&pid,
+                                        exe_path,
+                                        NULL,
+                                        &attr,
+                                        argv,
+                                        envp),
+                        eErrorTypePOSIX);
+
+        if (error.Fail() || log)
+        {
+            error.PutToLog(log, "::posix_spawnp ( pid => %i, path = '%s', file_actions = NULL, attr = %p, argv = %p, envp = %p )",
+                           pid,
+                           exe_path,
+                           &attr,
+                           argv,
+                           envp);
+            if (log)
+            {
+                for (int ii=0; argv[ii]; ++ii)
+                    log->Printf("argv[%i] = '%s'", ii, argv[ii]);
+            }
+        }
     }
 
-    error.SetError (::posix_spawnp (&pid,
-                                    exe_path,
-                                    (num_file_actions > 0) ? &file_actions : NULL,
-                                    &attr,
-                                    argv,
-                                    envp),
-                    eErrorTypePOSIX);
-
-    error.LogIfError(log, "::posix_spawnp ( pid => %i, path = '%s', file_actions = %p, attr = %p, argv = %p, envp = %p )",
-                     pid, exe_path, file_action_ptr, &attr, argv, envp);
-
-    // Change back the current directory.
-    // NOTE: do not override previously established error from posix_spawnp.
-    if (working_dir != NULL && ::chdir(current_dir) == -1 && error.Success())
-    {
-        error.SetError(errno, eErrorTypePOSIX);
-        error.LogIfError(log, "unable to change current directory back to %s",
-                         current_dir);
+    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);
+            error.LogIfError(log, "unable to change current directory back to %s",
+                    current_dir);
+        }
+#endif
     }
 
     return error;
 }
 
+#endif // LaunchProcedssPosixSpawn: Apple, Linux, FreeBSD and other GLIBC systems
+
+
+#if defined(__linux__) || defined(__FreeBSD__) || defined(__GLIBC__)
+// The functions below implement process launching via posix_spawn() for Linux
+// and FreeBSD.
 
 Error
 Host::LaunchProcess (ProcessLaunchInfo &launch_info)
@@ -1815,6 +1972,8 @@ Host::LaunchProcess (ProcessLaunchInfo &
         // If all went well, then set the process ID into the launch info
         launch_info.SetProcessID(pid);
 
+        Log *log(lldb_private::GetLogIfAllCategoriesSet (LIBLLDB_LOG_PROCESS));
+
         // Make sure we reap any processes we spawn or we will have zombies.
         if (!launch_info.MonitorProcess())
         {
@@ -1823,6 +1982,13 @@ Host::LaunchProcess (ProcessLaunchInfo &
                                          NULL,
                                          pid,
                                          monitor_signals);
+            if (log)
+                log->PutCString ("monitored child process with default Process::SetProcessExitStatus.");
+        }
+        else
+        {
+            if (log)
+                log->PutCString ("monitored child process with user-specified process monitor.");
         }
     }
     else

Modified: lldb/trunk/source/Host/macosx/Host.mm
URL: http://llvm.org/viewvc/llvm-project/lldb/trunk/source/Host/macosx/Host.mm?rev=199856&r1=199855&r2=199856&view=diff
==============================================================================
--- lldb/trunk/source/Host/macosx/Host.mm (original)
+++ lldb/trunk/source/Host/macosx/Host.mm Wed Jan 22 18:52:28 2014
@@ -1318,51 +1318,6 @@ Host::GetProcessInfo (lldb::pid_t pid, P
     return false;
 }
 
-static short
-GetPosixspawnFlags (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 (__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 (Host::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
-    
-    return flags;
-}
-
 #if !NO_XPC_SERVICES
 static void
 PackageXPCArguments (xpc_object_t message, const char *prefix, const Args& args)
@@ -1543,7 +1498,7 @@ LaunchProcessXPC (const char *exe_path,
     
     // Posix spawn stuff.
     xpc_dictionary_set_int64(message, LauncherXPCServiceCPUTypeKey, launch_info.GetArchitecture().GetMachOCPUType());
-    xpc_dictionary_set_int64(message, LauncherXPCServicePosixspawnFlagsKey, GetPosixspawnFlags(launch_info));
+    xpc_dictionary_set_int64(message, LauncherXPCServicePosixspawnFlagsKey, Host::GetPosixspawnFlags(launch_info));
     
     xpc_object_t reply = xpc_connection_send_message_with_reply_sync(conn, message);
     xpc_type_t returnType = xpc_get_type(reply);
@@ -1586,178 +1541,6 @@ LaunchProcessXPC (const char *exe_path,
 #endif
 }
 
-static Error
-LaunchProcessPosixSpawn (const char *exe_path, ProcessLaunchInfo &launch_info, ::pid_t &pid)
-{
-    Error 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() || log)
-        error.PutToLog(log, "::posix_spawnattr_init ( &attr )");
-    if (error.Fail())
-        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() || log)
-        error.PutToLog(log, "::posix_spawnattr_setflags ( &attr, flags=0x%8.8x )", flags);
-    if (error.Fail())
-        return error;
-    
-#if !defined(__arm__)
-    
-    // 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 != UINT32_MAX && 
-        cpu != 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() || log)
-            error.PutToLog(log, "::posix_spawnattr_setbinpref_np ( &attr, 1, cpu_type = 0x%8.8x, count => %llu )", cpu, (uint64_t)ocount);
-        
-        if (error.Fail() || ocount != 1)
-            return error;
-    }
-    
-#endif
-    
-    const char *tmp_argv[2];
-    char * const *argv = (char * const*)launch_info.GetArguments().GetConstArgumentVector();
-    char * const *envp = (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 = (char * const*)tmp_argv;
-    }
-
-    const char *working_dir = launch_info.GetWorkingDirectory();
-    if (working_dir)
-    {
-        // No more thread specific current working directory
-        if (__pthread_chdir (working_dir) < 0) {
-            if (errno == ENOENT) {
-                error.SetErrorStringWithFormat("No such file or directory: %s", working_dir);
-            } else if (errno == ENOTDIR) {
-                error.SetErrorStringWithFormat("Path doesn't name a directory: %s", working_dir);
-            } else {
-                error.SetErrorStringWithFormat("An unknown error occurred when changing directory for process execution.");
-            }
-            return error;
-        }
-    }
-    
-    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() || log)
-            error.PutToLog(log, "::posix_spawn_file_actions_init ( &file_actions )");
-        if (error.Fail())
-            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 ProcessLaunchInfo::FileAction *launch_file_action = launch_info.GetFileActionAtIndex(i);
-            if (launch_file_action)
-            {
-                if (!ProcessLaunchInfo::FileAction::AddPosixSpawnFileAction (&file_actions,
-                                                                             launch_file_action,
-                                                                             log,
-                                                                             error))
-                    return error;
-            }
-        }
-        
-        error.SetError (::posix_spawnp (&pid, 
-                                        exe_path, 
-                                        &file_actions, 
-                                        &attr, 
-                                        argv,
-                                        envp),
-                        eErrorTypePOSIX);
-
-        if (error.Fail() || log)
-        {
-            error.PutToLog(log, "::posix_spawnp ( pid => %i, path = '%s', file_actions = %p, attr = %p, argv = %p, envp = %p )",
-                           pid, 
-                           exe_path, 
-                           &file_actions, 
-                           &attr, 
-                           argv, 
-                           envp);
-            if (log)
-            {
-                for (int ii=0; argv[ii]; ++ii)
-                    log->Printf("argv[%i] = '%s'", ii, argv[ii]);
-            }
-        }
-
-    }
-    else
-    {
-        error.SetError (::posix_spawnp (&pid, 
-                                        exe_path, 
-                                        NULL, 
-                                        &attr, 
-                                        argv,
-                                        envp),
-                        eErrorTypePOSIX);
-
-        if (error.Fail() || log)
-        {
-            error.PutToLog(log, "::posix_spawnp ( pid => %i, path = '%s', file_actions = NULL, attr = %p, argv = %p, envp = %p )",
-                           pid, 
-                           exe_path, 
-                           &attr, 
-                           argv, 
-                           envp);
-            if (log)
-            {
-                for (int ii=0; argv[ii]; ++ii)
-                    log->Printf("argv[%i] = '%s'", ii, argv[ii]);
-            }
-        }
-    }
-    
-    if (working_dir)
-    {
-        // No more thread specific current working directory
-        __pthread_fchdir (-1);
-    }
-    
-    return error;
-}
-
 static bool
 ShouldLaunchUsingXPC(ProcessLaunchInfo &launch_info)
 {





More information about the lldb-commits mailing list