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