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 <dlfcn.h> 14#include <errno.h> 15#include <grp.h> 16#include <limits.h> 17#include <netdb.h> 18#include <pwd.h> 19#include <sys/types.h> 20#include <sys/sysctl.h> 21#include <unistd.h> 22 23#if defined (__APPLE__) 24 25#include <dispatch/dispatch.h> 26#include <libproc.h> 27#include <mach-o/dyld.h> 28#include <mach/mach_port.h> 29 30#endif 31 32#if defined (__linux__) || defined (__FreeBSD__) || defined (__FreeBSD_kernel__) 33#include <sys/wait.h> 34#include <sys/syscall.h> 35#endif 36 37#if defined (__FreeBSD__) 38#include <pthread_np.h> 39#endif 40 41#include "lldb/Host/Host.h" 42#include "lldb/Core/ArchSpec.h" 43#include "lldb/Core/ConstString.h" 44#include "lldb/Core/Debugger.h" 45#include "lldb/Core/Error.h" 46#include "lldb/Core/Log.h" 47#include "lldb/Core/StreamString.h" 48#include "lldb/Core/ThreadSafeSTLMap.h" 49#include "lldb/Host/Config.h" 50#include "lldb/Host/Endian.h" 51#include "lldb/Host/FileSpec.h" 52#include "lldb/Host/Mutex.h" 53#include "lldb/Target/Process.h" 54#include "lldb/Target/TargetList.h" 55 56#include "llvm/ADT/SmallString.h" 57#include "llvm/Support/Host.h" 58#include "llvm/Support/MachO.h" 59#include "llvm/Support/raw_ostream.h" 60 61 62 63 64 65using namespace lldb; 66using namespace lldb_private; 67 68 69#if !defined (__APPLE__) 70struct MonitorInfo 71{ 72 lldb::pid_t pid; // The process ID to monitor 73 Host::MonitorChildProcessCallback callback; // The callback function to call when "pid" exits or signals 74 void *callback_baton; // The callback baton for the callback function 75 bool monitor_signals; // If true, call the callback when "pid" gets signaled. 76}; 77 78static void * 79MonitorChildProcessThreadFunction (void *arg); 80 81lldb::thread_t 82Host::StartMonitoringChildProcess 83( 84 Host::MonitorChildProcessCallback callback, 85 void *callback_baton, 86 lldb::pid_t pid, 87 bool monitor_signals 88) 89{ 90 lldb::thread_t thread = LLDB_INVALID_HOST_THREAD; 91 MonitorInfo * info_ptr = new MonitorInfo(); 92 93 info_ptr->pid = pid; 94 info_ptr->callback = callback; 95 info_ptr->callback_baton = callback_baton; 96 info_ptr->monitor_signals = monitor_signals; 97 98 char thread_name[256]; 99 ::snprintf (thread_name, sizeof(thread_name), "<lldb.host.wait4(pid=%" PRIu64 ")>", pid); 100 thread = ThreadCreate (thread_name, 101 MonitorChildProcessThreadFunction, 102 info_ptr, 103 NULL); 104 105 return thread; 106} 107 108//------------------------------------------------------------------ 109// Scoped class that will disable thread canceling when it is 110// constructed, and exception safely restore the previous value it 111// when it goes out of scope. 112//------------------------------------------------------------------ 113class ScopedPThreadCancelDisabler 114{ 115public: 116 ScopedPThreadCancelDisabler() 117 { 118 // Disable the ability for this thread to be cancelled 119 int err = ::pthread_setcancelstate (PTHREAD_CANCEL_DISABLE, &m_old_state); 120 if (err != 0) 121 m_old_state = -1; 122 123 } 124 125 ~ScopedPThreadCancelDisabler() 126 { 127 // Restore the ability for this thread to be cancelled to what it 128 // previously was. 129 if (m_old_state != -1) 130 ::pthread_setcancelstate (m_old_state, 0); 131 } 132private: 133 int m_old_state; // Save the old cancelability state. 134}; 135 136static void * 137MonitorChildProcessThreadFunction (void *arg) 138{ 139 Log *log(lldb_private::GetLogIfAllCategoriesSet (LIBLLDB_LOG_PROCESS)); 140 const char *function = __FUNCTION__; 141 if (log) 142 log->Printf ("%s (arg = %p) thread starting...", function, arg); 143 144 MonitorInfo *info = (MonitorInfo *)arg; 145 146 const Host::MonitorChildProcessCallback callback = info->callback; 147 void * const callback_baton = info->callback_baton; 148 const lldb::pid_t pid = info->pid; 149 const bool monitor_signals = info->monitor_signals; 150 151 delete info; 152 153 int status = -1; 154#if defined (__FreeBSD__) || defined (__FreeBSD_kernel__) 155 #define __WALL 0 156#endif 157 const int options = __WALL; 158 159 while (1) 160 { 161 log = lldb_private::GetLogIfAllCategoriesSet (LIBLLDB_LOG_PROCESS); 162 if (log) 163 log->Printf("%s ::wait_pid (pid = %" PRIu64 ", &status, options = %i)...", function, pid, options); 164 165 // Wait for all child processes 166 ::pthread_testcancel (); 167 // Get signals from all children with same process group of pid 168 const lldb::pid_t wait_pid = ::waitpid (-1*pid, &status, options); 169 ::pthread_testcancel (); 170 171 if (wait_pid == -1) 172 { 173 if (errno == EINTR) 174 continue; 175 else 176 { 177 if (log) 178 log->Printf ("%s (arg = %p) thread exiting because waitpid failed (%s)...", __FUNCTION__, arg, strerror(errno)); 179 break; 180 } 181 } 182 else if (wait_pid > 0) 183 { 184 bool exited = false; 185 int signal = 0; 186 int exit_status = 0; 187 const char *status_cstr = NULL; 188 if (WIFSTOPPED(status)) 189 { 190 signal = WSTOPSIG(status); 191 status_cstr = "STOPPED"; 192 } 193 else if (WIFEXITED(status)) 194 { 195 exit_status = WEXITSTATUS(status); 196 status_cstr = "EXITED"; 197 exited = true; 198 } 199 else if (WIFSIGNALED(status)) 200 { 201 signal = WTERMSIG(status); 202 status_cstr = "SIGNALED"; 203 if (wait_pid == pid) { 204 exited = true; 205 exit_status = -1; 206 } 207 } 208 else 209 { 210 status_cstr = "(\?\?\?)"; 211 } 212 213 // Scope for pthread_cancel_disabler 214 { 215 ScopedPThreadCancelDisabler pthread_cancel_disabler; 216 217 log = lldb_private::GetLogIfAllCategoriesSet (LIBLLDB_LOG_PROCESS); 218 if (log) 219 log->Printf ("%s ::waitpid (pid = %" PRIu64 ", &status, options = %i) => pid = %" PRIu64 ", status = 0x%8.8x (%s), signal = %i, exit_state = %i", 220 function, 221 wait_pid, 222 options, 223 pid, 224 status, 225 status_cstr, 226 signal, 227 exit_status); 228 229 if (exited || (signal != 0 && monitor_signals)) 230 { 231 bool callback_return = false; 232 if (callback) 233 callback_return = callback (callback_baton, wait_pid, exited, signal, exit_status); 234 235 // If our process exited, then this thread should exit 236 if (exited && wait_pid == pid) 237 { 238 if (log) 239 log->Printf ("%s (arg = %p) thread exiting because pid received exit signal...", __FUNCTION__, arg); 240 break; 241 } 242 // If the callback returns true, it means this process should 243 // exit 244 if (callback_return) 245 { 246 if (log) 247 log->Printf ("%s (arg = %p) thread exiting because callback returned true...", __FUNCTION__, arg); 248 break; 249 } 250 } 251 } 252 } 253 } 254 255 log = lldb_private::GetLogIfAllCategoriesSet (LIBLLDB_LOG_PROCESS); 256 if (log) 257 log->Printf ("%s (arg = %p) thread exiting...", __FUNCTION__, arg); 258 259 return NULL; 260} 261 262 263void 264Host::SystemLog (SystemLogType type, const char *format, va_list args) 265{ 266 vfprintf (stderr, format, args); 267} 268 269#endif // #if !defined (__APPLE__) 270 271void 272Host::SystemLog (SystemLogType type, const char *format, ...) 273{ 274 va_list args; 275 va_start (args, format); 276 SystemLog (type, format, args); 277 va_end (args); 278} 279 280size_t 281Host::GetPageSize() 282{ 283 return ::getpagesize(); 284} 285 286const ArchSpec & 287Host::GetArchitecture (SystemDefaultArchitecture arch_kind) 288{ 289 static bool g_supports_32 = false; 290 static bool g_supports_64 = false; 291 static ArchSpec g_host_arch_32; 292 static ArchSpec g_host_arch_64; 293 294#if defined (__APPLE__) 295 296 // Apple is different in that it can support both 32 and 64 bit executables 297 // in the same operating system running concurrently. Here we detect the 298 // correct host architectures for both 32 and 64 bit including if 64 bit 299 // executables are supported on the system. 300 301 if (g_supports_32 == false && g_supports_64 == false) 302 { 303 // All apple systems support 32 bit execution. 304 g_supports_32 = true; 305 uint32_t cputype, cpusubtype; 306 uint32_t is_64_bit_capable = false; 307 size_t len = sizeof(cputype); 308 ArchSpec host_arch; 309 // These will tell us about the kernel architecture, which even on a 64 310 // bit machine can be 32 bit... 311 if (::sysctlbyname("hw.cputype", &cputype, &len, NULL, 0) == 0) 312 { 313 len = sizeof (cpusubtype); 314 if (::sysctlbyname("hw.cpusubtype", &cpusubtype, &len, NULL, 0) != 0) 315 cpusubtype = CPU_TYPE_ANY; 316 317 len = sizeof (is_64_bit_capable); 318 if (::sysctlbyname("hw.cpu64bit_capable", &is_64_bit_capable, &len, NULL, 0) == 0) 319 { 320 if (is_64_bit_capable) 321 g_supports_64 = true; 322 } 323 324 if (is_64_bit_capable) 325 { 326#if defined (__i386__) || defined (__x86_64__) 327 if (cpusubtype == CPU_SUBTYPE_486) 328 cpusubtype = CPU_SUBTYPE_I386_ALL; 329#endif 330 if (cputype & CPU_ARCH_ABI64) 331 { 332 // We have a 64 bit kernel on a 64 bit system 333 g_host_arch_32.SetArchitecture (eArchTypeMachO, ~(CPU_ARCH_MASK) & cputype, cpusubtype); 334 g_host_arch_64.SetArchitecture (eArchTypeMachO, cputype, cpusubtype); 335 } 336 else 337 { 338 // We have a 32 bit kernel on a 64 bit system 339 g_host_arch_32.SetArchitecture (eArchTypeMachO, cputype, cpusubtype); 340 cputype |= CPU_ARCH_ABI64; 341 g_host_arch_64.SetArchitecture (eArchTypeMachO, cputype, cpusubtype); 342 } 343 } 344 else 345 { 346 g_host_arch_32.SetArchitecture (eArchTypeMachO, cputype, cpusubtype); 347 g_host_arch_64.Clear(); 348 } 349 } 350 } 351 352#else // #if defined (__APPLE__) 353 354 if (g_supports_32 == false && g_supports_64 == false) 355 { 356 llvm::Triple triple(llvm::sys::getDefaultTargetTriple()); 357 358 g_host_arch_32.Clear(); 359 g_host_arch_64.Clear(); 360 361 // If the OS is Linux, "unknown" in the vendor slot isn't what we want 362 // for the default triple. It's probably an artifact of config.guess. 363 if (triple.getOS() == llvm::Triple::Linux && triple.getVendor() == llvm::Triple::UnknownVendor) 364 triple.setVendorName(""); 365 366 switch (triple.getArch()) 367 { 368 default: 369 g_host_arch_32.SetTriple(triple); 370 g_supports_32 = true; 371 break; 372 373 case llvm::Triple::x86_64: 374 g_host_arch_64.SetTriple(triple); 375 g_supports_64 = true; 376 g_host_arch_32.SetTriple(triple.get32BitArchVariant()); 377 g_supports_32 = true; 378 break; 379 380 case llvm::Triple::sparcv9: 381 case llvm::Triple::ppc64: 382 g_host_arch_64.SetTriple(triple); 383 g_supports_64 = true; 384 break; 385 } 386 387 g_supports_32 = g_host_arch_32.IsValid(); 388 g_supports_64 = g_host_arch_64.IsValid(); 389 } 390 391#endif // #else for #if defined (__APPLE__) 392 393 if (arch_kind == eSystemDefaultArchitecture32) 394 return g_host_arch_32; 395 else if (arch_kind == eSystemDefaultArchitecture64) 396 return g_host_arch_64; 397 398 if (g_supports_64) 399 return g_host_arch_64; 400 401 return g_host_arch_32; 402} 403 404const ConstString & 405Host::GetVendorString() 406{ 407 static ConstString g_vendor; 408 if (!g_vendor) 409 { 410 const ArchSpec &host_arch = GetArchitecture (eSystemDefaultArchitecture); 411 const llvm::StringRef &str_ref = host_arch.GetTriple().getVendorName(); 412 g_vendor.SetCStringWithLength(str_ref.data(), str_ref.size()); 413 } 414 return g_vendor; 415} 416 417const ConstString & 418Host::GetOSString() 419{ 420 static ConstString g_os_string; 421 if (!g_os_string) 422 { 423 const ArchSpec &host_arch = GetArchitecture (eSystemDefaultArchitecture); 424 const llvm::StringRef &str_ref = host_arch.GetTriple().getOSName(); 425 g_os_string.SetCStringWithLength(str_ref.data(), str_ref.size()); 426 } 427 return g_os_string; 428} 429 430const ConstString & 431Host::GetTargetTriple() 432{ 433 static ConstString g_host_triple; 434 if (!(g_host_triple)) 435 { 436 const ArchSpec &host_arch = GetArchitecture (eSystemDefaultArchitecture); 437 g_host_triple.SetCString(host_arch.GetTriple().getTriple().c_str()); 438 } 439 return g_host_triple; 440} 441 442lldb::pid_t 443Host::GetCurrentProcessID() 444{ 445 return ::getpid(); 446} 447 448lldb::tid_t 449Host::GetCurrentThreadID() 450{ 451#if defined (__APPLE__) 452 // Calling "mach_port_deallocate()" bumps the reference count on the thread 453 // port, so we need to deallocate it. mach_task_self() doesn't bump the ref 454 // count. 455 thread_port_t thread_self = mach_thread_self(); 456 mach_port_deallocate(mach_task_self(), thread_self); 457 return thread_self; 458#elif defined(__FreeBSD__) 459 return lldb::tid_t(pthread_getthreadid_np()); 460#elif defined(__linux__) 461 return lldb::tid_t(syscall(SYS_gettid)); 462#else 463 return lldb::tid_t(pthread_self()); 464#endif 465} 466 467lldb::thread_t 468Host::GetCurrentThread () 469{ 470 return lldb::thread_t(pthread_self()); 471} 472 473const char * 474Host::GetSignalAsCString (int signo) 475{ 476 switch (signo) 477 { 478 case SIGHUP: return "SIGHUP"; // 1 hangup 479 case SIGINT: return "SIGINT"; // 2 interrupt 480 case SIGQUIT: return "SIGQUIT"; // 3 quit 481 case SIGILL: return "SIGILL"; // 4 illegal instruction (not reset when caught) 482 case SIGTRAP: return "SIGTRAP"; // 5 trace trap (not reset when caught) 483 case SIGABRT: return "SIGABRT"; // 6 abort() 484#if (defined(_POSIX_C_SOURCE) && !defined(_DARWIN_C_SOURCE)) 485 case SIGPOLL: return "SIGPOLL"; // 7 pollable event ([XSR] generated, not supported) 486#endif 487#if !defined(_POSIX_C_SOURCE) 488 case SIGEMT: return "SIGEMT"; // 7 EMT instruction 489#endif 490 case SIGFPE: return "SIGFPE"; // 8 floating point exception 491 case SIGKILL: return "SIGKILL"; // 9 kill (cannot be caught or ignored) 492 case SIGBUS: return "SIGBUS"; // 10 bus error 493 case SIGSEGV: return "SIGSEGV"; // 11 segmentation violation 494 case SIGSYS: return "SIGSYS"; // 12 bad argument to system call 495 case SIGPIPE: return "SIGPIPE"; // 13 write on a pipe with no one to read it 496 case SIGALRM: return "SIGALRM"; // 14 alarm clock 497 case SIGTERM: return "SIGTERM"; // 15 software termination signal from kill 498 case SIGURG: return "SIGURG"; // 16 urgent condition on IO channel 499 case SIGSTOP: return "SIGSTOP"; // 17 sendable stop signal not from tty 500 case SIGTSTP: return "SIGTSTP"; // 18 stop signal from tty 501 case SIGCONT: return "SIGCONT"; // 19 continue a stopped process 502 case SIGCHLD: return "SIGCHLD"; // 20 to parent on child stop or exit 503 case SIGTTIN: return "SIGTTIN"; // 21 to readers pgrp upon background tty read 504 case SIGTTOU: return "SIGTTOU"; // 22 like TTIN for output if (tp->t_local<OSTOP) 505#if !defined(_POSIX_C_SOURCE) 506 case SIGIO: return "SIGIO"; // 23 input/output possible signal 507#endif 508 case SIGXCPU: return "SIGXCPU"; // 24 exceeded CPU time limit 509 case SIGXFSZ: return "SIGXFSZ"; // 25 exceeded file size limit 510 case SIGVTALRM: return "SIGVTALRM"; // 26 virtual time alarm 511 case SIGPROF: return "SIGPROF"; // 27 profiling time alarm 512#if !defined(_POSIX_C_SOURCE) 513 case SIGWINCH: return "SIGWINCH"; // 28 window size changes 514 case SIGINFO: return "SIGINFO"; // 29 information request 515#endif 516 case SIGUSR1: return "SIGUSR1"; // 30 user defined signal 1 517 case SIGUSR2: return "SIGUSR2"; // 31 user defined signal 2 518 default: 519 break; 520 } 521 return NULL; 522} 523 524void 525Host::WillTerminate () 526{ 527} 528 529#if !defined (__APPLE__) && !defined (__FreeBSD__) && !defined (__FreeBSD_kernel__) && !defined (__linux__) // see macosx/Host.mm 530 531void 532Host::ThreadCreated (const char *thread_name) 533{ 534} 535 536void 537Host::Backtrace (Stream &strm, uint32_t max_frames) 538{ 539 // TODO: Is there a way to backtrace the current process on other systems? 540} 541 542size_t 543Host::GetEnvironment (StringList &env) 544{ 545 // TODO: Is there a way to the host environment for this process on other systems? 546 return 0; 547} 548 549#endif // #if !defined (__APPLE__) && !defined (__FreeBSD__) && !defined (__FreeBSD_kernel__) && !defined (__linux__) 550 551struct HostThreadCreateInfo 552{ 553 std::string thread_name; 554 thread_func_t thread_fptr; 555 thread_arg_t thread_arg; 556 557 HostThreadCreateInfo (const char *name, thread_func_t fptr, thread_arg_t arg) : 558 thread_name (name ? name : ""), 559 thread_fptr (fptr), 560 thread_arg (arg) 561 { 562 } 563}; 564 565static thread_result_t 566ThreadCreateTrampoline (thread_arg_t arg) 567{ 568 HostThreadCreateInfo *info = (HostThreadCreateInfo *)arg; 569 Host::ThreadCreated (info->thread_name.c_str()); 570 thread_func_t thread_fptr = info->thread_fptr; 571 thread_arg_t thread_arg = info->thread_arg; 572 573 Log *log(lldb_private::GetLogIfAllCategoriesSet (LIBLLDB_LOG_THREAD)); 574 if (log) 575 log->Printf("thread created"); 576 577 delete info; 578 return thread_fptr (thread_arg); 579} 580 581lldb::thread_t 582Host::ThreadCreate 583( 584 const char *thread_name, 585 thread_func_t thread_fptr, 586 thread_arg_t thread_arg, 587 Error *error 588) 589{ 590 lldb::thread_t thread = LLDB_INVALID_HOST_THREAD; 591 592 // Host::ThreadCreateTrampoline will delete this pointer for us. 593 HostThreadCreateInfo *info_ptr = new HostThreadCreateInfo (thread_name, thread_fptr, thread_arg); 594 595 int err = ::pthread_create (&thread, NULL, ThreadCreateTrampoline, info_ptr); 596 if (err == 0) 597 { 598 if (error) 599 error->Clear(); 600 return thread; 601 } 602 603 if (error) 604 error->SetError (err, eErrorTypePOSIX); 605 606 return LLDB_INVALID_HOST_THREAD; 607} 608 609bool 610Host::ThreadCancel (lldb::thread_t thread, Error *error) 611{ 612 int err = ::pthread_cancel (thread); 613 if (error) 614 error->SetError(err, eErrorTypePOSIX); 615 return err == 0; 616} 617 618bool 619Host::ThreadDetach (lldb::thread_t thread, Error *error) 620{ 621 int err = ::pthread_detach (thread); 622 if (error) 623 error->SetError(err, eErrorTypePOSIX); 624 return err == 0; 625} 626 627bool 628Host::ThreadJoin (lldb::thread_t thread, thread_result_t *thread_result_ptr, Error *error) 629{ 630 int err = ::pthread_join (thread, thread_result_ptr); 631 if (error) 632 error->SetError(err, eErrorTypePOSIX); 633 return err == 0; 634} 635 636bool 637Host::SetThreadName (lldb::pid_t pid, lldb::tid_t tid, const char *name) 638{ 639#if defined(__APPLE__) && MAC_OS_X_VERSION_MAX_ALLOWED > MAC_OS_X_VERSION_10_5 640 lldb::pid_t curr_pid = Host::GetCurrentProcessID(); 641 lldb::tid_t curr_tid = Host::GetCurrentThreadID(); 642 if (pid == LLDB_INVALID_PROCESS_ID) 643 pid = curr_pid; 644 645 if (tid == LLDB_INVALID_THREAD_ID) 646 tid = curr_tid; 647 648 // Set the pthread name if possible 649 if (pid == curr_pid && tid == curr_tid) 650 { 651 if (::pthread_setname_np (name) == 0) 652 return true; 653 } 654 return false; 655#elif defined (__FreeBSD__) 656 lldb::pid_t curr_pid = Host::GetCurrentProcessID(); 657 lldb::tid_t curr_tid = Host::GetCurrentThreadID(); 658 if (pid == LLDB_INVALID_PROCESS_ID) 659 pid = curr_pid; 660 661 if (tid == LLDB_INVALID_THREAD_ID) 662 tid = curr_tid; 663 664 // Set the pthread name if possible 665 if (pid == curr_pid && tid == curr_tid) 666 { 667 ::pthread_set_name_np (::pthread_self(), name); 668 return true; 669 } 670 return false; 671#elif defined (__linux__) || defined (__GLIBC__) 672 void *fn = dlsym (RTLD_DEFAULT, "pthread_setname_np"); 673 if (fn) 674 { 675 lldb::pid_t curr_pid = Host::GetCurrentProcessID(); 676 lldb::tid_t curr_tid = Host::GetCurrentThreadID(); 677 if (pid == LLDB_INVALID_PROCESS_ID) 678 pid = curr_pid; 679 680 if (tid == LLDB_INVALID_THREAD_ID) 681 tid = curr_tid; 682 683 if (pid == curr_pid && tid == curr_tid) 684 { 685 int (*pthread_setname_np_func)(pthread_t thread, const char *name); 686 *reinterpret_cast<void **> (&pthread_setname_np_func) = fn; 687 688 if (pthread_setname_np_func (::pthread_self(), name) == 0) 689 return true; 690 } 691 } 692 return false; 693#else 694 return false; 695#endif 696} 697 698bool 699Host::SetShortThreadName (lldb::pid_t pid, lldb::tid_t tid, 700 const char *thread_name, size_t len) 701{ 702 char *namebuf = (char *)::malloc (len + 1); 703 704 // Thread names are coming in like '<lldb.comm.debugger.edit>' and 705 // '<lldb.comm.debugger.editline>'. So just chopping the end of the string 706 // off leads to a lot of similar named threads. Go through the thread name 707 // and search for the last dot and use that. 708 const char *lastdot = ::strrchr (thread_name, '.'); 709 710 if (lastdot && lastdot != thread_name) 711 thread_name = lastdot + 1; 712 ::strncpy (namebuf, thread_name, len); 713 namebuf[len] = 0; 714 715 int namebuflen = strlen(namebuf); 716 if (namebuflen > 0) 717 { 718 if (namebuf[namebuflen - 1] == '(' || namebuf[namebuflen - 1] == '>') 719 { 720 // Trim off trailing '(' and '>' characters for a bit more cleanup. 721 namebuflen--; 722 namebuf[namebuflen] = 0; 723 } 724 return Host::SetThreadName (pid, tid, namebuf); 725 } 726 return false; 727} 728 729FileSpec 730Host::GetProgramFileSpec () 731{ 732 static FileSpec g_program_filespec; 733 if (!g_program_filespec) 734 { 735#if defined (__APPLE__) 736 char program_fullpath[PATH_MAX]; 737 // If DST is NULL, then return the number of bytes needed. 738 uint32_t len = sizeof(program_fullpath); 739 int err = _NSGetExecutablePath (program_fullpath, &len); 740 if (err == 0) 741 g_program_filespec.SetFile (program_fullpath, false); 742 else if (err == -1) 743 { 744 char *large_program_fullpath = (char *)::malloc (len + 1); 745 746 err = _NSGetExecutablePath (large_program_fullpath, &len); 747 if (err == 0) 748 g_program_filespec.SetFile (large_program_fullpath, false); 749 750 ::free (large_program_fullpath); 751 } 752#elif defined (__linux__) 753 char exe_path[PATH_MAX]; 754 ssize_t len = readlink("/proc/self/exe", exe_path, sizeof(exe_path) - 1); 755 if (len > 0) { 756 exe_path[len] = 0; 757 g_program_filespec.SetFile(exe_path, false); 758 } 759#elif defined (__FreeBSD__) || defined (__FreeBSD_kernel__) 760 int exe_path_mib[4] = { CTL_KERN, KERN_PROC, KERN_PROC_PATHNAME, getpid() }; 761 size_t exe_path_size; 762 if (sysctl(exe_path_mib, 4, NULL, &exe_path_size, NULL, 0) == 0) 763 { 764 char *exe_path = new char[exe_path_size]; 765 if (sysctl(exe_path_mib, 4, exe_path, &exe_path_size, NULL, 0) == 0) 766 g_program_filespec.SetFile(exe_path, false); 767 delete[] exe_path; 768 } 769#endif 770 } 771 return g_program_filespec; 772} 773 774FileSpec 775Host::GetModuleFileSpecForHostAddress (const void *host_addr) 776{ 777 FileSpec module_filespec; 778 Dl_info info; 779 if (::dladdr (host_addr, &info)) 780 { 781 if (info.dli_fname) 782 module_filespec.SetFile(info.dli_fname, true); 783 } 784 return module_filespec; 785} 786 787#if !defined (__APPLE__) // see Host.mm 788 789bool 790Host::GetBundleDirectory (const FileSpec &file, FileSpec &bundle) 791{ 792 bundle.Clear(); 793 return false; 794} 795 796bool 797Host::ResolveExecutableInBundle (FileSpec &file) 798{ 799 return false; 800} 801#endif 802 803// Opaque info that tracks a dynamic library that was loaded 804struct DynamicLibraryInfo 805{ 806 DynamicLibraryInfo (const FileSpec &fs, int o, void *h) : 807 file_spec (fs), 808 open_options (o), 809 handle (h) 810 { 811 } 812 813 const FileSpec file_spec; 814 uint32_t open_options; 815 void * handle; 816}; 817 818void * 819Host::DynamicLibraryOpen (const FileSpec &file_spec, uint32_t options, Error &error) 820{ 821 char path[PATH_MAX]; 822 if (file_spec.GetPath(path, sizeof(path))) 823 { 824 int mode = 0; 825 826 if (options & eDynamicLibraryOpenOptionLazy) 827 mode |= RTLD_LAZY; 828 else 829 mode |= RTLD_NOW; 830 831 832 if (options & eDynamicLibraryOpenOptionLocal) 833 mode |= RTLD_LOCAL; 834 else 835 mode |= RTLD_GLOBAL; 836 837#ifdef LLDB_CONFIG_DLOPEN_RTLD_FIRST_SUPPORTED 838 if (options & eDynamicLibraryOpenOptionLimitGetSymbol) 839 mode |= RTLD_FIRST; 840#endif 841 842 void * opaque = ::dlopen (path, mode); 843 844 if (opaque) 845 { 846 error.Clear(); 847 return new DynamicLibraryInfo (file_spec, options, opaque); 848 } 849 else 850 { 851 error.SetErrorString(::dlerror()); 852 } 853 } 854 else 855 { 856 error.SetErrorString("failed to extract path"); 857 } 858 return NULL; 859} 860 861Error 862Host::DynamicLibraryClose (void *opaque) 863{ 864 Error error; 865 if (opaque == NULL) 866 { 867 error.SetErrorString ("invalid dynamic library handle"); 868 } 869 else 870 { 871 DynamicLibraryInfo *dylib_info = (DynamicLibraryInfo *) opaque; 872 if (::dlclose (dylib_info->handle) != 0) 873 { 874 error.SetErrorString(::dlerror()); 875 } 876 877 dylib_info->open_options = 0; 878 dylib_info->handle = 0; 879 delete dylib_info; 880 } 881 return error; 882} 883 884void * 885Host::DynamicLibraryGetSymbol (void *opaque, const char *symbol_name, Error &error) 886{ 887 if (opaque == NULL) 888 { 889 error.SetErrorString ("invalid dynamic library handle"); 890 } 891 else 892 { 893 DynamicLibraryInfo *dylib_info = (DynamicLibraryInfo *) opaque; 894 895 void *symbol_addr = ::dlsym (dylib_info->handle, symbol_name); 896 if (symbol_addr) 897 { 898#ifndef LLDB_CONFIG_DLOPEN_RTLD_FIRST_SUPPORTED 899 // This host doesn't support limiting searches to this shared library 900 // so we need to verify that the match came from this shared library 901 // if it was requested in the Host::DynamicLibraryOpen() function. 902 if (dylib_info->open_options & eDynamicLibraryOpenOptionLimitGetSymbol) 903 { 904 FileSpec match_dylib_spec (Host::GetModuleFileSpecForHostAddress (symbol_addr)); 905 if (match_dylib_spec != dylib_info->file_spec) 906 { 907 char dylib_path[PATH_MAX]; 908 if (dylib_info->file_spec.GetPath (dylib_path, sizeof(dylib_path))) 909 error.SetErrorStringWithFormat ("symbol not found in \"%s\"", dylib_path); 910 else 911 error.SetErrorString ("symbol not found"); 912 return NULL; 913 } 914 } 915#endif 916 error.Clear(); 917 return symbol_addr; 918 } 919 else 920 { 921 error.SetErrorString(::dlerror()); 922 } 923 } 924 return NULL; 925} 926 927bool 928Host::GetLLDBPath (PathType path_type, FileSpec &file_spec) 929{ 930 // To get paths related to LLDB we get the path to the executable that 931 // contains this function. On MacOSX this will be "LLDB.framework/.../LLDB", 932 // on linux this is assumed to be the "lldb" main executable. If LLDB on 933 // linux is actually in a shared library (liblldb.so) then this function will 934 // need to be modified to "do the right thing". 935 936 switch (path_type) 937 { 938 case ePathTypeLLDBShlibDir: 939 { 940 static ConstString g_lldb_so_dir; 941 if (!g_lldb_so_dir) 942 { 943 FileSpec lldb_file_spec (Host::GetModuleFileSpecForHostAddress ((void *)Host::GetLLDBPath)); 944 g_lldb_so_dir = lldb_file_spec.GetDirectory(); 945 } 946 file_spec.GetDirectory() = g_lldb_so_dir; 947 return file_spec.GetDirectory(); 948 } 949 break; 950 951 case ePathTypeSupportExecutableDir: 952 { 953 static ConstString g_lldb_support_exe_dir; 954 if (!g_lldb_support_exe_dir) 955 { 956 FileSpec lldb_file_spec; 957 if (GetLLDBPath (ePathTypeLLDBShlibDir, lldb_file_spec)) 958 { 959 char raw_path[PATH_MAX]; 960 char resolved_path[PATH_MAX]; 961 lldb_file_spec.GetPath(raw_path, sizeof(raw_path)); 962 963#if defined (__APPLE__) 964 char *framework_pos = ::strstr (raw_path, "LLDB.framework"); 965 if (framework_pos) 966 { 967 framework_pos += strlen("LLDB.framework"); 968#if !defined (__arm__) 969 ::strncpy (framework_pos, "/Resources", PATH_MAX - (framework_pos - raw_path)); 970#endif 971 } 972#endif 973 FileSpec::Resolve (raw_path, resolved_path, sizeof(resolved_path)); 974 g_lldb_support_exe_dir.SetCString(resolved_path); 975 } 976 } 977 file_spec.GetDirectory() = g_lldb_support_exe_dir; 978 return file_spec.GetDirectory(); 979 } 980 break; 981 982 case ePathTypeHeaderDir: 983 { 984 static ConstString g_lldb_headers_dir; 985 if (!g_lldb_headers_dir) 986 { 987#if defined (__APPLE__) 988 FileSpec lldb_file_spec; 989 if (GetLLDBPath (ePathTypeLLDBShlibDir, lldb_file_spec)) 990 { 991 char raw_path[PATH_MAX]; 992 char resolved_path[PATH_MAX]; 993 lldb_file_spec.GetPath(raw_path, sizeof(raw_path)); 994 995 char *framework_pos = ::strstr (raw_path, "LLDB.framework"); 996 if (framework_pos) 997 { 998 framework_pos += strlen("LLDB.framework"); 999 ::strncpy (framework_pos, "/Headers", PATH_MAX - (framework_pos - raw_path)); 1000 } 1001 FileSpec::Resolve (raw_path, resolved_path, sizeof(resolved_path)); 1002 g_lldb_headers_dir.SetCString(resolved_path); 1003 } 1004#else 1005 // TODO: Anyone know how we can determine this for linux? Other systems?? 1006 g_lldb_headers_dir.SetCString ("/opt/local/include/lldb"); 1007#endif 1008 } 1009 file_spec.GetDirectory() = g_lldb_headers_dir; 1010 return file_spec.GetDirectory(); 1011 } 1012 break; 1013 1014#ifndef LLDB_DISABLE_PYTHON 1015 case ePathTypePythonDir: 1016 { 1017 static ConstString g_lldb_python_dir; 1018 if (!g_lldb_python_dir) 1019 { 1020 FileSpec lldb_file_spec; 1021 if (GetLLDBPath (ePathTypeLLDBShlibDir, lldb_file_spec)) 1022 { 1023 char raw_path[PATH_MAX]; 1024 char resolved_path[PATH_MAX]; 1025 lldb_file_spec.GetPath(raw_path, sizeof(raw_path)); 1026 1027#if defined (__APPLE__) 1028 char *framework_pos = ::strstr (raw_path, "LLDB.framework"); 1029 if (framework_pos) 1030 { 1031 framework_pos += strlen("LLDB.framework"); 1032 ::strncpy (framework_pos, "/Resources/Python", PATH_MAX - (framework_pos - raw_path)); 1033 } 1034#else 1035 llvm::SmallString<256> python_version_dir; 1036 llvm::raw_svector_ostream os(python_version_dir); 1037 os << "/python" << PY_MAJOR_VERSION << '.' << PY_MINOR_VERSION << "/site-packages"; 1038 os.flush(); 1039 1040 // We may get our string truncated. Should we protect 1041 // this with an assert? 1042 1043 ::strncat(raw_path, python_version_dir.c_str(), 1044 sizeof(raw_path) - strlen(raw_path) - 1); 1045 1046#endif 1047 FileSpec::Resolve (raw_path, resolved_path, sizeof(resolved_path)); 1048 g_lldb_python_dir.SetCString(resolved_path); 1049 } 1050 } 1051 file_spec.GetDirectory() = g_lldb_python_dir; 1052 return file_spec.GetDirectory(); 1053 } 1054 break; 1055#endif 1056 1057 case ePathTypeLLDBSystemPlugins: // System plug-ins directory 1058 { 1059#if defined (__APPLE__) || defined(__linux__) 1060 static ConstString g_lldb_system_plugin_dir; 1061 static bool g_lldb_system_plugin_dir_located = false; 1062 if (!g_lldb_system_plugin_dir_located) 1063 { 1064 g_lldb_system_plugin_dir_located = true; 1065#if defined (__APPLE__) 1066 FileSpec lldb_file_spec; 1067 if (GetLLDBPath (ePathTypeLLDBShlibDir, lldb_file_spec)) 1068 { 1069 char raw_path[PATH_MAX]; 1070 char resolved_path[PATH_MAX]; 1071 lldb_file_spec.GetPath(raw_path, sizeof(raw_path)); 1072 1073 char *framework_pos = ::strstr (raw_path, "LLDB.framework"); 1074 if (framework_pos) 1075 { 1076 framework_pos += strlen("LLDB.framework"); 1077 ::strncpy (framework_pos, "/Resources/PlugIns", PATH_MAX - (framework_pos - raw_path)); 1078 FileSpec::Resolve (raw_path, resolved_path, sizeof(resolved_path)); 1079 g_lldb_system_plugin_dir.SetCString(resolved_path); 1080 } 1081 return false; 1082 } 1083#elif defined (__linux__) 1084 FileSpec lldb_file_spec("/usr/lib/lldb", true); 1085 if (lldb_file_spec.Exists()) 1086 { 1087 g_lldb_system_plugin_dir.SetCString(lldb_file_spec.GetPath().c_str()); 1088 } 1089#endif // __APPLE__ || __linux__ 1090 } 1091 1092 if (g_lldb_system_plugin_dir) 1093 { 1094 file_spec.GetDirectory() = g_lldb_system_plugin_dir; 1095 return true; 1096 } 1097#else 1098 // TODO: where would system LLDB plug-ins be located on other systems? 1099 return false; 1100#endif 1101 } 1102 break; 1103 1104 case ePathTypeLLDBUserPlugins: // User plug-ins directory 1105 { 1106#if defined (__APPLE__) 1107 static ConstString g_lldb_user_plugin_dir; 1108 if (!g_lldb_user_plugin_dir) 1109 { 1110 char user_plugin_path[PATH_MAX]; 1111 if (FileSpec::Resolve ("~/Library/Application Support/LLDB/PlugIns", 1112 user_plugin_path, 1113 sizeof(user_plugin_path))) 1114 { 1115 g_lldb_user_plugin_dir.SetCString(user_plugin_path); 1116 } 1117 } 1118 file_spec.GetDirectory() = g_lldb_user_plugin_dir; 1119 return file_spec.GetDirectory(); 1120#elif defined (__linux__) 1121 static ConstString g_lldb_user_plugin_dir; 1122 if (!g_lldb_user_plugin_dir) 1123 { 1124 // XDG Base Directory Specification 1125 // http://standards.freedesktop.org/basedir-spec/basedir-spec-latest.html 1126 // If XDG_DATA_HOME exists, use that, otherwise use ~/.local/share/lldb. 1127 FileSpec lldb_file_spec; 1128 const char *xdg_data_home = getenv("XDG_DATA_HOME"); 1129 if (xdg_data_home && xdg_data_home[0]) 1130 { 1131 std::string user_plugin_dir (xdg_data_home); 1132 user_plugin_dir += "/lldb"; 1133 lldb_file_spec.SetFile (user_plugin_dir.c_str(), true); 1134 } 1135 else 1136 { 1137 const char *home_dir = getenv("HOME"); 1138 if (home_dir && home_dir[0]) 1139 { 1140 std::string user_plugin_dir (home_dir); 1141 user_plugin_dir += "/.local/share/lldb"; 1142 lldb_file_spec.SetFile (user_plugin_dir.c_str(), true); 1143 } 1144 } 1145 1146 if (lldb_file_spec.Exists()) 1147 g_lldb_user_plugin_dir.SetCString(lldb_file_spec.GetPath().c_str()); 1148 } 1149 file_spec.GetDirectory() = g_lldb_user_plugin_dir; 1150 return file_spec.GetDirectory(); 1151#endif 1152 // TODO: where would user LLDB plug-ins be located on other systems? 1153 return false; 1154 } 1155 } 1156 1157 return false; 1158} 1159 1160 1161bool 1162Host::GetHostname (std::string &s) 1163{ 1164 char hostname[PATH_MAX]; 1165 hostname[sizeof(hostname) - 1] = '\0'; 1166 if (::gethostname (hostname, sizeof(hostname) - 1) == 0) 1167 { 1168 struct hostent* h = ::gethostbyname (hostname); 1169 if (h) 1170 s.assign (h->h_name); 1171 else 1172 s.assign (hostname); 1173 return true; 1174 } 1175 return false; 1176} 1177 1178const char * 1179Host::GetUserName (uint32_t uid, std::string &user_name) 1180{ 1181 struct passwd user_info; 1182 struct passwd *user_info_ptr = &user_info; 1183 char user_buffer[PATH_MAX]; 1184 size_t user_buffer_size = sizeof(user_buffer); 1185 if (::getpwuid_r (uid, 1186 &user_info, 1187 user_buffer, 1188 user_buffer_size, 1189 &user_info_ptr) == 0) 1190 { 1191 if (user_info_ptr) 1192 { 1193 user_name.assign (user_info_ptr->pw_name); 1194 return user_name.c_str(); 1195 } 1196 } 1197 user_name.clear(); 1198 return NULL; 1199} 1200 1201const char * 1202Host::GetGroupName (uint32_t gid, std::string &group_name) 1203{ 1204 char group_buffer[PATH_MAX]; 1205 size_t group_buffer_size = sizeof(group_buffer); 1206 struct group group_info; 1207 struct group *group_info_ptr = &group_info; 1208 // Try the threadsafe version first 1209 if (::getgrgid_r (gid, 1210 &group_info, 1211 group_buffer, 1212 group_buffer_size, 1213 &group_info_ptr) == 0) 1214 { 1215 if (group_info_ptr) 1216 { 1217 group_name.assign (group_info_ptr->gr_name); 1218 return group_name.c_str(); 1219 } 1220 } 1221 else 1222 { 1223 // The threadsafe version isn't currently working 1224 // for me on darwin, but the non-threadsafe version 1225 // is, so I am calling it below. 1226 group_info_ptr = ::getgrgid (gid); 1227 if (group_info_ptr) 1228 { 1229 group_name.assign (group_info_ptr->gr_name); 1230 return group_name.c_str(); 1231 } 1232 } 1233 group_name.clear(); 1234 return NULL; 1235} 1236 1237#if !defined (__APPLE__) && !defined (__FreeBSD__) && !defined (__FreeBSD_kernel__) // see macosx/Host.mm 1238bool 1239Host::GetOSBuildString (std::string &s) 1240{ 1241 s.clear(); 1242 return false; 1243} 1244 1245bool 1246Host::GetOSKernelDescription (std::string &s) 1247{ 1248 s.clear(); 1249 return false; 1250} 1251#endif 1252 1253uint32_t 1254Host::GetUserID () 1255{ 1256 return getuid(); 1257} 1258 1259uint32_t 1260Host::GetGroupID () 1261{ 1262 return getgid(); 1263} 1264 1265uint32_t 1266Host::GetEffectiveUserID () 1267{ 1268 return geteuid(); 1269} 1270 1271uint32_t 1272Host::GetEffectiveGroupID () 1273{ 1274 return getegid(); 1275} 1276 1277#if !defined (__APPLE__) && !defined(__linux__) 1278uint32_t 1279Host::FindProcesses (const ProcessInstanceInfoMatch &match_info, ProcessInstanceInfoList &process_infos) 1280{ 1281 process_infos.Clear(); 1282 return process_infos.GetSize(); 1283} 1284#endif // #if !defined (__APPLE__) && !defined(__linux__) 1285 1286#if !defined (__APPLE__) && !defined (__FreeBSD__) && !defined (__FreeBSD_kernel__) && !defined(__linux__) 1287bool 1288Host::GetProcessInfo (lldb::pid_t pid, ProcessInstanceInfo &process_info) 1289{ 1290 process_info.Clear(); 1291 return false; 1292} 1293#endif 1294 1295#if !defined(__linux__) 1296bool 1297Host::FindProcessThreads (const lldb::pid_t pid, TidMap &tids_to_attach) 1298{ 1299 return false; 1300} 1301#endif 1302 1303lldb::TargetSP 1304Host::GetDummyTarget (lldb_private::Debugger &debugger) 1305{ 1306 static TargetSP g_dummy_target_sp; 1307 1308 // FIXME: Maybe the dummy target should be per-Debugger 1309 if (!g_dummy_target_sp || !g_dummy_target_sp->IsValid()) 1310 { 1311 ArchSpec arch(Target::GetDefaultArchitecture()); 1312 if (!arch.IsValid()) 1313 arch = Host::GetArchitecture (); 1314 Error err = debugger.GetTargetList().CreateTarget(debugger, 1315 NULL, 1316 arch.GetTriple().getTriple().c_str(), 1317 false, 1318 NULL, 1319 g_dummy_target_sp); 1320 } 1321 1322 return g_dummy_target_sp; 1323} 1324 1325struct ShellInfo 1326{ 1327 ShellInfo () : 1328 process_reaped (false), 1329 can_delete (false), 1330 pid (LLDB_INVALID_PROCESS_ID), 1331 signo(-1), 1332 status(-1) 1333 { 1334 } 1335 1336 lldb_private::Predicate<bool> process_reaped; 1337 lldb_private::Predicate<bool> can_delete; 1338 lldb::pid_t pid; 1339 int signo; 1340 int status; 1341}; 1342 1343static bool 1344MonitorShellCommand (void *callback_baton, 1345 lldb::pid_t pid, 1346 bool exited, // True if the process did exit 1347 int signo, // Zero for no signal 1348 int status) // Exit value of process if signal is zero 1349{ 1350 ShellInfo *shell_info = (ShellInfo *)callback_baton; 1351 shell_info->pid = pid; 1352 shell_info->signo = signo; 1353 shell_info->status = status; 1354 // Let the thread running Host::RunShellCommand() know that the process 1355 // exited and that ShellInfo has been filled in by broadcasting to it 1356 shell_info->process_reaped.SetValue(1, eBroadcastAlways); 1357 // Now wait for a handshake back from that thread running Host::RunShellCommand 1358 // so we know that we can delete shell_info_ptr 1359 shell_info->can_delete.WaitForValueEqualTo(true); 1360 // Sleep a bit to allow the shell_info->can_delete.SetValue() to complete... 1361 usleep(1000); 1362 // Now delete the shell info that was passed into this function 1363 delete shell_info; 1364 return true; 1365} 1366 1367Error 1368Host::RunShellCommand (const char *command, 1369 const char *working_dir, 1370 int *status_ptr, 1371 int *signo_ptr, 1372 std::string *command_output_ptr, 1373 uint32_t timeout_sec, 1374 const char *shell) 1375{ 1376 Error error; 1377 ProcessLaunchInfo launch_info; 1378 if (shell && shell[0]) 1379 { 1380 // Run the command in a shell 1381 launch_info.SetShell(shell); 1382 launch_info.GetArguments().AppendArgument(command); 1383 const bool localhost = true; 1384 const bool will_debug = false; 1385 const bool first_arg_is_full_shell_command = true; 1386 launch_info.ConvertArgumentsForLaunchingInShell (error, 1387 localhost, 1388 will_debug, 1389 first_arg_is_full_shell_command); 1390 } 1391 else 1392 { 1393 // No shell, just run it 1394 Args args (command); 1395 const bool first_arg_is_executable = true; 1396 launch_info.SetArguments(args, first_arg_is_executable); 1397 } 1398 1399 if (working_dir) 1400 launch_info.SetWorkingDirectory(working_dir); 1401 char output_file_path_buffer[L_tmpnam]; 1402 const char *output_file_path = NULL; 1403 if (command_output_ptr) 1404 { 1405 // Create a temporary file to get the stdout/stderr and redirect the 1406 // output of the command into this file. We will later read this file 1407 // if all goes well and fill the data into "command_output_ptr" 1408 output_file_path = ::tmpnam(output_file_path_buffer); 1409 launch_info.AppendSuppressFileAction (STDIN_FILENO, true, false); 1410 launch_info.AppendOpenFileAction(STDOUT_FILENO, output_file_path, false, true); 1411 launch_info.AppendDuplicateFileAction(STDOUT_FILENO, STDERR_FILENO); 1412 } 1413 else 1414 { 1415 launch_info.AppendSuppressFileAction (STDIN_FILENO, true, false); 1416 launch_info.AppendSuppressFileAction (STDOUT_FILENO, false, true); 1417 launch_info.AppendSuppressFileAction (STDERR_FILENO, false, true); 1418 } 1419 1420 // The process monitor callback will delete the 'shell_info_ptr' below... 1421 std::unique_ptr<ShellInfo> shell_info_ap (new ShellInfo()); 1422 1423 const bool monitor_signals = false; 1424 launch_info.SetMonitorProcessCallback(MonitorShellCommand, shell_info_ap.get(), monitor_signals); 1425 1426 error = LaunchProcess (launch_info); 1427 const lldb::pid_t pid = launch_info.GetProcessID(); 1428 if (pid != LLDB_INVALID_PROCESS_ID) 1429 { 1430 // The process successfully launched, so we can defer ownership of 1431 // "shell_info" to the MonitorShellCommand callback function that will 1432 // get called when the process dies. We release the unique pointer as it 1433 // doesn't need to delete the ShellInfo anymore. 1434 ShellInfo *shell_info = shell_info_ap.release(); 1435 TimeValue timeout_time(TimeValue::Now()); 1436 timeout_time.OffsetWithSeconds(timeout_sec); 1437 bool timed_out = false; 1438 shell_info->process_reaped.WaitForValueEqualTo(true, &timeout_time, &timed_out); 1439 if (timed_out) 1440 { 1441 error.SetErrorString("timed out waiting for shell command to complete"); 1442 1443 // Kill the process since it didn't complete withint the timeout specified 1444 ::kill (pid, SIGKILL); 1445 // Wait for the monitor callback to get the message 1446 timeout_time = TimeValue::Now(); 1447 timeout_time.OffsetWithSeconds(1); 1448 timed_out = false; 1449 shell_info->process_reaped.WaitForValueEqualTo(true, &timeout_time, &timed_out); 1450 } 1451 else 1452 { 1453 if (status_ptr) 1454 *status_ptr = shell_info->status; 1455 1456 if (signo_ptr) 1457 *signo_ptr = shell_info->signo; 1458 1459 if (command_output_ptr) 1460 { 1461 command_output_ptr->clear(); 1462 FileSpec file_spec(output_file_path, File::eOpenOptionRead); 1463 uint64_t file_size = file_spec.GetByteSize(); 1464 if (file_size > 0) 1465 { 1466 if (file_size > command_output_ptr->max_size()) 1467 { 1468 error.SetErrorStringWithFormat("shell command output is too large to fit into a std::string"); 1469 } 1470 else 1471 { 1472 command_output_ptr->resize(file_size); 1473 file_spec.ReadFileContents(0, &((*command_output_ptr)[0]), command_output_ptr->size(), &error); 1474 } 1475 } 1476 } 1477 } 1478 shell_info->can_delete.SetValue(true, eBroadcastAlways); 1479 } 1480 else 1481 { 1482 error.SetErrorString("failed to get process ID"); 1483 } 1484 1485 if (output_file_path) 1486 ::unlink (output_file_path); 1487 // Handshake with the monitor thread, or just let it know in advance that 1488 // it can delete "shell_info" in case we timed out and were not able to kill 1489 // the process... 1490 return error; 1491} 1492 1493 1494uint32_t 1495Host::GetNumberCPUS () 1496{ 1497 static uint32_t g_num_cores = UINT32_MAX; 1498 if (g_num_cores == UINT32_MAX) 1499 { 1500#if defined(__APPLE__) or defined (__linux__) or defined (__FreeBSD__) or defined (__FreeBSD_kernel__) 1501 1502 g_num_cores = ::sysconf(_SC_NPROCESSORS_ONLN); 1503 1504#elif defined(_WIN32) || defined(__WIN32__) || defined(__CYGWIN__) 1505 1506 // Header file for this might need to be included at the top of this file 1507 SYSTEM_INFO system_info; 1508 ::GetSystemInfo (&system_info); 1509 g_num_cores = system_info.dwNumberOfProcessors; 1510 1511#else 1512 1513 // Assume POSIX support if a host specific case has not been supplied above 1514 g_num_cores = 0; 1515 int num_cores = 0; 1516 size_t num_cores_len = sizeof(num_cores); 1517#ifdef HW_AVAILCPU 1518 int mib[] = { CTL_HW, HW_AVAILCPU }; 1519#else 1520 int mib[] = { CTL_HW, HW_NCPU }; 1521#endif 1522 1523 /* get the number of CPUs from the system */ 1524 if (sysctl(mib, sizeof(mib)/sizeof(int), &num_cores, &num_cores_len, NULL, 0) == 0 && (num_cores > 0)) 1525 { 1526 g_num_cores = num_cores; 1527 } 1528 else 1529 { 1530 mib[1] = HW_NCPU; 1531 num_cores_len = sizeof(num_cores); 1532 if (sysctl(mib, sizeof(mib)/sizeof(int), &num_cores, &num_cores_len, NULL, 0) == 0 && (num_cores > 0)) 1533 { 1534 if (num_cores > 0) 1535 g_num_cores = num_cores; 1536 } 1537 } 1538#endif 1539 } 1540 return g_num_cores; 1541} 1542 1543 1544 1545#if !defined (__APPLE__) 1546bool 1547Host::OpenFileInExternalEditor (const FileSpec &file_spec, uint32_t line_no) 1548{ 1549 return false; 1550} 1551 1552void 1553Host::SetCrashDescriptionWithFormat (const char *format, ...) 1554{ 1555} 1556 1557void 1558Host::SetCrashDescription (const char *description) 1559{ 1560} 1561 1562lldb::pid_t 1563LaunchApplication (const FileSpec &app_file_spec) 1564{ 1565 return LLDB_INVALID_PROCESS_ID; 1566} 1567 1568#endif 1569