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 <dlfcn.h> 14 #include <errno.h> 15 #include <grp.h> 16 #include <limits.h> 17 #include <netdb.h> 18 #include <pwd.h> 19 #include <sys/sysctl.h> 20 #include <sys/types.h> 21 #include <unistd.h> 22 23 #if defined (__APPLE__) 24 25 #include <dispatch/dispatch.h> 26 #include <libproc.h> 27 #include <mach-o/dyld.h> 28 #include <mach/mach_port.h> 29 30 #elif defined (__linux__) 31 32 #include <sys/wait.h> 33 34 #elif defined (__FreeBSD__) 35 36 #include <sys/wait.h> 37 #include <pthread_np.h> 38 39 #endif 40 41 #include "lldb/Host/Host.h" 42 #include "lldb/Core/ArchSpec.h" 43 #include "lldb/Core/ConstString.h" 44 #include "lldb/Core/Debugger.h" 45 #include "lldb/Core/Error.h" 46 #include "lldb/Core/Log.h" 47 #include "lldb/Core/StreamString.h" 48 #include "lldb/Core/ThreadSafeSTLMap.h" 49 #include "lldb/Host/Config.h" 50 #include "lldb/Host/Endian.h" 51 #include "lldb/Host/FileSpec.h" 52 #include "lldb/Host/Mutex.h" 53 #include "lldb/Target/Process.h" 54 #include "lldb/Target/TargetList.h" 55 56 #include "llvm/Support/Host.h" 57 #include "llvm/Support/MachO.h" 58 #include "llvm/ADT/Twine.h" 59 60 61 62 63 64 using namespace lldb; 65 using namespace lldb_private; 66 67 68 #if !defined (__APPLE__) 69 struct MonitorInfo 70 { 71 lldb::pid_t pid; // The process ID to monitor 72 Host::MonitorChildProcessCallback callback; // The callback function to call when "pid" exits or signals 73 void *callback_baton; // The callback baton for the callback function 74 bool monitor_signals; // If true, call the callback when "pid" gets signaled. 75 }; 76 77 static void * 78 MonitorChildProcessThreadFunction (void *arg); 79 80 lldb::thread_t 81 Host::StartMonitoringChildProcess 82 ( 83 Host::MonitorChildProcessCallback callback, 84 void *callback_baton, 85 lldb::pid_t pid, 86 bool monitor_signals 87 ) 88 { 89 lldb::thread_t thread = LLDB_INVALID_HOST_THREAD; 90 MonitorInfo * info_ptr = new MonitorInfo(); 91 92 info_ptr->pid = pid; 93 info_ptr->callback = callback; 94 info_ptr->callback_baton = callback_baton; 95 info_ptr->monitor_signals = monitor_signals; 96 97 char thread_name[256]; 98 ::snprintf (thread_name, sizeof(thread_name), "<lldb.host.wait4(pid=%" PRIu64 ")>", pid); 99 thread = ThreadCreate (thread_name, 100 MonitorChildProcessThreadFunction, 101 info_ptr, 102 NULL); 103 104 return thread; 105 } 106 107 //------------------------------------------------------------------ 108 // Scoped class that will disable thread canceling when it is 109 // constructed, and exception safely restore the previous value it 110 // when it goes out of scope. 111 //------------------------------------------------------------------ 112 class ScopedPThreadCancelDisabler 113 { 114 public: 115 ScopedPThreadCancelDisabler() 116 { 117 // Disable the ability for this thread to be cancelled 118 int err = ::pthread_setcancelstate (PTHREAD_CANCEL_DISABLE, &m_old_state); 119 if (err != 0) 120 m_old_state = -1; 121 122 } 123 124 ~ScopedPThreadCancelDisabler() 125 { 126 // Restore the ability for this thread to be cancelled to what it 127 // previously was. 128 if (m_old_state != -1) 129 ::pthread_setcancelstate (m_old_state, 0); 130 } 131 private: 132 int m_old_state; // Save the old cancelability state. 133 }; 134 135 static void * 136 MonitorChildProcessThreadFunction (void *arg) 137 { 138 LogSP log(lldb_private::GetLogIfAllCategoriesSet (LIBLLDB_LOG_PROCESS)); 139 const char *function = __FUNCTION__; 140 if (log) 141 log->Printf ("%s (arg = %p) thread starting...", function, arg); 142 143 MonitorInfo *info = (MonitorInfo *)arg; 144 145 const Host::MonitorChildProcessCallback callback = info->callback; 146 void * const callback_baton = info->callback_baton; 147 const lldb::pid_t pid = info->pid; 148 const bool monitor_signals = info->monitor_signals; 149 150 delete info; 151 152 int status = -1; 153 const int options = __WALL; 154 155 while (1) 156 { 157 log = lldb_private::GetLogIfAllCategoriesSet (LIBLLDB_LOG_PROCESS); 158 if (log) 159 log->Printf("%s ::wait_pid (pid = %" PRIu64 ", &status, options = %i)...", function, pid, options); 160 161 // Wait for all child processes 162 ::pthread_testcancel (); 163 // Get signals from all children with same process group of pid 164 const lldb::pid_t wait_pid = ::waitpid (-1*pid, &status, options); 165 ::pthread_testcancel (); 166 167 if (wait_pid == -1) 168 { 169 if (errno == EINTR) 170 continue; 171 else 172 break; 173 } 174 else if (wait_pid > 0) 175 { 176 bool exited = false; 177 int signal = 0; 178 int exit_status = 0; 179 const char *status_cstr = NULL; 180 if (WIFSTOPPED(status)) 181 { 182 signal = WSTOPSIG(status); 183 status_cstr = "STOPPED"; 184 } 185 else if (WIFEXITED(status)) 186 { 187 exit_status = WEXITSTATUS(status); 188 status_cstr = "EXITED"; 189 if (wait_pid == pid) 190 exited = true; 191 } 192 else if (WIFSIGNALED(status)) 193 { 194 signal = WTERMSIG(status); 195 status_cstr = "SIGNALED"; 196 if (wait_pid == pid) { 197 exited = true; 198 exit_status = -1; 199 } 200 } 201 else 202 { 203 status_cstr = "(\?\?\?)"; 204 } 205 206 // Scope for pthread_cancel_disabler 207 { 208 ScopedPThreadCancelDisabler pthread_cancel_disabler; 209 210 log = lldb_private::GetLogIfAllCategoriesSet (LIBLLDB_LOG_PROCESS); 211 if (log) 212 log->Printf ("%s ::waitpid (pid = %" PRIu64 ", &status, options = %i) => pid = %" PRIu64 ", status = 0x%8.8x (%s), signal = %i, exit_state = %i", 213 function, 214 wait_pid, 215 options, 216 pid, 217 status, 218 status_cstr, 219 signal, 220 exit_status); 221 222 if (exited || (signal != 0 && monitor_signals)) 223 { 224 bool callback_return = false; 225 if (callback) 226 callback_return = callback (callback_baton, wait_pid, exited, signal, exit_status); 227 228 // If our process exited, then this thread should exit 229 if (exited) 230 break; 231 // If the callback returns true, it means this process should 232 // exit 233 if (callback_return) 234 break; 235 } 236 } 237 } 238 } 239 240 log = lldb_private::GetLogIfAllCategoriesSet (LIBLLDB_LOG_PROCESS); 241 if (log) 242 log->Printf ("%s (arg = %p) thread exiting...", __FUNCTION__, arg); 243 244 return NULL; 245 } 246 247 248 void 249 Host::SystemLog (SystemLogType type, const char *format, va_list args) 250 { 251 vfprintf (stderr, format, args); 252 } 253 254 #endif // #if !defined (__APPLE__) 255 256 void 257 Host::SystemLog (SystemLogType type, const char *format, ...) 258 { 259 va_list args; 260 va_start (args, format); 261 SystemLog (type, format, args); 262 va_end (args); 263 } 264 265 size_t 266 Host::GetPageSize() 267 { 268 return ::getpagesize(); 269 } 270 271 const ArchSpec & 272 Host::GetArchitecture (SystemDefaultArchitecture arch_kind) 273 { 274 static bool g_supports_32 = false; 275 static bool g_supports_64 = false; 276 static ArchSpec g_host_arch_32; 277 static ArchSpec g_host_arch_64; 278 279 #if defined (__APPLE__) 280 281 // Apple is different in that it can support both 32 and 64 bit executables 282 // in the same operating system running concurrently. Here we detect the 283 // correct host architectures for both 32 and 64 bit including if 64 bit 284 // executables are supported on the system. 285 286 if (g_supports_32 == false && g_supports_64 == false) 287 { 288 // All apple systems support 32 bit execution. 289 g_supports_32 = true; 290 uint32_t cputype, cpusubtype; 291 uint32_t is_64_bit_capable = false; 292 size_t len = sizeof(cputype); 293 ArchSpec host_arch; 294 // These will tell us about the kernel architecture, which even on a 64 295 // bit machine can be 32 bit... 296 if (::sysctlbyname("hw.cputype", &cputype, &len, NULL, 0) == 0) 297 { 298 len = sizeof (cpusubtype); 299 if (::sysctlbyname("hw.cpusubtype", &cpusubtype, &len, NULL, 0) != 0) 300 cpusubtype = CPU_TYPE_ANY; 301 302 len = sizeof (is_64_bit_capable); 303 if (::sysctlbyname("hw.cpu64bit_capable", &is_64_bit_capable, &len, NULL, 0) == 0) 304 { 305 if (is_64_bit_capable) 306 g_supports_64 = true; 307 } 308 309 if (is_64_bit_capable) 310 { 311 #if defined (__i386__) || defined (__x86_64__) 312 if (cpusubtype == CPU_SUBTYPE_486) 313 cpusubtype = CPU_SUBTYPE_I386_ALL; 314 #endif 315 if (cputype & CPU_ARCH_ABI64) 316 { 317 // We have a 64 bit kernel on a 64 bit system 318 g_host_arch_32.SetArchitecture (eArchTypeMachO, ~(CPU_ARCH_MASK) & cputype, cpusubtype); 319 g_host_arch_64.SetArchitecture (eArchTypeMachO, cputype, cpusubtype); 320 } 321 else 322 { 323 // We have a 32 bit kernel on a 64 bit system 324 g_host_arch_32.SetArchitecture (eArchTypeMachO, cputype, cpusubtype); 325 cputype |= CPU_ARCH_ABI64; 326 g_host_arch_64.SetArchitecture (eArchTypeMachO, cputype, cpusubtype); 327 } 328 } 329 else 330 { 331 g_host_arch_32.SetArchitecture (eArchTypeMachO, cputype, cpusubtype); 332 g_host_arch_64.Clear(); 333 } 334 } 335 } 336 337 #else // #if defined (__APPLE__) 338 339 if (g_supports_32 == false && g_supports_64 == false) 340 { 341 llvm::Triple triple(llvm::sys::getDefaultTargetTriple()); 342 343 g_host_arch_32.Clear(); 344 g_host_arch_64.Clear(); 345 346 // If the OS is Linux, "unknown" in the vendor slot isn't what we want 347 // for the default triple. It's probably an artifact of config.guess. 348 if (triple.getOS() == llvm::Triple::Linux && triple.getVendor() == llvm::Triple::UnknownVendor) 349 triple.setVendorName(""); 350 351 switch (triple.getArch()) 352 { 353 default: 354 g_host_arch_32.SetTriple(triple); 355 g_supports_32 = true; 356 break; 357 358 case llvm::Triple::x86_64: 359 g_host_arch_64.SetTriple(triple); 360 g_supports_64 = true; 361 g_host_arch_32.SetTriple(triple.get32BitArchVariant()); 362 g_supports_32 = true; 363 break; 364 365 case llvm::Triple::sparcv9: 366 case llvm::Triple::ppc64: 367 g_host_arch_64.SetTriple(triple); 368 g_supports_64 = true; 369 break; 370 } 371 372 g_supports_32 = g_host_arch_32.IsValid(); 373 g_supports_64 = g_host_arch_64.IsValid(); 374 } 375 376 #endif // #else for #if defined (__APPLE__) 377 378 if (arch_kind == eSystemDefaultArchitecture32) 379 return g_host_arch_32; 380 else if (arch_kind == eSystemDefaultArchitecture64) 381 return g_host_arch_64; 382 383 if (g_supports_64) 384 return g_host_arch_64; 385 386 return g_host_arch_32; 387 } 388 389 const ConstString & 390 Host::GetVendorString() 391 { 392 static ConstString g_vendor; 393 if (!g_vendor) 394 { 395 const ArchSpec &host_arch = GetArchitecture (eSystemDefaultArchitecture); 396 const llvm::StringRef &str_ref = host_arch.GetTriple().getVendorName(); 397 g_vendor.SetCStringWithLength(str_ref.data(), str_ref.size()); 398 } 399 return g_vendor; 400 } 401 402 const ConstString & 403 Host::GetOSString() 404 { 405 static ConstString g_os_string; 406 if (!g_os_string) 407 { 408 const ArchSpec &host_arch = GetArchitecture (eSystemDefaultArchitecture); 409 const llvm::StringRef &str_ref = host_arch.GetTriple().getOSName(); 410 g_os_string.SetCStringWithLength(str_ref.data(), str_ref.size()); 411 } 412 return g_os_string; 413 } 414 415 const ConstString & 416 Host::GetTargetTriple() 417 { 418 static ConstString g_host_triple; 419 if (!(g_host_triple)) 420 { 421 const ArchSpec &host_arch = GetArchitecture (eSystemDefaultArchitecture); 422 g_host_triple.SetCString(host_arch.GetTriple().getTriple().c_str()); 423 } 424 return g_host_triple; 425 } 426 427 lldb::pid_t 428 Host::GetCurrentProcessID() 429 { 430 return ::getpid(); 431 } 432 433 lldb::tid_t 434 Host::GetCurrentThreadID() 435 { 436 #if defined (__APPLE__) 437 // Calling "mach_port_deallocate()" bumps the reference count on the thread 438 // port, so we need to deallocate it. mach_task_self() doesn't bump the ref 439 // count. 440 thread_port_t thread_self = mach_thread_self(); 441 mach_port_deallocate(mach_task_self(), thread_self); 442 return thread_self; 443 #elif defined(__FreeBSD__) 444 return lldb::tid_t(pthread_getthreadid_np()); 445 #else 446 return lldb::tid_t(pthread_self()); 447 #endif 448 } 449 450 lldb::thread_t 451 Host::GetCurrentThread () 452 { 453 return lldb::thread_t(pthread_self()); 454 } 455 456 const char * 457 Host::GetSignalAsCString (int signo) 458 { 459 switch (signo) 460 { 461 case SIGHUP: return "SIGHUP"; // 1 hangup 462 case SIGINT: return "SIGINT"; // 2 interrupt 463 case SIGQUIT: return "SIGQUIT"; // 3 quit 464 case SIGILL: return "SIGILL"; // 4 illegal instruction (not reset when caught) 465 case SIGTRAP: return "SIGTRAP"; // 5 trace trap (not reset when caught) 466 case SIGABRT: return "SIGABRT"; // 6 abort() 467 #if (defined(_POSIX_C_SOURCE) && !defined(_DARWIN_C_SOURCE)) 468 case SIGPOLL: return "SIGPOLL"; // 7 pollable event ([XSR] generated, not supported) 469 #endif 470 #if !defined(_POSIX_C_SOURCE) 471 case SIGEMT: return "SIGEMT"; // 7 EMT instruction 472 #endif 473 case SIGFPE: return "SIGFPE"; // 8 floating point exception 474 case SIGKILL: return "SIGKILL"; // 9 kill (cannot be caught or ignored) 475 case SIGBUS: return "SIGBUS"; // 10 bus error 476 case SIGSEGV: return "SIGSEGV"; // 11 segmentation violation 477 case SIGSYS: return "SIGSYS"; // 12 bad argument to system call 478 case SIGPIPE: return "SIGPIPE"; // 13 write on a pipe with no one to read it 479 case SIGALRM: return "SIGALRM"; // 14 alarm clock 480 case SIGTERM: return "SIGTERM"; // 15 software termination signal from kill 481 case SIGURG: return "SIGURG"; // 16 urgent condition on IO channel 482 case SIGSTOP: return "SIGSTOP"; // 17 sendable stop signal not from tty 483 case SIGTSTP: return "SIGTSTP"; // 18 stop signal from tty 484 case SIGCONT: return "SIGCONT"; // 19 continue a stopped process 485 case SIGCHLD: return "SIGCHLD"; // 20 to parent on child stop or exit 486 case SIGTTIN: return "SIGTTIN"; // 21 to readers pgrp upon background tty read 487 case SIGTTOU: return "SIGTTOU"; // 22 like TTIN for output if (tp->t_local<OSTOP) 488 #if !defined(_POSIX_C_SOURCE) 489 case SIGIO: return "SIGIO"; // 23 input/output possible signal 490 #endif 491 case SIGXCPU: return "SIGXCPU"; // 24 exceeded CPU time limit 492 case SIGXFSZ: return "SIGXFSZ"; // 25 exceeded file size limit 493 case SIGVTALRM: return "SIGVTALRM"; // 26 virtual time alarm 494 case SIGPROF: return "SIGPROF"; // 27 profiling time alarm 495 #if !defined(_POSIX_C_SOURCE) 496 case SIGWINCH: return "SIGWINCH"; // 28 window size changes 497 case SIGINFO: return "SIGINFO"; // 29 information request 498 #endif 499 case SIGUSR1: return "SIGUSR1"; // 30 user defined signal 1 500 case SIGUSR2: return "SIGUSR2"; // 31 user defined signal 2 501 default: 502 break; 503 } 504 return NULL; 505 } 506 507 void 508 Host::WillTerminate () 509 { 510 } 511 512 #if !defined (__APPLE__) && !defined (__FreeBSD__) // see macosx/Host.mm 513 void 514 Host::ThreadCreated (const char *thread_name) 515 { 516 } 517 518 void 519 Host::Backtrace (Stream &strm, uint32_t max_frames) 520 { 521 // TODO: Is there a way to backtrace the current process on linux? Other systems? 522 } 523 524 size_t 525 Host::GetEnvironment (StringList &env) 526 { 527 // TODO: Is there a way to the host environment for this process on linux? Other systems? 528 return 0; 529 } 530 531 #endif 532 533 struct HostThreadCreateInfo 534 { 535 std::string thread_name; 536 thread_func_t thread_fptr; 537 thread_arg_t thread_arg; 538 539 HostThreadCreateInfo (const char *name, thread_func_t fptr, thread_arg_t arg) : 540 thread_name (name ? name : ""), 541 thread_fptr (fptr), 542 thread_arg (arg) 543 { 544 } 545 }; 546 547 static thread_result_t 548 ThreadCreateTrampoline (thread_arg_t arg) 549 { 550 HostThreadCreateInfo *info = (HostThreadCreateInfo *)arg; 551 Host::ThreadCreated (info->thread_name.c_str()); 552 thread_func_t thread_fptr = info->thread_fptr; 553 thread_arg_t thread_arg = info->thread_arg; 554 555 LogSP log(lldb_private::GetLogIfAllCategoriesSet (LIBLLDB_LOG_THREAD)); 556 if (log) 557 log->Printf("thread created"); 558 559 delete info; 560 return thread_fptr (thread_arg); 561 } 562 563 lldb::thread_t 564 Host::ThreadCreate 565 ( 566 const char *thread_name, 567 thread_func_t thread_fptr, 568 thread_arg_t thread_arg, 569 Error *error 570 ) 571 { 572 lldb::thread_t thread = LLDB_INVALID_HOST_THREAD; 573 574 // Host::ThreadCreateTrampoline will delete this pointer for us. 575 HostThreadCreateInfo *info_ptr = new HostThreadCreateInfo (thread_name, thread_fptr, thread_arg); 576 577 int err = ::pthread_create (&thread, NULL, ThreadCreateTrampoline, info_ptr); 578 if (err == 0) 579 { 580 if (error) 581 error->Clear(); 582 return thread; 583 } 584 585 if (error) 586 error->SetError (err, eErrorTypePOSIX); 587 588 return LLDB_INVALID_HOST_THREAD; 589 } 590 591 bool 592 Host::ThreadCancel (lldb::thread_t thread, Error *error) 593 { 594 int err = ::pthread_cancel (thread); 595 if (error) 596 error->SetError(err, eErrorTypePOSIX); 597 return err == 0; 598 } 599 600 bool 601 Host::ThreadDetach (lldb::thread_t thread, Error *error) 602 { 603 int err = ::pthread_detach (thread); 604 if (error) 605 error->SetError(err, eErrorTypePOSIX); 606 return err == 0; 607 } 608 609 bool 610 Host::ThreadJoin (lldb::thread_t thread, thread_result_t *thread_result_ptr, Error *error) 611 { 612 int err = ::pthread_join (thread, thread_result_ptr); 613 if (error) 614 error->SetError(err, eErrorTypePOSIX); 615 return err == 0; 616 } 617 618 619 std::string 620 Host::GetThreadName (lldb::pid_t pid, lldb::tid_t tid) 621 { 622 std::string thread_name; 623 #if defined(__APPLE__) && MAC_OS_X_VERSION_MAX_ALLOWED > MAC_OS_X_VERSION_10_5 624 // We currently can only get the name of a thread in the current process. 625 if (pid == Host::GetCurrentProcessID()) 626 { 627 char pthread_name[1024]; 628 if (::pthread_getname_np (::pthread_from_mach_thread_np (tid), pthread_name, sizeof(pthread_name)) == 0) 629 { 630 if (pthread_name[0]) 631 { 632 thread_name = pthread_name; 633 } 634 } 635 else 636 { 637 dispatch_queue_t current_queue = ::dispatch_get_current_queue (); 638 if (current_queue != NULL) 639 { 640 const char *queue_name = dispatch_queue_get_label (current_queue); 641 if (queue_name && queue_name[0]) 642 { 643 thread_name = queue_name; 644 } 645 } 646 } 647 } 648 #endif 649 return thread_name; 650 } 651 652 void 653 Host::SetThreadName (lldb::pid_t pid, lldb::tid_t tid, const char *name) 654 { 655 #if defined(__APPLE__) && MAC_OS_X_VERSION_MAX_ALLOWED > MAC_OS_X_VERSION_10_5 656 lldb::pid_t curr_pid = Host::GetCurrentProcessID(); 657 lldb::tid_t curr_tid = Host::GetCurrentThreadID(); 658 if (pid == LLDB_INVALID_PROCESS_ID) 659 pid = curr_pid; 660 661 if (tid == LLDB_INVALID_THREAD_ID) 662 tid = curr_tid; 663 664 // Set the pthread name if possible 665 if (pid == curr_pid && tid == curr_tid) 666 { 667 ::pthread_setname_np (name); 668 } 669 #endif 670 } 671 672 FileSpec 673 Host::GetProgramFileSpec () 674 { 675 static FileSpec g_program_filespec; 676 if (!g_program_filespec) 677 { 678 #if defined (__APPLE__) 679 char program_fullpath[PATH_MAX]; 680 // If DST is NULL, then return the number of bytes needed. 681 uint32_t len = sizeof(program_fullpath); 682 int err = _NSGetExecutablePath (program_fullpath, &len); 683 if (err == 0) 684 g_program_filespec.SetFile (program_fullpath, false); 685 else if (err == -1) 686 { 687 char *large_program_fullpath = (char *)::malloc (len + 1); 688 689 err = _NSGetExecutablePath (large_program_fullpath, &len); 690 if (err == 0) 691 g_program_filespec.SetFile (large_program_fullpath, false); 692 693 ::free (large_program_fullpath); 694 } 695 #elif defined (__linux__) 696 char exe_path[PATH_MAX]; 697 ssize_t len = readlink("/proc/self/exe", exe_path, sizeof(exe_path) - 1); 698 if (len > 0) { 699 exe_path[len] = 0; 700 g_program_filespec.SetFile(exe_path, false); 701 } 702 #elif defined (__FreeBSD__) 703 int exe_path_mib[4] = { CTL_KERN, KERN_PROC, KERN_PROC_PATHNAME, getpid() }; 704 size_t exe_path_size; 705 if (sysctl(exe_path_mib, 4, NULL, &exe_path_size, NULL, 0) == 0) 706 { 707 char *exe_path = new char[exe_path_size]; 708 if (sysctl(exe_path_mib, 4, exe_path, &exe_path_size, NULL, 0) == 0) 709 g_program_filespec.SetFile(exe_path, false); 710 delete[] exe_path; 711 } 712 #endif 713 } 714 return g_program_filespec; 715 } 716 717 FileSpec 718 Host::GetModuleFileSpecForHostAddress (const void *host_addr) 719 { 720 FileSpec module_filespec; 721 Dl_info info; 722 if (::dladdr (host_addr, &info)) 723 { 724 if (info.dli_fname) 725 module_filespec.SetFile(info.dli_fname, true); 726 } 727 return module_filespec; 728 } 729 730 #if !defined (__APPLE__) // see Host.mm 731 732 bool 733 Host::GetBundleDirectory (const FileSpec &file, FileSpec &bundle) 734 { 735 bundle.Clear(); 736 return false; 737 } 738 739 bool 740 Host::ResolveExecutableInBundle (FileSpec &file) 741 { 742 return false; 743 } 744 #endif 745 746 // Opaque info that tracks a dynamic library that was loaded 747 struct DynamicLibraryInfo 748 { 749 DynamicLibraryInfo (const FileSpec &fs, int o, void *h) : 750 file_spec (fs), 751 open_options (o), 752 handle (h) 753 { 754 } 755 756 const FileSpec file_spec; 757 uint32_t open_options; 758 void * handle; 759 }; 760 761 void * 762 Host::DynamicLibraryOpen (const FileSpec &file_spec, uint32_t options, Error &error) 763 { 764 char path[PATH_MAX]; 765 if (file_spec.GetPath(path, sizeof(path))) 766 { 767 int mode = 0; 768 769 if (options & eDynamicLibraryOpenOptionLazy) 770 mode |= RTLD_LAZY; 771 else 772 mode |= RTLD_NOW; 773 774 775 if (options & eDynamicLibraryOpenOptionLocal) 776 mode |= RTLD_LOCAL; 777 else 778 mode |= RTLD_GLOBAL; 779 780 #ifdef LLDB_CONFIG_DLOPEN_RTLD_FIRST_SUPPORTED 781 if (options & eDynamicLibraryOpenOptionLimitGetSymbol) 782 mode |= RTLD_FIRST; 783 #endif 784 785 void * opaque = ::dlopen (path, mode); 786 787 if (opaque) 788 { 789 error.Clear(); 790 return new DynamicLibraryInfo (file_spec, options, opaque); 791 } 792 else 793 { 794 error.SetErrorString(::dlerror()); 795 } 796 } 797 else 798 { 799 error.SetErrorString("failed to extract path"); 800 } 801 return NULL; 802 } 803 804 Error 805 Host::DynamicLibraryClose (void *opaque) 806 { 807 Error error; 808 if (opaque == NULL) 809 { 810 error.SetErrorString ("invalid dynamic library handle"); 811 } 812 else 813 { 814 DynamicLibraryInfo *dylib_info = (DynamicLibraryInfo *) opaque; 815 if (::dlclose (dylib_info->handle) != 0) 816 { 817 error.SetErrorString(::dlerror()); 818 } 819 820 dylib_info->open_options = 0; 821 dylib_info->handle = 0; 822 delete dylib_info; 823 } 824 return error; 825 } 826 827 void * 828 Host::DynamicLibraryGetSymbol (void *opaque, const char *symbol_name, Error &error) 829 { 830 if (opaque == NULL) 831 { 832 error.SetErrorString ("invalid dynamic library handle"); 833 } 834 else 835 { 836 DynamicLibraryInfo *dylib_info = (DynamicLibraryInfo *) opaque; 837 838 void *symbol_addr = ::dlsym (dylib_info->handle, symbol_name); 839 if (symbol_addr) 840 { 841 #ifndef LLDB_CONFIG_DLOPEN_RTLD_FIRST_SUPPORTED 842 // This host doesn't support limiting searches to this shared library 843 // so we need to verify that the match came from this shared library 844 // if it was requested in the Host::DynamicLibraryOpen() function. 845 if (dylib_info->open_options & eDynamicLibraryOpenOptionLimitGetSymbol) 846 { 847 FileSpec match_dylib_spec (Host::GetModuleFileSpecForHostAddress (symbol_addr)); 848 if (match_dylib_spec != dylib_info->file_spec) 849 { 850 char dylib_path[PATH_MAX]; 851 if (dylib_info->file_spec.GetPath (dylib_path, sizeof(dylib_path))) 852 error.SetErrorStringWithFormat ("symbol not found in \"%s\"", dylib_path); 853 else 854 error.SetErrorString ("symbol not found"); 855 return NULL; 856 } 857 } 858 #endif 859 error.Clear(); 860 return symbol_addr; 861 } 862 else 863 { 864 error.SetErrorString(::dlerror()); 865 } 866 } 867 return NULL; 868 } 869 870 bool 871 Host::GetLLDBPath (PathType path_type, FileSpec &file_spec) 872 { 873 // To get paths related to LLDB we get the path to the executable that 874 // contains this function. On MacOSX this will be "LLDB.framework/.../LLDB", 875 // on linux this is assumed to be the "lldb" main executable. If LLDB on 876 // linux is actually in a shared library (lldb.so??) then this function will 877 // need to be modified to "do the right thing". 878 879 switch (path_type) 880 { 881 case ePathTypeLLDBShlibDir: 882 { 883 static ConstString g_lldb_so_dir; 884 if (!g_lldb_so_dir) 885 { 886 FileSpec lldb_file_spec (Host::GetModuleFileSpecForHostAddress ((void *)Host::GetLLDBPath)); 887 g_lldb_so_dir = lldb_file_spec.GetDirectory(); 888 } 889 file_spec.GetDirectory() = g_lldb_so_dir; 890 return file_spec.GetDirectory(); 891 } 892 break; 893 894 case ePathTypeSupportExecutableDir: 895 { 896 static ConstString g_lldb_support_exe_dir; 897 if (!g_lldb_support_exe_dir) 898 { 899 FileSpec lldb_file_spec; 900 if (GetLLDBPath (ePathTypeLLDBShlibDir, lldb_file_spec)) 901 { 902 char raw_path[PATH_MAX]; 903 char resolved_path[PATH_MAX]; 904 lldb_file_spec.GetPath(raw_path, sizeof(raw_path)); 905 906 #if defined (__APPLE__) 907 char *framework_pos = ::strstr (raw_path, "LLDB.framework"); 908 if (framework_pos) 909 { 910 framework_pos += strlen("LLDB.framework"); 911 #if !defined (__arm__) 912 ::strncpy (framework_pos, "/Resources", PATH_MAX - (framework_pos - raw_path)); 913 #endif 914 } 915 #endif 916 FileSpec::Resolve (raw_path, resolved_path, sizeof(resolved_path)); 917 g_lldb_support_exe_dir.SetCString(resolved_path); 918 } 919 } 920 file_spec.GetDirectory() = g_lldb_support_exe_dir; 921 return file_spec.GetDirectory(); 922 } 923 break; 924 925 case ePathTypeHeaderDir: 926 { 927 static ConstString g_lldb_headers_dir; 928 if (!g_lldb_headers_dir) 929 { 930 #if defined (__APPLE__) 931 FileSpec lldb_file_spec; 932 if (GetLLDBPath (ePathTypeLLDBShlibDir, lldb_file_spec)) 933 { 934 char raw_path[PATH_MAX]; 935 char resolved_path[PATH_MAX]; 936 lldb_file_spec.GetPath(raw_path, sizeof(raw_path)); 937 938 char *framework_pos = ::strstr (raw_path, "LLDB.framework"); 939 if (framework_pos) 940 { 941 framework_pos += strlen("LLDB.framework"); 942 ::strncpy (framework_pos, "/Headers", PATH_MAX - (framework_pos - raw_path)); 943 } 944 FileSpec::Resolve (raw_path, resolved_path, sizeof(resolved_path)); 945 g_lldb_headers_dir.SetCString(resolved_path); 946 } 947 #else 948 // TODO: Anyone know how we can determine this for linux? Other systems?? 949 g_lldb_headers_dir.SetCString ("/opt/local/include/lldb"); 950 #endif 951 } 952 file_spec.GetDirectory() = g_lldb_headers_dir; 953 return file_spec.GetDirectory(); 954 } 955 break; 956 957 case ePathTypePythonDir: 958 { 959 static ConstString g_lldb_python_dir; 960 if (!g_lldb_python_dir) 961 { 962 FileSpec lldb_file_spec; 963 if (GetLLDBPath (ePathTypeLLDBShlibDir, lldb_file_spec)) 964 { 965 char raw_path[PATH_MAX]; 966 char resolved_path[PATH_MAX]; 967 lldb_file_spec.GetPath(raw_path, sizeof(raw_path)); 968 969 #if defined (__APPLE__) 970 char *framework_pos = ::strstr (raw_path, "LLDB.framework"); 971 if (framework_pos) 972 { 973 framework_pos += strlen("LLDB.framework"); 974 ::strncpy (framework_pos, "/Resources/Python", PATH_MAX - (framework_pos - raw_path)); 975 } 976 #else 977 llvm::Twine python_version_dir; 978 python_version_dir = "/python" 979 + llvm::Twine(PY_MAJOR_VERSION) 980 + "." 981 + llvm::Twine(PY_MINOR_VERSION) 982 + "/site-packages"; 983 984 // We may get our string truncated. Should we protect 985 // this with an assert? 986 987 ::strncat(raw_path, python_version_dir.str().c_str(), 988 sizeof(raw_path) - strlen(raw_path) - 1); 989 990 #endif 991 FileSpec::Resolve (raw_path, resolved_path, sizeof(resolved_path)); 992 g_lldb_python_dir.SetCString(resolved_path); 993 } 994 } 995 file_spec.GetDirectory() = g_lldb_python_dir; 996 return file_spec.GetDirectory(); 997 } 998 break; 999 1000 case ePathTypeLLDBSystemPlugins: // System plug-ins directory 1001 { 1002 #if defined (__APPLE__) 1003 static ConstString g_lldb_system_plugin_dir; 1004 static bool g_lldb_system_plugin_dir_located = false; 1005 if (!g_lldb_system_plugin_dir_located) 1006 { 1007 g_lldb_system_plugin_dir_located = true; 1008 FileSpec lldb_file_spec; 1009 if (GetLLDBPath (ePathTypeLLDBShlibDir, lldb_file_spec)) 1010 { 1011 char raw_path[PATH_MAX]; 1012 char resolved_path[PATH_MAX]; 1013 lldb_file_spec.GetPath(raw_path, sizeof(raw_path)); 1014 1015 char *framework_pos = ::strstr (raw_path, "LLDB.framework"); 1016 if (framework_pos) 1017 { 1018 framework_pos += strlen("LLDB.framework"); 1019 ::strncpy (framework_pos, "/Resources/PlugIns", PATH_MAX - (framework_pos - raw_path)); 1020 FileSpec::Resolve (raw_path, resolved_path, sizeof(resolved_path)); 1021 g_lldb_system_plugin_dir.SetCString(resolved_path); 1022 } 1023 return false; 1024 } 1025 } 1026 1027 if (g_lldb_system_plugin_dir) 1028 { 1029 file_spec.GetDirectory() = g_lldb_system_plugin_dir; 1030 return true; 1031 } 1032 #endif 1033 // TODO: where would system LLDB plug-ins be located on linux? Other systems? 1034 return false; 1035 } 1036 break; 1037 1038 case ePathTypeLLDBUserPlugins: // User plug-ins directory 1039 { 1040 #if defined (__APPLE__) 1041 static ConstString g_lldb_user_plugin_dir; 1042 if (!g_lldb_user_plugin_dir) 1043 { 1044 char user_plugin_path[PATH_MAX]; 1045 if (FileSpec::Resolve ("~/Library/Application Support/LLDB/PlugIns", 1046 user_plugin_path, 1047 sizeof(user_plugin_path))) 1048 { 1049 g_lldb_user_plugin_dir.SetCString(user_plugin_path); 1050 } 1051 } 1052 file_spec.GetDirectory() = g_lldb_user_plugin_dir; 1053 return file_spec.GetDirectory(); 1054 #endif 1055 // TODO: where would user LLDB plug-ins be located on linux? Other systems? 1056 return false; 1057 } 1058 } 1059 1060 return false; 1061 } 1062 1063 1064 bool 1065 Host::GetHostname (std::string &s) 1066 { 1067 char hostname[PATH_MAX]; 1068 hostname[sizeof(hostname) - 1] = '\0'; 1069 if (::gethostname (hostname, sizeof(hostname) - 1) == 0) 1070 { 1071 struct hostent* h = ::gethostbyname (hostname); 1072 if (h) 1073 s.assign (h->h_name); 1074 else 1075 s.assign (hostname); 1076 return true; 1077 } 1078 return false; 1079 } 1080 1081 const char * 1082 Host::GetUserName (uint32_t uid, std::string &user_name) 1083 { 1084 struct passwd user_info; 1085 struct passwd *user_info_ptr = &user_info; 1086 char user_buffer[PATH_MAX]; 1087 size_t user_buffer_size = sizeof(user_buffer); 1088 if (::getpwuid_r (uid, 1089 &user_info, 1090 user_buffer, 1091 user_buffer_size, 1092 &user_info_ptr) == 0) 1093 { 1094 if (user_info_ptr) 1095 { 1096 user_name.assign (user_info_ptr->pw_name); 1097 return user_name.c_str(); 1098 } 1099 } 1100 user_name.clear(); 1101 return NULL; 1102 } 1103 1104 const char * 1105 Host::GetGroupName (uint32_t gid, std::string &group_name) 1106 { 1107 char group_buffer[PATH_MAX]; 1108 size_t group_buffer_size = sizeof(group_buffer); 1109 struct group group_info; 1110 struct group *group_info_ptr = &group_info; 1111 // Try the threadsafe version first 1112 if (::getgrgid_r (gid, 1113 &group_info, 1114 group_buffer, 1115 group_buffer_size, 1116 &group_info_ptr) == 0) 1117 { 1118 if (group_info_ptr) 1119 { 1120 group_name.assign (group_info_ptr->gr_name); 1121 return group_name.c_str(); 1122 } 1123 } 1124 else 1125 { 1126 // The threadsafe version isn't currently working 1127 // for me on darwin, but the non-threadsafe version 1128 // is, so I am calling it below. 1129 group_info_ptr = ::getgrgid (gid); 1130 if (group_info_ptr) 1131 { 1132 group_name.assign (group_info_ptr->gr_name); 1133 return group_name.c_str(); 1134 } 1135 } 1136 group_name.clear(); 1137 return NULL; 1138 } 1139 1140 #if !defined (__APPLE__) && !defined (__FreeBSD__) // see macosx/Host.mm 1141 bool 1142 Host::GetOSBuildString (std::string &s) 1143 { 1144 s.clear(); 1145 return false; 1146 } 1147 1148 bool 1149 Host::GetOSKernelDescription (std::string &s) 1150 { 1151 s.clear(); 1152 return false; 1153 } 1154 #endif 1155 1156 uint32_t 1157 Host::GetUserID () 1158 { 1159 return getuid(); 1160 } 1161 1162 uint32_t 1163 Host::GetGroupID () 1164 { 1165 return getgid(); 1166 } 1167 1168 uint32_t 1169 Host::GetEffectiveUserID () 1170 { 1171 return geteuid(); 1172 } 1173 1174 uint32_t 1175 Host::GetEffectiveGroupID () 1176 { 1177 return getegid(); 1178 } 1179 1180 #if !defined (__APPLE__) 1181 uint32_t 1182 Host::FindProcesses (const ProcessInstanceInfoMatch &match_info, ProcessInstanceInfoList &process_infos) 1183 { 1184 process_infos.Clear(); 1185 return process_infos.GetSize(); 1186 } 1187 #endif 1188 1189 #if !defined (__APPLE__) && !defined (__FreeBSD__) 1190 bool 1191 Host::GetProcessInfo (lldb::pid_t pid, ProcessInstanceInfo &process_info) 1192 { 1193 process_info.Clear(); 1194 return false; 1195 } 1196 #endif 1197 1198 lldb::TargetSP 1199 Host::GetDummyTarget (lldb_private::Debugger &debugger) 1200 { 1201 static TargetSP g_dummy_target_sp; 1202 1203 // FIXME: Maybe the dummy target should be per-Debugger 1204 if (!g_dummy_target_sp || !g_dummy_target_sp->IsValid()) 1205 { 1206 ArchSpec arch(Target::GetDefaultArchitecture()); 1207 if (!arch.IsValid()) 1208 arch = Host::GetArchitecture (); 1209 Error err = debugger.GetTargetList().CreateTarget(debugger, 1210 NULL, 1211 arch.GetTriple().getTriple().c_str(), 1212 false, 1213 NULL, 1214 g_dummy_target_sp); 1215 } 1216 1217 return g_dummy_target_sp; 1218 } 1219 1220 struct ShellInfo 1221 { 1222 ShellInfo () : 1223 process_reaped (false), 1224 can_delete (false), 1225 pid (LLDB_INVALID_PROCESS_ID), 1226 signo(-1), 1227 status(-1) 1228 { 1229 } 1230 1231 lldb_private::Predicate<bool> process_reaped; 1232 lldb_private::Predicate<bool> can_delete; 1233 lldb::pid_t pid; 1234 int signo; 1235 int status; 1236 }; 1237 1238 static bool 1239 MonitorShellCommand (void *callback_baton, 1240 lldb::pid_t pid, 1241 bool exited, // True if the process did exit 1242 int signo, // Zero for no signal 1243 int status) // Exit value of process if signal is zero 1244 { 1245 ShellInfo *shell_info = (ShellInfo *)callback_baton; 1246 shell_info->pid = pid; 1247 shell_info->signo = signo; 1248 shell_info->status = status; 1249 // Let the thread running Host::RunShellCommand() know that the process 1250 // exited and that ShellInfo has been filled in by broadcasting to it 1251 shell_info->process_reaped.SetValue(1, eBroadcastAlways); 1252 // Now wait for a handshake back from that thread running Host::RunShellCommand 1253 // so we know that we can delete shell_info_ptr 1254 shell_info->can_delete.WaitForValueEqualTo(true); 1255 // Sleep a bit to allow the shell_info->can_delete.SetValue() to complete... 1256 usleep(1000); 1257 // Now delete the shell info that was passed into this function 1258 delete shell_info; 1259 return true; 1260 } 1261 1262 Error 1263 Host::RunShellCommand (const char *command, 1264 const char *working_dir, 1265 int *status_ptr, 1266 int *signo_ptr, 1267 std::string *command_output_ptr, 1268 uint32_t timeout_sec, 1269 const char *shell) 1270 { 1271 Error error; 1272 ProcessLaunchInfo launch_info; 1273 if (shell && shell[0]) 1274 { 1275 // Run the command in a shell 1276 launch_info.SetShell(shell); 1277 launch_info.GetArguments().AppendArgument(command); 1278 const bool localhost = true; 1279 const bool will_debug = false; 1280 const bool first_arg_is_full_shell_command = true; 1281 launch_info.ConvertArgumentsForLaunchingInShell (error, 1282 localhost, 1283 will_debug, 1284 first_arg_is_full_shell_command); 1285 } 1286 else 1287 { 1288 // No shell, just run it 1289 Args args (command); 1290 const bool first_arg_is_executable = true; 1291 launch_info.SetArguments(args, first_arg_is_executable); 1292 } 1293 1294 if (working_dir) 1295 launch_info.SetWorkingDirectory(working_dir); 1296 char output_file_path_buffer[L_tmpnam]; 1297 const char *output_file_path = NULL; 1298 if (command_output_ptr) 1299 { 1300 // Create a temporary file to get the stdout/stderr and redirect the 1301 // output of the command into this file. We will later read this file 1302 // if all goes well and fill the data into "command_output_ptr" 1303 output_file_path = ::tmpnam(output_file_path_buffer); 1304 launch_info.AppendSuppressFileAction (STDIN_FILENO, true, false); 1305 launch_info.AppendOpenFileAction(STDOUT_FILENO, output_file_path, false, true); 1306 launch_info.AppendDuplicateFileAction(STDOUT_FILENO, STDERR_FILENO); 1307 } 1308 else 1309 { 1310 launch_info.AppendSuppressFileAction (STDIN_FILENO, true, false); 1311 launch_info.AppendSuppressFileAction (STDOUT_FILENO, false, true); 1312 launch_info.AppendSuppressFileAction (STDERR_FILENO, false, true); 1313 } 1314 1315 // The process monitor callback will delete the 'shell_info_ptr' below... 1316 std::auto_ptr<ShellInfo> shell_info_ap (new ShellInfo()); 1317 1318 const bool monitor_signals = false; 1319 launch_info.SetMonitorProcessCallback(MonitorShellCommand, shell_info_ap.get(), monitor_signals); 1320 1321 error = LaunchProcess (launch_info); 1322 const lldb::pid_t pid = launch_info.GetProcessID(); 1323 if (pid != LLDB_INVALID_PROCESS_ID) 1324 { 1325 // The process successfully launched, so we can defer ownership of 1326 // "shell_info" to the MonitorShellCommand callback function that will 1327 // get called when the process dies. We release the std::auto_ptr as it 1328 // doesn't need to delete the ShellInfo anymore. 1329 ShellInfo *shell_info = shell_info_ap.release(); 1330 TimeValue timeout_time(TimeValue::Now()); 1331 timeout_time.OffsetWithSeconds(timeout_sec); 1332 bool timed_out = false; 1333 shell_info->process_reaped.WaitForValueEqualTo(true, &timeout_time, &timed_out); 1334 if (timed_out) 1335 { 1336 error.SetErrorString("timed out waiting for shell command to complete"); 1337 1338 // Kill the process since it didn't complete withint the timeout specified 1339 ::kill (pid, SIGKILL); 1340 // Wait for the monitor callback to get the message 1341 timeout_time = TimeValue::Now(); 1342 timeout_time.OffsetWithSeconds(1); 1343 timed_out = false; 1344 shell_info->process_reaped.WaitForValueEqualTo(true, &timeout_time, &timed_out); 1345 } 1346 else 1347 { 1348 if (status_ptr) 1349 *status_ptr = shell_info->status; 1350 1351 if (signo_ptr) 1352 *signo_ptr = shell_info->signo; 1353 1354 if (command_output_ptr) 1355 { 1356 command_output_ptr->clear(); 1357 FileSpec file_spec(output_file_path, File::eOpenOptionRead); 1358 uint64_t file_size = file_spec.GetByteSize(); 1359 if (file_size > 0) 1360 { 1361 if (file_size > command_output_ptr->max_size()) 1362 { 1363 error.SetErrorStringWithFormat("shell command output is too large to fit into a std::string"); 1364 } 1365 else 1366 { 1367 command_output_ptr->resize(file_size); 1368 file_spec.ReadFileContents(0, &((*command_output_ptr)[0]), command_output_ptr->size(), &error); 1369 } 1370 } 1371 } 1372 } 1373 shell_info->can_delete.SetValue(true, eBroadcastAlways); 1374 } 1375 else 1376 { 1377 error.SetErrorString("failed to get process ID"); 1378 } 1379 1380 if (output_file_path) 1381 ::unlink (output_file_path); 1382 // Handshake with the monitor thread, or just let it know in advance that 1383 // it can delete "shell_info" in case we timed out and were not able to kill 1384 // the process... 1385 return error; 1386 } 1387 1388 1389 uint32_t 1390 Host::GetNumberCPUS () 1391 { 1392 static uint32_t g_num_cores = UINT32_MAX; 1393 if (g_num_cores == UINT32_MAX) 1394 { 1395 #if defined(__APPLE__) or defined (__linux__) 1396 1397 g_num_cores = ::sysconf(_SC_NPROCESSORS_ONLN); 1398 1399 #elif defined(_WIN32) || defined(__WIN32__) || defined(__CYGWIN__) 1400 1401 // Header file for this might need to be included at the top of this file 1402 SYSTEM_INFO system_info; 1403 ::GetSystemInfo (&system_info); 1404 g_num_cores = system_info.dwNumberOfProcessors; 1405 1406 #else 1407 1408 // Assume POSIX support if a host specific case has not been supplied above 1409 g_num_cores = 0; 1410 int num_cores = 0; 1411 size_t num_cores_len = sizeof(num_cores); 1412 int mib[] = { CTL_HW, HW_AVAILCPU }; 1413 1414 /* get the number of CPUs from the system */ 1415 if (sysctl(mib, sizeof(mib)/sizeof(int), &num_cores, &num_cores_len, NULL, 0) == 0 && (num_cores > 0)) 1416 { 1417 g_num_cores = num_cores; 1418 } 1419 else 1420 { 1421 mib[1] = HW_NCPU; 1422 num_cores_len = sizeof(num_cores); 1423 if (sysctl(mib, sizeof(mib)/sizeof(int), &num_cores, &num_cores_len, NULL, 0) == 0 && (num_cores > 0)) 1424 { 1425 if (num_cores > 0) 1426 g_num_cores = num_cores; 1427 } 1428 } 1429 #endif 1430 } 1431 return g_num_cores; 1432 } 1433 1434 1435 1436 #if !defined (__APPLE__) 1437 bool 1438 Host::OpenFileInExternalEditor (const FileSpec &file_spec, uint32_t line_no) 1439 { 1440 return false; 1441 } 1442 1443 void 1444 Host::SetCrashDescriptionWithFormat (const char *format, ...) 1445 { 1446 } 1447 1448 void 1449 Host::SetCrashDescription (const char *description) 1450 { 1451 } 1452 1453 lldb::pid_t 1454 LaunchApplication (const FileSpec &app_file_spec) 1455 { 1456 return LLDB_INVALID_PROCESS_ID; 1457 } 1458 1459 #endif 1460