Host.cpp revision 269024
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/lldb-python.h" 11 12// C includes 13#include <errno.h> 14#include <limits.h> 15#include <sys/types.h> 16#ifdef _WIN32 17#include "lldb/Host/windows/windows.h" 18#include <winsock2.h> 19#include <WS2tcpip.h> 20#else 21#include <unistd.h> 22#include <dlfcn.h> 23#include <grp.h> 24#include <netdb.h> 25#include <pwd.h> 26#include <sys/stat.h> 27#endif 28 29#if !defined (__GNU__) && !defined (_WIN32) 30// Does not exist under GNU/HURD or Windows 31#include <sys/sysctl.h> 32#endif 33 34#if defined (__APPLE__) 35#include <mach/mach_port.h> 36#include <mach/mach_init.h> 37#include <mach-o/dyld.h> 38#include <AvailabilityMacros.h> 39#endif 40 41#if defined (__linux__) || defined (__FreeBSD__) || defined (__FreeBSD_kernel__) || defined (__APPLE__) 42#include <spawn.h> 43#include <sys/wait.h> 44#include <sys/syscall.h> 45#endif 46 47#if defined (__FreeBSD__) 48#include <pthread_np.h> 49#endif 50 51#include "lldb/Host/Host.h" 52#include "lldb/Core/ArchSpec.h" 53#include "lldb/Core/ConstString.h" 54#include "lldb/Core/Debugger.h" 55#include "lldb/Core/Error.h" 56#include "lldb/Core/Log.h" 57#include "lldb/Core/Module.h" 58#include "lldb/Core/StreamString.h" 59#include "lldb/Core/ThreadSafeSTLMap.h" 60#include "lldb/Host/Config.h" 61#include "lldb/Host/Endian.h" 62#include "lldb/Host/FileSpec.h" 63#include "lldb/Host/Mutex.h" 64#include "lldb/Target/Process.h" 65#include "lldb/Target/TargetList.h" 66#include "lldb/Utility/CleanUp.h" 67 68#include "llvm/ADT/SmallString.h" 69#include "llvm/Support/Host.h" 70#include "llvm/Support/raw_ostream.h" 71 72#if defined (__APPLE__) 73#ifndef _POSIX_SPAWN_DISABLE_ASLR 74#define _POSIX_SPAWN_DISABLE_ASLR 0x0100 75#endif 76 77extern "C" 78{ 79 int __pthread_chdir(const char *path); 80 int __pthread_fchdir (int fildes); 81} 82 83#endif 84 85using namespace lldb; 86using namespace lldb_private; 87 88 89#if !defined (__APPLE__) && !defined (_WIN32) 90struct MonitorInfo 91{ 92 lldb::pid_t pid; // The process ID to monitor 93 Host::MonitorChildProcessCallback callback; // The callback function to call when "pid" exits or signals 94 void *callback_baton; // The callback baton for the callback function 95 bool monitor_signals; // If true, call the callback when "pid" gets signaled. 96}; 97 98static thread_result_t 99MonitorChildProcessThreadFunction (void *arg); 100 101lldb::thread_t 102Host::StartMonitoringChildProcess 103( 104 Host::MonitorChildProcessCallback callback, 105 void *callback_baton, 106 lldb::pid_t pid, 107 bool monitor_signals 108) 109{ 110 lldb::thread_t thread = LLDB_INVALID_HOST_THREAD; 111 MonitorInfo * info_ptr = new MonitorInfo(); 112 113 info_ptr->pid = pid; 114 info_ptr->callback = callback; 115 info_ptr->callback_baton = callback_baton; 116 info_ptr->monitor_signals = monitor_signals; 117 118 char thread_name[256]; 119 ::snprintf (thread_name, sizeof(thread_name), "<lldb.host.wait4(pid=%" PRIu64 ")>", pid); 120 thread = ThreadCreate (thread_name, 121 MonitorChildProcessThreadFunction, 122 info_ptr, 123 NULL); 124 125 return thread; 126} 127 128//------------------------------------------------------------------ 129// Scoped class that will disable thread canceling when it is 130// constructed, and exception safely restore the previous value it 131// when it goes out of scope. 132//------------------------------------------------------------------ 133class ScopedPThreadCancelDisabler 134{ 135public: 136 ScopedPThreadCancelDisabler() 137 { 138 // Disable the ability for this thread to be cancelled 139 int err = ::pthread_setcancelstate (PTHREAD_CANCEL_DISABLE, &m_old_state); 140 if (err != 0) 141 m_old_state = -1; 142 143 } 144 145 ~ScopedPThreadCancelDisabler() 146 { 147 // Restore the ability for this thread to be cancelled to what it 148 // previously was. 149 if (m_old_state != -1) 150 ::pthread_setcancelstate (m_old_state, 0); 151 } 152private: 153 int m_old_state; // Save the old cancelability state. 154}; 155 156static thread_result_t 157MonitorChildProcessThreadFunction (void *arg) 158{ 159 Log *log(lldb_private::GetLogIfAllCategoriesSet (LIBLLDB_LOG_PROCESS)); 160 const char *function = __FUNCTION__; 161 if (log) 162 log->Printf ("%s (arg = %p) thread starting...", function, arg); 163 164 MonitorInfo *info = (MonitorInfo *)arg; 165 166 const Host::MonitorChildProcessCallback callback = info->callback; 167 void * const callback_baton = info->callback_baton; 168 const bool monitor_signals = info->monitor_signals; 169 170 assert (info->pid <= UINT32_MAX); 171 const ::pid_t pid = monitor_signals ? -1 * info->pid : info->pid; 172 173 delete info; 174 175 int status = -1; 176#if defined (__FreeBSD__) || defined (__FreeBSD_kernel__) 177 #define __WALL 0 178#endif 179 const int options = __WALL; 180 181 while (1) 182 { 183 log = lldb_private::GetLogIfAllCategoriesSet (LIBLLDB_LOG_PROCESS); 184 if (log) 185 log->Printf("%s ::wait_pid (pid = %" PRIi32 ", &status, options = %i)...", function, pid, options); 186 187 // Wait for all child processes 188 ::pthread_testcancel (); 189 // Get signals from all children with same process group of pid 190 const ::pid_t wait_pid = ::waitpid (pid, &status, options); 191 ::pthread_testcancel (); 192 193 if (wait_pid == -1) 194 { 195 if (errno == EINTR) 196 continue; 197 else 198 { 199 if (log) 200 log->Printf ("%s (arg = %p) thread exiting because waitpid failed (%s)...", __FUNCTION__, arg, strerror(errno)); 201 break; 202 } 203 } 204 else if (wait_pid > 0) 205 { 206 bool exited = false; 207 int signal = 0; 208 int exit_status = 0; 209 const char *status_cstr = NULL; 210 if (WIFSTOPPED(status)) 211 { 212 signal = WSTOPSIG(status); 213 status_cstr = "STOPPED"; 214 } 215 else if (WIFEXITED(status)) 216 { 217 exit_status = WEXITSTATUS(status); 218 status_cstr = "EXITED"; 219 exited = true; 220 } 221 else if (WIFSIGNALED(status)) 222 { 223 signal = WTERMSIG(status); 224 status_cstr = "SIGNALED"; 225 if (wait_pid == abs(pid)) { 226 exited = true; 227 exit_status = -1; 228 } 229 } 230 else 231 { 232 status_cstr = "(\?\?\?)"; 233 } 234 235 // Scope for pthread_cancel_disabler 236 { 237 ScopedPThreadCancelDisabler pthread_cancel_disabler; 238 239 log = lldb_private::GetLogIfAllCategoriesSet (LIBLLDB_LOG_PROCESS); 240 if (log) 241 log->Printf ("%s ::waitpid (pid = %" PRIi32 ", &status, options = %i) => pid = %" PRIi32 ", status = 0x%8.8x (%s), signal = %i, exit_state = %i", 242 function, 243 wait_pid, 244 options, 245 pid, 246 status, 247 status_cstr, 248 signal, 249 exit_status); 250 251 if (exited || (signal != 0 && monitor_signals)) 252 { 253 bool callback_return = false; 254 if (callback) 255 callback_return = callback (callback_baton, wait_pid, exited, signal, exit_status); 256 257 // If our process exited, then this thread should exit 258 if (exited && wait_pid == abs(pid)) 259 { 260 if (log) 261 log->Printf ("%s (arg = %p) thread exiting because pid received exit signal...", __FUNCTION__, arg); 262 break; 263 } 264 // If the callback returns true, it means this process should 265 // exit 266 if (callback_return) 267 { 268 if (log) 269 log->Printf ("%s (arg = %p) thread exiting because callback returned true...", __FUNCTION__, arg); 270 break; 271 } 272 } 273 } 274 } 275 } 276 277 log = lldb_private::GetLogIfAllCategoriesSet (LIBLLDB_LOG_PROCESS); 278 if (log) 279 log->Printf ("%s (arg = %p) thread exiting...", __FUNCTION__, arg); 280 281 return NULL; 282} 283 284#endif // #if !defined (__APPLE__) && !defined (_WIN32) 285 286#if !defined (__APPLE__) 287 288void 289Host::SystemLog (SystemLogType type, const char *format, va_list args) 290{ 291 vfprintf (stderr, format, args); 292} 293 294#endif 295 296void 297Host::SystemLog (SystemLogType type, const char *format, ...) 298{ 299 va_list args; 300 va_start (args, format); 301 SystemLog (type, format, args); 302 va_end (args); 303} 304 305const ArchSpec & 306Host::GetArchitecture (SystemDefaultArchitecture arch_kind) 307{ 308 static bool g_supports_32 = false; 309 static bool g_supports_64 = false; 310 static ArchSpec g_host_arch_32; 311 static ArchSpec g_host_arch_64; 312 313#if defined (__APPLE__) 314 315 // Apple is different in that it can support both 32 and 64 bit executables 316 // in the same operating system running concurrently. Here we detect the 317 // correct host architectures for both 32 and 64 bit including if 64 bit 318 // executables are supported on the system. 319 320 if (g_supports_32 == false && g_supports_64 == false) 321 { 322 // All apple systems support 32 bit execution. 323 g_supports_32 = true; 324 uint32_t cputype, cpusubtype; 325 uint32_t is_64_bit_capable = false; 326 size_t len = sizeof(cputype); 327 ArchSpec host_arch; 328 // These will tell us about the kernel architecture, which even on a 64 329 // bit machine can be 32 bit... 330 if (::sysctlbyname("hw.cputype", &cputype, &len, NULL, 0) == 0) 331 { 332 len = sizeof (cpusubtype); 333 if (::sysctlbyname("hw.cpusubtype", &cpusubtype, &len, NULL, 0) != 0) 334 cpusubtype = CPU_TYPE_ANY; 335 336 len = sizeof (is_64_bit_capable); 337 if (::sysctlbyname("hw.cpu64bit_capable", &is_64_bit_capable, &len, NULL, 0) == 0) 338 { 339 if (is_64_bit_capable) 340 g_supports_64 = true; 341 } 342 343 if (is_64_bit_capable) 344 { 345#if defined (__i386__) || defined (__x86_64__) 346 if (cpusubtype == CPU_SUBTYPE_486) 347 cpusubtype = CPU_SUBTYPE_I386_ALL; 348#endif 349 if (cputype & CPU_ARCH_ABI64) 350 { 351 // We have a 64 bit kernel on a 64 bit system 352 g_host_arch_32.SetArchitecture (eArchTypeMachO, ~(CPU_ARCH_MASK) & cputype, cpusubtype); 353 g_host_arch_64.SetArchitecture (eArchTypeMachO, cputype, cpusubtype); 354 } 355 else 356 { 357 // We have a 32 bit kernel on a 64 bit system 358 g_host_arch_32.SetArchitecture (eArchTypeMachO, cputype, cpusubtype); 359 cputype |= CPU_ARCH_ABI64; 360 g_host_arch_64.SetArchitecture (eArchTypeMachO, cputype, cpusubtype); 361 } 362 } 363 else 364 { 365 g_host_arch_32.SetArchitecture (eArchTypeMachO, cputype, cpusubtype); 366 g_host_arch_64.Clear(); 367 } 368 } 369 } 370 371#else // #if defined (__APPLE__) 372 373 if (g_supports_32 == false && g_supports_64 == false) 374 { 375 llvm::Triple triple(llvm::sys::getDefaultTargetTriple()); 376 377 g_host_arch_32.Clear(); 378 g_host_arch_64.Clear(); 379 380 // If the OS is Linux, "unknown" in the vendor slot isn't what we want 381 // for the default triple. It's probably an artifact of config.guess. 382 if (triple.getOS() == llvm::Triple::Linux && triple.getVendor() == llvm::Triple::UnknownVendor) 383 triple.setVendorName (""); 384 385 const char* distribution_id = GetDistributionId ().AsCString(); 386 387 switch (triple.getArch()) 388 { 389 default: 390 g_host_arch_32.SetTriple(triple); 391 g_host_arch_32.SetDistributionId (distribution_id); 392 g_supports_32 = true; 393 break; 394 395 case llvm::Triple::x86_64: 396 g_host_arch_64.SetTriple(triple); 397 g_host_arch_64.SetDistributionId (distribution_id); 398 g_supports_64 = true; 399 g_host_arch_32.SetTriple(triple.get32BitArchVariant()); 400 g_host_arch_32.SetDistributionId (distribution_id); 401 g_supports_32 = true; 402 break; 403 404 case llvm::Triple::sparcv9: 405 case llvm::Triple::ppc64: 406 g_host_arch_64.SetTriple(triple); 407 g_host_arch_64.SetDistributionId (distribution_id); 408 g_supports_64 = true; 409 break; 410 } 411 412 g_supports_32 = g_host_arch_32.IsValid(); 413 g_supports_64 = g_host_arch_64.IsValid(); 414 } 415 416#endif // #else for #if defined (__APPLE__) 417 418 if (arch_kind == eSystemDefaultArchitecture32) 419 return g_host_arch_32; 420 else if (arch_kind == eSystemDefaultArchitecture64) 421 return g_host_arch_64; 422 423 if (g_supports_64) 424 return g_host_arch_64; 425 426 return g_host_arch_32; 427} 428 429const ConstString & 430Host::GetVendorString() 431{ 432 static ConstString g_vendor; 433 if (!g_vendor) 434 { 435 const ArchSpec &host_arch = GetArchitecture (eSystemDefaultArchitecture); 436 const llvm::StringRef &str_ref = host_arch.GetTriple().getVendorName(); 437 g_vendor.SetCStringWithLength(str_ref.data(), str_ref.size()); 438 } 439 return g_vendor; 440} 441 442const ConstString & 443Host::GetOSString() 444{ 445 static ConstString g_os_string; 446 if (!g_os_string) 447 { 448 const ArchSpec &host_arch = GetArchitecture (eSystemDefaultArchitecture); 449 const llvm::StringRef &str_ref = host_arch.GetTriple().getOSName(); 450 g_os_string.SetCStringWithLength(str_ref.data(), str_ref.size()); 451 } 452 return g_os_string; 453} 454 455const ConstString & 456Host::GetTargetTriple() 457{ 458 static ConstString g_host_triple; 459 if (!(g_host_triple)) 460 { 461 const ArchSpec &host_arch = GetArchitecture (eSystemDefaultArchitecture); 462 g_host_triple.SetCString(host_arch.GetTriple().getTriple().c_str()); 463 } 464 return g_host_triple; 465} 466 467// See linux/Host.cpp for Linux-based implementations of this. 468// Add your platform-specific implementation to the appropriate host file. 469#if !defined(__linux__) 470 471const ConstString & 472 Host::GetDistributionId () 473{ 474 static ConstString s_distribution_id; 475 return s_distribution_id; 476} 477 478#endif // #if !defined(__linux__) 479 480lldb::pid_t 481Host::GetCurrentProcessID() 482{ 483 return ::getpid(); 484} 485 486#ifndef _WIN32 487 488lldb::tid_t 489Host::GetCurrentThreadID() 490{ 491#if defined (__APPLE__) 492 // Calling "mach_thread_self()" bumps the reference count on the thread 493 // port, so we need to deallocate it. mach_task_self() doesn't bump the ref 494 // count. 495 thread_port_t thread_self = mach_thread_self(); 496 mach_port_deallocate(mach_task_self(), thread_self); 497 return thread_self; 498#elif defined(__FreeBSD__) 499 return lldb::tid_t(pthread_getthreadid_np()); 500#elif defined(__linux__) 501 return lldb::tid_t(syscall(SYS_gettid)); 502#else 503 return lldb::tid_t(pthread_self()); 504#endif 505} 506 507lldb::thread_t 508Host::GetCurrentThread () 509{ 510 return lldb::thread_t(pthread_self()); 511} 512 513const char * 514Host::GetSignalAsCString (int signo) 515{ 516 switch (signo) 517 { 518 case SIGHUP: return "SIGHUP"; // 1 hangup 519 case SIGINT: return "SIGINT"; // 2 interrupt 520 case SIGQUIT: return "SIGQUIT"; // 3 quit 521 case SIGILL: return "SIGILL"; // 4 illegal instruction (not reset when caught) 522 case SIGTRAP: return "SIGTRAP"; // 5 trace trap (not reset when caught) 523 case SIGABRT: return "SIGABRT"; // 6 abort() 524#if defined(SIGPOLL) 525#if !defined(SIGIO) || (SIGPOLL != SIGIO) 526// Under some GNU/Linux, SIGPOLL and SIGIO are the same. Causing the build to 527// fail with 'multiple define cases with same value' 528 case SIGPOLL: return "SIGPOLL"; // 7 pollable event ([XSR] generated, not supported) 529#endif 530#endif 531#if defined(SIGEMT) 532 case SIGEMT: return "SIGEMT"; // 7 EMT instruction 533#endif 534 case SIGFPE: return "SIGFPE"; // 8 floating point exception 535 case SIGKILL: return "SIGKILL"; // 9 kill (cannot be caught or ignored) 536 case SIGBUS: return "SIGBUS"; // 10 bus error 537 case SIGSEGV: return "SIGSEGV"; // 11 segmentation violation 538 case SIGSYS: return "SIGSYS"; // 12 bad argument to system call 539 case SIGPIPE: return "SIGPIPE"; // 13 write on a pipe with no one to read it 540 case SIGALRM: return "SIGALRM"; // 14 alarm clock 541 case SIGTERM: return "SIGTERM"; // 15 software termination signal from kill 542 case SIGURG: return "SIGURG"; // 16 urgent condition on IO channel 543 case SIGSTOP: return "SIGSTOP"; // 17 sendable stop signal not from tty 544 case SIGTSTP: return "SIGTSTP"; // 18 stop signal from tty 545 case SIGCONT: return "SIGCONT"; // 19 continue a stopped process 546 case SIGCHLD: return "SIGCHLD"; // 20 to parent on child stop or exit 547 case SIGTTIN: return "SIGTTIN"; // 21 to readers pgrp upon background tty read 548 case SIGTTOU: return "SIGTTOU"; // 22 like TTIN for output if (tp->t_local<OSTOP) 549#if defined(SIGIO) 550 case SIGIO: return "SIGIO"; // 23 input/output possible signal 551#endif 552 case SIGXCPU: return "SIGXCPU"; // 24 exceeded CPU time limit 553 case SIGXFSZ: return "SIGXFSZ"; // 25 exceeded file size limit 554 case SIGVTALRM: return "SIGVTALRM"; // 26 virtual time alarm 555 case SIGPROF: return "SIGPROF"; // 27 profiling time alarm 556#if defined(SIGWINCH) 557 case SIGWINCH: return "SIGWINCH"; // 28 window size changes 558#endif 559#if defined(SIGINFO) 560 case SIGINFO: return "SIGINFO"; // 29 information request 561#endif 562 case SIGUSR1: return "SIGUSR1"; // 30 user defined signal 1 563 case SIGUSR2: return "SIGUSR2"; // 31 user defined signal 2 564 default: 565 break; 566 } 567 return NULL; 568} 569 570#endif 571 572void 573Host::WillTerminate () 574{ 575} 576 577#if !defined (__APPLE__) && !defined (__FreeBSD__) && !defined (__FreeBSD_kernel__) && !defined (__linux__) // see macosx/Host.mm 578 579void 580Host::ThreadCreated (const char *thread_name) 581{ 582} 583 584void 585Host::Backtrace (Stream &strm, uint32_t max_frames) 586{ 587 // TODO: Is there a way to backtrace the current process on other systems? 588} 589 590size_t 591Host::GetEnvironment (StringList &env) 592{ 593 // TODO: Is there a way to the host environment for this process on other systems? 594 return 0; 595} 596 597#endif // #if !defined (__APPLE__) && !defined (__FreeBSD__) && !defined (__FreeBSD_kernel__) && !defined (__linux__) 598 599struct HostThreadCreateInfo 600{ 601 std::string thread_name; 602 thread_func_t thread_fptr; 603 thread_arg_t thread_arg; 604 605 HostThreadCreateInfo (const char *name, thread_func_t fptr, thread_arg_t arg) : 606 thread_name (name ? name : ""), 607 thread_fptr (fptr), 608 thread_arg (arg) 609 { 610 } 611}; 612 613static thread_result_t 614#ifdef _WIN32 615__stdcall 616#endif 617ThreadCreateTrampoline (thread_arg_t arg) 618{ 619 HostThreadCreateInfo *info = (HostThreadCreateInfo *)arg; 620 Host::ThreadCreated (info->thread_name.c_str()); 621 thread_func_t thread_fptr = info->thread_fptr; 622 thread_arg_t thread_arg = info->thread_arg; 623 624 Log *log(lldb_private::GetLogIfAllCategoriesSet (LIBLLDB_LOG_THREAD)); 625 if (log) 626 log->Printf("thread created"); 627 628 delete info; 629 return thread_fptr (thread_arg); 630} 631 632lldb::thread_t 633Host::ThreadCreate 634( 635 const char *thread_name, 636 thread_func_t thread_fptr, 637 thread_arg_t thread_arg, 638 Error *error 639) 640{ 641 lldb::thread_t thread = LLDB_INVALID_HOST_THREAD; 642 643 // Host::ThreadCreateTrampoline will delete this pointer for us. 644 HostThreadCreateInfo *info_ptr = new HostThreadCreateInfo (thread_name, thread_fptr, thread_arg); 645 646#ifdef _WIN32 647 thread = ::_beginthreadex(0, 0, ThreadCreateTrampoline, info_ptr, 0, NULL); 648 int err = thread <= 0 ? GetLastError() : 0; 649#else 650 int err = ::pthread_create (&thread, NULL, ThreadCreateTrampoline, info_ptr); 651#endif 652 if (err == 0) 653 { 654 if (error) 655 error->Clear(); 656 return thread; 657 } 658 659 if (error) 660 error->SetError (err, eErrorTypePOSIX); 661 662 return LLDB_INVALID_HOST_THREAD; 663} 664 665#ifndef _WIN32 666 667bool 668Host::ThreadCancel (lldb::thread_t thread, Error *error) 669{ 670 int err = ::pthread_cancel (thread); 671 if (error) 672 error->SetError(err, eErrorTypePOSIX); 673 return err == 0; 674} 675 676bool 677Host::ThreadDetach (lldb::thread_t thread, Error *error) 678{ 679 int err = ::pthread_detach (thread); 680 if (error) 681 error->SetError(err, eErrorTypePOSIX); 682 return err == 0; 683} 684 685bool 686Host::ThreadJoin (lldb::thread_t thread, thread_result_t *thread_result_ptr, Error *error) 687{ 688 int err = ::pthread_join (thread, thread_result_ptr); 689 if (error) 690 error->SetError(err, eErrorTypePOSIX); 691 return err == 0; 692} 693 694lldb::thread_key_t 695Host::ThreadLocalStorageCreate(ThreadLocalStorageCleanupCallback callback) 696{ 697 pthread_key_t key; 698 ::pthread_key_create (&key, callback); 699 return key; 700} 701 702void* 703Host::ThreadLocalStorageGet(lldb::thread_key_t key) 704{ 705 return ::pthread_getspecific (key); 706} 707 708void 709Host::ThreadLocalStorageSet(lldb::thread_key_t key, void *value) 710{ 711 ::pthread_setspecific (key, value); 712} 713 714bool 715Host::SetThreadName (lldb::pid_t pid, lldb::tid_t tid, const char *name) 716{ 717#if defined(__APPLE__) && MAC_OS_X_VERSION_MAX_ALLOWED > MAC_OS_X_VERSION_10_5 718 lldb::pid_t curr_pid = Host::GetCurrentProcessID(); 719 lldb::tid_t curr_tid = Host::GetCurrentThreadID(); 720 if (pid == LLDB_INVALID_PROCESS_ID) 721 pid = curr_pid; 722 723 if (tid == LLDB_INVALID_THREAD_ID) 724 tid = curr_tid; 725 726 // Set the pthread name if possible 727 if (pid == curr_pid && tid == curr_tid) 728 { 729 if (::pthread_setname_np (name) == 0) 730 return true; 731 } 732 return false; 733#elif defined (__FreeBSD__) 734 lldb::pid_t curr_pid = Host::GetCurrentProcessID(); 735 lldb::tid_t curr_tid = Host::GetCurrentThreadID(); 736 if (pid == LLDB_INVALID_PROCESS_ID) 737 pid = curr_pid; 738 739 if (tid == LLDB_INVALID_THREAD_ID) 740 tid = curr_tid; 741 742 // Set the pthread name if possible 743 if (pid == curr_pid && tid == curr_tid) 744 { 745 ::pthread_set_name_np (::pthread_self(), name); 746 return true; 747 } 748 return false; 749#elif defined (__linux__) || defined (__GLIBC__) 750 void *fn = dlsym (RTLD_DEFAULT, "pthread_setname_np"); 751 if (fn) 752 { 753 lldb::pid_t curr_pid = Host::GetCurrentProcessID(); 754 lldb::tid_t curr_tid = Host::GetCurrentThreadID(); 755 if (pid == LLDB_INVALID_PROCESS_ID) 756 pid = curr_pid; 757 758 if (tid == LLDB_INVALID_THREAD_ID) 759 tid = curr_tid; 760 761 if (pid == curr_pid && tid == curr_tid) 762 { 763 int (*pthread_setname_np_func)(pthread_t thread, const char *name); 764 *reinterpret_cast<void **> (&pthread_setname_np_func) = fn; 765 766 if (pthread_setname_np_func (::pthread_self(), name) == 0) 767 return true; 768 } 769 } 770 return false; 771#else 772 return false; 773#endif 774} 775 776bool 777Host::SetShortThreadName (lldb::pid_t pid, lldb::tid_t tid, 778 const char *thread_name, size_t len) 779{ 780 std::unique_ptr<char[]> namebuf(new char[len+1]); 781 782 // Thread names are coming in like '<lldb.comm.debugger.edit>' and 783 // '<lldb.comm.debugger.editline>'. So just chopping the end of the string 784 // off leads to a lot of similar named threads. Go through the thread name 785 // and search for the last dot and use that. 786 const char *lastdot = ::strrchr (thread_name, '.'); 787 788 if (lastdot && lastdot != thread_name) 789 thread_name = lastdot + 1; 790 ::strncpy (namebuf.get(), thread_name, len); 791 namebuf[len] = 0; 792 793 int namebuflen = strlen(namebuf.get()); 794 if (namebuflen > 0) 795 { 796 if (namebuf[namebuflen - 1] == '(' || namebuf[namebuflen - 1] == '>') 797 { 798 // Trim off trailing '(' and '>' characters for a bit more cleanup. 799 namebuflen--; 800 namebuf[namebuflen] = 0; 801 } 802 return Host::SetThreadName (pid, tid, namebuf.get()); 803 } 804 return false; 805} 806 807#endif 808 809FileSpec 810Host::GetProgramFileSpec () 811{ 812 static FileSpec g_program_filespec; 813 if (!g_program_filespec) 814 { 815#if defined (__APPLE__) 816 char program_fullpath[PATH_MAX]; 817 // If DST is NULL, then return the number of bytes needed. 818 uint32_t len = sizeof(program_fullpath); 819 int err = _NSGetExecutablePath (program_fullpath, &len); 820 if (err == 0) 821 g_program_filespec.SetFile (program_fullpath, false); 822 else if (err == -1) 823 { 824 char *large_program_fullpath = (char *)::malloc (len + 1); 825 826 err = _NSGetExecutablePath (large_program_fullpath, &len); 827 if (err == 0) 828 g_program_filespec.SetFile (large_program_fullpath, false); 829 830 ::free (large_program_fullpath); 831 } 832#elif defined (__linux__) 833 char exe_path[PATH_MAX]; 834 ssize_t len = readlink("/proc/self/exe", exe_path, sizeof(exe_path) - 1); 835 if (len > 0) { 836 exe_path[len] = 0; 837 g_program_filespec.SetFile(exe_path, false); 838 } 839#elif defined (__FreeBSD__) || defined (__FreeBSD_kernel__) 840 int exe_path_mib[4] = { CTL_KERN, KERN_PROC, KERN_PROC_PATHNAME, getpid() }; 841 size_t exe_path_size; 842 if (sysctl(exe_path_mib, 4, NULL, &exe_path_size, NULL, 0) == 0) 843 { 844 char *exe_path = new char[exe_path_size]; 845 if (sysctl(exe_path_mib, 4, exe_path, &exe_path_size, NULL, 0) == 0) 846 g_program_filespec.SetFile(exe_path, false); 847 delete[] exe_path; 848 } 849#endif 850 } 851 return g_program_filespec; 852} 853 854#if !defined (__APPLE__) // see Host.mm 855 856bool 857Host::GetBundleDirectory (const FileSpec &file, FileSpec &bundle) 858{ 859 bundle.Clear(); 860 return false; 861} 862 863bool 864Host::ResolveExecutableInBundle (FileSpec &file) 865{ 866 return false; 867} 868#endif 869 870#ifndef _WIN32 871 872// Opaque info that tracks a dynamic library that was loaded 873struct DynamicLibraryInfo 874{ 875 DynamicLibraryInfo (const FileSpec &fs, int o, void *h) : 876 file_spec (fs), 877 open_options (o), 878 handle (h) 879 { 880 } 881 882 const FileSpec file_spec; 883 uint32_t open_options; 884 void * handle; 885}; 886 887void * 888Host::DynamicLibraryOpen (const FileSpec &file_spec, uint32_t options, Error &error) 889{ 890 char path[PATH_MAX]; 891 if (file_spec.GetPath(path, sizeof(path))) 892 { 893 int mode = 0; 894 895 if (options & eDynamicLibraryOpenOptionLazy) 896 mode |= RTLD_LAZY; 897 else 898 mode |= RTLD_NOW; 899 900 901 if (options & eDynamicLibraryOpenOptionLocal) 902 mode |= RTLD_LOCAL; 903 else 904 mode |= RTLD_GLOBAL; 905 906#ifdef LLDB_CONFIG_DLOPEN_RTLD_FIRST_SUPPORTED 907 if (options & eDynamicLibraryOpenOptionLimitGetSymbol) 908 mode |= RTLD_FIRST; 909#endif 910 911 void * opaque = ::dlopen (path, mode); 912 913 if (opaque) 914 { 915 error.Clear(); 916 return new DynamicLibraryInfo (file_spec, options, opaque); 917 } 918 else 919 { 920 error.SetErrorString(::dlerror()); 921 } 922 } 923 else 924 { 925 error.SetErrorString("failed to extract path"); 926 } 927 return NULL; 928} 929 930Error 931Host::DynamicLibraryClose (void *opaque) 932{ 933 Error error; 934 if (opaque == NULL) 935 { 936 error.SetErrorString ("invalid dynamic library handle"); 937 } 938 else 939 { 940 DynamicLibraryInfo *dylib_info = (DynamicLibraryInfo *) opaque; 941 if (::dlclose (dylib_info->handle) != 0) 942 { 943 error.SetErrorString(::dlerror()); 944 } 945 946 dylib_info->open_options = 0; 947 dylib_info->handle = 0; 948 delete dylib_info; 949 } 950 return error; 951} 952 953void * 954Host::DynamicLibraryGetSymbol (void *opaque, const char *symbol_name, Error &error) 955{ 956 if (opaque == NULL) 957 { 958 error.SetErrorString ("invalid dynamic library handle"); 959 } 960 else 961 { 962 DynamicLibraryInfo *dylib_info = (DynamicLibraryInfo *) opaque; 963 964 void *symbol_addr = ::dlsym (dylib_info->handle, symbol_name); 965 if (symbol_addr) 966 { 967#ifndef LLDB_CONFIG_DLOPEN_RTLD_FIRST_SUPPORTED 968 // This host doesn't support limiting searches to this shared library 969 // so we need to verify that the match came from this shared library 970 // if it was requested in the Host::DynamicLibraryOpen() function. 971 if (dylib_info->open_options & eDynamicLibraryOpenOptionLimitGetSymbol) 972 { 973 FileSpec match_dylib_spec (Host::GetModuleFileSpecForHostAddress (symbol_addr)); 974 if (match_dylib_spec != dylib_info->file_spec) 975 { 976 char dylib_path[PATH_MAX]; 977 if (dylib_info->file_spec.GetPath (dylib_path, sizeof(dylib_path))) 978 error.SetErrorStringWithFormat ("symbol not found in \"%s\"", dylib_path); 979 else 980 error.SetErrorString ("symbol not found"); 981 return NULL; 982 } 983 } 984#endif 985 error.Clear(); 986 return symbol_addr; 987 } 988 else 989 { 990 error.SetErrorString(::dlerror()); 991 } 992 } 993 return NULL; 994} 995 996FileSpec 997Host::GetModuleFileSpecForHostAddress (const void *host_addr) 998{ 999 FileSpec module_filespec; 1000 Dl_info info; 1001 if (::dladdr (host_addr, &info)) 1002 { 1003 if (info.dli_fname) 1004 module_filespec.SetFile(info.dli_fname, true); 1005 } 1006 return module_filespec; 1007} 1008 1009#endif 1010 1011bool 1012Host::GetLLDBPath (PathType path_type, FileSpec &file_spec) 1013{ 1014 // To get paths related to LLDB we get the path to the executable that 1015 // contains this function. On MacOSX this will be "LLDB.framework/.../LLDB", 1016 // on linux this is assumed to be the "lldb" main executable. If LLDB on 1017 // linux is actually in a shared library (liblldb.so) then this function will 1018 // need to be modified to "do the right thing". 1019 Log *log = lldb_private::GetLogIfAllCategoriesSet (LIBLLDB_LOG_HOST); 1020 1021 switch (path_type) 1022 { 1023 case ePathTypeLLDBShlibDir: 1024 { 1025 static ConstString g_lldb_so_dir; 1026 if (!g_lldb_so_dir) 1027 { 1028 FileSpec lldb_file_spec (Host::GetModuleFileSpecForHostAddress ((void *)Host::GetLLDBPath)); 1029 g_lldb_so_dir = lldb_file_spec.GetDirectory(); 1030 if (log) 1031 log->Printf("Host::GetLLDBPath(ePathTypeLLDBShlibDir) => '%s'", g_lldb_so_dir.GetCString()); 1032 } 1033 file_spec.GetDirectory() = g_lldb_so_dir; 1034 return (bool)file_spec.GetDirectory(); 1035 } 1036 break; 1037 1038 case ePathTypeSupportExecutableDir: 1039 { 1040 static ConstString g_lldb_support_exe_dir; 1041 if (!g_lldb_support_exe_dir) 1042 { 1043 FileSpec lldb_file_spec; 1044 if (GetLLDBPath (ePathTypeLLDBShlibDir, lldb_file_spec)) 1045 { 1046 char raw_path[PATH_MAX]; 1047 char resolved_path[PATH_MAX]; 1048 lldb_file_spec.GetPath(raw_path, sizeof(raw_path)); 1049 1050#if defined (__APPLE__) 1051 char *framework_pos = ::strstr (raw_path, "LLDB.framework"); 1052 if (framework_pos) 1053 { 1054 framework_pos += strlen("LLDB.framework"); 1055#if defined (__arm__) 1056 // Shallow bundle 1057 *framework_pos = '\0'; 1058#else 1059 // Normal bundle 1060 ::strncpy (framework_pos, "/Resources", PATH_MAX - (framework_pos - raw_path)); 1061#endif 1062 } 1063#endif 1064 FileSpec::Resolve (raw_path, resolved_path, sizeof(resolved_path)); 1065 g_lldb_support_exe_dir.SetCString(resolved_path); 1066 } 1067 if (log) 1068 log->Printf("Host::GetLLDBPath(ePathTypeSupportExecutableDir) => '%s'", g_lldb_support_exe_dir.GetCString()); 1069 } 1070 file_spec.GetDirectory() = g_lldb_support_exe_dir; 1071 return (bool)file_spec.GetDirectory(); 1072 } 1073 break; 1074 1075 case ePathTypeHeaderDir: 1076 { 1077 static ConstString g_lldb_headers_dir; 1078 if (!g_lldb_headers_dir) 1079 { 1080#if defined (__APPLE__) 1081 FileSpec lldb_file_spec; 1082 if (GetLLDBPath (ePathTypeLLDBShlibDir, lldb_file_spec)) 1083 { 1084 char raw_path[PATH_MAX]; 1085 char resolved_path[PATH_MAX]; 1086 lldb_file_spec.GetPath(raw_path, sizeof(raw_path)); 1087 1088 char *framework_pos = ::strstr (raw_path, "LLDB.framework"); 1089 if (framework_pos) 1090 { 1091 framework_pos += strlen("LLDB.framework"); 1092 ::strncpy (framework_pos, "/Headers", PATH_MAX - (framework_pos - raw_path)); 1093 } 1094 FileSpec::Resolve (raw_path, resolved_path, sizeof(resolved_path)); 1095 g_lldb_headers_dir.SetCString(resolved_path); 1096 } 1097#else 1098 // TODO: Anyone know how we can determine this for linux? Other systems?? 1099 g_lldb_headers_dir.SetCString ("/opt/local/include/lldb"); 1100#endif 1101 if (log) 1102 log->Printf("Host::GetLLDBPath(ePathTypeHeaderDir) => '%s'", g_lldb_headers_dir.GetCString()); 1103 } 1104 file_spec.GetDirectory() = g_lldb_headers_dir; 1105 return (bool)file_spec.GetDirectory(); 1106 } 1107 break; 1108 1109#ifdef LLDB_DISABLE_PYTHON 1110 case ePathTypePythonDir: 1111 return false; 1112#else 1113 case ePathTypePythonDir: 1114 { 1115 static ConstString g_lldb_python_dir; 1116 if (!g_lldb_python_dir) 1117 { 1118 FileSpec lldb_file_spec; 1119 if (GetLLDBPath (ePathTypeLLDBShlibDir, lldb_file_spec)) 1120 { 1121 char raw_path[PATH_MAX]; 1122 char resolved_path[PATH_MAX]; 1123 lldb_file_spec.GetPath(raw_path, sizeof(raw_path)); 1124 1125#if defined (__APPLE__) 1126 char *framework_pos = ::strstr (raw_path, "LLDB.framework"); 1127 if (framework_pos) 1128 { 1129 framework_pos += strlen("LLDB.framework"); 1130 ::strncpy (framework_pos, "/Resources/Python", PATH_MAX - (framework_pos - raw_path)); 1131 } 1132 else 1133 { 1134#endif 1135 llvm::SmallString<256> python_version_dir; 1136 llvm::raw_svector_ostream os(python_version_dir); 1137 os << "/python" << PY_MAJOR_VERSION << '.' << PY_MINOR_VERSION << "/site-packages"; 1138 os.flush(); 1139 1140 // We may get our string truncated. Should we protect 1141 // this with an assert? 1142 1143 ::strncat(raw_path, python_version_dir.c_str(), 1144 sizeof(raw_path) - strlen(raw_path) - 1); 1145 1146#if defined (__APPLE__) 1147 } 1148#endif 1149 FileSpec::Resolve (raw_path, resolved_path, sizeof(resolved_path)); 1150 g_lldb_python_dir.SetCString(resolved_path); 1151 } 1152 1153 if (log) 1154 log->Printf("Host::GetLLDBPath(ePathTypePythonDir) => '%s'", g_lldb_python_dir.GetCString()); 1155 1156 } 1157 file_spec.GetDirectory() = g_lldb_python_dir; 1158 return (bool)file_spec.GetDirectory(); 1159 } 1160 break; 1161#endif 1162 1163 case ePathTypeLLDBSystemPlugins: // System plug-ins directory 1164 { 1165#if defined (__APPLE__) || defined(__linux__) 1166 static ConstString g_lldb_system_plugin_dir; 1167 static bool g_lldb_system_plugin_dir_located = false; 1168 if (!g_lldb_system_plugin_dir_located) 1169 { 1170 g_lldb_system_plugin_dir_located = true; 1171#if defined (__APPLE__) 1172 FileSpec lldb_file_spec; 1173 if (GetLLDBPath (ePathTypeLLDBShlibDir, lldb_file_spec)) 1174 { 1175 char raw_path[PATH_MAX]; 1176 char resolved_path[PATH_MAX]; 1177 lldb_file_spec.GetPath(raw_path, sizeof(raw_path)); 1178 1179 char *framework_pos = ::strstr (raw_path, "LLDB.framework"); 1180 if (framework_pos) 1181 { 1182 framework_pos += strlen("LLDB.framework"); 1183 ::strncpy (framework_pos, "/Resources/PlugIns", PATH_MAX - (framework_pos - raw_path)); 1184 FileSpec::Resolve (raw_path, resolved_path, sizeof(resolved_path)); 1185 g_lldb_system_plugin_dir.SetCString(resolved_path); 1186 } 1187 return false; 1188 } 1189#elif defined (__linux__) 1190 FileSpec lldb_file_spec("/usr/lib/lldb", true); 1191 if (lldb_file_spec.Exists()) 1192 { 1193 g_lldb_system_plugin_dir.SetCString(lldb_file_spec.GetPath().c_str()); 1194 } 1195#endif // __APPLE__ || __linux__ 1196 1197 if (log) 1198 log->Printf("Host::GetLLDBPath(ePathTypeLLDBSystemPlugins) => '%s'", g_lldb_system_plugin_dir.GetCString()); 1199 1200 } 1201 1202 if (g_lldb_system_plugin_dir) 1203 { 1204 file_spec.GetDirectory() = g_lldb_system_plugin_dir; 1205 return true; 1206 } 1207#else 1208 // TODO: where would system LLDB plug-ins be located on other systems? 1209 return false; 1210#endif 1211 } 1212 break; 1213 1214 case ePathTypeLLDBUserPlugins: // User plug-ins directory 1215 { 1216#if defined (__APPLE__) 1217 static ConstString g_lldb_user_plugin_dir; 1218 if (!g_lldb_user_plugin_dir) 1219 { 1220 char user_plugin_path[PATH_MAX]; 1221 if (FileSpec::Resolve ("~/Library/Application Support/LLDB/PlugIns", 1222 user_plugin_path, 1223 sizeof(user_plugin_path))) 1224 { 1225 g_lldb_user_plugin_dir.SetCString(user_plugin_path); 1226 } 1227 } 1228 file_spec.GetDirectory() = g_lldb_user_plugin_dir; 1229 return (bool)file_spec.GetDirectory(); 1230#elif defined (__linux__) 1231 static ConstString g_lldb_user_plugin_dir; 1232 if (!g_lldb_user_plugin_dir) 1233 { 1234 // XDG Base Directory Specification 1235 // http://standards.freedesktop.org/basedir-spec/basedir-spec-latest.html 1236 // If XDG_DATA_HOME exists, use that, otherwise use ~/.local/share/lldb. 1237 FileSpec lldb_file_spec; 1238 const char *xdg_data_home = getenv("XDG_DATA_HOME"); 1239 if (xdg_data_home && xdg_data_home[0]) 1240 { 1241 std::string user_plugin_dir (xdg_data_home); 1242 user_plugin_dir += "/lldb"; 1243 lldb_file_spec.SetFile (user_plugin_dir.c_str(), true); 1244 } 1245 else 1246 { 1247 const char *home_dir = getenv("HOME"); 1248 if (home_dir && home_dir[0]) 1249 { 1250 std::string user_plugin_dir (home_dir); 1251 user_plugin_dir += "/.local/share/lldb"; 1252 lldb_file_spec.SetFile (user_plugin_dir.c_str(), true); 1253 } 1254 } 1255 1256 if (lldb_file_spec.Exists()) 1257 g_lldb_user_plugin_dir.SetCString(lldb_file_spec.GetPath().c_str()); 1258 if (log) 1259 log->Printf("Host::GetLLDBPath(ePathTypeLLDBUserPlugins) => '%s'", g_lldb_user_plugin_dir.GetCString()); 1260 } 1261 file_spec.GetDirectory() = g_lldb_user_plugin_dir; 1262 return (bool)file_spec.GetDirectory(); 1263#endif 1264 // TODO: where would user LLDB plug-ins be located on other systems? 1265 return false; 1266 } 1267 1268 case ePathTypeLLDBTempSystemDir: 1269 { 1270 static ConstString g_lldb_tmp_dir; 1271 if (!g_lldb_tmp_dir) 1272 { 1273 const char *tmpdir_cstr = getenv("TMPDIR"); 1274 if (tmpdir_cstr == NULL) 1275 { 1276 tmpdir_cstr = getenv("TMP"); 1277 if (tmpdir_cstr == NULL) 1278 tmpdir_cstr = getenv("TEMP"); 1279 } 1280 if (tmpdir_cstr) 1281 { 1282 g_lldb_tmp_dir.SetCString(tmpdir_cstr); 1283 if (log) 1284 log->Printf("Host::GetLLDBPath(ePathTypeLLDBTempSystemDir) => '%s'", g_lldb_tmp_dir.GetCString()); 1285 } 1286 } 1287 file_spec.GetDirectory() = g_lldb_tmp_dir; 1288 return (bool)file_spec.GetDirectory(); 1289 } 1290 } 1291 1292 return false; 1293} 1294 1295 1296bool 1297Host::GetHostname (std::string &s) 1298{ 1299 char hostname[PATH_MAX]; 1300 hostname[sizeof(hostname) - 1] = '\0'; 1301 if (::gethostname (hostname, sizeof(hostname) - 1) == 0) 1302 { 1303 struct hostent* h = ::gethostbyname (hostname); 1304 if (h) 1305 s.assign (h->h_name); 1306 else 1307 s.assign (hostname); 1308 return true; 1309 } 1310 return false; 1311} 1312 1313#ifndef _WIN32 1314 1315const char * 1316Host::GetUserName (uint32_t uid, std::string &user_name) 1317{ 1318 struct passwd user_info; 1319 struct passwd *user_info_ptr = &user_info; 1320 char user_buffer[PATH_MAX]; 1321 size_t user_buffer_size = sizeof(user_buffer); 1322 if (::getpwuid_r (uid, 1323 &user_info, 1324 user_buffer, 1325 user_buffer_size, 1326 &user_info_ptr) == 0) 1327 { 1328 if (user_info_ptr) 1329 { 1330 user_name.assign (user_info_ptr->pw_name); 1331 return user_name.c_str(); 1332 } 1333 } 1334 user_name.clear(); 1335 return NULL; 1336} 1337 1338const char * 1339Host::GetGroupName (uint32_t gid, std::string &group_name) 1340{ 1341 char group_buffer[PATH_MAX]; 1342 size_t group_buffer_size = sizeof(group_buffer); 1343 struct group group_info; 1344 struct group *group_info_ptr = &group_info; 1345 // Try the threadsafe version first 1346 if (::getgrgid_r (gid, 1347 &group_info, 1348 group_buffer, 1349 group_buffer_size, 1350 &group_info_ptr) == 0) 1351 { 1352 if (group_info_ptr) 1353 { 1354 group_name.assign (group_info_ptr->gr_name); 1355 return group_name.c_str(); 1356 } 1357 } 1358 else 1359 { 1360 // The threadsafe version isn't currently working 1361 // for me on darwin, but the non-threadsafe version 1362 // is, so I am calling it below. 1363 group_info_ptr = ::getgrgid (gid); 1364 if (group_info_ptr) 1365 { 1366 group_name.assign (group_info_ptr->gr_name); 1367 return group_name.c_str(); 1368 } 1369 } 1370 group_name.clear(); 1371 return NULL; 1372} 1373 1374uint32_t 1375Host::GetUserID () 1376{ 1377 return getuid(); 1378} 1379 1380uint32_t 1381Host::GetGroupID () 1382{ 1383 return getgid(); 1384} 1385 1386uint32_t 1387Host::GetEffectiveUserID () 1388{ 1389 return geteuid(); 1390} 1391 1392uint32_t 1393Host::GetEffectiveGroupID () 1394{ 1395 return getegid(); 1396} 1397 1398#endif 1399 1400#if !defined (__APPLE__) && !defined (__FreeBSD__) && !defined (__FreeBSD_kernel__) // see macosx/Host.mm 1401bool 1402Host::GetOSBuildString (std::string &s) 1403{ 1404 s.clear(); 1405 return false; 1406} 1407 1408bool 1409Host::GetOSKernelDescription (std::string &s) 1410{ 1411 s.clear(); 1412 return false; 1413} 1414#endif 1415 1416#if !defined (__APPLE__) && !defined (__FreeBSD__) && !defined (__FreeBSD_kernel__) && !defined(__linux__) 1417uint32_t 1418Host::FindProcesses (const ProcessInstanceInfoMatch &match_info, ProcessInstanceInfoList &process_infos) 1419{ 1420 process_infos.Clear(); 1421 return process_infos.GetSize(); 1422} 1423 1424bool 1425Host::GetProcessInfo (lldb::pid_t pid, ProcessInstanceInfo &process_info) 1426{ 1427 process_info.Clear(); 1428 return false; 1429} 1430#endif 1431 1432#if !defined(__linux__) 1433bool 1434Host::FindProcessThreads (const lldb::pid_t pid, TidMap &tids_to_attach) 1435{ 1436 return false; 1437} 1438#endif 1439 1440lldb::TargetSP 1441Host::GetDummyTarget (lldb_private::Debugger &debugger) 1442{ 1443 static TargetSP g_dummy_target_sp; 1444 1445 // FIXME: Maybe the dummy target should be per-Debugger 1446 if (!g_dummy_target_sp || !g_dummy_target_sp->IsValid()) 1447 { 1448 ArchSpec arch(Target::GetDefaultArchitecture()); 1449 if (!arch.IsValid()) 1450 arch = Host::GetArchitecture (); 1451 Error err = debugger.GetTargetList().CreateTarget(debugger, 1452 NULL, 1453 arch.GetTriple().getTriple().c_str(), 1454 false, 1455 NULL, 1456 g_dummy_target_sp); 1457 } 1458 1459 return g_dummy_target_sp; 1460} 1461 1462struct ShellInfo 1463{ 1464 ShellInfo () : 1465 process_reaped (false), 1466 can_delete (false), 1467 pid (LLDB_INVALID_PROCESS_ID), 1468 signo(-1), 1469 status(-1) 1470 { 1471 } 1472 1473 lldb_private::Predicate<bool> process_reaped; 1474 lldb_private::Predicate<bool> can_delete; 1475 lldb::pid_t pid; 1476 int signo; 1477 int status; 1478}; 1479 1480static bool 1481MonitorShellCommand (void *callback_baton, 1482 lldb::pid_t pid, 1483 bool exited, // True if the process did exit 1484 int signo, // Zero for no signal 1485 int status) // Exit value of process if signal is zero 1486{ 1487 ShellInfo *shell_info = (ShellInfo *)callback_baton; 1488 shell_info->pid = pid; 1489 shell_info->signo = signo; 1490 shell_info->status = status; 1491 // Let the thread running Host::RunShellCommand() know that the process 1492 // exited and that ShellInfo has been filled in by broadcasting to it 1493 shell_info->process_reaped.SetValue(1, eBroadcastAlways); 1494 // Now wait for a handshake back from that thread running Host::RunShellCommand 1495 // so we know that we can delete shell_info_ptr 1496 shell_info->can_delete.WaitForValueEqualTo(true); 1497 // Sleep a bit to allow the shell_info->can_delete.SetValue() to complete... 1498 usleep(1000); 1499 // Now delete the shell info that was passed into this function 1500 delete shell_info; 1501 return true; 1502} 1503 1504Error 1505Host::RunShellCommand (const char *command, 1506 const char *working_dir, 1507 int *status_ptr, 1508 int *signo_ptr, 1509 std::string *command_output_ptr, 1510 uint32_t timeout_sec, 1511 const char *shell) 1512{ 1513 Error error; 1514 ProcessLaunchInfo launch_info; 1515 if (shell && shell[0]) 1516 { 1517 // Run the command in a shell 1518 launch_info.SetShell(shell); 1519 launch_info.GetArguments().AppendArgument(command); 1520 const bool localhost = true; 1521 const bool will_debug = false; 1522 const bool first_arg_is_full_shell_command = true; 1523 launch_info.ConvertArgumentsForLaunchingInShell (error, 1524 localhost, 1525 will_debug, 1526 first_arg_is_full_shell_command, 1527 0); 1528 } 1529 else 1530 { 1531 // No shell, just run it 1532 Args args (command); 1533 const bool first_arg_is_executable = true; 1534 launch_info.SetArguments(args, first_arg_is_executable); 1535 } 1536 1537 if (working_dir) 1538 launch_info.SetWorkingDirectory(working_dir); 1539 char output_file_path_buffer[PATH_MAX]; 1540 const char *output_file_path = NULL; 1541 1542 if (command_output_ptr) 1543 { 1544 // Create a temporary file to get the stdout/stderr and redirect the 1545 // output of the command into this file. We will later read this file 1546 // if all goes well and fill the data into "command_output_ptr" 1547 FileSpec tmpdir_file_spec; 1548 if (Host::GetLLDBPath (ePathTypeLLDBTempSystemDir, tmpdir_file_spec)) 1549 { 1550 tmpdir_file_spec.GetFilename().SetCString("lldb-shell-output.XXXXXX"); 1551 strncpy(output_file_path_buffer, tmpdir_file_spec.GetPath().c_str(), sizeof(output_file_path_buffer)); 1552 } 1553 else 1554 { 1555 strncpy(output_file_path_buffer, "/tmp/lldb-shell-output.XXXXXX", sizeof(output_file_path_buffer)); 1556 } 1557 1558 output_file_path = ::mktemp(output_file_path_buffer); 1559 } 1560 1561 launch_info.AppendSuppressFileAction (STDIN_FILENO, true, false); 1562 if (output_file_path) 1563 { 1564 launch_info.AppendOpenFileAction(STDOUT_FILENO, output_file_path, false, true); 1565 launch_info.AppendDuplicateFileAction(STDOUT_FILENO, STDERR_FILENO); 1566 } 1567 else 1568 { 1569 launch_info.AppendSuppressFileAction (STDOUT_FILENO, false, true); 1570 launch_info.AppendSuppressFileAction (STDERR_FILENO, false, true); 1571 } 1572 1573 // The process monitor callback will delete the 'shell_info_ptr' below... 1574 std::unique_ptr<ShellInfo> shell_info_ap (new ShellInfo()); 1575 1576 const bool monitor_signals = false; 1577 launch_info.SetMonitorProcessCallback(MonitorShellCommand, shell_info_ap.get(), monitor_signals); 1578 1579 error = LaunchProcess (launch_info); 1580 const lldb::pid_t pid = launch_info.GetProcessID(); 1581 1582 if (error.Success() && pid == LLDB_INVALID_PROCESS_ID) 1583 error.SetErrorString("failed to get process ID"); 1584 1585 if (error.Success()) 1586 { 1587 // The process successfully launched, so we can defer ownership of 1588 // "shell_info" to the MonitorShellCommand callback function that will 1589 // get called when the process dies. We release the unique pointer as it 1590 // doesn't need to delete the ShellInfo anymore. 1591 ShellInfo *shell_info = shell_info_ap.release(); 1592 TimeValue *timeout_ptr = nullptr; 1593 TimeValue timeout_time(TimeValue::Now()); 1594 if (timeout_sec > 0) { 1595 timeout_time.OffsetWithSeconds(timeout_sec); 1596 timeout_ptr = &timeout_time; 1597 } 1598 bool timed_out = false; 1599 shell_info->process_reaped.WaitForValueEqualTo(true, timeout_ptr, &timed_out); 1600 if (timed_out) 1601 { 1602 error.SetErrorString("timed out waiting for shell command to complete"); 1603 1604 // Kill the process since it didn't complete withint the timeout specified 1605 Kill (pid, SIGKILL); 1606 // Wait for the monitor callback to get the message 1607 timeout_time = TimeValue::Now(); 1608 timeout_time.OffsetWithSeconds(1); 1609 timed_out = false; 1610 shell_info->process_reaped.WaitForValueEqualTo(true, &timeout_time, &timed_out); 1611 } 1612 else 1613 { 1614 if (status_ptr) 1615 *status_ptr = shell_info->status; 1616 1617 if (signo_ptr) 1618 *signo_ptr = shell_info->signo; 1619 1620 if (command_output_ptr) 1621 { 1622 command_output_ptr->clear(); 1623 FileSpec file_spec(output_file_path, File::eOpenOptionRead); 1624 uint64_t file_size = file_spec.GetByteSize(); 1625 if (file_size > 0) 1626 { 1627 if (file_size > command_output_ptr->max_size()) 1628 { 1629 error.SetErrorStringWithFormat("shell command output is too large to fit into a std::string"); 1630 } 1631 else 1632 { 1633 command_output_ptr->resize(file_size); 1634 file_spec.ReadFileContents(0, &((*command_output_ptr)[0]), command_output_ptr->size(), &error); 1635 } 1636 } 1637 } 1638 } 1639 shell_info->can_delete.SetValue(true, eBroadcastAlways); 1640 } 1641 1642 if (output_file_path) 1643 ::unlink (output_file_path); 1644 // Handshake with the monitor thread, or just let it know in advance that 1645 // it can delete "shell_info" in case we timed out and were not able to kill 1646 // the process... 1647 return error; 1648} 1649 1650 1651// LaunchProcessPosixSpawn for Apple, Linux, FreeBSD and other GLIBC 1652// systems 1653 1654#if defined (__APPLE__) || defined (__linux__) || defined (__FreeBSD__) || defined (__GLIBC__) 1655 1656// this method needs to be visible to macosx/Host.cpp and 1657// common/Host.cpp. 1658 1659short 1660Host::GetPosixspawnFlags (ProcessLaunchInfo &launch_info) 1661{ 1662 short flags = POSIX_SPAWN_SETSIGDEF | POSIX_SPAWN_SETSIGMASK; 1663 1664#if defined (__APPLE__) 1665 if (launch_info.GetFlags().Test (eLaunchFlagExec)) 1666 flags |= POSIX_SPAWN_SETEXEC; // Darwin specific posix_spawn flag 1667 1668 if (launch_info.GetFlags().Test (eLaunchFlagDebug)) 1669 flags |= POSIX_SPAWN_START_SUSPENDED; // Darwin specific posix_spawn flag 1670 1671 if (launch_info.GetFlags().Test (eLaunchFlagDisableASLR)) 1672 flags |= _POSIX_SPAWN_DISABLE_ASLR; // Darwin specific posix_spawn flag 1673 1674 if (launch_info.GetLaunchInSeparateProcessGroup()) 1675 flags |= POSIX_SPAWN_SETPGROUP; 1676 1677#ifdef POSIX_SPAWN_CLOEXEC_DEFAULT 1678#if defined (__APPLE__) && (defined (__x86_64__) || defined (__i386__)) 1679 static LazyBool g_use_close_on_exec_flag = eLazyBoolCalculate; 1680 if (g_use_close_on_exec_flag == eLazyBoolCalculate) 1681 { 1682 g_use_close_on_exec_flag = eLazyBoolNo; 1683 1684 uint32_t major, minor, update; 1685 if (Host::GetOSVersion(major, minor, update)) 1686 { 1687 // Kernel panic if we use the POSIX_SPAWN_CLOEXEC_DEFAULT on 10.7 or earlier 1688 if (major > 10 || (major == 10 && minor > 7)) 1689 { 1690 // Only enable for 10.8 and later OS versions 1691 g_use_close_on_exec_flag = eLazyBoolYes; 1692 } 1693 } 1694 } 1695#else 1696 static LazyBool g_use_close_on_exec_flag = eLazyBoolYes; 1697#endif 1698 // Close all files exception those with file actions if this is supported. 1699 if (g_use_close_on_exec_flag == eLazyBoolYes) 1700 flags |= POSIX_SPAWN_CLOEXEC_DEFAULT; 1701#endif 1702#endif // #if defined (__APPLE__) 1703 return flags; 1704} 1705 1706Error 1707Host::LaunchProcessPosixSpawn (const char *exe_path, ProcessLaunchInfo &launch_info, ::pid_t &pid) 1708{ 1709 Error error; 1710 Log *log(lldb_private::GetLogIfAllCategoriesSet (LIBLLDB_LOG_HOST | LIBLLDB_LOG_PROCESS)); 1711 1712 posix_spawnattr_t attr; 1713 error.SetError( ::posix_spawnattr_init (&attr), eErrorTypePOSIX); 1714 1715 if (error.Fail() || log) 1716 error.PutToLog(log, "::posix_spawnattr_init ( &attr )"); 1717 if (error.Fail()) 1718 return error; 1719 1720 // Make a quick class that will cleanup the posix spawn attributes in case 1721 // we return in the middle of this function. 1722 lldb_utility::CleanUp <posix_spawnattr_t *, int> posix_spawnattr_cleanup(&attr, posix_spawnattr_destroy); 1723 1724 sigset_t no_signals; 1725 sigset_t all_signals; 1726 sigemptyset (&no_signals); 1727 sigfillset (&all_signals); 1728 ::posix_spawnattr_setsigmask(&attr, &no_signals); 1729#if defined (__linux__) || defined (__FreeBSD__) 1730 ::posix_spawnattr_setsigdefault(&attr, &no_signals); 1731#else 1732 ::posix_spawnattr_setsigdefault(&attr, &all_signals); 1733#endif 1734 1735 short flags = GetPosixspawnFlags(launch_info); 1736 1737 error.SetError( ::posix_spawnattr_setflags (&attr, flags), eErrorTypePOSIX); 1738 if (error.Fail() || log) 1739 error.PutToLog(log, "::posix_spawnattr_setflags ( &attr, flags=0x%8.8x )", flags); 1740 if (error.Fail()) 1741 return error; 1742 1743 // posix_spawnattr_setbinpref_np appears to be an Apple extension per: 1744 // http://www.unix.com/man-page/OSX/3/posix_spawnattr_setbinpref_np/ 1745#if defined (__APPLE__) && !defined (__arm__) 1746 1747 // Don't set the binpref if a shell was provided. After all, that's only going to affect what version of the shell 1748 // is launched, not what fork of the binary is launched. We insert "arch --arch <ARCH> as part of the shell invocation 1749 // to do that job on OSX. 1750 1751 if (launch_info.GetShell() == nullptr) 1752 { 1753 // We don't need to do this for ARM, and we really shouldn't now that we 1754 // have multiple CPU subtypes and no posix_spawnattr call that allows us 1755 // to set which CPU subtype to launch... 1756 const ArchSpec &arch_spec = launch_info.GetArchitecture(); 1757 cpu_type_t cpu = arch_spec.GetMachOCPUType(); 1758 cpu_type_t sub = arch_spec.GetMachOCPUSubType(); 1759 if (cpu != 0 && 1760 cpu != UINT32_MAX && 1761 cpu != LLDB_INVALID_CPUTYPE && 1762 !(cpu == 0x01000007 && sub == 8)) // If haswell is specified, don't try to set the CPU type or we will fail 1763 { 1764 size_t ocount = 0; 1765 error.SetError( ::posix_spawnattr_setbinpref_np (&attr, 1, &cpu, &ocount), eErrorTypePOSIX); 1766 if (error.Fail() || log) 1767 error.PutToLog(log, "::posix_spawnattr_setbinpref_np ( &attr, 1, cpu_type = 0x%8.8x, count => %llu )", cpu, (uint64_t)ocount); 1768 1769 if (error.Fail() || ocount != 1) 1770 return error; 1771 } 1772 } 1773 1774#endif 1775 1776 const char *tmp_argv[2]; 1777 char * const *argv = (char * const*)launch_info.GetArguments().GetConstArgumentVector(); 1778 char * const *envp = (char * const*)launch_info.GetEnvironmentEntries().GetConstArgumentVector(); 1779 if (argv == NULL) 1780 { 1781 // posix_spawn gets very unhappy if it doesn't have at least the program 1782 // name in argv[0]. One of the side affects I have noticed is the environment 1783 // variables don't make it into the child process if "argv == NULL"!!! 1784 tmp_argv[0] = exe_path; 1785 tmp_argv[1] = NULL; 1786 argv = (char * const*)tmp_argv; 1787 } 1788 1789#if !defined (__APPLE__) 1790 // manage the working directory 1791 char current_dir[PATH_MAX]; 1792 current_dir[0] = '\0'; 1793#endif 1794 1795 const char *working_dir = launch_info.GetWorkingDirectory(); 1796 if (working_dir) 1797 { 1798#if defined (__APPLE__) 1799 // Set the working directory on this thread only 1800 if (__pthread_chdir (working_dir) < 0) { 1801 if (errno == ENOENT) { 1802 error.SetErrorStringWithFormat("No such file or directory: %s", working_dir); 1803 } else if (errno == ENOTDIR) { 1804 error.SetErrorStringWithFormat("Path doesn't name a directory: %s", working_dir); 1805 } else { 1806 error.SetErrorStringWithFormat("An unknown error occurred when changing directory for process execution."); 1807 } 1808 return error; 1809 } 1810#else 1811 if (::getcwd(current_dir, sizeof(current_dir)) == NULL) 1812 { 1813 error.SetError(errno, eErrorTypePOSIX); 1814 error.LogIfError(log, "unable to save the current directory"); 1815 return error; 1816 } 1817 1818 if (::chdir(working_dir) == -1) 1819 { 1820 error.SetError(errno, eErrorTypePOSIX); 1821 error.LogIfError(log, "unable to change working directory to %s", working_dir); 1822 return error; 1823 } 1824#endif 1825 } 1826 1827 const size_t num_file_actions = launch_info.GetNumFileActions (); 1828 if (num_file_actions > 0) 1829 { 1830 posix_spawn_file_actions_t file_actions; 1831 error.SetError( ::posix_spawn_file_actions_init (&file_actions), eErrorTypePOSIX); 1832 if (error.Fail() || log) 1833 error.PutToLog(log, "::posix_spawn_file_actions_init ( &file_actions )"); 1834 if (error.Fail()) 1835 return error; 1836 1837 // Make a quick class that will cleanup the posix spawn attributes in case 1838 // we return in the middle of this function. 1839 lldb_utility::CleanUp <posix_spawn_file_actions_t *, int> posix_spawn_file_actions_cleanup (&file_actions, posix_spawn_file_actions_destroy); 1840 1841 for (size_t i=0; i<num_file_actions; ++i) 1842 { 1843 const ProcessLaunchInfo::FileAction *launch_file_action = launch_info.GetFileActionAtIndex(i); 1844 if (launch_file_action) 1845 { 1846 if (!ProcessLaunchInfo::FileAction::AddPosixSpawnFileAction (&file_actions, 1847 launch_file_action, 1848 log, 1849 error)) 1850 return error; 1851 } 1852 } 1853 1854 error.SetError (::posix_spawnp (&pid, 1855 exe_path, 1856 &file_actions, 1857 &attr, 1858 argv, 1859 envp), 1860 eErrorTypePOSIX); 1861 1862 if (error.Fail() || log) 1863 { 1864 error.PutToLog(log, "::posix_spawnp ( pid => %i, path = '%s', file_actions = %p, attr = %p, argv = %p, envp = %p )", 1865 pid, 1866 exe_path, 1867 &file_actions, 1868 &attr, 1869 argv, 1870 envp); 1871 if (log) 1872 { 1873 for (int ii=0; argv[ii]; ++ii) 1874 log->Printf("argv[%i] = '%s'", ii, argv[ii]); 1875 } 1876 } 1877 1878 } 1879 else 1880 { 1881 error.SetError (::posix_spawnp (&pid, 1882 exe_path, 1883 NULL, 1884 &attr, 1885 argv, 1886 envp), 1887 eErrorTypePOSIX); 1888 1889 if (error.Fail() || log) 1890 { 1891 error.PutToLog(log, "::posix_spawnp ( pid => %i, path = '%s', file_actions = NULL, attr = %p, argv = %p, envp = %p )", 1892 pid, 1893 exe_path, 1894 &attr, 1895 argv, 1896 envp); 1897 if (log) 1898 { 1899 for (int ii=0; argv[ii]; ++ii) 1900 log->Printf("argv[%i] = '%s'", ii, argv[ii]); 1901 } 1902 } 1903 } 1904 1905 if (working_dir) 1906 { 1907#if defined (__APPLE__) 1908 // No more thread specific current working directory 1909 __pthread_fchdir (-1); 1910#else 1911 if (::chdir(current_dir) == -1 && error.Success()) 1912 { 1913 error.SetError(errno, eErrorTypePOSIX); 1914 error.LogIfError(log, "unable to change current directory back to %s", 1915 current_dir); 1916 } 1917#endif 1918 } 1919 1920 return error; 1921} 1922 1923#endif // LaunchProcedssPosixSpawn: Apple, Linux, FreeBSD and other GLIBC systems 1924 1925 1926#if defined(__linux__) || defined(__FreeBSD__) || defined(__GLIBC__) 1927// The functions below implement process launching via posix_spawn() for Linux 1928// and FreeBSD. 1929 1930Error 1931Host::LaunchProcess (ProcessLaunchInfo &launch_info) 1932{ 1933 Error error; 1934 char exe_path[PATH_MAX]; 1935 1936 PlatformSP host_platform_sp (Platform::GetDefaultPlatform ()); 1937 1938 const ArchSpec &arch_spec = launch_info.GetArchitecture(); 1939 1940 FileSpec exe_spec(launch_info.GetExecutableFile()); 1941 1942 FileSpec::FileType file_type = exe_spec.GetFileType(); 1943 if (file_type != FileSpec::eFileTypeRegular) 1944 { 1945 lldb::ModuleSP exe_module_sp; 1946 error = host_platform_sp->ResolveExecutable (exe_spec, 1947 arch_spec, 1948 exe_module_sp, 1949 NULL); 1950 1951 if (error.Fail()) 1952 return error; 1953 1954 if (exe_module_sp) 1955 exe_spec = exe_module_sp->GetFileSpec(); 1956 } 1957 1958 if (exe_spec.Exists()) 1959 { 1960 exe_spec.GetPath (exe_path, sizeof(exe_path)); 1961 } 1962 else 1963 { 1964 launch_info.GetExecutableFile().GetPath (exe_path, sizeof(exe_path)); 1965 error.SetErrorStringWithFormat ("executable doesn't exist: '%s'", exe_path); 1966 return error; 1967 } 1968 1969 assert(!launch_info.GetFlags().Test (eLaunchFlagLaunchInTTY)); 1970 1971 ::pid_t pid = LLDB_INVALID_PROCESS_ID; 1972 1973 error = LaunchProcessPosixSpawn(exe_path, launch_info, pid); 1974 1975 if (pid != LLDB_INVALID_PROCESS_ID) 1976 { 1977 // If all went well, then set the process ID into the launch info 1978 launch_info.SetProcessID(pid); 1979 1980 Log *log(lldb_private::GetLogIfAllCategoriesSet (LIBLLDB_LOG_PROCESS)); 1981 1982 // Make sure we reap any processes we spawn or we will have zombies. 1983 if (!launch_info.MonitorProcess()) 1984 { 1985 const bool monitor_signals = false; 1986 StartMonitoringChildProcess (Process::SetProcessExitStatus, 1987 NULL, 1988 pid, 1989 monitor_signals); 1990 if (log) 1991 log->PutCString ("monitored child process with default Process::SetProcessExitStatus."); 1992 } 1993 else 1994 { 1995 if (log) 1996 log->PutCString ("monitored child process with user-specified process monitor."); 1997 } 1998 } 1999 else 2000 { 2001 // Invalid process ID, something didn't go well 2002 if (error.Success()) 2003 error.SetErrorString ("process launch failed for unknown reasons"); 2004 } 2005 return error; 2006} 2007 2008#endif // defined(__linux__) or defined(__FreeBSD__) 2009 2010#ifndef _WIN32 2011 2012size_t 2013Host::GetPageSize() 2014{ 2015 return ::getpagesize(); 2016} 2017 2018uint32_t 2019Host::GetNumberCPUS () 2020{ 2021 static uint32_t g_num_cores = UINT32_MAX; 2022 if (g_num_cores == UINT32_MAX) 2023 { 2024#if defined(__APPLE__) or defined (__linux__) or defined (__FreeBSD__) or defined (__FreeBSD_kernel__) 2025 2026 g_num_cores = ::sysconf(_SC_NPROCESSORS_ONLN); 2027 2028#else 2029 2030 // Assume POSIX support if a host specific case has not been supplied above 2031 g_num_cores = 0; 2032 int num_cores = 0; 2033 size_t num_cores_len = sizeof(num_cores); 2034#ifdef HW_AVAILCPU 2035 int mib[] = { CTL_HW, HW_AVAILCPU }; 2036#else 2037 int mib[] = { CTL_HW, HW_NCPU }; 2038#endif 2039 2040 /* get the number of CPUs from the system */ 2041 if (sysctl(mib, sizeof(mib)/sizeof(int), &num_cores, &num_cores_len, NULL, 0) == 0 && (num_cores > 0)) 2042 { 2043 g_num_cores = num_cores; 2044 } 2045 else 2046 { 2047 mib[1] = HW_NCPU; 2048 num_cores_len = sizeof(num_cores); 2049 if (sysctl(mib, sizeof(mib)/sizeof(int), &num_cores, &num_cores_len, NULL, 0) == 0 && (num_cores > 0)) 2050 { 2051 if (num_cores > 0) 2052 g_num_cores = num_cores; 2053 } 2054 } 2055#endif 2056 } 2057 return g_num_cores; 2058} 2059 2060void 2061Host::Kill(lldb::pid_t pid, int signo) 2062{ 2063 ::kill(pid, signo); 2064} 2065 2066#endif 2067 2068#if !defined (__APPLE__) 2069bool 2070Host::OpenFileInExternalEditor (const FileSpec &file_spec, uint32_t line_no) 2071{ 2072 return false; 2073} 2074 2075void 2076Host::SetCrashDescriptionWithFormat (const char *format, ...) 2077{ 2078} 2079 2080void 2081Host::SetCrashDescription (const char *description) 2082{ 2083} 2084 2085lldb::pid_t 2086Host::LaunchApplication (const FileSpec &app_file_spec) 2087{ 2088 return LLDB_INVALID_PROCESS_ID; 2089} 2090 2091#endif 2092 2093 2094#ifdef LLDB_DISABLE_POSIX 2095 2096Error 2097Host::MakeDirectory (const char* path, uint32_t mode) 2098{ 2099 Error error; 2100 error.SetErrorStringWithFormat("%s in not implemented on this host", __PRETTY_FUNCTION__); 2101 return error; 2102} 2103 2104Error 2105Host::GetFilePermissions (const char* path, uint32_t &file_permissions) 2106{ 2107 Error error; 2108 error.SetErrorStringWithFormat("%s is not supported on this host", __PRETTY_FUNCTION__); 2109 return error; 2110} 2111 2112Error 2113Host::SetFilePermissions (const char* path, uint32_t file_permissions) 2114{ 2115 Error error; 2116 error.SetErrorStringWithFormat("%s is not supported on this host", __PRETTY_FUNCTION__); 2117 return error; 2118} 2119 2120Error 2121Host::Symlink (const char *src, const char *dst) 2122{ 2123 Error error; 2124 error.SetErrorStringWithFormat("%s is not supported on this host", __PRETTY_FUNCTION__); 2125 return error; 2126} 2127 2128Error 2129Host::Readlink (const char *path, char *buf, size_t buf_len) 2130{ 2131 Error error; 2132 error.SetErrorStringWithFormat("%s is not supported on this host", __PRETTY_FUNCTION__); 2133 return error; 2134} 2135 2136Error 2137Host::Unlink (const char *path) 2138{ 2139 Error error; 2140 error.SetErrorStringWithFormat("%s is not supported on this host", __PRETTY_FUNCTION__); 2141 return error; 2142} 2143 2144#else 2145 2146Error 2147Host::MakeDirectory (const char* path, uint32_t file_permissions) 2148{ 2149 Error error; 2150 if (path && path[0]) 2151 { 2152 if (::mkdir(path, file_permissions) != 0) 2153 { 2154 error.SetErrorToErrno(); 2155 switch (error.GetError()) 2156 { 2157 case ENOENT: 2158 { 2159 // Parent directory doesn't exist, so lets make it if we can 2160 FileSpec spec(path, false); 2161 if (spec.GetDirectory() && spec.GetFilename()) 2162 { 2163 // Make the parent directory and try again 2164 Error error2 = Host::MakeDirectory(spec.GetDirectory().GetCString(), file_permissions); 2165 if (error2.Success()) 2166 { 2167 // Try and make the directory again now that the parent directory was made successfully 2168 if (::mkdir(path, file_permissions) == 0) 2169 error.Clear(); 2170 else 2171 error.SetErrorToErrno(); 2172 } 2173 } 2174 } 2175 break; 2176 case EEXIST: 2177 { 2178 FileSpec path_spec(path, false); 2179 if (path_spec.IsDirectory()) 2180 error.Clear(); // It is a directory and it already exists 2181 } 2182 break; 2183 } 2184 } 2185 } 2186 else 2187 { 2188 error.SetErrorString("empty path"); 2189 } 2190 return error; 2191} 2192 2193Error 2194Host::GetFilePermissions (const char* path, uint32_t &file_permissions) 2195{ 2196 Error error; 2197 struct stat file_stats; 2198 if (::stat (path, &file_stats) == 0) 2199 { 2200 // The bits in "st_mode" currently match the definitions 2201 // for the file mode bits in unix. 2202 file_permissions = file_stats.st_mode & (S_IRWXU | S_IRWXG | S_IRWXO); 2203 } 2204 else 2205 { 2206 error.SetErrorToErrno(); 2207 } 2208 return error; 2209} 2210 2211Error 2212Host::SetFilePermissions (const char* path, uint32_t file_permissions) 2213{ 2214 Error error; 2215 if (::chmod(path, file_permissions) != 0) 2216 error.SetErrorToErrno(); 2217 return error; 2218} 2219 2220Error 2221Host::Symlink (const char *src, const char *dst) 2222{ 2223 Error error; 2224 if (::symlink(dst, src) == -1) 2225 error.SetErrorToErrno(); 2226 return error; 2227} 2228 2229Error 2230Host::Unlink (const char *path) 2231{ 2232 Error error; 2233 if (::unlink(path) == -1) 2234 error.SetErrorToErrno(); 2235 return error; 2236} 2237 2238Error 2239Host::Readlink (const char *path, char *buf, size_t buf_len) 2240{ 2241 Error error; 2242 ssize_t count = ::readlink(path, buf, buf_len); 2243 if (count < 0) 2244 error.SetErrorToErrno(); 2245 else if (count < (buf_len-1)) 2246 buf[count] = '\0'; // Success 2247 else 2248 error.SetErrorString("'buf' buffer is too small to contain link contents"); 2249 return error; 2250} 2251 2252 2253#endif 2254 2255typedef std::map<lldb::user_id_t, lldb::FileSP> FDToFileMap; 2256FDToFileMap& GetFDToFileMap() 2257{ 2258 static FDToFileMap g_fd2filemap; 2259 return g_fd2filemap; 2260} 2261 2262lldb::user_id_t 2263Host::OpenFile (const FileSpec& file_spec, 2264 uint32_t flags, 2265 uint32_t mode, 2266 Error &error) 2267{ 2268 std::string path (file_spec.GetPath()); 2269 if (path.empty()) 2270 { 2271 error.SetErrorString("empty path"); 2272 return UINT64_MAX; 2273 } 2274 FileSP file_sp(new File()); 2275 error = file_sp->Open(path.c_str(),flags,mode); 2276 if (file_sp->IsValid() == false) 2277 return UINT64_MAX; 2278 lldb::user_id_t fd = file_sp->GetDescriptor(); 2279 GetFDToFileMap()[fd] = file_sp; 2280 return fd; 2281} 2282 2283bool 2284Host::CloseFile (lldb::user_id_t fd, Error &error) 2285{ 2286 if (fd == UINT64_MAX) 2287 { 2288 error.SetErrorString ("invalid file descriptor"); 2289 return false; 2290 } 2291 FDToFileMap& file_map = GetFDToFileMap(); 2292 FDToFileMap::iterator pos = file_map.find(fd); 2293 if (pos == file_map.end()) 2294 { 2295 error.SetErrorStringWithFormat ("invalid host file descriptor %" PRIu64, fd); 2296 return false; 2297 } 2298 FileSP file_sp = pos->second; 2299 if (!file_sp) 2300 { 2301 error.SetErrorString ("invalid host backing file"); 2302 return false; 2303 } 2304 error = file_sp->Close(); 2305 file_map.erase(pos); 2306 return error.Success(); 2307} 2308 2309uint64_t 2310Host::WriteFile (lldb::user_id_t fd, uint64_t offset, const void* src, uint64_t src_len, Error &error) 2311{ 2312 if (fd == UINT64_MAX) 2313 { 2314 error.SetErrorString ("invalid file descriptor"); 2315 return UINT64_MAX; 2316 } 2317 FDToFileMap& file_map = GetFDToFileMap(); 2318 FDToFileMap::iterator pos = file_map.find(fd); 2319 if (pos == file_map.end()) 2320 { 2321 error.SetErrorStringWithFormat("invalid host file descriptor %" PRIu64 , fd); 2322 return false; 2323 } 2324 FileSP file_sp = pos->second; 2325 if (!file_sp) 2326 { 2327 error.SetErrorString ("invalid host backing file"); 2328 return UINT64_MAX; 2329 } 2330 if (file_sp->SeekFromStart(offset, &error) != offset || error.Fail()) 2331 return UINT64_MAX; 2332 size_t bytes_written = src_len; 2333 error = file_sp->Write(src, bytes_written); 2334 if (error.Fail()) 2335 return UINT64_MAX; 2336 return bytes_written; 2337} 2338 2339uint64_t 2340Host::ReadFile (lldb::user_id_t fd, uint64_t offset, void* dst, uint64_t dst_len, Error &error) 2341{ 2342 if (fd == UINT64_MAX) 2343 { 2344 error.SetErrorString ("invalid file descriptor"); 2345 return UINT64_MAX; 2346 } 2347 FDToFileMap& file_map = GetFDToFileMap(); 2348 FDToFileMap::iterator pos = file_map.find(fd); 2349 if (pos == file_map.end()) 2350 { 2351 error.SetErrorStringWithFormat ("invalid host file descriptor %" PRIu64, fd); 2352 return false; 2353 } 2354 FileSP file_sp = pos->second; 2355 if (!file_sp) 2356 { 2357 error.SetErrorString ("invalid host backing file"); 2358 return UINT64_MAX; 2359 } 2360 if (file_sp->SeekFromStart(offset, &error) != offset || error.Fail()) 2361 return UINT64_MAX; 2362 size_t bytes_read = dst_len; 2363 error = file_sp->Read(dst ,bytes_read); 2364 if (error.Fail()) 2365 return UINT64_MAX; 2366 return bytes_read; 2367} 2368 2369lldb::user_id_t 2370Host::GetFileSize (const FileSpec& file_spec) 2371{ 2372 return file_spec.GetByteSize(); 2373} 2374 2375bool 2376Host::GetFileExists (const FileSpec& file_spec) 2377{ 2378 return file_spec.Exists(); 2379} 2380 2381bool 2382Host::CalculateMD5 (const FileSpec& file_spec, 2383 uint64_t &low, 2384 uint64_t &high) 2385{ 2386#if defined (__APPLE__) 2387 StreamString md5_cmd_line; 2388 md5_cmd_line.Printf("md5 -q '%s'", file_spec.GetPath().c_str()); 2389 std::string hash_string; 2390 Error err = Host::RunShellCommand(md5_cmd_line.GetData(), NULL, NULL, NULL, &hash_string, 60); 2391 if (err.Fail()) 2392 return false; 2393 // a correctly formed MD5 is 16-bytes, that is 32 hex digits 2394 // if the output is any other length it is probably wrong 2395 if (hash_string.size() != 32) 2396 return false; 2397 std::string part1(hash_string,0,16); 2398 std::string part2(hash_string,16); 2399 const char* part1_cstr = part1.c_str(); 2400 const char* part2_cstr = part2.c_str(); 2401 high = ::strtoull(part1_cstr, NULL, 16); 2402 low = ::strtoull(part2_cstr, NULL, 16); 2403 return true; 2404#else 2405 // your own MD5 implementation here 2406 return false; 2407#endif 2408} 2409