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