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 <errno.h> 14 #include <limits.h> 15 #include <sys/types.h> 16 #ifdef _WIN32 17 #include "lldb/Host/windows/windows.h" 18 #include <winsock2.h> 19 #include <WS2tcpip.h> 20 #else 21 #include <unistd.h> 22 #include <dlfcn.h> 23 #include <grp.h> 24 #include <netdb.h> 25 #include <pwd.h> 26 #include <sys/stat.h> 27 #endif 28 29 #if !defined (__GNU__) && !defined (_WIN32) 30 // Does not exist under GNU/HURD or Windows 31 #include <sys/sysctl.h> 32 #endif 33 34 #if defined (__APPLE__) 35 #include <mach/mach_port.h> 36 #include <mach/mach_init.h> 37 #include <mach-o/dyld.h> 38 #include <AvailabilityMacros.h> 39 #endif 40 41 #if defined (__linux__) || defined (__FreeBSD__) || defined (__FreeBSD_kernel__) || defined (__APPLE__) 42 #include <spawn.h> 43 #include <sys/wait.h> 44 #include <sys/syscall.h> 45 #endif 46 47 #if defined (__FreeBSD__) 48 #include <pthread_np.h> 49 #endif 50 51 #include "lldb/Host/Host.h" 52 #include "lldb/Core/ArchSpec.h" 53 #include "lldb/Core/ConstString.h" 54 #include "lldb/Core/Debugger.h" 55 #include "lldb/Core/Error.h" 56 #include "lldb/Core/Log.h" 57 #include "lldb/Core/Module.h" 58 #include "lldb/Core/StreamString.h" 59 #include "lldb/Core/ThreadSafeSTLMap.h" 60 #include "lldb/Host/Config.h" 61 #include "lldb/Host/Endian.h" 62 #include "lldb/Host/FileSpec.h" 63 #include "lldb/Host/Mutex.h" 64 #include "lldb/Target/Process.h" 65 #include "lldb/Target/TargetList.h" 66 #include "lldb/Utility/CleanUp.h" 67 68 #include "llvm/ADT/SmallString.h" 69 #include "llvm/Support/Host.h" 70 #include "llvm/Support/raw_ostream.h" 71 72 #if defined (__APPLE__) 73 #ifndef _POSIX_SPAWN_DISABLE_ASLR 74 #define _POSIX_SPAWN_DISABLE_ASLR 0x0100 75 #endif 76 77 extern "C" 78 { 79 int __pthread_chdir(const char *path); 80 int __pthread_fchdir (int fildes); 81 } 82 83 #endif 84 85 using namespace lldb; 86 using namespace lldb_private; 87 88 89 #if !defined (__APPLE__) && !defined (_WIN32) 90 struct MonitorInfo 91 { 92 lldb::pid_t pid; // The process ID to monitor 93 Host::MonitorChildProcessCallback callback; // The callback function to call when "pid" exits or signals 94 void *callback_baton; // The callback baton for the callback function 95 bool monitor_signals; // If true, call the callback when "pid" gets signaled. 96 }; 97 98 static thread_result_t 99 MonitorChildProcessThreadFunction (void *arg); 100 101 lldb::thread_t 102 Host::StartMonitoringChildProcess 103 ( 104 Host::MonitorChildProcessCallback callback, 105 void *callback_baton, 106 lldb::pid_t pid, 107 bool monitor_signals 108 ) 109 { 110 lldb::thread_t thread = LLDB_INVALID_HOST_THREAD; 111 MonitorInfo * info_ptr = new MonitorInfo(); 112 113 info_ptr->pid = pid; 114 info_ptr->callback = callback; 115 info_ptr->callback_baton = callback_baton; 116 info_ptr->monitor_signals = monitor_signals; 117 118 char thread_name[256]; 119 ::snprintf (thread_name, sizeof(thread_name), "<lldb.host.wait4(pid=%" PRIu64 ")>", pid); 120 thread = ThreadCreate (thread_name, 121 MonitorChildProcessThreadFunction, 122 info_ptr, 123 NULL); 124 125 return thread; 126 } 127 128 //------------------------------------------------------------------ 129 // Scoped class that will disable thread canceling when it is 130 // constructed, and exception safely restore the previous value it 131 // when it goes out of scope. 132 //------------------------------------------------------------------ 133 class ScopedPThreadCancelDisabler 134 { 135 public: 136 ScopedPThreadCancelDisabler() 137 { 138 // Disable the ability for this thread to be cancelled 139 int err = ::pthread_setcancelstate (PTHREAD_CANCEL_DISABLE, &m_old_state); 140 if (err != 0) 141 m_old_state = -1; 142 143 } 144 145 ~ScopedPThreadCancelDisabler() 146 { 147 // Restore the ability for this thread to be cancelled to what it 148 // previously was. 149 if (m_old_state != -1) 150 ::pthread_setcancelstate (m_old_state, 0); 151 } 152 private: 153 int m_old_state; // Save the old cancelability state. 154 }; 155 156 static thread_result_t 157 MonitorChildProcessThreadFunction (void *arg) 158 { 159 Log *log(lldb_private::GetLogIfAllCategoriesSet (LIBLLDB_LOG_PROCESS)); 160 const char *function = __FUNCTION__; 161 if (log) 162 log->Printf ("%s (arg = %p) thread starting...", function, arg); 163 164 MonitorInfo *info = (MonitorInfo *)arg; 165 166 const Host::MonitorChildProcessCallback callback = info->callback; 167 void * const callback_baton = info->callback_baton; 168 const bool monitor_signals = info->monitor_signals; 169 170 assert (info->pid <= UINT32_MAX); 171 const ::pid_t pid = monitor_signals ? -1 * info->pid : info->pid; 172 173 delete info; 174 175 int status = -1; 176 #if defined (__FreeBSD__) || defined (__FreeBSD_kernel__) 177 #define __WALL 0 178 #endif 179 const int options = __WALL; 180 181 while (1) 182 { 183 log = lldb_private::GetLogIfAllCategoriesSet (LIBLLDB_LOG_PROCESS); 184 if (log) 185 log->Printf("%s ::wait_pid (pid = %" PRIi32 ", &status, options = %i)...", function, pid, options); 186 187 // Wait for all child processes 188 ::pthread_testcancel (); 189 // Get signals from all children with same process group of pid 190 const ::pid_t wait_pid = ::waitpid (pid, &status, options); 191 ::pthread_testcancel (); 192 193 if (wait_pid == -1) 194 { 195 if (errno == EINTR) 196 continue; 197 else 198 { 199 if (log) 200 log->Printf ("%s (arg = %p) thread exiting because waitpid failed (%s)...", __FUNCTION__, arg, strerror(errno)); 201 break; 202 } 203 } 204 else if (wait_pid > 0) 205 { 206 bool exited = false; 207 int signal = 0; 208 int exit_status = 0; 209 const char *status_cstr = NULL; 210 if (WIFSTOPPED(status)) 211 { 212 signal = WSTOPSIG(status); 213 status_cstr = "STOPPED"; 214 } 215 else if (WIFEXITED(status)) 216 { 217 exit_status = WEXITSTATUS(status); 218 status_cstr = "EXITED"; 219 exited = true; 220 } 221 else if (WIFSIGNALED(status)) 222 { 223 signal = WTERMSIG(status); 224 status_cstr = "SIGNALED"; 225 if (wait_pid == abs(pid)) { 226 exited = true; 227 exit_status = -1; 228 } 229 } 230 else 231 { 232 status_cstr = "(\?\?\?)"; 233 } 234 235 // Scope for pthread_cancel_disabler 236 { 237 ScopedPThreadCancelDisabler pthread_cancel_disabler; 238 239 log = lldb_private::GetLogIfAllCategoriesSet (LIBLLDB_LOG_PROCESS); 240 if (log) 241 log->Printf ("%s ::waitpid (pid = %" PRIi32 ", &status, options = %i) => pid = %" PRIi32 ", status = 0x%8.8x (%s), signal = %i, exit_state = %i", 242 function, 243 wait_pid, 244 options, 245 pid, 246 status, 247 status_cstr, 248 signal, 249 exit_status); 250 251 if (exited || (signal != 0 && monitor_signals)) 252 { 253 bool callback_return = false; 254 if (callback) 255 callback_return = callback (callback_baton, wait_pid, exited, signal, exit_status); 256 257 // If our process exited, then this thread should exit 258 if (exited && wait_pid == abs(pid)) 259 { 260 if (log) 261 log->Printf ("%s (arg = %p) thread exiting because pid received exit signal...", __FUNCTION__, arg); 262 break; 263 } 264 // If the callback returns true, it means this process should 265 // exit 266 if (callback_return) 267 { 268 if (log) 269 log->Printf ("%s (arg = %p) thread exiting because callback returned true...", __FUNCTION__, arg); 270 break; 271 } 272 } 273 } 274 } 275 } 276 277 log = lldb_private::GetLogIfAllCategoriesSet (LIBLLDB_LOG_PROCESS); 278 if (log) 279 log->Printf ("%s (arg = %p) thread exiting...", __FUNCTION__, arg); 280 281 return NULL; 282 } 283 284 #endif // #if !defined (__APPLE__) && !defined (_WIN32) 285 286 #if !defined (__APPLE__) 287 288 void 289 Host::SystemLog (SystemLogType type, const char *format, va_list args) 290 { 291 vfprintf (stderr, format, args); 292 } 293 294 #endif 295 296 void 297 Host::SystemLog (SystemLogType type, const char *format, ...) 298 { 299 va_list args; 300 va_start (args, format); 301 SystemLog (type, format, args); 302 va_end (args); 303 } 304 305 const ArchSpec & 306 Host::GetArchitecture (SystemDefaultArchitecture arch_kind) 307 { 308 static bool g_supports_32 = false; 309 static bool g_supports_64 = false; 310 static ArchSpec g_host_arch_32; 311 static ArchSpec g_host_arch_64; 312 313 #if defined (__APPLE__) 314 315 // Apple is different in that it can support both 32 and 64 bit executables 316 // in the same operating system running concurrently. Here we detect the 317 // correct host architectures for both 32 and 64 bit including if 64 bit 318 // executables are supported on the system. 319 320 if (g_supports_32 == false && g_supports_64 == false) 321 { 322 // All apple systems support 32 bit execution. 323 g_supports_32 = true; 324 uint32_t cputype, cpusubtype; 325 uint32_t is_64_bit_capable = false; 326 size_t len = sizeof(cputype); 327 ArchSpec host_arch; 328 // These will tell us about the kernel architecture, which even on a 64 329 // bit machine can be 32 bit... 330 if (::sysctlbyname("hw.cputype", &cputype, &len, NULL, 0) == 0) 331 { 332 len = sizeof (cpusubtype); 333 if (::sysctlbyname("hw.cpusubtype", &cpusubtype, &len, NULL, 0) != 0) 334 cpusubtype = CPU_TYPE_ANY; 335 336 len = sizeof (is_64_bit_capable); 337 if (::sysctlbyname("hw.cpu64bit_capable", &is_64_bit_capable, &len, NULL, 0) == 0) 338 { 339 if (is_64_bit_capable) 340 g_supports_64 = true; 341 } 342 343 if (is_64_bit_capable) 344 { 345 #if defined (__i386__) || defined (__x86_64__) 346 if (cpusubtype == CPU_SUBTYPE_486) 347 cpusubtype = CPU_SUBTYPE_I386_ALL; 348 #endif 349 if (cputype & CPU_ARCH_ABI64) 350 { 351 // We have a 64 bit kernel on a 64 bit system 352 g_host_arch_32.SetArchitecture (eArchTypeMachO, ~(CPU_ARCH_MASK) & cputype, cpusubtype); 353 g_host_arch_64.SetArchitecture (eArchTypeMachO, cputype, cpusubtype); 354 } 355 else 356 { 357 // We have a 32 bit kernel on a 64 bit system 358 g_host_arch_32.SetArchitecture (eArchTypeMachO, cputype, cpusubtype); 359 cputype |= CPU_ARCH_ABI64; 360 g_host_arch_64.SetArchitecture (eArchTypeMachO, cputype, cpusubtype); 361 } 362 } 363 else 364 { 365 g_host_arch_32.SetArchitecture (eArchTypeMachO, cputype, cpusubtype); 366 g_host_arch_64.Clear(); 367 } 368 } 369 } 370 371 #else // #if defined (__APPLE__) 372 373 if (g_supports_32 == false && g_supports_64 == false) 374 { 375 llvm::Triple triple(llvm::sys::getDefaultTargetTriple()); 376 377 g_host_arch_32.Clear(); 378 g_host_arch_64.Clear(); 379 380 // If the OS is Linux, "unknown" in the vendor slot isn't what we want 381 // for the default triple. It's probably an artifact of config.guess. 382 if (triple.getOS() == llvm::Triple::Linux && triple.getVendor() == llvm::Triple::UnknownVendor) 383 triple.setVendorName (""); 384 385 const char* distribution_id = GetDistributionId ().AsCString(); 386 387 switch (triple.getArch()) 388 { 389 default: 390 g_host_arch_32.SetTriple(triple); 391 g_host_arch_32.SetDistributionId (distribution_id); 392 g_supports_32 = true; 393 break; 394 395 case llvm::Triple::x86_64: 396 g_host_arch_64.SetTriple(triple); 397 g_host_arch_64.SetDistributionId (distribution_id); 398 g_supports_64 = true; 399 g_host_arch_32.SetTriple(triple.get32BitArchVariant()); 400 g_host_arch_32.SetDistributionId (distribution_id); 401 g_supports_32 = true; 402 break; 403 404 case llvm::Triple::sparcv9: 405 case llvm::Triple::ppc64: 406 g_host_arch_64.SetTriple(triple); 407 g_host_arch_64.SetDistributionId (distribution_id); 408 g_supports_64 = true; 409 break; 410 } 411 412 g_supports_32 = g_host_arch_32.IsValid(); 413 g_supports_64 = g_host_arch_64.IsValid(); 414 } 415 416 #endif // #else for #if defined (__APPLE__) 417 418 if (arch_kind == eSystemDefaultArchitecture32) 419 return g_host_arch_32; 420 else if (arch_kind == eSystemDefaultArchitecture64) 421 return g_host_arch_64; 422 423 if (g_supports_64) 424 return g_host_arch_64; 425 426 return g_host_arch_32; 427 } 428 429 const ConstString & 430 Host::GetVendorString() 431 { 432 static ConstString g_vendor; 433 if (!g_vendor) 434 { 435 const ArchSpec &host_arch = GetArchitecture (eSystemDefaultArchitecture); 436 const llvm::StringRef &str_ref = host_arch.GetTriple().getVendorName(); 437 g_vendor.SetCStringWithLength(str_ref.data(), str_ref.size()); 438 } 439 return g_vendor; 440 } 441 442 const ConstString & 443 Host::GetOSString() 444 { 445 static ConstString g_os_string; 446 if (!g_os_string) 447 { 448 const ArchSpec &host_arch = GetArchitecture (eSystemDefaultArchitecture); 449 const llvm::StringRef &str_ref = host_arch.GetTriple().getOSName(); 450 g_os_string.SetCStringWithLength(str_ref.data(), str_ref.size()); 451 } 452 return g_os_string; 453 } 454 455 const ConstString & 456 Host::GetTargetTriple() 457 { 458 static ConstString g_host_triple; 459 if (!(g_host_triple)) 460 { 461 const ArchSpec &host_arch = GetArchitecture (eSystemDefaultArchitecture); 462 g_host_triple.SetCString(host_arch.GetTriple().getTriple().c_str()); 463 } 464 return g_host_triple; 465 } 466 467 // See linux/Host.cpp for Linux-based implementations of this. 468 // Add your platform-specific implementation to the appropriate host file. 469 #if !defined(__linux__) 470 471 const ConstString & 472 Host::GetDistributionId () 473 { 474 static ConstString s_distribution_id; 475 return s_distribution_id; 476 } 477 478 #endif // #if !defined(__linux__) 479 480 lldb::pid_t 481 Host::GetCurrentProcessID() 482 { 483 return ::getpid(); 484 } 485 486 #ifndef _WIN32 487 488 lldb::tid_t 489 Host::GetCurrentThreadID() 490 { 491 #if defined (__APPLE__) 492 // Calling "mach_thread_self()" bumps the reference count on the thread 493 // port, so we need to deallocate it. mach_task_self() doesn't bump the ref 494 // count. 495 thread_port_t thread_self = mach_thread_self(); 496 mach_port_deallocate(mach_task_self(), thread_self); 497 return thread_self; 498 #elif defined(__FreeBSD__) 499 return lldb::tid_t(pthread_getthreadid_np()); 500 #elif defined(__linux__) 501 return lldb::tid_t(syscall(SYS_gettid)); 502 #else 503 return lldb::tid_t(pthread_self()); 504 #endif 505 } 506 507 lldb::thread_t 508 Host::GetCurrentThread () 509 { 510 return lldb::thread_t(pthread_self()); 511 } 512 513 const char * 514 Host::GetSignalAsCString (int signo) 515 { 516 switch (signo) 517 { 518 case SIGHUP: return "SIGHUP"; // 1 hangup 519 case SIGINT: return "SIGINT"; // 2 interrupt 520 case SIGQUIT: return "SIGQUIT"; // 3 quit 521 case SIGILL: return "SIGILL"; // 4 illegal instruction (not reset when caught) 522 case SIGTRAP: return "SIGTRAP"; // 5 trace trap (not reset when caught) 523 case SIGABRT: return "SIGABRT"; // 6 abort() 524 #if defined(SIGPOLL) 525 #if !defined(SIGIO) || (SIGPOLL != SIGIO) 526 // Under some GNU/Linux, SIGPOLL and SIGIO are the same. Causing the build to 527 // fail with 'multiple define cases with same value' 528 case SIGPOLL: return "SIGPOLL"; // 7 pollable event ([XSR] generated, not supported) 529 #endif 530 #endif 531 #if defined(SIGEMT) 532 case SIGEMT: return "SIGEMT"; // 7 EMT instruction 533 #endif 534 case SIGFPE: return "SIGFPE"; // 8 floating point exception 535 case SIGKILL: return "SIGKILL"; // 9 kill (cannot be caught or ignored) 536 case SIGBUS: return "SIGBUS"; // 10 bus error 537 case SIGSEGV: return "SIGSEGV"; // 11 segmentation violation 538 case SIGSYS: return "SIGSYS"; // 12 bad argument to system call 539 case SIGPIPE: return "SIGPIPE"; // 13 write on a pipe with no one to read it 540 case SIGALRM: return "SIGALRM"; // 14 alarm clock 541 case SIGTERM: return "SIGTERM"; // 15 software termination signal from kill 542 case SIGURG: return "SIGURG"; // 16 urgent condition on IO channel 543 case SIGSTOP: return "SIGSTOP"; // 17 sendable stop signal not from tty 544 case SIGTSTP: return "SIGTSTP"; // 18 stop signal from tty 545 case SIGCONT: return "SIGCONT"; // 19 continue a stopped process 546 case SIGCHLD: return "SIGCHLD"; // 20 to parent on child stop or exit 547 case SIGTTIN: return "SIGTTIN"; // 21 to readers pgrp upon background tty read 548 case SIGTTOU: return "SIGTTOU"; // 22 like TTIN for output if (tp->t_local<OSTOP) 549 #if defined(SIGIO) 550 case SIGIO: return "SIGIO"; // 23 input/output possible signal 551 #endif 552 case SIGXCPU: return "SIGXCPU"; // 24 exceeded CPU time limit 553 case SIGXFSZ: return "SIGXFSZ"; // 25 exceeded file size limit 554 case SIGVTALRM: return "SIGVTALRM"; // 26 virtual time alarm 555 case SIGPROF: return "SIGPROF"; // 27 profiling time alarm 556 #if defined(SIGWINCH) 557 case SIGWINCH: return "SIGWINCH"; // 28 window size changes 558 #endif 559 #if defined(SIGINFO) 560 case SIGINFO: return "SIGINFO"; // 29 information request 561 #endif 562 case SIGUSR1: return "SIGUSR1"; // 30 user defined signal 1 563 case SIGUSR2: return "SIGUSR2"; // 31 user defined signal 2 564 default: 565 break; 566 } 567 return NULL; 568 } 569 570 #endif 571 572 void 573 Host::WillTerminate () 574 { 575 } 576 577 #if !defined (__APPLE__) && !defined (__FreeBSD__) && !defined (__FreeBSD_kernel__) && !defined (__linux__) // see macosx/Host.mm 578 579 void 580 Host::ThreadCreated (const char *thread_name) 581 { 582 } 583 584 void 585 Host::Backtrace (Stream &strm, uint32_t max_frames) 586 { 587 // TODO: Is there a way to backtrace the current process on other systems? 588 } 589 590 size_t 591 Host::GetEnvironment (StringList &env) 592 { 593 // TODO: Is there a way to the host environment for this process on other systems? 594 return 0; 595 } 596 597 #endif // #if !defined (__APPLE__) && !defined (__FreeBSD__) && !defined (__FreeBSD_kernel__) && !defined (__linux__) 598 599 struct HostThreadCreateInfo 600 { 601 std::string thread_name; 602 thread_func_t thread_fptr; 603 thread_arg_t thread_arg; 604 605 HostThreadCreateInfo (const char *name, thread_func_t fptr, thread_arg_t arg) : 606 thread_name (name ? name : ""), 607 thread_fptr (fptr), 608 thread_arg (arg) 609 { 610 } 611 }; 612 613 static thread_result_t 614 #ifdef _WIN32 615 __stdcall 616 #endif 617 ThreadCreateTrampoline (thread_arg_t arg) 618 { 619 HostThreadCreateInfo *info = (HostThreadCreateInfo *)arg; 620 Host::ThreadCreated (info->thread_name.c_str()); 621 thread_func_t thread_fptr = info->thread_fptr; 622 thread_arg_t thread_arg = info->thread_arg; 623 624 Log *log(lldb_private::GetLogIfAllCategoriesSet (LIBLLDB_LOG_THREAD)); 625 if (log) 626 log->Printf("thread created"); 627 628 delete info; 629 return thread_fptr (thread_arg); 630 } 631 632 lldb::thread_t 633 Host::ThreadCreate 634 ( 635 const char *thread_name, 636 thread_func_t thread_fptr, 637 thread_arg_t thread_arg, 638 Error *error 639 ) 640 { 641 lldb::thread_t thread = LLDB_INVALID_HOST_THREAD; 642 643 // Host::ThreadCreateTrampoline will delete this pointer for us. 644 HostThreadCreateInfo *info_ptr = new HostThreadCreateInfo (thread_name, thread_fptr, thread_arg); 645 646 #ifdef _WIN32 647 thread = ::_beginthreadex(0, 0, ThreadCreateTrampoline, info_ptr, 0, NULL); 648 int err = thread <= 0 ? GetLastError() : 0; 649 #else 650 int err = ::pthread_create (&thread, NULL, ThreadCreateTrampoline, info_ptr); 651 #endif 652 if (err == 0) 653 { 654 if (error) 655 error->Clear(); 656 return thread; 657 } 658 659 if (error) 660 error->SetError (err, eErrorTypePOSIX); 661 662 return LLDB_INVALID_HOST_THREAD; 663 } 664 665 #ifndef _WIN32 666 667 bool 668 Host::ThreadCancel (lldb::thread_t thread, Error *error) 669 { 670 int err = ::pthread_cancel (thread); 671 if (error) 672 error->SetError(err, eErrorTypePOSIX); 673 return err == 0; 674 } 675 676 bool 677 Host::ThreadDetach (lldb::thread_t thread, Error *error) 678 { 679 int err = ::pthread_detach (thread); 680 if (error) 681 error->SetError(err, eErrorTypePOSIX); 682 return err == 0; 683 } 684 685 bool 686 Host::ThreadJoin (lldb::thread_t thread, thread_result_t *thread_result_ptr, Error *error) 687 { 688 int err = ::pthread_join (thread, thread_result_ptr); 689 if (error) 690 error->SetError(err, eErrorTypePOSIX); 691 return err == 0; 692 } 693 694 lldb::thread_key_t 695 Host::ThreadLocalStorageCreate(ThreadLocalStorageCleanupCallback callback) 696 { 697 pthread_key_t key; 698 ::pthread_key_create (&key, callback); 699 return key; 700 } 701 702 void* 703 Host::ThreadLocalStorageGet(lldb::thread_key_t key) 704 { 705 return ::pthread_getspecific (key); 706 } 707 708 void 709 Host::ThreadLocalStorageSet(lldb::thread_key_t key, void *value) 710 { 711 ::pthread_setspecific (key, value); 712 } 713 714 bool 715 Host::SetThreadName (lldb::pid_t pid, lldb::tid_t tid, const char *name) 716 { 717 #if defined(__APPLE__) && MAC_OS_X_VERSION_MAX_ALLOWED > MAC_OS_X_VERSION_10_5 718 lldb::pid_t curr_pid = Host::GetCurrentProcessID(); 719 lldb::tid_t curr_tid = Host::GetCurrentThreadID(); 720 if (pid == LLDB_INVALID_PROCESS_ID) 721 pid = curr_pid; 722 723 if (tid == LLDB_INVALID_THREAD_ID) 724 tid = curr_tid; 725 726 // Set the pthread name if possible 727 if (pid == curr_pid && tid == curr_tid) 728 { 729 if (::pthread_setname_np (name) == 0) 730 return true; 731 } 732 return false; 733 #elif defined (__FreeBSD__) 734 lldb::pid_t curr_pid = Host::GetCurrentProcessID(); 735 lldb::tid_t curr_tid = Host::GetCurrentThreadID(); 736 if (pid == LLDB_INVALID_PROCESS_ID) 737 pid = curr_pid; 738 739 if (tid == LLDB_INVALID_THREAD_ID) 740 tid = curr_tid; 741 742 // Set the pthread name if possible 743 if (pid == curr_pid && tid == curr_tid) 744 { 745 ::pthread_set_name_np (::pthread_self(), name); 746 return true; 747 } 748 return false; 749 #elif defined (__linux__) || defined (__GLIBC__) 750 void *fn = dlsym (RTLD_DEFAULT, "pthread_setname_np"); 751 if (fn) 752 { 753 lldb::pid_t curr_pid = Host::GetCurrentProcessID(); 754 lldb::tid_t curr_tid = Host::GetCurrentThreadID(); 755 if (pid == LLDB_INVALID_PROCESS_ID) 756 pid = curr_pid; 757 758 if (tid == LLDB_INVALID_THREAD_ID) 759 tid = curr_tid; 760 761 if (pid == curr_pid && tid == curr_tid) 762 { 763 int (*pthread_setname_np_func)(pthread_t thread, const char *name); 764 *reinterpret_cast<void **> (&pthread_setname_np_func) = fn; 765 766 if (pthread_setname_np_func (::pthread_self(), name) == 0) 767 return true; 768 } 769 } 770 return false; 771 #else 772 return false; 773 #endif 774 } 775 776 bool 777 Host::SetShortThreadName (lldb::pid_t pid, lldb::tid_t tid, 778 const char *thread_name, size_t len) 779 { 780 char *namebuf = (char *)::malloc (len + 1); 781 782 // Thread names are coming in like '<lldb.comm.debugger.edit>' and 783 // '<lldb.comm.debugger.editline>'. So just chopping the end of the string 784 // off leads to a lot of similar named threads. Go through the thread name 785 // and search for the last dot and use that. 786 const char *lastdot = ::strrchr (thread_name, '.'); 787 788 if (lastdot && lastdot != thread_name) 789 thread_name = lastdot + 1; 790 ::strncpy (namebuf, thread_name, len); 791 namebuf[len] = 0; 792 793 int namebuflen = strlen(namebuf); 794 if (namebuflen > 0) 795 { 796 if (namebuf[namebuflen - 1] == '(' || namebuf[namebuflen - 1] == '>') 797 { 798 // Trim off trailing '(' and '>' characters for a bit more cleanup. 799 namebuflen--; 800 namebuf[namebuflen] = 0; 801 } 802 return Host::SetThreadName (pid, tid, namebuf); 803 } 804 805 ::free(namebuf); 806 return false; 807 } 808 809 #endif 810 811 FileSpec 812 Host::GetProgramFileSpec () 813 { 814 static FileSpec g_program_filespec; 815 if (!g_program_filespec) 816 { 817 #if defined (__APPLE__) 818 char program_fullpath[PATH_MAX]; 819 // If DST is NULL, then return the number of bytes needed. 820 uint32_t len = sizeof(program_fullpath); 821 int err = _NSGetExecutablePath (program_fullpath, &len); 822 if (err == 0) 823 g_program_filespec.SetFile (program_fullpath, false); 824 else if (err == -1) 825 { 826 char *large_program_fullpath = (char *)::malloc (len + 1); 827 828 err = _NSGetExecutablePath (large_program_fullpath, &len); 829 if (err == 0) 830 g_program_filespec.SetFile (large_program_fullpath, false); 831 832 ::free (large_program_fullpath); 833 } 834 #elif defined (__linux__) 835 char exe_path[PATH_MAX]; 836 ssize_t len = readlink("/proc/self/exe", exe_path, sizeof(exe_path) - 1); 837 if (len > 0) { 838 exe_path[len] = 0; 839 g_program_filespec.SetFile(exe_path, false); 840 } 841 #elif defined (__FreeBSD__) || defined (__FreeBSD_kernel__) 842 int exe_path_mib[4] = { CTL_KERN, KERN_PROC, KERN_PROC_PATHNAME, getpid() }; 843 size_t exe_path_size; 844 if (sysctl(exe_path_mib, 4, NULL, &exe_path_size, NULL, 0) == 0) 845 { 846 char *exe_path = new char[exe_path_size]; 847 if (sysctl(exe_path_mib, 4, exe_path, &exe_path_size, NULL, 0) == 0) 848 g_program_filespec.SetFile(exe_path, false); 849 delete[] exe_path; 850 } 851 #endif 852 } 853 return g_program_filespec; 854 } 855 856 #if !defined (__APPLE__) // see Host.mm 857 858 bool 859 Host::GetBundleDirectory (const FileSpec &file, FileSpec &bundle) 860 { 861 bundle.Clear(); 862 return false; 863 } 864 865 bool 866 Host::ResolveExecutableInBundle (FileSpec &file) 867 { 868 return false; 869 } 870 #endif 871 872 #ifndef _WIN32 873 874 // Opaque info that tracks a dynamic library that was loaded 875 struct DynamicLibraryInfo 876 { 877 DynamicLibraryInfo (const FileSpec &fs, int o, void *h) : 878 file_spec (fs), 879 open_options (o), 880 handle (h) 881 { 882 } 883 884 const FileSpec file_spec; 885 uint32_t open_options; 886 void * handle; 887 }; 888 889 void * 890 Host::DynamicLibraryOpen (const FileSpec &file_spec, uint32_t options, Error &error) 891 { 892 char path[PATH_MAX]; 893 if (file_spec.GetPath(path, sizeof(path))) 894 { 895 int mode = 0; 896 897 if (options & eDynamicLibraryOpenOptionLazy) 898 mode |= RTLD_LAZY; 899 else 900 mode |= RTLD_NOW; 901 902 903 if (options & eDynamicLibraryOpenOptionLocal) 904 mode |= RTLD_LOCAL; 905 else 906 mode |= RTLD_GLOBAL; 907 908 #ifdef LLDB_CONFIG_DLOPEN_RTLD_FIRST_SUPPORTED 909 if (options & eDynamicLibraryOpenOptionLimitGetSymbol) 910 mode |= RTLD_FIRST; 911 #endif 912 913 void * opaque = ::dlopen (path, mode); 914 915 if (opaque) 916 { 917 error.Clear(); 918 return new DynamicLibraryInfo (file_spec, options, opaque); 919 } 920 else 921 { 922 error.SetErrorString(::dlerror()); 923 } 924 } 925 else 926 { 927 error.SetErrorString("failed to extract path"); 928 } 929 return NULL; 930 } 931 932 Error 933 Host::DynamicLibraryClose (void *opaque) 934 { 935 Error error; 936 if (opaque == NULL) 937 { 938 error.SetErrorString ("invalid dynamic library handle"); 939 } 940 else 941 { 942 DynamicLibraryInfo *dylib_info = (DynamicLibraryInfo *) opaque; 943 if (::dlclose (dylib_info->handle) != 0) 944 { 945 error.SetErrorString(::dlerror()); 946 } 947 948 dylib_info->open_options = 0; 949 dylib_info->handle = 0; 950 delete dylib_info; 951 } 952 return error; 953 } 954 955 void * 956 Host::DynamicLibraryGetSymbol (void *opaque, const char *symbol_name, Error &error) 957 { 958 if (opaque == NULL) 959 { 960 error.SetErrorString ("invalid dynamic library handle"); 961 } 962 else 963 { 964 DynamicLibraryInfo *dylib_info = (DynamicLibraryInfo *) opaque; 965 966 void *symbol_addr = ::dlsym (dylib_info->handle, symbol_name); 967 if (symbol_addr) 968 { 969 #ifndef LLDB_CONFIG_DLOPEN_RTLD_FIRST_SUPPORTED 970 // This host doesn't support limiting searches to this shared library 971 // so we need to verify that the match came from this shared library 972 // if it was requested in the Host::DynamicLibraryOpen() function. 973 if (dylib_info->open_options & eDynamicLibraryOpenOptionLimitGetSymbol) 974 { 975 FileSpec match_dylib_spec (Host::GetModuleFileSpecForHostAddress (symbol_addr)); 976 if (match_dylib_spec != dylib_info->file_spec) 977 { 978 char dylib_path[PATH_MAX]; 979 if (dylib_info->file_spec.GetPath (dylib_path, sizeof(dylib_path))) 980 error.SetErrorStringWithFormat ("symbol not found in \"%s\"", dylib_path); 981 else 982 error.SetErrorString ("symbol not found"); 983 return NULL; 984 } 985 } 986 #endif 987 error.Clear(); 988 return symbol_addr; 989 } 990 else 991 { 992 error.SetErrorString(::dlerror()); 993 } 994 } 995 return NULL; 996 } 997 998 FileSpec 999 Host::GetModuleFileSpecForHostAddress (const void *host_addr) 1000 { 1001 FileSpec module_filespec; 1002 Dl_info info; 1003 if (::dladdr (host_addr, &info)) 1004 { 1005 if (info.dli_fname) 1006 module_filespec.SetFile(info.dli_fname, true); 1007 } 1008 return module_filespec; 1009 } 1010 1011 #endif 1012 1013 bool 1014 Host::GetLLDBPath (PathType path_type, FileSpec &file_spec) 1015 { 1016 // To get paths related to LLDB we get the path to the executable that 1017 // contains this function. On MacOSX this will be "LLDB.framework/.../LLDB", 1018 // on linux this is assumed to be the "lldb" main executable. If LLDB on 1019 // linux is actually in a shared library (liblldb.so) then this function will 1020 // need to be modified to "do the right thing". 1021 Log *log = lldb_private::GetLogIfAllCategoriesSet (LIBLLDB_LOG_HOST); 1022 1023 switch (path_type) 1024 { 1025 case ePathTypeLLDBShlibDir: 1026 { 1027 static ConstString g_lldb_so_dir; 1028 if (!g_lldb_so_dir) 1029 { 1030 FileSpec lldb_file_spec (Host::GetModuleFileSpecForHostAddress ((void *)Host::GetLLDBPath)); 1031 g_lldb_so_dir = lldb_file_spec.GetDirectory(); 1032 if (log) 1033 log->Printf("Host::GetLLDBPath(ePathTypeLLDBShlibDir) => '%s'", g_lldb_so_dir.GetCString()); 1034 } 1035 file_spec.GetDirectory() = g_lldb_so_dir; 1036 return (bool)file_spec.GetDirectory(); 1037 } 1038 break; 1039 1040 case ePathTypeSupportExecutableDir: 1041 { 1042 static ConstString g_lldb_support_exe_dir; 1043 if (!g_lldb_support_exe_dir) 1044 { 1045 FileSpec lldb_file_spec; 1046 if (GetLLDBPath (ePathTypeLLDBShlibDir, lldb_file_spec)) 1047 { 1048 char raw_path[PATH_MAX]; 1049 char resolved_path[PATH_MAX]; 1050 lldb_file_spec.GetPath(raw_path, sizeof(raw_path)); 1051 1052 #if defined (__APPLE__) 1053 char *framework_pos = ::strstr (raw_path, "LLDB.framework"); 1054 if (framework_pos) 1055 { 1056 framework_pos += strlen("LLDB.framework"); 1057 #if defined (__arm__) 1058 // Shallow bundle 1059 *framework_pos = '\0'; 1060 #else 1061 // Normal bundle 1062 ::strncpy (framework_pos, "/Resources", PATH_MAX - (framework_pos - raw_path)); 1063 #endif 1064 } 1065 #endif 1066 FileSpec::Resolve (raw_path, resolved_path, sizeof(resolved_path)); 1067 g_lldb_support_exe_dir.SetCString(resolved_path); 1068 } 1069 if (log) 1070 log->Printf("Host::GetLLDBPath(ePathTypeSupportExecutableDir) => '%s'", g_lldb_support_exe_dir.GetCString()); 1071 } 1072 file_spec.GetDirectory() = g_lldb_support_exe_dir; 1073 return (bool)file_spec.GetDirectory(); 1074 } 1075 break; 1076 1077 case ePathTypeHeaderDir: 1078 { 1079 static ConstString g_lldb_headers_dir; 1080 if (!g_lldb_headers_dir) 1081 { 1082 #if defined (__APPLE__) 1083 FileSpec lldb_file_spec; 1084 if (GetLLDBPath (ePathTypeLLDBShlibDir, lldb_file_spec)) 1085 { 1086 char raw_path[PATH_MAX]; 1087 char resolved_path[PATH_MAX]; 1088 lldb_file_spec.GetPath(raw_path, sizeof(raw_path)); 1089 1090 char *framework_pos = ::strstr (raw_path, "LLDB.framework"); 1091 if (framework_pos) 1092 { 1093 framework_pos += strlen("LLDB.framework"); 1094 ::strncpy (framework_pos, "/Headers", PATH_MAX - (framework_pos - raw_path)); 1095 } 1096 FileSpec::Resolve (raw_path, resolved_path, sizeof(resolved_path)); 1097 g_lldb_headers_dir.SetCString(resolved_path); 1098 } 1099 #else 1100 // TODO: Anyone know how we can determine this for linux? Other systems?? 1101 g_lldb_headers_dir.SetCString ("/opt/local/include/lldb"); 1102 #endif 1103 if (log) 1104 log->Printf("Host::GetLLDBPath(ePathTypeHeaderDir) => '%s'", g_lldb_headers_dir.GetCString()); 1105 } 1106 file_spec.GetDirectory() = g_lldb_headers_dir; 1107 return (bool)file_spec.GetDirectory(); 1108 } 1109 break; 1110 1111 #ifdef LLDB_DISABLE_PYTHON 1112 case ePathTypePythonDir: 1113 return false; 1114 #else 1115 case ePathTypePythonDir: 1116 { 1117 static ConstString g_lldb_python_dir; 1118 if (!g_lldb_python_dir) 1119 { 1120 FileSpec lldb_file_spec; 1121 if (GetLLDBPath (ePathTypeLLDBShlibDir, lldb_file_spec)) 1122 { 1123 char raw_path[PATH_MAX]; 1124 char resolved_path[PATH_MAX]; 1125 lldb_file_spec.GetPath(raw_path, sizeof(raw_path)); 1126 1127 #if defined (__APPLE__) 1128 char *framework_pos = ::strstr (raw_path, "LLDB.framework"); 1129 if (framework_pos) 1130 { 1131 framework_pos += strlen("LLDB.framework"); 1132 ::strncpy (framework_pos, "/Resources/Python", PATH_MAX - (framework_pos - raw_path)); 1133 } 1134 else 1135 { 1136 #endif 1137 llvm::SmallString<256> python_version_dir; 1138 llvm::raw_svector_ostream os(python_version_dir); 1139 os << "/python" << PY_MAJOR_VERSION << '.' << PY_MINOR_VERSION << "/site-packages"; 1140 os.flush(); 1141 1142 // We may get our string truncated. Should we protect 1143 // this with an assert? 1144 1145 ::strncat(raw_path, python_version_dir.c_str(), 1146 sizeof(raw_path) - strlen(raw_path) - 1); 1147 1148 #if defined (__APPLE__) 1149 } 1150 #endif 1151 FileSpec::Resolve (raw_path, resolved_path, sizeof(resolved_path)); 1152 g_lldb_python_dir.SetCString(resolved_path); 1153 } 1154 1155 if (log) 1156 log->Printf("Host::GetLLDBPath(ePathTypePythonDir) => '%s'", g_lldb_python_dir.GetCString()); 1157 1158 } 1159 file_spec.GetDirectory() = g_lldb_python_dir; 1160 return (bool)file_spec.GetDirectory(); 1161 } 1162 break; 1163 #endif 1164 1165 case ePathTypeLLDBSystemPlugins: // System plug-ins directory 1166 { 1167 #if defined (__APPLE__) || defined(__linux__) 1168 static ConstString g_lldb_system_plugin_dir; 1169 static bool g_lldb_system_plugin_dir_located = false; 1170 if (!g_lldb_system_plugin_dir_located) 1171 { 1172 g_lldb_system_plugin_dir_located = true; 1173 #if defined (__APPLE__) 1174 FileSpec lldb_file_spec; 1175 if (GetLLDBPath (ePathTypeLLDBShlibDir, lldb_file_spec)) 1176 { 1177 char raw_path[PATH_MAX]; 1178 char resolved_path[PATH_MAX]; 1179 lldb_file_spec.GetPath(raw_path, sizeof(raw_path)); 1180 1181 char *framework_pos = ::strstr (raw_path, "LLDB.framework"); 1182 if (framework_pos) 1183 { 1184 framework_pos += strlen("LLDB.framework"); 1185 ::strncpy (framework_pos, "/Resources/PlugIns", PATH_MAX - (framework_pos - raw_path)); 1186 FileSpec::Resolve (raw_path, resolved_path, sizeof(resolved_path)); 1187 g_lldb_system_plugin_dir.SetCString(resolved_path); 1188 } 1189 return false; 1190 } 1191 #elif defined (__linux__) 1192 FileSpec lldb_file_spec("/usr/lib/lldb", true); 1193 if (lldb_file_spec.Exists()) 1194 { 1195 g_lldb_system_plugin_dir.SetCString(lldb_file_spec.GetPath().c_str()); 1196 } 1197 #endif // __APPLE__ || __linux__ 1198 1199 if (log) 1200 log->Printf("Host::GetLLDBPath(ePathTypeLLDBSystemPlugins) => '%s'", g_lldb_system_plugin_dir.GetCString()); 1201 1202 } 1203 1204 if (g_lldb_system_plugin_dir) 1205 { 1206 file_spec.GetDirectory() = g_lldb_system_plugin_dir; 1207 return true; 1208 } 1209 #else 1210 // TODO: where would system LLDB plug-ins be located on other systems? 1211 return false; 1212 #endif 1213 } 1214 break; 1215 1216 case ePathTypeLLDBUserPlugins: // User plug-ins directory 1217 { 1218 #if defined (__APPLE__) 1219 static ConstString g_lldb_user_plugin_dir; 1220 if (!g_lldb_user_plugin_dir) 1221 { 1222 char user_plugin_path[PATH_MAX]; 1223 if (FileSpec::Resolve ("~/Library/Application Support/LLDB/PlugIns", 1224 user_plugin_path, 1225 sizeof(user_plugin_path))) 1226 { 1227 g_lldb_user_plugin_dir.SetCString(user_plugin_path); 1228 } 1229 } 1230 file_spec.GetDirectory() = g_lldb_user_plugin_dir; 1231 return (bool)file_spec.GetDirectory(); 1232 #elif defined (__linux__) 1233 static ConstString g_lldb_user_plugin_dir; 1234 if (!g_lldb_user_plugin_dir) 1235 { 1236 // XDG Base Directory Specification 1237 // http://standards.freedesktop.org/basedir-spec/basedir-spec-latest.html 1238 // If XDG_DATA_HOME exists, use that, otherwise use ~/.local/share/lldb. 1239 FileSpec lldb_file_spec; 1240 const char *xdg_data_home = getenv("XDG_DATA_HOME"); 1241 if (xdg_data_home && xdg_data_home[0]) 1242 { 1243 std::string user_plugin_dir (xdg_data_home); 1244 user_plugin_dir += "/lldb"; 1245 lldb_file_spec.SetFile (user_plugin_dir.c_str(), true); 1246 } 1247 else 1248 { 1249 const char *home_dir = getenv("HOME"); 1250 if (home_dir && home_dir[0]) 1251 { 1252 std::string user_plugin_dir (home_dir); 1253 user_plugin_dir += "/.local/share/lldb"; 1254 lldb_file_spec.SetFile (user_plugin_dir.c_str(), true); 1255 } 1256 } 1257 1258 if (lldb_file_spec.Exists()) 1259 g_lldb_user_plugin_dir.SetCString(lldb_file_spec.GetPath().c_str()); 1260 if (log) 1261 log->Printf("Host::GetLLDBPath(ePathTypeLLDBUserPlugins) => '%s'", g_lldb_user_plugin_dir.GetCString()); 1262 } 1263 file_spec.GetDirectory() = g_lldb_user_plugin_dir; 1264 return (bool)file_spec.GetDirectory(); 1265 #endif 1266 // TODO: where would user LLDB plug-ins be located on other systems? 1267 return false; 1268 } 1269 1270 case ePathTypeLLDBTempSystemDir: 1271 { 1272 static ConstString g_lldb_tmp_dir; 1273 if (!g_lldb_tmp_dir) 1274 { 1275 const char *tmpdir_cstr = getenv("TMPDIR"); 1276 if (tmpdir_cstr == NULL) 1277 { 1278 tmpdir_cstr = getenv("TMP"); 1279 if (tmpdir_cstr == NULL) 1280 tmpdir_cstr = getenv("TEMP"); 1281 } 1282 if (tmpdir_cstr) 1283 { 1284 g_lldb_tmp_dir.SetCString(tmpdir_cstr); 1285 if (log) 1286 log->Printf("Host::GetLLDBPath(ePathTypeLLDBTempSystemDir) => '%s'", g_lldb_tmp_dir.GetCString()); 1287 } 1288 } 1289 file_spec.GetDirectory() = g_lldb_tmp_dir; 1290 return (bool)file_spec.GetDirectory(); 1291 } 1292 } 1293 1294 return false; 1295 } 1296 1297 1298 bool 1299 Host::GetHostname (std::string &s) 1300 { 1301 char hostname[PATH_MAX]; 1302 hostname[sizeof(hostname) - 1] = '\0'; 1303 if (::gethostname (hostname, sizeof(hostname) - 1) == 0) 1304 { 1305 struct hostent* h = ::gethostbyname (hostname); 1306 if (h) 1307 s.assign (h->h_name); 1308 else 1309 s.assign (hostname); 1310 return true; 1311 } 1312 return false; 1313 } 1314 1315 #ifndef _WIN32 1316 1317 const char * 1318 Host::GetUserName (uint32_t uid, std::string &user_name) 1319 { 1320 struct passwd user_info; 1321 struct passwd *user_info_ptr = &user_info; 1322 char user_buffer[PATH_MAX]; 1323 size_t user_buffer_size = sizeof(user_buffer); 1324 if (::getpwuid_r (uid, 1325 &user_info, 1326 user_buffer, 1327 user_buffer_size, 1328 &user_info_ptr) == 0) 1329 { 1330 if (user_info_ptr) 1331 { 1332 user_name.assign (user_info_ptr->pw_name); 1333 return user_name.c_str(); 1334 } 1335 } 1336 user_name.clear(); 1337 return NULL; 1338 } 1339 1340 const char * 1341 Host::GetGroupName (uint32_t gid, std::string &group_name) 1342 { 1343 char group_buffer[PATH_MAX]; 1344 size_t group_buffer_size = sizeof(group_buffer); 1345 struct group group_info; 1346 struct group *group_info_ptr = &group_info; 1347 // Try the threadsafe version first 1348 if (::getgrgid_r (gid, 1349 &group_info, 1350 group_buffer, 1351 group_buffer_size, 1352 &group_info_ptr) == 0) 1353 { 1354 if (group_info_ptr) 1355 { 1356 group_name.assign (group_info_ptr->gr_name); 1357 return group_name.c_str(); 1358 } 1359 } 1360 else 1361 { 1362 // The threadsafe version isn't currently working 1363 // for me on darwin, but the non-threadsafe version 1364 // is, so I am calling it below. 1365 group_info_ptr = ::getgrgid (gid); 1366 if (group_info_ptr) 1367 { 1368 group_name.assign (group_info_ptr->gr_name); 1369 return group_name.c_str(); 1370 } 1371 } 1372 group_name.clear(); 1373 return NULL; 1374 } 1375 1376 uint32_t 1377 Host::GetUserID () 1378 { 1379 return getuid(); 1380 } 1381 1382 uint32_t 1383 Host::GetGroupID () 1384 { 1385 return getgid(); 1386 } 1387 1388 uint32_t 1389 Host::GetEffectiveUserID () 1390 { 1391 return geteuid(); 1392 } 1393 1394 uint32_t 1395 Host::GetEffectiveGroupID () 1396 { 1397 return getegid(); 1398 } 1399 1400 #endif 1401 1402 #if !defined (__APPLE__) && !defined (__FreeBSD__) && !defined (__FreeBSD_kernel__) // see macosx/Host.mm 1403 bool 1404 Host::GetOSBuildString (std::string &s) 1405 { 1406 s.clear(); 1407 return false; 1408 } 1409 1410 bool 1411 Host::GetOSKernelDescription (std::string &s) 1412 { 1413 s.clear(); 1414 return false; 1415 } 1416 #endif 1417 1418 #if !defined (__APPLE__) && !defined (__FreeBSD__) && !defined (__FreeBSD_kernel__) && !defined(__linux__) 1419 uint32_t 1420 Host::FindProcesses (const ProcessInstanceInfoMatch &match_info, ProcessInstanceInfoList &process_infos) 1421 { 1422 process_infos.Clear(); 1423 return process_infos.GetSize(); 1424 } 1425 1426 bool 1427 Host::GetProcessInfo (lldb::pid_t pid, ProcessInstanceInfo &process_info) 1428 { 1429 process_info.Clear(); 1430 return false; 1431 } 1432 #endif 1433 1434 #if !defined(__linux__) 1435 bool 1436 Host::FindProcessThreads (const lldb::pid_t pid, TidMap &tids_to_attach) 1437 { 1438 return false; 1439 } 1440 #endif 1441 1442 lldb::TargetSP 1443 Host::GetDummyTarget (lldb_private::Debugger &debugger) 1444 { 1445 static TargetSP g_dummy_target_sp; 1446 1447 // FIXME: Maybe the dummy target should be per-Debugger 1448 if (!g_dummy_target_sp || !g_dummy_target_sp->IsValid()) 1449 { 1450 ArchSpec arch(Target::GetDefaultArchitecture()); 1451 if (!arch.IsValid()) 1452 arch = Host::GetArchitecture (); 1453 Error err = debugger.GetTargetList().CreateTarget(debugger, 1454 NULL, 1455 arch.GetTriple().getTriple().c_str(), 1456 false, 1457 NULL, 1458 g_dummy_target_sp); 1459 } 1460 1461 return g_dummy_target_sp; 1462 } 1463 1464 struct ShellInfo 1465 { 1466 ShellInfo () : 1467 process_reaped (false), 1468 can_delete (false), 1469 pid (LLDB_INVALID_PROCESS_ID), 1470 signo(-1), 1471 status(-1) 1472 { 1473 } 1474 1475 lldb_private::Predicate<bool> process_reaped; 1476 lldb_private::Predicate<bool> can_delete; 1477 lldb::pid_t pid; 1478 int signo; 1479 int status; 1480 }; 1481 1482 static bool 1483 MonitorShellCommand (void *callback_baton, 1484 lldb::pid_t pid, 1485 bool exited, // True if the process did exit 1486 int signo, // Zero for no signal 1487 int status) // Exit value of process if signal is zero 1488 { 1489 ShellInfo *shell_info = (ShellInfo *)callback_baton; 1490 shell_info->pid = pid; 1491 shell_info->signo = signo; 1492 shell_info->status = status; 1493 // Let the thread running Host::RunShellCommand() know that the process 1494 // exited and that ShellInfo has been filled in by broadcasting to it 1495 shell_info->process_reaped.SetValue(1, eBroadcastAlways); 1496 // Now wait for a handshake back from that thread running Host::RunShellCommand 1497 // so we know that we can delete shell_info_ptr 1498 shell_info->can_delete.WaitForValueEqualTo(true); 1499 // Sleep a bit to allow the shell_info->can_delete.SetValue() to complete... 1500 usleep(1000); 1501 // Now delete the shell info that was passed into this function 1502 delete shell_info; 1503 return true; 1504 } 1505 1506 Error 1507 Host::RunShellCommand (const char *command, 1508 const char *working_dir, 1509 int *status_ptr, 1510 int *signo_ptr, 1511 std::string *command_output_ptr, 1512 uint32_t timeout_sec, 1513 const char *shell) 1514 { 1515 Error error; 1516 ProcessLaunchInfo launch_info; 1517 if (shell && shell[0]) 1518 { 1519 // Run the command in a shell 1520 launch_info.SetShell(shell); 1521 launch_info.GetArguments().AppendArgument(command); 1522 const bool localhost = true; 1523 const bool will_debug = false; 1524 const bool first_arg_is_full_shell_command = true; 1525 launch_info.ConvertArgumentsForLaunchingInShell (error, 1526 localhost, 1527 will_debug, 1528 first_arg_is_full_shell_command, 1529 0); 1530 } 1531 else 1532 { 1533 // No shell, just run it 1534 Args args (command); 1535 const bool first_arg_is_executable = true; 1536 launch_info.SetArguments(args, first_arg_is_executable); 1537 } 1538 1539 if (working_dir) 1540 launch_info.SetWorkingDirectory(working_dir); 1541 char output_file_path_buffer[PATH_MAX]; 1542 const char *output_file_path = NULL; 1543 1544 if (command_output_ptr) 1545 { 1546 // Create a temporary file to get the stdout/stderr and redirect the 1547 // output of the command into this file. We will later read this file 1548 // if all goes well and fill the data into "command_output_ptr" 1549 FileSpec tmpdir_file_spec; 1550 if (Host::GetLLDBPath (ePathTypeLLDBTempSystemDir, tmpdir_file_spec)) 1551 { 1552 tmpdir_file_spec.GetFilename().SetCString("lldb-shell-output.XXXXXX"); 1553 strncpy(output_file_path_buffer, tmpdir_file_spec.GetPath().c_str(), sizeof(output_file_path_buffer)); 1554 } 1555 else 1556 { 1557 strncpy(output_file_path_buffer, "/tmp/lldb-shell-output.XXXXXX", sizeof(output_file_path_buffer)); 1558 } 1559 1560 output_file_path = ::mktemp(output_file_path_buffer); 1561 } 1562 1563 launch_info.AppendSuppressFileAction (STDIN_FILENO, true, false); 1564 if (output_file_path) 1565 { 1566 launch_info.AppendOpenFileAction(STDOUT_FILENO, output_file_path, false, true); 1567 launch_info.AppendDuplicateFileAction(STDOUT_FILENO, STDERR_FILENO); 1568 } 1569 else 1570 { 1571 launch_info.AppendSuppressFileAction (STDOUT_FILENO, false, true); 1572 launch_info.AppendSuppressFileAction (STDERR_FILENO, false, true); 1573 } 1574 1575 // The process monitor callback will delete the 'shell_info_ptr' below... 1576 std::unique_ptr<ShellInfo> shell_info_ap (new ShellInfo()); 1577 1578 const bool monitor_signals = false; 1579 launch_info.SetMonitorProcessCallback(MonitorShellCommand, shell_info_ap.get(), monitor_signals); 1580 1581 error = LaunchProcess (launch_info); 1582 const lldb::pid_t pid = launch_info.GetProcessID(); 1583 1584 if (error.Success() && pid == LLDB_INVALID_PROCESS_ID) 1585 error.SetErrorString("failed to get process ID"); 1586 1587 if (error.Success()) 1588 { 1589 // The process successfully launched, so we can defer ownership of 1590 // "shell_info" to the MonitorShellCommand callback function that will 1591 // get called when the process dies. We release the unique pointer as it 1592 // doesn't need to delete the ShellInfo anymore. 1593 ShellInfo *shell_info = shell_info_ap.release(); 1594 TimeValue *timeout_ptr = nullptr; 1595 TimeValue timeout_time(TimeValue::Now()); 1596 if (timeout_sec > 0) { 1597 timeout_time.OffsetWithSeconds(timeout_sec); 1598 timeout_ptr = &timeout_time; 1599 } 1600 bool timed_out = false; 1601 shell_info->process_reaped.WaitForValueEqualTo(true, timeout_ptr, &timed_out); 1602 if (timed_out) 1603 { 1604 error.SetErrorString("timed out waiting for shell command to complete"); 1605 1606 // Kill the process since it didn't complete withint the timeout specified 1607 Kill (pid, SIGKILL); 1608 // Wait for the monitor callback to get the message 1609 timeout_time = TimeValue::Now(); 1610 timeout_time.OffsetWithSeconds(1); 1611 timed_out = false; 1612 shell_info->process_reaped.WaitForValueEqualTo(true, &timeout_time, &timed_out); 1613 } 1614 else 1615 { 1616 if (status_ptr) 1617 *status_ptr = shell_info->status; 1618 1619 if (signo_ptr) 1620 *signo_ptr = shell_info->signo; 1621 1622 if (command_output_ptr) 1623 { 1624 command_output_ptr->clear(); 1625 FileSpec file_spec(output_file_path, File::eOpenOptionRead); 1626 uint64_t file_size = file_spec.GetByteSize(); 1627 if (file_size > 0) 1628 { 1629 if (file_size > command_output_ptr->max_size()) 1630 { 1631 error.SetErrorStringWithFormat("shell command output is too large to fit into a std::string"); 1632 } 1633 else 1634 { 1635 command_output_ptr->resize(file_size); 1636 file_spec.ReadFileContents(0, &((*command_output_ptr)[0]), command_output_ptr->size(), &error); 1637 } 1638 } 1639 } 1640 } 1641 shell_info->can_delete.SetValue(true, eBroadcastAlways); 1642 } 1643 1644 if (output_file_path) 1645 ::unlink (output_file_path); 1646 // Handshake with the monitor thread, or just let it know in advance that 1647 // it can delete "shell_info" in case we timed out and were not able to kill 1648 // the process... 1649 return error; 1650 } 1651 1652 1653 // LaunchProcessPosixSpawn for Apple, Linux, FreeBSD and other GLIBC 1654 // systems 1655 1656 #if defined (__APPLE__) || defined (__linux__) || defined (__FreeBSD__) || defined (__GLIBC__) 1657 1658 // this method needs to be visible to macosx/Host.cpp and 1659 // common/Host.cpp. 1660 1661 short 1662 Host::GetPosixspawnFlags (ProcessLaunchInfo &launch_info) 1663 { 1664 short flags = POSIX_SPAWN_SETSIGDEF | POSIX_SPAWN_SETSIGMASK; 1665 1666 #if defined (__APPLE__) 1667 if (launch_info.GetFlags().Test (eLaunchFlagExec)) 1668 flags |= POSIX_SPAWN_SETEXEC; // Darwin specific posix_spawn flag 1669 1670 if (launch_info.GetFlags().Test (eLaunchFlagDebug)) 1671 flags |= POSIX_SPAWN_START_SUSPENDED; // Darwin specific posix_spawn flag 1672 1673 if (launch_info.GetFlags().Test (eLaunchFlagDisableASLR)) 1674 flags |= _POSIX_SPAWN_DISABLE_ASLR; // Darwin specific posix_spawn flag 1675 1676 if (launch_info.GetLaunchInSeparateProcessGroup()) 1677 flags |= POSIX_SPAWN_SETPGROUP; 1678 1679 #ifdef POSIX_SPAWN_CLOEXEC_DEFAULT 1680 #if defined (__APPLE__) && (defined (__x86_64__) || defined (__i386__)) 1681 static LazyBool g_use_close_on_exec_flag = eLazyBoolCalculate; 1682 if (g_use_close_on_exec_flag == eLazyBoolCalculate) 1683 { 1684 g_use_close_on_exec_flag = eLazyBoolNo; 1685 1686 uint32_t major, minor, update; 1687 if (Host::GetOSVersion(major, minor, update)) 1688 { 1689 // Kernel panic if we use the POSIX_SPAWN_CLOEXEC_DEFAULT on 10.7 or earlier 1690 if (major > 10 || (major == 10 && minor > 7)) 1691 { 1692 // Only enable for 10.8 and later OS versions 1693 g_use_close_on_exec_flag = eLazyBoolYes; 1694 } 1695 } 1696 } 1697 #else 1698 static LazyBool g_use_close_on_exec_flag = eLazyBoolYes; 1699 #endif 1700 // Close all files exception those with file actions if this is supported. 1701 if (g_use_close_on_exec_flag == eLazyBoolYes) 1702 flags |= POSIX_SPAWN_CLOEXEC_DEFAULT; 1703 #endif 1704 #endif // #if defined (__APPLE__) 1705 return flags; 1706 } 1707 1708 Error 1709 Host::LaunchProcessPosixSpawn (const char *exe_path, ProcessLaunchInfo &launch_info, ::pid_t &pid) 1710 { 1711 Error error; 1712 Log *log(lldb_private::GetLogIfAllCategoriesSet (LIBLLDB_LOG_HOST | LIBLLDB_LOG_PROCESS)); 1713 1714 posix_spawnattr_t attr; 1715 error.SetError( ::posix_spawnattr_init (&attr), eErrorTypePOSIX); 1716 1717 if (error.Fail() || log) 1718 error.PutToLog(log, "::posix_spawnattr_init ( &attr )"); 1719 if (error.Fail()) 1720 return error; 1721 1722 // Make a quick class that will cleanup the posix spawn attributes in case 1723 // we return in the middle of this function. 1724 lldb_utility::CleanUp <posix_spawnattr_t *, int> posix_spawnattr_cleanup(&attr, posix_spawnattr_destroy); 1725 1726 sigset_t no_signals; 1727 sigset_t all_signals; 1728 sigemptyset (&no_signals); 1729 sigfillset (&all_signals); 1730 ::posix_spawnattr_setsigmask(&attr, &no_signals); 1731 #if defined (__linux__) || defined (__FreeBSD__) 1732 ::posix_spawnattr_setsigdefault(&attr, &no_signals); 1733 #else 1734 ::posix_spawnattr_setsigdefault(&attr, &all_signals); 1735 #endif 1736 1737 short flags = GetPosixspawnFlags(launch_info); 1738 1739 error.SetError( ::posix_spawnattr_setflags (&attr, flags), eErrorTypePOSIX); 1740 if (error.Fail() || log) 1741 error.PutToLog(log, "::posix_spawnattr_setflags ( &attr, flags=0x%8.8x )", flags); 1742 if (error.Fail()) 1743 return error; 1744 1745 // posix_spawnattr_setbinpref_np appears to be an Apple extension per: 1746 // http://www.unix.com/man-page/OSX/3/posix_spawnattr_setbinpref_np/ 1747 #if defined (__APPLE__) && !defined (__arm__) 1748 1749 // We don't need to do this for ARM, and we really shouldn't now that we 1750 // have multiple CPU subtypes and no posix_spawnattr call that allows us 1751 // to set which CPU subtype to launch... 1752 const ArchSpec &arch_spec = launch_info.GetArchitecture(); 1753 cpu_type_t cpu = arch_spec.GetMachOCPUType(); 1754 cpu_type_t sub = arch_spec.GetMachOCPUSubType(); 1755 if (cpu != 0 && 1756 cpu != UINT32_MAX && 1757 cpu != LLDB_INVALID_CPUTYPE && 1758 !(cpu == 0x01000007 && sub == 8)) // If haswell is specified, don't try to set the CPU type or we will fail 1759 { 1760 size_t ocount = 0; 1761 error.SetError( ::posix_spawnattr_setbinpref_np (&attr, 1, &cpu, &ocount), eErrorTypePOSIX); 1762 if (error.Fail() || log) 1763 error.PutToLog(log, "::posix_spawnattr_setbinpref_np ( &attr, 1, cpu_type = 0x%8.8x, count => %llu )", cpu, (uint64_t)ocount); 1764 1765 if (error.Fail() || ocount != 1) 1766 return error; 1767 } 1768 1769 #endif 1770 1771 const char *tmp_argv[2]; 1772 char * const *argv = (char * const*)launch_info.GetArguments().GetConstArgumentVector(); 1773 char * const *envp = (char * const*)launch_info.GetEnvironmentEntries().GetConstArgumentVector(); 1774 if (argv == NULL) 1775 { 1776 // posix_spawn gets very unhappy if it doesn't have at least the program 1777 // name in argv[0]. One of the side affects I have noticed is the environment 1778 // variables don't make it into the child process if "argv == NULL"!!! 1779 tmp_argv[0] = exe_path; 1780 tmp_argv[1] = NULL; 1781 argv = (char * const*)tmp_argv; 1782 } 1783 1784 #if !defined (__APPLE__) 1785 // manage the working directory 1786 char current_dir[PATH_MAX]; 1787 current_dir[0] = '\0'; 1788 #endif 1789 1790 const char *working_dir = launch_info.GetWorkingDirectory(); 1791 if (working_dir) 1792 { 1793 #if defined (__APPLE__) 1794 // Set the working directory on this thread only 1795 if (__pthread_chdir (working_dir) < 0) { 1796 if (errno == ENOENT) { 1797 error.SetErrorStringWithFormat("No such file or directory: %s", working_dir); 1798 } else if (errno == ENOTDIR) { 1799 error.SetErrorStringWithFormat("Path doesn't name a directory: %s", working_dir); 1800 } else { 1801 error.SetErrorStringWithFormat("An unknown error occurred when changing directory for process execution."); 1802 } 1803 return error; 1804 } 1805 #else 1806 if (::getcwd(current_dir, sizeof(current_dir)) == NULL) 1807 { 1808 error.SetError(errno, eErrorTypePOSIX); 1809 error.LogIfError(log, "unable to save the current directory"); 1810 return error; 1811 } 1812 1813 if (::chdir(working_dir) == -1) 1814 { 1815 error.SetError(errno, eErrorTypePOSIX); 1816 error.LogIfError(log, "unable to change working directory to %s", working_dir); 1817 return error; 1818 } 1819 #endif 1820 } 1821 1822 const size_t num_file_actions = launch_info.GetNumFileActions (); 1823 if (num_file_actions > 0) 1824 { 1825 posix_spawn_file_actions_t file_actions; 1826 error.SetError( ::posix_spawn_file_actions_init (&file_actions), eErrorTypePOSIX); 1827 if (error.Fail() || log) 1828 error.PutToLog(log, "::posix_spawn_file_actions_init ( &file_actions )"); 1829 if (error.Fail()) 1830 return error; 1831 1832 // Make a quick class that will cleanup the posix spawn attributes in case 1833 // we return in the middle of this function. 1834 lldb_utility::CleanUp <posix_spawn_file_actions_t *, int> posix_spawn_file_actions_cleanup (&file_actions, posix_spawn_file_actions_destroy); 1835 1836 for (size_t i=0; i<num_file_actions; ++i) 1837 { 1838 const ProcessLaunchInfo::FileAction *launch_file_action = launch_info.GetFileActionAtIndex(i); 1839 if (launch_file_action) 1840 { 1841 if (!ProcessLaunchInfo::FileAction::AddPosixSpawnFileAction (&file_actions, 1842 launch_file_action, 1843 log, 1844 error)) 1845 return error; 1846 } 1847 } 1848 1849 error.SetError (::posix_spawnp (&pid, 1850 exe_path, 1851 &file_actions, 1852 &attr, 1853 argv, 1854 envp), 1855 eErrorTypePOSIX); 1856 1857 if (error.Fail() || log) 1858 { 1859 error.PutToLog(log, "::posix_spawnp ( pid => %i, path = '%s', file_actions = %p, attr = %p, argv = %p, envp = %p )", 1860 pid, 1861 exe_path, 1862 &file_actions, 1863 &attr, 1864 argv, 1865 envp); 1866 if (log) 1867 { 1868 for (int ii=0; argv[ii]; ++ii) 1869 log->Printf("argv[%i] = '%s'", ii, argv[ii]); 1870 } 1871 } 1872 1873 } 1874 else 1875 { 1876 error.SetError (::posix_spawnp (&pid, 1877 exe_path, 1878 NULL, 1879 &attr, 1880 argv, 1881 envp), 1882 eErrorTypePOSIX); 1883 1884 if (error.Fail() || log) 1885 { 1886 error.PutToLog(log, "::posix_spawnp ( pid => %i, path = '%s', file_actions = NULL, attr = %p, argv = %p, envp = %p )", 1887 pid, 1888 exe_path, 1889 &attr, 1890 argv, 1891 envp); 1892 if (log) 1893 { 1894 for (int ii=0; argv[ii]; ++ii) 1895 log->Printf("argv[%i] = '%s'", ii, argv[ii]); 1896 } 1897 } 1898 } 1899 1900 if (working_dir) 1901 { 1902 #if defined (__APPLE__) 1903 // No more thread specific current working directory 1904 __pthread_fchdir (-1); 1905 #else 1906 if (::chdir(current_dir) == -1 && error.Success()) 1907 { 1908 error.SetError(errno, eErrorTypePOSIX); 1909 error.LogIfError(log, "unable to change current directory back to %s", 1910 current_dir); 1911 } 1912 #endif 1913 } 1914 1915 return error; 1916 } 1917 1918 #endif // LaunchProcedssPosixSpawn: Apple, Linux, FreeBSD and other GLIBC systems 1919 1920 1921 #if defined(__linux__) || defined(__FreeBSD__) || defined(__GLIBC__) 1922 // The functions below implement process launching via posix_spawn() for Linux 1923 // and FreeBSD. 1924 1925 Error 1926 Host::LaunchProcess (ProcessLaunchInfo &launch_info) 1927 { 1928 Error error; 1929 char exe_path[PATH_MAX]; 1930 1931 PlatformSP host_platform_sp (Platform::GetDefaultPlatform ()); 1932 1933 const ArchSpec &arch_spec = launch_info.GetArchitecture(); 1934 1935 FileSpec exe_spec(launch_info.GetExecutableFile()); 1936 1937 FileSpec::FileType file_type = exe_spec.GetFileType(); 1938 if (file_type != FileSpec::eFileTypeRegular) 1939 { 1940 lldb::ModuleSP exe_module_sp; 1941 error = host_platform_sp->ResolveExecutable (exe_spec, 1942 arch_spec, 1943 exe_module_sp, 1944 NULL); 1945 1946 if (error.Fail()) 1947 return error; 1948 1949 if (exe_module_sp) 1950 exe_spec = exe_module_sp->GetFileSpec(); 1951 } 1952 1953 if (exe_spec.Exists()) 1954 { 1955 exe_spec.GetPath (exe_path, sizeof(exe_path)); 1956 } 1957 else 1958 { 1959 launch_info.GetExecutableFile().GetPath (exe_path, sizeof(exe_path)); 1960 error.SetErrorStringWithFormat ("executable doesn't exist: '%s'", exe_path); 1961 return error; 1962 } 1963 1964 assert(!launch_info.GetFlags().Test (eLaunchFlagLaunchInTTY)); 1965 1966 ::pid_t pid = LLDB_INVALID_PROCESS_ID; 1967 1968 error = LaunchProcessPosixSpawn(exe_path, launch_info, pid); 1969 1970 if (pid != LLDB_INVALID_PROCESS_ID) 1971 { 1972 // If all went well, then set the process ID into the launch info 1973 launch_info.SetProcessID(pid); 1974 1975 Log *log(lldb_private::GetLogIfAllCategoriesSet (LIBLLDB_LOG_PROCESS)); 1976 1977 // Make sure we reap any processes we spawn or we will have zombies. 1978 if (!launch_info.MonitorProcess()) 1979 { 1980 const bool monitor_signals = false; 1981 StartMonitoringChildProcess (Process::SetProcessExitStatus, 1982 NULL, 1983 pid, 1984 monitor_signals); 1985 if (log) 1986 log->PutCString ("monitored child process with default Process::SetProcessExitStatus."); 1987 } 1988 else 1989 { 1990 if (log) 1991 log->PutCString ("monitored child process with user-specified process monitor."); 1992 } 1993 } 1994 else 1995 { 1996 // Invalid process ID, something didn't go well 1997 if (error.Success()) 1998 error.SetErrorString ("process launch failed for unknown reasons"); 1999 } 2000 return error; 2001 } 2002 2003 #endif // defined(__linux__) or defined(__FreeBSD__) 2004 2005 #ifndef _WIN32 2006 2007 size_t 2008 Host::GetPageSize() 2009 { 2010 return ::getpagesize(); 2011 } 2012 2013 uint32_t 2014 Host::GetNumberCPUS () 2015 { 2016 static uint32_t g_num_cores = UINT32_MAX; 2017 if (g_num_cores == UINT32_MAX) 2018 { 2019 #if defined(__APPLE__) or defined (__linux__) or defined (__FreeBSD__) or defined (__FreeBSD_kernel__) 2020 2021 g_num_cores = ::sysconf(_SC_NPROCESSORS_ONLN); 2022 2023 #else 2024 2025 // Assume POSIX support if a host specific case has not been supplied above 2026 g_num_cores = 0; 2027 int num_cores = 0; 2028 size_t num_cores_len = sizeof(num_cores); 2029 #ifdef HW_AVAILCPU 2030 int mib[] = { CTL_HW, HW_AVAILCPU }; 2031 #else 2032 int mib[] = { CTL_HW, HW_NCPU }; 2033 #endif 2034 2035 /* get the number of CPUs from the system */ 2036 if (sysctl(mib, sizeof(mib)/sizeof(int), &num_cores, &num_cores_len, NULL, 0) == 0 && (num_cores > 0)) 2037 { 2038 g_num_cores = num_cores; 2039 } 2040 else 2041 { 2042 mib[1] = HW_NCPU; 2043 num_cores_len = sizeof(num_cores); 2044 if (sysctl(mib, sizeof(mib)/sizeof(int), &num_cores, &num_cores_len, NULL, 0) == 0 && (num_cores > 0)) 2045 { 2046 if (num_cores > 0) 2047 g_num_cores = num_cores; 2048 } 2049 } 2050 #endif 2051 } 2052 return g_num_cores; 2053 } 2054 2055 void 2056 Host::Kill(lldb::pid_t pid, int signo) 2057 { 2058 ::kill(pid, signo); 2059 } 2060 2061 #endif 2062 2063 #if !defined (__APPLE__) 2064 bool 2065 Host::OpenFileInExternalEditor (const FileSpec &file_spec, uint32_t line_no) 2066 { 2067 return false; 2068 } 2069 2070 void 2071 Host::SetCrashDescriptionWithFormat (const char *format, ...) 2072 { 2073 } 2074 2075 void 2076 Host::SetCrashDescription (const char *description) 2077 { 2078 } 2079 2080 lldb::pid_t 2081 Host::LaunchApplication (const FileSpec &app_file_spec) 2082 { 2083 return LLDB_INVALID_PROCESS_ID; 2084 } 2085 2086 #endif 2087 2088 2089 #ifdef LLDB_DISABLE_POSIX 2090 2091 Error 2092 Host::MakeDirectory (const char* path, uint32_t mode) 2093 { 2094 Error error; 2095 error.SetErrorStringWithFormat("%s in not implemented on this host", __PRETTY_FUNCTION__); 2096 return error; 2097 } 2098 2099 Error 2100 Host::GetFilePermissions (const char* path, uint32_t &file_permissions) 2101 { 2102 Error error; 2103 error.SetErrorStringWithFormat("%s is not supported on this host", __PRETTY_FUNCTION__); 2104 return error; 2105 } 2106 2107 Error 2108 Host::SetFilePermissions (const char* path, uint32_t file_permissions) 2109 { 2110 Error error; 2111 error.SetErrorStringWithFormat("%s is not supported on this host", __PRETTY_FUNCTION__); 2112 return error; 2113 } 2114 2115 Error 2116 Host::Symlink (const char *src, const char *dst) 2117 { 2118 Error error; 2119 error.SetErrorStringWithFormat("%s is not supported on this host", __PRETTY_FUNCTION__); 2120 return error; 2121 } 2122 2123 Error 2124 Host::Readlink (const char *path, char *buf, size_t buf_len) 2125 { 2126 Error error; 2127 error.SetErrorStringWithFormat("%s is not supported on this host", __PRETTY_FUNCTION__); 2128 return error; 2129 } 2130 2131 Error 2132 Host::Unlink (const char *path) 2133 { 2134 Error error; 2135 error.SetErrorStringWithFormat("%s is not supported on this host", __PRETTY_FUNCTION__); 2136 return error; 2137 } 2138 2139 #else 2140 2141 Error 2142 Host::MakeDirectory (const char* path, uint32_t file_permissions) 2143 { 2144 Error error; 2145 if (path && path[0]) 2146 { 2147 if (::mkdir(path, file_permissions) != 0) 2148 { 2149 error.SetErrorToErrno(); 2150 switch (error.GetError()) 2151 { 2152 case ENOENT: 2153 { 2154 // Parent directory doesn't exist, so lets make it if we can 2155 FileSpec spec(path, false); 2156 if (spec.GetDirectory() && spec.GetFilename()) 2157 { 2158 // Make the parent directory and try again 2159 Error error2 = Host::MakeDirectory(spec.GetDirectory().GetCString(), file_permissions); 2160 if (error2.Success()) 2161 { 2162 // Try and make the directory again now that the parent directory was made successfully 2163 if (::mkdir(path, file_permissions) == 0) 2164 error.Clear(); 2165 else 2166 error.SetErrorToErrno(); 2167 } 2168 } 2169 } 2170 break; 2171 case EEXIST: 2172 { 2173 FileSpec path_spec(path, false); 2174 if (path_spec.IsDirectory()) 2175 error.Clear(); // It is a directory and it already exists 2176 } 2177 break; 2178 } 2179 } 2180 } 2181 else 2182 { 2183 error.SetErrorString("empty path"); 2184 } 2185 return error; 2186 } 2187 2188 Error 2189 Host::GetFilePermissions (const char* path, uint32_t &file_permissions) 2190 { 2191 Error error; 2192 struct stat file_stats; 2193 if (::stat (path, &file_stats) == 0) 2194 { 2195 // The bits in "st_mode" currently match the definitions 2196 // for the file mode bits in unix. 2197 file_permissions = file_stats.st_mode & (S_IRWXU | S_IRWXG | S_IRWXO); 2198 } 2199 else 2200 { 2201 error.SetErrorToErrno(); 2202 } 2203 return error; 2204 } 2205 2206 Error 2207 Host::SetFilePermissions (const char* path, uint32_t file_permissions) 2208 { 2209 Error error; 2210 if (::chmod(path, file_permissions) != 0) 2211 error.SetErrorToErrno(); 2212 return error; 2213 } 2214 2215 Error 2216 Host::Symlink (const char *src, const char *dst) 2217 { 2218 Error error; 2219 if (::symlink(dst, src) == -1) 2220 error.SetErrorToErrno(); 2221 return error; 2222 } 2223 2224 Error 2225 Host::Unlink (const char *path) 2226 { 2227 Error error; 2228 if (::unlink(path) == -1) 2229 error.SetErrorToErrno(); 2230 return error; 2231 } 2232 2233 Error 2234 Host::Readlink (const char *path, char *buf, size_t buf_len) 2235 { 2236 Error error; 2237 ssize_t count = ::readlink(path, buf, buf_len); 2238 if (count < 0) 2239 error.SetErrorToErrno(); 2240 else if (count < (buf_len-1)) 2241 buf[count] = '\0'; // Success 2242 else 2243 error.SetErrorString("'buf' buffer is too small to contain link contents"); 2244 return error; 2245 } 2246 2247 2248 #endif 2249 2250 typedef std::map<lldb::user_id_t, lldb::FileSP> FDToFileMap; 2251 FDToFileMap& GetFDToFileMap() 2252 { 2253 static FDToFileMap g_fd2filemap; 2254 return g_fd2filemap; 2255 } 2256 2257 lldb::user_id_t 2258 Host::OpenFile (const FileSpec& file_spec, 2259 uint32_t flags, 2260 uint32_t mode, 2261 Error &error) 2262 { 2263 std::string path (file_spec.GetPath()); 2264 if (path.empty()) 2265 { 2266 error.SetErrorString("empty path"); 2267 return UINT64_MAX; 2268 } 2269 FileSP file_sp(new File()); 2270 error = file_sp->Open(path.c_str(),flags,mode); 2271 if (file_sp->IsValid() == false) 2272 return UINT64_MAX; 2273 lldb::user_id_t fd = file_sp->GetDescriptor(); 2274 GetFDToFileMap()[fd] = file_sp; 2275 return fd; 2276 } 2277 2278 bool 2279 Host::CloseFile (lldb::user_id_t fd, Error &error) 2280 { 2281 if (fd == UINT64_MAX) 2282 { 2283 error.SetErrorString ("invalid file descriptor"); 2284 return false; 2285 } 2286 FDToFileMap& file_map = GetFDToFileMap(); 2287 FDToFileMap::iterator pos = file_map.find(fd); 2288 if (pos == file_map.end()) 2289 { 2290 error.SetErrorStringWithFormat ("invalid host file descriptor %" PRIu64, fd); 2291 return false; 2292 } 2293 FileSP file_sp = pos->second; 2294 if (!file_sp) 2295 { 2296 error.SetErrorString ("invalid host backing file"); 2297 return false; 2298 } 2299 error = file_sp->Close(); 2300 file_map.erase(pos); 2301 return error.Success(); 2302 } 2303 2304 uint64_t 2305 Host::WriteFile (lldb::user_id_t fd, uint64_t offset, const void* src, uint64_t src_len, Error &error) 2306 { 2307 if (fd == UINT64_MAX) 2308 { 2309 error.SetErrorString ("invalid file descriptor"); 2310 return UINT64_MAX; 2311 } 2312 FDToFileMap& file_map = GetFDToFileMap(); 2313 FDToFileMap::iterator pos = file_map.find(fd); 2314 if (pos == file_map.end()) 2315 { 2316 error.SetErrorStringWithFormat("invalid host file descriptor %" PRIu64 , fd); 2317 return false; 2318 } 2319 FileSP file_sp = pos->second; 2320 if (!file_sp) 2321 { 2322 error.SetErrorString ("invalid host backing file"); 2323 return UINT64_MAX; 2324 } 2325 if (file_sp->SeekFromStart(offset, &error) != offset || error.Fail()) 2326 return UINT64_MAX; 2327 size_t bytes_written = src_len; 2328 error = file_sp->Write(src, bytes_written); 2329 if (error.Fail()) 2330 return UINT64_MAX; 2331 return bytes_written; 2332 } 2333 2334 uint64_t 2335 Host::ReadFile (lldb::user_id_t fd, uint64_t offset, void* dst, uint64_t dst_len, Error &error) 2336 { 2337 if (fd == UINT64_MAX) 2338 { 2339 error.SetErrorString ("invalid file descriptor"); 2340 return UINT64_MAX; 2341 } 2342 FDToFileMap& file_map = GetFDToFileMap(); 2343 FDToFileMap::iterator pos = file_map.find(fd); 2344 if (pos == file_map.end()) 2345 { 2346 error.SetErrorStringWithFormat ("invalid host file descriptor %" PRIu64, fd); 2347 return false; 2348 } 2349 FileSP file_sp = pos->second; 2350 if (!file_sp) 2351 { 2352 error.SetErrorString ("invalid host backing file"); 2353 return UINT64_MAX; 2354 } 2355 if (file_sp->SeekFromStart(offset, &error) != offset || error.Fail()) 2356 return UINT64_MAX; 2357 size_t bytes_read = dst_len; 2358 error = file_sp->Read(dst ,bytes_read); 2359 if (error.Fail()) 2360 return UINT64_MAX; 2361 return bytes_read; 2362 } 2363 2364 lldb::user_id_t 2365 Host::GetFileSize (const FileSpec& file_spec) 2366 { 2367 return file_spec.GetByteSize(); 2368 } 2369 2370 bool 2371 Host::GetFileExists (const FileSpec& file_spec) 2372 { 2373 return file_spec.Exists(); 2374 } 2375 2376 bool 2377 Host::CalculateMD5 (const FileSpec& file_spec, 2378 uint64_t &low, 2379 uint64_t &high) 2380 { 2381 #if defined (__APPLE__) 2382 StreamString md5_cmd_line; 2383 md5_cmd_line.Printf("md5 -q '%s'", file_spec.GetPath().c_str()); 2384 std::string hash_string; 2385 Error err = Host::RunShellCommand(md5_cmd_line.GetData(), NULL, NULL, NULL, &hash_string, 60); 2386 if (err.Fail()) 2387 return false; 2388 // a correctly formed MD5 is 16-bytes, that is 32 hex digits 2389 // if the output is any other length it is probably wrong 2390 if (hash_string.size() != 32) 2391 return false; 2392 std::string part1(hash_string,0,16); 2393 std::string part2(hash_string,16); 2394 const char* part1_cstr = part1.c_str(); 2395 const char* part2_cstr = part2.c_str(); 2396 high = ::strtoull(part1_cstr, NULL, 16); 2397 low = ::strtoull(part2_cstr, NULL, 16); 2398 return true; 2399 #else 2400 // your own MD5 implementation here 2401 return false; 2402 #endif 2403 } 2404