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