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 13254721Semaste#include <dlfcn.h> 14254721Semaste#include <errno.h> 15254721Semaste#include <grp.h> 16254721Semaste#include <limits.h> 17254721Semaste#include <netdb.h> 18254721Semaste#include <pwd.h> 19254721Semaste#include <sys/types.h> 20254721Semaste#include <sys/sysctl.h> 21254721Semaste#include <unistd.h> 22254721Semaste 23254721Semaste#if defined (__APPLE__) 24254721Semaste 25254721Semaste#include <dispatch/dispatch.h> 26254721Semaste#include <libproc.h> 27254721Semaste#include <mach-o/dyld.h> 28254721Semaste#include <mach/mach_port.h> 29254721Semaste 30254721Semaste#endif 31254721Semaste 32254721Semaste#if defined (__linux__) || defined (__FreeBSD__) || defined (__FreeBSD_kernel__) 33254721Semaste#include <sys/wait.h> 34254721Semaste#include <sys/syscall.h> 35254721Semaste#endif 36254721Semaste 37254721Semaste#if defined (__FreeBSD__) 38254721Semaste#include <pthread_np.h> 39254721Semaste#endif 40254721Semaste 41254721Semaste#include "lldb/Host/Host.h" 42254721Semaste#include "lldb/Core/ArchSpec.h" 43254721Semaste#include "lldb/Core/ConstString.h" 44254721Semaste#include "lldb/Core/Debugger.h" 45254721Semaste#include "lldb/Core/Error.h" 46254721Semaste#include "lldb/Core/Log.h" 47254721Semaste#include "lldb/Core/StreamString.h" 48254721Semaste#include "lldb/Core/ThreadSafeSTLMap.h" 49254721Semaste#include "lldb/Host/Config.h" 50254721Semaste#include "lldb/Host/Endian.h" 51254721Semaste#include "lldb/Host/FileSpec.h" 52254721Semaste#include "lldb/Host/Mutex.h" 53254721Semaste#include "lldb/Target/Process.h" 54254721Semaste#include "lldb/Target/TargetList.h" 55254721Semaste 56254721Semaste#include "llvm/ADT/SmallString.h" 57254721Semaste#include "llvm/Support/Host.h" 58254721Semaste#include "llvm/Support/MachO.h" 59254721Semaste#include "llvm/Support/raw_ostream.h" 60254721Semaste 61254721Semaste 62254721Semaste 63254721Semaste 64254721Semaste 65254721Semasteusing namespace lldb; 66254721Semasteusing namespace lldb_private; 67254721Semaste 68254721Semaste 69254721Semaste#if !defined (__APPLE__) 70254721Semastestruct MonitorInfo 71254721Semaste{ 72254721Semaste lldb::pid_t pid; // The process ID to monitor 73254721Semaste Host::MonitorChildProcessCallback callback; // The callback function to call when "pid" exits or signals 74254721Semaste void *callback_baton; // The callback baton for the callback function 75254721Semaste bool monitor_signals; // If true, call the callback when "pid" gets signaled. 76254721Semaste}; 77254721Semaste 78254721Semastestatic void * 79254721SemasteMonitorChildProcessThreadFunction (void *arg); 80254721Semaste 81254721Semastelldb::thread_t 82254721SemasteHost::StartMonitoringChildProcess 83254721Semaste( 84254721Semaste Host::MonitorChildProcessCallback callback, 85254721Semaste void *callback_baton, 86254721Semaste lldb::pid_t pid, 87254721Semaste bool monitor_signals 88254721Semaste) 89254721Semaste{ 90254721Semaste lldb::thread_t thread = LLDB_INVALID_HOST_THREAD; 91254721Semaste MonitorInfo * info_ptr = new MonitorInfo(); 92254721Semaste 93254721Semaste info_ptr->pid = pid; 94254721Semaste info_ptr->callback = callback; 95254721Semaste info_ptr->callback_baton = callback_baton; 96254721Semaste info_ptr->monitor_signals = monitor_signals; 97254721Semaste 98254721Semaste char thread_name[256]; 99254721Semaste ::snprintf (thread_name, sizeof(thread_name), "<lldb.host.wait4(pid=%" PRIu64 ")>", pid); 100254721Semaste thread = ThreadCreate (thread_name, 101254721Semaste MonitorChildProcessThreadFunction, 102254721Semaste info_ptr, 103254721Semaste NULL); 104254721Semaste 105254721Semaste return thread; 106254721Semaste} 107254721Semaste 108254721Semaste//------------------------------------------------------------------ 109254721Semaste// Scoped class that will disable thread canceling when it is 110254721Semaste// constructed, and exception safely restore the previous value it 111254721Semaste// when it goes out of scope. 112254721Semaste//------------------------------------------------------------------ 113254721Semasteclass ScopedPThreadCancelDisabler 114254721Semaste{ 115254721Semastepublic: 116254721Semaste ScopedPThreadCancelDisabler() 117254721Semaste { 118254721Semaste // Disable the ability for this thread to be cancelled 119254721Semaste int err = ::pthread_setcancelstate (PTHREAD_CANCEL_DISABLE, &m_old_state); 120254721Semaste if (err != 0) 121254721Semaste m_old_state = -1; 122254721Semaste 123254721Semaste } 124254721Semaste 125254721Semaste ~ScopedPThreadCancelDisabler() 126254721Semaste { 127254721Semaste // Restore the ability for this thread to be cancelled to what it 128254721Semaste // previously was. 129254721Semaste if (m_old_state != -1) 130254721Semaste ::pthread_setcancelstate (m_old_state, 0); 131254721Semaste } 132254721Semasteprivate: 133254721Semaste int m_old_state; // Save the old cancelability state. 134254721Semaste}; 135254721Semaste 136254721Semastestatic void * 137254721SemasteMonitorChildProcessThreadFunction (void *arg) 138254721Semaste{ 139254721Semaste Log *log(lldb_private::GetLogIfAllCategoriesSet (LIBLLDB_LOG_PROCESS)); 140254721Semaste const char *function = __FUNCTION__; 141254721Semaste if (log) 142254721Semaste log->Printf ("%s (arg = %p) thread starting...", function, arg); 143254721Semaste 144254721Semaste MonitorInfo *info = (MonitorInfo *)arg; 145254721Semaste 146254721Semaste const Host::MonitorChildProcessCallback callback = info->callback; 147254721Semaste void * const callback_baton = info->callback_baton; 148254721Semaste const lldb::pid_t pid = info->pid; 149254721Semaste const bool monitor_signals = info->monitor_signals; 150254721Semaste 151254721Semaste delete info; 152254721Semaste 153254721Semaste int status = -1; 154254721Semaste#if defined (__FreeBSD__) || defined (__FreeBSD_kernel__) 155254721Semaste #define __WALL 0 156254721Semaste#endif 157254721Semaste const int options = __WALL; 158254721Semaste 159254721Semaste while (1) 160254721Semaste { 161254721Semaste log = lldb_private::GetLogIfAllCategoriesSet (LIBLLDB_LOG_PROCESS); 162254721Semaste if (log) 163254721Semaste log->Printf("%s ::wait_pid (pid = %" PRIu64 ", &status, options = %i)...", function, pid, options); 164254721Semaste 165254721Semaste // Wait for all child processes 166254721Semaste ::pthread_testcancel (); 167254721Semaste // Get signals from all children with same process group of pid 168254721Semaste const lldb::pid_t wait_pid = ::waitpid (-1*pid, &status, options); 169254721Semaste ::pthread_testcancel (); 170254721Semaste 171254721Semaste if (wait_pid == -1) 172254721Semaste { 173254721Semaste if (errno == EINTR) 174254721Semaste continue; 175254721Semaste else 176254721Semaste { 177254721Semaste if (log) 178254721Semaste log->Printf ("%s (arg = %p) thread exiting because waitpid failed (%s)...", __FUNCTION__, arg, strerror(errno)); 179254721Semaste break; 180254721Semaste } 181254721Semaste } 182254721Semaste else if (wait_pid > 0) 183254721Semaste { 184254721Semaste bool exited = false; 185254721Semaste int signal = 0; 186254721Semaste int exit_status = 0; 187254721Semaste const char *status_cstr = NULL; 188254721Semaste if (WIFSTOPPED(status)) 189254721Semaste { 190254721Semaste signal = WSTOPSIG(status); 191254721Semaste status_cstr = "STOPPED"; 192254721Semaste } 193254721Semaste else if (WIFEXITED(status)) 194254721Semaste { 195254721Semaste exit_status = WEXITSTATUS(status); 196254721Semaste status_cstr = "EXITED"; 197254721Semaste exited = true; 198254721Semaste } 199254721Semaste else if (WIFSIGNALED(status)) 200254721Semaste { 201254721Semaste signal = WTERMSIG(status); 202254721Semaste status_cstr = "SIGNALED"; 203254721Semaste if (wait_pid == pid) { 204254721Semaste exited = true; 205254721Semaste exit_status = -1; 206254721Semaste } 207254721Semaste } 208254721Semaste else 209254721Semaste { 210254721Semaste status_cstr = "(\?\?\?)"; 211254721Semaste } 212254721Semaste 213254721Semaste // Scope for pthread_cancel_disabler 214254721Semaste { 215254721Semaste ScopedPThreadCancelDisabler pthread_cancel_disabler; 216254721Semaste 217254721Semaste log = lldb_private::GetLogIfAllCategoriesSet (LIBLLDB_LOG_PROCESS); 218254721Semaste if (log) 219254721Semaste log->Printf ("%s ::waitpid (pid = %" PRIu64 ", &status, options = %i) => pid = %" PRIu64 ", status = 0x%8.8x (%s), signal = %i, exit_state = %i", 220254721Semaste function, 221254721Semaste wait_pid, 222254721Semaste options, 223254721Semaste pid, 224254721Semaste status, 225254721Semaste status_cstr, 226254721Semaste signal, 227254721Semaste exit_status); 228254721Semaste 229254721Semaste if (exited || (signal != 0 && monitor_signals)) 230254721Semaste { 231254721Semaste bool callback_return = false; 232254721Semaste if (callback) 233254721Semaste callback_return = callback (callback_baton, wait_pid, exited, signal, exit_status); 234254721Semaste 235254721Semaste // If our process exited, then this thread should exit 236254721Semaste if (exited && wait_pid == pid) 237254721Semaste { 238254721Semaste if (log) 239254721Semaste log->Printf ("%s (arg = %p) thread exiting because pid received exit signal...", __FUNCTION__, arg); 240254721Semaste break; 241254721Semaste } 242254721Semaste // If the callback returns true, it means this process should 243254721Semaste // exit 244254721Semaste if (callback_return) 245254721Semaste { 246254721Semaste if (log) 247254721Semaste log->Printf ("%s (arg = %p) thread exiting because callback returned true...", __FUNCTION__, arg); 248254721Semaste break; 249254721Semaste } 250254721Semaste } 251254721Semaste } 252254721Semaste } 253254721Semaste } 254254721Semaste 255254721Semaste log = lldb_private::GetLogIfAllCategoriesSet (LIBLLDB_LOG_PROCESS); 256254721Semaste if (log) 257254721Semaste log->Printf ("%s (arg = %p) thread exiting...", __FUNCTION__, arg); 258254721Semaste 259254721Semaste return NULL; 260254721Semaste} 261254721Semaste 262254721Semaste 263254721Semastevoid 264254721SemasteHost::SystemLog (SystemLogType type, const char *format, va_list args) 265254721Semaste{ 266254721Semaste vfprintf (stderr, format, args); 267254721Semaste} 268254721Semaste 269254721Semaste#endif // #if !defined (__APPLE__) 270254721Semaste 271254721Semastevoid 272254721SemasteHost::SystemLog (SystemLogType type, const char *format, ...) 273254721Semaste{ 274254721Semaste va_list args; 275254721Semaste va_start (args, format); 276254721Semaste SystemLog (type, format, args); 277254721Semaste va_end (args); 278254721Semaste} 279254721Semaste 280254721Semastesize_t 281254721SemasteHost::GetPageSize() 282254721Semaste{ 283254721Semaste return ::getpagesize(); 284254721Semaste} 285254721Semaste 286254721Semasteconst ArchSpec & 287254721SemasteHost::GetArchitecture (SystemDefaultArchitecture arch_kind) 288254721Semaste{ 289254721Semaste static bool g_supports_32 = false; 290254721Semaste static bool g_supports_64 = false; 291254721Semaste static ArchSpec g_host_arch_32; 292254721Semaste static ArchSpec g_host_arch_64; 293254721Semaste 294254721Semaste#if defined (__APPLE__) 295254721Semaste 296254721Semaste // Apple is different in that it can support both 32 and 64 bit executables 297254721Semaste // in the same operating system running concurrently. Here we detect the 298254721Semaste // correct host architectures for both 32 and 64 bit including if 64 bit 299254721Semaste // executables are supported on the system. 300254721Semaste 301254721Semaste if (g_supports_32 == false && g_supports_64 == false) 302254721Semaste { 303254721Semaste // All apple systems support 32 bit execution. 304254721Semaste g_supports_32 = true; 305254721Semaste uint32_t cputype, cpusubtype; 306254721Semaste uint32_t is_64_bit_capable = false; 307254721Semaste size_t len = sizeof(cputype); 308254721Semaste ArchSpec host_arch; 309254721Semaste // These will tell us about the kernel architecture, which even on a 64 310254721Semaste // bit machine can be 32 bit... 311254721Semaste if (::sysctlbyname("hw.cputype", &cputype, &len, NULL, 0) == 0) 312254721Semaste { 313254721Semaste len = sizeof (cpusubtype); 314254721Semaste if (::sysctlbyname("hw.cpusubtype", &cpusubtype, &len, NULL, 0) != 0) 315254721Semaste cpusubtype = CPU_TYPE_ANY; 316254721Semaste 317254721Semaste len = sizeof (is_64_bit_capable); 318254721Semaste if (::sysctlbyname("hw.cpu64bit_capable", &is_64_bit_capable, &len, NULL, 0) == 0) 319254721Semaste { 320254721Semaste if (is_64_bit_capable) 321254721Semaste g_supports_64 = true; 322254721Semaste } 323254721Semaste 324254721Semaste if (is_64_bit_capable) 325254721Semaste { 326254721Semaste#if defined (__i386__) || defined (__x86_64__) 327254721Semaste if (cpusubtype == CPU_SUBTYPE_486) 328254721Semaste cpusubtype = CPU_SUBTYPE_I386_ALL; 329254721Semaste#endif 330254721Semaste if (cputype & CPU_ARCH_ABI64) 331254721Semaste { 332254721Semaste // We have a 64 bit kernel on a 64 bit system 333254721Semaste g_host_arch_32.SetArchitecture (eArchTypeMachO, ~(CPU_ARCH_MASK) & cputype, cpusubtype); 334254721Semaste g_host_arch_64.SetArchitecture (eArchTypeMachO, cputype, cpusubtype); 335254721Semaste } 336254721Semaste else 337254721Semaste { 338254721Semaste // We have a 32 bit kernel on a 64 bit system 339254721Semaste g_host_arch_32.SetArchitecture (eArchTypeMachO, cputype, cpusubtype); 340254721Semaste cputype |= CPU_ARCH_ABI64; 341254721Semaste g_host_arch_64.SetArchitecture (eArchTypeMachO, cputype, cpusubtype); 342254721Semaste } 343254721Semaste } 344254721Semaste else 345254721Semaste { 346254721Semaste g_host_arch_32.SetArchitecture (eArchTypeMachO, cputype, cpusubtype); 347254721Semaste g_host_arch_64.Clear(); 348254721Semaste } 349254721Semaste } 350254721Semaste } 351254721Semaste 352254721Semaste#else // #if defined (__APPLE__) 353254721Semaste 354254721Semaste if (g_supports_32 == false && g_supports_64 == false) 355254721Semaste { 356254721Semaste llvm::Triple triple(llvm::sys::getDefaultTargetTriple()); 357254721Semaste 358254721Semaste g_host_arch_32.Clear(); 359254721Semaste g_host_arch_64.Clear(); 360254721Semaste 361254721Semaste // If the OS is Linux, "unknown" in the vendor slot isn't what we want 362254721Semaste // for the default triple. It's probably an artifact of config.guess. 363254721Semaste if (triple.getOS() == llvm::Triple::Linux && triple.getVendor() == llvm::Triple::UnknownVendor) 364254721Semaste triple.setVendorName(""); 365254721Semaste 366254721Semaste switch (triple.getArch()) 367254721Semaste { 368254721Semaste default: 369254721Semaste g_host_arch_32.SetTriple(triple); 370254721Semaste g_supports_32 = true; 371254721Semaste break; 372254721Semaste 373254721Semaste case llvm::Triple::x86_64: 374254721Semaste g_host_arch_64.SetTriple(triple); 375254721Semaste g_supports_64 = true; 376254721Semaste g_host_arch_32.SetTriple(triple.get32BitArchVariant()); 377254721Semaste g_supports_32 = true; 378254721Semaste break; 379254721Semaste 380254721Semaste case llvm::Triple::sparcv9: 381254721Semaste case llvm::Triple::ppc64: 382254721Semaste g_host_arch_64.SetTriple(triple); 383254721Semaste g_supports_64 = true; 384254721Semaste break; 385254721Semaste } 386254721Semaste 387254721Semaste g_supports_32 = g_host_arch_32.IsValid(); 388254721Semaste g_supports_64 = g_host_arch_64.IsValid(); 389254721Semaste } 390254721Semaste 391254721Semaste#endif // #else for #if defined (__APPLE__) 392254721Semaste 393254721Semaste if (arch_kind == eSystemDefaultArchitecture32) 394254721Semaste return g_host_arch_32; 395254721Semaste else if (arch_kind == eSystemDefaultArchitecture64) 396254721Semaste return g_host_arch_64; 397254721Semaste 398254721Semaste if (g_supports_64) 399254721Semaste return g_host_arch_64; 400254721Semaste 401254721Semaste return g_host_arch_32; 402254721Semaste} 403254721Semaste 404254721Semasteconst ConstString & 405254721SemasteHost::GetVendorString() 406254721Semaste{ 407254721Semaste static ConstString g_vendor; 408254721Semaste if (!g_vendor) 409254721Semaste { 410254721Semaste const ArchSpec &host_arch = GetArchitecture (eSystemDefaultArchitecture); 411254721Semaste const llvm::StringRef &str_ref = host_arch.GetTriple().getVendorName(); 412254721Semaste g_vendor.SetCStringWithLength(str_ref.data(), str_ref.size()); 413254721Semaste } 414254721Semaste return g_vendor; 415254721Semaste} 416254721Semaste 417254721Semasteconst ConstString & 418254721SemasteHost::GetOSString() 419254721Semaste{ 420254721Semaste static ConstString g_os_string; 421254721Semaste if (!g_os_string) 422254721Semaste { 423254721Semaste const ArchSpec &host_arch = GetArchitecture (eSystemDefaultArchitecture); 424254721Semaste const llvm::StringRef &str_ref = host_arch.GetTriple().getOSName(); 425254721Semaste g_os_string.SetCStringWithLength(str_ref.data(), str_ref.size()); 426254721Semaste } 427254721Semaste return g_os_string; 428254721Semaste} 429254721Semaste 430254721Semasteconst ConstString & 431254721SemasteHost::GetTargetTriple() 432254721Semaste{ 433254721Semaste static ConstString g_host_triple; 434254721Semaste if (!(g_host_triple)) 435254721Semaste { 436254721Semaste const ArchSpec &host_arch = GetArchitecture (eSystemDefaultArchitecture); 437254721Semaste g_host_triple.SetCString(host_arch.GetTriple().getTriple().c_str()); 438254721Semaste } 439254721Semaste return g_host_triple; 440254721Semaste} 441254721Semaste 442254721Semastelldb::pid_t 443254721SemasteHost::GetCurrentProcessID() 444254721Semaste{ 445254721Semaste return ::getpid(); 446254721Semaste} 447254721Semaste 448254721Semastelldb::tid_t 449254721SemasteHost::GetCurrentThreadID() 450254721Semaste{ 451254721Semaste#if defined (__APPLE__) 452254721Semaste // Calling "mach_port_deallocate()" bumps the reference count on the thread 453254721Semaste // port, so we need to deallocate it. mach_task_self() doesn't bump the ref 454254721Semaste // count. 455254721Semaste thread_port_t thread_self = mach_thread_self(); 456254721Semaste mach_port_deallocate(mach_task_self(), thread_self); 457254721Semaste return thread_self; 458254721Semaste#elif defined(__FreeBSD__) 459254721Semaste return lldb::tid_t(pthread_getthreadid_np()); 460254721Semaste#elif defined(__linux__) 461254721Semaste return lldb::tid_t(syscall(SYS_gettid)); 462254721Semaste#else 463254721Semaste return lldb::tid_t(pthread_self()); 464254721Semaste#endif 465254721Semaste} 466254721Semaste 467254721Semastelldb::thread_t 468254721SemasteHost::GetCurrentThread () 469254721Semaste{ 470254721Semaste return lldb::thread_t(pthread_self()); 471254721Semaste} 472254721Semaste 473254721Semasteconst char * 474254721SemasteHost::GetSignalAsCString (int signo) 475254721Semaste{ 476254721Semaste switch (signo) 477254721Semaste { 478254721Semaste case SIGHUP: return "SIGHUP"; // 1 hangup 479254721Semaste case SIGINT: return "SIGINT"; // 2 interrupt 480254721Semaste case SIGQUIT: return "SIGQUIT"; // 3 quit 481254721Semaste case SIGILL: return "SIGILL"; // 4 illegal instruction (not reset when caught) 482254721Semaste case SIGTRAP: return "SIGTRAP"; // 5 trace trap (not reset when caught) 483254721Semaste case SIGABRT: return "SIGABRT"; // 6 abort() 484254721Semaste#if (defined(_POSIX_C_SOURCE) && !defined(_DARWIN_C_SOURCE)) 485254721Semaste case SIGPOLL: return "SIGPOLL"; // 7 pollable event ([XSR] generated, not supported) 486254721Semaste#endif 487254721Semaste#if !defined(_POSIX_C_SOURCE) 488254721Semaste case SIGEMT: return "SIGEMT"; // 7 EMT instruction 489254721Semaste#endif 490254721Semaste case SIGFPE: return "SIGFPE"; // 8 floating point exception 491254721Semaste case SIGKILL: return "SIGKILL"; // 9 kill (cannot be caught or ignored) 492254721Semaste case SIGBUS: return "SIGBUS"; // 10 bus error 493254721Semaste case SIGSEGV: return "SIGSEGV"; // 11 segmentation violation 494254721Semaste case SIGSYS: return "SIGSYS"; // 12 bad argument to system call 495254721Semaste case SIGPIPE: return "SIGPIPE"; // 13 write on a pipe with no one to read it 496254721Semaste case SIGALRM: return "SIGALRM"; // 14 alarm clock 497254721Semaste case SIGTERM: return "SIGTERM"; // 15 software termination signal from kill 498254721Semaste case SIGURG: return "SIGURG"; // 16 urgent condition on IO channel 499254721Semaste case SIGSTOP: return "SIGSTOP"; // 17 sendable stop signal not from tty 500254721Semaste case SIGTSTP: return "SIGTSTP"; // 18 stop signal from tty 501254721Semaste case SIGCONT: return "SIGCONT"; // 19 continue a stopped process 502254721Semaste case SIGCHLD: return "SIGCHLD"; // 20 to parent on child stop or exit 503254721Semaste case SIGTTIN: return "SIGTTIN"; // 21 to readers pgrp upon background tty read 504254721Semaste case SIGTTOU: return "SIGTTOU"; // 22 like TTIN for output if (tp->t_local<OSTOP) 505254721Semaste#if !defined(_POSIX_C_SOURCE) 506254721Semaste case SIGIO: return "SIGIO"; // 23 input/output possible signal 507254721Semaste#endif 508254721Semaste case SIGXCPU: return "SIGXCPU"; // 24 exceeded CPU time limit 509254721Semaste case SIGXFSZ: return "SIGXFSZ"; // 25 exceeded file size limit 510254721Semaste case SIGVTALRM: return "SIGVTALRM"; // 26 virtual time alarm 511254721Semaste case SIGPROF: return "SIGPROF"; // 27 profiling time alarm 512254721Semaste#if !defined(_POSIX_C_SOURCE) 513254721Semaste case SIGWINCH: return "SIGWINCH"; // 28 window size changes 514254721Semaste case SIGINFO: return "SIGINFO"; // 29 information request 515254721Semaste#endif 516254721Semaste case SIGUSR1: return "SIGUSR1"; // 30 user defined signal 1 517254721Semaste case SIGUSR2: return "SIGUSR2"; // 31 user defined signal 2 518254721Semaste default: 519254721Semaste break; 520254721Semaste } 521254721Semaste return NULL; 522254721Semaste} 523254721Semaste 524254721Semastevoid 525254721SemasteHost::WillTerminate () 526254721Semaste{ 527254721Semaste} 528254721Semaste 529254721Semaste#if !defined (__APPLE__) && !defined (__FreeBSD__) && !defined (__FreeBSD_kernel__) && !defined (__linux__) // see macosx/Host.mm 530254721Semaste 531254721Semastevoid 532254721SemasteHost::ThreadCreated (const char *thread_name) 533254721Semaste{ 534254721Semaste} 535254721Semaste 536254721Semastevoid 537254721SemasteHost::Backtrace (Stream &strm, uint32_t max_frames) 538254721Semaste{ 539254721Semaste // TODO: Is there a way to backtrace the current process on other systems? 540254721Semaste} 541254721Semaste 542254721Semastesize_t 543254721SemasteHost::GetEnvironment (StringList &env) 544254721Semaste{ 545254721Semaste // TODO: Is there a way to the host environment for this process on other systems? 546254721Semaste return 0; 547254721Semaste} 548254721Semaste 549254721Semaste#endif // #if !defined (__APPLE__) && !defined (__FreeBSD__) && !defined (__FreeBSD_kernel__) && !defined (__linux__) 550254721Semaste 551254721Semastestruct HostThreadCreateInfo 552254721Semaste{ 553254721Semaste std::string thread_name; 554254721Semaste thread_func_t thread_fptr; 555254721Semaste thread_arg_t thread_arg; 556254721Semaste 557254721Semaste HostThreadCreateInfo (const char *name, thread_func_t fptr, thread_arg_t arg) : 558254721Semaste thread_name (name ? name : ""), 559254721Semaste thread_fptr (fptr), 560254721Semaste thread_arg (arg) 561254721Semaste { 562254721Semaste } 563254721Semaste}; 564254721Semaste 565254721Semastestatic thread_result_t 566254721SemasteThreadCreateTrampoline (thread_arg_t arg) 567254721Semaste{ 568254721Semaste HostThreadCreateInfo *info = (HostThreadCreateInfo *)arg; 569254721Semaste Host::ThreadCreated (info->thread_name.c_str()); 570254721Semaste thread_func_t thread_fptr = info->thread_fptr; 571254721Semaste thread_arg_t thread_arg = info->thread_arg; 572254721Semaste 573254721Semaste Log *log(lldb_private::GetLogIfAllCategoriesSet (LIBLLDB_LOG_THREAD)); 574254721Semaste if (log) 575254721Semaste log->Printf("thread created"); 576254721Semaste 577254721Semaste delete info; 578254721Semaste return thread_fptr (thread_arg); 579254721Semaste} 580254721Semaste 581254721Semastelldb::thread_t 582254721SemasteHost::ThreadCreate 583254721Semaste( 584254721Semaste const char *thread_name, 585254721Semaste thread_func_t thread_fptr, 586254721Semaste thread_arg_t thread_arg, 587254721Semaste Error *error 588254721Semaste) 589254721Semaste{ 590254721Semaste lldb::thread_t thread = LLDB_INVALID_HOST_THREAD; 591254721Semaste 592254721Semaste // Host::ThreadCreateTrampoline will delete this pointer for us. 593254721Semaste HostThreadCreateInfo *info_ptr = new HostThreadCreateInfo (thread_name, thread_fptr, thread_arg); 594254721Semaste 595254721Semaste int err = ::pthread_create (&thread, NULL, ThreadCreateTrampoline, info_ptr); 596254721Semaste if (err == 0) 597254721Semaste { 598254721Semaste if (error) 599254721Semaste error->Clear(); 600254721Semaste return thread; 601254721Semaste } 602254721Semaste 603254721Semaste if (error) 604254721Semaste error->SetError (err, eErrorTypePOSIX); 605254721Semaste 606254721Semaste return LLDB_INVALID_HOST_THREAD; 607254721Semaste} 608254721Semaste 609254721Semastebool 610254721SemasteHost::ThreadCancel (lldb::thread_t thread, Error *error) 611254721Semaste{ 612254721Semaste int err = ::pthread_cancel (thread); 613254721Semaste if (error) 614254721Semaste error->SetError(err, eErrorTypePOSIX); 615254721Semaste return err == 0; 616254721Semaste} 617254721Semaste 618254721Semastebool 619254721SemasteHost::ThreadDetach (lldb::thread_t thread, Error *error) 620254721Semaste{ 621254721Semaste int err = ::pthread_detach (thread); 622254721Semaste if (error) 623254721Semaste error->SetError(err, eErrorTypePOSIX); 624254721Semaste return err == 0; 625254721Semaste} 626254721Semaste 627254721Semastebool 628254721SemasteHost::ThreadJoin (lldb::thread_t thread, thread_result_t *thread_result_ptr, Error *error) 629254721Semaste{ 630254721Semaste int err = ::pthread_join (thread, thread_result_ptr); 631254721Semaste if (error) 632254721Semaste error->SetError(err, eErrorTypePOSIX); 633254721Semaste return err == 0; 634254721Semaste} 635254721Semaste 636254721Semastebool 637254721SemasteHost::SetThreadName (lldb::pid_t pid, lldb::tid_t tid, const char *name) 638254721Semaste{ 639254721Semaste#if defined(__APPLE__) && MAC_OS_X_VERSION_MAX_ALLOWED > MAC_OS_X_VERSION_10_5 640254721Semaste lldb::pid_t curr_pid = Host::GetCurrentProcessID(); 641254721Semaste lldb::tid_t curr_tid = Host::GetCurrentThreadID(); 642254721Semaste if (pid == LLDB_INVALID_PROCESS_ID) 643254721Semaste pid = curr_pid; 644254721Semaste 645254721Semaste if (tid == LLDB_INVALID_THREAD_ID) 646254721Semaste tid = curr_tid; 647254721Semaste 648254721Semaste // Set the pthread name if possible 649254721Semaste if (pid == curr_pid && tid == curr_tid) 650254721Semaste { 651254721Semaste if (::pthread_setname_np (name) == 0) 652254721Semaste return true; 653254721Semaste } 654254721Semaste return false; 655254721Semaste#elif defined (__FreeBSD__) 656254721Semaste lldb::pid_t curr_pid = Host::GetCurrentProcessID(); 657254721Semaste lldb::tid_t curr_tid = Host::GetCurrentThreadID(); 658254721Semaste if (pid == LLDB_INVALID_PROCESS_ID) 659254721Semaste pid = curr_pid; 660254721Semaste 661254721Semaste if (tid == LLDB_INVALID_THREAD_ID) 662254721Semaste tid = curr_tid; 663254721Semaste 664254721Semaste // Set the pthread name if possible 665254721Semaste if (pid == curr_pid && tid == curr_tid) 666254721Semaste { 667254721Semaste ::pthread_set_name_np (::pthread_self(), name); 668254721Semaste return true; 669254721Semaste } 670254721Semaste return false; 671254721Semaste#elif defined (__linux__) || defined (__GLIBC__) 672254721Semaste void *fn = dlsym (RTLD_DEFAULT, "pthread_setname_np"); 673254721Semaste if (fn) 674254721Semaste { 675254721Semaste lldb::pid_t curr_pid = Host::GetCurrentProcessID(); 676254721Semaste lldb::tid_t curr_tid = Host::GetCurrentThreadID(); 677254721Semaste if (pid == LLDB_INVALID_PROCESS_ID) 678254721Semaste pid = curr_pid; 679254721Semaste 680254721Semaste if (tid == LLDB_INVALID_THREAD_ID) 681254721Semaste tid = curr_tid; 682254721Semaste 683254721Semaste if (pid == curr_pid && tid == curr_tid) 684254721Semaste { 685254721Semaste int (*pthread_setname_np_func)(pthread_t thread, const char *name); 686254721Semaste *reinterpret_cast<void **> (&pthread_setname_np_func) = fn; 687254721Semaste 688254721Semaste if (pthread_setname_np_func (::pthread_self(), name) == 0) 689254721Semaste return true; 690254721Semaste } 691254721Semaste } 692254721Semaste return false; 693254721Semaste#else 694254721Semaste return false; 695254721Semaste#endif 696254721Semaste} 697254721Semaste 698254721Semastebool 699254721SemasteHost::SetShortThreadName (lldb::pid_t pid, lldb::tid_t tid, 700254721Semaste const char *thread_name, size_t len) 701254721Semaste{ 702254721Semaste char *namebuf = (char *)::malloc (len + 1); 703254721Semaste 704254721Semaste // Thread names are coming in like '<lldb.comm.debugger.edit>' and 705254721Semaste // '<lldb.comm.debugger.editline>'. So just chopping the end of the string 706254721Semaste // off leads to a lot of similar named threads. Go through the thread name 707254721Semaste // and search for the last dot and use that. 708254721Semaste const char *lastdot = ::strrchr (thread_name, '.'); 709254721Semaste 710254721Semaste if (lastdot && lastdot != thread_name) 711254721Semaste thread_name = lastdot + 1; 712254721Semaste ::strncpy (namebuf, thread_name, len); 713254721Semaste namebuf[len] = 0; 714254721Semaste 715254721Semaste int namebuflen = strlen(namebuf); 716254721Semaste if (namebuflen > 0) 717254721Semaste { 718254721Semaste if (namebuf[namebuflen - 1] == '(' || namebuf[namebuflen - 1] == '>') 719254721Semaste { 720254721Semaste // Trim off trailing '(' and '>' characters for a bit more cleanup. 721254721Semaste namebuflen--; 722254721Semaste namebuf[namebuflen] = 0; 723254721Semaste } 724254721Semaste return Host::SetThreadName (pid, tid, namebuf); 725254721Semaste } 726254721Semaste return false; 727254721Semaste} 728254721Semaste 729254721SemasteFileSpec 730254721SemasteHost::GetProgramFileSpec () 731254721Semaste{ 732254721Semaste static FileSpec g_program_filespec; 733254721Semaste if (!g_program_filespec) 734254721Semaste { 735254721Semaste#if defined (__APPLE__) 736254721Semaste char program_fullpath[PATH_MAX]; 737254721Semaste // If DST is NULL, then return the number of bytes needed. 738254721Semaste uint32_t len = sizeof(program_fullpath); 739254721Semaste int err = _NSGetExecutablePath (program_fullpath, &len); 740254721Semaste if (err == 0) 741254721Semaste g_program_filespec.SetFile (program_fullpath, false); 742254721Semaste else if (err == -1) 743254721Semaste { 744254721Semaste char *large_program_fullpath = (char *)::malloc (len + 1); 745254721Semaste 746254721Semaste err = _NSGetExecutablePath (large_program_fullpath, &len); 747254721Semaste if (err == 0) 748254721Semaste g_program_filespec.SetFile (large_program_fullpath, false); 749254721Semaste 750254721Semaste ::free (large_program_fullpath); 751254721Semaste } 752254721Semaste#elif defined (__linux__) 753254721Semaste char exe_path[PATH_MAX]; 754254721Semaste ssize_t len = readlink("/proc/self/exe", exe_path, sizeof(exe_path) - 1); 755254721Semaste if (len > 0) { 756254721Semaste exe_path[len] = 0; 757254721Semaste g_program_filespec.SetFile(exe_path, false); 758254721Semaste } 759254721Semaste#elif defined (__FreeBSD__) || defined (__FreeBSD_kernel__) 760254721Semaste int exe_path_mib[4] = { CTL_KERN, KERN_PROC, KERN_PROC_PATHNAME, getpid() }; 761254721Semaste size_t exe_path_size; 762254721Semaste if (sysctl(exe_path_mib, 4, NULL, &exe_path_size, NULL, 0) == 0) 763254721Semaste { 764254721Semaste char *exe_path = new char[exe_path_size]; 765254721Semaste if (sysctl(exe_path_mib, 4, exe_path, &exe_path_size, NULL, 0) == 0) 766254721Semaste g_program_filespec.SetFile(exe_path, false); 767254721Semaste delete[] exe_path; 768254721Semaste } 769254721Semaste#endif 770254721Semaste } 771254721Semaste return g_program_filespec; 772254721Semaste} 773254721Semaste 774254721SemasteFileSpec 775254721SemasteHost::GetModuleFileSpecForHostAddress (const void *host_addr) 776254721Semaste{ 777254721Semaste FileSpec module_filespec; 778254721Semaste Dl_info info; 779254721Semaste if (::dladdr (host_addr, &info)) 780254721Semaste { 781254721Semaste if (info.dli_fname) 782254721Semaste module_filespec.SetFile(info.dli_fname, true); 783254721Semaste } 784254721Semaste return module_filespec; 785254721Semaste} 786254721Semaste 787254721Semaste#if !defined (__APPLE__) // see Host.mm 788254721Semaste 789254721Semastebool 790254721SemasteHost::GetBundleDirectory (const FileSpec &file, FileSpec &bundle) 791254721Semaste{ 792254721Semaste bundle.Clear(); 793254721Semaste return false; 794254721Semaste} 795254721Semaste 796254721Semastebool 797254721SemasteHost::ResolveExecutableInBundle (FileSpec &file) 798254721Semaste{ 799254721Semaste return false; 800254721Semaste} 801254721Semaste#endif 802254721Semaste 803254721Semaste// Opaque info that tracks a dynamic library that was loaded 804254721Semastestruct DynamicLibraryInfo 805254721Semaste{ 806254721Semaste DynamicLibraryInfo (const FileSpec &fs, int o, void *h) : 807254721Semaste file_spec (fs), 808254721Semaste open_options (o), 809254721Semaste handle (h) 810254721Semaste { 811254721Semaste } 812254721Semaste 813254721Semaste const FileSpec file_spec; 814254721Semaste uint32_t open_options; 815254721Semaste void * handle; 816254721Semaste}; 817254721Semaste 818254721Semastevoid * 819254721SemasteHost::DynamicLibraryOpen (const FileSpec &file_spec, uint32_t options, Error &error) 820254721Semaste{ 821254721Semaste char path[PATH_MAX]; 822254721Semaste if (file_spec.GetPath(path, sizeof(path))) 823254721Semaste { 824254721Semaste int mode = 0; 825254721Semaste 826254721Semaste if (options & eDynamicLibraryOpenOptionLazy) 827254721Semaste mode |= RTLD_LAZY; 828254721Semaste else 829254721Semaste mode |= RTLD_NOW; 830254721Semaste 831254721Semaste 832254721Semaste if (options & eDynamicLibraryOpenOptionLocal) 833254721Semaste mode |= RTLD_LOCAL; 834254721Semaste else 835254721Semaste mode |= RTLD_GLOBAL; 836254721Semaste 837254721Semaste#ifdef LLDB_CONFIG_DLOPEN_RTLD_FIRST_SUPPORTED 838254721Semaste if (options & eDynamicLibraryOpenOptionLimitGetSymbol) 839254721Semaste mode |= RTLD_FIRST; 840254721Semaste#endif 841254721Semaste 842254721Semaste void * opaque = ::dlopen (path, mode); 843254721Semaste 844254721Semaste if (opaque) 845254721Semaste { 846254721Semaste error.Clear(); 847254721Semaste return new DynamicLibraryInfo (file_spec, options, opaque); 848254721Semaste } 849254721Semaste else 850254721Semaste { 851254721Semaste error.SetErrorString(::dlerror()); 852254721Semaste } 853254721Semaste } 854254721Semaste else 855254721Semaste { 856254721Semaste error.SetErrorString("failed to extract path"); 857254721Semaste } 858254721Semaste return NULL; 859254721Semaste} 860254721Semaste 861254721SemasteError 862254721SemasteHost::DynamicLibraryClose (void *opaque) 863254721Semaste{ 864254721Semaste Error error; 865254721Semaste if (opaque == NULL) 866254721Semaste { 867254721Semaste error.SetErrorString ("invalid dynamic library handle"); 868254721Semaste } 869254721Semaste else 870254721Semaste { 871254721Semaste DynamicLibraryInfo *dylib_info = (DynamicLibraryInfo *) opaque; 872254721Semaste if (::dlclose (dylib_info->handle) != 0) 873254721Semaste { 874254721Semaste error.SetErrorString(::dlerror()); 875254721Semaste } 876254721Semaste 877254721Semaste dylib_info->open_options = 0; 878254721Semaste dylib_info->handle = 0; 879254721Semaste delete dylib_info; 880254721Semaste } 881254721Semaste return error; 882254721Semaste} 883254721Semaste 884254721Semastevoid * 885254721SemasteHost::DynamicLibraryGetSymbol (void *opaque, const char *symbol_name, Error &error) 886254721Semaste{ 887254721Semaste if (opaque == NULL) 888254721Semaste { 889254721Semaste error.SetErrorString ("invalid dynamic library handle"); 890254721Semaste } 891254721Semaste else 892254721Semaste { 893254721Semaste DynamicLibraryInfo *dylib_info = (DynamicLibraryInfo *) opaque; 894254721Semaste 895254721Semaste void *symbol_addr = ::dlsym (dylib_info->handle, symbol_name); 896254721Semaste if (symbol_addr) 897254721Semaste { 898254721Semaste#ifndef LLDB_CONFIG_DLOPEN_RTLD_FIRST_SUPPORTED 899254721Semaste // This host doesn't support limiting searches to this shared library 900254721Semaste // so we need to verify that the match came from this shared library 901254721Semaste // if it was requested in the Host::DynamicLibraryOpen() function. 902254721Semaste if (dylib_info->open_options & eDynamicLibraryOpenOptionLimitGetSymbol) 903254721Semaste { 904254721Semaste FileSpec match_dylib_spec (Host::GetModuleFileSpecForHostAddress (symbol_addr)); 905254721Semaste if (match_dylib_spec != dylib_info->file_spec) 906254721Semaste { 907254721Semaste char dylib_path[PATH_MAX]; 908254721Semaste if (dylib_info->file_spec.GetPath (dylib_path, sizeof(dylib_path))) 909254721Semaste error.SetErrorStringWithFormat ("symbol not found in \"%s\"", dylib_path); 910254721Semaste else 911254721Semaste error.SetErrorString ("symbol not found"); 912254721Semaste return NULL; 913254721Semaste } 914254721Semaste } 915254721Semaste#endif 916254721Semaste error.Clear(); 917254721Semaste return symbol_addr; 918254721Semaste } 919254721Semaste else 920254721Semaste { 921254721Semaste error.SetErrorString(::dlerror()); 922254721Semaste } 923254721Semaste } 924254721Semaste return NULL; 925254721Semaste} 926254721Semaste 927254721Semastebool 928254721SemasteHost::GetLLDBPath (PathType path_type, FileSpec &file_spec) 929254721Semaste{ 930254721Semaste // To get paths related to LLDB we get the path to the executable that 931254721Semaste // contains this function. On MacOSX this will be "LLDB.framework/.../LLDB", 932254721Semaste // on linux this is assumed to be the "lldb" main executable. If LLDB on 933254721Semaste // linux is actually in a shared library (liblldb.so) then this function will 934254721Semaste // need to be modified to "do the right thing". 935254721Semaste 936254721Semaste switch (path_type) 937254721Semaste { 938254721Semaste case ePathTypeLLDBShlibDir: 939254721Semaste { 940254721Semaste static ConstString g_lldb_so_dir; 941254721Semaste if (!g_lldb_so_dir) 942254721Semaste { 943254721Semaste FileSpec lldb_file_spec (Host::GetModuleFileSpecForHostAddress ((void *)Host::GetLLDBPath)); 944254721Semaste g_lldb_so_dir = lldb_file_spec.GetDirectory(); 945254721Semaste } 946254721Semaste file_spec.GetDirectory() = g_lldb_so_dir; 947254721Semaste return file_spec.GetDirectory(); 948254721Semaste } 949254721Semaste break; 950254721Semaste 951254721Semaste case ePathTypeSupportExecutableDir: 952254721Semaste { 953254721Semaste static ConstString g_lldb_support_exe_dir; 954254721Semaste if (!g_lldb_support_exe_dir) 955254721Semaste { 956254721Semaste FileSpec lldb_file_spec; 957254721Semaste if (GetLLDBPath (ePathTypeLLDBShlibDir, lldb_file_spec)) 958254721Semaste { 959254721Semaste char raw_path[PATH_MAX]; 960254721Semaste char resolved_path[PATH_MAX]; 961254721Semaste lldb_file_spec.GetPath(raw_path, sizeof(raw_path)); 962254721Semaste 963254721Semaste#if defined (__APPLE__) 964254721Semaste char *framework_pos = ::strstr (raw_path, "LLDB.framework"); 965254721Semaste if (framework_pos) 966254721Semaste { 967254721Semaste framework_pos += strlen("LLDB.framework"); 968254721Semaste#if !defined (__arm__) 969254721Semaste ::strncpy (framework_pos, "/Resources", PATH_MAX - (framework_pos - raw_path)); 970254721Semaste#endif 971254721Semaste } 972254721Semaste#endif 973254721Semaste FileSpec::Resolve (raw_path, resolved_path, sizeof(resolved_path)); 974254721Semaste g_lldb_support_exe_dir.SetCString(resolved_path); 975254721Semaste } 976254721Semaste } 977254721Semaste file_spec.GetDirectory() = g_lldb_support_exe_dir; 978254721Semaste return file_spec.GetDirectory(); 979254721Semaste } 980254721Semaste break; 981254721Semaste 982254721Semaste case ePathTypeHeaderDir: 983254721Semaste { 984254721Semaste static ConstString g_lldb_headers_dir; 985254721Semaste if (!g_lldb_headers_dir) 986254721Semaste { 987254721Semaste#if defined (__APPLE__) 988254721Semaste FileSpec lldb_file_spec; 989254721Semaste if (GetLLDBPath (ePathTypeLLDBShlibDir, lldb_file_spec)) 990254721Semaste { 991254721Semaste char raw_path[PATH_MAX]; 992254721Semaste char resolved_path[PATH_MAX]; 993254721Semaste lldb_file_spec.GetPath(raw_path, sizeof(raw_path)); 994254721Semaste 995254721Semaste char *framework_pos = ::strstr (raw_path, "LLDB.framework"); 996254721Semaste if (framework_pos) 997254721Semaste { 998254721Semaste framework_pos += strlen("LLDB.framework"); 999254721Semaste ::strncpy (framework_pos, "/Headers", PATH_MAX - (framework_pos - raw_path)); 1000254721Semaste } 1001254721Semaste FileSpec::Resolve (raw_path, resolved_path, sizeof(resolved_path)); 1002254721Semaste g_lldb_headers_dir.SetCString(resolved_path); 1003254721Semaste } 1004254721Semaste#else 1005254721Semaste // TODO: Anyone know how we can determine this for linux? Other systems?? 1006254721Semaste g_lldb_headers_dir.SetCString ("/opt/local/include/lldb"); 1007254721Semaste#endif 1008254721Semaste } 1009254721Semaste file_spec.GetDirectory() = g_lldb_headers_dir; 1010254721Semaste return file_spec.GetDirectory(); 1011254721Semaste } 1012254721Semaste break; 1013254721Semaste 1014254721Semaste#ifndef LLDB_DISABLE_PYTHON 1015254721Semaste case ePathTypePythonDir: 1016254721Semaste { 1017254721Semaste static ConstString g_lldb_python_dir; 1018254721Semaste if (!g_lldb_python_dir) 1019254721Semaste { 1020254721Semaste FileSpec lldb_file_spec; 1021254721Semaste if (GetLLDBPath (ePathTypeLLDBShlibDir, lldb_file_spec)) 1022254721Semaste { 1023254721Semaste char raw_path[PATH_MAX]; 1024254721Semaste char resolved_path[PATH_MAX]; 1025254721Semaste lldb_file_spec.GetPath(raw_path, sizeof(raw_path)); 1026254721Semaste 1027254721Semaste#if defined (__APPLE__) 1028254721Semaste char *framework_pos = ::strstr (raw_path, "LLDB.framework"); 1029254721Semaste if (framework_pos) 1030254721Semaste { 1031254721Semaste framework_pos += strlen("LLDB.framework"); 1032254721Semaste ::strncpy (framework_pos, "/Resources/Python", PATH_MAX - (framework_pos - raw_path)); 1033254721Semaste } 1034254721Semaste#else 1035254721Semaste llvm::SmallString<256> python_version_dir; 1036254721Semaste llvm::raw_svector_ostream os(python_version_dir); 1037254721Semaste os << "/python" << PY_MAJOR_VERSION << '.' << PY_MINOR_VERSION << "/site-packages"; 1038254721Semaste os.flush(); 1039254721Semaste 1040254721Semaste // We may get our string truncated. Should we protect 1041254721Semaste // this with an assert? 1042254721Semaste 1043254721Semaste ::strncat(raw_path, python_version_dir.c_str(), 1044254721Semaste sizeof(raw_path) - strlen(raw_path) - 1); 1045254721Semaste 1046254721Semaste#endif 1047254721Semaste FileSpec::Resolve (raw_path, resolved_path, sizeof(resolved_path)); 1048254721Semaste g_lldb_python_dir.SetCString(resolved_path); 1049254721Semaste } 1050254721Semaste } 1051254721Semaste file_spec.GetDirectory() = g_lldb_python_dir; 1052254721Semaste return file_spec.GetDirectory(); 1053254721Semaste } 1054254721Semaste break; 1055254721Semaste#endif 1056254721Semaste 1057254721Semaste case ePathTypeLLDBSystemPlugins: // System plug-ins directory 1058254721Semaste { 1059254721Semaste#if defined (__APPLE__) || defined(__linux__) 1060254721Semaste static ConstString g_lldb_system_plugin_dir; 1061254721Semaste static bool g_lldb_system_plugin_dir_located = false; 1062254721Semaste if (!g_lldb_system_plugin_dir_located) 1063254721Semaste { 1064254721Semaste g_lldb_system_plugin_dir_located = true; 1065254721Semaste#if defined (__APPLE__) 1066254721Semaste FileSpec lldb_file_spec; 1067254721Semaste if (GetLLDBPath (ePathTypeLLDBShlibDir, lldb_file_spec)) 1068254721Semaste { 1069254721Semaste char raw_path[PATH_MAX]; 1070254721Semaste char resolved_path[PATH_MAX]; 1071254721Semaste lldb_file_spec.GetPath(raw_path, sizeof(raw_path)); 1072254721Semaste 1073254721Semaste char *framework_pos = ::strstr (raw_path, "LLDB.framework"); 1074254721Semaste if (framework_pos) 1075254721Semaste { 1076254721Semaste framework_pos += strlen("LLDB.framework"); 1077254721Semaste ::strncpy (framework_pos, "/Resources/PlugIns", PATH_MAX - (framework_pos - raw_path)); 1078254721Semaste FileSpec::Resolve (raw_path, resolved_path, sizeof(resolved_path)); 1079254721Semaste g_lldb_system_plugin_dir.SetCString(resolved_path); 1080254721Semaste } 1081254721Semaste return false; 1082254721Semaste } 1083254721Semaste#elif defined (__linux__) 1084254721Semaste FileSpec lldb_file_spec("/usr/lib/lldb", true); 1085254721Semaste if (lldb_file_spec.Exists()) 1086254721Semaste { 1087254721Semaste g_lldb_system_plugin_dir.SetCString(lldb_file_spec.GetPath().c_str()); 1088254721Semaste } 1089254721Semaste#endif // __APPLE__ || __linux__ 1090254721Semaste } 1091254721Semaste 1092254721Semaste if (g_lldb_system_plugin_dir) 1093254721Semaste { 1094254721Semaste file_spec.GetDirectory() = g_lldb_system_plugin_dir; 1095254721Semaste return true; 1096254721Semaste } 1097254721Semaste#else 1098254721Semaste // TODO: where would system LLDB plug-ins be located on other systems? 1099254721Semaste return false; 1100254721Semaste#endif 1101254721Semaste } 1102254721Semaste break; 1103254721Semaste 1104254721Semaste case ePathTypeLLDBUserPlugins: // User plug-ins directory 1105254721Semaste { 1106254721Semaste#if defined (__APPLE__) 1107254721Semaste static ConstString g_lldb_user_plugin_dir; 1108254721Semaste if (!g_lldb_user_plugin_dir) 1109254721Semaste { 1110254721Semaste char user_plugin_path[PATH_MAX]; 1111254721Semaste if (FileSpec::Resolve ("~/Library/Application Support/LLDB/PlugIns", 1112254721Semaste user_plugin_path, 1113254721Semaste sizeof(user_plugin_path))) 1114254721Semaste { 1115254721Semaste g_lldb_user_plugin_dir.SetCString(user_plugin_path); 1116254721Semaste } 1117254721Semaste } 1118254721Semaste file_spec.GetDirectory() = g_lldb_user_plugin_dir; 1119254721Semaste return file_spec.GetDirectory(); 1120254721Semaste#elif defined (__linux__) 1121254721Semaste static ConstString g_lldb_user_plugin_dir; 1122254721Semaste if (!g_lldb_user_plugin_dir) 1123254721Semaste { 1124254721Semaste // XDG Base Directory Specification 1125254721Semaste // http://standards.freedesktop.org/basedir-spec/basedir-spec-latest.html 1126254721Semaste // If XDG_DATA_HOME exists, use that, otherwise use ~/.local/share/lldb. 1127254721Semaste FileSpec lldb_file_spec; 1128254721Semaste const char *xdg_data_home = getenv("XDG_DATA_HOME"); 1129254721Semaste if (xdg_data_home && xdg_data_home[0]) 1130254721Semaste { 1131254721Semaste std::string user_plugin_dir (xdg_data_home); 1132254721Semaste user_plugin_dir += "/lldb"; 1133254721Semaste lldb_file_spec.SetFile (user_plugin_dir.c_str(), true); 1134254721Semaste } 1135254721Semaste else 1136254721Semaste { 1137254721Semaste const char *home_dir = getenv("HOME"); 1138254721Semaste if (home_dir && home_dir[0]) 1139254721Semaste { 1140254721Semaste std::string user_plugin_dir (home_dir); 1141254721Semaste user_plugin_dir += "/.local/share/lldb"; 1142254721Semaste lldb_file_spec.SetFile (user_plugin_dir.c_str(), true); 1143254721Semaste } 1144254721Semaste } 1145254721Semaste 1146254721Semaste if (lldb_file_spec.Exists()) 1147254721Semaste g_lldb_user_plugin_dir.SetCString(lldb_file_spec.GetPath().c_str()); 1148254721Semaste } 1149254721Semaste file_spec.GetDirectory() = g_lldb_user_plugin_dir; 1150254721Semaste return file_spec.GetDirectory(); 1151254721Semaste#endif 1152254721Semaste // TODO: where would user LLDB plug-ins be located on other systems? 1153254721Semaste return false; 1154254721Semaste } 1155254721Semaste } 1156254721Semaste 1157254721Semaste return false; 1158254721Semaste} 1159254721Semaste 1160254721Semaste 1161254721Semastebool 1162254721SemasteHost::GetHostname (std::string &s) 1163254721Semaste{ 1164254721Semaste char hostname[PATH_MAX]; 1165254721Semaste hostname[sizeof(hostname) - 1] = '\0'; 1166254721Semaste if (::gethostname (hostname, sizeof(hostname) - 1) == 0) 1167254721Semaste { 1168254721Semaste struct hostent* h = ::gethostbyname (hostname); 1169254721Semaste if (h) 1170254721Semaste s.assign (h->h_name); 1171254721Semaste else 1172254721Semaste s.assign (hostname); 1173254721Semaste return true; 1174254721Semaste } 1175254721Semaste return false; 1176254721Semaste} 1177254721Semaste 1178254721Semasteconst char * 1179254721SemasteHost::GetUserName (uint32_t uid, std::string &user_name) 1180254721Semaste{ 1181254721Semaste struct passwd user_info; 1182254721Semaste struct passwd *user_info_ptr = &user_info; 1183254721Semaste char user_buffer[PATH_MAX]; 1184254721Semaste size_t user_buffer_size = sizeof(user_buffer); 1185254721Semaste if (::getpwuid_r (uid, 1186254721Semaste &user_info, 1187254721Semaste user_buffer, 1188254721Semaste user_buffer_size, 1189254721Semaste &user_info_ptr) == 0) 1190254721Semaste { 1191254721Semaste if (user_info_ptr) 1192254721Semaste { 1193254721Semaste user_name.assign (user_info_ptr->pw_name); 1194254721Semaste return user_name.c_str(); 1195254721Semaste } 1196254721Semaste } 1197254721Semaste user_name.clear(); 1198254721Semaste return NULL; 1199254721Semaste} 1200254721Semaste 1201254721Semasteconst char * 1202254721SemasteHost::GetGroupName (uint32_t gid, std::string &group_name) 1203254721Semaste{ 1204254721Semaste char group_buffer[PATH_MAX]; 1205254721Semaste size_t group_buffer_size = sizeof(group_buffer); 1206254721Semaste struct group group_info; 1207254721Semaste struct group *group_info_ptr = &group_info; 1208254721Semaste // Try the threadsafe version first 1209254721Semaste if (::getgrgid_r (gid, 1210254721Semaste &group_info, 1211254721Semaste group_buffer, 1212254721Semaste group_buffer_size, 1213254721Semaste &group_info_ptr) == 0) 1214254721Semaste { 1215254721Semaste if (group_info_ptr) 1216254721Semaste { 1217254721Semaste group_name.assign (group_info_ptr->gr_name); 1218254721Semaste return group_name.c_str(); 1219254721Semaste } 1220254721Semaste } 1221254721Semaste else 1222254721Semaste { 1223254721Semaste // The threadsafe version isn't currently working 1224254721Semaste // for me on darwin, but the non-threadsafe version 1225254721Semaste // is, so I am calling it below. 1226254721Semaste group_info_ptr = ::getgrgid (gid); 1227254721Semaste if (group_info_ptr) 1228254721Semaste { 1229254721Semaste group_name.assign (group_info_ptr->gr_name); 1230254721Semaste return group_name.c_str(); 1231254721Semaste } 1232254721Semaste } 1233254721Semaste group_name.clear(); 1234254721Semaste return NULL; 1235254721Semaste} 1236254721Semaste 1237254721Semaste#if !defined (__APPLE__) && !defined (__FreeBSD__) && !defined (__FreeBSD_kernel__) // see macosx/Host.mm 1238254721Semastebool 1239254721SemasteHost::GetOSBuildString (std::string &s) 1240254721Semaste{ 1241254721Semaste s.clear(); 1242254721Semaste return false; 1243254721Semaste} 1244254721Semaste 1245254721Semastebool 1246254721SemasteHost::GetOSKernelDescription (std::string &s) 1247254721Semaste{ 1248254721Semaste s.clear(); 1249254721Semaste return false; 1250254721Semaste} 1251254721Semaste#endif 1252254721Semaste 1253254721Semasteuint32_t 1254254721SemasteHost::GetUserID () 1255254721Semaste{ 1256254721Semaste return getuid(); 1257254721Semaste} 1258254721Semaste 1259254721Semasteuint32_t 1260254721SemasteHost::GetGroupID () 1261254721Semaste{ 1262254721Semaste return getgid(); 1263254721Semaste} 1264254721Semaste 1265254721Semasteuint32_t 1266254721SemasteHost::GetEffectiveUserID () 1267254721Semaste{ 1268254721Semaste return geteuid(); 1269254721Semaste} 1270254721Semaste 1271254721Semasteuint32_t 1272254721SemasteHost::GetEffectiveGroupID () 1273254721Semaste{ 1274254721Semaste return getegid(); 1275254721Semaste} 1276254721Semaste 1277254721Semaste#if !defined (__APPLE__) && !defined(__linux__) 1278254721Semasteuint32_t 1279254721SemasteHost::FindProcesses (const ProcessInstanceInfoMatch &match_info, ProcessInstanceInfoList &process_infos) 1280254721Semaste{ 1281254721Semaste process_infos.Clear(); 1282254721Semaste return process_infos.GetSize(); 1283254721Semaste} 1284254721Semaste#endif // #if !defined (__APPLE__) && !defined(__linux__) 1285254721Semaste 1286254721Semaste#if !defined (__APPLE__) && !defined (__FreeBSD__) && !defined (__FreeBSD_kernel__) && !defined(__linux__) 1287254721Semastebool 1288254721SemasteHost::GetProcessInfo (lldb::pid_t pid, ProcessInstanceInfo &process_info) 1289254721Semaste{ 1290254721Semaste process_info.Clear(); 1291254721Semaste return false; 1292254721Semaste} 1293254721Semaste#endif 1294254721Semaste 1295254721Semaste#if !defined(__linux__) 1296254721Semastebool 1297254721SemasteHost::FindProcessThreads (const lldb::pid_t pid, TidMap &tids_to_attach) 1298254721Semaste{ 1299254721Semaste return false; 1300254721Semaste} 1301254721Semaste#endif 1302254721Semaste 1303254721Semastelldb::TargetSP 1304254721SemasteHost::GetDummyTarget (lldb_private::Debugger &debugger) 1305254721Semaste{ 1306254721Semaste static TargetSP g_dummy_target_sp; 1307254721Semaste 1308254721Semaste // FIXME: Maybe the dummy target should be per-Debugger 1309254721Semaste if (!g_dummy_target_sp || !g_dummy_target_sp->IsValid()) 1310254721Semaste { 1311254721Semaste ArchSpec arch(Target::GetDefaultArchitecture()); 1312254721Semaste if (!arch.IsValid()) 1313254721Semaste arch = Host::GetArchitecture (); 1314254721Semaste Error err = debugger.GetTargetList().CreateTarget(debugger, 1315254721Semaste NULL, 1316254721Semaste arch.GetTriple().getTriple().c_str(), 1317254721Semaste false, 1318254721Semaste NULL, 1319254721Semaste g_dummy_target_sp); 1320254721Semaste } 1321254721Semaste 1322254721Semaste return g_dummy_target_sp; 1323254721Semaste} 1324254721Semaste 1325254721Semastestruct ShellInfo 1326254721Semaste{ 1327254721Semaste ShellInfo () : 1328254721Semaste process_reaped (false), 1329254721Semaste can_delete (false), 1330254721Semaste pid (LLDB_INVALID_PROCESS_ID), 1331254721Semaste signo(-1), 1332254721Semaste status(-1) 1333254721Semaste { 1334254721Semaste } 1335254721Semaste 1336254721Semaste lldb_private::Predicate<bool> process_reaped; 1337254721Semaste lldb_private::Predicate<bool> can_delete; 1338254721Semaste lldb::pid_t pid; 1339254721Semaste int signo; 1340254721Semaste int status; 1341254721Semaste}; 1342254721Semaste 1343254721Semastestatic bool 1344254721SemasteMonitorShellCommand (void *callback_baton, 1345254721Semaste lldb::pid_t pid, 1346254721Semaste bool exited, // True if the process did exit 1347254721Semaste int signo, // Zero for no signal 1348254721Semaste int status) // Exit value of process if signal is zero 1349254721Semaste{ 1350254721Semaste ShellInfo *shell_info = (ShellInfo *)callback_baton; 1351254721Semaste shell_info->pid = pid; 1352254721Semaste shell_info->signo = signo; 1353254721Semaste shell_info->status = status; 1354254721Semaste // Let the thread running Host::RunShellCommand() know that the process 1355254721Semaste // exited and that ShellInfo has been filled in by broadcasting to it 1356254721Semaste shell_info->process_reaped.SetValue(1, eBroadcastAlways); 1357254721Semaste // Now wait for a handshake back from that thread running Host::RunShellCommand 1358254721Semaste // so we know that we can delete shell_info_ptr 1359254721Semaste shell_info->can_delete.WaitForValueEqualTo(true); 1360254721Semaste // Sleep a bit to allow the shell_info->can_delete.SetValue() to complete... 1361254721Semaste usleep(1000); 1362254721Semaste // Now delete the shell info that was passed into this function 1363254721Semaste delete shell_info; 1364254721Semaste return true; 1365254721Semaste} 1366254721Semaste 1367254721SemasteError 1368254721SemasteHost::RunShellCommand (const char *command, 1369254721Semaste const char *working_dir, 1370254721Semaste int *status_ptr, 1371254721Semaste int *signo_ptr, 1372254721Semaste std::string *command_output_ptr, 1373254721Semaste uint32_t timeout_sec, 1374254721Semaste const char *shell) 1375254721Semaste{ 1376254721Semaste Error error; 1377254721Semaste ProcessLaunchInfo launch_info; 1378254721Semaste if (shell && shell[0]) 1379254721Semaste { 1380254721Semaste // Run the command in a shell 1381254721Semaste launch_info.SetShell(shell); 1382254721Semaste launch_info.GetArguments().AppendArgument(command); 1383254721Semaste const bool localhost = true; 1384254721Semaste const bool will_debug = false; 1385254721Semaste const bool first_arg_is_full_shell_command = true; 1386254721Semaste launch_info.ConvertArgumentsForLaunchingInShell (error, 1387254721Semaste localhost, 1388254721Semaste will_debug, 1389254721Semaste first_arg_is_full_shell_command); 1390254721Semaste } 1391254721Semaste else 1392254721Semaste { 1393254721Semaste // No shell, just run it 1394254721Semaste Args args (command); 1395254721Semaste const bool first_arg_is_executable = true; 1396254721Semaste launch_info.SetArguments(args, first_arg_is_executable); 1397254721Semaste } 1398254721Semaste 1399254721Semaste if (working_dir) 1400254721Semaste launch_info.SetWorkingDirectory(working_dir); 1401254721Semaste char output_file_path_buffer[L_tmpnam]; 1402254721Semaste const char *output_file_path = NULL; 1403254721Semaste if (command_output_ptr) 1404254721Semaste { 1405254721Semaste // Create a temporary file to get the stdout/stderr and redirect the 1406254721Semaste // output of the command into this file. We will later read this file 1407254721Semaste // if all goes well and fill the data into "command_output_ptr" 1408254721Semaste output_file_path = ::tmpnam(output_file_path_buffer); 1409254721Semaste launch_info.AppendSuppressFileAction (STDIN_FILENO, true, false); 1410254721Semaste launch_info.AppendOpenFileAction(STDOUT_FILENO, output_file_path, false, true); 1411254721Semaste launch_info.AppendDuplicateFileAction(STDOUT_FILENO, STDERR_FILENO); 1412254721Semaste } 1413254721Semaste else 1414254721Semaste { 1415254721Semaste launch_info.AppendSuppressFileAction (STDIN_FILENO, true, false); 1416254721Semaste launch_info.AppendSuppressFileAction (STDOUT_FILENO, false, true); 1417254721Semaste launch_info.AppendSuppressFileAction (STDERR_FILENO, false, true); 1418254721Semaste } 1419254721Semaste 1420254721Semaste // The process monitor callback will delete the 'shell_info_ptr' below... 1421254721Semaste std::unique_ptr<ShellInfo> shell_info_ap (new ShellInfo()); 1422254721Semaste 1423254721Semaste const bool monitor_signals = false; 1424254721Semaste launch_info.SetMonitorProcessCallback(MonitorShellCommand, shell_info_ap.get(), monitor_signals); 1425254721Semaste 1426254721Semaste error = LaunchProcess (launch_info); 1427254721Semaste const lldb::pid_t pid = launch_info.GetProcessID(); 1428254721Semaste if (pid != LLDB_INVALID_PROCESS_ID) 1429254721Semaste { 1430254721Semaste // The process successfully launched, so we can defer ownership of 1431254721Semaste // "shell_info" to the MonitorShellCommand callback function that will 1432254721Semaste // get called when the process dies. We release the unique pointer as it 1433254721Semaste // doesn't need to delete the ShellInfo anymore. 1434254721Semaste ShellInfo *shell_info = shell_info_ap.release(); 1435254721Semaste TimeValue timeout_time(TimeValue::Now()); 1436254721Semaste timeout_time.OffsetWithSeconds(timeout_sec); 1437254721Semaste bool timed_out = false; 1438254721Semaste shell_info->process_reaped.WaitForValueEqualTo(true, &timeout_time, &timed_out); 1439254721Semaste if (timed_out) 1440254721Semaste { 1441254721Semaste error.SetErrorString("timed out waiting for shell command to complete"); 1442254721Semaste 1443254721Semaste // Kill the process since it didn't complete withint the timeout specified 1444254721Semaste ::kill (pid, SIGKILL); 1445254721Semaste // Wait for the monitor callback to get the message 1446254721Semaste timeout_time = TimeValue::Now(); 1447254721Semaste timeout_time.OffsetWithSeconds(1); 1448254721Semaste timed_out = false; 1449254721Semaste shell_info->process_reaped.WaitForValueEqualTo(true, &timeout_time, &timed_out); 1450254721Semaste } 1451254721Semaste else 1452254721Semaste { 1453254721Semaste if (status_ptr) 1454254721Semaste *status_ptr = shell_info->status; 1455254721Semaste 1456254721Semaste if (signo_ptr) 1457254721Semaste *signo_ptr = shell_info->signo; 1458254721Semaste 1459254721Semaste if (command_output_ptr) 1460254721Semaste { 1461254721Semaste command_output_ptr->clear(); 1462254721Semaste FileSpec file_spec(output_file_path, File::eOpenOptionRead); 1463254721Semaste uint64_t file_size = file_spec.GetByteSize(); 1464254721Semaste if (file_size > 0) 1465254721Semaste { 1466254721Semaste if (file_size > command_output_ptr->max_size()) 1467254721Semaste { 1468254721Semaste error.SetErrorStringWithFormat("shell command output is too large to fit into a std::string"); 1469254721Semaste } 1470254721Semaste else 1471254721Semaste { 1472254721Semaste command_output_ptr->resize(file_size); 1473254721Semaste file_spec.ReadFileContents(0, &((*command_output_ptr)[0]), command_output_ptr->size(), &error); 1474254721Semaste } 1475254721Semaste } 1476254721Semaste } 1477254721Semaste } 1478254721Semaste shell_info->can_delete.SetValue(true, eBroadcastAlways); 1479254721Semaste } 1480254721Semaste else 1481254721Semaste { 1482254721Semaste error.SetErrorString("failed to get process ID"); 1483254721Semaste } 1484254721Semaste 1485254721Semaste if (output_file_path) 1486254721Semaste ::unlink (output_file_path); 1487254721Semaste // Handshake with the monitor thread, or just let it know in advance that 1488254721Semaste // it can delete "shell_info" in case we timed out and were not able to kill 1489254721Semaste // the process... 1490254721Semaste return error; 1491254721Semaste} 1492254721Semaste 1493254721Semaste 1494254721Semasteuint32_t 1495254721SemasteHost::GetNumberCPUS () 1496254721Semaste{ 1497254721Semaste static uint32_t g_num_cores = UINT32_MAX; 1498254721Semaste if (g_num_cores == UINT32_MAX) 1499254721Semaste { 1500254721Semaste#if defined(__APPLE__) or defined (__linux__) or defined (__FreeBSD__) or defined (__FreeBSD_kernel__) 1501254721Semaste 1502254721Semaste g_num_cores = ::sysconf(_SC_NPROCESSORS_ONLN); 1503254721Semaste 1504254721Semaste#elif defined(_WIN32) || defined(__WIN32__) || defined(__CYGWIN__) 1505254721Semaste 1506254721Semaste // Header file for this might need to be included at the top of this file 1507254721Semaste SYSTEM_INFO system_info; 1508254721Semaste ::GetSystemInfo (&system_info); 1509254721Semaste g_num_cores = system_info.dwNumberOfProcessors; 1510254721Semaste 1511254721Semaste#else 1512254721Semaste 1513254721Semaste // Assume POSIX support if a host specific case has not been supplied above 1514254721Semaste g_num_cores = 0; 1515254721Semaste int num_cores = 0; 1516254721Semaste size_t num_cores_len = sizeof(num_cores); 1517254721Semaste#ifdef HW_AVAILCPU 1518254721Semaste int mib[] = { CTL_HW, HW_AVAILCPU }; 1519254721Semaste#else 1520254721Semaste int mib[] = { CTL_HW, HW_NCPU }; 1521254721Semaste#endif 1522254721Semaste 1523254721Semaste /* get the number of CPUs from the system */ 1524254721Semaste if (sysctl(mib, sizeof(mib)/sizeof(int), &num_cores, &num_cores_len, NULL, 0) == 0 && (num_cores > 0)) 1525254721Semaste { 1526254721Semaste g_num_cores = num_cores; 1527254721Semaste } 1528254721Semaste else 1529254721Semaste { 1530254721Semaste mib[1] = HW_NCPU; 1531254721Semaste num_cores_len = sizeof(num_cores); 1532254721Semaste if (sysctl(mib, sizeof(mib)/sizeof(int), &num_cores, &num_cores_len, NULL, 0) == 0 && (num_cores > 0)) 1533254721Semaste { 1534254721Semaste if (num_cores > 0) 1535254721Semaste g_num_cores = num_cores; 1536254721Semaste } 1537254721Semaste } 1538254721Semaste#endif 1539254721Semaste } 1540254721Semaste return g_num_cores; 1541254721Semaste} 1542254721Semaste 1543254721Semaste 1544254721Semaste 1545254721Semaste#if !defined (__APPLE__) 1546254721Semastebool 1547254721SemasteHost::OpenFileInExternalEditor (const FileSpec &file_spec, uint32_t line_no) 1548254721Semaste{ 1549254721Semaste return false; 1550254721Semaste} 1551254721Semaste 1552254721Semastevoid 1553254721SemasteHost::SetCrashDescriptionWithFormat (const char *format, ...) 1554254721Semaste{ 1555254721Semaste} 1556254721Semaste 1557254721Semastevoid 1558254721SemasteHost::SetCrashDescription (const char *description) 1559254721Semaste{ 1560254721Semaste} 1561254721Semaste 1562254721Semastelldb::pid_t 1563254721SemasteLaunchApplication (const FileSpec &app_file_spec) 1564254721Semaste{ 1565254721Semaste return LLDB_INVALID_PROCESS_ID; 1566254721Semaste} 1567254721Semaste 1568254721Semaste#endif 1569