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