blob: 2e5b6e98f882fb6e8e5481685f25bfb6cb92c257 [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>
Greg Claytone3e3fee2013-02-17 20:46:30 +000019#include <sys/types.h>
Ed Mastef2b01622013-06-28 12:35:08 +000020#include <sys/sysctl.h>
Greg Claytone3e3fee2013-02-17 20:46:30 +000021#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
Ed Maste8b006c62013-06-25 18:58:11 +000030#endif
Greg Claytone3e3fee2013-02-17 20:46:30 +000031
Ed Maste8b006c62013-06-25 18:58:11 +000032#if defined (__linux__) || defined (__FreeBSD__) || defined (__FreeBSD_kernel__)
Greg Claytone3e3fee2013-02-17 20:46:30 +000033#include <sys/wait.h>
Michael Sartainc2052432013-08-01 18:51:08 +000034#include <sys/syscall.h>
Ed Maste8b006c62013-06-25 18:58:11 +000035#endif
Greg Claytone3e3fee2013-02-17 20:46:30 +000036
Ed Maste8b006c62013-06-25 18:58:11 +000037#if defined (__FreeBSD__)
Greg Claytone3e3fee2013-02-17 20:46:30 +000038#include <pthread_np.h>
Greg Claytone3e3fee2013-02-17 20:46:30 +000039#endif
40
Greg Clayton2bddd342010-09-07 20:11:56 +000041#include "lldb/Host/Host.h"
42#include "lldb/Core/ArchSpec.h"
43#include "lldb/Core/ConstString.h"
Sean Callananc0a6e062011-10-27 21:22:25 +000044#include "lldb/Core/Debugger.h"
Greg Clayton2bddd342010-09-07 20:11:56 +000045#include "lldb/Core/Error.h"
Greg Clayton2bddd342010-09-07 20:11:56 +000046#include "lldb/Core/Log.h"
47#include "lldb/Core/StreamString.h"
Jim Inghamc075ecd2012-05-04 19:24:49 +000048#include "lldb/Core/ThreadSafeSTLMap.h"
Greg Clayton45319462011-02-08 00:35:34 +000049#include "lldb/Host/Config.h"
Greg Clayton7fb56d02011-02-01 01:31:41 +000050#include "lldb/Host/Endian.h"
Greg Claytone996fd32011-03-08 22:40:15 +000051#include "lldb/Host/FileSpec.h"
Greg Clayton2bddd342010-09-07 20:11:56 +000052#include "lldb/Host/Mutex.h"
Greg Claytone996fd32011-03-08 22:40:15 +000053#include "lldb/Target/Process.h"
Sean Callananc0a6e062011-10-27 21:22:25 +000054#include "lldb/Target/TargetList.h"
Greg Clayton2bddd342010-09-07 20:11:56 +000055
Stephen Wilsonbd588712011-02-24 19:15:09 +000056#include "llvm/Support/Host.h"
Greg Claytone996fd32011-03-08 22:40:15 +000057#include "llvm/Support/MachO.h"
Daniel Malea53430eb2013-01-04 23:35:13 +000058#include "llvm/ADT/Twine.h"
Stephen Wilsonbd588712011-02-24 19:15:09 +000059
Greg Clayton32e0a752011-03-30 18:16:51 +000060
Greg Clayton2bddd342010-09-07 20:11:56 +000061
Greg Clayton45319462011-02-08 00:35:34 +000062
Greg Clayton2bddd342010-09-07 20:11:56 +000063
64using namespace lldb;
65using namespace lldb_private;
66
Greg Claytone4e45922011-11-16 05:37:56 +000067
Greg Clayton1c4cd072011-11-17 19:41:57 +000068#if !defined (__APPLE__)
Greg Clayton2bddd342010-09-07 20:11:56 +000069struct MonitorInfo
70{
71 lldb::pid_t pid; // The process ID to monitor
72 Host::MonitorChildProcessCallback callback; // The callback function to call when "pid" exits or signals
73 void *callback_baton; // The callback baton for the callback function
74 bool monitor_signals; // If true, call the callback when "pid" gets signaled.
75};
76
77static void *
78MonitorChildProcessThreadFunction (void *arg);
79
80lldb::thread_t
81Host::StartMonitoringChildProcess
82(
83 Host::MonitorChildProcessCallback callback,
84 void *callback_baton,
85 lldb::pid_t pid,
86 bool monitor_signals
87)
88{
89 lldb::thread_t thread = LLDB_INVALID_HOST_THREAD;
Greg Claytone4e45922011-11-16 05:37:56 +000090 MonitorInfo * info_ptr = new MonitorInfo();
Greg Clayton2bddd342010-09-07 20:11:56 +000091
Greg Claytone4e45922011-11-16 05:37:56 +000092 info_ptr->pid = pid;
93 info_ptr->callback = callback;
94 info_ptr->callback_baton = callback_baton;
95 info_ptr->monitor_signals = monitor_signals;
96
97 char thread_name[256];
Daniel Malead01b2952012-11-29 21:49:15 +000098 ::snprintf (thread_name, sizeof(thread_name), "<lldb.host.wait4(pid=%" PRIu64 ")>", pid);
Greg Claytone4e45922011-11-16 05:37:56 +000099 thread = ThreadCreate (thread_name,
100 MonitorChildProcessThreadFunction,
101 info_ptr,
102 NULL);
103
Greg Clayton2bddd342010-09-07 20:11:56 +0000104 return thread;
105}
106
107//------------------------------------------------------------------
108// Scoped class that will disable thread canceling when it is
109// constructed, and exception safely restore the previous value it
110// when it goes out of scope.
111//------------------------------------------------------------------
112class ScopedPThreadCancelDisabler
113{
114public:
115 ScopedPThreadCancelDisabler()
116 {
117 // Disable the ability for this thread to be cancelled
118 int err = ::pthread_setcancelstate (PTHREAD_CANCEL_DISABLE, &m_old_state);
119 if (err != 0)
120 m_old_state = -1;
121
122 }
123
124 ~ScopedPThreadCancelDisabler()
125 {
126 // Restore the ability for this thread to be cancelled to what it
127 // previously was.
128 if (m_old_state != -1)
129 ::pthread_setcancelstate (m_old_state, 0);
130 }
131private:
132 int m_old_state; // Save the old cancelability state.
133};
134
135static void *
136MonitorChildProcessThreadFunction (void *arg)
137{
Greg Clayton5160ce52013-03-27 23:08:40 +0000138 Log *log(lldb_private::GetLogIfAllCategoriesSet (LIBLLDB_LOG_PROCESS));
Greg Clayton2bddd342010-09-07 20:11:56 +0000139 const char *function = __FUNCTION__;
140 if (log)
141 log->Printf ("%s (arg = %p) thread starting...", function, arg);
142
143 MonitorInfo *info = (MonitorInfo *)arg;
144
145 const Host::MonitorChildProcessCallback callback = info->callback;
146 void * const callback_baton = info->callback_baton;
147 const lldb::pid_t pid = info->pid;
148 const bool monitor_signals = info->monitor_signals;
149
150 delete info;
151
152 int status = -1;
Sylvestre Ledru59405832013-07-01 08:21:36 +0000153#if defined (__FreeBSD__) || defined (__FreeBSD_kernel__)
Ashok Thirumurthi0f3b9b82013-05-01 20:38:19 +0000154 #define __WALL 0
155#endif
Matt Kopec650648f2013-01-08 16:30:18 +0000156 const int options = __WALL;
157
Greg Clayton2bddd342010-09-07 20:11:56 +0000158 while (1)
159 {
Caroline Tice20ad3c42010-10-29 21:48:37 +0000160 log = lldb_private::GetLogIfAllCategoriesSet (LIBLLDB_LOG_PROCESS);
Greg Clayton2bddd342010-09-07 20:11:56 +0000161 if (log)
Daniel Malead01b2952012-11-29 21:49:15 +0000162 log->Printf("%s ::wait_pid (pid = %" PRIu64 ", &status, options = %i)...", function, pid, options);
Greg Clayton2bddd342010-09-07 20:11:56 +0000163
164 // Wait for all child processes
165 ::pthread_testcancel ();
Matt Kopec650648f2013-01-08 16:30:18 +0000166 // Get signals from all children with same process group of pid
167 const lldb::pid_t wait_pid = ::waitpid (-1*pid, &status, options);
Greg Clayton2bddd342010-09-07 20:11:56 +0000168 ::pthread_testcancel ();
169
170 if (wait_pid == -1)
171 {
172 if (errno == EINTR)
173 continue;
174 else
Andrew Kaylor93132f52013-05-28 23:04:25 +0000175 {
176 if (log)
177 log->Printf ("%s (arg = %p) thread exiting because waitpid failed (%s)...", __FUNCTION__, arg, strerror(errno));
Greg Clayton2bddd342010-09-07 20:11:56 +0000178 break;
Andrew Kaylor93132f52013-05-28 23:04:25 +0000179 }
Greg Clayton2bddd342010-09-07 20:11:56 +0000180 }
Matt Kopec650648f2013-01-08 16:30:18 +0000181 else if (wait_pid > 0)
Greg Clayton2bddd342010-09-07 20:11:56 +0000182 {
183 bool exited = false;
184 int signal = 0;
185 int exit_status = 0;
186 const char *status_cstr = NULL;
187 if (WIFSTOPPED(status))
188 {
189 signal = WSTOPSIG(status);
190 status_cstr = "STOPPED";
191 }
192 else if (WIFEXITED(status))
193 {
194 exit_status = WEXITSTATUS(status);
195 status_cstr = "EXITED";
Andrew Kaylor93132f52013-05-28 23:04:25 +0000196 exited = true;
Greg Clayton2bddd342010-09-07 20:11:56 +0000197 }
198 else if (WIFSIGNALED(status))
199 {
200 signal = WTERMSIG(status);
201 status_cstr = "SIGNALED";
Matt Kopec650648f2013-01-08 16:30:18 +0000202 if (wait_pid == pid) {
203 exited = true;
204 exit_status = -1;
205 }
Greg Clayton2bddd342010-09-07 20:11:56 +0000206 }
207 else
208 {
Johnny Chen44805302011-07-19 19:48:13 +0000209 status_cstr = "(\?\?\?)";
Greg Clayton2bddd342010-09-07 20:11:56 +0000210 }
211
212 // Scope for pthread_cancel_disabler
213 {
214 ScopedPThreadCancelDisabler pthread_cancel_disabler;
215
Caroline Tice20ad3c42010-10-29 21:48:37 +0000216 log = lldb_private::GetLogIfAllCategoriesSet (LIBLLDB_LOG_PROCESS);
Greg Clayton2bddd342010-09-07 20:11:56 +0000217 if (log)
Daniel Malead01b2952012-11-29 21:49:15 +0000218 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 +0000219 function,
220 wait_pid,
221 options,
Greg Clayton2bddd342010-09-07 20:11:56 +0000222 pid,
223 status,
224 status_cstr,
225 signal,
226 exit_status);
227
228 if (exited || (signal != 0 && monitor_signals))
229 {
Greg Claytone4e45922011-11-16 05:37:56 +0000230 bool callback_return = false;
231 if (callback)
Matt Kopec650648f2013-01-08 16:30:18 +0000232 callback_return = callback (callback_baton, wait_pid, exited, signal, exit_status);
Greg Clayton2bddd342010-09-07 20:11:56 +0000233
234 // If our process exited, then this thread should exit
Andrew Kaylor93132f52013-05-28 23:04:25 +0000235 if (exited && wait_pid == pid)
236 {
237 if (log)
238 log->Printf ("%s (arg = %p) thread exiting because pid received exit signal...", __FUNCTION__, arg);
Greg Clayton2bddd342010-09-07 20:11:56 +0000239 break;
Andrew Kaylor93132f52013-05-28 23:04:25 +0000240 }
Greg Clayton2bddd342010-09-07 20:11:56 +0000241 // If the callback returns true, it means this process should
242 // exit
243 if (callback_return)
Andrew Kaylor93132f52013-05-28 23:04:25 +0000244 {
245 if (log)
246 log->Printf ("%s (arg = %p) thread exiting because callback returned true...", __FUNCTION__, arg);
Greg Clayton2bddd342010-09-07 20:11:56 +0000247 break;
Andrew Kaylor93132f52013-05-28 23:04:25 +0000248 }
Greg Clayton2bddd342010-09-07 20:11:56 +0000249 }
250 }
251 }
252 }
253
Caroline Tice20ad3c42010-10-29 21:48:37 +0000254 log = lldb_private::GetLogIfAllCategoriesSet (LIBLLDB_LOG_PROCESS);
Greg Clayton2bddd342010-09-07 20:11:56 +0000255 if (log)
256 log->Printf ("%s (arg = %p) thread exiting...", __FUNCTION__, arg);
257
258 return NULL;
259}
260
Greg Claytone38a5ed2012-01-05 03:57:59 +0000261
262void
263Host::SystemLog (SystemLogType type, const char *format, va_list args)
264{
265 vfprintf (stderr, format, args);
266}
267
Greg Claytone4e45922011-11-16 05:37:56 +0000268#endif // #if !defined (__APPLE__)
269
Greg Claytone38a5ed2012-01-05 03:57:59 +0000270void
271Host::SystemLog (SystemLogType type, const char *format, ...)
272{
273 va_list args;
274 va_start (args, format);
275 SystemLog (type, format, args);
276 va_end (args);
277}
278
Greg Clayton2bddd342010-09-07 20:11:56 +0000279size_t
280Host::GetPageSize()
281{
282 return ::getpagesize();
283}
284
Greg Clayton2bddd342010-09-07 20:11:56 +0000285const ArchSpec &
Greg Clayton514487e2011-02-15 21:59:32 +0000286Host::GetArchitecture (SystemDefaultArchitecture arch_kind)
Greg Clayton2bddd342010-09-07 20:11:56 +0000287{
Greg Clayton514487e2011-02-15 21:59:32 +0000288 static bool g_supports_32 = false;
289 static bool g_supports_64 = false;
290 static ArchSpec g_host_arch_32;
291 static ArchSpec g_host_arch_64;
292
Greg Clayton2bddd342010-09-07 20:11:56 +0000293#if defined (__APPLE__)
Greg Clayton514487e2011-02-15 21:59:32 +0000294
295 // Apple is different in that it can support both 32 and 64 bit executables
296 // in the same operating system running concurrently. Here we detect the
297 // correct host architectures for both 32 and 64 bit including if 64 bit
298 // executables are supported on the system.
299
300 if (g_supports_32 == false && g_supports_64 == false)
301 {
302 // All apple systems support 32 bit execution.
303 g_supports_32 = true;
Greg Clayton2bddd342010-09-07 20:11:56 +0000304 uint32_t cputype, cpusubtype;
Greg Clayton514487e2011-02-15 21:59:32 +0000305 uint32_t is_64_bit_capable = false;
Greg Clayton2bddd342010-09-07 20:11:56 +0000306 size_t len = sizeof(cputype);
Greg Clayton514487e2011-02-15 21:59:32 +0000307 ArchSpec host_arch;
308 // These will tell us about the kernel architecture, which even on a 64
309 // bit machine can be 32 bit...
Greg Clayton2bddd342010-09-07 20:11:56 +0000310 if (::sysctlbyname("hw.cputype", &cputype, &len, NULL, 0) == 0)
311 {
Greg Clayton514487e2011-02-15 21:59:32 +0000312 len = sizeof (cpusubtype);
313 if (::sysctlbyname("hw.cpusubtype", &cpusubtype, &len, NULL, 0) != 0)
314 cpusubtype = CPU_TYPE_ANY;
315
Greg Clayton2bddd342010-09-07 20:11:56 +0000316 len = sizeof (is_64_bit_capable);
317 if (::sysctlbyname("hw.cpu64bit_capable", &is_64_bit_capable, &len, NULL, 0) == 0)
318 {
319 if (is_64_bit_capable)
Greg Clayton514487e2011-02-15 21:59:32 +0000320 g_supports_64 = true;
321 }
322
323 if (is_64_bit_capable)
324 {
Greg Clayton93d3c8332011-02-16 04:46:07 +0000325#if defined (__i386__) || defined (__x86_64__)
326 if (cpusubtype == CPU_SUBTYPE_486)
327 cpusubtype = CPU_SUBTYPE_I386_ALL;
328#endif
Greg Clayton514487e2011-02-15 21:59:32 +0000329 if (cputype & CPU_ARCH_ABI64)
Greg Clayton2bddd342010-09-07 20:11:56 +0000330 {
Greg Clayton514487e2011-02-15 21:59:32 +0000331 // We have a 64 bit kernel on a 64 bit system
Greg Claytone0d378b2011-03-24 21:19:54 +0000332 g_host_arch_32.SetArchitecture (eArchTypeMachO, ~(CPU_ARCH_MASK) & cputype, cpusubtype);
333 g_host_arch_64.SetArchitecture (eArchTypeMachO, cputype, cpusubtype);
Greg Clayton514487e2011-02-15 21:59:32 +0000334 }
335 else
336 {
337 // We have a 32 bit kernel on a 64 bit system
Greg Claytone0d378b2011-03-24 21:19:54 +0000338 g_host_arch_32.SetArchitecture (eArchTypeMachO, cputype, cpusubtype);
Greg Clayton2bddd342010-09-07 20:11:56 +0000339 cputype |= CPU_ARCH_ABI64;
Greg Claytone0d378b2011-03-24 21:19:54 +0000340 g_host_arch_64.SetArchitecture (eArchTypeMachO, cputype, cpusubtype);
Greg Clayton2bddd342010-09-07 20:11:56 +0000341 }
342 }
Greg Clayton514487e2011-02-15 21:59:32 +0000343 else
344 {
Greg Claytone0d378b2011-03-24 21:19:54 +0000345 g_host_arch_32.SetArchitecture (eArchTypeMachO, cputype, cpusubtype);
Greg Clayton514487e2011-02-15 21:59:32 +0000346 g_host_arch_64.Clear();
347 }
Greg Clayton2bddd342010-09-07 20:11:56 +0000348 }
Greg Clayton514487e2011-02-15 21:59:32 +0000349 }
350
351#else // #if defined (__APPLE__)
Stephen Wilsonbd588712011-02-24 19:15:09 +0000352
Greg Clayton514487e2011-02-15 21:59:32 +0000353 if (g_supports_32 == false && g_supports_64 == false)
354 {
Peter Collingbourne1f6198d2011-11-05 01:35:31 +0000355 llvm::Triple triple(llvm::sys::getDefaultTargetTriple());
Greg Clayton514487e2011-02-15 21:59:32 +0000356
Stephen Wilsonbd588712011-02-24 19:15:09 +0000357 g_host_arch_32.Clear();
358 g_host_arch_64.Clear();
Greg Clayton514487e2011-02-15 21:59:32 +0000359
Greg Claytonb29e6c62012-10-11 17:38:58 +0000360 // If the OS is Linux, "unknown" in the vendor slot isn't what we want
361 // for the default triple. It's probably an artifact of config.guess.
362 if (triple.getOS() == llvm::Triple::Linux && triple.getVendor() == llvm::Triple::UnknownVendor)
363 triple.setVendorName("");
364
Stephen Wilsonbd588712011-02-24 19:15:09 +0000365 switch (triple.getArch())
366 {
367 default:
368 g_host_arch_32.SetTriple(triple);
369 g_supports_32 = true;
370 break;
Greg Clayton514487e2011-02-15 21:59:32 +0000371
Stephen Wilsonbd588712011-02-24 19:15:09 +0000372 case llvm::Triple::x86_64:
Greg Clayton542e4072012-09-07 17:49:29 +0000373 g_host_arch_64.SetTriple(triple);
374 g_supports_64 = true;
375 g_host_arch_32.SetTriple(triple.get32BitArchVariant());
376 g_supports_32 = true;
377 break;
378
Stephen Wilsonbd588712011-02-24 19:15:09 +0000379 case llvm::Triple::sparcv9:
380 case llvm::Triple::ppc64:
Stephen Wilsonbd588712011-02-24 19:15:09 +0000381 g_host_arch_64.SetTriple(triple);
382 g_supports_64 = true;
383 break;
384 }
Greg Clayton4796c4f2011-02-17 02:05:38 +0000385
386 g_supports_32 = g_host_arch_32.IsValid();
387 g_supports_64 = g_host_arch_64.IsValid();
Greg Clayton2bddd342010-09-07 20:11:56 +0000388 }
Greg Clayton514487e2011-02-15 21:59:32 +0000389
390#endif // #else for #if defined (__APPLE__)
391
392 if (arch_kind == eSystemDefaultArchitecture32)
393 return g_host_arch_32;
394 else if (arch_kind == eSystemDefaultArchitecture64)
395 return g_host_arch_64;
396
397 if (g_supports_64)
398 return g_host_arch_64;
399
400 return g_host_arch_32;
Greg Clayton2bddd342010-09-07 20:11:56 +0000401}
402
403const ConstString &
404Host::GetVendorString()
405{
406 static ConstString g_vendor;
407 if (!g_vendor)
408 {
Greg Clayton950971f2012-05-12 00:01:21 +0000409 const ArchSpec &host_arch = GetArchitecture (eSystemDefaultArchitecture);
410 const llvm::StringRef &str_ref = host_arch.GetTriple().getVendorName();
411 g_vendor.SetCStringWithLength(str_ref.data(), str_ref.size());
Greg Clayton2bddd342010-09-07 20:11:56 +0000412 }
413 return g_vendor;
414}
415
416const ConstString &
417Host::GetOSString()
418{
419 static ConstString g_os_string;
420 if (!g_os_string)
421 {
Greg Clayton950971f2012-05-12 00:01:21 +0000422 const ArchSpec &host_arch = GetArchitecture (eSystemDefaultArchitecture);
423 const llvm::StringRef &str_ref = host_arch.GetTriple().getOSName();
424 g_os_string.SetCStringWithLength(str_ref.data(), str_ref.size());
Greg Clayton2bddd342010-09-07 20:11:56 +0000425 }
426 return g_os_string;
427}
428
429const ConstString &
430Host::GetTargetTriple()
431{
432 static ConstString g_host_triple;
433 if (!(g_host_triple))
434 {
Greg Clayton950971f2012-05-12 00:01:21 +0000435 const ArchSpec &host_arch = GetArchitecture (eSystemDefaultArchitecture);
436 g_host_triple.SetCString(host_arch.GetTriple().getTriple().c_str());
Greg Clayton2bddd342010-09-07 20:11:56 +0000437 }
438 return g_host_triple;
439}
440
441lldb::pid_t
442Host::GetCurrentProcessID()
443{
444 return ::getpid();
445}
446
447lldb::tid_t
448Host::GetCurrentThreadID()
449{
450#if defined (__APPLE__)
Greg Clayton813ddfc2012-09-18 18:19:49 +0000451 // Calling "mach_port_deallocate()" bumps the reference count on the thread
452 // port, so we need to deallocate it. mach_task_self() doesn't bump the ref
453 // count.
454 thread_port_t thread_self = mach_thread_self();
455 mach_port_deallocate(mach_task_self(), thread_self);
456 return thread_self;
Johnny Chen8f3d8382011-08-02 20:52:42 +0000457#elif defined(__FreeBSD__)
458 return lldb::tid_t(pthread_getthreadid_np());
Michael Sartainc2052432013-08-01 18:51:08 +0000459#elif defined(__linux__)
460 return lldb::tid_t(syscall(SYS_gettid));
Greg Clayton2bddd342010-09-07 20:11:56 +0000461#else
462 return lldb::tid_t(pthread_self());
463#endif
464}
465
Jim Ingham372787f2012-04-07 00:00:41 +0000466lldb::thread_t
467Host::GetCurrentThread ()
468{
469 return lldb::thread_t(pthread_self());
470}
471
Greg Clayton2bddd342010-09-07 20:11:56 +0000472const char *
473Host::GetSignalAsCString (int signo)
474{
475 switch (signo)
476 {
477 case SIGHUP: return "SIGHUP"; // 1 hangup
478 case SIGINT: return "SIGINT"; // 2 interrupt
479 case SIGQUIT: return "SIGQUIT"; // 3 quit
480 case SIGILL: return "SIGILL"; // 4 illegal instruction (not reset when caught)
481 case SIGTRAP: return "SIGTRAP"; // 5 trace trap (not reset when caught)
482 case SIGABRT: return "SIGABRT"; // 6 abort()
Greg Clayton0ddf6be2011-11-04 03:42:38 +0000483#if (defined(_POSIX_C_SOURCE) && !defined(_DARWIN_C_SOURCE))
Greg Clayton2bddd342010-09-07 20:11:56 +0000484 case SIGPOLL: return "SIGPOLL"; // 7 pollable event ([XSR] generated, not supported)
Benjamin Kramer44030f12011-11-04 16:06:40 +0000485#endif
486#if !defined(_POSIX_C_SOURCE)
Greg Clayton2bddd342010-09-07 20:11:56 +0000487 case SIGEMT: return "SIGEMT"; // 7 EMT instruction
Benjamin Kramer44030f12011-11-04 16:06:40 +0000488#endif
Greg Clayton2bddd342010-09-07 20:11:56 +0000489 case SIGFPE: return "SIGFPE"; // 8 floating point exception
490 case SIGKILL: return "SIGKILL"; // 9 kill (cannot be caught or ignored)
491 case SIGBUS: return "SIGBUS"; // 10 bus error
492 case SIGSEGV: return "SIGSEGV"; // 11 segmentation violation
493 case SIGSYS: return "SIGSYS"; // 12 bad argument to system call
494 case SIGPIPE: return "SIGPIPE"; // 13 write on a pipe with no one to read it
495 case SIGALRM: return "SIGALRM"; // 14 alarm clock
496 case SIGTERM: return "SIGTERM"; // 15 software termination signal from kill
497 case SIGURG: return "SIGURG"; // 16 urgent condition on IO channel
498 case SIGSTOP: return "SIGSTOP"; // 17 sendable stop signal not from tty
499 case SIGTSTP: return "SIGTSTP"; // 18 stop signal from tty
500 case SIGCONT: return "SIGCONT"; // 19 continue a stopped process
501 case SIGCHLD: return "SIGCHLD"; // 20 to parent on child stop or exit
502 case SIGTTIN: return "SIGTTIN"; // 21 to readers pgrp upon background tty read
503 case SIGTTOU: return "SIGTTOU"; // 22 like TTIN for output if (tp->t_local&LTOSTOP)
504#if !defined(_POSIX_C_SOURCE)
505 case SIGIO: return "SIGIO"; // 23 input/output possible signal
506#endif
507 case SIGXCPU: return "SIGXCPU"; // 24 exceeded CPU time limit
508 case SIGXFSZ: return "SIGXFSZ"; // 25 exceeded file size limit
509 case SIGVTALRM: return "SIGVTALRM"; // 26 virtual time alarm
510 case SIGPROF: return "SIGPROF"; // 27 profiling time alarm
511#if !defined(_POSIX_C_SOURCE)
512 case SIGWINCH: return "SIGWINCH"; // 28 window size changes
513 case SIGINFO: return "SIGINFO"; // 29 information request
514#endif
515 case SIGUSR1: return "SIGUSR1"; // 30 user defined signal 1
516 case SIGUSR2: return "SIGUSR2"; // 31 user defined signal 2
517 default:
518 break;
519 }
520 return NULL;
521}
522
523void
524Host::WillTerminate ()
525{
526}
527
Sylvestre Ledru59405832013-07-01 08:21:36 +0000528#if !defined (__APPLE__) && !defined (__FreeBSD__) && !defined (__FreeBSD_kernel__) && !defined (__linux__) // see macosx/Host.mm
Matt Kopec62502c62013-05-13 19:33:58 +0000529
Greg Clayton2bddd342010-09-07 20:11:56 +0000530void
531Host::ThreadCreated (const char *thread_name)
532{
533}
Greg Claytone5219662010-12-03 06:02:24 +0000534
Peter Collingbourne2ced9132011-08-05 00:35:43 +0000535void
Greg Claytone5219662010-12-03 06:02:24 +0000536Host::Backtrace (Stream &strm, uint32_t max_frames)
537{
Michael Sartain3cf443d2013-07-17 00:26:30 +0000538 // TODO: Is there a way to backtrace the current process on other systems?
Greg Claytone5219662010-12-03 06:02:24 +0000539}
540
Greg Clayton85851dd2010-12-04 00:10:17 +0000541size_t
542Host::GetEnvironment (StringList &env)
543{
Michael Sartain3cf443d2013-07-17 00:26:30 +0000544 // TODO: Is there a way to the host environment for this process on other systems?
Greg Clayton85851dd2010-12-04 00:10:17 +0000545 return 0;
546}
547
Sylvestre Ledru59405832013-07-01 08:21:36 +0000548#endif // #if !defined (__APPLE__) && !defined (__FreeBSD__) && !defined (__FreeBSD_kernel__) && !defined (__linux__)
Greg Clayton2bddd342010-09-07 20:11:56 +0000549
550struct HostThreadCreateInfo
551{
552 std::string thread_name;
553 thread_func_t thread_fptr;
554 thread_arg_t thread_arg;
555
556 HostThreadCreateInfo (const char *name, thread_func_t fptr, thread_arg_t arg) :
557 thread_name (name ? name : ""),
558 thread_fptr (fptr),
559 thread_arg (arg)
560 {
561 }
562};
563
564static thread_result_t
565ThreadCreateTrampoline (thread_arg_t arg)
566{
567 HostThreadCreateInfo *info = (HostThreadCreateInfo *)arg;
568 Host::ThreadCreated (info->thread_name.c_str());
569 thread_func_t thread_fptr = info->thread_fptr;
570 thread_arg_t thread_arg = info->thread_arg;
571
Greg Clayton5160ce52013-03-27 23:08:40 +0000572 Log *log(lldb_private::GetLogIfAllCategoriesSet (LIBLLDB_LOG_THREAD));
Greg Clayton2bddd342010-09-07 20:11:56 +0000573 if (log)
574 log->Printf("thread created");
575
576 delete info;
577 return thread_fptr (thread_arg);
578}
579
580lldb::thread_t
581Host::ThreadCreate
582(
583 const char *thread_name,
584 thread_func_t thread_fptr,
585 thread_arg_t thread_arg,
586 Error *error
587)
588{
589 lldb::thread_t thread = LLDB_INVALID_HOST_THREAD;
590
591 // Host::ThreadCreateTrampoline will delete this pointer for us.
592 HostThreadCreateInfo *info_ptr = new HostThreadCreateInfo (thread_name, thread_fptr, thread_arg);
593
594 int err = ::pthread_create (&thread, NULL, ThreadCreateTrampoline, info_ptr);
595 if (err == 0)
596 {
597 if (error)
598 error->Clear();
599 return thread;
600 }
601
602 if (error)
603 error->SetError (err, eErrorTypePOSIX);
604
605 return LLDB_INVALID_HOST_THREAD;
606}
607
608bool
609Host::ThreadCancel (lldb::thread_t thread, Error *error)
610{
611 int err = ::pthread_cancel (thread);
612 if (error)
613 error->SetError(err, eErrorTypePOSIX);
614 return err == 0;
615}
616
617bool
618Host::ThreadDetach (lldb::thread_t thread, Error *error)
619{
620 int err = ::pthread_detach (thread);
621 if (error)
622 error->SetError(err, eErrorTypePOSIX);
623 return err == 0;
624}
625
626bool
627Host::ThreadJoin (lldb::thread_t thread, thread_result_t *thread_result_ptr, Error *error)
628{
629 int err = ::pthread_join (thread, thread_result_ptr);
630 if (error)
631 error->SetError(err, eErrorTypePOSIX);
632 return err == 0;
633}
634
Matt Kopec62502c62013-05-13 19:33:58 +0000635bool
Greg Clayton2bddd342010-09-07 20:11:56 +0000636Host::SetThreadName (lldb::pid_t pid, lldb::tid_t tid, const char *name)
637{
Greg Clayton85719632013-02-27 22:51:58 +0000638#if defined(__APPLE__) && MAC_OS_X_VERSION_MAX_ALLOWED > MAC_OS_X_VERSION_10_5
Greg Clayton2bddd342010-09-07 20:11:56 +0000639 lldb::pid_t curr_pid = Host::GetCurrentProcessID();
640 lldb::tid_t curr_tid = Host::GetCurrentThreadID();
641 if (pid == LLDB_INVALID_PROCESS_ID)
642 pid = curr_pid;
643
644 if (tid == LLDB_INVALID_THREAD_ID)
645 tid = curr_tid;
646
Greg Clayton2bddd342010-09-07 20:11:56 +0000647 // Set the pthread name if possible
648 if (pid == curr_pid && tid == curr_tid)
649 {
Matt Kopec62502c62013-05-13 19:33:58 +0000650 if (::pthread_setname_np (name) == 0)
651 return true;
Greg Clayton2bddd342010-09-07 20:11:56 +0000652 }
Matt Kopec62502c62013-05-13 19:33:58 +0000653 return false;
Ed Maste02983be2013-07-25 19:10:32 +0000654#elif defined (__FreeBSD__)
655 lldb::pid_t curr_pid = Host::GetCurrentProcessID();
656 lldb::tid_t curr_tid = Host::GetCurrentThreadID();
657 if (pid == LLDB_INVALID_PROCESS_ID)
658 pid = curr_pid;
659
660 if (tid == LLDB_INVALID_THREAD_ID)
661 tid = curr_tid;
662
663 // Set the pthread name if possible
664 if (pid == curr_pid && tid == curr_tid)
665 {
Michael Sartainc2052432013-08-01 18:51:08 +0000666 ::pthread_set_name_np (::pthread_self(), name);
Ed Maste02983be2013-07-25 19:10:32 +0000667 return true;
668 }
669 return false;
Sylvestre Ledru59405832013-07-01 08:21:36 +0000670#elif defined (__linux__) || defined (__GLIBC__)
Matt Kopec62502c62013-05-13 19:33:58 +0000671 void *fn = dlsym (RTLD_DEFAULT, "pthread_setname_np");
672 if (fn)
673 {
Matt Kopec62502c62013-05-13 19:33:58 +0000674 lldb::pid_t curr_pid = Host::GetCurrentProcessID();
675 lldb::tid_t curr_tid = Host::GetCurrentThreadID();
Matt Kopec62502c62013-05-13 19:33:58 +0000676 if (pid == LLDB_INVALID_PROCESS_ID)
677 pid = curr_pid;
678
679 if (tid == LLDB_INVALID_THREAD_ID)
680 tid = curr_tid;
681
Michael Sartainc2052432013-08-01 18:51:08 +0000682 if (pid == curr_pid && tid == curr_tid)
Matt Kopec62502c62013-05-13 19:33:58 +0000683 {
Michael Sartainc2052432013-08-01 18:51:08 +0000684 int (*pthread_setname_np_func)(pthread_t thread, const char *name);
685 *reinterpret_cast<void **> (&pthread_setname_np_func) = fn;
686
687 if (pthread_setname_np_func (::pthread_self(), name) == 0)
Matt Kopec62502c62013-05-13 19:33:58 +0000688 return true;
689 }
690 }
691 return false;
Jim Ingham5c42d8a2013-05-15 18:27:08 +0000692#else
693 return false;
Greg Clayton2bddd342010-09-07 20:11:56 +0000694#endif
Greg Clayton2bddd342010-09-07 20:11:56 +0000695}
696
Ed Maste02983be2013-07-25 19:10:32 +0000697bool
698Host::SetShortThreadName (lldb::pid_t pid, lldb::tid_t tid,
699 const char *thread_name, size_t len)
700{
701 char *namebuf = (char *)::malloc (len + 1);
702
703 // Thread names are coming in like '<lldb.comm.debugger.edit>' and
704 // '<lldb.comm.debugger.editline>'. So just chopping the end of the string
705 // off leads to a lot of similar named threads. Go through the thread name
706 // and search for the last dot and use that.
707 const char *lastdot = ::strrchr (thread_name, '.');
708
709 if (lastdot && lastdot != thread_name)
710 thread_name = lastdot + 1;
711 ::strncpy (namebuf, thread_name, len);
712 namebuf[len] = 0;
713
714 int namebuflen = strlen(namebuf);
715 if (namebuflen > 0)
716 {
717 if (namebuf[namebuflen - 1] == '(' || namebuf[namebuflen - 1] == '>')
718 {
719 // Trim off trailing '(' and '>' characters for a bit more cleanup.
720 namebuflen--;
721 namebuf[namebuflen] = 0;
722 }
723 return Host::SetThreadName (pid, tid, namebuf);
724 }
725 return false;
726}
727
Greg Clayton2bddd342010-09-07 20:11:56 +0000728FileSpec
729Host::GetProgramFileSpec ()
730{
731 static FileSpec g_program_filespec;
732 if (!g_program_filespec)
733 {
734#if defined (__APPLE__)
735 char program_fullpath[PATH_MAX];
736 // If DST is NULL, then return the number of bytes needed.
737 uint32_t len = sizeof(program_fullpath);
738 int err = _NSGetExecutablePath (program_fullpath, &len);
739 if (err == 0)
Greg Claytonb3326392011-01-13 01:23:43 +0000740 g_program_filespec.SetFile (program_fullpath, false);
Greg Clayton2bddd342010-09-07 20:11:56 +0000741 else if (err == -1)
742 {
743 char *large_program_fullpath = (char *)::malloc (len + 1);
744
745 err = _NSGetExecutablePath (large_program_fullpath, &len);
746 if (err == 0)
Greg Claytonb3326392011-01-13 01:23:43 +0000747 g_program_filespec.SetFile (large_program_fullpath, false);
Greg Clayton2bddd342010-09-07 20:11:56 +0000748
749 ::free (large_program_fullpath);
750 }
751#elif defined (__linux__)
752 char exe_path[PATH_MAX];
Stephen Wilsone5b94a92011-01-12 04:21:21 +0000753 ssize_t len = readlink("/proc/self/exe", exe_path, sizeof(exe_path) - 1);
754 if (len > 0) {
755 exe_path[len] = 0;
Greg Claytonb3326392011-01-13 01:23:43 +0000756 g_program_filespec.SetFile(exe_path, false);
Stephen Wilsone5b94a92011-01-12 04:21:21 +0000757 }
Sylvestre Ledru59405832013-07-01 08:21:36 +0000758#elif defined (__FreeBSD__) || defined (__FreeBSD_kernel__)
Greg Clayton2bddd342010-09-07 20:11:56 +0000759 int exe_path_mib[4] = { CTL_KERN, KERN_PROC, KERN_PROC_PATHNAME, getpid() };
760 size_t exe_path_size;
761 if (sysctl(exe_path_mib, 4, NULL, &exe_path_size, NULL, 0) == 0)
762 {
Greg Clayton87ff1ac2011-01-13 01:27:55 +0000763 char *exe_path = new char[exe_path_size];
764 if (sysctl(exe_path_mib, 4, exe_path, &exe_path_size, NULL, 0) == 0)
765 g_program_filespec.SetFile(exe_path, false);
766 delete[] exe_path;
Greg Clayton2bddd342010-09-07 20:11:56 +0000767 }
768#endif
769 }
770 return g_program_filespec;
771}
772
773FileSpec
774Host::GetModuleFileSpecForHostAddress (const void *host_addr)
775{
776 FileSpec module_filespec;
777 Dl_info info;
778 if (::dladdr (host_addr, &info))
779 {
780 if (info.dli_fname)
Greg Clayton274060b2010-10-20 20:54:39 +0000781 module_filespec.SetFile(info.dli_fname, true);
Greg Clayton2bddd342010-09-07 20:11:56 +0000782 }
783 return module_filespec;
784}
785
786#if !defined (__APPLE__) // see Host.mm
Greg Claytonc859e2d2012-02-13 23:10:39 +0000787
788bool
789Host::GetBundleDirectory (const FileSpec &file, FileSpec &bundle)
790{
791 bundle.Clear();
792 return false;
793}
794
Greg Clayton2bddd342010-09-07 20:11:56 +0000795bool
Greg Claytondd36def2010-10-17 22:03:32 +0000796Host::ResolveExecutableInBundle (FileSpec &file)
Greg Clayton2bddd342010-09-07 20:11:56 +0000797{
Greg Claytondd36def2010-10-17 22:03:32 +0000798 return false;
Greg Clayton2bddd342010-09-07 20:11:56 +0000799}
800#endif
801
Greg Clayton45319462011-02-08 00:35:34 +0000802// Opaque info that tracks a dynamic library that was loaded
803struct DynamicLibraryInfo
Greg Clayton4272cc72011-02-02 02:24:04 +0000804{
Greg Clayton45319462011-02-08 00:35:34 +0000805 DynamicLibraryInfo (const FileSpec &fs, int o, void *h) :
806 file_spec (fs),
807 open_options (o),
808 handle (h)
809 {
810 }
811
812 const FileSpec file_spec;
813 uint32_t open_options;
814 void * handle;
815};
816
817void *
818Host::DynamicLibraryOpen (const FileSpec &file_spec, uint32_t options, Error &error)
819{
Greg Clayton4272cc72011-02-02 02:24:04 +0000820 char path[PATH_MAX];
821 if (file_spec.GetPath(path, sizeof(path)))
822 {
Greg Clayton45319462011-02-08 00:35:34 +0000823 int mode = 0;
824
825 if (options & eDynamicLibraryOpenOptionLazy)
826 mode |= RTLD_LAZY;
Greg Claytonf9399452011-02-08 05:24:57 +0000827 else
828 mode |= RTLD_NOW;
829
Greg Clayton45319462011-02-08 00:35:34 +0000830
831 if (options & eDynamicLibraryOpenOptionLocal)
832 mode |= RTLD_LOCAL;
833 else
834 mode |= RTLD_GLOBAL;
835
836#ifdef LLDB_CONFIG_DLOPEN_RTLD_FIRST_SUPPORTED
837 if (options & eDynamicLibraryOpenOptionLimitGetSymbol)
838 mode |= RTLD_FIRST;
Greg Clayton75852f52011-02-07 17:43:47 +0000839#endif
Greg Clayton45319462011-02-08 00:35:34 +0000840
841 void * opaque = ::dlopen (path, mode);
842
843 if (opaque)
Greg Clayton4272cc72011-02-02 02:24:04 +0000844 {
845 error.Clear();
Greg Clayton45319462011-02-08 00:35:34 +0000846 return new DynamicLibraryInfo (file_spec, options, opaque);
Greg Clayton4272cc72011-02-02 02:24:04 +0000847 }
848 else
849 {
850 error.SetErrorString(::dlerror());
851 }
852 }
853 else
854 {
855 error.SetErrorString("failed to extract path");
856 }
Greg Clayton45319462011-02-08 00:35:34 +0000857 return NULL;
Greg Clayton4272cc72011-02-02 02:24:04 +0000858}
859
860Error
Greg Clayton45319462011-02-08 00:35:34 +0000861Host::DynamicLibraryClose (void *opaque)
Greg Clayton4272cc72011-02-02 02:24:04 +0000862{
863 Error error;
Greg Clayton45319462011-02-08 00:35:34 +0000864 if (opaque == NULL)
Greg Clayton4272cc72011-02-02 02:24:04 +0000865 {
866 error.SetErrorString ("invalid dynamic library handle");
867 }
Greg Clayton45319462011-02-08 00:35:34 +0000868 else
Greg Clayton4272cc72011-02-02 02:24:04 +0000869 {
Greg Clayton45319462011-02-08 00:35:34 +0000870 DynamicLibraryInfo *dylib_info = (DynamicLibraryInfo *) opaque;
871 if (::dlclose (dylib_info->handle) != 0)
872 {
873 error.SetErrorString(::dlerror());
874 }
875
876 dylib_info->open_options = 0;
877 dylib_info->handle = 0;
878 delete dylib_info;
Greg Clayton4272cc72011-02-02 02:24:04 +0000879 }
880 return error;
881}
882
883void *
Greg Clayton45319462011-02-08 00:35:34 +0000884Host::DynamicLibraryGetSymbol (void *opaque, const char *symbol_name, Error &error)
Greg Clayton4272cc72011-02-02 02:24:04 +0000885{
Greg Clayton45319462011-02-08 00:35:34 +0000886 if (opaque == NULL)
Greg Clayton4272cc72011-02-02 02:24:04 +0000887 {
888 error.SetErrorString ("invalid dynamic library handle");
Greg Clayton4272cc72011-02-02 02:24:04 +0000889 }
Greg Clayton4272cc72011-02-02 02:24:04 +0000890 else
Greg Clayton45319462011-02-08 00:35:34 +0000891 {
892 DynamicLibraryInfo *dylib_info = (DynamicLibraryInfo *) opaque;
893
894 void *symbol_addr = ::dlsym (dylib_info->handle, symbol_name);
895 if (symbol_addr)
896 {
897#ifndef LLDB_CONFIG_DLOPEN_RTLD_FIRST_SUPPORTED
898 // This host doesn't support limiting searches to this shared library
899 // so we need to verify that the match came from this shared library
900 // if it was requested in the Host::DynamicLibraryOpen() function.
Greg Claytonf9399452011-02-08 05:24:57 +0000901 if (dylib_info->open_options & eDynamicLibraryOpenOptionLimitGetSymbol)
Greg Clayton45319462011-02-08 00:35:34 +0000902 {
903 FileSpec match_dylib_spec (Host::GetModuleFileSpecForHostAddress (symbol_addr));
904 if (match_dylib_spec != dylib_info->file_spec)
905 {
906 char dylib_path[PATH_MAX];
907 if (dylib_info->file_spec.GetPath (dylib_path, sizeof(dylib_path)))
908 error.SetErrorStringWithFormat ("symbol not found in \"%s\"", dylib_path);
909 else
910 error.SetErrorString ("symbol not found");
911 return NULL;
912 }
913 }
914#endif
915 error.Clear();
916 return symbol_addr;
917 }
918 else
919 {
920 error.SetErrorString(::dlerror());
921 }
922 }
923 return NULL;
Greg Clayton4272cc72011-02-02 02:24:04 +0000924}
Greg Claytondd36def2010-10-17 22:03:32 +0000925
926bool
927Host::GetLLDBPath (PathType path_type, FileSpec &file_spec)
928{
Greg Clayton710dd5a2011-01-08 20:28:42 +0000929 // To get paths related to LLDB we get the path to the executable that
Greg Claytondd36def2010-10-17 22:03:32 +0000930 // contains this function. On MacOSX this will be "LLDB.framework/.../LLDB",
931 // on linux this is assumed to be the "lldb" main executable. If LLDB on
Michael Sartain3cf443d2013-07-17 00:26:30 +0000932 // linux is actually in a shared library (liblldb.so) then this function will
Greg Claytondd36def2010-10-17 22:03:32 +0000933 // need to be modified to "do the right thing".
934
935 switch (path_type)
936 {
937 case ePathTypeLLDBShlibDir:
938 {
939 static ConstString g_lldb_so_dir;
940 if (!g_lldb_so_dir)
941 {
942 FileSpec lldb_file_spec (Host::GetModuleFileSpecForHostAddress ((void *)Host::GetLLDBPath));
943 g_lldb_so_dir = lldb_file_spec.GetDirectory();
944 }
945 file_spec.GetDirectory() = g_lldb_so_dir;
946 return file_spec.GetDirectory();
947 }
948 break;
949
950 case ePathTypeSupportExecutableDir:
951 {
952 static ConstString g_lldb_support_exe_dir;
953 if (!g_lldb_support_exe_dir)
954 {
955 FileSpec lldb_file_spec;
956 if (GetLLDBPath (ePathTypeLLDBShlibDir, lldb_file_spec))
957 {
958 char raw_path[PATH_MAX];
959 char resolved_path[PATH_MAX];
960 lldb_file_spec.GetPath(raw_path, sizeof(raw_path));
961
962#if defined (__APPLE__)
963 char *framework_pos = ::strstr (raw_path, "LLDB.framework");
964 if (framework_pos)
965 {
966 framework_pos += strlen("LLDB.framework");
Greg Claytondce502e2011-11-04 03:34:56 +0000967#if !defined (__arm__)
Greg Claytondd36def2010-10-17 22:03:32 +0000968 ::strncpy (framework_pos, "/Resources", PATH_MAX - (framework_pos - raw_path));
Greg Claytondce502e2011-11-04 03:34:56 +0000969#endif
Greg Claytondd36def2010-10-17 22:03:32 +0000970 }
971#endif
972 FileSpec::Resolve (raw_path, resolved_path, sizeof(resolved_path));
973 g_lldb_support_exe_dir.SetCString(resolved_path);
974 }
975 }
976 file_spec.GetDirectory() = g_lldb_support_exe_dir;
977 return file_spec.GetDirectory();
978 }
979 break;
980
981 case ePathTypeHeaderDir:
982 {
983 static ConstString g_lldb_headers_dir;
984 if (!g_lldb_headers_dir)
985 {
986#if defined (__APPLE__)
987 FileSpec lldb_file_spec;
988 if (GetLLDBPath (ePathTypeLLDBShlibDir, lldb_file_spec))
989 {
990 char raw_path[PATH_MAX];
991 char resolved_path[PATH_MAX];
992 lldb_file_spec.GetPath(raw_path, sizeof(raw_path));
993
994 char *framework_pos = ::strstr (raw_path, "LLDB.framework");
995 if (framework_pos)
996 {
997 framework_pos += strlen("LLDB.framework");
998 ::strncpy (framework_pos, "/Headers", PATH_MAX - (framework_pos - raw_path));
999 }
1000 FileSpec::Resolve (raw_path, resolved_path, sizeof(resolved_path));
1001 g_lldb_headers_dir.SetCString(resolved_path);
1002 }
1003#else
Greg Clayton4272cc72011-02-02 02:24:04 +00001004 // TODO: Anyone know how we can determine this for linux? Other systems??
Greg Claytondd36def2010-10-17 22:03:32 +00001005 g_lldb_headers_dir.SetCString ("/opt/local/include/lldb");
1006#endif
1007 }
1008 file_spec.GetDirectory() = g_lldb_headers_dir;
1009 return file_spec.GetDirectory();
1010 }
1011 break;
1012
Ed Mastea85d3642013-07-02 19:30:52 +00001013#ifndef LLDB_DISABLE_PYTHON
Greg Claytondd36def2010-10-17 22:03:32 +00001014 case ePathTypePythonDir:
1015 {
Greg Claytondd36def2010-10-17 22:03:32 +00001016 static ConstString g_lldb_python_dir;
1017 if (!g_lldb_python_dir)
1018 {
1019 FileSpec lldb_file_spec;
1020 if (GetLLDBPath (ePathTypeLLDBShlibDir, lldb_file_spec))
1021 {
1022 char raw_path[PATH_MAX];
1023 char resolved_path[PATH_MAX];
1024 lldb_file_spec.GetPath(raw_path, sizeof(raw_path));
1025
1026#if defined (__APPLE__)
1027 char *framework_pos = ::strstr (raw_path, "LLDB.framework");
1028 if (framework_pos)
1029 {
1030 framework_pos += strlen("LLDB.framework");
1031 ::strncpy (framework_pos, "/Resources/Python", PATH_MAX - (framework_pos - raw_path));
1032 }
Filipe Cabecinhas0b751162012-07-30 16:46:32 +00001033#else
Daniel Malea53430eb2013-01-04 23:35:13 +00001034 llvm::Twine python_version_dir;
1035 python_version_dir = "/python"
1036 + llvm::Twine(PY_MAJOR_VERSION)
1037 + "."
1038 + llvm::Twine(PY_MINOR_VERSION)
1039 + "/site-packages";
1040
Filipe Cabecinhascffbd092012-07-30 18:56:10 +00001041 // We may get our string truncated. Should we protect
1042 // this with an assert?
Daniel Malea53430eb2013-01-04 23:35:13 +00001043
1044 ::strncat(raw_path, python_version_dir.str().c_str(),
1045 sizeof(raw_path) - strlen(raw_path) - 1);
1046
Greg Claytondd36def2010-10-17 22:03:32 +00001047#endif
1048 FileSpec::Resolve (raw_path, resolved_path, sizeof(resolved_path));
1049 g_lldb_python_dir.SetCString(resolved_path);
1050 }
1051 }
1052 file_spec.GetDirectory() = g_lldb_python_dir;
1053 return file_spec.GetDirectory();
1054 }
1055 break;
Ed Mastea85d3642013-07-02 19:30:52 +00001056#endif
1057
Greg Clayton4272cc72011-02-02 02:24:04 +00001058 case ePathTypeLLDBSystemPlugins: // System plug-ins directory
1059 {
Michael Sartain3cf443d2013-07-17 00:26:30 +00001060#if defined (__APPLE__) || defined(__linux__)
Greg Clayton4272cc72011-02-02 02:24:04 +00001061 static ConstString g_lldb_system_plugin_dir;
Greg Clayton1cb64962011-03-24 04:28:38 +00001062 static bool g_lldb_system_plugin_dir_located = false;
1063 if (!g_lldb_system_plugin_dir_located)
Greg Clayton4272cc72011-02-02 02:24:04 +00001064 {
Greg Clayton1cb64962011-03-24 04:28:38 +00001065 g_lldb_system_plugin_dir_located = true;
Michael Sartain3cf443d2013-07-17 00:26:30 +00001066#if defined (__APPLE__)
Greg Clayton4272cc72011-02-02 02:24:04 +00001067 FileSpec lldb_file_spec;
1068 if (GetLLDBPath (ePathTypeLLDBShlibDir, lldb_file_spec))
1069 {
1070 char raw_path[PATH_MAX];
1071 char resolved_path[PATH_MAX];
1072 lldb_file_spec.GetPath(raw_path, sizeof(raw_path));
1073
1074 char *framework_pos = ::strstr (raw_path, "LLDB.framework");
1075 if (framework_pos)
1076 {
1077 framework_pos += strlen("LLDB.framework");
1078 ::strncpy (framework_pos, "/Resources/PlugIns", PATH_MAX - (framework_pos - raw_path));
Greg Clayton1cb64962011-03-24 04:28:38 +00001079 FileSpec::Resolve (raw_path, resolved_path, sizeof(resolved_path));
1080 g_lldb_system_plugin_dir.SetCString(resolved_path);
Greg Clayton4272cc72011-02-02 02:24:04 +00001081 }
Greg Clayton1cb64962011-03-24 04:28:38 +00001082 return false;
Greg Clayton4272cc72011-02-02 02:24:04 +00001083 }
Michael Sartain3cf443d2013-07-17 00:26:30 +00001084#elif defined (__linux__)
1085 FileSpec lldb_file_spec("/usr/lib/lldb", true);
1086 if (lldb_file_spec.Exists())
1087 {
1088 g_lldb_system_plugin_dir.SetCString(lldb_file_spec.GetPath().c_str());
1089 }
1090#endif // __APPLE__ || __linux__
Greg Clayton4272cc72011-02-02 02:24:04 +00001091 }
Greg Clayton1cb64962011-03-24 04:28:38 +00001092
1093 if (g_lldb_system_plugin_dir)
1094 {
1095 file_spec.GetDirectory() = g_lldb_system_plugin_dir;
1096 return true;
1097 }
Michael Sartain3cf443d2013-07-17 00:26:30 +00001098#else
1099 // TODO: where would system LLDB plug-ins be located on other systems?
Greg Clayton4272cc72011-02-02 02:24:04 +00001100 return false;
Michael Sartain3cf443d2013-07-17 00:26:30 +00001101#endif
Greg Clayton4272cc72011-02-02 02:24:04 +00001102 }
1103 break;
1104
1105 case ePathTypeLLDBUserPlugins: // User plug-ins directory
1106 {
1107#if defined (__APPLE__)
1108 static ConstString g_lldb_user_plugin_dir;
1109 if (!g_lldb_user_plugin_dir)
1110 {
1111 char user_plugin_path[PATH_MAX];
1112 if (FileSpec::Resolve ("~/Library/Application Support/LLDB/PlugIns",
1113 user_plugin_path,
1114 sizeof(user_plugin_path)))
1115 {
1116 g_lldb_user_plugin_dir.SetCString(user_plugin_path);
1117 }
1118 }
1119 file_spec.GetDirectory() = g_lldb_user_plugin_dir;
1120 return file_spec.GetDirectory();
Michael Sartain3cf443d2013-07-17 00:26:30 +00001121#elif defined (__linux__)
1122 static ConstString g_lldb_user_plugin_dir;
1123 if (!g_lldb_user_plugin_dir)
1124 {
1125 // XDG Base Directory Specification
1126 // http://standards.freedesktop.org/basedir-spec/basedir-spec-latest.html
1127 // If XDG_DATA_HOME exists, use that, otherwise use ~/.local/share/lldb.
1128 FileSpec lldb_file_spec;
1129 const char *xdg_data_home = getenv("XDG_DATA_HOME");
1130 if (xdg_data_home && xdg_data_home[0])
1131 {
1132 std::string user_plugin_dir (xdg_data_home);
1133 user_plugin_dir += "/lldb";
1134 lldb_file_spec.SetFile (user_plugin_dir.c_str(), true);
1135 }
1136 else
1137 {
1138 const char *home_dir = getenv("HOME");
1139 if (home_dir && home_dir[0])
1140 {
1141 std::string user_plugin_dir (home_dir);
1142 user_plugin_dir += "/.local/share/lldb";
1143 lldb_file_spec.SetFile (user_plugin_dir.c_str(), true);
1144 }
1145 }
1146
1147 if (lldb_file_spec.Exists())
1148 g_lldb_user_plugin_dir.SetCString(lldb_file_spec.GetPath().c_str());
1149 }
1150 file_spec.GetDirectory() = g_lldb_user_plugin_dir;
1151 return file_spec.GetDirectory();
Greg Clayton4272cc72011-02-02 02:24:04 +00001152#endif
Michael Sartain3cf443d2013-07-17 00:26:30 +00001153 // TODO: where would user LLDB plug-ins be located on other systems?
Greg Clayton4272cc72011-02-02 02:24:04 +00001154 return false;
1155 }
Greg Claytondd36def2010-10-17 22:03:32 +00001156 }
1157
1158 return false;
1159}
1160
Greg Clayton1cb64962011-03-24 04:28:38 +00001161
1162bool
1163Host::GetHostname (std::string &s)
1164{
1165 char hostname[PATH_MAX];
1166 hostname[sizeof(hostname) - 1] = '\0';
1167 if (::gethostname (hostname, sizeof(hostname) - 1) == 0)
1168 {
1169 struct hostent* h = ::gethostbyname (hostname);
1170 if (h)
1171 s.assign (h->h_name);
1172 else
1173 s.assign (hostname);
1174 return true;
1175 }
1176 return false;
1177}
1178
Greg Clayton32e0a752011-03-30 18:16:51 +00001179const char *
1180Host::GetUserName (uint32_t uid, std::string &user_name)
1181{
1182 struct passwd user_info;
1183 struct passwd *user_info_ptr = &user_info;
1184 char user_buffer[PATH_MAX];
1185 size_t user_buffer_size = sizeof(user_buffer);
1186 if (::getpwuid_r (uid,
1187 &user_info,
1188 user_buffer,
1189 user_buffer_size,
1190 &user_info_ptr) == 0)
1191 {
1192 if (user_info_ptr)
1193 {
1194 user_name.assign (user_info_ptr->pw_name);
1195 return user_name.c_str();
1196 }
1197 }
1198 user_name.clear();
1199 return NULL;
1200}
1201
1202const char *
1203Host::GetGroupName (uint32_t gid, std::string &group_name)
1204{
1205 char group_buffer[PATH_MAX];
1206 size_t group_buffer_size = sizeof(group_buffer);
1207 struct group group_info;
1208 struct group *group_info_ptr = &group_info;
1209 // Try the threadsafe version first
1210 if (::getgrgid_r (gid,
1211 &group_info,
1212 group_buffer,
1213 group_buffer_size,
1214 &group_info_ptr) == 0)
1215 {
1216 if (group_info_ptr)
1217 {
1218 group_name.assign (group_info_ptr->gr_name);
1219 return group_name.c_str();
1220 }
1221 }
1222 else
1223 {
1224 // The threadsafe version isn't currently working
1225 // for me on darwin, but the non-threadsafe version
1226 // is, so I am calling it below.
1227 group_info_ptr = ::getgrgid (gid);
1228 if (group_info_ptr)
1229 {
1230 group_name.assign (group_info_ptr->gr_name);
1231 return group_name.c_str();
1232 }
1233 }
1234 group_name.clear();
1235 return NULL;
1236}
1237
Sylvestre Ledru59405832013-07-01 08:21:36 +00001238#if !defined (__APPLE__) && !defined (__FreeBSD__) && !defined (__FreeBSD_kernel__) // see macosx/Host.mm
Greg Clayton1cb64962011-03-24 04:28:38 +00001239bool
1240Host::GetOSBuildString (std::string &s)
1241{
1242 s.clear();
1243 return false;
1244}
1245
1246bool
1247Host::GetOSKernelDescription (std::string &s)
1248{
1249 s.clear();
1250 return false;
1251}
Johnny Chen8f3d8382011-08-02 20:52:42 +00001252#endif
Greg Clayton1cb64962011-03-24 04:28:38 +00001253
Han Ming Ong84647042012-02-25 01:07:38 +00001254uint32_t
1255Host::GetUserID ()
1256{
1257 return getuid();
1258}
1259
1260uint32_t
1261Host::GetGroupID ()
1262{
1263 return getgid();
1264}
1265
1266uint32_t
1267Host::GetEffectiveUserID ()
1268{
1269 return geteuid();
1270}
1271
1272uint32_t
1273Host::GetEffectiveGroupID ()
1274{
1275 return getegid();
1276}
1277
Daniel Malea25d7eb02013-05-15 17:54:07 +00001278#if !defined (__APPLE__) && !defined(__linux__)
Greg Claytone996fd32011-03-08 22:40:15 +00001279uint32_t
Greg Clayton8b82f082011-04-12 05:54:46 +00001280Host::FindProcesses (const ProcessInstanceInfoMatch &match_info, ProcessInstanceInfoList &process_infos)
Greg Claytone996fd32011-03-08 22:40:15 +00001281{
1282 process_infos.Clear();
Greg Claytone996fd32011-03-08 22:40:15 +00001283 return process_infos.GetSize();
Greg Clayton2bddd342010-09-07 20:11:56 +00001284}
Daniel Malea25d7eb02013-05-15 17:54:07 +00001285#endif // #if !defined (__APPLE__) && !defined(__linux__)
Greg Clayton2bddd342010-09-07 20:11:56 +00001286
Sylvestre Ledru59405832013-07-01 08:21:36 +00001287#if !defined (__APPLE__) && !defined (__FreeBSD__) && !defined (__FreeBSD_kernel__) && !defined(__linux__)
Greg Claytone996fd32011-03-08 22:40:15 +00001288bool
Greg Clayton8b82f082011-04-12 05:54:46 +00001289Host::GetProcessInfo (lldb::pid_t pid, ProcessInstanceInfo &process_info)
Greg Clayton2bddd342010-09-07 20:11:56 +00001290{
Greg Claytone996fd32011-03-08 22:40:15 +00001291 process_info.Clear();
1292 return false;
Greg Clayton2bddd342010-09-07 20:11:56 +00001293}
Johnny Chen8f3d8382011-08-02 20:52:42 +00001294#endif
Greg Clayton2bddd342010-09-07 20:11:56 +00001295
Matt Kopec085d6ce2013-05-31 22:00:07 +00001296#if !defined(__linux__)
1297bool
1298Host::FindProcessThreads (const lldb::pid_t pid, TidMap &tids_to_attach)
1299{
1300 return false;
1301}
1302#endif
1303
Sean Callananc0a6e062011-10-27 21:22:25 +00001304lldb::TargetSP
1305Host::GetDummyTarget (lldb_private::Debugger &debugger)
1306{
Filipe Cabecinhas721ba3f2012-05-19 09:59:08 +00001307 static TargetSP g_dummy_target_sp;
Filipe Cabecinhasb0183452012-05-17 15:48:02 +00001308
Filipe Cabecinhas721ba3f2012-05-19 09:59:08 +00001309 // FIXME: Maybe the dummy target should be per-Debugger
1310 if (!g_dummy_target_sp || !g_dummy_target_sp->IsValid())
1311 {
1312 ArchSpec arch(Target::GetDefaultArchitecture());
1313 if (!arch.IsValid())
1314 arch = Host::GetArchitecture ();
1315 Error err = debugger.GetTargetList().CreateTarget(debugger,
Greg Claytona0ca6602012-10-18 16:33:33 +00001316 NULL,
Filipe Cabecinhas721ba3f2012-05-19 09:59:08 +00001317 arch.GetTriple().getTriple().c_str(),
1318 false,
1319 NULL,
1320 g_dummy_target_sp);
1321 }
Filipe Cabecinhasb0183452012-05-17 15:48:02 +00001322
Filipe Cabecinhas721ba3f2012-05-19 09:59:08 +00001323 return g_dummy_target_sp;
Sean Callananc0a6e062011-10-27 21:22:25 +00001324}
1325
Greg Claytond1cf11a2012-04-14 01:42:46 +00001326struct ShellInfo
1327{
1328 ShellInfo () :
1329 process_reaped (false),
1330 can_delete (false),
1331 pid (LLDB_INVALID_PROCESS_ID),
1332 signo(-1),
1333 status(-1)
1334 {
1335 }
1336
1337 lldb_private::Predicate<bool> process_reaped;
1338 lldb_private::Predicate<bool> can_delete;
1339 lldb::pid_t pid;
1340 int signo;
1341 int status;
1342};
1343
1344static bool
1345MonitorShellCommand (void *callback_baton,
1346 lldb::pid_t pid,
1347 bool exited, // True if the process did exit
1348 int signo, // Zero for no signal
1349 int status) // Exit value of process if signal is zero
1350{
1351 ShellInfo *shell_info = (ShellInfo *)callback_baton;
1352 shell_info->pid = pid;
1353 shell_info->signo = signo;
1354 shell_info->status = status;
1355 // Let the thread running Host::RunShellCommand() know that the process
1356 // exited and that ShellInfo has been filled in by broadcasting to it
1357 shell_info->process_reaped.SetValue(1, eBroadcastAlways);
1358 // Now wait for a handshake back from that thread running Host::RunShellCommand
1359 // so we know that we can delete shell_info_ptr
1360 shell_info->can_delete.WaitForValueEqualTo(true);
1361 // Sleep a bit to allow the shell_info->can_delete.SetValue() to complete...
1362 usleep(1000);
1363 // Now delete the shell info that was passed into this function
1364 delete shell_info;
1365 return true;
1366}
1367
1368Error
1369Host::RunShellCommand (const char *command,
1370 const char *working_dir,
1371 int *status_ptr,
1372 int *signo_ptr,
1373 std::string *command_output_ptr,
Greg Claytonc8f814d2012-09-27 03:13:55 +00001374 uint32_t timeout_sec,
1375 const char *shell)
Greg Claytond1cf11a2012-04-14 01:42:46 +00001376{
1377 Error error;
1378 ProcessLaunchInfo launch_info;
Greg Claytonc8f814d2012-09-27 03:13:55 +00001379 if (shell && shell[0])
1380 {
1381 // Run the command in a shell
1382 launch_info.SetShell(shell);
1383 launch_info.GetArguments().AppendArgument(command);
1384 const bool localhost = true;
1385 const bool will_debug = false;
1386 const bool first_arg_is_full_shell_command = true;
1387 launch_info.ConvertArgumentsForLaunchingInShell (error,
1388 localhost,
1389 will_debug,
1390 first_arg_is_full_shell_command);
1391 }
1392 else
1393 {
1394 // No shell, just run it
1395 Args args (command);
1396 const bool first_arg_is_executable = true;
Greg Clayton45392552012-10-17 22:57:12 +00001397 launch_info.SetArguments(args, first_arg_is_executable);
Greg Claytonc8f814d2012-09-27 03:13:55 +00001398 }
Greg Claytond1cf11a2012-04-14 01:42:46 +00001399
1400 if (working_dir)
1401 launch_info.SetWorkingDirectory(working_dir);
1402 char output_file_path_buffer[L_tmpnam];
1403 const char *output_file_path = NULL;
1404 if (command_output_ptr)
1405 {
1406 // Create a temporary file to get the stdout/stderr and redirect the
1407 // output of the command into this file. We will later read this file
1408 // if all goes well and fill the data into "command_output_ptr"
1409 output_file_path = ::tmpnam(output_file_path_buffer);
1410 launch_info.AppendSuppressFileAction (STDIN_FILENO, true, false);
1411 launch_info.AppendOpenFileAction(STDOUT_FILENO, output_file_path, false, true);
Greg Claytonc8f814d2012-09-27 03:13:55 +00001412 launch_info.AppendDuplicateFileAction(STDOUT_FILENO, STDERR_FILENO);
Greg Claytond1cf11a2012-04-14 01:42:46 +00001413 }
1414 else
1415 {
1416 launch_info.AppendSuppressFileAction (STDIN_FILENO, true, false);
1417 launch_info.AppendSuppressFileAction (STDOUT_FILENO, false, true);
1418 launch_info.AppendSuppressFileAction (STDERR_FILENO, false, true);
1419 }
1420
1421 // The process monitor callback will delete the 'shell_info_ptr' below...
Greg Clayton7b0992d2013-04-18 22:45:39 +00001422 std::unique_ptr<ShellInfo> shell_info_ap (new ShellInfo());
Greg Claytond1cf11a2012-04-14 01:42:46 +00001423
1424 const bool monitor_signals = false;
1425 launch_info.SetMonitorProcessCallback(MonitorShellCommand, shell_info_ap.get(), monitor_signals);
1426
1427 error = LaunchProcess (launch_info);
1428 const lldb::pid_t pid = launch_info.GetProcessID();
1429 if (pid != LLDB_INVALID_PROCESS_ID)
1430 {
1431 // The process successfully launched, so we can defer ownership of
1432 // "shell_info" to the MonitorShellCommand callback function that will
Greg Claytone01e07b2013-04-18 18:10:51 +00001433 // get called when the process dies. We release the unique pointer as it
Greg Claytond1cf11a2012-04-14 01:42:46 +00001434 // doesn't need to delete the ShellInfo anymore.
1435 ShellInfo *shell_info = shell_info_ap.release();
1436 TimeValue timeout_time(TimeValue::Now());
1437 timeout_time.OffsetWithSeconds(timeout_sec);
1438 bool timed_out = false;
1439 shell_info->process_reaped.WaitForValueEqualTo(true, &timeout_time, &timed_out);
1440 if (timed_out)
1441 {
1442 error.SetErrorString("timed out waiting for shell command to complete");
1443
1444 // Kill the process since it didn't complete withint the timeout specified
1445 ::kill (pid, SIGKILL);
1446 // Wait for the monitor callback to get the message
1447 timeout_time = TimeValue::Now();
1448 timeout_time.OffsetWithSeconds(1);
1449 timed_out = false;
1450 shell_info->process_reaped.WaitForValueEqualTo(true, &timeout_time, &timed_out);
1451 }
1452 else
1453 {
1454 if (status_ptr)
1455 *status_ptr = shell_info->status;
1456
1457 if (signo_ptr)
1458 *signo_ptr = shell_info->signo;
1459
1460 if (command_output_ptr)
1461 {
1462 command_output_ptr->clear();
1463 FileSpec file_spec(output_file_path, File::eOpenOptionRead);
1464 uint64_t file_size = file_spec.GetByteSize();
1465 if (file_size > 0)
1466 {
1467 if (file_size > command_output_ptr->max_size())
1468 {
1469 error.SetErrorStringWithFormat("shell command output is too large to fit into a std::string");
1470 }
1471 else
1472 {
1473 command_output_ptr->resize(file_size);
1474 file_spec.ReadFileContents(0, &((*command_output_ptr)[0]), command_output_ptr->size(), &error);
1475 }
1476 }
1477 }
1478 }
1479 shell_info->can_delete.SetValue(true, eBroadcastAlways);
1480 }
1481 else
1482 {
1483 error.SetErrorString("failed to get process ID");
1484 }
1485
1486 if (output_file_path)
1487 ::unlink (output_file_path);
1488 // Handshake with the monitor thread, or just let it know in advance that
1489 // it can delete "shell_info" in case we timed out and were not able to kill
1490 // the process...
1491 return error;
1492}
1493
1494
Greg Claytone3e3fee2013-02-17 20:46:30 +00001495uint32_t
1496Host::GetNumberCPUS ()
1497{
1498 static uint32_t g_num_cores = UINT32_MAX;
1499 if (g_num_cores == UINT32_MAX)
1500 {
Sylvestre Ledru59405832013-07-01 08:21:36 +00001501#if defined(__APPLE__) or defined (__linux__) or defined (__FreeBSD__) or defined (__FreeBSD_kernel__)
Greg Claytone3e3fee2013-02-17 20:46:30 +00001502
1503 g_num_cores = ::sysconf(_SC_NPROCESSORS_ONLN);
1504
1505#elif defined(_WIN32) || defined(__WIN32__) || defined(__CYGWIN__)
1506
1507 // Header file for this might need to be included at the top of this file
1508 SYSTEM_INFO system_info;
1509 ::GetSystemInfo (&system_info);
1510 g_num_cores = system_info.dwNumberOfProcessors;
1511
1512#else
1513
1514 // Assume POSIX support if a host specific case has not been supplied above
1515 g_num_cores = 0;
1516 int num_cores = 0;
1517 size_t num_cores_len = sizeof(num_cores);
Sylvestre Ledru59405832013-07-01 08:21:36 +00001518#ifdef HW_AVAILCPU
Greg Claytone3e3fee2013-02-17 20:46:30 +00001519 int mib[] = { CTL_HW, HW_AVAILCPU };
Sylvestre Ledru59405832013-07-01 08:21:36 +00001520#else
1521 int mib[] = { CTL_HW, HW_NCPU };
1522#endif
Greg Claytone3e3fee2013-02-17 20:46:30 +00001523
1524 /* get the number of CPUs from the system */
1525 if (sysctl(mib, sizeof(mib)/sizeof(int), &num_cores, &num_cores_len, NULL, 0) == 0 && (num_cores > 0))
1526 {
1527 g_num_cores = num_cores;
1528 }
1529 else
1530 {
1531 mib[1] = HW_NCPU;
1532 num_cores_len = sizeof(num_cores);
1533 if (sysctl(mib, sizeof(mib)/sizeof(int), &num_cores, &num_cores_len, NULL, 0) == 0 && (num_cores > 0))
1534 {
1535 if (num_cores > 0)
1536 g_num_cores = num_cores;
1537 }
1538 }
1539#endif
1540 }
1541 return g_num_cores;
1542}
1543
1544
Greg Claytond1cf11a2012-04-14 01:42:46 +00001545
Johnny Chen8f3d8382011-08-02 20:52:42 +00001546#if !defined (__APPLE__)
Greg Clayton2bddd342010-09-07 20:11:56 +00001547bool
Greg Clayton3b147632010-12-18 01:54:34 +00001548Host::OpenFileInExternalEditor (const FileSpec &file_spec, uint32_t line_no)
Greg Clayton2bddd342010-09-07 20:11:56 +00001549{
1550 return false;
1551}
Greg Claytondd36def2010-10-17 22:03:32 +00001552
Greg Clayton2d95dc9b2010-11-10 04:57:04 +00001553void
1554Host::SetCrashDescriptionWithFormat (const char *format, ...)
1555{
1556}
1557
1558void
1559Host::SetCrashDescription (const char *description)
1560{
1561}
Greg Claytondd36def2010-10-17 22:03:32 +00001562
1563lldb::pid_t
1564LaunchApplication (const FileSpec &app_file_spec)
1565{
1566 return LLDB_INVALID_PROCESS_ID;
1567}
1568
Greg Clayton2bddd342010-09-07 20:11:56 +00001569#endif