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