1 //===-- Host.cpp ------------------------------------------------*- C++ -*-===//
2 //
3 // The LLVM Compiler Infrastructure
4 //
5 // This file is distributed under the University of Illinois Open Source
6 // License. See LICENSE.TXT for details.
7 //
8 //===----------------------------------------------------------------------===//
9
10 // C includes
11 #include <errno.h>
12 #include <limits.h>
13 #include <stdlib.h>
14 #include <sys/types.h>
15 #ifndef _WIN32
16 #include <unistd.h>
17 #include <dlfcn.h>
18 #include <grp.h>
19 #include <netdb.h>
20 #include <pwd.h>
21 #include <sys/stat.h>
22 #endif
23
24 #if defined (__APPLE__)
25 #include <mach/mach_port.h>
26 #include <mach/mach_init.h>
27 #include <mach-o/dyld.h>
28 #endif
29
30 #if defined (__linux__) || defined (__FreeBSD__) || defined (__FreeBSD_kernel__) || defined (__APPLE__) || defined(__NetBSD__)
31 #if !defined(__ANDROID__) && !defined(__ANDROID_NDK__)
32 #include <spawn.h>
33 #endif
34 #include <sys/wait.h>
35 #include <sys/syscall.h>
36 #endif
37
38 #if defined (__FreeBSD__)
39 #include <pthread_np.h>
40 #endif
41
42 // C++ includes
43 #include <limits>
44
45 #include "lldb/Host/FileSystem.h"
46 #include "lldb/Host/Host.h"
47 #include "lldb/Host/HostInfo.h"
48 #include "lldb/Core/ArchSpec.h"
49 #include "lldb/Core/Error.h"
50 #include "lldb/Core/Log.h"
51 #include "lldb/Host/FileSpec.h"
52 #include "lldb/Host/HostProcess.h"
53 #include "lldb/Host/MonitoringProcessLauncher.h"
54 #include "lldb/Host/Predicate.h"
55 #include "lldb/Host/ProcessLauncher.h"
56 #include "lldb/Host/ThreadLauncher.h"
57 #include "lldb/lldb-private-forward.h"
58 #include "llvm/Support/FileSystem.h"
59 #include "lldb/Target/FileAction.h"
60 #include "lldb/Target/ProcessLaunchInfo.h"
61 #include "lldb/Target/UnixSignals.h"
62 #include "lldb/Utility/CleanUp.h"
63 #include "llvm/ADT/SmallString.h"
64
65 #if defined(_WIN32)
66 #include "lldb/Host/windows/ProcessLauncherWindows.h"
67 #elif defined(__ANDROID__) || defined(__ANDROID_NDK__)
68 #include "lldb/Host/android/ProcessLauncherAndroid.h"
69 #else
70 #include "lldb/Host/posix/ProcessLauncherPosix.h"
71 #endif
72
73 #if defined (__APPLE__)
74 #ifndef _POSIX_SPAWN_DISABLE_ASLR
75 #define _POSIX_SPAWN_DISABLE_ASLR 0x0100
76 #endif
77
78 extern "C"
79 {
80 int __pthread_chdir(const char *path);
81 int __pthread_fchdir (int fildes);
82 }
83
84 #endif
85
86 using namespace lldb;
87 using namespace lldb_private;
88
89 #if !defined (__APPLE__) && !defined (_WIN32)
90 struct MonitorInfo
91 {
92 lldb::pid_t pid; // The process ID to monitor
93 Host::MonitorChildProcessCallback callback; // The callback function to call when "pid" exits or signals
94 void *callback_baton; // The callback baton for the callback function
95 bool monitor_signals; // If true, call the callback when "pid" gets signaled.
96 };
97
98 static thread_result_t
99 MonitorChildProcessThreadFunction (void *arg);
100
101 HostThread
StartMonitoringChildProcess(Host::MonitorChildProcessCallback callback,void * callback_baton,lldb::pid_t pid,bool monitor_signals)102 Host::StartMonitoringChildProcess(Host::MonitorChildProcessCallback callback, void *callback_baton, lldb::pid_t pid, bool monitor_signals)
103 {
104 MonitorInfo * info_ptr = new MonitorInfo();
105
106 info_ptr->pid = pid;
107 info_ptr->callback = callback;
108 info_ptr->callback_baton = callback_baton;
109 info_ptr->monitor_signals = monitor_signals;
110
111 char thread_name[256];
112 ::snprintf(thread_name, sizeof(thread_name), "<lldb.host.wait4(pid=%" PRIu64 ")>", pid);
113 return ThreadLauncher::LaunchThread(thread_name, MonitorChildProcessThreadFunction, info_ptr, NULL);
114 }
115
116 #ifndef __linux__
117 //------------------------------------------------------------------
118 // Scoped class that will disable thread canceling when it is
119 // constructed, and exception safely restore the previous value it
120 // when it goes out of scope.
121 //------------------------------------------------------------------
122 class ScopedPThreadCancelDisabler
123 {
124 public:
ScopedPThreadCancelDisabler()125 ScopedPThreadCancelDisabler()
126 {
127 // Disable the ability for this thread to be cancelled
128 int err = ::pthread_setcancelstate (PTHREAD_CANCEL_DISABLE, &m_old_state);
129 if (err != 0)
130 m_old_state = -1;
131 }
132
~ScopedPThreadCancelDisabler()133 ~ScopedPThreadCancelDisabler()
134 {
135 // Restore the ability for this thread to be cancelled to what it
136 // previously was.
137 if (m_old_state != -1)
138 ::pthread_setcancelstate (m_old_state, 0);
139 }
140 private:
141 int m_old_state; // Save the old cancelability state.
142 };
143 #endif // __linux__
144
145 #ifdef __linux__
146 static thread_local volatile sig_atomic_t g_usr1_called;
147
148 static void
SigUsr1Handler(int)149 SigUsr1Handler (int)
150 {
151 g_usr1_called = 1;
152 }
153 #endif // __linux__
154
155 static bool
CheckForMonitorCancellation()156 CheckForMonitorCancellation()
157 {
158 #ifdef __linux__
159 if (g_usr1_called)
160 {
161 g_usr1_called = 0;
162 return true;
163 }
164 #else
165 ::pthread_testcancel ();
166 #endif
167 return false;
168 }
169
170 static thread_result_t
MonitorChildProcessThreadFunction(void * arg)171 MonitorChildProcessThreadFunction (void *arg)
172 {
173 Log *log(lldb_private::GetLogIfAllCategoriesSet (LIBLLDB_LOG_PROCESS));
174 const char *function = __FUNCTION__;
175 if (log)
176 log->Printf ("%s (arg = %p) thread starting...", function, arg);
177
178 MonitorInfo *info = (MonitorInfo *)arg;
179
180 const Host::MonitorChildProcessCallback callback = info->callback;
181 void * const callback_baton = info->callback_baton;
182 const bool monitor_signals = info->monitor_signals;
183
184 assert (info->pid <= UINT32_MAX);
185 const ::pid_t pid = monitor_signals ? -1 * getpgid(info->pid) : info->pid;
186
187 delete info;
188
189 int status = -1;
190 #if defined (__FreeBSD__) || defined (__FreeBSD_kernel__)
191 #define __WALL 0
192 #endif
193 const int options = __WALL;
194
195 #ifdef __linux__
196 // This signal is only used to interrupt the thread from waitpid
197 struct sigaction sigUsr1Action;
198 memset(&sigUsr1Action, 0, sizeof(sigUsr1Action));
199 sigUsr1Action.sa_handler = SigUsr1Handler;
200 ::sigaction(SIGUSR1, &sigUsr1Action, nullptr);
201 #endif // __linux__
202
203 while (1)
204 {
205 log = lldb_private::GetLogIfAllCategoriesSet (LIBLLDB_LOG_PROCESS);
206 if (log)
207 log->Printf("%s ::waitpid (pid = %" PRIi32 ", &status, options = %i)...", function, pid, options);
208
209 if (CheckForMonitorCancellation ())
210 break;
211
212 // Get signals from all children with same process group of pid
213 const ::pid_t wait_pid = ::waitpid (pid, &status, options);
214
215 if (CheckForMonitorCancellation ())
216 break;
217
218 if (wait_pid == -1)
219 {
220 if (errno == EINTR)
221 continue;
222 else
223 {
224 if (log)
225 log->Printf ("%s (arg = %p) thread exiting because waitpid failed (%s)...", __FUNCTION__, arg, strerror(errno));
226 break;
227 }
228 }
229 else if (wait_pid > 0)
230 {
231 bool exited = false;
232 int signal = 0;
233 int exit_status = 0;
234 const char *status_cstr = NULL;
235 if (WIFSTOPPED(status))
236 {
237 signal = WSTOPSIG(status);
238 status_cstr = "STOPPED";
239 }
240 else if (WIFEXITED(status))
241 {
242 exit_status = WEXITSTATUS(status);
243 status_cstr = "EXITED";
244 exited = true;
245 }
246 else if (WIFSIGNALED(status))
247 {
248 signal = WTERMSIG(status);
249 status_cstr = "SIGNALED";
250 if (wait_pid == abs(pid)) {
251 exited = true;
252 exit_status = -1;
253 }
254 }
255 else
256 {
257 status_cstr = "(\?\?\?)";
258 }
259
260 // Scope for pthread_cancel_disabler
261 {
262 #ifndef __linux__
263 ScopedPThreadCancelDisabler pthread_cancel_disabler;
264 #endif
265
266 log = lldb_private::GetLogIfAllCategoriesSet (LIBLLDB_LOG_PROCESS);
267 if (log)
268 log->Printf ("%s ::waitpid (pid = %" PRIi32 ", &status, options = %i) => pid = %" PRIi32 ", status = 0x%8.8x (%s), signal = %i, exit_state = %i",
269 function,
270 pid,
271 options,
272 wait_pid,
273 status,
274 status_cstr,
275 signal,
276 exit_status);
277
278 if (exited || (signal != 0 && monitor_signals))
279 {
280 bool callback_return = false;
281 if (callback)
282 callback_return = callback (callback_baton, wait_pid, exited, signal, exit_status);
283
284 // If our process exited, then this thread should exit
285 if (exited && wait_pid == abs(pid))
286 {
287 if (log)
288 log->Printf ("%s (arg = %p) thread exiting because pid received exit signal...", __FUNCTION__, arg);
289 break;
290 }
291 // If the callback returns true, it means this process should
292 // exit
293 if (callback_return)
294 {
295 if (log)
296 log->Printf ("%s (arg = %p) thread exiting because callback returned true...", __FUNCTION__, arg);
297 break;
298 }
299 }
300 }
301 }
302 }
303
304 log = lldb_private::GetLogIfAllCategoriesSet (LIBLLDB_LOG_PROCESS);
305 if (log)
306 log->Printf ("%s (arg = %p) thread exiting...", __FUNCTION__, arg);
307
308 return NULL;
309 }
310
311 #endif // #if !defined (__APPLE__) && !defined (_WIN32)
312
313 #if !defined (__APPLE__)
314
315 void
SystemLog(SystemLogType type,const char * format,va_list args)316 Host::SystemLog (SystemLogType type, const char *format, va_list args)
317 {
318 vfprintf (stderr, format, args);
319 }
320
321 #endif
322
323 void
SystemLog(SystemLogType type,const char * format,...)324 Host::SystemLog (SystemLogType type, const char *format, ...)
325 {
326 va_list args;
327 va_start (args, format);
328 SystemLog (type, format, args);
329 va_end (args);
330 }
331
332 lldb::pid_t
GetCurrentProcessID()333 Host::GetCurrentProcessID()
334 {
335 return ::getpid();
336 }
337
338 #ifndef _WIN32
339
340 lldb::tid_t
GetCurrentThreadID()341 Host::GetCurrentThreadID()
342 {
343 #if defined (__APPLE__)
344 // Calling "mach_thread_self()" bumps the reference count on the thread
345 // port, so we need to deallocate it. mach_task_self() doesn't bump the ref
346 // count.
347 thread_port_t thread_self = mach_thread_self();
348 mach_port_deallocate(mach_task_self(), thread_self);
349 return thread_self;
350 #elif defined(__FreeBSD__)
351 return lldb::tid_t(pthread_getthreadid_np());
352 #elif defined(__ANDROID_NDK__)
353 return lldb::tid_t(gettid());
354 #elif defined(__linux__)
355 return lldb::tid_t(syscall(SYS_gettid));
356 #else
357 return lldb::tid_t(pthread_self());
358 #endif
359 }
360
361 lldb::thread_t
GetCurrentThread()362 Host::GetCurrentThread ()
363 {
364 return lldb::thread_t(pthread_self());
365 }
366
367 const char *
GetSignalAsCString(int signo)368 Host::GetSignalAsCString (int signo)
369 {
370 switch (signo)
371 {
372 case SIGHUP: return "SIGHUP"; // 1 hangup
373 case SIGINT: return "SIGINT"; // 2 interrupt
374 case SIGQUIT: return "SIGQUIT"; // 3 quit
375 case SIGILL: return "SIGILL"; // 4 illegal instruction (not reset when caught)
376 case SIGTRAP: return "SIGTRAP"; // 5 trace trap (not reset when caught)
377 case SIGABRT: return "SIGABRT"; // 6 abort()
378 #if defined(SIGPOLL)
379 #if !defined(SIGIO) || (SIGPOLL != SIGIO)
380 // Under some GNU/Linux, SIGPOLL and SIGIO are the same. Causing the build to
381 // fail with 'multiple define cases with same value'
382 case SIGPOLL: return "SIGPOLL"; // 7 pollable event ([XSR] generated, not supported)
383 #endif
384 #endif
385 #if defined(SIGEMT)
386 case SIGEMT: return "SIGEMT"; // 7 EMT instruction
387 #endif
388 case SIGFPE: return "SIGFPE"; // 8 floating point exception
389 case SIGKILL: return "SIGKILL"; // 9 kill (cannot be caught or ignored)
390 case SIGBUS: return "SIGBUS"; // 10 bus error
391 case SIGSEGV: return "SIGSEGV"; // 11 segmentation violation
392 case SIGSYS: return "SIGSYS"; // 12 bad argument to system call
393 case SIGPIPE: return "SIGPIPE"; // 13 write on a pipe with no one to read it
394 case SIGALRM: return "SIGALRM"; // 14 alarm clock
395 case SIGTERM: return "SIGTERM"; // 15 software termination signal from kill
396 case SIGURG: return "SIGURG"; // 16 urgent condition on IO channel
397 case SIGSTOP: return "SIGSTOP"; // 17 sendable stop signal not from tty
398 case SIGTSTP: return "SIGTSTP"; // 18 stop signal from tty
399 case SIGCONT: return "SIGCONT"; // 19 continue a stopped process
400 case SIGCHLD: return "SIGCHLD"; // 20 to parent on child stop or exit
401 case SIGTTIN: return "SIGTTIN"; // 21 to readers pgrp upon background tty read
402 case SIGTTOU: return "SIGTTOU"; // 22 like TTIN for output if (tp->t_local<OSTOP)
403 #if defined(SIGIO)
404 case SIGIO: return "SIGIO"; // 23 input/output possible signal
405 #endif
406 case SIGXCPU: return "SIGXCPU"; // 24 exceeded CPU time limit
407 case SIGXFSZ: return "SIGXFSZ"; // 25 exceeded file size limit
408 case SIGVTALRM: return "SIGVTALRM"; // 26 virtual time alarm
409 case SIGPROF: return "SIGPROF"; // 27 profiling time alarm
410 #if defined(SIGWINCH)
411 case SIGWINCH: return "SIGWINCH"; // 28 window size changes
412 #endif
413 #if defined(SIGINFO)
414 case SIGINFO: return "SIGINFO"; // 29 information request
415 #endif
416 case SIGUSR1: return "SIGUSR1"; // 30 user defined signal 1
417 case SIGUSR2: return "SIGUSR2"; // 31 user defined signal 2
418 default:
419 break;
420 }
421 return NULL;
422 }
423
424 #endif
425
426 #ifndef _WIN32
427
428 lldb::thread_key_t
ThreadLocalStorageCreate(ThreadLocalStorageCleanupCallback callback)429 Host::ThreadLocalStorageCreate(ThreadLocalStorageCleanupCallback callback)
430 {
431 pthread_key_t key;
432 ::pthread_key_create (&key, callback);
433 return key;
434 }
435
436 void*
ThreadLocalStorageGet(lldb::thread_key_t key)437 Host::ThreadLocalStorageGet(lldb::thread_key_t key)
438 {
439 return ::pthread_getspecific (key);
440 }
441
442 void
ThreadLocalStorageSet(lldb::thread_key_t key,void * value)443 Host::ThreadLocalStorageSet(lldb::thread_key_t key, void *value)
444 {
445 ::pthread_setspecific (key, value);
446 }
447
448 #endif
449
450 #if !defined (__APPLE__) // see Host.mm
451
452 bool
GetBundleDirectory(const FileSpec & file,FileSpec & bundle)453 Host::GetBundleDirectory (const FileSpec &file, FileSpec &bundle)
454 {
455 bundle.Clear();
456 return false;
457 }
458
459 bool
ResolveExecutableInBundle(FileSpec & file)460 Host::ResolveExecutableInBundle (FileSpec &file)
461 {
462 return false;
463 }
464 #endif
465
466 #ifndef _WIN32
467
468 FileSpec
GetModuleFileSpecForHostAddress(const void * host_addr)469 Host::GetModuleFileSpecForHostAddress (const void *host_addr)
470 {
471 FileSpec module_filespec;
472 #if !defined(__ANDROID__) && !defined(__ANDROID_NDK__)
473 Dl_info info;
474 if (::dladdr (host_addr, &info))
475 {
476 if (info.dli_fname)
477 module_filespec.SetFile(info.dli_fname, true);
478 }
479 #endif
480 return module_filespec;
481 }
482
483 #endif
484
485 #if !defined(__linux__)
486 bool
FindProcessThreads(const lldb::pid_t pid,TidMap & tids_to_attach)487 Host::FindProcessThreads (const lldb::pid_t pid, TidMap &tids_to_attach)
488 {
489 return false;
490 }
491 #endif
492
493 struct ShellInfo
494 {
ShellInfoShellInfo495 ShellInfo () :
496 process_reaped (false),
497 can_delete (false),
498 pid (LLDB_INVALID_PROCESS_ID),
499 signo(-1),
500 status(-1)
501 {
502 }
503
504 lldb_private::Predicate<bool> process_reaped;
505 lldb_private::Predicate<bool> can_delete;
506 lldb::pid_t pid;
507 int signo;
508 int status;
509 };
510
511 static bool
MonitorShellCommand(void * callback_baton,lldb::pid_t pid,bool exited,int signo,int status)512 MonitorShellCommand (void *callback_baton,
513 lldb::pid_t pid,
514 bool exited, // True if the process did exit
515 int signo, // Zero for no signal
516 int status) // Exit value of process if signal is zero
517 {
518 ShellInfo *shell_info = (ShellInfo *)callback_baton;
519 shell_info->pid = pid;
520 shell_info->signo = signo;
521 shell_info->status = status;
522 // Let the thread running Host::RunShellCommand() know that the process
523 // exited and that ShellInfo has been filled in by broadcasting to it
524 shell_info->process_reaped.SetValue(1, eBroadcastAlways);
525 // Now wait for a handshake back from that thread running Host::RunShellCommand
526 // so we know that we can delete shell_info_ptr
527 shell_info->can_delete.WaitForValueEqualTo(true);
528 // Sleep a bit to allow the shell_info->can_delete.SetValue() to complete...
529 usleep(1000);
530 // Now delete the shell info that was passed into this function
531 delete shell_info;
532 return true;
533 }
534
535 Error
RunShellCommand(const char * command,const FileSpec & working_dir,int * status_ptr,int * signo_ptr,std::string * command_output_ptr,uint32_t timeout_sec,bool run_in_default_shell)536 Host::RunShellCommand(const char *command,
537 const FileSpec &working_dir,
538 int *status_ptr,
539 int *signo_ptr,
540 std::string *command_output_ptr,
541 uint32_t timeout_sec,
542 bool run_in_default_shell)
543 {
544 return RunShellCommand(Args(command), working_dir, status_ptr, signo_ptr, command_output_ptr, timeout_sec, run_in_default_shell);
545 }
546
547 Error
RunShellCommand(const Args & args,const FileSpec & working_dir,int * status_ptr,int * signo_ptr,std::string * command_output_ptr,uint32_t timeout_sec,bool run_in_default_shell)548 Host::RunShellCommand(const Args &args,
549 const FileSpec &working_dir,
550 int *status_ptr,
551 int *signo_ptr,
552 std::string *command_output_ptr,
553 uint32_t timeout_sec,
554 bool run_in_default_shell)
555 {
556 Error error;
557 ProcessLaunchInfo launch_info;
558 launch_info.SetArchitecture(HostInfo::GetArchitecture());
559 if (run_in_default_shell)
560 {
561 // Run the command in a shell
562 launch_info.SetShell(HostInfo::GetDefaultShell());
563 launch_info.GetArguments().AppendArguments(args);
564 const bool localhost = true;
565 const bool will_debug = false;
566 const bool first_arg_is_full_shell_command = false;
567 launch_info.ConvertArgumentsForLaunchingInShell (error,
568 localhost,
569 will_debug,
570 first_arg_is_full_shell_command,
571 0);
572 }
573 else
574 {
575 // No shell, just run it
576 const bool first_arg_is_executable = true;
577 launch_info.SetArguments(args, first_arg_is_executable);
578 }
579
580 if (working_dir)
581 launch_info.SetWorkingDirectory(working_dir);
582 llvm::SmallString<PATH_MAX> output_file_path;
583
584 if (command_output_ptr)
585 {
586 // Create a temporary file to get the stdout/stderr and redirect the
587 // output of the command into this file. We will later read this file
588 // if all goes well and fill the data into "command_output_ptr"
589 FileSpec tmpdir_file_spec;
590 if (HostInfo::GetLLDBPath(ePathTypeLLDBTempSystemDir, tmpdir_file_spec))
591 {
592 tmpdir_file_spec.AppendPathComponent("lldb-shell-output.%%%%%%");
593 llvm::sys::fs::createUniqueFile(tmpdir_file_spec.GetPath().c_str(), output_file_path);
594 }
595 else
596 {
597 llvm::sys::fs::createTemporaryFile("lldb-shell-output.%%%%%%", "", output_file_path);
598 }
599 }
600
601 FileSpec output_file_spec{output_file_path.c_str(), false};
602
603 launch_info.AppendSuppressFileAction (STDIN_FILENO, true, false);
604 if (output_file_spec)
605 {
606 launch_info.AppendOpenFileAction(STDOUT_FILENO, output_file_spec, false, true);
607 launch_info.AppendDuplicateFileAction(STDOUT_FILENO, STDERR_FILENO);
608 }
609 else
610 {
611 launch_info.AppendSuppressFileAction (STDOUT_FILENO, false, true);
612 launch_info.AppendSuppressFileAction (STDERR_FILENO, false, true);
613 }
614
615 // The process monitor callback will delete the 'shell_info_ptr' below...
616 std::unique_ptr<ShellInfo> shell_info_ap (new ShellInfo());
617
618 const bool monitor_signals = false;
619 launch_info.SetMonitorProcessCallback(MonitorShellCommand, shell_info_ap.get(), monitor_signals);
620
621 error = LaunchProcess (launch_info);
622 const lldb::pid_t pid = launch_info.GetProcessID();
623
624 if (error.Success() && pid == LLDB_INVALID_PROCESS_ID)
625 error.SetErrorString("failed to get process ID");
626
627 if (error.Success())
628 {
629 // The process successfully launched, so we can defer ownership of
630 // "shell_info" to the MonitorShellCommand callback function that will
631 // get called when the process dies. We release the unique pointer as it
632 // doesn't need to delete the ShellInfo anymore.
633 ShellInfo *shell_info = shell_info_ap.release();
634 TimeValue *timeout_ptr = nullptr;
635 TimeValue timeout_time(TimeValue::Now());
636 if (timeout_sec > 0) {
637 timeout_time.OffsetWithSeconds(timeout_sec);
638 timeout_ptr = &timeout_time;
639 }
640 bool timed_out = false;
641 shell_info->process_reaped.WaitForValueEqualTo(true, timeout_ptr, &timed_out);
642 if (timed_out)
643 {
644 error.SetErrorString("timed out waiting for shell command to complete");
645
646 // Kill the process since it didn't complete within the timeout specified
647 Kill (pid, SIGKILL);
648 // Wait for the monitor callback to get the message
649 timeout_time = TimeValue::Now();
650 timeout_time.OffsetWithSeconds(1);
651 timed_out = false;
652 shell_info->process_reaped.WaitForValueEqualTo(true, &timeout_time, &timed_out);
653 }
654 else
655 {
656 if (status_ptr)
657 *status_ptr = shell_info->status;
658
659 if (signo_ptr)
660 *signo_ptr = shell_info->signo;
661
662 if (command_output_ptr)
663 {
664 command_output_ptr->clear();
665 uint64_t file_size = output_file_spec.GetByteSize();
666 if (file_size > 0)
667 {
668 if (file_size > command_output_ptr->max_size())
669 {
670 error.SetErrorStringWithFormat("shell command output is too large to fit into a std::string");
671 }
672 else
673 {
674 std::vector<char> command_output(file_size);
675 output_file_spec.ReadFileContents(0, command_output.data(), file_size, &error);
676 if (error.Success())
677 command_output_ptr->assign(command_output.data(), file_size);
678 }
679 }
680 }
681 }
682 shell_info->can_delete.SetValue(true, eBroadcastAlways);
683 }
684
685 if (FileSystem::GetFileExists(output_file_spec))
686 FileSystem::Unlink(output_file_spec);
687 // Handshake with the monitor thread, or just let it know in advance that
688 // it can delete "shell_info" in case we timed out and were not able to kill
689 // the process...
690 return error;
691 }
692
693 // LaunchProcessPosixSpawn for Apple, Linux, FreeBSD and other GLIBC
694 // systems
695
696 #if defined (__APPLE__) || defined (__linux__) || defined (__FreeBSD__) || defined (__GLIBC__) || defined(__NetBSD__)
697 #if !defined(__ANDROID__) && !defined(__ANDROID_NDK__)
698 // this method needs to be visible to macosx/Host.cpp and
699 // common/Host.cpp.
700
701 short
GetPosixspawnFlags(const ProcessLaunchInfo & launch_info)702 Host::GetPosixspawnFlags(const ProcessLaunchInfo &launch_info)
703 {
704 short flags = POSIX_SPAWN_SETSIGDEF | POSIX_SPAWN_SETSIGMASK;
705
706 #if defined (__APPLE__)
707 if (launch_info.GetFlags().Test (eLaunchFlagExec))
708 flags |= POSIX_SPAWN_SETEXEC; // Darwin specific posix_spawn flag
709
710 if (launch_info.GetFlags().Test (eLaunchFlagDebug))
711 flags |= POSIX_SPAWN_START_SUSPENDED; // Darwin specific posix_spawn flag
712
713 if (launch_info.GetFlags().Test (eLaunchFlagDisableASLR))
714 flags |= _POSIX_SPAWN_DISABLE_ASLR; // Darwin specific posix_spawn flag
715
716 if (launch_info.GetLaunchInSeparateProcessGroup())
717 flags |= POSIX_SPAWN_SETPGROUP;
718
719 #ifdef POSIX_SPAWN_CLOEXEC_DEFAULT
720 #if defined (__APPLE__) && (defined (__x86_64__) || defined (__i386__))
721 static LazyBool g_use_close_on_exec_flag = eLazyBoolCalculate;
722 if (g_use_close_on_exec_flag == eLazyBoolCalculate)
723 {
724 g_use_close_on_exec_flag = eLazyBoolNo;
725
726 uint32_t major, minor, update;
727 if (HostInfo::GetOSVersion(major, minor, update))
728 {
729 // Kernel panic if we use the POSIX_SPAWN_CLOEXEC_DEFAULT on 10.7 or earlier
730 if (major > 10 || (major == 10 && minor > 7))
731 {
732 // Only enable for 10.8 and later OS versions
733 g_use_close_on_exec_flag = eLazyBoolYes;
734 }
735 }
736 }
737 #else
738 static LazyBool g_use_close_on_exec_flag = eLazyBoolYes;
739 #endif
740 // Close all files exception those with file actions if this is supported.
741 if (g_use_close_on_exec_flag == eLazyBoolYes)
742 flags |= POSIX_SPAWN_CLOEXEC_DEFAULT;
743 #endif
744 #endif // #if defined (__APPLE__)
745 return flags;
746 }
747
748 Error
LaunchProcessPosixSpawn(const char * exe_path,const ProcessLaunchInfo & launch_info,lldb::pid_t & pid)749 Host::LaunchProcessPosixSpawn(const char *exe_path, const ProcessLaunchInfo &launch_info, lldb::pid_t &pid)
750 {
751 Error error;
752 Log *log(lldb_private::GetLogIfAllCategoriesSet (LIBLLDB_LOG_HOST | LIBLLDB_LOG_PROCESS));
753
754 posix_spawnattr_t attr;
755 error.SetError( ::posix_spawnattr_init (&attr), eErrorTypePOSIX);
756
757 if (error.Fail() || log)
758 error.PutToLog(log, "::posix_spawnattr_init ( &attr )");
759 if (error.Fail())
760 return error;
761
762 // Make a quick class that will cleanup the posix spawn attributes in case
763 // we return in the middle of this function.
764 lldb_utility::CleanUp <posix_spawnattr_t *, int> posix_spawnattr_cleanup(&attr, posix_spawnattr_destroy);
765
766 sigset_t no_signals;
767 sigset_t all_signals;
768 sigemptyset (&no_signals);
769 sigfillset (&all_signals);
770 ::posix_spawnattr_setsigmask(&attr, &no_signals);
771 #if defined (__linux__) || defined (__FreeBSD__)
772 ::posix_spawnattr_setsigdefault(&attr, &no_signals);
773 #else
774 ::posix_spawnattr_setsigdefault(&attr, &all_signals);
775 #endif
776
777 short flags = GetPosixspawnFlags(launch_info);
778
779 error.SetError( ::posix_spawnattr_setflags (&attr, flags), eErrorTypePOSIX);
780 if (error.Fail() || log)
781 error.PutToLog(log, "::posix_spawnattr_setflags ( &attr, flags=0x%8.8x )", flags);
782 if (error.Fail())
783 return error;
784
785 // posix_spawnattr_setbinpref_np appears to be an Apple extension per:
786 // http://www.unix.com/man-page/OSX/3/posix_spawnattr_setbinpref_np/
787 #if defined (__APPLE__) && !defined (__arm__)
788
789 // Don't set the binpref if a shell was provided. After all, that's only going to affect what version of the shell
790 // is launched, not what fork of the binary is launched. We insert "arch --arch <ARCH> as part of the shell invocation
791 // to do that job on OSX.
792
793 if (launch_info.GetShell() == nullptr)
794 {
795 // We don't need to do this for ARM, and we really shouldn't now that we
796 // have multiple CPU subtypes and no posix_spawnattr call that allows us
797 // to set which CPU subtype to launch...
798 const ArchSpec &arch_spec = launch_info.GetArchitecture();
799 cpu_type_t cpu = arch_spec.GetMachOCPUType();
800 cpu_type_t sub = arch_spec.GetMachOCPUSubType();
801 if (cpu != 0 &&
802 cpu != static_cast<cpu_type_t>(UINT32_MAX) &&
803 cpu != static_cast<cpu_type_t>(LLDB_INVALID_CPUTYPE) &&
804 !(cpu == 0x01000007 && sub == 8)) // If haswell is specified, don't try to set the CPU type or we will fail
805 {
806 size_t ocount = 0;
807 error.SetError( ::posix_spawnattr_setbinpref_np (&attr, 1, &cpu, &ocount), eErrorTypePOSIX);
808 if (error.Fail() || log)
809 error.PutToLog(log, "::posix_spawnattr_setbinpref_np ( &attr, 1, cpu_type = 0x%8.8x, count => %llu )", cpu, (uint64_t)ocount);
810
811 if (error.Fail() || ocount != 1)
812 return error;
813 }
814 }
815
816 #endif
817
818 const char *tmp_argv[2];
819 char * const *argv = (char * const*)launch_info.GetArguments().GetConstArgumentVector();
820 char * const *envp = (char * const*)launch_info.GetEnvironmentEntries().GetConstArgumentVector();
821 if (argv == NULL)
822 {
823 // posix_spawn gets very unhappy if it doesn't have at least the program
824 // name in argv[0]. One of the side affects I have noticed is the environment
825 // variables don't make it into the child process if "argv == NULL"!!!
826 tmp_argv[0] = exe_path;
827 tmp_argv[1] = NULL;
828 argv = (char * const*)tmp_argv;
829 }
830
831 #if !defined (__APPLE__)
832 // manage the working directory
833 char current_dir[PATH_MAX];
834 current_dir[0] = '\0';
835 #endif
836
837 FileSpec working_dir{launch_info.GetWorkingDirectory()};
838 if (working_dir)
839 {
840 #if defined (__APPLE__)
841 // Set the working directory on this thread only
842 if (__pthread_chdir(working_dir.GetCString()) < 0) {
843 if (errno == ENOENT) {
844 error.SetErrorStringWithFormat("No such file or directory: %s",
845 working_dir.GetCString());
846 } else if (errno == ENOTDIR) {
847 error.SetErrorStringWithFormat("Path doesn't name a directory: %s",
848 working_dir.GetCString());
849 } else {
850 error.SetErrorStringWithFormat("An unknown error occurred when changing directory for process execution.");
851 }
852 return error;
853 }
854 #else
855 if (::getcwd(current_dir, sizeof(current_dir)) == NULL)
856 {
857 error.SetError(errno, eErrorTypePOSIX);
858 error.LogIfError(log, "unable to save the current directory");
859 return error;
860 }
861
862 if (::chdir(working_dir.GetCString()) == -1)
863 {
864 error.SetError(errno, eErrorTypePOSIX);
865 error.LogIfError(log, "unable to change working directory to %s",
866 working_dir.GetCString());
867 return error;
868 }
869 #endif
870 }
871
872 ::pid_t result_pid = LLDB_INVALID_PROCESS_ID;
873 const size_t num_file_actions = launch_info.GetNumFileActions ();
874 if (num_file_actions > 0)
875 {
876 posix_spawn_file_actions_t file_actions;
877 error.SetError( ::posix_spawn_file_actions_init (&file_actions), eErrorTypePOSIX);
878 if (error.Fail() || log)
879 error.PutToLog(log, "::posix_spawn_file_actions_init ( &file_actions )");
880 if (error.Fail())
881 return error;
882
883 // Make a quick class that will cleanup the posix spawn attributes in case
884 // we return in the middle of this function.
885 lldb_utility::CleanUp <posix_spawn_file_actions_t *, int> posix_spawn_file_actions_cleanup (&file_actions, posix_spawn_file_actions_destroy);
886
887 for (size_t i=0; i<num_file_actions; ++i)
888 {
889 const FileAction *launch_file_action = launch_info.GetFileActionAtIndex(i);
890 if (launch_file_action)
891 {
892 if (!AddPosixSpawnFileAction(&file_actions, launch_file_action, log, error))
893 return error;
894 }
895 }
896
897 error.SetError(::posix_spawnp(&result_pid, exe_path, &file_actions, &attr, argv, envp), eErrorTypePOSIX);
898
899 if (error.Fail() || log)
900 {
901 error.PutToLog(log, "::posix_spawnp ( pid => %i, path = '%s', file_actions = %p, attr = %p, argv = %p, envp = %p )", result_pid,
902 exe_path, static_cast<void *>(&file_actions), static_cast<void *>(&attr), reinterpret_cast<const void *>(argv),
903 reinterpret_cast<const void *>(envp));
904 if (log)
905 {
906 for (int ii=0; argv[ii]; ++ii)
907 log->Printf("argv[%i] = '%s'", ii, argv[ii]);
908 }
909 }
910
911 }
912 else
913 {
914 error.SetError(::posix_spawnp(&result_pid, exe_path, NULL, &attr, argv, envp), eErrorTypePOSIX);
915
916 if (error.Fail() || log)
917 {
918 error.PutToLog(log, "::posix_spawnp ( pid => %i, path = '%s', file_actions = NULL, attr = %p, argv = %p, envp = %p )",
919 result_pid, exe_path, static_cast<void *>(&attr), reinterpret_cast<const void *>(argv),
920 reinterpret_cast<const void *>(envp));
921 if (log)
922 {
923 for (int ii=0; argv[ii]; ++ii)
924 log->Printf("argv[%i] = '%s'", ii, argv[ii]);
925 }
926 }
927 }
928 pid = result_pid;
929
930 if (working_dir)
931 {
932 #if defined (__APPLE__)
933 // No more thread specific current working directory
934 __pthread_fchdir (-1);
935 #else
936 if (::chdir(current_dir) == -1 && error.Success())
937 {
938 error.SetError(errno, eErrorTypePOSIX);
939 error.LogIfError(log, "unable to change current directory back to %s",
940 current_dir);
941 }
942 #endif
943 }
944
945 return error;
946 }
947
948 bool
AddPosixSpawnFileAction(void * _file_actions,const FileAction * info,Log * log,Error & error)949 Host::AddPosixSpawnFileAction(void *_file_actions, const FileAction *info, Log *log, Error &error)
950 {
951 if (info == NULL)
952 return false;
953
954 posix_spawn_file_actions_t *file_actions = reinterpret_cast<posix_spawn_file_actions_t *>(_file_actions);
955
956 switch (info->GetAction())
957 {
958 case FileAction::eFileActionNone:
959 error.Clear();
960 break;
961
962 case FileAction::eFileActionClose:
963 if (info->GetFD() == -1)
964 error.SetErrorString("invalid fd for posix_spawn_file_actions_addclose(...)");
965 else
966 {
967 error.SetError(::posix_spawn_file_actions_addclose(file_actions, info->GetFD()), eErrorTypePOSIX);
968 if (log && (error.Fail() || log))
969 error.PutToLog(log, "posix_spawn_file_actions_addclose (action=%p, fd=%i)",
970 static_cast<void *>(file_actions), info->GetFD());
971 }
972 break;
973
974 case FileAction::eFileActionDuplicate:
975 if (info->GetFD() == -1)
976 error.SetErrorString("invalid fd for posix_spawn_file_actions_adddup2(...)");
977 else if (info->GetActionArgument() == -1)
978 error.SetErrorString("invalid duplicate fd for posix_spawn_file_actions_adddup2(...)");
979 else
980 {
981 error.SetError(
982 ::posix_spawn_file_actions_adddup2(file_actions, info->GetFD(), info->GetActionArgument()),
983 eErrorTypePOSIX);
984 if (log && (error.Fail() || log))
985 error.PutToLog(log, "posix_spawn_file_actions_adddup2 (action=%p, fd=%i, dup_fd=%i)",
986 static_cast<void *>(file_actions), info->GetFD(), info->GetActionArgument());
987 }
988 break;
989
990 case FileAction::eFileActionOpen:
991 if (info->GetFD() == -1)
992 error.SetErrorString("invalid fd in posix_spawn_file_actions_addopen(...)");
993 else
994 {
995 int oflag = info->GetActionArgument();
996
997 mode_t mode = 0;
998
999 if (oflag & O_CREAT)
1000 mode = 0640;
1001
1002 error.SetError(
1003 ::posix_spawn_file_actions_addopen(file_actions, info->GetFD(), info->GetPath(), oflag, mode),
1004 eErrorTypePOSIX);
1005 if (error.Fail() || log)
1006 error.PutToLog(log,
1007 "posix_spawn_file_actions_addopen (action=%p, fd=%i, path='%s', oflag=%i, mode=%i)",
1008 static_cast<void *>(file_actions), info->GetFD(), info->GetPath(), oflag, mode);
1009 }
1010 break;
1011 }
1012 return error.Success();
1013 }
1014 #endif // !defined(__ANDROID__) && !defined(__ANDROID_NDK__)
1015 #endif // defined (__APPLE__) || defined (__linux__) || defined (__FreeBSD__) || defined (__GLIBC__) || defined(__NetBSD__)
1016
1017 #if defined(__linux__) || defined(__FreeBSD__) || defined(__GLIBC__) || defined(__NetBSD__) || defined(_WIN32)
1018 // The functions below implement process launching via posix_spawn() for Linux,
1019 // FreeBSD and NetBSD.
1020
1021 Error
LaunchProcess(ProcessLaunchInfo & launch_info)1022 Host::LaunchProcess (ProcessLaunchInfo &launch_info)
1023 {
1024 std::unique_ptr<ProcessLauncher> delegate_launcher;
1025 #if defined(_WIN32)
1026 delegate_launcher.reset(new ProcessLauncherWindows());
1027 #elif defined(__ANDROID__) || defined(__ANDROID_NDK__)
1028 delegate_launcher.reset(new ProcessLauncherAndroid());
1029 #else
1030 delegate_launcher.reset(new ProcessLauncherPosix());
1031 #endif
1032 MonitoringProcessLauncher launcher(std::move(delegate_launcher));
1033
1034 Error error;
1035 HostProcess process = launcher.LaunchProcess(launch_info, error);
1036
1037 // TODO(zturner): It would be better if the entire HostProcess were returned instead of writing
1038 // it into this structure.
1039 launch_info.SetProcessID(process.GetProcessId());
1040
1041 return error;
1042 }
1043 #endif // defined(__linux__) || defined(__FreeBSD__) || defined(__NetBSD__)
1044
1045 #ifndef _WIN32
1046 void
Kill(lldb::pid_t pid,int signo)1047 Host::Kill(lldb::pid_t pid, int signo)
1048 {
1049 ::kill(pid, signo);
1050 }
1051
1052 #endif
1053
1054 #if !defined (__APPLE__)
1055 bool
OpenFileInExternalEditor(const FileSpec & file_spec,uint32_t line_no)1056 Host::OpenFileInExternalEditor (const FileSpec &file_spec, uint32_t line_no)
1057 {
1058 return false;
1059 }
1060
1061 void
SetCrashDescriptionWithFormat(const char * format,...)1062 Host::SetCrashDescriptionWithFormat (const char *format, ...)
1063 {
1064 }
1065
1066 void
SetCrashDescription(const char * description)1067 Host::SetCrashDescription (const char *description)
1068 {
1069 }
1070
1071 #endif
1072
1073 const UnixSignalsSP &
GetUnixSignals()1074 Host::GetUnixSignals()
1075 {
1076 static const auto s_unix_signals_sp = UnixSignals::Create(HostInfo::GetArchitecture());
1077 return s_unix_signals_sp;
1078 }
1079