Host.cpp revision 280031
1254721Semaste//===-- Host.cpp ------------------------------------------------*- C++ -*-===// 2254721Semaste// 3254721Semaste// The LLVM Compiler Infrastructure 4254721Semaste// 5254721Semaste// This file is distributed under the University of Illinois Open Source 6254721Semaste// License. See LICENSE.TXT for details. 7254721Semaste// 8254721Semaste//===----------------------------------------------------------------------===// 9254721Semaste 10254721Semaste#include "lldb/lldb-python.h" 11254721Semaste 12254721Semaste// C includes 13258054Semaste#include <errno.h> 14258054Semaste#include <limits.h> 15276479Sdim#include <stdlib.h> 16258054Semaste#include <sys/types.h> 17280031Sdim#ifndef _WIN32 18262528Semaste#include <unistd.h> 19254721Semaste#include <dlfcn.h> 20254721Semaste#include <grp.h> 21254721Semaste#include <netdb.h> 22254721Semaste#include <pwd.h> 23258884Semaste#include <sys/stat.h> 24258054Semaste#endif 25258054Semaste 26254721Semaste#if defined (__APPLE__) 27258054Semaste#include <mach/mach_port.h> 28258054Semaste#include <mach/mach_init.h> 29254721Semaste#include <mach-o/dyld.h> 30254721Semaste#endif 31254721Semaste 32276479Sdim#if defined (__linux__) || defined (__FreeBSD__) || defined (__FreeBSD_kernel__) || defined (__APPLE__) || defined(__NetBSD__) 33280031Sdim#if !defined(__ANDROID__) && !defined(__ANDROID_NDK__) 34258054Semaste#include <spawn.h> 35280031Sdim#endif 36254721Semaste#include <sys/wait.h> 37254721Semaste#include <sys/syscall.h> 38254721Semaste#endif 39254721Semaste 40254721Semaste#if defined (__FreeBSD__) 41254721Semaste#include <pthread_np.h> 42254721Semaste#endif 43254721Semaste 44276479Sdim// C++ includes 45276479Sdim#include <limits> 46276479Sdim 47280031Sdim#include "lldb/Host/FileSystem.h" 48254721Semaste#include "lldb/Host/Host.h" 49276479Sdim#include "lldb/Host/HostInfo.h" 50254721Semaste#include "lldb/Core/ArchSpec.h" 51254721Semaste#include "lldb/Core/Debugger.h" 52254721Semaste#include "lldb/Core/Error.h" 53254721Semaste#include "lldb/Core/Log.h" 54258054Semaste#include "lldb/Core/Module.h" 55254721Semaste#include "lldb/Host/FileSpec.h" 56280031Sdim#include "lldb/Host/HostProcess.h" 57280031Sdim#include "lldb/Host/MonitoringProcessLauncher.h" 58280031Sdim#include "lldb/Host/ProcessLauncher.h" 59280031Sdim#include "lldb/Host/ThreadLauncher.h" 60276479Sdim#include "lldb/lldb-private-forward.h" 61276479Sdim#include "lldb/Target/FileAction.h" 62276479Sdim#include "lldb/Target/ProcessLaunchInfo.h" 63254721Semaste#include "lldb/Target/TargetList.h" 64258054Semaste#include "lldb/Utility/CleanUp.h" 65254721Semaste 66280031Sdim#if defined(_WIN32) 67280031Sdim#include "lldb/Host/windows/ProcessLauncherWindows.h" 68280031Sdim#else 69280031Sdim#include "lldb/Host/posix/ProcessLauncherPosix.h" 70280031Sdim#endif 71254721Semaste 72262528Semaste#if defined (__APPLE__) 73262528Semaste#ifndef _POSIX_SPAWN_DISABLE_ASLR 74262528Semaste#define _POSIX_SPAWN_DISABLE_ASLR 0x0100 75262528Semaste#endif 76254721Semaste 77262528Semasteextern "C" 78262528Semaste{ 79262528Semaste int __pthread_chdir(const char *path); 80262528Semaste int __pthread_fchdir (int fildes); 81262528Semaste} 82262528Semaste 83262528Semaste#endif 84262528Semaste 85254721Semasteusing namespace lldb; 86254721Semasteusing namespace lldb_private; 87254721Semaste 88258054Semaste#if !defined (__APPLE__) && !defined (_WIN32) 89254721Semastestruct MonitorInfo 90254721Semaste{ 91254721Semaste lldb::pid_t pid; // The process ID to monitor 92254721Semaste Host::MonitorChildProcessCallback callback; // The callback function to call when "pid" exits or signals 93254721Semaste void *callback_baton; // The callback baton for the callback function 94254721Semaste bool monitor_signals; // If true, call the callback when "pid" gets signaled. 95254721Semaste}; 96254721Semaste 97258054Semastestatic thread_result_t 98254721SemasteMonitorChildProcessThreadFunction (void *arg); 99254721Semaste 100280031SdimHostThread 101280031SdimHost::StartMonitoringChildProcess(Host::MonitorChildProcessCallback callback, void *callback_baton, lldb::pid_t pid, bool monitor_signals) 102254721Semaste{ 103254721Semaste MonitorInfo * info_ptr = new MonitorInfo(); 104258054Semaste 105254721Semaste info_ptr->pid = pid; 106254721Semaste info_ptr->callback = callback; 107254721Semaste info_ptr->callback_baton = callback_baton; 108254721Semaste info_ptr->monitor_signals = monitor_signals; 109254721Semaste 110254721Semaste char thread_name[256]; 111280031Sdim ::snprintf(thread_name, sizeof(thread_name), "<lldb.host.wait4(pid=%" PRIu64 ")>", pid); 112280031Sdim return ThreadLauncher::LaunchThread(thread_name, MonitorChildProcessThreadFunction, info_ptr, NULL); 113254721Semaste} 114254721Semaste 115280031Sdim#if !defined(__ANDROID__) && !defined(__ANDROID_NDK__) 116254721Semaste//------------------------------------------------------------------ 117254721Semaste// Scoped class that will disable thread canceling when it is 118254721Semaste// constructed, and exception safely restore the previous value it 119254721Semaste// when it goes out of scope. 120254721Semaste//------------------------------------------------------------------ 121254721Semasteclass ScopedPThreadCancelDisabler 122254721Semaste{ 123254721Semastepublic: 124254721Semaste ScopedPThreadCancelDisabler() 125254721Semaste { 126254721Semaste // Disable the ability for this thread to be cancelled 127254721Semaste int err = ::pthread_setcancelstate (PTHREAD_CANCEL_DISABLE, &m_old_state); 128254721Semaste if (err != 0) 129254721Semaste m_old_state = -1; 130254721Semaste } 131254721Semaste 132254721Semaste ~ScopedPThreadCancelDisabler() 133254721Semaste { 134254721Semaste // Restore the ability for this thread to be cancelled to what it 135254721Semaste // previously was. 136254721Semaste if (m_old_state != -1) 137254721Semaste ::pthread_setcancelstate (m_old_state, 0); 138254721Semaste } 139254721Semasteprivate: 140254721Semaste int m_old_state; // Save the old cancelability state. 141254721Semaste}; 142280031Sdim#endif // __ANDROID_NDK__ 143254721Semaste 144258054Semastestatic thread_result_t 145254721SemasteMonitorChildProcessThreadFunction (void *arg) 146254721Semaste{ 147254721Semaste Log *log(lldb_private::GetLogIfAllCategoriesSet (LIBLLDB_LOG_PROCESS)); 148254721Semaste const char *function = __FUNCTION__; 149254721Semaste if (log) 150254721Semaste log->Printf ("%s (arg = %p) thread starting...", function, arg); 151254721Semaste 152254721Semaste MonitorInfo *info = (MonitorInfo *)arg; 153254721Semaste 154254721Semaste const Host::MonitorChildProcessCallback callback = info->callback; 155254721Semaste void * const callback_baton = info->callback_baton; 156254721Semaste const bool monitor_signals = info->monitor_signals; 157254721Semaste 158258054Semaste assert (info->pid <= UINT32_MAX); 159276479Sdim const ::pid_t pid = monitor_signals ? -1 * getpgid(info->pid) : info->pid; 160258054Semaste 161254721Semaste delete info; 162254721Semaste 163254721Semaste int status = -1; 164254721Semaste#if defined (__FreeBSD__) || defined (__FreeBSD_kernel__) 165254721Semaste #define __WALL 0 166254721Semaste#endif 167254721Semaste const int options = __WALL; 168254721Semaste 169254721Semaste while (1) 170254721Semaste { 171254721Semaste log = lldb_private::GetLogIfAllCategoriesSet (LIBLLDB_LOG_PROCESS); 172254721Semaste if (log) 173258054Semaste log->Printf("%s ::wait_pid (pid = %" PRIi32 ", &status, options = %i)...", function, pid, options); 174254721Semaste 175254721Semaste // Wait for all child processes 176280031Sdim#if !defined(__ANDROID__) && !defined(__ANDROID_NDK__) 177254721Semaste ::pthread_testcancel (); 178280031Sdim#endif 179254721Semaste // Get signals from all children with same process group of pid 180258054Semaste const ::pid_t wait_pid = ::waitpid (pid, &status, options); 181280031Sdim#if !defined(__ANDROID__) && !defined(__ANDROID_NDK__) 182254721Semaste ::pthread_testcancel (); 183280031Sdim#endif 184254721Semaste if (wait_pid == -1) 185254721Semaste { 186254721Semaste if (errno == EINTR) 187254721Semaste continue; 188254721Semaste else 189254721Semaste { 190254721Semaste if (log) 191254721Semaste log->Printf ("%s (arg = %p) thread exiting because waitpid failed (%s)...", __FUNCTION__, arg, strerror(errno)); 192254721Semaste break; 193254721Semaste } 194254721Semaste } 195254721Semaste else if (wait_pid > 0) 196254721Semaste { 197254721Semaste bool exited = false; 198254721Semaste int signal = 0; 199254721Semaste int exit_status = 0; 200254721Semaste const char *status_cstr = NULL; 201254721Semaste if (WIFSTOPPED(status)) 202254721Semaste { 203254721Semaste signal = WSTOPSIG(status); 204254721Semaste status_cstr = "STOPPED"; 205254721Semaste } 206254721Semaste else if (WIFEXITED(status)) 207254721Semaste { 208254721Semaste exit_status = WEXITSTATUS(status); 209254721Semaste status_cstr = "EXITED"; 210254721Semaste exited = true; 211254721Semaste } 212254721Semaste else if (WIFSIGNALED(status)) 213254721Semaste { 214254721Semaste signal = WTERMSIG(status); 215254721Semaste status_cstr = "SIGNALED"; 216258054Semaste if (wait_pid == abs(pid)) { 217254721Semaste exited = true; 218254721Semaste exit_status = -1; 219254721Semaste } 220254721Semaste } 221254721Semaste else 222254721Semaste { 223254721Semaste status_cstr = "(\?\?\?)"; 224254721Semaste } 225254721Semaste 226254721Semaste // Scope for pthread_cancel_disabler 227254721Semaste { 228280031Sdim#if !defined(__ANDROID__) && !defined(__ANDROID_NDK__) 229254721Semaste ScopedPThreadCancelDisabler pthread_cancel_disabler; 230280031Sdim#endif 231254721Semaste 232254721Semaste log = lldb_private::GetLogIfAllCategoriesSet (LIBLLDB_LOG_PROCESS); 233254721Semaste if (log) 234258054Semaste log->Printf ("%s ::waitpid (pid = %" PRIi32 ", &status, options = %i) => pid = %" PRIi32 ", status = 0x%8.8x (%s), signal = %i, exit_state = %i", 235254721Semaste function, 236254721Semaste wait_pid, 237254721Semaste options, 238254721Semaste pid, 239254721Semaste status, 240254721Semaste status_cstr, 241254721Semaste signal, 242254721Semaste exit_status); 243254721Semaste 244254721Semaste if (exited || (signal != 0 && monitor_signals)) 245254721Semaste { 246254721Semaste bool callback_return = false; 247254721Semaste if (callback) 248254721Semaste callback_return = callback (callback_baton, wait_pid, exited, signal, exit_status); 249254721Semaste 250254721Semaste // If our process exited, then this thread should exit 251258054Semaste if (exited && wait_pid == abs(pid)) 252254721Semaste { 253254721Semaste if (log) 254254721Semaste log->Printf ("%s (arg = %p) thread exiting because pid received exit signal...", __FUNCTION__, arg); 255254721Semaste break; 256254721Semaste } 257254721Semaste // If the callback returns true, it means this process should 258254721Semaste // exit 259254721Semaste if (callback_return) 260254721Semaste { 261254721Semaste if (log) 262254721Semaste log->Printf ("%s (arg = %p) thread exiting because callback returned true...", __FUNCTION__, arg); 263254721Semaste break; 264254721Semaste } 265254721Semaste } 266254721Semaste } 267254721Semaste } 268254721Semaste } 269254721Semaste 270254721Semaste log = lldb_private::GetLogIfAllCategoriesSet (LIBLLDB_LOG_PROCESS); 271254721Semaste if (log) 272254721Semaste log->Printf ("%s (arg = %p) thread exiting...", __FUNCTION__, arg); 273254721Semaste 274254721Semaste return NULL; 275254721Semaste} 276254721Semaste 277258054Semaste#endif // #if !defined (__APPLE__) && !defined (_WIN32) 278254721Semaste 279258054Semaste#if !defined (__APPLE__) 280258054Semaste 281254721Semastevoid 282254721SemasteHost::SystemLog (SystemLogType type, const char *format, va_list args) 283254721Semaste{ 284254721Semaste vfprintf (stderr, format, args); 285254721Semaste} 286254721Semaste 287258054Semaste#endif 288254721Semaste 289254721Semastevoid 290254721SemasteHost::SystemLog (SystemLogType type, const char *format, ...) 291254721Semaste{ 292254721Semaste va_list args; 293254721Semaste va_start (args, format); 294254721Semaste SystemLog (type, format, args); 295254721Semaste va_end (args); 296254721Semaste} 297254721Semaste 298254721Semastelldb::pid_t 299254721SemasteHost::GetCurrentProcessID() 300254721Semaste{ 301254721Semaste return ::getpid(); 302254721Semaste} 303254721Semaste 304258054Semaste#ifndef _WIN32 305258054Semaste 306254721Semastelldb::tid_t 307254721SemasteHost::GetCurrentThreadID() 308254721Semaste{ 309254721Semaste#if defined (__APPLE__) 310262528Semaste // Calling "mach_thread_self()" bumps the reference count on the thread 311254721Semaste // port, so we need to deallocate it. mach_task_self() doesn't bump the ref 312254721Semaste // count. 313254721Semaste thread_port_t thread_self = mach_thread_self(); 314254721Semaste mach_port_deallocate(mach_task_self(), thread_self); 315254721Semaste return thread_self; 316254721Semaste#elif defined(__FreeBSD__) 317254721Semaste return lldb::tid_t(pthread_getthreadid_np()); 318280031Sdim#elif defined(__ANDROID_NDK__) 319280031Sdim return lldb::tid_t(gettid()); 320254721Semaste#elif defined(__linux__) 321254721Semaste return lldb::tid_t(syscall(SYS_gettid)); 322254721Semaste#else 323254721Semaste return lldb::tid_t(pthread_self()); 324254721Semaste#endif 325254721Semaste} 326254721Semaste 327254721Semastelldb::thread_t 328254721SemasteHost::GetCurrentThread () 329254721Semaste{ 330254721Semaste return lldb::thread_t(pthread_self()); 331254721Semaste} 332254721Semaste 333254721Semasteconst char * 334254721SemasteHost::GetSignalAsCString (int signo) 335254721Semaste{ 336254721Semaste switch (signo) 337254721Semaste { 338254721Semaste case SIGHUP: return "SIGHUP"; // 1 hangup 339254721Semaste case SIGINT: return "SIGINT"; // 2 interrupt 340254721Semaste case SIGQUIT: return "SIGQUIT"; // 3 quit 341254721Semaste case SIGILL: return "SIGILL"; // 4 illegal instruction (not reset when caught) 342254721Semaste case SIGTRAP: return "SIGTRAP"; // 5 trace trap (not reset when caught) 343254721Semaste case SIGABRT: return "SIGABRT"; // 6 abort() 344262528Semaste#if defined(SIGPOLL) 345262528Semaste#if !defined(SIGIO) || (SIGPOLL != SIGIO) 346262528Semaste// Under some GNU/Linux, SIGPOLL and SIGIO are the same. Causing the build to 347262528Semaste// fail with 'multiple define cases with same value' 348254721Semaste case SIGPOLL: return "SIGPOLL"; // 7 pollable event ([XSR] generated, not supported) 349254721Semaste#endif 350262528Semaste#endif 351262528Semaste#if defined(SIGEMT) 352254721Semaste case SIGEMT: return "SIGEMT"; // 7 EMT instruction 353254721Semaste#endif 354254721Semaste case SIGFPE: return "SIGFPE"; // 8 floating point exception 355254721Semaste case SIGKILL: return "SIGKILL"; // 9 kill (cannot be caught or ignored) 356254721Semaste case SIGBUS: return "SIGBUS"; // 10 bus error 357254721Semaste case SIGSEGV: return "SIGSEGV"; // 11 segmentation violation 358254721Semaste case SIGSYS: return "SIGSYS"; // 12 bad argument to system call 359254721Semaste case SIGPIPE: return "SIGPIPE"; // 13 write on a pipe with no one to read it 360254721Semaste case SIGALRM: return "SIGALRM"; // 14 alarm clock 361254721Semaste case SIGTERM: return "SIGTERM"; // 15 software termination signal from kill 362254721Semaste case SIGURG: return "SIGURG"; // 16 urgent condition on IO channel 363254721Semaste case SIGSTOP: return "SIGSTOP"; // 17 sendable stop signal not from tty 364254721Semaste case SIGTSTP: return "SIGTSTP"; // 18 stop signal from tty 365254721Semaste case SIGCONT: return "SIGCONT"; // 19 continue a stopped process 366254721Semaste case SIGCHLD: return "SIGCHLD"; // 20 to parent on child stop or exit 367254721Semaste case SIGTTIN: return "SIGTTIN"; // 21 to readers pgrp upon background tty read 368254721Semaste case SIGTTOU: return "SIGTTOU"; // 22 like TTIN for output if (tp->t_local<OSTOP) 369262528Semaste#if defined(SIGIO) 370254721Semaste case SIGIO: return "SIGIO"; // 23 input/output possible signal 371254721Semaste#endif 372254721Semaste case SIGXCPU: return "SIGXCPU"; // 24 exceeded CPU time limit 373254721Semaste case SIGXFSZ: return "SIGXFSZ"; // 25 exceeded file size limit 374254721Semaste case SIGVTALRM: return "SIGVTALRM"; // 26 virtual time alarm 375254721Semaste case SIGPROF: return "SIGPROF"; // 27 profiling time alarm 376262528Semaste#if defined(SIGWINCH) 377254721Semaste case SIGWINCH: return "SIGWINCH"; // 28 window size changes 378262528Semaste#endif 379262528Semaste#if defined(SIGINFO) 380254721Semaste case SIGINFO: return "SIGINFO"; // 29 information request 381254721Semaste#endif 382254721Semaste case SIGUSR1: return "SIGUSR1"; // 30 user defined signal 1 383254721Semaste case SIGUSR2: return "SIGUSR2"; // 31 user defined signal 2 384254721Semaste default: 385254721Semaste break; 386254721Semaste } 387254721Semaste return NULL; 388254721Semaste} 389254721Semaste 390258054Semaste#endif 391258054Semaste 392254721Semastevoid 393254721SemasteHost::WillTerminate () 394254721Semaste{ 395254721Semaste} 396254721Semaste 397254721Semaste#if !defined (__APPLE__) && !defined (__FreeBSD__) && !defined (__FreeBSD_kernel__) && !defined (__linux__) // see macosx/Host.mm 398254721Semaste 399254721Semastevoid 400254721SemasteHost::Backtrace (Stream &strm, uint32_t max_frames) 401254721Semaste{ 402254721Semaste // TODO: Is there a way to backtrace the current process on other systems? 403254721Semaste} 404254721Semaste 405254721Semastesize_t 406254721SemasteHost::GetEnvironment (StringList &env) 407254721Semaste{ 408254721Semaste // TODO: Is there a way to the host environment for this process on other systems? 409254721Semaste return 0; 410254721Semaste} 411254721Semaste 412254721Semaste#endif // #if !defined (__APPLE__) && !defined (__FreeBSD__) && !defined (__FreeBSD_kernel__) && !defined (__linux__) 413254721Semaste 414258054Semaste#ifndef _WIN32 415258054Semaste 416258054Semastelldb::thread_key_t 417258054SemasteHost::ThreadLocalStorageCreate(ThreadLocalStorageCleanupCallback callback) 418258054Semaste{ 419258054Semaste pthread_key_t key; 420258054Semaste ::pthread_key_create (&key, callback); 421258054Semaste return key; 422258054Semaste} 423258054Semaste 424258054Semastevoid* 425258054SemasteHost::ThreadLocalStorageGet(lldb::thread_key_t key) 426258054Semaste{ 427258054Semaste return ::pthread_getspecific (key); 428258054Semaste} 429258054Semaste 430258054Semastevoid 431258054SemasteHost::ThreadLocalStorageSet(lldb::thread_key_t key, void *value) 432258054Semaste{ 433258054Semaste ::pthread_setspecific (key, value); 434258054Semaste} 435258054Semaste 436254721Semaste#endif 437254721Semaste 438254721Semaste#if !defined (__APPLE__) // see Host.mm 439254721Semaste 440254721Semastebool 441254721SemasteHost::GetBundleDirectory (const FileSpec &file, FileSpec &bundle) 442254721Semaste{ 443254721Semaste bundle.Clear(); 444254721Semaste return false; 445254721Semaste} 446254721Semaste 447254721Semastebool 448254721SemasteHost::ResolveExecutableInBundle (FileSpec &file) 449254721Semaste{ 450254721Semaste return false; 451254721Semaste} 452254721Semaste#endif 453254721Semaste 454258054Semaste#ifndef _WIN32 455258054Semaste 456258054SemasteFileSpec 457258054SemasteHost::GetModuleFileSpecForHostAddress (const void *host_addr) 458258054Semaste{ 459258054Semaste FileSpec module_filespec; 460280031Sdim#if !defined(__ANDROID__) && !defined(__ANDROID_NDK__) 461258054Semaste Dl_info info; 462258054Semaste if (::dladdr (host_addr, &info)) 463258054Semaste { 464258054Semaste if (info.dli_fname) 465258054Semaste module_filespec.SetFile(info.dli_fname, true); 466258054Semaste } 467280031Sdim#else 468280031Sdim assert(false && "dladdr() not supported on Android"); 469280031Sdim#endif 470258054Semaste return module_filespec; 471258054Semaste} 472258054Semaste 473258054Semaste#endif 474258054Semaste 475254721Semaste#if !defined(__linux__) 476254721Semastebool 477254721SemasteHost::FindProcessThreads (const lldb::pid_t pid, TidMap &tids_to_attach) 478254721Semaste{ 479254721Semaste return false; 480254721Semaste} 481254721Semaste#endif 482254721Semaste 483254721Semastestruct ShellInfo 484254721Semaste{ 485254721Semaste ShellInfo () : 486254721Semaste process_reaped (false), 487254721Semaste can_delete (false), 488254721Semaste pid (LLDB_INVALID_PROCESS_ID), 489254721Semaste signo(-1), 490254721Semaste status(-1) 491254721Semaste { 492254721Semaste } 493254721Semaste 494254721Semaste lldb_private::Predicate<bool> process_reaped; 495254721Semaste lldb_private::Predicate<bool> can_delete; 496254721Semaste lldb::pid_t pid; 497254721Semaste int signo; 498254721Semaste int status; 499254721Semaste}; 500254721Semaste 501254721Semastestatic bool 502254721SemasteMonitorShellCommand (void *callback_baton, 503254721Semaste lldb::pid_t pid, 504254721Semaste bool exited, // True if the process did exit 505254721Semaste int signo, // Zero for no signal 506254721Semaste int status) // Exit value of process if signal is zero 507254721Semaste{ 508254721Semaste ShellInfo *shell_info = (ShellInfo *)callback_baton; 509254721Semaste shell_info->pid = pid; 510254721Semaste shell_info->signo = signo; 511254721Semaste shell_info->status = status; 512254721Semaste // Let the thread running Host::RunShellCommand() know that the process 513254721Semaste // exited and that ShellInfo has been filled in by broadcasting to it 514254721Semaste shell_info->process_reaped.SetValue(1, eBroadcastAlways); 515254721Semaste // Now wait for a handshake back from that thread running Host::RunShellCommand 516254721Semaste // so we know that we can delete shell_info_ptr 517254721Semaste shell_info->can_delete.WaitForValueEqualTo(true); 518254721Semaste // Sleep a bit to allow the shell_info->can_delete.SetValue() to complete... 519254721Semaste usleep(1000); 520254721Semaste // Now delete the shell info that was passed into this function 521254721Semaste delete shell_info; 522254721Semaste return true; 523254721Semaste} 524254721Semaste 525254721SemasteError 526254721SemasteHost::RunShellCommand (const char *command, 527254721Semaste const char *working_dir, 528254721Semaste int *status_ptr, 529254721Semaste int *signo_ptr, 530254721Semaste std::string *command_output_ptr, 531254721Semaste uint32_t timeout_sec, 532280031Sdim bool run_in_default_shell) 533254721Semaste{ 534254721Semaste Error error; 535254721Semaste ProcessLaunchInfo launch_info; 536280031Sdim launch_info.SetArchitecture(HostInfo::GetArchitecture()); 537280031Sdim if (run_in_default_shell) 538254721Semaste { 539254721Semaste // Run the command in a shell 540280031Sdim launch_info.SetShell(HostInfo::GetDefaultShell()); 541254721Semaste launch_info.GetArguments().AppendArgument(command); 542254721Semaste const bool localhost = true; 543254721Semaste const bool will_debug = false; 544254721Semaste const bool first_arg_is_full_shell_command = true; 545254721Semaste launch_info.ConvertArgumentsForLaunchingInShell (error, 546254721Semaste localhost, 547254721Semaste will_debug, 548258054Semaste first_arg_is_full_shell_command, 549258054Semaste 0); 550254721Semaste } 551254721Semaste else 552254721Semaste { 553254721Semaste // No shell, just run it 554254721Semaste Args args (command); 555254721Semaste const bool first_arg_is_executable = true; 556254721Semaste launch_info.SetArguments(args, first_arg_is_executable); 557254721Semaste } 558254721Semaste 559254721Semaste if (working_dir) 560254721Semaste launch_info.SetWorkingDirectory(working_dir); 561280031Sdim llvm::SmallString<PATH_MAX> output_file_path; 562280031Sdim 563254721Semaste if (command_output_ptr) 564254721Semaste { 565254721Semaste // Create a temporary file to get the stdout/stderr and redirect the 566254721Semaste // output of the command into this file. We will later read this file 567254721Semaste // if all goes well and fill the data into "command_output_ptr" 568262528Semaste FileSpec tmpdir_file_spec; 569276479Sdim if (HostInfo::GetLLDBPath(ePathTypeLLDBTempSystemDir, tmpdir_file_spec)) 570262528Semaste { 571280031Sdim tmpdir_file_spec.AppendPathComponent("lldb-shell-output.%%%%%%"); 572280031Sdim llvm::sys::fs::createUniqueFile(tmpdir_file_spec.GetPath().c_str(), output_file_path); 573262528Semaste } 574262528Semaste else 575262528Semaste { 576280031Sdim llvm::sys::fs::createTemporaryFile("lldb-shell-output.%%%%%%", "", output_file_path); 577262528Semaste } 578262528Semaste } 579262528Semaste 580262528Semaste launch_info.AppendSuppressFileAction (STDIN_FILENO, true, false); 581280031Sdim if (!output_file_path.empty()) 582262528Semaste { 583280031Sdim launch_info.AppendOpenFileAction(STDOUT_FILENO, output_file_path.c_str(), false, true); 584254721Semaste launch_info.AppendDuplicateFileAction(STDOUT_FILENO, STDERR_FILENO); 585254721Semaste } 586254721Semaste else 587254721Semaste { 588254721Semaste launch_info.AppendSuppressFileAction (STDOUT_FILENO, false, true); 589254721Semaste launch_info.AppendSuppressFileAction (STDERR_FILENO, false, true); 590254721Semaste } 591254721Semaste 592254721Semaste // The process monitor callback will delete the 'shell_info_ptr' below... 593254721Semaste std::unique_ptr<ShellInfo> shell_info_ap (new ShellInfo()); 594254721Semaste 595254721Semaste const bool monitor_signals = false; 596254721Semaste launch_info.SetMonitorProcessCallback(MonitorShellCommand, shell_info_ap.get(), monitor_signals); 597254721Semaste 598254721Semaste error = LaunchProcess (launch_info); 599254721Semaste const lldb::pid_t pid = launch_info.GetProcessID(); 600258054Semaste 601258054Semaste if (error.Success() && pid == LLDB_INVALID_PROCESS_ID) 602258054Semaste error.SetErrorString("failed to get process ID"); 603258054Semaste 604258054Semaste if (error.Success()) 605254721Semaste { 606254721Semaste // The process successfully launched, so we can defer ownership of 607254721Semaste // "shell_info" to the MonitorShellCommand callback function that will 608254721Semaste // get called when the process dies. We release the unique pointer as it 609254721Semaste // doesn't need to delete the ShellInfo anymore. 610254721Semaste ShellInfo *shell_info = shell_info_ap.release(); 611258054Semaste TimeValue *timeout_ptr = nullptr; 612254721Semaste TimeValue timeout_time(TimeValue::Now()); 613258054Semaste if (timeout_sec > 0) { 614258054Semaste timeout_time.OffsetWithSeconds(timeout_sec); 615258054Semaste timeout_ptr = &timeout_time; 616258054Semaste } 617254721Semaste bool timed_out = false; 618258054Semaste shell_info->process_reaped.WaitForValueEqualTo(true, timeout_ptr, &timed_out); 619254721Semaste if (timed_out) 620254721Semaste { 621254721Semaste error.SetErrorString("timed out waiting for shell command to complete"); 622258054Semaste 623276479Sdim // Kill the process since it didn't complete within the timeout specified 624258054Semaste Kill (pid, SIGKILL); 625254721Semaste // Wait for the monitor callback to get the message 626254721Semaste timeout_time = TimeValue::Now(); 627254721Semaste timeout_time.OffsetWithSeconds(1); 628254721Semaste timed_out = false; 629254721Semaste shell_info->process_reaped.WaitForValueEqualTo(true, &timeout_time, &timed_out); 630254721Semaste } 631254721Semaste else 632254721Semaste { 633254721Semaste if (status_ptr) 634254721Semaste *status_ptr = shell_info->status; 635254721Semaste 636254721Semaste if (signo_ptr) 637254721Semaste *signo_ptr = shell_info->signo; 638254721Semaste 639254721Semaste if (command_output_ptr) 640254721Semaste { 641254721Semaste command_output_ptr->clear(); 642280031Sdim FileSpec file_spec(output_file_path.c_str(), File::eOpenOptionRead); 643254721Semaste uint64_t file_size = file_spec.GetByteSize(); 644254721Semaste if (file_size > 0) 645254721Semaste { 646254721Semaste if (file_size > command_output_ptr->max_size()) 647254721Semaste { 648254721Semaste error.SetErrorStringWithFormat("shell command output is too large to fit into a std::string"); 649254721Semaste } 650254721Semaste else 651254721Semaste { 652254721Semaste command_output_ptr->resize(file_size); 653254721Semaste file_spec.ReadFileContents(0, &((*command_output_ptr)[0]), command_output_ptr->size(), &error); 654254721Semaste } 655254721Semaste } 656254721Semaste } 657254721Semaste } 658254721Semaste shell_info->can_delete.SetValue(true, eBroadcastAlways); 659254721Semaste } 660254721Semaste 661280031Sdim FileSpec output_file_spec(output_file_path.c_str(), false); 662280031Sdim if (FileSystem::GetFileExists(output_file_spec)) 663280031Sdim FileSystem::Unlink(output_file_path.c_str()); 664254721Semaste // Handshake with the monitor thread, or just let it know in advance that 665254721Semaste // it can delete "shell_info" in case we timed out and were not able to kill 666254721Semaste // the process... 667254721Semaste return error; 668254721Semaste} 669254721Semaste 670254721Semaste 671262528Semaste// LaunchProcessPosixSpawn for Apple, Linux, FreeBSD and other GLIBC 672262528Semaste// systems 673262528Semaste 674276479Sdim#if defined (__APPLE__) || defined (__linux__) || defined (__FreeBSD__) || defined (__GLIBC__) || defined(__NetBSD__) 675262528Semaste// this method needs to be visible to macosx/Host.cpp and 676262528Semaste// common/Host.cpp. 677262528Semaste 678262528Semasteshort 679280031SdimHost::GetPosixspawnFlags(const ProcessLaunchInfo &launch_info) 680258054Semaste{ 681280031Sdim#if !defined(__ANDROID__) && !defined(__ANDROID_NDK__) 682262528Semaste short flags = POSIX_SPAWN_SETSIGDEF | POSIX_SPAWN_SETSIGMASK; 683262528Semaste 684262528Semaste#if defined (__APPLE__) 685262528Semaste if (launch_info.GetFlags().Test (eLaunchFlagExec)) 686262528Semaste flags |= POSIX_SPAWN_SETEXEC; // Darwin specific posix_spawn flag 687262528Semaste 688262528Semaste if (launch_info.GetFlags().Test (eLaunchFlagDebug)) 689262528Semaste flags |= POSIX_SPAWN_START_SUSPENDED; // Darwin specific posix_spawn flag 690262528Semaste 691262528Semaste if (launch_info.GetFlags().Test (eLaunchFlagDisableASLR)) 692262528Semaste flags |= _POSIX_SPAWN_DISABLE_ASLR; // Darwin specific posix_spawn flag 693262528Semaste 694262528Semaste if (launch_info.GetLaunchInSeparateProcessGroup()) 695262528Semaste flags |= POSIX_SPAWN_SETPGROUP; 696262528Semaste 697262528Semaste#ifdef POSIX_SPAWN_CLOEXEC_DEFAULT 698262528Semaste#if defined (__APPLE__) && (defined (__x86_64__) || defined (__i386__)) 699262528Semaste static LazyBool g_use_close_on_exec_flag = eLazyBoolCalculate; 700262528Semaste if (g_use_close_on_exec_flag == eLazyBoolCalculate) 701262528Semaste { 702262528Semaste g_use_close_on_exec_flag = eLazyBoolNo; 703262528Semaste 704262528Semaste uint32_t major, minor, update; 705276479Sdim if (HostInfo::GetOSVersion(major, minor, update)) 706262528Semaste { 707262528Semaste // Kernel panic if we use the POSIX_SPAWN_CLOEXEC_DEFAULT on 10.7 or earlier 708262528Semaste if (major > 10 || (major == 10 && minor > 7)) 709262528Semaste { 710262528Semaste // Only enable for 10.8 and later OS versions 711262528Semaste g_use_close_on_exec_flag = eLazyBoolYes; 712262528Semaste } 713262528Semaste } 714262528Semaste } 715262528Semaste#else 716262528Semaste static LazyBool g_use_close_on_exec_flag = eLazyBoolYes; 717262528Semaste#endif 718262528Semaste // Close all files exception those with file actions if this is supported. 719262528Semaste if (g_use_close_on_exec_flag == eLazyBoolYes) 720262528Semaste flags |= POSIX_SPAWN_CLOEXEC_DEFAULT; 721262528Semaste#endif 722262528Semaste#endif // #if defined (__APPLE__) 723262528Semaste return flags; 724280031Sdim#else 725280031Sdim assert(false && "Host::GetPosixspawnFlags() not supported on Android"); 726280031Sdim return 0; 727280031Sdim#endif 728262528Semaste} 729262528Semaste 730262528SemasteError 731280031SdimHost::LaunchProcessPosixSpawn(const char *exe_path, const ProcessLaunchInfo &launch_info, lldb::pid_t &pid) 732262528Semaste{ 733258054Semaste Error error; 734280031Sdim#if !defined(__ANDROID__) && !defined(__ANDROID_NDK__) 735258054Semaste Log *log(lldb_private::GetLogIfAllCategoriesSet (LIBLLDB_LOG_HOST | LIBLLDB_LOG_PROCESS)); 736258054Semaste 737258054Semaste posix_spawnattr_t attr; 738262528Semaste error.SetError( ::posix_spawnattr_init (&attr), eErrorTypePOSIX); 739258054Semaste 740262528Semaste if (error.Fail() || log) 741262528Semaste error.PutToLog(log, "::posix_spawnattr_init ( &attr )"); 742258054Semaste if (error.Fail()) 743258054Semaste return error; 744258054Semaste 745258054Semaste // Make a quick class that will cleanup the posix spawn attributes in case 746258054Semaste // we return in the middle of this function. 747258054Semaste lldb_utility::CleanUp <posix_spawnattr_t *, int> posix_spawnattr_cleanup(&attr, posix_spawnattr_destroy); 748258054Semaste 749258054Semaste sigset_t no_signals; 750258054Semaste sigset_t all_signals; 751258054Semaste sigemptyset (&no_signals); 752258054Semaste sigfillset (&all_signals); 753262528Semaste ::posix_spawnattr_setsigmask(&attr, &no_signals); 754262528Semaste#if defined (__linux__) || defined (__FreeBSD__) 755258054Semaste ::posix_spawnattr_setsigdefault(&attr, &no_signals); 756262528Semaste#else 757262528Semaste ::posix_spawnattr_setsigdefault(&attr, &all_signals); 758262528Semaste#endif 759258054Semaste 760262528Semaste short flags = GetPosixspawnFlags(launch_info); 761258054Semaste 762258054Semaste error.SetError( ::posix_spawnattr_setflags (&attr, flags), eErrorTypePOSIX); 763262528Semaste if (error.Fail() || log) 764262528Semaste error.PutToLog(log, "::posix_spawnattr_setflags ( &attr, flags=0x%8.8x )", flags); 765258054Semaste if (error.Fail()) 766258054Semaste return error; 767258054Semaste 768262528Semaste // posix_spawnattr_setbinpref_np appears to be an Apple extension per: 769262528Semaste // http://www.unix.com/man-page/OSX/3/posix_spawnattr_setbinpref_np/ 770262528Semaste#if defined (__APPLE__) && !defined (__arm__) 771262528Semaste 772262528Semaste // Don't set the binpref if a shell was provided. After all, that's only going to affect what version of the shell 773262528Semaste // is launched, not what fork of the binary is launched. We insert "arch --arch <ARCH> as part of the shell invocation 774262528Semaste // to do that job on OSX. 775262528Semaste 776262528Semaste if (launch_info.GetShell() == nullptr) 777258054Semaste { 778262528Semaste // We don't need to do this for ARM, and we really shouldn't now that we 779262528Semaste // have multiple CPU subtypes and no posix_spawnattr call that allows us 780262528Semaste // to set which CPU subtype to launch... 781262528Semaste const ArchSpec &arch_spec = launch_info.GetArchitecture(); 782262528Semaste cpu_type_t cpu = arch_spec.GetMachOCPUType(); 783262528Semaste cpu_type_t sub = arch_spec.GetMachOCPUSubType(); 784262528Semaste if (cpu != 0 && 785276479Sdim cpu != static_cast<cpu_type_t>(UINT32_MAX) && 786276479Sdim cpu != static_cast<cpu_type_t>(LLDB_INVALID_CPUTYPE) && 787262528Semaste !(cpu == 0x01000007 && sub == 8)) // If haswell is specified, don't try to set the CPU type or we will fail 788262528Semaste { 789262528Semaste size_t ocount = 0; 790262528Semaste error.SetError( ::posix_spawnattr_setbinpref_np (&attr, 1, &cpu, &ocount), eErrorTypePOSIX); 791262528Semaste if (error.Fail() || log) 792262528Semaste error.PutToLog(log, "::posix_spawnattr_setbinpref_np ( &attr, 1, cpu_type = 0x%8.8x, count => %llu )", cpu, (uint64_t)ocount); 793258054Semaste 794262528Semaste if (error.Fail() || ocount != 1) 795258054Semaste return error; 796258054Semaste } 797258054Semaste } 798258054Semaste 799262528Semaste#endif 800262528Semaste 801262528Semaste const char *tmp_argv[2]; 802262528Semaste char * const *argv = (char * const*)launch_info.GetArguments().GetConstArgumentVector(); 803262528Semaste char * const *envp = (char * const*)launch_info.GetEnvironmentEntries().GetConstArgumentVector(); 804262528Semaste if (argv == NULL) 805262528Semaste { 806262528Semaste // posix_spawn gets very unhappy if it doesn't have at least the program 807262528Semaste // name in argv[0]. One of the side affects I have noticed is the environment 808262528Semaste // variables don't make it into the child process if "argv == NULL"!!! 809262528Semaste tmp_argv[0] = exe_path; 810262528Semaste tmp_argv[1] = NULL; 811262528Semaste argv = (char * const*)tmp_argv; 812262528Semaste } 813262528Semaste 814262528Semaste#if !defined (__APPLE__) 815262528Semaste // manage the working directory 816258054Semaste char current_dir[PATH_MAX]; 817258054Semaste current_dir[0] = '\0'; 818262528Semaste#endif 819258054Semaste 820258054Semaste const char *working_dir = launch_info.GetWorkingDirectory(); 821262528Semaste if (working_dir) 822258054Semaste { 823262528Semaste#if defined (__APPLE__) 824262528Semaste // Set the working directory on this thread only 825262528Semaste if (__pthread_chdir (working_dir) < 0) { 826262528Semaste if (errno == ENOENT) { 827262528Semaste error.SetErrorStringWithFormat("No such file or directory: %s", working_dir); 828262528Semaste } else if (errno == ENOTDIR) { 829262528Semaste error.SetErrorStringWithFormat("Path doesn't name a directory: %s", working_dir); 830262528Semaste } else { 831262528Semaste error.SetErrorStringWithFormat("An unknown error occurred when changing directory for process execution."); 832262528Semaste } 833262528Semaste return error; 834262528Semaste } 835262528Semaste#else 836258054Semaste if (::getcwd(current_dir, sizeof(current_dir)) == NULL) 837258054Semaste { 838258054Semaste error.SetError(errno, eErrorTypePOSIX); 839258054Semaste error.LogIfError(log, "unable to save the current directory"); 840258054Semaste return error; 841258054Semaste } 842258054Semaste 843258054Semaste if (::chdir(working_dir) == -1) 844258054Semaste { 845258054Semaste error.SetError(errno, eErrorTypePOSIX); 846258054Semaste error.LogIfError(log, "unable to change working directory to %s", working_dir); 847258054Semaste return error; 848258054Semaste } 849262528Semaste#endif 850258054Semaste } 851258054Semaste 852280031Sdim ::pid_t result_pid = LLDB_INVALID_PROCESS_ID; 853262528Semaste const size_t num_file_actions = launch_info.GetNumFileActions (); 854262528Semaste if (num_file_actions > 0) 855258054Semaste { 856262528Semaste posix_spawn_file_actions_t file_actions; 857262528Semaste error.SetError( ::posix_spawn_file_actions_init (&file_actions), eErrorTypePOSIX); 858262528Semaste if (error.Fail() || log) 859262528Semaste error.PutToLog(log, "::posix_spawn_file_actions_init ( &file_actions )"); 860262528Semaste if (error.Fail()) 861262528Semaste return error; 862258054Semaste 863262528Semaste // Make a quick class that will cleanup the posix spawn attributes in case 864262528Semaste // we return in the middle of this function. 865262528Semaste lldb_utility::CleanUp <posix_spawn_file_actions_t *, int> posix_spawn_file_actions_cleanup (&file_actions, posix_spawn_file_actions_destroy); 866258054Semaste 867262528Semaste for (size_t i=0; i<num_file_actions; ++i) 868262528Semaste { 869276479Sdim const FileAction *launch_file_action = launch_info.GetFileActionAtIndex(i); 870262528Semaste if (launch_file_action) 871262528Semaste { 872276479Sdim if (!AddPosixSpawnFileAction(&file_actions, launch_file_action, log, error)) 873262528Semaste return error; 874262528Semaste } 875262528Semaste } 876258054Semaste 877280031Sdim error.SetError(::posix_spawnp(&result_pid, exe_path, &file_actions, &attr, argv, envp), eErrorTypePOSIX); 878262528Semaste 879262528Semaste if (error.Fail() || log) 880262528Semaste { 881280031Sdim error.PutToLog(log, "::posix_spawnp ( pid => %i, path = '%s', file_actions = %p, attr = %p, argv = %p, envp = %p )", result_pid, 882280031Sdim exe_path, static_cast<void *>(&file_actions), static_cast<void *>(&attr), reinterpret_cast<const void *>(argv), 883280031Sdim reinterpret_cast<const void *>(envp)); 884262528Semaste if (log) 885262528Semaste { 886262528Semaste for (int ii=0; argv[ii]; ++ii) 887262528Semaste log->Printf("argv[%i] = '%s'", ii, argv[ii]); 888262528Semaste } 889262528Semaste } 890262528Semaste 891262528Semaste } 892262528Semaste else 893258054Semaste { 894280031Sdim error.SetError(::posix_spawnp(&result_pid, exe_path, NULL, &attr, argv, envp), eErrorTypePOSIX); 895262528Semaste 896262528Semaste if (error.Fail() || log) 897262528Semaste { 898262528Semaste error.PutToLog(log, "::posix_spawnp ( pid => %i, path = '%s', file_actions = NULL, attr = %p, argv = %p, envp = %p )", 899280031Sdim result_pid, exe_path, static_cast<void *>(&attr), reinterpret_cast<const void *>(argv), 900280031Sdim reinterpret_cast<const void *>(envp)); 901262528Semaste if (log) 902262528Semaste { 903262528Semaste for (int ii=0; argv[ii]; ++ii) 904262528Semaste log->Printf("argv[%i] = '%s'", ii, argv[ii]); 905262528Semaste } 906262528Semaste } 907258054Semaste } 908280031Sdim pid = result_pid; 909258054Semaste 910262528Semaste if (working_dir) 911262528Semaste { 912262528Semaste#if defined (__APPLE__) 913262528Semaste // No more thread specific current working directory 914262528Semaste __pthread_fchdir (-1); 915262528Semaste#else 916262528Semaste if (::chdir(current_dir) == -1 && error.Success()) 917262528Semaste { 918262528Semaste error.SetError(errno, eErrorTypePOSIX); 919262528Semaste error.LogIfError(log, "unable to change current directory back to %s", 920262528Semaste current_dir); 921262528Semaste } 922262528Semaste#endif 923262528Semaste } 924280031Sdim#else 925280031Sdim error.SetErrorString("Host::LaunchProcessPosixSpawn() not supported on Android"); 926280031Sdim#endif 927262528Semaste 928258054Semaste return error; 929258054Semaste} 930258054Semaste 931276479Sdimbool 932276479SdimHost::AddPosixSpawnFileAction(void *_file_actions, const FileAction *info, Log *log, Error &error) 933276479Sdim{ 934280031Sdim#if !defined(__ANDROID__) && !defined(__ANDROID_NDK__) 935276479Sdim if (info == NULL) 936276479Sdim return false; 937276479Sdim 938276479Sdim posix_spawn_file_actions_t *file_actions = reinterpret_cast<posix_spawn_file_actions_t *>(_file_actions); 939276479Sdim 940276479Sdim switch (info->GetAction()) 941276479Sdim { 942276479Sdim case FileAction::eFileActionNone: 943276479Sdim error.Clear(); 944276479Sdim break; 945276479Sdim 946276479Sdim case FileAction::eFileActionClose: 947276479Sdim if (info->GetFD() == -1) 948276479Sdim error.SetErrorString("invalid fd for posix_spawn_file_actions_addclose(...)"); 949276479Sdim else 950276479Sdim { 951276479Sdim error.SetError(::posix_spawn_file_actions_addclose(file_actions, info->GetFD()), eErrorTypePOSIX); 952276479Sdim if (log && (error.Fail() || log)) 953276479Sdim error.PutToLog(log, "posix_spawn_file_actions_addclose (action=%p, fd=%i)", 954276479Sdim static_cast<void *>(file_actions), info->GetFD()); 955276479Sdim } 956276479Sdim break; 957276479Sdim 958276479Sdim case FileAction::eFileActionDuplicate: 959276479Sdim if (info->GetFD() == -1) 960276479Sdim error.SetErrorString("invalid fd for posix_spawn_file_actions_adddup2(...)"); 961276479Sdim else if (info->GetActionArgument() == -1) 962276479Sdim error.SetErrorString("invalid duplicate fd for posix_spawn_file_actions_adddup2(...)"); 963276479Sdim else 964276479Sdim { 965276479Sdim error.SetError( 966276479Sdim ::posix_spawn_file_actions_adddup2(file_actions, info->GetFD(), info->GetActionArgument()), 967276479Sdim eErrorTypePOSIX); 968276479Sdim if (log && (error.Fail() || log)) 969276479Sdim error.PutToLog(log, "posix_spawn_file_actions_adddup2 (action=%p, fd=%i, dup_fd=%i)", 970276479Sdim static_cast<void *>(file_actions), info->GetFD(), info->GetActionArgument()); 971276479Sdim } 972276479Sdim break; 973276479Sdim 974276479Sdim case FileAction::eFileActionOpen: 975276479Sdim if (info->GetFD() == -1) 976276479Sdim error.SetErrorString("invalid fd in posix_spawn_file_actions_addopen(...)"); 977276479Sdim else 978276479Sdim { 979276479Sdim int oflag = info->GetActionArgument(); 980276479Sdim 981276479Sdim mode_t mode = 0; 982276479Sdim 983276479Sdim if (oflag & O_CREAT) 984276479Sdim mode = 0640; 985276479Sdim 986276479Sdim error.SetError( 987276479Sdim ::posix_spawn_file_actions_addopen(file_actions, info->GetFD(), info->GetPath(), oflag, mode), 988276479Sdim eErrorTypePOSIX); 989276479Sdim if (error.Fail() || log) 990276479Sdim error.PutToLog(log, 991276479Sdim "posix_spawn_file_actions_addopen (action=%p, fd=%i, path='%s', oflag=%i, mode=%i)", 992276479Sdim static_cast<void *>(file_actions), info->GetFD(), info->GetPath(), oflag, mode); 993276479Sdim } 994276479Sdim break; 995276479Sdim } 996276479Sdim return error.Success(); 997280031Sdim#else 998280031Sdim error.SetErrorString("Host::AddPosixSpawnFileAction() not supported on Android"); 999280031Sdim return false; 1000280031Sdim#endif 1001276479Sdim} 1002262528Semaste#endif // LaunchProcedssPosixSpawn: Apple, Linux, FreeBSD and other GLIBC systems 1003258054Semaste 1004280031Sdim#if defined(__linux__) || defined(__FreeBSD__) || defined(__GLIBC__) || defined(__NetBSD__) || defined(_WIN32) 1005276479Sdim// The functions below implement process launching via posix_spawn() for Linux, 1006276479Sdim// FreeBSD and NetBSD. 1007262528Semaste 1008258054SemasteError 1009258054SemasteHost::LaunchProcess (ProcessLaunchInfo &launch_info) 1010258054Semaste{ 1011280031Sdim std::unique_ptr<ProcessLauncher> delegate_launcher; 1012280031Sdim#if defined(_WIN32) 1013280031Sdim delegate_launcher.reset(new ProcessLauncherWindows()); 1014280031Sdim#else 1015280031Sdim delegate_launcher.reset(new ProcessLauncherPosix()); 1016280031Sdim#endif 1017280031Sdim MonitoringProcessLauncher launcher(std::move(delegate_launcher)); 1018280031Sdim 1019258054Semaste Error error; 1020280031Sdim HostProcess process = launcher.LaunchProcess(launch_info, error); 1021258054Semaste 1022280031Sdim // TODO(zturner): It would be better if the entire HostProcess were returned instead of writing 1023280031Sdim // it into this structure. 1024280031Sdim launch_info.SetProcessID(process.GetProcessId()); 1025258054Semaste 1026258054Semaste return error; 1027258054Semaste} 1028276479Sdim#endif // defined(__linux__) || defined(__FreeBSD__) || defined(__NetBSD__) 1029258054Semaste 1030258054Semaste#ifndef _WIN32 1031258054Semastevoid 1032258054SemasteHost::Kill(lldb::pid_t pid, int signo) 1033258054Semaste{ 1034258054Semaste ::kill(pid, signo); 1035258054Semaste} 1036254721Semaste 1037258054Semaste#endif 1038254721Semaste 1039254721Semaste#if !defined (__APPLE__) 1040254721Semastebool 1041254721SemasteHost::OpenFileInExternalEditor (const FileSpec &file_spec, uint32_t line_no) 1042254721Semaste{ 1043254721Semaste return false; 1044254721Semaste} 1045254721Semaste 1046254721Semastevoid 1047254721SemasteHost::SetCrashDescriptionWithFormat (const char *format, ...) 1048254721Semaste{ 1049254721Semaste} 1050254721Semaste 1051254721Semastevoid 1052254721SemasteHost::SetCrashDescription (const char *description) 1053254721Semaste{ 1054254721Semaste} 1055254721Semaste 1056254721Semastelldb::pid_t 1057258054SemasteHost::LaunchApplication (const FileSpec &app_file_spec) 1058254721Semaste{ 1059254721Semaste return LLDB_INVALID_PROCESS_ID; 1060254721Semaste} 1061254721Semaste 1062258884Semaste#endif 1063258884Semaste 1064276479Sdim#if !defined (__linux__) && !defined (__FreeBSD__) && !defined (__NetBSD__) 1065258884Semaste 1066276479Sdimconst lldb_private::UnixSignalsSP& 1067276479SdimHost::GetUnixSignals () 1068258054Semaste{ 1069276479Sdim static UnixSignalsSP s_unix_signals_sp (new UnixSignals ()); 1070276479Sdim return s_unix_signals_sp; 1071258054Semaste} 1072258884Semaste 1073254721Semaste#endif 1074