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