Host.cpp revision 0c2921f5b9dab2ca1832bb746ab3aa3f66fdd0b5
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 <dlfcn.h>
14#include <errno.h>
15#include <grp.h>
16#include <limits.h>
17#include <netdb.h>
18#include <pwd.h>
19#include <sys/sysctl.h>
20#include <sys/types.h>
21#include <unistd.h>
22
23#if defined (__APPLE__)
24
25#include <dispatch/dispatch.h>
26#include <libproc.h>
27#include <mach-o/dyld.h>
28#include <mach/mach_port.h>
29
30#elif defined (__linux__) || defined(__FreeBSD_kernel__)
31/*  Linux or the FreeBSD kernel with glibc (Debian KFreeBSD for example) */
32
33#include <sys/wait.h>
34
35#elif defined (__FreeBSD__)
36
37#include <sys/wait.h>
38#include <pthread_np.h>
39
40#endif
41
42#include "lldb/Host/Host.h"
43#include "lldb/Core/ArchSpec.h"
44#include "lldb/Core/ConstString.h"
45#include "lldb/Core/Debugger.h"
46#include "lldb/Core/Error.h"
47#include "lldb/Core/Log.h"
48#include "lldb/Core/StreamString.h"
49#include "lldb/Core/ThreadSafeSTLMap.h"
50#include "lldb/Host/Config.h"
51#include "lldb/Host/Endian.h"
52#include "lldb/Host/FileSpec.h"
53#include "lldb/Host/Mutex.h"
54#include "lldb/Target/Process.h"
55#include "lldb/Target/TargetList.h"
56
57#include "llvm/Support/Host.h"
58#include "llvm/Support/MachO.h"
59#include "llvm/ADT/Twine.h"
60
61
62
63
64
65using namespace lldb;
66using namespace lldb_private;
67
68
69#if !defined (__APPLE__)
70struct MonitorInfo
71{
72    lldb::pid_t pid;                            // The process ID to monitor
73    Host::MonitorChildProcessCallback callback; // The callback function to call when "pid" exits or signals
74    void *callback_baton;                       // The callback baton for the callback function
75    bool monitor_signals;                       // If true, call the callback when "pid" gets signaled.
76};
77
78static void *
79MonitorChildProcessThreadFunction (void *arg);
80
81lldb::thread_t
82Host::StartMonitoringChildProcess
83(
84    Host::MonitorChildProcessCallback callback,
85    void *callback_baton,
86    lldb::pid_t pid,
87    bool monitor_signals
88)
89{
90    lldb::thread_t thread = LLDB_INVALID_HOST_THREAD;
91    MonitorInfo * info_ptr = new MonitorInfo();
92
93    info_ptr->pid = pid;
94    info_ptr->callback = callback;
95    info_ptr->callback_baton = callback_baton;
96    info_ptr->monitor_signals = monitor_signals;
97
98    char thread_name[256];
99    ::snprintf (thread_name, sizeof(thread_name), "<lldb.host.wait4(pid=%" PRIu64 ")>", pid);
100    thread = ThreadCreate (thread_name,
101                           MonitorChildProcessThreadFunction,
102                           info_ptr,
103                           NULL);
104
105    return thread;
106}
107
108//------------------------------------------------------------------
109// Scoped class that will disable thread canceling when it is
110// constructed, and exception safely restore the previous value it
111// when it goes out of scope.
112//------------------------------------------------------------------
113class ScopedPThreadCancelDisabler
114{
115public:
116    ScopedPThreadCancelDisabler()
117    {
118        // Disable the ability for this thread to be cancelled
119        int err = ::pthread_setcancelstate (PTHREAD_CANCEL_DISABLE, &m_old_state);
120        if (err != 0)
121            m_old_state = -1;
122
123    }
124
125    ~ScopedPThreadCancelDisabler()
126    {
127        // Restore the ability for this thread to be cancelled to what it
128        // previously was.
129        if (m_old_state != -1)
130            ::pthread_setcancelstate (m_old_state, 0);
131    }
132private:
133    int m_old_state;    // Save the old cancelability state.
134};
135
136static void *
137MonitorChildProcessThreadFunction (void *arg)
138{
139    Log *log(lldb_private::GetLogIfAllCategoriesSet (LIBLLDB_LOG_PROCESS));
140    const char *function = __FUNCTION__;
141    if (log)
142        log->Printf ("%s (arg = %p) thread starting...", function, arg);
143
144    MonitorInfo *info = (MonitorInfo *)arg;
145
146    const Host::MonitorChildProcessCallback callback = info->callback;
147    void * const callback_baton = info->callback_baton;
148    const lldb::pid_t pid = info->pid;
149    const bool monitor_signals = info->monitor_signals;
150
151    delete info;
152
153    int status = -1;
154#if defined (__FreeBSD__)
155    #define __WALL 0
156#endif
157    const int options = __WALL;
158
159    while (1)
160    {
161        log = lldb_private::GetLogIfAllCategoriesSet (LIBLLDB_LOG_PROCESS);
162        if (log)
163            log->Printf("%s ::wait_pid (pid = %" PRIu64 ", &status, options = %i)...", function, pid, options);
164
165        // Wait for all child processes
166        ::pthread_testcancel ();
167        // Get signals from all children with same process group of pid
168        const lldb::pid_t wait_pid = ::waitpid (-1*pid, &status, options);
169        ::pthread_testcancel ();
170
171        if (wait_pid == -1)
172        {
173            if (errno == EINTR)
174                continue;
175            else
176                break;
177        }
178        else if (wait_pid > 0)
179        {
180            bool exited = false;
181            int signal = 0;
182            int exit_status = 0;
183            const char *status_cstr = NULL;
184            if (WIFSTOPPED(status))
185            {
186                signal = WSTOPSIG(status);
187                status_cstr = "STOPPED";
188            }
189            else if (WIFEXITED(status))
190            {
191                exit_status = WEXITSTATUS(status);
192                status_cstr = "EXITED";
193                if (wait_pid == pid)
194                    exited = true;
195            }
196            else if (WIFSIGNALED(status))
197            {
198                signal = WTERMSIG(status);
199                status_cstr = "SIGNALED";
200                if (wait_pid == pid) {
201                    exited = true;
202                    exit_status = -1;
203                }
204            }
205            else
206            {
207                status_cstr = "(\?\?\?)";
208            }
209
210            // Scope for pthread_cancel_disabler
211            {
212                ScopedPThreadCancelDisabler pthread_cancel_disabler;
213
214                log = lldb_private::GetLogIfAllCategoriesSet (LIBLLDB_LOG_PROCESS);
215                if (log)
216                    log->Printf ("%s ::waitpid (pid = %" PRIu64 ", &status, options = %i) => pid = %" PRIu64 ", status = 0x%8.8x (%s), signal = %i, exit_state = %i",
217                                 function,
218                                 wait_pid,
219                                 options,
220                                 pid,
221                                 status,
222                                 status_cstr,
223                                 signal,
224                                 exit_status);
225
226                if (exited || (signal != 0 && monitor_signals))
227                {
228                    bool callback_return = false;
229                    if (callback)
230                        callback_return = callback (callback_baton, wait_pid, exited, signal, exit_status);
231
232                    // If our process exited, then this thread should exit
233                    if (exited)
234                        break;
235                    // If the callback returns true, it means this process should
236                    // exit
237                    if (callback_return)
238                        break;
239                }
240            }
241        }
242    }
243
244    log = lldb_private::GetLogIfAllCategoriesSet (LIBLLDB_LOG_PROCESS);
245    if (log)
246        log->Printf ("%s (arg = %p) thread exiting...", __FUNCTION__, arg);
247
248    return NULL;
249}
250
251
252void
253Host::SystemLog (SystemLogType type, const char *format, va_list args)
254{
255    vfprintf (stderr, format, args);
256}
257
258#endif // #if !defined (__APPLE__)
259
260void
261Host::SystemLog (SystemLogType type, const char *format, ...)
262{
263    va_list args;
264    va_start (args, format);
265    SystemLog (type, format, args);
266    va_end (args);
267}
268
269size_t
270Host::GetPageSize()
271{
272    return ::getpagesize();
273}
274
275const ArchSpec &
276Host::GetArchitecture (SystemDefaultArchitecture arch_kind)
277{
278    static bool g_supports_32 = false;
279    static bool g_supports_64 = false;
280    static ArchSpec g_host_arch_32;
281    static ArchSpec g_host_arch_64;
282
283#if defined (__APPLE__)
284
285    // Apple is different in that it can support both 32 and 64 bit executables
286    // in the same operating system running concurrently. Here we detect the
287    // correct host architectures for both 32 and 64 bit including if 64 bit
288    // executables are supported on the system.
289
290    if (g_supports_32 == false && g_supports_64 == false)
291    {
292        // All apple systems support 32 bit execution.
293        g_supports_32 = true;
294        uint32_t cputype, cpusubtype;
295        uint32_t is_64_bit_capable = false;
296        size_t len = sizeof(cputype);
297        ArchSpec host_arch;
298        // These will tell us about the kernel architecture, which even on a 64
299        // bit machine can be 32 bit...
300        if  (::sysctlbyname("hw.cputype", &cputype, &len, NULL, 0) == 0)
301        {
302            len = sizeof (cpusubtype);
303            if (::sysctlbyname("hw.cpusubtype", &cpusubtype, &len, NULL, 0) != 0)
304                cpusubtype = CPU_TYPE_ANY;
305
306            len = sizeof (is_64_bit_capable);
307            if  (::sysctlbyname("hw.cpu64bit_capable", &is_64_bit_capable, &len, NULL, 0) == 0)
308            {
309                if (is_64_bit_capable)
310                    g_supports_64 = true;
311            }
312
313            if (is_64_bit_capable)
314            {
315#if defined (__i386__) || defined (__x86_64__)
316                if (cpusubtype == CPU_SUBTYPE_486)
317                    cpusubtype = CPU_SUBTYPE_I386_ALL;
318#endif
319                if (cputype & CPU_ARCH_ABI64)
320                {
321                    // We have a 64 bit kernel on a 64 bit system
322                    g_host_arch_32.SetArchitecture (eArchTypeMachO, ~(CPU_ARCH_MASK) & cputype, cpusubtype);
323                    g_host_arch_64.SetArchitecture (eArchTypeMachO, cputype, cpusubtype);
324                }
325                else
326                {
327                    // We have a 32 bit kernel on a 64 bit system
328                    g_host_arch_32.SetArchitecture (eArchTypeMachO, cputype, cpusubtype);
329                    cputype |= CPU_ARCH_ABI64;
330                    g_host_arch_64.SetArchitecture (eArchTypeMachO, cputype, cpusubtype);
331                }
332            }
333            else
334            {
335                g_host_arch_32.SetArchitecture (eArchTypeMachO, cputype, cpusubtype);
336                g_host_arch_64.Clear();
337            }
338        }
339    }
340
341#else // #if defined (__APPLE__)
342
343    if (g_supports_32 == false && g_supports_64 == false)
344    {
345        llvm::Triple triple(llvm::sys::getDefaultTargetTriple());
346
347        g_host_arch_32.Clear();
348        g_host_arch_64.Clear();
349
350        // If the OS is Linux, "unknown" in the vendor slot isn't what we want
351        // for the default triple.  It's probably an artifact of config.guess.
352        if (triple.getOS() == llvm::Triple::Linux && triple.getVendor() == llvm::Triple::UnknownVendor)
353            triple.setVendorName("");
354
355        switch (triple.getArch())
356        {
357        default:
358            g_host_arch_32.SetTriple(triple);
359            g_supports_32 = true;
360            break;
361
362        case llvm::Triple::x86_64:
363            g_host_arch_64.SetTriple(triple);
364            g_supports_64 = true;
365            g_host_arch_32.SetTriple(triple.get32BitArchVariant());
366            g_supports_32 = true;
367            break;
368
369        case llvm::Triple::sparcv9:
370        case llvm::Triple::ppc64:
371            g_host_arch_64.SetTriple(triple);
372            g_supports_64 = true;
373            break;
374        }
375
376        g_supports_32 = g_host_arch_32.IsValid();
377        g_supports_64 = g_host_arch_64.IsValid();
378    }
379
380#endif // #else for #if defined (__APPLE__)
381
382    if (arch_kind == eSystemDefaultArchitecture32)
383        return g_host_arch_32;
384    else if (arch_kind == eSystemDefaultArchitecture64)
385        return g_host_arch_64;
386
387    if (g_supports_64)
388        return g_host_arch_64;
389
390    return g_host_arch_32;
391}
392
393const ConstString &
394Host::GetVendorString()
395{
396    static ConstString g_vendor;
397    if (!g_vendor)
398    {
399        const ArchSpec &host_arch = GetArchitecture (eSystemDefaultArchitecture);
400        const llvm::StringRef &str_ref = host_arch.GetTriple().getVendorName();
401        g_vendor.SetCStringWithLength(str_ref.data(), str_ref.size());
402    }
403    return g_vendor;
404}
405
406const ConstString &
407Host::GetOSString()
408{
409    static ConstString g_os_string;
410    if (!g_os_string)
411    {
412        const ArchSpec &host_arch = GetArchitecture (eSystemDefaultArchitecture);
413        const llvm::StringRef &str_ref = host_arch.GetTriple().getOSName();
414        g_os_string.SetCStringWithLength(str_ref.data(), str_ref.size());
415    }
416    return g_os_string;
417}
418
419const ConstString &
420Host::GetTargetTriple()
421{
422    static ConstString g_host_triple;
423    if (!(g_host_triple))
424    {
425        const ArchSpec &host_arch = GetArchitecture (eSystemDefaultArchitecture);
426        g_host_triple.SetCString(host_arch.GetTriple().getTriple().c_str());
427    }
428    return g_host_triple;
429}
430
431lldb::pid_t
432Host::GetCurrentProcessID()
433{
434    return ::getpid();
435}
436
437lldb::tid_t
438Host::GetCurrentThreadID()
439{
440#if defined (__APPLE__)
441    // Calling "mach_port_deallocate()" bumps the reference count on the thread
442    // port, so we need to deallocate it. mach_task_self() doesn't bump the ref
443    // count.
444    thread_port_t thread_self = mach_thread_self();
445    mach_port_deallocate(mach_task_self(), thread_self);
446    return thread_self;
447#elif defined(__FreeBSD__)
448    return lldb::tid_t(pthread_getthreadid_np());
449#else
450    return lldb::tid_t(pthread_self());
451#endif
452}
453
454lldb::thread_t
455Host::GetCurrentThread ()
456{
457    return lldb::thread_t(pthread_self());
458}
459
460const char *
461Host::GetSignalAsCString (int signo)
462{
463    switch (signo)
464    {
465    case SIGHUP:    return "SIGHUP";    // 1    hangup
466    case SIGINT:    return "SIGINT";    // 2    interrupt
467    case SIGQUIT:   return "SIGQUIT";   // 3    quit
468    case SIGILL:    return "SIGILL";    // 4    illegal instruction (not reset when caught)
469    case SIGTRAP:   return "SIGTRAP";   // 5    trace trap (not reset when caught)
470    case SIGABRT:   return "SIGABRT";   // 6    abort()
471#if  (defined(_POSIX_C_SOURCE) && !defined(_DARWIN_C_SOURCE))
472    case SIGPOLL:   return "SIGPOLL";   // 7    pollable event ([XSR] generated, not supported)
473#endif
474#if  !defined(_POSIX_C_SOURCE)
475    case SIGEMT:    return "SIGEMT";    // 7    EMT instruction
476#endif
477    case SIGFPE:    return "SIGFPE";    // 8    floating point exception
478    case SIGKILL:   return "SIGKILL";   // 9    kill (cannot be caught or ignored)
479    case SIGBUS:    return "SIGBUS";    // 10    bus error
480    case SIGSEGV:   return "SIGSEGV";   // 11    segmentation violation
481    case SIGSYS:    return "SIGSYS";    // 12    bad argument to system call
482    case SIGPIPE:   return "SIGPIPE";   // 13    write on a pipe with no one to read it
483    case SIGALRM:   return "SIGALRM";   // 14    alarm clock
484    case SIGTERM:   return "SIGTERM";   // 15    software termination signal from kill
485    case SIGURG:    return "SIGURG";    // 16    urgent condition on IO channel
486    case SIGSTOP:   return "SIGSTOP";   // 17    sendable stop signal not from tty
487    case SIGTSTP:   return "SIGTSTP";   // 18    stop signal from tty
488    case SIGCONT:   return "SIGCONT";   // 19    continue a stopped process
489    case SIGCHLD:   return "SIGCHLD";   // 20    to parent on child stop or exit
490    case SIGTTIN:   return "SIGTTIN";   // 21    to readers pgrp upon background tty read
491    case SIGTTOU:   return "SIGTTOU";   // 22    like TTIN for output if (tp->t_local&LTOSTOP)
492#if  !defined(_POSIX_C_SOURCE)
493    case SIGIO:     return "SIGIO";     // 23    input/output possible signal
494#endif
495    case SIGXCPU:   return "SIGXCPU";   // 24    exceeded CPU time limit
496    case SIGXFSZ:   return "SIGXFSZ";   // 25    exceeded file size limit
497    case SIGVTALRM: return "SIGVTALRM"; // 26    virtual time alarm
498    case SIGPROF:   return "SIGPROF";   // 27    profiling time alarm
499#if  !defined(_POSIX_C_SOURCE)
500    case SIGWINCH:  return "SIGWINCH";  // 28    window size changes
501    case SIGINFO:   return "SIGINFO";   // 29    information request
502#endif
503    case SIGUSR1:   return "SIGUSR1";   // 30    user defined signal 1
504    case SIGUSR2:   return "SIGUSR2";   // 31    user defined signal 2
505    default:
506        break;
507    }
508    return NULL;
509}
510
511void
512Host::WillTerminate ()
513{
514}
515
516#if !defined (__APPLE__) && !defined (__FreeBSD__) && !defined (__linux__) // see macosx/Host.mm
517
518void
519Host::ThreadCreated (const char *thread_name)
520{
521}
522
523void
524Host::Backtrace (Stream &strm, uint32_t max_frames)
525{
526    // TODO: Is there a way to backtrace the current process on linux? Other systems?
527}
528
529size_t
530Host::GetEnvironment (StringList &env)
531{
532    // TODO: Is there a way to the host environment for this process on linux? Other systems?
533    return 0;
534}
535
536#endif // #if !defined (__APPLE__) && !defined (__FreeBSD__) && !defined (__linux__)
537
538struct HostThreadCreateInfo
539{
540    std::string thread_name;
541    thread_func_t thread_fptr;
542    thread_arg_t thread_arg;
543
544    HostThreadCreateInfo (const char *name, thread_func_t fptr, thread_arg_t arg) :
545        thread_name (name ? name : ""),
546        thread_fptr (fptr),
547        thread_arg (arg)
548    {
549    }
550};
551
552static thread_result_t
553ThreadCreateTrampoline (thread_arg_t arg)
554{
555    HostThreadCreateInfo *info = (HostThreadCreateInfo *)arg;
556    Host::ThreadCreated (info->thread_name.c_str());
557    thread_func_t thread_fptr = info->thread_fptr;
558    thread_arg_t thread_arg = info->thread_arg;
559
560    Log *log(lldb_private::GetLogIfAllCategoriesSet (LIBLLDB_LOG_THREAD));
561    if (log)
562        log->Printf("thread created");
563
564    delete info;
565    return thread_fptr (thread_arg);
566}
567
568lldb::thread_t
569Host::ThreadCreate
570(
571    const char *thread_name,
572    thread_func_t thread_fptr,
573    thread_arg_t thread_arg,
574    Error *error
575)
576{
577    lldb::thread_t thread = LLDB_INVALID_HOST_THREAD;
578
579    // Host::ThreadCreateTrampoline will delete this pointer for us.
580    HostThreadCreateInfo *info_ptr = new HostThreadCreateInfo (thread_name, thread_fptr, thread_arg);
581
582    int err = ::pthread_create (&thread, NULL, ThreadCreateTrampoline, info_ptr);
583    if (err == 0)
584    {
585        if (error)
586            error->Clear();
587        return thread;
588    }
589
590    if (error)
591        error->SetError (err, eErrorTypePOSIX);
592
593    return LLDB_INVALID_HOST_THREAD;
594}
595
596bool
597Host::ThreadCancel (lldb::thread_t thread, Error *error)
598{
599    int err = ::pthread_cancel (thread);
600    if (error)
601        error->SetError(err, eErrorTypePOSIX);
602    return err == 0;
603}
604
605bool
606Host::ThreadDetach (lldb::thread_t thread, Error *error)
607{
608    int err = ::pthread_detach (thread);
609    if (error)
610        error->SetError(err, eErrorTypePOSIX);
611    return err == 0;
612}
613
614bool
615Host::ThreadJoin (lldb::thread_t thread, thread_result_t *thread_result_ptr, Error *error)
616{
617    int err = ::pthread_join (thread, thread_result_ptr);
618    if (error)
619        error->SetError(err, eErrorTypePOSIX);
620    return err == 0;
621}
622
623
624std::string
625Host::GetThreadName (lldb::pid_t pid, lldb::tid_t tid)
626{
627    std::string thread_name;
628#if defined(__APPLE__) && MAC_OS_X_VERSION_MAX_ALLOWED > MAC_OS_X_VERSION_10_5
629    // We currently can only get the name of a thread in the current process.
630    if (pid == Host::GetCurrentProcessID())
631    {
632        char pthread_name[1024];
633        if (::pthread_getname_np (::pthread_from_mach_thread_np (tid), pthread_name, sizeof(pthread_name)) == 0)
634        {
635            if (pthread_name[0])
636            {
637                thread_name = pthread_name;
638            }
639        }
640        else
641        {
642            dispatch_queue_t current_queue = ::dispatch_get_current_queue ();
643            if (current_queue != NULL)
644            {
645                const char *queue_name = dispatch_queue_get_label (current_queue);
646                if (queue_name && queue_name[0])
647                {
648                    thread_name = queue_name;
649                }
650            }
651        }
652    }
653#endif
654    return thread_name;
655}
656
657bool
658Host::SetThreadName (lldb::pid_t pid, lldb::tid_t tid, const char *name)
659{
660#if defined(__APPLE__) && MAC_OS_X_VERSION_MAX_ALLOWED > MAC_OS_X_VERSION_10_5
661    lldb::pid_t curr_pid = Host::GetCurrentProcessID();
662    lldb::tid_t curr_tid = Host::GetCurrentThreadID();
663    if (pid == LLDB_INVALID_PROCESS_ID)
664        pid = curr_pid;
665
666    if (tid == LLDB_INVALID_THREAD_ID)
667        tid = curr_tid;
668
669    // Set the pthread name if possible
670    if (pid == curr_pid && tid == curr_tid)
671    {
672        if (::pthread_setname_np (name) == 0)
673            return true;
674    }
675    return false;
676#elif defined (__linux__)
677    void *fn = dlsym (RTLD_DEFAULT, "pthread_setname_np");
678    if (fn)
679    {
680        int (*pthread_setname_np_func)(pthread_t thread, const char *name);
681        *reinterpret_cast<void **> (&pthread_setname_np_func) = fn;
682
683        lldb::pid_t curr_pid = Host::GetCurrentProcessID();
684        lldb::tid_t curr_tid = Host::GetCurrentThreadID();
685
686        if (pid == LLDB_INVALID_PROCESS_ID)
687            pid = curr_pid;
688
689        if (tid == LLDB_INVALID_THREAD_ID)
690            tid = curr_tid;
691
692        if (pid == curr_pid)
693        {
694            if (pthread_setname_np_func (tid, name) == 0)
695                return true;
696        }
697    }
698    return false;
699#else
700    return false;
701#endif
702}
703
704FileSpec
705Host::GetProgramFileSpec ()
706{
707    static FileSpec g_program_filespec;
708    if (!g_program_filespec)
709    {
710#if defined (__APPLE__)
711        char program_fullpath[PATH_MAX];
712        // If DST is NULL, then return the number of bytes needed.
713        uint32_t len = sizeof(program_fullpath);
714        int err = _NSGetExecutablePath (program_fullpath, &len);
715        if (err == 0)
716            g_program_filespec.SetFile (program_fullpath, false);
717        else if (err == -1)
718        {
719            char *large_program_fullpath = (char *)::malloc (len + 1);
720
721            err = _NSGetExecutablePath (large_program_fullpath, &len);
722            if (err == 0)
723                g_program_filespec.SetFile (large_program_fullpath, false);
724
725            ::free (large_program_fullpath);
726        }
727#elif defined (__linux__)
728        char exe_path[PATH_MAX];
729        ssize_t len = readlink("/proc/self/exe", exe_path, sizeof(exe_path) - 1);
730        if (len > 0) {
731            exe_path[len] = 0;
732            g_program_filespec.SetFile(exe_path, false);
733        }
734#elif defined (__FreeBSD__)
735        int exe_path_mib[4] = { CTL_KERN, KERN_PROC, KERN_PROC_PATHNAME, getpid() };
736        size_t exe_path_size;
737        if (sysctl(exe_path_mib, 4, NULL, &exe_path_size, NULL, 0) == 0)
738        {
739            char *exe_path = new char[exe_path_size];
740            if (sysctl(exe_path_mib, 4, exe_path, &exe_path_size, NULL, 0) == 0)
741                g_program_filespec.SetFile(exe_path, false);
742            delete[] exe_path;
743        }
744#endif
745    }
746    return g_program_filespec;
747}
748
749FileSpec
750Host::GetModuleFileSpecForHostAddress (const void *host_addr)
751{
752    FileSpec module_filespec;
753    Dl_info info;
754    if (::dladdr (host_addr, &info))
755    {
756        if (info.dli_fname)
757            module_filespec.SetFile(info.dli_fname, true);
758    }
759    return module_filespec;
760}
761
762#if !defined (__APPLE__) // see Host.mm
763
764bool
765Host::GetBundleDirectory (const FileSpec &file, FileSpec &bundle)
766{
767    bundle.Clear();
768    return false;
769}
770
771bool
772Host::ResolveExecutableInBundle (FileSpec &file)
773{
774    return false;
775}
776#endif
777
778// Opaque info that tracks a dynamic library that was loaded
779struct DynamicLibraryInfo
780{
781    DynamicLibraryInfo (const FileSpec &fs, int o, void *h) :
782        file_spec (fs),
783        open_options (o),
784        handle (h)
785    {
786    }
787
788    const FileSpec file_spec;
789    uint32_t open_options;
790    void * handle;
791};
792
793void *
794Host::DynamicLibraryOpen (const FileSpec &file_spec, uint32_t options, Error &error)
795{
796    char path[PATH_MAX];
797    if (file_spec.GetPath(path, sizeof(path)))
798    {
799        int mode = 0;
800
801        if (options & eDynamicLibraryOpenOptionLazy)
802            mode |= RTLD_LAZY;
803        else
804            mode |= RTLD_NOW;
805
806
807        if (options & eDynamicLibraryOpenOptionLocal)
808            mode |= RTLD_LOCAL;
809        else
810            mode |= RTLD_GLOBAL;
811
812#ifdef LLDB_CONFIG_DLOPEN_RTLD_FIRST_SUPPORTED
813        if (options & eDynamicLibraryOpenOptionLimitGetSymbol)
814            mode |= RTLD_FIRST;
815#endif
816
817        void * opaque = ::dlopen (path, mode);
818
819        if (opaque)
820        {
821            error.Clear();
822            return new DynamicLibraryInfo (file_spec, options, opaque);
823        }
824        else
825        {
826            error.SetErrorString(::dlerror());
827        }
828    }
829    else
830    {
831        error.SetErrorString("failed to extract path");
832    }
833    return NULL;
834}
835
836Error
837Host::DynamicLibraryClose (void *opaque)
838{
839    Error error;
840    if (opaque == NULL)
841    {
842        error.SetErrorString ("invalid dynamic library handle");
843    }
844    else
845    {
846        DynamicLibraryInfo *dylib_info = (DynamicLibraryInfo *) opaque;
847        if (::dlclose (dylib_info->handle) != 0)
848        {
849            error.SetErrorString(::dlerror());
850        }
851
852        dylib_info->open_options = 0;
853        dylib_info->handle = 0;
854        delete dylib_info;
855    }
856    return error;
857}
858
859void *
860Host::DynamicLibraryGetSymbol (void *opaque, const char *symbol_name, Error &error)
861{
862    if (opaque == NULL)
863    {
864        error.SetErrorString ("invalid dynamic library handle");
865    }
866    else
867    {
868        DynamicLibraryInfo *dylib_info = (DynamicLibraryInfo *) opaque;
869
870        void *symbol_addr = ::dlsym (dylib_info->handle, symbol_name);
871        if (symbol_addr)
872        {
873#ifndef LLDB_CONFIG_DLOPEN_RTLD_FIRST_SUPPORTED
874            // This host doesn't support limiting searches to this shared library
875            // so we need to verify that the match came from this shared library
876            // if it was requested in the Host::DynamicLibraryOpen() function.
877            if (dylib_info->open_options & eDynamicLibraryOpenOptionLimitGetSymbol)
878            {
879                FileSpec match_dylib_spec (Host::GetModuleFileSpecForHostAddress (symbol_addr));
880                if (match_dylib_spec != dylib_info->file_spec)
881                {
882                    char dylib_path[PATH_MAX];
883                    if (dylib_info->file_spec.GetPath (dylib_path, sizeof(dylib_path)))
884                        error.SetErrorStringWithFormat ("symbol not found in \"%s\"", dylib_path);
885                    else
886                        error.SetErrorString ("symbol not found");
887                    return NULL;
888                }
889            }
890#endif
891            error.Clear();
892            return symbol_addr;
893        }
894        else
895        {
896            error.SetErrorString(::dlerror());
897        }
898    }
899    return NULL;
900}
901
902bool
903Host::GetLLDBPath (PathType path_type, FileSpec &file_spec)
904{
905    // To get paths related to LLDB we get the path to the executable that
906    // contains this function. On MacOSX this will be "LLDB.framework/.../LLDB",
907    // on linux this is assumed to be the "lldb" main executable. If LLDB on
908    // linux is actually in a shared library (lldb.so??) then this function will
909    // need to be modified to "do the right thing".
910
911    switch (path_type)
912    {
913    case ePathTypeLLDBShlibDir:
914        {
915            static ConstString g_lldb_so_dir;
916            if (!g_lldb_so_dir)
917            {
918                FileSpec lldb_file_spec (Host::GetModuleFileSpecForHostAddress ((void *)Host::GetLLDBPath));
919                g_lldb_so_dir = lldb_file_spec.GetDirectory();
920            }
921            file_spec.GetDirectory() = g_lldb_so_dir;
922            return file_spec.GetDirectory();
923        }
924        break;
925
926    case ePathTypeSupportExecutableDir:
927        {
928            static ConstString g_lldb_support_exe_dir;
929            if (!g_lldb_support_exe_dir)
930            {
931                FileSpec lldb_file_spec;
932                if (GetLLDBPath (ePathTypeLLDBShlibDir, lldb_file_spec))
933                {
934                    char raw_path[PATH_MAX];
935                    char resolved_path[PATH_MAX];
936                    lldb_file_spec.GetPath(raw_path, sizeof(raw_path));
937
938#if defined (__APPLE__)
939                    char *framework_pos = ::strstr (raw_path, "LLDB.framework");
940                    if (framework_pos)
941                    {
942                        framework_pos += strlen("LLDB.framework");
943#if !defined (__arm__)
944                        ::strncpy (framework_pos, "/Resources", PATH_MAX - (framework_pos - raw_path));
945#endif
946                    }
947#endif
948                    FileSpec::Resolve (raw_path, resolved_path, sizeof(resolved_path));
949                    g_lldb_support_exe_dir.SetCString(resolved_path);
950                }
951            }
952            file_spec.GetDirectory() = g_lldb_support_exe_dir;
953            return file_spec.GetDirectory();
954        }
955        break;
956
957    case ePathTypeHeaderDir:
958        {
959            static ConstString g_lldb_headers_dir;
960            if (!g_lldb_headers_dir)
961            {
962#if defined (__APPLE__)
963                FileSpec lldb_file_spec;
964                if (GetLLDBPath (ePathTypeLLDBShlibDir, lldb_file_spec))
965                {
966                    char raw_path[PATH_MAX];
967                    char resolved_path[PATH_MAX];
968                    lldb_file_spec.GetPath(raw_path, sizeof(raw_path));
969
970                    char *framework_pos = ::strstr (raw_path, "LLDB.framework");
971                    if (framework_pos)
972                    {
973                        framework_pos += strlen("LLDB.framework");
974                        ::strncpy (framework_pos, "/Headers", PATH_MAX - (framework_pos - raw_path));
975                    }
976                    FileSpec::Resolve (raw_path, resolved_path, sizeof(resolved_path));
977                    g_lldb_headers_dir.SetCString(resolved_path);
978                }
979#else
980                // TODO: Anyone know how we can determine this for linux? Other systems??
981                g_lldb_headers_dir.SetCString ("/opt/local/include/lldb");
982#endif
983            }
984            file_spec.GetDirectory() = g_lldb_headers_dir;
985            return file_spec.GetDirectory();
986        }
987        break;
988
989    case ePathTypePythonDir:
990        {
991            static ConstString g_lldb_python_dir;
992            if (!g_lldb_python_dir)
993            {
994                FileSpec lldb_file_spec;
995                if (GetLLDBPath (ePathTypeLLDBShlibDir, lldb_file_spec))
996                {
997                    char raw_path[PATH_MAX];
998                    char resolved_path[PATH_MAX];
999                    lldb_file_spec.GetPath(raw_path, sizeof(raw_path));
1000
1001#if defined (__APPLE__)
1002                    char *framework_pos = ::strstr (raw_path, "LLDB.framework");
1003                    if (framework_pos)
1004                    {
1005                        framework_pos += strlen("LLDB.framework");
1006                        ::strncpy (framework_pos, "/Resources/Python", PATH_MAX - (framework_pos - raw_path));
1007                    }
1008#else
1009                    llvm::Twine python_version_dir;
1010                    python_version_dir = "/python"
1011                                       + llvm::Twine(PY_MAJOR_VERSION)
1012                                       + "."
1013                                       + llvm::Twine(PY_MINOR_VERSION)
1014                                       + "/site-packages";
1015
1016                    // We may get our string truncated. Should we protect
1017                    // this with an assert?
1018
1019                    ::strncat(raw_path, python_version_dir.str().c_str(),
1020                              sizeof(raw_path) - strlen(raw_path) - 1);
1021
1022#endif
1023                    FileSpec::Resolve (raw_path, resolved_path, sizeof(resolved_path));
1024                    g_lldb_python_dir.SetCString(resolved_path);
1025                }
1026            }
1027            file_spec.GetDirectory() = g_lldb_python_dir;
1028            return file_spec.GetDirectory();
1029        }
1030        break;
1031
1032    case ePathTypeLLDBSystemPlugins:    // System plug-ins directory
1033        {
1034#if defined (__APPLE__)
1035            static ConstString g_lldb_system_plugin_dir;
1036            static bool g_lldb_system_plugin_dir_located = false;
1037            if (!g_lldb_system_plugin_dir_located)
1038            {
1039                g_lldb_system_plugin_dir_located = true;
1040                FileSpec lldb_file_spec;
1041                if (GetLLDBPath (ePathTypeLLDBShlibDir, lldb_file_spec))
1042                {
1043                    char raw_path[PATH_MAX];
1044                    char resolved_path[PATH_MAX];
1045                    lldb_file_spec.GetPath(raw_path, sizeof(raw_path));
1046
1047                    char *framework_pos = ::strstr (raw_path, "LLDB.framework");
1048                    if (framework_pos)
1049                    {
1050                        framework_pos += strlen("LLDB.framework");
1051                        ::strncpy (framework_pos, "/Resources/PlugIns", PATH_MAX - (framework_pos - raw_path));
1052                        FileSpec::Resolve (raw_path, resolved_path, sizeof(resolved_path));
1053                        g_lldb_system_plugin_dir.SetCString(resolved_path);
1054                    }
1055                    return false;
1056                }
1057            }
1058
1059            if (g_lldb_system_plugin_dir)
1060            {
1061                file_spec.GetDirectory() = g_lldb_system_plugin_dir;
1062                return true;
1063            }
1064#endif
1065            // TODO: where would system LLDB plug-ins be located on linux? Other systems?
1066            return false;
1067        }
1068        break;
1069
1070    case ePathTypeLLDBUserPlugins:      // User plug-ins directory
1071        {
1072#if defined (__APPLE__)
1073            static ConstString g_lldb_user_plugin_dir;
1074            if (!g_lldb_user_plugin_dir)
1075            {
1076                char user_plugin_path[PATH_MAX];
1077                if (FileSpec::Resolve ("~/Library/Application Support/LLDB/PlugIns",
1078                                       user_plugin_path,
1079                                       sizeof(user_plugin_path)))
1080                {
1081                    g_lldb_user_plugin_dir.SetCString(user_plugin_path);
1082                }
1083            }
1084            file_spec.GetDirectory() = g_lldb_user_plugin_dir;
1085            return file_spec.GetDirectory();
1086#endif
1087            // TODO: where would user LLDB plug-ins be located on linux? Other systems?
1088            return false;
1089        }
1090    }
1091
1092    return false;
1093}
1094
1095
1096bool
1097Host::GetHostname (std::string &s)
1098{
1099    char hostname[PATH_MAX];
1100    hostname[sizeof(hostname) - 1] = '\0';
1101    if (::gethostname (hostname, sizeof(hostname) - 1) == 0)
1102    {
1103        struct hostent* h = ::gethostbyname (hostname);
1104        if (h)
1105            s.assign (h->h_name);
1106        else
1107            s.assign (hostname);
1108        return true;
1109    }
1110    return false;
1111}
1112
1113const char *
1114Host::GetUserName (uint32_t uid, std::string &user_name)
1115{
1116    struct passwd user_info;
1117    struct passwd *user_info_ptr = &user_info;
1118    char user_buffer[PATH_MAX];
1119    size_t user_buffer_size = sizeof(user_buffer);
1120    if (::getpwuid_r (uid,
1121                      &user_info,
1122                      user_buffer,
1123                      user_buffer_size,
1124                      &user_info_ptr) == 0)
1125    {
1126        if (user_info_ptr)
1127        {
1128            user_name.assign (user_info_ptr->pw_name);
1129            return user_name.c_str();
1130        }
1131    }
1132    user_name.clear();
1133    return NULL;
1134}
1135
1136const char *
1137Host::GetGroupName (uint32_t gid, std::string &group_name)
1138{
1139    char group_buffer[PATH_MAX];
1140    size_t group_buffer_size = sizeof(group_buffer);
1141    struct group group_info;
1142    struct group *group_info_ptr = &group_info;
1143    // Try the threadsafe version first
1144    if (::getgrgid_r (gid,
1145                      &group_info,
1146                      group_buffer,
1147                      group_buffer_size,
1148                      &group_info_ptr) == 0)
1149    {
1150        if (group_info_ptr)
1151        {
1152            group_name.assign (group_info_ptr->gr_name);
1153            return group_name.c_str();
1154        }
1155    }
1156    else
1157    {
1158        // The threadsafe version isn't currently working
1159        // for me on darwin, but the non-threadsafe version
1160        // is, so I am calling it below.
1161        group_info_ptr = ::getgrgid (gid);
1162        if (group_info_ptr)
1163        {
1164            group_name.assign (group_info_ptr->gr_name);
1165            return group_name.c_str();
1166        }
1167    }
1168    group_name.clear();
1169    return NULL;
1170}
1171
1172#if !defined (__APPLE__) && !defined (__FreeBSD__) // see macosx/Host.mm
1173bool
1174Host::GetOSBuildString (std::string &s)
1175{
1176    s.clear();
1177    return false;
1178}
1179
1180bool
1181Host::GetOSKernelDescription (std::string &s)
1182{
1183    s.clear();
1184    return false;
1185}
1186#endif
1187
1188uint32_t
1189Host::GetUserID ()
1190{
1191    return getuid();
1192}
1193
1194uint32_t
1195Host::GetGroupID ()
1196{
1197    return getgid();
1198}
1199
1200uint32_t
1201Host::GetEffectiveUserID ()
1202{
1203    return geteuid();
1204}
1205
1206uint32_t
1207Host::GetEffectiveGroupID ()
1208{
1209    return getegid();
1210}
1211
1212#if !defined (__APPLE__) && !defined(__linux__)
1213uint32_t
1214Host::FindProcesses (const ProcessInstanceInfoMatch &match_info, ProcessInstanceInfoList &process_infos)
1215{
1216    process_infos.Clear();
1217    return process_infos.GetSize();
1218}
1219#endif // #if !defined (__APPLE__) && !defined(__linux__)
1220
1221#if !defined (__APPLE__) && !defined (__FreeBSD__) && !defined(__linux__)
1222bool
1223Host::GetProcessInfo (lldb::pid_t pid, ProcessInstanceInfo &process_info)
1224{
1225    process_info.Clear();
1226    return false;
1227}
1228#endif
1229
1230lldb::TargetSP
1231Host::GetDummyTarget (lldb_private::Debugger &debugger)
1232{
1233    static TargetSP g_dummy_target_sp;
1234
1235    // FIXME: Maybe the dummy target should be per-Debugger
1236    if (!g_dummy_target_sp || !g_dummy_target_sp->IsValid())
1237    {
1238        ArchSpec arch(Target::GetDefaultArchitecture());
1239        if (!arch.IsValid())
1240            arch = Host::GetArchitecture ();
1241        Error err = debugger.GetTargetList().CreateTarget(debugger,
1242                                                          NULL,
1243                                                          arch.GetTriple().getTriple().c_str(),
1244                                                          false,
1245                                                          NULL,
1246                                                          g_dummy_target_sp);
1247    }
1248
1249    return g_dummy_target_sp;
1250}
1251
1252struct ShellInfo
1253{
1254    ShellInfo () :
1255        process_reaped (false),
1256        can_delete (false),
1257        pid (LLDB_INVALID_PROCESS_ID),
1258        signo(-1),
1259        status(-1)
1260    {
1261    }
1262
1263    lldb_private::Predicate<bool> process_reaped;
1264    lldb_private::Predicate<bool> can_delete;
1265    lldb::pid_t pid;
1266    int signo;
1267    int status;
1268};
1269
1270static bool
1271MonitorShellCommand (void *callback_baton,
1272                     lldb::pid_t pid,
1273                     bool exited,       // True if the process did exit
1274                     int signo,         // Zero for no signal
1275                     int status)   // Exit value of process if signal is zero
1276{
1277    ShellInfo *shell_info = (ShellInfo *)callback_baton;
1278    shell_info->pid = pid;
1279    shell_info->signo = signo;
1280    shell_info->status = status;
1281    // Let the thread running Host::RunShellCommand() know that the process
1282    // exited and that ShellInfo has been filled in by broadcasting to it
1283    shell_info->process_reaped.SetValue(1, eBroadcastAlways);
1284    // Now wait for a handshake back from that thread running Host::RunShellCommand
1285    // so we know that we can delete shell_info_ptr
1286    shell_info->can_delete.WaitForValueEqualTo(true);
1287    // Sleep a bit to allow the shell_info->can_delete.SetValue() to complete...
1288    usleep(1000);
1289    // Now delete the shell info that was passed into this function
1290    delete shell_info;
1291    return true;
1292}
1293
1294Error
1295Host::RunShellCommand (const char *command,
1296                       const char *working_dir,
1297                       int *status_ptr,
1298                       int *signo_ptr,
1299                       std::string *command_output_ptr,
1300                       uint32_t timeout_sec,
1301                       const char *shell)
1302{
1303    Error error;
1304    ProcessLaunchInfo launch_info;
1305    if (shell && shell[0])
1306    {
1307        // Run the command in a shell
1308        launch_info.SetShell(shell);
1309        launch_info.GetArguments().AppendArgument(command);
1310        const bool localhost = true;
1311        const bool will_debug = false;
1312        const bool first_arg_is_full_shell_command = true;
1313        launch_info.ConvertArgumentsForLaunchingInShell (error,
1314                                                         localhost,
1315                                                         will_debug,
1316                                                         first_arg_is_full_shell_command);
1317    }
1318    else
1319    {
1320        // No shell, just run it
1321        Args args (command);
1322        const bool first_arg_is_executable = true;
1323        launch_info.SetArguments(args, first_arg_is_executable);
1324    }
1325
1326    if (working_dir)
1327        launch_info.SetWorkingDirectory(working_dir);
1328    char output_file_path_buffer[L_tmpnam];
1329    const char *output_file_path = NULL;
1330    if (command_output_ptr)
1331    {
1332        // Create a temporary file to get the stdout/stderr and redirect the
1333        // output of the command into this file. We will later read this file
1334        // if all goes well and fill the data into "command_output_ptr"
1335        output_file_path = ::tmpnam(output_file_path_buffer);
1336        launch_info.AppendSuppressFileAction (STDIN_FILENO, true, false);
1337        launch_info.AppendOpenFileAction(STDOUT_FILENO, output_file_path, false, true);
1338        launch_info.AppendDuplicateFileAction(STDOUT_FILENO, STDERR_FILENO);
1339    }
1340    else
1341    {
1342        launch_info.AppendSuppressFileAction (STDIN_FILENO, true, false);
1343        launch_info.AppendSuppressFileAction (STDOUT_FILENO, false, true);
1344        launch_info.AppendSuppressFileAction (STDERR_FILENO, false, true);
1345    }
1346
1347    // The process monitor callback will delete the 'shell_info_ptr' below...
1348    std::unique_ptr<ShellInfo> shell_info_ap (new ShellInfo());
1349
1350    const bool monitor_signals = false;
1351    launch_info.SetMonitorProcessCallback(MonitorShellCommand, shell_info_ap.get(), monitor_signals);
1352
1353    error = LaunchProcess (launch_info);
1354    const lldb::pid_t pid = launch_info.GetProcessID();
1355    if (pid != LLDB_INVALID_PROCESS_ID)
1356    {
1357        // The process successfully launched, so we can defer ownership of
1358        // "shell_info" to the MonitorShellCommand callback function that will
1359        // get called when the process dies. We release the unique pointer as it
1360        // doesn't need to delete the ShellInfo anymore.
1361        ShellInfo *shell_info = shell_info_ap.release();
1362        TimeValue timeout_time(TimeValue::Now());
1363        timeout_time.OffsetWithSeconds(timeout_sec);
1364        bool timed_out = false;
1365        shell_info->process_reaped.WaitForValueEqualTo(true, &timeout_time, &timed_out);
1366        if (timed_out)
1367        {
1368            error.SetErrorString("timed out waiting for shell command to complete");
1369
1370            // Kill the process since it didn't complete withint the timeout specified
1371            ::kill (pid, SIGKILL);
1372            // Wait for the monitor callback to get the message
1373            timeout_time = TimeValue::Now();
1374            timeout_time.OffsetWithSeconds(1);
1375            timed_out = false;
1376            shell_info->process_reaped.WaitForValueEqualTo(true, &timeout_time, &timed_out);
1377        }
1378        else
1379        {
1380            if (status_ptr)
1381                *status_ptr = shell_info->status;
1382
1383            if (signo_ptr)
1384                *signo_ptr = shell_info->signo;
1385
1386            if (command_output_ptr)
1387            {
1388                command_output_ptr->clear();
1389                FileSpec file_spec(output_file_path, File::eOpenOptionRead);
1390                uint64_t file_size = file_spec.GetByteSize();
1391                if (file_size > 0)
1392                {
1393                    if (file_size > command_output_ptr->max_size())
1394                    {
1395                        error.SetErrorStringWithFormat("shell command output is too large to fit into a std::string");
1396                    }
1397                    else
1398                    {
1399                        command_output_ptr->resize(file_size);
1400                        file_spec.ReadFileContents(0, &((*command_output_ptr)[0]), command_output_ptr->size(), &error);
1401                    }
1402                }
1403            }
1404        }
1405        shell_info->can_delete.SetValue(true, eBroadcastAlways);
1406    }
1407    else
1408    {
1409        error.SetErrorString("failed to get process ID");
1410    }
1411
1412    if (output_file_path)
1413        ::unlink (output_file_path);
1414    // Handshake with the monitor thread, or just let it know in advance that
1415    // it can delete "shell_info" in case we timed out and were not able to kill
1416    // the process...
1417    return error;
1418}
1419
1420
1421uint32_t
1422Host::GetNumberCPUS ()
1423{
1424    static uint32_t g_num_cores = UINT32_MAX;
1425    if (g_num_cores == UINT32_MAX)
1426    {
1427#if defined(__APPLE__) or defined (__linux__) or defined (__FreeBSD__)
1428
1429        g_num_cores = ::sysconf(_SC_NPROCESSORS_ONLN);
1430
1431#elif defined(_WIN32) || defined(__WIN32__) || defined(__CYGWIN__)
1432
1433        // Header file for this might need to be included at the top of this file
1434        SYSTEM_INFO system_info;
1435        ::GetSystemInfo (&system_info);
1436        g_num_cores = system_info.dwNumberOfProcessors;
1437
1438#else
1439
1440        // Assume POSIX support if a host specific case has not been supplied above
1441        g_num_cores = 0;
1442        int num_cores = 0;
1443        size_t num_cores_len = sizeof(num_cores);
1444        int mib[] = { CTL_HW, HW_AVAILCPU };
1445
1446        /* get the number of CPUs from the system */
1447        if (sysctl(mib, sizeof(mib)/sizeof(int), &num_cores, &num_cores_len, NULL, 0) == 0 && (num_cores > 0))
1448        {
1449            g_num_cores = num_cores;
1450        }
1451        else
1452        {
1453            mib[1] = HW_NCPU;
1454            num_cores_len = sizeof(num_cores);
1455            if (sysctl(mib, sizeof(mib)/sizeof(int), &num_cores, &num_cores_len, NULL, 0) == 0 && (num_cores > 0))
1456            {
1457                if (num_cores > 0)
1458                    g_num_cores = num_cores;
1459            }
1460        }
1461#endif
1462    }
1463    return g_num_cores;
1464}
1465
1466
1467
1468#if !defined (__APPLE__)
1469bool
1470Host::OpenFileInExternalEditor (const FileSpec &file_spec, uint32_t line_no)
1471{
1472    return false;
1473}
1474
1475void
1476Host::SetCrashDescriptionWithFormat (const char *format, ...)
1477{
1478}
1479
1480void
1481Host::SetCrashDescription (const char *description)
1482{
1483}
1484
1485lldb::pid_t
1486LaunchApplication (const FileSpec &app_file_spec)
1487{
1488    return LLDB_INVALID_PROCESS_ID;
1489}
1490
1491#endif
1492