Host.cpp revision d1040dd360c07305a30d33b5d4501cb9dfb03114
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/Host/Host.h"
11#include "lldb/Core/ArchSpec.h"
12#include "lldb/Core/ConstString.h"
13#include "lldb/Core/Debugger.h"
14#include "lldb/Core/Error.h"
15#include "lldb/Core/Log.h"
16#include "lldb/Core/StreamString.h"
17#include "lldb/Host/Config.h"
18#include "lldb/Host/Endian.h"
19#include "lldb/Host/FileSpec.h"
20#include "lldb/Host/Mutex.h"
21#include "lldb/Target/Process.h"
22#include "lldb/Target/TargetList.h"
23
24#include "llvm/Support/Host.h"
25#include "llvm/Support/MachO.h"
26
27#include <dlfcn.h>
28#include <errno.h>
29#include <grp.h>
30#include <limits.h>
31#include <netdb.h>
32#include <pwd.h>
33#include <sys/types.h>
34
35
36#if defined (__APPLE__)
37
38#include <dispatch/dispatch.h>
39#include <libproc.h>
40#include <mach-o/dyld.h>
41#include <sys/sysctl.h>
42
43
44#elif defined (__linux__)
45
46#include <sys/wait.h>
47
48#elif defined (__FreeBSD__)
49
50#include <sys/wait.h>
51#include <sys/sysctl.h>
52#include <pthread_np.h>
53
54#endif
55
56using namespace lldb;
57using namespace lldb_private;
58
59
60#if !defined (__APPLE__)
61struct MonitorInfo
62{
63    lldb::pid_t pid;                            // The process ID to monitor
64    Host::MonitorChildProcessCallback callback; // The callback function to call when "pid" exits or signals
65    void *callback_baton;                       // The callback baton for the callback function
66    bool monitor_signals;                       // If true, call the callback when "pid" gets signaled.
67};
68
69static void *
70MonitorChildProcessThreadFunction (void *arg);
71
72lldb::thread_t
73Host::StartMonitoringChildProcess
74(
75    Host::MonitorChildProcessCallback callback,
76    void *callback_baton,
77    lldb::pid_t pid,
78    bool monitor_signals
79)
80{
81    lldb::thread_t thread = LLDB_INVALID_HOST_THREAD;
82    MonitorInfo * info_ptr = new MonitorInfo();
83
84    info_ptr->pid = pid;
85    info_ptr->callback = callback;
86    info_ptr->callback_baton = callback_baton;
87    info_ptr->monitor_signals = monitor_signals;
88
89    char thread_name[256];
90    ::snprintf (thread_name, sizeof(thread_name), "<lldb.host.wait4(pid=%i)>", pid);
91    thread = ThreadCreate (thread_name,
92                           MonitorChildProcessThreadFunction,
93                           info_ptr,
94                           NULL);
95
96    return thread;
97}
98
99//------------------------------------------------------------------
100// Scoped class that will disable thread canceling when it is
101// constructed, and exception safely restore the previous value it
102// when it goes out of scope.
103//------------------------------------------------------------------
104class ScopedPThreadCancelDisabler
105{
106public:
107    ScopedPThreadCancelDisabler()
108    {
109        // Disable the ability for this thread to be cancelled
110        int err = ::pthread_setcancelstate (PTHREAD_CANCEL_DISABLE, &m_old_state);
111        if (err != 0)
112            m_old_state = -1;
113
114    }
115
116    ~ScopedPThreadCancelDisabler()
117    {
118        // Restore the ability for this thread to be cancelled to what it
119        // previously was.
120        if (m_old_state != -1)
121            ::pthread_setcancelstate (m_old_state, 0);
122    }
123private:
124    int m_old_state;    // Save the old cancelability state.
125};
126
127static void *
128MonitorChildProcessThreadFunction (void *arg)
129{
130    LogSP log(lldb_private::GetLogIfAllCategoriesSet (LIBLLDB_LOG_PROCESS));
131    const char *function = __FUNCTION__;
132    if (log)
133        log->Printf ("%s (arg = %p) thread starting...", function, arg);
134
135    MonitorInfo *info = (MonitorInfo *)arg;
136
137    const Host::MonitorChildProcessCallback callback = info->callback;
138    void * const callback_baton = info->callback_baton;
139    const lldb::pid_t pid = info->pid;
140    const bool monitor_signals = info->monitor_signals;
141
142    delete info;
143
144    int status = -1;
145    const int options = 0;
146    while (1)
147    {
148        log = lldb_private::GetLogIfAllCategoriesSet (LIBLLDB_LOG_PROCESS);
149        if (log)
150            log->Printf("%s ::wait_pid (pid = %i, &status, options = %i)...", function, pid, options);
151
152        // Wait for all child processes
153        ::pthread_testcancel ();
154        const lldb::pid_t wait_pid = ::waitpid (pid, &status, options);
155        ::pthread_testcancel ();
156
157        if (wait_pid == -1)
158        {
159            if (errno == EINTR)
160                continue;
161            else
162                break;
163        }
164        else if (wait_pid == pid)
165        {
166            bool exited = false;
167            int signal = 0;
168            int exit_status = 0;
169            const char *status_cstr = NULL;
170            if (WIFSTOPPED(status))
171            {
172                signal = WSTOPSIG(status);
173                status_cstr = "STOPPED";
174            }
175            else if (WIFEXITED(status))
176            {
177                exit_status = WEXITSTATUS(status);
178                status_cstr = "EXITED";
179                exited = true;
180            }
181            else if (WIFSIGNALED(status))
182            {
183                signal = WTERMSIG(status);
184                status_cstr = "SIGNALED";
185                exited = true;
186                exit_status = -1;
187            }
188            else
189            {
190                status_cstr = "(\?\?\?)";
191            }
192
193            // Scope for pthread_cancel_disabler
194            {
195                ScopedPThreadCancelDisabler pthread_cancel_disabler;
196
197                log = lldb_private::GetLogIfAllCategoriesSet (LIBLLDB_LOG_PROCESS);
198                if (log)
199                    log->Printf ("%s ::waitpid (pid = %i, &status, options = %i) => pid = %i, status = 0x%8.8x (%s), signal = %i, exit_state = %i",
200                                 function,
201                                 wait_pid,
202                                 options,
203                                 pid,
204                                 status,
205                                 status_cstr,
206                                 signal,
207                                 exit_status);
208
209                if (exited || (signal != 0 && monitor_signals))
210                {
211                    bool callback_return = false;
212                    if (callback)
213                        callback_return = callback (callback_baton, pid, exited, signal, exit_status);
214
215                    // If our process exited, then this thread should exit
216                    if (exited)
217                        break;
218                    // If the callback returns true, it means this process should
219                    // exit
220                    if (callback_return)
221                        break;
222                }
223            }
224        }
225    }
226
227    log = lldb_private::GetLogIfAllCategoriesSet (LIBLLDB_LOG_PROCESS);
228    if (log)
229        log->Printf ("%s (arg = %p) thread exiting...", __FUNCTION__, arg);
230
231    return NULL;
232}
233
234
235void
236Host::SystemLog (SystemLogType type, const char *format, va_list args)
237{
238    vfprintf (stderr, format, args);
239}
240
241#endif // #if !defined (__APPLE__)
242
243void
244Host::SystemLog (SystemLogType type, const char *format, ...)
245{
246    va_list args;
247    va_start (args, format);
248    SystemLog (type, format, args);
249    va_end (args);
250}
251
252size_t
253Host::GetPageSize()
254{
255    return ::getpagesize();
256}
257
258const ArchSpec &
259Host::GetArchitecture (SystemDefaultArchitecture arch_kind)
260{
261    static bool g_supports_32 = false;
262    static bool g_supports_64 = false;
263    static ArchSpec g_host_arch_32;
264    static ArchSpec g_host_arch_64;
265
266#if defined (__APPLE__)
267
268    // Apple is different in that it can support both 32 and 64 bit executables
269    // in the same operating system running concurrently. Here we detect the
270    // correct host architectures for both 32 and 64 bit including if 64 bit
271    // executables are supported on the system.
272
273    if (g_supports_32 == false && g_supports_64 == false)
274    {
275        // All apple systems support 32 bit execution.
276        g_supports_32 = true;
277        uint32_t cputype, cpusubtype;
278        uint32_t is_64_bit_capable = false;
279        size_t len = sizeof(cputype);
280        ArchSpec host_arch;
281        // These will tell us about the kernel architecture, which even on a 64
282        // bit machine can be 32 bit...
283        if  (::sysctlbyname("hw.cputype", &cputype, &len, NULL, 0) == 0)
284        {
285            len = sizeof (cpusubtype);
286            if (::sysctlbyname("hw.cpusubtype", &cpusubtype, &len, NULL, 0) != 0)
287                cpusubtype = CPU_TYPE_ANY;
288
289            len = sizeof (is_64_bit_capable);
290            if  (::sysctlbyname("hw.cpu64bit_capable", &is_64_bit_capable, &len, NULL, 0) == 0)
291            {
292                if (is_64_bit_capable)
293                    g_supports_64 = true;
294            }
295
296            if (is_64_bit_capable)
297            {
298#if defined (__i386__) || defined (__x86_64__)
299                if (cpusubtype == CPU_SUBTYPE_486)
300                    cpusubtype = CPU_SUBTYPE_I386_ALL;
301#endif
302                if (cputype & CPU_ARCH_ABI64)
303                {
304                    // We have a 64 bit kernel on a 64 bit system
305                    g_host_arch_32.SetArchitecture (eArchTypeMachO, ~(CPU_ARCH_MASK) & cputype, cpusubtype);
306                    g_host_arch_64.SetArchitecture (eArchTypeMachO, cputype, cpusubtype);
307                }
308                else
309                {
310                    // We have a 32 bit kernel on a 64 bit system
311                    g_host_arch_32.SetArchitecture (eArchTypeMachO, cputype, cpusubtype);
312                    cputype |= CPU_ARCH_ABI64;
313                    g_host_arch_64.SetArchitecture (eArchTypeMachO, cputype, cpusubtype);
314                }
315            }
316            else
317            {
318                g_host_arch_32.SetArchitecture (eArchTypeMachO, cputype, cpusubtype);
319                g_host_arch_64.Clear();
320            }
321        }
322    }
323
324#else // #if defined (__APPLE__)
325
326    if (g_supports_32 == false && g_supports_64 == false)
327    {
328        llvm::Triple triple(llvm::sys::getDefaultTargetTriple());
329
330        g_host_arch_32.Clear();
331        g_host_arch_64.Clear();
332
333        switch (triple.getArch())
334        {
335        default:
336            g_host_arch_32.SetTriple(triple);
337            g_supports_32 = true;
338            break;
339
340        case llvm::Triple::x86_64:
341        case llvm::Triple::sparcv9:
342        case llvm::Triple::ppc64:
343        case llvm::Triple::cellspu:
344            g_host_arch_64.SetTriple(triple);
345            g_supports_64 = true;
346            break;
347        }
348
349        g_supports_32 = g_host_arch_32.IsValid();
350        g_supports_64 = g_host_arch_64.IsValid();
351    }
352
353#endif // #else for #if defined (__APPLE__)
354
355    if (arch_kind == eSystemDefaultArchitecture32)
356        return g_host_arch_32;
357    else if (arch_kind == eSystemDefaultArchitecture64)
358        return g_host_arch_64;
359
360    if (g_supports_64)
361        return g_host_arch_64;
362
363    return g_host_arch_32;
364}
365
366const ConstString &
367Host::GetVendorString()
368{
369    static ConstString g_vendor;
370    if (!g_vendor)
371    {
372#if defined (__APPLE__)
373        char ostype[64];
374        size_t len = sizeof(ostype);
375        if (::sysctlbyname("kern.ostype", &ostype, &len, NULL, 0) == 0)
376            g_vendor.SetCString (ostype);
377        else
378            g_vendor.SetCString("apple");
379#elif defined (__linux__)
380        g_vendor.SetCString("gnu");
381#elif defined (__FreeBSD__)
382        g_vendor.SetCString("freebsd");
383#endif
384    }
385    return g_vendor;
386}
387
388const ConstString &
389Host::GetOSString()
390{
391    static ConstString g_os_string;
392    if (!g_os_string)
393    {
394#if defined (__APPLE__)
395        g_os_string.SetCString("darwin");
396#elif defined (__linux__)
397        g_os_string.SetCString("linux");
398#elif defined (__FreeBSD__)
399        g_os_string.SetCString("freebsd");
400#endif
401    }
402    return g_os_string;
403}
404
405const ConstString &
406Host::GetTargetTriple()
407{
408    static ConstString g_host_triple;
409    if (!(g_host_triple))
410    {
411        StreamString triple;
412        triple.Printf("%s-%s-%s",
413                      GetArchitecture().GetArchitectureName(),
414                      GetVendorString().AsCString(),
415                      GetOSString().AsCString());
416
417        std::transform (triple.GetString().begin(),
418                        triple.GetString().end(),
419                        triple.GetString().begin(),
420                        ::tolower);
421
422        g_host_triple.SetCString(triple.GetString().c_str());
423    }
424    return g_host_triple;
425}
426
427lldb::pid_t
428Host::GetCurrentProcessID()
429{
430    return ::getpid();
431}
432
433lldb::tid_t
434Host::GetCurrentThreadID()
435{
436#if defined (__APPLE__)
437    return ::mach_thread_self();
438#elif defined(__FreeBSD__)
439    return lldb::tid_t(pthread_getthreadid_np());
440#else
441    return lldb::tid_t(pthread_self());
442#endif
443}
444
445const char *
446Host::GetSignalAsCString (int signo)
447{
448    switch (signo)
449    {
450    case SIGHUP:    return "SIGHUP";    // 1    hangup
451    case SIGINT:    return "SIGINT";    // 2    interrupt
452    case SIGQUIT:   return "SIGQUIT";   // 3    quit
453    case SIGILL:    return "SIGILL";    // 4    illegal instruction (not reset when caught)
454    case SIGTRAP:   return "SIGTRAP";   // 5    trace trap (not reset when caught)
455    case SIGABRT:   return "SIGABRT";   // 6    abort()
456#if  (defined(_POSIX_C_SOURCE) && !defined(_DARWIN_C_SOURCE))
457    case SIGPOLL:   return "SIGPOLL";   // 7    pollable event ([XSR] generated, not supported)
458#endif
459#if  !defined(_POSIX_C_SOURCE)
460    case SIGEMT:    return "SIGEMT";    // 7    EMT instruction
461#endif
462    case SIGFPE:    return "SIGFPE";    // 8    floating point exception
463    case SIGKILL:   return "SIGKILL";   // 9    kill (cannot be caught or ignored)
464    case SIGBUS:    return "SIGBUS";    // 10    bus error
465    case SIGSEGV:   return "SIGSEGV";   // 11    segmentation violation
466    case SIGSYS:    return "SIGSYS";    // 12    bad argument to system call
467    case SIGPIPE:   return "SIGPIPE";   // 13    write on a pipe with no one to read it
468    case SIGALRM:   return "SIGALRM";   // 14    alarm clock
469    case SIGTERM:   return "SIGTERM";   // 15    software termination signal from kill
470    case SIGURG:    return "SIGURG";    // 16    urgent condition on IO channel
471    case SIGSTOP:   return "SIGSTOP";   // 17    sendable stop signal not from tty
472    case SIGTSTP:   return "SIGTSTP";   // 18    stop signal from tty
473    case SIGCONT:   return "SIGCONT";   // 19    continue a stopped process
474    case SIGCHLD:   return "SIGCHLD";   // 20    to parent on child stop or exit
475    case SIGTTIN:   return "SIGTTIN";   // 21    to readers pgrp upon background tty read
476    case SIGTTOU:   return "SIGTTOU";   // 22    like TTIN for output if (tp->t_local&LTOSTOP)
477#if  !defined(_POSIX_C_SOURCE)
478    case SIGIO:     return "SIGIO";     // 23    input/output possible signal
479#endif
480    case SIGXCPU:   return "SIGXCPU";   // 24    exceeded CPU time limit
481    case SIGXFSZ:   return "SIGXFSZ";   // 25    exceeded file size limit
482    case SIGVTALRM: return "SIGVTALRM"; // 26    virtual time alarm
483    case SIGPROF:   return "SIGPROF";   // 27    profiling time alarm
484#if  !defined(_POSIX_C_SOURCE)
485    case SIGWINCH:  return "SIGWINCH";  // 28    window size changes
486    case SIGINFO:   return "SIGINFO";   // 29    information request
487#endif
488    case SIGUSR1:   return "SIGUSR1";   // 30    user defined signal 1
489    case SIGUSR2:   return "SIGUSR2";   // 31    user defined signal 2
490    default:
491        break;
492    }
493    return NULL;
494}
495
496void
497Host::WillTerminate ()
498{
499}
500
501#if !defined (__APPLE__) && !defined (__FreeBSD__) // see macosx/Host.mm
502void
503Host::ThreadCreated (const char *thread_name)
504{
505}
506
507void
508Host::Backtrace (Stream &strm, uint32_t max_frames)
509{
510    // TODO: Is there a way to backtrace the current process on linux? Other systems?
511}
512
513size_t
514Host::GetEnvironment (StringList &env)
515{
516    // TODO: Is there a way to the host environment for this process on linux? Other systems?
517    return 0;
518}
519
520#endif
521
522struct HostThreadCreateInfo
523{
524    std::string thread_name;
525    thread_func_t thread_fptr;
526    thread_arg_t thread_arg;
527
528    HostThreadCreateInfo (const char *name, thread_func_t fptr, thread_arg_t arg) :
529        thread_name (name ? name : ""),
530        thread_fptr (fptr),
531        thread_arg (arg)
532    {
533    }
534};
535
536static thread_result_t
537ThreadCreateTrampoline (thread_arg_t arg)
538{
539    HostThreadCreateInfo *info = (HostThreadCreateInfo *)arg;
540    Host::ThreadCreated (info->thread_name.c_str());
541    thread_func_t thread_fptr = info->thread_fptr;
542    thread_arg_t thread_arg = info->thread_arg;
543
544    LogSP log(lldb_private::GetLogIfAllCategoriesSet (LIBLLDB_LOG_THREAD));
545    if (log)
546        log->Printf("thread created");
547
548    delete info;
549    return thread_fptr (thread_arg);
550}
551
552lldb::thread_t
553Host::ThreadCreate
554(
555    const char *thread_name,
556    thread_func_t thread_fptr,
557    thread_arg_t thread_arg,
558    Error *error
559)
560{
561    lldb::thread_t thread = LLDB_INVALID_HOST_THREAD;
562
563    // Host::ThreadCreateTrampoline will delete this pointer for us.
564    HostThreadCreateInfo *info_ptr = new HostThreadCreateInfo (thread_name, thread_fptr, thread_arg);
565
566    int err = ::pthread_create (&thread, NULL, ThreadCreateTrampoline, info_ptr);
567    if (err == 0)
568    {
569        if (error)
570            error->Clear();
571        return thread;
572    }
573
574    if (error)
575        error->SetError (err, eErrorTypePOSIX);
576
577    return LLDB_INVALID_HOST_THREAD;
578}
579
580bool
581Host::ThreadCancel (lldb::thread_t thread, Error *error)
582{
583    int err = ::pthread_cancel (thread);
584    if (error)
585        error->SetError(err, eErrorTypePOSIX);
586    return err == 0;
587}
588
589bool
590Host::ThreadDetach (lldb::thread_t thread, Error *error)
591{
592    int err = ::pthread_detach (thread);
593    if (error)
594        error->SetError(err, eErrorTypePOSIX);
595    return err == 0;
596}
597
598bool
599Host::ThreadJoin (lldb::thread_t thread, thread_result_t *thread_result_ptr, Error *error)
600{
601    int err = ::pthread_join (thread, thread_result_ptr);
602    if (error)
603        error->SetError(err, eErrorTypePOSIX);
604    return err == 0;
605}
606
607//------------------------------------------------------------------
608// Control access to a static file thread name map using a single
609// static function to avoid a static constructor.
610//------------------------------------------------------------------
611static const char *
612ThreadNameAccessor (bool get, lldb::pid_t pid, lldb::tid_t tid, const char *name)
613{
614    uint64_t pid_tid = ((uint64_t)pid << 32) | (uint64_t)tid;
615
616    static pthread_mutex_t g_mutex = PTHREAD_MUTEX_INITIALIZER;
617    Mutex::Locker locker(&g_mutex);
618
619    typedef std::map<uint64_t, std::string> thread_name_map;
620    // rdar://problem/8153284
621    // Fixed a crasher where during shutdown, loggings attempted to access the
622    // thread name but the static map instance had already been destructed.
623    // Another approach is to introduce a static guard object which monitors its
624    // own destruction and raises a flag, but this incurs more overhead.
625    static thread_name_map *g_thread_names_ptr = new thread_name_map();
626    thread_name_map &g_thread_names = *g_thread_names_ptr;
627
628    if (get)
629    {
630        // See if the thread name exists in our thread name pool
631        thread_name_map::iterator pos = g_thread_names.find(pid_tid);
632        if (pos != g_thread_names.end())
633            return pos->second.c_str();
634    }
635    else
636    {
637        // Set the thread name
638        g_thread_names[pid_tid] = name;
639    }
640    return NULL;
641}
642
643const char *
644Host::GetThreadName (lldb::pid_t pid, lldb::tid_t tid)
645{
646    const char *name = ThreadNameAccessor (true, pid, tid, NULL);
647    if (name == NULL)
648    {
649#if defined(__APPLE__) && MAC_OS_X_VERSION_MAX_ALLOWED > MAC_OS_X_VERSION_10_5
650        // We currently can only get the name of a thread in the current process.
651        if (pid == Host::GetCurrentProcessID())
652        {
653            char pthread_name[1024];
654            if (::pthread_getname_np (::pthread_from_mach_thread_np (tid), pthread_name, sizeof(pthread_name)) == 0)
655            {
656                if (pthread_name[0])
657                {
658                    // Set the thread in our string pool
659                    ThreadNameAccessor (false, pid, tid, pthread_name);
660                    // Get our copy of the thread name string
661                    name = ThreadNameAccessor (true, pid, tid, NULL);
662                }
663            }
664
665            if (name == NULL)
666            {
667                dispatch_queue_t current_queue = ::dispatch_get_current_queue ();
668                if (current_queue != NULL)
669                    name = dispatch_queue_get_label (current_queue);
670            }
671        }
672#endif
673    }
674    return name;
675}
676
677void
678Host::SetThreadName (lldb::pid_t pid, lldb::tid_t tid, const char *name)
679{
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#if defined(__APPLE__) && MAC_OS_X_VERSION_MAX_ALLOWED > MAC_OS_X_VERSION_10_5
689    // Set the pthread name if possible
690    if (pid == curr_pid && tid == curr_tid)
691    {
692        ::pthread_setname_np (name);
693    }
694#endif
695    ThreadNameAccessor (false, pid, tid, name);
696}
697
698FileSpec
699Host::GetProgramFileSpec ()
700{
701    static FileSpec g_program_filespec;
702    if (!g_program_filespec)
703    {
704#if defined (__APPLE__)
705        char program_fullpath[PATH_MAX];
706        // If DST is NULL, then return the number of bytes needed.
707        uint32_t len = sizeof(program_fullpath);
708        int err = _NSGetExecutablePath (program_fullpath, &len);
709        if (err == 0)
710            g_program_filespec.SetFile (program_fullpath, false);
711        else if (err == -1)
712        {
713            char *large_program_fullpath = (char *)::malloc (len + 1);
714
715            err = _NSGetExecutablePath (large_program_fullpath, &len);
716            if (err == 0)
717                g_program_filespec.SetFile (large_program_fullpath, false);
718
719            ::free (large_program_fullpath);
720        }
721#elif defined (__linux__)
722        char exe_path[PATH_MAX];
723        ssize_t len = readlink("/proc/self/exe", exe_path, sizeof(exe_path) - 1);
724        if (len > 0) {
725            exe_path[len] = 0;
726            g_program_filespec.SetFile(exe_path, false);
727        }
728#elif defined (__FreeBSD__)
729        int exe_path_mib[4] = { CTL_KERN, KERN_PROC, KERN_PROC_PATHNAME, getpid() };
730        size_t exe_path_size;
731        if (sysctl(exe_path_mib, 4, NULL, &exe_path_size, NULL, 0) == 0)
732        {
733            char *exe_path = new char[exe_path_size];
734            if (sysctl(exe_path_mib, 4, exe_path, &exe_path_size, NULL, 0) == 0)
735                g_program_filespec.SetFile(exe_path, false);
736            delete[] exe_path;
737        }
738#endif
739    }
740    return g_program_filespec;
741}
742
743FileSpec
744Host::GetModuleFileSpecForHostAddress (const void *host_addr)
745{
746    FileSpec module_filespec;
747    Dl_info info;
748    if (::dladdr (host_addr, &info))
749    {
750        if (info.dli_fname)
751            module_filespec.SetFile(info.dli_fname, true);
752    }
753    return module_filespec;
754}
755
756#if !defined (__APPLE__) // see Host.mm
757
758bool
759Host::GetBundleDirectory (const FileSpec &file, FileSpec &bundle)
760{
761    bundle.Clear();
762    return false;
763}
764
765bool
766Host::ResolveExecutableInBundle (FileSpec &file)
767{
768    return false;
769}
770#endif
771
772// Opaque info that tracks a dynamic library that was loaded
773struct DynamicLibraryInfo
774{
775    DynamicLibraryInfo (const FileSpec &fs, int o, void *h) :
776        file_spec (fs),
777        open_options (o),
778        handle (h)
779    {
780    }
781
782    const FileSpec file_spec;
783    uint32_t open_options;
784    void * handle;
785};
786
787void *
788Host::DynamicLibraryOpen (const FileSpec &file_spec, uint32_t options, Error &error)
789{
790    char path[PATH_MAX];
791    if (file_spec.GetPath(path, sizeof(path)))
792    {
793        int mode = 0;
794
795        if (options & eDynamicLibraryOpenOptionLazy)
796            mode |= RTLD_LAZY;
797        else
798            mode |= RTLD_NOW;
799
800
801        if (options & eDynamicLibraryOpenOptionLocal)
802            mode |= RTLD_LOCAL;
803        else
804            mode |= RTLD_GLOBAL;
805
806#ifdef LLDB_CONFIG_DLOPEN_RTLD_FIRST_SUPPORTED
807        if (options & eDynamicLibraryOpenOptionLimitGetSymbol)
808            mode |= RTLD_FIRST;
809#endif
810
811        void * opaque = ::dlopen (path, mode);
812
813        if (opaque)
814        {
815            error.Clear();
816            return new DynamicLibraryInfo (file_spec, options, opaque);
817        }
818        else
819        {
820            error.SetErrorString(::dlerror());
821        }
822    }
823    else
824    {
825        error.SetErrorString("failed to extract path");
826    }
827    return NULL;
828}
829
830Error
831Host::DynamicLibraryClose (void *opaque)
832{
833    Error error;
834    if (opaque == NULL)
835    {
836        error.SetErrorString ("invalid dynamic library handle");
837    }
838    else
839    {
840        DynamicLibraryInfo *dylib_info = (DynamicLibraryInfo *) opaque;
841        if (::dlclose (dylib_info->handle) != 0)
842        {
843            error.SetErrorString(::dlerror());
844        }
845
846        dylib_info->open_options = 0;
847        dylib_info->handle = 0;
848        delete dylib_info;
849    }
850    return error;
851}
852
853void *
854Host::DynamicLibraryGetSymbol (void *opaque, const char *symbol_name, Error &error)
855{
856    if (opaque == NULL)
857    {
858        error.SetErrorString ("invalid dynamic library handle");
859    }
860    else
861    {
862        DynamicLibraryInfo *dylib_info = (DynamicLibraryInfo *) opaque;
863
864        void *symbol_addr = ::dlsym (dylib_info->handle, symbol_name);
865        if (symbol_addr)
866        {
867#ifndef LLDB_CONFIG_DLOPEN_RTLD_FIRST_SUPPORTED
868            // This host doesn't support limiting searches to this shared library
869            // so we need to verify that the match came from this shared library
870            // if it was requested in the Host::DynamicLibraryOpen() function.
871            if (dylib_info->open_options & eDynamicLibraryOpenOptionLimitGetSymbol)
872            {
873                FileSpec match_dylib_spec (Host::GetModuleFileSpecForHostAddress (symbol_addr));
874                if (match_dylib_spec != dylib_info->file_spec)
875                {
876                    char dylib_path[PATH_MAX];
877                    if (dylib_info->file_spec.GetPath (dylib_path, sizeof(dylib_path)))
878                        error.SetErrorStringWithFormat ("symbol not found in \"%s\"", dylib_path);
879                    else
880                        error.SetErrorString ("symbol not found");
881                    return NULL;
882                }
883            }
884#endif
885            error.Clear();
886            return symbol_addr;
887        }
888        else
889        {
890            error.SetErrorString(::dlerror());
891        }
892    }
893    return NULL;
894}
895
896bool
897Host::GetLLDBPath (PathType path_type, FileSpec &file_spec)
898{
899    // To get paths related to LLDB we get the path to the executable that
900    // contains this function. On MacOSX this will be "LLDB.framework/.../LLDB",
901    // on linux this is assumed to be the "lldb" main executable. If LLDB on
902    // linux is actually in a shared library (lldb.so??) then this function will
903    // need to be modified to "do the right thing".
904
905    switch (path_type)
906    {
907    case ePathTypeLLDBShlibDir:
908        {
909            static ConstString g_lldb_so_dir;
910            if (!g_lldb_so_dir)
911            {
912                FileSpec lldb_file_spec (Host::GetModuleFileSpecForHostAddress ((void *)Host::GetLLDBPath));
913                g_lldb_so_dir = lldb_file_spec.GetDirectory();
914            }
915            file_spec.GetDirectory() = g_lldb_so_dir;
916            return file_spec.GetDirectory();
917        }
918        break;
919
920    case ePathTypeSupportExecutableDir:
921        {
922            static ConstString g_lldb_support_exe_dir;
923            if (!g_lldb_support_exe_dir)
924            {
925                FileSpec lldb_file_spec;
926                if (GetLLDBPath (ePathTypeLLDBShlibDir, lldb_file_spec))
927                {
928                    char raw_path[PATH_MAX];
929                    char resolved_path[PATH_MAX];
930                    lldb_file_spec.GetPath(raw_path, sizeof(raw_path));
931
932#if defined (__APPLE__)
933                    char *framework_pos = ::strstr (raw_path, "LLDB.framework");
934                    if (framework_pos)
935                    {
936                        framework_pos += strlen("LLDB.framework");
937#if !defined (__arm__)
938                        ::strncpy (framework_pos, "/Resources", PATH_MAX - (framework_pos - raw_path));
939#endif
940                    }
941#endif
942                    FileSpec::Resolve (raw_path, resolved_path, sizeof(resolved_path));
943                    g_lldb_support_exe_dir.SetCString(resolved_path);
944                }
945            }
946            file_spec.GetDirectory() = g_lldb_support_exe_dir;
947            return file_spec.GetDirectory();
948        }
949        break;
950
951    case ePathTypeHeaderDir:
952        {
953            static ConstString g_lldb_headers_dir;
954            if (!g_lldb_headers_dir)
955            {
956#if defined (__APPLE__)
957                FileSpec lldb_file_spec;
958                if (GetLLDBPath (ePathTypeLLDBShlibDir, lldb_file_spec))
959                {
960                    char raw_path[PATH_MAX];
961                    char resolved_path[PATH_MAX];
962                    lldb_file_spec.GetPath(raw_path, sizeof(raw_path));
963
964                    char *framework_pos = ::strstr (raw_path, "LLDB.framework");
965                    if (framework_pos)
966                    {
967                        framework_pos += strlen("LLDB.framework");
968                        ::strncpy (framework_pos, "/Headers", PATH_MAX - (framework_pos - raw_path));
969                    }
970                    FileSpec::Resolve (raw_path, resolved_path, sizeof(resolved_path));
971                    g_lldb_headers_dir.SetCString(resolved_path);
972                }
973#else
974                // TODO: Anyone know how we can determine this for linux? Other systems??
975                g_lldb_headers_dir.SetCString ("/opt/local/include/lldb");
976#endif
977            }
978            file_spec.GetDirectory() = g_lldb_headers_dir;
979            return file_spec.GetDirectory();
980        }
981        break;
982
983    case ePathTypePythonDir:
984        {
985            // TODO: Anyone know how we can determine this for linux? Other systems?
986            // For linux we are currently assuming the location of the lldb
987            // binary that contains this function is the directory that will
988            // contain lldb.so, lldb.py and embedded_interpreter.py...
989
990            static ConstString g_lldb_python_dir;
991            if (!g_lldb_python_dir)
992            {
993                FileSpec lldb_file_spec;
994                if (GetLLDBPath (ePathTypeLLDBShlibDir, lldb_file_spec))
995                {
996                    char raw_path[PATH_MAX];
997                    char resolved_path[PATH_MAX];
998                    lldb_file_spec.GetPath(raw_path, sizeof(raw_path));
999
1000#if defined (__APPLE__)
1001                    char *framework_pos = ::strstr (raw_path, "LLDB.framework");
1002                    if (framework_pos)
1003                    {
1004                        framework_pos += strlen("LLDB.framework");
1005                        ::strncpy (framework_pos, "/Resources/Python", PATH_MAX - (framework_pos - raw_path));
1006                    }
1007#endif
1008                    FileSpec::Resolve (raw_path, resolved_path, sizeof(resolved_path));
1009                    g_lldb_python_dir.SetCString(resolved_path);
1010                }
1011            }
1012            file_spec.GetDirectory() = g_lldb_python_dir;
1013            return file_spec.GetDirectory();
1014        }
1015        break;
1016
1017    case ePathTypeLLDBSystemPlugins:    // System plug-ins directory
1018        {
1019#if defined (__APPLE__)
1020            static ConstString g_lldb_system_plugin_dir;
1021            static bool g_lldb_system_plugin_dir_located = false;
1022            if (!g_lldb_system_plugin_dir_located)
1023            {
1024                g_lldb_system_plugin_dir_located = true;
1025                FileSpec lldb_file_spec;
1026                if (GetLLDBPath (ePathTypeLLDBShlibDir, lldb_file_spec))
1027                {
1028                    char raw_path[PATH_MAX];
1029                    char resolved_path[PATH_MAX];
1030                    lldb_file_spec.GetPath(raw_path, sizeof(raw_path));
1031
1032                    char *framework_pos = ::strstr (raw_path, "LLDB.framework");
1033                    if (framework_pos)
1034                    {
1035                        framework_pos += strlen("LLDB.framework");
1036                        ::strncpy (framework_pos, "/Resources/PlugIns", PATH_MAX - (framework_pos - raw_path));
1037                        FileSpec::Resolve (raw_path, resolved_path, sizeof(resolved_path));
1038                        g_lldb_system_plugin_dir.SetCString(resolved_path);
1039                    }
1040                    return false;
1041                }
1042            }
1043
1044            if (g_lldb_system_plugin_dir)
1045            {
1046                file_spec.GetDirectory() = g_lldb_system_plugin_dir;
1047                return true;
1048            }
1049#endif
1050            // TODO: where would system LLDB plug-ins be located on linux? Other systems?
1051            return false;
1052        }
1053        break;
1054
1055    case ePathTypeLLDBUserPlugins:      // User plug-ins directory
1056        {
1057#if defined (__APPLE__)
1058            static ConstString g_lldb_user_plugin_dir;
1059            if (!g_lldb_user_plugin_dir)
1060            {
1061                char user_plugin_path[PATH_MAX];
1062                if (FileSpec::Resolve ("~/Library/Application Support/LLDB/PlugIns",
1063                                       user_plugin_path,
1064                                       sizeof(user_plugin_path)))
1065                {
1066                    g_lldb_user_plugin_dir.SetCString(user_plugin_path);
1067                }
1068            }
1069            file_spec.GetDirectory() = g_lldb_user_plugin_dir;
1070            return file_spec.GetDirectory();
1071#endif
1072            // TODO: where would user LLDB plug-ins be located on linux? Other systems?
1073            return false;
1074        }
1075    default:
1076        assert (!"Unhandled PathType");
1077        break;
1078    }
1079
1080    return false;
1081}
1082
1083
1084bool
1085Host::GetHostname (std::string &s)
1086{
1087    char hostname[PATH_MAX];
1088    hostname[sizeof(hostname) - 1] = '\0';
1089    if (::gethostname (hostname, sizeof(hostname) - 1) == 0)
1090    {
1091        struct hostent* h = ::gethostbyname (hostname);
1092        if (h)
1093            s.assign (h->h_name);
1094        else
1095            s.assign (hostname);
1096        return true;
1097    }
1098    return false;
1099}
1100
1101const char *
1102Host::GetUserName (uint32_t uid, std::string &user_name)
1103{
1104    struct passwd user_info;
1105    struct passwd *user_info_ptr = &user_info;
1106    char user_buffer[PATH_MAX];
1107    size_t user_buffer_size = sizeof(user_buffer);
1108    if (::getpwuid_r (uid,
1109                      &user_info,
1110                      user_buffer,
1111                      user_buffer_size,
1112                      &user_info_ptr) == 0)
1113    {
1114        if (user_info_ptr)
1115        {
1116            user_name.assign (user_info_ptr->pw_name);
1117            return user_name.c_str();
1118        }
1119    }
1120    user_name.clear();
1121    return NULL;
1122}
1123
1124const char *
1125Host::GetGroupName (uint32_t gid, std::string &group_name)
1126{
1127    char group_buffer[PATH_MAX];
1128    size_t group_buffer_size = sizeof(group_buffer);
1129    struct group group_info;
1130    struct group *group_info_ptr = &group_info;
1131    // Try the threadsafe version first
1132    if (::getgrgid_r (gid,
1133                      &group_info,
1134                      group_buffer,
1135                      group_buffer_size,
1136                      &group_info_ptr) == 0)
1137    {
1138        if (group_info_ptr)
1139        {
1140            group_name.assign (group_info_ptr->gr_name);
1141            return group_name.c_str();
1142        }
1143    }
1144    else
1145    {
1146        // The threadsafe version isn't currently working
1147        // for me on darwin, but the non-threadsafe version
1148        // is, so I am calling it below.
1149        group_info_ptr = ::getgrgid (gid);
1150        if (group_info_ptr)
1151        {
1152            group_name.assign (group_info_ptr->gr_name);
1153            return group_name.c_str();
1154        }
1155    }
1156    group_name.clear();
1157    return NULL;
1158}
1159
1160#if !defined (__APPLE__) && !defined (__FreeBSD__) // see macosx/Host.mm
1161bool
1162Host::GetOSBuildString (std::string &s)
1163{
1164    s.clear();
1165    return false;
1166}
1167
1168bool
1169Host::GetOSKernelDescription (std::string &s)
1170{
1171    s.clear();
1172    return false;
1173}
1174#endif
1175
1176uint32_t
1177Host::GetUserID ()
1178{
1179    return getuid();
1180}
1181
1182uint32_t
1183Host::GetGroupID ()
1184{
1185    return getgid();
1186}
1187
1188uint32_t
1189Host::GetEffectiveUserID ()
1190{
1191    return geteuid();
1192}
1193
1194uint32_t
1195Host::GetEffectiveGroupID ()
1196{
1197    return getegid();
1198}
1199
1200#if !defined (__APPLE__)
1201uint32_t
1202Host::FindProcesses (const ProcessInstanceInfoMatch &match_info, ProcessInstanceInfoList &process_infos)
1203{
1204    process_infos.Clear();
1205    return process_infos.GetSize();
1206}
1207#endif
1208
1209#if !defined (__APPLE__) && !defined (__FreeBSD__)
1210bool
1211Host::GetProcessInfo (lldb::pid_t pid, ProcessInstanceInfo &process_info)
1212{
1213    process_info.Clear();
1214    return false;
1215}
1216#endif
1217
1218lldb::TargetSP
1219Host::GetDummyTarget (lldb_private::Debugger &debugger)
1220{
1221    static TargetSP dummy_target;
1222
1223    if (!dummy_target)
1224    {
1225        Error err = debugger.GetTargetList().CreateTarget(debugger,
1226                                                          FileSpec(),
1227                                                          Host::GetTargetTriple().AsCString(),
1228                                                          false,
1229                                                          NULL,
1230                                                          dummy_target);
1231    }
1232
1233    return dummy_target;
1234}
1235
1236#if !defined (__APPLE__)
1237bool
1238Host::OpenFileInExternalEditor (const FileSpec &file_spec, uint32_t line_no)
1239{
1240    return false;
1241}
1242
1243void
1244Host::SetCrashDescriptionWithFormat (const char *format, ...)
1245{
1246}
1247
1248void
1249Host::SetCrashDescription (const char *description)
1250{
1251}
1252
1253lldb::pid_t
1254LaunchApplication (const FileSpec &app_file_spec)
1255{
1256    return LLDB_INVALID_PROCESS_ID;
1257}
1258
1259#endif
1260