diff options
Diffstat (limited to 'contrib/llvm/tools/lldb/source/Host/common/Host.cpp')
-rw-r--r-- | contrib/llvm/tools/lldb/source/Host/common/Host.cpp | 471 |
1 files changed, 84 insertions, 387 deletions
diff --git a/contrib/llvm/tools/lldb/source/Host/common/Host.cpp b/contrib/llvm/tools/lldb/source/Host/common/Host.cpp index 00c2fa37b383..c8daa175d1bd 100644 --- a/contrib/llvm/tools/lldb/source/Host/common/Host.cpp +++ b/contrib/llvm/tools/lldb/source/Host/common/Host.cpp @@ -14,11 +14,7 @@ #include <limits.h> #include <stdlib.h> #include <sys/types.h> -#ifdef _WIN32 -#include "lldb/Host/windows/windows.h" -#include <winsock2.h> -#include <ws2tcpip.h> -#else +#ifndef _WIN32 #include <unistd.h> #include <dlfcn.h> #include <grp.h> @@ -27,11 +23,6 @@ #include <sys/stat.h> #endif -#if !defined (__GNU__) && !defined (_WIN32) -// Does not exist under GNU/HURD or Windows -#include <sys/sysctl.h> -#endif - #if defined (__APPLE__) #include <mach/mach_port.h> #include <mach/mach_init.h> @@ -39,7 +30,9 @@ #endif #if defined (__linux__) || defined (__FreeBSD__) || defined (__FreeBSD_kernel__) || defined (__APPLE__) || defined(__NetBSD__) +#if !defined(__ANDROID__) && !defined(__ANDROID_NDK__) #include <spawn.h> +#endif #include <sys/wait.h> #include <sys/syscall.h> #endif @@ -51,33 +44,30 @@ // C++ includes #include <limits> +#include "lldb/Host/FileSystem.h" #include "lldb/Host/Host.h" #include "lldb/Host/HostInfo.h" #include "lldb/Core/ArchSpec.h" -#include "lldb/Core/ConstString.h" #include "lldb/Core/Debugger.h" #include "lldb/Core/Error.h" #include "lldb/Core/Log.h" #include "lldb/Core/Module.h" -#include "lldb/Core/StreamString.h" -#include "lldb/Core/ThreadSafeSTLMap.h" -#include "lldb/Host/Config.h" -#include "lldb/Host/Endian.h" #include "lldb/Host/FileSpec.h" -#include "lldb/Host/FileSystem.h" -#include "lldb/Host/Mutex.h" +#include "lldb/Host/HostProcess.h" +#include "lldb/Host/MonitoringProcessLauncher.h" +#include "lldb/Host/ProcessLauncher.h" +#include "lldb/Host/ThreadLauncher.h" #include "lldb/lldb-private-forward.h" #include "lldb/Target/FileAction.h" -#include "lldb/Target/Process.h" #include "lldb/Target/ProcessLaunchInfo.h" #include "lldb/Target/TargetList.h" #include "lldb/Utility/CleanUp.h" -#include "llvm/ADT/STLExtras.h" -#include "llvm/ADT/SmallString.h" -#include "llvm/Support/Host.h" -#include "llvm/Support/Path.h" -#include "llvm/Support/raw_ostream.h" +#if defined(_WIN32) +#include "lldb/Host/windows/ProcessLauncherWindows.h" +#else +#include "lldb/Host/posix/ProcessLauncherPosix.h" +#endif #if defined (__APPLE__) #ifndef _POSIX_SPAWN_DISABLE_ASLR @@ -95,13 +85,6 @@ extern "C" using namespace lldb; using namespace lldb_private; -// Define maximum thread name length -#if defined (__linux__) || defined (__FreeBSD__) || defined (__FreeBSD_kernel__) || defined (__NetBSD__) -uint32_t const Host::MAX_THREAD_NAME_LENGTH = 16; -#else -uint32_t const Host::MAX_THREAD_NAME_LENGTH = std::numeric_limits<uint32_t>::max (); -#endif - #if !defined (__APPLE__) && !defined (_WIN32) struct MonitorInfo { @@ -114,16 +97,9 @@ struct MonitorInfo static thread_result_t MonitorChildProcessThreadFunction (void *arg); -lldb::thread_t -Host::StartMonitoringChildProcess -( - Host::MonitorChildProcessCallback callback, - void *callback_baton, - lldb::pid_t pid, - bool monitor_signals -) +HostThread +Host::StartMonitoringChildProcess(Host::MonitorChildProcessCallback callback, void *callback_baton, lldb::pid_t pid, bool monitor_signals) { - lldb::thread_t thread = LLDB_INVALID_HOST_THREAD; MonitorInfo * info_ptr = new MonitorInfo(); info_ptr->pid = pid; @@ -132,26 +108,11 @@ Host::StartMonitoringChildProcess info_ptr->monitor_signals = monitor_signals; char thread_name[256]; - - if (Host::MAX_THREAD_NAME_LENGTH <= 16) - { - // On some platforms, the thread name is limited to 16 characters. We need to - // abbreviate there or the pid info would get truncated. - ::snprintf (thread_name, sizeof(thread_name), "wait4(%" PRIu64 ")", pid); - } - else - { - ::snprintf (thread_name, sizeof(thread_name), "<lldb.host.wait4(pid=%" PRIu64 ")>", pid); - } - - thread = ThreadCreate (thread_name, - MonitorChildProcessThreadFunction, - info_ptr, - NULL); - - return thread; + ::snprintf(thread_name, sizeof(thread_name), "<lldb.host.wait4(pid=%" PRIu64 ")>", pid); + return ThreadLauncher::LaunchThread(thread_name, MonitorChildProcessThreadFunction, info_ptr, NULL); } +#if !defined(__ANDROID__) && !defined(__ANDROID_NDK__) //------------------------------------------------------------------ // Scoped class that will disable thread canceling when it is // constructed, and exception safely restore the previous value it @@ -166,7 +127,6 @@ public: int err = ::pthread_setcancelstate (PTHREAD_CANCEL_DISABLE, &m_old_state); if (err != 0) m_old_state = -1; - } ~ScopedPThreadCancelDisabler() @@ -179,6 +139,7 @@ public: private: int m_old_state; // Save the old cancelability state. }; +#endif // __ANDROID_NDK__ static thread_result_t MonitorChildProcessThreadFunction (void *arg) @@ -212,11 +173,14 @@ MonitorChildProcessThreadFunction (void *arg) log->Printf("%s ::wait_pid (pid = %" PRIi32 ", &status, options = %i)...", function, pid, options); // Wait for all child processes +#if !defined(__ANDROID__) && !defined(__ANDROID_NDK__) ::pthread_testcancel (); +#endif // Get signals from all children with same process group of pid const ::pid_t wait_pid = ::waitpid (pid, &status, options); +#if !defined(__ANDROID__) && !defined(__ANDROID_NDK__) ::pthread_testcancel (); - +#endif if (wait_pid == -1) { if (errno == EINTR) @@ -261,7 +225,9 @@ MonitorChildProcessThreadFunction (void *arg) // Scope for pthread_cancel_disabler { +#if !defined(__ANDROID__) && !defined(__ANDROID_NDK__) ScopedPThreadCancelDisabler pthread_cancel_disabler; +#endif log = lldb_private::GetLogIfAllCategoriesSet (LIBLLDB_LOG_PROCESS); if (log) @@ -349,6 +315,8 @@ Host::GetCurrentThreadID() return thread_self; #elif defined(__FreeBSD__) return lldb::tid_t(pthread_getthreadid_np()); +#elif defined(__ANDROID_NDK__) + return lldb::tid_t(gettid()); #elif defined(__linux__) return lldb::tid_t(syscall(SYS_gettid)); #else @@ -429,11 +397,6 @@ Host::WillTerminate () #if !defined (__APPLE__) && !defined (__FreeBSD__) && !defined (__FreeBSD_kernel__) && !defined (__linux__) // see macosx/Host.mm void -Host::ThreadCreated (const char *thread_name) -{ -} - -void Host::Backtrace (Stream &strm, uint32_t max_frames) { // TODO: Is there a way to backtrace the current process on other systems? @@ -448,101 +411,8 @@ Host::GetEnvironment (StringList &env) #endif // #if !defined (__APPLE__) && !defined (__FreeBSD__) && !defined (__FreeBSD_kernel__) && !defined (__linux__) -struct HostThreadCreateInfo -{ - std::string thread_name; - thread_func_t thread_fptr; - thread_arg_t thread_arg; - - HostThreadCreateInfo (const char *name, thread_func_t fptr, thread_arg_t arg) : - thread_name (name ? name : ""), - thread_fptr (fptr), - thread_arg (arg) - { - } -}; - -static thread_result_t -#ifdef _WIN32 -__stdcall -#endif -ThreadCreateTrampoline (thread_arg_t arg) -{ - HostThreadCreateInfo *info = (HostThreadCreateInfo *)arg; - Host::ThreadCreated (info->thread_name.c_str()); - thread_func_t thread_fptr = info->thread_fptr; - thread_arg_t thread_arg = info->thread_arg; - - Log *log(lldb_private::GetLogIfAllCategoriesSet (LIBLLDB_LOG_THREAD)); - if (log) - log->Printf("thread created"); - - delete info; - return thread_fptr (thread_arg); -} - -lldb::thread_t -Host::ThreadCreate -( - const char *thread_name, - thread_func_t thread_fptr, - thread_arg_t thread_arg, - Error *error -) -{ - lldb::thread_t thread = LLDB_INVALID_HOST_THREAD; - - // Host::ThreadCreateTrampoline will delete this pointer for us. - HostThreadCreateInfo *info_ptr = new HostThreadCreateInfo (thread_name, thread_fptr, thread_arg); - -#ifdef _WIN32 - thread = ::_beginthreadex(0, 0, ThreadCreateTrampoline, info_ptr, 0, NULL); - int err = thread <= 0 ? GetLastError() : 0; -#else - int err = ::pthread_create (&thread, NULL, ThreadCreateTrampoline, info_ptr); -#endif - if (err == 0) - { - if (error) - error->Clear(); - return thread; - } - - if (error) - error->SetError (err, eErrorTypePOSIX); - - return LLDB_INVALID_HOST_THREAD; -} - #ifndef _WIN32 -bool -Host::ThreadCancel (lldb::thread_t thread, Error *error) -{ - int err = ::pthread_cancel (thread); - if (error) - error->SetError(err, eErrorTypePOSIX); - return err == 0; -} - -bool -Host::ThreadDetach (lldb::thread_t thread, Error *error) -{ - int err = ::pthread_detach (thread); - if (error) - error->SetError(err, eErrorTypePOSIX); - return err == 0; -} - -bool -Host::ThreadJoin (lldb::thread_t thread, thread_result_t *thread_result_ptr, Error *error) -{ - int err = ::pthread_join (thread, thread_result_ptr); - if (error) - error->SetError(err, eErrorTypePOSIX); - return err == 0; -} - lldb::thread_key_t Host::ThreadLocalStorageCreate(ThreadLocalStorageCleanupCallback callback) { @@ -563,99 +433,6 @@ Host::ThreadLocalStorageSet(lldb::thread_key_t key, void *value) ::pthread_setspecific (key, value); } -bool -Host::SetThreadName (lldb::pid_t pid, lldb::tid_t tid, const char *name) -{ -#if defined(__APPLE__) && MAC_OS_X_VERSION_MAX_ALLOWED > MAC_OS_X_VERSION_10_5 - lldb::pid_t curr_pid = Host::GetCurrentProcessID(); - lldb::tid_t curr_tid = Host::GetCurrentThreadID(); - if (pid == LLDB_INVALID_PROCESS_ID) - pid = curr_pid; - - if (tid == LLDB_INVALID_THREAD_ID) - tid = curr_tid; - - // Set the pthread name if possible - if (pid == curr_pid && tid == curr_tid) - { - if (::pthread_setname_np (name) == 0) - return true; - } - return false; -#elif defined (__FreeBSD__) - lldb::pid_t curr_pid = Host::GetCurrentProcessID(); - lldb::tid_t curr_tid = Host::GetCurrentThreadID(); - if (pid == LLDB_INVALID_PROCESS_ID) - pid = curr_pid; - - if (tid == LLDB_INVALID_THREAD_ID) - tid = curr_tid; - - // Set the pthread name if possible - if (pid == curr_pid && tid == curr_tid) - { - ::pthread_set_name_np (::pthread_self(), name); - return true; - } - return false; -#elif defined (__linux__) || defined (__GLIBC__) - void *fn = dlsym (RTLD_DEFAULT, "pthread_setname_np"); - if (fn) - { - lldb::pid_t curr_pid = Host::GetCurrentProcessID(); - lldb::tid_t curr_tid = Host::GetCurrentThreadID(); - if (pid == LLDB_INVALID_PROCESS_ID) - pid = curr_pid; - - if (tid == LLDB_INVALID_THREAD_ID) - tid = curr_tid; - - if (pid == curr_pid && tid == curr_tid) - { - int (*pthread_setname_np_func)(pthread_t thread, const char *name); - *reinterpret_cast<void **> (&pthread_setname_np_func) = fn; - - if (pthread_setname_np_func (::pthread_self(), name) == 0) - return true; - } - } - return false; -#else - return false; -#endif -} - -bool -Host::SetShortThreadName (lldb::pid_t pid, lldb::tid_t tid, - const char *thread_name, size_t len) -{ - std::unique_ptr<char[]> namebuf(new char[len+1]); - - // Thread names are coming in like '<lldb.comm.debugger.edit>' and - // '<lldb.comm.debugger.editline>'. So just chopping the end of the string - // off leads to a lot of similar named threads. Go through the thread name - // and search for the last dot and use that. - const char *lastdot = ::strrchr (thread_name, '.'); - - if (lastdot && lastdot != thread_name) - thread_name = lastdot + 1; - ::strncpy (namebuf.get(), thread_name, len); - namebuf[len] = 0; - - int namebuflen = strlen(namebuf.get()); - if (namebuflen > 0) - { - if (namebuf[namebuflen - 1] == '(' || namebuf[namebuflen - 1] == '>') - { - // Trim off trailing '(' and '>' characters for a bit more cleanup. - namebuflen--; - namebuf[namebuflen] = 0; - } - return Host::SetThreadName (pid, tid, namebuf.get()); - } - return false; -} - #endif #if !defined (__APPLE__) // see Host.mm @@ -680,12 +457,16 @@ FileSpec Host::GetModuleFileSpecForHostAddress (const void *host_addr) { FileSpec module_filespec; +#if !defined(__ANDROID__) && !defined(__ANDROID_NDK__) Dl_info info; if (::dladdr (host_addr, &info)) { if (info.dli_fname) module_filespec.SetFile(info.dli_fname, true); } +#else + assert(false && "dladdr() not supported on Android"); +#endif return module_filespec; } @@ -699,28 +480,6 @@ Host::FindProcessThreads (const lldb::pid_t pid, TidMap &tids_to_attach) } #endif -lldb::TargetSP -Host::GetDummyTarget (lldb_private::Debugger &debugger) -{ - static TargetSP g_dummy_target_sp; - - // FIXME: Maybe the dummy target should be per-Debugger - if (!g_dummy_target_sp || !g_dummy_target_sp->IsValid()) - { - ArchSpec arch(Target::GetDefaultArchitecture()); - if (!arch.IsValid()) - arch = HostInfo::GetArchitecture(); - Error err = debugger.GetTargetList().CreateTarget(debugger, - NULL, - arch.GetTriple().getTriple().c_str(), - false, - NULL, - g_dummy_target_sp); - } - - return g_dummy_target_sp; -} - struct ShellInfo { ShellInfo () : @@ -770,14 +529,15 @@ Host::RunShellCommand (const char *command, int *signo_ptr, std::string *command_output_ptr, uint32_t timeout_sec, - const char *shell) + bool run_in_default_shell) { Error error; ProcessLaunchInfo launch_info; - if (shell && shell[0]) + launch_info.SetArchitecture(HostInfo::GetArchitecture()); + if (run_in_default_shell) { // Run the command in a shell - launch_info.SetShell(shell); + launch_info.SetShell(HostInfo::GetDefaultShell()); launch_info.GetArguments().AppendArgument(command); const bool localhost = true; const bool will_debug = false; @@ -798,9 +558,8 @@ Host::RunShellCommand (const char *command, if (working_dir) launch_info.SetWorkingDirectory(working_dir); - char output_file_path_buffer[PATH_MAX]; - const char *output_file_path = NULL; - + llvm::SmallString<PATH_MAX> output_file_path; + if (command_output_ptr) { // Create a temporary file to get the stdout/stderr and redirect the @@ -809,21 +568,19 @@ Host::RunShellCommand (const char *command, FileSpec tmpdir_file_spec; if (HostInfo::GetLLDBPath(ePathTypeLLDBTempSystemDir, tmpdir_file_spec)) { - tmpdir_file_spec.AppendPathComponent("lldb-shell-output.XXXXXX"); - strncpy(output_file_path_buffer, tmpdir_file_spec.GetPath().c_str(), sizeof(output_file_path_buffer)); + tmpdir_file_spec.AppendPathComponent("lldb-shell-output.%%%%%%"); + llvm::sys::fs::createUniqueFile(tmpdir_file_spec.GetPath().c_str(), output_file_path); } else { - strncpy(output_file_path_buffer, "/tmp/lldb-shell-output.XXXXXX", sizeof(output_file_path_buffer)); + llvm::sys::fs::createTemporaryFile("lldb-shell-output.%%%%%%", "", output_file_path); } - - output_file_path = ::mktemp(output_file_path_buffer); } launch_info.AppendSuppressFileAction (STDIN_FILENO, true, false); - if (output_file_path) + if (!output_file_path.empty()) { - launch_info.AppendOpenFileAction(STDOUT_FILENO, output_file_path, false, true); + launch_info.AppendOpenFileAction(STDOUT_FILENO, output_file_path.c_str(), false, true); launch_info.AppendDuplicateFileAction(STDOUT_FILENO, STDERR_FILENO); } else @@ -882,7 +639,7 @@ Host::RunShellCommand (const char *command, if (command_output_ptr) { command_output_ptr->clear(); - FileSpec file_spec(output_file_path, File::eOpenOptionRead); + FileSpec file_spec(output_file_path.c_str(), File::eOpenOptionRead); uint64_t file_size = file_spec.GetByteSize(); if (file_size > 0) { @@ -901,8 +658,9 @@ Host::RunShellCommand (const char *command, shell_info->can_delete.SetValue(true, eBroadcastAlways); } - if (output_file_path) - ::unlink (output_file_path); + FileSpec output_file_spec(output_file_path.c_str(), false); + if (FileSystem::GetFileExists(output_file_spec)) + FileSystem::Unlink(output_file_path.c_str()); // Handshake with the monitor thread, or just let it know in advance that // it can delete "shell_info" in case we timed out and were not able to kill // the process... @@ -914,13 +672,13 @@ Host::RunShellCommand (const char *command, // systems #if defined (__APPLE__) || defined (__linux__) || defined (__FreeBSD__) || defined (__GLIBC__) || defined(__NetBSD__) - // this method needs to be visible to macosx/Host.cpp and // common/Host.cpp. short -Host::GetPosixspawnFlags (ProcessLaunchInfo &launch_info) +Host::GetPosixspawnFlags(const ProcessLaunchInfo &launch_info) { +#if !defined(__ANDROID__) && !defined(__ANDROID_NDK__) short flags = POSIX_SPAWN_SETSIGDEF | POSIX_SPAWN_SETSIGMASK; #if defined (__APPLE__) @@ -963,12 +721,17 @@ Host::GetPosixspawnFlags (ProcessLaunchInfo &launch_info) #endif #endif // #if defined (__APPLE__) return flags; +#else + assert(false && "Host::GetPosixspawnFlags() not supported on Android"); + return 0; +#endif } Error -Host::LaunchProcessPosixSpawn (const char *exe_path, ProcessLaunchInfo &launch_info, ::pid_t &pid) +Host::LaunchProcessPosixSpawn(const char *exe_path, const ProcessLaunchInfo &launch_info, lldb::pid_t &pid) { Error error; +#if !defined(__ANDROID__) && !defined(__ANDROID_NDK__) Log *log(lldb_private::GetLogIfAllCategoriesSet (LIBLLDB_LOG_HOST | LIBLLDB_LOG_PROCESS)); posix_spawnattr_t attr; @@ -1086,6 +849,7 @@ Host::LaunchProcessPosixSpawn (const char *exe_path, ProcessLaunchInfo &launch_i #endif } + ::pid_t result_pid = LLDB_INVALID_PROCESS_ID; const size_t num_file_actions = launch_info.GetNumFileActions (); if (num_file_actions > 0) { @@ -1110,21 +874,13 @@ Host::LaunchProcessPosixSpawn (const char *exe_path, ProcessLaunchInfo &launch_i } } - error.SetError (::posix_spawnp (&pid, - exe_path, - &file_actions, - &attr, - argv, - envp), - eErrorTypePOSIX); + error.SetError(::posix_spawnp(&result_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, static_cast<void*>(&file_actions), - static_cast<void*>(&attr), - reinterpret_cast<const void*>(argv), - reinterpret_cast<const void*>(envp)); + error.PutToLog(log, "::posix_spawnp ( pid => %i, path = '%s', file_actions = %p, attr = %p, argv = %p, envp = %p )", result_pid, + exe_path, static_cast<void *>(&file_actions), static_cast<void *>(&attr), reinterpret_cast<const void *>(argv), + reinterpret_cast<const void *>(envp)); if (log) { for (int ii=0; argv[ii]; ++ii) @@ -1135,20 +891,13 @@ Host::LaunchProcessPosixSpawn (const char *exe_path, ProcessLaunchInfo &launch_i } else { - error.SetError (::posix_spawnp (&pid, - exe_path, - NULL, - &attr, - argv, - envp), - eErrorTypePOSIX); + error.SetError(::posix_spawnp(&result_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, static_cast<void*>(&attr), - reinterpret_cast<const void*>(argv), - reinterpret_cast<const void*>(envp)); + result_pid, exe_path, static_cast<void *>(&attr), reinterpret_cast<const void *>(argv), + reinterpret_cast<const void *>(envp)); if (log) { for (int ii=0; argv[ii]; ++ii) @@ -1156,6 +905,7 @@ Host::LaunchProcessPosixSpawn (const char *exe_path, ProcessLaunchInfo &launch_i } } } + pid = result_pid; if (working_dir) { @@ -1171,6 +921,9 @@ Host::LaunchProcessPosixSpawn (const char *exe_path, ProcessLaunchInfo &launch_i } #endif } +#else + error.SetErrorString("Host::LaunchProcessPosixSpawn() not supported on Android"); +#endif return error; } @@ -1178,6 +931,7 @@ Host::LaunchProcessPosixSpawn (const char *exe_path, ProcessLaunchInfo &launch_i bool Host::AddPosixSpawnFileAction(void *_file_actions, const FileAction *info, Log *log, Error &error) { +#if !defined(__ANDROID__) && !defined(__ANDROID_NDK__) if (info == NULL) return false; @@ -1240,97 +994,40 @@ Host::AddPosixSpawnFileAction(void *_file_actions, const FileAction *info, Log * break; } return error.Success(); +#else + error.SetErrorString("Host::AddPosixSpawnFileAction() not supported on Android"); + return false; +#endif } - #endif // LaunchProcedssPosixSpawn: Apple, Linux, FreeBSD and other GLIBC systems - -#if 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. Error Host::LaunchProcess (ProcessLaunchInfo &launch_info) { - Error error; - char exe_path[PATH_MAX]; - - PlatformSP host_platform_sp (Platform::GetDefaultPlatform ()); - - const ArchSpec &arch_spec = launch_info.GetArchitecture(); - - FileSpec exe_spec(launch_info.GetExecutableFile()); - - FileSpec::FileType file_type = exe_spec.GetFileType(); - if (file_type != FileSpec::eFileTypeRegular) - { - lldb::ModuleSP exe_module_sp; - error = host_platform_sp->ResolveExecutable (exe_spec, - arch_spec, - exe_module_sp, - NULL); - - if (error.Fail()) - return error; - - if (exe_module_sp) - exe_spec = exe_module_sp->GetFileSpec(); - } - - if (exe_spec.Exists()) - { - exe_spec.GetPath (exe_path, sizeof(exe_path)); - } - else - { - launch_info.GetExecutableFile().GetPath (exe_path, sizeof(exe_path)); - error.SetErrorStringWithFormat ("executable doesn't exist: '%s'", exe_path); - return error; - } - - assert(!launch_info.GetFlags().Test (eLaunchFlagLaunchInTTY)); - - ::pid_t pid = LLDB_INVALID_PROCESS_ID; - - error = LaunchProcessPosixSpawn(exe_path, launch_info, pid); + std::unique_ptr<ProcessLauncher> delegate_launcher; +#if defined(_WIN32) + delegate_launcher.reset(new ProcessLauncherWindows()); +#else + delegate_launcher.reset(new ProcessLauncherPosix()); +#endif + MonitoringProcessLauncher launcher(std::move(delegate_launcher)); - if (pid != LLDB_INVALID_PROCESS_ID) - { - // If all went well, then set the process ID into the launch info - launch_info.SetProcessID(pid); + Error error; + HostProcess process = launcher.LaunchProcess(launch_info, error); - Log *log(lldb_private::GetLogIfAllCategoriesSet (LIBLLDB_LOG_PROCESS)); + // TODO(zturner): It would be better if the entire HostProcess were returned instead of writing + // it into this structure. + launch_info.SetProcessID(process.GetProcessId()); - // Make sure we reap any processes we spawn or we will have zombies. - if (!launch_info.MonitorProcess()) - { - const bool monitor_signals = false; - StartMonitoringChildProcess (Process::SetProcessExitStatus, - 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 - { - // Invalid process ID, something didn't go well - if (error.Success()) - error.SetErrorString ("process launch failed for unknown reasons"); - } return error; } - #endif // defined(__linux__) || defined(__FreeBSD__) || defined(__NetBSD__) #ifndef _WIN32 - void Host::Kill(lldb::pid_t pid, int signo) { |