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