Host.cpp revision 309124
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(__ANDROID__) || defined(__ANDROID_NDK__) 70#include "lldb/Host/android/ProcessLauncherAndroid.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 80extern "C" 81{ 82 int __pthread_chdir(const char *path); 83 int __pthread_fchdir (int fildes); 84} 85 86#endif 87 88using namespace lldb; 89using namespace lldb_private; 90 91#if !defined (__APPLE__) && !defined (_WIN32) 92struct 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 99static thread_result_t 100MonitorChildProcessThreadFunction (void *arg); 101 102HostThread 103Host::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//------------------------------------------------------------------ 123class ScopedPThreadCancelDisabler 124{ 125public: 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 } 141private: 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)) 148static __thread volatile sig_atomic_t g_usr1_called; 149#else 150static thread_local volatile sig_atomic_t g_usr1_called; 151#endif 152 153static void 154SigUsr1Handler (int) 155{ 156 g_usr1_called = 1; 157} 158#endif // __linux__ 159 160static bool 161CheckForMonitorCancellation() 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 175static thread_result_t 176MonitorChildProcessThreadFunction (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 319void 320Host::SystemLog (SystemLogType type, const char *format, va_list args) 321{ 322 vfprintf (stderr, format, args); 323} 324 325#endif 326 327void 328Host::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 336lldb::pid_t 337Host::GetCurrentProcessID() 338{ 339 return ::getpid(); 340} 341 342#ifndef _WIN32 343 344lldb::tid_t 345Host::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 365lldb::thread_t 366Host::GetCurrentThread () 367{ 368 return lldb::thread_t(pthread_self()); 369} 370 371const char * 372Host::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 432lldb::thread_key_t 433Host::ThreadLocalStorageCreate(ThreadLocalStorageCleanupCallback callback) 434{ 435 pthread_key_t key; 436 ::pthread_key_create (&key, callback); 437 return key; 438} 439 440void* 441Host::ThreadLocalStorageGet(lldb::thread_key_t key) 442{ 443 return ::pthread_getspecific (key); 444} 445 446void 447Host::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 456bool 457Host::GetBundleDirectory (const FileSpec &file, FileSpec &bundle) 458{ 459 bundle.Clear(); 460 return false; 461} 462 463bool 464Host::ResolveExecutableInBundle (FileSpec &file) 465{ 466 return false; 467} 468#endif 469 470#ifndef _WIN32 471 472FileSpec 473Host::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__) 490bool 491Host::FindProcessThreads (const lldb::pid_t pid, TidMap &tids_to_attach) 492{ 493 return false; 494} 495#endif 496 497struct 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 513static bool 514MonitorShellCommand(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 528Error 529Host::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 540Error 541Host::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 TimeValue *timeout_ptr = nullptr; 624 TimeValue timeout_time(TimeValue::Now()); 625 if (timeout_sec > 0) { 626 timeout_time.OffsetWithSeconds(timeout_sec); 627 timeout_ptr = &timeout_time; 628 } 629 bool timed_out = false; 630 shell_info_sp->process_reaped.WaitForValueEqualTo(true, timeout_ptr, &timed_out); 631 if (timed_out) 632 { 633 error.SetErrorString("timed out waiting for shell command to complete"); 634 635 // Kill the process since it didn't complete within the timeout specified 636 Kill (pid, SIGKILL); 637 // Wait for the monitor callback to get the message 638 timeout_time = TimeValue::Now(); 639 timeout_time.OffsetWithSeconds(1); 640 timed_out = false; 641 shell_info_sp->process_reaped.WaitForValueEqualTo(true, &timeout_time, &timed_out); 642 } 643 else 644 { 645 if (status_ptr) 646 *status_ptr = shell_info_sp->status; 647 648 if (signo_ptr) 649 *signo_ptr = shell_info_sp->signo; 650 651 if (command_output_ptr) 652 { 653 command_output_ptr->clear(); 654 uint64_t file_size = output_file_spec.GetByteSize(); 655 if (file_size > 0) 656 { 657 if (file_size > command_output_ptr->max_size()) 658 { 659 error.SetErrorStringWithFormat("shell command output is too large to fit into a std::string"); 660 } 661 else 662 { 663 std::vector<char> command_output(file_size); 664 output_file_spec.ReadFileContents(0, command_output.data(), file_size, &error); 665 if (error.Success()) 666 command_output_ptr->assign(command_output.data(), file_size); 667 } 668 } 669 } 670 } 671 } 672 673 if (FileSystem::GetFileExists(output_file_spec)) 674 FileSystem::Unlink(output_file_spec); 675 return error; 676} 677 678// LaunchProcessPosixSpawn for Apple, Linux, FreeBSD and other GLIBC 679// systems 680 681#if defined (__APPLE__) || defined (__linux__) || defined (__FreeBSD__) || defined (__GLIBC__) || defined(__NetBSD__) 682#if !defined(__ANDROID__) && !defined(__ANDROID_NDK__) 683// this method needs to be visible to macosx/Host.cpp and 684// common/Host.cpp. 685 686short 687Host::GetPosixspawnFlags(const ProcessLaunchInfo &launch_info) 688{ 689 short flags = POSIX_SPAWN_SETSIGDEF | POSIX_SPAWN_SETSIGMASK; 690 691#if defined (__APPLE__) 692 if (launch_info.GetFlags().Test (eLaunchFlagExec)) 693 flags |= POSIX_SPAWN_SETEXEC; // Darwin specific posix_spawn flag 694 695 if (launch_info.GetFlags().Test (eLaunchFlagDebug)) 696 flags |= POSIX_SPAWN_START_SUSPENDED; // Darwin specific posix_spawn flag 697 698 if (launch_info.GetFlags().Test (eLaunchFlagDisableASLR)) 699 flags |= _POSIX_SPAWN_DISABLE_ASLR; // Darwin specific posix_spawn flag 700 701 if (launch_info.GetLaunchInSeparateProcessGroup()) 702 flags |= POSIX_SPAWN_SETPGROUP; 703 704#ifdef POSIX_SPAWN_CLOEXEC_DEFAULT 705#if defined (__APPLE__) && (defined (__x86_64__) || defined (__i386__)) 706 static LazyBool g_use_close_on_exec_flag = eLazyBoolCalculate; 707 if (g_use_close_on_exec_flag == eLazyBoolCalculate) 708 { 709 g_use_close_on_exec_flag = eLazyBoolNo; 710 711 uint32_t major, minor, update; 712 if (HostInfo::GetOSVersion(major, minor, update)) 713 { 714 // Kernel panic if we use the POSIX_SPAWN_CLOEXEC_DEFAULT on 10.7 or earlier 715 if (major > 10 || (major == 10 && minor > 7)) 716 { 717 // Only enable for 10.8 and later OS versions 718 g_use_close_on_exec_flag = eLazyBoolYes; 719 } 720 } 721 } 722#else 723 static LazyBool g_use_close_on_exec_flag = eLazyBoolYes; 724#endif 725 // Close all files exception those with file actions if this is supported. 726 if (g_use_close_on_exec_flag == eLazyBoolYes) 727 flags |= POSIX_SPAWN_CLOEXEC_DEFAULT; 728#endif 729#endif // #if defined (__APPLE__) 730 return flags; 731} 732 733Error 734Host::LaunchProcessPosixSpawn(const char *exe_path, const ProcessLaunchInfo &launch_info, lldb::pid_t &pid) 735{ 736 Error error; 737 Log *log(lldb_private::GetLogIfAllCategoriesSet (LIBLLDB_LOG_HOST | LIBLLDB_LOG_PROCESS)); 738 739 posix_spawnattr_t attr; 740 error.SetError( ::posix_spawnattr_init (&attr), eErrorTypePOSIX); 741 742 if (error.Fail() || log) 743 error.PutToLog(log, "::posix_spawnattr_init ( &attr )"); 744 if (error.Fail()) 745 return error; 746 747 // Make a quick class that will cleanup the posix spawn attributes in case 748 // we return in the middle of this function. 749 lldb_utility::CleanUp <posix_spawnattr_t *, int> posix_spawnattr_cleanup(&attr, posix_spawnattr_destroy); 750 751 sigset_t no_signals; 752 sigset_t all_signals; 753 sigemptyset (&no_signals); 754 sigfillset (&all_signals); 755 ::posix_spawnattr_setsigmask(&attr, &no_signals); 756#if defined (__linux__) || defined (__FreeBSD__) 757 ::posix_spawnattr_setsigdefault(&attr, &no_signals); 758#else 759 ::posix_spawnattr_setsigdefault(&attr, &all_signals); 760#endif 761 762 short flags = GetPosixspawnFlags(launch_info); 763 764 error.SetError( ::posix_spawnattr_setflags (&attr, flags), eErrorTypePOSIX); 765 if (error.Fail() || log) 766 error.PutToLog(log, "::posix_spawnattr_setflags ( &attr, flags=0x%8.8x )", flags); 767 if (error.Fail()) 768 return error; 769 770 // posix_spawnattr_setbinpref_np appears to be an Apple extension per: 771 // http://www.unix.com/man-page/OSX/3/posix_spawnattr_setbinpref_np/ 772#if defined (__APPLE__) && !defined (__arm__) 773 774 // Don't set the binpref if a shell was provided. After all, that's only going to affect what version of the shell 775 // is launched, not what fork of the binary is launched. We insert "arch --arch <ARCH> as part of the shell invocation 776 // to do that job on OSX. 777 778 if (launch_info.GetShell() == nullptr) 779 { 780 // We don't need to do this for ARM, and we really shouldn't now that we 781 // have multiple CPU subtypes and no posix_spawnattr call that allows us 782 // to set which CPU subtype to launch... 783 const ArchSpec &arch_spec = launch_info.GetArchitecture(); 784 cpu_type_t cpu = arch_spec.GetMachOCPUType(); 785 cpu_type_t sub = arch_spec.GetMachOCPUSubType(); 786 if (cpu != 0 && 787 cpu != static_cast<cpu_type_t>(UINT32_MAX) && 788 cpu != static_cast<cpu_type_t>(LLDB_INVALID_CPUTYPE) && 789 !(cpu == 0x01000007 && sub == 8)) // If haswell is specified, don't try to set the CPU type or we will fail 790 { 791 size_t ocount = 0; 792 error.SetError( ::posix_spawnattr_setbinpref_np (&attr, 1, &cpu, &ocount), eErrorTypePOSIX); 793 if (error.Fail() || log) 794 error.PutToLog(log, "::posix_spawnattr_setbinpref_np ( &attr, 1, cpu_type = 0x%8.8x, count => %llu )", cpu, (uint64_t)ocount); 795 796 if (error.Fail() || ocount != 1) 797 return error; 798 } 799 } 800 801#endif 802 803 const char *tmp_argv[2]; 804 char * const *argv = const_cast<char * const*>(launch_info.GetArguments().GetConstArgumentVector()); 805 char * const *envp = const_cast<char * const*>(launch_info.GetEnvironmentEntries().GetConstArgumentVector()); 806 if (argv == NULL) 807 { 808 // posix_spawn gets very unhappy if it doesn't have at least the program 809 // name in argv[0]. One of the side affects I have noticed is the environment 810 // variables don't make it into the child process if "argv == NULL"!!! 811 tmp_argv[0] = exe_path; 812 tmp_argv[1] = NULL; 813 argv = const_cast<char * const*>(tmp_argv); 814 } 815 816#if !defined (__APPLE__) 817 // manage the working directory 818 char current_dir[PATH_MAX]; 819 current_dir[0] = '\0'; 820#endif 821 822 FileSpec working_dir{launch_info.GetWorkingDirectory()}; 823 if (working_dir) 824 { 825#if defined (__APPLE__) 826 // Set the working directory on this thread only 827 if (__pthread_chdir(working_dir.GetCString()) < 0) { 828 if (errno == ENOENT) { 829 error.SetErrorStringWithFormat("No such file or directory: %s", 830 working_dir.GetCString()); 831 } else if (errno == ENOTDIR) { 832 error.SetErrorStringWithFormat("Path doesn't name a directory: %s", 833 working_dir.GetCString()); 834 } else { 835 error.SetErrorStringWithFormat("An unknown error occurred when changing directory for process execution."); 836 } 837 return error; 838 } 839#else 840 if (::getcwd(current_dir, sizeof(current_dir)) == NULL) 841 { 842 error.SetError(errno, eErrorTypePOSIX); 843 error.LogIfError(log, "unable to save the current directory"); 844 return error; 845 } 846 847 if (::chdir(working_dir.GetCString()) == -1) 848 { 849 error.SetError(errno, eErrorTypePOSIX); 850 error.LogIfError(log, "unable to change working directory to %s", 851 working_dir.GetCString()); 852 return error; 853 } 854#endif 855 } 856 857 ::pid_t result_pid = LLDB_INVALID_PROCESS_ID; 858 const size_t num_file_actions = launch_info.GetNumFileActions (); 859 if (num_file_actions > 0) 860 { 861 posix_spawn_file_actions_t file_actions; 862 error.SetError( ::posix_spawn_file_actions_init (&file_actions), eErrorTypePOSIX); 863 if (error.Fail() || log) 864 error.PutToLog(log, "::posix_spawn_file_actions_init ( &file_actions )"); 865 if (error.Fail()) 866 return error; 867 868 // Make a quick class that will cleanup the posix spawn attributes in case 869 // we return in the middle of this function. 870 lldb_utility::CleanUp <posix_spawn_file_actions_t *, int> posix_spawn_file_actions_cleanup (&file_actions, posix_spawn_file_actions_destroy); 871 872 for (size_t i=0; i<num_file_actions; ++i) 873 { 874 const FileAction *launch_file_action = launch_info.GetFileActionAtIndex(i); 875 if (launch_file_action) 876 { 877 if (!AddPosixSpawnFileAction(&file_actions, launch_file_action, log, error)) 878 return error; 879 } 880 } 881 882 error.SetError(::posix_spawnp(&result_pid, exe_path, &file_actions, &attr, argv, envp), eErrorTypePOSIX); 883 884 if (error.Fail() || log) 885 { 886 error.PutToLog(log, "::posix_spawnp ( pid => %i, path = '%s', file_actions = %p, attr = %p, argv = %p, envp = %p )", result_pid, 887 exe_path, static_cast<void *>(&file_actions), static_cast<void *>(&attr), reinterpret_cast<const void *>(argv), 888 reinterpret_cast<const void *>(envp)); 889 if (log) 890 { 891 for (int ii=0; argv[ii]; ++ii) 892 log->Printf("argv[%i] = '%s'", ii, argv[ii]); 893 } 894 } 895 896 } 897 else 898 { 899 error.SetError(::posix_spawnp(&result_pid, exe_path, NULL, &attr, argv, envp), eErrorTypePOSIX); 900 901 if (error.Fail() || log) 902 { 903 error.PutToLog(log, "::posix_spawnp ( pid => %i, path = '%s', file_actions = NULL, attr = %p, argv = %p, envp = %p )", 904 result_pid, exe_path, static_cast<void *>(&attr), reinterpret_cast<const void *>(argv), 905 reinterpret_cast<const void *>(envp)); 906 if (log) 907 { 908 for (int ii=0; argv[ii]; ++ii) 909 log->Printf("argv[%i] = '%s'", ii, argv[ii]); 910 } 911 } 912 } 913 pid = result_pid; 914 915 if (working_dir) 916 { 917#if defined (__APPLE__) 918 // No more thread specific current working directory 919 __pthread_fchdir (-1); 920#else 921 if (::chdir(current_dir) == -1 && error.Success()) 922 { 923 error.SetError(errno, eErrorTypePOSIX); 924 error.LogIfError(log, "unable to change current directory back to %s", 925 current_dir); 926 } 927#endif 928 } 929 930 return error; 931} 932 933bool 934Host::AddPosixSpawnFileAction(void *_file_actions, const FileAction *info, Log *log, Error &error) 935{ 936 if (info == NULL) 937 return false; 938 939 posix_spawn_file_actions_t *file_actions = reinterpret_cast<posix_spawn_file_actions_t *>(_file_actions); 940 941 switch (info->GetAction()) 942 { 943 case FileAction::eFileActionNone: 944 error.Clear(); 945 break; 946 947 case FileAction::eFileActionClose: 948 if (info->GetFD() == -1) 949 error.SetErrorString("invalid fd for posix_spawn_file_actions_addclose(...)"); 950 else 951 { 952 error.SetError(::posix_spawn_file_actions_addclose(file_actions, info->GetFD()), eErrorTypePOSIX); 953 if (log && (error.Fail() || log)) 954 error.PutToLog(log, "posix_spawn_file_actions_addclose (action=%p, fd=%i)", 955 static_cast<void *>(file_actions), info->GetFD()); 956 } 957 break; 958 959 case FileAction::eFileActionDuplicate: 960 if (info->GetFD() == -1) 961 error.SetErrorString("invalid fd for posix_spawn_file_actions_adddup2(...)"); 962 else if (info->GetActionArgument() == -1) 963 error.SetErrorString("invalid duplicate fd for posix_spawn_file_actions_adddup2(...)"); 964 else 965 { 966 error.SetError( 967 ::posix_spawn_file_actions_adddup2(file_actions, info->GetFD(), info->GetActionArgument()), 968 eErrorTypePOSIX); 969 if (log && (error.Fail() || log)) 970 error.PutToLog(log, "posix_spawn_file_actions_adddup2 (action=%p, fd=%i, dup_fd=%i)", 971 static_cast<void *>(file_actions), info->GetFD(), info->GetActionArgument()); 972 } 973 break; 974 975 case FileAction::eFileActionOpen: 976 if (info->GetFD() == -1) 977 error.SetErrorString("invalid fd in posix_spawn_file_actions_addopen(...)"); 978 else 979 { 980 int oflag = info->GetActionArgument(); 981 982 mode_t mode = 0; 983 984 if (oflag & O_CREAT) 985 mode = 0640; 986 987 error.SetError( 988 ::posix_spawn_file_actions_addopen(file_actions, info->GetFD(), info->GetPath(), oflag, mode), 989 eErrorTypePOSIX); 990 if (error.Fail() || log) 991 error.PutToLog(log, 992 "posix_spawn_file_actions_addopen (action=%p, fd=%i, path='%s', oflag=%i, mode=%i)", 993 static_cast<void *>(file_actions), info->GetFD(), info->GetPath(), oflag, mode); 994 } 995 break; 996 } 997 return error.Success(); 998} 999#endif // !defined(__ANDROID__) && !defined(__ANDROID_NDK__) 1000#endif // defined (__APPLE__) || defined (__linux__) || defined (__FreeBSD__) || defined (__GLIBC__) || defined(__NetBSD__) 1001 1002#if defined(__linux__) || defined(__FreeBSD__) || defined(__GLIBC__) || defined(__NetBSD__) || defined(_WIN32) 1003// The functions below implement process launching via posix_spawn() for Linux, 1004// FreeBSD and NetBSD. 1005 1006Error 1007Host::LaunchProcess (ProcessLaunchInfo &launch_info) 1008{ 1009 std::unique_ptr<ProcessLauncher> delegate_launcher; 1010#if defined(_WIN32) 1011 delegate_launcher.reset(new ProcessLauncherWindows()); 1012#elif defined(__ANDROID__) || defined(__ANDROID_NDK__) 1013 delegate_launcher.reset(new ProcessLauncherAndroid()); 1014#else 1015 delegate_launcher.reset(new ProcessLauncherPosix()); 1016#endif 1017 MonitoringProcessLauncher launcher(std::move(delegate_launcher)); 1018 1019 Error error; 1020 HostProcess process = launcher.LaunchProcess(launch_info, error); 1021 1022 // TODO(zturner): It would be better if the entire HostProcess were returned instead of writing 1023 // it into this structure. 1024 launch_info.SetProcessID(process.GetProcessId()); 1025 1026 return error; 1027} 1028#endif // defined(__linux__) || defined(__FreeBSD__) || defined(__NetBSD__) 1029 1030#ifndef _WIN32 1031void 1032Host::Kill(lldb::pid_t pid, int signo) 1033{ 1034 ::kill(pid, signo); 1035} 1036 1037#endif 1038 1039#if !defined (__APPLE__) 1040bool 1041Host::OpenFileInExternalEditor (const FileSpec &file_spec, uint32_t line_no) 1042{ 1043 return false; 1044} 1045 1046void 1047Host::SetCrashDescriptionWithFormat (const char *format, ...) 1048{ 1049} 1050 1051void 1052Host::SetCrashDescription (const char *description) 1053{ 1054} 1055 1056#endif 1057 1058const UnixSignalsSP & 1059Host::GetUnixSignals() 1060{ 1061 static const auto s_unix_signals_sp = UnixSignals::Create(HostInfo::GetArchitecture()); 1062 return s_unix_signals_sp; 1063} 1064