blob: e8d2cedaa940aea6b4e920d766c3cc22d59d750d [file] [log] [blame]
Greg Clayton2bddd342010-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
Daniel Malea93a64302012-12-05 00:20:57 +000010#include "lldb/lldb-python.h"
11
Greg Claytone3e3fee2013-02-17 20:46:30 +000012// C includes
13#include <dlfcn.h>
14#include <errno.h>
15#include <grp.h>
16#include <limits.h>
17#include <netdb.h>
18#include <pwd.h>
19#include <sys/sysctl.h>
20#include <sys/types.h>
21#include <unistd.h>
22
23#if defined (__APPLE__)
24
25#include <dispatch/dispatch.h>
26#include <libproc.h>
27#include <mach-o/dyld.h>
28#include <mach/mach_port.h>
29
Sylvestre Ledru99446cf2013-05-15 13:56:44 +000030#elif defined (__linux__) || defined(__FreeBSD_kernel__)
31/* Linux or the FreeBSD kernel with glibc (Debian KFreeBSD for example) */
Greg Claytone3e3fee2013-02-17 20:46:30 +000032
33#include <sys/wait.h>
34
35#elif defined (__FreeBSD__)
36
37#include <sys/wait.h>
38#include <pthread_np.h>
39
40#endif
41
Greg Clayton2bddd342010-09-07 20:11:56 +000042#include "lldb/Host/Host.h"
43#include "lldb/Core/ArchSpec.h"
44#include "lldb/Core/ConstString.h"
Sean Callananc0a6e062011-10-27 21:22:25 +000045#include "lldb/Core/Debugger.h"
Greg Clayton2bddd342010-09-07 20:11:56 +000046#include "lldb/Core/Error.h"
Greg Clayton2bddd342010-09-07 20:11:56 +000047#include "lldb/Core/Log.h"
48#include "lldb/Core/StreamString.h"
Jim Inghamc075ecd2012-05-04 19:24:49 +000049#include "lldb/Core/ThreadSafeSTLMap.h"
Greg Clayton45319462011-02-08 00:35:34 +000050#include "lldb/Host/Config.h"
Greg Clayton7fb56d02011-02-01 01:31:41 +000051#include "lldb/Host/Endian.h"
Greg Claytone996fd32011-03-08 22:40:15 +000052#include "lldb/Host/FileSpec.h"
Greg Clayton2bddd342010-09-07 20:11:56 +000053#include "lldb/Host/Mutex.h"
Greg Claytone996fd32011-03-08 22:40:15 +000054#include "lldb/Target/Process.h"
Sean Callananc0a6e062011-10-27 21:22:25 +000055#include "lldb/Target/TargetList.h"
Greg Clayton2bddd342010-09-07 20:11:56 +000056
Stephen Wilsonbd588712011-02-24 19:15:09 +000057#include "llvm/Support/Host.h"
Greg Claytone996fd32011-03-08 22:40:15 +000058#include "llvm/Support/MachO.h"
Daniel Malea53430eb2013-01-04 23:35:13 +000059#include "llvm/ADT/Twine.h"
Stephen Wilsonbd588712011-02-24 19:15:09 +000060
Greg Clayton32e0a752011-03-30 18:16:51 +000061
Greg Clayton2bddd342010-09-07 20:11:56 +000062
Greg Clayton45319462011-02-08 00:35:34 +000063
Greg Clayton2bddd342010-09-07 20:11:56 +000064
65using namespace lldb;
66using namespace lldb_private;
67
Greg Claytone4e45922011-11-16 05:37:56 +000068
Greg Clayton1c4cd072011-11-17 19:41:57 +000069#if !defined (__APPLE__)
Greg Clayton2bddd342010-09-07 20:11:56 +000070struct MonitorInfo
71{
72 lldb::pid_t pid; // The process ID to monitor
73 Host::MonitorChildProcessCallback callback; // The callback function to call when "pid" exits or signals
74 void *callback_baton; // The callback baton for the callback function
75 bool monitor_signals; // If true, call the callback when "pid" gets signaled.
76};
77
78static void *
79MonitorChildProcessThreadFunction (void *arg);
80
81lldb::thread_t
82Host::StartMonitoringChildProcess
83(
84 Host::MonitorChildProcessCallback callback,
85 void *callback_baton,
86 lldb::pid_t pid,
87 bool monitor_signals
88)
89{
90 lldb::thread_t thread = LLDB_INVALID_HOST_THREAD;
Greg Claytone4e45922011-11-16 05:37:56 +000091 MonitorInfo * info_ptr = new MonitorInfo();
Greg Clayton2bddd342010-09-07 20:11:56 +000092
Greg Claytone4e45922011-11-16 05:37:56 +000093 info_ptr->pid = pid;
94 info_ptr->callback = callback;
95 info_ptr->callback_baton = callback_baton;
96 info_ptr->monitor_signals = monitor_signals;
97
98 char thread_name[256];
Daniel Malead01b2952012-11-29 21:49:15 +000099 ::snprintf (thread_name, sizeof(thread_name), "<lldb.host.wait4(pid=%" PRIu64 ")>", pid);
Greg Claytone4e45922011-11-16 05:37:56 +0000100 thread = ThreadCreate (thread_name,
101 MonitorChildProcessThreadFunction,
102 info_ptr,
103 NULL);
104
Greg Clayton2bddd342010-09-07 20:11:56 +0000105 return thread;
106}
107
108//------------------------------------------------------------------
109// Scoped class that will disable thread canceling when it is
110// constructed, and exception safely restore the previous value it
111// when it goes out of scope.
112//------------------------------------------------------------------
113class ScopedPThreadCancelDisabler
114{
115public:
116 ScopedPThreadCancelDisabler()
117 {
118 // Disable the ability for this thread to be cancelled
119 int err = ::pthread_setcancelstate (PTHREAD_CANCEL_DISABLE, &m_old_state);
120 if (err != 0)
121 m_old_state = -1;
122
123 }
124
125 ~ScopedPThreadCancelDisabler()
126 {
127 // Restore the ability for this thread to be cancelled to what it
128 // previously was.
129 if (m_old_state != -1)
130 ::pthread_setcancelstate (m_old_state, 0);
131 }
132private:
133 int m_old_state; // Save the old cancelability state.
134};
135
136static void *
137MonitorChildProcessThreadFunction (void *arg)
138{
Greg Clayton5160ce52013-03-27 23:08:40 +0000139 Log *log(lldb_private::GetLogIfAllCategoriesSet (LIBLLDB_LOG_PROCESS));
Greg Clayton2bddd342010-09-07 20:11:56 +0000140 const char *function = __FUNCTION__;
141 if (log)
142 log->Printf ("%s (arg = %p) thread starting...", function, arg);
143
144 MonitorInfo *info = (MonitorInfo *)arg;
145
146 const Host::MonitorChildProcessCallback callback = info->callback;
147 void * const callback_baton = info->callback_baton;
148 const lldb::pid_t pid = info->pid;
149 const bool monitor_signals = info->monitor_signals;
150
151 delete info;
152
153 int status = -1;
Ashok Thirumurthi0f3b9b82013-05-01 20:38:19 +0000154#if defined (__FreeBSD__)
155 #define __WALL 0
156#endif
Matt Kopec650648f2013-01-08 16:30:18 +0000157 const int options = __WALL;
158
Greg Clayton2bddd342010-09-07 20:11:56 +0000159 while (1)
160 {
Caroline Tice20ad3c42010-10-29 21:48:37 +0000161 log = lldb_private::GetLogIfAllCategoriesSet (LIBLLDB_LOG_PROCESS);
Greg Clayton2bddd342010-09-07 20:11:56 +0000162 if (log)
Daniel Malead01b2952012-11-29 21:49:15 +0000163 log->Printf("%s ::wait_pid (pid = %" PRIu64 ", &status, options = %i)...", function, pid, options);
Greg Clayton2bddd342010-09-07 20:11:56 +0000164
165 // Wait for all child processes
166 ::pthread_testcancel ();
Matt Kopec650648f2013-01-08 16:30:18 +0000167 // Get signals from all children with same process group of pid
168 const lldb::pid_t wait_pid = ::waitpid (-1*pid, &status, options);
Greg Clayton2bddd342010-09-07 20:11:56 +0000169 ::pthread_testcancel ();
170
171 if (wait_pid == -1)
172 {
173 if (errno == EINTR)
174 continue;
175 else
176 break;
177 }
Matt Kopec650648f2013-01-08 16:30:18 +0000178 else if (wait_pid > 0)
Greg Clayton2bddd342010-09-07 20:11:56 +0000179 {
180 bool exited = false;
181 int signal = 0;
182 int exit_status = 0;
183 const char *status_cstr = NULL;
184 if (WIFSTOPPED(status))
185 {
186 signal = WSTOPSIG(status);
187 status_cstr = "STOPPED";
188 }
189 else if (WIFEXITED(status))
190 {
191 exit_status = WEXITSTATUS(status);
192 status_cstr = "EXITED";
Matt Kopec650648f2013-01-08 16:30:18 +0000193 if (wait_pid == pid)
194 exited = true;
Greg Clayton2bddd342010-09-07 20:11:56 +0000195 }
196 else if (WIFSIGNALED(status))
197 {
198 signal = WTERMSIG(status);
199 status_cstr = "SIGNALED";
Matt Kopec650648f2013-01-08 16:30:18 +0000200 if (wait_pid == pid) {
201 exited = true;
202 exit_status = -1;
203 }
Greg Clayton2bddd342010-09-07 20:11:56 +0000204 }
205 else
206 {
Johnny Chen44805302011-07-19 19:48:13 +0000207 status_cstr = "(\?\?\?)";
Greg Clayton2bddd342010-09-07 20:11:56 +0000208 }
209
210 // Scope for pthread_cancel_disabler
211 {
212 ScopedPThreadCancelDisabler pthread_cancel_disabler;
213
Caroline Tice20ad3c42010-10-29 21:48:37 +0000214 log = lldb_private::GetLogIfAllCategoriesSet (LIBLLDB_LOG_PROCESS);
Greg Clayton2bddd342010-09-07 20:11:56 +0000215 if (log)
Daniel Malead01b2952012-11-29 21:49:15 +0000216 log->Printf ("%s ::waitpid (pid = %" PRIu64 ", &status, options = %i) => pid = %" PRIu64 ", status = 0x%8.8x (%s), signal = %i, exit_state = %i",
Greg Clayton2bddd342010-09-07 20:11:56 +0000217 function,
218 wait_pid,
219 options,
Greg Clayton2bddd342010-09-07 20:11:56 +0000220 pid,
221 status,
222 status_cstr,
223 signal,
224 exit_status);
225
226 if (exited || (signal != 0 && monitor_signals))
227 {
Greg Claytone4e45922011-11-16 05:37:56 +0000228 bool callback_return = false;
229 if (callback)
Matt Kopec650648f2013-01-08 16:30:18 +0000230 callback_return = callback (callback_baton, wait_pid, exited, signal, exit_status);
Greg Clayton2bddd342010-09-07 20:11:56 +0000231
232 // If our process exited, then this thread should exit
233 if (exited)
234 break;
235 // If the callback returns true, it means this process should
236 // exit
237 if (callback_return)
238 break;
239 }
240 }
241 }
242 }
243
Caroline Tice20ad3c42010-10-29 21:48:37 +0000244 log = lldb_private::GetLogIfAllCategoriesSet (LIBLLDB_LOG_PROCESS);
Greg Clayton2bddd342010-09-07 20:11:56 +0000245 if (log)
246 log->Printf ("%s (arg = %p) thread exiting...", __FUNCTION__, arg);
247
248 return NULL;
249}
250
Greg Claytone38a5ed2012-01-05 03:57:59 +0000251
252void
253Host::SystemLog (SystemLogType type, const char *format, va_list args)
254{
255 vfprintf (stderr, format, args);
256}
257
Greg Claytone4e45922011-11-16 05:37:56 +0000258#endif // #if !defined (__APPLE__)
259
Greg Claytone38a5ed2012-01-05 03:57:59 +0000260void
261Host::SystemLog (SystemLogType type, const char *format, ...)
262{
263 va_list args;
264 va_start (args, format);
265 SystemLog (type, format, args);
266 va_end (args);
267}
268
Greg Clayton2bddd342010-09-07 20:11:56 +0000269size_t
270Host::GetPageSize()
271{
272 return ::getpagesize();
273}
274
Greg Clayton2bddd342010-09-07 20:11:56 +0000275const ArchSpec &
Greg Clayton514487e2011-02-15 21:59:32 +0000276Host::GetArchitecture (SystemDefaultArchitecture arch_kind)
Greg Clayton2bddd342010-09-07 20:11:56 +0000277{
Greg Clayton514487e2011-02-15 21:59:32 +0000278 static bool g_supports_32 = false;
279 static bool g_supports_64 = false;
280 static ArchSpec g_host_arch_32;
281 static ArchSpec g_host_arch_64;
282
Greg Clayton2bddd342010-09-07 20:11:56 +0000283#if defined (__APPLE__)
Greg Clayton514487e2011-02-15 21:59:32 +0000284
285 // Apple is different in that it can support both 32 and 64 bit executables
286 // in the same operating system running concurrently. Here we detect the
287 // correct host architectures for both 32 and 64 bit including if 64 bit
288 // executables are supported on the system.
289
290 if (g_supports_32 == false && g_supports_64 == false)
291 {
292 // All apple systems support 32 bit execution.
293 g_supports_32 = true;
Greg Clayton2bddd342010-09-07 20:11:56 +0000294 uint32_t cputype, cpusubtype;
Greg Clayton514487e2011-02-15 21:59:32 +0000295 uint32_t is_64_bit_capable = false;
Greg Clayton2bddd342010-09-07 20:11:56 +0000296 size_t len = sizeof(cputype);
Greg Clayton514487e2011-02-15 21:59:32 +0000297 ArchSpec host_arch;
298 // These will tell us about the kernel architecture, which even on a 64
299 // bit machine can be 32 bit...
Greg Clayton2bddd342010-09-07 20:11:56 +0000300 if (::sysctlbyname("hw.cputype", &cputype, &len, NULL, 0) == 0)
301 {
Greg Clayton514487e2011-02-15 21:59:32 +0000302 len = sizeof (cpusubtype);
303 if (::sysctlbyname("hw.cpusubtype", &cpusubtype, &len, NULL, 0) != 0)
304 cpusubtype = CPU_TYPE_ANY;
305
Greg Clayton2bddd342010-09-07 20:11:56 +0000306 len = sizeof (is_64_bit_capable);
307 if (::sysctlbyname("hw.cpu64bit_capable", &is_64_bit_capable, &len, NULL, 0) == 0)
308 {
309 if (is_64_bit_capable)
Greg Clayton514487e2011-02-15 21:59:32 +0000310 g_supports_64 = true;
311 }
312
313 if (is_64_bit_capable)
314 {
Greg Clayton93d3c8332011-02-16 04:46:07 +0000315#if defined (__i386__) || defined (__x86_64__)
316 if (cpusubtype == CPU_SUBTYPE_486)
317 cpusubtype = CPU_SUBTYPE_I386_ALL;
318#endif
Greg Clayton514487e2011-02-15 21:59:32 +0000319 if (cputype & CPU_ARCH_ABI64)
Greg Clayton2bddd342010-09-07 20:11:56 +0000320 {
Greg Clayton514487e2011-02-15 21:59:32 +0000321 // We have a 64 bit kernel on a 64 bit system
Greg Claytone0d378b2011-03-24 21:19:54 +0000322 g_host_arch_32.SetArchitecture (eArchTypeMachO, ~(CPU_ARCH_MASK) & cputype, cpusubtype);
323 g_host_arch_64.SetArchitecture (eArchTypeMachO, cputype, cpusubtype);
Greg Clayton514487e2011-02-15 21:59:32 +0000324 }
325 else
326 {
327 // We have a 32 bit kernel on a 64 bit system
Greg Claytone0d378b2011-03-24 21:19:54 +0000328 g_host_arch_32.SetArchitecture (eArchTypeMachO, cputype, cpusubtype);
Greg Clayton2bddd342010-09-07 20:11:56 +0000329 cputype |= CPU_ARCH_ABI64;
Greg Claytone0d378b2011-03-24 21:19:54 +0000330 g_host_arch_64.SetArchitecture (eArchTypeMachO, cputype, cpusubtype);
Greg Clayton2bddd342010-09-07 20:11:56 +0000331 }
332 }
Greg Clayton514487e2011-02-15 21:59:32 +0000333 else
334 {
Greg Claytone0d378b2011-03-24 21:19:54 +0000335 g_host_arch_32.SetArchitecture (eArchTypeMachO, cputype, cpusubtype);
Greg Clayton514487e2011-02-15 21:59:32 +0000336 g_host_arch_64.Clear();
337 }
Greg Clayton2bddd342010-09-07 20:11:56 +0000338 }
Greg Clayton514487e2011-02-15 21:59:32 +0000339 }
340
341#else // #if defined (__APPLE__)
Stephen Wilsonbd588712011-02-24 19:15:09 +0000342
Greg Clayton514487e2011-02-15 21:59:32 +0000343 if (g_supports_32 == false && g_supports_64 == false)
344 {
Peter Collingbourne1f6198d2011-11-05 01:35:31 +0000345 llvm::Triple triple(llvm::sys::getDefaultTargetTriple());
Greg Clayton514487e2011-02-15 21:59:32 +0000346
Stephen Wilsonbd588712011-02-24 19:15:09 +0000347 g_host_arch_32.Clear();
348 g_host_arch_64.Clear();
Greg Clayton514487e2011-02-15 21:59:32 +0000349
Greg Claytonb29e6c62012-10-11 17:38:58 +0000350 // If the OS is Linux, "unknown" in the vendor slot isn't what we want
351 // for the default triple. It's probably an artifact of config.guess.
352 if (triple.getOS() == llvm::Triple::Linux && triple.getVendor() == llvm::Triple::UnknownVendor)
353 triple.setVendorName("");
354
Stephen Wilsonbd588712011-02-24 19:15:09 +0000355 switch (triple.getArch())
356 {
357 default:
358 g_host_arch_32.SetTriple(triple);
359 g_supports_32 = true;
360 break;
Greg Clayton514487e2011-02-15 21:59:32 +0000361
Stephen Wilsonbd588712011-02-24 19:15:09 +0000362 case llvm::Triple::x86_64:
Greg Clayton542e4072012-09-07 17:49:29 +0000363 g_host_arch_64.SetTriple(triple);
364 g_supports_64 = true;
365 g_host_arch_32.SetTriple(triple.get32BitArchVariant());
366 g_supports_32 = true;
367 break;
368
Stephen Wilsonbd588712011-02-24 19:15:09 +0000369 case llvm::Triple::sparcv9:
370 case llvm::Triple::ppc64:
Stephen Wilsonbd588712011-02-24 19:15:09 +0000371 g_host_arch_64.SetTriple(triple);
372 g_supports_64 = true;
373 break;
374 }
Greg Clayton4796c4f2011-02-17 02:05:38 +0000375
376 g_supports_32 = g_host_arch_32.IsValid();
377 g_supports_64 = g_host_arch_64.IsValid();
Greg Clayton2bddd342010-09-07 20:11:56 +0000378 }
Greg Clayton514487e2011-02-15 21:59:32 +0000379
380#endif // #else for #if defined (__APPLE__)
381
382 if (arch_kind == eSystemDefaultArchitecture32)
383 return g_host_arch_32;
384 else if (arch_kind == eSystemDefaultArchitecture64)
385 return g_host_arch_64;
386
387 if (g_supports_64)
388 return g_host_arch_64;
389
390 return g_host_arch_32;
Greg Clayton2bddd342010-09-07 20:11:56 +0000391}
392
393const ConstString &
394Host::GetVendorString()
395{
396 static ConstString g_vendor;
397 if (!g_vendor)
398 {
Greg Clayton950971f2012-05-12 00:01:21 +0000399 const ArchSpec &host_arch = GetArchitecture (eSystemDefaultArchitecture);
400 const llvm::StringRef &str_ref = host_arch.GetTriple().getVendorName();
401 g_vendor.SetCStringWithLength(str_ref.data(), str_ref.size());
Greg Clayton2bddd342010-09-07 20:11:56 +0000402 }
403 return g_vendor;
404}
405
406const ConstString &
407Host::GetOSString()
408{
409 static ConstString g_os_string;
410 if (!g_os_string)
411 {
Greg Clayton950971f2012-05-12 00:01:21 +0000412 const ArchSpec &host_arch = GetArchitecture (eSystemDefaultArchitecture);
413 const llvm::StringRef &str_ref = host_arch.GetTriple().getOSName();
414 g_os_string.SetCStringWithLength(str_ref.data(), str_ref.size());
Greg Clayton2bddd342010-09-07 20:11:56 +0000415 }
416 return g_os_string;
417}
418
419const ConstString &
420Host::GetTargetTriple()
421{
422 static ConstString g_host_triple;
423 if (!(g_host_triple))
424 {
Greg Clayton950971f2012-05-12 00:01:21 +0000425 const ArchSpec &host_arch = GetArchitecture (eSystemDefaultArchitecture);
426 g_host_triple.SetCString(host_arch.GetTriple().getTriple().c_str());
Greg Clayton2bddd342010-09-07 20:11:56 +0000427 }
428 return g_host_triple;
429}
430
431lldb::pid_t
432Host::GetCurrentProcessID()
433{
434 return ::getpid();
435}
436
437lldb::tid_t
438Host::GetCurrentThreadID()
439{
440#if defined (__APPLE__)
Greg Clayton813ddfc2012-09-18 18:19:49 +0000441 // Calling "mach_port_deallocate()" bumps the reference count on the thread
442 // port, so we need to deallocate it. mach_task_self() doesn't bump the ref
443 // count.
444 thread_port_t thread_self = mach_thread_self();
445 mach_port_deallocate(mach_task_self(), thread_self);
446 return thread_self;
Johnny Chen8f3d8382011-08-02 20:52:42 +0000447#elif defined(__FreeBSD__)
448 return lldb::tid_t(pthread_getthreadid_np());
Greg Clayton2bddd342010-09-07 20:11:56 +0000449#else
450 return lldb::tid_t(pthread_self());
451#endif
452}
453
Jim Ingham372787f2012-04-07 00:00:41 +0000454lldb::thread_t
455Host::GetCurrentThread ()
456{
457 return lldb::thread_t(pthread_self());
458}
459
Greg Clayton2bddd342010-09-07 20:11:56 +0000460const char *
461Host::GetSignalAsCString (int signo)
462{
463 switch (signo)
464 {
465 case SIGHUP: return "SIGHUP"; // 1 hangup
466 case SIGINT: return "SIGINT"; // 2 interrupt
467 case SIGQUIT: return "SIGQUIT"; // 3 quit
468 case SIGILL: return "SIGILL"; // 4 illegal instruction (not reset when caught)
469 case SIGTRAP: return "SIGTRAP"; // 5 trace trap (not reset when caught)
470 case SIGABRT: return "SIGABRT"; // 6 abort()
Greg Clayton0ddf6be2011-11-04 03:42:38 +0000471#if (defined(_POSIX_C_SOURCE) && !defined(_DARWIN_C_SOURCE))
Greg Clayton2bddd342010-09-07 20:11:56 +0000472 case SIGPOLL: return "SIGPOLL"; // 7 pollable event ([XSR] generated, not supported)
Benjamin Kramer44030f12011-11-04 16:06:40 +0000473#endif
474#if !defined(_POSIX_C_SOURCE)
Greg Clayton2bddd342010-09-07 20:11:56 +0000475 case SIGEMT: return "SIGEMT"; // 7 EMT instruction
Benjamin Kramer44030f12011-11-04 16:06:40 +0000476#endif
Greg Clayton2bddd342010-09-07 20:11:56 +0000477 case SIGFPE: return "SIGFPE"; // 8 floating point exception
478 case SIGKILL: return "SIGKILL"; // 9 kill (cannot be caught or ignored)
479 case SIGBUS: return "SIGBUS"; // 10 bus error
480 case SIGSEGV: return "SIGSEGV"; // 11 segmentation violation
481 case SIGSYS: return "SIGSYS"; // 12 bad argument to system call
482 case SIGPIPE: return "SIGPIPE"; // 13 write on a pipe with no one to read it
483 case SIGALRM: return "SIGALRM"; // 14 alarm clock
484 case SIGTERM: return "SIGTERM"; // 15 software termination signal from kill
485 case SIGURG: return "SIGURG"; // 16 urgent condition on IO channel
486 case SIGSTOP: return "SIGSTOP"; // 17 sendable stop signal not from tty
487 case SIGTSTP: return "SIGTSTP"; // 18 stop signal from tty
488 case SIGCONT: return "SIGCONT"; // 19 continue a stopped process
489 case SIGCHLD: return "SIGCHLD"; // 20 to parent on child stop or exit
490 case SIGTTIN: return "SIGTTIN"; // 21 to readers pgrp upon background tty read
491 case SIGTTOU: return "SIGTTOU"; // 22 like TTIN for output if (tp->t_local&LTOSTOP)
492#if !defined(_POSIX_C_SOURCE)
493 case SIGIO: return "SIGIO"; // 23 input/output possible signal
494#endif
495 case SIGXCPU: return "SIGXCPU"; // 24 exceeded CPU time limit
496 case SIGXFSZ: return "SIGXFSZ"; // 25 exceeded file size limit
497 case SIGVTALRM: return "SIGVTALRM"; // 26 virtual time alarm
498 case SIGPROF: return "SIGPROF"; // 27 profiling time alarm
499#if !defined(_POSIX_C_SOURCE)
500 case SIGWINCH: return "SIGWINCH"; // 28 window size changes
501 case SIGINFO: return "SIGINFO"; // 29 information request
502#endif
503 case SIGUSR1: return "SIGUSR1"; // 30 user defined signal 1
504 case SIGUSR2: return "SIGUSR2"; // 31 user defined signal 2
505 default:
506 break;
507 }
508 return NULL;
509}
510
511void
512Host::WillTerminate ()
513{
514}
515
Matt Kopec62502c62013-05-13 19:33:58 +0000516#if !defined (__APPLE__) && !defined (__FreeBSD__) && !defined (__linux__) // see macosx/Host.mm
517
Greg Clayton2bddd342010-09-07 20:11:56 +0000518void
519Host::ThreadCreated (const char *thread_name)
520{
521}
Greg Claytone5219662010-12-03 06:02:24 +0000522
Peter Collingbourne2ced9132011-08-05 00:35:43 +0000523void
Greg Claytone5219662010-12-03 06:02:24 +0000524Host::Backtrace (Stream &strm, uint32_t max_frames)
525{
Greg Clayton4272cc72011-02-02 02:24:04 +0000526 // TODO: Is there a way to backtrace the current process on linux? Other systems?
Greg Claytone5219662010-12-03 06:02:24 +0000527}
528
Greg Clayton85851dd2010-12-04 00:10:17 +0000529size_t
530Host::GetEnvironment (StringList &env)
531{
Greg Clayton4272cc72011-02-02 02:24:04 +0000532 // TODO: Is there a way to the host environment for this process on linux? Other systems?
Greg Clayton85851dd2010-12-04 00:10:17 +0000533 return 0;
534}
535
Matt Kopec62502c62013-05-13 19:33:58 +0000536#endif // #if !defined (__APPLE__) && !defined (__FreeBSD__) && !defined (__linux__)
Greg Clayton2bddd342010-09-07 20:11:56 +0000537
538struct HostThreadCreateInfo
539{
540 std::string thread_name;
541 thread_func_t thread_fptr;
542 thread_arg_t thread_arg;
543
544 HostThreadCreateInfo (const char *name, thread_func_t fptr, thread_arg_t arg) :
545 thread_name (name ? name : ""),
546 thread_fptr (fptr),
547 thread_arg (arg)
548 {
549 }
550};
551
552static thread_result_t
553ThreadCreateTrampoline (thread_arg_t arg)
554{
555 HostThreadCreateInfo *info = (HostThreadCreateInfo *)arg;
556 Host::ThreadCreated (info->thread_name.c_str());
557 thread_func_t thread_fptr = info->thread_fptr;
558 thread_arg_t thread_arg = info->thread_arg;
559
Greg Clayton5160ce52013-03-27 23:08:40 +0000560 Log *log(lldb_private::GetLogIfAllCategoriesSet (LIBLLDB_LOG_THREAD));
Greg Clayton2bddd342010-09-07 20:11:56 +0000561 if (log)
562 log->Printf("thread created");
563
564 delete info;
565 return thread_fptr (thread_arg);
566}
567
568lldb::thread_t
569Host::ThreadCreate
570(
571 const char *thread_name,
572 thread_func_t thread_fptr,
573 thread_arg_t thread_arg,
574 Error *error
575)
576{
577 lldb::thread_t thread = LLDB_INVALID_HOST_THREAD;
578
579 // Host::ThreadCreateTrampoline will delete this pointer for us.
580 HostThreadCreateInfo *info_ptr = new HostThreadCreateInfo (thread_name, thread_fptr, thread_arg);
581
582 int err = ::pthread_create (&thread, NULL, ThreadCreateTrampoline, info_ptr);
583 if (err == 0)
584 {
585 if (error)
586 error->Clear();
587 return thread;
588 }
589
590 if (error)
591 error->SetError (err, eErrorTypePOSIX);
592
593 return LLDB_INVALID_HOST_THREAD;
594}
595
596bool
597Host::ThreadCancel (lldb::thread_t thread, Error *error)
598{
599 int err = ::pthread_cancel (thread);
600 if (error)
601 error->SetError(err, eErrorTypePOSIX);
602 return err == 0;
603}
604
605bool
606Host::ThreadDetach (lldb::thread_t thread, Error *error)
607{
608 int err = ::pthread_detach (thread);
609 if (error)
610 error->SetError(err, eErrorTypePOSIX);
611 return err == 0;
612}
613
614bool
615Host::ThreadJoin (lldb::thread_t thread, thread_result_t *thread_result_ptr, Error *error)
616{
617 int err = ::pthread_join (thread, thread_result_ptr);
618 if (error)
619 error->SetError(err, eErrorTypePOSIX);
620 return err == 0;
621}
622
Jim Inghamc075ecd2012-05-04 19:24:49 +0000623
Greg Clayton85719632013-02-27 22:51:58 +0000624std::string
Greg Clayton2bddd342010-09-07 20:11:56 +0000625Host::GetThreadName (lldb::pid_t pid, lldb::tid_t tid)
626{
Greg Clayton85719632013-02-27 22:51:58 +0000627 std::string thread_name;
Greg Clayton2bddd342010-09-07 20:11:56 +0000628#if defined(__APPLE__) && MAC_OS_X_VERSION_MAX_ALLOWED > MAC_OS_X_VERSION_10_5
Greg Clayton85719632013-02-27 22:51:58 +0000629 // We currently can only get the name of a thread in the current process.
630 if (pid == Host::GetCurrentProcessID())
631 {
632 char pthread_name[1024];
633 if (::pthread_getname_np (::pthread_from_mach_thread_np (tid), pthread_name, sizeof(pthread_name)) == 0)
Greg Clayton2bddd342010-09-07 20:11:56 +0000634 {
Greg Clayton85719632013-02-27 22:51:58 +0000635 if (pthread_name[0])
Greg Clayton2bddd342010-09-07 20:11:56 +0000636 {
Greg Clayton85719632013-02-27 22:51:58 +0000637 thread_name = pthread_name;
Greg Claytoncfd1ace2010-10-31 03:01:06 +0000638 }
Greg Clayton2bddd342010-09-07 20:11:56 +0000639 }
Greg Clayton85719632013-02-27 22:51:58 +0000640 else
641 {
642 dispatch_queue_t current_queue = ::dispatch_get_current_queue ();
643 if (current_queue != NULL)
644 {
645 const char *queue_name = dispatch_queue_get_label (current_queue);
646 if (queue_name && queue_name[0])
647 {
648 thread_name = queue_name;
649 }
650 }
651 }
Greg Clayton2bddd342010-09-07 20:11:56 +0000652 }
Greg Clayton85719632013-02-27 22:51:58 +0000653#endif
654 return thread_name;
Greg Clayton2bddd342010-09-07 20:11:56 +0000655}
656
Matt Kopec62502c62013-05-13 19:33:58 +0000657bool
Greg Clayton2bddd342010-09-07 20:11:56 +0000658Host::SetThreadName (lldb::pid_t pid, lldb::tid_t tid, const char *name)
659{
Greg Clayton85719632013-02-27 22:51:58 +0000660#if defined(__APPLE__) && MAC_OS_X_VERSION_MAX_ALLOWED > MAC_OS_X_VERSION_10_5
Greg Clayton2bddd342010-09-07 20:11:56 +0000661 lldb::pid_t curr_pid = Host::GetCurrentProcessID();
662 lldb::tid_t curr_tid = Host::GetCurrentThreadID();
663 if (pid == LLDB_INVALID_PROCESS_ID)
664 pid = curr_pid;
665
666 if (tid == LLDB_INVALID_THREAD_ID)
667 tid = curr_tid;
668
Greg Clayton2bddd342010-09-07 20:11:56 +0000669 // Set the pthread name if possible
670 if (pid == curr_pid && tid == curr_tid)
671 {
Matt Kopec62502c62013-05-13 19:33:58 +0000672 if (::pthread_setname_np (name) == 0)
673 return true;
Greg Clayton2bddd342010-09-07 20:11:56 +0000674 }
Matt Kopec62502c62013-05-13 19:33:58 +0000675 return false;
676#elif defined (__linux__)
677 void *fn = dlsym (RTLD_DEFAULT, "pthread_setname_np");
678 if (fn)
679 {
680 int (*pthread_setname_np_func)(pthread_t thread, const char *name);
681 *reinterpret_cast<void **> (&pthread_setname_np_func) = fn;
682
683 lldb::pid_t curr_pid = Host::GetCurrentProcessID();
684 lldb::tid_t curr_tid = Host::GetCurrentThreadID();
685
686 if (pid == LLDB_INVALID_PROCESS_ID)
687 pid = curr_pid;
688
689 if (tid == LLDB_INVALID_THREAD_ID)
690 tid = curr_tid;
691
692 if (pid == curr_pid)
693 {
694 if (pthread_setname_np_func (tid, name) == 0)
695 return true;
696 }
697 }
698 return false;
Greg Clayton2bddd342010-09-07 20:11:56 +0000699#endif
Greg Clayton2bddd342010-09-07 20:11:56 +0000700}
701
702FileSpec
703Host::GetProgramFileSpec ()
704{
705 static FileSpec g_program_filespec;
706 if (!g_program_filespec)
707 {
708#if defined (__APPLE__)
709 char program_fullpath[PATH_MAX];
710 // If DST is NULL, then return the number of bytes needed.
711 uint32_t len = sizeof(program_fullpath);
712 int err = _NSGetExecutablePath (program_fullpath, &len);
713 if (err == 0)
Greg Claytonb3326392011-01-13 01:23:43 +0000714 g_program_filespec.SetFile (program_fullpath, false);
Greg Clayton2bddd342010-09-07 20:11:56 +0000715 else if (err == -1)
716 {
717 char *large_program_fullpath = (char *)::malloc (len + 1);
718
719 err = _NSGetExecutablePath (large_program_fullpath, &len);
720 if (err == 0)
Greg Claytonb3326392011-01-13 01:23:43 +0000721 g_program_filespec.SetFile (large_program_fullpath, false);
Greg Clayton2bddd342010-09-07 20:11:56 +0000722
723 ::free (large_program_fullpath);
724 }
725#elif defined (__linux__)
726 char exe_path[PATH_MAX];
Stephen Wilsone5b94a92011-01-12 04:21:21 +0000727 ssize_t len = readlink("/proc/self/exe", exe_path, sizeof(exe_path) - 1);
728 if (len > 0) {
729 exe_path[len] = 0;
Greg Claytonb3326392011-01-13 01:23:43 +0000730 g_program_filespec.SetFile(exe_path, false);
Stephen Wilsone5b94a92011-01-12 04:21:21 +0000731 }
Greg Clayton2bddd342010-09-07 20:11:56 +0000732#elif defined (__FreeBSD__)
733 int exe_path_mib[4] = { CTL_KERN, KERN_PROC, KERN_PROC_PATHNAME, getpid() };
734 size_t exe_path_size;
735 if (sysctl(exe_path_mib, 4, NULL, &exe_path_size, NULL, 0) == 0)
736 {
Greg Clayton87ff1ac2011-01-13 01:27:55 +0000737 char *exe_path = new char[exe_path_size];
738 if (sysctl(exe_path_mib, 4, exe_path, &exe_path_size, NULL, 0) == 0)
739 g_program_filespec.SetFile(exe_path, false);
740 delete[] exe_path;
Greg Clayton2bddd342010-09-07 20:11:56 +0000741 }
742#endif
743 }
744 return g_program_filespec;
745}
746
747FileSpec
748Host::GetModuleFileSpecForHostAddress (const void *host_addr)
749{
750 FileSpec module_filespec;
751 Dl_info info;
752 if (::dladdr (host_addr, &info))
753 {
754 if (info.dli_fname)
Greg Clayton274060b2010-10-20 20:54:39 +0000755 module_filespec.SetFile(info.dli_fname, true);
Greg Clayton2bddd342010-09-07 20:11:56 +0000756 }
757 return module_filespec;
758}
759
760#if !defined (__APPLE__) // see Host.mm
Greg Claytonc859e2d2012-02-13 23:10:39 +0000761
762bool
763Host::GetBundleDirectory (const FileSpec &file, FileSpec &bundle)
764{
765 bundle.Clear();
766 return false;
767}
768
Greg Clayton2bddd342010-09-07 20:11:56 +0000769bool
Greg Claytondd36def2010-10-17 22:03:32 +0000770Host::ResolveExecutableInBundle (FileSpec &file)
Greg Clayton2bddd342010-09-07 20:11:56 +0000771{
Greg Claytondd36def2010-10-17 22:03:32 +0000772 return false;
Greg Clayton2bddd342010-09-07 20:11:56 +0000773}
774#endif
775
Greg Clayton45319462011-02-08 00:35:34 +0000776// Opaque info that tracks a dynamic library that was loaded
777struct DynamicLibraryInfo
Greg Clayton4272cc72011-02-02 02:24:04 +0000778{
Greg Clayton45319462011-02-08 00:35:34 +0000779 DynamicLibraryInfo (const FileSpec &fs, int o, void *h) :
780 file_spec (fs),
781 open_options (o),
782 handle (h)
783 {
784 }
785
786 const FileSpec file_spec;
787 uint32_t open_options;
788 void * handle;
789};
790
791void *
792Host::DynamicLibraryOpen (const FileSpec &file_spec, uint32_t options, Error &error)
793{
Greg Clayton4272cc72011-02-02 02:24:04 +0000794 char path[PATH_MAX];
795 if (file_spec.GetPath(path, sizeof(path)))
796 {
Greg Clayton45319462011-02-08 00:35:34 +0000797 int mode = 0;
798
799 if (options & eDynamicLibraryOpenOptionLazy)
800 mode |= RTLD_LAZY;
Greg Claytonf9399452011-02-08 05:24:57 +0000801 else
802 mode |= RTLD_NOW;
803
Greg Clayton45319462011-02-08 00:35:34 +0000804
805 if (options & eDynamicLibraryOpenOptionLocal)
806 mode |= RTLD_LOCAL;
807 else
808 mode |= RTLD_GLOBAL;
809
810#ifdef LLDB_CONFIG_DLOPEN_RTLD_FIRST_SUPPORTED
811 if (options & eDynamicLibraryOpenOptionLimitGetSymbol)
812 mode |= RTLD_FIRST;
Greg Clayton75852f52011-02-07 17:43:47 +0000813#endif
Greg Clayton45319462011-02-08 00:35:34 +0000814
815 void * opaque = ::dlopen (path, mode);
816
817 if (opaque)
Greg Clayton4272cc72011-02-02 02:24:04 +0000818 {
819 error.Clear();
Greg Clayton45319462011-02-08 00:35:34 +0000820 return new DynamicLibraryInfo (file_spec, options, opaque);
Greg Clayton4272cc72011-02-02 02:24:04 +0000821 }
822 else
823 {
824 error.SetErrorString(::dlerror());
825 }
826 }
827 else
828 {
829 error.SetErrorString("failed to extract path");
830 }
Greg Clayton45319462011-02-08 00:35:34 +0000831 return NULL;
Greg Clayton4272cc72011-02-02 02:24:04 +0000832}
833
834Error
Greg Clayton45319462011-02-08 00:35:34 +0000835Host::DynamicLibraryClose (void *opaque)
Greg Clayton4272cc72011-02-02 02:24:04 +0000836{
837 Error error;
Greg Clayton45319462011-02-08 00:35:34 +0000838 if (opaque == NULL)
Greg Clayton4272cc72011-02-02 02:24:04 +0000839 {
840 error.SetErrorString ("invalid dynamic library handle");
841 }
Greg Clayton45319462011-02-08 00:35:34 +0000842 else
Greg Clayton4272cc72011-02-02 02:24:04 +0000843 {
Greg Clayton45319462011-02-08 00:35:34 +0000844 DynamicLibraryInfo *dylib_info = (DynamicLibraryInfo *) opaque;
845 if (::dlclose (dylib_info->handle) != 0)
846 {
847 error.SetErrorString(::dlerror());
848 }
849
850 dylib_info->open_options = 0;
851 dylib_info->handle = 0;
852 delete dylib_info;
Greg Clayton4272cc72011-02-02 02:24:04 +0000853 }
854 return error;
855}
856
857void *
Greg Clayton45319462011-02-08 00:35:34 +0000858Host::DynamicLibraryGetSymbol (void *opaque, const char *symbol_name, Error &error)
Greg Clayton4272cc72011-02-02 02:24:04 +0000859{
Greg Clayton45319462011-02-08 00:35:34 +0000860 if (opaque == NULL)
Greg Clayton4272cc72011-02-02 02:24:04 +0000861 {
862 error.SetErrorString ("invalid dynamic library handle");
Greg Clayton4272cc72011-02-02 02:24:04 +0000863 }
Greg Clayton4272cc72011-02-02 02:24:04 +0000864 else
Greg Clayton45319462011-02-08 00:35:34 +0000865 {
866 DynamicLibraryInfo *dylib_info = (DynamicLibraryInfo *) opaque;
867
868 void *symbol_addr = ::dlsym (dylib_info->handle, symbol_name);
869 if (symbol_addr)
870 {
871#ifndef LLDB_CONFIG_DLOPEN_RTLD_FIRST_SUPPORTED
872 // This host doesn't support limiting searches to this shared library
873 // so we need to verify that the match came from this shared library
874 // if it was requested in the Host::DynamicLibraryOpen() function.
Greg Claytonf9399452011-02-08 05:24:57 +0000875 if (dylib_info->open_options & eDynamicLibraryOpenOptionLimitGetSymbol)
Greg Clayton45319462011-02-08 00:35:34 +0000876 {
877 FileSpec match_dylib_spec (Host::GetModuleFileSpecForHostAddress (symbol_addr));
878 if (match_dylib_spec != dylib_info->file_spec)
879 {
880 char dylib_path[PATH_MAX];
881 if (dylib_info->file_spec.GetPath (dylib_path, sizeof(dylib_path)))
882 error.SetErrorStringWithFormat ("symbol not found in \"%s\"", dylib_path);
883 else
884 error.SetErrorString ("symbol not found");
885 return NULL;
886 }
887 }
888#endif
889 error.Clear();
890 return symbol_addr;
891 }
892 else
893 {
894 error.SetErrorString(::dlerror());
895 }
896 }
897 return NULL;
Greg Clayton4272cc72011-02-02 02:24:04 +0000898}
Greg Claytondd36def2010-10-17 22:03:32 +0000899
900bool
901Host::GetLLDBPath (PathType path_type, FileSpec &file_spec)
902{
Greg Clayton710dd5a2011-01-08 20:28:42 +0000903 // To get paths related to LLDB we get the path to the executable that
Greg Claytondd36def2010-10-17 22:03:32 +0000904 // contains this function. On MacOSX this will be "LLDB.framework/.../LLDB",
905 // on linux this is assumed to be the "lldb" main executable. If LLDB on
906 // linux is actually in a shared library (lldb.so??) then this function will
907 // need to be modified to "do the right thing".
908
909 switch (path_type)
910 {
911 case ePathTypeLLDBShlibDir:
912 {
913 static ConstString g_lldb_so_dir;
914 if (!g_lldb_so_dir)
915 {
916 FileSpec lldb_file_spec (Host::GetModuleFileSpecForHostAddress ((void *)Host::GetLLDBPath));
917 g_lldb_so_dir = lldb_file_spec.GetDirectory();
918 }
919 file_spec.GetDirectory() = g_lldb_so_dir;
920 return file_spec.GetDirectory();
921 }
922 break;
923
924 case ePathTypeSupportExecutableDir:
925 {
926 static ConstString g_lldb_support_exe_dir;
927 if (!g_lldb_support_exe_dir)
928 {
929 FileSpec lldb_file_spec;
930 if (GetLLDBPath (ePathTypeLLDBShlibDir, lldb_file_spec))
931 {
932 char raw_path[PATH_MAX];
933 char resolved_path[PATH_MAX];
934 lldb_file_spec.GetPath(raw_path, sizeof(raw_path));
935
936#if defined (__APPLE__)
937 char *framework_pos = ::strstr (raw_path, "LLDB.framework");
938 if (framework_pos)
939 {
940 framework_pos += strlen("LLDB.framework");
Greg Claytondce502e2011-11-04 03:34:56 +0000941#if !defined (__arm__)
Greg Claytondd36def2010-10-17 22:03:32 +0000942 ::strncpy (framework_pos, "/Resources", PATH_MAX - (framework_pos - raw_path));
Greg Claytondce502e2011-11-04 03:34:56 +0000943#endif
Greg Claytondd36def2010-10-17 22:03:32 +0000944 }
945#endif
946 FileSpec::Resolve (raw_path, resolved_path, sizeof(resolved_path));
947 g_lldb_support_exe_dir.SetCString(resolved_path);
948 }
949 }
950 file_spec.GetDirectory() = g_lldb_support_exe_dir;
951 return file_spec.GetDirectory();
952 }
953 break;
954
955 case ePathTypeHeaderDir:
956 {
957 static ConstString g_lldb_headers_dir;
958 if (!g_lldb_headers_dir)
959 {
960#if defined (__APPLE__)
961 FileSpec lldb_file_spec;
962 if (GetLLDBPath (ePathTypeLLDBShlibDir, lldb_file_spec))
963 {
964 char raw_path[PATH_MAX];
965 char resolved_path[PATH_MAX];
966 lldb_file_spec.GetPath(raw_path, sizeof(raw_path));
967
968 char *framework_pos = ::strstr (raw_path, "LLDB.framework");
969 if (framework_pos)
970 {
971 framework_pos += strlen("LLDB.framework");
972 ::strncpy (framework_pos, "/Headers", PATH_MAX - (framework_pos - raw_path));
973 }
974 FileSpec::Resolve (raw_path, resolved_path, sizeof(resolved_path));
975 g_lldb_headers_dir.SetCString(resolved_path);
976 }
977#else
Greg Clayton4272cc72011-02-02 02:24:04 +0000978 // TODO: Anyone know how we can determine this for linux? Other systems??
Greg Claytondd36def2010-10-17 22:03:32 +0000979 g_lldb_headers_dir.SetCString ("/opt/local/include/lldb");
980#endif
981 }
982 file_spec.GetDirectory() = g_lldb_headers_dir;
983 return file_spec.GetDirectory();
984 }
985 break;
986
987 case ePathTypePythonDir:
988 {
Greg Claytondd36def2010-10-17 22:03:32 +0000989 static ConstString g_lldb_python_dir;
990 if (!g_lldb_python_dir)
991 {
992 FileSpec lldb_file_spec;
993 if (GetLLDBPath (ePathTypeLLDBShlibDir, lldb_file_spec))
994 {
995 char raw_path[PATH_MAX];
996 char resolved_path[PATH_MAX];
997 lldb_file_spec.GetPath(raw_path, sizeof(raw_path));
998
999#if defined (__APPLE__)
1000 char *framework_pos = ::strstr (raw_path, "LLDB.framework");
1001 if (framework_pos)
1002 {
1003 framework_pos += strlen("LLDB.framework");
1004 ::strncpy (framework_pos, "/Resources/Python", PATH_MAX - (framework_pos - raw_path));
1005 }
Filipe Cabecinhas0b751162012-07-30 16:46:32 +00001006#else
Daniel Malea53430eb2013-01-04 23:35:13 +00001007 llvm::Twine python_version_dir;
1008 python_version_dir = "/python"
1009 + llvm::Twine(PY_MAJOR_VERSION)
1010 + "."
1011 + llvm::Twine(PY_MINOR_VERSION)
1012 + "/site-packages";
1013
Filipe Cabecinhascffbd092012-07-30 18:56:10 +00001014 // We may get our string truncated. Should we protect
1015 // this with an assert?
Daniel Malea53430eb2013-01-04 23:35:13 +00001016
1017 ::strncat(raw_path, python_version_dir.str().c_str(),
1018 sizeof(raw_path) - strlen(raw_path) - 1);
1019
Greg Claytondd36def2010-10-17 22:03:32 +00001020#endif
1021 FileSpec::Resolve (raw_path, resolved_path, sizeof(resolved_path));
1022 g_lldb_python_dir.SetCString(resolved_path);
1023 }
1024 }
1025 file_spec.GetDirectory() = g_lldb_python_dir;
1026 return file_spec.GetDirectory();
1027 }
1028 break;
1029
Greg Clayton4272cc72011-02-02 02:24:04 +00001030 case ePathTypeLLDBSystemPlugins: // System plug-ins directory
1031 {
1032#if defined (__APPLE__)
1033 static ConstString g_lldb_system_plugin_dir;
Greg Clayton1cb64962011-03-24 04:28:38 +00001034 static bool g_lldb_system_plugin_dir_located = false;
1035 if (!g_lldb_system_plugin_dir_located)
Greg Clayton4272cc72011-02-02 02:24:04 +00001036 {
Greg Clayton1cb64962011-03-24 04:28:38 +00001037 g_lldb_system_plugin_dir_located = true;
Greg Clayton4272cc72011-02-02 02:24:04 +00001038 FileSpec lldb_file_spec;
1039 if (GetLLDBPath (ePathTypeLLDBShlibDir, lldb_file_spec))
1040 {
1041 char raw_path[PATH_MAX];
1042 char resolved_path[PATH_MAX];
1043 lldb_file_spec.GetPath(raw_path, sizeof(raw_path));
1044
1045 char *framework_pos = ::strstr (raw_path, "LLDB.framework");
1046 if (framework_pos)
1047 {
1048 framework_pos += strlen("LLDB.framework");
1049 ::strncpy (framework_pos, "/Resources/PlugIns", PATH_MAX - (framework_pos - raw_path));
Greg Clayton1cb64962011-03-24 04:28:38 +00001050 FileSpec::Resolve (raw_path, resolved_path, sizeof(resolved_path));
1051 g_lldb_system_plugin_dir.SetCString(resolved_path);
Greg Clayton4272cc72011-02-02 02:24:04 +00001052 }
Greg Clayton1cb64962011-03-24 04:28:38 +00001053 return false;
Greg Clayton4272cc72011-02-02 02:24:04 +00001054 }
1055 }
Greg Clayton1cb64962011-03-24 04:28:38 +00001056
1057 if (g_lldb_system_plugin_dir)
1058 {
1059 file_spec.GetDirectory() = g_lldb_system_plugin_dir;
1060 return true;
1061 }
Greg Clayton4272cc72011-02-02 02:24:04 +00001062#endif
1063 // TODO: where would system LLDB plug-ins be located on linux? Other systems?
1064 return false;
1065 }
1066 break;
1067
1068 case ePathTypeLLDBUserPlugins: // User plug-ins directory
1069 {
1070#if defined (__APPLE__)
1071 static ConstString g_lldb_user_plugin_dir;
1072 if (!g_lldb_user_plugin_dir)
1073 {
1074 char user_plugin_path[PATH_MAX];
1075 if (FileSpec::Resolve ("~/Library/Application Support/LLDB/PlugIns",
1076 user_plugin_path,
1077 sizeof(user_plugin_path)))
1078 {
1079 g_lldb_user_plugin_dir.SetCString(user_plugin_path);
1080 }
1081 }
1082 file_spec.GetDirectory() = g_lldb_user_plugin_dir;
1083 return file_spec.GetDirectory();
1084#endif
1085 // TODO: where would user LLDB plug-ins be located on linux? Other systems?
1086 return false;
1087 }
Greg Claytondd36def2010-10-17 22:03:32 +00001088 }
1089
1090 return false;
1091}
1092
Greg Clayton1cb64962011-03-24 04:28:38 +00001093
1094bool
1095Host::GetHostname (std::string &s)
1096{
1097 char hostname[PATH_MAX];
1098 hostname[sizeof(hostname) - 1] = '\0';
1099 if (::gethostname (hostname, sizeof(hostname) - 1) == 0)
1100 {
1101 struct hostent* h = ::gethostbyname (hostname);
1102 if (h)
1103 s.assign (h->h_name);
1104 else
1105 s.assign (hostname);
1106 return true;
1107 }
1108 return false;
1109}
1110
Greg Clayton32e0a752011-03-30 18:16:51 +00001111const char *
1112Host::GetUserName (uint32_t uid, std::string &user_name)
1113{
1114 struct passwd user_info;
1115 struct passwd *user_info_ptr = &user_info;
1116 char user_buffer[PATH_MAX];
1117 size_t user_buffer_size = sizeof(user_buffer);
1118 if (::getpwuid_r (uid,
1119 &user_info,
1120 user_buffer,
1121 user_buffer_size,
1122 &user_info_ptr) == 0)
1123 {
1124 if (user_info_ptr)
1125 {
1126 user_name.assign (user_info_ptr->pw_name);
1127 return user_name.c_str();
1128 }
1129 }
1130 user_name.clear();
1131 return NULL;
1132}
1133
1134const char *
1135Host::GetGroupName (uint32_t gid, std::string &group_name)
1136{
1137 char group_buffer[PATH_MAX];
1138 size_t group_buffer_size = sizeof(group_buffer);
1139 struct group group_info;
1140 struct group *group_info_ptr = &group_info;
1141 // Try the threadsafe version first
1142 if (::getgrgid_r (gid,
1143 &group_info,
1144 group_buffer,
1145 group_buffer_size,
1146 &group_info_ptr) == 0)
1147 {
1148 if (group_info_ptr)
1149 {
1150 group_name.assign (group_info_ptr->gr_name);
1151 return group_name.c_str();
1152 }
1153 }
1154 else
1155 {
1156 // The threadsafe version isn't currently working
1157 // for me on darwin, but the non-threadsafe version
1158 // is, so I am calling it below.
1159 group_info_ptr = ::getgrgid (gid);
1160 if (group_info_ptr)
1161 {
1162 group_name.assign (group_info_ptr->gr_name);
1163 return group_name.c_str();
1164 }
1165 }
1166 group_name.clear();
1167 return NULL;
1168}
1169
Johnny Chen8f3d8382011-08-02 20:52:42 +00001170#if !defined (__APPLE__) && !defined (__FreeBSD__) // see macosx/Host.mm
Greg Clayton1cb64962011-03-24 04:28:38 +00001171bool
1172Host::GetOSBuildString (std::string &s)
1173{
1174 s.clear();
1175 return false;
1176}
1177
1178bool
1179Host::GetOSKernelDescription (std::string &s)
1180{
1181 s.clear();
1182 return false;
1183}
Johnny Chen8f3d8382011-08-02 20:52:42 +00001184#endif
Greg Clayton1cb64962011-03-24 04:28:38 +00001185
Han Ming Ong84647042012-02-25 01:07:38 +00001186uint32_t
1187Host::GetUserID ()
1188{
1189 return getuid();
1190}
1191
1192uint32_t
1193Host::GetGroupID ()
1194{
1195 return getgid();
1196}
1197
1198uint32_t
1199Host::GetEffectiveUserID ()
1200{
1201 return geteuid();
1202}
1203
1204uint32_t
1205Host::GetEffectiveGroupID ()
1206{
1207 return getegid();
1208}
1209
1210#if !defined (__APPLE__)
Greg Claytone996fd32011-03-08 22:40:15 +00001211uint32_t
Greg Clayton8b82f082011-04-12 05:54:46 +00001212Host::FindProcesses (const ProcessInstanceInfoMatch &match_info, ProcessInstanceInfoList &process_infos)
Greg Claytone996fd32011-03-08 22:40:15 +00001213{
1214 process_infos.Clear();
Greg Claytone996fd32011-03-08 22:40:15 +00001215 return process_infos.GetSize();
Greg Clayton2bddd342010-09-07 20:11:56 +00001216}
Johnny Chen8f3d8382011-08-02 20:52:42 +00001217#endif
Greg Clayton2bddd342010-09-07 20:11:56 +00001218
Andrew Kaylorbf9b4c12013-05-07 22:46:38 +00001219#if !defined (__APPLE__) && !defined (__FreeBSD__) && !defined(__linux__)
Greg Claytone996fd32011-03-08 22:40:15 +00001220bool
Greg Clayton8b82f082011-04-12 05:54:46 +00001221Host::GetProcessInfo (lldb::pid_t pid, ProcessInstanceInfo &process_info)
Greg Clayton2bddd342010-09-07 20:11:56 +00001222{
Greg Claytone996fd32011-03-08 22:40:15 +00001223 process_info.Clear();
1224 return false;
Greg Clayton2bddd342010-09-07 20:11:56 +00001225}
Johnny Chen8f3d8382011-08-02 20:52:42 +00001226#endif
Greg Clayton2bddd342010-09-07 20:11:56 +00001227
Sean Callananc0a6e062011-10-27 21:22:25 +00001228lldb::TargetSP
1229Host::GetDummyTarget (lldb_private::Debugger &debugger)
1230{
Filipe Cabecinhas721ba3f2012-05-19 09:59:08 +00001231 static TargetSP g_dummy_target_sp;
Filipe Cabecinhasb0183452012-05-17 15:48:02 +00001232
Filipe Cabecinhas721ba3f2012-05-19 09:59:08 +00001233 // FIXME: Maybe the dummy target should be per-Debugger
1234 if (!g_dummy_target_sp || !g_dummy_target_sp->IsValid())
1235 {
1236 ArchSpec arch(Target::GetDefaultArchitecture());
1237 if (!arch.IsValid())
1238 arch = Host::GetArchitecture ();
1239 Error err = debugger.GetTargetList().CreateTarget(debugger,
Greg Claytona0ca6602012-10-18 16:33:33 +00001240 NULL,
Filipe Cabecinhas721ba3f2012-05-19 09:59:08 +00001241 arch.GetTriple().getTriple().c_str(),
1242 false,
1243 NULL,
1244 g_dummy_target_sp);
1245 }
Filipe Cabecinhasb0183452012-05-17 15:48:02 +00001246
Filipe Cabecinhas721ba3f2012-05-19 09:59:08 +00001247 return g_dummy_target_sp;
Sean Callananc0a6e062011-10-27 21:22:25 +00001248}
1249
Greg Claytond1cf11a2012-04-14 01:42:46 +00001250struct ShellInfo
1251{
1252 ShellInfo () :
1253 process_reaped (false),
1254 can_delete (false),
1255 pid (LLDB_INVALID_PROCESS_ID),
1256 signo(-1),
1257 status(-1)
1258 {
1259 }
1260
1261 lldb_private::Predicate<bool> process_reaped;
1262 lldb_private::Predicate<bool> can_delete;
1263 lldb::pid_t pid;
1264 int signo;
1265 int status;
1266};
1267
1268static bool
1269MonitorShellCommand (void *callback_baton,
1270 lldb::pid_t pid,
1271 bool exited, // True if the process did exit
1272 int signo, // Zero for no signal
1273 int status) // Exit value of process if signal is zero
1274{
1275 ShellInfo *shell_info = (ShellInfo *)callback_baton;
1276 shell_info->pid = pid;
1277 shell_info->signo = signo;
1278 shell_info->status = status;
1279 // Let the thread running Host::RunShellCommand() know that the process
1280 // exited and that ShellInfo has been filled in by broadcasting to it
1281 shell_info->process_reaped.SetValue(1, eBroadcastAlways);
1282 // Now wait for a handshake back from that thread running Host::RunShellCommand
1283 // so we know that we can delete shell_info_ptr
1284 shell_info->can_delete.WaitForValueEqualTo(true);
1285 // Sleep a bit to allow the shell_info->can_delete.SetValue() to complete...
1286 usleep(1000);
1287 // Now delete the shell info that was passed into this function
1288 delete shell_info;
1289 return true;
1290}
1291
1292Error
1293Host::RunShellCommand (const char *command,
1294 const char *working_dir,
1295 int *status_ptr,
1296 int *signo_ptr,
1297 std::string *command_output_ptr,
Greg Claytonc8f814d2012-09-27 03:13:55 +00001298 uint32_t timeout_sec,
1299 const char *shell)
Greg Claytond1cf11a2012-04-14 01:42:46 +00001300{
1301 Error error;
1302 ProcessLaunchInfo launch_info;
Greg Claytonc8f814d2012-09-27 03:13:55 +00001303 if (shell && shell[0])
1304 {
1305 // Run the command in a shell
1306 launch_info.SetShell(shell);
1307 launch_info.GetArguments().AppendArgument(command);
1308 const bool localhost = true;
1309 const bool will_debug = false;
1310 const bool first_arg_is_full_shell_command = true;
1311 launch_info.ConvertArgumentsForLaunchingInShell (error,
1312 localhost,
1313 will_debug,
1314 first_arg_is_full_shell_command);
1315 }
1316 else
1317 {
1318 // No shell, just run it
1319 Args args (command);
1320 const bool first_arg_is_executable = true;
Greg Clayton45392552012-10-17 22:57:12 +00001321 launch_info.SetArguments(args, first_arg_is_executable);
Greg Claytonc8f814d2012-09-27 03:13:55 +00001322 }
Greg Claytond1cf11a2012-04-14 01:42:46 +00001323
1324 if (working_dir)
1325 launch_info.SetWorkingDirectory(working_dir);
1326 char output_file_path_buffer[L_tmpnam];
1327 const char *output_file_path = NULL;
1328 if (command_output_ptr)
1329 {
1330 // Create a temporary file to get the stdout/stderr and redirect the
1331 // output of the command into this file. We will later read this file
1332 // if all goes well and fill the data into "command_output_ptr"
1333 output_file_path = ::tmpnam(output_file_path_buffer);
1334 launch_info.AppendSuppressFileAction (STDIN_FILENO, true, false);
1335 launch_info.AppendOpenFileAction(STDOUT_FILENO, output_file_path, false, true);
Greg Claytonc8f814d2012-09-27 03:13:55 +00001336 launch_info.AppendDuplicateFileAction(STDOUT_FILENO, STDERR_FILENO);
Greg Claytond1cf11a2012-04-14 01:42:46 +00001337 }
1338 else
1339 {
1340 launch_info.AppendSuppressFileAction (STDIN_FILENO, true, false);
1341 launch_info.AppendSuppressFileAction (STDOUT_FILENO, false, true);
1342 launch_info.AppendSuppressFileAction (STDERR_FILENO, false, true);
1343 }
1344
1345 // The process monitor callback will delete the 'shell_info_ptr' below...
Greg Clayton7b0992d2013-04-18 22:45:39 +00001346 std::unique_ptr<ShellInfo> shell_info_ap (new ShellInfo());
Greg Claytond1cf11a2012-04-14 01:42:46 +00001347
1348 const bool monitor_signals = false;
1349 launch_info.SetMonitorProcessCallback(MonitorShellCommand, shell_info_ap.get(), monitor_signals);
1350
1351 error = LaunchProcess (launch_info);
1352 const lldb::pid_t pid = launch_info.GetProcessID();
1353 if (pid != LLDB_INVALID_PROCESS_ID)
1354 {
1355 // The process successfully launched, so we can defer ownership of
1356 // "shell_info" to the MonitorShellCommand callback function that will
Greg Claytone01e07b2013-04-18 18:10:51 +00001357 // get called when the process dies. We release the unique pointer as it
Greg Claytond1cf11a2012-04-14 01:42:46 +00001358 // doesn't need to delete the ShellInfo anymore.
1359 ShellInfo *shell_info = shell_info_ap.release();
1360 TimeValue timeout_time(TimeValue::Now());
1361 timeout_time.OffsetWithSeconds(timeout_sec);
1362 bool timed_out = false;
1363 shell_info->process_reaped.WaitForValueEqualTo(true, &timeout_time, &timed_out);
1364 if (timed_out)
1365 {
1366 error.SetErrorString("timed out waiting for shell command to complete");
1367
1368 // Kill the process since it didn't complete withint the timeout specified
1369 ::kill (pid, SIGKILL);
1370 // Wait for the monitor callback to get the message
1371 timeout_time = TimeValue::Now();
1372 timeout_time.OffsetWithSeconds(1);
1373 timed_out = false;
1374 shell_info->process_reaped.WaitForValueEqualTo(true, &timeout_time, &timed_out);
1375 }
1376 else
1377 {
1378 if (status_ptr)
1379 *status_ptr = shell_info->status;
1380
1381 if (signo_ptr)
1382 *signo_ptr = shell_info->signo;
1383
1384 if (command_output_ptr)
1385 {
1386 command_output_ptr->clear();
1387 FileSpec file_spec(output_file_path, File::eOpenOptionRead);
1388 uint64_t file_size = file_spec.GetByteSize();
1389 if (file_size > 0)
1390 {
1391 if (file_size > command_output_ptr->max_size())
1392 {
1393 error.SetErrorStringWithFormat("shell command output is too large to fit into a std::string");
1394 }
1395 else
1396 {
1397 command_output_ptr->resize(file_size);
1398 file_spec.ReadFileContents(0, &((*command_output_ptr)[0]), command_output_ptr->size(), &error);
1399 }
1400 }
1401 }
1402 }
1403 shell_info->can_delete.SetValue(true, eBroadcastAlways);
1404 }
1405 else
1406 {
1407 error.SetErrorString("failed to get process ID");
1408 }
1409
1410 if (output_file_path)
1411 ::unlink (output_file_path);
1412 // Handshake with the monitor thread, or just let it know in advance that
1413 // it can delete "shell_info" in case we timed out and were not able to kill
1414 // the process...
1415 return error;
1416}
1417
1418
Greg Claytone3e3fee2013-02-17 20:46:30 +00001419uint32_t
1420Host::GetNumberCPUS ()
1421{
1422 static uint32_t g_num_cores = UINT32_MAX;
1423 if (g_num_cores == UINT32_MAX)
1424 {
Ashok Thirumurthi0f3b9b82013-05-01 20:38:19 +00001425#if defined(__APPLE__) or defined (__linux__) or defined (__FreeBSD__)
Greg Claytone3e3fee2013-02-17 20:46:30 +00001426
1427 g_num_cores = ::sysconf(_SC_NPROCESSORS_ONLN);
1428
1429#elif defined(_WIN32) || defined(__WIN32__) || defined(__CYGWIN__)
1430
1431 // Header file for this might need to be included at the top of this file
1432 SYSTEM_INFO system_info;
1433 ::GetSystemInfo (&system_info);
1434 g_num_cores = system_info.dwNumberOfProcessors;
1435
1436#else
1437
1438 // Assume POSIX support if a host specific case has not been supplied above
1439 g_num_cores = 0;
1440 int num_cores = 0;
1441 size_t num_cores_len = sizeof(num_cores);
1442 int mib[] = { CTL_HW, HW_AVAILCPU };
1443
1444 /* get the number of CPUs from the system */
1445 if (sysctl(mib, sizeof(mib)/sizeof(int), &num_cores, &num_cores_len, NULL, 0) == 0 && (num_cores > 0))
1446 {
1447 g_num_cores = num_cores;
1448 }
1449 else
1450 {
1451 mib[1] = HW_NCPU;
1452 num_cores_len = sizeof(num_cores);
1453 if (sysctl(mib, sizeof(mib)/sizeof(int), &num_cores, &num_cores_len, NULL, 0) == 0 && (num_cores > 0))
1454 {
1455 if (num_cores > 0)
1456 g_num_cores = num_cores;
1457 }
1458 }
1459#endif
1460 }
1461 return g_num_cores;
1462}
1463
1464
Greg Claytond1cf11a2012-04-14 01:42:46 +00001465
Johnny Chen8f3d8382011-08-02 20:52:42 +00001466#if !defined (__APPLE__)
Greg Clayton2bddd342010-09-07 20:11:56 +00001467bool
Greg Clayton3b147632010-12-18 01:54:34 +00001468Host::OpenFileInExternalEditor (const FileSpec &file_spec, uint32_t line_no)
Greg Clayton2bddd342010-09-07 20:11:56 +00001469{
1470 return false;
1471}
Greg Claytondd36def2010-10-17 22:03:32 +00001472
Greg Clayton2d95dc9b2010-11-10 04:57:04 +00001473void
1474Host::SetCrashDescriptionWithFormat (const char *format, ...)
1475{
1476}
1477
1478void
1479Host::SetCrashDescription (const char *description)
1480{
1481}
Greg Claytondd36def2010-10-17 22:03:32 +00001482
1483lldb::pid_t
1484LaunchApplication (const FileSpec &app_file_spec)
1485{
1486 return LLDB_INVALID_PROCESS_ID;
1487}
1488
Greg Clayton2bddd342010-09-07 20:11:56 +00001489#endif