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