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