1 //===-- Host.cpp ----------------------------------------------------------===//
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
7 //===----------------------------------------------------------------------===//
13 #include <sys/types.h>
23 #if defined(__APPLE__)
24 #include <mach-o/dyld.h>
25 #include <mach/mach_init.h>
26 #include <mach/mach_port.h>
29 #if defined(__linux__) || defined(__FreeBSD__) || \
30 defined(__FreeBSD_kernel__) || defined(__APPLE__) || \
31 defined(__NetBSD__) || defined(__OpenBSD__) || defined(__EMSCRIPTEN__)
32 #if !defined(__ANDROID__)
35 #include <sys/syscall.h>
39 #if defined(__FreeBSD__)
40 #include <pthread_np.h>
43 #if defined(__NetBSD__)
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/Config/llvm-config.h" // for LLVM_ON_UNIX
67 #include "llvm/Support/Errno.h"
68 #include "llvm/Support/FileSystem.h"
71 #include "lldb/Host/windows/ConnectionGenericFileWindows.h"
72 #include "lldb/Host/windows/ProcessLauncherWindows.h"
74 #include "lldb/Host/posix/ProcessLauncherPosixFork.h"
77 #if defined(__APPLE__)
78 #ifndef _POSIX_SPAWN_DISABLE_ASLR
79 #define _POSIX_SPAWN_DISABLE_ASLR 0x0100
83 int __pthread_chdir(const char *path
);
84 int __pthread_fchdir(int fildes
);
90 using namespace lldb_private
;
92 #if !defined(__APPLE__)
93 // The system log is currently only meaningful on Darwin, where this means
94 // os_log. The meaning of a "system log" isn't as clear on other platforms, and
95 // therefore we don't providate a default implementation. Vendors are free to
96 // to implement this function if they have a use for it.
97 void Host::SystemLog(Severity severity
, llvm::StringRef message
) {}
100 static constexpr Log::Category g_categories
[] = {
101 {{"system"}, {"system log"}, SystemLog::System
}};
103 static Log::Channel
g_system_channel(g_categories
, SystemLog::System
);
104 static Log
g_system_log(g_system_channel
);
106 template <> Log::Channel
&lldb_private::LogChannelFor
<SystemLog
>() {
107 return g_system_channel
;
110 void LogChannelSystem::Initialize() {
111 g_system_log
.Enable(std::make_shared
<SystemLogHandler
>());
114 void LogChannelSystem::Terminate() { g_system_log
.Disable(); }
116 #if !defined(__APPLE__) && !defined(_WIN32)
117 static thread_result_t
118 MonitorChildProcessThreadFunction(::pid_t pid
,
119 Host::MonitorChildProcessCallback callback
);
121 llvm::Expected
<HostThread
> Host::StartMonitoringChildProcess(
122 const Host::MonitorChildProcessCallback
&callback
, lldb::pid_t pid
) {
123 char thread_name
[256];
124 ::snprintf(thread_name
, sizeof(thread_name
),
125 "<lldb.host.wait4(pid=%" PRIu64
")>", pid
);
126 assert(pid
<= UINT32_MAX
);
127 return ThreadLauncher::LaunchThread(thread_name
, [pid
, callback
] {
128 return MonitorChildProcessThreadFunction(pid
, callback
);
133 // Scoped class that will disable thread canceling when it is constructed, and
134 // exception safely restore the previous value it when it goes out of scope.
135 class ScopedPThreadCancelDisabler
{
137 ScopedPThreadCancelDisabler() {
138 // Disable the ability for this thread to be cancelled
139 int err
= ::pthread_setcancelstate(PTHREAD_CANCEL_DISABLE
, &m_old_state
);
144 ~ScopedPThreadCancelDisabler() {
145 // Restore the ability for this thread to be cancelled to what it
147 if (m_old_state
!= -1)
148 ::pthread_setcancelstate(m_old_state
, 0);
152 int m_old_state
; // Save the old cancelability state.
157 static thread_local
volatile sig_atomic_t g_usr1_called
;
159 static void SigUsr1Handler(int) { g_usr1_called
= 1; }
162 static bool CheckForMonitorCancellation() {
169 ::pthread_testcancel();
174 static thread_result_t
175 MonitorChildProcessThreadFunction(::pid_t pid
,
176 Host::MonitorChildProcessCallback callback
) {
177 Log
*log
= GetLog(LLDBLog::Process
);
178 LLDB_LOG(log
, "pid = {0}", pid
);
183 // This signal is only used to interrupt the thread from waitpid
184 struct sigaction sigUsr1Action
;
185 memset(&sigUsr1Action
, 0, sizeof(sigUsr1Action
));
186 sigUsr1Action
.sa_handler
= SigUsr1Handler
;
187 ::sigaction(SIGUSR1
, &sigUsr1Action
, nullptr);
191 log
= GetLog(LLDBLog::Process
);
192 LLDB_LOG(log
, "::waitpid({0}, &status, 0)...", pid
);
194 if (CheckForMonitorCancellation())
197 const ::pid_t wait_pid
= ::waitpid(pid
, &status
, 0);
199 LLDB_LOG(log
, "::waitpid({0}, &status, 0) => pid = {1}, status = {2:x}", pid
,
202 if (CheckForMonitorCancellation())
207 if (errno
!= EINTR
) {
208 LLDB_LOG(log
, "pid = {0}, thread exiting because waitpid failed ({1})...",
209 pid
, llvm::sys::StrError());
216 if (WIFEXITED(status
)) {
217 exit_status
= WEXITSTATUS(status
);
218 } else if (WIFSIGNALED(status
)) {
219 signal
= WTERMSIG(status
);
222 llvm_unreachable("Unknown status");
225 // Scope for pthread_cancel_disabler
228 ScopedPThreadCancelDisabler pthread_cancel_disabler
;
232 callback(pid
, signal
, exit_status
);
235 LLDB_LOG(GetLog(LLDBLog::Process
), "pid = {0} thread exiting...", pid
);
239 #endif // #if !defined (__APPLE__) && !defined (_WIN32)
241 lldb::pid_t
Host::GetCurrentProcessID() { return ::getpid(); }
245 lldb::thread_t
Host::GetCurrentThread() {
246 return lldb::thread_t(pthread_self());
249 const char *Host::GetSignalAsCString(int signo
) {
252 return "SIGHUP"; // 1 hangup
254 return "SIGINT"; // 2 interrupt
256 return "SIGQUIT"; // 3 quit
258 return "SIGILL"; // 4 illegal instruction (not reset when caught)
260 return "SIGTRAP"; // 5 trace trap (not reset when caught)
262 return "SIGABRT"; // 6 abort()
264 #if !defined(SIGIO) || (SIGPOLL != SIGIO)
265 // Under some GNU/Linux, SIGPOLL and SIGIO are the same. Causing the build to
266 // fail with 'multiple define cases with same value'
268 return "SIGPOLL"; // 7 pollable event ([XSR] generated, not supported)
273 return "SIGEMT"; // 7 EMT instruction
276 return "SIGFPE"; // 8 floating point exception
278 return "SIGKILL"; // 9 kill (cannot be caught or ignored)
280 return "SIGBUS"; // 10 bus error
282 return "SIGSEGV"; // 11 segmentation violation
284 return "SIGSYS"; // 12 bad argument to system call
286 return "SIGPIPE"; // 13 write on a pipe with no one to read it
288 return "SIGALRM"; // 14 alarm clock
290 return "SIGTERM"; // 15 software termination signal from kill
292 return "SIGURG"; // 16 urgent condition on IO channel
294 return "SIGSTOP"; // 17 sendable stop signal not from tty
296 return "SIGTSTP"; // 18 stop signal from tty
298 return "SIGCONT"; // 19 continue a stopped process
300 return "SIGCHLD"; // 20 to parent on child stop or exit
302 return "SIGTTIN"; // 21 to readers pgrp upon background tty read
304 return "SIGTTOU"; // 22 like TTIN for output if (tp->t_local<OSTOP)
307 return "SIGIO"; // 23 input/output possible signal
310 return "SIGXCPU"; // 24 exceeded CPU time limit
312 return "SIGXFSZ"; // 25 exceeded file size limit
314 return "SIGVTALRM"; // 26 virtual time alarm
316 return "SIGPROF"; // 27 profiling time alarm
317 #if defined(SIGWINCH)
319 return "SIGWINCH"; // 28 window size changes
323 return "SIGINFO"; // 29 information request
326 return "SIGUSR1"; // 30 user defined signal 1
328 return "SIGUSR2"; // 31 user defined signal 2
337 #if !defined(__APPLE__) // see Host.mm
339 bool Host::GetBundleDirectory(const FileSpec
&file
, FileSpec
&bundle
) {
344 bool Host::ResolveExecutableInBundle(FileSpec
&file
) { return false; }
349 FileSpec
Host::GetModuleFileSpecForHostAddress(const void *host_addr
) {
350 FileSpec module_filespec
;
351 #if !defined(__ANDROID__)
353 if (::dladdr(host_addr
, &info
)) {
354 if (info
.dli_fname
) {
355 module_filespec
.SetFile(info
.dli_fname
, FileSpec::Style::native
);
356 FileSystem::Instance().Resolve(module_filespec
);
360 return module_filespec
;
365 #if !defined(__linux__)
366 bool Host::FindProcessThreads(const lldb::pid_t pid
, TidMap
&tids_to_attach
) {
372 ShellInfo() : process_reaped(false) {}
374 lldb_private::Predicate
<bool> process_reaped
;
375 lldb::pid_t pid
= LLDB_INVALID_PROCESS_ID
;
381 MonitorShellCommand(std::shared_ptr
<ShellInfo
> shell_info
, lldb::pid_t pid
,
382 int signo
, // Zero for no signal
383 int status
) // Exit value of process if signal is zero
385 shell_info
->pid
= pid
;
386 shell_info
->signo
= signo
;
387 shell_info
->status
= status
;
388 // Let the thread running Host::RunShellCommand() know that the process
389 // exited and that ShellInfo has been filled in by broadcasting to it
390 shell_info
->process_reaped
.SetValue(true, eBroadcastAlways
);
393 Status
Host::RunShellCommand(llvm::StringRef command
,
394 const FileSpec
&working_dir
, int *status_ptr
,
395 int *signo_ptr
, std::string
*command_output_ptr
,
396 const Timeout
<std::micro
> &timeout
,
397 bool run_in_shell
, bool hide_stderr
) {
398 return RunShellCommand(llvm::StringRef(), Args(command
), working_dir
,
399 status_ptr
, signo_ptr
, command_output_ptr
, timeout
,
400 run_in_shell
, hide_stderr
);
403 Status
Host::RunShellCommand(llvm::StringRef shell_path
,
404 llvm::StringRef command
,
405 const FileSpec
&working_dir
, int *status_ptr
,
406 int *signo_ptr
, std::string
*command_output_ptr
,
407 const Timeout
<std::micro
> &timeout
,
408 bool run_in_shell
, bool hide_stderr
) {
409 return RunShellCommand(shell_path
, Args(command
), working_dir
, status_ptr
,
410 signo_ptr
, command_output_ptr
, timeout
, run_in_shell
,
414 Status
Host::RunShellCommand(const Args
&args
, const FileSpec
&working_dir
,
415 int *status_ptr
, int *signo_ptr
,
416 std::string
*command_output_ptr
,
417 const Timeout
<std::micro
> &timeout
,
418 bool run_in_shell
, bool hide_stderr
) {
419 return RunShellCommand(llvm::StringRef(), args
, working_dir
, status_ptr
,
420 signo_ptr
, command_output_ptr
, timeout
, run_in_shell
,
424 Status
Host::RunShellCommand(llvm::StringRef shell_path
, const Args
&args
,
425 const FileSpec
&working_dir
, int *status_ptr
,
426 int *signo_ptr
, std::string
*command_output_ptr
,
427 const Timeout
<std::micro
> &timeout
,
428 bool run_in_shell
, bool hide_stderr
) {
430 ProcessLaunchInfo launch_info
;
431 launch_info
.SetArchitecture(HostInfo::GetArchitecture());
433 // Run the command in a shell
434 FileSpec shell
= HostInfo::GetDefaultShell();
435 if (!shell_path
.empty())
436 shell
.SetPath(shell_path
);
438 launch_info
.SetShell(shell
);
439 launch_info
.GetArguments().AppendArguments(args
);
440 const bool will_debug
= false;
441 const bool first_arg_is_full_shell_command
= false;
442 launch_info
.ConvertArgumentsForLaunchingInShell(
443 error
, will_debug
, first_arg_is_full_shell_command
, 0);
445 // No shell, just run it
446 const bool first_arg_is_executable
= true;
447 launch_info
.SetArguments(args
, first_arg_is_executable
);
450 launch_info
.GetEnvironment() = Host::GetEnvironment();
453 launch_info
.SetWorkingDirectory(working_dir
);
454 llvm::SmallString
<64> output_file_path
;
456 if (command_output_ptr
) {
457 // Create a temporary file to get the stdout/stderr and redirect the output
458 // of the command into this file. We will later read this file if all goes
459 // well and fill the data into "command_output_ptr"
460 if (FileSpec tmpdir_file_spec
= HostInfo::GetProcessTempDir()) {
461 tmpdir_file_spec
.AppendPathComponent("lldb-shell-output.%%%%%%");
462 llvm::sys::fs::createUniqueFile(tmpdir_file_spec
.GetPath(),
465 llvm::sys::fs::createTemporaryFile("lldb-shell-output.%%%%%%", "",
470 FileSpec
output_file_spec(output_file_path
.str());
471 // Set up file descriptors.
472 launch_info
.AppendSuppressFileAction(STDIN_FILENO
, true, false);
473 if (output_file_spec
)
474 launch_info
.AppendOpenFileAction(STDOUT_FILENO
, output_file_spec
, false,
477 launch_info
.AppendSuppressFileAction(STDOUT_FILENO
, false, true);
479 if (output_file_spec
&& !hide_stderr
)
480 launch_info
.AppendDuplicateFileAction(STDOUT_FILENO
, STDERR_FILENO
);
482 launch_info
.AppendSuppressFileAction(STDERR_FILENO
, false, true);
484 std::shared_ptr
<ShellInfo
> shell_info_sp(new ShellInfo());
485 launch_info
.SetMonitorProcessCallback(
486 std::bind(MonitorShellCommand
, shell_info_sp
, std::placeholders::_1
,
487 std::placeholders::_2
, std::placeholders::_3
));
489 error
= LaunchProcess(launch_info
);
490 const lldb::pid_t pid
= launch_info
.GetProcessID();
492 if (error
.Success() && pid
== LLDB_INVALID_PROCESS_ID
)
493 error
= Status::FromErrorString("failed to get process ID");
495 if (error
.Success()) {
496 if (!shell_info_sp
->process_reaped
.WaitForValueEqualTo(true, timeout
)) {
497 error
= Status::FromErrorString(
498 "timed out waiting for shell command to complete");
500 // Kill the process since it didn't complete within the timeout specified
502 // Wait for the monitor callback to get the message
503 shell_info_sp
->process_reaped
.WaitForValueEqualTo(
504 true, std::chrono::seconds(1));
507 *status_ptr
= shell_info_sp
->status
;
510 *signo_ptr
= shell_info_sp
->signo
;
512 if (command_output_ptr
) {
513 command_output_ptr
->clear();
515 FileSystem::Instance().GetByteSize(output_file_spec
);
517 if (file_size
> command_output_ptr
->max_size()) {
518 error
= Status::FromErrorStringWithFormat(
519 "shell command output is too large to fit into a std::string");
521 WritableDataBufferSP Buffer
=
522 FileSystem::Instance().CreateWritableDataBuffer(
525 command_output_ptr
->assign(
526 reinterpret_cast<char *>(Buffer
->GetBytes()),
527 Buffer
->GetByteSize());
534 llvm::sys::fs::remove(output_file_spec
.GetPath());
538 // The functions below implement process launching for non-Apple-based
540 #if !defined(__APPLE__)
541 Status
Host::LaunchProcess(ProcessLaunchInfo
&launch_info
) {
542 std::unique_ptr
<ProcessLauncher
> delegate_launcher
;
544 delegate_launcher
.reset(new ProcessLauncherWindows());
546 delegate_launcher
.reset(new ProcessLauncherPosixFork());
548 MonitoringProcessLauncher
launcher(std::move(delegate_launcher
));
551 HostProcess process
= launcher
.LaunchProcess(launch_info
, error
);
553 // TODO(zturner): It would be better if the entire HostProcess were returned
554 // instead of writing it into this structure.
555 launch_info
.SetProcessID(process
.GetProcessId());
559 #endif // !defined(__APPLE__)
562 void Host::Kill(lldb::pid_t pid
, int signo
) { ::kill(pid
, signo
); }
566 #if !defined(__APPLE__)
567 llvm::Error
Host::OpenFileInExternalEditor(llvm::StringRef editor
,
568 const FileSpec
&file_spec
,
570 return llvm::errorCodeToError(
571 std::error_code(ENOTSUP
, std::system_category()));
574 bool Host::IsInteractiveGraphicSession() { return false; }
577 std::unique_ptr
<Connection
> Host::CreateDefaultConnection(llvm::StringRef url
) {
579 if (url
.starts_with("file://"))
580 return std::unique_ptr
<Connection
>(new ConnectionGenericFile());
582 return std::unique_ptr
<Connection
>(new ConnectionFileDescriptor());
585 #if defined(LLVM_ON_UNIX)
586 WaitStatus
WaitStatus::Decode(int wstatus
) {
587 if (WIFEXITED(wstatus
))
588 return {Exit
, uint8_t(WEXITSTATUS(wstatus
))};
589 else if (WIFSIGNALED(wstatus
))
590 return {Signal
, uint8_t(WTERMSIG(wstatus
))};
591 else if (WIFSTOPPED(wstatus
))
592 return {Stop
, uint8_t(WSTOPSIG(wstatus
))};
593 llvm_unreachable("Unknown wait status");
597 void llvm::format_provider
<WaitStatus
>::format(const WaitStatus
&WS
,
600 if (Options
== "g") {
603 case WaitStatus::Exit
:
606 case WaitStatus::Signal
:
609 case WaitStatus::Stop
:
613 OS
<< formatv("{0}{1:x-2}", type
, WS
.status
);
617 assert(Options
.empty());
620 case WaitStatus::Exit
:
621 desc
= "Exited with status";
623 case WaitStatus::Signal
:
624 desc
= "Killed by signal";
626 case WaitStatus::Stop
:
627 desc
= "Stopped by signal";
630 OS
<< desc
<< " " << int(WS
.status
);
633 uint32_t Host::FindProcesses(const ProcessInstanceInfoMatch
&match_info
,
634 ProcessInstanceInfoList
&process_infos
) {
635 return FindProcessesImpl(match_info
, process_infos
);
638 char SystemLogHandler::ID
;
640 SystemLogHandler::SystemLogHandler() {}
642 void SystemLogHandler::Emit(llvm::StringRef message
) {
643 Host::SystemLog(lldb::eSeverityInfo
, message
);