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