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