Host.cpp revision 341825
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// C includes 11258054Semaste#include <errno.h> 12258054Semaste#include <limits.h> 13276479Sdim#include <stdlib.h> 14258054Semaste#include <sys/types.h> 15280031Sdim#ifndef _WIN32 16254721Semaste#include <dlfcn.h> 17254721Semaste#include <grp.h> 18254721Semaste#include <netdb.h> 19254721Semaste#include <pwd.h> 20258884Semaste#include <sys/stat.h> 21314564Sdim#include <unistd.h> 22258054Semaste#endif 23258054Semaste 24314564Sdim#if defined(__APPLE__) 25314564Sdim#include <mach-o/dyld.h> 26314564Sdim#include <mach/mach_init.h> 27258054Semaste#include <mach/mach_port.h> 28254721Semaste#endif 29254721Semaste 30314564Sdim#if defined(__linux__) || defined(__FreeBSD__) || \ 31321369Sdim defined(__FreeBSD_kernel__) || defined(__APPLE__) || \ 32321369Sdim defined(__NetBSD__) || defined(__OpenBSD__) 33314564Sdim#if !defined(__ANDROID__) 34258054Semaste#include <spawn.h> 35280031Sdim#endif 36314564Sdim#include <sys/syscall.h> 37254721Semaste#include <sys/wait.h> 38254721Semaste#endif 39254721Semaste 40314564Sdim#if defined(__FreeBSD__) 41254721Semaste#include <pthread_np.h> 42254721Semaste#endif 43254721Semaste 44321369Sdim#if defined(__NetBSD__) 45321369Sdim#include <lwp.h> 46321369Sdim#endif 47321369Sdim 48309124Sdim// C++ Includes 49321369Sdim#include <csignal> 50276479Sdim 51314564Sdim#include "lldb/Host/Host.h" 52314564Sdim#include "lldb/Host/HostInfo.h" 53280031Sdim#include "lldb/Host/HostProcess.h" 54280031Sdim#include "lldb/Host/MonitoringProcessLauncher.h" 55288943Sdim#include "lldb/Host/Predicate.h" 56280031Sdim#include "lldb/Host/ProcessLauncher.h" 57280031Sdim#include "lldb/Host/ThreadLauncher.h" 58321369Sdim#include "lldb/Host/posix/ConnectionFileDescriptorPosix.h" 59276479Sdim#include "lldb/Target/FileAction.h" 60276479Sdim#include "lldb/Target/ProcessLaunchInfo.h" 61288943Sdim#include "lldb/Target/UnixSignals.h" 62321369Sdim#include "lldb/Utility/DataBufferLLVM.h" 63321369Sdim#include "lldb/Utility/FileSpec.h" 64321369Sdim#include "lldb/Utility/Log.h" 65321369Sdim#include "lldb/Utility/Status.h" 66314564Sdim#include "lldb/lldb-private-forward.h" 67288943Sdim#include "llvm/ADT/SmallString.h" 68321369Sdim#include "llvm/ADT/StringSwitch.h" 69321369Sdim#include "llvm/Support/Errno.h" 70314564Sdim#include "llvm/Support/FileSystem.h" 71254721Semaste 72280031Sdim#if defined(_WIN32) 73321369Sdim#include "lldb/Host/windows/ConnectionGenericFileWindows.h" 74280031Sdim#include "lldb/Host/windows/ProcessLauncherWindows.h" 75280031Sdim#else 76321369Sdim#include "lldb/Host/posix/ProcessLauncherPosixFork.h" 77280031Sdim#endif 78254721Semaste 79314564Sdim#if defined(__APPLE__) 80262528Semaste#ifndef _POSIX_SPAWN_DISABLE_ASLR 81314564Sdim#define _POSIX_SPAWN_DISABLE_ASLR 0x0100 82262528Semaste#endif 83254721Semaste 84314564Sdimextern "C" { 85314564Sdimint __pthread_chdir(const char *path); 86314564Sdimint __pthread_fchdir(int fildes); 87262528Semaste} 88262528Semaste 89262528Semaste#endif 90262528Semaste 91254721Semasteusing namespace lldb; 92254721Semasteusing namespace lldb_private; 93254721Semaste 94314564Sdim#if !defined(__APPLE__) && !defined(_WIN32) 95314564Sdimstruct MonitorInfo { 96314564Sdim lldb::pid_t pid; // The process ID to monitor 97314564Sdim Host::MonitorChildProcessCallback 98314564Sdim callback; // The callback function to call when "pid" exits or signals 99314564Sdim bool monitor_signals; // If true, call the callback when "pid" gets signaled. 100254721Semaste}; 101254721Semaste 102314564Sdimstatic thread_result_t MonitorChildProcessThreadFunction(void *arg); 103254721Semaste 104314564SdimHostThread Host::StartMonitoringChildProcess( 105314564Sdim const Host::MonitorChildProcessCallback &callback, lldb::pid_t pid, 106314564Sdim bool monitor_signals) { 107314564Sdim MonitorInfo *info_ptr = new MonitorInfo(); 108258054Semaste 109314564Sdim info_ptr->pid = pid; 110314564Sdim info_ptr->callback = callback; 111314564Sdim info_ptr->monitor_signals = monitor_signals; 112314564Sdim 113314564Sdim char thread_name[256]; 114314564Sdim ::snprintf(thread_name, sizeof(thread_name), 115314564Sdim "<lldb.host.wait4(pid=%" PRIu64 ")>", pid); 116314564Sdim return ThreadLauncher::LaunchThread( 117314564Sdim thread_name, MonitorChildProcessThreadFunction, info_ptr, NULL); 118254721Semaste} 119254721Semaste 120288943Sdim#ifndef __linux__ 121254721Semaste//------------------------------------------------------------------ 122341825Sdim// Scoped class that will disable thread canceling when it is constructed, and 123341825Sdim// exception safely restore the previous value it when it goes out of scope. 124254721Semaste//------------------------------------------------------------------ 125314564Sdimclass ScopedPThreadCancelDisabler { 126254721Semastepublic: 127314564Sdim ScopedPThreadCancelDisabler() { 128314564Sdim // Disable the ability for this thread to be cancelled 129314564Sdim int err = ::pthread_setcancelstate(PTHREAD_CANCEL_DISABLE, &m_old_state); 130314564Sdim if (err != 0) 131314564Sdim m_old_state = -1; 132314564Sdim } 133254721Semaste 134314564Sdim ~ScopedPThreadCancelDisabler() { 135314564Sdim // Restore the ability for this thread to be cancelled to what it 136314564Sdim // previously was. 137314564Sdim if (m_old_state != -1) 138314564Sdim ::pthread_setcancelstate(m_old_state, 0); 139314564Sdim } 140314564Sdim 141254721Semasteprivate: 142314564Sdim int m_old_state; // Save the old cancelability state. 143254721Semaste}; 144288943Sdim#endif // __linux__ 145254721Semaste 146288943Sdim#ifdef __linux__ 147296417Sdim#if defined(__GNUC__) && (__GNUC__ < 4 || (__GNUC__ == 4 && __GNUC_MINOR__ < 8)) 148296417Sdimstatic __thread volatile sig_atomic_t g_usr1_called; 149296417Sdim#else 150288943Sdimstatic thread_local volatile sig_atomic_t g_usr1_called; 151296417Sdim#endif 152288943Sdim 153314564Sdimstatic void SigUsr1Handler(int) { g_usr1_called = 1; } 154288943Sdim#endif // __linux__ 155288943Sdim 156314564Sdimstatic bool CheckForMonitorCancellation() { 157288943Sdim#ifdef __linux__ 158314564Sdim if (g_usr1_called) { 159314564Sdim g_usr1_called = 0; 160314564Sdim return true; 161314564Sdim } 162288943Sdim#else 163314564Sdim ::pthread_testcancel(); 164288943Sdim#endif 165314564Sdim return false; 166288943Sdim} 167288943Sdim 168314564Sdimstatic thread_result_t MonitorChildProcessThreadFunction(void *arg) { 169314564Sdim Log *log(lldb_private::GetLogIfAllCategoriesSet(LIBLLDB_LOG_PROCESS)); 170314564Sdim const char *function = __FUNCTION__; 171314564Sdim if (log) 172314564Sdim log->Printf("%s (arg = %p) thread starting...", function, arg); 173254721Semaste 174314564Sdim MonitorInfo *info = (MonitorInfo *)arg; 175254721Semaste 176314564Sdim const Host::MonitorChildProcessCallback callback = info->callback; 177314564Sdim const bool monitor_signals = info->monitor_signals; 178254721Semaste 179314564Sdim assert(info->pid <= UINT32_MAX); 180314564Sdim const ::pid_t pid = monitor_signals ? -1 * getpgid(info->pid) : info->pid; 181258054Semaste 182314564Sdim delete info; 183254721Semaste 184314564Sdim int status = -1; 185321369Sdim#if defined(__FreeBSD__) || defined(__FreeBSD_kernel__) || defined(__OpenBSD__) 186314564Sdim#define __WALL 0 187254721Semaste#endif 188314564Sdim const int options = __WALL; 189254721Semaste 190288943Sdim#ifdef __linux__ 191314564Sdim // This signal is only used to interrupt the thread from waitpid 192314564Sdim struct sigaction sigUsr1Action; 193314564Sdim memset(&sigUsr1Action, 0, sizeof(sigUsr1Action)); 194314564Sdim sigUsr1Action.sa_handler = SigUsr1Handler; 195314564Sdim ::sigaction(SIGUSR1, &sigUsr1Action, nullptr); 196314564Sdim#endif // __linux__ 197288943Sdim 198314564Sdim while (1) { 199314564Sdim log = lldb_private::GetLogIfAllCategoriesSet(LIBLLDB_LOG_PROCESS); 200314564Sdim if (log) 201314564Sdim log->Printf("%s ::waitpid (pid = %" PRIi32 ", &status, options = %i)...", 202314564Sdim function, pid, options); 203254721Semaste 204314564Sdim if (CheckForMonitorCancellation()) 205314564Sdim break; 206288943Sdim 207314564Sdim // Get signals from all children with same process group of pid 208314564Sdim const ::pid_t wait_pid = ::waitpid(pid, &status, options); 209288943Sdim 210314564Sdim if (CheckForMonitorCancellation()) 211314564Sdim break; 212288943Sdim 213314564Sdim if (wait_pid == -1) { 214314564Sdim if (errno == EINTR) 215314564Sdim continue; 216314564Sdim else { 217321369Sdim LLDB_LOG(log, 218321369Sdim "arg = {0}, thread exiting because waitpid failed ({1})...", 219321369Sdim arg, llvm::sys::StrError()); 220314564Sdim break; 221314564Sdim } 222314564Sdim } else if (wait_pid > 0) { 223314564Sdim bool exited = false; 224314564Sdim int signal = 0; 225314564Sdim int exit_status = 0; 226314564Sdim const char *status_cstr = NULL; 227314564Sdim if (WIFSTOPPED(status)) { 228314564Sdim signal = WSTOPSIG(status); 229314564Sdim status_cstr = "STOPPED"; 230314564Sdim } else if (WIFEXITED(status)) { 231314564Sdim exit_status = WEXITSTATUS(status); 232314564Sdim status_cstr = "EXITED"; 233314564Sdim exited = true; 234314564Sdim } else if (WIFSIGNALED(status)) { 235314564Sdim signal = WTERMSIG(status); 236314564Sdim status_cstr = "SIGNALED"; 237314564Sdim if (wait_pid == abs(pid)) { 238314564Sdim exited = true; 239314564Sdim exit_status = -1; 240254721Semaste } 241314564Sdim } else { 242314564Sdim status_cstr = "(\?\?\?)"; 243314564Sdim } 244254721Semaste 245314564Sdim // Scope for pthread_cancel_disabler 246314564Sdim { 247288943Sdim#ifndef __linux__ 248314564Sdim ScopedPThreadCancelDisabler pthread_cancel_disabler; 249280031Sdim#endif 250254721Semaste 251314564Sdim log = lldb_private::GetLogIfAllCategoriesSet(LIBLLDB_LOG_PROCESS); 252314564Sdim if (log) 253314564Sdim log->Printf("%s ::waitpid (pid = %" PRIi32 254314564Sdim ", &status, options = %i) => pid = %" PRIi32 255314564Sdim ", status = 0x%8.8x (%s), signal = %i, exit_state = %i", 256314564Sdim function, pid, options, wait_pid, status, status_cstr, 257314564Sdim signal, exit_status); 258254721Semaste 259314564Sdim if (exited || (signal != 0 && monitor_signals)) { 260314564Sdim bool callback_return = false; 261314564Sdim if (callback) 262314564Sdim callback_return = callback(wait_pid, exited, signal, exit_status); 263309124Sdim 264314564Sdim // If our process exited, then this thread should exit 265314564Sdim if (exited && wait_pid == abs(pid)) { 266314564Sdim if (log) 267314564Sdim log->Printf("%s (arg = %p) thread exiting because pid received " 268314564Sdim "exit signal...", 269314564Sdim __FUNCTION__, arg); 270314564Sdim break; 271314564Sdim } 272341825Sdim // If the callback returns true, it means this process should exit 273314564Sdim if (callback_return) { 274314564Sdim if (log) 275314564Sdim log->Printf("%s (arg = %p) thread exiting because callback " 276314564Sdim "returned true...", 277314564Sdim __FUNCTION__, arg); 278314564Sdim break; 279314564Sdim } 280254721Semaste } 281314564Sdim } 282254721Semaste } 283314564Sdim } 284254721Semaste 285314564Sdim log = lldb_private::GetLogIfAllCategoriesSet(LIBLLDB_LOG_PROCESS); 286314564Sdim if (log) 287314564Sdim log->Printf("%s (arg = %p) thread exiting...", __FUNCTION__, arg); 288254721Semaste 289314564Sdim return NULL; 290254721Semaste} 291254721Semaste 292258054Semaste#endif // #if !defined (__APPLE__) && !defined (_WIN32) 293254721Semaste 294314564Sdim#if !defined(__APPLE__) 295258054Semaste 296314564Sdimvoid Host::SystemLog(SystemLogType type, const char *format, va_list args) { 297314564Sdim vfprintf(stderr, format, args); 298254721Semaste} 299254721Semaste 300258054Semaste#endif 301254721Semaste 302314564Sdimvoid Host::SystemLog(SystemLogType type, const char *format, ...) { 303314564Sdim va_list args; 304314564Sdim va_start(args, format); 305314564Sdim SystemLog(type, format, args); 306314564Sdim va_end(args); 307254721Semaste} 308254721Semaste 309314564Sdimlldb::pid_t Host::GetCurrentProcessID() { return ::getpid(); } 310254721Semaste 311258054Semaste#ifndef _WIN32 312258054Semaste 313314564Sdimlldb::thread_t Host::GetCurrentThread() { 314314564Sdim return lldb::thread_t(pthread_self()); 315254721Semaste} 316254721Semaste 317314564Sdimconst char *Host::GetSignalAsCString(int signo) { 318314564Sdim switch (signo) { 319314564Sdim case SIGHUP: 320314564Sdim return "SIGHUP"; // 1 hangup 321314564Sdim case SIGINT: 322314564Sdim return "SIGINT"; // 2 interrupt 323314564Sdim case SIGQUIT: 324314564Sdim return "SIGQUIT"; // 3 quit 325314564Sdim case SIGILL: 326314564Sdim return "SIGILL"; // 4 illegal instruction (not reset when caught) 327314564Sdim case SIGTRAP: 328314564Sdim return "SIGTRAP"; // 5 trace trap (not reset when caught) 329314564Sdim case SIGABRT: 330314564Sdim return "SIGABRT"; // 6 abort() 331314564Sdim#if defined(SIGPOLL) 332262528Semaste#if !defined(SIGIO) || (SIGPOLL != SIGIO) 333314564Sdim // Under some GNU/Linux, SIGPOLL and SIGIO are the same. Causing the build to 334314564Sdim // fail with 'multiple define cases with same value' 335314564Sdim case SIGPOLL: 336314564Sdim return "SIGPOLL"; // 7 pollable event ([XSR] generated, not supported) 337254721Semaste#endif 338262528Semaste#endif 339314564Sdim#if defined(SIGEMT) 340314564Sdim case SIGEMT: 341314564Sdim return "SIGEMT"; // 7 EMT instruction 342254721Semaste#endif 343314564Sdim case SIGFPE: 344314564Sdim return "SIGFPE"; // 8 floating point exception 345314564Sdim case SIGKILL: 346314564Sdim return "SIGKILL"; // 9 kill (cannot be caught or ignored) 347314564Sdim case SIGBUS: 348314564Sdim return "SIGBUS"; // 10 bus error 349314564Sdim case SIGSEGV: 350314564Sdim return "SIGSEGV"; // 11 segmentation violation 351314564Sdim case SIGSYS: 352314564Sdim return "SIGSYS"; // 12 bad argument to system call 353314564Sdim case SIGPIPE: 354314564Sdim return "SIGPIPE"; // 13 write on a pipe with no one to read it 355314564Sdim case SIGALRM: 356314564Sdim return "SIGALRM"; // 14 alarm clock 357314564Sdim case SIGTERM: 358314564Sdim return "SIGTERM"; // 15 software termination signal from kill 359314564Sdim case SIGURG: 360314564Sdim return "SIGURG"; // 16 urgent condition on IO channel 361314564Sdim case SIGSTOP: 362314564Sdim return "SIGSTOP"; // 17 sendable stop signal not from tty 363314564Sdim case SIGTSTP: 364314564Sdim return "SIGTSTP"; // 18 stop signal from tty 365314564Sdim case SIGCONT: 366314564Sdim return "SIGCONT"; // 19 continue a stopped process 367314564Sdim case SIGCHLD: 368314564Sdim return "SIGCHLD"; // 20 to parent on child stop or exit 369314564Sdim case SIGTTIN: 370314564Sdim return "SIGTTIN"; // 21 to readers pgrp upon background tty read 371314564Sdim case SIGTTOU: 372314564Sdim return "SIGTTOU"; // 22 like TTIN for output if (tp->t_local<OSTOP) 373314564Sdim#if defined(SIGIO) 374314564Sdim case SIGIO: 375314564Sdim return "SIGIO"; // 23 input/output possible signal 376254721Semaste#endif 377314564Sdim case SIGXCPU: 378314564Sdim return "SIGXCPU"; // 24 exceeded CPU time limit 379314564Sdim case SIGXFSZ: 380314564Sdim return "SIGXFSZ"; // 25 exceeded file size limit 381314564Sdim case SIGVTALRM: 382314564Sdim return "SIGVTALRM"; // 26 virtual time alarm 383314564Sdim case SIGPROF: 384314564Sdim return "SIGPROF"; // 27 profiling time alarm 385314564Sdim#if defined(SIGWINCH) 386314564Sdim case SIGWINCH: 387314564Sdim return "SIGWINCH"; // 28 window size changes 388262528Semaste#endif 389314564Sdim#if defined(SIGINFO) 390314564Sdim case SIGINFO: 391314564Sdim return "SIGINFO"; // 29 information request 392254721Semaste#endif 393314564Sdim case SIGUSR1: 394314564Sdim return "SIGUSR1"; // 30 user defined signal 1 395314564Sdim case SIGUSR2: 396314564Sdim return "SIGUSR2"; // 31 user defined signal 2 397314564Sdim default: 398314564Sdim break; 399314564Sdim } 400314564Sdim return NULL; 401254721Semaste} 402254721Semaste 403258054Semaste#endif 404258054Semaste 405314564Sdim#if !defined(__APPLE__) // see Host.mm 406254721Semaste 407314564Sdimbool Host::GetBundleDirectory(const FileSpec &file, FileSpec &bundle) { 408314564Sdim bundle.Clear(); 409314564Sdim return false; 410254721Semaste} 411254721Semaste 412314564Sdimbool Host::ResolveExecutableInBundle(FileSpec &file) { return false; } 413254721Semaste#endif 414254721Semaste 415258054Semaste#ifndef _WIN32 416258054Semaste 417314564SdimFileSpec Host::GetModuleFileSpecForHostAddress(const void *host_addr) { 418314564Sdim FileSpec module_filespec; 419314564Sdim#if !defined(__ANDROID__) 420314564Sdim Dl_info info; 421314564Sdim if (::dladdr(host_addr, &info)) { 422314564Sdim if (info.dli_fname) 423341825Sdim module_filespec.SetFile(info.dli_fname, true, FileSpec::Style::native); 424314564Sdim } 425280031Sdim#endif 426314564Sdim return module_filespec; 427258054Semaste} 428258054Semaste 429258054Semaste#endif 430258054Semaste 431254721Semaste#if !defined(__linux__) 432314564Sdimbool Host::FindProcessThreads(const lldb::pid_t pid, TidMap &tids_to_attach) { 433314564Sdim return false; 434254721Semaste} 435254721Semaste#endif 436254721Semaste 437314564Sdimstruct ShellInfo { 438314564Sdim ShellInfo() 439314564Sdim : process_reaped(false), pid(LLDB_INVALID_PROCESS_ID), signo(-1), 440314564Sdim status(-1) {} 441254721Semaste 442314564Sdim lldb_private::Predicate<bool> process_reaped; 443314564Sdim lldb::pid_t pid; 444314564Sdim int signo; 445314564Sdim int status; 446254721Semaste}; 447254721Semaste 448254721Semastestatic bool 449309124SdimMonitorShellCommand(std::shared_ptr<ShellInfo> shell_info, lldb::pid_t pid, 450309124Sdim bool exited, // True if the process did exit 451309124Sdim int signo, // Zero for no signal 452309124Sdim int status) // Exit value of process if signal is zero 453254721Semaste{ 454314564Sdim shell_info->pid = pid; 455314564Sdim shell_info->signo = signo; 456314564Sdim shell_info->status = status; 457314564Sdim // Let the thread running Host::RunShellCommand() know that the process 458314564Sdim // exited and that ShellInfo has been filled in by broadcasting to it 459314564Sdim shell_info->process_reaped.SetValue(true, eBroadcastAlways); 460314564Sdim return true; 461254721Semaste} 462254721Semaste 463321369SdimStatus Host::RunShellCommand(const char *command, const FileSpec &working_dir, 464321369Sdim int *status_ptr, int *signo_ptr, 465321369Sdim std::string *command_output_ptr, 466341825Sdim const Timeout<std::micro> &timeout, 467341825Sdim bool run_in_default_shell) { 468314564Sdim return RunShellCommand(Args(command), working_dir, status_ptr, signo_ptr, 469341825Sdim command_output_ptr, timeout, run_in_default_shell); 470288943Sdim} 471288943Sdim 472321369SdimStatus Host::RunShellCommand(const Args &args, const FileSpec &working_dir, 473321369Sdim int *status_ptr, int *signo_ptr, 474321369Sdim std::string *command_output_ptr, 475341825Sdim const Timeout<std::micro> &timeout, 476341825Sdim bool run_in_default_shell) { 477321369Sdim Status error; 478314564Sdim ProcessLaunchInfo launch_info; 479314564Sdim launch_info.SetArchitecture(HostInfo::GetArchitecture()); 480314564Sdim if (run_in_default_shell) { 481314564Sdim // Run the command in a shell 482314564Sdim launch_info.SetShell(HostInfo::GetDefaultShell()); 483314564Sdim launch_info.GetArguments().AppendArguments(args); 484314564Sdim const bool localhost = true; 485314564Sdim const bool will_debug = false; 486314564Sdim const bool first_arg_is_full_shell_command = false; 487314564Sdim launch_info.ConvertArgumentsForLaunchingInShell( 488314564Sdim error, localhost, will_debug, first_arg_is_full_shell_command, 0); 489314564Sdim } else { 490314564Sdim // No shell, just run it 491314564Sdim const bool first_arg_is_executable = true; 492314564Sdim launch_info.SetArguments(args, first_arg_is_executable); 493314564Sdim } 494288943Sdim 495314564Sdim if (working_dir) 496314564Sdim launch_info.SetWorkingDirectory(working_dir); 497314564Sdim llvm::SmallString<PATH_MAX> output_file_path; 498288943Sdim 499314564Sdim if (command_output_ptr) { 500341825Sdim // Create a temporary file to get the stdout/stderr and redirect the output 501341825Sdim // of the command into this file. We will later read this file if all goes 502341825Sdim // well and fill the data into "command_output_ptr" 503341825Sdim if (FileSpec tmpdir_file_spec = HostInfo::GetProcessTempDir()) { 504314564Sdim tmpdir_file_spec.AppendPathComponent("lldb-shell-output.%%%%%%"); 505314564Sdim llvm::sys::fs::createUniqueFile(tmpdir_file_spec.GetPath(), 506314564Sdim output_file_path); 507314564Sdim } else { 508314564Sdim llvm::sys::fs::createTemporaryFile("lldb-shell-output.%%%%%%", "", 509314564Sdim output_file_path); 510254721Semaste } 511314564Sdim } 512309124Sdim 513314564Sdim FileSpec output_file_spec{output_file_path.c_str(), false}; 514309124Sdim 515314564Sdim launch_info.AppendSuppressFileAction(STDIN_FILENO, true, false); 516314564Sdim if (output_file_spec) { 517314564Sdim launch_info.AppendOpenFileAction(STDOUT_FILENO, output_file_spec, false, 518314564Sdim true); 519314564Sdim launch_info.AppendDuplicateFileAction(STDOUT_FILENO, STDERR_FILENO); 520314564Sdim } else { 521314564Sdim launch_info.AppendSuppressFileAction(STDOUT_FILENO, false, true); 522314564Sdim launch_info.AppendSuppressFileAction(STDERR_FILENO, false, true); 523314564Sdim } 524309124Sdim 525314564Sdim std::shared_ptr<ShellInfo> shell_info_sp(new ShellInfo()); 526314564Sdim const bool monitor_signals = false; 527314564Sdim launch_info.SetMonitorProcessCallback( 528314564Sdim std::bind(MonitorShellCommand, shell_info_sp, std::placeholders::_1, 529314564Sdim std::placeholders::_2, std::placeholders::_3, 530314564Sdim std::placeholders::_4), 531314564Sdim monitor_signals); 532309124Sdim 533314564Sdim error = LaunchProcess(launch_info); 534314564Sdim const lldb::pid_t pid = launch_info.GetProcessID(); 535314564Sdim 536314564Sdim if (error.Success() && pid == LLDB_INVALID_PROCESS_ID) 537314564Sdim error.SetErrorString("failed to get process ID"); 538314564Sdim 539314564Sdim if (error.Success()) { 540341825Sdim if (!shell_info_sp->process_reaped.WaitForValueEqualTo(true, timeout)) { 541314564Sdim error.SetErrorString("timed out waiting for shell command to complete"); 542314564Sdim 543314564Sdim // Kill the process since it didn't complete within the timeout specified 544314564Sdim Kill(pid, SIGKILL); 545314564Sdim // Wait for the monitor callback to get the message 546314564Sdim shell_info_sp->process_reaped.WaitForValueEqualTo( 547341825Sdim true, std::chrono::seconds(1)); 548314564Sdim } else { 549314564Sdim if (status_ptr) 550314564Sdim *status_ptr = shell_info_sp->status; 551314564Sdim 552314564Sdim if (signo_ptr) 553314564Sdim *signo_ptr = shell_info_sp->signo; 554314564Sdim 555314564Sdim if (command_output_ptr) { 556314564Sdim command_output_ptr->clear(); 557314564Sdim uint64_t file_size = output_file_spec.GetByteSize(); 558314564Sdim if (file_size > 0) { 559314564Sdim if (file_size > command_output_ptr->max_size()) { 560314564Sdim error.SetErrorStringWithFormat( 561314564Sdim "shell command output is too large to fit into a std::string"); 562314564Sdim } else { 563321369Sdim auto Buffer = 564321369Sdim DataBufferLLVM::CreateFromPath(output_file_spec.GetPath()); 565314564Sdim if (error.Success()) 566321369Sdim command_output_ptr->assign(Buffer->GetChars(), 567321369Sdim Buffer->GetByteSize()); 568314564Sdim } 569254721Semaste } 570314564Sdim } 571254721Semaste } 572314564Sdim } 573254721Semaste 574321369Sdim llvm::sys::fs::remove(output_file_spec.GetPath()); 575314564Sdim return error; 576254721Semaste} 577254721Semaste 578341825Sdim// The functions below implement process launching for non-Apple-based 579341825Sdim// platforms 580314564Sdim#if !defined(__APPLE__) 581321369SdimStatus Host::LaunchProcess(ProcessLaunchInfo &launch_info) { 582314564Sdim std::unique_ptr<ProcessLauncher> delegate_launcher; 583280031Sdim#if defined(_WIN32) 584314564Sdim delegate_launcher.reset(new ProcessLauncherWindows()); 585280031Sdim#else 586321369Sdim delegate_launcher.reset(new ProcessLauncherPosixFork()); 587280031Sdim#endif 588314564Sdim MonitoringProcessLauncher launcher(std::move(delegate_launcher)); 589280031Sdim 590321369Sdim Status error; 591314564Sdim HostProcess process = launcher.LaunchProcess(launch_info, error); 592258054Semaste 593314564Sdim // TODO(zturner): It would be better if the entire HostProcess were returned 594341825Sdim // instead of writing it into this structure. 595314564Sdim launch_info.SetProcessID(process.GetProcessId()); 596258054Semaste 597314564Sdim return error; 598258054Semaste} 599321369Sdim#endif // !defined(__APPLE__) 600258054Semaste 601258054Semaste#ifndef _WIN32 602314564Sdimvoid Host::Kill(lldb::pid_t pid, int signo) { ::kill(pid, signo); } 603254721Semaste 604258054Semaste#endif 605254721Semaste 606314564Sdim#if !defined(__APPLE__) 607314564Sdimbool Host::OpenFileInExternalEditor(const FileSpec &file_spec, 608314564Sdim uint32_t line_no) { 609314564Sdim return false; 610254721Semaste} 611254721Semaste 612258884Semaste#endif 613258884Semaste 614314564Sdimconst UnixSignalsSP &Host::GetUnixSignals() { 615314564Sdim static const auto s_unix_signals_sp = 616314564Sdim UnixSignals::Create(HostInfo::GetArchitecture()); 617314564Sdim return s_unix_signals_sp; 618258054Semaste} 619321369Sdim 620321369Sdimstd::unique_ptr<Connection> Host::CreateDefaultConnection(llvm::StringRef url) { 621321369Sdim#if defined(_WIN32) 622321369Sdim if (url.startswith("file://")) 623321369Sdim return std::unique_ptr<Connection>(new ConnectionGenericFile()); 624321369Sdim#endif 625321369Sdim return std::unique_ptr<Connection>(new ConnectionFileDescriptor()); 626321369Sdim} 627321369Sdim 628321369Sdim#if defined(LLVM_ON_UNIX) 629321369SdimWaitStatus WaitStatus::Decode(int wstatus) { 630321369Sdim if (WIFEXITED(wstatus)) 631321369Sdim return {Exit, uint8_t(WEXITSTATUS(wstatus))}; 632321369Sdim else if (WIFSIGNALED(wstatus)) 633321369Sdim return {Signal, uint8_t(WTERMSIG(wstatus))}; 634321369Sdim else if (WIFSTOPPED(wstatus)) 635321369Sdim return {Stop, uint8_t(WSTOPSIG(wstatus))}; 636321369Sdim llvm_unreachable("Unknown wait status"); 637321369Sdim} 638321369Sdim#endif 639321369Sdim 640321369Sdimvoid llvm::format_provider<WaitStatus>::format(const WaitStatus &WS, 641321369Sdim raw_ostream &OS, 642321369Sdim StringRef Options) { 643321369Sdim if (Options == "g") { 644321369Sdim char type; 645321369Sdim switch (WS.type) { 646321369Sdim case WaitStatus::Exit: 647321369Sdim type = 'W'; 648321369Sdim break; 649321369Sdim case WaitStatus::Signal: 650321369Sdim type = 'X'; 651321369Sdim break; 652321369Sdim case WaitStatus::Stop: 653321369Sdim type = 'S'; 654321369Sdim break; 655321369Sdim } 656321369Sdim OS << formatv("{0}{1:x-2}", type, WS.status); 657321369Sdim return; 658321369Sdim } 659321369Sdim 660321369Sdim assert(Options.empty()); 661321369Sdim const char *desc; 662321369Sdim switch(WS.type) { 663321369Sdim case WaitStatus::Exit: 664321369Sdim desc = "Exited with status"; 665321369Sdim break; 666321369Sdim case WaitStatus::Signal: 667321369Sdim desc = "Killed by signal"; 668321369Sdim break; 669321369Sdim case WaitStatus::Stop: 670321369Sdim desc = "Stopped by signal"; 671321369Sdim break; 672321369Sdim } 673321369Sdim OS << desc << " " << int(WS.status); 674321369Sdim} 675