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 #ifdef _WIN32 18 #include "lldb/Host/windows/windows.h" 19 #include <winsock2.h> 20 #include <ws2tcpip.h> 21 #else 22 #include <unistd.h> 23 #include <dlfcn.h> 24 #include <grp.h> 25 #include <netdb.h> 26 #include <pwd.h> 27 #include <sys/stat.h> 28 #endif 29 30 #if !defined (__GNU__) && !defined (_WIN32) 31 // Does not exist under GNU/HURD or Windows 32 #include <sys/sysctl.h> 33 #endif 34 35 #if defined (__APPLE__) 36 #include <mach/mach_port.h> 37 #include <mach/mach_init.h> 38 #include <mach-o/dyld.h> 39 #endif 40 41 #if defined (__linux__) || defined (__FreeBSD__) || defined (__FreeBSD_kernel__) || defined (__APPLE__) || defined(__NetBSD__) 42 #include <spawn.h> 43 #include <sys/wait.h> 44 #include <sys/syscall.h> 45 #endif 46 47 #if defined (__FreeBSD__) 48 #include <pthread_np.h> 49 #endif 50 51 // C++ includes 52 #include <limits> 53 54 #include "lldb/Host/Host.h" 55 #include "lldb/Host/HostInfo.h" 56 #include "lldb/Core/ArchSpec.h" 57 #include "lldb/Core/ConstString.h" 58 #include "lldb/Core/Debugger.h" 59 #include "lldb/Core/Error.h" 60 #include "lldb/Core/Log.h" 61 #include "lldb/Core/Module.h" 62 #include "lldb/Core/StreamString.h" 63 #include "lldb/Core/ThreadSafeSTLMap.h" 64 #include "lldb/Host/Config.h" 65 #include "lldb/Host/Endian.h" 66 #include "lldb/Host/FileSpec.h" 67 #include "lldb/Host/FileSystem.h" 68 #include "lldb/Host/Mutex.h" 69 #include "lldb/lldb-private-forward.h" 70 #include "lldb/Target/FileAction.h" 71 #include "lldb/Target/Process.h" 72 #include "lldb/Target/ProcessLaunchInfo.h" 73 #include "lldb/Target/TargetList.h" 74 #include "lldb/Utility/CleanUp.h" 75 76 #include "llvm/ADT/STLExtras.h" 77 #include "llvm/ADT/SmallString.h" 78 #include "llvm/Support/Host.h" 79 #include "llvm/Support/Path.h" 80 #include "llvm/Support/raw_ostream.h" 81 82 #if defined (__APPLE__) 83 #ifndef _POSIX_SPAWN_DISABLE_ASLR 84 #define _POSIX_SPAWN_DISABLE_ASLR 0x0100 85 #endif 86 87 extern "C" 88 { 89 int __pthread_chdir(const char *path); 90 int __pthread_fchdir (int fildes); 91 } 92 93 #endif 94 95 using namespace lldb; 96 using namespace lldb_private; 97 98 // Define maximum thread name length 99 #if defined (__linux__) || defined (__FreeBSD__) || defined (__FreeBSD_kernel__) || defined (__NetBSD__) 100 uint32_t const Host::MAX_THREAD_NAME_LENGTH = 16; 101 #else 102 uint32_t const Host::MAX_THREAD_NAME_LENGTH = std::numeric_limits<uint32_t>::max (); 103 #endif 104 105 #if !defined (__APPLE__) && !defined (_WIN32) 106 struct MonitorInfo 107 { 108 lldb::pid_t pid; // The process ID to monitor 109 Host::MonitorChildProcessCallback callback; // The callback function to call when "pid" exits or signals 110 void *callback_baton; // The callback baton for the callback function 111 bool monitor_signals; // If true, call the callback when "pid" gets signaled. 112 }; 113 114 static thread_result_t 115 MonitorChildProcessThreadFunction (void *arg); 116 117 lldb::thread_t 118 Host::StartMonitoringChildProcess 119 ( 120 Host::MonitorChildProcessCallback callback, 121 void *callback_baton, 122 lldb::pid_t pid, 123 bool monitor_signals 124 ) 125 { 126 lldb::thread_t thread = LLDB_INVALID_HOST_THREAD; 127 MonitorInfo * info_ptr = new MonitorInfo(); 128 129 info_ptr->pid = pid; 130 info_ptr->callback = callback; 131 info_ptr->callback_baton = callback_baton; 132 info_ptr->monitor_signals = monitor_signals; 133 134 char thread_name[256]; 135 136 if (Host::MAX_THREAD_NAME_LENGTH <= 16) 137 { 138 // On some platforms, the thread name is limited to 16 characters. We need to 139 // abbreviate there or the pid info would get truncated. 140 ::snprintf (thread_name, sizeof(thread_name), "wait4(%" PRIu64 ")", pid); 141 } 142 else 143 { 144 ::snprintf (thread_name, sizeof(thread_name), "<lldb.host.wait4(pid=%" PRIu64 ")>", pid); 145 } 146 147 thread = ThreadCreate (thread_name, 148 MonitorChildProcessThreadFunction, 149 info_ptr, 150 NULL); 151 152 return thread; 153 } 154 155 //------------------------------------------------------------------ 156 // Scoped class that will disable thread canceling when it is 157 // constructed, and exception safely restore the previous value it 158 // when it goes out of scope. 159 //------------------------------------------------------------------ 160 class ScopedPThreadCancelDisabler 161 { 162 public: 163 ScopedPThreadCancelDisabler() 164 { 165 // Disable the ability for this thread to be cancelled 166 int err = ::pthread_setcancelstate (PTHREAD_CANCEL_DISABLE, &m_old_state); 167 if (err != 0) 168 m_old_state = -1; 169 170 } 171 172 ~ScopedPThreadCancelDisabler() 173 { 174 // Restore the ability for this thread to be cancelled to what it 175 // previously was. 176 if (m_old_state != -1) 177 ::pthread_setcancelstate (m_old_state, 0); 178 } 179 private: 180 int m_old_state; // Save the old cancelability state. 181 }; 182 183 static thread_result_t 184 MonitorChildProcessThreadFunction (void *arg) 185 { 186 Log *log(lldb_private::GetLogIfAllCategoriesSet (LIBLLDB_LOG_PROCESS)); 187 const char *function = __FUNCTION__; 188 if (log) 189 log->Printf ("%s (arg = %p) thread starting...", function, arg); 190 191 MonitorInfo *info = (MonitorInfo *)arg; 192 193 const Host::MonitorChildProcessCallback callback = info->callback; 194 void * const callback_baton = info->callback_baton; 195 const bool monitor_signals = info->monitor_signals; 196 197 assert (info->pid <= UINT32_MAX); 198 const ::pid_t pid = monitor_signals ? -1 * getpgid(info->pid) : info->pid; 199 200 delete info; 201 202 int status = -1; 203 #if defined (__FreeBSD__) || defined (__FreeBSD_kernel__) 204 #define __WALL 0 205 #endif 206 const int options = __WALL; 207 208 while (1) 209 { 210 log = lldb_private::GetLogIfAllCategoriesSet (LIBLLDB_LOG_PROCESS); 211 if (log) 212 log->Printf("%s ::wait_pid (pid = %" PRIi32 ", &status, options = %i)...", function, pid, options); 213 214 // Wait for all child processes 215 ::pthread_testcancel (); 216 // Get signals from all children with same process group of pid 217 const ::pid_t wait_pid = ::waitpid (pid, &status, options); 218 ::pthread_testcancel (); 219 220 if (wait_pid == -1) 221 { 222 if (errno == EINTR) 223 continue; 224 else 225 { 226 if (log) 227 log->Printf ("%s (arg = %p) thread exiting because waitpid failed (%s)...", __FUNCTION__, arg, strerror(errno)); 228 break; 229 } 230 } 231 else if (wait_pid > 0) 232 { 233 bool exited = false; 234 int signal = 0; 235 int exit_status = 0; 236 const char *status_cstr = NULL; 237 if (WIFSTOPPED(status)) 238 { 239 signal = WSTOPSIG(status); 240 status_cstr = "STOPPED"; 241 } 242 else if (WIFEXITED(status)) 243 { 244 exit_status = WEXITSTATUS(status); 245 status_cstr = "EXITED"; 246 exited = true; 247 } 248 else if (WIFSIGNALED(status)) 249 { 250 signal = WTERMSIG(status); 251 status_cstr = "SIGNALED"; 252 if (wait_pid == abs(pid)) { 253 exited = true; 254 exit_status = -1; 255 } 256 } 257 else 258 { 259 status_cstr = "(\?\?\?)"; 260 } 261 262 // Scope for pthread_cancel_disabler 263 { 264 ScopedPThreadCancelDisabler pthread_cancel_disabler; 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 wait_pid, 271 options, 272 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(__linux__) 353 return lldb::tid_t(syscall(SYS_gettid)); 354 #else 355 return lldb::tid_t(pthread_self()); 356 #endif 357 } 358 359 lldb::thread_t 360 Host::GetCurrentThread () 361 { 362 return lldb::thread_t(pthread_self()); 363 } 364 365 const char * 366 Host::GetSignalAsCString (int signo) 367 { 368 switch (signo) 369 { 370 case SIGHUP: return "SIGHUP"; // 1 hangup 371 case SIGINT: return "SIGINT"; // 2 interrupt 372 case SIGQUIT: return "SIGQUIT"; // 3 quit 373 case SIGILL: return "SIGILL"; // 4 illegal instruction (not reset when caught) 374 case SIGTRAP: return "SIGTRAP"; // 5 trace trap (not reset when caught) 375 case SIGABRT: return "SIGABRT"; // 6 abort() 376 #if defined(SIGPOLL) 377 #if !defined(SIGIO) || (SIGPOLL != SIGIO) 378 // Under some GNU/Linux, SIGPOLL and SIGIO are the same. Causing the build to 379 // fail with 'multiple define cases with same value' 380 case SIGPOLL: return "SIGPOLL"; // 7 pollable event ([XSR] generated, not supported) 381 #endif 382 #endif 383 #if defined(SIGEMT) 384 case SIGEMT: return "SIGEMT"; // 7 EMT instruction 385 #endif 386 case SIGFPE: return "SIGFPE"; // 8 floating point exception 387 case SIGKILL: return "SIGKILL"; // 9 kill (cannot be caught or ignored) 388 case SIGBUS: return "SIGBUS"; // 10 bus error 389 case SIGSEGV: return "SIGSEGV"; // 11 segmentation violation 390 case SIGSYS: return "SIGSYS"; // 12 bad argument to system call 391 case SIGPIPE: return "SIGPIPE"; // 13 write on a pipe with no one to read it 392 case SIGALRM: return "SIGALRM"; // 14 alarm clock 393 case SIGTERM: return "SIGTERM"; // 15 software termination signal from kill 394 case SIGURG: return "SIGURG"; // 16 urgent condition on IO channel 395 case SIGSTOP: return "SIGSTOP"; // 17 sendable stop signal not from tty 396 case SIGTSTP: return "SIGTSTP"; // 18 stop signal from tty 397 case SIGCONT: return "SIGCONT"; // 19 continue a stopped process 398 case SIGCHLD: return "SIGCHLD"; // 20 to parent on child stop or exit 399 case SIGTTIN: return "SIGTTIN"; // 21 to readers pgrp upon background tty read 400 case SIGTTOU: return "SIGTTOU"; // 22 like TTIN for output if (tp->t_local<OSTOP) 401 #if defined(SIGIO) 402 case SIGIO: return "SIGIO"; // 23 input/output possible signal 403 #endif 404 case SIGXCPU: return "SIGXCPU"; // 24 exceeded CPU time limit 405 case SIGXFSZ: return "SIGXFSZ"; // 25 exceeded file size limit 406 case SIGVTALRM: return "SIGVTALRM"; // 26 virtual time alarm 407 case SIGPROF: return "SIGPROF"; // 27 profiling time alarm 408 #if defined(SIGWINCH) 409 case SIGWINCH: return "SIGWINCH"; // 28 window size changes 410 #endif 411 #if defined(SIGINFO) 412 case SIGINFO: return "SIGINFO"; // 29 information request 413 #endif 414 case SIGUSR1: return "SIGUSR1"; // 30 user defined signal 1 415 case SIGUSR2: return "SIGUSR2"; // 31 user defined signal 2 416 default: 417 break; 418 } 419 return NULL; 420 } 421 422 #endif 423 424 void 425 Host::WillTerminate () 426 { 427 } 428 429 #if !defined (__APPLE__) && !defined (__FreeBSD__) && !defined (__FreeBSD_kernel__) && !defined (__linux__) // see macosx/Host.mm 430 431 void 432 Host::ThreadCreated (const char *thread_name) 433 { 434 } 435 436 void 437 Host::Backtrace (Stream &strm, uint32_t max_frames) 438 { 439 // TODO: Is there a way to backtrace the current process on other systems? 440 } 441 442 size_t 443 Host::GetEnvironment (StringList &env) 444 { 445 // TODO: Is there a way to the host environment for this process on other systems? 446 return 0; 447 } 448 449 #endif // #if !defined (__APPLE__) && !defined (__FreeBSD__) && !defined (__FreeBSD_kernel__) && !defined (__linux__) 450 451 struct HostThreadCreateInfo 452 { 453 std::string thread_name; 454 thread_func_t thread_fptr; 455 thread_arg_t thread_arg; 456 457 HostThreadCreateInfo (const char *name, thread_func_t fptr, thread_arg_t arg) : 458 thread_name (name ? name : ""), 459 thread_fptr (fptr), 460 thread_arg (arg) 461 { 462 } 463 }; 464 465 static thread_result_t 466 #ifdef _WIN32 467 __stdcall 468 #endif 469 ThreadCreateTrampoline (thread_arg_t arg) 470 { 471 HostThreadCreateInfo *info = (HostThreadCreateInfo *)arg; 472 Host::ThreadCreated (info->thread_name.c_str()); 473 thread_func_t thread_fptr = info->thread_fptr; 474 thread_arg_t thread_arg = info->thread_arg; 475 476 Log *log(lldb_private::GetLogIfAllCategoriesSet (LIBLLDB_LOG_THREAD)); 477 if (log) 478 log->Printf("thread created"); 479 480 delete info; 481 return thread_fptr (thread_arg); 482 } 483 484 lldb::thread_t 485 Host::ThreadCreate 486 ( 487 const char *thread_name, 488 thread_func_t thread_fptr, 489 thread_arg_t thread_arg, 490 Error *error 491 ) 492 { 493 lldb::thread_t thread = LLDB_INVALID_HOST_THREAD; 494 495 // Host::ThreadCreateTrampoline will delete this pointer for us. 496 HostThreadCreateInfo *info_ptr = new HostThreadCreateInfo (thread_name, thread_fptr, thread_arg); 497 498 #ifdef _WIN32 499 thread = ::_beginthreadex(0, 0, ThreadCreateTrampoline, info_ptr, 0, NULL); 500 int err = thread <= 0 ? GetLastError() : 0; 501 #else 502 int err = ::pthread_create (&thread, NULL, ThreadCreateTrampoline, info_ptr); 503 #endif 504 if (err == 0) 505 { 506 if (error) 507 error->Clear(); 508 return thread; 509 } 510 511 if (error) 512 error->SetError (err, eErrorTypePOSIX); 513 514 return LLDB_INVALID_HOST_THREAD; 515 } 516 517 #ifndef _WIN32 518 519 bool 520 Host::ThreadCancel (lldb::thread_t thread, Error *error) 521 { 522 int err = ::pthread_cancel (thread); 523 if (error) 524 error->SetError(err, eErrorTypePOSIX); 525 return err == 0; 526 } 527 528 bool 529 Host::ThreadDetach (lldb::thread_t thread, Error *error) 530 { 531 int err = ::pthread_detach (thread); 532 if (error) 533 error->SetError(err, eErrorTypePOSIX); 534 return err == 0; 535 } 536 537 bool 538 Host::ThreadJoin (lldb::thread_t thread, thread_result_t *thread_result_ptr, Error *error) 539 { 540 int err = ::pthread_join (thread, thread_result_ptr); 541 if (error) 542 error->SetError(err, eErrorTypePOSIX); 543 return err == 0; 544 } 545 546 lldb::thread_key_t 547 Host::ThreadLocalStorageCreate(ThreadLocalStorageCleanupCallback callback) 548 { 549 pthread_key_t key; 550 ::pthread_key_create (&key, callback); 551 return key; 552 } 553 554 void* 555 Host::ThreadLocalStorageGet(lldb::thread_key_t key) 556 { 557 return ::pthread_getspecific (key); 558 } 559 560 void 561 Host::ThreadLocalStorageSet(lldb::thread_key_t key, void *value) 562 { 563 ::pthread_setspecific (key, value); 564 } 565 566 bool 567 Host::SetThreadName (lldb::pid_t pid, lldb::tid_t tid, const char *name) 568 { 569 #if defined(__APPLE__) && MAC_OS_X_VERSION_MAX_ALLOWED > MAC_OS_X_VERSION_10_5 570 lldb::pid_t curr_pid = Host::GetCurrentProcessID(); 571 lldb::tid_t curr_tid = Host::GetCurrentThreadID(); 572 if (pid == LLDB_INVALID_PROCESS_ID) 573 pid = curr_pid; 574 575 if (tid == LLDB_INVALID_THREAD_ID) 576 tid = curr_tid; 577 578 // Set the pthread name if possible 579 if (pid == curr_pid && tid == curr_tid) 580 { 581 if (::pthread_setname_np (name) == 0) 582 return true; 583 } 584 return false; 585 #elif defined (__FreeBSD__) 586 lldb::pid_t curr_pid = Host::GetCurrentProcessID(); 587 lldb::tid_t curr_tid = Host::GetCurrentThreadID(); 588 if (pid == LLDB_INVALID_PROCESS_ID) 589 pid = curr_pid; 590 591 if (tid == LLDB_INVALID_THREAD_ID) 592 tid = curr_tid; 593 594 // Set the pthread name if possible 595 if (pid == curr_pid && tid == curr_tid) 596 { 597 ::pthread_set_name_np (::pthread_self(), name); 598 return true; 599 } 600 return false; 601 #elif defined (__linux__) || defined (__GLIBC__) 602 void *fn = dlsym (RTLD_DEFAULT, "pthread_setname_np"); 603 if (fn) 604 { 605 lldb::pid_t curr_pid = Host::GetCurrentProcessID(); 606 lldb::tid_t curr_tid = Host::GetCurrentThreadID(); 607 if (pid == LLDB_INVALID_PROCESS_ID) 608 pid = curr_pid; 609 610 if (tid == LLDB_INVALID_THREAD_ID) 611 tid = curr_tid; 612 613 if (pid == curr_pid && tid == curr_tid) 614 { 615 int (*pthread_setname_np_func)(pthread_t thread, const char *name); 616 *reinterpret_cast<void **> (&pthread_setname_np_func) = fn; 617 618 if (pthread_setname_np_func (::pthread_self(), name) == 0) 619 return true; 620 } 621 } 622 return false; 623 #else 624 return false; 625 #endif 626 } 627 628 bool 629 Host::SetShortThreadName (lldb::pid_t pid, lldb::tid_t tid, 630 const char *thread_name, size_t len) 631 { 632 std::unique_ptr<char[]> namebuf(new char[len+1]); 633 634 // Thread names are coming in like '<lldb.comm.debugger.edit>' and 635 // '<lldb.comm.debugger.editline>'. So just chopping the end of the string 636 // off leads to a lot of similar named threads. Go through the thread name 637 // and search for the last dot and use that. 638 const char *lastdot = ::strrchr (thread_name, '.'); 639 640 if (lastdot && lastdot != thread_name) 641 thread_name = lastdot + 1; 642 ::strncpy (namebuf.get(), thread_name, len); 643 namebuf[len] = 0; 644 645 int namebuflen = strlen(namebuf.get()); 646 if (namebuflen > 0) 647 { 648 if (namebuf[namebuflen - 1] == '(' || namebuf[namebuflen - 1] == '>') 649 { 650 // Trim off trailing '(' and '>' characters for a bit more cleanup. 651 namebuflen--; 652 namebuf[namebuflen] = 0; 653 } 654 return Host::SetThreadName (pid, tid, namebuf.get()); 655 } 656 return false; 657 } 658 659 #endif 660 661 #if !defined (__APPLE__) // see Host.mm 662 663 bool 664 Host::GetBundleDirectory (const FileSpec &file, FileSpec &bundle) 665 { 666 bundle.Clear(); 667 return false; 668 } 669 670 bool 671 Host::ResolveExecutableInBundle (FileSpec &file) 672 { 673 return false; 674 } 675 #endif 676 677 #ifndef _WIN32 678 679 FileSpec 680 Host::GetModuleFileSpecForHostAddress (const void *host_addr) 681 { 682 FileSpec module_filespec; 683 Dl_info info; 684 if (::dladdr (host_addr, &info)) 685 { 686 if (info.dli_fname) 687 module_filespec.SetFile(info.dli_fname, true); 688 } 689 return module_filespec; 690 } 691 692 #endif 693 694 #if !defined(__linux__) 695 bool 696 Host::FindProcessThreads (const lldb::pid_t pid, TidMap &tids_to_attach) 697 { 698 return false; 699 } 700 #endif 701 702 lldb::TargetSP 703 Host::GetDummyTarget (lldb_private::Debugger &debugger) 704 { 705 static TargetSP g_dummy_target_sp; 706 707 // FIXME: Maybe the dummy target should be per-Debugger 708 if (!g_dummy_target_sp || !g_dummy_target_sp->IsValid()) 709 { 710 ArchSpec arch(Target::GetDefaultArchitecture()); 711 if (!arch.IsValid()) 712 arch = HostInfo::GetArchitecture(); 713 Error err = debugger.GetTargetList().CreateTarget(debugger, 714 NULL, 715 arch.GetTriple().getTriple().c_str(), 716 false, 717 NULL, 718 g_dummy_target_sp); 719 } 720 721 return g_dummy_target_sp; 722 } 723 724 struct ShellInfo 725 { 726 ShellInfo () : 727 process_reaped (false), 728 can_delete (false), 729 pid (LLDB_INVALID_PROCESS_ID), 730 signo(-1), 731 status(-1) 732 { 733 } 734 735 lldb_private::Predicate<bool> process_reaped; 736 lldb_private::Predicate<bool> can_delete; 737 lldb::pid_t pid; 738 int signo; 739 int status; 740 }; 741 742 static bool 743 MonitorShellCommand (void *callback_baton, 744 lldb::pid_t pid, 745 bool exited, // True if the process did exit 746 int signo, // Zero for no signal 747 int status) // Exit value of process if signal is zero 748 { 749 ShellInfo *shell_info = (ShellInfo *)callback_baton; 750 shell_info->pid = pid; 751 shell_info->signo = signo; 752 shell_info->status = status; 753 // Let the thread running Host::RunShellCommand() know that the process 754 // exited and that ShellInfo has been filled in by broadcasting to it 755 shell_info->process_reaped.SetValue(1, eBroadcastAlways); 756 // Now wait for a handshake back from that thread running Host::RunShellCommand 757 // so we know that we can delete shell_info_ptr 758 shell_info->can_delete.WaitForValueEqualTo(true); 759 // Sleep a bit to allow the shell_info->can_delete.SetValue() to complete... 760 usleep(1000); 761 // Now delete the shell info that was passed into this function 762 delete shell_info; 763 return true; 764 } 765 766 Error 767 Host::RunShellCommand (const char *command, 768 const char *working_dir, 769 int *status_ptr, 770 int *signo_ptr, 771 std::string *command_output_ptr, 772 uint32_t timeout_sec, 773 const char *shell) 774 { 775 Error error; 776 ProcessLaunchInfo launch_info; 777 if (shell && shell[0]) 778 { 779 // Run the command in a shell 780 launch_info.SetShell(shell); 781 launch_info.GetArguments().AppendArgument(command); 782 const bool localhost = true; 783 const bool will_debug = false; 784 const bool first_arg_is_full_shell_command = true; 785 launch_info.ConvertArgumentsForLaunchingInShell (error, 786 localhost, 787 will_debug, 788 first_arg_is_full_shell_command, 789 0); 790 } 791 else 792 { 793 // No shell, just run it 794 Args args (command); 795 const bool first_arg_is_executable = true; 796 launch_info.SetArguments(args, first_arg_is_executable); 797 } 798 799 if (working_dir) 800 launch_info.SetWorkingDirectory(working_dir); 801 char output_file_path_buffer[PATH_MAX]; 802 const char *output_file_path = NULL; 803 804 if (command_output_ptr) 805 { 806 // Create a temporary file to get the stdout/stderr and redirect the 807 // output of the command into this file. We will later read this file 808 // if all goes well and fill the data into "command_output_ptr" 809 FileSpec tmpdir_file_spec; 810 if (HostInfo::GetLLDBPath(ePathTypeLLDBTempSystemDir, tmpdir_file_spec)) 811 { 812 tmpdir_file_spec.AppendPathComponent("lldb-shell-output.XXXXXX"); 813 strncpy(output_file_path_buffer, tmpdir_file_spec.GetPath().c_str(), sizeof(output_file_path_buffer)); 814 } 815 else 816 { 817 strncpy(output_file_path_buffer, "/tmp/lldb-shell-output.XXXXXX", sizeof(output_file_path_buffer)); 818 } 819 820 output_file_path = ::mktemp(output_file_path_buffer); 821 } 822 823 launch_info.AppendSuppressFileAction (STDIN_FILENO, true, false); 824 if (output_file_path) 825 { 826 launch_info.AppendOpenFileAction(STDOUT_FILENO, output_file_path, false, true); 827 launch_info.AppendDuplicateFileAction(STDOUT_FILENO, STDERR_FILENO); 828 } 829 else 830 { 831 launch_info.AppendSuppressFileAction (STDOUT_FILENO, false, true); 832 launch_info.AppendSuppressFileAction (STDERR_FILENO, false, true); 833 } 834 835 // The process monitor callback will delete the 'shell_info_ptr' below... 836 std::unique_ptr<ShellInfo> shell_info_ap (new ShellInfo()); 837 838 const bool monitor_signals = false; 839 launch_info.SetMonitorProcessCallback(MonitorShellCommand, shell_info_ap.get(), monitor_signals); 840 841 error = LaunchProcess (launch_info); 842 const lldb::pid_t pid = launch_info.GetProcessID(); 843 844 if (error.Success() && pid == LLDB_INVALID_PROCESS_ID) 845 error.SetErrorString("failed to get process ID"); 846 847 if (error.Success()) 848 { 849 // The process successfully launched, so we can defer ownership of 850 // "shell_info" to the MonitorShellCommand callback function that will 851 // get called when the process dies. We release the unique pointer as it 852 // doesn't need to delete the ShellInfo anymore. 853 ShellInfo *shell_info = shell_info_ap.release(); 854 TimeValue *timeout_ptr = nullptr; 855 TimeValue timeout_time(TimeValue::Now()); 856 if (timeout_sec > 0) { 857 timeout_time.OffsetWithSeconds(timeout_sec); 858 timeout_ptr = &timeout_time; 859 } 860 bool timed_out = false; 861 shell_info->process_reaped.WaitForValueEqualTo(true, timeout_ptr, &timed_out); 862 if (timed_out) 863 { 864 error.SetErrorString("timed out waiting for shell command to complete"); 865 866 // Kill the process since it didn't complete within the timeout specified 867 Kill (pid, SIGKILL); 868 // Wait for the monitor callback to get the message 869 timeout_time = TimeValue::Now(); 870 timeout_time.OffsetWithSeconds(1); 871 timed_out = false; 872 shell_info->process_reaped.WaitForValueEqualTo(true, &timeout_time, &timed_out); 873 } 874 else 875 { 876 if (status_ptr) 877 *status_ptr = shell_info->status; 878 879 if (signo_ptr) 880 *signo_ptr = shell_info->signo; 881 882 if (command_output_ptr) 883 { 884 command_output_ptr->clear(); 885 FileSpec file_spec(output_file_path, File::eOpenOptionRead); 886 uint64_t file_size = file_spec.GetByteSize(); 887 if (file_size > 0) 888 { 889 if (file_size > command_output_ptr->max_size()) 890 { 891 error.SetErrorStringWithFormat("shell command output is too large to fit into a std::string"); 892 } 893 else 894 { 895 command_output_ptr->resize(file_size); 896 file_spec.ReadFileContents(0, &((*command_output_ptr)[0]), command_output_ptr->size(), &error); 897 } 898 } 899 } 900 } 901 shell_info->can_delete.SetValue(true, eBroadcastAlways); 902 } 903 904 if (output_file_path) 905 ::unlink (output_file_path); 906 // Handshake with the monitor thread, or just let it know in advance that 907 // it can delete "shell_info" in case we timed out and were not able to kill 908 // the process... 909 return error; 910 } 911 912 913 // LaunchProcessPosixSpawn for Apple, Linux, FreeBSD and other GLIBC 914 // systems 915 916 #if defined (__APPLE__) || defined (__linux__) || defined (__FreeBSD__) || defined (__GLIBC__) || defined(__NetBSD__) 917 918 // this method needs to be visible to macosx/Host.cpp and 919 // common/Host.cpp. 920 921 short 922 Host::GetPosixspawnFlags (ProcessLaunchInfo &launch_info) 923 { 924 short flags = POSIX_SPAWN_SETSIGDEF | POSIX_SPAWN_SETSIGMASK; 925 926 #if defined (__APPLE__) 927 if (launch_info.GetFlags().Test (eLaunchFlagExec)) 928 flags |= POSIX_SPAWN_SETEXEC; // Darwin specific posix_spawn flag 929 930 if (launch_info.GetFlags().Test (eLaunchFlagDebug)) 931 flags |= POSIX_SPAWN_START_SUSPENDED; // Darwin specific posix_spawn flag 932 933 if (launch_info.GetFlags().Test (eLaunchFlagDisableASLR)) 934 flags |= _POSIX_SPAWN_DISABLE_ASLR; // Darwin specific posix_spawn flag 935 936 if (launch_info.GetLaunchInSeparateProcessGroup()) 937 flags |= POSIX_SPAWN_SETPGROUP; 938 939 #ifdef POSIX_SPAWN_CLOEXEC_DEFAULT 940 #if defined (__APPLE__) && (defined (__x86_64__) || defined (__i386__)) 941 static LazyBool g_use_close_on_exec_flag = eLazyBoolCalculate; 942 if (g_use_close_on_exec_flag == eLazyBoolCalculate) 943 { 944 g_use_close_on_exec_flag = eLazyBoolNo; 945 946 uint32_t major, minor, update; 947 if (HostInfo::GetOSVersion(major, minor, update)) 948 { 949 // Kernel panic if we use the POSIX_SPAWN_CLOEXEC_DEFAULT on 10.7 or earlier 950 if (major > 10 || (major == 10 && minor > 7)) 951 { 952 // Only enable for 10.8 and later OS versions 953 g_use_close_on_exec_flag = eLazyBoolYes; 954 } 955 } 956 } 957 #else 958 static LazyBool g_use_close_on_exec_flag = eLazyBoolYes; 959 #endif 960 // Close all files exception those with file actions if this is supported. 961 if (g_use_close_on_exec_flag == eLazyBoolYes) 962 flags |= POSIX_SPAWN_CLOEXEC_DEFAULT; 963 #endif 964 #endif // #if defined (__APPLE__) 965 return flags; 966 } 967 968 Error 969 Host::LaunchProcessPosixSpawn (const char *exe_path, ProcessLaunchInfo &launch_info, ::pid_t &pid) 970 { 971 Error error; 972 Log *log(lldb_private::GetLogIfAllCategoriesSet (LIBLLDB_LOG_HOST | LIBLLDB_LOG_PROCESS)); 973 974 posix_spawnattr_t attr; 975 error.SetError( ::posix_spawnattr_init (&attr), eErrorTypePOSIX); 976 977 if (error.Fail() || log) 978 error.PutToLog(log, "::posix_spawnattr_init ( &attr )"); 979 if (error.Fail()) 980 return error; 981 982 // Make a quick class that will cleanup the posix spawn attributes in case 983 // we return in the middle of this function. 984 lldb_utility::CleanUp <posix_spawnattr_t *, int> posix_spawnattr_cleanup(&attr, posix_spawnattr_destroy); 985 986 sigset_t no_signals; 987 sigset_t all_signals; 988 sigemptyset (&no_signals); 989 sigfillset (&all_signals); 990 ::posix_spawnattr_setsigmask(&attr, &no_signals); 991 #if defined (__linux__) || defined (__FreeBSD__) 992 ::posix_spawnattr_setsigdefault(&attr, &no_signals); 993 #else 994 ::posix_spawnattr_setsigdefault(&attr, &all_signals); 995 #endif 996 997 short flags = GetPosixspawnFlags(launch_info); 998 999 error.SetError( ::posix_spawnattr_setflags (&attr, flags), eErrorTypePOSIX); 1000 if (error.Fail() || log) 1001 error.PutToLog(log, "::posix_spawnattr_setflags ( &attr, flags=0x%8.8x )", flags); 1002 if (error.Fail()) 1003 return error; 1004 1005 // posix_spawnattr_setbinpref_np appears to be an Apple extension per: 1006 // http://www.unix.com/man-page/OSX/3/posix_spawnattr_setbinpref_np/ 1007 #if defined (__APPLE__) && !defined (__arm__) 1008 1009 // Don't set the binpref if a shell was provided. After all, that's only going to affect what version of the shell 1010 // is launched, not what fork of the binary is launched. We insert "arch --arch <ARCH> as part of the shell invocation 1011 // to do that job on OSX. 1012 1013 if (launch_info.GetShell() == nullptr) 1014 { 1015 // We don't need to do this for ARM, and we really shouldn't now that we 1016 // have multiple CPU subtypes and no posix_spawnattr call that allows us 1017 // to set which CPU subtype to launch... 1018 const ArchSpec &arch_spec = launch_info.GetArchitecture(); 1019 cpu_type_t cpu = arch_spec.GetMachOCPUType(); 1020 cpu_type_t sub = arch_spec.GetMachOCPUSubType(); 1021 if (cpu != 0 && 1022 cpu != static_cast<cpu_type_t>(UINT32_MAX) && 1023 cpu != static_cast<cpu_type_t>(LLDB_INVALID_CPUTYPE) && 1024 !(cpu == 0x01000007 && sub == 8)) // If haswell is specified, don't try to set the CPU type or we will fail 1025 { 1026 size_t ocount = 0; 1027 error.SetError( ::posix_spawnattr_setbinpref_np (&attr, 1, &cpu, &ocount), eErrorTypePOSIX); 1028 if (error.Fail() || log) 1029 error.PutToLog(log, "::posix_spawnattr_setbinpref_np ( &attr, 1, cpu_type = 0x%8.8x, count => %llu )", cpu, (uint64_t)ocount); 1030 1031 if (error.Fail() || ocount != 1) 1032 return error; 1033 } 1034 } 1035 1036 #endif 1037 1038 const char *tmp_argv[2]; 1039 char * const *argv = (char * const*)launch_info.GetArguments().GetConstArgumentVector(); 1040 char * const *envp = (char * const*)launch_info.GetEnvironmentEntries().GetConstArgumentVector(); 1041 if (argv == NULL) 1042 { 1043 // posix_spawn gets very unhappy if it doesn't have at least the program 1044 // name in argv[0]. One of the side affects I have noticed is the environment 1045 // variables don't make it into the child process if "argv == NULL"!!! 1046 tmp_argv[0] = exe_path; 1047 tmp_argv[1] = NULL; 1048 argv = (char * const*)tmp_argv; 1049 } 1050 1051 #if !defined (__APPLE__) 1052 // manage the working directory 1053 char current_dir[PATH_MAX]; 1054 current_dir[0] = '\0'; 1055 #endif 1056 1057 const char *working_dir = launch_info.GetWorkingDirectory(); 1058 if (working_dir) 1059 { 1060 #if defined (__APPLE__) 1061 // Set the working directory on this thread only 1062 if (__pthread_chdir (working_dir) < 0) { 1063 if (errno == ENOENT) { 1064 error.SetErrorStringWithFormat("No such file or directory: %s", working_dir); 1065 } else if (errno == ENOTDIR) { 1066 error.SetErrorStringWithFormat("Path doesn't name a directory: %s", working_dir); 1067 } else { 1068 error.SetErrorStringWithFormat("An unknown error occurred when changing directory for process execution."); 1069 } 1070 return error; 1071 } 1072 #else 1073 if (::getcwd(current_dir, sizeof(current_dir)) == NULL) 1074 { 1075 error.SetError(errno, eErrorTypePOSIX); 1076 error.LogIfError(log, "unable to save the current directory"); 1077 return error; 1078 } 1079 1080 if (::chdir(working_dir) == -1) 1081 { 1082 error.SetError(errno, eErrorTypePOSIX); 1083 error.LogIfError(log, "unable to change working directory to %s", working_dir); 1084 return error; 1085 } 1086 #endif 1087 } 1088 1089 const size_t num_file_actions = launch_info.GetNumFileActions (); 1090 if (num_file_actions > 0) 1091 { 1092 posix_spawn_file_actions_t file_actions; 1093 error.SetError( ::posix_spawn_file_actions_init (&file_actions), eErrorTypePOSIX); 1094 if (error.Fail() || log) 1095 error.PutToLog(log, "::posix_spawn_file_actions_init ( &file_actions )"); 1096 if (error.Fail()) 1097 return error; 1098 1099 // Make a quick class that will cleanup the posix spawn attributes in case 1100 // we return in the middle of this function. 1101 lldb_utility::CleanUp <posix_spawn_file_actions_t *, int> posix_spawn_file_actions_cleanup (&file_actions, posix_spawn_file_actions_destroy); 1102 1103 for (size_t i=0; i<num_file_actions; ++i) 1104 { 1105 const FileAction *launch_file_action = launch_info.GetFileActionAtIndex(i); 1106 if (launch_file_action) 1107 { 1108 if (!AddPosixSpawnFileAction(&file_actions, launch_file_action, log, error)) 1109 return error; 1110 } 1111 } 1112 1113 error.SetError (::posix_spawnp (&pid, 1114 exe_path, 1115 &file_actions, 1116 &attr, 1117 argv, 1118 envp), 1119 eErrorTypePOSIX); 1120 1121 if (error.Fail() || log) 1122 { 1123 error.PutToLog(log, "::posix_spawnp ( pid => %i, path = '%s', file_actions = %p, attr = %p, argv = %p, envp = %p )", 1124 pid, exe_path, static_cast<void*>(&file_actions), 1125 static_cast<void*>(&attr), 1126 reinterpret_cast<const void*>(argv), 1127 reinterpret_cast<const void*>(envp)); 1128 if (log) 1129 { 1130 for (int ii=0; argv[ii]; ++ii) 1131 log->Printf("argv[%i] = '%s'", ii, argv[ii]); 1132 } 1133 } 1134 1135 } 1136 else 1137 { 1138 error.SetError (::posix_spawnp (&pid, 1139 exe_path, 1140 NULL, 1141 &attr, 1142 argv, 1143 envp), 1144 eErrorTypePOSIX); 1145 1146 if (error.Fail() || log) 1147 { 1148 error.PutToLog(log, "::posix_spawnp ( pid => %i, path = '%s', file_actions = NULL, attr = %p, argv = %p, envp = %p )", 1149 pid, exe_path, static_cast<void*>(&attr), 1150 reinterpret_cast<const void*>(argv), 1151 reinterpret_cast<const void*>(envp)); 1152 if (log) 1153 { 1154 for (int ii=0; argv[ii]; ++ii) 1155 log->Printf("argv[%i] = '%s'", ii, argv[ii]); 1156 } 1157 } 1158 } 1159 1160 if (working_dir) 1161 { 1162 #if defined (__APPLE__) 1163 // No more thread specific current working directory 1164 __pthread_fchdir (-1); 1165 #else 1166 if (::chdir(current_dir) == -1 && error.Success()) 1167 { 1168 error.SetError(errno, eErrorTypePOSIX); 1169 error.LogIfError(log, "unable to change current directory back to %s", 1170 current_dir); 1171 } 1172 #endif 1173 } 1174 1175 return error; 1176 } 1177 1178 bool 1179 Host::AddPosixSpawnFileAction(void *_file_actions, const FileAction *info, Log *log, Error &error) 1180 { 1181 if (info == NULL) 1182 return false; 1183 1184 posix_spawn_file_actions_t *file_actions = reinterpret_cast<posix_spawn_file_actions_t *>(_file_actions); 1185 1186 switch (info->GetAction()) 1187 { 1188 case FileAction::eFileActionNone: 1189 error.Clear(); 1190 break; 1191 1192 case FileAction::eFileActionClose: 1193 if (info->GetFD() == -1) 1194 error.SetErrorString("invalid fd for posix_spawn_file_actions_addclose(...)"); 1195 else 1196 { 1197 error.SetError(::posix_spawn_file_actions_addclose(file_actions, info->GetFD()), eErrorTypePOSIX); 1198 if (log && (error.Fail() || log)) 1199 error.PutToLog(log, "posix_spawn_file_actions_addclose (action=%p, fd=%i)", 1200 static_cast<void *>(file_actions), info->GetFD()); 1201 } 1202 break; 1203 1204 case FileAction::eFileActionDuplicate: 1205 if (info->GetFD() == -1) 1206 error.SetErrorString("invalid fd for posix_spawn_file_actions_adddup2(...)"); 1207 else if (info->GetActionArgument() == -1) 1208 error.SetErrorString("invalid duplicate fd for posix_spawn_file_actions_adddup2(...)"); 1209 else 1210 { 1211 error.SetError( 1212 ::posix_spawn_file_actions_adddup2(file_actions, info->GetFD(), info->GetActionArgument()), 1213 eErrorTypePOSIX); 1214 if (log && (error.Fail() || log)) 1215 error.PutToLog(log, "posix_spawn_file_actions_adddup2 (action=%p, fd=%i, dup_fd=%i)", 1216 static_cast<void *>(file_actions), info->GetFD(), info->GetActionArgument()); 1217 } 1218 break; 1219 1220 case FileAction::eFileActionOpen: 1221 if (info->GetFD() == -1) 1222 error.SetErrorString("invalid fd in posix_spawn_file_actions_addopen(...)"); 1223 else 1224 { 1225 int oflag = info->GetActionArgument(); 1226 1227 mode_t mode = 0; 1228 1229 if (oflag & O_CREAT) 1230 mode = 0640; 1231 1232 error.SetError( 1233 ::posix_spawn_file_actions_addopen(file_actions, info->GetFD(), info->GetPath(), oflag, mode), 1234 eErrorTypePOSIX); 1235 if (error.Fail() || log) 1236 error.PutToLog(log, 1237 "posix_spawn_file_actions_addopen (action=%p, fd=%i, path='%s', oflag=%i, mode=%i)", 1238 static_cast<void *>(file_actions), info->GetFD(), info->GetPath(), oflag, mode); 1239 } 1240 break; 1241 } 1242 return error.Success(); 1243 } 1244 1245 #endif // LaunchProcedssPosixSpawn: Apple, Linux, FreeBSD and other GLIBC systems 1246 1247 1248 #if defined(__linux__) || defined(__FreeBSD__) || defined(__GLIBC__) || defined(__NetBSD__) 1249 // The functions below implement process launching via posix_spawn() for Linux, 1250 // FreeBSD and NetBSD. 1251 1252 Error 1253 Host::LaunchProcess (ProcessLaunchInfo &launch_info) 1254 { 1255 Error error; 1256 char exe_path[PATH_MAX]; 1257 1258 PlatformSP host_platform_sp (Platform::GetDefaultPlatform ()); 1259 1260 const ArchSpec &arch_spec = launch_info.GetArchitecture(); 1261 1262 FileSpec exe_spec(launch_info.GetExecutableFile()); 1263 1264 FileSpec::FileType file_type = exe_spec.GetFileType(); 1265 if (file_type != FileSpec::eFileTypeRegular) 1266 { 1267 lldb::ModuleSP exe_module_sp; 1268 error = host_platform_sp->ResolveExecutable (exe_spec, 1269 arch_spec, 1270 exe_module_sp, 1271 NULL); 1272 1273 if (error.Fail()) 1274 return error; 1275 1276 if (exe_module_sp) 1277 exe_spec = exe_module_sp->GetFileSpec(); 1278 } 1279 1280 if (exe_spec.Exists()) 1281 { 1282 exe_spec.GetPath (exe_path, sizeof(exe_path)); 1283 } 1284 else 1285 { 1286 launch_info.GetExecutableFile().GetPath (exe_path, sizeof(exe_path)); 1287 error.SetErrorStringWithFormat ("executable doesn't exist: '%s'", exe_path); 1288 return error; 1289 } 1290 1291 assert(!launch_info.GetFlags().Test (eLaunchFlagLaunchInTTY)); 1292 1293 ::pid_t pid = LLDB_INVALID_PROCESS_ID; 1294 1295 error = LaunchProcessPosixSpawn(exe_path, launch_info, pid); 1296 1297 if (pid != LLDB_INVALID_PROCESS_ID) 1298 { 1299 // If all went well, then set the process ID into the launch info 1300 launch_info.SetProcessID(pid); 1301 1302 Log *log(lldb_private::GetLogIfAllCategoriesSet (LIBLLDB_LOG_PROCESS)); 1303 1304 // Make sure we reap any processes we spawn or we will have zombies. 1305 if (!launch_info.MonitorProcess()) 1306 { 1307 const bool monitor_signals = false; 1308 StartMonitoringChildProcess (Process::SetProcessExitStatus, 1309 NULL, 1310 pid, 1311 monitor_signals); 1312 if (log) 1313 log->PutCString ("monitored child process with default Process::SetProcessExitStatus."); 1314 } 1315 else 1316 { 1317 if (log) 1318 log->PutCString ("monitored child process with user-specified process monitor."); 1319 } 1320 } 1321 else 1322 { 1323 // Invalid process ID, something didn't go well 1324 if (error.Success()) 1325 error.SetErrorString ("process launch failed for unknown reasons"); 1326 } 1327 return error; 1328 } 1329 1330 #endif // defined(__linux__) || defined(__FreeBSD__) || defined(__NetBSD__) 1331 1332 #ifndef _WIN32 1333 1334 void 1335 Host::Kill(lldb::pid_t pid, int signo) 1336 { 1337 ::kill(pid, signo); 1338 } 1339 1340 #endif 1341 1342 #if !defined (__APPLE__) 1343 bool 1344 Host::OpenFileInExternalEditor (const FileSpec &file_spec, uint32_t line_no) 1345 { 1346 return false; 1347 } 1348 1349 void 1350 Host::SetCrashDescriptionWithFormat (const char *format, ...) 1351 { 1352 } 1353 1354 void 1355 Host::SetCrashDescription (const char *description) 1356 { 1357 } 1358 1359 lldb::pid_t 1360 Host::LaunchApplication (const FileSpec &app_file_spec) 1361 { 1362 return LLDB_INVALID_PROCESS_ID; 1363 } 1364 1365 #endif 1366 1367 #if !defined (__linux__) && !defined (__FreeBSD__) && !defined (__NetBSD__) 1368 1369 const lldb_private::UnixSignalsSP& 1370 Host::GetUnixSignals () 1371 { 1372 static UnixSignalsSP s_unix_signals_sp (new UnixSignals ()); 1373 return s_unix_signals_sp; 1374 } 1375 1376 #endif 1377