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