1 //===-- Host.cpp ------------------------------------------------*- C++ -*-===// 2 // 3 // The LLVM Compiler Infrastructure 4 // 5 // This file is distributed under the University of Illinois Open Source 6 // License. See LICENSE.TXT for details. 7 // 8 //===----------------------------------------------------------------------===// 9 10 #include "lldb/Host/Host.h" 11 #include "lldb/Core/ArchSpec.h" 12 #include "lldb/Core/ConstString.h" 13 #include "lldb/Core/Debugger.h" 14 #include "lldb/Core/Error.h" 15 #include "lldb/Core/Log.h" 16 #include "lldb/Core/StreamString.h" 17 #include "lldb/Host/Config.h" 18 #include "lldb/Host/Endian.h" 19 #include "lldb/Host/FileSpec.h" 20 #include "lldb/Host/Mutex.h" 21 #include "lldb/Target/Process.h" 22 #include "lldb/Target/TargetList.h" 23 24 #include "llvm/Support/Host.h" 25 #include "llvm/Support/MachO.h" 26 27 #include <dlfcn.h> 28 #include <errno.h> 29 #include <grp.h> 30 #include <limits.h> 31 #include <netdb.h> 32 #include <pwd.h> 33 #include <sys/types.h> 34 35 36 #if defined (__APPLE__) 37 38 #include <dispatch/dispatch.h> 39 #include <libproc.h> 40 #include <mach-o/dyld.h> 41 #include <sys/sysctl.h> 42 43 44 #elif defined (__linux__) 45 46 #include <sys/wait.h> 47 48 #elif defined (__FreeBSD__) 49 50 #include <sys/wait.h> 51 #include <sys/sysctl.h> 52 #include <pthread_np.h> 53 54 #endif 55 56 using namespace lldb; 57 using namespace lldb_private; 58 59 60 #if !defined (__APPLE__) 61 struct MonitorInfo 62 { 63 lldb::pid_t pid; // The process ID to monitor 64 Host::MonitorChildProcessCallback callback; // The callback function to call when "pid" exits or signals 65 void *callback_baton; // The callback baton for the callback function 66 bool monitor_signals; // If true, call the callback when "pid" gets signaled. 67 }; 68 69 static void * 70 MonitorChildProcessThreadFunction (void *arg); 71 72 lldb::thread_t 73 Host::StartMonitoringChildProcess 74 ( 75 Host::MonitorChildProcessCallback callback, 76 void *callback_baton, 77 lldb::pid_t pid, 78 bool monitor_signals 79 ) 80 { 81 lldb::thread_t thread = LLDB_INVALID_HOST_THREAD; 82 MonitorInfo * info_ptr = new MonitorInfo(); 83 84 info_ptr->pid = pid; 85 info_ptr->callback = callback; 86 info_ptr->callback_baton = callback_baton; 87 info_ptr->monitor_signals = monitor_signals; 88 89 char thread_name[256]; 90 ::snprintf (thread_name, sizeof(thread_name), "<lldb.host.wait4(pid=%i)>", pid); 91 thread = ThreadCreate (thread_name, 92 MonitorChildProcessThreadFunction, 93 info_ptr, 94 NULL); 95 96 return thread; 97 } 98 99 //------------------------------------------------------------------ 100 // Scoped class that will disable thread canceling when it is 101 // constructed, and exception safely restore the previous value it 102 // when it goes out of scope. 103 //------------------------------------------------------------------ 104 class ScopedPThreadCancelDisabler 105 { 106 public: 107 ScopedPThreadCancelDisabler() 108 { 109 // Disable the ability for this thread to be cancelled 110 int err = ::pthread_setcancelstate (PTHREAD_CANCEL_DISABLE, &m_old_state); 111 if (err != 0) 112 m_old_state = -1; 113 114 } 115 116 ~ScopedPThreadCancelDisabler() 117 { 118 // Restore the ability for this thread to be cancelled to what it 119 // previously was. 120 if (m_old_state != -1) 121 ::pthread_setcancelstate (m_old_state, 0); 122 } 123 private: 124 int m_old_state; // Save the old cancelability state. 125 }; 126 127 static void * 128 MonitorChildProcessThreadFunction (void *arg) 129 { 130 LogSP log(lldb_private::GetLogIfAllCategoriesSet (LIBLLDB_LOG_PROCESS)); 131 const char *function = __FUNCTION__; 132 if (log) 133 log->Printf ("%s (arg = %p) thread starting...", function, arg); 134 135 MonitorInfo *info = (MonitorInfo *)arg; 136 137 const Host::MonitorChildProcessCallback callback = info->callback; 138 void * const callback_baton = info->callback_baton; 139 const lldb::pid_t pid = info->pid; 140 const bool monitor_signals = info->monitor_signals; 141 142 delete info; 143 144 int status = -1; 145 const int options = 0; 146 while (1) 147 { 148 log = lldb_private::GetLogIfAllCategoriesSet (LIBLLDB_LOG_PROCESS); 149 if (log) 150 log->Printf("%s ::wait_pid (pid = %i, &status, options = %i)...", function, pid, options); 151 152 // Wait for all child processes 153 ::pthread_testcancel (); 154 const lldb::pid_t wait_pid = ::waitpid (pid, &status, options); 155 ::pthread_testcancel (); 156 157 if (wait_pid == -1) 158 { 159 if (errno == EINTR) 160 continue; 161 else 162 break; 163 } 164 else if (wait_pid == pid) 165 { 166 bool exited = false; 167 int signal = 0; 168 int exit_status = 0; 169 const char *status_cstr = NULL; 170 if (WIFSTOPPED(status)) 171 { 172 signal = WSTOPSIG(status); 173 status_cstr = "STOPPED"; 174 } 175 else if (WIFEXITED(status)) 176 { 177 exit_status = WEXITSTATUS(status); 178 status_cstr = "EXITED"; 179 exited = true; 180 } 181 else if (WIFSIGNALED(status)) 182 { 183 signal = WTERMSIG(status); 184 status_cstr = "SIGNALED"; 185 exited = true; 186 exit_status = -1; 187 } 188 else 189 { 190 status_cstr = "(\?\?\?)"; 191 } 192 193 // Scope for pthread_cancel_disabler 194 { 195 ScopedPThreadCancelDisabler pthread_cancel_disabler; 196 197 log = lldb_private::GetLogIfAllCategoriesSet (LIBLLDB_LOG_PROCESS); 198 if (log) 199 log->Printf ("%s ::waitpid (pid = %i, &status, options = %i) => pid = %i, status = 0x%8.8x (%s), signal = %i, exit_state = %i", 200 function, 201 wait_pid, 202 options, 203 pid, 204 status, 205 status_cstr, 206 signal, 207 exit_status); 208 209 if (exited || (signal != 0 && monitor_signals)) 210 { 211 bool callback_return = false; 212 if (callback) 213 callback_return = callback (callback_baton, pid, exited, signal, exit_status); 214 215 // If our process exited, then this thread should exit 216 if (exited) 217 break; 218 // If the callback returns true, it means this process should 219 // exit 220 if (callback_return) 221 break; 222 } 223 } 224 } 225 } 226 227 log = lldb_private::GetLogIfAllCategoriesSet (LIBLLDB_LOG_PROCESS); 228 if (log) 229 log->Printf ("%s (arg = %p) thread exiting...", __FUNCTION__, arg); 230 231 return NULL; 232 } 233 234 #endif // #if !defined (__APPLE__) 235 236 size_t 237 Host::GetPageSize() 238 { 239 return ::getpagesize(); 240 } 241 242 const ArchSpec & 243 Host::GetArchitecture (SystemDefaultArchitecture arch_kind) 244 { 245 static bool g_supports_32 = false; 246 static bool g_supports_64 = false; 247 static ArchSpec g_host_arch_32; 248 static ArchSpec g_host_arch_64; 249 250 #if defined (__APPLE__) 251 252 // Apple is different in that it can support both 32 and 64 bit executables 253 // in the same operating system running concurrently. Here we detect the 254 // correct host architectures for both 32 and 64 bit including if 64 bit 255 // executables are supported on the system. 256 257 if (g_supports_32 == false && g_supports_64 == false) 258 { 259 // All apple systems support 32 bit execution. 260 g_supports_32 = true; 261 uint32_t cputype, cpusubtype; 262 uint32_t is_64_bit_capable = false; 263 size_t len = sizeof(cputype); 264 ArchSpec host_arch; 265 // These will tell us about the kernel architecture, which even on a 64 266 // bit machine can be 32 bit... 267 if (::sysctlbyname("hw.cputype", &cputype, &len, NULL, 0) == 0) 268 { 269 len = sizeof (cpusubtype); 270 if (::sysctlbyname("hw.cpusubtype", &cpusubtype, &len, NULL, 0) != 0) 271 cpusubtype = CPU_TYPE_ANY; 272 273 len = sizeof (is_64_bit_capable); 274 if (::sysctlbyname("hw.cpu64bit_capable", &is_64_bit_capable, &len, NULL, 0) == 0) 275 { 276 if (is_64_bit_capable) 277 g_supports_64 = true; 278 } 279 280 if (is_64_bit_capable) 281 { 282 #if defined (__i386__) || defined (__x86_64__) 283 if (cpusubtype == CPU_SUBTYPE_486) 284 cpusubtype = CPU_SUBTYPE_I386_ALL; 285 #endif 286 if (cputype & CPU_ARCH_ABI64) 287 { 288 // We have a 64 bit kernel on a 64 bit system 289 g_host_arch_32.SetArchitecture (eArchTypeMachO, ~(CPU_ARCH_MASK) & cputype, cpusubtype); 290 g_host_arch_64.SetArchitecture (eArchTypeMachO, cputype, cpusubtype); 291 } 292 else 293 { 294 // We have a 32 bit kernel on a 64 bit system 295 g_host_arch_32.SetArchitecture (eArchTypeMachO, cputype, cpusubtype); 296 cputype |= CPU_ARCH_ABI64; 297 g_host_arch_64.SetArchitecture (eArchTypeMachO, cputype, cpusubtype); 298 } 299 } 300 else 301 { 302 g_host_arch_32.SetArchitecture (eArchTypeMachO, cputype, cpusubtype); 303 g_host_arch_64.Clear(); 304 } 305 } 306 } 307 308 #else // #if defined (__APPLE__) 309 310 if (g_supports_32 == false && g_supports_64 == false) 311 { 312 llvm::Triple triple(llvm::sys::getDefaultTargetTriple()); 313 314 g_host_arch_32.Clear(); 315 g_host_arch_64.Clear(); 316 317 switch (triple.getArch()) 318 { 319 default: 320 g_host_arch_32.SetTriple(triple); 321 g_supports_32 = true; 322 break; 323 324 case llvm::Triple::x86_64: 325 case llvm::Triple::sparcv9: 326 case llvm::Triple::ppc64: 327 case llvm::Triple::cellspu: 328 g_host_arch_64.SetTriple(triple); 329 g_supports_64 = true; 330 break; 331 } 332 333 g_supports_32 = g_host_arch_32.IsValid(); 334 g_supports_64 = g_host_arch_64.IsValid(); 335 } 336 337 #endif // #else for #if defined (__APPLE__) 338 339 if (arch_kind == eSystemDefaultArchitecture32) 340 return g_host_arch_32; 341 else if (arch_kind == eSystemDefaultArchitecture64) 342 return g_host_arch_64; 343 344 if (g_supports_64) 345 return g_host_arch_64; 346 347 return g_host_arch_32; 348 } 349 350 const ConstString & 351 Host::GetVendorString() 352 { 353 static ConstString g_vendor; 354 if (!g_vendor) 355 { 356 #if defined (__APPLE__) 357 char ostype[64]; 358 size_t len = sizeof(ostype); 359 if (::sysctlbyname("kern.ostype", &ostype, &len, NULL, 0) == 0) 360 g_vendor.SetCString (ostype); 361 else 362 g_vendor.SetCString("apple"); 363 #elif defined (__linux__) 364 g_vendor.SetCString("gnu"); 365 #elif defined (__FreeBSD__) 366 g_vendor.SetCString("freebsd"); 367 #endif 368 } 369 return g_vendor; 370 } 371 372 const ConstString & 373 Host::GetOSString() 374 { 375 static ConstString g_os_string; 376 if (!g_os_string) 377 { 378 #if defined (__APPLE__) 379 g_os_string.SetCString("darwin"); 380 #elif defined (__linux__) 381 g_os_string.SetCString("linux"); 382 #elif defined (__FreeBSD__) 383 g_os_string.SetCString("freebsd"); 384 #endif 385 } 386 return g_os_string; 387 } 388 389 const ConstString & 390 Host::GetTargetTriple() 391 { 392 static ConstString g_host_triple; 393 if (!(g_host_triple)) 394 { 395 StreamString triple; 396 triple.Printf("%s-%s-%s", 397 GetArchitecture().GetArchitectureName(), 398 GetVendorString().AsCString(), 399 GetOSString().AsCString()); 400 401 std::transform (triple.GetString().begin(), 402 triple.GetString().end(), 403 triple.GetString().begin(), 404 ::tolower); 405 406 g_host_triple.SetCString(triple.GetString().c_str()); 407 } 408 return g_host_triple; 409 } 410 411 lldb::pid_t 412 Host::GetCurrentProcessID() 413 { 414 return ::getpid(); 415 } 416 417 lldb::tid_t 418 Host::GetCurrentThreadID() 419 { 420 #if defined (__APPLE__) 421 return ::mach_thread_self(); 422 #elif defined(__FreeBSD__) 423 return lldb::tid_t(pthread_getthreadid_np()); 424 #else 425 return lldb::tid_t(pthread_self()); 426 #endif 427 } 428 429 const char * 430 Host::GetSignalAsCString (int signo) 431 { 432 switch (signo) 433 { 434 case SIGHUP: return "SIGHUP"; // 1 hangup 435 case SIGINT: return "SIGINT"; // 2 interrupt 436 case SIGQUIT: return "SIGQUIT"; // 3 quit 437 case SIGILL: return "SIGILL"; // 4 illegal instruction (not reset when caught) 438 case SIGTRAP: return "SIGTRAP"; // 5 trace trap (not reset when caught) 439 case SIGABRT: return "SIGABRT"; // 6 abort() 440 #if (defined(_POSIX_C_SOURCE) && !defined(_DARWIN_C_SOURCE)) 441 case SIGPOLL: return "SIGPOLL"; // 7 pollable event ([XSR] generated, not supported) 442 #endif 443 #if !defined(_POSIX_C_SOURCE) 444 case SIGEMT: return "SIGEMT"; // 7 EMT instruction 445 #endif 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 #if !defined (__arm__) 914 ::strncpy (framework_pos, "/Resources", PATH_MAX - (framework_pos - raw_path)); 915 #endif 916 } 917 #endif 918 FileSpec::Resolve (raw_path, resolved_path, sizeof(resolved_path)); 919 g_lldb_support_exe_dir.SetCString(resolved_path); 920 } 921 } 922 file_spec.GetDirectory() = g_lldb_support_exe_dir; 923 return file_spec.GetDirectory(); 924 } 925 break; 926 927 case ePathTypeHeaderDir: 928 { 929 static ConstString g_lldb_headers_dir; 930 if (!g_lldb_headers_dir) 931 { 932 #if defined (__APPLE__) 933 FileSpec lldb_file_spec; 934 if (GetLLDBPath (ePathTypeLLDBShlibDir, lldb_file_spec)) 935 { 936 char raw_path[PATH_MAX]; 937 char resolved_path[PATH_MAX]; 938 lldb_file_spec.GetPath(raw_path, sizeof(raw_path)); 939 940 char *framework_pos = ::strstr (raw_path, "LLDB.framework"); 941 if (framework_pos) 942 { 943 framework_pos += strlen("LLDB.framework"); 944 ::strncpy (framework_pos, "/Headers", PATH_MAX - (framework_pos - raw_path)); 945 } 946 FileSpec::Resolve (raw_path, resolved_path, sizeof(resolved_path)); 947 g_lldb_headers_dir.SetCString(resolved_path); 948 } 949 #else 950 // TODO: Anyone know how we can determine this for linux? Other systems?? 951 g_lldb_headers_dir.SetCString ("/opt/local/include/lldb"); 952 #endif 953 } 954 file_spec.GetDirectory() = g_lldb_headers_dir; 955 return file_spec.GetDirectory(); 956 } 957 break; 958 959 case ePathTypePythonDir: 960 { 961 // TODO: Anyone know how we can determine this for linux? Other systems? 962 // For linux we are currently assuming the location of the lldb 963 // binary that contains this function is the directory that will 964 // contain lldb.so, lldb.py and embedded_interpreter.py... 965 966 static ConstString g_lldb_python_dir; 967 if (!g_lldb_python_dir) 968 { 969 FileSpec lldb_file_spec; 970 if (GetLLDBPath (ePathTypeLLDBShlibDir, lldb_file_spec)) 971 { 972 char raw_path[PATH_MAX]; 973 char resolved_path[PATH_MAX]; 974 lldb_file_spec.GetPath(raw_path, sizeof(raw_path)); 975 976 #if defined (__APPLE__) 977 char *framework_pos = ::strstr (raw_path, "LLDB.framework"); 978 if (framework_pos) 979 { 980 framework_pos += strlen("LLDB.framework"); 981 ::strncpy (framework_pos, "/Resources/Python", PATH_MAX - (framework_pos - raw_path)); 982 } 983 #endif 984 FileSpec::Resolve (raw_path, resolved_path, sizeof(resolved_path)); 985 g_lldb_python_dir.SetCString(resolved_path); 986 } 987 } 988 file_spec.GetDirectory() = g_lldb_python_dir; 989 return file_spec.GetDirectory(); 990 } 991 break; 992 993 case ePathTypeLLDBSystemPlugins: // System plug-ins directory 994 { 995 #if defined (__APPLE__) 996 static ConstString g_lldb_system_plugin_dir; 997 static bool g_lldb_system_plugin_dir_located = false; 998 if (!g_lldb_system_plugin_dir_located) 999 { 1000 g_lldb_system_plugin_dir_located = true; 1001 FileSpec lldb_file_spec; 1002 if (GetLLDBPath (ePathTypeLLDBShlibDir, lldb_file_spec)) 1003 { 1004 char raw_path[PATH_MAX]; 1005 char resolved_path[PATH_MAX]; 1006 lldb_file_spec.GetPath(raw_path, sizeof(raw_path)); 1007 1008 char *framework_pos = ::strstr (raw_path, "LLDB.framework"); 1009 if (framework_pos) 1010 { 1011 framework_pos += strlen("LLDB.framework"); 1012 ::strncpy (framework_pos, "/Resources/PlugIns", PATH_MAX - (framework_pos - raw_path)); 1013 FileSpec::Resolve (raw_path, resolved_path, sizeof(resolved_path)); 1014 g_lldb_system_plugin_dir.SetCString(resolved_path); 1015 } 1016 return false; 1017 } 1018 } 1019 1020 if (g_lldb_system_plugin_dir) 1021 { 1022 file_spec.GetDirectory() = g_lldb_system_plugin_dir; 1023 return true; 1024 } 1025 #endif 1026 // TODO: where would system LLDB plug-ins be located on linux? Other systems? 1027 return false; 1028 } 1029 break; 1030 1031 case ePathTypeLLDBUserPlugins: // User plug-ins directory 1032 { 1033 #if defined (__APPLE__) 1034 static ConstString g_lldb_user_plugin_dir; 1035 if (!g_lldb_user_plugin_dir) 1036 { 1037 char user_plugin_path[PATH_MAX]; 1038 if (FileSpec::Resolve ("~/Library/Application Support/LLDB/PlugIns", 1039 user_plugin_path, 1040 sizeof(user_plugin_path))) 1041 { 1042 g_lldb_user_plugin_dir.SetCString(user_plugin_path); 1043 } 1044 } 1045 file_spec.GetDirectory() = g_lldb_user_plugin_dir; 1046 return file_spec.GetDirectory(); 1047 #endif 1048 // TODO: where would user LLDB plug-ins be located on linux? Other systems? 1049 return false; 1050 } 1051 default: 1052 assert (!"Unhandled PathType"); 1053 break; 1054 } 1055 1056 return false; 1057 } 1058 1059 1060 bool 1061 Host::GetHostname (std::string &s) 1062 { 1063 char hostname[PATH_MAX]; 1064 hostname[sizeof(hostname) - 1] = '\0'; 1065 if (::gethostname (hostname, sizeof(hostname) - 1) == 0) 1066 { 1067 struct hostent* h = ::gethostbyname (hostname); 1068 if (h) 1069 s.assign (h->h_name); 1070 else 1071 s.assign (hostname); 1072 return true; 1073 } 1074 return false; 1075 } 1076 1077 const char * 1078 Host::GetUserName (uint32_t uid, std::string &user_name) 1079 { 1080 struct passwd user_info; 1081 struct passwd *user_info_ptr = &user_info; 1082 char user_buffer[PATH_MAX]; 1083 size_t user_buffer_size = sizeof(user_buffer); 1084 if (::getpwuid_r (uid, 1085 &user_info, 1086 user_buffer, 1087 user_buffer_size, 1088 &user_info_ptr) == 0) 1089 { 1090 if (user_info_ptr) 1091 { 1092 user_name.assign (user_info_ptr->pw_name); 1093 return user_name.c_str(); 1094 } 1095 } 1096 user_name.clear(); 1097 return NULL; 1098 } 1099 1100 const char * 1101 Host::GetGroupName (uint32_t gid, std::string &group_name) 1102 { 1103 char group_buffer[PATH_MAX]; 1104 size_t group_buffer_size = sizeof(group_buffer); 1105 struct group group_info; 1106 struct group *group_info_ptr = &group_info; 1107 // Try the threadsafe version first 1108 if (::getgrgid_r (gid, 1109 &group_info, 1110 group_buffer, 1111 group_buffer_size, 1112 &group_info_ptr) == 0) 1113 { 1114 if (group_info_ptr) 1115 { 1116 group_name.assign (group_info_ptr->gr_name); 1117 return group_name.c_str(); 1118 } 1119 } 1120 else 1121 { 1122 // The threadsafe version isn't currently working 1123 // for me on darwin, but the non-threadsafe version 1124 // is, so I am calling it below. 1125 group_info_ptr = ::getgrgid (gid); 1126 if (group_info_ptr) 1127 { 1128 group_name.assign (group_info_ptr->gr_name); 1129 return group_name.c_str(); 1130 } 1131 } 1132 group_name.clear(); 1133 return NULL; 1134 } 1135 1136 #if !defined (__APPLE__) && !defined (__FreeBSD__) // see macosx/Host.mm 1137 bool 1138 Host::GetOSBuildString (std::string &s) 1139 { 1140 s.clear(); 1141 return false; 1142 } 1143 1144 bool 1145 Host::GetOSKernelDescription (std::string &s) 1146 { 1147 s.clear(); 1148 return false; 1149 } 1150 #endif 1151 1152 #if !defined(__APPLE__) 1153 uint32_t 1154 Host::FindProcesses (const ProcessInstanceInfoMatch &match_info, ProcessInstanceInfoList &process_infos) 1155 { 1156 process_infos.Clear(); 1157 return process_infos.GetSize(); 1158 } 1159 #endif 1160 1161 #if !defined (__APPLE__) && !defined (__FreeBSD__) 1162 bool 1163 Host::GetProcessInfo (lldb::pid_t pid, ProcessInstanceInfo &process_info) 1164 { 1165 process_info.Clear(); 1166 return false; 1167 } 1168 #endif 1169 1170 lldb::TargetSP 1171 Host::GetDummyTarget (lldb_private::Debugger &debugger) 1172 { 1173 static TargetSP dummy_target; 1174 1175 if (!dummy_target) 1176 { 1177 Error err = debugger.GetTargetList().CreateTarget(debugger, 1178 FileSpec(), 1179 Host::GetTargetTriple().AsCString(), 1180 false, 1181 NULL, 1182 dummy_target); 1183 } 1184 1185 return dummy_target; 1186 } 1187 1188 #if !defined (__APPLE__) 1189 bool 1190 Host::OpenFileInExternalEditor (const FileSpec &file_spec, uint32_t line_no) 1191 { 1192 return false; 1193 } 1194 1195 void 1196 Host::SetCrashDescriptionWithFormat (const char *format, ...) 1197 { 1198 } 1199 1200 void 1201 Host::SetCrashDescription (const char *description) 1202 { 1203 } 1204 1205 lldb::pid_t 1206 LaunchApplication (const FileSpec &app_file_spec) 1207 { 1208 return LLDB_INVALID_PROCESS_ID; 1209 } 1210 1211 #endif 1212