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