Host.cpp revision 0f577c2ab79604f7300ac66afebcaa4a4b2dceef
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/Error.h"
14#include "lldb/Core/FileSpec.h"
15#include "lldb/Core/Log.h"
16#include "lldb/Core/StreamString.h"
17#include "lldb/Host/Endian.h"
18#include "lldb/Host/Mutex.h"
19
20#include <dlfcn.h>
21#include <errno.h>
22
23#if defined (__APPLE__)
24#include <dispatch/dispatch.h>
25#include <libproc.h>
26#include <mach-o/dyld.h>
27#include <sys/sysctl.h>
28#elif defined (__linux__)
29#include <sys/wait.h>
30#endif
31
32using namespace lldb;
33using namespace lldb_private;
34
35struct MonitorInfo
36{
37    lldb::pid_t pid;                            // The process ID to monitor
38    Host::MonitorChildProcessCallback callback; // The callback function to call when "pid" exits or signals
39    void *callback_baton;                       // The callback baton for the callback function
40    bool monitor_signals;                       // If true, call the callback when "pid" gets signaled.
41};
42
43static void *
44MonitorChildProcessThreadFunction (void *arg);
45
46lldb::thread_t
47Host::StartMonitoringChildProcess
48(
49    Host::MonitorChildProcessCallback callback,
50    void *callback_baton,
51    lldb::pid_t pid,
52    bool monitor_signals
53)
54{
55    lldb::thread_t thread = LLDB_INVALID_HOST_THREAD;
56    if (callback)
57    {
58        std::auto_ptr<MonitorInfo> info_ap(new MonitorInfo);
59
60        info_ap->pid = pid;
61        info_ap->callback = callback;
62        info_ap->callback_baton = callback_baton;
63        info_ap->monitor_signals = monitor_signals;
64
65        char thread_name[256];
66        ::snprintf (thread_name, sizeof(thread_name), "<lldb.host.wait4(pid=%i)>", pid);
67        thread = ThreadCreate (thread_name,
68                               MonitorChildProcessThreadFunction,
69                               info_ap.get(),
70                               NULL);
71
72        if (thread != LLDB_INVALID_HOST_THREAD)
73            info_ap.release();
74    }
75    return thread;
76}
77
78//------------------------------------------------------------------
79// Scoped class that will disable thread canceling when it is
80// constructed, and exception safely restore the previous value it
81// when it goes out of scope.
82//------------------------------------------------------------------
83class ScopedPThreadCancelDisabler
84{
85public:
86    ScopedPThreadCancelDisabler()
87    {
88        // Disable the ability for this thread to be cancelled
89        int err = ::pthread_setcancelstate (PTHREAD_CANCEL_DISABLE, &m_old_state);
90        if (err != 0)
91            m_old_state = -1;
92
93    }
94
95    ~ScopedPThreadCancelDisabler()
96    {
97        // Restore the ability for this thread to be cancelled to what it
98        // previously was.
99        if (m_old_state != -1)
100            ::pthread_setcancelstate (m_old_state, 0);
101    }
102private:
103    int m_old_state;    // Save the old cancelability state.
104};
105
106static void *
107MonitorChildProcessThreadFunction (void *arg)
108{
109    LogSP log(lldb_private::GetLogIfAllCategoriesSet (LIBLLDB_LOG_PROCESS));
110    const char *function = __FUNCTION__;
111    if (log)
112        log->Printf ("%s (arg = %p) thread starting...", function, arg);
113
114    MonitorInfo *info = (MonitorInfo *)arg;
115
116    const Host::MonitorChildProcessCallback callback = info->callback;
117    void * const callback_baton = info->callback_baton;
118    const lldb::pid_t pid = info->pid;
119    const bool monitor_signals = info->monitor_signals;
120
121    delete info;
122
123    int status = -1;
124    const int options = 0;
125    struct rusage *rusage = NULL;
126    while (1)
127    {
128        log = lldb_private::GetLogIfAllCategoriesSet (LIBLLDB_LOG_PROCESS);
129        if (log)
130            log->Printf("%s ::wait4 (pid = %i, &status, options = %i, rusage = %p)...", function, pid, options, rusage);
131
132        // Wait for all child processes
133        ::pthread_testcancel ();
134        const lldb::pid_t wait_pid = ::wait4 (pid, &status, options, rusage);
135        ::pthread_testcancel ();
136
137        if (wait_pid == -1)
138        {
139            if (errno == EINTR)
140                continue;
141            else
142                break;
143        }
144        else if (wait_pid == pid)
145        {
146            bool exited = false;
147            int signal = 0;
148            int exit_status = 0;
149            const char *status_cstr = NULL;
150            if (WIFSTOPPED(status))
151            {
152                signal = WSTOPSIG(status);
153                status_cstr = "STOPPED";
154            }
155            else if (WIFEXITED(status))
156            {
157                exit_status = WEXITSTATUS(status);
158                status_cstr = "EXITED";
159                exited = true;
160            }
161            else if (WIFSIGNALED(status))
162            {
163                signal = WTERMSIG(status);
164                status_cstr = "SIGNALED";
165                exited = true;
166                exit_status = -1;
167            }
168            else
169            {
170                status_cstr = "(???)";
171            }
172
173            // Scope for pthread_cancel_disabler
174            {
175                ScopedPThreadCancelDisabler pthread_cancel_disabler;
176
177                log = lldb_private::GetLogIfAllCategoriesSet (LIBLLDB_LOG_PROCESS);
178                if (log)
179                    log->Printf ("%s ::wait4 (pid = %i, &status, options = %i, rusage = %p) => pid = %i, status = 0x%8.8x (%s), signal = %i, exit_state = %i",
180                                 function,
181                                 wait_pid,
182                                 options,
183                                 rusage,
184                                 pid,
185                                 status,
186                                 status_cstr,
187                                 signal,
188                                 exit_status);
189
190                if (exited || (signal != 0 && monitor_signals))
191                {
192                    bool callback_return = callback (callback_baton, pid, signal, exit_status);
193
194                    // If our process exited, then this thread should exit
195                    if (exited)
196                        break;
197                    // If the callback returns true, it means this process should
198                    // exit
199                    if (callback_return)
200                        break;
201                }
202            }
203        }
204    }
205
206    log = lldb_private::GetLogIfAllCategoriesSet (LIBLLDB_LOG_PROCESS);
207    if (log)
208        log->Printf ("%s (arg = %p) thread exiting...", __FUNCTION__, arg);
209
210    return NULL;
211}
212
213size_t
214Host::GetPageSize()
215{
216    return ::getpagesize();
217}
218
219const ArchSpec &
220Host::GetArchitecture ()
221{
222    static ArchSpec g_host_arch;
223    if (!g_host_arch.IsValid())
224    {
225#if defined (__APPLE__)
226        uint32_t cputype, cpusubtype;
227        uint32_t is_64_bit_capable;
228        size_t len = sizeof(cputype);
229        if  (::sysctlbyname("hw.cputype", &cputype, &len, NULL, 0) == 0)
230        {
231            len = sizeof(cpusubtype);
232            if (::sysctlbyname("hw.cpusubtype", &cpusubtype, &len, NULL, 0) == 0)
233                g_host_arch.SetMachOArch (cputype, cpusubtype);
234
235            len = sizeof (is_64_bit_capable);
236            if  (::sysctlbyname("hw.cpu64bit_capable", &is_64_bit_capable, &len, NULL, 0) == 0)
237            {
238                if (is_64_bit_capable)
239                {
240                    if (cputype == CPU_TYPE_I386 && cpusubtype == CPU_SUBTYPE_486)
241                        cpusubtype = CPU_SUBTYPE_I386_ALL;
242
243                    cputype |= CPU_ARCH_ABI64;
244                }
245            }
246        }
247#elif defined (__linux__)
248        g_host_arch.SetElfArch(7u, 144u);
249#endif
250    }
251    return g_host_arch;
252}
253
254const ConstString &
255Host::GetVendorString()
256{
257    static ConstString g_vendor;
258    if (!g_vendor)
259    {
260#if defined (__APPLE__)
261        char ostype[64];
262        size_t len = sizeof(ostype);
263        if (::sysctlbyname("kern.ostype", &ostype, &len, NULL, 0) == 0)
264            g_vendor.SetCString (ostype);
265        else
266            g_vendor.SetCString("apple");
267#elif defined (__linux__)
268        g_vendor.SetCString("gnu");
269#endif
270    }
271    return g_vendor;
272}
273
274const ConstString &
275Host::GetOSString()
276{
277    static ConstString g_os_string;
278    if (!g_os_string)
279    {
280#if defined (__APPLE__)
281        g_os_string.SetCString("darwin");
282#elif defined (__linux__)
283        g_os_string.SetCString("linux");
284#endif
285    }
286    return g_os_string;
287}
288
289const ConstString &
290Host::GetTargetTriple()
291{
292    static ConstString g_host_triple;
293    if (!(g_host_triple))
294    {
295        StreamString triple;
296        triple.Printf("%s-%s-%s",
297                      GetArchitecture().AsCString(),
298                      GetVendorString().AsCString(),
299                      GetOSString().AsCString());
300
301        std::transform (triple.GetString().begin(),
302                        triple.GetString().end(),
303                        triple.GetString().begin(),
304                        ::tolower);
305
306        g_host_triple.SetCString(triple.GetString().c_str());
307    }
308    return g_host_triple;
309}
310
311lldb::pid_t
312Host::GetCurrentProcessID()
313{
314    return ::getpid();
315}
316
317lldb::tid_t
318Host::GetCurrentThreadID()
319{
320#if defined (__APPLE__)
321    return ::mach_thread_self();
322#else
323    return lldb::tid_t(pthread_self());
324#endif
325}
326
327const char *
328Host::GetSignalAsCString (int signo)
329{
330    switch (signo)
331    {
332    case SIGHUP:    return "SIGHUP";    // 1    hangup
333    case SIGINT:    return "SIGINT";    // 2    interrupt
334    case SIGQUIT:   return "SIGQUIT";   // 3    quit
335    case SIGILL:    return "SIGILL";    // 4    illegal instruction (not reset when caught)
336    case SIGTRAP:   return "SIGTRAP";   // 5    trace trap (not reset when caught)
337    case SIGABRT:   return "SIGABRT";   // 6    abort()
338#if  defined(_POSIX_C_SOURCE)
339    case SIGPOLL:   return "SIGPOLL";   // 7    pollable event ([XSR] generated, not supported)
340#else    // !_POSIX_C_SOURCE
341    case SIGEMT:    return "SIGEMT";    // 7    EMT instruction
342#endif    // !_POSIX_C_SOURCE
343    case SIGFPE:    return "SIGFPE";    // 8    floating point exception
344    case SIGKILL:   return "SIGKILL";   // 9    kill (cannot be caught or ignored)
345    case SIGBUS:    return "SIGBUS";    // 10    bus error
346    case SIGSEGV:   return "SIGSEGV";   // 11    segmentation violation
347    case SIGSYS:    return "SIGSYS";    // 12    bad argument to system call
348    case SIGPIPE:   return "SIGPIPE";   // 13    write on a pipe with no one to read it
349    case SIGALRM:   return "SIGALRM";   // 14    alarm clock
350    case SIGTERM:   return "SIGTERM";   // 15    software termination signal from kill
351    case SIGURG:    return "SIGURG";    // 16    urgent condition on IO channel
352    case SIGSTOP:   return "SIGSTOP";   // 17    sendable stop signal not from tty
353    case SIGTSTP:   return "SIGTSTP";   // 18    stop signal from tty
354    case SIGCONT:   return "SIGCONT";   // 19    continue a stopped process
355    case SIGCHLD:   return "SIGCHLD";   // 20    to parent on child stop or exit
356    case SIGTTIN:   return "SIGTTIN";   // 21    to readers pgrp upon background tty read
357    case SIGTTOU:   return "SIGTTOU";   // 22    like TTIN for output if (tp->t_local&LTOSTOP)
358#if  !defined(_POSIX_C_SOURCE)
359    case SIGIO:     return "SIGIO";     // 23    input/output possible signal
360#endif
361    case SIGXCPU:   return "SIGXCPU";   // 24    exceeded CPU time limit
362    case SIGXFSZ:   return "SIGXFSZ";   // 25    exceeded file size limit
363    case SIGVTALRM: return "SIGVTALRM"; // 26    virtual time alarm
364    case SIGPROF:   return "SIGPROF";   // 27    profiling time alarm
365#if  !defined(_POSIX_C_SOURCE)
366    case SIGWINCH:  return "SIGWINCH";  // 28    window size changes
367    case SIGINFO:   return "SIGINFO";   // 29    information request
368#endif
369    case SIGUSR1:   return "SIGUSR1";   // 30    user defined signal 1
370    case SIGUSR2:   return "SIGUSR2";   // 31    user defined signal 2
371    default:
372        break;
373    }
374    return NULL;
375}
376
377void
378Host::WillTerminate ()
379{
380}
381
382#if !defined (__APPLE__) // see macosx/Host.mm
383void
384Host::ThreadCreated (const char *thread_name)
385{
386}
387
388void
389Host::Backtrace (Stream &strm, uint32_t max_frames)
390{
391    // TODO: Is there a way to backtrace the current process on linux? Other systems?
392}
393
394
395size_t
396Host::GetEnvironment (StringList &env)
397{
398    // TODO: Is there a way to the host environment for this process on linux? Other systems?
399    return 0;
400}
401
402#endif
403
404struct HostThreadCreateInfo
405{
406    std::string thread_name;
407    thread_func_t thread_fptr;
408    thread_arg_t thread_arg;
409
410    HostThreadCreateInfo (const char *name, thread_func_t fptr, thread_arg_t arg) :
411        thread_name (name ? name : ""),
412        thread_fptr (fptr),
413        thread_arg (arg)
414    {
415    }
416};
417
418static thread_result_t
419ThreadCreateTrampoline (thread_arg_t arg)
420{
421    HostThreadCreateInfo *info = (HostThreadCreateInfo *)arg;
422    Host::ThreadCreated (info->thread_name.c_str());
423    thread_func_t thread_fptr = info->thread_fptr;
424    thread_arg_t thread_arg = info->thread_arg;
425
426    LogSP log(lldb_private::GetLogIfAllCategoriesSet (LIBLLDB_LOG_THREAD));
427    if (log)
428        log->Printf("thread created");
429
430    delete info;
431    return thread_fptr (thread_arg);
432}
433
434lldb::thread_t
435Host::ThreadCreate
436(
437    const char *thread_name,
438    thread_func_t thread_fptr,
439    thread_arg_t thread_arg,
440    Error *error
441)
442{
443    lldb::thread_t thread = LLDB_INVALID_HOST_THREAD;
444
445    // Host::ThreadCreateTrampoline will delete this pointer for us.
446    HostThreadCreateInfo *info_ptr = new HostThreadCreateInfo (thread_name, thread_fptr, thread_arg);
447
448    int err = ::pthread_create (&thread, NULL, ThreadCreateTrampoline, info_ptr);
449    if (err == 0)
450    {
451        if (error)
452            error->Clear();
453        return thread;
454    }
455
456    if (error)
457        error->SetError (err, eErrorTypePOSIX);
458
459    return LLDB_INVALID_HOST_THREAD;
460}
461
462bool
463Host::ThreadCancel (lldb::thread_t thread, Error *error)
464{
465    int err = ::pthread_cancel (thread);
466    if (error)
467        error->SetError(err, eErrorTypePOSIX);
468    return err == 0;
469}
470
471bool
472Host::ThreadDetach (lldb::thread_t thread, Error *error)
473{
474    int err = ::pthread_detach (thread);
475    if (error)
476        error->SetError(err, eErrorTypePOSIX);
477    return err == 0;
478}
479
480bool
481Host::ThreadJoin (lldb::thread_t thread, thread_result_t *thread_result_ptr, Error *error)
482{
483    int err = ::pthread_join (thread, thread_result_ptr);
484    if (error)
485        error->SetError(err, eErrorTypePOSIX);
486    return err == 0;
487}
488
489//------------------------------------------------------------------
490// Control access to a static file thread name map using a single
491// static function to avoid a static constructor.
492//------------------------------------------------------------------
493static const char *
494ThreadNameAccessor (bool get, lldb::pid_t pid, lldb::tid_t tid, const char *name)
495{
496    uint64_t pid_tid = ((uint64_t)pid << 32) | (uint64_t)tid;
497
498    static pthread_mutex_t g_mutex = PTHREAD_MUTEX_INITIALIZER;
499    Mutex::Locker locker(&g_mutex);
500
501    typedef std::map<uint64_t, std::string> thread_name_map;
502    // rdar://problem/8153284
503    // Fixed a crasher where during shutdown, loggings attempted to access the
504    // thread name but the static map instance had already been destructed.
505    // Another approach is to introduce a static guard object which monitors its
506    // own destruction and raises a flag, but this incurs more overhead.
507    static thread_name_map *g_thread_names_ptr = new thread_name_map();
508    thread_name_map &g_thread_names = *g_thread_names_ptr;
509
510    if (get)
511    {
512        // See if the thread name exists in our thread name pool
513        thread_name_map::iterator pos = g_thread_names.find(pid_tid);
514        if (pos != g_thread_names.end())
515            return pos->second.c_str();
516    }
517    else
518    {
519        // Set the thread name
520        g_thread_names[pid_tid] = name;
521    }
522    return NULL;
523}
524
525const char *
526Host::GetThreadName (lldb::pid_t pid, lldb::tid_t tid)
527{
528    const char *name = ThreadNameAccessor (true, pid, tid, NULL);
529    if (name == NULL)
530    {
531#if defined(__APPLE__) && MAC_OS_X_VERSION_MAX_ALLOWED > MAC_OS_X_VERSION_10_5
532        // We currently can only get the name of a thread in the current process.
533        if (pid == Host::GetCurrentProcessID())
534        {
535            char pthread_name[1024];
536            if (::pthread_getname_np (::pthread_from_mach_thread_np (tid), pthread_name, sizeof(pthread_name)) == 0)
537            {
538                if (pthread_name[0])
539                {
540                    // Set the thread in our string pool
541                    ThreadNameAccessor (false, pid, tid, pthread_name);
542                    // Get our copy of the thread name string
543                    name = ThreadNameAccessor (true, pid, tid, NULL);
544                }
545            }
546
547            if (name == NULL)
548            {
549                dispatch_queue_t current_queue = ::dispatch_get_current_queue ();
550                if (current_queue != NULL)
551                    name = dispatch_queue_get_label (current_queue);
552            }
553        }
554#endif
555    }
556    return name;
557}
558
559void
560Host::SetThreadName (lldb::pid_t pid, lldb::tid_t tid, const char *name)
561{
562    lldb::pid_t curr_pid = Host::GetCurrentProcessID();
563    lldb::tid_t curr_tid = Host::GetCurrentThreadID();
564    if (pid == LLDB_INVALID_PROCESS_ID)
565        pid = curr_pid;
566
567    if (tid == LLDB_INVALID_THREAD_ID)
568        tid = curr_tid;
569
570#if defined(__APPLE__) && MAC_OS_X_VERSION_MAX_ALLOWED > MAC_OS_X_VERSION_10_5
571    // Set the pthread name if possible
572    if (pid == curr_pid && tid == curr_tid)
573    {
574        ::pthread_setname_np (name);
575    }
576#endif
577    ThreadNameAccessor (false, pid, tid, name);
578}
579
580FileSpec
581Host::GetProgramFileSpec ()
582{
583    static FileSpec g_program_filespec;
584    if (!g_program_filespec)
585    {
586#if defined (__APPLE__)
587        char program_fullpath[PATH_MAX];
588        // If DST is NULL, then return the number of bytes needed.
589        uint32_t len = sizeof(program_fullpath);
590        int err = _NSGetExecutablePath (program_fullpath, &len);
591        if (err == 0)
592            g_program_filespec.SetFile (program_fullpath, false);
593        else if (err == -1)
594        {
595            char *large_program_fullpath = (char *)::malloc (len + 1);
596
597            err = _NSGetExecutablePath (large_program_fullpath, &len);
598            if (err == 0)
599                g_program_filespec.SetFile (large_program_fullpath, false);
600
601            ::free (large_program_fullpath);
602        }
603#elif defined (__linux__)
604        char exe_path[PATH_MAX];
605        ssize_t len = readlink("/proc/self/exe", exe_path, sizeof(exe_path) - 1);
606        if (len > 0) {
607            exe_path[len] = 0;
608            g_program_filespec.SetFile(exe_path, false);
609        }
610#elif defined (__FreeBSD__)
611        int exe_path_mib[4] = { CTL_KERN, KERN_PROC, KERN_PROC_PATHNAME, getpid() };
612        size_t exe_path_size;
613        if (sysctl(exe_path_mib, 4, NULL, &exe_path_size, NULL, 0) == 0)
614        {
615            char *exe_path = new char[exe_path_size];
616            if (sysctl(exe_path_mib, 4, exe_path, &exe_path_size, NULL, 0) == 0)
617                g_program_filespec.SetFile(exe_path, false);
618            delete[] exe_path;
619        }
620#endif
621    }
622    return g_program_filespec;
623}
624
625FileSpec
626Host::GetModuleFileSpecForHostAddress (const void *host_addr)
627{
628    FileSpec module_filespec;
629    Dl_info info;
630    if (::dladdr (host_addr, &info))
631    {
632        if (info.dli_fname)
633            module_filespec.SetFile(info.dli_fname, true);
634    }
635    return module_filespec;
636}
637
638#if !defined (__APPLE__) // see Host.mm
639bool
640Host::ResolveExecutableInBundle (FileSpec &file)
641{
642    return false;
643}
644#endif
645
646void *
647Host::DynamicLibraryOpen (const FileSpec &file_spec, Error &error)
648{
649    void *dynamic_library_handle = NULL;
650    char path[PATH_MAX];
651    if (file_spec.GetPath(path, sizeof(path)))
652    {
653#if defined (__linux__)
654        dynamic_library_handle = ::dlopen (path, RTLD_LAZY | RTLD_GLOBAL);
655#else
656        dynamic_library_handle = ::dlopen (path, RTLD_LAZY | RTLD_GLOBAL | RTLD_FIRST);
657#endif
658        if (dynamic_library_handle)
659        {
660            error.Clear();
661        }
662        else
663        {
664            error.SetErrorString(::dlerror());
665        }
666    }
667    else
668    {
669        error.SetErrorString("failed to extract path");
670    }
671
672    return dynamic_library_handle;
673}
674
675Error
676Host::DynamicLibraryClose (void *dynamic_library_handle)
677{
678    Error error;
679    if (dynamic_library_handle == NULL)
680    {
681        error.SetErrorString ("invalid dynamic library handle");
682    }
683    else if (::dlclose(dynamic_library_handle) != 0)
684    {
685        error.SetErrorString(::dlerror());
686    }
687    return error;
688}
689
690void *
691Host::DynamicLibraryGetSymbol (void *dynamic_library_handle, const char *symbol_name, Error &error)
692{
693    if (dynamic_library_handle == NULL)
694    {
695        error.SetErrorString ("invalid dynamic library handle");
696        return NULL;
697    }
698
699    void *symbol_addr = ::dlsym (dynamic_library_handle, symbol_name);
700    if (symbol_addr == NULL)
701        error.SetErrorString(::dlerror());
702    else
703        error.Clear();
704    return symbol_addr;
705}
706
707bool
708Host::GetLLDBPath (PathType path_type, FileSpec &file_spec)
709{
710    // To get paths related to LLDB we get the path to the executable that
711    // contains this function. On MacOSX this will be "LLDB.framework/.../LLDB",
712    // on linux this is assumed to be the "lldb" main executable. If LLDB on
713    // linux is actually in a shared library (lldb.so??) then this function will
714    // need to be modified to "do the right thing".
715
716    switch (path_type)
717    {
718    case ePathTypeLLDBShlibDir:
719        {
720            static ConstString g_lldb_so_dir;
721            if (!g_lldb_so_dir)
722            {
723                FileSpec lldb_file_spec (Host::GetModuleFileSpecForHostAddress ((void *)Host::GetLLDBPath));
724                g_lldb_so_dir = lldb_file_spec.GetDirectory();
725            }
726            file_spec.GetDirectory() = g_lldb_so_dir;
727            return file_spec.GetDirectory();
728        }
729        break;
730
731    case ePathTypeSupportExecutableDir:
732        {
733            static ConstString g_lldb_support_exe_dir;
734            if (!g_lldb_support_exe_dir)
735            {
736                FileSpec lldb_file_spec;
737                if (GetLLDBPath (ePathTypeLLDBShlibDir, lldb_file_spec))
738                {
739                    char raw_path[PATH_MAX];
740                    char resolved_path[PATH_MAX];
741                    lldb_file_spec.GetPath(raw_path, sizeof(raw_path));
742
743#if defined (__APPLE__)
744                    char *framework_pos = ::strstr (raw_path, "LLDB.framework");
745                    if (framework_pos)
746                    {
747                        framework_pos += strlen("LLDB.framework");
748                        ::strncpy (framework_pos, "/Resources", PATH_MAX - (framework_pos - raw_path));
749                    }
750#endif
751                    FileSpec::Resolve (raw_path, resolved_path, sizeof(resolved_path));
752                    g_lldb_support_exe_dir.SetCString(resolved_path);
753                }
754            }
755            file_spec.GetDirectory() = g_lldb_support_exe_dir;
756            return file_spec.GetDirectory();
757        }
758        break;
759
760    case ePathTypeHeaderDir:
761        {
762            static ConstString g_lldb_headers_dir;
763            if (!g_lldb_headers_dir)
764            {
765#if defined (__APPLE__)
766                FileSpec lldb_file_spec;
767                if (GetLLDBPath (ePathTypeLLDBShlibDir, lldb_file_spec))
768                {
769                    char raw_path[PATH_MAX];
770                    char resolved_path[PATH_MAX];
771                    lldb_file_spec.GetPath(raw_path, sizeof(raw_path));
772
773                    char *framework_pos = ::strstr (raw_path, "LLDB.framework");
774                    if (framework_pos)
775                    {
776                        framework_pos += strlen("LLDB.framework");
777                        ::strncpy (framework_pos, "/Headers", PATH_MAX - (framework_pos - raw_path));
778                    }
779                    FileSpec::Resolve (raw_path, resolved_path, sizeof(resolved_path));
780                    g_lldb_headers_dir.SetCString(resolved_path);
781                }
782#else
783                // TODO: Anyone know how we can determine this for linux? Other systems??
784                g_lldb_headers_dir.SetCString ("/opt/local/include/lldb");
785#endif
786            }
787            file_spec.GetDirectory() = g_lldb_headers_dir;
788            return file_spec.GetDirectory();
789        }
790        break;
791
792    case ePathTypePythonDir:
793        {
794            // TODO: Anyone know how we can determine this for linux? Other systems?
795            // For linux we are currently assuming the location of the lldb
796            // binary that contains this function is the directory that will
797            // contain lldb.so, lldb.py and embedded_interpreter.py...
798
799            static ConstString g_lldb_python_dir;
800            if (!g_lldb_python_dir)
801            {
802                FileSpec lldb_file_spec;
803                if (GetLLDBPath (ePathTypeLLDBShlibDir, lldb_file_spec))
804                {
805                    char raw_path[PATH_MAX];
806                    char resolved_path[PATH_MAX];
807                    lldb_file_spec.GetPath(raw_path, sizeof(raw_path));
808
809#if defined (__APPLE__)
810                    char *framework_pos = ::strstr (raw_path, "LLDB.framework");
811                    if (framework_pos)
812                    {
813                        framework_pos += strlen("LLDB.framework");
814                        ::strncpy (framework_pos, "/Resources/Python", PATH_MAX - (framework_pos - raw_path));
815                    }
816#endif
817                    FileSpec::Resolve (raw_path, resolved_path, sizeof(resolved_path));
818                    g_lldb_python_dir.SetCString(resolved_path);
819                }
820            }
821            file_spec.GetDirectory() = g_lldb_python_dir;
822            return file_spec.GetDirectory();
823        }
824        break;
825
826    case ePathTypeLLDBSystemPlugins:    // System plug-ins directory
827        {
828#if defined (__APPLE__)
829            static ConstString g_lldb_system_plugin_dir;
830            if (!g_lldb_system_plugin_dir)
831            {
832                FileSpec lldb_file_spec;
833                if (GetLLDBPath (ePathTypeLLDBShlibDir, lldb_file_spec))
834                {
835                    char raw_path[PATH_MAX];
836                    char resolved_path[PATH_MAX];
837                    lldb_file_spec.GetPath(raw_path, sizeof(raw_path));
838
839                    char *framework_pos = ::strstr (raw_path, "LLDB.framework");
840                    if (framework_pos)
841                    {
842                        framework_pos += strlen("LLDB.framework");
843                        ::strncpy (framework_pos, "/Resources/PlugIns", PATH_MAX - (framework_pos - raw_path));
844                    }
845                    FileSpec::Resolve (raw_path, resolved_path, sizeof(resolved_path));
846                    g_lldb_system_plugin_dir.SetCString(resolved_path);
847                }
848            }
849            file_spec.GetDirectory() = g_lldb_system_plugin_dir;
850            return file_spec.GetDirectory();
851#endif
852            // TODO: where would system LLDB plug-ins be located on linux? Other systems?
853            return false;
854        }
855        break;
856
857    case ePathTypeLLDBUserPlugins:      // User plug-ins directory
858        {
859#if defined (__APPLE__)
860            static ConstString g_lldb_user_plugin_dir;
861            if (!g_lldb_user_plugin_dir)
862            {
863                char user_plugin_path[PATH_MAX];
864                if (FileSpec::Resolve ("~/Library/Application Support/LLDB/PlugIns",
865                                       user_plugin_path,
866                                       sizeof(user_plugin_path)))
867                {
868                    g_lldb_user_plugin_dir.SetCString(user_plugin_path);
869                }
870            }
871            file_spec.GetDirectory() = g_lldb_user_plugin_dir;
872            return file_spec.GetDirectory();
873#endif
874            // TODO: where would user LLDB plug-ins be located on linux? Other systems?
875            return false;
876        }
877    default:
878        assert (!"Unhandled PathType");
879        break;
880    }
881
882    return false;
883}
884
885uint32_t
886Host::ListProcessesMatchingName (const char *name, StringList &matches, std::vector<lldb::pid_t> &pids)
887{
888    uint32_t num_matches = 0;
889
890#if defined (__APPLE__)
891    int num_pids;
892    int size_of_pids;
893    std::vector<int> pid_list;
894
895    size_of_pids = proc_listpids(PROC_ALL_PIDS, 0, NULL, 0);
896    if (size_of_pids == -1)
897        return 0;
898
899    num_pids = size_of_pids/sizeof(int);
900
901    pid_list.resize (size_of_pids);
902    size_of_pids = proc_listpids(PROC_ALL_PIDS, 0, &pid_list[0], size_of_pids);
903    if (size_of_pids == -1)
904        return 0;
905
906    lldb::pid_t our_pid = getpid();
907
908    for (int i = 0; i < num_pids; i++)
909    {
910        struct proc_bsdinfo bsd_info;
911        int error = proc_pidinfo (pid_list[i], PROC_PIDTBSDINFO, (uint64_t) 0, &bsd_info, PROC_PIDTBSDINFO_SIZE);
912        if (error == 0)
913            continue;
914
915        // Don't offer to attach to zombie processes, already traced or exiting
916        // processes, and of course, ourselves...  It looks like passing the second arg of
917        // 0 to proc_listpids will exclude zombies anyway, but that's not documented so...
918        if (((bsd_info.pbi_flags & (PROC_FLAG_TRACED | PROC_FLAG_INEXIT)) != 0)
919             || (bsd_info.pbi_status == SZOMB)
920             || (bsd_info.pbi_pid == our_pid))
921             continue;
922        char pid_name[MAXCOMLEN * 2 + 1];
923        int name_len;
924        name_len = proc_name(bsd_info.pbi_pid, pid_name, MAXCOMLEN * 2);
925        if (name_len == 0)
926            continue;
927
928        if (strstr(pid_name, name) != pid_name)
929            continue;
930        matches.AppendString (pid_name);
931        pids.push_back (bsd_info.pbi_pid);
932        num_matches++;
933    }
934#endif
935
936    return num_matches;
937}
938
939ArchSpec
940Host::GetArchSpecForExistingProcess (lldb::pid_t pid)
941{
942    ArchSpec return_spec;
943
944#if defined (__APPLE__)
945    struct proc_bsdinfo bsd_info;
946    int error = proc_pidinfo (pid, PROC_PIDTBSDINFO, (uint64_t) 0, &bsd_info, PROC_PIDTBSDINFO_SIZE);
947    if (error == 0)
948        return return_spec;
949    if (bsd_info.pbi_flags & PROC_FLAG_LP64)
950        return_spec.SetArch(LLDB_ARCH_DEFAULT_64BIT);
951    else
952        return_spec.SetArch(LLDB_ARCH_DEFAULT_32BIT);
953#endif
954
955    return return_spec;
956}
957
958ArchSpec
959Host::GetArchSpecForExistingProcess (const char *process_name)
960{
961    ArchSpec returnSpec;
962    StringList matches;
963    std::vector<lldb::pid_t> pids;
964    if (ListProcessesMatchingName(process_name, matches, pids))
965    {
966        if (matches.GetSize() == 1)
967        {
968            return GetArchSpecForExistingProcess(pids[0]);
969        }
970    }
971    return returnSpec;
972}
973
974#if !defined (__APPLE__) // see macosx/Host.mm
975bool
976Host::OpenFileInExternalEditor (const FileSpec &file_spec, uint32_t line_no)
977{
978    return false;
979}
980
981void
982Host::SetCrashDescriptionWithFormat (const char *format, ...)
983{
984}
985
986void
987Host::SetCrashDescription (const char *description)
988{
989}
990
991lldb::pid_t
992LaunchApplication (const FileSpec &app_file_spec)
993{
994    return LLDB_INVALID_PROCESS_ID;
995}
996
997lldb::pid_t
998Host::LaunchInNewTerminal
999(
1000    const char *tty_name,
1001    const char **argv,
1002    const char **envp,
1003    const char *working_dir,
1004    const ArchSpec *arch_spec,
1005    bool stop_at_entry,
1006    bool disable_aslr
1007)
1008{
1009    return LLDB_INVALID_PROCESS_ID;
1010}
1011
1012#endif
1013