1 //===-- Host.cpp ----------------------------------------------------------===//
2 //
3 // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
4 // See https://llvm.org/LICENSE.txt for license information.
5 // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
6 //
7 //===----------------------------------------------------------------------===//
8 
9 // C includes
10 #include <cerrno>
11 #include <climits>
12 #include <cstdlib>
13 #include <sys/types.h>
14 #ifndef _WIN32
15 #include <dlfcn.h>
16 #include <grp.h>
17 #include <netdb.h>
18 #include <pwd.h>
19 #include <sys/stat.h>
20 #include <unistd.h>
21 #endif
22 
23 #if defined(__APPLE__)
24 #include <mach-o/dyld.h>
25 #include <mach/mach_init.h>
26 #include <mach/mach_port.h>
27 #endif
28 
29 #if defined(__linux__) || defined(__FreeBSD__) ||                              \
30     defined(__FreeBSD_kernel__) || defined(__APPLE__) ||                       \
31     defined(__NetBSD__) || defined(__OpenBSD__) || defined(__EMSCRIPTEN__)
32 #if !defined(__ANDROID__)
33 #include <spawn.h>
34 #endif
35 #include <sys/syscall.h>
36 #include <sys/wait.h>
37 #endif
38 
39 #if defined(__FreeBSD__)
40 #include <pthread_np.h>
41 #endif
42 
43 #if defined(__NetBSD__)
44 #include <lwp.h>
45 #endif
46 
47 #include <csignal>
48 
49 #include "lldb/Host/FileAction.h"
50 #include "lldb/Host/FileSystem.h"
51 #include "lldb/Host/Host.h"
52 #include "lldb/Host/HostInfo.h"
53 #include "lldb/Host/HostProcess.h"
54 #include "lldb/Host/MonitoringProcessLauncher.h"
55 #include "lldb/Host/ProcessLaunchInfo.h"
56 #include "lldb/Host/ProcessLauncher.h"
57 #include "lldb/Host/ThreadLauncher.h"
58 #include "lldb/Host/posix/ConnectionFileDescriptorPosix.h"
59 #include "lldb/Utility/DataBufferLLVM.h"
60 #include "lldb/Utility/FileSpec.h"
61 #include "lldb/Utility/LLDBLog.h"
62 #include "lldb/Utility/Log.h"
63 #include "lldb/Utility/Predicate.h"
64 #include "lldb/Utility/ReproducerProvider.h"
65 #include "lldb/Utility/Status.h"
66 #include "lldb/lldb-private-forward.h"
67 #include "llvm/ADT/SmallString.h"
68 #include "llvm/ADT/StringSwitch.h"
69 #include "llvm/Support/Errno.h"
70 #include "llvm/Support/FileSystem.h"
71 
72 #if defined(_WIN32)
73 #include "lldb/Host/windows/ConnectionGenericFileWindows.h"
74 #include "lldb/Host/windows/ProcessLauncherWindows.h"
75 #else
76 #include "lldb/Host/posix/ProcessLauncherPosixFork.h"
77 #endif
78 
79 #if defined(__APPLE__)
80 #ifndef _POSIX_SPAWN_DISABLE_ASLR
81 #define _POSIX_SPAWN_DISABLE_ASLR 0x0100
82 #endif
83 
84 extern "C" {
85 int __pthread_chdir(const char *path);
86 int __pthread_fchdir(int fildes);
87 }
88 
89 #endif
90 
91 using namespace lldb;
92 using namespace lldb_private;
93 
94 #if !defined(__APPLE__) && !defined(_WIN32)
95 static thread_result_t
96 MonitorChildProcessThreadFunction(::pid_t pid,
97                                   Host::MonitorChildProcessCallback callback);
98 
99 llvm::Expected<HostThread> Host::StartMonitoringChildProcess(
100     const Host::MonitorChildProcessCallback &callback, lldb::pid_t pid) {
101   char thread_name[256];
102   ::snprintf(thread_name, sizeof(thread_name),
103              "<lldb.host.wait4(pid=%" PRIu64 ")>", pid);
104   assert(pid <= UINT32_MAX);
105   return ThreadLauncher::LaunchThread(thread_name, [pid, callback] {
106     return MonitorChildProcessThreadFunction(pid, callback);
107   });
108 }
109 
110 #ifndef __linux__
111 // Scoped class that will disable thread canceling when it is constructed, and
112 // exception safely restore the previous value it when it goes out of scope.
113 class ScopedPThreadCancelDisabler {
114 public:
115   ScopedPThreadCancelDisabler() {
116     // Disable the ability for this thread to be cancelled
117     int err = ::pthread_setcancelstate(PTHREAD_CANCEL_DISABLE, &m_old_state);
118     if (err != 0)
119       m_old_state = -1;
120   }
121 
122   ~ScopedPThreadCancelDisabler() {
123     // Restore the ability for this thread to be cancelled to what it
124     // previously was.
125     if (m_old_state != -1)
126       ::pthread_setcancelstate(m_old_state, 0);
127   }
128 
129 private:
130   int m_old_state; // Save the old cancelability state.
131 };
132 #endif // __linux__
133 
134 #ifdef __linux__
135 #if defined(__GNUC__) && (__GNUC__ < 4 || (__GNUC__ == 4 && __GNUC_MINOR__ < 8))
136 static __thread volatile sig_atomic_t g_usr1_called;
137 #else
138 static thread_local volatile sig_atomic_t g_usr1_called;
139 #endif
140 
141 static void SigUsr1Handler(int) { g_usr1_called = 1; }
142 #endif // __linux__
143 
144 static bool CheckForMonitorCancellation() {
145 #ifdef __linux__
146   if (g_usr1_called) {
147     g_usr1_called = 0;
148     return true;
149   }
150 #else
151   ::pthread_testcancel();
152 #endif
153   return false;
154 }
155 
156 static thread_result_t
157 MonitorChildProcessThreadFunction(::pid_t pid,
158                                   Host::MonitorChildProcessCallback callback) {
159   Log *log = GetLog(LLDBLog::Process);
160   LLDB_LOG(log, "pid = {0}", pid);
161 
162   int status = -1;
163 
164 #ifdef __linux__
165   // This signal is only used to interrupt the thread from waitpid
166   struct sigaction sigUsr1Action;
167   memset(&sigUsr1Action, 0, sizeof(sigUsr1Action));
168   sigUsr1Action.sa_handler = SigUsr1Handler;
169   ::sigaction(SIGUSR1, &sigUsr1Action, nullptr);
170 #endif // __linux__
171 
172   while(1) {
173     log = GetLog(LLDBLog::Process);
174     LLDB_LOG(log, "::waitpid({0}, &status, 0)...", pid);
175 
176     if (CheckForMonitorCancellation())
177       return nullptr;
178 
179     const ::pid_t wait_pid = ::waitpid(pid, &status, 0);
180 
181     LLDB_LOG(log, "::waitpid({0}, &status, 0) => pid = {1}, status = {2:x}", pid,
182              wait_pid, status);
183 
184     if (CheckForMonitorCancellation())
185       return nullptr;
186 
187     if (wait_pid != -1)
188       break;
189     if (errno != EINTR) {
190       LLDB_LOG(log, "pid = {0}, thread exiting because waitpid failed ({1})...",
191                pid, llvm::sys::StrError());
192       return nullptr;
193     }
194   }
195 
196   int signal = 0;
197   int exit_status = 0;
198   if (WIFEXITED(status)) {
199     exit_status = WEXITSTATUS(status);
200   } else if (WIFSIGNALED(status)) {
201     signal = WTERMSIG(status);
202     exit_status = -1;
203   } else {
204     llvm_unreachable("Unknown status");
205   }
206 
207   // Scope for pthread_cancel_disabler
208   {
209 #ifndef __linux__
210     ScopedPThreadCancelDisabler pthread_cancel_disabler;
211 #endif
212 
213     if (callback)
214       callback(pid, signal, exit_status);
215   }
216 
217   LLDB_LOG(GetLog(LLDBLog::Process), "pid = {0} thread exiting...", pid);
218   return nullptr;
219 }
220 
221 #endif // #if !defined (__APPLE__) && !defined (_WIN32)
222 
223 #if !defined(__APPLE__)
224 
225 void Host::SystemLog(SystemLogType type, const char *format, va_list args) {
226   vfprintf(stderr, format, args);
227 }
228 
229 #endif
230 
231 void Host::SystemLog(SystemLogType type, const char *format, ...) {
232   {
233     va_list args;
234     va_start(args, format);
235     SystemLog(type, format, args);
236     va_end(args);
237   }
238 
239   Log *log = GetLog(LLDBLog::Host);
240   if (log && log->GetVerbose()) {
241     // Log to log channel. This allows testcases to grep for log output.
242     va_list args;
243     va_start(args, format);
244     log->VAPrintf(format, args);
245     va_end(args);
246   }
247 }
248 
249 lldb::pid_t Host::GetCurrentProcessID() { return ::getpid(); }
250 
251 #ifndef _WIN32
252 
253 lldb::thread_t Host::GetCurrentThread() {
254   return lldb::thread_t(pthread_self());
255 }
256 
257 const char *Host::GetSignalAsCString(int signo) {
258   switch (signo) {
259   case SIGHUP:
260     return "SIGHUP"; // 1    hangup
261   case SIGINT:
262     return "SIGINT"; // 2    interrupt
263   case SIGQUIT:
264     return "SIGQUIT"; // 3    quit
265   case SIGILL:
266     return "SIGILL"; // 4    illegal instruction (not reset when caught)
267   case SIGTRAP:
268     return "SIGTRAP"; // 5    trace trap (not reset when caught)
269   case SIGABRT:
270     return "SIGABRT"; // 6    abort()
271 #if defined(SIGPOLL)
272 #if !defined(SIGIO) || (SIGPOLL != SIGIO)
273   // Under some GNU/Linux, SIGPOLL and SIGIO are the same. Causing the build to
274   // fail with 'multiple define cases with same value'
275   case SIGPOLL:
276     return "SIGPOLL"; // 7    pollable event ([XSR] generated, not supported)
277 #endif
278 #endif
279 #if defined(SIGEMT)
280   case SIGEMT:
281     return "SIGEMT"; // 7    EMT instruction
282 #endif
283   case SIGFPE:
284     return "SIGFPE"; // 8    floating point exception
285   case SIGKILL:
286     return "SIGKILL"; // 9    kill (cannot be caught or ignored)
287   case SIGBUS:
288     return "SIGBUS"; // 10    bus error
289   case SIGSEGV:
290     return "SIGSEGV"; // 11    segmentation violation
291   case SIGSYS:
292     return "SIGSYS"; // 12    bad argument to system call
293   case SIGPIPE:
294     return "SIGPIPE"; // 13    write on a pipe with no one to read it
295   case SIGALRM:
296     return "SIGALRM"; // 14    alarm clock
297   case SIGTERM:
298     return "SIGTERM"; // 15    software termination signal from kill
299   case SIGURG:
300     return "SIGURG"; // 16    urgent condition on IO channel
301   case SIGSTOP:
302     return "SIGSTOP"; // 17    sendable stop signal not from tty
303   case SIGTSTP:
304     return "SIGTSTP"; // 18    stop signal from tty
305   case SIGCONT:
306     return "SIGCONT"; // 19    continue a stopped process
307   case SIGCHLD:
308     return "SIGCHLD"; // 20    to parent on child stop or exit
309   case SIGTTIN:
310     return "SIGTTIN"; // 21    to readers pgrp upon background tty read
311   case SIGTTOU:
312     return "SIGTTOU"; // 22    like TTIN for output if (tp->t_local&LTOSTOP)
313 #if defined(SIGIO)
314   case SIGIO:
315     return "SIGIO"; // 23    input/output possible signal
316 #endif
317   case SIGXCPU:
318     return "SIGXCPU"; // 24    exceeded CPU time limit
319   case SIGXFSZ:
320     return "SIGXFSZ"; // 25    exceeded file size limit
321   case SIGVTALRM:
322     return "SIGVTALRM"; // 26    virtual time alarm
323   case SIGPROF:
324     return "SIGPROF"; // 27    profiling time alarm
325 #if defined(SIGWINCH)
326   case SIGWINCH:
327     return "SIGWINCH"; // 28    window size changes
328 #endif
329 #if defined(SIGINFO)
330   case SIGINFO:
331     return "SIGINFO"; // 29    information request
332 #endif
333   case SIGUSR1:
334     return "SIGUSR1"; // 30    user defined signal 1
335   case SIGUSR2:
336     return "SIGUSR2"; // 31    user defined signal 2
337   default:
338     break;
339   }
340   return nullptr;
341 }
342 
343 #endif
344 
345 #if !defined(__APPLE__) // see Host.mm
346 
347 bool Host::GetBundleDirectory(const FileSpec &file, FileSpec &bundle) {
348   bundle.Clear();
349   return false;
350 }
351 
352 bool Host::ResolveExecutableInBundle(FileSpec &file) { return false; }
353 #endif
354 
355 #ifndef _WIN32
356 
357 FileSpec Host::GetModuleFileSpecForHostAddress(const void *host_addr) {
358   FileSpec module_filespec;
359 #if !defined(__ANDROID__)
360   Dl_info info;
361   if (::dladdr(host_addr, &info)) {
362     if (info.dli_fname) {
363       module_filespec.SetFile(info.dli_fname, FileSpec::Style::native);
364       FileSystem::Instance().Resolve(module_filespec);
365     }
366   }
367 #endif
368   return module_filespec;
369 }
370 
371 #endif
372 
373 #if !defined(__linux__)
374 bool Host::FindProcessThreads(const lldb::pid_t pid, TidMap &tids_to_attach) {
375   return false;
376 }
377 #endif
378 
379 struct ShellInfo {
380   ShellInfo() : process_reaped(false) {}
381 
382   lldb_private::Predicate<bool> process_reaped;
383   lldb::pid_t pid = LLDB_INVALID_PROCESS_ID;
384   int signo = -1;
385   int status = -1;
386 };
387 
388 static void
389 MonitorShellCommand(std::shared_ptr<ShellInfo> shell_info, lldb::pid_t pid,
390                     int signo,  // Zero for no signal
391                     int status) // Exit value of process if signal is zero
392 {
393   shell_info->pid = pid;
394   shell_info->signo = signo;
395   shell_info->status = status;
396   // Let the thread running Host::RunShellCommand() know that the process
397   // exited and that ShellInfo has been filled in by broadcasting to it
398   shell_info->process_reaped.SetValue(true, eBroadcastAlways);
399 }
400 
401 Status Host::RunShellCommand(llvm::StringRef command,
402                              const FileSpec &working_dir, int *status_ptr,
403                              int *signo_ptr, std::string *command_output_ptr,
404                              const Timeout<std::micro> &timeout,
405                              bool run_in_shell, bool hide_stderr) {
406   return RunShellCommand(llvm::StringRef(), Args(command), working_dir,
407                          status_ptr, signo_ptr, command_output_ptr, timeout,
408                          run_in_shell, hide_stderr);
409 }
410 
411 Status Host::RunShellCommand(llvm::StringRef shell_path,
412                              llvm::StringRef command,
413                              const FileSpec &working_dir, int *status_ptr,
414                              int *signo_ptr, std::string *command_output_ptr,
415                              const Timeout<std::micro> &timeout,
416                              bool run_in_shell, bool hide_stderr) {
417   return RunShellCommand(shell_path, Args(command), working_dir, status_ptr,
418                          signo_ptr, command_output_ptr, timeout, run_in_shell,
419                          hide_stderr);
420 }
421 
422 Status Host::RunShellCommand(const Args &args, const FileSpec &working_dir,
423                              int *status_ptr, int *signo_ptr,
424                              std::string *command_output_ptr,
425                              const Timeout<std::micro> &timeout,
426                              bool run_in_shell, bool hide_stderr) {
427   return RunShellCommand(llvm::StringRef(), args, working_dir, status_ptr,
428                          signo_ptr, command_output_ptr, timeout, run_in_shell,
429                          hide_stderr);
430 }
431 
432 Status Host::RunShellCommand(llvm::StringRef shell_path, const Args &args,
433                              const FileSpec &working_dir, int *status_ptr,
434                              int *signo_ptr, std::string *command_output_ptr,
435                              const Timeout<std::micro> &timeout,
436                              bool run_in_shell, bool hide_stderr) {
437   Status error;
438   ProcessLaunchInfo launch_info;
439   launch_info.SetArchitecture(HostInfo::GetArchitecture());
440   if (run_in_shell) {
441     // Run the command in a shell
442     FileSpec shell = HostInfo::GetDefaultShell();
443     if (!shell_path.empty())
444       shell.SetPath(shell_path);
445 
446     launch_info.SetShell(shell);
447     launch_info.GetArguments().AppendArguments(args);
448     const bool will_debug = false;
449     const bool first_arg_is_full_shell_command = false;
450     launch_info.ConvertArgumentsForLaunchingInShell(
451         error, will_debug, first_arg_is_full_shell_command, 0);
452   } else {
453     // No shell, just run it
454     const bool first_arg_is_executable = true;
455     launch_info.SetArguments(args, first_arg_is_executable);
456   }
457 
458   launch_info.GetEnvironment() = Host::GetEnvironment();
459 
460   if (working_dir)
461     launch_info.SetWorkingDirectory(working_dir);
462   llvm::SmallString<64> output_file_path;
463 
464   if (command_output_ptr) {
465     // Create a temporary file to get the stdout/stderr and redirect the output
466     // of the command into this file. We will later read this file if all goes
467     // well and fill the data into "command_output_ptr"
468     if (FileSpec tmpdir_file_spec = HostInfo::GetProcessTempDir()) {
469       tmpdir_file_spec.AppendPathComponent("lldb-shell-output.%%%%%%");
470       llvm::sys::fs::createUniqueFile(tmpdir_file_spec.GetPath(),
471                                       output_file_path);
472     } else {
473       llvm::sys::fs::createTemporaryFile("lldb-shell-output.%%%%%%", "",
474                                          output_file_path);
475     }
476   }
477 
478   FileSpec output_file_spec(output_file_path.str());
479   // Set up file descriptors.
480   launch_info.AppendSuppressFileAction(STDIN_FILENO, true, false);
481   if (output_file_spec)
482     launch_info.AppendOpenFileAction(STDOUT_FILENO, output_file_spec, false,
483                                      true);
484   else
485     launch_info.AppendSuppressFileAction(STDOUT_FILENO, false, true);
486 
487   if (output_file_spec && !hide_stderr)
488     launch_info.AppendDuplicateFileAction(STDOUT_FILENO, STDERR_FILENO);
489   else
490     launch_info.AppendSuppressFileAction(STDERR_FILENO, false, true);
491 
492   std::shared_ptr<ShellInfo> shell_info_sp(new ShellInfo());
493   launch_info.SetMonitorProcessCallback(
494       std::bind(MonitorShellCommand, shell_info_sp, std::placeholders::_1,
495                 std::placeholders::_2, std::placeholders::_3));
496 
497   error = LaunchProcess(launch_info);
498   const lldb::pid_t pid = launch_info.GetProcessID();
499 
500   if (error.Success() && pid == LLDB_INVALID_PROCESS_ID)
501     error.SetErrorString("failed to get process ID");
502 
503   if (error.Success()) {
504     if (!shell_info_sp->process_reaped.WaitForValueEqualTo(true, timeout)) {
505       error.SetErrorString("timed out waiting for shell command to complete");
506 
507       // Kill the process since it didn't complete within the timeout specified
508       Kill(pid, SIGKILL);
509       // Wait for the monitor callback to get the message
510       shell_info_sp->process_reaped.WaitForValueEqualTo(
511           true, std::chrono::seconds(1));
512     } else {
513       if (status_ptr)
514         *status_ptr = shell_info_sp->status;
515 
516       if (signo_ptr)
517         *signo_ptr = shell_info_sp->signo;
518 
519       if (command_output_ptr) {
520         command_output_ptr->clear();
521         uint64_t file_size =
522             FileSystem::Instance().GetByteSize(output_file_spec);
523         if (file_size > 0) {
524           if (file_size > command_output_ptr->max_size()) {
525             error.SetErrorStringWithFormat(
526                 "shell command output is too large to fit into a std::string");
527           } else {
528             auto Buffer =
529                 FileSystem::Instance().CreateDataBuffer(output_file_spec);
530             if (error.Success())
531               command_output_ptr->assign(Buffer->GetChars(),
532                                          Buffer->GetByteSize());
533           }
534         }
535       }
536     }
537   }
538 
539   llvm::sys::fs::remove(output_file_spec.GetPath());
540   return error;
541 }
542 
543 // The functions below implement process launching for non-Apple-based
544 // platforms
545 #if !defined(__APPLE__)
546 Status Host::LaunchProcess(ProcessLaunchInfo &launch_info) {
547   std::unique_ptr<ProcessLauncher> delegate_launcher;
548 #if defined(_WIN32)
549   delegate_launcher.reset(new ProcessLauncherWindows());
550 #else
551   delegate_launcher.reset(new ProcessLauncherPosixFork());
552 #endif
553   MonitoringProcessLauncher launcher(std::move(delegate_launcher));
554 
555   Status error;
556   HostProcess process = launcher.LaunchProcess(launch_info, error);
557 
558   // TODO(zturner): It would be better if the entire HostProcess were returned
559   // instead of writing it into this structure.
560   launch_info.SetProcessID(process.GetProcessId());
561 
562   return error;
563 }
564 #endif // !defined(__APPLE__)
565 
566 #ifndef _WIN32
567 void Host::Kill(lldb::pid_t pid, int signo) { ::kill(pid, signo); }
568 
569 #endif
570 
571 #if !defined(__APPLE__)
572 bool Host::OpenFileInExternalEditor(const FileSpec &file_spec,
573                                     uint32_t line_no) {
574   return false;
575 }
576 
577 #endif
578 
579 std::unique_ptr<Connection> Host::CreateDefaultConnection(llvm::StringRef url) {
580 #if defined(_WIN32)
581   if (url.startswith("file://"))
582     return std::unique_ptr<Connection>(new ConnectionGenericFile());
583 #endif
584   return std::unique_ptr<Connection>(new ConnectionFileDescriptor());
585 }
586 
587 #if defined(LLVM_ON_UNIX)
588 WaitStatus WaitStatus::Decode(int wstatus) {
589   if (WIFEXITED(wstatus))
590     return {Exit, uint8_t(WEXITSTATUS(wstatus))};
591   else if (WIFSIGNALED(wstatus))
592     return {Signal, uint8_t(WTERMSIG(wstatus))};
593   else if (WIFSTOPPED(wstatus))
594     return {Stop, uint8_t(WSTOPSIG(wstatus))};
595   llvm_unreachable("Unknown wait status");
596 }
597 #endif
598 
599 void llvm::format_provider<WaitStatus>::format(const WaitStatus &WS,
600                                                raw_ostream &OS,
601                                                StringRef Options) {
602   if (Options == "g") {
603     char type;
604     switch (WS.type) {
605     case WaitStatus::Exit:
606       type = 'W';
607       break;
608     case WaitStatus::Signal:
609       type = 'X';
610       break;
611     case WaitStatus::Stop:
612       type = 'S';
613       break;
614     }
615     OS << formatv("{0}{1:x-2}", type, WS.status);
616     return;
617   }
618 
619   assert(Options.empty());
620   const char *desc;
621   switch(WS.type) {
622   case WaitStatus::Exit:
623     desc = "Exited with status";
624     break;
625   case WaitStatus::Signal:
626     desc = "Killed by signal";
627     break;
628   case WaitStatus::Stop:
629     desc = "Stopped by signal";
630     break;
631   }
632   OS << desc << " " << int(WS.status);
633 }
634 
635 uint32_t Host::FindProcesses(const ProcessInstanceInfoMatch &match_info,
636                              ProcessInstanceInfoList &process_infos) {
637 
638   if (llvm::Optional<ProcessInstanceInfoList> infos =
639           repro::GetReplayProcessInstanceInfoList()) {
640     process_infos = *infos;
641     return process_infos.size();
642   }
643 
644   uint32_t result = FindProcessesImpl(match_info, process_infos);
645 
646   if (repro::Generator *g = repro::Reproducer::Instance().GetGenerator()) {
647     g->GetOrCreate<repro::ProcessInfoProvider>()
648         .GetNewProcessInfoRecorder()
649         ->Record(process_infos);
650   }
651 
652   return result;
653 }
654