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__)
66 #include "llvm/ADT/SmallString.h"
67 #include "llvm/ADT/StringSwitch.h"
68 #include "llvm/Support/Errno.h"
69 #include "llvm/Support/FileSystem.h"
78 #if defined(__APPLE__)
79 #ifndef _POSIX_SPAWN_DISABLE_ASLR
80 #define _POSIX_SPAWN_DISABLE_ASLR 0x0100
93 #if !defined(__APPLE__)
97 #if !defined(__APPLE__) && !defined(_WIN32)
102 llvm::Expected<HostThread> Host::StartMonitoringChildProcess(
104 char thread_name[256];
105 ::snprintf(thread_name,
sizeof(thread_name),
106 "<lldb.host.wait4(pid=%" PRIu64
")>", pid);
108 return ThreadLauncher::LaunchThread(thread_name, [pid, callback] {
120 int err = ::pthread_setcancelstate(PTHREAD_CANCEL_DISABLE, &m_old_state);
128 if (m_old_state != -1)
129 ::pthread_setcancelstate(m_old_state, 0);
138 #if defined(__GNUC__) && (__GNUC__ < 4 || (__GNUC__ == 4 && __GNUC_MINOR__ < 8))
139 static __thread
volatile sig_atomic_t g_usr1_called;
141 static thread_local
volatile sig_atomic_t g_usr1_called;
144 static void SigUsr1Handler(
int) { g_usr1_called = 1; }
154 ::pthread_testcancel();
169 struct sigaction sigUsr1Action;
170 memset(&sigUsr1Action, 0,
sizeof(sigUsr1Action));
171 sigUsr1Action.sa_handler = SigUsr1Handler;
172 ::sigaction(SIGUSR1, &sigUsr1Action,
nullptr);
176 log =
GetLog(LLDBLog::Process);
177 LLDB_LOG(log,
"::waitpid({0}, &status, 0)...", pid);
184 LLDB_LOG(log,
"::waitpid({0}, &status, 0) => pid = {1}, status = {2:x}", pid,
192 if (errno != EINTR) {
193 LLDB_LOG(log,
"pid = {0}, thread exiting because waitpid failed ({1})...",
194 pid, llvm::sys::StrError());
201 if (WIFEXITED(status)) {
202 exit_status = WEXITSTATUS(status);
203 }
else if (WIFSIGNALED(status)) {
204 signal = WTERMSIG(status);
207 llvm_unreachable(
"Unknown status");
217 callback(pid, signal, exit_status);
220 LLDB_LOG(
GetLog(LLDBLog::Process),
"pid = {0} thread exiting...", pid);
224 #endif // #if !defined (__APPLE__) && !defined (_WIN32)
234 const char *Host::GetSignalAsCString(
int signo) {
249 #if !defined(SIGIO) || (SIGPOLL != SIGIO)
302 #if defined(SIGWINCH)
322 #if !defined(__APPLE__) // see Host.mm
329 bool Host::ResolveExecutableInBundle(
FileSpec &file) {
return false; }
334 FileSpec Host::GetModuleFileSpecForHostAddress(
const void *host_addr) {
336 #if !defined(__ANDROID__)
338 if (::dladdr(host_addr, &info)) {
339 if (info.dli_fname) {
340 module_filespec.
SetFile(info.dli_fname, FileSpec::Style::native);
341 FileSystem::Instance().Resolve(module_filespec);
345 return module_filespec;
350 #if !defined(__linux__)
370 shell_info->pid = pid;
371 shell_info->signo = signo;
372 shell_info->status = status;
378 Status Host::RunShellCommand(llvm::StringRef command,
379 const FileSpec &working_dir,
int *status_ptr,
382 bool run_in_shell,
bool hide_stderr) {
383 return RunShellCommand(llvm::StringRef(),
Args(command), working_dir,
384 status_ptr, signo_ptr, command_output_ptr, timeout,
385 run_in_shell, hide_stderr);
388 Status Host::RunShellCommand(llvm::StringRef shell_path,
389 llvm::StringRef command,
390 const FileSpec &working_dir,
int *status_ptr,
393 bool run_in_shell,
bool hide_stderr) {
394 return RunShellCommand(shell_path,
Args(command), working_dir, status_ptr,
395 signo_ptr, command_output_ptr, timeout, run_in_shell,
400 int *status_ptr,
int *signo_ptr,
403 bool run_in_shell,
bool hide_stderr) {
404 return RunShellCommand(llvm::StringRef(), args, working_dir, status_ptr,
405 signo_ptr, command_output_ptr, timeout, run_in_shell,
409 Status Host::RunShellCommand(llvm::StringRef shell_path,
const Args &args,
410 const FileSpec &working_dir,
int *status_ptr,
413 bool run_in_shell,
bool hide_stderr) {
419 FileSpec shell = HostInfo::GetDefaultShell();
420 if (!shell_path.empty())
425 const bool will_debug =
false;
426 const bool first_arg_is_full_shell_command =
false;
428 error, will_debug, first_arg_is_full_shell_command, 0);
431 const bool first_arg_is_executable =
true;
432 launch_info.
SetArguments(args, first_arg_is_executable);
439 llvm::SmallString<64> output_file_path;
441 if (command_output_ptr) {
445 if (
FileSpec tmpdir_file_spec = HostInfo::GetProcessTempDir()) {
446 tmpdir_file_spec.AppendPathComponent(
"lldb-shell-output.%%%%%%");
447 llvm::sys::fs::createUniqueFile(tmpdir_file_spec.GetPath(),
450 llvm::sys::fs::createTemporaryFile(
"lldb-shell-output.%%%%%%",
"",
455 FileSpec output_file_spec(output_file_path.str());
458 if (output_file_spec)
464 if (output_file_spec && !hide_stderr)
469 std::shared_ptr<ShellInfo> shell_info_sp(
new ShellInfo());
472 std::placeholders::_2, std::placeholders::_3));
474 error = LaunchProcess(launch_info);
478 error.SetErrorString(
"failed to get process ID");
480 if (
error.Success()) {
481 if (!shell_info_sp->process_reaped.WaitForValueEqualTo(
true, timeout)) {
482 error.SetErrorString(
"timed out waiting for shell command to complete");
487 shell_info_sp->process_reaped.WaitForValueEqualTo(
488 true, std::chrono::seconds(1));
491 *status_ptr = shell_info_sp->status;
494 *signo_ptr = shell_info_sp->signo;
496 if (command_output_ptr) {
497 command_output_ptr->clear();
499 FileSystem::Instance().GetByteSize(output_file_spec);
501 if (file_size > command_output_ptr->max_size()) {
502 error.SetErrorStringWithFormat(
503 "shell command output is too large to fit into a std::string");
505 WritableDataBufferSP Buffer =
506 FileSystem::Instance().CreateWritableDataBuffer(
509 command_output_ptr->assign(
510 reinterpret_cast<char *
>(Buffer->GetBytes()),
511 Buffer->GetByteSize());
518 llvm::sys::fs::remove(output_file_spec.
GetPath());
524 #if !defined(__APPLE__)
526 std::unique_ptr<ProcessLauncher> delegate_launcher;
543 #endif // !defined(__APPLE__)
546 void Host::Kill(
lldb::pid_t pid,
int signo) { ::kill(pid, signo); }
550 #if !defined(__APPLE__)
551 bool Host::OpenFileInExternalEditor(
const FileSpec &file_spec,
556 bool Host::IsInteractiveGraphicSession() {
return false; }
559 std::unique_ptr<Connection> Host::CreateDefaultConnection(llvm::StringRef url) {
561 if (url.startswith(
"file://"))
567 #if defined(LLVM_ON_UNIX)
569 if (WIFEXITED(wstatus))
570 return {Exit, uint8_t(WEXITSTATUS(wstatus))};
571 else if (WIFSIGNALED(wstatus))
572 return {Signal, uint8_t(WTERMSIG(wstatus))};
573 else if (WIFSTOPPED(wstatus))
574 return {Stop, uint8_t(WSTOPSIG(wstatus))};
575 llvm_unreachable(
"Unknown wait status");
579 void llvm::format_provider<WaitStatus>::format(
const WaitStatus &WS,
585 case WaitStatus::Exit:
588 case WaitStatus::Signal:
591 case WaitStatus::Stop:
595 OS << formatv(
"{0}{1:x-2}", type, WS.
status);
602 case WaitStatus::Exit:
603 desc =
"Exited with status";
605 case WaitStatus::Signal:
606 desc =
"Killed by signal";
608 case WaitStatus::Stop:
609 desc =
"Stopped by signal";
612 OS << desc <<
" " << int(WS.
status);
618 if (llvm::Optional<ProcessInstanceInfoList> infos =
620 process_infos = *infos;
621 return process_infos.size();
624 uint32_t result = FindProcessesImpl(match_info, process_infos);
628 .GetNewProcessInfoRecorder()
629 ->Record(process_infos);
637 SystemLogHandler::SystemLogHandler() {}
639 void SystemLogHandler::Emit(llvm::StringRef
message) {