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