Host.cpp revision 288943
1//===-- Host.cpp ------------------------------------------------*- C++ -*-===// 2// 3// The LLVM Compiler Infrastructure 4// 5// This file is distributed under the University of Illinois Open Source 6// License. See LICENSE.TXT for details. 7// 8//===----------------------------------------------------------------------===// 9 10// C includes 11#include <errno.h> 12#include <limits.h> 13#include <stdlib.h> 14#include <sys/types.h> 15#ifndef _WIN32 16#include <unistd.h> 17#include <dlfcn.h> 18#include <grp.h> 19#include <netdb.h> 20#include <pwd.h> 21#include <sys/stat.h> 22#endif 23 24#if defined (__APPLE__) 25#include <mach/mach_port.h> 26#include <mach/mach_init.h> 27#include <mach-o/dyld.h> 28#endif 29 30#if defined (__linux__) || defined (__FreeBSD__) || defined (__FreeBSD_kernel__) || defined (__APPLE__) || defined(__NetBSD__) 31#if !defined(__ANDROID__) && !defined(__ANDROID_NDK__) 32#include <spawn.h> 33#endif 34#include <sys/wait.h> 35#include <sys/syscall.h> 36#endif 37 38#if defined (__FreeBSD__) 39#include <pthread_np.h> 40#endif 41 42// C++ includes 43#include <limits> 44 45#include "lldb/Host/FileSystem.h" 46#include "lldb/Host/Host.h" 47#include "lldb/Host/HostInfo.h" 48#include "lldb/Core/ArchSpec.h" 49#include "lldb/Core/Error.h" 50#include "lldb/Core/Log.h" 51#include "lldb/Host/FileSpec.h" 52#include "lldb/Host/HostProcess.h" 53#include "lldb/Host/MonitoringProcessLauncher.h" 54#include "lldb/Host/Predicate.h" 55#include "lldb/Host/ProcessLauncher.h" 56#include "lldb/Host/ThreadLauncher.h" 57#include "lldb/lldb-private-forward.h" 58#include "llvm/Support/FileSystem.h" 59#include "lldb/Target/FileAction.h" 60#include "lldb/Target/ProcessLaunchInfo.h" 61#include "lldb/Target/UnixSignals.h" 62#include "lldb/Utility/CleanUp.h" 63#include "llvm/ADT/SmallString.h" 64 65#if defined(_WIN32) 66#include "lldb/Host/windows/ProcessLauncherWindows.h" 67#elif defined(__ANDROID__) || defined(__ANDROID_NDK__) 68#include "lldb/Host/android/ProcessLauncherAndroid.h" 69#else 70#include "lldb/Host/posix/ProcessLauncherPosix.h" 71#endif 72 73#if defined (__APPLE__) 74#ifndef _POSIX_SPAWN_DISABLE_ASLR 75#define _POSIX_SPAWN_DISABLE_ASLR 0x0100 76#endif 77 78extern "C" 79{ 80 int __pthread_chdir(const char *path); 81 int __pthread_fchdir (int fildes); 82} 83 84#endif 85 86using namespace lldb; 87using namespace lldb_private; 88 89#if !defined (__APPLE__) && !defined (_WIN32) 90struct MonitorInfo 91{ 92 lldb::pid_t pid; // The process ID to monitor 93 Host::MonitorChildProcessCallback callback; // The callback function to call when "pid" exits or signals 94 void *callback_baton; // The callback baton for the callback function 95 bool monitor_signals; // If true, call the callback when "pid" gets signaled. 96}; 97 98static thread_result_t 99MonitorChildProcessThreadFunction (void *arg); 100 101HostThread 102Host::StartMonitoringChildProcess(Host::MonitorChildProcessCallback callback, void *callback_baton, lldb::pid_t pid, bool monitor_signals) 103{ 104 MonitorInfo * info_ptr = new MonitorInfo(); 105 106 info_ptr->pid = pid; 107 info_ptr->callback = callback; 108 info_ptr->callback_baton = callback_baton; 109 info_ptr->monitor_signals = monitor_signals; 110 111 char thread_name[256]; 112 ::snprintf(thread_name, sizeof(thread_name), "<lldb.host.wait4(pid=%" PRIu64 ")>", pid); 113 return ThreadLauncher::LaunchThread(thread_name, MonitorChildProcessThreadFunction, info_ptr, NULL); 114} 115 116#ifndef __linux__ 117//------------------------------------------------------------------ 118// Scoped class that will disable thread canceling when it is 119// constructed, and exception safely restore the previous value it 120// when it goes out of scope. 121//------------------------------------------------------------------ 122class ScopedPThreadCancelDisabler 123{ 124public: 125 ScopedPThreadCancelDisabler() 126 { 127 // Disable the ability for this thread to be cancelled 128 int err = ::pthread_setcancelstate (PTHREAD_CANCEL_DISABLE, &m_old_state); 129 if (err != 0) 130 m_old_state = -1; 131 } 132 133 ~ScopedPThreadCancelDisabler() 134 { 135 // Restore the ability for this thread to be cancelled to what it 136 // previously was. 137 if (m_old_state != -1) 138 ::pthread_setcancelstate (m_old_state, 0); 139 } 140private: 141 int m_old_state; // Save the old cancelability state. 142}; 143#endif // __linux__ 144 145#ifdef __linux__ 146static thread_local volatile sig_atomic_t g_usr1_called; 147 148static void 149SigUsr1Handler (int) 150{ 151 g_usr1_called = 1; 152} 153#endif // __linux__ 154 155static bool 156CheckForMonitorCancellation() 157{ 158#ifdef __linux__ 159 if (g_usr1_called) 160 { 161 g_usr1_called = 0; 162 return true; 163 } 164#else 165 ::pthread_testcancel (); 166#endif 167 return false; 168} 169 170static thread_result_t 171MonitorChildProcessThreadFunction (void *arg) 172{ 173 Log *log(lldb_private::GetLogIfAllCategoriesSet (LIBLLDB_LOG_PROCESS)); 174 const char *function = __FUNCTION__; 175 if (log) 176 log->Printf ("%s (arg = %p) thread starting...", function, arg); 177 178 MonitorInfo *info = (MonitorInfo *)arg; 179 180 const Host::MonitorChildProcessCallback callback = info->callback; 181 void * const callback_baton = info->callback_baton; 182 const bool monitor_signals = info->monitor_signals; 183 184 assert (info->pid <= UINT32_MAX); 185 const ::pid_t pid = monitor_signals ? -1 * getpgid(info->pid) : info->pid; 186 187 delete info; 188 189 int status = -1; 190#if defined (__FreeBSD__) || defined (__FreeBSD_kernel__) 191 #define __WALL 0 192#endif 193 const int options = __WALL; 194 195#ifdef __linux__ 196 // This signal is only used to interrupt the thread from waitpid 197 struct sigaction sigUsr1Action; 198 memset(&sigUsr1Action, 0, sizeof(sigUsr1Action)); 199 sigUsr1Action.sa_handler = SigUsr1Handler; 200 ::sigaction(SIGUSR1, &sigUsr1Action, nullptr); 201#endif // __linux__ 202 203 while (1) 204 { 205 log = lldb_private::GetLogIfAllCategoriesSet (LIBLLDB_LOG_PROCESS); 206 if (log) 207 log->Printf("%s ::waitpid (pid = %" PRIi32 ", &status, options = %i)...", function, pid, options); 208 209 if (CheckForMonitorCancellation ()) 210 break; 211 212 // Get signals from all children with same process group of pid 213 const ::pid_t wait_pid = ::waitpid (pid, &status, options); 214 215 if (CheckForMonitorCancellation ()) 216 break; 217 218 if (wait_pid == -1) 219 { 220 if (errno == EINTR) 221 continue; 222 else 223 { 224 if (log) 225 log->Printf ("%s (arg = %p) thread exiting because waitpid failed (%s)...", __FUNCTION__, arg, strerror(errno)); 226 break; 227 } 228 } 229 else if (wait_pid > 0) 230 { 231 bool exited = false; 232 int signal = 0; 233 int exit_status = 0; 234 const char *status_cstr = NULL; 235 if (WIFSTOPPED(status)) 236 { 237 signal = WSTOPSIG(status); 238 status_cstr = "STOPPED"; 239 } 240 else if (WIFEXITED(status)) 241 { 242 exit_status = WEXITSTATUS(status); 243 status_cstr = "EXITED"; 244 exited = true; 245 } 246 else if (WIFSIGNALED(status)) 247 { 248 signal = WTERMSIG(status); 249 status_cstr = "SIGNALED"; 250 if (wait_pid == abs(pid)) { 251 exited = true; 252 exit_status = -1; 253 } 254 } 255 else 256 { 257 status_cstr = "(\?\?\?)"; 258 } 259 260 // Scope for pthread_cancel_disabler 261 { 262#ifndef __linux__ 263 ScopedPThreadCancelDisabler pthread_cancel_disabler; 264#endif 265 266 log = lldb_private::GetLogIfAllCategoriesSet (LIBLLDB_LOG_PROCESS); 267 if (log) 268 log->Printf ("%s ::waitpid (pid = %" PRIi32 ", &status, options = %i) => pid = %" PRIi32 ", status = 0x%8.8x (%s), signal = %i, exit_state = %i", 269 function, 270 pid, 271 options, 272 wait_pid, 273 status, 274 status_cstr, 275 signal, 276 exit_status); 277 278 if (exited || (signal != 0 && monitor_signals)) 279 { 280 bool callback_return = false; 281 if (callback) 282 callback_return = callback (callback_baton, wait_pid, exited, signal, exit_status); 283 284 // If our process exited, then this thread should exit 285 if (exited && wait_pid == abs(pid)) 286 { 287 if (log) 288 log->Printf ("%s (arg = %p) thread exiting because pid received exit signal...", __FUNCTION__, arg); 289 break; 290 } 291 // If the callback returns true, it means this process should 292 // exit 293 if (callback_return) 294 { 295 if (log) 296 log->Printf ("%s (arg = %p) thread exiting because callback returned true...", __FUNCTION__, arg); 297 break; 298 } 299 } 300 } 301 } 302 } 303 304 log = lldb_private::GetLogIfAllCategoriesSet (LIBLLDB_LOG_PROCESS); 305 if (log) 306 log->Printf ("%s (arg = %p) thread exiting...", __FUNCTION__, arg); 307 308 return NULL; 309} 310 311#endif // #if !defined (__APPLE__) && !defined (_WIN32) 312 313#if !defined (__APPLE__) 314 315void 316Host::SystemLog (SystemLogType type, const char *format, va_list args) 317{ 318 vfprintf (stderr, format, args); 319} 320 321#endif 322 323void 324Host::SystemLog (SystemLogType type, const char *format, ...) 325{ 326 va_list args; 327 va_start (args, format); 328 SystemLog (type, format, args); 329 va_end (args); 330} 331 332lldb::pid_t 333Host::GetCurrentProcessID() 334{ 335 return ::getpid(); 336} 337 338#ifndef _WIN32 339 340lldb::tid_t 341Host::GetCurrentThreadID() 342{ 343#if defined (__APPLE__) 344 // Calling "mach_thread_self()" bumps the reference count on the thread 345 // port, so we need to deallocate it. mach_task_self() doesn't bump the ref 346 // count. 347 thread_port_t thread_self = mach_thread_self(); 348 mach_port_deallocate(mach_task_self(), thread_self); 349 return thread_self; 350#elif defined(__FreeBSD__) 351 return lldb::tid_t(pthread_getthreadid_np()); 352#elif defined(__ANDROID_NDK__) 353 return lldb::tid_t(gettid()); 354#elif defined(__linux__) 355 return lldb::tid_t(syscall(SYS_gettid)); 356#else 357 return lldb::tid_t(pthread_self()); 358#endif 359} 360 361lldb::thread_t 362Host::GetCurrentThread () 363{ 364 return lldb::thread_t(pthread_self()); 365} 366 367const char * 368Host::GetSignalAsCString (int signo) 369{ 370 switch (signo) 371 { 372 case SIGHUP: return "SIGHUP"; // 1 hangup 373 case SIGINT: return "SIGINT"; // 2 interrupt 374 case SIGQUIT: return "SIGQUIT"; // 3 quit 375 case SIGILL: return "SIGILL"; // 4 illegal instruction (not reset when caught) 376 case SIGTRAP: return "SIGTRAP"; // 5 trace trap (not reset when caught) 377 case SIGABRT: return "SIGABRT"; // 6 abort() 378#if defined(SIGPOLL) 379#if !defined(SIGIO) || (SIGPOLL != SIGIO) 380// Under some GNU/Linux, SIGPOLL and SIGIO are the same. Causing the build to 381// fail with 'multiple define cases with same value' 382 case SIGPOLL: return "SIGPOLL"; // 7 pollable event ([XSR] generated, not supported) 383#endif 384#endif 385#if defined(SIGEMT) 386 case SIGEMT: return "SIGEMT"; // 7 EMT instruction 387#endif 388 case SIGFPE: return "SIGFPE"; // 8 floating point exception 389 case SIGKILL: return "SIGKILL"; // 9 kill (cannot be caught or ignored) 390 case SIGBUS: return "SIGBUS"; // 10 bus error 391 case SIGSEGV: return "SIGSEGV"; // 11 segmentation violation 392 case SIGSYS: return "SIGSYS"; // 12 bad argument to system call 393 case SIGPIPE: return "SIGPIPE"; // 13 write on a pipe with no one to read it 394 case SIGALRM: return "SIGALRM"; // 14 alarm clock 395 case SIGTERM: return "SIGTERM"; // 15 software termination signal from kill 396 case SIGURG: return "SIGURG"; // 16 urgent condition on IO channel 397 case SIGSTOP: return "SIGSTOP"; // 17 sendable stop signal not from tty 398 case SIGTSTP: return "SIGTSTP"; // 18 stop signal from tty 399 case SIGCONT: return "SIGCONT"; // 19 continue a stopped process 400 case SIGCHLD: return "SIGCHLD"; // 20 to parent on child stop or exit 401 case SIGTTIN: return "SIGTTIN"; // 21 to readers pgrp upon background tty read 402 case SIGTTOU: return "SIGTTOU"; // 22 like TTIN for output if (tp->t_local<OSTOP) 403#if defined(SIGIO) 404 case SIGIO: return "SIGIO"; // 23 input/output possible signal 405#endif 406 case SIGXCPU: return "SIGXCPU"; // 24 exceeded CPU time limit 407 case SIGXFSZ: return "SIGXFSZ"; // 25 exceeded file size limit 408 case SIGVTALRM: return "SIGVTALRM"; // 26 virtual time alarm 409 case SIGPROF: return "SIGPROF"; // 27 profiling time alarm 410#if defined(SIGWINCH) 411 case SIGWINCH: return "SIGWINCH"; // 28 window size changes 412#endif 413#if defined(SIGINFO) 414 case SIGINFO: return "SIGINFO"; // 29 information request 415#endif 416 case SIGUSR1: return "SIGUSR1"; // 30 user defined signal 1 417 case SIGUSR2: return "SIGUSR2"; // 31 user defined signal 2 418 default: 419 break; 420 } 421 return NULL; 422} 423 424#endif 425 426#ifndef _WIN32 427 428lldb::thread_key_t 429Host::ThreadLocalStorageCreate(ThreadLocalStorageCleanupCallback callback) 430{ 431 pthread_key_t key; 432 ::pthread_key_create (&key, callback); 433 return key; 434} 435 436void* 437Host::ThreadLocalStorageGet(lldb::thread_key_t key) 438{ 439 return ::pthread_getspecific (key); 440} 441 442void 443Host::ThreadLocalStorageSet(lldb::thread_key_t key, void *value) 444{ 445 ::pthread_setspecific (key, value); 446} 447 448#endif 449 450#if !defined (__APPLE__) // see Host.mm 451 452bool 453Host::GetBundleDirectory (const FileSpec &file, FileSpec &bundle) 454{ 455 bundle.Clear(); 456 return false; 457} 458 459bool 460Host::ResolveExecutableInBundle (FileSpec &file) 461{ 462 return false; 463} 464#endif 465 466#ifndef _WIN32 467 468FileSpec 469Host::GetModuleFileSpecForHostAddress (const void *host_addr) 470{ 471 FileSpec module_filespec; 472#if !defined(__ANDROID__) && !defined(__ANDROID_NDK__) 473 Dl_info info; 474 if (::dladdr (host_addr, &info)) 475 { 476 if (info.dli_fname) 477 module_filespec.SetFile(info.dli_fname, true); 478 } 479#endif 480 return module_filespec; 481} 482 483#endif 484 485#if !defined(__linux__) 486bool 487Host::FindProcessThreads (const lldb::pid_t pid, TidMap &tids_to_attach) 488{ 489 return false; 490} 491#endif 492 493struct ShellInfo 494{ 495 ShellInfo () : 496 process_reaped (false), 497 can_delete (false), 498 pid (LLDB_INVALID_PROCESS_ID), 499 signo(-1), 500 status(-1) 501 { 502 } 503 504 lldb_private::Predicate<bool> process_reaped; 505 lldb_private::Predicate<bool> can_delete; 506 lldb::pid_t pid; 507 int signo; 508 int status; 509}; 510 511static bool 512MonitorShellCommand (void *callback_baton, 513 lldb::pid_t pid, 514 bool exited, // True if the process did exit 515 int signo, // Zero for no signal 516 int status) // Exit value of process if signal is zero 517{ 518 ShellInfo *shell_info = (ShellInfo *)callback_baton; 519 shell_info->pid = pid; 520 shell_info->signo = signo; 521 shell_info->status = status; 522 // Let the thread running Host::RunShellCommand() know that the process 523 // exited and that ShellInfo has been filled in by broadcasting to it 524 shell_info->process_reaped.SetValue(1, eBroadcastAlways); 525 // Now wait for a handshake back from that thread running Host::RunShellCommand 526 // so we know that we can delete shell_info_ptr 527 shell_info->can_delete.WaitForValueEqualTo(true); 528 // Sleep a bit to allow the shell_info->can_delete.SetValue() to complete... 529 usleep(1000); 530 // Now delete the shell info that was passed into this function 531 delete shell_info; 532 return true; 533} 534 535Error 536Host::RunShellCommand(const char *command, 537 const FileSpec &working_dir, 538 int *status_ptr, 539 int *signo_ptr, 540 std::string *command_output_ptr, 541 uint32_t timeout_sec, 542 bool run_in_default_shell) 543{ 544 return RunShellCommand(Args(command), working_dir, status_ptr, signo_ptr, command_output_ptr, timeout_sec, run_in_default_shell); 545} 546 547Error 548Host::RunShellCommand(const Args &args, 549 const FileSpec &working_dir, 550 int *status_ptr, 551 int *signo_ptr, 552 std::string *command_output_ptr, 553 uint32_t timeout_sec, 554 bool run_in_default_shell) 555{ 556 Error error; 557 ProcessLaunchInfo launch_info; 558 launch_info.SetArchitecture(HostInfo::GetArchitecture()); 559 if (run_in_default_shell) 560 { 561 // Run the command in a shell 562 launch_info.SetShell(HostInfo::GetDefaultShell()); 563 launch_info.GetArguments().AppendArguments(args); 564 const bool localhost = true; 565 const bool will_debug = false; 566 const bool first_arg_is_full_shell_command = false; 567 launch_info.ConvertArgumentsForLaunchingInShell (error, 568 localhost, 569 will_debug, 570 first_arg_is_full_shell_command, 571 0); 572 } 573 else 574 { 575 // No shell, just run it 576 const bool first_arg_is_executable = true; 577 launch_info.SetArguments(args, first_arg_is_executable); 578 } 579 580 if (working_dir) 581 launch_info.SetWorkingDirectory(working_dir); 582 llvm::SmallString<PATH_MAX> output_file_path; 583 584 if (command_output_ptr) 585 { 586 // Create a temporary file to get the stdout/stderr and redirect the 587 // output of the command into this file. We will later read this file 588 // if all goes well and fill the data into "command_output_ptr" 589 FileSpec tmpdir_file_spec; 590 if (HostInfo::GetLLDBPath(ePathTypeLLDBTempSystemDir, tmpdir_file_spec)) 591 { 592 tmpdir_file_spec.AppendPathComponent("lldb-shell-output.%%%%%%"); 593 llvm::sys::fs::createUniqueFile(tmpdir_file_spec.GetPath().c_str(), output_file_path); 594 } 595 else 596 { 597 llvm::sys::fs::createTemporaryFile("lldb-shell-output.%%%%%%", "", output_file_path); 598 } 599 } 600 601 FileSpec output_file_spec{output_file_path.c_str(), false}; 602 603 launch_info.AppendSuppressFileAction (STDIN_FILENO, true, false); 604 if (output_file_spec) 605 { 606 launch_info.AppendOpenFileAction(STDOUT_FILENO, output_file_spec, false, true); 607 launch_info.AppendDuplicateFileAction(STDOUT_FILENO, STDERR_FILENO); 608 } 609 else 610 { 611 launch_info.AppendSuppressFileAction (STDOUT_FILENO, false, true); 612 launch_info.AppendSuppressFileAction (STDERR_FILENO, false, true); 613 } 614 615 // The process monitor callback will delete the 'shell_info_ptr' below... 616 std::unique_ptr<ShellInfo> shell_info_ap (new ShellInfo()); 617 618 const bool monitor_signals = false; 619 launch_info.SetMonitorProcessCallback(MonitorShellCommand, shell_info_ap.get(), monitor_signals); 620 621 error = LaunchProcess (launch_info); 622 const lldb::pid_t pid = launch_info.GetProcessID(); 623 624 if (error.Success() && pid == LLDB_INVALID_PROCESS_ID) 625 error.SetErrorString("failed to get process ID"); 626 627 if (error.Success()) 628 { 629 // The process successfully launched, so we can defer ownership of 630 // "shell_info" to the MonitorShellCommand callback function that will 631 // get called when the process dies. We release the unique pointer as it 632 // doesn't need to delete the ShellInfo anymore. 633 ShellInfo *shell_info = shell_info_ap.release(); 634 TimeValue *timeout_ptr = nullptr; 635 TimeValue timeout_time(TimeValue::Now()); 636 if (timeout_sec > 0) { 637 timeout_time.OffsetWithSeconds(timeout_sec); 638 timeout_ptr = &timeout_time; 639 } 640 bool timed_out = false; 641 shell_info->process_reaped.WaitForValueEqualTo(true, timeout_ptr, &timed_out); 642 if (timed_out) 643 { 644 error.SetErrorString("timed out waiting for shell command to complete"); 645 646 // Kill the process since it didn't complete within the timeout specified 647 Kill (pid, SIGKILL); 648 // Wait for the monitor callback to get the message 649 timeout_time = TimeValue::Now(); 650 timeout_time.OffsetWithSeconds(1); 651 timed_out = false; 652 shell_info->process_reaped.WaitForValueEqualTo(true, &timeout_time, &timed_out); 653 } 654 else 655 { 656 if (status_ptr) 657 *status_ptr = shell_info->status; 658 659 if (signo_ptr) 660 *signo_ptr = shell_info->signo; 661 662 if (command_output_ptr) 663 { 664 command_output_ptr->clear(); 665 uint64_t file_size = output_file_spec.GetByteSize(); 666 if (file_size > 0) 667 { 668 if (file_size > command_output_ptr->max_size()) 669 { 670 error.SetErrorStringWithFormat("shell command output is too large to fit into a std::string"); 671 } 672 else 673 { 674 std::vector<char> command_output(file_size); 675 output_file_spec.ReadFileContents(0, command_output.data(), file_size, &error); 676 if (error.Success()) 677 command_output_ptr->assign(command_output.data(), file_size); 678 } 679 } 680 } 681 } 682 shell_info->can_delete.SetValue(true, eBroadcastAlways); 683 } 684 685 if (FileSystem::GetFileExists(output_file_spec)) 686 FileSystem::Unlink(output_file_spec); 687 // Handshake with the monitor thread, or just let it know in advance that 688 // it can delete "shell_info" in case we timed out and were not able to kill 689 // the process... 690 return error; 691} 692 693// LaunchProcessPosixSpawn for Apple, Linux, FreeBSD and other GLIBC 694// systems 695 696#if defined (__APPLE__) || defined (__linux__) || defined (__FreeBSD__) || defined (__GLIBC__) || defined(__NetBSD__) 697#if !defined(__ANDROID__) && !defined(__ANDROID_NDK__) 698// this method needs to be visible to macosx/Host.cpp and 699// common/Host.cpp. 700 701short 702Host::GetPosixspawnFlags(const ProcessLaunchInfo &launch_info) 703{ 704 short flags = POSIX_SPAWN_SETSIGDEF | POSIX_SPAWN_SETSIGMASK; 705 706#if defined (__APPLE__) 707 if (launch_info.GetFlags().Test (eLaunchFlagExec)) 708 flags |= POSIX_SPAWN_SETEXEC; // Darwin specific posix_spawn flag 709 710 if (launch_info.GetFlags().Test (eLaunchFlagDebug)) 711 flags |= POSIX_SPAWN_START_SUSPENDED; // Darwin specific posix_spawn flag 712 713 if (launch_info.GetFlags().Test (eLaunchFlagDisableASLR)) 714 flags |= _POSIX_SPAWN_DISABLE_ASLR; // Darwin specific posix_spawn flag 715 716 if (launch_info.GetLaunchInSeparateProcessGroup()) 717 flags |= POSIX_SPAWN_SETPGROUP; 718 719#ifdef POSIX_SPAWN_CLOEXEC_DEFAULT 720#if defined (__APPLE__) && (defined (__x86_64__) || defined (__i386__)) 721 static LazyBool g_use_close_on_exec_flag = eLazyBoolCalculate; 722 if (g_use_close_on_exec_flag == eLazyBoolCalculate) 723 { 724 g_use_close_on_exec_flag = eLazyBoolNo; 725 726 uint32_t major, minor, update; 727 if (HostInfo::GetOSVersion(major, minor, update)) 728 { 729 // Kernel panic if we use the POSIX_SPAWN_CLOEXEC_DEFAULT on 10.7 or earlier 730 if (major > 10 || (major == 10 && minor > 7)) 731 { 732 // Only enable for 10.8 and later OS versions 733 g_use_close_on_exec_flag = eLazyBoolYes; 734 } 735 } 736 } 737#else 738 static LazyBool g_use_close_on_exec_flag = eLazyBoolYes; 739#endif 740 // Close all files exception those with file actions if this is supported. 741 if (g_use_close_on_exec_flag == eLazyBoolYes) 742 flags |= POSIX_SPAWN_CLOEXEC_DEFAULT; 743#endif 744#endif // #if defined (__APPLE__) 745 return flags; 746} 747 748Error 749Host::LaunchProcessPosixSpawn(const char *exe_path, const ProcessLaunchInfo &launch_info, lldb::pid_t &pid) 750{ 751 Error error; 752 Log *log(lldb_private::GetLogIfAllCategoriesSet (LIBLLDB_LOG_HOST | LIBLLDB_LOG_PROCESS)); 753 754 posix_spawnattr_t attr; 755 error.SetError( ::posix_spawnattr_init (&attr), eErrorTypePOSIX); 756 757 if (error.Fail() || log) 758 error.PutToLog(log, "::posix_spawnattr_init ( &attr )"); 759 if (error.Fail()) 760 return error; 761 762 // Make a quick class that will cleanup the posix spawn attributes in case 763 // we return in the middle of this function. 764 lldb_utility::CleanUp <posix_spawnattr_t *, int> posix_spawnattr_cleanup(&attr, posix_spawnattr_destroy); 765 766 sigset_t no_signals; 767 sigset_t all_signals; 768 sigemptyset (&no_signals); 769 sigfillset (&all_signals); 770 ::posix_spawnattr_setsigmask(&attr, &no_signals); 771#if defined (__linux__) || defined (__FreeBSD__) 772 ::posix_spawnattr_setsigdefault(&attr, &no_signals); 773#else 774 ::posix_spawnattr_setsigdefault(&attr, &all_signals); 775#endif 776 777 short flags = GetPosixspawnFlags(launch_info); 778 779 error.SetError( ::posix_spawnattr_setflags (&attr, flags), eErrorTypePOSIX); 780 if (error.Fail() || log) 781 error.PutToLog(log, "::posix_spawnattr_setflags ( &attr, flags=0x%8.8x )", flags); 782 if (error.Fail()) 783 return error; 784 785 // posix_spawnattr_setbinpref_np appears to be an Apple extension per: 786 // http://www.unix.com/man-page/OSX/3/posix_spawnattr_setbinpref_np/ 787#if defined (__APPLE__) && !defined (__arm__) 788 789 // Don't set the binpref if a shell was provided. After all, that's only going to affect what version of the shell 790 // is launched, not what fork of the binary is launched. We insert "arch --arch <ARCH> as part of the shell invocation 791 // to do that job on OSX. 792 793 if (launch_info.GetShell() == nullptr) 794 { 795 // We don't need to do this for ARM, and we really shouldn't now that we 796 // have multiple CPU subtypes and no posix_spawnattr call that allows us 797 // to set which CPU subtype to launch... 798 const ArchSpec &arch_spec = launch_info.GetArchitecture(); 799 cpu_type_t cpu = arch_spec.GetMachOCPUType(); 800 cpu_type_t sub = arch_spec.GetMachOCPUSubType(); 801 if (cpu != 0 && 802 cpu != static_cast<cpu_type_t>(UINT32_MAX) && 803 cpu != static_cast<cpu_type_t>(LLDB_INVALID_CPUTYPE) && 804 !(cpu == 0x01000007 && sub == 8)) // If haswell is specified, don't try to set the CPU type or we will fail 805 { 806 size_t ocount = 0; 807 error.SetError( ::posix_spawnattr_setbinpref_np (&attr, 1, &cpu, &ocount), eErrorTypePOSIX); 808 if (error.Fail() || log) 809 error.PutToLog(log, "::posix_spawnattr_setbinpref_np ( &attr, 1, cpu_type = 0x%8.8x, count => %llu )", cpu, (uint64_t)ocount); 810 811 if (error.Fail() || ocount != 1) 812 return error; 813 } 814 } 815 816#endif 817 818 const char *tmp_argv[2]; 819 char * const *argv = (char * const*)launch_info.GetArguments().GetConstArgumentVector(); 820 char * const *envp = (char * const*)launch_info.GetEnvironmentEntries().GetConstArgumentVector(); 821 if (argv == NULL) 822 { 823 // posix_spawn gets very unhappy if it doesn't have at least the program 824 // name in argv[0]. One of the side affects I have noticed is the environment 825 // variables don't make it into the child process if "argv == NULL"!!! 826 tmp_argv[0] = exe_path; 827 tmp_argv[1] = NULL; 828 argv = (char * const*)tmp_argv; 829 } 830 831#if !defined (__APPLE__) 832 // manage the working directory 833 char current_dir[PATH_MAX]; 834 current_dir[0] = '\0'; 835#endif 836 837 FileSpec working_dir{launch_info.GetWorkingDirectory()}; 838 if (working_dir) 839 { 840#if defined (__APPLE__) 841 // Set the working directory on this thread only 842 if (__pthread_chdir(working_dir.GetCString()) < 0) { 843 if (errno == ENOENT) { 844 error.SetErrorStringWithFormat("No such file or directory: %s", 845 working_dir.GetCString()); 846 } else if (errno == ENOTDIR) { 847 error.SetErrorStringWithFormat("Path doesn't name a directory: %s", 848 working_dir.GetCString()); 849 } else { 850 error.SetErrorStringWithFormat("An unknown error occurred when changing directory for process execution."); 851 } 852 return error; 853 } 854#else 855 if (::getcwd(current_dir, sizeof(current_dir)) == NULL) 856 { 857 error.SetError(errno, eErrorTypePOSIX); 858 error.LogIfError(log, "unable to save the current directory"); 859 return error; 860 } 861 862 if (::chdir(working_dir.GetCString()) == -1) 863 { 864 error.SetError(errno, eErrorTypePOSIX); 865 error.LogIfError(log, "unable to change working directory to %s", 866 working_dir.GetCString()); 867 return error; 868 } 869#endif 870 } 871 872 ::pid_t result_pid = LLDB_INVALID_PROCESS_ID; 873 const size_t num_file_actions = launch_info.GetNumFileActions (); 874 if (num_file_actions > 0) 875 { 876 posix_spawn_file_actions_t file_actions; 877 error.SetError( ::posix_spawn_file_actions_init (&file_actions), eErrorTypePOSIX); 878 if (error.Fail() || log) 879 error.PutToLog(log, "::posix_spawn_file_actions_init ( &file_actions )"); 880 if (error.Fail()) 881 return error; 882 883 // Make a quick class that will cleanup the posix spawn attributes in case 884 // we return in the middle of this function. 885 lldb_utility::CleanUp <posix_spawn_file_actions_t *, int> posix_spawn_file_actions_cleanup (&file_actions, posix_spawn_file_actions_destroy); 886 887 for (size_t i=0; i<num_file_actions; ++i) 888 { 889 const FileAction *launch_file_action = launch_info.GetFileActionAtIndex(i); 890 if (launch_file_action) 891 { 892 if (!AddPosixSpawnFileAction(&file_actions, launch_file_action, log, error)) 893 return error; 894 } 895 } 896 897 error.SetError(::posix_spawnp(&result_pid, exe_path, &file_actions, &attr, argv, envp), eErrorTypePOSIX); 898 899 if (error.Fail() || log) 900 { 901 error.PutToLog(log, "::posix_spawnp ( pid => %i, path = '%s', file_actions = %p, attr = %p, argv = %p, envp = %p )", result_pid, 902 exe_path, static_cast<void *>(&file_actions), static_cast<void *>(&attr), reinterpret_cast<const void *>(argv), 903 reinterpret_cast<const void *>(envp)); 904 if (log) 905 { 906 for (int ii=0; argv[ii]; ++ii) 907 log->Printf("argv[%i] = '%s'", ii, argv[ii]); 908 } 909 } 910 911 } 912 else 913 { 914 error.SetError(::posix_spawnp(&result_pid, exe_path, NULL, &attr, argv, envp), eErrorTypePOSIX); 915 916 if (error.Fail() || log) 917 { 918 error.PutToLog(log, "::posix_spawnp ( pid => %i, path = '%s', file_actions = NULL, attr = %p, argv = %p, envp = %p )", 919 result_pid, exe_path, static_cast<void *>(&attr), reinterpret_cast<const void *>(argv), 920 reinterpret_cast<const void *>(envp)); 921 if (log) 922 { 923 for (int ii=0; argv[ii]; ++ii) 924 log->Printf("argv[%i] = '%s'", ii, argv[ii]); 925 } 926 } 927 } 928 pid = result_pid; 929 930 if (working_dir) 931 { 932#if defined (__APPLE__) 933 // No more thread specific current working directory 934 __pthread_fchdir (-1); 935#else 936 if (::chdir(current_dir) == -1 && error.Success()) 937 { 938 error.SetError(errno, eErrorTypePOSIX); 939 error.LogIfError(log, "unable to change current directory back to %s", 940 current_dir); 941 } 942#endif 943 } 944 945 return error; 946} 947 948bool 949Host::AddPosixSpawnFileAction(void *_file_actions, const FileAction *info, Log *log, Error &error) 950{ 951 if (info == NULL) 952 return false; 953 954 posix_spawn_file_actions_t *file_actions = reinterpret_cast<posix_spawn_file_actions_t *>(_file_actions); 955 956 switch (info->GetAction()) 957 { 958 case FileAction::eFileActionNone: 959 error.Clear(); 960 break; 961 962 case FileAction::eFileActionClose: 963 if (info->GetFD() == -1) 964 error.SetErrorString("invalid fd for posix_spawn_file_actions_addclose(...)"); 965 else 966 { 967 error.SetError(::posix_spawn_file_actions_addclose(file_actions, info->GetFD()), eErrorTypePOSIX); 968 if (log && (error.Fail() || log)) 969 error.PutToLog(log, "posix_spawn_file_actions_addclose (action=%p, fd=%i)", 970 static_cast<void *>(file_actions), info->GetFD()); 971 } 972 break; 973 974 case FileAction::eFileActionDuplicate: 975 if (info->GetFD() == -1) 976 error.SetErrorString("invalid fd for posix_spawn_file_actions_adddup2(...)"); 977 else if (info->GetActionArgument() == -1) 978 error.SetErrorString("invalid duplicate fd for posix_spawn_file_actions_adddup2(...)"); 979 else 980 { 981 error.SetError( 982 ::posix_spawn_file_actions_adddup2(file_actions, info->GetFD(), info->GetActionArgument()), 983 eErrorTypePOSIX); 984 if (log && (error.Fail() || log)) 985 error.PutToLog(log, "posix_spawn_file_actions_adddup2 (action=%p, fd=%i, dup_fd=%i)", 986 static_cast<void *>(file_actions), info->GetFD(), info->GetActionArgument()); 987 } 988 break; 989 990 case FileAction::eFileActionOpen: 991 if (info->GetFD() == -1) 992 error.SetErrorString("invalid fd in posix_spawn_file_actions_addopen(...)"); 993 else 994 { 995 int oflag = info->GetActionArgument(); 996 997 mode_t mode = 0; 998 999 if (oflag & O_CREAT) 1000 mode = 0640; 1001 1002 error.SetError( 1003 ::posix_spawn_file_actions_addopen(file_actions, info->GetFD(), info->GetPath(), oflag, mode), 1004 eErrorTypePOSIX); 1005 if (error.Fail() || log) 1006 error.PutToLog(log, 1007 "posix_spawn_file_actions_addopen (action=%p, fd=%i, path='%s', oflag=%i, mode=%i)", 1008 static_cast<void *>(file_actions), info->GetFD(), info->GetPath(), oflag, mode); 1009 } 1010 break; 1011 } 1012 return error.Success(); 1013} 1014#endif // !defined(__ANDROID__) && !defined(__ANDROID_NDK__) 1015#endif // defined (__APPLE__) || defined (__linux__) || defined (__FreeBSD__) || defined (__GLIBC__) || defined(__NetBSD__) 1016 1017#if defined(__linux__) || defined(__FreeBSD__) || defined(__GLIBC__) || defined(__NetBSD__) || defined(_WIN32) 1018// The functions below implement process launching via posix_spawn() for Linux, 1019// FreeBSD and NetBSD. 1020 1021Error 1022Host::LaunchProcess (ProcessLaunchInfo &launch_info) 1023{ 1024 std::unique_ptr<ProcessLauncher> delegate_launcher; 1025#if defined(_WIN32) 1026 delegate_launcher.reset(new ProcessLauncherWindows()); 1027#elif defined(__ANDROID__) || defined(__ANDROID_NDK__) 1028 delegate_launcher.reset(new ProcessLauncherAndroid()); 1029#else 1030 delegate_launcher.reset(new ProcessLauncherPosix()); 1031#endif 1032 MonitoringProcessLauncher launcher(std::move(delegate_launcher)); 1033 1034 Error error; 1035 HostProcess process = launcher.LaunchProcess(launch_info, error); 1036 1037 // TODO(zturner): It would be better if the entire HostProcess were returned instead of writing 1038 // it into this structure. 1039 launch_info.SetProcessID(process.GetProcessId()); 1040 1041 return error; 1042} 1043#endif // defined(__linux__) || defined(__FreeBSD__) || defined(__NetBSD__) 1044 1045#ifndef _WIN32 1046void 1047Host::Kill(lldb::pid_t pid, int signo) 1048{ 1049 ::kill(pid, signo); 1050} 1051 1052#endif 1053 1054#if !defined (__APPLE__) 1055bool 1056Host::OpenFileInExternalEditor (const FileSpec &file_spec, uint32_t line_no) 1057{ 1058 return false; 1059} 1060 1061void 1062Host::SetCrashDescriptionWithFormat (const char *format, ...) 1063{ 1064} 1065 1066void 1067Host::SetCrashDescription (const char *description) 1068{ 1069} 1070 1071#endif 1072 1073const UnixSignalsSP & 1074Host::GetUnixSignals() 1075{ 1076 static const auto s_unix_signals_sp = UnixSignals::Create(HostInfo::GetArchitecture()); 1077 return s_unix_signals_sp; 1078} 1079