1 //===-- Host.cpp ------------------------------------------------*- C++ -*-===// 2 // 3 // The LLVM Compiler Infrastructure 4 // 5 // This file is distributed under the University of Illinois Open Source 6 // License. See LICENSE.TXT for details. 7 // 8 //===----------------------------------------------------------------------===// 9 10 #include "lldb/Host/Host.h" 11 #include "lldb/Core/ArchSpec.h" 12 #include "lldb/Core/ConstString.h" 13 #include "lldb/Core/Error.h" 14 #include "lldb/Core/Log.h" 15 #include "lldb/Core/StreamString.h" 16 #include "lldb/Host/Config.h" 17 #include "lldb/Host/Endian.h" 18 #include "lldb/Host/FileSpec.h" 19 #include "lldb/Host/Mutex.h" 20 #include "lldb/Target/Process.h" 21 22 #include "llvm/Support/Host.h" 23 #include "llvm/Support/MachO.h" 24 25 #include <dlfcn.h> 26 #include <errno.h> 27 #include <grp.h> 28 #include <limits.h> 29 #include <netdb.h> 30 #include <pwd.h> 31 #include <sys/types.h> 32 33 34 #if defined (__APPLE__) 35 36 #include <dispatch/dispatch.h> 37 #include <libproc.h> 38 #include <mach-o/dyld.h> 39 #include <sys/sysctl.h> 40 41 42 #elif defined (__linux__) 43 44 #include <sys/wait.h> 45 46 #elif defined (__FreeBSD__) 47 48 #include <sys/wait.h> 49 #include <sys/sysctl.h> 50 #include <pthread_np.h> 51 52 #endif 53 54 using namespace lldb; 55 using namespace lldb_private; 56 57 struct MonitorInfo 58 { 59 lldb::pid_t pid; // The process ID to monitor 60 Host::MonitorChildProcessCallback callback; // The callback function to call when "pid" exits or signals 61 void *callback_baton; // The callback baton for the callback function 62 bool monitor_signals; // If true, call the callback when "pid" gets signaled. 63 }; 64 65 static void * 66 MonitorChildProcessThreadFunction (void *arg); 67 68 lldb::thread_t 69 Host::StartMonitoringChildProcess 70 ( 71 Host::MonitorChildProcessCallback callback, 72 void *callback_baton, 73 lldb::pid_t pid, 74 bool monitor_signals 75 ) 76 { 77 lldb::thread_t thread = LLDB_INVALID_HOST_THREAD; 78 if (callback) 79 { 80 std::auto_ptr<MonitorInfo> info_ap(new MonitorInfo); 81 82 info_ap->pid = pid; 83 info_ap->callback = callback; 84 info_ap->callback_baton = callback_baton; 85 info_ap->monitor_signals = monitor_signals; 86 87 char thread_name[256]; 88 ::snprintf (thread_name, sizeof(thread_name), "<lldb.host.wait4(pid=%i)>", pid); 89 thread = ThreadCreate (thread_name, 90 MonitorChildProcessThreadFunction, 91 info_ap.get(), 92 NULL); 93 94 if (IS_VALID_LLDB_HOST_THREAD(thread)) 95 info_ap.release(); 96 } 97 return thread; 98 } 99 100 //------------------------------------------------------------------ 101 // Scoped class that will disable thread canceling when it is 102 // constructed, and exception safely restore the previous value it 103 // when it goes out of scope. 104 //------------------------------------------------------------------ 105 class ScopedPThreadCancelDisabler 106 { 107 public: 108 ScopedPThreadCancelDisabler() 109 { 110 // Disable the ability for this thread to be cancelled 111 int err = ::pthread_setcancelstate (PTHREAD_CANCEL_DISABLE, &m_old_state); 112 if (err != 0) 113 m_old_state = -1; 114 115 } 116 117 ~ScopedPThreadCancelDisabler() 118 { 119 // Restore the ability for this thread to be cancelled to what it 120 // previously was. 121 if (m_old_state != -1) 122 ::pthread_setcancelstate (m_old_state, 0); 123 } 124 private: 125 int m_old_state; // Save the old cancelability state. 126 }; 127 128 static void * 129 MonitorChildProcessThreadFunction (void *arg) 130 { 131 LogSP log(lldb_private::GetLogIfAllCategoriesSet (LIBLLDB_LOG_PROCESS)); 132 const char *function = __FUNCTION__; 133 if (log) 134 log->Printf ("%s (arg = %p) thread starting...", function, arg); 135 136 MonitorInfo *info = (MonitorInfo *)arg; 137 138 const Host::MonitorChildProcessCallback callback = info->callback; 139 void * const callback_baton = info->callback_baton; 140 const lldb::pid_t pid = info->pid; 141 const bool monitor_signals = info->monitor_signals; 142 143 delete info; 144 145 int status = -1; 146 const int options = 0; 147 struct rusage *rusage = NULL; 148 while (1) 149 { 150 log = lldb_private::GetLogIfAllCategoriesSet (LIBLLDB_LOG_PROCESS); 151 if (log) 152 log->Printf("%s ::wait4 (pid = %i, &status, options = %i, rusage = %p)...", function, pid, options, rusage); 153 154 // Wait for all child processes 155 ::pthread_testcancel (); 156 const lldb::pid_t wait_pid = ::wait4 (pid, &status, options, rusage); 157 ::pthread_testcancel (); 158 159 if (wait_pid == -1) 160 { 161 if (errno == EINTR) 162 continue; 163 else 164 break; 165 } 166 else if (wait_pid == pid) 167 { 168 bool exited = false; 169 int signal = 0; 170 int exit_status = 0; 171 const char *status_cstr = NULL; 172 if (WIFSTOPPED(status)) 173 { 174 signal = WSTOPSIG(status); 175 status_cstr = "STOPPED"; 176 } 177 else if (WIFEXITED(status)) 178 { 179 exit_status = WEXITSTATUS(status); 180 status_cstr = "EXITED"; 181 exited = true; 182 } 183 else if (WIFSIGNALED(status)) 184 { 185 signal = WTERMSIG(status); 186 status_cstr = "SIGNALED"; 187 exited = true; 188 exit_status = -1; 189 } 190 else 191 { 192 status_cstr = "(\?\?\?)"; 193 } 194 195 // Scope for pthread_cancel_disabler 196 { 197 ScopedPThreadCancelDisabler pthread_cancel_disabler; 198 199 log = lldb_private::GetLogIfAllCategoriesSet (LIBLLDB_LOG_PROCESS); 200 if (log) 201 log->Printf ("%s ::wait4 (pid = %i, &status, options = %i, rusage = %p) => pid = %i, status = 0x%8.8x (%s), signal = %i, exit_state = %i", 202 function, 203 wait_pid, 204 options, 205 rusage, 206 pid, 207 status, 208 status_cstr, 209 signal, 210 exit_status); 211 212 if (exited || (signal != 0 && monitor_signals)) 213 { 214 bool callback_return = callback (callback_baton, pid, signal, exit_status); 215 216 // If our process exited, then this thread should exit 217 if (exited) 218 break; 219 // If the callback returns true, it means this process should 220 // exit 221 if (callback_return) 222 break; 223 } 224 } 225 } 226 } 227 228 log = lldb_private::GetLogIfAllCategoriesSet (LIBLLDB_LOG_PROCESS); 229 if (log) 230 log->Printf ("%s (arg = %p) thread exiting...", __FUNCTION__, arg); 231 232 return NULL; 233 } 234 235 size_t 236 Host::GetPageSize() 237 { 238 return ::getpagesize(); 239 } 240 241 const ArchSpec & 242 Host::GetArchitecture (SystemDefaultArchitecture arch_kind) 243 { 244 static bool g_supports_32 = false; 245 static bool g_supports_64 = false; 246 static ArchSpec g_host_arch_32; 247 static ArchSpec g_host_arch_64; 248 249 #if defined (__APPLE__) 250 251 // Apple is different in that it can support both 32 and 64 bit executables 252 // in the same operating system running concurrently. Here we detect the 253 // correct host architectures for both 32 and 64 bit including if 64 bit 254 // executables are supported on the system. 255 256 if (g_supports_32 == false && g_supports_64 == false) 257 { 258 // All apple systems support 32 bit execution. 259 g_supports_32 = true; 260 uint32_t cputype, cpusubtype; 261 uint32_t is_64_bit_capable = false; 262 size_t len = sizeof(cputype); 263 ArchSpec host_arch; 264 // These will tell us about the kernel architecture, which even on a 64 265 // bit machine can be 32 bit... 266 if (::sysctlbyname("hw.cputype", &cputype, &len, NULL, 0) == 0) 267 { 268 len = sizeof (cpusubtype); 269 if (::sysctlbyname("hw.cpusubtype", &cpusubtype, &len, NULL, 0) != 0) 270 cpusubtype = CPU_TYPE_ANY; 271 272 len = sizeof (is_64_bit_capable); 273 if (::sysctlbyname("hw.cpu64bit_capable", &is_64_bit_capable, &len, NULL, 0) == 0) 274 { 275 if (is_64_bit_capable) 276 g_supports_64 = true; 277 } 278 279 if (is_64_bit_capable) 280 { 281 #if defined (__i386__) || defined (__x86_64__) 282 if (cpusubtype == CPU_SUBTYPE_486) 283 cpusubtype = CPU_SUBTYPE_I386_ALL; 284 #endif 285 if (cputype & CPU_ARCH_ABI64) 286 { 287 // We have a 64 bit kernel on a 64 bit system 288 g_host_arch_32.SetArchitecture (eArchTypeMachO, ~(CPU_ARCH_MASK) & cputype, cpusubtype); 289 g_host_arch_64.SetArchitecture (eArchTypeMachO, cputype, cpusubtype); 290 } 291 else 292 { 293 // We have a 32 bit kernel on a 64 bit system 294 g_host_arch_32.SetArchitecture (eArchTypeMachO, cputype, cpusubtype); 295 cputype |= CPU_ARCH_ABI64; 296 g_host_arch_64.SetArchitecture (eArchTypeMachO, cputype, cpusubtype); 297 } 298 } 299 else 300 { 301 g_host_arch_32.SetArchitecture (eArchTypeMachO, cputype, cpusubtype); 302 g_host_arch_64.Clear(); 303 } 304 } 305 } 306 307 #else // #if defined (__APPLE__) 308 309 if (g_supports_32 == false && g_supports_64 == false) 310 { 311 llvm::Triple triple(llvm::sys::getHostTriple()); 312 313 g_host_arch_32.Clear(); 314 g_host_arch_64.Clear(); 315 316 switch (triple.getArch()) 317 { 318 default: 319 g_host_arch_32.SetTriple(triple); 320 g_supports_32 = true; 321 break; 322 323 case llvm::Triple::alpha: 324 case llvm::Triple::x86_64: 325 case llvm::Triple::sparcv9: 326 case llvm::Triple::ppc64: 327 case llvm::Triple::systemz: 328 case llvm::Triple::cellspu: 329 g_host_arch_64.SetTriple(triple); 330 g_supports_64 = true; 331 break; 332 } 333 334 g_supports_32 = g_host_arch_32.IsValid(); 335 g_supports_64 = g_host_arch_64.IsValid(); 336 } 337 338 #endif // #else for #if defined (__APPLE__) 339 340 if (arch_kind == eSystemDefaultArchitecture32) 341 return g_host_arch_32; 342 else if (arch_kind == eSystemDefaultArchitecture64) 343 return g_host_arch_64; 344 345 if (g_supports_64) 346 return g_host_arch_64; 347 348 return g_host_arch_32; 349 } 350 351 const ConstString & 352 Host::GetVendorString() 353 { 354 static ConstString g_vendor; 355 if (!g_vendor) 356 { 357 #if defined (__APPLE__) 358 char ostype[64]; 359 size_t len = sizeof(ostype); 360 if (::sysctlbyname("kern.ostype", &ostype, &len, NULL, 0) == 0) 361 g_vendor.SetCString (ostype); 362 else 363 g_vendor.SetCString("apple"); 364 #elif defined (__linux__) 365 g_vendor.SetCString("gnu"); 366 #elif defined (__FreeBSD__) 367 g_vendor.SetCString("freebsd"); 368 #endif 369 } 370 return g_vendor; 371 } 372 373 const ConstString & 374 Host::GetOSString() 375 { 376 static ConstString g_os_string; 377 if (!g_os_string) 378 { 379 #if defined (__APPLE__) 380 g_os_string.SetCString("darwin"); 381 #elif defined (__linux__) 382 g_os_string.SetCString("linux"); 383 #elif defined (__FreeBSD__) 384 g_os_string.SetCString("freebsd"); 385 #endif 386 } 387 return g_os_string; 388 } 389 390 const ConstString & 391 Host::GetTargetTriple() 392 { 393 static ConstString g_host_triple; 394 if (!(g_host_triple)) 395 { 396 StreamString triple; 397 triple.Printf("%s-%s-%s", 398 GetArchitecture().GetArchitectureName(), 399 GetVendorString().AsCString(), 400 GetOSString().AsCString()); 401 402 std::transform (triple.GetString().begin(), 403 triple.GetString().end(), 404 triple.GetString().begin(), 405 ::tolower); 406 407 g_host_triple.SetCString(triple.GetString().c_str()); 408 } 409 return g_host_triple; 410 } 411 412 lldb::pid_t 413 Host::GetCurrentProcessID() 414 { 415 return ::getpid(); 416 } 417 418 lldb::tid_t 419 Host::GetCurrentThreadID() 420 { 421 #if defined (__APPLE__) 422 return ::mach_thread_self(); 423 #elif defined(__FreeBSD__) 424 return lldb::tid_t(pthread_getthreadid_np()); 425 #else 426 return lldb::tid_t(pthread_self()); 427 #endif 428 } 429 430 const char * 431 Host::GetSignalAsCString (int signo) 432 { 433 switch (signo) 434 { 435 case SIGHUP: return "SIGHUP"; // 1 hangup 436 case SIGINT: return "SIGINT"; // 2 interrupt 437 case SIGQUIT: return "SIGQUIT"; // 3 quit 438 case SIGILL: return "SIGILL"; // 4 illegal instruction (not reset when caught) 439 case SIGTRAP: return "SIGTRAP"; // 5 trace trap (not reset when caught) 440 case SIGABRT: return "SIGABRT"; // 6 abort() 441 #if defined(_POSIX_C_SOURCE) 442 case SIGPOLL: return "SIGPOLL"; // 7 pollable event ([XSR] generated, not supported) 443 #else // !_POSIX_C_SOURCE 444 case SIGEMT: return "SIGEMT"; // 7 EMT instruction 445 #endif // !_POSIX_C_SOURCE 446 case SIGFPE: return "SIGFPE"; // 8 floating point exception 447 case SIGKILL: return "SIGKILL"; // 9 kill (cannot be caught or ignored) 448 case SIGBUS: return "SIGBUS"; // 10 bus error 449 case SIGSEGV: return "SIGSEGV"; // 11 segmentation violation 450 case SIGSYS: return "SIGSYS"; // 12 bad argument to system call 451 case SIGPIPE: return "SIGPIPE"; // 13 write on a pipe with no one to read it 452 case SIGALRM: return "SIGALRM"; // 14 alarm clock 453 case SIGTERM: return "SIGTERM"; // 15 software termination signal from kill 454 case SIGURG: return "SIGURG"; // 16 urgent condition on IO channel 455 case SIGSTOP: return "SIGSTOP"; // 17 sendable stop signal not from tty 456 case SIGTSTP: return "SIGTSTP"; // 18 stop signal from tty 457 case SIGCONT: return "SIGCONT"; // 19 continue a stopped process 458 case SIGCHLD: return "SIGCHLD"; // 20 to parent on child stop or exit 459 case SIGTTIN: return "SIGTTIN"; // 21 to readers pgrp upon background tty read 460 case SIGTTOU: return "SIGTTOU"; // 22 like TTIN for output if (tp->t_local<OSTOP) 461 #if !defined(_POSIX_C_SOURCE) 462 case SIGIO: return "SIGIO"; // 23 input/output possible signal 463 #endif 464 case SIGXCPU: return "SIGXCPU"; // 24 exceeded CPU time limit 465 case SIGXFSZ: return "SIGXFSZ"; // 25 exceeded file size limit 466 case SIGVTALRM: return "SIGVTALRM"; // 26 virtual time alarm 467 case SIGPROF: return "SIGPROF"; // 27 profiling time alarm 468 #if !defined(_POSIX_C_SOURCE) 469 case SIGWINCH: return "SIGWINCH"; // 28 window size changes 470 case SIGINFO: return "SIGINFO"; // 29 information request 471 #endif 472 case SIGUSR1: return "SIGUSR1"; // 30 user defined signal 1 473 case SIGUSR2: return "SIGUSR2"; // 31 user defined signal 2 474 default: 475 break; 476 } 477 return NULL; 478 } 479 480 void 481 Host::WillTerminate () 482 { 483 } 484 485 #if !defined (__APPLE__) && !defined (__FreeBSD__) // see macosx/Host.mm 486 void 487 Host::ThreadCreated (const char *thread_name) 488 { 489 } 490 491 void 492 Host::Backtrace (Stream &strm, uint32_t max_frames) 493 { 494 // TODO: Is there a way to backtrace the current process on linux? Other systems? 495 } 496 497 size_t 498 Host::GetEnvironment (StringList &env) 499 { 500 // TODO: Is there a way to the host environment for this process on linux? Other systems? 501 return 0; 502 } 503 504 #endif 505 506 struct HostThreadCreateInfo 507 { 508 std::string thread_name; 509 thread_func_t thread_fptr; 510 thread_arg_t thread_arg; 511 512 HostThreadCreateInfo (const char *name, thread_func_t fptr, thread_arg_t arg) : 513 thread_name (name ? name : ""), 514 thread_fptr (fptr), 515 thread_arg (arg) 516 { 517 } 518 }; 519 520 static thread_result_t 521 ThreadCreateTrampoline (thread_arg_t arg) 522 { 523 HostThreadCreateInfo *info = (HostThreadCreateInfo *)arg; 524 Host::ThreadCreated (info->thread_name.c_str()); 525 thread_func_t thread_fptr = info->thread_fptr; 526 thread_arg_t thread_arg = info->thread_arg; 527 528 LogSP log(lldb_private::GetLogIfAllCategoriesSet (LIBLLDB_LOG_THREAD)); 529 if (log) 530 log->Printf("thread created"); 531 532 delete info; 533 return thread_fptr (thread_arg); 534 } 535 536 lldb::thread_t 537 Host::ThreadCreate 538 ( 539 const char *thread_name, 540 thread_func_t thread_fptr, 541 thread_arg_t thread_arg, 542 Error *error 543 ) 544 { 545 lldb::thread_t thread = LLDB_INVALID_HOST_THREAD; 546 547 // Host::ThreadCreateTrampoline will delete this pointer for us. 548 HostThreadCreateInfo *info_ptr = new HostThreadCreateInfo (thread_name, thread_fptr, thread_arg); 549 550 int err = ::pthread_create (&thread, NULL, ThreadCreateTrampoline, info_ptr); 551 if (err == 0) 552 { 553 if (error) 554 error->Clear(); 555 return thread; 556 } 557 558 if (error) 559 error->SetError (err, eErrorTypePOSIX); 560 561 return LLDB_INVALID_HOST_THREAD; 562 } 563 564 bool 565 Host::ThreadCancel (lldb::thread_t thread, Error *error) 566 { 567 int err = ::pthread_cancel (thread); 568 if (error) 569 error->SetError(err, eErrorTypePOSIX); 570 return err == 0; 571 } 572 573 bool 574 Host::ThreadDetach (lldb::thread_t thread, Error *error) 575 { 576 int err = ::pthread_detach (thread); 577 if (error) 578 error->SetError(err, eErrorTypePOSIX); 579 return err == 0; 580 } 581 582 bool 583 Host::ThreadJoin (lldb::thread_t thread, thread_result_t *thread_result_ptr, Error *error) 584 { 585 int err = ::pthread_join (thread, thread_result_ptr); 586 if (error) 587 error->SetError(err, eErrorTypePOSIX); 588 return err == 0; 589 } 590 591 //------------------------------------------------------------------ 592 // Control access to a static file thread name map using a single 593 // static function to avoid a static constructor. 594 //------------------------------------------------------------------ 595 static const char * 596 ThreadNameAccessor (bool get, lldb::pid_t pid, lldb::tid_t tid, const char *name) 597 { 598 uint64_t pid_tid = ((uint64_t)pid << 32) | (uint64_t)tid; 599 600 static pthread_mutex_t g_mutex = PTHREAD_MUTEX_INITIALIZER; 601 Mutex::Locker locker(&g_mutex); 602 603 typedef std::map<uint64_t, std::string> thread_name_map; 604 // rdar://problem/8153284 605 // Fixed a crasher where during shutdown, loggings attempted to access the 606 // thread name but the static map instance had already been destructed. 607 // Another approach is to introduce a static guard object which monitors its 608 // own destruction and raises a flag, but this incurs more overhead. 609 static thread_name_map *g_thread_names_ptr = new thread_name_map(); 610 thread_name_map &g_thread_names = *g_thread_names_ptr; 611 612 if (get) 613 { 614 // See if the thread name exists in our thread name pool 615 thread_name_map::iterator pos = g_thread_names.find(pid_tid); 616 if (pos != g_thread_names.end()) 617 return pos->second.c_str(); 618 } 619 else 620 { 621 // Set the thread name 622 g_thread_names[pid_tid] = name; 623 } 624 return NULL; 625 } 626 627 const char * 628 Host::GetThreadName (lldb::pid_t pid, lldb::tid_t tid) 629 { 630 const char *name = ThreadNameAccessor (true, pid, tid, NULL); 631 if (name == NULL) 632 { 633 #if defined(__APPLE__) && MAC_OS_X_VERSION_MAX_ALLOWED > MAC_OS_X_VERSION_10_5 634 // We currently can only get the name of a thread in the current process. 635 if (pid == Host::GetCurrentProcessID()) 636 { 637 char pthread_name[1024]; 638 if (::pthread_getname_np (::pthread_from_mach_thread_np (tid), pthread_name, sizeof(pthread_name)) == 0) 639 { 640 if (pthread_name[0]) 641 { 642 // Set the thread in our string pool 643 ThreadNameAccessor (false, pid, tid, pthread_name); 644 // Get our copy of the thread name string 645 name = ThreadNameAccessor (true, pid, tid, NULL); 646 } 647 } 648 649 if (name == NULL) 650 { 651 dispatch_queue_t current_queue = ::dispatch_get_current_queue (); 652 if (current_queue != NULL) 653 name = dispatch_queue_get_label (current_queue); 654 } 655 } 656 #endif 657 } 658 return name; 659 } 660 661 void 662 Host::SetThreadName (lldb::pid_t pid, lldb::tid_t tid, const char *name) 663 { 664 lldb::pid_t curr_pid = Host::GetCurrentProcessID(); 665 lldb::tid_t curr_tid = Host::GetCurrentThreadID(); 666 if (pid == LLDB_INVALID_PROCESS_ID) 667 pid = curr_pid; 668 669 if (tid == LLDB_INVALID_THREAD_ID) 670 tid = curr_tid; 671 672 #if defined(__APPLE__) && MAC_OS_X_VERSION_MAX_ALLOWED > MAC_OS_X_VERSION_10_5 673 // Set the pthread name if possible 674 if (pid == curr_pid && tid == curr_tid) 675 { 676 ::pthread_setname_np (name); 677 } 678 #endif 679 ThreadNameAccessor (false, pid, tid, name); 680 } 681 682 FileSpec 683 Host::GetProgramFileSpec () 684 { 685 static FileSpec g_program_filespec; 686 if (!g_program_filespec) 687 { 688 #if defined (__APPLE__) 689 char program_fullpath[PATH_MAX]; 690 // If DST is NULL, then return the number of bytes needed. 691 uint32_t len = sizeof(program_fullpath); 692 int err = _NSGetExecutablePath (program_fullpath, &len); 693 if (err == 0) 694 g_program_filespec.SetFile (program_fullpath, false); 695 else if (err == -1) 696 { 697 char *large_program_fullpath = (char *)::malloc (len + 1); 698 699 err = _NSGetExecutablePath (large_program_fullpath, &len); 700 if (err == 0) 701 g_program_filespec.SetFile (large_program_fullpath, false); 702 703 ::free (large_program_fullpath); 704 } 705 #elif defined (__linux__) 706 char exe_path[PATH_MAX]; 707 ssize_t len = readlink("/proc/self/exe", exe_path, sizeof(exe_path) - 1); 708 if (len > 0) { 709 exe_path[len] = 0; 710 g_program_filespec.SetFile(exe_path, false); 711 } 712 #elif defined (__FreeBSD__) 713 int exe_path_mib[4] = { CTL_KERN, KERN_PROC, KERN_PROC_PATHNAME, getpid() }; 714 size_t exe_path_size; 715 if (sysctl(exe_path_mib, 4, NULL, &exe_path_size, NULL, 0) == 0) 716 { 717 char *exe_path = new char[exe_path_size]; 718 if (sysctl(exe_path_mib, 4, exe_path, &exe_path_size, NULL, 0) == 0) 719 g_program_filespec.SetFile(exe_path, false); 720 delete[] exe_path; 721 } 722 #endif 723 } 724 return g_program_filespec; 725 } 726 727 FileSpec 728 Host::GetModuleFileSpecForHostAddress (const void *host_addr) 729 { 730 FileSpec module_filespec; 731 Dl_info info; 732 if (::dladdr (host_addr, &info)) 733 { 734 if (info.dli_fname) 735 module_filespec.SetFile(info.dli_fname, true); 736 } 737 return module_filespec; 738 } 739 740 #if !defined (__APPLE__) // see Host.mm 741 bool 742 Host::ResolveExecutableInBundle (FileSpec &file) 743 { 744 return false; 745 } 746 #endif 747 748 // Opaque info that tracks a dynamic library that was loaded 749 struct DynamicLibraryInfo 750 { 751 DynamicLibraryInfo (const FileSpec &fs, int o, void *h) : 752 file_spec (fs), 753 open_options (o), 754 handle (h) 755 { 756 } 757 758 const FileSpec file_spec; 759 uint32_t open_options; 760 void * handle; 761 }; 762 763 void * 764 Host::DynamicLibraryOpen (const FileSpec &file_spec, uint32_t options, Error &error) 765 { 766 char path[PATH_MAX]; 767 if (file_spec.GetPath(path, sizeof(path))) 768 { 769 int mode = 0; 770 771 if (options & eDynamicLibraryOpenOptionLazy) 772 mode |= RTLD_LAZY; 773 else 774 mode |= RTLD_NOW; 775 776 777 if (options & eDynamicLibraryOpenOptionLocal) 778 mode |= RTLD_LOCAL; 779 else 780 mode |= RTLD_GLOBAL; 781 782 #ifdef LLDB_CONFIG_DLOPEN_RTLD_FIRST_SUPPORTED 783 if (options & eDynamicLibraryOpenOptionLimitGetSymbol) 784 mode |= RTLD_FIRST; 785 #endif 786 787 void * opaque = ::dlopen (path, mode); 788 789 if (opaque) 790 { 791 error.Clear(); 792 return new DynamicLibraryInfo (file_spec, options, opaque); 793 } 794 else 795 { 796 error.SetErrorString(::dlerror()); 797 } 798 } 799 else 800 { 801 error.SetErrorString("failed to extract path"); 802 } 803 return NULL; 804 } 805 806 Error 807 Host::DynamicLibraryClose (void *opaque) 808 { 809 Error error; 810 if (opaque == NULL) 811 { 812 error.SetErrorString ("invalid dynamic library handle"); 813 } 814 else 815 { 816 DynamicLibraryInfo *dylib_info = (DynamicLibraryInfo *) opaque; 817 if (::dlclose (dylib_info->handle) != 0) 818 { 819 error.SetErrorString(::dlerror()); 820 } 821 822 dylib_info->open_options = 0; 823 dylib_info->handle = 0; 824 delete dylib_info; 825 } 826 return error; 827 } 828 829 void * 830 Host::DynamicLibraryGetSymbol (void *opaque, const char *symbol_name, Error &error) 831 { 832 if (opaque == NULL) 833 { 834 error.SetErrorString ("invalid dynamic library handle"); 835 } 836 else 837 { 838 DynamicLibraryInfo *dylib_info = (DynamicLibraryInfo *) opaque; 839 840 void *symbol_addr = ::dlsym (dylib_info->handle, symbol_name); 841 if (symbol_addr) 842 { 843 #ifndef LLDB_CONFIG_DLOPEN_RTLD_FIRST_SUPPORTED 844 // This host doesn't support limiting searches to this shared library 845 // so we need to verify that the match came from this shared library 846 // if it was requested in the Host::DynamicLibraryOpen() function. 847 if (dylib_info->open_options & eDynamicLibraryOpenOptionLimitGetSymbol) 848 { 849 FileSpec match_dylib_spec (Host::GetModuleFileSpecForHostAddress (symbol_addr)); 850 if (match_dylib_spec != dylib_info->file_spec) 851 { 852 char dylib_path[PATH_MAX]; 853 if (dylib_info->file_spec.GetPath (dylib_path, sizeof(dylib_path))) 854 error.SetErrorStringWithFormat ("symbol not found in \"%s\"", dylib_path); 855 else 856 error.SetErrorString ("symbol not found"); 857 return NULL; 858 } 859 } 860 #endif 861 error.Clear(); 862 return symbol_addr; 863 } 864 else 865 { 866 error.SetErrorString(::dlerror()); 867 } 868 } 869 return NULL; 870 } 871 872 bool 873 Host::GetLLDBPath (PathType path_type, FileSpec &file_spec) 874 { 875 // To get paths related to LLDB we get the path to the executable that 876 // contains this function. On MacOSX this will be "LLDB.framework/.../LLDB", 877 // on linux this is assumed to be the "lldb" main executable. If LLDB on 878 // linux is actually in a shared library (lldb.so??) then this function will 879 // need to be modified to "do the right thing". 880 881 switch (path_type) 882 { 883 case ePathTypeLLDBShlibDir: 884 { 885 static ConstString g_lldb_so_dir; 886 if (!g_lldb_so_dir) 887 { 888 FileSpec lldb_file_spec (Host::GetModuleFileSpecForHostAddress ((void *)Host::GetLLDBPath)); 889 g_lldb_so_dir = lldb_file_spec.GetDirectory(); 890 } 891 file_spec.GetDirectory() = g_lldb_so_dir; 892 return file_spec.GetDirectory(); 893 } 894 break; 895 896 case ePathTypeSupportExecutableDir: 897 { 898 static ConstString g_lldb_support_exe_dir; 899 if (!g_lldb_support_exe_dir) 900 { 901 FileSpec lldb_file_spec; 902 if (GetLLDBPath (ePathTypeLLDBShlibDir, lldb_file_spec)) 903 { 904 char raw_path[PATH_MAX]; 905 char resolved_path[PATH_MAX]; 906 lldb_file_spec.GetPath(raw_path, sizeof(raw_path)); 907 908 #if defined (__APPLE__) 909 char *framework_pos = ::strstr (raw_path, "LLDB.framework"); 910 if (framework_pos) 911 { 912 framework_pos += strlen("LLDB.framework"); 913 ::strncpy (framework_pos, "/Resources", PATH_MAX - (framework_pos - raw_path)); 914 } 915 #endif 916 FileSpec::Resolve (raw_path, resolved_path, sizeof(resolved_path)); 917 g_lldb_support_exe_dir.SetCString(resolved_path); 918 } 919 } 920 file_spec.GetDirectory() = g_lldb_support_exe_dir; 921 return file_spec.GetDirectory(); 922 } 923 break; 924 925 case ePathTypeHeaderDir: 926 { 927 static ConstString g_lldb_headers_dir; 928 if (!g_lldb_headers_dir) 929 { 930 #if defined (__APPLE__) 931 FileSpec lldb_file_spec; 932 if (GetLLDBPath (ePathTypeLLDBShlibDir, lldb_file_spec)) 933 { 934 char raw_path[PATH_MAX]; 935 char resolved_path[PATH_MAX]; 936 lldb_file_spec.GetPath(raw_path, sizeof(raw_path)); 937 938 char *framework_pos = ::strstr (raw_path, "LLDB.framework"); 939 if (framework_pos) 940 { 941 framework_pos += strlen("LLDB.framework"); 942 ::strncpy (framework_pos, "/Headers", PATH_MAX - (framework_pos - raw_path)); 943 } 944 FileSpec::Resolve (raw_path, resolved_path, sizeof(resolved_path)); 945 g_lldb_headers_dir.SetCString(resolved_path); 946 } 947 #else 948 // TODO: Anyone know how we can determine this for linux? Other systems?? 949 g_lldb_headers_dir.SetCString ("/opt/local/include/lldb"); 950 #endif 951 } 952 file_spec.GetDirectory() = g_lldb_headers_dir; 953 return file_spec.GetDirectory(); 954 } 955 break; 956 957 case ePathTypePythonDir: 958 { 959 // TODO: Anyone know how we can determine this for linux? Other systems? 960 // For linux we are currently assuming the location of the lldb 961 // binary that contains this function is the directory that will 962 // contain lldb.so, lldb.py and embedded_interpreter.py... 963 964 static ConstString g_lldb_python_dir; 965 if (!g_lldb_python_dir) 966 { 967 FileSpec lldb_file_spec; 968 if (GetLLDBPath (ePathTypeLLDBShlibDir, lldb_file_spec)) 969 { 970 char raw_path[PATH_MAX]; 971 char resolved_path[PATH_MAX]; 972 lldb_file_spec.GetPath(raw_path, sizeof(raw_path)); 973 974 #if defined (__APPLE__) 975 char *framework_pos = ::strstr (raw_path, "LLDB.framework"); 976 if (framework_pos) 977 { 978 framework_pos += strlen("LLDB.framework"); 979 ::strncpy (framework_pos, "/Resources/Python", PATH_MAX - (framework_pos - raw_path)); 980 } 981 #endif 982 FileSpec::Resolve (raw_path, resolved_path, sizeof(resolved_path)); 983 g_lldb_python_dir.SetCString(resolved_path); 984 } 985 } 986 file_spec.GetDirectory() = g_lldb_python_dir; 987 return file_spec.GetDirectory(); 988 } 989 break; 990 991 case ePathTypeLLDBSystemPlugins: // System plug-ins directory 992 { 993 #if defined (__APPLE__) 994 static ConstString g_lldb_system_plugin_dir; 995 static bool g_lldb_system_plugin_dir_located = false; 996 if (!g_lldb_system_plugin_dir_located) 997 { 998 g_lldb_system_plugin_dir_located = true; 999 FileSpec lldb_file_spec; 1000 if (GetLLDBPath (ePathTypeLLDBShlibDir, lldb_file_spec)) 1001 { 1002 char raw_path[PATH_MAX]; 1003 char resolved_path[PATH_MAX]; 1004 lldb_file_spec.GetPath(raw_path, sizeof(raw_path)); 1005 1006 char *framework_pos = ::strstr (raw_path, "LLDB.framework"); 1007 if (framework_pos) 1008 { 1009 framework_pos += strlen("LLDB.framework"); 1010 ::strncpy (framework_pos, "/Resources/PlugIns", PATH_MAX - (framework_pos - raw_path)); 1011 FileSpec::Resolve (raw_path, resolved_path, sizeof(resolved_path)); 1012 g_lldb_system_plugin_dir.SetCString(resolved_path); 1013 } 1014 return false; 1015 } 1016 } 1017 1018 if (g_lldb_system_plugin_dir) 1019 { 1020 file_spec.GetDirectory() = g_lldb_system_plugin_dir; 1021 return true; 1022 } 1023 #endif 1024 // TODO: where would system LLDB plug-ins be located on linux? Other systems? 1025 return false; 1026 } 1027 break; 1028 1029 case ePathTypeLLDBUserPlugins: // User plug-ins directory 1030 { 1031 #if defined (__APPLE__) 1032 static ConstString g_lldb_user_plugin_dir; 1033 if (!g_lldb_user_plugin_dir) 1034 { 1035 char user_plugin_path[PATH_MAX]; 1036 if (FileSpec::Resolve ("~/Library/Application Support/LLDB/PlugIns", 1037 user_plugin_path, 1038 sizeof(user_plugin_path))) 1039 { 1040 g_lldb_user_plugin_dir.SetCString(user_plugin_path); 1041 } 1042 } 1043 file_spec.GetDirectory() = g_lldb_user_plugin_dir; 1044 return file_spec.GetDirectory(); 1045 #endif 1046 // TODO: where would user LLDB plug-ins be located on linux? Other systems? 1047 return false; 1048 } 1049 default: 1050 assert (!"Unhandled PathType"); 1051 break; 1052 } 1053 1054 return false; 1055 } 1056 1057 1058 bool 1059 Host::GetHostname (std::string &s) 1060 { 1061 char hostname[PATH_MAX]; 1062 hostname[sizeof(hostname) - 1] = '\0'; 1063 if (::gethostname (hostname, sizeof(hostname) - 1) == 0) 1064 { 1065 struct hostent* h = ::gethostbyname (hostname); 1066 if (h) 1067 s.assign (h->h_name); 1068 else 1069 s.assign (hostname); 1070 return true; 1071 } 1072 return false; 1073 } 1074 1075 const char * 1076 Host::GetUserName (uint32_t uid, std::string &user_name) 1077 { 1078 struct passwd user_info; 1079 struct passwd *user_info_ptr = &user_info; 1080 char user_buffer[PATH_MAX]; 1081 size_t user_buffer_size = sizeof(user_buffer); 1082 if (::getpwuid_r (uid, 1083 &user_info, 1084 user_buffer, 1085 user_buffer_size, 1086 &user_info_ptr) == 0) 1087 { 1088 if (user_info_ptr) 1089 { 1090 user_name.assign (user_info_ptr->pw_name); 1091 return user_name.c_str(); 1092 } 1093 } 1094 user_name.clear(); 1095 return NULL; 1096 } 1097 1098 const char * 1099 Host::GetGroupName (uint32_t gid, std::string &group_name) 1100 { 1101 char group_buffer[PATH_MAX]; 1102 size_t group_buffer_size = sizeof(group_buffer); 1103 struct group group_info; 1104 struct group *group_info_ptr = &group_info; 1105 // Try the threadsafe version first 1106 if (::getgrgid_r (gid, 1107 &group_info, 1108 group_buffer, 1109 group_buffer_size, 1110 &group_info_ptr) == 0) 1111 { 1112 if (group_info_ptr) 1113 { 1114 group_name.assign (group_info_ptr->gr_name); 1115 return group_name.c_str(); 1116 } 1117 } 1118 else 1119 { 1120 // The threadsafe version isn't currently working 1121 // for me on darwin, but the non-threadsafe version 1122 // is, so I am calling it below. 1123 group_info_ptr = ::getgrgid (gid); 1124 if (group_info_ptr) 1125 { 1126 group_name.assign (group_info_ptr->gr_name); 1127 return group_name.c_str(); 1128 } 1129 } 1130 group_name.clear(); 1131 return NULL; 1132 } 1133 1134 #if !defined (__APPLE__) && !defined (__FreeBSD__) // see macosx/Host.mm 1135 bool 1136 Host::GetOSBuildString (std::string &s) 1137 { 1138 s.clear(); 1139 return false; 1140 } 1141 1142 bool 1143 Host::GetOSKernelDescription (std::string &s) 1144 { 1145 s.clear(); 1146 return false; 1147 } 1148 #endif 1149 1150 #if !defined(__APPLE__) 1151 uint32_t 1152 Host::FindProcesses (const ProcessInstanceInfoMatch &match_info, ProcessInstanceInfoList &process_infos) 1153 { 1154 process_infos.Clear(); 1155 return process_infos.GetSize(); 1156 } 1157 #endif 1158 1159 #if !defined (__APPLE__) && !defined (__FreeBSD__) 1160 bool 1161 Host::GetProcessInfo (lldb::pid_t pid, ProcessInstanceInfo &process_info) 1162 { 1163 process_info.Clear(); 1164 return false; 1165 } 1166 #endif 1167 1168 #if !defined (__APPLE__) 1169 bool 1170 Host::OpenFileInExternalEditor (const FileSpec &file_spec, uint32_t line_no) 1171 { 1172 return false; 1173 } 1174 1175 void 1176 Host::SetCrashDescriptionWithFormat (const char *format, ...) 1177 { 1178 } 1179 1180 void 1181 Host::SetCrashDescription (const char *description) 1182 { 1183 } 1184 1185 lldb::pid_t 1186 LaunchApplication (const FileSpec &app_file_spec) 1187 { 1188 return LLDB_INVALID_PROCESS_ID; 1189 } 1190 1191 #endif 1192