blob: 68c715332da62199ea01a86b8f54c4e2294acf31 [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
Greg Claytone3e3fee2013-02-17 20:46:30 +000013#include <errno.h>
Greg Claytone3e3fee2013-02-17 20:46:30 +000014#include <limits.h>
Virgile Bellob2f1fb22013-08-23 12:44:05 +000015#include <sys/types.h>
16#include <unistd.h>
17#ifdef _WIN32
18#include "lldb/Host/windows/windows.h"
19#include <winsock2.h>
20#include <WS2tcpip.h>
21#else
22#include <dlfcn.h>
23#include <grp.h>
Greg Claytone3e3fee2013-02-17 20:46:30 +000024#include <netdb.h>
25#include <pwd.h>
Ed Mastef2b01622013-06-28 12:35:08 +000026#include <sys/sysctl.h>
Virgile Bellob2f1fb22013-08-23 12:44:05 +000027#endif
Greg Claytone3e3fee2013-02-17 20:46:30 +000028
29#if defined (__APPLE__)
Greg Claytone3e3fee2013-02-17 20:46:30 +000030#include <mach/mach_port.h>
Charles Davis510938e2013-08-27 05:04:57 +000031#include <mach/mach_init.h>
32#include <mach-o/dyld.h>
Ed Maste8b006c62013-06-25 18:58:11 +000033#endif
Greg Claytone3e3fee2013-02-17 20:46:30 +000034
Ed Maste8b006c62013-06-25 18:58:11 +000035#if defined (__linux__) || defined (__FreeBSD__) || defined (__FreeBSD_kernel__)
Greg Claytone3e3fee2013-02-17 20:46:30 +000036#include <sys/wait.h>
Michael Sartainc2052432013-08-01 18:51:08 +000037#include <sys/syscall.h>
Ed Maste8b006c62013-06-25 18:58:11 +000038#endif
Greg Claytone3e3fee2013-02-17 20:46:30 +000039
Ed Maste8b006c62013-06-25 18:58:11 +000040#if defined (__FreeBSD__)
Greg Claytone3e3fee2013-02-17 20:46:30 +000041#include <pthread_np.h>
Greg Claytone3e3fee2013-02-17 20:46:30 +000042#endif
43
Greg Clayton2bddd342010-09-07 20:11:56 +000044#include "lldb/Host/Host.h"
45#include "lldb/Core/ArchSpec.h"
46#include "lldb/Core/ConstString.h"
Sean Callananc0a6e062011-10-27 21:22:25 +000047#include "lldb/Core/Debugger.h"
Greg Clayton2bddd342010-09-07 20:11:56 +000048#include "lldb/Core/Error.h"
Greg Clayton2bddd342010-09-07 20:11:56 +000049#include "lldb/Core/Log.h"
50#include "lldb/Core/StreamString.h"
Jim Inghamc075ecd2012-05-04 19:24:49 +000051#include "lldb/Core/ThreadSafeSTLMap.h"
Greg Clayton45319462011-02-08 00:35:34 +000052#include "lldb/Host/Config.h"
Greg Clayton7fb56d02011-02-01 01:31:41 +000053#include "lldb/Host/Endian.h"
Greg Claytone996fd32011-03-08 22:40:15 +000054#include "lldb/Host/FileSpec.h"
Greg Clayton2bddd342010-09-07 20:11:56 +000055#include "lldb/Host/Mutex.h"
Greg Claytone996fd32011-03-08 22:40:15 +000056#include "lldb/Target/Process.h"
Sean Callananc0a6e062011-10-27 21:22:25 +000057#include "lldb/Target/TargetList.h"
Greg Clayton2bddd342010-09-07 20:11:56 +000058
Daniel Maleafa7425d2013-08-06 21:40:08 +000059#include "llvm/ADT/SmallString.h"
Stephen Wilsonbd588712011-02-24 19:15:09 +000060#include "llvm/Support/Host.h"
Daniel Maleafa7425d2013-08-06 21:40:08 +000061#include "llvm/Support/raw_ostream.h"
Stephen Wilsonbd588712011-02-24 19:15:09 +000062
Greg Clayton32e0a752011-03-30 18:16:51 +000063
Greg Clayton2bddd342010-09-07 20:11:56 +000064
Greg Clayton45319462011-02-08 00:35:34 +000065
Greg Clayton2bddd342010-09-07 20:11:56 +000066
67using namespace lldb;
68using namespace lldb_private;
69
Greg Claytone4e45922011-11-16 05:37:56 +000070
Virgile Bellob2f1fb22013-08-23 12:44:05 +000071#if !defined (__APPLE__) && !defined (_WIN32)
Greg Clayton2bddd342010-09-07 20:11:56 +000072struct MonitorInfo
73{
74 lldb::pid_t pid; // The process ID to monitor
75 Host::MonitorChildProcessCallback callback; // The callback function to call when "pid" exits or signals
76 void *callback_baton; // The callback baton for the callback function
77 bool monitor_signals; // If true, call the callback when "pid" gets signaled.
78};
79
Virgile Bellob2f1fb22013-08-23 12:44:05 +000080static thread_result_t
Greg Clayton2bddd342010-09-07 20:11:56 +000081MonitorChildProcessThreadFunction (void *arg);
82
83lldb::thread_t
84Host::StartMonitoringChildProcess
85(
86 Host::MonitorChildProcessCallback callback,
87 void *callback_baton,
88 lldb::pid_t pid,
89 bool monitor_signals
90)
91{
92 lldb::thread_t thread = LLDB_INVALID_HOST_THREAD;
Greg Claytone4e45922011-11-16 05:37:56 +000093 MonitorInfo * info_ptr = new MonitorInfo();
Greg Clayton2bddd342010-09-07 20:11:56 +000094
Greg Claytone4e45922011-11-16 05:37:56 +000095 info_ptr->pid = pid;
96 info_ptr->callback = callback;
97 info_ptr->callback_baton = callback_baton;
98 info_ptr->monitor_signals = monitor_signals;
99
100 char thread_name[256];
Daniel Malead01b2952012-11-29 21:49:15 +0000101 ::snprintf (thread_name, sizeof(thread_name), "<lldb.host.wait4(pid=%" PRIu64 ")>", pid);
Greg Claytone4e45922011-11-16 05:37:56 +0000102 thread = ThreadCreate (thread_name,
103 MonitorChildProcessThreadFunction,
104 info_ptr,
105 NULL);
106
Greg Clayton2bddd342010-09-07 20:11:56 +0000107 return thread;
108}
109
110//------------------------------------------------------------------
111// Scoped class that will disable thread canceling when it is
112// constructed, and exception safely restore the previous value it
113// when it goes out of scope.
114//------------------------------------------------------------------
115class ScopedPThreadCancelDisabler
116{
117public:
118 ScopedPThreadCancelDisabler()
119 {
120 // Disable the ability for this thread to be cancelled
121 int err = ::pthread_setcancelstate (PTHREAD_CANCEL_DISABLE, &m_old_state);
122 if (err != 0)
123 m_old_state = -1;
124
125 }
126
127 ~ScopedPThreadCancelDisabler()
128 {
129 // Restore the ability for this thread to be cancelled to what it
130 // previously was.
131 if (m_old_state != -1)
132 ::pthread_setcancelstate (m_old_state, 0);
133 }
134private:
135 int m_old_state; // Save the old cancelability state.
136};
137
Virgile Bellob2f1fb22013-08-23 12:44:05 +0000138static thread_result_t
Greg Clayton2bddd342010-09-07 20:11:56 +0000139MonitorChildProcessThreadFunction (void *arg)
140{
Greg Clayton5160ce52013-03-27 23:08:40 +0000141 Log *log(lldb_private::GetLogIfAllCategoriesSet (LIBLLDB_LOG_PROCESS));
Greg Clayton2bddd342010-09-07 20:11:56 +0000142 const char *function = __FUNCTION__;
143 if (log)
144 log->Printf ("%s (arg = %p) thread starting...", function, arg);
145
146 MonitorInfo *info = (MonitorInfo *)arg;
147
148 const Host::MonitorChildProcessCallback callback = info->callback;
149 void * const callback_baton = info->callback_baton;
150 const lldb::pid_t pid = info->pid;
151 const bool monitor_signals = info->monitor_signals;
152
153 delete info;
154
155 int status = -1;
Sylvestre Ledru59405832013-07-01 08:21:36 +0000156#if defined (__FreeBSD__) || defined (__FreeBSD_kernel__)
Ashok Thirumurthi0f3b9b82013-05-01 20:38:19 +0000157 #define __WALL 0
158#endif
Matt Kopec650648f2013-01-08 16:30:18 +0000159 const int options = __WALL;
160
Greg Clayton2bddd342010-09-07 20:11:56 +0000161 while (1)
162 {
Caroline Tice20ad3c42010-10-29 21:48:37 +0000163 log = lldb_private::GetLogIfAllCategoriesSet (LIBLLDB_LOG_PROCESS);
Greg Clayton2bddd342010-09-07 20:11:56 +0000164 if (log)
Daniel Malead01b2952012-11-29 21:49:15 +0000165 log->Printf("%s ::wait_pid (pid = %" PRIu64 ", &status, options = %i)...", function, pid, options);
Greg Clayton2bddd342010-09-07 20:11:56 +0000166
167 // Wait for all child processes
168 ::pthread_testcancel ();
Matt Kopec650648f2013-01-08 16:30:18 +0000169 // Get signals from all children with same process group of pid
170 const lldb::pid_t wait_pid = ::waitpid (-1*pid, &status, options);
Greg Clayton2bddd342010-09-07 20:11:56 +0000171 ::pthread_testcancel ();
172
173 if (wait_pid == -1)
174 {
175 if (errno == EINTR)
176 continue;
177 else
Andrew Kaylor93132f52013-05-28 23:04:25 +0000178 {
179 if (log)
180 log->Printf ("%s (arg = %p) thread exiting because waitpid failed (%s)...", __FUNCTION__, arg, strerror(errno));
Greg Clayton2bddd342010-09-07 20:11:56 +0000181 break;
Andrew Kaylor93132f52013-05-28 23:04:25 +0000182 }
Greg Clayton2bddd342010-09-07 20:11:56 +0000183 }
Matt Kopec650648f2013-01-08 16:30:18 +0000184 else if (wait_pid > 0)
Greg Clayton2bddd342010-09-07 20:11:56 +0000185 {
186 bool exited = false;
187 int signal = 0;
188 int exit_status = 0;
189 const char *status_cstr = NULL;
190 if (WIFSTOPPED(status))
191 {
192 signal = WSTOPSIG(status);
193 status_cstr = "STOPPED";
194 }
195 else if (WIFEXITED(status))
196 {
197 exit_status = WEXITSTATUS(status);
198 status_cstr = "EXITED";
Andrew Kaylor93132f52013-05-28 23:04:25 +0000199 exited = true;
Greg Clayton2bddd342010-09-07 20:11:56 +0000200 }
201 else if (WIFSIGNALED(status))
202 {
203 signal = WTERMSIG(status);
204 status_cstr = "SIGNALED";
Matt Kopec650648f2013-01-08 16:30:18 +0000205 if (wait_pid == pid) {
206 exited = true;
207 exit_status = -1;
208 }
Greg Clayton2bddd342010-09-07 20:11:56 +0000209 }
210 else
211 {
Johnny Chen44805302011-07-19 19:48:13 +0000212 status_cstr = "(\?\?\?)";
Greg Clayton2bddd342010-09-07 20:11:56 +0000213 }
214
215 // Scope for pthread_cancel_disabler
216 {
217 ScopedPThreadCancelDisabler pthread_cancel_disabler;
218
Caroline Tice20ad3c42010-10-29 21:48:37 +0000219 log = lldb_private::GetLogIfAllCategoriesSet (LIBLLDB_LOG_PROCESS);
Greg Clayton2bddd342010-09-07 20:11:56 +0000220 if (log)
Daniel Malead01b2952012-11-29 21:49:15 +0000221 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 +0000222 function,
223 wait_pid,
224 options,
Greg Clayton2bddd342010-09-07 20:11:56 +0000225 pid,
226 status,
227 status_cstr,
228 signal,
229 exit_status);
230
231 if (exited || (signal != 0 && monitor_signals))
232 {
Greg Claytone4e45922011-11-16 05:37:56 +0000233 bool callback_return = false;
234 if (callback)
Matt Kopec650648f2013-01-08 16:30:18 +0000235 callback_return = callback (callback_baton, wait_pid, exited, signal, exit_status);
Greg Clayton2bddd342010-09-07 20:11:56 +0000236
237 // If our process exited, then this thread should exit
Andrew Kaylor93132f52013-05-28 23:04:25 +0000238 if (exited && wait_pid == pid)
239 {
240 if (log)
241 log->Printf ("%s (arg = %p) thread exiting because pid received exit signal...", __FUNCTION__, arg);
Greg Clayton2bddd342010-09-07 20:11:56 +0000242 break;
Andrew Kaylor93132f52013-05-28 23:04:25 +0000243 }
Greg Clayton2bddd342010-09-07 20:11:56 +0000244 // If the callback returns true, it means this process should
245 // exit
246 if (callback_return)
Andrew Kaylor93132f52013-05-28 23:04:25 +0000247 {
248 if (log)
249 log->Printf ("%s (arg = %p) thread exiting because callback returned true...", __FUNCTION__, arg);
Greg Clayton2bddd342010-09-07 20:11:56 +0000250 break;
Andrew Kaylor93132f52013-05-28 23:04:25 +0000251 }
Greg Clayton2bddd342010-09-07 20:11:56 +0000252 }
253 }
254 }
255 }
256
Caroline Tice20ad3c42010-10-29 21:48:37 +0000257 log = lldb_private::GetLogIfAllCategoriesSet (LIBLLDB_LOG_PROCESS);
Greg Clayton2bddd342010-09-07 20:11:56 +0000258 if (log)
259 log->Printf ("%s (arg = %p) thread exiting...", __FUNCTION__, arg);
260
261 return NULL;
262}
263
Virgile Bellob2f1fb22013-08-23 12:44:05 +0000264#endif // #if !defined (__APPLE__) && !defined (_WIN32)
265
266#if !defined (__APPLE__)
Greg Claytone38a5ed2012-01-05 03:57:59 +0000267
268void
269Host::SystemLog (SystemLogType type, const char *format, va_list args)
270{
271 vfprintf (stderr, format, args);
272}
273
Virgile Bellob2f1fb22013-08-23 12:44:05 +0000274#endif
Greg Claytone4e45922011-11-16 05:37:56 +0000275
Greg Claytone38a5ed2012-01-05 03:57:59 +0000276void
277Host::SystemLog (SystemLogType type, const char *format, ...)
278{
279 va_list args;
280 va_start (args, format);
281 SystemLog (type, format, args);
282 va_end (args);
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
Virgile Bellob2f1fb22013-08-23 12:44:05 +0000447#ifndef _WIN32
448
Greg Clayton2bddd342010-09-07 20:11:56 +0000449lldb::tid_t
450Host::GetCurrentThreadID()
451{
452#if defined (__APPLE__)
Greg Clayton813ddfc2012-09-18 18:19:49 +0000453 // Calling "mach_port_deallocate()" bumps the reference count on the thread
454 // port, so we need to deallocate it. mach_task_self() doesn't bump the ref
455 // count.
456 thread_port_t thread_self = mach_thread_self();
457 mach_port_deallocate(mach_task_self(), thread_self);
458 return thread_self;
Johnny Chen8f3d8382011-08-02 20:52:42 +0000459#elif defined(__FreeBSD__)
460 return lldb::tid_t(pthread_getthreadid_np());
Michael Sartainc2052432013-08-01 18:51:08 +0000461#elif defined(__linux__)
462 return lldb::tid_t(syscall(SYS_gettid));
Greg Clayton2bddd342010-09-07 20:11:56 +0000463#else
464 return lldb::tid_t(pthread_self());
465#endif
466}
467
Jim Ingham372787f2012-04-07 00:00:41 +0000468lldb::thread_t
469Host::GetCurrentThread ()
470{
471 return lldb::thread_t(pthread_self());
472}
473
Greg Clayton2bddd342010-09-07 20:11:56 +0000474const char *
475Host::GetSignalAsCString (int signo)
476{
477 switch (signo)
478 {
479 case SIGHUP: return "SIGHUP"; // 1 hangup
480 case SIGINT: return "SIGINT"; // 2 interrupt
481 case SIGQUIT: return "SIGQUIT"; // 3 quit
482 case SIGILL: return "SIGILL"; // 4 illegal instruction (not reset when caught)
483 case SIGTRAP: return "SIGTRAP"; // 5 trace trap (not reset when caught)
484 case SIGABRT: return "SIGABRT"; // 6 abort()
Greg Clayton0ddf6be2011-11-04 03:42:38 +0000485#if (defined(_POSIX_C_SOURCE) && !defined(_DARWIN_C_SOURCE))
Greg Clayton2bddd342010-09-07 20:11:56 +0000486 case SIGPOLL: return "SIGPOLL"; // 7 pollable event ([XSR] generated, not supported)
Benjamin Kramer44030f12011-11-04 16:06:40 +0000487#endif
488#if !defined(_POSIX_C_SOURCE)
Greg Clayton2bddd342010-09-07 20:11:56 +0000489 case SIGEMT: return "SIGEMT"; // 7 EMT instruction
Benjamin Kramer44030f12011-11-04 16:06:40 +0000490#endif
Greg Clayton2bddd342010-09-07 20:11:56 +0000491 case SIGFPE: return "SIGFPE"; // 8 floating point exception
492 case SIGKILL: return "SIGKILL"; // 9 kill (cannot be caught or ignored)
493 case SIGBUS: return "SIGBUS"; // 10 bus error
494 case SIGSEGV: return "SIGSEGV"; // 11 segmentation violation
495 case SIGSYS: return "SIGSYS"; // 12 bad argument to system call
496 case SIGPIPE: return "SIGPIPE"; // 13 write on a pipe with no one to read it
497 case SIGALRM: return "SIGALRM"; // 14 alarm clock
498 case SIGTERM: return "SIGTERM"; // 15 software termination signal from kill
499 case SIGURG: return "SIGURG"; // 16 urgent condition on IO channel
500 case SIGSTOP: return "SIGSTOP"; // 17 sendable stop signal not from tty
501 case SIGTSTP: return "SIGTSTP"; // 18 stop signal from tty
502 case SIGCONT: return "SIGCONT"; // 19 continue a stopped process
503 case SIGCHLD: return "SIGCHLD"; // 20 to parent on child stop or exit
504 case SIGTTIN: return "SIGTTIN"; // 21 to readers pgrp upon background tty read
505 case SIGTTOU: return "SIGTTOU"; // 22 like TTIN for output if (tp->t_local&LTOSTOP)
506#if !defined(_POSIX_C_SOURCE)
507 case SIGIO: return "SIGIO"; // 23 input/output possible signal
508#endif
509 case SIGXCPU: return "SIGXCPU"; // 24 exceeded CPU time limit
510 case SIGXFSZ: return "SIGXFSZ"; // 25 exceeded file size limit
511 case SIGVTALRM: return "SIGVTALRM"; // 26 virtual time alarm
512 case SIGPROF: return "SIGPROF"; // 27 profiling time alarm
513#if !defined(_POSIX_C_SOURCE)
514 case SIGWINCH: return "SIGWINCH"; // 28 window size changes
515 case SIGINFO: return "SIGINFO"; // 29 information request
516#endif
517 case SIGUSR1: return "SIGUSR1"; // 30 user defined signal 1
518 case SIGUSR2: return "SIGUSR2"; // 31 user defined signal 2
519 default:
520 break;
521 }
522 return NULL;
523}
524
Virgile Bellob2f1fb22013-08-23 12:44:05 +0000525#endif
526
Greg Clayton2bddd342010-09-07 20:11:56 +0000527void
528Host::WillTerminate ()
529{
530}
531
Sylvestre Ledru59405832013-07-01 08:21:36 +0000532#if !defined (__APPLE__) && !defined (__FreeBSD__) && !defined (__FreeBSD_kernel__) && !defined (__linux__) // see macosx/Host.mm
Matt Kopec62502c62013-05-13 19:33:58 +0000533
Greg Clayton2bddd342010-09-07 20:11:56 +0000534void
535Host::ThreadCreated (const char *thread_name)
536{
537}
Greg Claytone5219662010-12-03 06:02:24 +0000538
Peter Collingbourne2ced9132011-08-05 00:35:43 +0000539void
Greg Claytone5219662010-12-03 06:02:24 +0000540Host::Backtrace (Stream &strm, uint32_t max_frames)
541{
Michael Sartain3cf443d2013-07-17 00:26:30 +0000542 // TODO: Is there a way to backtrace the current process on other systems?
Greg Claytone5219662010-12-03 06:02:24 +0000543}
544
Greg Clayton85851dd2010-12-04 00:10:17 +0000545size_t
546Host::GetEnvironment (StringList &env)
547{
Michael Sartain3cf443d2013-07-17 00:26:30 +0000548 // TODO: Is there a way to the host environment for this process on other systems?
Greg Clayton85851dd2010-12-04 00:10:17 +0000549 return 0;
550}
551
Sylvestre Ledru59405832013-07-01 08:21:36 +0000552#endif // #if !defined (__APPLE__) && !defined (__FreeBSD__) && !defined (__FreeBSD_kernel__) && !defined (__linux__)
Greg Clayton2bddd342010-09-07 20:11:56 +0000553
554struct HostThreadCreateInfo
555{
556 std::string thread_name;
557 thread_func_t thread_fptr;
558 thread_arg_t thread_arg;
559
560 HostThreadCreateInfo (const char *name, thread_func_t fptr, thread_arg_t arg) :
561 thread_name (name ? name : ""),
562 thread_fptr (fptr),
563 thread_arg (arg)
564 {
565 }
566};
567
568static thread_result_t
Virgile Bellob2f1fb22013-08-23 12:44:05 +0000569#ifdef _WIN32
570__stdcall
571#endif
Greg Clayton2bddd342010-09-07 20:11:56 +0000572ThreadCreateTrampoline (thread_arg_t arg)
573{
574 HostThreadCreateInfo *info = (HostThreadCreateInfo *)arg;
575 Host::ThreadCreated (info->thread_name.c_str());
576 thread_func_t thread_fptr = info->thread_fptr;
577 thread_arg_t thread_arg = info->thread_arg;
578
Greg Clayton5160ce52013-03-27 23:08:40 +0000579 Log *log(lldb_private::GetLogIfAllCategoriesSet (LIBLLDB_LOG_THREAD));
Greg Clayton2bddd342010-09-07 20:11:56 +0000580 if (log)
581 log->Printf("thread created");
582
583 delete info;
584 return thread_fptr (thread_arg);
585}
586
587lldb::thread_t
588Host::ThreadCreate
589(
590 const char *thread_name,
591 thread_func_t thread_fptr,
592 thread_arg_t thread_arg,
593 Error *error
594)
595{
596 lldb::thread_t thread = LLDB_INVALID_HOST_THREAD;
597
598 // Host::ThreadCreateTrampoline will delete this pointer for us.
599 HostThreadCreateInfo *info_ptr = new HostThreadCreateInfo (thread_name, thread_fptr, thread_arg);
600
Virgile Bellob2f1fb22013-08-23 12:44:05 +0000601#ifdef _WIN32
602 thread = ::_beginthreadex(0, 0, ThreadCreateTrampoline, info_ptr, 0, NULL);
603 int err = thread <= 0 ? GetLastError() : 0;
604#else
Greg Clayton2bddd342010-09-07 20:11:56 +0000605 int err = ::pthread_create (&thread, NULL, ThreadCreateTrampoline, info_ptr);
Virgile Bellob2f1fb22013-08-23 12:44:05 +0000606#endif
Greg Clayton2bddd342010-09-07 20:11:56 +0000607 if (err == 0)
608 {
609 if (error)
610 error->Clear();
611 return thread;
612 }
613
614 if (error)
615 error->SetError (err, eErrorTypePOSIX);
616
617 return LLDB_INVALID_HOST_THREAD;
618}
619
Virgile Bellob2f1fb22013-08-23 12:44:05 +0000620#ifndef _WIN32
621
Greg Clayton2bddd342010-09-07 20:11:56 +0000622bool
623Host::ThreadCancel (lldb::thread_t thread, Error *error)
624{
625 int err = ::pthread_cancel (thread);
626 if (error)
627 error->SetError(err, eErrorTypePOSIX);
628 return err == 0;
629}
630
631bool
632Host::ThreadDetach (lldb::thread_t thread, Error *error)
633{
634 int err = ::pthread_detach (thread);
635 if (error)
636 error->SetError(err, eErrorTypePOSIX);
637 return err == 0;
638}
639
640bool
641Host::ThreadJoin (lldb::thread_t thread, thread_result_t *thread_result_ptr, Error *error)
642{
643 int err = ::pthread_join (thread, thread_result_ptr);
644 if (error)
645 error->SetError(err, eErrorTypePOSIX);
646 return err == 0;
647}
648
Virgile Bellob2f1fb22013-08-23 12:44:05 +0000649lldb::thread_key_t
650Host::ThreadLocalStorageCreate(ThreadLocalStorageCleanupCallback callback)
651{
652 pthread_key_t key;
653 ::pthread_key_create (&key, callback);
654 return key;
655}
656
657void*
658Host::ThreadLocalStorageGet(lldb::thread_key_t key)
659{
660 return ::pthread_getspecific (key);
661}
662
663void
664Host::ThreadLocalStorageSet(lldb::thread_key_t key, void *value)
665{
666 ::pthread_setspecific (key, value);
667}
668
Matt Kopec62502c62013-05-13 19:33:58 +0000669bool
Greg Clayton2bddd342010-09-07 20:11:56 +0000670Host::SetThreadName (lldb::pid_t pid, lldb::tid_t tid, const char *name)
671{
Greg Clayton85719632013-02-27 22:51:58 +0000672#if defined(__APPLE__) && MAC_OS_X_VERSION_MAX_ALLOWED > MAC_OS_X_VERSION_10_5
Greg Clayton2bddd342010-09-07 20:11:56 +0000673 lldb::pid_t curr_pid = Host::GetCurrentProcessID();
674 lldb::tid_t curr_tid = Host::GetCurrentThreadID();
675 if (pid == LLDB_INVALID_PROCESS_ID)
676 pid = curr_pid;
677
678 if (tid == LLDB_INVALID_THREAD_ID)
679 tid = curr_tid;
680
Greg Clayton2bddd342010-09-07 20:11:56 +0000681 // Set the pthread name if possible
682 if (pid == curr_pid && tid == curr_tid)
683 {
Matt Kopec62502c62013-05-13 19:33:58 +0000684 if (::pthread_setname_np (name) == 0)
685 return true;
Greg Clayton2bddd342010-09-07 20:11:56 +0000686 }
Matt Kopec62502c62013-05-13 19:33:58 +0000687 return false;
Ed Maste02983be2013-07-25 19:10:32 +0000688#elif defined (__FreeBSD__)
689 lldb::pid_t curr_pid = Host::GetCurrentProcessID();
690 lldb::tid_t curr_tid = Host::GetCurrentThreadID();
691 if (pid == LLDB_INVALID_PROCESS_ID)
692 pid = curr_pid;
693
694 if (tid == LLDB_INVALID_THREAD_ID)
695 tid = curr_tid;
696
697 // Set the pthread name if possible
698 if (pid == curr_pid && tid == curr_tid)
699 {
Michael Sartainc2052432013-08-01 18:51:08 +0000700 ::pthread_set_name_np (::pthread_self(), name);
Ed Maste02983be2013-07-25 19:10:32 +0000701 return true;
702 }
703 return false;
Sylvestre Ledru59405832013-07-01 08:21:36 +0000704#elif defined (__linux__) || defined (__GLIBC__)
Matt Kopec62502c62013-05-13 19:33:58 +0000705 void *fn = dlsym (RTLD_DEFAULT, "pthread_setname_np");
706 if (fn)
707 {
Matt Kopec62502c62013-05-13 19:33:58 +0000708 lldb::pid_t curr_pid = Host::GetCurrentProcessID();
709 lldb::tid_t curr_tid = Host::GetCurrentThreadID();
Matt Kopec62502c62013-05-13 19:33:58 +0000710 if (pid == LLDB_INVALID_PROCESS_ID)
711 pid = curr_pid;
712
713 if (tid == LLDB_INVALID_THREAD_ID)
714 tid = curr_tid;
715
Michael Sartainc2052432013-08-01 18:51:08 +0000716 if (pid == curr_pid && tid == curr_tid)
Matt Kopec62502c62013-05-13 19:33:58 +0000717 {
Michael Sartainc2052432013-08-01 18:51:08 +0000718 int (*pthread_setname_np_func)(pthread_t thread, const char *name);
719 *reinterpret_cast<void **> (&pthread_setname_np_func) = fn;
720
721 if (pthread_setname_np_func (::pthread_self(), name) == 0)
Matt Kopec62502c62013-05-13 19:33:58 +0000722 return true;
723 }
724 }
725 return false;
Jim Ingham5c42d8a2013-05-15 18:27:08 +0000726#else
727 return false;
Greg Clayton2bddd342010-09-07 20:11:56 +0000728#endif
Greg Clayton2bddd342010-09-07 20:11:56 +0000729}
730
Ed Maste02983be2013-07-25 19:10:32 +0000731bool
732Host::SetShortThreadName (lldb::pid_t pid, lldb::tid_t tid,
733 const char *thread_name, size_t len)
734{
735 char *namebuf = (char *)::malloc (len + 1);
736
737 // Thread names are coming in like '<lldb.comm.debugger.edit>' and
738 // '<lldb.comm.debugger.editline>'. So just chopping the end of the string
739 // off leads to a lot of similar named threads. Go through the thread name
740 // and search for the last dot and use that.
741 const char *lastdot = ::strrchr (thread_name, '.');
742
743 if (lastdot && lastdot != thread_name)
744 thread_name = lastdot + 1;
745 ::strncpy (namebuf, thread_name, len);
746 namebuf[len] = 0;
747
748 int namebuflen = strlen(namebuf);
749 if (namebuflen > 0)
750 {
751 if (namebuf[namebuflen - 1] == '(' || namebuf[namebuflen - 1] == '>')
752 {
753 // Trim off trailing '(' and '>' characters for a bit more cleanup.
754 namebuflen--;
755 namebuf[namebuflen] = 0;
756 }
757 return Host::SetThreadName (pid, tid, namebuf);
758 }
759 return false;
760}
761
Virgile Bellob2f1fb22013-08-23 12:44:05 +0000762#endif
763
Greg Clayton2bddd342010-09-07 20:11:56 +0000764FileSpec
765Host::GetProgramFileSpec ()
766{
767 static FileSpec g_program_filespec;
768 if (!g_program_filespec)
769 {
770#if defined (__APPLE__)
771 char program_fullpath[PATH_MAX];
772 // If DST is NULL, then return the number of bytes needed.
773 uint32_t len = sizeof(program_fullpath);
774 int err = _NSGetExecutablePath (program_fullpath, &len);
775 if (err == 0)
Greg Claytonb3326392011-01-13 01:23:43 +0000776 g_program_filespec.SetFile (program_fullpath, false);
Greg Clayton2bddd342010-09-07 20:11:56 +0000777 else if (err == -1)
778 {
779 char *large_program_fullpath = (char *)::malloc (len + 1);
780
781 err = _NSGetExecutablePath (large_program_fullpath, &len);
782 if (err == 0)
Greg Claytonb3326392011-01-13 01:23:43 +0000783 g_program_filespec.SetFile (large_program_fullpath, false);
Greg Clayton2bddd342010-09-07 20:11:56 +0000784
785 ::free (large_program_fullpath);
786 }
787#elif defined (__linux__)
788 char exe_path[PATH_MAX];
Stephen Wilsone5b94a92011-01-12 04:21:21 +0000789 ssize_t len = readlink("/proc/self/exe", exe_path, sizeof(exe_path) - 1);
790 if (len > 0) {
791 exe_path[len] = 0;
Greg Claytonb3326392011-01-13 01:23:43 +0000792 g_program_filespec.SetFile(exe_path, false);
Stephen Wilsone5b94a92011-01-12 04:21:21 +0000793 }
Sylvestre Ledru59405832013-07-01 08:21:36 +0000794#elif defined (__FreeBSD__) || defined (__FreeBSD_kernel__)
Greg Clayton2bddd342010-09-07 20:11:56 +0000795 int exe_path_mib[4] = { CTL_KERN, KERN_PROC, KERN_PROC_PATHNAME, getpid() };
796 size_t exe_path_size;
797 if (sysctl(exe_path_mib, 4, NULL, &exe_path_size, NULL, 0) == 0)
798 {
Greg Clayton87ff1ac2011-01-13 01:27:55 +0000799 char *exe_path = new char[exe_path_size];
800 if (sysctl(exe_path_mib, 4, exe_path, &exe_path_size, NULL, 0) == 0)
801 g_program_filespec.SetFile(exe_path, false);
802 delete[] exe_path;
Greg Clayton2bddd342010-09-07 20:11:56 +0000803 }
804#endif
805 }
806 return g_program_filespec;
807}
808
Greg Clayton2bddd342010-09-07 20:11:56 +0000809#if !defined (__APPLE__) // see Host.mm
Greg Claytonc859e2d2012-02-13 23:10:39 +0000810
811bool
812Host::GetBundleDirectory (const FileSpec &file, FileSpec &bundle)
813{
814 bundle.Clear();
815 return false;
816}
817
Greg Clayton2bddd342010-09-07 20:11:56 +0000818bool
Greg Claytondd36def2010-10-17 22:03:32 +0000819Host::ResolveExecutableInBundle (FileSpec &file)
Greg Clayton2bddd342010-09-07 20:11:56 +0000820{
Greg Claytondd36def2010-10-17 22:03:32 +0000821 return false;
Greg Clayton2bddd342010-09-07 20:11:56 +0000822}
823#endif
824
Virgile Bellob2f1fb22013-08-23 12:44:05 +0000825#ifndef _WIN32
826
Greg Clayton45319462011-02-08 00:35:34 +0000827// Opaque info that tracks a dynamic library that was loaded
828struct DynamicLibraryInfo
Greg Clayton4272cc72011-02-02 02:24:04 +0000829{
Greg Clayton45319462011-02-08 00:35:34 +0000830 DynamicLibraryInfo (const FileSpec &fs, int o, void *h) :
831 file_spec (fs),
832 open_options (o),
833 handle (h)
834 {
835 }
836
837 const FileSpec file_spec;
838 uint32_t open_options;
839 void * handle;
840};
841
842void *
843Host::DynamicLibraryOpen (const FileSpec &file_spec, uint32_t options, Error &error)
844{
Greg Clayton4272cc72011-02-02 02:24:04 +0000845 char path[PATH_MAX];
846 if (file_spec.GetPath(path, sizeof(path)))
847 {
Greg Clayton45319462011-02-08 00:35:34 +0000848 int mode = 0;
849
850 if (options & eDynamicLibraryOpenOptionLazy)
851 mode |= RTLD_LAZY;
Greg Claytonf9399452011-02-08 05:24:57 +0000852 else
853 mode |= RTLD_NOW;
854
Greg Clayton45319462011-02-08 00:35:34 +0000855
856 if (options & eDynamicLibraryOpenOptionLocal)
857 mode |= RTLD_LOCAL;
858 else
859 mode |= RTLD_GLOBAL;
860
861#ifdef LLDB_CONFIG_DLOPEN_RTLD_FIRST_SUPPORTED
862 if (options & eDynamicLibraryOpenOptionLimitGetSymbol)
863 mode |= RTLD_FIRST;
Greg Clayton75852f52011-02-07 17:43:47 +0000864#endif
Greg Clayton45319462011-02-08 00:35:34 +0000865
866 void * opaque = ::dlopen (path, mode);
867
868 if (opaque)
Greg Clayton4272cc72011-02-02 02:24:04 +0000869 {
870 error.Clear();
Greg Clayton45319462011-02-08 00:35:34 +0000871 return new DynamicLibraryInfo (file_spec, options, opaque);
Greg Clayton4272cc72011-02-02 02:24:04 +0000872 }
873 else
874 {
875 error.SetErrorString(::dlerror());
876 }
877 }
878 else
879 {
880 error.SetErrorString("failed to extract path");
881 }
Greg Clayton45319462011-02-08 00:35:34 +0000882 return NULL;
Greg Clayton4272cc72011-02-02 02:24:04 +0000883}
884
885Error
Greg Clayton45319462011-02-08 00:35:34 +0000886Host::DynamicLibraryClose (void *opaque)
Greg Clayton4272cc72011-02-02 02:24:04 +0000887{
888 Error error;
Greg Clayton45319462011-02-08 00:35:34 +0000889 if (opaque == NULL)
Greg Clayton4272cc72011-02-02 02:24:04 +0000890 {
891 error.SetErrorString ("invalid dynamic library handle");
892 }
Greg Clayton45319462011-02-08 00:35:34 +0000893 else
Greg Clayton4272cc72011-02-02 02:24:04 +0000894 {
Greg Clayton45319462011-02-08 00:35:34 +0000895 DynamicLibraryInfo *dylib_info = (DynamicLibraryInfo *) opaque;
896 if (::dlclose (dylib_info->handle) != 0)
897 {
898 error.SetErrorString(::dlerror());
899 }
900
901 dylib_info->open_options = 0;
902 dylib_info->handle = 0;
903 delete dylib_info;
Greg Clayton4272cc72011-02-02 02:24:04 +0000904 }
905 return error;
906}
907
908void *
Greg Clayton45319462011-02-08 00:35:34 +0000909Host::DynamicLibraryGetSymbol (void *opaque, const char *symbol_name, Error &error)
Greg Clayton4272cc72011-02-02 02:24:04 +0000910{
Greg Clayton45319462011-02-08 00:35:34 +0000911 if (opaque == NULL)
Greg Clayton4272cc72011-02-02 02:24:04 +0000912 {
913 error.SetErrorString ("invalid dynamic library handle");
Greg Clayton4272cc72011-02-02 02:24:04 +0000914 }
Greg Clayton4272cc72011-02-02 02:24:04 +0000915 else
Greg Clayton45319462011-02-08 00:35:34 +0000916 {
917 DynamicLibraryInfo *dylib_info = (DynamicLibraryInfo *) opaque;
918
919 void *symbol_addr = ::dlsym (dylib_info->handle, symbol_name);
920 if (symbol_addr)
921 {
922#ifndef LLDB_CONFIG_DLOPEN_RTLD_FIRST_SUPPORTED
923 // This host doesn't support limiting searches to this shared library
924 // so we need to verify that the match came from this shared library
925 // if it was requested in the Host::DynamicLibraryOpen() function.
Greg Claytonf9399452011-02-08 05:24:57 +0000926 if (dylib_info->open_options & eDynamicLibraryOpenOptionLimitGetSymbol)
Greg Clayton45319462011-02-08 00:35:34 +0000927 {
928 FileSpec match_dylib_spec (Host::GetModuleFileSpecForHostAddress (symbol_addr));
929 if (match_dylib_spec != dylib_info->file_spec)
930 {
931 char dylib_path[PATH_MAX];
932 if (dylib_info->file_spec.GetPath (dylib_path, sizeof(dylib_path)))
933 error.SetErrorStringWithFormat ("symbol not found in \"%s\"", dylib_path);
934 else
935 error.SetErrorString ("symbol not found");
936 return NULL;
937 }
938 }
939#endif
940 error.Clear();
941 return symbol_addr;
942 }
943 else
944 {
945 error.SetErrorString(::dlerror());
946 }
947 }
948 return NULL;
Greg Clayton4272cc72011-02-02 02:24:04 +0000949}
Greg Claytondd36def2010-10-17 22:03:32 +0000950
Virgile Bellob2f1fb22013-08-23 12:44:05 +0000951FileSpec
952Host::GetModuleFileSpecForHostAddress (const void *host_addr)
953{
954 FileSpec module_filespec;
955 Dl_info info;
956 if (::dladdr (host_addr, &info))
957 {
958 if (info.dli_fname)
959 module_filespec.SetFile(info.dli_fname, true);
960 }
961 return module_filespec;
962}
963
964#endif
965
Greg Claytondd36def2010-10-17 22:03:32 +0000966bool
967Host::GetLLDBPath (PathType path_type, FileSpec &file_spec)
968{
Greg Clayton710dd5a2011-01-08 20:28:42 +0000969 // To get paths related to LLDB we get the path to the executable that
Greg Claytondd36def2010-10-17 22:03:32 +0000970 // contains this function. On MacOSX this will be "LLDB.framework/.../LLDB",
971 // on linux this is assumed to be the "lldb" main executable. If LLDB on
Michael Sartain3cf443d2013-07-17 00:26:30 +0000972 // linux is actually in a shared library (liblldb.so) then this function will
Greg Claytondd36def2010-10-17 22:03:32 +0000973 // need to be modified to "do the right thing".
974
975 switch (path_type)
976 {
977 case ePathTypeLLDBShlibDir:
978 {
979 static ConstString g_lldb_so_dir;
980 if (!g_lldb_so_dir)
981 {
982 FileSpec lldb_file_spec (Host::GetModuleFileSpecForHostAddress ((void *)Host::GetLLDBPath));
983 g_lldb_so_dir = lldb_file_spec.GetDirectory();
984 }
985 file_spec.GetDirectory() = g_lldb_so_dir;
986 return file_spec.GetDirectory();
987 }
988 break;
989
990 case ePathTypeSupportExecutableDir:
991 {
992 static ConstString g_lldb_support_exe_dir;
993 if (!g_lldb_support_exe_dir)
994 {
995 FileSpec lldb_file_spec;
996 if (GetLLDBPath (ePathTypeLLDBShlibDir, lldb_file_spec))
997 {
998 char raw_path[PATH_MAX];
999 char resolved_path[PATH_MAX];
1000 lldb_file_spec.GetPath(raw_path, sizeof(raw_path));
1001
1002#if defined (__APPLE__)
1003 char *framework_pos = ::strstr (raw_path, "LLDB.framework");
1004 if (framework_pos)
1005 {
1006 framework_pos += strlen("LLDB.framework");
Greg Claytondce502e2011-11-04 03:34:56 +00001007#if !defined (__arm__)
Greg Claytondd36def2010-10-17 22:03:32 +00001008 ::strncpy (framework_pos, "/Resources", PATH_MAX - (framework_pos - raw_path));
Greg Claytondce502e2011-11-04 03:34:56 +00001009#endif
Greg Claytondd36def2010-10-17 22:03:32 +00001010 }
1011#endif
1012 FileSpec::Resolve (raw_path, resolved_path, sizeof(resolved_path));
1013 g_lldb_support_exe_dir.SetCString(resolved_path);
1014 }
1015 }
1016 file_spec.GetDirectory() = g_lldb_support_exe_dir;
1017 return file_spec.GetDirectory();
1018 }
1019 break;
1020
1021 case ePathTypeHeaderDir:
1022 {
1023 static ConstString g_lldb_headers_dir;
1024 if (!g_lldb_headers_dir)
1025 {
1026#if defined (__APPLE__)
1027 FileSpec lldb_file_spec;
1028 if (GetLLDBPath (ePathTypeLLDBShlibDir, lldb_file_spec))
1029 {
1030 char raw_path[PATH_MAX];
1031 char resolved_path[PATH_MAX];
1032 lldb_file_spec.GetPath(raw_path, sizeof(raw_path));
1033
1034 char *framework_pos = ::strstr (raw_path, "LLDB.framework");
1035 if (framework_pos)
1036 {
1037 framework_pos += strlen("LLDB.framework");
1038 ::strncpy (framework_pos, "/Headers", PATH_MAX - (framework_pos - raw_path));
1039 }
1040 FileSpec::Resolve (raw_path, resolved_path, sizeof(resolved_path));
1041 g_lldb_headers_dir.SetCString(resolved_path);
1042 }
1043#else
Greg Clayton4272cc72011-02-02 02:24:04 +00001044 // TODO: Anyone know how we can determine this for linux? Other systems??
Greg Claytondd36def2010-10-17 22:03:32 +00001045 g_lldb_headers_dir.SetCString ("/opt/local/include/lldb");
1046#endif
1047 }
1048 file_spec.GetDirectory() = g_lldb_headers_dir;
1049 return file_spec.GetDirectory();
1050 }
1051 break;
1052
Ed Mastea85d3642013-07-02 19:30:52 +00001053#ifndef LLDB_DISABLE_PYTHON
Greg Claytondd36def2010-10-17 22:03:32 +00001054 case ePathTypePythonDir:
1055 {
Greg Claytondd36def2010-10-17 22:03:32 +00001056 static ConstString g_lldb_python_dir;
1057 if (!g_lldb_python_dir)
1058 {
1059 FileSpec lldb_file_spec;
1060 if (GetLLDBPath (ePathTypeLLDBShlibDir, lldb_file_spec))
1061 {
1062 char raw_path[PATH_MAX];
1063 char resolved_path[PATH_MAX];
1064 lldb_file_spec.GetPath(raw_path, sizeof(raw_path));
1065
1066#if defined (__APPLE__)
1067 char *framework_pos = ::strstr (raw_path, "LLDB.framework");
1068 if (framework_pos)
1069 {
1070 framework_pos += strlen("LLDB.framework");
1071 ::strncpy (framework_pos, "/Resources/Python", PATH_MAX - (framework_pos - raw_path));
1072 }
Filipe Cabecinhas0b751162012-07-30 16:46:32 +00001073#else
Daniel Maleafa7425d2013-08-06 21:40:08 +00001074 llvm::SmallString<256> python_version_dir;
1075 llvm::raw_svector_ostream os(python_version_dir);
1076 os << "/python" << PY_MAJOR_VERSION << '.' << PY_MINOR_VERSION << "/site-packages";
1077 os.flush();
Daniel Malea53430eb2013-01-04 23:35:13 +00001078
Filipe Cabecinhascffbd092012-07-30 18:56:10 +00001079 // We may get our string truncated. Should we protect
1080 // this with an assert?
Daniel Malea53430eb2013-01-04 23:35:13 +00001081
Daniel Maleafa7425d2013-08-06 21:40:08 +00001082 ::strncat(raw_path, python_version_dir.c_str(),
Daniel Malea53430eb2013-01-04 23:35:13 +00001083 sizeof(raw_path) - strlen(raw_path) - 1);
1084
Greg Claytondd36def2010-10-17 22:03:32 +00001085#endif
1086 FileSpec::Resolve (raw_path, resolved_path, sizeof(resolved_path));
1087 g_lldb_python_dir.SetCString(resolved_path);
1088 }
1089 }
1090 file_spec.GetDirectory() = g_lldb_python_dir;
1091 return file_spec.GetDirectory();
1092 }
1093 break;
Ed Mastea85d3642013-07-02 19:30:52 +00001094#endif
1095
Greg Clayton4272cc72011-02-02 02:24:04 +00001096 case ePathTypeLLDBSystemPlugins: // System plug-ins directory
1097 {
Michael Sartain3cf443d2013-07-17 00:26:30 +00001098#if defined (__APPLE__) || defined(__linux__)
Greg Clayton4272cc72011-02-02 02:24:04 +00001099 static ConstString g_lldb_system_plugin_dir;
Greg Clayton1cb64962011-03-24 04:28:38 +00001100 static bool g_lldb_system_plugin_dir_located = false;
1101 if (!g_lldb_system_plugin_dir_located)
Greg Clayton4272cc72011-02-02 02:24:04 +00001102 {
Greg Clayton1cb64962011-03-24 04:28:38 +00001103 g_lldb_system_plugin_dir_located = true;
Michael Sartain3cf443d2013-07-17 00:26:30 +00001104#if defined (__APPLE__)
Greg Clayton4272cc72011-02-02 02:24:04 +00001105 FileSpec lldb_file_spec;
1106 if (GetLLDBPath (ePathTypeLLDBShlibDir, lldb_file_spec))
1107 {
1108 char raw_path[PATH_MAX];
1109 char resolved_path[PATH_MAX];
1110 lldb_file_spec.GetPath(raw_path, sizeof(raw_path));
1111
1112 char *framework_pos = ::strstr (raw_path, "LLDB.framework");
1113 if (framework_pos)
1114 {
1115 framework_pos += strlen("LLDB.framework");
1116 ::strncpy (framework_pos, "/Resources/PlugIns", PATH_MAX - (framework_pos - raw_path));
Greg Clayton1cb64962011-03-24 04:28:38 +00001117 FileSpec::Resolve (raw_path, resolved_path, sizeof(resolved_path));
1118 g_lldb_system_plugin_dir.SetCString(resolved_path);
Greg Clayton4272cc72011-02-02 02:24:04 +00001119 }
Greg Clayton1cb64962011-03-24 04:28:38 +00001120 return false;
Greg Clayton4272cc72011-02-02 02:24:04 +00001121 }
Michael Sartain3cf443d2013-07-17 00:26:30 +00001122#elif defined (__linux__)
1123 FileSpec lldb_file_spec("/usr/lib/lldb", true);
1124 if (lldb_file_spec.Exists())
1125 {
1126 g_lldb_system_plugin_dir.SetCString(lldb_file_spec.GetPath().c_str());
1127 }
1128#endif // __APPLE__ || __linux__
Greg Clayton4272cc72011-02-02 02:24:04 +00001129 }
Greg Clayton1cb64962011-03-24 04:28:38 +00001130
1131 if (g_lldb_system_plugin_dir)
1132 {
1133 file_spec.GetDirectory() = g_lldb_system_plugin_dir;
1134 return true;
1135 }
Michael Sartain3cf443d2013-07-17 00:26:30 +00001136#else
1137 // TODO: where would system LLDB plug-ins be located on other systems?
Greg Clayton4272cc72011-02-02 02:24:04 +00001138 return false;
Michael Sartain3cf443d2013-07-17 00:26:30 +00001139#endif
Greg Clayton4272cc72011-02-02 02:24:04 +00001140 }
1141 break;
1142
1143 case ePathTypeLLDBUserPlugins: // User plug-ins directory
1144 {
1145#if defined (__APPLE__)
1146 static ConstString g_lldb_user_plugin_dir;
1147 if (!g_lldb_user_plugin_dir)
1148 {
1149 char user_plugin_path[PATH_MAX];
1150 if (FileSpec::Resolve ("~/Library/Application Support/LLDB/PlugIns",
1151 user_plugin_path,
1152 sizeof(user_plugin_path)))
1153 {
1154 g_lldb_user_plugin_dir.SetCString(user_plugin_path);
1155 }
1156 }
1157 file_spec.GetDirectory() = g_lldb_user_plugin_dir;
1158 return file_spec.GetDirectory();
Michael Sartain3cf443d2013-07-17 00:26:30 +00001159#elif defined (__linux__)
1160 static ConstString g_lldb_user_plugin_dir;
1161 if (!g_lldb_user_plugin_dir)
1162 {
1163 // XDG Base Directory Specification
1164 // http://standards.freedesktop.org/basedir-spec/basedir-spec-latest.html
1165 // If XDG_DATA_HOME exists, use that, otherwise use ~/.local/share/lldb.
1166 FileSpec lldb_file_spec;
1167 const char *xdg_data_home = getenv("XDG_DATA_HOME");
1168 if (xdg_data_home && xdg_data_home[0])
1169 {
1170 std::string user_plugin_dir (xdg_data_home);
1171 user_plugin_dir += "/lldb";
1172 lldb_file_spec.SetFile (user_plugin_dir.c_str(), true);
1173 }
1174 else
1175 {
1176 const char *home_dir = getenv("HOME");
1177 if (home_dir && home_dir[0])
1178 {
1179 std::string user_plugin_dir (home_dir);
1180 user_plugin_dir += "/.local/share/lldb";
1181 lldb_file_spec.SetFile (user_plugin_dir.c_str(), true);
1182 }
1183 }
1184
1185 if (lldb_file_spec.Exists())
1186 g_lldb_user_plugin_dir.SetCString(lldb_file_spec.GetPath().c_str());
1187 }
1188 file_spec.GetDirectory() = g_lldb_user_plugin_dir;
1189 return file_spec.GetDirectory();
Greg Clayton4272cc72011-02-02 02:24:04 +00001190#endif
Michael Sartain3cf443d2013-07-17 00:26:30 +00001191 // TODO: where would user LLDB plug-ins be located on other systems?
Greg Clayton4272cc72011-02-02 02:24:04 +00001192 return false;
1193 }
Greg Claytondd36def2010-10-17 22:03:32 +00001194 }
1195
1196 return false;
1197}
1198
Greg Clayton1cb64962011-03-24 04:28:38 +00001199
1200bool
1201Host::GetHostname (std::string &s)
1202{
1203 char hostname[PATH_MAX];
1204 hostname[sizeof(hostname) - 1] = '\0';
1205 if (::gethostname (hostname, sizeof(hostname) - 1) == 0)
1206 {
1207 struct hostent* h = ::gethostbyname (hostname);
1208 if (h)
1209 s.assign (h->h_name);
1210 else
1211 s.assign (hostname);
1212 return true;
1213 }
1214 return false;
1215}
1216
Virgile Bellob2f1fb22013-08-23 12:44:05 +00001217#ifndef _WIN32
1218
Greg Clayton32e0a752011-03-30 18:16:51 +00001219const char *
1220Host::GetUserName (uint32_t uid, std::string &user_name)
1221{
1222 struct passwd user_info;
1223 struct passwd *user_info_ptr = &user_info;
1224 char user_buffer[PATH_MAX];
1225 size_t user_buffer_size = sizeof(user_buffer);
1226 if (::getpwuid_r (uid,
1227 &user_info,
1228 user_buffer,
1229 user_buffer_size,
1230 &user_info_ptr) == 0)
1231 {
1232 if (user_info_ptr)
1233 {
1234 user_name.assign (user_info_ptr->pw_name);
1235 return user_name.c_str();
1236 }
1237 }
1238 user_name.clear();
1239 return NULL;
1240}
1241
1242const char *
1243Host::GetGroupName (uint32_t gid, std::string &group_name)
1244{
1245 char group_buffer[PATH_MAX];
1246 size_t group_buffer_size = sizeof(group_buffer);
1247 struct group group_info;
1248 struct group *group_info_ptr = &group_info;
1249 // Try the threadsafe version first
1250 if (::getgrgid_r (gid,
1251 &group_info,
1252 group_buffer,
1253 group_buffer_size,
1254 &group_info_ptr) == 0)
1255 {
1256 if (group_info_ptr)
1257 {
1258 group_name.assign (group_info_ptr->gr_name);
1259 return group_name.c_str();
1260 }
1261 }
1262 else
1263 {
1264 // The threadsafe version isn't currently working
1265 // for me on darwin, but the non-threadsafe version
1266 // is, so I am calling it below.
1267 group_info_ptr = ::getgrgid (gid);
1268 if (group_info_ptr)
1269 {
1270 group_name.assign (group_info_ptr->gr_name);
1271 return group_name.c_str();
1272 }
1273 }
1274 group_name.clear();
1275 return NULL;
1276}
1277
Han Ming Ong84647042012-02-25 01:07:38 +00001278uint32_t
1279Host::GetUserID ()
1280{
1281 return getuid();
1282}
1283
1284uint32_t
1285Host::GetGroupID ()
1286{
1287 return getgid();
1288}
1289
1290uint32_t
1291Host::GetEffectiveUserID ()
1292{
1293 return geteuid();
1294}
1295
1296uint32_t
1297Host::GetEffectiveGroupID ()
1298{
1299 return getegid();
1300}
1301
Virgile Bellob2f1fb22013-08-23 12:44:05 +00001302#endif
1303
1304#if !defined (__APPLE__) && !defined (__FreeBSD__) && !defined (__FreeBSD_kernel__) // see macosx/Host.mm
1305bool
1306Host::GetOSBuildString (std::string &s)
1307{
1308 s.clear();
1309 return false;
1310}
1311
1312bool
1313Host::GetOSKernelDescription (std::string &s)
1314{
1315 s.clear();
1316 return false;
1317}
1318#endif
1319
Daniel Malea25d7eb02013-05-15 17:54:07 +00001320#if !defined (__APPLE__) && !defined(__linux__)
Greg Claytone996fd32011-03-08 22:40:15 +00001321uint32_t
Greg Clayton8b82f082011-04-12 05:54:46 +00001322Host::FindProcesses (const ProcessInstanceInfoMatch &match_info, ProcessInstanceInfoList &process_infos)
Greg Claytone996fd32011-03-08 22:40:15 +00001323{
1324 process_infos.Clear();
Greg Claytone996fd32011-03-08 22:40:15 +00001325 return process_infos.GetSize();
Greg Clayton2bddd342010-09-07 20:11:56 +00001326}
Daniel Malea25d7eb02013-05-15 17:54:07 +00001327#endif // #if !defined (__APPLE__) && !defined(__linux__)
Greg Clayton2bddd342010-09-07 20:11:56 +00001328
Sylvestre Ledru59405832013-07-01 08:21:36 +00001329#if !defined (__APPLE__) && !defined (__FreeBSD__) && !defined (__FreeBSD_kernel__) && !defined(__linux__)
Greg Claytone996fd32011-03-08 22:40:15 +00001330bool
Greg Clayton8b82f082011-04-12 05:54:46 +00001331Host::GetProcessInfo (lldb::pid_t pid, ProcessInstanceInfo &process_info)
Greg Clayton2bddd342010-09-07 20:11:56 +00001332{
Greg Claytone996fd32011-03-08 22:40:15 +00001333 process_info.Clear();
1334 return false;
Greg Clayton2bddd342010-09-07 20:11:56 +00001335}
Johnny Chen8f3d8382011-08-02 20:52:42 +00001336#endif
Greg Clayton2bddd342010-09-07 20:11:56 +00001337
Matt Kopec085d6ce2013-05-31 22:00:07 +00001338#if !defined(__linux__)
1339bool
1340Host::FindProcessThreads (const lldb::pid_t pid, TidMap &tids_to_attach)
1341{
1342 return false;
1343}
1344#endif
1345
Sean Callananc0a6e062011-10-27 21:22:25 +00001346lldb::TargetSP
1347Host::GetDummyTarget (lldb_private::Debugger &debugger)
1348{
Filipe Cabecinhas721ba3f2012-05-19 09:59:08 +00001349 static TargetSP g_dummy_target_sp;
Filipe Cabecinhasb0183452012-05-17 15:48:02 +00001350
Filipe Cabecinhas721ba3f2012-05-19 09:59:08 +00001351 // FIXME: Maybe the dummy target should be per-Debugger
1352 if (!g_dummy_target_sp || !g_dummy_target_sp->IsValid())
1353 {
1354 ArchSpec arch(Target::GetDefaultArchitecture());
1355 if (!arch.IsValid())
1356 arch = Host::GetArchitecture ();
1357 Error err = debugger.GetTargetList().CreateTarget(debugger,
Greg Claytona0ca6602012-10-18 16:33:33 +00001358 NULL,
Filipe Cabecinhas721ba3f2012-05-19 09:59:08 +00001359 arch.GetTriple().getTriple().c_str(),
1360 false,
1361 NULL,
1362 g_dummy_target_sp);
1363 }
Filipe Cabecinhasb0183452012-05-17 15:48:02 +00001364
Filipe Cabecinhas721ba3f2012-05-19 09:59:08 +00001365 return g_dummy_target_sp;
Sean Callananc0a6e062011-10-27 21:22:25 +00001366}
1367
Greg Claytond1cf11a2012-04-14 01:42:46 +00001368struct ShellInfo
1369{
1370 ShellInfo () :
1371 process_reaped (false),
1372 can_delete (false),
1373 pid (LLDB_INVALID_PROCESS_ID),
1374 signo(-1),
1375 status(-1)
1376 {
1377 }
1378
1379 lldb_private::Predicate<bool> process_reaped;
1380 lldb_private::Predicate<bool> can_delete;
1381 lldb::pid_t pid;
1382 int signo;
1383 int status;
1384};
1385
1386static bool
1387MonitorShellCommand (void *callback_baton,
1388 lldb::pid_t pid,
1389 bool exited, // True if the process did exit
1390 int signo, // Zero for no signal
1391 int status) // Exit value of process if signal is zero
1392{
1393 ShellInfo *shell_info = (ShellInfo *)callback_baton;
1394 shell_info->pid = pid;
1395 shell_info->signo = signo;
1396 shell_info->status = status;
1397 // Let the thread running Host::RunShellCommand() know that the process
1398 // exited and that ShellInfo has been filled in by broadcasting to it
1399 shell_info->process_reaped.SetValue(1, eBroadcastAlways);
1400 // Now wait for a handshake back from that thread running Host::RunShellCommand
1401 // so we know that we can delete shell_info_ptr
1402 shell_info->can_delete.WaitForValueEqualTo(true);
1403 // Sleep a bit to allow the shell_info->can_delete.SetValue() to complete...
1404 usleep(1000);
1405 // Now delete the shell info that was passed into this function
1406 delete shell_info;
1407 return true;
1408}
1409
1410Error
1411Host::RunShellCommand (const char *command,
1412 const char *working_dir,
1413 int *status_ptr,
1414 int *signo_ptr,
1415 std::string *command_output_ptr,
Greg Claytonc8f814d2012-09-27 03:13:55 +00001416 uint32_t timeout_sec,
1417 const char *shell)
Greg Claytond1cf11a2012-04-14 01:42:46 +00001418{
1419 Error error;
1420 ProcessLaunchInfo launch_info;
Greg Claytonc8f814d2012-09-27 03:13:55 +00001421 if (shell && shell[0])
1422 {
1423 // Run the command in a shell
1424 launch_info.SetShell(shell);
1425 launch_info.GetArguments().AppendArgument(command);
1426 const bool localhost = true;
1427 const bool will_debug = false;
1428 const bool first_arg_is_full_shell_command = true;
1429 launch_info.ConvertArgumentsForLaunchingInShell (error,
1430 localhost,
1431 will_debug,
1432 first_arg_is_full_shell_command);
1433 }
1434 else
1435 {
1436 // No shell, just run it
1437 Args args (command);
1438 const bool first_arg_is_executable = true;
Greg Clayton45392552012-10-17 22:57:12 +00001439 launch_info.SetArguments(args, first_arg_is_executable);
Greg Claytonc8f814d2012-09-27 03:13:55 +00001440 }
Greg Claytond1cf11a2012-04-14 01:42:46 +00001441
1442 if (working_dir)
1443 launch_info.SetWorkingDirectory(working_dir);
1444 char output_file_path_buffer[L_tmpnam];
1445 const char *output_file_path = NULL;
1446 if (command_output_ptr)
1447 {
1448 // Create a temporary file to get the stdout/stderr and redirect the
1449 // output of the command into this file. We will later read this file
1450 // if all goes well and fill the data into "command_output_ptr"
1451 output_file_path = ::tmpnam(output_file_path_buffer);
1452 launch_info.AppendSuppressFileAction (STDIN_FILENO, true, false);
1453 launch_info.AppendOpenFileAction(STDOUT_FILENO, output_file_path, false, true);
Greg Claytonc8f814d2012-09-27 03:13:55 +00001454 launch_info.AppendDuplicateFileAction(STDOUT_FILENO, STDERR_FILENO);
Greg Claytond1cf11a2012-04-14 01:42:46 +00001455 }
1456 else
1457 {
1458 launch_info.AppendSuppressFileAction (STDIN_FILENO, true, false);
1459 launch_info.AppendSuppressFileAction (STDOUT_FILENO, false, true);
1460 launch_info.AppendSuppressFileAction (STDERR_FILENO, false, true);
1461 }
1462
1463 // The process monitor callback will delete the 'shell_info_ptr' below...
Greg Clayton7b0992d2013-04-18 22:45:39 +00001464 std::unique_ptr<ShellInfo> shell_info_ap (new ShellInfo());
Greg Claytond1cf11a2012-04-14 01:42:46 +00001465
1466 const bool monitor_signals = false;
1467 launch_info.SetMonitorProcessCallback(MonitorShellCommand, shell_info_ap.get(), monitor_signals);
1468
1469 error = LaunchProcess (launch_info);
1470 const lldb::pid_t pid = launch_info.GetProcessID();
Daniel Maleae0f8f572013-08-26 23:57:52 +00001471
1472 if (error.Success() && pid == LLDB_INVALID_PROCESS_ID)
1473 error.SetErrorString("failed to get process ID");
1474
1475 if (error.Success())
Greg Claytond1cf11a2012-04-14 01:42:46 +00001476 {
1477 // The process successfully launched, so we can defer ownership of
1478 // "shell_info" to the MonitorShellCommand callback function that will
Greg Claytone01e07b2013-04-18 18:10:51 +00001479 // get called when the process dies. We release the unique pointer as it
Greg Claytond1cf11a2012-04-14 01:42:46 +00001480 // doesn't need to delete the ShellInfo anymore.
1481 ShellInfo *shell_info = shell_info_ap.release();
1482 TimeValue timeout_time(TimeValue::Now());
1483 timeout_time.OffsetWithSeconds(timeout_sec);
1484 bool timed_out = false;
1485 shell_info->process_reaped.WaitForValueEqualTo(true, &timeout_time, &timed_out);
1486 if (timed_out)
1487 {
1488 error.SetErrorString("timed out waiting for shell command to complete");
1489
1490 // Kill the process since it didn't complete withint the timeout specified
Virgile Bellob2f1fb22013-08-23 12:44:05 +00001491 Kill (pid, SIGKILL);
Greg Claytond1cf11a2012-04-14 01:42:46 +00001492 // Wait for the monitor callback to get the message
1493 timeout_time = TimeValue::Now();
1494 timeout_time.OffsetWithSeconds(1);
1495 timed_out = false;
1496 shell_info->process_reaped.WaitForValueEqualTo(true, &timeout_time, &timed_out);
1497 }
1498 else
1499 {
1500 if (status_ptr)
1501 *status_ptr = shell_info->status;
1502
1503 if (signo_ptr)
1504 *signo_ptr = shell_info->signo;
1505
1506 if (command_output_ptr)
1507 {
1508 command_output_ptr->clear();
1509 FileSpec file_spec(output_file_path, File::eOpenOptionRead);
1510 uint64_t file_size = file_spec.GetByteSize();
1511 if (file_size > 0)
1512 {
1513 if (file_size > command_output_ptr->max_size())
1514 {
1515 error.SetErrorStringWithFormat("shell command output is too large to fit into a std::string");
1516 }
1517 else
1518 {
1519 command_output_ptr->resize(file_size);
1520 file_spec.ReadFileContents(0, &((*command_output_ptr)[0]), command_output_ptr->size(), &error);
1521 }
1522 }
1523 }
1524 }
1525 shell_info->can_delete.SetValue(true, eBroadcastAlways);
1526 }
Greg Claytond1cf11a2012-04-14 01:42:46 +00001527
1528 if (output_file_path)
1529 ::unlink (output_file_path);
1530 // Handshake with the monitor thread, or just let it know in advance that
1531 // it can delete "shell_info" in case we timed out and were not able to kill
1532 // the process...
1533 return error;
1534}
1535
Virgile Bellob2f1fb22013-08-23 12:44:05 +00001536#ifndef _WIN32
1537
1538size_t
1539Host::GetPageSize()
1540{
1541 return ::getpagesize();
1542}
Greg Claytond1cf11a2012-04-14 01:42:46 +00001543
Greg Claytone3e3fee2013-02-17 20:46:30 +00001544uint32_t
1545Host::GetNumberCPUS ()
1546{
1547 static uint32_t g_num_cores = UINT32_MAX;
1548 if (g_num_cores == UINT32_MAX)
1549 {
Sylvestre Ledru59405832013-07-01 08:21:36 +00001550#if defined(__APPLE__) or defined (__linux__) or defined (__FreeBSD__) or defined (__FreeBSD_kernel__)
Greg Claytone3e3fee2013-02-17 20:46:30 +00001551
1552 g_num_cores = ::sysconf(_SC_NPROCESSORS_ONLN);
Virgile Bellob2f1fb22013-08-23 12:44:05 +00001553
Greg Claytone3e3fee2013-02-17 20:46:30 +00001554#else
1555
1556 // Assume POSIX support if a host specific case has not been supplied above
1557 g_num_cores = 0;
1558 int num_cores = 0;
1559 size_t num_cores_len = sizeof(num_cores);
Sylvestre Ledru59405832013-07-01 08:21:36 +00001560#ifdef HW_AVAILCPU
Greg Claytone3e3fee2013-02-17 20:46:30 +00001561 int mib[] = { CTL_HW, HW_AVAILCPU };
Sylvestre Ledru59405832013-07-01 08:21:36 +00001562#else
1563 int mib[] = { CTL_HW, HW_NCPU };
1564#endif
Greg Claytone3e3fee2013-02-17 20:46:30 +00001565
1566 /* get the number of CPUs from the system */
1567 if (sysctl(mib, sizeof(mib)/sizeof(int), &num_cores, &num_cores_len, NULL, 0) == 0 && (num_cores > 0))
1568 {
1569 g_num_cores = num_cores;
1570 }
1571 else
1572 {
1573 mib[1] = HW_NCPU;
1574 num_cores_len = sizeof(num_cores);
1575 if (sysctl(mib, sizeof(mib)/sizeof(int), &num_cores, &num_cores_len, NULL, 0) == 0 && (num_cores > 0))
1576 {
1577 if (num_cores > 0)
1578 g_num_cores = num_cores;
1579 }
1580 }
1581#endif
1582 }
1583 return g_num_cores;
1584}
1585
Virgile Bellob2f1fb22013-08-23 12:44:05 +00001586void
1587Host::Kill(lldb::pid_t pid, int signo)
1588{
1589 ::kill(pid, signo);
1590}
Greg Claytone3e3fee2013-02-17 20:46:30 +00001591
Virgile Bellob2f1fb22013-08-23 12:44:05 +00001592#endif
Greg Claytond1cf11a2012-04-14 01:42:46 +00001593
Johnny Chen8f3d8382011-08-02 20:52:42 +00001594#if !defined (__APPLE__)
Greg Clayton2bddd342010-09-07 20:11:56 +00001595bool
Greg Clayton3b147632010-12-18 01:54:34 +00001596Host::OpenFileInExternalEditor (const FileSpec &file_spec, uint32_t line_no)
Greg Clayton2bddd342010-09-07 20:11:56 +00001597{
1598 return false;
1599}
Greg Claytondd36def2010-10-17 22:03:32 +00001600
Greg Clayton2d95dc9b2010-11-10 04:57:04 +00001601void
1602Host::SetCrashDescriptionWithFormat (const char *format, ...)
1603{
1604}
1605
1606void
1607Host::SetCrashDescription (const char *description)
1608{
1609}
Greg Claytondd36def2010-10-17 22:03:32 +00001610
1611lldb::pid_t
Daniel Maleae0f8f572013-08-26 23:57:52 +00001612Host::LaunchApplication (const FileSpec &app_file_spec)
Greg Claytondd36def2010-10-17 22:03:32 +00001613{
1614 return LLDB_INVALID_PROCESS_ID;
1615}
1616
Daniel Maleae0f8f572013-08-26 23:57:52 +00001617uint32_t
1618Host::MakeDirectory (const char* path, mode_t mode)
1619{
1620 return UINT32_MAX;
1621}
Greg Clayton2bddd342010-09-07 20:11:56 +00001622#endif
Daniel Maleae0f8f572013-08-26 23:57:52 +00001623
1624typedef std::map<lldb::user_id_t, lldb::FileSP> FDToFileMap;
1625FDToFileMap& GetFDToFileMap()
1626{
1627 static FDToFileMap g_fd2filemap;
1628 return g_fd2filemap;
1629}
1630
1631lldb::user_id_t
1632Host::OpenFile (const FileSpec& file_spec,
1633 uint32_t flags,
1634 mode_t mode,
1635 Error &error)
1636{
1637 std::string path (file_spec.GetPath());
1638 if (path.empty())
1639 {
1640 error.SetErrorString("empty path");
1641 return UINT64_MAX;
1642 }
1643 FileSP file_sp(new File());
1644 error = file_sp->Open(path.c_str(),flags,mode);
1645 if (file_sp->IsValid() == false)
1646 return UINT64_MAX;
1647 lldb::user_id_t fd = file_sp->GetDescriptor();
1648 GetFDToFileMap()[fd] = file_sp;
1649 return fd;
1650}
1651
1652bool
1653Host::CloseFile (lldb::user_id_t fd, Error &error)
1654{
1655 if (fd == UINT64_MAX)
1656 {
1657 error.SetErrorString ("invalid file descriptor");
1658 return false;
1659 }
1660 FDToFileMap& file_map = GetFDToFileMap();
1661 FDToFileMap::iterator pos = file_map.find(fd);
1662 if (pos == file_map.end())
1663 {
1664 error.SetErrorStringWithFormat ("invalid host file descriptor %" PRIu64, fd);
1665 return false;
1666 }
1667 FileSP file_sp = pos->second;
1668 if (!file_sp)
1669 {
1670 error.SetErrorString ("invalid host backing file");
1671 return false;
1672 }
1673 error = file_sp->Close();
1674 file_map.erase(pos);
1675 return error.Success();
1676}
1677
1678uint64_t
1679Host::WriteFile (lldb::user_id_t fd, uint64_t offset, const void* src, uint64_t src_len, Error &error)
1680{
1681 if (fd == UINT64_MAX)
1682 {
1683 error.SetErrorString ("invalid file descriptor");
1684 return UINT64_MAX;
1685 }
1686 FDToFileMap& file_map = GetFDToFileMap();
1687 FDToFileMap::iterator pos = file_map.find(fd);
1688 if (pos == file_map.end())
1689 {
1690 error.SetErrorStringWithFormat("invalid host file descriptor %" PRIu64 , fd);
1691 return false;
1692 }
1693 FileSP file_sp = pos->second;
1694 if (!file_sp)
1695 {
1696 error.SetErrorString ("invalid host backing file");
1697 return UINT64_MAX;
1698 }
1699 if (file_sp->SeekFromStart(offset, &error) != offset || error.Fail())
1700 return UINT64_MAX;
1701 size_t bytes_written = src_len;
1702 error = file_sp->Write(src, bytes_written);
1703 if (error.Fail())
1704 return UINT64_MAX;
1705 return bytes_written;
1706}
1707
1708uint64_t
1709Host::ReadFile (lldb::user_id_t fd, uint64_t offset, void* dst, uint64_t dst_len, Error &error)
1710{
1711 if (fd == UINT64_MAX)
1712 {
1713 error.SetErrorString ("invalid file descriptor");
1714 return UINT64_MAX;
1715 }
1716 FDToFileMap& file_map = GetFDToFileMap();
1717 FDToFileMap::iterator pos = file_map.find(fd);
1718 if (pos == file_map.end())
1719 {
1720 error.SetErrorStringWithFormat ("invalid host file descriptor %" PRIu64, fd);
1721 return false;
1722 }
1723 FileSP file_sp = pos->second;
1724 if (!file_sp)
1725 {
1726 error.SetErrorString ("invalid host backing file");
1727 return UINT64_MAX;
1728 }
1729 if (file_sp->SeekFromStart(offset, &error) != offset || error.Fail())
1730 return UINT64_MAX;
1731 size_t bytes_read = dst_len;
1732 error = file_sp->Read(dst ,bytes_read);
1733 if (error.Fail())
1734 return UINT64_MAX;
1735 return bytes_read;
1736}
1737
1738lldb::user_id_t
1739Host::GetFileSize (const FileSpec& file_spec)
1740{
1741 return file_spec.GetByteSize();
1742}
1743
1744bool
1745Host::GetFileExists (const FileSpec& file_spec)
1746{
1747 return file_spec.Exists();
1748}
1749
1750bool
1751Host::CalculateMD5 (const FileSpec& file_spec,
1752 uint64_t &low,
1753 uint64_t &high)
1754{
1755#if defined (__APPLE__)
1756 StreamString md5_cmd_line;
1757 md5_cmd_line.Printf("md5 -q '%s'", file_spec.GetPath().c_str());
1758 std::string hash_string;
1759 Error err = Host::RunShellCommand(md5_cmd_line.GetData(), NULL, NULL, NULL, &hash_string, 60);
1760 if (err.Fail())
1761 return false;
1762 // a correctly formed MD5 is 16-bytes, that is 32 hex digits
1763 // if the output is any other length it is probably wrong
1764 if (hash_string.size() != 32)
1765 return false;
1766 std::string part1(hash_string,0,16);
1767 std::string part2(hash_string,16);
1768 const char* part1_cstr = part1.c_str();
1769 const char* part2_cstr = part2.c_str();
1770 high = ::strtoull(part1_cstr, NULL, 16);
1771 low = ::strtoull(part2_cstr, NULL, 16);
1772 return true;
1773#else
1774 // your own MD5 implementation here
1775 return false;
1776#endif
1777}