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