1254721Semaste//===-- Host.cpp ------------------------------------------------*- C++ -*-===// 2254721Semaste// 3353358Sdim// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. 4353358Sdim// See https://llvm.org/LICENSE.txt for license information. 5353358Sdim// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception 6254721Semaste// 7254721Semaste//===----------------------------------------------------------------------===// 8254721Semaste 9254721Semaste// C includes 10258054Semaste#include <errno.h> 11258054Semaste#include <limits.h> 12276479Sdim#include <stdlib.h> 13258054Semaste#include <sys/types.h> 14280031Sdim#ifndef _WIN32 15254721Semaste#include <dlfcn.h> 16254721Semaste#include <grp.h> 17254721Semaste#include <netdb.h> 18254721Semaste#include <pwd.h> 19258884Semaste#include <sys/stat.h> 20314564Sdim#include <unistd.h> 21258054Semaste#endif 22258054Semaste 23314564Sdim#if defined(__APPLE__) 24314564Sdim#include <mach-o/dyld.h> 25314564Sdim#include <mach/mach_init.h> 26258054Semaste#include <mach/mach_port.h> 27254721Semaste#endif 28254721Semaste 29314564Sdim#if defined(__linux__) || defined(__FreeBSD__) || \ 30321369Sdim defined(__FreeBSD_kernel__) || defined(__APPLE__) || \ 31321369Sdim defined(__NetBSD__) || defined(__OpenBSD__) 32314564Sdim#if !defined(__ANDROID__) 33258054Semaste#include <spawn.h> 34280031Sdim#endif 35314564Sdim#include <sys/syscall.h> 36254721Semaste#include <sys/wait.h> 37254721Semaste#endif 38254721Semaste 39314564Sdim#if defined(__FreeBSD__) 40254721Semaste#include <pthread_np.h> 41254721Semaste#endif 42254721Semaste 43321369Sdim#if defined(__NetBSD__) 44321369Sdim#include <lwp.h> 45321369Sdim#endif 46321369Sdim 47321369Sdim#include <csignal> 48276479Sdim 49353358Sdim#include "lldb/Host/FileAction.h" 50344779Sdim#include "lldb/Host/FileSystem.h" 51314564Sdim#include "lldb/Host/Host.h" 52314564Sdim#include "lldb/Host/HostInfo.h" 53280031Sdim#include "lldb/Host/HostProcess.h" 54280031Sdim#include "lldb/Host/MonitoringProcessLauncher.h" 55353358Sdim#include "lldb/Host/ProcessLaunchInfo.h" 56280031Sdim#include "lldb/Host/ProcessLauncher.h" 57280031Sdim#include "lldb/Host/ThreadLauncher.h" 58321369Sdim#include "lldb/Host/posix/ConnectionFileDescriptorPosix.h" 59321369Sdim#include "lldb/Utility/DataBufferLLVM.h" 60321369Sdim#include "lldb/Utility/FileSpec.h" 61321369Sdim#include "lldb/Utility/Log.h" 62344779Sdim#include "lldb/Utility/Predicate.h" 63321369Sdim#include "lldb/Utility/Status.h" 64314564Sdim#include "lldb/lldb-private-forward.h" 65288943Sdim#include "llvm/ADT/SmallString.h" 66321369Sdim#include "llvm/ADT/StringSwitch.h" 67321369Sdim#include "llvm/Support/Errno.h" 68314564Sdim#include "llvm/Support/FileSystem.h" 69254721Semaste 70280031Sdim#if defined(_WIN32) 71321369Sdim#include "lldb/Host/windows/ConnectionGenericFileWindows.h" 72280031Sdim#include "lldb/Host/windows/ProcessLauncherWindows.h" 73280031Sdim#else 74321369Sdim#include "lldb/Host/posix/ProcessLauncherPosixFork.h" 75280031Sdim#endif 76254721Semaste 77314564Sdim#if defined(__APPLE__) 78262528Semaste#ifndef _POSIX_SPAWN_DISABLE_ASLR 79314564Sdim#define _POSIX_SPAWN_DISABLE_ASLR 0x0100 80262528Semaste#endif 81254721Semaste 82314564Sdimextern "C" { 83314564Sdimint __pthread_chdir(const char *path); 84314564Sdimint __pthread_fchdir(int fildes); 85262528Semaste} 86262528Semaste 87262528Semaste#endif 88262528Semaste 89254721Semasteusing namespace lldb; 90254721Semasteusing namespace lldb_private; 91254721Semaste 92314564Sdim#if !defined(__APPLE__) && !defined(_WIN32) 93314564Sdimstruct MonitorInfo { 94314564Sdim lldb::pid_t pid; // The process ID to monitor 95314564Sdim Host::MonitorChildProcessCallback 96314564Sdim callback; // The callback function to call when "pid" exits or signals 97314564Sdim bool monitor_signals; // If true, call the callback when "pid" gets signaled. 98254721Semaste}; 99254721Semaste 100314564Sdimstatic thread_result_t MonitorChildProcessThreadFunction(void *arg); 101254721Semaste 102353358Sdimllvm::Expected<HostThread> Host::StartMonitoringChildProcess( 103314564Sdim const Host::MonitorChildProcessCallback &callback, lldb::pid_t pid, 104314564Sdim bool monitor_signals) { 105314564Sdim MonitorInfo *info_ptr = new MonitorInfo(); 106258054Semaste 107314564Sdim info_ptr->pid = pid; 108314564Sdim info_ptr->callback = callback; 109314564Sdim info_ptr->monitor_signals = monitor_signals; 110314564Sdim 111314564Sdim char thread_name[256]; 112314564Sdim ::snprintf(thread_name, sizeof(thread_name), 113314564Sdim "<lldb.host.wait4(pid=%" PRIu64 ")>", pid); 114314564Sdim return ThreadLauncher::LaunchThread( 115353358Sdim thread_name, MonitorChildProcessThreadFunction, info_ptr, 0); 116254721Semaste} 117254721Semaste 118288943Sdim#ifndef __linux__ 119341825Sdim// Scoped class that will disable thread canceling when it is constructed, and 120341825Sdim// exception safely restore the previous value it when it goes out of scope. 121314564Sdimclass ScopedPThreadCancelDisabler { 122254721Semastepublic: 123314564Sdim ScopedPThreadCancelDisabler() { 124314564Sdim // Disable the ability for this thread to be cancelled 125314564Sdim int err = ::pthread_setcancelstate(PTHREAD_CANCEL_DISABLE, &m_old_state); 126314564Sdim if (err != 0) 127314564Sdim m_old_state = -1; 128314564Sdim } 129254721Semaste 130314564Sdim ~ScopedPThreadCancelDisabler() { 131314564Sdim // Restore the ability for this thread to be cancelled to what it 132314564Sdim // previously was. 133314564Sdim if (m_old_state != -1) 134314564Sdim ::pthread_setcancelstate(m_old_state, 0); 135314564Sdim } 136314564Sdim 137254721Semasteprivate: 138314564Sdim int m_old_state; // Save the old cancelability state. 139254721Semaste}; 140288943Sdim#endif // __linux__ 141254721Semaste 142288943Sdim#ifdef __linux__ 143296417Sdim#if defined(__GNUC__) && (__GNUC__ < 4 || (__GNUC__ == 4 && __GNUC_MINOR__ < 8)) 144296417Sdimstatic __thread volatile sig_atomic_t g_usr1_called; 145296417Sdim#else 146288943Sdimstatic thread_local volatile sig_atomic_t g_usr1_called; 147296417Sdim#endif 148288943Sdim 149314564Sdimstatic void SigUsr1Handler(int) { g_usr1_called = 1; } 150288943Sdim#endif // __linux__ 151288943Sdim 152314564Sdimstatic bool CheckForMonitorCancellation() { 153288943Sdim#ifdef __linux__ 154314564Sdim if (g_usr1_called) { 155314564Sdim g_usr1_called = 0; 156314564Sdim return true; 157314564Sdim } 158288943Sdim#else 159314564Sdim ::pthread_testcancel(); 160288943Sdim#endif 161314564Sdim return false; 162288943Sdim} 163288943Sdim 164314564Sdimstatic thread_result_t MonitorChildProcessThreadFunction(void *arg) { 165314564Sdim Log *log(lldb_private::GetLogIfAllCategoriesSet(LIBLLDB_LOG_PROCESS)); 166314564Sdim const char *function = __FUNCTION__; 167360784Sdim LLDB_LOGF(log, "%s (arg = %p) thread starting...", function, arg); 168254721Semaste 169314564Sdim MonitorInfo *info = (MonitorInfo *)arg; 170254721Semaste 171314564Sdim const Host::MonitorChildProcessCallback callback = info->callback; 172314564Sdim const bool monitor_signals = info->monitor_signals; 173254721Semaste 174314564Sdim assert(info->pid <= UINT32_MAX); 175314564Sdim const ::pid_t pid = monitor_signals ? -1 * getpgid(info->pid) : info->pid; 176258054Semaste 177314564Sdim delete info; 178254721Semaste 179314564Sdim int status = -1; 180321369Sdim#if defined(__FreeBSD__) || defined(__FreeBSD_kernel__) || defined(__OpenBSD__) 181314564Sdim#define __WALL 0 182254721Semaste#endif 183314564Sdim const int options = __WALL; 184254721Semaste 185288943Sdim#ifdef __linux__ 186314564Sdim // This signal is only used to interrupt the thread from waitpid 187314564Sdim struct sigaction sigUsr1Action; 188314564Sdim memset(&sigUsr1Action, 0, sizeof(sigUsr1Action)); 189314564Sdim sigUsr1Action.sa_handler = SigUsr1Handler; 190314564Sdim ::sigaction(SIGUSR1, &sigUsr1Action, nullptr); 191314564Sdim#endif // __linux__ 192288943Sdim 193314564Sdim while (1) { 194314564Sdim log = lldb_private::GetLogIfAllCategoriesSet(LIBLLDB_LOG_PROCESS); 195360784Sdim LLDB_LOGF(log, "%s ::waitpid (pid = %" PRIi32 ", &status, options = %i)...", 196360784Sdim function, pid, options); 197254721Semaste 198314564Sdim if (CheckForMonitorCancellation()) 199314564Sdim break; 200288943Sdim 201314564Sdim // Get signals from all children with same process group of pid 202314564Sdim const ::pid_t wait_pid = ::waitpid(pid, &status, options); 203288943Sdim 204314564Sdim if (CheckForMonitorCancellation()) 205314564Sdim break; 206288943Sdim 207314564Sdim if (wait_pid == -1) { 208314564Sdim if (errno == EINTR) 209314564Sdim continue; 210314564Sdim else { 211321369Sdim LLDB_LOG(log, 212321369Sdim "arg = {0}, thread exiting because waitpid failed ({1})...", 213321369Sdim arg, llvm::sys::StrError()); 214314564Sdim break; 215314564Sdim } 216314564Sdim } else if (wait_pid > 0) { 217314564Sdim bool exited = false; 218314564Sdim int signal = 0; 219314564Sdim int exit_status = 0; 220353358Sdim const char *status_cstr = nullptr; 221314564Sdim if (WIFSTOPPED(status)) { 222314564Sdim signal = WSTOPSIG(status); 223314564Sdim status_cstr = "STOPPED"; 224314564Sdim } else if (WIFEXITED(status)) { 225314564Sdim exit_status = WEXITSTATUS(status); 226314564Sdim status_cstr = "EXITED"; 227314564Sdim exited = true; 228314564Sdim } else if (WIFSIGNALED(status)) { 229314564Sdim signal = WTERMSIG(status); 230314564Sdim status_cstr = "SIGNALED"; 231314564Sdim if (wait_pid == abs(pid)) { 232314564Sdim exited = true; 233314564Sdim exit_status = -1; 234254721Semaste } 235314564Sdim } else { 236314564Sdim status_cstr = "(\?\?\?)"; 237314564Sdim } 238254721Semaste 239314564Sdim // Scope for pthread_cancel_disabler 240314564Sdim { 241288943Sdim#ifndef __linux__ 242314564Sdim ScopedPThreadCancelDisabler pthread_cancel_disabler; 243280031Sdim#endif 244254721Semaste 245314564Sdim log = lldb_private::GetLogIfAllCategoriesSet(LIBLLDB_LOG_PROCESS); 246360784Sdim LLDB_LOGF(log, 247360784Sdim "%s ::waitpid (pid = %" PRIi32 248360784Sdim ", &status, options = %i) => pid = %" PRIi32 249360784Sdim ", status = 0x%8.8x (%s), signal = %i, exit_state = %i", 250360784Sdim function, pid, options, wait_pid, status, status_cstr, signal, 251360784Sdim exit_status); 252254721Semaste 253314564Sdim if (exited || (signal != 0 && monitor_signals)) { 254314564Sdim bool callback_return = false; 255314564Sdim if (callback) 256314564Sdim callback_return = callback(wait_pid, exited, signal, exit_status); 257309124Sdim 258314564Sdim // If our process exited, then this thread should exit 259314564Sdim if (exited && wait_pid == abs(pid)) { 260360784Sdim LLDB_LOGF(log, 261360784Sdim "%s (arg = %p) thread exiting because pid received " 262360784Sdim "exit signal...", 263360784Sdim __FUNCTION__, arg); 264314564Sdim break; 265314564Sdim } 266341825Sdim // If the callback returns true, it means this process should exit 267314564Sdim if (callback_return) { 268360784Sdim LLDB_LOGF(log, 269360784Sdim "%s (arg = %p) thread exiting because callback " 270360784Sdim "returned true...", 271360784Sdim __FUNCTION__, arg); 272314564Sdim break; 273314564Sdim } 274254721Semaste } 275314564Sdim } 276254721Semaste } 277314564Sdim } 278254721Semaste 279314564Sdim log = lldb_private::GetLogIfAllCategoriesSet(LIBLLDB_LOG_PROCESS); 280360784Sdim LLDB_LOGF(log, "%s (arg = %p) thread exiting...", __FUNCTION__, arg); 281254721Semaste 282353358Sdim return nullptr; 283254721Semaste} 284254721Semaste 285258054Semaste#endif // #if !defined (__APPLE__) && !defined (_WIN32) 286254721Semaste 287314564Sdim#if !defined(__APPLE__) 288258054Semaste 289314564Sdimvoid Host::SystemLog(SystemLogType type, const char *format, va_list args) { 290314564Sdim vfprintf(stderr, format, args); 291254721Semaste} 292254721Semaste 293258054Semaste#endif 294254721Semaste 295314564Sdimvoid Host::SystemLog(SystemLogType type, const char *format, ...) { 296360784Sdim { 297360784Sdim va_list args; 298360784Sdim va_start(args, format); 299360784Sdim SystemLog(type, format, args); 300360784Sdim va_end(args); 301360784Sdim } 302360784Sdim 303360784Sdim Log *log(GetLogIfAllCategoriesSet(LIBLLDB_LOG_HOST)); 304360784Sdim if (log && log->GetVerbose()) { 305360784Sdim // Log to log channel. This allows testcases to grep for log output. 306360784Sdim va_list args; 307360784Sdim va_start(args, format); 308360784Sdim log->VAPrintf(format, args); 309360784Sdim va_end(args); 310360784Sdim } 311254721Semaste} 312254721Semaste 313314564Sdimlldb::pid_t Host::GetCurrentProcessID() { return ::getpid(); } 314254721Semaste 315258054Semaste#ifndef _WIN32 316258054Semaste 317314564Sdimlldb::thread_t Host::GetCurrentThread() { 318314564Sdim return lldb::thread_t(pthread_self()); 319254721Semaste} 320254721Semaste 321314564Sdimconst char *Host::GetSignalAsCString(int signo) { 322314564Sdim switch (signo) { 323314564Sdim case SIGHUP: 324314564Sdim return "SIGHUP"; // 1 hangup 325314564Sdim case SIGINT: 326314564Sdim return "SIGINT"; // 2 interrupt 327314564Sdim case SIGQUIT: 328314564Sdim return "SIGQUIT"; // 3 quit 329314564Sdim case SIGILL: 330314564Sdim return "SIGILL"; // 4 illegal instruction (not reset when caught) 331314564Sdim case SIGTRAP: 332314564Sdim return "SIGTRAP"; // 5 trace trap (not reset when caught) 333314564Sdim case SIGABRT: 334314564Sdim return "SIGABRT"; // 6 abort() 335314564Sdim#if defined(SIGPOLL) 336262528Semaste#if !defined(SIGIO) || (SIGPOLL != SIGIO) 337314564Sdim // Under some GNU/Linux, SIGPOLL and SIGIO are the same. Causing the build to 338314564Sdim // fail with 'multiple define cases with same value' 339314564Sdim case SIGPOLL: 340314564Sdim return "SIGPOLL"; // 7 pollable event ([XSR] generated, not supported) 341254721Semaste#endif 342262528Semaste#endif 343314564Sdim#if defined(SIGEMT) 344314564Sdim case SIGEMT: 345314564Sdim return "SIGEMT"; // 7 EMT instruction 346254721Semaste#endif 347314564Sdim case SIGFPE: 348314564Sdim return "SIGFPE"; // 8 floating point exception 349314564Sdim case SIGKILL: 350314564Sdim return "SIGKILL"; // 9 kill (cannot be caught or ignored) 351314564Sdim case SIGBUS: 352314564Sdim return "SIGBUS"; // 10 bus error 353314564Sdim case SIGSEGV: 354314564Sdim return "SIGSEGV"; // 11 segmentation violation 355314564Sdim case SIGSYS: 356314564Sdim return "SIGSYS"; // 12 bad argument to system call 357314564Sdim case SIGPIPE: 358314564Sdim return "SIGPIPE"; // 13 write on a pipe with no one to read it 359314564Sdim case SIGALRM: 360314564Sdim return "SIGALRM"; // 14 alarm clock 361314564Sdim case SIGTERM: 362314564Sdim return "SIGTERM"; // 15 software termination signal from kill 363314564Sdim case SIGURG: 364314564Sdim return "SIGURG"; // 16 urgent condition on IO channel 365314564Sdim case SIGSTOP: 366314564Sdim return "SIGSTOP"; // 17 sendable stop signal not from tty 367314564Sdim case SIGTSTP: 368314564Sdim return "SIGTSTP"; // 18 stop signal from tty 369314564Sdim case SIGCONT: 370314564Sdim return "SIGCONT"; // 19 continue a stopped process 371314564Sdim case SIGCHLD: 372314564Sdim return "SIGCHLD"; // 20 to parent on child stop or exit 373314564Sdim case SIGTTIN: 374314564Sdim return "SIGTTIN"; // 21 to readers pgrp upon background tty read 375314564Sdim case SIGTTOU: 376314564Sdim return "SIGTTOU"; // 22 like TTIN for output if (tp->t_local<OSTOP) 377314564Sdim#if defined(SIGIO) 378314564Sdim case SIGIO: 379314564Sdim return "SIGIO"; // 23 input/output possible signal 380254721Semaste#endif 381314564Sdim case SIGXCPU: 382314564Sdim return "SIGXCPU"; // 24 exceeded CPU time limit 383314564Sdim case SIGXFSZ: 384314564Sdim return "SIGXFSZ"; // 25 exceeded file size limit 385314564Sdim case SIGVTALRM: 386314564Sdim return "SIGVTALRM"; // 26 virtual time alarm 387314564Sdim case SIGPROF: 388314564Sdim return "SIGPROF"; // 27 profiling time alarm 389314564Sdim#if defined(SIGWINCH) 390314564Sdim case SIGWINCH: 391314564Sdim return "SIGWINCH"; // 28 window size changes 392262528Semaste#endif 393314564Sdim#if defined(SIGINFO) 394314564Sdim case SIGINFO: 395314564Sdim return "SIGINFO"; // 29 information request 396254721Semaste#endif 397314564Sdim case SIGUSR1: 398314564Sdim return "SIGUSR1"; // 30 user defined signal 1 399314564Sdim case SIGUSR2: 400314564Sdim return "SIGUSR2"; // 31 user defined signal 2 401314564Sdim default: 402314564Sdim break; 403314564Sdim } 404353358Sdim return nullptr; 405254721Semaste} 406254721Semaste 407258054Semaste#endif 408258054Semaste 409314564Sdim#if !defined(__APPLE__) // see Host.mm 410254721Semaste 411314564Sdimbool Host::GetBundleDirectory(const FileSpec &file, FileSpec &bundle) { 412314564Sdim bundle.Clear(); 413314564Sdim return false; 414254721Semaste} 415254721Semaste 416314564Sdimbool Host::ResolveExecutableInBundle(FileSpec &file) { return false; } 417254721Semaste#endif 418254721Semaste 419258054Semaste#ifndef _WIN32 420258054Semaste 421314564SdimFileSpec Host::GetModuleFileSpecForHostAddress(const void *host_addr) { 422314564Sdim FileSpec module_filespec; 423314564Sdim#if !defined(__ANDROID__) 424314564Sdim Dl_info info; 425314564Sdim if (::dladdr(host_addr, &info)) { 426344779Sdim if (info.dli_fname) { 427344779Sdim module_filespec.SetFile(info.dli_fname, FileSpec::Style::native); 428344779Sdim FileSystem::Instance().Resolve(module_filespec); 429344779Sdim } 430314564Sdim } 431280031Sdim#endif 432314564Sdim return module_filespec; 433258054Semaste} 434258054Semaste 435258054Semaste#endif 436258054Semaste 437254721Semaste#if !defined(__linux__) 438314564Sdimbool Host::FindProcessThreads(const lldb::pid_t pid, TidMap &tids_to_attach) { 439314564Sdim return false; 440254721Semaste} 441254721Semaste#endif 442254721Semaste 443314564Sdimstruct ShellInfo { 444314564Sdim ShellInfo() 445314564Sdim : process_reaped(false), pid(LLDB_INVALID_PROCESS_ID), signo(-1), 446314564Sdim status(-1) {} 447254721Semaste 448314564Sdim lldb_private::Predicate<bool> process_reaped; 449314564Sdim lldb::pid_t pid; 450314564Sdim int signo; 451314564Sdim int status; 452254721Semaste}; 453254721Semaste 454254721Semastestatic bool 455309124SdimMonitorShellCommand(std::shared_ptr<ShellInfo> shell_info, lldb::pid_t pid, 456309124Sdim bool exited, // True if the process did exit 457309124Sdim int signo, // Zero for no signal 458309124Sdim int status) // Exit value of process if signal is zero 459254721Semaste{ 460314564Sdim shell_info->pid = pid; 461314564Sdim shell_info->signo = signo; 462314564Sdim shell_info->status = status; 463314564Sdim // Let the thread running Host::RunShellCommand() know that the process 464314564Sdim // exited and that ShellInfo has been filled in by broadcasting to it 465314564Sdim shell_info->process_reaped.SetValue(true, eBroadcastAlways); 466314564Sdim return true; 467254721Semaste} 468254721Semaste 469321369SdimStatus Host::RunShellCommand(const char *command, const FileSpec &working_dir, 470321369Sdim int *status_ptr, int *signo_ptr, 471321369Sdim std::string *command_output_ptr, 472341825Sdim const Timeout<std::micro> &timeout, 473353358Sdim bool run_in_default_shell, 474353358Sdim bool hide_stderr) { 475314564Sdim return RunShellCommand(Args(command), working_dir, status_ptr, signo_ptr, 476353358Sdim command_output_ptr, timeout, run_in_default_shell, 477353358Sdim hide_stderr); 478288943Sdim} 479288943Sdim 480321369SdimStatus Host::RunShellCommand(const Args &args, const FileSpec &working_dir, 481321369Sdim int *status_ptr, int *signo_ptr, 482321369Sdim std::string *command_output_ptr, 483341825Sdim const Timeout<std::micro> &timeout, 484353358Sdim bool run_in_default_shell, 485353358Sdim bool hide_stderr) { 486321369Sdim Status error; 487314564Sdim ProcessLaunchInfo launch_info; 488314564Sdim launch_info.SetArchitecture(HostInfo::GetArchitecture()); 489314564Sdim if (run_in_default_shell) { 490314564Sdim // Run the command in a shell 491314564Sdim launch_info.SetShell(HostInfo::GetDefaultShell()); 492314564Sdim launch_info.GetArguments().AppendArguments(args); 493314564Sdim const bool localhost = true; 494314564Sdim const bool will_debug = false; 495314564Sdim const bool first_arg_is_full_shell_command = false; 496314564Sdim launch_info.ConvertArgumentsForLaunchingInShell( 497314564Sdim error, localhost, will_debug, first_arg_is_full_shell_command, 0); 498314564Sdim } else { 499314564Sdim // No shell, just run it 500314564Sdim const bool first_arg_is_executable = true; 501314564Sdim launch_info.SetArguments(args, first_arg_is_executable); 502314564Sdim } 503288943Sdim 504314564Sdim if (working_dir) 505314564Sdim launch_info.SetWorkingDirectory(working_dir); 506344779Sdim llvm::SmallString<64> output_file_path; 507288943Sdim 508314564Sdim if (command_output_ptr) { 509341825Sdim // Create a temporary file to get the stdout/stderr and redirect the output 510341825Sdim // of the command into this file. We will later read this file if all goes 511341825Sdim // well and fill the data into "command_output_ptr" 512341825Sdim if (FileSpec tmpdir_file_spec = HostInfo::GetProcessTempDir()) { 513314564Sdim tmpdir_file_spec.AppendPathComponent("lldb-shell-output.%%%%%%"); 514314564Sdim llvm::sys::fs::createUniqueFile(tmpdir_file_spec.GetPath(), 515314564Sdim output_file_path); 516314564Sdim } else { 517314564Sdim llvm::sys::fs::createTemporaryFile("lldb-shell-output.%%%%%%", "", 518314564Sdim output_file_path); 519254721Semaste } 520314564Sdim } 521309124Sdim 522344779Sdim FileSpec output_file_spec(output_file_path.c_str()); 523353358Sdim // Set up file descriptors. 524314564Sdim launch_info.AppendSuppressFileAction(STDIN_FILENO, true, false); 525353358Sdim if (output_file_spec) 526314564Sdim launch_info.AppendOpenFileAction(STDOUT_FILENO, output_file_spec, false, 527314564Sdim true); 528353358Sdim else 529353358Sdim launch_info.AppendSuppressFileAction(STDOUT_FILENO, false, true); 530353358Sdim 531353358Sdim if (output_file_spec && !hide_stderr) 532314564Sdim launch_info.AppendDuplicateFileAction(STDOUT_FILENO, STDERR_FILENO); 533353358Sdim else 534314564Sdim launch_info.AppendSuppressFileAction(STDERR_FILENO, false, true); 535309124Sdim 536314564Sdim std::shared_ptr<ShellInfo> shell_info_sp(new ShellInfo()); 537314564Sdim const bool monitor_signals = false; 538314564Sdim launch_info.SetMonitorProcessCallback( 539314564Sdim std::bind(MonitorShellCommand, shell_info_sp, std::placeholders::_1, 540314564Sdim std::placeholders::_2, std::placeholders::_3, 541314564Sdim std::placeholders::_4), 542314564Sdim monitor_signals); 543309124Sdim 544314564Sdim error = LaunchProcess(launch_info); 545314564Sdim const lldb::pid_t pid = launch_info.GetProcessID(); 546314564Sdim 547314564Sdim if (error.Success() && pid == LLDB_INVALID_PROCESS_ID) 548314564Sdim error.SetErrorString("failed to get process ID"); 549314564Sdim 550314564Sdim if (error.Success()) { 551341825Sdim if (!shell_info_sp->process_reaped.WaitForValueEqualTo(true, timeout)) { 552314564Sdim error.SetErrorString("timed out waiting for shell command to complete"); 553314564Sdim 554314564Sdim // Kill the process since it didn't complete within the timeout specified 555314564Sdim Kill(pid, SIGKILL); 556314564Sdim // Wait for the monitor callback to get the message 557314564Sdim shell_info_sp->process_reaped.WaitForValueEqualTo( 558341825Sdim true, std::chrono::seconds(1)); 559314564Sdim } else { 560314564Sdim if (status_ptr) 561314564Sdim *status_ptr = shell_info_sp->status; 562314564Sdim 563314564Sdim if (signo_ptr) 564314564Sdim *signo_ptr = shell_info_sp->signo; 565314564Sdim 566314564Sdim if (command_output_ptr) { 567314564Sdim command_output_ptr->clear(); 568344779Sdim uint64_t file_size = 569344779Sdim FileSystem::Instance().GetByteSize(output_file_spec); 570314564Sdim if (file_size > 0) { 571314564Sdim if (file_size > command_output_ptr->max_size()) { 572314564Sdim error.SetErrorStringWithFormat( 573314564Sdim "shell command output is too large to fit into a std::string"); 574314564Sdim } else { 575321369Sdim auto Buffer = 576344779Sdim FileSystem::Instance().CreateDataBuffer(output_file_spec); 577314564Sdim if (error.Success()) 578321369Sdim command_output_ptr->assign(Buffer->GetChars(), 579321369Sdim Buffer->GetByteSize()); 580314564Sdim } 581254721Semaste } 582314564Sdim } 583254721Semaste } 584314564Sdim } 585254721Semaste 586321369Sdim llvm::sys::fs::remove(output_file_spec.GetPath()); 587314564Sdim return error; 588254721Semaste} 589254721Semaste 590341825Sdim// The functions below implement process launching for non-Apple-based 591341825Sdim// platforms 592314564Sdim#if !defined(__APPLE__) 593321369SdimStatus Host::LaunchProcess(ProcessLaunchInfo &launch_info) { 594314564Sdim std::unique_ptr<ProcessLauncher> delegate_launcher; 595280031Sdim#if defined(_WIN32) 596314564Sdim delegate_launcher.reset(new ProcessLauncherWindows()); 597280031Sdim#else 598321369Sdim delegate_launcher.reset(new ProcessLauncherPosixFork()); 599280031Sdim#endif 600314564Sdim MonitoringProcessLauncher launcher(std::move(delegate_launcher)); 601280031Sdim 602321369Sdim Status error; 603314564Sdim HostProcess process = launcher.LaunchProcess(launch_info, error); 604258054Semaste 605314564Sdim // TODO(zturner): It would be better if the entire HostProcess were returned 606341825Sdim // instead of writing it into this structure. 607314564Sdim launch_info.SetProcessID(process.GetProcessId()); 608258054Semaste 609314564Sdim return error; 610258054Semaste} 611321369Sdim#endif // !defined(__APPLE__) 612258054Semaste 613258054Semaste#ifndef _WIN32 614314564Sdimvoid Host::Kill(lldb::pid_t pid, int signo) { ::kill(pid, signo); } 615254721Semaste 616258054Semaste#endif 617254721Semaste 618314564Sdim#if !defined(__APPLE__) 619314564Sdimbool Host::OpenFileInExternalEditor(const FileSpec &file_spec, 620314564Sdim uint32_t line_no) { 621314564Sdim return false; 622254721Semaste} 623254721Semaste 624258884Semaste#endif 625258884Semaste 626321369Sdimstd::unique_ptr<Connection> Host::CreateDefaultConnection(llvm::StringRef url) { 627321369Sdim#if defined(_WIN32) 628321369Sdim if (url.startswith("file://")) 629321369Sdim return std::unique_ptr<Connection>(new ConnectionGenericFile()); 630321369Sdim#endif 631321369Sdim return std::unique_ptr<Connection>(new ConnectionFileDescriptor()); 632321369Sdim} 633321369Sdim 634321369Sdim#if defined(LLVM_ON_UNIX) 635321369SdimWaitStatus WaitStatus::Decode(int wstatus) { 636321369Sdim if (WIFEXITED(wstatus)) 637321369Sdim return {Exit, uint8_t(WEXITSTATUS(wstatus))}; 638321369Sdim else if (WIFSIGNALED(wstatus)) 639321369Sdim return {Signal, uint8_t(WTERMSIG(wstatus))}; 640321369Sdim else if (WIFSTOPPED(wstatus)) 641321369Sdim return {Stop, uint8_t(WSTOPSIG(wstatus))}; 642321369Sdim llvm_unreachable("Unknown wait status"); 643321369Sdim} 644321369Sdim#endif 645321369Sdim 646321369Sdimvoid llvm::format_provider<WaitStatus>::format(const WaitStatus &WS, 647321369Sdim raw_ostream &OS, 648321369Sdim StringRef Options) { 649321369Sdim if (Options == "g") { 650321369Sdim char type; 651321369Sdim switch (WS.type) { 652321369Sdim case WaitStatus::Exit: 653321369Sdim type = 'W'; 654321369Sdim break; 655321369Sdim case WaitStatus::Signal: 656321369Sdim type = 'X'; 657321369Sdim break; 658321369Sdim case WaitStatus::Stop: 659321369Sdim type = 'S'; 660321369Sdim break; 661321369Sdim } 662321369Sdim OS << formatv("{0}{1:x-2}", type, WS.status); 663321369Sdim return; 664321369Sdim } 665321369Sdim 666321369Sdim assert(Options.empty()); 667321369Sdim const char *desc; 668321369Sdim switch(WS.type) { 669321369Sdim case WaitStatus::Exit: 670321369Sdim desc = "Exited with status"; 671321369Sdim break; 672321369Sdim case WaitStatus::Signal: 673321369Sdim desc = "Killed by signal"; 674321369Sdim break; 675321369Sdim case WaitStatus::Stop: 676321369Sdim desc = "Stopped by signal"; 677321369Sdim break; 678321369Sdim } 679321369Sdim OS << desc << " " << int(WS.status); 680321369Sdim} 681