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 #endif 31 32 #if defined (__linux__) || defined (__FreeBSD__) || defined (__FreeBSD_kernel__) 33 #include <sys/wait.h> 34 #endif 35 36 #if defined (__FreeBSD__) 37 #include <pthread_np.h> 38 #endif 39 40 #include "lldb/Host/Host.h" 41 #include "lldb/Core/ArchSpec.h" 42 #include "lldb/Core/ConstString.h" 43 #include "lldb/Core/Debugger.h" 44 #include "lldb/Core/Error.h" 45 #include "lldb/Core/Log.h" 46 #include "lldb/Core/StreamString.h" 47 #include "lldb/Core/ThreadSafeSTLMap.h" 48 #include "lldb/Host/Config.h" 49 #include "lldb/Host/Endian.h" 50 #include "lldb/Host/FileSpec.h" 51 #include "lldb/Host/Mutex.h" 52 #include "lldb/Target/Process.h" 53 #include "lldb/Target/TargetList.h" 54 55 #include "llvm/Support/Host.h" 56 #include "llvm/Support/MachO.h" 57 #include "llvm/ADT/Twine.h" 58 59 60 61 62 63 using namespace lldb; 64 using namespace lldb_private; 65 66 67 #if !defined (__APPLE__) 68 struct MonitorInfo 69 { 70 lldb::pid_t pid; // The process ID to monitor 71 Host::MonitorChildProcessCallback callback; // The callback function to call when "pid" exits or signals 72 void *callback_baton; // The callback baton for the callback function 73 bool monitor_signals; // If true, call the callback when "pid" gets signaled. 74 }; 75 76 static void * 77 MonitorChildProcessThreadFunction (void *arg); 78 79 lldb::thread_t 80 Host::StartMonitoringChildProcess 81 ( 82 Host::MonitorChildProcessCallback callback, 83 void *callback_baton, 84 lldb::pid_t pid, 85 bool monitor_signals 86 ) 87 { 88 lldb::thread_t thread = LLDB_INVALID_HOST_THREAD; 89 MonitorInfo * info_ptr = new MonitorInfo(); 90 91 info_ptr->pid = pid; 92 info_ptr->callback = callback; 93 info_ptr->callback_baton = callback_baton; 94 info_ptr->monitor_signals = monitor_signals; 95 96 char thread_name[256]; 97 ::snprintf (thread_name, sizeof(thread_name), "<lldb.host.wait4(pid=%" PRIu64 ")>", pid); 98 thread = ThreadCreate (thread_name, 99 MonitorChildProcessThreadFunction, 100 info_ptr, 101 NULL); 102 103 return thread; 104 } 105 106 //------------------------------------------------------------------ 107 // Scoped class that will disable thread canceling when it is 108 // constructed, and exception safely restore the previous value it 109 // when it goes out of scope. 110 //------------------------------------------------------------------ 111 class ScopedPThreadCancelDisabler 112 { 113 public: 114 ScopedPThreadCancelDisabler() 115 { 116 // Disable the ability for this thread to be cancelled 117 int err = ::pthread_setcancelstate (PTHREAD_CANCEL_DISABLE, &m_old_state); 118 if (err != 0) 119 m_old_state = -1; 120 121 } 122 123 ~ScopedPThreadCancelDisabler() 124 { 125 // Restore the ability for this thread to be cancelled to what it 126 // previously was. 127 if (m_old_state != -1) 128 ::pthread_setcancelstate (m_old_state, 0); 129 } 130 private: 131 int m_old_state; // Save the old cancelability state. 132 }; 133 134 static void * 135 MonitorChildProcessThreadFunction (void *arg) 136 { 137 Log *log(lldb_private::GetLogIfAllCategoriesSet (LIBLLDB_LOG_PROCESS)); 138 const char *function = __FUNCTION__; 139 if (log) 140 log->Printf ("%s (arg = %p) thread starting...", function, arg); 141 142 MonitorInfo *info = (MonitorInfo *)arg; 143 144 const Host::MonitorChildProcessCallback callback = info->callback; 145 void * const callback_baton = info->callback_baton; 146 const lldb::pid_t pid = info->pid; 147 const bool monitor_signals = info->monitor_signals; 148 149 delete info; 150 151 int status = -1; 152 #if defined (__FreeBSD__) 153 #define __WALL 0 154 #endif 155 const int options = __WALL; 156 157 while (1) 158 { 159 log = lldb_private::GetLogIfAllCategoriesSet (LIBLLDB_LOG_PROCESS); 160 if (log) 161 log->Printf("%s ::wait_pid (pid = %" PRIu64 ", &status, options = %i)...", function, pid, options); 162 163 // Wait for all child processes 164 ::pthread_testcancel (); 165 // Get signals from all children with same process group of pid 166 const lldb::pid_t wait_pid = ::waitpid (-1*pid, &status, options); 167 ::pthread_testcancel (); 168 169 if (wait_pid == -1) 170 { 171 if (errno == EINTR) 172 continue; 173 else 174 { 175 if (log) 176 log->Printf ("%s (arg = %p) thread exiting because waitpid failed (%s)...", __FUNCTION__, arg, strerror(errno)); 177 break; 178 } 179 } 180 else if (wait_pid > 0) 181 { 182 bool exited = false; 183 int signal = 0; 184 int exit_status = 0; 185 const char *status_cstr = NULL; 186 if (WIFSTOPPED(status)) 187 { 188 signal = WSTOPSIG(status); 189 status_cstr = "STOPPED"; 190 } 191 else if (WIFEXITED(status)) 192 { 193 exit_status = WEXITSTATUS(status); 194 status_cstr = "EXITED"; 195 exited = true; 196 } 197 else if (WIFSIGNALED(status)) 198 { 199 signal = WTERMSIG(status); 200 status_cstr = "SIGNALED"; 201 if (wait_pid == pid) { 202 exited = true; 203 exit_status = -1; 204 } 205 } 206 else 207 { 208 status_cstr = "(\?\?\?)"; 209 } 210 211 // Scope for pthread_cancel_disabler 212 { 213 ScopedPThreadCancelDisabler pthread_cancel_disabler; 214 215 log = lldb_private::GetLogIfAllCategoriesSet (LIBLLDB_LOG_PROCESS); 216 if (log) 217 log->Printf ("%s ::waitpid (pid = %" PRIu64 ", &status, options = %i) => pid = %" PRIu64 ", status = 0x%8.8x (%s), signal = %i, exit_state = %i", 218 function, 219 wait_pid, 220 options, 221 pid, 222 status, 223 status_cstr, 224 signal, 225 exit_status); 226 227 if (exited || (signal != 0 && monitor_signals)) 228 { 229 bool callback_return = false; 230 if (callback) 231 callback_return = callback (callback_baton, wait_pid, exited, signal, exit_status); 232 233 // If our process exited, then this thread should exit 234 if (exited && wait_pid == pid) 235 { 236 if (log) 237 log->Printf ("%s (arg = %p) thread exiting because pid received exit signal...", __FUNCTION__, arg); 238 break; 239 } 240 // If the callback returns true, it means this process should 241 // exit 242 if (callback_return) 243 { 244 if (log) 245 log->Printf ("%s (arg = %p) thread exiting because callback returned true...", __FUNCTION__, arg); 246 break; 247 } 248 } 249 } 250 } 251 } 252 253 log = lldb_private::GetLogIfAllCategoriesSet (LIBLLDB_LOG_PROCESS); 254 if (log) 255 log->Printf ("%s (arg = %p) thread exiting...", __FUNCTION__, arg); 256 257 return NULL; 258 } 259 260 261 void 262 Host::SystemLog (SystemLogType type, const char *format, va_list args) 263 { 264 vfprintf (stderr, format, args); 265 } 266 267 #endif // #if !defined (__APPLE__) 268 269 void 270 Host::SystemLog (SystemLogType type, const char *format, ...) 271 { 272 va_list args; 273 va_start (args, format); 274 SystemLog (type, format, args); 275 va_end (args); 276 } 277 278 size_t 279 Host::GetPageSize() 280 { 281 return ::getpagesize(); 282 } 283 284 const ArchSpec & 285 Host::GetArchitecture (SystemDefaultArchitecture arch_kind) 286 { 287 static bool g_supports_32 = false; 288 static bool g_supports_64 = false; 289 static ArchSpec g_host_arch_32; 290 static ArchSpec g_host_arch_64; 291 292 #if defined (__APPLE__) 293 294 // Apple is different in that it can support both 32 and 64 bit executables 295 // in the same operating system running concurrently. Here we detect the 296 // correct host architectures for both 32 and 64 bit including if 64 bit 297 // executables are supported on the system. 298 299 if (g_supports_32 == false && g_supports_64 == false) 300 { 301 // All apple systems support 32 bit execution. 302 g_supports_32 = true; 303 uint32_t cputype, cpusubtype; 304 uint32_t is_64_bit_capable = false; 305 size_t len = sizeof(cputype); 306 ArchSpec host_arch; 307 // These will tell us about the kernel architecture, which even on a 64 308 // bit machine can be 32 bit... 309 if (::sysctlbyname("hw.cputype", &cputype, &len, NULL, 0) == 0) 310 { 311 len = sizeof (cpusubtype); 312 if (::sysctlbyname("hw.cpusubtype", &cpusubtype, &len, NULL, 0) != 0) 313 cpusubtype = CPU_TYPE_ANY; 314 315 len = sizeof (is_64_bit_capable); 316 if (::sysctlbyname("hw.cpu64bit_capable", &is_64_bit_capable, &len, NULL, 0) == 0) 317 { 318 if (is_64_bit_capable) 319 g_supports_64 = true; 320 } 321 322 if (is_64_bit_capable) 323 { 324 #if defined (__i386__) || defined (__x86_64__) 325 if (cpusubtype == CPU_SUBTYPE_486) 326 cpusubtype = CPU_SUBTYPE_I386_ALL; 327 #endif 328 if (cputype & CPU_ARCH_ABI64) 329 { 330 // We have a 64 bit kernel on a 64 bit system 331 g_host_arch_32.SetArchitecture (eArchTypeMachO, ~(CPU_ARCH_MASK) & cputype, cpusubtype); 332 g_host_arch_64.SetArchitecture (eArchTypeMachO, cputype, cpusubtype); 333 } 334 else 335 { 336 // We have a 32 bit kernel on a 64 bit system 337 g_host_arch_32.SetArchitecture (eArchTypeMachO, cputype, cpusubtype); 338 cputype |= CPU_ARCH_ABI64; 339 g_host_arch_64.SetArchitecture (eArchTypeMachO, cputype, cpusubtype); 340 } 341 } 342 else 343 { 344 g_host_arch_32.SetArchitecture (eArchTypeMachO, cputype, cpusubtype); 345 g_host_arch_64.Clear(); 346 } 347 } 348 } 349 350 #else // #if defined (__APPLE__) 351 352 if (g_supports_32 == false && g_supports_64 == false) 353 { 354 llvm::Triple triple(llvm::sys::getDefaultTargetTriple()); 355 356 g_host_arch_32.Clear(); 357 g_host_arch_64.Clear(); 358 359 // If the OS is Linux, "unknown" in the vendor slot isn't what we want 360 // for the default triple. It's probably an artifact of config.guess. 361 if (triple.getOS() == llvm::Triple::Linux && triple.getVendor() == llvm::Triple::UnknownVendor) 362 triple.setVendorName(""); 363 364 switch (triple.getArch()) 365 { 366 default: 367 g_host_arch_32.SetTriple(triple); 368 g_supports_32 = true; 369 break; 370 371 case llvm::Triple::x86_64: 372 g_host_arch_64.SetTriple(triple); 373 g_supports_64 = true; 374 g_host_arch_32.SetTriple(triple.get32BitArchVariant()); 375 g_supports_32 = true; 376 break; 377 378 case llvm::Triple::sparcv9: 379 case llvm::Triple::ppc64: 380 g_host_arch_64.SetTriple(triple); 381 g_supports_64 = true; 382 break; 383 } 384 385 g_supports_32 = g_host_arch_32.IsValid(); 386 g_supports_64 = g_host_arch_64.IsValid(); 387 } 388 389 #endif // #else for #if defined (__APPLE__) 390 391 if (arch_kind == eSystemDefaultArchitecture32) 392 return g_host_arch_32; 393 else if (arch_kind == eSystemDefaultArchitecture64) 394 return g_host_arch_64; 395 396 if (g_supports_64) 397 return g_host_arch_64; 398 399 return g_host_arch_32; 400 } 401 402 const ConstString & 403 Host::GetVendorString() 404 { 405 static ConstString g_vendor; 406 if (!g_vendor) 407 { 408 const ArchSpec &host_arch = GetArchitecture (eSystemDefaultArchitecture); 409 const llvm::StringRef &str_ref = host_arch.GetTriple().getVendorName(); 410 g_vendor.SetCStringWithLength(str_ref.data(), str_ref.size()); 411 } 412 return g_vendor; 413 } 414 415 const ConstString & 416 Host::GetOSString() 417 { 418 static ConstString g_os_string; 419 if (!g_os_string) 420 { 421 const ArchSpec &host_arch = GetArchitecture (eSystemDefaultArchitecture); 422 const llvm::StringRef &str_ref = host_arch.GetTriple().getOSName(); 423 g_os_string.SetCStringWithLength(str_ref.data(), str_ref.size()); 424 } 425 return g_os_string; 426 } 427 428 const ConstString & 429 Host::GetTargetTriple() 430 { 431 static ConstString g_host_triple; 432 if (!(g_host_triple)) 433 { 434 const ArchSpec &host_arch = GetArchitecture (eSystemDefaultArchitecture); 435 g_host_triple.SetCString(host_arch.GetTriple().getTriple().c_str()); 436 } 437 return g_host_triple; 438 } 439 440 lldb::pid_t 441 Host::GetCurrentProcessID() 442 { 443 return ::getpid(); 444 } 445 446 lldb::tid_t 447 Host::GetCurrentThreadID() 448 { 449 #if defined (__APPLE__) 450 // Calling "mach_port_deallocate()" bumps the reference count on the thread 451 // port, so we need to deallocate it. mach_task_self() doesn't bump the ref 452 // count. 453 thread_port_t thread_self = mach_thread_self(); 454 mach_port_deallocate(mach_task_self(), thread_self); 455 return thread_self; 456 #elif defined(__FreeBSD__) 457 return lldb::tid_t(pthread_getthreadid_np()); 458 #else 459 return lldb::tid_t(pthread_self()); 460 #endif 461 } 462 463 lldb::thread_t 464 Host::GetCurrentThread () 465 { 466 return lldb::thread_t(pthread_self()); 467 } 468 469 const char * 470 Host::GetSignalAsCString (int signo) 471 { 472 switch (signo) 473 { 474 case SIGHUP: return "SIGHUP"; // 1 hangup 475 case SIGINT: return "SIGINT"; // 2 interrupt 476 case SIGQUIT: return "SIGQUIT"; // 3 quit 477 case SIGILL: return "SIGILL"; // 4 illegal instruction (not reset when caught) 478 case SIGTRAP: return "SIGTRAP"; // 5 trace trap (not reset when caught) 479 case SIGABRT: return "SIGABRT"; // 6 abort() 480 #if (defined(_POSIX_C_SOURCE) && !defined(_DARWIN_C_SOURCE)) 481 case SIGPOLL: return "SIGPOLL"; // 7 pollable event ([XSR] generated, not supported) 482 #endif 483 #if !defined(_POSIX_C_SOURCE) 484 case SIGEMT: return "SIGEMT"; // 7 EMT instruction 485 #endif 486 case SIGFPE: return "SIGFPE"; // 8 floating point exception 487 case SIGKILL: return "SIGKILL"; // 9 kill (cannot be caught or ignored) 488 case SIGBUS: return "SIGBUS"; // 10 bus error 489 case SIGSEGV: return "SIGSEGV"; // 11 segmentation violation 490 case SIGSYS: return "SIGSYS"; // 12 bad argument to system call 491 case SIGPIPE: return "SIGPIPE"; // 13 write on a pipe with no one to read it 492 case SIGALRM: return "SIGALRM"; // 14 alarm clock 493 case SIGTERM: return "SIGTERM"; // 15 software termination signal from kill 494 case SIGURG: return "SIGURG"; // 16 urgent condition on IO channel 495 case SIGSTOP: return "SIGSTOP"; // 17 sendable stop signal not from tty 496 case SIGTSTP: return "SIGTSTP"; // 18 stop signal from tty 497 case SIGCONT: return "SIGCONT"; // 19 continue a stopped process 498 case SIGCHLD: return "SIGCHLD"; // 20 to parent on child stop or exit 499 case SIGTTIN: return "SIGTTIN"; // 21 to readers pgrp upon background tty read 500 case SIGTTOU: return "SIGTTOU"; // 22 like TTIN for output if (tp->t_local<OSTOP) 501 #if !defined(_POSIX_C_SOURCE) 502 case SIGIO: return "SIGIO"; // 23 input/output possible signal 503 #endif 504 case SIGXCPU: return "SIGXCPU"; // 24 exceeded CPU time limit 505 case SIGXFSZ: return "SIGXFSZ"; // 25 exceeded file size limit 506 case SIGVTALRM: return "SIGVTALRM"; // 26 virtual time alarm 507 case SIGPROF: return "SIGPROF"; // 27 profiling time alarm 508 #if !defined(_POSIX_C_SOURCE) 509 case SIGWINCH: return "SIGWINCH"; // 28 window size changes 510 case SIGINFO: return "SIGINFO"; // 29 information request 511 #endif 512 case SIGUSR1: return "SIGUSR1"; // 30 user defined signal 1 513 case SIGUSR2: return "SIGUSR2"; // 31 user defined signal 2 514 default: 515 break; 516 } 517 return NULL; 518 } 519 520 void 521 Host::WillTerminate () 522 { 523 } 524 525 #if !defined (__APPLE__) && !defined (__FreeBSD__) && !defined (__linux__) // see macosx/Host.mm 526 527 void 528 Host::ThreadCreated (const char *thread_name) 529 { 530 } 531 532 void 533 Host::Backtrace (Stream &strm, uint32_t max_frames) 534 { 535 // TODO: Is there a way to backtrace the current process on linux? Other systems? 536 } 537 538 size_t 539 Host::GetEnvironment (StringList &env) 540 { 541 // TODO: Is there a way to the host environment for this process on linux? Other systems? 542 return 0; 543 } 544 545 #endif // #if !defined (__APPLE__) && !defined (__FreeBSD__) && !defined (__linux__) 546 547 struct HostThreadCreateInfo 548 { 549 std::string thread_name; 550 thread_func_t thread_fptr; 551 thread_arg_t thread_arg; 552 553 HostThreadCreateInfo (const char *name, thread_func_t fptr, thread_arg_t arg) : 554 thread_name (name ? name : ""), 555 thread_fptr (fptr), 556 thread_arg (arg) 557 { 558 } 559 }; 560 561 static thread_result_t 562 ThreadCreateTrampoline (thread_arg_t arg) 563 { 564 HostThreadCreateInfo *info = (HostThreadCreateInfo *)arg; 565 Host::ThreadCreated (info->thread_name.c_str()); 566 thread_func_t thread_fptr = info->thread_fptr; 567 thread_arg_t thread_arg = info->thread_arg; 568 569 Log *log(lldb_private::GetLogIfAllCategoriesSet (LIBLLDB_LOG_THREAD)); 570 if (log) 571 log->Printf("thread created"); 572 573 delete info; 574 return thread_fptr (thread_arg); 575 } 576 577 lldb::thread_t 578 Host::ThreadCreate 579 ( 580 const char *thread_name, 581 thread_func_t thread_fptr, 582 thread_arg_t thread_arg, 583 Error *error 584 ) 585 { 586 lldb::thread_t thread = LLDB_INVALID_HOST_THREAD; 587 588 // Host::ThreadCreateTrampoline will delete this pointer for us. 589 HostThreadCreateInfo *info_ptr = new HostThreadCreateInfo (thread_name, thread_fptr, thread_arg); 590 591 int err = ::pthread_create (&thread, NULL, ThreadCreateTrampoline, info_ptr); 592 if (err == 0) 593 { 594 if (error) 595 error->Clear(); 596 return thread; 597 } 598 599 if (error) 600 error->SetError (err, eErrorTypePOSIX); 601 602 return LLDB_INVALID_HOST_THREAD; 603 } 604 605 bool 606 Host::ThreadCancel (lldb::thread_t thread, Error *error) 607 { 608 int err = ::pthread_cancel (thread); 609 if (error) 610 error->SetError(err, eErrorTypePOSIX); 611 return err == 0; 612 } 613 614 bool 615 Host::ThreadDetach (lldb::thread_t thread, Error *error) 616 { 617 int err = ::pthread_detach (thread); 618 if (error) 619 error->SetError(err, eErrorTypePOSIX); 620 return err == 0; 621 } 622 623 bool 624 Host::ThreadJoin (lldb::thread_t thread, thread_result_t *thread_result_ptr, Error *error) 625 { 626 int err = ::pthread_join (thread, thread_result_ptr); 627 if (error) 628 error->SetError(err, eErrorTypePOSIX); 629 return err == 0; 630 } 631 632 633 std::string 634 Host::GetThreadName (lldb::pid_t pid, lldb::tid_t tid) 635 { 636 std::string thread_name; 637 #if defined(__APPLE__) && MAC_OS_X_VERSION_MAX_ALLOWED > MAC_OS_X_VERSION_10_5 638 // We currently can only get the name of a thread in the current process. 639 if (pid == Host::GetCurrentProcessID()) 640 { 641 char pthread_name[1024]; 642 if (::pthread_getname_np (::pthread_from_mach_thread_np (tid), pthread_name, sizeof(pthread_name)) == 0) 643 { 644 if (pthread_name[0]) 645 { 646 thread_name = pthread_name; 647 } 648 } 649 else 650 { 651 dispatch_queue_t current_queue = ::dispatch_get_current_queue (); 652 if (current_queue != NULL) 653 { 654 const char *queue_name = dispatch_queue_get_label (current_queue); 655 if (queue_name && queue_name[0]) 656 { 657 thread_name = queue_name; 658 } 659 } 660 } 661 } 662 #endif 663 return thread_name; 664 } 665 666 bool 667 Host::SetThreadName (lldb::pid_t pid, lldb::tid_t tid, const char *name) 668 { 669 #if defined(__APPLE__) && MAC_OS_X_VERSION_MAX_ALLOWED > MAC_OS_X_VERSION_10_5 670 lldb::pid_t curr_pid = Host::GetCurrentProcessID(); 671 lldb::tid_t curr_tid = Host::GetCurrentThreadID(); 672 if (pid == LLDB_INVALID_PROCESS_ID) 673 pid = curr_pid; 674 675 if (tid == LLDB_INVALID_THREAD_ID) 676 tid = curr_tid; 677 678 // Set the pthread name if possible 679 if (pid == curr_pid && tid == curr_tid) 680 { 681 if (::pthread_setname_np (name) == 0) 682 return true; 683 } 684 return false; 685 #elif defined (__linux__) 686 void *fn = dlsym (RTLD_DEFAULT, "pthread_setname_np"); 687 if (fn) 688 { 689 int (*pthread_setname_np_func)(pthread_t thread, const char *name); 690 *reinterpret_cast<void **> (&pthread_setname_np_func) = fn; 691 692 lldb::pid_t curr_pid = Host::GetCurrentProcessID(); 693 lldb::tid_t curr_tid = Host::GetCurrentThreadID(); 694 695 if (pid == LLDB_INVALID_PROCESS_ID) 696 pid = curr_pid; 697 698 if (tid == LLDB_INVALID_THREAD_ID) 699 tid = curr_tid; 700 701 if (pid == curr_pid) 702 { 703 if (pthread_setname_np_func (tid, name) == 0) 704 return true; 705 } 706 } 707 return false; 708 #else 709 return false; 710 #endif 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 static ConstString g_lldb_python_dir; 1001 if (!g_lldb_python_dir) 1002 { 1003 FileSpec lldb_file_spec; 1004 if (GetLLDBPath (ePathTypeLLDBShlibDir, lldb_file_spec)) 1005 { 1006 char raw_path[PATH_MAX]; 1007 char resolved_path[PATH_MAX]; 1008 lldb_file_spec.GetPath(raw_path, sizeof(raw_path)); 1009 1010 #if defined (__APPLE__) 1011 char *framework_pos = ::strstr (raw_path, "LLDB.framework"); 1012 if (framework_pos) 1013 { 1014 framework_pos += strlen("LLDB.framework"); 1015 ::strncpy (framework_pos, "/Resources/Python", PATH_MAX - (framework_pos - raw_path)); 1016 } 1017 #else 1018 llvm::Twine python_version_dir; 1019 python_version_dir = "/python" 1020 + llvm::Twine(PY_MAJOR_VERSION) 1021 + "." 1022 + llvm::Twine(PY_MINOR_VERSION) 1023 + "/site-packages"; 1024 1025 // We may get our string truncated. Should we protect 1026 // this with an assert? 1027 1028 ::strncat(raw_path, python_version_dir.str().c_str(), 1029 sizeof(raw_path) - strlen(raw_path) - 1); 1030 1031 #endif 1032 FileSpec::Resolve (raw_path, resolved_path, sizeof(resolved_path)); 1033 g_lldb_python_dir.SetCString(resolved_path); 1034 } 1035 } 1036 file_spec.GetDirectory() = g_lldb_python_dir; 1037 return file_spec.GetDirectory(); 1038 } 1039 break; 1040 1041 case ePathTypeLLDBSystemPlugins: // System plug-ins directory 1042 { 1043 #if defined (__APPLE__) 1044 static ConstString g_lldb_system_plugin_dir; 1045 static bool g_lldb_system_plugin_dir_located = false; 1046 if (!g_lldb_system_plugin_dir_located) 1047 { 1048 g_lldb_system_plugin_dir_located = true; 1049 FileSpec lldb_file_spec; 1050 if (GetLLDBPath (ePathTypeLLDBShlibDir, lldb_file_spec)) 1051 { 1052 char raw_path[PATH_MAX]; 1053 char resolved_path[PATH_MAX]; 1054 lldb_file_spec.GetPath(raw_path, sizeof(raw_path)); 1055 1056 char *framework_pos = ::strstr (raw_path, "LLDB.framework"); 1057 if (framework_pos) 1058 { 1059 framework_pos += strlen("LLDB.framework"); 1060 ::strncpy (framework_pos, "/Resources/PlugIns", PATH_MAX - (framework_pos - raw_path)); 1061 FileSpec::Resolve (raw_path, resolved_path, sizeof(resolved_path)); 1062 g_lldb_system_plugin_dir.SetCString(resolved_path); 1063 } 1064 return false; 1065 } 1066 } 1067 1068 if (g_lldb_system_plugin_dir) 1069 { 1070 file_spec.GetDirectory() = g_lldb_system_plugin_dir; 1071 return true; 1072 } 1073 #endif 1074 // TODO: where would system LLDB plug-ins be located on linux? Other systems? 1075 return false; 1076 } 1077 break; 1078 1079 case ePathTypeLLDBUserPlugins: // User plug-ins directory 1080 { 1081 #if defined (__APPLE__) 1082 static ConstString g_lldb_user_plugin_dir; 1083 if (!g_lldb_user_plugin_dir) 1084 { 1085 char user_plugin_path[PATH_MAX]; 1086 if (FileSpec::Resolve ("~/Library/Application Support/LLDB/PlugIns", 1087 user_plugin_path, 1088 sizeof(user_plugin_path))) 1089 { 1090 g_lldb_user_plugin_dir.SetCString(user_plugin_path); 1091 } 1092 } 1093 file_spec.GetDirectory() = g_lldb_user_plugin_dir; 1094 return file_spec.GetDirectory(); 1095 #endif 1096 // TODO: where would user LLDB plug-ins be located on linux? Other systems? 1097 return false; 1098 } 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__) && !defined(__linux__) 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 // #if !defined (__APPLE__) && !defined(__linux__) 1229 1230 #if !defined (__APPLE__) && !defined (__FreeBSD__) && !defined(__linux__) 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 #if !defined(__linux__) 1240 bool 1241 Host::FindProcessThreads (const lldb::pid_t pid, TidMap &tids_to_attach) 1242 { 1243 return false; 1244 } 1245 #endif 1246 1247 lldb::TargetSP 1248 Host::GetDummyTarget (lldb_private::Debugger &debugger) 1249 { 1250 static TargetSP g_dummy_target_sp; 1251 1252 // FIXME: Maybe the dummy target should be per-Debugger 1253 if (!g_dummy_target_sp || !g_dummy_target_sp->IsValid()) 1254 { 1255 ArchSpec arch(Target::GetDefaultArchitecture()); 1256 if (!arch.IsValid()) 1257 arch = Host::GetArchitecture (); 1258 Error err = debugger.GetTargetList().CreateTarget(debugger, 1259 NULL, 1260 arch.GetTriple().getTriple().c_str(), 1261 false, 1262 NULL, 1263 g_dummy_target_sp); 1264 } 1265 1266 return g_dummy_target_sp; 1267 } 1268 1269 struct ShellInfo 1270 { 1271 ShellInfo () : 1272 process_reaped (false), 1273 can_delete (false), 1274 pid (LLDB_INVALID_PROCESS_ID), 1275 signo(-1), 1276 status(-1) 1277 { 1278 } 1279 1280 lldb_private::Predicate<bool> process_reaped; 1281 lldb_private::Predicate<bool> can_delete; 1282 lldb::pid_t pid; 1283 int signo; 1284 int status; 1285 }; 1286 1287 static bool 1288 MonitorShellCommand (void *callback_baton, 1289 lldb::pid_t pid, 1290 bool exited, // True if the process did exit 1291 int signo, // Zero for no signal 1292 int status) // Exit value of process if signal is zero 1293 { 1294 ShellInfo *shell_info = (ShellInfo *)callback_baton; 1295 shell_info->pid = pid; 1296 shell_info->signo = signo; 1297 shell_info->status = status; 1298 // Let the thread running Host::RunShellCommand() know that the process 1299 // exited and that ShellInfo has been filled in by broadcasting to it 1300 shell_info->process_reaped.SetValue(1, eBroadcastAlways); 1301 // Now wait for a handshake back from that thread running Host::RunShellCommand 1302 // so we know that we can delete shell_info_ptr 1303 shell_info->can_delete.WaitForValueEqualTo(true); 1304 // Sleep a bit to allow the shell_info->can_delete.SetValue() to complete... 1305 usleep(1000); 1306 // Now delete the shell info that was passed into this function 1307 delete shell_info; 1308 return true; 1309 } 1310 1311 Error 1312 Host::RunShellCommand (const char *command, 1313 const char *working_dir, 1314 int *status_ptr, 1315 int *signo_ptr, 1316 std::string *command_output_ptr, 1317 uint32_t timeout_sec, 1318 const char *shell) 1319 { 1320 Error error; 1321 ProcessLaunchInfo launch_info; 1322 if (shell && shell[0]) 1323 { 1324 // Run the command in a shell 1325 launch_info.SetShell(shell); 1326 launch_info.GetArguments().AppendArgument(command); 1327 const bool localhost = true; 1328 const bool will_debug = false; 1329 const bool first_arg_is_full_shell_command = true; 1330 launch_info.ConvertArgumentsForLaunchingInShell (error, 1331 localhost, 1332 will_debug, 1333 first_arg_is_full_shell_command); 1334 } 1335 else 1336 { 1337 // No shell, just run it 1338 Args args (command); 1339 const bool first_arg_is_executable = true; 1340 launch_info.SetArguments(args, first_arg_is_executable); 1341 } 1342 1343 if (working_dir) 1344 launch_info.SetWorkingDirectory(working_dir); 1345 char output_file_path_buffer[L_tmpnam]; 1346 const char *output_file_path = NULL; 1347 if (command_output_ptr) 1348 { 1349 // Create a temporary file to get the stdout/stderr and redirect the 1350 // output of the command into this file. We will later read this file 1351 // if all goes well and fill the data into "command_output_ptr" 1352 output_file_path = ::tmpnam(output_file_path_buffer); 1353 launch_info.AppendSuppressFileAction (STDIN_FILENO, true, false); 1354 launch_info.AppendOpenFileAction(STDOUT_FILENO, output_file_path, false, true); 1355 launch_info.AppendDuplicateFileAction(STDOUT_FILENO, STDERR_FILENO); 1356 } 1357 else 1358 { 1359 launch_info.AppendSuppressFileAction (STDIN_FILENO, true, false); 1360 launch_info.AppendSuppressFileAction (STDOUT_FILENO, false, true); 1361 launch_info.AppendSuppressFileAction (STDERR_FILENO, false, true); 1362 } 1363 1364 // The process monitor callback will delete the 'shell_info_ptr' below... 1365 std::unique_ptr<ShellInfo> shell_info_ap (new ShellInfo()); 1366 1367 const bool monitor_signals = false; 1368 launch_info.SetMonitorProcessCallback(MonitorShellCommand, shell_info_ap.get(), monitor_signals); 1369 1370 error = LaunchProcess (launch_info); 1371 const lldb::pid_t pid = launch_info.GetProcessID(); 1372 if (pid != LLDB_INVALID_PROCESS_ID) 1373 { 1374 // The process successfully launched, so we can defer ownership of 1375 // "shell_info" to the MonitorShellCommand callback function that will 1376 // get called when the process dies. We release the unique pointer as it 1377 // doesn't need to delete the ShellInfo anymore. 1378 ShellInfo *shell_info = shell_info_ap.release(); 1379 TimeValue timeout_time(TimeValue::Now()); 1380 timeout_time.OffsetWithSeconds(timeout_sec); 1381 bool timed_out = false; 1382 shell_info->process_reaped.WaitForValueEqualTo(true, &timeout_time, &timed_out); 1383 if (timed_out) 1384 { 1385 error.SetErrorString("timed out waiting for shell command to complete"); 1386 1387 // Kill the process since it didn't complete withint the timeout specified 1388 ::kill (pid, SIGKILL); 1389 // Wait for the monitor callback to get the message 1390 timeout_time = TimeValue::Now(); 1391 timeout_time.OffsetWithSeconds(1); 1392 timed_out = false; 1393 shell_info->process_reaped.WaitForValueEqualTo(true, &timeout_time, &timed_out); 1394 } 1395 else 1396 { 1397 if (status_ptr) 1398 *status_ptr = shell_info->status; 1399 1400 if (signo_ptr) 1401 *signo_ptr = shell_info->signo; 1402 1403 if (command_output_ptr) 1404 { 1405 command_output_ptr->clear(); 1406 FileSpec file_spec(output_file_path, File::eOpenOptionRead); 1407 uint64_t file_size = file_spec.GetByteSize(); 1408 if (file_size > 0) 1409 { 1410 if (file_size > command_output_ptr->max_size()) 1411 { 1412 error.SetErrorStringWithFormat("shell command output is too large to fit into a std::string"); 1413 } 1414 else 1415 { 1416 command_output_ptr->resize(file_size); 1417 file_spec.ReadFileContents(0, &((*command_output_ptr)[0]), command_output_ptr->size(), &error); 1418 } 1419 } 1420 } 1421 } 1422 shell_info->can_delete.SetValue(true, eBroadcastAlways); 1423 } 1424 else 1425 { 1426 error.SetErrorString("failed to get process ID"); 1427 } 1428 1429 if (output_file_path) 1430 ::unlink (output_file_path); 1431 // Handshake with the monitor thread, or just let it know in advance that 1432 // it can delete "shell_info" in case we timed out and were not able to kill 1433 // the process... 1434 return error; 1435 } 1436 1437 1438 uint32_t 1439 Host::GetNumberCPUS () 1440 { 1441 static uint32_t g_num_cores = UINT32_MAX; 1442 if (g_num_cores == UINT32_MAX) 1443 { 1444 #if defined(__APPLE__) or defined (__linux__) or defined (__FreeBSD__) 1445 1446 g_num_cores = ::sysconf(_SC_NPROCESSORS_ONLN); 1447 1448 #elif defined(_WIN32) || defined(__WIN32__) || defined(__CYGWIN__) 1449 1450 // Header file for this might need to be included at the top of this file 1451 SYSTEM_INFO system_info; 1452 ::GetSystemInfo (&system_info); 1453 g_num_cores = system_info.dwNumberOfProcessors; 1454 1455 #else 1456 1457 // Assume POSIX support if a host specific case has not been supplied above 1458 g_num_cores = 0; 1459 int num_cores = 0; 1460 size_t num_cores_len = sizeof(num_cores); 1461 int mib[] = { CTL_HW, HW_AVAILCPU }; 1462 1463 /* get the number of CPUs from the system */ 1464 if (sysctl(mib, sizeof(mib)/sizeof(int), &num_cores, &num_cores_len, NULL, 0) == 0 && (num_cores > 0)) 1465 { 1466 g_num_cores = num_cores; 1467 } 1468 else 1469 { 1470 mib[1] = HW_NCPU; 1471 num_cores_len = sizeof(num_cores); 1472 if (sysctl(mib, sizeof(mib)/sizeof(int), &num_cores, &num_cores_len, NULL, 0) == 0 && (num_cores > 0)) 1473 { 1474 if (num_cores > 0) 1475 g_num_cores = num_cores; 1476 } 1477 } 1478 #endif 1479 } 1480 return g_num_cores; 1481 } 1482 1483 1484 1485 #if !defined (__APPLE__) 1486 bool 1487 Host::OpenFileInExternalEditor (const FileSpec &file_spec, uint32_t line_no) 1488 { 1489 return false; 1490 } 1491 1492 void 1493 Host::SetCrashDescriptionWithFormat (const char *format, ...) 1494 { 1495 } 1496 1497 void 1498 Host::SetCrashDescription (const char *description) 1499 { 1500 } 1501 1502 lldb::pid_t 1503 LaunchApplication (const FileSpec &app_file_spec) 1504 { 1505 return LLDB_INVALID_PROCESS_ID; 1506 } 1507 1508 #endif 1509