aboutsummaryrefslogtreecommitdiff
path: root/source/Host/common/Host.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'source/Host/common/Host.cpp')
-rw-r--r--source/Host/common/Host.cpp471
1 files changed, 84 insertions, 387 deletions
diff --git a/source/Host/common/Host.cpp b/source/Host/common/Host.cpp
index 00c2fa37b383..c8daa175d1bd 100644
--- a/source/Host/common/Host.cpp
+++ b/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)
{