Host.cpp revision 258054
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 13258054Semaste#include <errno.h> 14258054Semaste#include <limits.h> 15258054Semaste#include <sys/types.h> 16258054Semaste#ifdef _WIN32 17258054Semaste#include "lldb/Host/windows/windows.h" 18258054Semaste#include <winsock2.h> 19258054Semaste#include <WS2tcpip.h> 20258054Semaste#else 21254721Semaste#include <dlfcn.h> 22254721Semaste#include <grp.h> 23254721Semaste#include <netdb.h> 24254721Semaste#include <pwd.h> 25258054Semaste#endif 26258054Semaste 27258054Semaste#if !defined (__GNU__) && !defined (_WIN32) 28258054Semaste// Does not exist under GNU/HURD or Windows 29254721Semaste#include <sys/sysctl.h> 30258054Semaste#endif 31254721Semaste 32254721Semaste#if defined (__APPLE__) 33258054Semaste#include <mach/mach_port.h> 34258054Semaste#include <mach/mach_init.h> 35254721Semaste#include <mach-o/dyld.h> 36254721Semaste#endif 37254721Semaste 38254721Semaste#if defined (__linux__) || defined (__FreeBSD__) || defined (__FreeBSD_kernel__) 39258054Semaste#include <spawn.h> 40254721Semaste#include <sys/wait.h> 41254721Semaste#include <sys/syscall.h> 42254721Semaste#endif 43254721Semaste 44254721Semaste#if defined (__FreeBSD__) 45254721Semaste#include <pthread_np.h> 46254721Semaste#endif 47254721Semaste 48254721Semaste#include "lldb/Host/Host.h" 49254721Semaste#include "lldb/Core/ArchSpec.h" 50254721Semaste#include "lldb/Core/ConstString.h" 51254721Semaste#include "lldb/Core/Debugger.h" 52254721Semaste#include "lldb/Core/Error.h" 53254721Semaste#include "lldb/Core/Log.h" 54258054Semaste#include "lldb/Core/Module.h" 55254721Semaste#include "lldb/Core/StreamString.h" 56254721Semaste#include "lldb/Core/ThreadSafeSTLMap.h" 57254721Semaste#include "lldb/Host/Config.h" 58254721Semaste#include "lldb/Host/Endian.h" 59254721Semaste#include "lldb/Host/FileSpec.h" 60254721Semaste#include "lldb/Host/Mutex.h" 61254721Semaste#include "lldb/Target/Process.h" 62254721Semaste#include "lldb/Target/TargetList.h" 63258054Semaste#include "lldb/Utility/CleanUp.h" 64254721Semaste 65254721Semaste#include "llvm/ADT/SmallString.h" 66254721Semaste#include "llvm/Support/Host.h" 67254721Semaste#include "llvm/Support/raw_ostream.h" 68254721Semaste 69254721Semaste 70254721Semasteusing namespace lldb; 71254721Semasteusing namespace lldb_private; 72254721Semaste 73254721Semaste 74258054Semaste#if !defined (__APPLE__) && !defined (_WIN32) 75254721Semastestruct MonitorInfo 76254721Semaste{ 77254721Semaste lldb::pid_t pid; // The process ID to monitor 78254721Semaste Host::MonitorChildProcessCallback callback; // The callback function to call when "pid" exits or signals 79254721Semaste void *callback_baton; // The callback baton for the callback function 80254721Semaste bool monitor_signals; // If true, call the callback when "pid" gets signaled. 81254721Semaste}; 82254721Semaste 83258054Semastestatic thread_result_t 84254721SemasteMonitorChildProcessThreadFunction (void *arg); 85254721Semaste 86254721Semastelldb::thread_t 87254721SemasteHost::StartMonitoringChildProcess 88254721Semaste( 89254721Semaste Host::MonitorChildProcessCallback callback, 90254721Semaste void *callback_baton, 91254721Semaste lldb::pid_t pid, 92254721Semaste bool monitor_signals 93254721Semaste) 94254721Semaste{ 95254721Semaste lldb::thread_t thread = LLDB_INVALID_HOST_THREAD; 96254721Semaste MonitorInfo * info_ptr = new MonitorInfo(); 97258054Semaste 98254721Semaste info_ptr->pid = pid; 99254721Semaste info_ptr->callback = callback; 100254721Semaste info_ptr->callback_baton = callback_baton; 101254721Semaste info_ptr->monitor_signals = monitor_signals; 102254721Semaste 103254721Semaste char thread_name[256]; 104254721Semaste ::snprintf (thread_name, sizeof(thread_name), "<lldb.host.wait4(pid=%" PRIu64 ")>", pid); 105254721Semaste thread = ThreadCreate (thread_name, 106254721Semaste MonitorChildProcessThreadFunction, 107254721Semaste info_ptr, 108254721Semaste NULL); 109254721Semaste 110254721Semaste return thread; 111254721Semaste} 112254721Semaste 113254721Semaste//------------------------------------------------------------------ 114254721Semaste// Scoped class that will disable thread canceling when it is 115254721Semaste// constructed, and exception safely restore the previous value it 116254721Semaste// when it goes out of scope. 117254721Semaste//------------------------------------------------------------------ 118254721Semasteclass ScopedPThreadCancelDisabler 119254721Semaste{ 120254721Semastepublic: 121254721Semaste ScopedPThreadCancelDisabler() 122254721Semaste { 123254721Semaste // Disable the ability for this thread to be cancelled 124254721Semaste int err = ::pthread_setcancelstate (PTHREAD_CANCEL_DISABLE, &m_old_state); 125254721Semaste if (err != 0) 126254721Semaste m_old_state = -1; 127254721Semaste 128254721Semaste } 129254721Semaste 130254721Semaste ~ScopedPThreadCancelDisabler() 131254721Semaste { 132254721Semaste // Restore the ability for this thread to be cancelled to what it 133254721Semaste // previously was. 134254721Semaste if (m_old_state != -1) 135254721Semaste ::pthread_setcancelstate (m_old_state, 0); 136254721Semaste } 137254721Semasteprivate: 138254721Semaste int m_old_state; // Save the old cancelability state. 139254721Semaste}; 140254721Semaste 141258054Semastestatic thread_result_t 142254721SemasteMonitorChildProcessThreadFunction (void *arg) 143254721Semaste{ 144254721Semaste Log *log(lldb_private::GetLogIfAllCategoriesSet (LIBLLDB_LOG_PROCESS)); 145254721Semaste const char *function = __FUNCTION__; 146254721Semaste if (log) 147254721Semaste log->Printf ("%s (arg = %p) thread starting...", function, arg); 148254721Semaste 149254721Semaste MonitorInfo *info = (MonitorInfo *)arg; 150254721Semaste 151254721Semaste const Host::MonitorChildProcessCallback callback = info->callback; 152254721Semaste void * const callback_baton = info->callback_baton; 153254721Semaste const bool monitor_signals = info->monitor_signals; 154254721Semaste 155258054Semaste assert (info->pid <= UINT32_MAX); 156258054Semaste const ::pid_t pid = monitor_signals ? -1 * info->pid : info->pid; 157258054Semaste 158254721Semaste delete info; 159254721Semaste 160254721Semaste int status = -1; 161254721Semaste#if defined (__FreeBSD__) || defined (__FreeBSD_kernel__) 162254721Semaste #define __WALL 0 163254721Semaste#endif 164254721Semaste const int options = __WALL; 165254721Semaste 166254721Semaste while (1) 167254721Semaste { 168254721Semaste log = lldb_private::GetLogIfAllCategoriesSet (LIBLLDB_LOG_PROCESS); 169254721Semaste if (log) 170258054Semaste log->Printf("%s ::wait_pid (pid = %" PRIi32 ", &status, options = %i)...", function, pid, options); 171254721Semaste 172254721Semaste // Wait for all child processes 173254721Semaste ::pthread_testcancel (); 174254721Semaste // Get signals from all children with same process group of pid 175258054Semaste const ::pid_t wait_pid = ::waitpid (pid, &status, options); 176254721Semaste ::pthread_testcancel (); 177254721Semaste 178254721Semaste if (wait_pid == -1) 179254721Semaste { 180254721Semaste if (errno == EINTR) 181254721Semaste continue; 182254721Semaste else 183254721Semaste { 184254721Semaste if (log) 185254721Semaste log->Printf ("%s (arg = %p) thread exiting because waitpid failed (%s)...", __FUNCTION__, arg, strerror(errno)); 186254721Semaste break; 187254721Semaste } 188254721Semaste } 189254721Semaste else if (wait_pid > 0) 190254721Semaste { 191254721Semaste bool exited = false; 192254721Semaste int signal = 0; 193254721Semaste int exit_status = 0; 194254721Semaste const char *status_cstr = NULL; 195254721Semaste if (WIFSTOPPED(status)) 196254721Semaste { 197254721Semaste signal = WSTOPSIG(status); 198254721Semaste status_cstr = "STOPPED"; 199254721Semaste } 200254721Semaste else if (WIFEXITED(status)) 201254721Semaste { 202254721Semaste exit_status = WEXITSTATUS(status); 203254721Semaste status_cstr = "EXITED"; 204254721Semaste exited = true; 205254721Semaste } 206254721Semaste else if (WIFSIGNALED(status)) 207254721Semaste { 208254721Semaste signal = WTERMSIG(status); 209254721Semaste status_cstr = "SIGNALED"; 210258054Semaste if (wait_pid == abs(pid)) { 211254721Semaste exited = true; 212254721Semaste exit_status = -1; 213254721Semaste } 214254721Semaste } 215254721Semaste else 216254721Semaste { 217254721Semaste status_cstr = "(\?\?\?)"; 218254721Semaste } 219254721Semaste 220254721Semaste // Scope for pthread_cancel_disabler 221254721Semaste { 222254721Semaste ScopedPThreadCancelDisabler pthread_cancel_disabler; 223254721Semaste 224254721Semaste log = lldb_private::GetLogIfAllCategoriesSet (LIBLLDB_LOG_PROCESS); 225254721Semaste if (log) 226258054Semaste log->Printf ("%s ::waitpid (pid = %" PRIi32 ", &status, options = %i) => pid = %" PRIi32 ", status = 0x%8.8x (%s), signal = %i, exit_state = %i", 227254721Semaste function, 228254721Semaste wait_pid, 229254721Semaste options, 230254721Semaste pid, 231254721Semaste status, 232254721Semaste status_cstr, 233254721Semaste signal, 234254721Semaste exit_status); 235254721Semaste 236254721Semaste if (exited || (signal != 0 && monitor_signals)) 237254721Semaste { 238254721Semaste bool callback_return = false; 239254721Semaste if (callback) 240254721Semaste callback_return = callback (callback_baton, wait_pid, exited, signal, exit_status); 241254721Semaste 242254721Semaste // If our process exited, then this thread should exit 243258054Semaste if (exited && wait_pid == abs(pid)) 244254721Semaste { 245254721Semaste if (log) 246254721Semaste log->Printf ("%s (arg = %p) thread exiting because pid received exit signal...", __FUNCTION__, arg); 247254721Semaste break; 248254721Semaste } 249254721Semaste // If the callback returns true, it means this process should 250254721Semaste // exit 251254721Semaste if (callback_return) 252254721Semaste { 253254721Semaste if (log) 254254721Semaste log->Printf ("%s (arg = %p) thread exiting because callback returned true...", __FUNCTION__, arg); 255254721Semaste break; 256254721Semaste } 257254721Semaste } 258254721Semaste } 259254721Semaste } 260254721Semaste } 261254721Semaste 262254721Semaste log = lldb_private::GetLogIfAllCategoriesSet (LIBLLDB_LOG_PROCESS); 263254721Semaste if (log) 264254721Semaste log->Printf ("%s (arg = %p) thread exiting...", __FUNCTION__, arg); 265254721Semaste 266254721Semaste return NULL; 267254721Semaste} 268254721Semaste 269258054Semaste#endif // #if !defined (__APPLE__) && !defined (_WIN32) 270254721Semaste 271258054Semaste#if !defined (__APPLE__) 272258054Semaste 273254721Semastevoid 274254721SemasteHost::SystemLog (SystemLogType type, const char *format, va_list args) 275254721Semaste{ 276254721Semaste vfprintf (stderr, format, args); 277254721Semaste} 278254721Semaste 279258054Semaste#endif 280254721Semaste 281254721Semastevoid 282254721SemasteHost::SystemLog (SystemLogType type, const char *format, ...) 283254721Semaste{ 284254721Semaste va_list args; 285254721Semaste va_start (args, format); 286254721Semaste SystemLog (type, format, args); 287254721Semaste va_end (args); 288254721Semaste} 289254721Semaste 290254721Semasteconst ArchSpec & 291254721SemasteHost::GetArchitecture (SystemDefaultArchitecture arch_kind) 292254721Semaste{ 293254721Semaste static bool g_supports_32 = false; 294254721Semaste static bool g_supports_64 = false; 295254721Semaste static ArchSpec g_host_arch_32; 296254721Semaste static ArchSpec g_host_arch_64; 297254721Semaste 298254721Semaste#if defined (__APPLE__) 299254721Semaste 300254721Semaste // Apple is different in that it can support both 32 and 64 bit executables 301254721Semaste // in the same operating system running concurrently. Here we detect the 302254721Semaste // correct host architectures for both 32 and 64 bit including if 64 bit 303254721Semaste // executables are supported on the system. 304254721Semaste 305254721Semaste if (g_supports_32 == false && g_supports_64 == false) 306254721Semaste { 307254721Semaste // All apple systems support 32 bit execution. 308254721Semaste g_supports_32 = true; 309254721Semaste uint32_t cputype, cpusubtype; 310254721Semaste uint32_t is_64_bit_capable = false; 311254721Semaste size_t len = sizeof(cputype); 312254721Semaste ArchSpec host_arch; 313254721Semaste // These will tell us about the kernel architecture, which even on a 64 314254721Semaste // bit machine can be 32 bit... 315254721Semaste if (::sysctlbyname("hw.cputype", &cputype, &len, NULL, 0) == 0) 316254721Semaste { 317254721Semaste len = sizeof (cpusubtype); 318254721Semaste if (::sysctlbyname("hw.cpusubtype", &cpusubtype, &len, NULL, 0) != 0) 319254721Semaste cpusubtype = CPU_TYPE_ANY; 320254721Semaste 321254721Semaste len = sizeof (is_64_bit_capable); 322254721Semaste if (::sysctlbyname("hw.cpu64bit_capable", &is_64_bit_capable, &len, NULL, 0) == 0) 323254721Semaste { 324254721Semaste if (is_64_bit_capable) 325254721Semaste g_supports_64 = true; 326254721Semaste } 327254721Semaste 328254721Semaste if (is_64_bit_capable) 329254721Semaste { 330254721Semaste#if defined (__i386__) || defined (__x86_64__) 331254721Semaste if (cpusubtype == CPU_SUBTYPE_486) 332254721Semaste cpusubtype = CPU_SUBTYPE_I386_ALL; 333254721Semaste#endif 334254721Semaste if (cputype & CPU_ARCH_ABI64) 335254721Semaste { 336254721Semaste // We have a 64 bit kernel on a 64 bit system 337254721Semaste g_host_arch_32.SetArchitecture (eArchTypeMachO, ~(CPU_ARCH_MASK) & cputype, cpusubtype); 338254721Semaste g_host_arch_64.SetArchitecture (eArchTypeMachO, cputype, cpusubtype); 339254721Semaste } 340254721Semaste else 341254721Semaste { 342254721Semaste // We have a 32 bit kernel on a 64 bit system 343254721Semaste g_host_arch_32.SetArchitecture (eArchTypeMachO, cputype, cpusubtype); 344254721Semaste cputype |= CPU_ARCH_ABI64; 345254721Semaste g_host_arch_64.SetArchitecture (eArchTypeMachO, cputype, cpusubtype); 346254721Semaste } 347254721Semaste } 348254721Semaste else 349254721Semaste { 350254721Semaste g_host_arch_32.SetArchitecture (eArchTypeMachO, cputype, cpusubtype); 351254721Semaste g_host_arch_64.Clear(); 352254721Semaste } 353254721Semaste } 354254721Semaste } 355254721Semaste 356254721Semaste#else // #if defined (__APPLE__) 357254721Semaste 358254721Semaste if (g_supports_32 == false && g_supports_64 == false) 359254721Semaste { 360254721Semaste llvm::Triple triple(llvm::sys::getDefaultTargetTriple()); 361254721Semaste 362254721Semaste g_host_arch_32.Clear(); 363254721Semaste g_host_arch_64.Clear(); 364254721Semaste 365254721Semaste // If the OS is Linux, "unknown" in the vendor slot isn't what we want 366254721Semaste // for the default triple. It's probably an artifact of config.guess. 367254721Semaste if (triple.getOS() == llvm::Triple::Linux && triple.getVendor() == llvm::Triple::UnknownVendor) 368254721Semaste triple.setVendorName(""); 369254721Semaste 370254721Semaste switch (triple.getArch()) 371254721Semaste { 372254721Semaste default: 373254721Semaste g_host_arch_32.SetTriple(triple); 374254721Semaste g_supports_32 = true; 375254721Semaste break; 376254721Semaste 377254721Semaste case llvm::Triple::x86_64: 378254721Semaste g_host_arch_64.SetTriple(triple); 379254721Semaste g_supports_64 = true; 380254721Semaste g_host_arch_32.SetTriple(triple.get32BitArchVariant()); 381254721Semaste g_supports_32 = true; 382254721Semaste break; 383254721Semaste 384254721Semaste case llvm::Triple::sparcv9: 385254721Semaste case llvm::Triple::ppc64: 386254721Semaste g_host_arch_64.SetTriple(triple); 387254721Semaste g_supports_64 = true; 388254721Semaste break; 389254721Semaste } 390254721Semaste 391254721Semaste g_supports_32 = g_host_arch_32.IsValid(); 392254721Semaste g_supports_64 = g_host_arch_64.IsValid(); 393254721Semaste } 394254721Semaste 395254721Semaste#endif // #else for #if defined (__APPLE__) 396254721Semaste 397254721Semaste if (arch_kind == eSystemDefaultArchitecture32) 398254721Semaste return g_host_arch_32; 399254721Semaste else if (arch_kind == eSystemDefaultArchitecture64) 400254721Semaste return g_host_arch_64; 401254721Semaste 402254721Semaste if (g_supports_64) 403254721Semaste return g_host_arch_64; 404254721Semaste 405254721Semaste return g_host_arch_32; 406254721Semaste} 407254721Semaste 408254721Semasteconst ConstString & 409254721SemasteHost::GetVendorString() 410254721Semaste{ 411254721Semaste static ConstString g_vendor; 412254721Semaste if (!g_vendor) 413254721Semaste { 414254721Semaste const ArchSpec &host_arch = GetArchitecture (eSystemDefaultArchitecture); 415254721Semaste const llvm::StringRef &str_ref = host_arch.GetTriple().getVendorName(); 416254721Semaste g_vendor.SetCStringWithLength(str_ref.data(), str_ref.size()); 417254721Semaste } 418254721Semaste return g_vendor; 419254721Semaste} 420254721Semaste 421254721Semasteconst ConstString & 422254721SemasteHost::GetOSString() 423254721Semaste{ 424254721Semaste static ConstString g_os_string; 425254721Semaste if (!g_os_string) 426254721Semaste { 427254721Semaste const ArchSpec &host_arch = GetArchitecture (eSystemDefaultArchitecture); 428254721Semaste const llvm::StringRef &str_ref = host_arch.GetTriple().getOSName(); 429254721Semaste g_os_string.SetCStringWithLength(str_ref.data(), str_ref.size()); 430254721Semaste } 431254721Semaste return g_os_string; 432254721Semaste} 433254721Semaste 434254721Semasteconst ConstString & 435254721SemasteHost::GetTargetTriple() 436254721Semaste{ 437254721Semaste static ConstString g_host_triple; 438254721Semaste if (!(g_host_triple)) 439254721Semaste { 440254721Semaste const ArchSpec &host_arch = GetArchitecture (eSystemDefaultArchitecture); 441254721Semaste g_host_triple.SetCString(host_arch.GetTriple().getTriple().c_str()); 442254721Semaste } 443254721Semaste return g_host_triple; 444254721Semaste} 445254721Semaste 446254721Semastelldb::pid_t 447254721SemasteHost::GetCurrentProcessID() 448254721Semaste{ 449254721Semaste return ::getpid(); 450254721Semaste} 451254721Semaste 452258054Semaste#ifndef _WIN32 453258054Semaste 454254721Semastelldb::tid_t 455254721SemasteHost::GetCurrentThreadID() 456254721Semaste{ 457254721Semaste#if defined (__APPLE__) 458254721Semaste // Calling "mach_port_deallocate()" bumps the reference count on the thread 459254721Semaste // port, so we need to deallocate it. mach_task_self() doesn't bump the ref 460254721Semaste // count. 461254721Semaste thread_port_t thread_self = mach_thread_self(); 462254721Semaste mach_port_deallocate(mach_task_self(), thread_self); 463254721Semaste return thread_self; 464254721Semaste#elif defined(__FreeBSD__) 465254721Semaste return lldb::tid_t(pthread_getthreadid_np()); 466254721Semaste#elif defined(__linux__) 467254721Semaste return lldb::tid_t(syscall(SYS_gettid)); 468254721Semaste#else 469254721Semaste return lldb::tid_t(pthread_self()); 470254721Semaste#endif 471254721Semaste} 472254721Semaste 473254721Semastelldb::thread_t 474254721SemasteHost::GetCurrentThread () 475254721Semaste{ 476254721Semaste return lldb::thread_t(pthread_self()); 477254721Semaste} 478254721Semaste 479254721Semasteconst char * 480254721SemasteHost::GetSignalAsCString (int signo) 481254721Semaste{ 482254721Semaste switch (signo) 483254721Semaste { 484254721Semaste case SIGHUP: return "SIGHUP"; // 1 hangup 485254721Semaste case SIGINT: return "SIGINT"; // 2 interrupt 486254721Semaste case SIGQUIT: return "SIGQUIT"; // 3 quit 487254721Semaste case SIGILL: return "SIGILL"; // 4 illegal instruction (not reset when caught) 488254721Semaste case SIGTRAP: return "SIGTRAP"; // 5 trace trap (not reset when caught) 489254721Semaste case SIGABRT: return "SIGABRT"; // 6 abort() 490254721Semaste#if (defined(_POSIX_C_SOURCE) && !defined(_DARWIN_C_SOURCE)) 491254721Semaste case SIGPOLL: return "SIGPOLL"; // 7 pollable event ([XSR] generated, not supported) 492254721Semaste#endif 493254721Semaste#if !defined(_POSIX_C_SOURCE) 494254721Semaste case SIGEMT: return "SIGEMT"; // 7 EMT instruction 495254721Semaste#endif 496254721Semaste case SIGFPE: return "SIGFPE"; // 8 floating point exception 497254721Semaste case SIGKILL: return "SIGKILL"; // 9 kill (cannot be caught or ignored) 498254721Semaste case SIGBUS: return "SIGBUS"; // 10 bus error 499254721Semaste case SIGSEGV: return "SIGSEGV"; // 11 segmentation violation 500254721Semaste case SIGSYS: return "SIGSYS"; // 12 bad argument to system call 501254721Semaste case SIGPIPE: return "SIGPIPE"; // 13 write on a pipe with no one to read it 502254721Semaste case SIGALRM: return "SIGALRM"; // 14 alarm clock 503254721Semaste case SIGTERM: return "SIGTERM"; // 15 software termination signal from kill 504254721Semaste case SIGURG: return "SIGURG"; // 16 urgent condition on IO channel 505254721Semaste case SIGSTOP: return "SIGSTOP"; // 17 sendable stop signal not from tty 506254721Semaste case SIGTSTP: return "SIGTSTP"; // 18 stop signal from tty 507254721Semaste case SIGCONT: return "SIGCONT"; // 19 continue a stopped process 508254721Semaste case SIGCHLD: return "SIGCHLD"; // 20 to parent on child stop or exit 509254721Semaste case SIGTTIN: return "SIGTTIN"; // 21 to readers pgrp upon background tty read 510254721Semaste case SIGTTOU: return "SIGTTOU"; // 22 like TTIN for output if (tp->t_local<OSTOP) 511254721Semaste#if !defined(_POSIX_C_SOURCE) 512254721Semaste case SIGIO: return "SIGIO"; // 23 input/output possible signal 513254721Semaste#endif 514254721Semaste case SIGXCPU: return "SIGXCPU"; // 24 exceeded CPU time limit 515254721Semaste case SIGXFSZ: return "SIGXFSZ"; // 25 exceeded file size limit 516254721Semaste case SIGVTALRM: return "SIGVTALRM"; // 26 virtual time alarm 517254721Semaste case SIGPROF: return "SIGPROF"; // 27 profiling time alarm 518254721Semaste#if !defined(_POSIX_C_SOURCE) 519254721Semaste case SIGWINCH: return "SIGWINCH"; // 28 window size changes 520254721Semaste case SIGINFO: return "SIGINFO"; // 29 information request 521254721Semaste#endif 522254721Semaste case SIGUSR1: return "SIGUSR1"; // 30 user defined signal 1 523254721Semaste case SIGUSR2: return "SIGUSR2"; // 31 user defined signal 2 524254721Semaste default: 525254721Semaste break; 526254721Semaste } 527254721Semaste return NULL; 528254721Semaste} 529254721Semaste 530258054Semaste#endif 531258054Semaste 532254721Semastevoid 533254721SemasteHost::WillTerminate () 534254721Semaste{ 535254721Semaste} 536254721Semaste 537254721Semaste#if !defined (__APPLE__) && !defined (__FreeBSD__) && !defined (__FreeBSD_kernel__) && !defined (__linux__) // see macosx/Host.mm 538254721Semaste 539254721Semastevoid 540254721SemasteHost::ThreadCreated (const char *thread_name) 541254721Semaste{ 542254721Semaste} 543254721Semaste 544254721Semastevoid 545254721SemasteHost::Backtrace (Stream &strm, uint32_t max_frames) 546254721Semaste{ 547254721Semaste // TODO: Is there a way to backtrace the current process on other systems? 548254721Semaste} 549254721Semaste 550254721Semastesize_t 551254721SemasteHost::GetEnvironment (StringList &env) 552254721Semaste{ 553254721Semaste // TODO: Is there a way to the host environment for this process on other systems? 554254721Semaste return 0; 555254721Semaste} 556254721Semaste 557254721Semaste#endif // #if !defined (__APPLE__) && !defined (__FreeBSD__) && !defined (__FreeBSD_kernel__) && !defined (__linux__) 558254721Semaste 559254721Semastestruct HostThreadCreateInfo 560254721Semaste{ 561254721Semaste std::string thread_name; 562254721Semaste thread_func_t thread_fptr; 563254721Semaste thread_arg_t thread_arg; 564254721Semaste 565254721Semaste HostThreadCreateInfo (const char *name, thread_func_t fptr, thread_arg_t arg) : 566254721Semaste thread_name (name ? name : ""), 567254721Semaste thread_fptr (fptr), 568254721Semaste thread_arg (arg) 569254721Semaste { 570254721Semaste } 571254721Semaste}; 572254721Semaste 573254721Semastestatic thread_result_t 574258054Semaste#ifdef _WIN32 575258054Semaste__stdcall 576258054Semaste#endif 577254721SemasteThreadCreateTrampoline (thread_arg_t arg) 578254721Semaste{ 579254721Semaste HostThreadCreateInfo *info = (HostThreadCreateInfo *)arg; 580254721Semaste Host::ThreadCreated (info->thread_name.c_str()); 581254721Semaste thread_func_t thread_fptr = info->thread_fptr; 582254721Semaste thread_arg_t thread_arg = info->thread_arg; 583254721Semaste 584254721Semaste Log *log(lldb_private::GetLogIfAllCategoriesSet (LIBLLDB_LOG_THREAD)); 585254721Semaste if (log) 586254721Semaste log->Printf("thread created"); 587254721Semaste 588254721Semaste delete info; 589254721Semaste return thread_fptr (thread_arg); 590254721Semaste} 591254721Semaste 592254721Semastelldb::thread_t 593254721SemasteHost::ThreadCreate 594254721Semaste( 595254721Semaste const char *thread_name, 596254721Semaste thread_func_t thread_fptr, 597254721Semaste thread_arg_t thread_arg, 598254721Semaste Error *error 599254721Semaste) 600254721Semaste{ 601254721Semaste lldb::thread_t thread = LLDB_INVALID_HOST_THREAD; 602254721Semaste 603254721Semaste // Host::ThreadCreateTrampoline will delete this pointer for us. 604254721Semaste HostThreadCreateInfo *info_ptr = new HostThreadCreateInfo (thread_name, thread_fptr, thread_arg); 605254721Semaste 606258054Semaste#ifdef _WIN32 607258054Semaste thread = ::_beginthreadex(0, 0, ThreadCreateTrampoline, info_ptr, 0, NULL); 608258054Semaste int err = thread <= 0 ? GetLastError() : 0; 609258054Semaste#else 610254721Semaste int err = ::pthread_create (&thread, NULL, ThreadCreateTrampoline, info_ptr); 611258054Semaste#endif 612254721Semaste if (err == 0) 613254721Semaste { 614254721Semaste if (error) 615254721Semaste error->Clear(); 616254721Semaste return thread; 617254721Semaste } 618254721Semaste 619254721Semaste if (error) 620254721Semaste error->SetError (err, eErrorTypePOSIX); 621254721Semaste 622254721Semaste return LLDB_INVALID_HOST_THREAD; 623254721Semaste} 624254721Semaste 625258054Semaste#ifndef _WIN32 626258054Semaste 627254721Semastebool 628254721SemasteHost::ThreadCancel (lldb::thread_t thread, Error *error) 629254721Semaste{ 630254721Semaste int err = ::pthread_cancel (thread); 631254721Semaste if (error) 632254721Semaste error->SetError(err, eErrorTypePOSIX); 633254721Semaste return err == 0; 634254721Semaste} 635254721Semaste 636254721Semastebool 637254721SemasteHost::ThreadDetach (lldb::thread_t thread, Error *error) 638254721Semaste{ 639254721Semaste int err = ::pthread_detach (thread); 640254721Semaste if (error) 641254721Semaste error->SetError(err, eErrorTypePOSIX); 642254721Semaste return err == 0; 643254721Semaste} 644254721Semaste 645254721Semastebool 646254721SemasteHost::ThreadJoin (lldb::thread_t thread, thread_result_t *thread_result_ptr, Error *error) 647254721Semaste{ 648254721Semaste int err = ::pthread_join (thread, thread_result_ptr); 649254721Semaste if (error) 650254721Semaste error->SetError(err, eErrorTypePOSIX); 651254721Semaste return err == 0; 652254721Semaste} 653254721Semaste 654258054Semastelldb::thread_key_t 655258054SemasteHost::ThreadLocalStorageCreate(ThreadLocalStorageCleanupCallback callback) 656258054Semaste{ 657258054Semaste pthread_key_t key; 658258054Semaste ::pthread_key_create (&key, callback); 659258054Semaste return key; 660258054Semaste} 661258054Semaste 662258054Semastevoid* 663258054SemasteHost::ThreadLocalStorageGet(lldb::thread_key_t key) 664258054Semaste{ 665258054Semaste return ::pthread_getspecific (key); 666258054Semaste} 667258054Semaste 668258054Semastevoid 669258054SemasteHost::ThreadLocalStorageSet(lldb::thread_key_t key, void *value) 670258054Semaste{ 671258054Semaste ::pthread_setspecific (key, value); 672258054Semaste} 673258054Semaste 674254721Semastebool 675254721SemasteHost::SetThreadName (lldb::pid_t pid, lldb::tid_t tid, const char *name) 676254721Semaste{ 677254721Semaste#if defined(__APPLE__) && MAC_OS_X_VERSION_MAX_ALLOWED > MAC_OS_X_VERSION_10_5 678254721Semaste lldb::pid_t curr_pid = Host::GetCurrentProcessID(); 679254721Semaste lldb::tid_t curr_tid = Host::GetCurrentThreadID(); 680254721Semaste if (pid == LLDB_INVALID_PROCESS_ID) 681254721Semaste pid = curr_pid; 682254721Semaste 683254721Semaste if (tid == LLDB_INVALID_THREAD_ID) 684254721Semaste tid = curr_tid; 685254721Semaste 686254721Semaste // Set the pthread name if possible 687254721Semaste if (pid == curr_pid && tid == curr_tid) 688254721Semaste { 689254721Semaste if (::pthread_setname_np (name) == 0) 690254721Semaste return true; 691254721Semaste } 692254721Semaste return false; 693254721Semaste#elif defined (__FreeBSD__) 694254721Semaste lldb::pid_t curr_pid = Host::GetCurrentProcessID(); 695254721Semaste lldb::tid_t curr_tid = Host::GetCurrentThreadID(); 696254721Semaste if (pid == LLDB_INVALID_PROCESS_ID) 697254721Semaste pid = curr_pid; 698254721Semaste 699254721Semaste if (tid == LLDB_INVALID_THREAD_ID) 700254721Semaste tid = curr_tid; 701254721Semaste 702254721Semaste // Set the pthread name if possible 703254721Semaste if (pid == curr_pid && tid == curr_tid) 704254721Semaste { 705254721Semaste ::pthread_set_name_np (::pthread_self(), name); 706254721Semaste return true; 707254721Semaste } 708254721Semaste return false; 709254721Semaste#elif defined (__linux__) || defined (__GLIBC__) 710254721Semaste void *fn = dlsym (RTLD_DEFAULT, "pthread_setname_np"); 711254721Semaste if (fn) 712254721Semaste { 713254721Semaste lldb::pid_t curr_pid = Host::GetCurrentProcessID(); 714254721Semaste lldb::tid_t curr_tid = Host::GetCurrentThreadID(); 715254721Semaste if (pid == LLDB_INVALID_PROCESS_ID) 716254721Semaste pid = curr_pid; 717254721Semaste 718254721Semaste if (tid == LLDB_INVALID_THREAD_ID) 719254721Semaste tid = curr_tid; 720254721Semaste 721254721Semaste if (pid == curr_pid && tid == curr_tid) 722254721Semaste { 723254721Semaste int (*pthread_setname_np_func)(pthread_t thread, const char *name); 724254721Semaste *reinterpret_cast<void **> (&pthread_setname_np_func) = fn; 725254721Semaste 726254721Semaste if (pthread_setname_np_func (::pthread_self(), name) == 0) 727254721Semaste return true; 728254721Semaste } 729254721Semaste } 730254721Semaste return false; 731254721Semaste#else 732254721Semaste return false; 733254721Semaste#endif 734254721Semaste} 735254721Semaste 736254721Semastebool 737254721SemasteHost::SetShortThreadName (lldb::pid_t pid, lldb::tid_t tid, 738254721Semaste const char *thread_name, size_t len) 739254721Semaste{ 740254721Semaste char *namebuf = (char *)::malloc (len + 1); 741254721Semaste 742254721Semaste // Thread names are coming in like '<lldb.comm.debugger.edit>' and 743254721Semaste // '<lldb.comm.debugger.editline>'. So just chopping the end of the string 744254721Semaste // off leads to a lot of similar named threads. Go through the thread name 745254721Semaste // and search for the last dot and use that. 746254721Semaste const char *lastdot = ::strrchr (thread_name, '.'); 747254721Semaste 748254721Semaste if (lastdot && lastdot != thread_name) 749254721Semaste thread_name = lastdot + 1; 750254721Semaste ::strncpy (namebuf, thread_name, len); 751254721Semaste namebuf[len] = 0; 752254721Semaste 753254721Semaste int namebuflen = strlen(namebuf); 754254721Semaste if (namebuflen > 0) 755254721Semaste { 756254721Semaste if (namebuf[namebuflen - 1] == '(' || namebuf[namebuflen - 1] == '>') 757254721Semaste { 758254721Semaste // Trim off trailing '(' and '>' characters for a bit more cleanup. 759254721Semaste namebuflen--; 760254721Semaste namebuf[namebuflen] = 0; 761254721Semaste } 762254721Semaste return Host::SetThreadName (pid, tid, namebuf); 763254721Semaste } 764258054Semaste 765258054Semaste ::free(namebuf); 766254721Semaste return false; 767254721Semaste} 768254721Semaste 769258054Semaste#endif 770258054Semaste 771254721SemasteFileSpec 772254721SemasteHost::GetProgramFileSpec () 773254721Semaste{ 774254721Semaste static FileSpec g_program_filespec; 775254721Semaste if (!g_program_filespec) 776254721Semaste { 777254721Semaste#if defined (__APPLE__) 778254721Semaste char program_fullpath[PATH_MAX]; 779254721Semaste // If DST is NULL, then return the number of bytes needed. 780254721Semaste uint32_t len = sizeof(program_fullpath); 781254721Semaste int err = _NSGetExecutablePath (program_fullpath, &len); 782254721Semaste if (err == 0) 783254721Semaste g_program_filespec.SetFile (program_fullpath, false); 784254721Semaste else if (err == -1) 785254721Semaste { 786254721Semaste char *large_program_fullpath = (char *)::malloc (len + 1); 787254721Semaste 788254721Semaste err = _NSGetExecutablePath (large_program_fullpath, &len); 789254721Semaste if (err == 0) 790254721Semaste g_program_filespec.SetFile (large_program_fullpath, false); 791254721Semaste 792254721Semaste ::free (large_program_fullpath); 793254721Semaste } 794254721Semaste#elif defined (__linux__) 795254721Semaste char exe_path[PATH_MAX]; 796254721Semaste ssize_t len = readlink("/proc/self/exe", exe_path, sizeof(exe_path) - 1); 797254721Semaste if (len > 0) { 798254721Semaste exe_path[len] = 0; 799254721Semaste g_program_filespec.SetFile(exe_path, false); 800254721Semaste } 801254721Semaste#elif defined (__FreeBSD__) || defined (__FreeBSD_kernel__) 802254721Semaste int exe_path_mib[4] = { CTL_KERN, KERN_PROC, KERN_PROC_PATHNAME, getpid() }; 803254721Semaste size_t exe_path_size; 804254721Semaste if (sysctl(exe_path_mib, 4, NULL, &exe_path_size, NULL, 0) == 0) 805254721Semaste { 806254721Semaste char *exe_path = new char[exe_path_size]; 807254721Semaste if (sysctl(exe_path_mib, 4, exe_path, &exe_path_size, NULL, 0) == 0) 808254721Semaste g_program_filespec.SetFile(exe_path, false); 809254721Semaste delete[] exe_path; 810254721Semaste } 811254721Semaste#endif 812254721Semaste } 813254721Semaste return g_program_filespec; 814254721Semaste} 815254721Semaste 816254721Semaste#if !defined (__APPLE__) // see Host.mm 817254721Semaste 818254721Semastebool 819254721SemasteHost::GetBundleDirectory (const FileSpec &file, FileSpec &bundle) 820254721Semaste{ 821254721Semaste bundle.Clear(); 822254721Semaste return false; 823254721Semaste} 824254721Semaste 825254721Semastebool 826254721SemasteHost::ResolveExecutableInBundle (FileSpec &file) 827254721Semaste{ 828254721Semaste return false; 829254721Semaste} 830254721Semaste#endif 831254721Semaste 832258054Semaste#ifndef _WIN32 833258054Semaste 834254721Semaste// Opaque info that tracks a dynamic library that was loaded 835254721Semastestruct DynamicLibraryInfo 836254721Semaste{ 837254721Semaste DynamicLibraryInfo (const FileSpec &fs, int o, void *h) : 838254721Semaste file_spec (fs), 839254721Semaste open_options (o), 840254721Semaste handle (h) 841254721Semaste { 842254721Semaste } 843254721Semaste 844254721Semaste const FileSpec file_spec; 845254721Semaste uint32_t open_options; 846254721Semaste void * handle; 847254721Semaste}; 848254721Semaste 849254721Semastevoid * 850254721SemasteHost::DynamicLibraryOpen (const FileSpec &file_spec, uint32_t options, Error &error) 851254721Semaste{ 852254721Semaste char path[PATH_MAX]; 853254721Semaste if (file_spec.GetPath(path, sizeof(path))) 854254721Semaste { 855254721Semaste int mode = 0; 856254721Semaste 857254721Semaste if (options & eDynamicLibraryOpenOptionLazy) 858254721Semaste mode |= RTLD_LAZY; 859254721Semaste else 860254721Semaste mode |= RTLD_NOW; 861254721Semaste 862254721Semaste 863254721Semaste if (options & eDynamicLibraryOpenOptionLocal) 864254721Semaste mode |= RTLD_LOCAL; 865254721Semaste else 866254721Semaste mode |= RTLD_GLOBAL; 867254721Semaste 868254721Semaste#ifdef LLDB_CONFIG_DLOPEN_RTLD_FIRST_SUPPORTED 869254721Semaste if (options & eDynamicLibraryOpenOptionLimitGetSymbol) 870254721Semaste mode |= RTLD_FIRST; 871254721Semaste#endif 872254721Semaste 873254721Semaste void * opaque = ::dlopen (path, mode); 874254721Semaste 875254721Semaste if (opaque) 876254721Semaste { 877254721Semaste error.Clear(); 878254721Semaste return new DynamicLibraryInfo (file_spec, options, opaque); 879254721Semaste } 880254721Semaste else 881254721Semaste { 882254721Semaste error.SetErrorString(::dlerror()); 883254721Semaste } 884254721Semaste } 885254721Semaste else 886254721Semaste { 887254721Semaste error.SetErrorString("failed to extract path"); 888254721Semaste } 889254721Semaste return NULL; 890254721Semaste} 891254721Semaste 892254721SemasteError 893254721SemasteHost::DynamicLibraryClose (void *opaque) 894254721Semaste{ 895254721Semaste Error error; 896254721Semaste if (opaque == NULL) 897254721Semaste { 898254721Semaste error.SetErrorString ("invalid dynamic library handle"); 899254721Semaste } 900254721Semaste else 901254721Semaste { 902254721Semaste DynamicLibraryInfo *dylib_info = (DynamicLibraryInfo *) opaque; 903254721Semaste if (::dlclose (dylib_info->handle) != 0) 904254721Semaste { 905254721Semaste error.SetErrorString(::dlerror()); 906254721Semaste } 907254721Semaste 908254721Semaste dylib_info->open_options = 0; 909254721Semaste dylib_info->handle = 0; 910254721Semaste delete dylib_info; 911254721Semaste } 912254721Semaste return error; 913254721Semaste} 914254721Semaste 915254721Semastevoid * 916254721SemasteHost::DynamicLibraryGetSymbol (void *opaque, const char *symbol_name, Error &error) 917254721Semaste{ 918254721Semaste if (opaque == NULL) 919254721Semaste { 920254721Semaste error.SetErrorString ("invalid dynamic library handle"); 921254721Semaste } 922254721Semaste else 923254721Semaste { 924254721Semaste DynamicLibraryInfo *dylib_info = (DynamicLibraryInfo *) opaque; 925254721Semaste 926254721Semaste void *symbol_addr = ::dlsym (dylib_info->handle, symbol_name); 927254721Semaste if (symbol_addr) 928254721Semaste { 929254721Semaste#ifndef LLDB_CONFIG_DLOPEN_RTLD_FIRST_SUPPORTED 930254721Semaste // This host doesn't support limiting searches to this shared library 931254721Semaste // so we need to verify that the match came from this shared library 932254721Semaste // if it was requested in the Host::DynamicLibraryOpen() function. 933254721Semaste if (dylib_info->open_options & eDynamicLibraryOpenOptionLimitGetSymbol) 934254721Semaste { 935254721Semaste FileSpec match_dylib_spec (Host::GetModuleFileSpecForHostAddress (symbol_addr)); 936254721Semaste if (match_dylib_spec != dylib_info->file_spec) 937254721Semaste { 938254721Semaste char dylib_path[PATH_MAX]; 939254721Semaste if (dylib_info->file_spec.GetPath (dylib_path, sizeof(dylib_path))) 940254721Semaste error.SetErrorStringWithFormat ("symbol not found in \"%s\"", dylib_path); 941254721Semaste else 942254721Semaste error.SetErrorString ("symbol not found"); 943254721Semaste return NULL; 944254721Semaste } 945254721Semaste } 946254721Semaste#endif 947254721Semaste error.Clear(); 948254721Semaste return symbol_addr; 949254721Semaste } 950254721Semaste else 951254721Semaste { 952254721Semaste error.SetErrorString(::dlerror()); 953254721Semaste } 954254721Semaste } 955254721Semaste return NULL; 956254721Semaste} 957254721Semaste 958258054SemasteFileSpec 959258054SemasteHost::GetModuleFileSpecForHostAddress (const void *host_addr) 960258054Semaste{ 961258054Semaste FileSpec module_filespec; 962258054Semaste Dl_info info; 963258054Semaste if (::dladdr (host_addr, &info)) 964258054Semaste { 965258054Semaste if (info.dli_fname) 966258054Semaste module_filespec.SetFile(info.dli_fname, true); 967258054Semaste } 968258054Semaste return module_filespec; 969258054Semaste} 970258054Semaste 971258054Semaste#endif 972258054Semaste 973254721Semastebool 974254721SemasteHost::GetLLDBPath (PathType path_type, FileSpec &file_spec) 975254721Semaste{ 976254721Semaste // To get paths related to LLDB we get the path to the executable that 977254721Semaste // contains this function. On MacOSX this will be "LLDB.framework/.../LLDB", 978254721Semaste // on linux this is assumed to be the "lldb" main executable. If LLDB on 979254721Semaste // linux is actually in a shared library (liblldb.so) then this function will 980254721Semaste // need to be modified to "do the right thing". 981254721Semaste 982254721Semaste switch (path_type) 983254721Semaste { 984254721Semaste case ePathTypeLLDBShlibDir: 985254721Semaste { 986254721Semaste static ConstString g_lldb_so_dir; 987254721Semaste if (!g_lldb_so_dir) 988254721Semaste { 989254721Semaste FileSpec lldb_file_spec (Host::GetModuleFileSpecForHostAddress ((void *)Host::GetLLDBPath)); 990254721Semaste g_lldb_so_dir = lldb_file_spec.GetDirectory(); 991254721Semaste } 992254721Semaste file_spec.GetDirectory() = g_lldb_so_dir; 993258054Semaste return (bool)file_spec.GetDirectory(); 994254721Semaste } 995254721Semaste break; 996254721Semaste 997254721Semaste case ePathTypeSupportExecutableDir: 998254721Semaste { 999254721Semaste static ConstString g_lldb_support_exe_dir; 1000254721Semaste if (!g_lldb_support_exe_dir) 1001254721Semaste { 1002254721Semaste FileSpec lldb_file_spec; 1003254721Semaste if (GetLLDBPath (ePathTypeLLDBShlibDir, lldb_file_spec)) 1004254721Semaste { 1005254721Semaste char raw_path[PATH_MAX]; 1006254721Semaste char resolved_path[PATH_MAX]; 1007254721Semaste lldb_file_spec.GetPath(raw_path, sizeof(raw_path)); 1008254721Semaste 1009254721Semaste#if defined (__APPLE__) 1010254721Semaste char *framework_pos = ::strstr (raw_path, "LLDB.framework"); 1011254721Semaste if (framework_pos) 1012254721Semaste { 1013254721Semaste framework_pos += strlen("LLDB.framework"); 1014254721Semaste#if !defined (__arm__) 1015254721Semaste ::strncpy (framework_pos, "/Resources", PATH_MAX - (framework_pos - raw_path)); 1016254721Semaste#endif 1017254721Semaste } 1018254721Semaste#endif 1019254721Semaste FileSpec::Resolve (raw_path, resolved_path, sizeof(resolved_path)); 1020254721Semaste g_lldb_support_exe_dir.SetCString(resolved_path); 1021254721Semaste } 1022254721Semaste } 1023254721Semaste file_spec.GetDirectory() = g_lldb_support_exe_dir; 1024258054Semaste return (bool)file_spec.GetDirectory(); 1025254721Semaste } 1026254721Semaste break; 1027254721Semaste 1028254721Semaste case ePathTypeHeaderDir: 1029254721Semaste { 1030254721Semaste static ConstString g_lldb_headers_dir; 1031254721Semaste if (!g_lldb_headers_dir) 1032254721Semaste { 1033254721Semaste#if defined (__APPLE__) 1034254721Semaste FileSpec lldb_file_spec; 1035254721Semaste if (GetLLDBPath (ePathTypeLLDBShlibDir, lldb_file_spec)) 1036254721Semaste { 1037254721Semaste char raw_path[PATH_MAX]; 1038254721Semaste char resolved_path[PATH_MAX]; 1039254721Semaste lldb_file_spec.GetPath(raw_path, sizeof(raw_path)); 1040254721Semaste 1041254721Semaste char *framework_pos = ::strstr (raw_path, "LLDB.framework"); 1042254721Semaste if (framework_pos) 1043254721Semaste { 1044254721Semaste framework_pos += strlen("LLDB.framework"); 1045254721Semaste ::strncpy (framework_pos, "/Headers", PATH_MAX - (framework_pos - raw_path)); 1046254721Semaste } 1047254721Semaste FileSpec::Resolve (raw_path, resolved_path, sizeof(resolved_path)); 1048254721Semaste g_lldb_headers_dir.SetCString(resolved_path); 1049254721Semaste } 1050254721Semaste#else 1051254721Semaste // TODO: Anyone know how we can determine this for linux? Other systems?? 1052254721Semaste g_lldb_headers_dir.SetCString ("/opt/local/include/lldb"); 1053254721Semaste#endif 1054254721Semaste } 1055254721Semaste file_spec.GetDirectory() = g_lldb_headers_dir; 1056258054Semaste return (bool)file_spec.GetDirectory(); 1057254721Semaste } 1058254721Semaste break; 1059254721Semaste 1060258054Semaste#ifdef LLDB_DISABLE_PYTHON 1061258054Semaste case ePathTypePythonDir: 1062258054Semaste return false; 1063258054Semaste#else 1064258054Semaste case ePathTypePythonDir: 1065254721Semaste { 1066254721Semaste static ConstString g_lldb_python_dir; 1067254721Semaste if (!g_lldb_python_dir) 1068254721Semaste { 1069254721Semaste FileSpec lldb_file_spec; 1070254721Semaste if (GetLLDBPath (ePathTypeLLDBShlibDir, lldb_file_spec)) 1071254721Semaste { 1072254721Semaste char raw_path[PATH_MAX]; 1073254721Semaste char resolved_path[PATH_MAX]; 1074254721Semaste lldb_file_spec.GetPath(raw_path, sizeof(raw_path)); 1075254721Semaste 1076254721Semaste#if defined (__APPLE__) 1077254721Semaste char *framework_pos = ::strstr (raw_path, "LLDB.framework"); 1078254721Semaste if (framework_pos) 1079254721Semaste { 1080254721Semaste framework_pos += strlen("LLDB.framework"); 1081254721Semaste ::strncpy (framework_pos, "/Resources/Python", PATH_MAX - (framework_pos - raw_path)); 1082254721Semaste } 1083254721Semaste#else 1084254721Semaste llvm::SmallString<256> python_version_dir; 1085254721Semaste llvm::raw_svector_ostream os(python_version_dir); 1086254721Semaste os << "/python" << PY_MAJOR_VERSION << '.' << PY_MINOR_VERSION << "/site-packages"; 1087254721Semaste os.flush(); 1088254721Semaste 1089254721Semaste // We may get our string truncated. Should we protect 1090254721Semaste // this with an assert? 1091254721Semaste 1092254721Semaste ::strncat(raw_path, python_version_dir.c_str(), 1093254721Semaste sizeof(raw_path) - strlen(raw_path) - 1); 1094254721Semaste 1095254721Semaste#endif 1096254721Semaste FileSpec::Resolve (raw_path, resolved_path, sizeof(resolved_path)); 1097254721Semaste g_lldb_python_dir.SetCString(resolved_path); 1098254721Semaste } 1099254721Semaste } 1100254721Semaste file_spec.GetDirectory() = g_lldb_python_dir; 1101258054Semaste return (bool)file_spec.GetDirectory(); 1102254721Semaste } 1103254721Semaste break; 1104254721Semaste#endif 1105254721Semaste 1106254721Semaste case ePathTypeLLDBSystemPlugins: // System plug-ins directory 1107254721Semaste { 1108254721Semaste#if defined (__APPLE__) || defined(__linux__) 1109254721Semaste static ConstString g_lldb_system_plugin_dir; 1110254721Semaste static bool g_lldb_system_plugin_dir_located = false; 1111254721Semaste if (!g_lldb_system_plugin_dir_located) 1112254721Semaste { 1113254721Semaste g_lldb_system_plugin_dir_located = true; 1114254721Semaste#if defined (__APPLE__) 1115254721Semaste FileSpec lldb_file_spec; 1116254721Semaste if (GetLLDBPath (ePathTypeLLDBShlibDir, lldb_file_spec)) 1117254721Semaste { 1118254721Semaste char raw_path[PATH_MAX]; 1119254721Semaste char resolved_path[PATH_MAX]; 1120254721Semaste lldb_file_spec.GetPath(raw_path, sizeof(raw_path)); 1121254721Semaste 1122254721Semaste char *framework_pos = ::strstr (raw_path, "LLDB.framework"); 1123254721Semaste if (framework_pos) 1124254721Semaste { 1125254721Semaste framework_pos += strlen("LLDB.framework"); 1126254721Semaste ::strncpy (framework_pos, "/Resources/PlugIns", PATH_MAX - (framework_pos - raw_path)); 1127254721Semaste FileSpec::Resolve (raw_path, resolved_path, sizeof(resolved_path)); 1128254721Semaste g_lldb_system_plugin_dir.SetCString(resolved_path); 1129254721Semaste } 1130254721Semaste return false; 1131254721Semaste } 1132254721Semaste#elif defined (__linux__) 1133254721Semaste FileSpec lldb_file_spec("/usr/lib/lldb", true); 1134254721Semaste if (lldb_file_spec.Exists()) 1135254721Semaste { 1136254721Semaste g_lldb_system_plugin_dir.SetCString(lldb_file_spec.GetPath().c_str()); 1137254721Semaste } 1138254721Semaste#endif // __APPLE__ || __linux__ 1139254721Semaste } 1140254721Semaste 1141254721Semaste if (g_lldb_system_plugin_dir) 1142254721Semaste { 1143254721Semaste file_spec.GetDirectory() = g_lldb_system_plugin_dir; 1144254721Semaste return true; 1145254721Semaste } 1146254721Semaste#else 1147254721Semaste // TODO: where would system LLDB plug-ins be located on other systems? 1148254721Semaste return false; 1149254721Semaste#endif 1150254721Semaste } 1151254721Semaste break; 1152254721Semaste 1153254721Semaste case ePathTypeLLDBUserPlugins: // User plug-ins directory 1154254721Semaste { 1155254721Semaste#if defined (__APPLE__) 1156254721Semaste static ConstString g_lldb_user_plugin_dir; 1157254721Semaste if (!g_lldb_user_plugin_dir) 1158254721Semaste { 1159254721Semaste char user_plugin_path[PATH_MAX]; 1160254721Semaste if (FileSpec::Resolve ("~/Library/Application Support/LLDB/PlugIns", 1161254721Semaste user_plugin_path, 1162254721Semaste sizeof(user_plugin_path))) 1163254721Semaste { 1164254721Semaste g_lldb_user_plugin_dir.SetCString(user_plugin_path); 1165254721Semaste } 1166254721Semaste } 1167254721Semaste file_spec.GetDirectory() = g_lldb_user_plugin_dir; 1168258054Semaste return (bool)file_spec.GetDirectory(); 1169254721Semaste#elif defined (__linux__) 1170254721Semaste static ConstString g_lldb_user_plugin_dir; 1171254721Semaste if (!g_lldb_user_plugin_dir) 1172254721Semaste { 1173254721Semaste // XDG Base Directory Specification 1174254721Semaste // http://standards.freedesktop.org/basedir-spec/basedir-spec-latest.html 1175254721Semaste // If XDG_DATA_HOME exists, use that, otherwise use ~/.local/share/lldb. 1176254721Semaste FileSpec lldb_file_spec; 1177254721Semaste const char *xdg_data_home = getenv("XDG_DATA_HOME"); 1178254721Semaste if (xdg_data_home && xdg_data_home[0]) 1179254721Semaste { 1180254721Semaste std::string user_plugin_dir (xdg_data_home); 1181254721Semaste user_plugin_dir += "/lldb"; 1182254721Semaste lldb_file_spec.SetFile (user_plugin_dir.c_str(), true); 1183254721Semaste } 1184254721Semaste else 1185254721Semaste { 1186254721Semaste const char *home_dir = getenv("HOME"); 1187254721Semaste if (home_dir && home_dir[0]) 1188254721Semaste { 1189254721Semaste std::string user_plugin_dir (home_dir); 1190254721Semaste user_plugin_dir += "/.local/share/lldb"; 1191254721Semaste lldb_file_spec.SetFile (user_plugin_dir.c_str(), true); 1192254721Semaste } 1193254721Semaste } 1194254721Semaste 1195254721Semaste if (lldb_file_spec.Exists()) 1196254721Semaste g_lldb_user_plugin_dir.SetCString(lldb_file_spec.GetPath().c_str()); 1197254721Semaste } 1198254721Semaste file_spec.GetDirectory() = g_lldb_user_plugin_dir; 1199258054Semaste return (bool)file_spec.GetDirectory(); 1200254721Semaste#endif 1201254721Semaste // TODO: where would user LLDB plug-ins be located on other systems? 1202254721Semaste return false; 1203254721Semaste } 1204254721Semaste } 1205254721Semaste 1206254721Semaste return false; 1207254721Semaste} 1208254721Semaste 1209254721Semaste 1210254721Semastebool 1211254721SemasteHost::GetHostname (std::string &s) 1212254721Semaste{ 1213254721Semaste char hostname[PATH_MAX]; 1214254721Semaste hostname[sizeof(hostname) - 1] = '\0'; 1215254721Semaste if (::gethostname (hostname, sizeof(hostname) - 1) == 0) 1216254721Semaste { 1217254721Semaste struct hostent* h = ::gethostbyname (hostname); 1218254721Semaste if (h) 1219254721Semaste s.assign (h->h_name); 1220254721Semaste else 1221254721Semaste s.assign (hostname); 1222254721Semaste return true; 1223254721Semaste } 1224254721Semaste return false; 1225254721Semaste} 1226254721Semaste 1227258054Semaste#ifndef _WIN32 1228258054Semaste 1229254721Semasteconst char * 1230254721SemasteHost::GetUserName (uint32_t uid, std::string &user_name) 1231254721Semaste{ 1232254721Semaste struct passwd user_info; 1233254721Semaste struct passwd *user_info_ptr = &user_info; 1234254721Semaste char user_buffer[PATH_MAX]; 1235254721Semaste size_t user_buffer_size = sizeof(user_buffer); 1236254721Semaste if (::getpwuid_r (uid, 1237254721Semaste &user_info, 1238254721Semaste user_buffer, 1239254721Semaste user_buffer_size, 1240254721Semaste &user_info_ptr) == 0) 1241254721Semaste { 1242254721Semaste if (user_info_ptr) 1243254721Semaste { 1244254721Semaste user_name.assign (user_info_ptr->pw_name); 1245254721Semaste return user_name.c_str(); 1246254721Semaste } 1247254721Semaste } 1248254721Semaste user_name.clear(); 1249254721Semaste return NULL; 1250254721Semaste} 1251254721Semaste 1252254721Semasteconst char * 1253254721SemasteHost::GetGroupName (uint32_t gid, std::string &group_name) 1254254721Semaste{ 1255254721Semaste char group_buffer[PATH_MAX]; 1256254721Semaste size_t group_buffer_size = sizeof(group_buffer); 1257254721Semaste struct group group_info; 1258254721Semaste struct group *group_info_ptr = &group_info; 1259254721Semaste // Try the threadsafe version first 1260254721Semaste if (::getgrgid_r (gid, 1261254721Semaste &group_info, 1262254721Semaste group_buffer, 1263254721Semaste group_buffer_size, 1264254721Semaste &group_info_ptr) == 0) 1265254721Semaste { 1266254721Semaste if (group_info_ptr) 1267254721Semaste { 1268254721Semaste group_name.assign (group_info_ptr->gr_name); 1269254721Semaste return group_name.c_str(); 1270254721Semaste } 1271254721Semaste } 1272254721Semaste else 1273254721Semaste { 1274254721Semaste // The threadsafe version isn't currently working 1275254721Semaste // for me on darwin, but the non-threadsafe version 1276254721Semaste // is, so I am calling it below. 1277254721Semaste group_info_ptr = ::getgrgid (gid); 1278254721Semaste if (group_info_ptr) 1279254721Semaste { 1280254721Semaste group_name.assign (group_info_ptr->gr_name); 1281254721Semaste return group_name.c_str(); 1282254721Semaste } 1283254721Semaste } 1284254721Semaste group_name.clear(); 1285254721Semaste return NULL; 1286254721Semaste} 1287254721Semaste 1288254721Semasteuint32_t 1289254721SemasteHost::GetUserID () 1290254721Semaste{ 1291254721Semaste return getuid(); 1292254721Semaste} 1293254721Semaste 1294254721Semasteuint32_t 1295254721SemasteHost::GetGroupID () 1296254721Semaste{ 1297254721Semaste return getgid(); 1298254721Semaste} 1299254721Semaste 1300254721Semasteuint32_t 1301254721SemasteHost::GetEffectiveUserID () 1302254721Semaste{ 1303254721Semaste return geteuid(); 1304254721Semaste} 1305254721Semaste 1306254721Semasteuint32_t 1307254721SemasteHost::GetEffectiveGroupID () 1308254721Semaste{ 1309254721Semaste return getegid(); 1310254721Semaste} 1311254721Semaste 1312258054Semaste#endif 1313258054Semaste 1314258054Semaste#if !defined (__APPLE__) && !defined (__FreeBSD__) && !defined (__FreeBSD_kernel__) // see macosx/Host.mm 1315258054Semastebool 1316258054SemasteHost::GetOSBuildString (std::string &s) 1317258054Semaste{ 1318258054Semaste s.clear(); 1319258054Semaste return false; 1320258054Semaste} 1321258054Semaste 1322258054Semastebool 1323258054SemasteHost::GetOSKernelDescription (std::string &s) 1324258054Semaste{ 1325258054Semaste s.clear(); 1326258054Semaste return false; 1327258054Semaste} 1328258054Semaste#endif 1329258054Semaste 1330258054Semaste#if !defined (__APPLE__) && !defined (__FreeBSD__) && !defined (__FreeBSD_kernel__) && !defined(__linux__) 1331254721Semasteuint32_t 1332254721SemasteHost::FindProcesses (const ProcessInstanceInfoMatch &match_info, ProcessInstanceInfoList &process_infos) 1333254721Semaste{ 1334254721Semaste process_infos.Clear(); 1335254721Semaste return process_infos.GetSize(); 1336254721Semaste} 1337254721Semaste 1338254721Semastebool 1339254721SemasteHost::GetProcessInfo (lldb::pid_t pid, ProcessInstanceInfo &process_info) 1340254721Semaste{ 1341254721Semaste process_info.Clear(); 1342254721Semaste return false; 1343254721Semaste} 1344254721Semaste#endif 1345254721Semaste 1346254721Semaste#if !defined(__linux__) 1347254721Semastebool 1348254721SemasteHost::FindProcessThreads (const lldb::pid_t pid, TidMap &tids_to_attach) 1349254721Semaste{ 1350254721Semaste return false; 1351254721Semaste} 1352254721Semaste#endif 1353254721Semaste 1354254721Semastelldb::TargetSP 1355254721SemasteHost::GetDummyTarget (lldb_private::Debugger &debugger) 1356254721Semaste{ 1357254721Semaste static TargetSP g_dummy_target_sp; 1358254721Semaste 1359254721Semaste // FIXME: Maybe the dummy target should be per-Debugger 1360254721Semaste if (!g_dummy_target_sp || !g_dummy_target_sp->IsValid()) 1361254721Semaste { 1362254721Semaste ArchSpec arch(Target::GetDefaultArchitecture()); 1363254721Semaste if (!arch.IsValid()) 1364254721Semaste arch = Host::GetArchitecture (); 1365254721Semaste Error err = debugger.GetTargetList().CreateTarget(debugger, 1366254721Semaste NULL, 1367254721Semaste arch.GetTriple().getTriple().c_str(), 1368254721Semaste false, 1369254721Semaste NULL, 1370254721Semaste g_dummy_target_sp); 1371254721Semaste } 1372254721Semaste 1373254721Semaste return g_dummy_target_sp; 1374254721Semaste} 1375254721Semaste 1376254721Semastestruct ShellInfo 1377254721Semaste{ 1378254721Semaste ShellInfo () : 1379254721Semaste process_reaped (false), 1380254721Semaste can_delete (false), 1381254721Semaste pid (LLDB_INVALID_PROCESS_ID), 1382254721Semaste signo(-1), 1383254721Semaste status(-1) 1384254721Semaste { 1385254721Semaste } 1386254721Semaste 1387254721Semaste lldb_private::Predicate<bool> process_reaped; 1388254721Semaste lldb_private::Predicate<bool> can_delete; 1389254721Semaste lldb::pid_t pid; 1390254721Semaste int signo; 1391254721Semaste int status; 1392254721Semaste}; 1393254721Semaste 1394254721Semastestatic bool 1395254721SemasteMonitorShellCommand (void *callback_baton, 1396254721Semaste lldb::pid_t pid, 1397254721Semaste bool exited, // True if the process did exit 1398254721Semaste int signo, // Zero for no signal 1399254721Semaste int status) // Exit value of process if signal is zero 1400254721Semaste{ 1401254721Semaste ShellInfo *shell_info = (ShellInfo *)callback_baton; 1402254721Semaste shell_info->pid = pid; 1403254721Semaste shell_info->signo = signo; 1404254721Semaste shell_info->status = status; 1405254721Semaste // Let the thread running Host::RunShellCommand() know that the process 1406254721Semaste // exited and that ShellInfo has been filled in by broadcasting to it 1407254721Semaste shell_info->process_reaped.SetValue(1, eBroadcastAlways); 1408254721Semaste // Now wait for a handshake back from that thread running Host::RunShellCommand 1409254721Semaste // so we know that we can delete shell_info_ptr 1410254721Semaste shell_info->can_delete.WaitForValueEqualTo(true); 1411254721Semaste // Sleep a bit to allow the shell_info->can_delete.SetValue() to complete... 1412254721Semaste usleep(1000); 1413254721Semaste // Now delete the shell info that was passed into this function 1414254721Semaste delete shell_info; 1415254721Semaste return true; 1416254721Semaste} 1417254721Semaste 1418254721SemasteError 1419254721SemasteHost::RunShellCommand (const char *command, 1420254721Semaste const char *working_dir, 1421254721Semaste int *status_ptr, 1422254721Semaste int *signo_ptr, 1423254721Semaste std::string *command_output_ptr, 1424254721Semaste uint32_t timeout_sec, 1425254721Semaste const char *shell) 1426254721Semaste{ 1427254721Semaste Error error; 1428254721Semaste ProcessLaunchInfo launch_info; 1429254721Semaste if (shell && shell[0]) 1430254721Semaste { 1431254721Semaste // Run the command in a shell 1432254721Semaste launch_info.SetShell(shell); 1433254721Semaste launch_info.GetArguments().AppendArgument(command); 1434254721Semaste const bool localhost = true; 1435254721Semaste const bool will_debug = false; 1436254721Semaste const bool first_arg_is_full_shell_command = true; 1437254721Semaste launch_info.ConvertArgumentsForLaunchingInShell (error, 1438254721Semaste localhost, 1439254721Semaste will_debug, 1440258054Semaste first_arg_is_full_shell_command, 1441258054Semaste 0); 1442254721Semaste } 1443254721Semaste else 1444254721Semaste { 1445254721Semaste // No shell, just run it 1446254721Semaste Args args (command); 1447254721Semaste const bool first_arg_is_executable = true; 1448254721Semaste launch_info.SetArguments(args, first_arg_is_executable); 1449254721Semaste } 1450254721Semaste 1451254721Semaste if (working_dir) 1452254721Semaste launch_info.SetWorkingDirectory(working_dir); 1453254721Semaste char output_file_path_buffer[L_tmpnam]; 1454254721Semaste const char *output_file_path = NULL; 1455254721Semaste if (command_output_ptr) 1456254721Semaste { 1457254721Semaste // Create a temporary file to get the stdout/stderr and redirect the 1458254721Semaste // output of the command into this file. We will later read this file 1459254721Semaste // if all goes well and fill the data into "command_output_ptr" 1460254721Semaste output_file_path = ::tmpnam(output_file_path_buffer); 1461254721Semaste launch_info.AppendSuppressFileAction (STDIN_FILENO, true, false); 1462254721Semaste launch_info.AppendOpenFileAction(STDOUT_FILENO, output_file_path, false, true); 1463254721Semaste launch_info.AppendDuplicateFileAction(STDOUT_FILENO, STDERR_FILENO); 1464254721Semaste } 1465254721Semaste else 1466254721Semaste { 1467254721Semaste launch_info.AppendSuppressFileAction (STDIN_FILENO, true, false); 1468254721Semaste launch_info.AppendSuppressFileAction (STDOUT_FILENO, false, true); 1469254721Semaste launch_info.AppendSuppressFileAction (STDERR_FILENO, false, true); 1470254721Semaste } 1471254721Semaste 1472254721Semaste // The process monitor callback will delete the 'shell_info_ptr' below... 1473254721Semaste std::unique_ptr<ShellInfo> shell_info_ap (new ShellInfo()); 1474254721Semaste 1475254721Semaste const bool monitor_signals = false; 1476254721Semaste launch_info.SetMonitorProcessCallback(MonitorShellCommand, shell_info_ap.get(), monitor_signals); 1477254721Semaste 1478254721Semaste error = LaunchProcess (launch_info); 1479254721Semaste const lldb::pid_t pid = launch_info.GetProcessID(); 1480258054Semaste 1481258054Semaste if (error.Success() && pid == LLDB_INVALID_PROCESS_ID) 1482258054Semaste error.SetErrorString("failed to get process ID"); 1483258054Semaste 1484258054Semaste if (error.Success()) 1485254721Semaste { 1486254721Semaste // The process successfully launched, so we can defer ownership of 1487254721Semaste // "shell_info" to the MonitorShellCommand callback function that will 1488254721Semaste // get called when the process dies. We release the unique pointer as it 1489254721Semaste // doesn't need to delete the ShellInfo anymore. 1490254721Semaste ShellInfo *shell_info = shell_info_ap.release(); 1491258054Semaste TimeValue *timeout_ptr = nullptr; 1492254721Semaste TimeValue timeout_time(TimeValue::Now()); 1493258054Semaste if (timeout_sec > 0) { 1494258054Semaste timeout_time.OffsetWithSeconds(timeout_sec); 1495258054Semaste timeout_ptr = &timeout_time; 1496258054Semaste } 1497254721Semaste bool timed_out = false; 1498258054Semaste shell_info->process_reaped.WaitForValueEqualTo(true, timeout_ptr, &timed_out); 1499254721Semaste if (timed_out) 1500254721Semaste { 1501254721Semaste error.SetErrorString("timed out waiting for shell command to complete"); 1502258054Semaste 1503254721Semaste // Kill the process since it didn't complete withint the timeout specified 1504258054Semaste Kill (pid, SIGKILL); 1505254721Semaste // Wait for the monitor callback to get the message 1506254721Semaste timeout_time = TimeValue::Now(); 1507254721Semaste timeout_time.OffsetWithSeconds(1); 1508254721Semaste timed_out = false; 1509254721Semaste shell_info->process_reaped.WaitForValueEqualTo(true, &timeout_time, &timed_out); 1510254721Semaste } 1511254721Semaste else 1512254721Semaste { 1513254721Semaste if (status_ptr) 1514254721Semaste *status_ptr = shell_info->status; 1515254721Semaste 1516254721Semaste if (signo_ptr) 1517254721Semaste *signo_ptr = shell_info->signo; 1518254721Semaste 1519254721Semaste if (command_output_ptr) 1520254721Semaste { 1521254721Semaste command_output_ptr->clear(); 1522254721Semaste FileSpec file_spec(output_file_path, File::eOpenOptionRead); 1523254721Semaste uint64_t file_size = file_spec.GetByteSize(); 1524254721Semaste if (file_size > 0) 1525254721Semaste { 1526254721Semaste if (file_size > command_output_ptr->max_size()) 1527254721Semaste { 1528254721Semaste error.SetErrorStringWithFormat("shell command output is too large to fit into a std::string"); 1529254721Semaste } 1530254721Semaste else 1531254721Semaste { 1532254721Semaste command_output_ptr->resize(file_size); 1533254721Semaste file_spec.ReadFileContents(0, &((*command_output_ptr)[0]), command_output_ptr->size(), &error); 1534254721Semaste } 1535254721Semaste } 1536254721Semaste } 1537254721Semaste } 1538254721Semaste shell_info->can_delete.SetValue(true, eBroadcastAlways); 1539254721Semaste } 1540254721Semaste 1541254721Semaste if (output_file_path) 1542254721Semaste ::unlink (output_file_path); 1543254721Semaste // Handshake with the monitor thread, or just let it know in advance that 1544254721Semaste // it can delete "shell_info" in case we timed out and were not able to kill 1545254721Semaste // the process... 1546254721Semaste return error; 1547254721Semaste} 1548254721Semaste 1549258054Semaste#if defined(__linux__) or defined(__FreeBSD__) 1550258054Semaste// The functions below implement process launching via posix_spawn() for Linux 1551258054Semaste// and FreeBSD. 1552254721Semaste 1553258054Semaste// The posix_spawn() and posix_spawnp() functions first appeared in FreeBSD 8.0, 1554258054Semastestatic Error 1555258054SemasteLaunchProcessPosixSpawn (const char *exe_path, ProcessLaunchInfo &launch_info, ::pid_t &pid) 1556258054Semaste{ 1557258054Semaste Error error; 1558258054Semaste Log *log(lldb_private::GetLogIfAllCategoriesSet (LIBLLDB_LOG_HOST | LIBLLDB_LOG_PROCESS)); 1559258054Semaste 1560258054Semaste assert(exe_path); 1561258054Semaste assert(!launch_info.GetFlags().Test (eLaunchFlagDebug)); 1562258054Semaste 1563258054Semaste posix_spawnattr_t attr; 1564258054Semaste 1565258054Semaste error.SetError( ::posix_spawnattr_init (&attr), eErrorTypePOSIX); 1566258054Semaste error.LogIfError(log, "::posix_spawnattr_init ( &attr )"); 1567258054Semaste if (error.Fail()) 1568258054Semaste return error; 1569258054Semaste 1570258054Semaste // Make a quick class that will cleanup the posix spawn attributes in case 1571258054Semaste // we return in the middle of this function. 1572258054Semaste lldb_utility::CleanUp <posix_spawnattr_t *, int> posix_spawnattr_cleanup(&attr, posix_spawnattr_destroy); 1573258054Semaste 1574258054Semaste sigset_t no_signals; 1575258054Semaste sigset_t all_signals; 1576258054Semaste sigemptyset (&no_signals); 1577258054Semaste sigfillset (&all_signals); 1578258054Semaste ::posix_spawnattr_setsigmask(&attr, &all_signals); 1579258054Semaste ::posix_spawnattr_setsigdefault(&attr, &no_signals); 1580258054Semaste 1581258054Semaste short flags = POSIX_SPAWN_SETSIGDEF | POSIX_SPAWN_SETSIGMASK; 1582258054Semaste 1583258054Semaste error.SetError( ::posix_spawnattr_setflags (&attr, flags), eErrorTypePOSIX); 1584258054Semaste error.LogIfError(log, "::posix_spawnattr_setflags ( &attr, flags=0x%8.8x )", flags); 1585258054Semaste if (error.Fail()) 1586258054Semaste return error; 1587258054Semaste 1588258054Semaste const size_t num_file_actions = launch_info.GetNumFileActions (); 1589258054Semaste posix_spawn_file_actions_t file_actions, *file_action_ptr = NULL; 1590258054Semaste // Make a quick class that will cleanup the posix spawn attributes in case 1591258054Semaste // we return in the middle of this function. 1592258054Semaste lldb_utility::CleanUp <posix_spawn_file_actions_t *, int> 1593258054Semaste posix_spawn_file_actions_cleanup (file_action_ptr, NULL, posix_spawn_file_actions_destroy); 1594258054Semaste 1595258054Semaste if (num_file_actions > 0) 1596258054Semaste { 1597258054Semaste error.SetError( ::posix_spawn_file_actions_init (&file_actions), eErrorTypePOSIX); 1598258054Semaste error.LogIfError(log, "::posix_spawn_file_actions_init ( &file_actions )"); 1599258054Semaste if (error.Fail()) 1600258054Semaste return error; 1601258054Semaste 1602258054Semaste file_action_ptr = &file_actions; 1603258054Semaste posix_spawn_file_actions_cleanup.set(file_action_ptr); 1604258054Semaste 1605258054Semaste for (size_t i = 0; i < num_file_actions; ++i) 1606258054Semaste { 1607258054Semaste const ProcessLaunchInfo::FileAction *launch_file_action = launch_info.GetFileActionAtIndex(i); 1608258054Semaste if (launch_file_action && 1609258054Semaste !ProcessLaunchInfo::FileAction::AddPosixSpawnFileAction (&file_actions, 1610258054Semaste launch_file_action, 1611258054Semaste log, 1612258054Semaste error)) 1613258054Semaste return error; 1614258054Semaste } 1615258054Semaste } 1616258054Semaste 1617258054Semaste // Change working directory if neccessary. 1618258054Semaste char current_dir[PATH_MAX]; 1619258054Semaste current_dir[0] = '\0'; 1620258054Semaste 1621258054Semaste const char *working_dir = launch_info.GetWorkingDirectory(); 1622258054Semaste if (working_dir != NULL) 1623258054Semaste { 1624258054Semaste if (::getcwd(current_dir, sizeof(current_dir)) == NULL) 1625258054Semaste { 1626258054Semaste error.SetError(errno, eErrorTypePOSIX); 1627258054Semaste error.LogIfError(log, "unable to save the current directory"); 1628258054Semaste return error; 1629258054Semaste } 1630258054Semaste 1631258054Semaste if (::chdir(working_dir) == -1) 1632258054Semaste { 1633258054Semaste error.SetError(errno, eErrorTypePOSIX); 1634258054Semaste error.LogIfError(log, "unable to change working directory to %s", working_dir); 1635258054Semaste return error; 1636258054Semaste } 1637258054Semaste } 1638258054Semaste 1639258054Semaste const char *tmp_argv[2]; 1640258054Semaste char * const *argv = (char * const*)launch_info.GetArguments().GetConstArgumentVector(); 1641258054Semaste char * const *envp = (char * const*)launch_info.GetEnvironmentEntries().GetConstArgumentVector(); 1642258054Semaste 1643258054Semaste // Prepare minimal argument list if we didn't get it from the launch_info structure. 1644258054Semaste // We must pass argv into posix_spawnp and it must contain at least two items - 1645258054Semaste // pointer to an executable and NULL. 1646258054Semaste if (argv == NULL) 1647258054Semaste { 1648258054Semaste tmp_argv[0] = exe_path; 1649258054Semaste tmp_argv[1] = NULL; 1650258054Semaste argv = (char * const*)tmp_argv; 1651258054Semaste } 1652258054Semaste 1653258054Semaste error.SetError (::posix_spawnp (&pid, 1654258054Semaste exe_path, 1655258054Semaste (num_file_actions > 0) ? &file_actions : NULL, 1656258054Semaste &attr, 1657258054Semaste argv, 1658258054Semaste envp), 1659258054Semaste eErrorTypePOSIX); 1660258054Semaste 1661258054Semaste error.LogIfError(log, "::posix_spawnp ( pid => %i, path = '%s', file_actions = %p, attr = %p, argv = %p, envp = %p )", 1662258054Semaste pid, exe_path, file_action_ptr, &attr, argv, envp); 1663258054Semaste 1664258054Semaste // Change back the current directory. 1665258054Semaste // NOTE: do not override previously established error from posix_spawnp. 1666258054Semaste if (working_dir != NULL && ::chdir(current_dir) == -1 && error.Success()) 1667258054Semaste { 1668258054Semaste error.SetError(errno, eErrorTypePOSIX); 1669258054Semaste error.LogIfError(log, "unable to change current directory back to %s", 1670258054Semaste current_dir); 1671258054Semaste } 1672258054Semaste 1673258054Semaste return error; 1674258054Semaste} 1675258054Semaste 1676258054Semaste 1677258054SemasteError 1678258054SemasteHost::LaunchProcess (ProcessLaunchInfo &launch_info) 1679258054Semaste{ 1680258054Semaste Error error; 1681258054Semaste char exe_path[PATH_MAX]; 1682258054Semaste 1683258054Semaste PlatformSP host_platform_sp (Platform::GetDefaultPlatform ()); 1684258054Semaste 1685258054Semaste const ArchSpec &arch_spec = launch_info.GetArchitecture(); 1686258054Semaste 1687258054Semaste FileSpec exe_spec(launch_info.GetExecutableFile()); 1688258054Semaste 1689258054Semaste FileSpec::FileType file_type = exe_spec.GetFileType(); 1690258054Semaste if (file_type != FileSpec::eFileTypeRegular) 1691258054Semaste { 1692258054Semaste lldb::ModuleSP exe_module_sp; 1693258054Semaste error = host_platform_sp->ResolveExecutable (exe_spec, 1694258054Semaste arch_spec, 1695258054Semaste exe_module_sp, 1696258054Semaste NULL); 1697258054Semaste 1698258054Semaste if (error.Fail()) 1699258054Semaste return error; 1700258054Semaste 1701258054Semaste if (exe_module_sp) 1702258054Semaste exe_spec = exe_module_sp->GetFileSpec(); 1703258054Semaste } 1704258054Semaste 1705258054Semaste if (exe_spec.Exists()) 1706258054Semaste { 1707258054Semaste exe_spec.GetPath (exe_path, sizeof(exe_path)); 1708258054Semaste } 1709258054Semaste else 1710258054Semaste { 1711258054Semaste launch_info.GetExecutableFile().GetPath (exe_path, sizeof(exe_path)); 1712258054Semaste error.SetErrorStringWithFormat ("executable doesn't exist: '%s'", exe_path); 1713258054Semaste return error; 1714258054Semaste } 1715258054Semaste 1716258054Semaste assert(!launch_info.GetFlags().Test (eLaunchFlagLaunchInTTY)); 1717258054Semaste 1718258054Semaste ::pid_t pid = LLDB_INVALID_PROCESS_ID; 1719258054Semaste 1720258054Semaste error = LaunchProcessPosixSpawn(exe_path, launch_info, pid); 1721258054Semaste 1722258054Semaste if (pid != LLDB_INVALID_PROCESS_ID) 1723258054Semaste { 1724258054Semaste // If all went well, then set the process ID into the launch info 1725258054Semaste launch_info.SetProcessID(pid); 1726258054Semaste 1727258054Semaste // Make sure we reap any processes we spawn or we will have zombies. 1728258054Semaste if (!launch_info.MonitorProcess()) 1729258054Semaste { 1730258054Semaste const bool monitor_signals = false; 1731258054Semaste StartMonitoringChildProcess (Process::SetProcessExitStatus, 1732258054Semaste NULL, 1733258054Semaste pid, 1734258054Semaste monitor_signals); 1735258054Semaste } 1736258054Semaste } 1737258054Semaste else 1738258054Semaste { 1739258054Semaste // Invalid process ID, something didn't go well 1740258054Semaste if (error.Success()) 1741258054Semaste error.SetErrorString ("process launch failed for unknown reasons"); 1742258054Semaste } 1743258054Semaste return error; 1744258054Semaste} 1745258054Semaste 1746258054Semaste#endif // defined(__linux__) or defined(__FreeBSD__) 1747258054Semaste 1748258054Semaste#ifndef _WIN32 1749258054Semaste 1750258054Semastesize_t 1751258054SemasteHost::GetPageSize() 1752258054Semaste{ 1753258054Semaste return ::getpagesize(); 1754258054Semaste} 1755258054Semaste 1756254721Semasteuint32_t 1757254721SemasteHost::GetNumberCPUS () 1758254721Semaste{ 1759254721Semaste static uint32_t g_num_cores = UINT32_MAX; 1760254721Semaste if (g_num_cores == UINT32_MAX) 1761254721Semaste { 1762254721Semaste#if defined(__APPLE__) or defined (__linux__) or defined (__FreeBSD__) or defined (__FreeBSD_kernel__) 1763254721Semaste 1764254721Semaste g_num_cores = ::sysconf(_SC_NPROCESSORS_ONLN); 1765258054Semaste 1766254721Semaste#else 1767254721Semaste 1768254721Semaste // Assume POSIX support if a host specific case has not been supplied above 1769254721Semaste g_num_cores = 0; 1770254721Semaste int num_cores = 0; 1771254721Semaste size_t num_cores_len = sizeof(num_cores); 1772254721Semaste#ifdef HW_AVAILCPU 1773254721Semaste int mib[] = { CTL_HW, HW_AVAILCPU }; 1774254721Semaste#else 1775254721Semaste int mib[] = { CTL_HW, HW_NCPU }; 1776254721Semaste#endif 1777254721Semaste 1778254721Semaste /* get the number of CPUs from the system */ 1779254721Semaste if (sysctl(mib, sizeof(mib)/sizeof(int), &num_cores, &num_cores_len, NULL, 0) == 0 && (num_cores > 0)) 1780254721Semaste { 1781254721Semaste g_num_cores = num_cores; 1782254721Semaste } 1783254721Semaste else 1784254721Semaste { 1785254721Semaste mib[1] = HW_NCPU; 1786254721Semaste num_cores_len = sizeof(num_cores); 1787254721Semaste if (sysctl(mib, sizeof(mib)/sizeof(int), &num_cores, &num_cores_len, NULL, 0) == 0 && (num_cores > 0)) 1788254721Semaste { 1789254721Semaste if (num_cores > 0) 1790254721Semaste g_num_cores = num_cores; 1791254721Semaste } 1792254721Semaste } 1793254721Semaste#endif 1794254721Semaste } 1795254721Semaste return g_num_cores; 1796254721Semaste} 1797254721Semaste 1798258054Semastevoid 1799258054SemasteHost::Kill(lldb::pid_t pid, int signo) 1800258054Semaste{ 1801258054Semaste ::kill(pid, signo); 1802258054Semaste} 1803254721Semaste 1804258054Semaste#endif 1805254721Semaste 1806254721Semaste#if !defined (__APPLE__) 1807254721Semastebool 1808254721SemasteHost::OpenFileInExternalEditor (const FileSpec &file_spec, uint32_t line_no) 1809254721Semaste{ 1810254721Semaste return false; 1811254721Semaste} 1812254721Semaste 1813254721Semastevoid 1814254721SemasteHost::SetCrashDescriptionWithFormat (const char *format, ...) 1815254721Semaste{ 1816254721Semaste} 1817254721Semaste 1818254721Semastevoid 1819254721SemasteHost::SetCrashDescription (const char *description) 1820254721Semaste{ 1821254721Semaste} 1822254721Semaste 1823254721Semastelldb::pid_t 1824258054SemasteHost::LaunchApplication (const FileSpec &app_file_spec) 1825254721Semaste{ 1826254721Semaste return LLDB_INVALID_PROCESS_ID; 1827254721Semaste} 1828254721Semaste 1829258054Semasteuint32_t 1830258054SemasteHost::MakeDirectory (const char* path, mode_t mode) 1831258054Semaste{ 1832258054Semaste return UINT32_MAX; 1833258054Semaste} 1834254721Semaste#endif 1835258054Semaste 1836258054Semastetypedef std::map<lldb::user_id_t, lldb::FileSP> FDToFileMap; 1837258054SemasteFDToFileMap& GetFDToFileMap() 1838258054Semaste{ 1839258054Semaste static FDToFileMap g_fd2filemap; 1840258054Semaste return g_fd2filemap; 1841258054Semaste} 1842258054Semaste 1843258054Semastelldb::user_id_t 1844258054SemasteHost::OpenFile (const FileSpec& file_spec, 1845258054Semaste uint32_t flags, 1846258054Semaste mode_t mode, 1847258054Semaste Error &error) 1848258054Semaste{ 1849258054Semaste std::string path (file_spec.GetPath()); 1850258054Semaste if (path.empty()) 1851258054Semaste { 1852258054Semaste error.SetErrorString("empty path"); 1853258054Semaste return UINT64_MAX; 1854258054Semaste } 1855258054Semaste FileSP file_sp(new File()); 1856258054Semaste error = file_sp->Open(path.c_str(),flags,mode); 1857258054Semaste if (file_sp->IsValid() == false) 1858258054Semaste return UINT64_MAX; 1859258054Semaste lldb::user_id_t fd = file_sp->GetDescriptor(); 1860258054Semaste GetFDToFileMap()[fd] = file_sp; 1861258054Semaste return fd; 1862258054Semaste} 1863258054Semaste 1864258054Semastebool 1865258054SemasteHost::CloseFile (lldb::user_id_t fd, Error &error) 1866258054Semaste{ 1867258054Semaste if (fd == UINT64_MAX) 1868258054Semaste { 1869258054Semaste error.SetErrorString ("invalid file descriptor"); 1870258054Semaste return false; 1871258054Semaste } 1872258054Semaste FDToFileMap& file_map = GetFDToFileMap(); 1873258054Semaste FDToFileMap::iterator pos = file_map.find(fd); 1874258054Semaste if (pos == file_map.end()) 1875258054Semaste { 1876258054Semaste error.SetErrorStringWithFormat ("invalid host file descriptor %" PRIu64, fd); 1877258054Semaste return false; 1878258054Semaste } 1879258054Semaste FileSP file_sp = pos->second; 1880258054Semaste if (!file_sp) 1881258054Semaste { 1882258054Semaste error.SetErrorString ("invalid host backing file"); 1883258054Semaste return false; 1884258054Semaste } 1885258054Semaste error = file_sp->Close(); 1886258054Semaste file_map.erase(pos); 1887258054Semaste return error.Success(); 1888258054Semaste} 1889258054Semaste 1890258054Semasteuint64_t 1891258054SemasteHost::WriteFile (lldb::user_id_t fd, uint64_t offset, const void* src, uint64_t src_len, Error &error) 1892258054Semaste{ 1893258054Semaste if (fd == UINT64_MAX) 1894258054Semaste { 1895258054Semaste error.SetErrorString ("invalid file descriptor"); 1896258054Semaste return UINT64_MAX; 1897258054Semaste } 1898258054Semaste FDToFileMap& file_map = GetFDToFileMap(); 1899258054Semaste FDToFileMap::iterator pos = file_map.find(fd); 1900258054Semaste if (pos == file_map.end()) 1901258054Semaste { 1902258054Semaste error.SetErrorStringWithFormat("invalid host file descriptor %" PRIu64 , fd); 1903258054Semaste return false; 1904258054Semaste } 1905258054Semaste FileSP file_sp = pos->second; 1906258054Semaste if (!file_sp) 1907258054Semaste { 1908258054Semaste error.SetErrorString ("invalid host backing file"); 1909258054Semaste return UINT64_MAX; 1910258054Semaste } 1911258054Semaste if (file_sp->SeekFromStart(offset, &error) != offset || error.Fail()) 1912258054Semaste return UINT64_MAX; 1913258054Semaste size_t bytes_written = src_len; 1914258054Semaste error = file_sp->Write(src, bytes_written); 1915258054Semaste if (error.Fail()) 1916258054Semaste return UINT64_MAX; 1917258054Semaste return bytes_written; 1918258054Semaste} 1919258054Semaste 1920258054Semasteuint64_t 1921258054SemasteHost::ReadFile (lldb::user_id_t fd, uint64_t offset, void* dst, uint64_t dst_len, Error &error) 1922258054Semaste{ 1923258054Semaste if (fd == UINT64_MAX) 1924258054Semaste { 1925258054Semaste error.SetErrorString ("invalid file descriptor"); 1926258054Semaste return UINT64_MAX; 1927258054Semaste } 1928258054Semaste FDToFileMap& file_map = GetFDToFileMap(); 1929258054Semaste FDToFileMap::iterator pos = file_map.find(fd); 1930258054Semaste if (pos == file_map.end()) 1931258054Semaste { 1932258054Semaste error.SetErrorStringWithFormat ("invalid host file descriptor %" PRIu64, fd); 1933258054Semaste return false; 1934258054Semaste } 1935258054Semaste FileSP file_sp = pos->second; 1936258054Semaste if (!file_sp) 1937258054Semaste { 1938258054Semaste error.SetErrorString ("invalid host backing file"); 1939258054Semaste return UINT64_MAX; 1940258054Semaste } 1941258054Semaste if (file_sp->SeekFromStart(offset, &error) != offset || error.Fail()) 1942258054Semaste return UINT64_MAX; 1943258054Semaste size_t bytes_read = dst_len; 1944258054Semaste error = file_sp->Read(dst ,bytes_read); 1945258054Semaste if (error.Fail()) 1946258054Semaste return UINT64_MAX; 1947258054Semaste return bytes_read; 1948258054Semaste} 1949258054Semaste 1950258054Semastelldb::user_id_t 1951258054SemasteHost::GetFileSize (const FileSpec& file_spec) 1952258054Semaste{ 1953258054Semaste return file_spec.GetByteSize(); 1954258054Semaste} 1955258054Semaste 1956258054Semastebool 1957258054SemasteHost::GetFileExists (const FileSpec& file_spec) 1958258054Semaste{ 1959258054Semaste return file_spec.Exists(); 1960258054Semaste} 1961258054Semaste 1962258054Semastebool 1963258054SemasteHost::CalculateMD5 (const FileSpec& file_spec, 1964258054Semaste uint64_t &low, 1965258054Semaste uint64_t &high) 1966258054Semaste{ 1967258054Semaste#if defined (__APPLE__) 1968258054Semaste StreamString md5_cmd_line; 1969258054Semaste md5_cmd_line.Printf("md5 -q '%s'", file_spec.GetPath().c_str()); 1970258054Semaste std::string hash_string; 1971258054Semaste Error err = Host::RunShellCommand(md5_cmd_line.GetData(), NULL, NULL, NULL, &hash_string, 60); 1972258054Semaste if (err.Fail()) 1973258054Semaste return false; 1974258054Semaste // a correctly formed MD5 is 16-bytes, that is 32 hex digits 1975258054Semaste // if the output is any other length it is probably wrong 1976258054Semaste if (hash_string.size() != 32) 1977258054Semaste return false; 1978258054Semaste std::string part1(hash_string,0,16); 1979258054Semaste std::string part2(hash_string,16); 1980258054Semaste const char* part1_cstr = part1.c_str(); 1981258054Semaste const char* part2_cstr = part2.c_str(); 1982258054Semaste high = ::strtoull(part1_cstr, NULL, 16); 1983258054Semaste low = ::strtoull(part2_cstr, NULL, 16); 1984258054Semaste return true; 1985258054Semaste#else 1986258054Semaste // your own MD5 implementation here 1987258054Semaste return false; 1988258054Semaste#endif 1989258054Semaste} 1990