1254721Semaste//===-- Host.cpp ------------------------------------------------*- C++ -*-===// 2254721Semaste// 3254721Semaste// The LLVM Compiler Infrastructure 4254721Semaste// 5254721Semaste// This file is distributed under the University of Illinois Open Source 6254721Semaste// License. See LICENSE.TXT for details. 7254721Semaste// 8254721Semaste//===----------------------------------------------------------------------===// 9254721Semaste 10254721Semaste#include "lldb/lldb-python.h" 11254721Semaste 12254721Semaste// C includes 13263363Semaste#include <errno.h> 14263363Semaste#include <limits.h> 15263363Semaste#include <sys/types.h> 16263363Semaste#ifdef _WIN32 17263363Semaste#include "lldb/Host/windows/windows.h" 18263363Semaste#include <winsock2.h> 19263363Semaste#include <WS2tcpip.h> 20263363Semaste#else 21269024Semaste#include <unistd.h> 22254721Semaste#include <dlfcn.h> 23254721Semaste#include <grp.h> 24254721Semaste#include <netdb.h> 25254721Semaste#include <pwd.h> 26263367Semaste#include <sys/stat.h> 27263363Semaste#endif 28263363Semaste 29263363Semaste#if !defined (__GNU__) && !defined (_WIN32) 30263363Semaste// Does not exist under GNU/HURD or Windows 31254721Semaste#include <sys/sysctl.h> 32263363Semaste#endif 33254721Semaste 34254721Semaste#if defined (__APPLE__) 35263363Semaste#include <mach/mach_port.h> 36263363Semaste#include <mach/mach_init.h> 37254721Semaste#include <mach-o/dyld.h> 38263367Semaste#include <AvailabilityMacros.h> 39254721Semaste#endif 40254721Semaste 41269024Semaste#if defined (__linux__) || defined (__FreeBSD__) || defined (__FreeBSD_kernel__) || defined (__APPLE__) 42263363Semaste#include <spawn.h> 43254721Semaste#include <sys/wait.h> 44254721Semaste#include <sys/syscall.h> 45254721Semaste#endif 46254721Semaste 47254721Semaste#if defined (__FreeBSD__) 48254721Semaste#include <pthread_np.h> 49254721Semaste#endif 50254721Semaste 51254721Semaste#include "lldb/Host/Host.h" 52254721Semaste#include "lldb/Core/ArchSpec.h" 53254721Semaste#include "lldb/Core/ConstString.h" 54254721Semaste#include "lldb/Core/Debugger.h" 55254721Semaste#include "lldb/Core/Error.h" 56254721Semaste#include "lldb/Core/Log.h" 57263363Semaste#include "lldb/Core/Module.h" 58254721Semaste#include "lldb/Core/StreamString.h" 59254721Semaste#include "lldb/Core/ThreadSafeSTLMap.h" 60254721Semaste#include "lldb/Host/Config.h" 61254721Semaste#include "lldb/Host/Endian.h" 62254721Semaste#include "lldb/Host/FileSpec.h" 63254721Semaste#include "lldb/Host/Mutex.h" 64254721Semaste#include "lldb/Target/Process.h" 65254721Semaste#include "lldb/Target/TargetList.h" 66263363Semaste#include "lldb/Utility/CleanUp.h" 67254721Semaste 68254721Semaste#include "llvm/ADT/SmallString.h" 69254721Semaste#include "llvm/Support/Host.h" 70254721Semaste#include "llvm/Support/raw_ostream.h" 71254721Semaste 72269024Semaste#if defined (__APPLE__) 73269024Semaste#ifndef _POSIX_SPAWN_DISABLE_ASLR 74269024Semaste#define _POSIX_SPAWN_DISABLE_ASLR 0x0100 75269024Semaste#endif 76254721Semaste 77269024Semasteextern "C" 78269024Semaste{ 79269024Semaste int __pthread_chdir(const char *path); 80269024Semaste int __pthread_fchdir (int fildes); 81269024Semaste} 82269024Semaste 83269024Semaste#endif 84269024Semaste 85254721Semasteusing namespace lldb; 86254721Semasteusing namespace lldb_private; 87254721Semaste 88254721Semaste 89263363Semaste#if !defined (__APPLE__) && !defined (_WIN32) 90254721Semastestruct MonitorInfo 91254721Semaste{ 92254721Semaste lldb::pid_t pid; // The process ID to monitor 93254721Semaste Host::MonitorChildProcessCallback callback; // The callback function to call when "pid" exits or signals 94254721Semaste void *callback_baton; // The callback baton for the callback function 95254721Semaste bool monitor_signals; // If true, call the callback when "pid" gets signaled. 96254721Semaste}; 97254721Semaste 98263363Semastestatic thread_result_t 99254721SemasteMonitorChildProcessThreadFunction (void *arg); 100254721Semaste 101254721Semastelldb::thread_t 102254721SemasteHost::StartMonitoringChildProcess 103254721Semaste( 104254721Semaste Host::MonitorChildProcessCallback callback, 105254721Semaste void *callback_baton, 106254721Semaste lldb::pid_t pid, 107254721Semaste bool monitor_signals 108254721Semaste) 109254721Semaste{ 110254721Semaste lldb::thread_t thread = LLDB_INVALID_HOST_THREAD; 111254721Semaste MonitorInfo * info_ptr = new MonitorInfo(); 112263363Semaste 113254721Semaste info_ptr->pid = pid; 114254721Semaste info_ptr->callback = callback; 115254721Semaste info_ptr->callback_baton = callback_baton; 116254721Semaste info_ptr->monitor_signals = monitor_signals; 117254721Semaste 118254721Semaste char thread_name[256]; 119254721Semaste ::snprintf (thread_name, sizeof(thread_name), "<lldb.host.wait4(pid=%" PRIu64 ")>", pid); 120254721Semaste thread = ThreadCreate (thread_name, 121254721Semaste MonitorChildProcessThreadFunction, 122254721Semaste info_ptr, 123254721Semaste NULL); 124254721Semaste 125254721Semaste return thread; 126254721Semaste} 127254721Semaste 128254721Semaste//------------------------------------------------------------------ 129254721Semaste// Scoped class that will disable thread canceling when it is 130254721Semaste// constructed, and exception safely restore the previous value it 131254721Semaste// when it goes out of scope. 132254721Semaste//------------------------------------------------------------------ 133254721Semasteclass ScopedPThreadCancelDisabler 134254721Semaste{ 135254721Semastepublic: 136254721Semaste ScopedPThreadCancelDisabler() 137254721Semaste { 138254721Semaste // Disable the ability for this thread to be cancelled 139254721Semaste int err = ::pthread_setcancelstate (PTHREAD_CANCEL_DISABLE, &m_old_state); 140254721Semaste if (err != 0) 141254721Semaste m_old_state = -1; 142254721Semaste 143254721Semaste } 144254721Semaste 145254721Semaste ~ScopedPThreadCancelDisabler() 146254721Semaste { 147254721Semaste // Restore the ability for this thread to be cancelled to what it 148254721Semaste // previously was. 149254721Semaste if (m_old_state != -1) 150254721Semaste ::pthread_setcancelstate (m_old_state, 0); 151254721Semaste } 152254721Semasteprivate: 153254721Semaste int m_old_state; // Save the old cancelability state. 154254721Semaste}; 155254721Semaste 156263363Semastestatic thread_result_t 157254721SemasteMonitorChildProcessThreadFunction (void *arg) 158254721Semaste{ 159254721Semaste Log *log(lldb_private::GetLogIfAllCategoriesSet (LIBLLDB_LOG_PROCESS)); 160254721Semaste const char *function = __FUNCTION__; 161254721Semaste if (log) 162254721Semaste log->Printf ("%s (arg = %p) thread starting...", function, arg); 163254721Semaste 164254721Semaste MonitorInfo *info = (MonitorInfo *)arg; 165254721Semaste 166254721Semaste const Host::MonitorChildProcessCallback callback = info->callback; 167254721Semaste void * const callback_baton = info->callback_baton; 168254721Semaste const bool monitor_signals = info->monitor_signals; 169254721Semaste 170263363Semaste assert (info->pid <= UINT32_MAX); 171263363Semaste const ::pid_t pid = monitor_signals ? -1 * info->pid : info->pid; 172263363Semaste 173254721Semaste delete info; 174254721Semaste 175254721Semaste int status = -1; 176254721Semaste#if defined (__FreeBSD__) || defined (__FreeBSD_kernel__) 177254721Semaste #define __WALL 0 178254721Semaste#endif 179254721Semaste const int options = __WALL; 180254721Semaste 181254721Semaste while (1) 182254721Semaste { 183254721Semaste log = lldb_private::GetLogIfAllCategoriesSet (LIBLLDB_LOG_PROCESS); 184254721Semaste if (log) 185263363Semaste log->Printf("%s ::wait_pid (pid = %" PRIi32 ", &status, options = %i)...", function, pid, options); 186254721Semaste 187254721Semaste // Wait for all child processes 188254721Semaste ::pthread_testcancel (); 189254721Semaste // Get signals from all children with same process group of pid 190263363Semaste const ::pid_t wait_pid = ::waitpid (pid, &status, options); 191254721Semaste ::pthread_testcancel (); 192254721Semaste 193254721Semaste if (wait_pid == -1) 194254721Semaste { 195254721Semaste if (errno == EINTR) 196254721Semaste continue; 197254721Semaste else 198254721Semaste { 199254721Semaste if (log) 200254721Semaste log->Printf ("%s (arg = %p) thread exiting because waitpid failed (%s)...", __FUNCTION__, arg, strerror(errno)); 201254721Semaste break; 202254721Semaste } 203254721Semaste } 204254721Semaste else if (wait_pid > 0) 205254721Semaste { 206254721Semaste bool exited = false; 207254721Semaste int signal = 0; 208254721Semaste int exit_status = 0; 209254721Semaste const char *status_cstr = NULL; 210254721Semaste if (WIFSTOPPED(status)) 211254721Semaste { 212254721Semaste signal = WSTOPSIG(status); 213254721Semaste status_cstr = "STOPPED"; 214254721Semaste } 215254721Semaste else if (WIFEXITED(status)) 216254721Semaste { 217254721Semaste exit_status = WEXITSTATUS(status); 218254721Semaste status_cstr = "EXITED"; 219254721Semaste exited = true; 220254721Semaste } 221254721Semaste else if (WIFSIGNALED(status)) 222254721Semaste { 223254721Semaste signal = WTERMSIG(status); 224254721Semaste status_cstr = "SIGNALED"; 225263363Semaste if (wait_pid == abs(pid)) { 226254721Semaste exited = true; 227254721Semaste exit_status = -1; 228254721Semaste } 229254721Semaste } 230254721Semaste else 231254721Semaste { 232254721Semaste status_cstr = "(\?\?\?)"; 233254721Semaste } 234254721Semaste 235254721Semaste // Scope for pthread_cancel_disabler 236254721Semaste { 237254721Semaste ScopedPThreadCancelDisabler pthread_cancel_disabler; 238254721Semaste 239254721Semaste log = lldb_private::GetLogIfAllCategoriesSet (LIBLLDB_LOG_PROCESS); 240254721Semaste if (log) 241263363Semaste log->Printf ("%s ::waitpid (pid = %" PRIi32 ", &status, options = %i) => pid = %" PRIi32 ", status = 0x%8.8x (%s), signal = %i, exit_state = %i", 242254721Semaste function, 243254721Semaste wait_pid, 244254721Semaste options, 245254721Semaste pid, 246254721Semaste status, 247254721Semaste status_cstr, 248254721Semaste signal, 249254721Semaste exit_status); 250254721Semaste 251254721Semaste if (exited || (signal != 0 && monitor_signals)) 252254721Semaste { 253254721Semaste bool callback_return = false; 254254721Semaste if (callback) 255254721Semaste callback_return = callback (callback_baton, wait_pid, exited, signal, exit_status); 256254721Semaste 257254721Semaste // If our process exited, then this thread should exit 258263363Semaste if (exited && wait_pid == abs(pid)) 259254721Semaste { 260254721Semaste if (log) 261254721Semaste log->Printf ("%s (arg = %p) thread exiting because pid received exit signal...", __FUNCTION__, arg); 262254721Semaste break; 263254721Semaste } 264254721Semaste // If the callback returns true, it means this process should 265254721Semaste // exit 266254721Semaste if (callback_return) 267254721Semaste { 268254721Semaste if (log) 269254721Semaste log->Printf ("%s (arg = %p) thread exiting because callback returned true...", __FUNCTION__, arg); 270254721Semaste break; 271254721Semaste } 272254721Semaste } 273254721Semaste } 274254721Semaste } 275254721Semaste } 276254721Semaste 277254721Semaste log = lldb_private::GetLogIfAllCategoriesSet (LIBLLDB_LOG_PROCESS); 278254721Semaste if (log) 279254721Semaste log->Printf ("%s (arg = %p) thread exiting...", __FUNCTION__, arg); 280254721Semaste 281254721Semaste return NULL; 282254721Semaste} 283254721Semaste 284263363Semaste#endif // #if !defined (__APPLE__) && !defined (_WIN32) 285254721Semaste 286263363Semaste#if !defined (__APPLE__) 287263363Semaste 288254721Semastevoid 289254721SemasteHost::SystemLog (SystemLogType type, const char *format, va_list args) 290254721Semaste{ 291254721Semaste vfprintf (stderr, format, args); 292254721Semaste} 293254721Semaste 294263363Semaste#endif 295254721Semaste 296254721Semastevoid 297254721SemasteHost::SystemLog (SystemLogType type, const char *format, ...) 298254721Semaste{ 299254721Semaste va_list args; 300254721Semaste va_start (args, format); 301254721Semaste SystemLog (type, format, args); 302254721Semaste va_end (args); 303254721Semaste} 304254721Semaste 305254721Semasteconst ArchSpec & 306254721SemasteHost::GetArchitecture (SystemDefaultArchitecture arch_kind) 307254721Semaste{ 308254721Semaste static bool g_supports_32 = false; 309254721Semaste static bool g_supports_64 = false; 310254721Semaste static ArchSpec g_host_arch_32; 311254721Semaste static ArchSpec g_host_arch_64; 312254721Semaste 313254721Semaste#if defined (__APPLE__) 314254721Semaste 315254721Semaste // Apple is different in that it can support both 32 and 64 bit executables 316254721Semaste // in the same operating system running concurrently. Here we detect the 317254721Semaste // correct host architectures for both 32 and 64 bit including if 64 bit 318254721Semaste // executables are supported on the system. 319254721Semaste 320254721Semaste if (g_supports_32 == false && g_supports_64 == false) 321254721Semaste { 322254721Semaste // All apple systems support 32 bit execution. 323254721Semaste g_supports_32 = true; 324254721Semaste uint32_t cputype, cpusubtype; 325254721Semaste uint32_t is_64_bit_capable = false; 326254721Semaste size_t len = sizeof(cputype); 327254721Semaste ArchSpec host_arch; 328254721Semaste // These will tell us about the kernel architecture, which even on a 64 329254721Semaste // bit machine can be 32 bit... 330254721Semaste if (::sysctlbyname("hw.cputype", &cputype, &len, NULL, 0) == 0) 331254721Semaste { 332254721Semaste len = sizeof (cpusubtype); 333254721Semaste if (::sysctlbyname("hw.cpusubtype", &cpusubtype, &len, NULL, 0) != 0) 334254721Semaste cpusubtype = CPU_TYPE_ANY; 335254721Semaste 336254721Semaste len = sizeof (is_64_bit_capable); 337254721Semaste if (::sysctlbyname("hw.cpu64bit_capable", &is_64_bit_capable, &len, NULL, 0) == 0) 338254721Semaste { 339254721Semaste if (is_64_bit_capable) 340254721Semaste g_supports_64 = true; 341254721Semaste } 342254721Semaste 343254721Semaste if (is_64_bit_capable) 344254721Semaste { 345254721Semaste#if defined (__i386__) || defined (__x86_64__) 346254721Semaste if (cpusubtype == CPU_SUBTYPE_486) 347254721Semaste cpusubtype = CPU_SUBTYPE_I386_ALL; 348254721Semaste#endif 349254721Semaste if (cputype & CPU_ARCH_ABI64) 350254721Semaste { 351254721Semaste // We have a 64 bit kernel on a 64 bit system 352254721Semaste g_host_arch_32.SetArchitecture (eArchTypeMachO, ~(CPU_ARCH_MASK) & cputype, cpusubtype); 353254721Semaste g_host_arch_64.SetArchitecture (eArchTypeMachO, cputype, cpusubtype); 354254721Semaste } 355254721Semaste else 356254721Semaste { 357254721Semaste // We have a 32 bit kernel on a 64 bit system 358254721Semaste g_host_arch_32.SetArchitecture (eArchTypeMachO, cputype, cpusubtype); 359254721Semaste cputype |= CPU_ARCH_ABI64; 360254721Semaste g_host_arch_64.SetArchitecture (eArchTypeMachO, cputype, cpusubtype); 361254721Semaste } 362254721Semaste } 363254721Semaste else 364254721Semaste { 365254721Semaste g_host_arch_32.SetArchitecture (eArchTypeMachO, cputype, cpusubtype); 366254721Semaste g_host_arch_64.Clear(); 367254721Semaste } 368254721Semaste } 369254721Semaste } 370254721Semaste 371254721Semaste#else // #if defined (__APPLE__) 372254721Semaste 373254721Semaste if (g_supports_32 == false && g_supports_64 == false) 374254721Semaste { 375254721Semaste llvm::Triple triple(llvm::sys::getDefaultTargetTriple()); 376254721Semaste 377254721Semaste g_host_arch_32.Clear(); 378254721Semaste g_host_arch_64.Clear(); 379254721Semaste 380254721Semaste // If the OS is Linux, "unknown" in the vendor slot isn't what we want 381254721Semaste // for the default triple. It's probably an artifact of config.guess. 382254721Semaste if (triple.getOS() == llvm::Triple::Linux && triple.getVendor() == llvm::Triple::UnknownVendor) 383269024Semaste triple.setVendorName (""); 384254721Semaste 385269024Semaste const char* distribution_id = GetDistributionId ().AsCString(); 386269024Semaste 387254721Semaste switch (triple.getArch()) 388254721Semaste { 389254721Semaste default: 390254721Semaste g_host_arch_32.SetTriple(triple); 391269024Semaste g_host_arch_32.SetDistributionId (distribution_id); 392254721Semaste g_supports_32 = true; 393254721Semaste break; 394254721Semaste 395254721Semaste case llvm::Triple::x86_64: 396254721Semaste g_host_arch_64.SetTriple(triple); 397269024Semaste g_host_arch_64.SetDistributionId (distribution_id); 398254721Semaste g_supports_64 = true; 399254721Semaste g_host_arch_32.SetTriple(triple.get32BitArchVariant()); 400269024Semaste g_host_arch_32.SetDistributionId (distribution_id); 401254721Semaste g_supports_32 = true; 402254721Semaste break; 403254721Semaste 404254721Semaste case llvm::Triple::sparcv9: 405254721Semaste case llvm::Triple::ppc64: 406254721Semaste g_host_arch_64.SetTriple(triple); 407269024Semaste g_host_arch_64.SetDistributionId (distribution_id); 408254721Semaste g_supports_64 = true; 409254721Semaste break; 410254721Semaste } 411254721Semaste 412254721Semaste g_supports_32 = g_host_arch_32.IsValid(); 413254721Semaste g_supports_64 = g_host_arch_64.IsValid(); 414254721Semaste } 415254721Semaste 416254721Semaste#endif // #else for #if defined (__APPLE__) 417254721Semaste 418254721Semaste if (arch_kind == eSystemDefaultArchitecture32) 419254721Semaste return g_host_arch_32; 420254721Semaste else if (arch_kind == eSystemDefaultArchitecture64) 421254721Semaste return g_host_arch_64; 422254721Semaste 423254721Semaste if (g_supports_64) 424254721Semaste return g_host_arch_64; 425254721Semaste 426254721Semaste return g_host_arch_32; 427254721Semaste} 428254721Semaste 429254721Semasteconst ConstString & 430254721SemasteHost::GetVendorString() 431254721Semaste{ 432254721Semaste static ConstString g_vendor; 433254721Semaste if (!g_vendor) 434254721Semaste { 435254721Semaste const ArchSpec &host_arch = GetArchitecture (eSystemDefaultArchitecture); 436254721Semaste const llvm::StringRef &str_ref = host_arch.GetTriple().getVendorName(); 437254721Semaste g_vendor.SetCStringWithLength(str_ref.data(), str_ref.size()); 438254721Semaste } 439254721Semaste return g_vendor; 440254721Semaste} 441254721Semaste 442254721Semasteconst ConstString & 443254721SemasteHost::GetOSString() 444254721Semaste{ 445254721Semaste static ConstString g_os_string; 446254721Semaste if (!g_os_string) 447254721Semaste { 448254721Semaste const ArchSpec &host_arch = GetArchitecture (eSystemDefaultArchitecture); 449254721Semaste const llvm::StringRef &str_ref = host_arch.GetTriple().getOSName(); 450254721Semaste g_os_string.SetCStringWithLength(str_ref.data(), str_ref.size()); 451254721Semaste } 452254721Semaste return g_os_string; 453254721Semaste} 454254721Semaste 455254721Semasteconst ConstString & 456254721SemasteHost::GetTargetTriple() 457254721Semaste{ 458254721Semaste static ConstString g_host_triple; 459254721Semaste if (!(g_host_triple)) 460254721Semaste { 461254721Semaste const ArchSpec &host_arch = GetArchitecture (eSystemDefaultArchitecture); 462254721Semaste g_host_triple.SetCString(host_arch.GetTriple().getTriple().c_str()); 463254721Semaste } 464254721Semaste return g_host_triple; 465254721Semaste} 466254721Semaste 467269024Semaste// See linux/Host.cpp for Linux-based implementations of this. 468269024Semaste// Add your platform-specific implementation to the appropriate host file. 469269024Semaste#if !defined(__linux__) 470269024Semaste 471269024Semasteconst ConstString & 472269024Semaste Host::GetDistributionId () 473269024Semaste{ 474269024Semaste static ConstString s_distribution_id; 475269024Semaste return s_distribution_id; 476269024Semaste} 477269024Semaste 478269024Semaste#endif // #if !defined(__linux__) 479269024Semaste 480254721Semastelldb::pid_t 481254721SemasteHost::GetCurrentProcessID() 482254721Semaste{ 483254721Semaste return ::getpid(); 484254721Semaste} 485254721Semaste 486263363Semaste#ifndef _WIN32 487263363Semaste 488254721Semastelldb::tid_t 489254721SemasteHost::GetCurrentThreadID() 490254721Semaste{ 491254721Semaste#if defined (__APPLE__) 492269024Semaste // Calling "mach_thread_self()" bumps the reference count on the thread 493254721Semaste // port, so we need to deallocate it. mach_task_self() doesn't bump the ref 494254721Semaste // count. 495254721Semaste thread_port_t thread_self = mach_thread_self(); 496254721Semaste mach_port_deallocate(mach_task_self(), thread_self); 497254721Semaste return thread_self; 498254721Semaste#elif defined(__FreeBSD__) 499254721Semaste return lldb::tid_t(pthread_getthreadid_np()); 500254721Semaste#elif defined(__linux__) 501254721Semaste return lldb::tid_t(syscall(SYS_gettid)); 502254721Semaste#else 503254721Semaste return lldb::tid_t(pthread_self()); 504254721Semaste#endif 505254721Semaste} 506254721Semaste 507254721Semastelldb::thread_t 508254721SemasteHost::GetCurrentThread () 509254721Semaste{ 510254721Semaste return lldb::thread_t(pthread_self()); 511254721Semaste} 512254721Semaste 513254721Semasteconst char * 514254721SemasteHost::GetSignalAsCString (int signo) 515254721Semaste{ 516254721Semaste switch (signo) 517254721Semaste { 518254721Semaste case SIGHUP: return "SIGHUP"; // 1 hangup 519254721Semaste case SIGINT: return "SIGINT"; // 2 interrupt 520254721Semaste case SIGQUIT: return "SIGQUIT"; // 3 quit 521254721Semaste case SIGILL: return "SIGILL"; // 4 illegal instruction (not reset when caught) 522254721Semaste case SIGTRAP: return "SIGTRAP"; // 5 trace trap (not reset when caught) 523254721Semaste case SIGABRT: return "SIGABRT"; // 6 abort() 524269024Semaste#if defined(SIGPOLL) 525269024Semaste#if !defined(SIGIO) || (SIGPOLL != SIGIO) 526269024Semaste// Under some GNU/Linux, SIGPOLL and SIGIO are the same. Causing the build to 527269024Semaste// fail with 'multiple define cases with same value' 528254721Semaste case SIGPOLL: return "SIGPOLL"; // 7 pollable event ([XSR] generated, not supported) 529254721Semaste#endif 530269024Semaste#endif 531269024Semaste#if defined(SIGEMT) 532254721Semaste case SIGEMT: return "SIGEMT"; // 7 EMT instruction 533254721Semaste#endif 534254721Semaste case SIGFPE: return "SIGFPE"; // 8 floating point exception 535254721Semaste case SIGKILL: return "SIGKILL"; // 9 kill (cannot be caught or ignored) 536254721Semaste case SIGBUS: return "SIGBUS"; // 10 bus error 537254721Semaste case SIGSEGV: return "SIGSEGV"; // 11 segmentation violation 538254721Semaste case SIGSYS: return "SIGSYS"; // 12 bad argument to system call 539254721Semaste case SIGPIPE: return "SIGPIPE"; // 13 write on a pipe with no one to read it 540254721Semaste case SIGALRM: return "SIGALRM"; // 14 alarm clock 541254721Semaste case SIGTERM: return "SIGTERM"; // 15 software termination signal from kill 542254721Semaste case SIGURG: return "SIGURG"; // 16 urgent condition on IO channel 543254721Semaste case SIGSTOP: return "SIGSTOP"; // 17 sendable stop signal not from tty 544254721Semaste case SIGTSTP: return "SIGTSTP"; // 18 stop signal from tty 545254721Semaste case SIGCONT: return "SIGCONT"; // 19 continue a stopped process 546254721Semaste case SIGCHLD: return "SIGCHLD"; // 20 to parent on child stop or exit 547254721Semaste case SIGTTIN: return "SIGTTIN"; // 21 to readers pgrp upon background tty read 548254721Semaste case SIGTTOU: return "SIGTTOU"; // 22 like TTIN for output if (tp->t_local<OSTOP) 549269024Semaste#if defined(SIGIO) 550254721Semaste case SIGIO: return "SIGIO"; // 23 input/output possible signal 551254721Semaste#endif 552254721Semaste case SIGXCPU: return "SIGXCPU"; // 24 exceeded CPU time limit 553254721Semaste case SIGXFSZ: return "SIGXFSZ"; // 25 exceeded file size limit 554254721Semaste case SIGVTALRM: return "SIGVTALRM"; // 26 virtual time alarm 555254721Semaste case SIGPROF: return "SIGPROF"; // 27 profiling time alarm 556269024Semaste#if defined(SIGWINCH) 557254721Semaste case SIGWINCH: return "SIGWINCH"; // 28 window size changes 558269024Semaste#endif 559269024Semaste#if defined(SIGINFO) 560254721Semaste case SIGINFO: return "SIGINFO"; // 29 information request 561254721Semaste#endif 562254721Semaste case SIGUSR1: return "SIGUSR1"; // 30 user defined signal 1 563254721Semaste case SIGUSR2: return "SIGUSR2"; // 31 user defined signal 2 564254721Semaste default: 565254721Semaste break; 566254721Semaste } 567254721Semaste return NULL; 568254721Semaste} 569254721Semaste 570263363Semaste#endif 571263363Semaste 572254721Semastevoid 573254721SemasteHost::WillTerminate () 574254721Semaste{ 575254721Semaste} 576254721Semaste 577254721Semaste#if !defined (__APPLE__) && !defined (__FreeBSD__) && !defined (__FreeBSD_kernel__) && !defined (__linux__) // see macosx/Host.mm 578254721Semaste 579254721Semastevoid 580254721SemasteHost::ThreadCreated (const char *thread_name) 581254721Semaste{ 582254721Semaste} 583254721Semaste 584254721Semastevoid 585254721SemasteHost::Backtrace (Stream &strm, uint32_t max_frames) 586254721Semaste{ 587254721Semaste // TODO: Is there a way to backtrace the current process on other systems? 588254721Semaste} 589254721Semaste 590254721Semastesize_t 591254721SemasteHost::GetEnvironment (StringList &env) 592254721Semaste{ 593254721Semaste // TODO: Is there a way to the host environment for this process on other systems? 594254721Semaste return 0; 595254721Semaste} 596254721Semaste 597254721Semaste#endif // #if !defined (__APPLE__) && !defined (__FreeBSD__) && !defined (__FreeBSD_kernel__) && !defined (__linux__) 598254721Semaste 599254721Semastestruct HostThreadCreateInfo 600254721Semaste{ 601254721Semaste std::string thread_name; 602254721Semaste thread_func_t thread_fptr; 603254721Semaste thread_arg_t thread_arg; 604254721Semaste 605254721Semaste HostThreadCreateInfo (const char *name, thread_func_t fptr, thread_arg_t arg) : 606254721Semaste thread_name (name ? name : ""), 607254721Semaste thread_fptr (fptr), 608254721Semaste thread_arg (arg) 609254721Semaste { 610254721Semaste } 611254721Semaste}; 612254721Semaste 613254721Semastestatic thread_result_t 614263363Semaste#ifdef _WIN32 615263363Semaste__stdcall 616263363Semaste#endif 617254721SemasteThreadCreateTrampoline (thread_arg_t arg) 618254721Semaste{ 619254721Semaste HostThreadCreateInfo *info = (HostThreadCreateInfo *)arg; 620254721Semaste Host::ThreadCreated (info->thread_name.c_str()); 621254721Semaste thread_func_t thread_fptr = info->thread_fptr; 622254721Semaste thread_arg_t thread_arg = info->thread_arg; 623254721Semaste 624254721Semaste Log *log(lldb_private::GetLogIfAllCategoriesSet (LIBLLDB_LOG_THREAD)); 625254721Semaste if (log) 626254721Semaste log->Printf("thread created"); 627254721Semaste 628254721Semaste delete info; 629254721Semaste return thread_fptr (thread_arg); 630254721Semaste} 631254721Semaste 632254721Semastelldb::thread_t 633254721SemasteHost::ThreadCreate 634254721Semaste( 635254721Semaste const char *thread_name, 636254721Semaste thread_func_t thread_fptr, 637254721Semaste thread_arg_t thread_arg, 638254721Semaste Error *error 639254721Semaste) 640254721Semaste{ 641254721Semaste lldb::thread_t thread = LLDB_INVALID_HOST_THREAD; 642254721Semaste 643254721Semaste // Host::ThreadCreateTrampoline will delete this pointer for us. 644254721Semaste HostThreadCreateInfo *info_ptr = new HostThreadCreateInfo (thread_name, thread_fptr, thread_arg); 645254721Semaste 646263363Semaste#ifdef _WIN32 647263363Semaste thread = ::_beginthreadex(0, 0, ThreadCreateTrampoline, info_ptr, 0, NULL); 648263363Semaste int err = thread <= 0 ? GetLastError() : 0; 649263363Semaste#else 650254721Semaste int err = ::pthread_create (&thread, NULL, ThreadCreateTrampoline, info_ptr); 651263363Semaste#endif 652254721Semaste if (err == 0) 653254721Semaste { 654254721Semaste if (error) 655254721Semaste error->Clear(); 656254721Semaste return thread; 657254721Semaste } 658254721Semaste 659254721Semaste if (error) 660254721Semaste error->SetError (err, eErrorTypePOSIX); 661254721Semaste 662254721Semaste return LLDB_INVALID_HOST_THREAD; 663254721Semaste} 664254721Semaste 665263363Semaste#ifndef _WIN32 666263363Semaste 667254721Semastebool 668254721SemasteHost::ThreadCancel (lldb::thread_t thread, Error *error) 669254721Semaste{ 670254721Semaste int err = ::pthread_cancel (thread); 671254721Semaste if (error) 672254721Semaste error->SetError(err, eErrorTypePOSIX); 673254721Semaste return err == 0; 674254721Semaste} 675254721Semaste 676254721Semastebool 677254721SemasteHost::ThreadDetach (lldb::thread_t thread, Error *error) 678254721Semaste{ 679254721Semaste int err = ::pthread_detach (thread); 680254721Semaste if (error) 681254721Semaste error->SetError(err, eErrorTypePOSIX); 682254721Semaste return err == 0; 683254721Semaste} 684254721Semaste 685254721Semastebool 686254721SemasteHost::ThreadJoin (lldb::thread_t thread, thread_result_t *thread_result_ptr, Error *error) 687254721Semaste{ 688254721Semaste int err = ::pthread_join (thread, thread_result_ptr); 689254721Semaste if (error) 690254721Semaste error->SetError(err, eErrorTypePOSIX); 691254721Semaste return err == 0; 692254721Semaste} 693254721Semaste 694263363Semastelldb::thread_key_t 695263363SemasteHost::ThreadLocalStorageCreate(ThreadLocalStorageCleanupCallback callback) 696263363Semaste{ 697263363Semaste pthread_key_t key; 698263363Semaste ::pthread_key_create (&key, callback); 699263363Semaste return key; 700263363Semaste} 701263363Semaste 702263363Semastevoid* 703263363SemasteHost::ThreadLocalStorageGet(lldb::thread_key_t key) 704263363Semaste{ 705263363Semaste return ::pthread_getspecific (key); 706263363Semaste} 707263363Semaste 708263363Semastevoid 709263363SemasteHost::ThreadLocalStorageSet(lldb::thread_key_t key, void *value) 710263363Semaste{ 711263363Semaste ::pthread_setspecific (key, value); 712263363Semaste} 713263363Semaste 714254721Semastebool 715254721SemasteHost::SetThreadName (lldb::pid_t pid, lldb::tid_t tid, const char *name) 716254721Semaste{ 717254721Semaste#if defined(__APPLE__) && MAC_OS_X_VERSION_MAX_ALLOWED > MAC_OS_X_VERSION_10_5 718254721Semaste lldb::pid_t curr_pid = Host::GetCurrentProcessID(); 719254721Semaste lldb::tid_t curr_tid = Host::GetCurrentThreadID(); 720254721Semaste if (pid == LLDB_INVALID_PROCESS_ID) 721254721Semaste pid = curr_pid; 722254721Semaste 723254721Semaste if (tid == LLDB_INVALID_THREAD_ID) 724254721Semaste tid = curr_tid; 725254721Semaste 726254721Semaste // Set the pthread name if possible 727254721Semaste if (pid == curr_pid && tid == curr_tid) 728254721Semaste { 729254721Semaste if (::pthread_setname_np (name) == 0) 730254721Semaste return true; 731254721Semaste } 732254721Semaste return false; 733254721Semaste#elif defined (__FreeBSD__) 734254721Semaste lldb::pid_t curr_pid = Host::GetCurrentProcessID(); 735254721Semaste lldb::tid_t curr_tid = Host::GetCurrentThreadID(); 736254721Semaste if (pid == LLDB_INVALID_PROCESS_ID) 737254721Semaste pid = curr_pid; 738254721Semaste 739254721Semaste if (tid == LLDB_INVALID_THREAD_ID) 740254721Semaste tid = curr_tid; 741254721Semaste 742254721Semaste // Set the pthread name if possible 743254721Semaste if (pid == curr_pid && tid == curr_tid) 744254721Semaste { 745254721Semaste ::pthread_set_name_np (::pthread_self(), name); 746254721Semaste return true; 747254721Semaste } 748254721Semaste return false; 749254721Semaste#elif defined (__linux__) || defined (__GLIBC__) 750254721Semaste void *fn = dlsym (RTLD_DEFAULT, "pthread_setname_np"); 751254721Semaste if (fn) 752254721Semaste { 753254721Semaste lldb::pid_t curr_pid = Host::GetCurrentProcessID(); 754254721Semaste lldb::tid_t curr_tid = Host::GetCurrentThreadID(); 755254721Semaste if (pid == LLDB_INVALID_PROCESS_ID) 756254721Semaste pid = curr_pid; 757254721Semaste 758254721Semaste if (tid == LLDB_INVALID_THREAD_ID) 759254721Semaste tid = curr_tid; 760254721Semaste 761254721Semaste if (pid == curr_pid && tid == curr_tid) 762254721Semaste { 763254721Semaste int (*pthread_setname_np_func)(pthread_t thread, const char *name); 764254721Semaste *reinterpret_cast<void **> (&pthread_setname_np_func) = fn; 765254721Semaste 766254721Semaste if (pthread_setname_np_func (::pthread_self(), name) == 0) 767254721Semaste return true; 768254721Semaste } 769254721Semaste } 770254721Semaste return false; 771254721Semaste#else 772254721Semaste return false; 773254721Semaste#endif 774254721Semaste} 775254721Semaste 776254721Semastebool 777254721SemasteHost::SetShortThreadName (lldb::pid_t pid, lldb::tid_t tid, 778254721Semaste const char *thread_name, size_t len) 779254721Semaste{ 780269024Semaste std::unique_ptr<char[]> namebuf(new char[len+1]); 781269024Semaste 782254721Semaste // Thread names are coming in like '<lldb.comm.debugger.edit>' and 783254721Semaste // '<lldb.comm.debugger.editline>'. So just chopping the end of the string 784254721Semaste // off leads to a lot of similar named threads. Go through the thread name 785254721Semaste // and search for the last dot and use that. 786254721Semaste const char *lastdot = ::strrchr (thread_name, '.'); 787254721Semaste 788254721Semaste if (lastdot && lastdot != thread_name) 789254721Semaste thread_name = lastdot + 1; 790269024Semaste ::strncpy (namebuf.get(), thread_name, len); 791254721Semaste namebuf[len] = 0; 792254721Semaste 793269024Semaste int namebuflen = strlen(namebuf.get()); 794254721Semaste if (namebuflen > 0) 795254721Semaste { 796254721Semaste if (namebuf[namebuflen - 1] == '(' || namebuf[namebuflen - 1] == '>') 797254721Semaste { 798254721Semaste // Trim off trailing '(' and '>' characters for a bit more cleanup. 799254721Semaste namebuflen--; 800254721Semaste namebuf[namebuflen] = 0; 801254721Semaste } 802269024Semaste return Host::SetThreadName (pid, tid, namebuf.get()); 803254721Semaste } 804254721Semaste return false; 805254721Semaste} 806254721Semaste 807263363Semaste#endif 808263363Semaste 809254721SemasteFileSpec 810254721SemasteHost::GetProgramFileSpec () 811254721Semaste{ 812254721Semaste static FileSpec g_program_filespec; 813254721Semaste if (!g_program_filespec) 814254721Semaste { 815254721Semaste#if defined (__APPLE__) 816254721Semaste char program_fullpath[PATH_MAX]; 817254721Semaste // If DST is NULL, then return the number of bytes needed. 818254721Semaste uint32_t len = sizeof(program_fullpath); 819254721Semaste int err = _NSGetExecutablePath (program_fullpath, &len); 820254721Semaste if (err == 0) 821254721Semaste g_program_filespec.SetFile (program_fullpath, false); 822254721Semaste else if (err == -1) 823254721Semaste { 824254721Semaste char *large_program_fullpath = (char *)::malloc (len + 1); 825254721Semaste 826254721Semaste err = _NSGetExecutablePath (large_program_fullpath, &len); 827254721Semaste if (err == 0) 828254721Semaste g_program_filespec.SetFile (large_program_fullpath, false); 829254721Semaste 830254721Semaste ::free (large_program_fullpath); 831254721Semaste } 832254721Semaste#elif defined (__linux__) 833254721Semaste char exe_path[PATH_MAX]; 834254721Semaste ssize_t len = readlink("/proc/self/exe", exe_path, sizeof(exe_path) - 1); 835254721Semaste if (len > 0) { 836254721Semaste exe_path[len] = 0; 837254721Semaste g_program_filespec.SetFile(exe_path, false); 838254721Semaste } 839254721Semaste#elif defined (__FreeBSD__) || defined (__FreeBSD_kernel__) 840254721Semaste int exe_path_mib[4] = { CTL_KERN, KERN_PROC, KERN_PROC_PATHNAME, getpid() }; 841254721Semaste size_t exe_path_size; 842254721Semaste if (sysctl(exe_path_mib, 4, NULL, &exe_path_size, NULL, 0) == 0) 843254721Semaste { 844254721Semaste char *exe_path = new char[exe_path_size]; 845254721Semaste if (sysctl(exe_path_mib, 4, exe_path, &exe_path_size, NULL, 0) == 0) 846254721Semaste g_program_filespec.SetFile(exe_path, false); 847254721Semaste delete[] exe_path; 848254721Semaste } 849254721Semaste#endif 850254721Semaste } 851254721Semaste return g_program_filespec; 852254721Semaste} 853254721Semaste 854254721Semaste#if !defined (__APPLE__) // see Host.mm 855254721Semaste 856254721Semastebool 857254721SemasteHost::GetBundleDirectory (const FileSpec &file, FileSpec &bundle) 858254721Semaste{ 859254721Semaste bundle.Clear(); 860254721Semaste return false; 861254721Semaste} 862254721Semaste 863254721Semastebool 864254721SemasteHost::ResolveExecutableInBundle (FileSpec &file) 865254721Semaste{ 866254721Semaste return false; 867254721Semaste} 868254721Semaste#endif 869254721Semaste 870263363Semaste#ifndef _WIN32 871263363Semaste 872254721Semaste// Opaque info that tracks a dynamic library that was loaded 873254721Semastestruct DynamicLibraryInfo 874254721Semaste{ 875254721Semaste DynamicLibraryInfo (const FileSpec &fs, int o, void *h) : 876254721Semaste file_spec (fs), 877254721Semaste open_options (o), 878254721Semaste handle (h) 879254721Semaste { 880254721Semaste } 881254721Semaste 882254721Semaste const FileSpec file_spec; 883254721Semaste uint32_t open_options; 884254721Semaste void * handle; 885254721Semaste}; 886254721Semaste 887254721Semastevoid * 888254721SemasteHost::DynamicLibraryOpen (const FileSpec &file_spec, uint32_t options, Error &error) 889254721Semaste{ 890254721Semaste char path[PATH_MAX]; 891254721Semaste if (file_spec.GetPath(path, sizeof(path))) 892254721Semaste { 893254721Semaste int mode = 0; 894254721Semaste 895254721Semaste if (options & eDynamicLibraryOpenOptionLazy) 896254721Semaste mode |= RTLD_LAZY; 897254721Semaste else 898254721Semaste mode |= RTLD_NOW; 899254721Semaste 900254721Semaste 901254721Semaste if (options & eDynamicLibraryOpenOptionLocal) 902254721Semaste mode |= RTLD_LOCAL; 903254721Semaste else 904254721Semaste mode |= RTLD_GLOBAL; 905254721Semaste 906254721Semaste#ifdef LLDB_CONFIG_DLOPEN_RTLD_FIRST_SUPPORTED 907254721Semaste if (options & eDynamicLibraryOpenOptionLimitGetSymbol) 908254721Semaste mode |= RTLD_FIRST; 909254721Semaste#endif 910254721Semaste 911254721Semaste void * opaque = ::dlopen (path, mode); 912254721Semaste 913254721Semaste if (opaque) 914254721Semaste { 915254721Semaste error.Clear(); 916254721Semaste return new DynamicLibraryInfo (file_spec, options, opaque); 917254721Semaste } 918254721Semaste else 919254721Semaste { 920254721Semaste error.SetErrorString(::dlerror()); 921254721Semaste } 922254721Semaste } 923254721Semaste else 924254721Semaste { 925254721Semaste error.SetErrorString("failed to extract path"); 926254721Semaste } 927254721Semaste return NULL; 928254721Semaste} 929254721Semaste 930254721SemasteError 931254721SemasteHost::DynamicLibraryClose (void *opaque) 932254721Semaste{ 933254721Semaste Error error; 934254721Semaste if (opaque == NULL) 935254721Semaste { 936254721Semaste error.SetErrorString ("invalid dynamic library handle"); 937254721Semaste } 938254721Semaste else 939254721Semaste { 940254721Semaste DynamicLibraryInfo *dylib_info = (DynamicLibraryInfo *) opaque; 941254721Semaste if (::dlclose (dylib_info->handle) != 0) 942254721Semaste { 943254721Semaste error.SetErrorString(::dlerror()); 944254721Semaste } 945254721Semaste 946254721Semaste dylib_info->open_options = 0; 947254721Semaste dylib_info->handle = 0; 948254721Semaste delete dylib_info; 949254721Semaste } 950254721Semaste return error; 951254721Semaste} 952254721Semaste 953254721Semastevoid * 954254721SemasteHost::DynamicLibraryGetSymbol (void *opaque, const char *symbol_name, Error &error) 955254721Semaste{ 956254721Semaste if (opaque == NULL) 957254721Semaste { 958254721Semaste error.SetErrorString ("invalid dynamic library handle"); 959254721Semaste } 960254721Semaste else 961254721Semaste { 962254721Semaste DynamicLibraryInfo *dylib_info = (DynamicLibraryInfo *) opaque; 963254721Semaste 964254721Semaste void *symbol_addr = ::dlsym (dylib_info->handle, symbol_name); 965254721Semaste if (symbol_addr) 966254721Semaste { 967254721Semaste#ifndef LLDB_CONFIG_DLOPEN_RTLD_FIRST_SUPPORTED 968254721Semaste // This host doesn't support limiting searches to this shared library 969254721Semaste // so we need to verify that the match came from this shared library 970254721Semaste // if it was requested in the Host::DynamicLibraryOpen() function. 971254721Semaste if (dylib_info->open_options & eDynamicLibraryOpenOptionLimitGetSymbol) 972254721Semaste { 973254721Semaste FileSpec match_dylib_spec (Host::GetModuleFileSpecForHostAddress (symbol_addr)); 974254721Semaste if (match_dylib_spec != dylib_info->file_spec) 975254721Semaste { 976254721Semaste char dylib_path[PATH_MAX]; 977254721Semaste if (dylib_info->file_spec.GetPath (dylib_path, sizeof(dylib_path))) 978254721Semaste error.SetErrorStringWithFormat ("symbol not found in \"%s\"", dylib_path); 979254721Semaste else 980254721Semaste error.SetErrorString ("symbol not found"); 981254721Semaste return NULL; 982254721Semaste } 983254721Semaste } 984254721Semaste#endif 985254721Semaste error.Clear(); 986254721Semaste return symbol_addr; 987254721Semaste } 988254721Semaste else 989254721Semaste { 990254721Semaste error.SetErrorString(::dlerror()); 991254721Semaste } 992254721Semaste } 993254721Semaste return NULL; 994254721Semaste} 995254721Semaste 996263363SemasteFileSpec 997263363SemasteHost::GetModuleFileSpecForHostAddress (const void *host_addr) 998263363Semaste{ 999263363Semaste FileSpec module_filespec; 1000263363Semaste Dl_info info; 1001263363Semaste if (::dladdr (host_addr, &info)) 1002263363Semaste { 1003263363Semaste if (info.dli_fname) 1004263363Semaste module_filespec.SetFile(info.dli_fname, true); 1005263363Semaste } 1006263363Semaste return module_filespec; 1007263363Semaste} 1008263363Semaste 1009263363Semaste#endif 1010263363Semaste 1011254721Semastebool 1012254721SemasteHost::GetLLDBPath (PathType path_type, FileSpec &file_spec) 1013254721Semaste{ 1014254721Semaste // To get paths related to LLDB we get the path to the executable that 1015254721Semaste // contains this function. On MacOSX this will be "LLDB.framework/.../LLDB", 1016254721Semaste // on linux this is assumed to be the "lldb" main executable. If LLDB on 1017254721Semaste // linux is actually in a shared library (liblldb.so) then this function will 1018254721Semaste // need to be modified to "do the right thing". 1019263367Semaste Log *log = lldb_private::GetLogIfAllCategoriesSet (LIBLLDB_LOG_HOST); 1020254721Semaste 1021254721Semaste switch (path_type) 1022254721Semaste { 1023254721Semaste case ePathTypeLLDBShlibDir: 1024254721Semaste { 1025254721Semaste static ConstString g_lldb_so_dir; 1026254721Semaste if (!g_lldb_so_dir) 1027254721Semaste { 1028254721Semaste FileSpec lldb_file_spec (Host::GetModuleFileSpecForHostAddress ((void *)Host::GetLLDBPath)); 1029254721Semaste g_lldb_so_dir = lldb_file_spec.GetDirectory(); 1030263367Semaste if (log) 1031263367Semaste log->Printf("Host::GetLLDBPath(ePathTypeLLDBShlibDir) => '%s'", g_lldb_so_dir.GetCString()); 1032254721Semaste } 1033254721Semaste file_spec.GetDirectory() = g_lldb_so_dir; 1034263363Semaste return (bool)file_spec.GetDirectory(); 1035254721Semaste } 1036254721Semaste break; 1037254721Semaste 1038254721Semaste case ePathTypeSupportExecutableDir: 1039254721Semaste { 1040254721Semaste static ConstString g_lldb_support_exe_dir; 1041254721Semaste if (!g_lldb_support_exe_dir) 1042254721Semaste { 1043254721Semaste FileSpec lldb_file_spec; 1044254721Semaste if (GetLLDBPath (ePathTypeLLDBShlibDir, lldb_file_spec)) 1045254721Semaste { 1046254721Semaste char raw_path[PATH_MAX]; 1047254721Semaste char resolved_path[PATH_MAX]; 1048254721Semaste lldb_file_spec.GetPath(raw_path, sizeof(raw_path)); 1049254721Semaste 1050254721Semaste#if defined (__APPLE__) 1051254721Semaste char *framework_pos = ::strstr (raw_path, "LLDB.framework"); 1052254721Semaste if (framework_pos) 1053254721Semaste { 1054254721Semaste framework_pos += strlen("LLDB.framework"); 1055263367Semaste#if defined (__arm__) 1056263367Semaste // Shallow bundle 1057263367Semaste *framework_pos = '\0'; 1058263367Semaste#else 1059263367Semaste // Normal bundle 1060254721Semaste ::strncpy (framework_pos, "/Resources", PATH_MAX - (framework_pos - raw_path)); 1061254721Semaste#endif 1062254721Semaste } 1063254721Semaste#endif 1064254721Semaste FileSpec::Resolve (raw_path, resolved_path, sizeof(resolved_path)); 1065254721Semaste g_lldb_support_exe_dir.SetCString(resolved_path); 1066254721Semaste } 1067263367Semaste if (log) 1068263367Semaste log->Printf("Host::GetLLDBPath(ePathTypeSupportExecutableDir) => '%s'", g_lldb_support_exe_dir.GetCString()); 1069254721Semaste } 1070254721Semaste file_spec.GetDirectory() = g_lldb_support_exe_dir; 1071263363Semaste return (bool)file_spec.GetDirectory(); 1072254721Semaste } 1073254721Semaste break; 1074254721Semaste 1075254721Semaste case ePathTypeHeaderDir: 1076254721Semaste { 1077254721Semaste static ConstString g_lldb_headers_dir; 1078254721Semaste if (!g_lldb_headers_dir) 1079254721Semaste { 1080254721Semaste#if defined (__APPLE__) 1081254721Semaste FileSpec lldb_file_spec; 1082254721Semaste if (GetLLDBPath (ePathTypeLLDBShlibDir, lldb_file_spec)) 1083254721Semaste { 1084254721Semaste char raw_path[PATH_MAX]; 1085254721Semaste char resolved_path[PATH_MAX]; 1086254721Semaste lldb_file_spec.GetPath(raw_path, sizeof(raw_path)); 1087254721Semaste 1088254721Semaste char *framework_pos = ::strstr (raw_path, "LLDB.framework"); 1089254721Semaste if (framework_pos) 1090254721Semaste { 1091254721Semaste framework_pos += strlen("LLDB.framework"); 1092254721Semaste ::strncpy (framework_pos, "/Headers", PATH_MAX - (framework_pos - raw_path)); 1093254721Semaste } 1094254721Semaste FileSpec::Resolve (raw_path, resolved_path, sizeof(resolved_path)); 1095254721Semaste g_lldb_headers_dir.SetCString(resolved_path); 1096254721Semaste } 1097254721Semaste#else 1098254721Semaste // TODO: Anyone know how we can determine this for linux? Other systems?? 1099254721Semaste g_lldb_headers_dir.SetCString ("/opt/local/include/lldb"); 1100254721Semaste#endif 1101263367Semaste if (log) 1102263367Semaste log->Printf("Host::GetLLDBPath(ePathTypeHeaderDir) => '%s'", g_lldb_headers_dir.GetCString()); 1103254721Semaste } 1104254721Semaste file_spec.GetDirectory() = g_lldb_headers_dir; 1105263363Semaste return (bool)file_spec.GetDirectory(); 1106254721Semaste } 1107254721Semaste break; 1108254721Semaste 1109263363Semaste#ifdef LLDB_DISABLE_PYTHON 1110263363Semaste case ePathTypePythonDir: 1111263363Semaste return false; 1112263363Semaste#else 1113263363Semaste case ePathTypePythonDir: 1114254721Semaste { 1115254721Semaste static ConstString g_lldb_python_dir; 1116254721Semaste if (!g_lldb_python_dir) 1117254721Semaste { 1118254721Semaste FileSpec lldb_file_spec; 1119254721Semaste if (GetLLDBPath (ePathTypeLLDBShlibDir, lldb_file_spec)) 1120254721Semaste { 1121254721Semaste char raw_path[PATH_MAX]; 1122254721Semaste char resolved_path[PATH_MAX]; 1123254721Semaste lldb_file_spec.GetPath(raw_path, sizeof(raw_path)); 1124254721Semaste 1125254721Semaste#if defined (__APPLE__) 1126254721Semaste char *framework_pos = ::strstr (raw_path, "LLDB.framework"); 1127254721Semaste if (framework_pos) 1128254721Semaste { 1129254721Semaste framework_pos += strlen("LLDB.framework"); 1130254721Semaste ::strncpy (framework_pos, "/Resources/Python", PATH_MAX - (framework_pos - raw_path)); 1131269024Semaste } 1132269024Semaste else 1133269024Semaste { 1134269024Semaste#endif 1135269024Semaste llvm::SmallString<256> python_version_dir; 1136269024Semaste llvm::raw_svector_ostream os(python_version_dir); 1137269024Semaste os << "/python" << PY_MAJOR_VERSION << '.' << PY_MINOR_VERSION << "/site-packages"; 1138269024Semaste os.flush(); 1139254721Semaste 1140269024Semaste // We may get our string truncated. Should we protect 1141269024Semaste // this with an assert? 1142254721Semaste 1143269024Semaste ::strncat(raw_path, python_version_dir.c_str(), 1144269024Semaste sizeof(raw_path) - strlen(raw_path) - 1); 1145254721Semaste 1146269024Semaste#if defined (__APPLE__) 1147269024Semaste } 1148254721Semaste#endif 1149254721Semaste FileSpec::Resolve (raw_path, resolved_path, sizeof(resolved_path)); 1150254721Semaste g_lldb_python_dir.SetCString(resolved_path); 1151254721Semaste } 1152263367Semaste 1153263367Semaste if (log) 1154263367Semaste log->Printf("Host::GetLLDBPath(ePathTypePythonDir) => '%s'", g_lldb_python_dir.GetCString()); 1155263367Semaste 1156254721Semaste } 1157254721Semaste file_spec.GetDirectory() = g_lldb_python_dir; 1158263363Semaste return (bool)file_spec.GetDirectory(); 1159254721Semaste } 1160254721Semaste break; 1161254721Semaste#endif 1162254721Semaste 1163254721Semaste case ePathTypeLLDBSystemPlugins: // System plug-ins directory 1164254721Semaste { 1165254721Semaste#if defined (__APPLE__) || defined(__linux__) 1166254721Semaste static ConstString g_lldb_system_plugin_dir; 1167254721Semaste static bool g_lldb_system_plugin_dir_located = false; 1168254721Semaste if (!g_lldb_system_plugin_dir_located) 1169254721Semaste { 1170254721Semaste g_lldb_system_plugin_dir_located = true; 1171254721Semaste#if defined (__APPLE__) 1172254721Semaste FileSpec lldb_file_spec; 1173254721Semaste if (GetLLDBPath (ePathTypeLLDBShlibDir, lldb_file_spec)) 1174254721Semaste { 1175254721Semaste char raw_path[PATH_MAX]; 1176254721Semaste char resolved_path[PATH_MAX]; 1177254721Semaste lldb_file_spec.GetPath(raw_path, sizeof(raw_path)); 1178254721Semaste 1179254721Semaste char *framework_pos = ::strstr (raw_path, "LLDB.framework"); 1180254721Semaste if (framework_pos) 1181254721Semaste { 1182254721Semaste framework_pos += strlen("LLDB.framework"); 1183254721Semaste ::strncpy (framework_pos, "/Resources/PlugIns", PATH_MAX - (framework_pos - raw_path)); 1184254721Semaste FileSpec::Resolve (raw_path, resolved_path, sizeof(resolved_path)); 1185254721Semaste g_lldb_system_plugin_dir.SetCString(resolved_path); 1186254721Semaste } 1187254721Semaste return false; 1188254721Semaste } 1189254721Semaste#elif defined (__linux__) 1190254721Semaste FileSpec lldb_file_spec("/usr/lib/lldb", true); 1191254721Semaste if (lldb_file_spec.Exists()) 1192254721Semaste { 1193254721Semaste g_lldb_system_plugin_dir.SetCString(lldb_file_spec.GetPath().c_str()); 1194254721Semaste } 1195254721Semaste#endif // __APPLE__ || __linux__ 1196263367Semaste 1197263367Semaste if (log) 1198263367Semaste log->Printf("Host::GetLLDBPath(ePathTypeLLDBSystemPlugins) => '%s'", g_lldb_system_plugin_dir.GetCString()); 1199263367Semaste 1200254721Semaste } 1201254721Semaste 1202254721Semaste if (g_lldb_system_plugin_dir) 1203254721Semaste { 1204254721Semaste file_spec.GetDirectory() = g_lldb_system_plugin_dir; 1205254721Semaste return true; 1206254721Semaste } 1207254721Semaste#else 1208254721Semaste // TODO: where would system LLDB plug-ins be located on other systems? 1209254721Semaste return false; 1210254721Semaste#endif 1211254721Semaste } 1212254721Semaste break; 1213254721Semaste 1214254721Semaste case ePathTypeLLDBUserPlugins: // User plug-ins directory 1215254721Semaste { 1216254721Semaste#if defined (__APPLE__) 1217254721Semaste static ConstString g_lldb_user_plugin_dir; 1218254721Semaste if (!g_lldb_user_plugin_dir) 1219254721Semaste { 1220254721Semaste char user_plugin_path[PATH_MAX]; 1221254721Semaste if (FileSpec::Resolve ("~/Library/Application Support/LLDB/PlugIns", 1222254721Semaste user_plugin_path, 1223254721Semaste sizeof(user_plugin_path))) 1224254721Semaste { 1225254721Semaste g_lldb_user_plugin_dir.SetCString(user_plugin_path); 1226254721Semaste } 1227254721Semaste } 1228254721Semaste file_spec.GetDirectory() = g_lldb_user_plugin_dir; 1229263363Semaste return (bool)file_spec.GetDirectory(); 1230254721Semaste#elif defined (__linux__) 1231254721Semaste static ConstString g_lldb_user_plugin_dir; 1232254721Semaste if (!g_lldb_user_plugin_dir) 1233254721Semaste { 1234254721Semaste // XDG Base Directory Specification 1235254721Semaste // http://standards.freedesktop.org/basedir-spec/basedir-spec-latest.html 1236254721Semaste // If XDG_DATA_HOME exists, use that, otherwise use ~/.local/share/lldb. 1237254721Semaste FileSpec lldb_file_spec; 1238254721Semaste const char *xdg_data_home = getenv("XDG_DATA_HOME"); 1239254721Semaste if (xdg_data_home && xdg_data_home[0]) 1240254721Semaste { 1241254721Semaste std::string user_plugin_dir (xdg_data_home); 1242254721Semaste user_plugin_dir += "/lldb"; 1243254721Semaste lldb_file_spec.SetFile (user_plugin_dir.c_str(), true); 1244254721Semaste } 1245254721Semaste else 1246254721Semaste { 1247254721Semaste const char *home_dir = getenv("HOME"); 1248254721Semaste if (home_dir && home_dir[0]) 1249254721Semaste { 1250254721Semaste std::string user_plugin_dir (home_dir); 1251254721Semaste user_plugin_dir += "/.local/share/lldb"; 1252254721Semaste lldb_file_spec.SetFile (user_plugin_dir.c_str(), true); 1253254721Semaste } 1254254721Semaste } 1255254721Semaste 1256254721Semaste if (lldb_file_spec.Exists()) 1257254721Semaste g_lldb_user_plugin_dir.SetCString(lldb_file_spec.GetPath().c_str()); 1258263367Semaste if (log) 1259263367Semaste log->Printf("Host::GetLLDBPath(ePathTypeLLDBUserPlugins) => '%s'", g_lldb_user_plugin_dir.GetCString()); 1260254721Semaste } 1261254721Semaste file_spec.GetDirectory() = g_lldb_user_plugin_dir; 1262263363Semaste return (bool)file_spec.GetDirectory(); 1263254721Semaste#endif 1264254721Semaste // TODO: where would user LLDB plug-ins be located on other systems? 1265254721Semaste return false; 1266254721Semaste } 1267269024Semaste 1268269024Semaste case ePathTypeLLDBTempSystemDir: 1269269024Semaste { 1270269024Semaste static ConstString g_lldb_tmp_dir; 1271269024Semaste if (!g_lldb_tmp_dir) 1272269024Semaste { 1273269024Semaste const char *tmpdir_cstr = getenv("TMPDIR"); 1274269024Semaste if (tmpdir_cstr == NULL) 1275269024Semaste { 1276269024Semaste tmpdir_cstr = getenv("TMP"); 1277269024Semaste if (tmpdir_cstr == NULL) 1278269024Semaste tmpdir_cstr = getenv("TEMP"); 1279269024Semaste } 1280269024Semaste if (tmpdir_cstr) 1281269024Semaste { 1282269024Semaste g_lldb_tmp_dir.SetCString(tmpdir_cstr); 1283269024Semaste if (log) 1284269024Semaste log->Printf("Host::GetLLDBPath(ePathTypeLLDBTempSystemDir) => '%s'", g_lldb_tmp_dir.GetCString()); 1285269024Semaste } 1286269024Semaste } 1287269024Semaste file_spec.GetDirectory() = g_lldb_tmp_dir; 1288269024Semaste return (bool)file_spec.GetDirectory(); 1289269024Semaste } 1290254721Semaste } 1291254721Semaste 1292254721Semaste return false; 1293254721Semaste} 1294254721Semaste 1295254721Semaste 1296254721Semastebool 1297254721SemasteHost::GetHostname (std::string &s) 1298254721Semaste{ 1299254721Semaste char hostname[PATH_MAX]; 1300254721Semaste hostname[sizeof(hostname) - 1] = '\0'; 1301254721Semaste if (::gethostname (hostname, sizeof(hostname) - 1) == 0) 1302254721Semaste { 1303254721Semaste struct hostent* h = ::gethostbyname (hostname); 1304254721Semaste if (h) 1305254721Semaste s.assign (h->h_name); 1306254721Semaste else 1307254721Semaste s.assign (hostname); 1308254721Semaste return true; 1309254721Semaste } 1310254721Semaste return false; 1311254721Semaste} 1312254721Semaste 1313263363Semaste#ifndef _WIN32 1314263363Semaste 1315254721Semasteconst char * 1316254721SemasteHost::GetUserName (uint32_t uid, std::string &user_name) 1317254721Semaste{ 1318254721Semaste struct passwd user_info; 1319254721Semaste struct passwd *user_info_ptr = &user_info; 1320254721Semaste char user_buffer[PATH_MAX]; 1321254721Semaste size_t user_buffer_size = sizeof(user_buffer); 1322254721Semaste if (::getpwuid_r (uid, 1323254721Semaste &user_info, 1324254721Semaste user_buffer, 1325254721Semaste user_buffer_size, 1326254721Semaste &user_info_ptr) == 0) 1327254721Semaste { 1328254721Semaste if (user_info_ptr) 1329254721Semaste { 1330254721Semaste user_name.assign (user_info_ptr->pw_name); 1331254721Semaste return user_name.c_str(); 1332254721Semaste } 1333254721Semaste } 1334254721Semaste user_name.clear(); 1335254721Semaste return NULL; 1336254721Semaste} 1337254721Semaste 1338254721Semasteconst char * 1339254721SemasteHost::GetGroupName (uint32_t gid, std::string &group_name) 1340254721Semaste{ 1341254721Semaste char group_buffer[PATH_MAX]; 1342254721Semaste size_t group_buffer_size = sizeof(group_buffer); 1343254721Semaste struct group group_info; 1344254721Semaste struct group *group_info_ptr = &group_info; 1345254721Semaste // Try the threadsafe version first 1346254721Semaste if (::getgrgid_r (gid, 1347254721Semaste &group_info, 1348254721Semaste group_buffer, 1349254721Semaste group_buffer_size, 1350254721Semaste &group_info_ptr) == 0) 1351254721Semaste { 1352254721Semaste if (group_info_ptr) 1353254721Semaste { 1354254721Semaste group_name.assign (group_info_ptr->gr_name); 1355254721Semaste return group_name.c_str(); 1356254721Semaste } 1357254721Semaste } 1358254721Semaste else 1359254721Semaste { 1360254721Semaste // The threadsafe version isn't currently working 1361254721Semaste // for me on darwin, but the non-threadsafe version 1362254721Semaste // is, so I am calling it below. 1363254721Semaste group_info_ptr = ::getgrgid (gid); 1364254721Semaste if (group_info_ptr) 1365254721Semaste { 1366254721Semaste group_name.assign (group_info_ptr->gr_name); 1367254721Semaste return group_name.c_str(); 1368254721Semaste } 1369254721Semaste } 1370254721Semaste group_name.clear(); 1371254721Semaste return NULL; 1372254721Semaste} 1373254721Semaste 1374254721Semasteuint32_t 1375254721SemasteHost::GetUserID () 1376254721Semaste{ 1377254721Semaste return getuid(); 1378254721Semaste} 1379254721Semaste 1380254721Semasteuint32_t 1381254721SemasteHost::GetGroupID () 1382254721Semaste{ 1383254721Semaste return getgid(); 1384254721Semaste} 1385254721Semaste 1386254721Semasteuint32_t 1387254721SemasteHost::GetEffectiveUserID () 1388254721Semaste{ 1389254721Semaste return geteuid(); 1390254721Semaste} 1391254721Semaste 1392254721Semasteuint32_t 1393254721SemasteHost::GetEffectiveGroupID () 1394254721Semaste{ 1395254721Semaste return getegid(); 1396254721Semaste} 1397254721Semaste 1398263363Semaste#endif 1399263363Semaste 1400263363Semaste#if !defined (__APPLE__) && !defined (__FreeBSD__) && !defined (__FreeBSD_kernel__) // see macosx/Host.mm 1401263363Semastebool 1402263363SemasteHost::GetOSBuildString (std::string &s) 1403263363Semaste{ 1404263363Semaste s.clear(); 1405263363Semaste return false; 1406263363Semaste} 1407263363Semaste 1408263363Semastebool 1409263363SemasteHost::GetOSKernelDescription (std::string &s) 1410263363Semaste{ 1411263363Semaste s.clear(); 1412263363Semaste return false; 1413263363Semaste} 1414263363Semaste#endif 1415263363Semaste 1416263363Semaste#if !defined (__APPLE__) && !defined (__FreeBSD__) && !defined (__FreeBSD_kernel__) && !defined(__linux__) 1417254721Semasteuint32_t 1418254721SemasteHost::FindProcesses (const ProcessInstanceInfoMatch &match_info, ProcessInstanceInfoList &process_infos) 1419254721Semaste{ 1420254721Semaste process_infos.Clear(); 1421254721Semaste return process_infos.GetSize(); 1422254721Semaste} 1423254721Semaste 1424254721Semastebool 1425254721SemasteHost::GetProcessInfo (lldb::pid_t pid, ProcessInstanceInfo &process_info) 1426254721Semaste{ 1427254721Semaste process_info.Clear(); 1428254721Semaste return false; 1429254721Semaste} 1430254721Semaste#endif 1431254721Semaste 1432254721Semaste#if !defined(__linux__) 1433254721Semastebool 1434254721SemasteHost::FindProcessThreads (const lldb::pid_t pid, TidMap &tids_to_attach) 1435254721Semaste{ 1436254721Semaste return false; 1437254721Semaste} 1438254721Semaste#endif 1439254721Semaste 1440254721Semastelldb::TargetSP 1441254721SemasteHost::GetDummyTarget (lldb_private::Debugger &debugger) 1442254721Semaste{ 1443254721Semaste static TargetSP g_dummy_target_sp; 1444254721Semaste 1445254721Semaste // FIXME: Maybe the dummy target should be per-Debugger 1446254721Semaste if (!g_dummy_target_sp || !g_dummy_target_sp->IsValid()) 1447254721Semaste { 1448254721Semaste ArchSpec arch(Target::GetDefaultArchitecture()); 1449254721Semaste if (!arch.IsValid()) 1450254721Semaste arch = Host::GetArchitecture (); 1451254721Semaste Error err = debugger.GetTargetList().CreateTarget(debugger, 1452254721Semaste NULL, 1453254721Semaste arch.GetTriple().getTriple().c_str(), 1454254721Semaste false, 1455254721Semaste NULL, 1456254721Semaste g_dummy_target_sp); 1457254721Semaste } 1458254721Semaste 1459254721Semaste return g_dummy_target_sp; 1460254721Semaste} 1461254721Semaste 1462254721Semastestruct ShellInfo 1463254721Semaste{ 1464254721Semaste ShellInfo () : 1465254721Semaste process_reaped (false), 1466254721Semaste can_delete (false), 1467254721Semaste pid (LLDB_INVALID_PROCESS_ID), 1468254721Semaste signo(-1), 1469254721Semaste status(-1) 1470254721Semaste { 1471254721Semaste } 1472254721Semaste 1473254721Semaste lldb_private::Predicate<bool> process_reaped; 1474254721Semaste lldb_private::Predicate<bool> can_delete; 1475254721Semaste lldb::pid_t pid; 1476254721Semaste int signo; 1477254721Semaste int status; 1478254721Semaste}; 1479254721Semaste 1480254721Semastestatic bool 1481254721SemasteMonitorShellCommand (void *callback_baton, 1482254721Semaste lldb::pid_t pid, 1483254721Semaste bool exited, // True if the process did exit 1484254721Semaste int signo, // Zero for no signal 1485254721Semaste int status) // Exit value of process if signal is zero 1486254721Semaste{ 1487254721Semaste ShellInfo *shell_info = (ShellInfo *)callback_baton; 1488254721Semaste shell_info->pid = pid; 1489254721Semaste shell_info->signo = signo; 1490254721Semaste shell_info->status = status; 1491254721Semaste // Let the thread running Host::RunShellCommand() know that the process 1492254721Semaste // exited and that ShellInfo has been filled in by broadcasting to it 1493254721Semaste shell_info->process_reaped.SetValue(1, eBroadcastAlways); 1494254721Semaste // Now wait for a handshake back from that thread running Host::RunShellCommand 1495254721Semaste // so we know that we can delete shell_info_ptr 1496254721Semaste shell_info->can_delete.WaitForValueEqualTo(true); 1497254721Semaste // Sleep a bit to allow the shell_info->can_delete.SetValue() to complete... 1498254721Semaste usleep(1000); 1499254721Semaste // Now delete the shell info that was passed into this function 1500254721Semaste delete shell_info; 1501254721Semaste return true; 1502254721Semaste} 1503254721Semaste 1504254721SemasteError 1505254721SemasteHost::RunShellCommand (const char *command, 1506254721Semaste const char *working_dir, 1507254721Semaste int *status_ptr, 1508254721Semaste int *signo_ptr, 1509254721Semaste std::string *command_output_ptr, 1510254721Semaste uint32_t timeout_sec, 1511254721Semaste const char *shell) 1512254721Semaste{ 1513254721Semaste Error error; 1514254721Semaste ProcessLaunchInfo launch_info; 1515254721Semaste if (shell && shell[0]) 1516254721Semaste { 1517254721Semaste // Run the command in a shell 1518254721Semaste launch_info.SetShell(shell); 1519254721Semaste launch_info.GetArguments().AppendArgument(command); 1520254721Semaste const bool localhost = true; 1521254721Semaste const bool will_debug = false; 1522254721Semaste const bool first_arg_is_full_shell_command = true; 1523254721Semaste launch_info.ConvertArgumentsForLaunchingInShell (error, 1524254721Semaste localhost, 1525254721Semaste will_debug, 1526263363Semaste first_arg_is_full_shell_command, 1527263363Semaste 0); 1528254721Semaste } 1529254721Semaste else 1530254721Semaste { 1531254721Semaste // No shell, just run it 1532254721Semaste Args args (command); 1533254721Semaste const bool first_arg_is_executable = true; 1534254721Semaste launch_info.SetArguments(args, first_arg_is_executable); 1535254721Semaste } 1536254721Semaste 1537254721Semaste if (working_dir) 1538254721Semaste launch_info.SetWorkingDirectory(working_dir); 1539269024Semaste char output_file_path_buffer[PATH_MAX]; 1540254721Semaste const char *output_file_path = NULL; 1541269024Semaste 1542254721Semaste if (command_output_ptr) 1543254721Semaste { 1544254721Semaste // Create a temporary file to get the stdout/stderr and redirect the 1545254721Semaste // output of the command into this file. We will later read this file 1546254721Semaste // if all goes well and fill the data into "command_output_ptr" 1547269024Semaste FileSpec tmpdir_file_spec; 1548269024Semaste if (Host::GetLLDBPath (ePathTypeLLDBTempSystemDir, tmpdir_file_spec)) 1549269024Semaste { 1550269024Semaste tmpdir_file_spec.GetFilename().SetCString("lldb-shell-output.XXXXXX"); 1551269024Semaste strncpy(output_file_path_buffer, tmpdir_file_spec.GetPath().c_str(), sizeof(output_file_path_buffer)); 1552269024Semaste } 1553269024Semaste else 1554269024Semaste { 1555269024Semaste strncpy(output_file_path_buffer, "/tmp/lldb-shell-output.XXXXXX", sizeof(output_file_path_buffer)); 1556269024Semaste } 1557269024Semaste 1558269024Semaste output_file_path = ::mktemp(output_file_path_buffer); 1559269024Semaste } 1560269024Semaste 1561269024Semaste launch_info.AppendSuppressFileAction (STDIN_FILENO, true, false); 1562269024Semaste if (output_file_path) 1563269024Semaste { 1564254721Semaste launch_info.AppendOpenFileAction(STDOUT_FILENO, output_file_path, false, true); 1565254721Semaste launch_info.AppendDuplicateFileAction(STDOUT_FILENO, STDERR_FILENO); 1566254721Semaste } 1567254721Semaste else 1568254721Semaste { 1569254721Semaste launch_info.AppendSuppressFileAction (STDOUT_FILENO, false, true); 1570254721Semaste launch_info.AppendSuppressFileAction (STDERR_FILENO, false, true); 1571254721Semaste } 1572254721Semaste 1573254721Semaste // The process monitor callback will delete the 'shell_info_ptr' below... 1574254721Semaste std::unique_ptr<ShellInfo> shell_info_ap (new ShellInfo()); 1575254721Semaste 1576254721Semaste const bool monitor_signals = false; 1577254721Semaste launch_info.SetMonitorProcessCallback(MonitorShellCommand, shell_info_ap.get(), monitor_signals); 1578254721Semaste 1579254721Semaste error = LaunchProcess (launch_info); 1580254721Semaste const lldb::pid_t pid = launch_info.GetProcessID(); 1581263363Semaste 1582263363Semaste if (error.Success() && pid == LLDB_INVALID_PROCESS_ID) 1583263363Semaste error.SetErrorString("failed to get process ID"); 1584263363Semaste 1585263363Semaste if (error.Success()) 1586254721Semaste { 1587254721Semaste // The process successfully launched, so we can defer ownership of 1588254721Semaste // "shell_info" to the MonitorShellCommand callback function that will 1589254721Semaste // get called when the process dies. We release the unique pointer as it 1590254721Semaste // doesn't need to delete the ShellInfo anymore. 1591254721Semaste ShellInfo *shell_info = shell_info_ap.release(); 1592263363Semaste TimeValue *timeout_ptr = nullptr; 1593254721Semaste TimeValue timeout_time(TimeValue::Now()); 1594263363Semaste if (timeout_sec > 0) { 1595263363Semaste timeout_time.OffsetWithSeconds(timeout_sec); 1596263363Semaste timeout_ptr = &timeout_time; 1597263363Semaste } 1598254721Semaste bool timed_out = false; 1599263363Semaste shell_info->process_reaped.WaitForValueEqualTo(true, timeout_ptr, &timed_out); 1600254721Semaste if (timed_out) 1601254721Semaste { 1602254721Semaste error.SetErrorString("timed out waiting for shell command to complete"); 1603263363Semaste 1604254721Semaste // Kill the process since it didn't complete withint the timeout specified 1605263363Semaste Kill (pid, SIGKILL); 1606254721Semaste // Wait for the monitor callback to get the message 1607254721Semaste timeout_time = TimeValue::Now(); 1608254721Semaste timeout_time.OffsetWithSeconds(1); 1609254721Semaste timed_out = false; 1610254721Semaste shell_info->process_reaped.WaitForValueEqualTo(true, &timeout_time, &timed_out); 1611254721Semaste } 1612254721Semaste else 1613254721Semaste { 1614254721Semaste if (status_ptr) 1615254721Semaste *status_ptr = shell_info->status; 1616254721Semaste 1617254721Semaste if (signo_ptr) 1618254721Semaste *signo_ptr = shell_info->signo; 1619254721Semaste 1620254721Semaste if (command_output_ptr) 1621254721Semaste { 1622254721Semaste command_output_ptr->clear(); 1623254721Semaste FileSpec file_spec(output_file_path, File::eOpenOptionRead); 1624254721Semaste uint64_t file_size = file_spec.GetByteSize(); 1625254721Semaste if (file_size > 0) 1626254721Semaste { 1627254721Semaste if (file_size > command_output_ptr->max_size()) 1628254721Semaste { 1629254721Semaste error.SetErrorStringWithFormat("shell command output is too large to fit into a std::string"); 1630254721Semaste } 1631254721Semaste else 1632254721Semaste { 1633254721Semaste command_output_ptr->resize(file_size); 1634254721Semaste file_spec.ReadFileContents(0, &((*command_output_ptr)[0]), command_output_ptr->size(), &error); 1635254721Semaste } 1636254721Semaste } 1637254721Semaste } 1638254721Semaste } 1639254721Semaste shell_info->can_delete.SetValue(true, eBroadcastAlways); 1640254721Semaste } 1641254721Semaste 1642254721Semaste if (output_file_path) 1643254721Semaste ::unlink (output_file_path); 1644254721Semaste // Handshake with the monitor thread, or just let it know in advance that 1645254721Semaste // it can delete "shell_info" in case we timed out and were not able to kill 1646254721Semaste // the process... 1647254721Semaste return error; 1648254721Semaste} 1649254721Semaste 1650254721Semaste 1651269024Semaste// LaunchProcessPosixSpawn for Apple, Linux, FreeBSD and other GLIBC 1652269024Semaste// systems 1653269024Semaste 1654269024Semaste#if defined (__APPLE__) || defined (__linux__) || defined (__FreeBSD__) || defined (__GLIBC__) 1655269024Semaste 1656269024Semaste// this method needs to be visible to macosx/Host.cpp and 1657269024Semaste// common/Host.cpp. 1658269024Semaste 1659269024Semasteshort 1660269024SemasteHost::GetPosixspawnFlags (ProcessLaunchInfo &launch_info) 1661263363Semaste{ 1662269024Semaste short flags = POSIX_SPAWN_SETSIGDEF | POSIX_SPAWN_SETSIGMASK; 1663269024Semaste 1664269024Semaste#if defined (__APPLE__) 1665269024Semaste if (launch_info.GetFlags().Test (eLaunchFlagExec)) 1666269024Semaste flags |= POSIX_SPAWN_SETEXEC; // Darwin specific posix_spawn flag 1667269024Semaste 1668269024Semaste if (launch_info.GetFlags().Test (eLaunchFlagDebug)) 1669269024Semaste flags |= POSIX_SPAWN_START_SUSPENDED; // Darwin specific posix_spawn flag 1670269024Semaste 1671269024Semaste if (launch_info.GetFlags().Test (eLaunchFlagDisableASLR)) 1672269024Semaste flags |= _POSIX_SPAWN_DISABLE_ASLR; // Darwin specific posix_spawn flag 1673269024Semaste 1674269024Semaste if (launch_info.GetLaunchInSeparateProcessGroup()) 1675269024Semaste flags |= POSIX_SPAWN_SETPGROUP; 1676269024Semaste 1677269024Semaste#ifdef POSIX_SPAWN_CLOEXEC_DEFAULT 1678269024Semaste#if defined (__APPLE__) && (defined (__x86_64__) || defined (__i386__)) 1679269024Semaste static LazyBool g_use_close_on_exec_flag = eLazyBoolCalculate; 1680269024Semaste if (g_use_close_on_exec_flag == eLazyBoolCalculate) 1681269024Semaste { 1682269024Semaste g_use_close_on_exec_flag = eLazyBoolNo; 1683269024Semaste 1684269024Semaste uint32_t major, minor, update; 1685269024Semaste if (Host::GetOSVersion(major, minor, update)) 1686269024Semaste { 1687269024Semaste // Kernel panic if we use the POSIX_SPAWN_CLOEXEC_DEFAULT on 10.7 or earlier 1688269024Semaste if (major > 10 || (major == 10 && minor > 7)) 1689269024Semaste { 1690269024Semaste // Only enable for 10.8 and later OS versions 1691269024Semaste g_use_close_on_exec_flag = eLazyBoolYes; 1692269024Semaste } 1693269024Semaste } 1694269024Semaste } 1695269024Semaste#else 1696269024Semaste static LazyBool g_use_close_on_exec_flag = eLazyBoolYes; 1697269024Semaste#endif 1698269024Semaste // Close all files exception those with file actions if this is supported. 1699269024Semaste if (g_use_close_on_exec_flag == eLazyBoolYes) 1700269024Semaste flags |= POSIX_SPAWN_CLOEXEC_DEFAULT; 1701269024Semaste#endif 1702269024Semaste#endif // #if defined (__APPLE__) 1703269024Semaste return flags; 1704269024Semaste} 1705269024Semaste 1706269024SemasteError 1707269024SemasteHost::LaunchProcessPosixSpawn (const char *exe_path, ProcessLaunchInfo &launch_info, ::pid_t &pid) 1708269024Semaste{ 1709263363Semaste Error error; 1710263363Semaste Log *log(lldb_private::GetLogIfAllCategoriesSet (LIBLLDB_LOG_HOST | LIBLLDB_LOG_PROCESS)); 1711263363Semaste 1712263363Semaste posix_spawnattr_t attr; 1713269024Semaste error.SetError( ::posix_spawnattr_init (&attr), eErrorTypePOSIX); 1714263363Semaste 1715269024Semaste if (error.Fail() || log) 1716269024Semaste error.PutToLog(log, "::posix_spawnattr_init ( &attr )"); 1717263363Semaste if (error.Fail()) 1718263363Semaste return error; 1719263363Semaste 1720263363Semaste // Make a quick class that will cleanup the posix spawn attributes in case 1721263363Semaste // we return in the middle of this function. 1722263363Semaste lldb_utility::CleanUp <posix_spawnattr_t *, int> posix_spawnattr_cleanup(&attr, posix_spawnattr_destroy); 1723263363Semaste 1724263363Semaste sigset_t no_signals; 1725263363Semaste sigset_t all_signals; 1726263363Semaste sigemptyset (&no_signals); 1727263363Semaste sigfillset (&all_signals); 1728269024Semaste ::posix_spawnattr_setsigmask(&attr, &no_signals); 1729269024Semaste#if defined (__linux__) || defined (__FreeBSD__) 1730263363Semaste ::posix_spawnattr_setsigdefault(&attr, &no_signals); 1731269024Semaste#else 1732269024Semaste ::posix_spawnattr_setsigdefault(&attr, &all_signals); 1733269024Semaste#endif 1734263363Semaste 1735269024Semaste short flags = GetPosixspawnFlags(launch_info); 1736263363Semaste 1737263363Semaste error.SetError( ::posix_spawnattr_setflags (&attr, flags), eErrorTypePOSIX); 1738269024Semaste if (error.Fail() || log) 1739269024Semaste error.PutToLog(log, "::posix_spawnattr_setflags ( &attr, flags=0x%8.8x )", flags); 1740263363Semaste if (error.Fail()) 1741263363Semaste return error; 1742263363Semaste 1743269024Semaste // posix_spawnattr_setbinpref_np appears to be an Apple extension per: 1744269024Semaste // http://www.unix.com/man-page/OSX/3/posix_spawnattr_setbinpref_np/ 1745269024Semaste#if defined (__APPLE__) && !defined (__arm__) 1746269024Semaste 1747269024Semaste // Don't set the binpref if a shell was provided. After all, that's only going to affect what version of the shell 1748269024Semaste // is launched, not what fork of the binary is launched. We insert "arch --arch <ARCH> as part of the shell invocation 1749269024Semaste // to do that job on OSX. 1750269024Semaste 1751269024Semaste if (launch_info.GetShell() == nullptr) 1752263363Semaste { 1753269024Semaste // We don't need to do this for ARM, and we really shouldn't now that we 1754269024Semaste // have multiple CPU subtypes and no posix_spawnattr call that allows us 1755269024Semaste // to set which CPU subtype to launch... 1756269024Semaste const ArchSpec &arch_spec = launch_info.GetArchitecture(); 1757269024Semaste cpu_type_t cpu = arch_spec.GetMachOCPUType(); 1758269024Semaste cpu_type_t sub = arch_spec.GetMachOCPUSubType(); 1759269024Semaste if (cpu != 0 && 1760269024Semaste cpu != UINT32_MAX && 1761269024Semaste cpu != LLDB_INVALID_CPUTYPE && 1762269024Semaste !(cpu == 0x01000007 && sub == 8)) // If haswell is specified, don't try to set the CPU type or we will fail 1763269024Semaste { 1764269024Semaste size_t ocount = 0; 1765269024Semaste error.SetError( ::posix_spawnattr_setbinpref_np (&attr, 1, &cpu, &ocount), eErrorTypePOSIX); 1766269024Semaste if (error.Fail() || log) 1767269024Semaste error.PutToLog(log, "::posix_spawnattr_setbinpref_np ( &attr, 1, cpu_type = 0x%8.8x, count => %llu )", cpu, (uint64_t)ocount); 1768263363Semaste 1769269024Semaste if (error.Fail() || ocount != 1) 1770263363Semaste return error; 1771263363Semaste } 1772263363Semaste } 1773263363Semaste 1774269024Semaste#endif 1775269024Semaste 1776269024Semaste const char *tmp_argv[2]; 1777269024Semaste char * const *argv = (char * const*)launch_info.GetArguments().GetConstArgumentVector(); 1778269024Semaste char * const *envp = (char * const*)launch_info.GetEnvironmentEntries().GetConstArgumentVector(); 1779269024Semaste if (argv == NULL) 1780269024Semaste { 1781269024Semaste // posix_spawn gets very unhappy if it doesn't have at least the program 1782269024Semaste // name in argv[0]. One of the side affects I have noticed is the environment 1783269024Semaste // variables don't make it into the child process if "argv == NULL"!!! 1784269024Semaste tmp_argv[0] = exe_path; 1785269024Semaste tmp_argv[1] = NULL; 1786269024Semaste argv = (char * const*)tmp_argv; 1787269024Semaste } 1788269024Semaste 1789269024Semaste#if !defined (__APPLE__) 1790269024Semaste // manage the working directory 1791263363Semaste char current_dir[PATH_MAX]; 1792263363Semaste current_dir[0] = '\0'; 1793269024Semaste#endif 1794263363Semaste 1795263363Semaste const char *working_dir = launch_info.GetWorkingDirectory(); 1796269024Semaste if (working_dir) 1797263363Semaste { 1798269024Semaste#if defined (__APPLE__) 1799269024Semaste // Set the working directory on this thread only 1800269024Semaste if (__pthread_chdir (working_dir) < 0) { 1801269024Semaste if (errno == ENOENT) { 1802269024Semaste error.SetErrorStringWithFormat("No such file or directory: %s", working_dir); 1803269024Semaste } else if (errno == ENOTDIR) { 1804269024Semaste error.SetErrorStringWithFormat("Path doesn't name a directory: %s", working_dir); 1805269024Semaste } else { 1806269024Semaste error.SetErrorStringWithFormat("An unknown error occurred when changing directory for process execution."); 1807269024Semaste } 1808269024Semaste return error; 1809269024Semaste } 1810269024Semaste#else 1811263363Semaste if (::getcwd(current_dir, sizeof(current_dir)) == NULL) 1812263363Semaste { 1813263363Semaste error.SetError(errno, eErrorTypePOSIX); 1814263363Semaste error.LogIfError(log, "unable to save the current directory"); 1815263363Semaste return error; 1816263363Semaste } 1817263363Semaste 1818263363Semaste if (::chdir(working_dir) == -1) 1819263363Semaste { 1820263363Semaste error.SetError(errno, eErrorTypePOSIX); 1821263363Semaste error.LogIfError(log, "unable to change working directory to %s", working_dir); 1822263363Semaste return error; 1823263363Semaste } 1824269024Semaste#endif 1825263363Semaste } 1826263363Semaste 1827269024Semaste const size_t num_file_actions = launch_info.GetNumFileActions (); 1828269024Semaste if (num_file_actions > 0) 1829263363Semaste { 1830269024Semaste posix_spawn_file_actions_t file_actions; 1831269024Semaste error.SetError( ::posix_spawn_file_actions_init (&file_actions), eErrorTypePOSIX); 1832269024Semaste if (error.Fail() || log) 1833269024Semaste error.PutToLog(log, "::posix_spawn_file_actions_init ( &file_actions )"); 1834269024Semaste if (error.Fail()) 1835269024Semaste return error; 1836263363Semaste 1837269024Semaste // Make a quick class that will cleanup the posix spawn attributes in case 1838269024Semaste // we return in the middle of this function. 1839269024Semaste lldb_utility::CleanUp <posix_spawn_file_actions_t *, int> posix_spawn_file_actions_cleanup (&file_actions, posix_spawn_file_actions_destroy); 1840263363Semaste 1841269024Semaste for (size_t i=0; i<num_file_actions; ++i) 1842269024Semaste { 1843269024Semaste const ProcessLaunchInfo::FileAction *launch_file_action = launch_info.GetFileActionAtIndex(i); 1844269024Semaste if (launch_file_action) 1845269024Semaste { 1846269024Semaste if (!ProcessLaunchInfo::FileAction::AddPosixSpawnFileAction (&file_actions, 1847269024Semaste launch_file_action, 1848269024Semaste log, 1849269024Semaste error)) 1850269024Semaste return error; 1851269024Semaste } 1852269024Semaste } 1853263363Semaste 1854269024Semaste error.SetError (::posix_spawnp (&pid, 1855269024Semaste exe_path, 1856269024Semaste &file_actions, 1857269024Semaste &attr, 1858269024Semaste argv, 1859269024Semaste envp), 1860269024Semaste eErrorTypePOSIX); 1861269024Semaste 1862269024Semaste if (error.Fail() || log) 1863269024Semaste { 1864269024Semaste error.PutToLog(log, "::posix_spawnp ( pid => %i, path = '%s', file_actions = %p, attr = %p, argv = %p, envp = %p )", 1865269024Semaste pid, 1866269024Semaste exe_path, 1867269024Semaste &file_actions, 1868269024Semaste &attr, 1869269024Semaste argv, 1870269024Semaste envp); 1871269024Semaste if (log) 1872269024Semaste { 1873269024Semaste for (int ii=0; argv[ii]; ++ii) 1874269024Semaste log->Printf("argv[%i] = '%s'", ii, argv[ii]); 1875269024Semaste } 1876269024Semaste } 1877269024Semaste 1878269024Semaste } 1879269024Semaste else 1880263363Semaste { 1881269024Semaste error.SetError (::posix_spawnp (&pid, 1882269024Semaste exe_path, 1883269024Semaste NULL, 1884269024Semaste &attr, 1885269024Semaste argv, 1886269024Semaste envp), 1887269024Semaste eErrorTypePOSIX); 1888269024Semaste 1889269024Semaste if (error.Fail() || log) 1890269024Semaste { 1891269024Semaste error.PutToLog(log, "::posix_spawnp ( pid => %i, path = '%s', file_actions = NULL, attr = %p, argv = %p, envp = %p )", 1892269024Semaste pid, 1893269024Semaste exe_path, 1894269024Semaste &attr, 1895269024Semaste argv, 1896269024Semaste envp); 1897269024Semaste if (log) 1898269024Semaste { 1899269024Semaste for (int ii=0; argv[ii]; ++ii) 1900269024Semaste log->Printf("argv[%i] = '%s'", ii, argv[ii]); 1901269024Semaste } 1902269024Semaste } 1903263363Semaste } 1904263363Semaste 1905269024Semaste if (working_dir) 1906269024Semaste { 1907269024Semaste#if defined (__APPLE__) 1908269024Semaste // No more thread specific current working directory 1909269024Semaste __pthread_fchdir (-1); 1910269024Semaste#else 1911269024Semaste if (::chdir(current_dir) == -1 && error.Success()) 1912269024Semaste { 1913269024Semaste error.SetError(errno, eErrorTypePOSIX); 1914269024Semaste error.LogIfError(log, "unable to change current directory back to %s", 1915269024Semaste current_dir); 1916269024Semaste } 1917269024Semaste#endif 1918269024Semaste } 1919269024Semaste 1920263363Semaste return error; 1921263363Semaste} 1922263363Semaste 1923269024Semaste#endif // LaunchProcedssPosixSpawn: Apple, Linux, FreeBSD and other GLIBC systems 1924263363Semaste 1925269024Semaste 1926269024Semaste#if defined(__linux__) || defined(__FreeBSD__) || defined(__GLIBC__) 1927269024Semaste// The functions below implement process launching via posix_spawn() for Linux 1928269024Semaste// and FreeBSD. 1929269024Semaste 1930263363SemasteError 1931263363SemasteHost::LaunchProcess (ProcessLaunchInfo &launch_info) 1932263363Semaste{ 1933263363Semaste Error error; 1934263363Semaste char exe_path[PATH_MAX]; 1935263363Semaste 1936263363Semaste PlatformSP host_platform_sp (Platform::GetDefaultPlatform ()); 1937263363Semaste 1938263363Semaste const ArchSpec &arch_spec = launch_info.GetArchitecture(); 1939263363Semaste 1940263363Semaste FileSpec exe_spec(launch_info.GetExecutableFile()); 1941263363Semaste 1942263363Semaste FileSpec::FileType file_type = exe_spec.GetFileType(); 1943263363Semaste if (file_type != FileSpec::eFileTypeRegular) 1944263363Semaste { 1945263363Semaste lldb::ModuleSP exe_module_sp; 1946263363Semaste error = host_platform_sp->ResolveExecutable (exe_spec, 1947263363Semaste arch_spec, 1948263363Semaste exe_module_sp, 1949263363Semaste NULL); 1950263363Semaste 1951263363Semaste if (error.Fail()) 1952263363Semaste return error; 1953263363Semaste 1954263363Semaste if (exe_module_sp) 1955263363Semaste exe_spec = exe_module_sp->GetFileSpec(); 1956263363Semaste } 1957263363Semaste 1958263363Semaste if (exe_spec.Exists()) 1959263363Semaste { 1960263363Semaste exe_spec.GetPath (exe_path, sizeof(exe_path)); 1961263363Semaste } 1962263363Semaste else 1963263363Semaste { 1964263363Semaste launch_info.GetExecutableFile().GetPath (exe_path, sizeof(exe_path)); 1965263363Semaste error.SetErrorStringWithFormat ("executable doesn't exist: '%s'", exe_path); 1966263363Semaste return error; 1967263363Semaste } 1968263363Semaste 1969263363Semaste assert(!launch_info.GetFlags().Test (eLaunchFlagLaunchInTTY)); 1970263363Semaste 1971263363Semaste ::pid_t pid = LLDB_INVALID_PROCESS_ID; 1972263363Semaste 1973263363Semaste error = LaunchProcessPosixSpawn(exe_path, launch_info, pid); 1974263363Semaste 1975263363Semaste if (pid != LLDB_INVALID_PROCESS_ID) 1976263363Semaste { 1977263363Semaste // If all went well, then set the process ID into the launch info 1978263363Semaste launch_info.SetProcessID(pid); 1979263363Semaste 1980269024Semaste Log *log(lldb_private::GetLogIfAllCategoriesSet (LIBLLDB_LOG_PROCESS)); 1981269024Semaste 1982263363Semaste // Make sure we reap any processes we spawn or we will have zombies. 1983263363Semaste if (!launch_info.MonitorProcess()) 1984263363Semaste { 1985263363Semaste const bool monitor_signals = false; 1986263363Semaste StartMonitoringChildProcess (Process::SetProcessExitStatus, 1987263363Semaste NULL, 1988263363Semaste pid, 1989263363Semaste monitor_signals); 1990269024Semaste if (log) 1991269024Semaste log->PutCString ("monitored child process with default Process::SetProcessExitStatus."); 1992263363Semaste } 1993269024Semaste else 1994269024Semaste { 1995269024Semaste if (log) 1996269024Semaste log->PutCString ("monitored child process with user-specified process monitor."); 1997269024Semaste } 1998263363Semaste } 1999263363Semaste else 2000263363Semaste { 2001263363Semaste // Invalid process ID, something didn't go well 2002263363Semaste if (error.Success()) 2003263363Semaste error.SetErrorString ("process launch failed for unknown reasons"); 2004263363Semaste } 2005263363Semaste return error; 2006263363Semaste} 2007263363Semaste 2008263363Semaste#endif // defined(__linux__) or defined(__FreeBSD__) 2009263363Semaste 2010263363Semaste#ifndef _WIN32 2011263363Semaste 2012263363Semastesize_t 2013263363SemasteHost::GetPageSize() 2014263363Semaste{ 2015263363Semaste return ::getpagesize(); 2016263363Semaste} 2017263363Semaste 2018254721Semasteuint32_t 2019254721SemasteHost::GetNumberCPUS () 2020254721Semaste{ 2021254721Semaste static uint32_t g_num_cores = UINT32_MAX; 2022254721Semaste if (g_num_cores == UINT32_MAX) 2023254721Semaste { 2024254721Semaste#if defined(__APPLE__) or defined (__linux__) or defined (__FreeBSD__) or defined (__FreeBSD_kernel__) 2025254721Semaste 2026254721Semaste g_num_cores = ::sysconf(_SC_NPROCESSORS_ONLN); 2027263363Semaste 2028254721Semaste#else 2029254721Semaste 2030254721Semaste // Assume POSIX support if a host specific case has not been supplied above 2031254721Semaste g_num_cores = 0; 2032254721Semaste int num_cores = 0; 2033254721Semaste size_t num_cores_len = sizeof(num_cores); 2034254721Semaste#ifdef HW_AVAILCPU 2035254721Semaste int mib[] = { CTL_HW, HW_AVAILCPU }; 2036254721Semaste#else 2037254721Semaste int mib[] = { CTL_HW, HW_NCPU }; 2038254721Semaste#endif 2039254721Semaste 2040254721Semaste /* get the number of CPUs from the system */ 2041254721Semaste if (sysctl(mib, sizeof(mib)/sizeof(int), &num_cores, &num_cores_len, NULL, 0) == 0 && (num_cores > 0)) 2042254721Semaste { 2043254721Semaste g_num_cores = num_cores; 2044254721Semaste } 2045254721Semaste else 2046254721Semaste { 2047254721Semaste mib[1] = HW_NCPU; 2048254721Semaste num_cores_len = sizeof(num_cores); 2049254721Semaste if (sysctl(mib, sizeof(mib)/sizeof(int), &num_cores, &num_cores_len, NULL, 0) == 0 && (num_cores > 0)) 2050254721Semaste { 2051254721Semaste if (num_cores > 0) 2052254721Semaste g_num_cores = num_cores; 2053254721Semaste } 2054254721Semaste } 2055254721Semaste#endif 2056254721Semaste } 2057254721Semaste return g_num_cores; 2058254721Semaste} 2059254721Semaste 2060263363Semastevoid 2061263363SemasteHost::Kill(lldb::pid_t pid, int signo) 2062263363Semaste{ 2063263363Semaste ::kill(pid, signo); 2064263363Semaste} 2065254721Semaste 2066263363Semaste#endif 2067254721Semaste 2068254721Semaste#if !defined (__APPLE__) 2069254721Semastebool 2070254721SemasteHost::OpenFileInExternalEditor (const FileSpec &file_spec, uint32_t line_no) 2071254721Semaste{ 2072254721Semaste return false; 2073254721Semaste} 2074254721Semaste 2075254721Semastevoid 2076254721SemasteHost::SetCrashDescriptionWithFormat (const char *format, ...) 2077254721Semaste{ 2078254721Semaste} 2079254721Semaste 2080254721Semastevoid 2081254721SemasteHost::SetCrashDescription (const char *description) 2082254721Semaste{ 2083254721Semaste} 2084254721Semaste 2085254721Semastelldb::pid_t 2086263363SemasteHost::LaunchApplication (const FileSpec &app_file_spec) 2087254721Semaste{ 2088254721Semaste return LLDB_INVALID_PROCESS_ID; 2089254721Semaste} 2090254721Semaste 2091263367Semaste#endif 2092263367Semaste 2093263367Semaste 2094263367Semaste#ifdef LLDB_DISABLE_POSIX 2095263367Semaste 2096263367SemasteError 2097263367SemasteHost::MakeDirectory (const char* path, uint32_t mode) 2098263363Semaste{ 2099263367Semaste Error error; 2100263367Semaste error.SetErrorStringWithFormat("%s in not implemented on this host", __PRETTY_FUNCTION__); 2101263367Semaste return error; 2102263363Semaste} 2103263367Semaste 2104263367SemasteError 2105263367SemasteHost::GetFilePermissions (const char* path, uint32_t &file_permissions) 2106263367Semaste{ 2107263367Semaste Error error; 2108263367Semaste error.SetErrorStringWithFormat("%s is not supported on this host", __PRETTY_FUNCTION__); 2109263367Semaste return error; 2110263367Semaste} 2111263367Semaste 2112263367SemasteError 2113263367SemasteHost::SetFilePermissions (const char* path, uint32_t file_permissions) 2114263367Semaste{ 2115263367Semaste Error error; 2116263367Semaste error.SetErrorStringWithFormat("%s is not supported on this host", __PRETTY_FUNCTION__); 2117263367Semaste return error; 2118263367Semaste} 2119263367Semaste 2120263367SemasteError 2121263367SemasteHost::Symlink (const char *src, const char *dst) 2122263367Semaste{ 2123263367Semaste Error error; 2124263367Semaste error.SetErrorStringWithFormat("%s is not supported on this host", __PRETTY_FUNCTION__); 2125263367Semaste return error; 2126263367Semaste} 2127263367Semaste 2128263367SemasteError 2129263367SemasteHost::Readlink (const char *path, char *buf, size_t buf_len) 2130263367Semaste{ 2131263367Semaste Error error; 2132263367Semaste error.SetErrorStringWithFormat("%s is not supported on this host", __PRETTY_FUNCTION__); 2133263367Semaste return error; 2134263367Semaste} 2135263367Semaste 2136263367SemasteError 2137263367SemasteHost::Unlink (const char *path) 2138263367Semaste{ 2139263367Semaste Error error; 2140263367Semaste error.SetErrorStringWithFormat("%s is not supported on this host", __PRETTY_FUNCTION__); 2141263367Semaste return error; 2142263367Semaste} 2143263367Semaste 2144263367Semaste#else 2145263367Semaste 2146263367SemasteError 2147263367SemasteHost::MakeDirectory (const char* path, uint32_t file_permissions) 2148263367Semaste{ 2149263367Semaste Error error; 2150263367Semaste if (path && path[0]) 2151263367Semaste { 2152263367Semaste if (::mkdir(path, file_permissions) != 0) 2153263367Semaste { 2154263367Semaste error.SetErrorToErrno(); 2155263367Semaste switch (error.GetError()) 2156263367Semaste { 2157263367Semaste case ENOENT: 2158263367Semaste { 2159263367Semaste // Parent directory doesn't exist, so lets make it if we can 2160263367Semaste FileSpec spec(path, false); 2161263367Semaste if (spec.GetDirectory() && spec.GetFilename()) 2162263367Semaste { 2163263367Semaste // Make the parent directory and try again 2164263367Semaste Error error2 = Host::MakeDirectory(spec.GetDirectory().GetCString(), file_permissions); 2165263367Semaste if (error2.Success()) 2166263367Semaste { 2167263367Semaste // Try and make the directory again now that the parent directory was made successfully 2168263367Semaste if (::mkdir(path, file_permissions) == 0) 2169263367Semaste error.Clear(); 2170263367Semaste else 2171263367Semaste error.SetErrorToErrno(); 2172263367Semaste } 2173263367Semaste } 2174263367Semaste } 2175263367Semaste break; 2176263367Semaste case EEXIST: 2177263367Semaste { 2178263367Semaste FileSpec path_spec(path, false); 2179263367Semaste if (path_spec.IsDirectory()) 2180263367Semaste error.Clear(); // It is a directory and it already exists 2181263367Semaste } 2182263367Semaste break; 2183263367Semaste } 2184263367Semaste } 2185263367Semaste } 2186263367Semaste else 2187263367Semaste { 2188263367Semaste error.SetErrorString("empty path"); 2189263367Semaste } 2190263367Semaste return error; 2191263367Semaste} 2192263367Semaste 2193263367SemasteError 2194263367SemasteHost::GetFilePermissions (const char* path, uint32_t &file_permissions) 2195263367Semaste{ 2196263367Semaste Error error; 2197263367Semaste struct stat file_stats; 2198263367Semaste if (::stat (path, &file_stats) == 0) 2199263367Semaste { 2200263367Semaste // The bits in "st_mode" currently match the definitions 2201263367Semaste // for the file mode bits in unix. 2202263367Semaste file_permissions = file_stats.st_mode & (S_IRWXU | S_IRWXG | S_IRWXO); 2203263367Semaste } 2204263367Semaste else 2205263367Semaste { 2206263367Semaste error.SetErrorToErrno(); 2207263367Semaste } 2208263367Semaste return error; 2209263367Semaste} 2210263367Semaste 2211263367SemasteError 2212263367SemasteHost::SetFilePermissions (const char* path, uint32_t file_permissions) 2213263367Semaste{ 2214263367Semaste Error error; 2215263367Semaste if (::chmod(path, file_permissions) != 0) 2216263367Semaste error.SetErrorToErrno(); 2217263367Semaste return error; 2218263367Semaste} 2219263367Semaste 2220263367SemasteError 2221263367SemasteHost::Symlink (const char *src, const char *dst) 2222263367Semaste{ 2223263367Semaste Error error; 2224263367Semaste if (::symlink(dst, src) == -1) 2225263367Semaste error.SetErrorToErrno(); 2226263367Semaste return error; 2227263367Semaste} 2228263367Semaste 2229263367SemasteError 2230263367SemasteHost::Unlink (const char *path) 2231263367Semaste{ 2232263367Semaste Error error; 2233263367Semaste if (::unlink(path) == -1) 2234263367Semaste error.SetErrorToErrno(); 2235263367Semaste return error; 2236263367Semaste} 2237263367Semaste 2238263367SemasteError 2239263367SemasteHost::Readlink (const char *path, char *buf, size_t buf_len) 2240263367Semaste{ 2241263367Semaste Error error; 2242263367Semaste ssize_t count = ::readlink(path, buf, buf_len); 2243263367Semaste if (count < 0) 2244263367Semaste error.SetErrorToErrno(); 2245263367Semaste else if (count < (buf_len-1)) 2246263367Semaste buf[count] = '\0'; // Success 2247263367Semaste else 2248263367Semaste error.SetErrorString("'buf' buffer is too small to contain link contents"); 2249263367Semaste return error; 2250263367Semaste} 2251263367Semaste 2252263367Semaste 2253254721Semaste#endif 2254263363Semaste 2255263363Semastetypedef std::map<lldb::user_id_t, lldb::FileSP> FDToFileMap; 2256263363SemasteFDToFileMap& GetFDToFileMap() 2257263363Semaste{ 2258263363Semaste static FDToFileMap g_fd2filemap; 2259263363Semaste return g_fd2filemap; 2260263363Semaste} 2261263363Semaste 2262263363Semastelldb::user_id_t 2263263363SemasteHost::OpenFile (const FileSpec& file_spec, 2264263363Semaste uint32_t flags, 2265263367Semaste uint32_t mode, 2266263363Semaste Error &error) 2267263363Semaste{ 2268263363Semaste std::string path (file_spec.GetPath()); 2269263363Semaste if (path.empty()) 2270263363Semaste { 2271263363Semaste error.SetErrorString("empty path"); 2272263363Semaste return UINT64_MAX; 2273263363Semaste } 2274263363Semaste FileSP file_sp(new File()); 2275263363Semaste error = file_sp->Open(path.c_str(),flags,mode); 2276263363Semaste if (file_sp->IsValid() == false) 2277263363Semaste return UINT64_MAX; 2278263363Semaste lldb::user_id_t fd = file_sp->GetDescriptor(); 2279263363Semaste GetFDToFileMap()[fd] = file_sp; 2280263363Semaste return fd; 2281263363Semaste} 2282263363Semaste 2283263363Semastebool 2284263363SemasteHost::CloseFile (lldb::user_id_t fd, Error &error) 2285263363Semaste{ 2286263363Semaste if (fd == UINT64_MAX) 2287263363Semaste { 2288263363Semaste error.SetErrorString ("invalid file descriptor"); 2289263363Semaste return false; 2290263363Semaste } 2291263363Semaste FDToFileMap& file_map = GetFDToFileMap(); 2292263363Semaste FDToFileMap::iterator pos = file_map.find(fd); 2293263363Semaste if (pos == file_map.end()) 2294263363Semaste { 2295263363Semaste error.SetErrorStringWithFormat ("invalid host file descriptor %" PRIu64, fd); 2296263363Semaste return false; 2297263363Semaste } 2298263363Semaste FileSP file_sp = pos->second; 2299263363Semaste if (!file_sp) 2300263363Semaste { 2301263363Semaste error.SetErrorString ("invalid host backing file"); 2302263363Semaste return false; 2303263363Semaste } 2304263363Semaste error = file_sp->Close(); 2305263363Semaste file_map.erase(pos); 2306263363Semaste return error.Success(); 2307263363Semaste} 2308263363Semaste 2309263363Semasteuint64_t 2310263363SemasteHost::WriteFile (lldb::user_id_t fd, uint64_t offset, const void* src, uint64_t src_len, Error &error) 2311263363Semaste{ 2312263363Semaste if (fd == UINT64_MAX) 2313263363Semaste { 2314263363Semaste error.SetErrorString ("invalid file descriptor"); 2315263363Semaste return UINT64_MAX; 2316263363Semaste } 2317263363Semaste FDToFileMap& file_map = GetFDToFileMap(); 2318263363Semaste FDToFileMap::iterator pos = file_map.find(fd); 2319263363Semaste if (pos == file_map.end()) 2320263363Semaste { 2321263363Semaste error.SetErrorStringWithFormat("invalid host file descriptor %" PRIu64 , fd); 2322263363Semaste return false; 2323263363Semaste } 2324263363Semaste FileSP file_sp = pos->second; 2325263363Semaste if (!file_sp) 2326263363Semaste { 2327263363Semaste error.SetErrorString ("invalid host backing file"); 2328263363Semaste return UINT64_MAX; 2329263363Semaste } 2330263363Semaste if (file_sp->SeekFromStart(offset, &error) != offset || error.Fail()) 2331263363Semaste return UINT64_MAX; 2332263363Semaste size_t bytes_written = src_len; 2333263363Semaste error = file_sp->Write(src, bytes_written); 2334263363Semaste if (error.Fail()) 2335263363Semaste return UINT64_MAX; 2336263363Semaste return bytes_written; 2337263363Semaste} 2338263363Semaste 2339263363Semasteuint64_t 2340263363SemasteHost::ReadFile (lldb::user_id_t fd, uint64_t offset, void* dst, uint64_t dst_len, Error &error) 2341263363Semaste{ 2342263363Semaste if (fd == UINT64_MAX) 2343263363Semaste { 2344263363Semaste error.SetErrorString ("invalid file descriptor"); 2345263363Semaste return UINT64_MAX; 2346263363Semaste } 2347263363Semaste FDToFileMap& file_map = GetFDToFileMap(); 2348263363Semaste FDToFileMap::iterator pos = file_map.find(fd); 2349263363Semaste if (pos == file_map.end()) 2350263363Semaste { 2351263363Semaste error.SetErrorStringWithFormat ("invalid host file descriptor %" PRIu64, fd); 2352263363Semaste return false; 2353263363Semaste } 2354263363Semaste FileSP file_sp = pos->second; 2355263363Semaste if (!file_sp) 2356263363Semaste { 2357263363Semaste error.SetErrorString ("invalid host backing file"); 2358263363Semaste return UINT64_MAX; 2359263363Semaste } 2360263363Semaste if (file_sp->SeekFromStart(offset, &error) != offset || error.Fail()) 2361263363Semaste return UINT64_MAX; 2362263363Semaste size_t bytes_read = dst_len; 2363263363Semaste error = file_sp->Read(dst ,bytes_read); 2364263363Semaste if (error.Fail()) 2365263363Semaste return UINT64_MAX; 2366263363Semaste return bytes_read; 2367263363Semaste} 2368263363Semaste 2369263363Semastelldb::user_id_t 2370263363SemasteHost::GetFileSize (const FileSpec& file_spec) 2371263363Semaste{ 2372263363Semaste return file_spec.GetByteSize(); 2373263363Semaste} 2374263363Semaste 2375263363Semastebool 2376263363SemasteHost::GetFileExists (const FileSpec& file_spec) 2377263363Semaste{ 2378263363Semaste return file_spec.Exists(); 2379263363Semaste} 2380263363Semaste 2381263363Semastebool 2382263363SemasteHost::CalculateMD5 (const FileSpec& file_spec, 2383263363Semaste uint64_t &low, 2384263363Semaste uint64_t &high) 2385263363Semaste{ 2386263363Semaste#if defined (__APPLE__) 2387263363Semaste StreamString md5_cmd_line; 2388263363Semaste md5_cmd_line.Printf("md5 -q '%s'", file_spec.GetPath().c_str()); 2389263363Semaste std::string hash_string; 2390263363Semaste Error err = Host::RunShellCommand(md5_cmd_line.GetData(), NULL, NULL, NULL, &hash_string, 60); 2391263363Semaste if (err.Fail()) 2392263363Semaste return false; 2393263363Semaste // a correctly formed MD5 is 16-bytes, that is 32 hex digits 2394263363Semaste // if the output is any other length it is probably wrong 2395263363Semaste if (hash_string.size() != 32) 2396263363Semaste return false; 2397263363Semaste std::string part1(hash_string,0,16); 2398263363Semaste std::string part2(hash_string,16); 2399263363Semaste const char* part1_cstr = part1.c_str(); 2400263363Semaste const char* part2_cstr = part2.c_str(); 2401263363Semaste high = ::strtoull(part1_cstr, NULL, 16); 2402263363Semaste low = ::strtoull(part2_cstr, NULL, 16); 2403263363Semaste return true; 2404263363Semaste#else 2405263363Semaste // your own MD5 implementation here 2406263363Semaste return false; 2407263363Semaste#endif 2408263363Semaste} 2409