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