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