blob: 061a31eef595423392d57ab0b072d17a5e675851 [file] [log] [blame]
Greg Clayton8f3b21d2010-09-07 20:11:56 +00001//===-- 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"
Greg Claytoncd548032011-02-01 01:31:41 +000017#include "lldb/Host/Endian.h"
Greg Clayton8f3b21d2010-09-07 20:11:56 +000018#include "lldb/Host/Mutex.h"
19
20#include <dlfcn.h>
21#include <errno.h>
Greg Clayton8f3b21d2010-09-07 20:11:56 +000022
23#if defined (__APPLE__)
Greg Clayton49ce6822010-10-31 03:01:06 +000024#include <dispatch/dispatch.h>
Greg Clayton8f3b21d2010-09-07 20:11:56 +000025#include <libproc.h>
26#include <mach-o/dyld.h>
Greg Claytonb5f67fb2011-02-05 06:36:35 +000027#include <sys/sysctl.h>
Greg Clayton0f577c22011-02-07 17:43:47 +000028#elif defined (__linux__)
29#include <sys/wait.h>
Greg Clayton8f3b21d2010-09-07 20:11:56 +000030#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{
Greg Claytone005f2c2010-11-06 01:53:30 +0000109 LogSP log(lldb_private::GetLogIfAllCategoriesSet (LIBLLDB_LOG_PROCESS));
Greg Clayton8f3b21d2010-09-07 20:11:56 +0000110 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 {
Caroline Tice926060e2010-10-29 21:48:37 +0000128 log = lldb_private::GetLogIfAllCategoriesSet (LIBLLDB_LOG_PROCESS);
Greg Clayton8f3b21d2010-09-07 20:11:56 +0000129 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
Caroline Tice926060e2010-10-29 21:48:37 +0000177 log = lldb_private::GetLogIfAllCategoriesSet (LIBLLDB_LOG_PROCESS);
Greg Clayton8f3b21d2010-09-07 20:11:56 +0000178 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
Caroline Tice926060e2010-10-29 21:48:37 +0000206 log = lldb_private::GetLogIfAllCategoriesSet (LIBLLDB_LOG_PROCESS);
Greg Clayton8f3b21d2010-09-07 20:11:56 +0000207 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
Greg Clayton8f3b21d2010-09-07 20:11:56 +0000219const 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)
Greg Claytone71e2582011-02-04 01:58:07 +0000233 g_host_arch.SetMachOArch (cputype, cpusubtype);
Greg Clayton8f3b21d2010-09-07 20:11:56 +0000234
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__)
Greg Clayton0f577c22011-02-07 17:43:47 +0000248 g_host_arch.SetElfArch(7u, 144u);
Greg Clayton8f3b21d2010-09-07 20:11:56 +0000249#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}
Greg Claytonb749a262010-12-03 06:02:24 +0000387
388void
389Host::Backtrace (Stream &strm, uint32_t max_frames)
390{
Greg Clayton52fd9842011-02-02 02:24:04 +0000391 // TODO: Is there a way to backtrace the current process on linux? Other systems?
Greg Claytonb749a262010-12-03 06:02:24 +0000392}
393
Greg Clayton638351a2010-12-04 00:10:17 +0000394
395size_t
396Host::GetEnvironment (StringList &env)
397{
Greg Clayton52fd9842011-02-02 02:24:04 +0000398 // TODO: Is there a way to the host environment for this process on linux? Other systems?
Greg Clayton638351a2010-12-04 00:10:17 +0000399 return 0;
400}
401
Greg Clayton8f3b21d2010-09-07 20:11:56 +0000402#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
Greg Claytone005f2c2010-11-06 01:53:30 +0000426 LogSP log(lldb_private::GetLogIfAllCategoriesSet (LIBLLDB_LOG_THREAD));
Greg Clayton8f3b21d2010-09-07 20:11:56 +0000427 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 }
Greg Clayton49ce6822010-10-31 03:01:06 +0000546
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 }
Greg Clayton8f3b21d2010-09-07 20:11:56 +0000553 }
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)
Greg Clayton20fbf8d2011-01-13 01:23:43 +0000592 g_program_filespec.SetFile (program_fullpath, false);
Greg Clayton8f3b21d2010-09-07 20:11:56 +0000593 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)
Greg Clayton20fbf8d2011-01-13 01:23:43 +0000599 g_program_filespec.SetFile (large_program_fullpath, false);
Greg Clayton8f3b21d2010-09-07 20:11:56 +0000600
601 ::free (large_program_fullpath);
602 }
603#elif defined (__linux__)
604 char exe_path[PATH_MAX];
Stephen Wilsonf302a9e2011-01-12 04:21:21 +0000605 ssize_t len = readlink("/proc/self/exe", exe_path, sizeof(exe_path) - 1);
606 if (len > 0) {
607 exe_path[len] = 0;
Greg Clayton20fbf8d2011-01-13 01:23:43 +0000608 g_program_filespec.SetFile(exe_path, false);
Stephen Wilsonf302a9e2011-01-12 04:21:21 +0000609 }
Greg Clayton8f3b21d2010-09-07 20:11:56 +0000610#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 {
Greg Clayton366795e2011-01-13 01:27:55 +0000615 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;
Greg Clayton8f3b21d2010-09-07 20:11:56 +0000619 }
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)
Greg Clayton537a7a82010-10-20 20:54:39 +0000633 module_filespec.SetFile(info.dli_fname, true);
Greg Clayton8f3b21d2010-09-07 20:11:56 +0000634 }
635 return module_filespec;
636}
637
638#if !defined (__APPLE__) // see Host.mm
639bool
Greg Clayton24b48ff2010-10-17 22:03:32 +0000640Host::ResolveExecutableInBundle (FileSpec &file)
Greg Clayton8f3b21d2010-09-07 20:11:56 +0000641{
Greg Clayton24b48ff2010-10-17 22:03:32 +0000642 return false;
Greg Clayton8f3b21d2010-09-07 20:11:56 +0000643}
644#endif
645
Greg Clayton52fd9842011-02-02 02:24:04 +0000646void *
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 {
Greg Clayton0f577c22011-02-07 17:43:47 +0000653#if defined (__linux__)
654 dynamic_library_handle = ::dlopen (path, RTLD_LAZY | RTLD_GLOBAL);
655#else
Greg Clayton52fd9842011-02-02 02:24:04 +0000656 dynamic_library_handle = ::dlopen (path, RTLD_LAZY | RTLD_GLOBAL | RTLD_FIRST);
Greg Clayton0f577c22011-02-07 17:43:47 +0000657#endif
Greg Clayton52fd9842011-02-02 02:24:04 +0000658 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}
Greg Clayton24b48ff2010-10-17 22:03:32 +0000706
707bool
708Host::GetLLDBPath (PathType path_type, FileSpec &file_spec)
709{
Greg Clayton5d187e52011-01-08 20:28:42 +0000710 // To get paths related to LLDB we get the path to the executable that
Greg Clayton24b48ff2010-10-17 22:03:32 +0000711 // 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
Greg Clayton52fd9842011-02-02 02:24:04 +0000783 // TODO: Anyone know how we can determine this for linux? Other systems??
Greg Clayton24b48ff2010-10-17 22:03:32 +0000784 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 {
Greg Clayton52fd9842011-02-02 02:24:04 +0000794 // TODO: Anyone know how we can determine this for linux? Other systems?
Greg Clayton24b48ff2010-10-17 22:03:32 +0000795 // 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
Greg Clayton52fd9842011-02-02 02:24:04 +0000826 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 }
Greg Clayton24b48ff2010-10-17 22:03:32 +0000877 default:
878 assert (!"Unhandled PathType");
879 break;
880 }
881
882 return false;
883}
884
Greg Clayton8f3b21d2010-09-07 20:11:56 +0000885uint32_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;
Greg Claytonfb8876d2010-10-10 22:07:18 +0000893 std::vector<int> pid_list;
Greg Clayton8f3b21d2010-09-07 20:11:56 +0000894
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);
Greg Claytonfb8876d2010-10-10 22:07:18 +0000900
901 pid_list.resize (size_of_pids);
902 size_of_pids = proc_listpids(PROC_ALL_PIDS, 0, &pid_list[0], size_of_pids);
Greg Clayton8f3b21d2010-09-07 20:11:56 +0000903 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
Greg Claytonb73620c2010-12-18 01:54:34 +0000976Host::OpenFileInExternalEditor (const FileSpec &file_spec, uint32_t line_no)
Greg Clayton8f3b21d2010-09-07 20:11:56 +0000977{
978 return false;
979}
Greg Clayton24b48ff2010-10-17 22:03:32 +0000980
Greg Claytone98ac252010-11-10 04:57:04 +0000981void
982Host::SetCrashDescriptionWithFormat (const char *format, ...)
983{
984}
985
986void
987Host::SetCrashDescription (const char *description)
988{
989}
Greg Clayton24b48ff2010-10-17 22:03:32 +0000990
991lldb::pid_t
992LaunchApplication (const FileSpec &app_file_spec)
993{
994 return LLDB_INVALID_PROCESS_ID;
995}
996
997lldb::pid_t
998Host::LaunchInNewTerminal
999(
Greg Claytonb73620c2010-12-18 01:54:34 +00001000 const char *tty_name,
Greg Clayton24b48ff2010-10-17 22:03:32 +00001001 const char **argv,
1002 const char **envp,
Greg Claytonde915be2011-01-23 05:56:20 +00001003 const char *working_dir,
Greg Clayton24b48ff2010-10-17 22:03:32 +00001004 const ArchSpec *arch_spec,
1005 bool stop_at_entry,
1006 bool disable_aslr
1007)
1008{
1009 return LLDB_INVALID_PROCESS_ID;
1010}
1011
Greg Clayton8f3b21d2010-09-07 20:11:56 +00001012#endif