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