clang 20.0.0 (based on r547379) from build 12806354. Bug: http://b/379133546 Test: N/A Change-Id: I2eb8938af55d809de674be63cb30cf27e801862b Upstream-Commit: ad834e67b1105d15ef907f6255d4c96e8e733f57
285 lines
12 KiB
C++
285 lines
12 KiB
C++
//===-- Host.h --------------------------------------------------*- C++ -*-===//
|
|
//
|
|
// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
|
|
// See https://llvm.org/LICENSE.txt for license information.
|
|
// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
|
|
//
|
|
//===----------------------------------------------------------------------===//
|
|
|
|
#ifndef LLDB_HOST_HOST_H
|
|
#define LLDB_HOST_HOST_H
|
|
|
|
#include "lldb/Host/File.h"
|
|
#include "lldb/Host/HostThread.h"
|
|
#include "lldb/Utility/Environment.h"
|
|
#include "lldb/Utility/FileSpec.h"
|
|
#include "lldb/Utility/Log.h"
|
|
#include "lldb/Utility/Timeout.h"
|
|
#include "lldb/lldb-private-forward.h"
|
|
#include "lldb/lldb-private.h"
|
|
#include <cerrno>
|
|
#include <cstdarg>
|
|
#include <map>
|
|
#include <string>
|
|
#include <type_traits>
|
|
|
|
namespace lldb_private {
|
|
|
|
class FileAction;
|
|
class ProcessLaunchInfo;
|
|
class ProcessInstanceInfo;
|
|
class ProcessInstanceInfoMatch;
|
|
typedef std::vector<ProcessInstanceInfo> ProcessInstanceInfoList;
|
|
|
|
// Exit Type for inferior processes
|
|
struct WaitStatus {
|
|
enum Type : uint8_t {
|
|
Exit, // The status represents the return code from normal
|
|
// program exit (i.e. WIFEXITED() was true)
|
|
Signal, // The status represents the signal number that caused
|
|
// the program to exit (i.e. WIFSIGNALED() was true)
|
|
Stop, // The status represents the signal number that caused the
|
|
// program to stop (i.e. WIFSTOPPED() was true)
|
|
};
|
|
|
|
Type type;
|
|
uint8_t status;
|
|
|
|
WaitStatus(Type type, uint8_t status) : type(type), status(status) {}
|
|
|
|
static WaitStatus Decode(int wstatus);
|
|
};
|
|
|
|
inline bool operator==(WaitStatus a, WaitStatus b) {
|
|
return a.type == b.type && a.status == b.status;
|
|
}
|
|
|
|
inline bool operator!=(WaitStatus a, WaitStatus b) { return !(a == b); }
|
|
|
|
/// \class Host Host.h "lldb/Host/Host.h"
|
|
/// A class that provides host computer information.
|
|
///
|
|
/// Host is a class that answers information about the host operating system.
|
|
class Host {
|
|
public:
|
|
typedef std::function<void(lldb::pid_t pid,
|
|
int signal, // Zero for no signal
|
|
int status)> // Exit value of process if signal is
|
|
// zero
|
|
MonitorChildProcessCallback;
|
|
|
|
/// Start monitoring a child process.
|
|
///
|
|
/// Allows easy monitoring of child processes. \a callback will be called
|
|
/// when the child process exits or if it dies from a signal.
|
|
///
|
|
/// \param[in] callback
|
|
/// A function callback to call when a child receives a signal
|
|
/// or exits.
|
|
///
|
|
/// \param[in] pid
|
|
/// The process ID of a child process to monitor.
|
|
///
|
|
/// \return
|
|
/// A thread handle that can be used to cancel the thread that
|
|
/// was spawned to monitor \a pid.
|
|
static llvm::Expected<HostThread>
|
|
StartMonitoringChildProcess(const MonitorChildProcessCallback &callback,
|
|
lldb::pid_t pid);
|
|
|
|
/// Emit the given message to the operating system log.
|
|
static void SystemLog(lldb::Severity severity, llvm::StringRef message);
|
|
|
|
/// Get the process ID for the calling process.
|
|
///
|
|
/// \return
|
|
/// The process ID for the current process.
|
|
static lldb::pid_t GetCurrentProcessID();
|
|
|
|
static void Kill(lldb::pid_t pid, int signo);
|
|
|
|
/// Get the thread token (the one returned by ThreadCreate when the thread
|
|
/// was created) for the calling thread in the current process.
|
|
///
|
|
/// \return
|
|
/// The thread token for the calling thread in the current process.
|
|
static lldb::thread_t GetCurrentThread();
|
|
|
|
static const char *GetSignalAsCString(int signo);
|
|
|
|
/// Given an address in the current process (the process that is running the
|
|
/// LLDB code), return the name of the module that it comes from. This can
|
|
/// be useful when you need to know the path to the shared library that your
|
|
/// code is running in for loading resources that are relative to your
|
|
/// binary.
|
|
///
|
|
/// \param[in] host_addr
|
|
/// The pointer to some code in the current process.
|
|
///
|
|
/// \return
|
|
/// \b A file spec with the module that contains \a host_addr,
|
|
/// which may be invalid if \a host_addr doesn't fall into
|
|
/// any valid module address range.
|
|
static FileSpec GetModuleFileSpecForHostAddress(const void *host_addr);
|
|
|
|
/// If you have an executable that is in a bundle and want to get back to
|
|
/// the bundle directory from the path itself, this function will change a
|
|
/// path to a file within a bundle to the bundle directory itself.
|
|
///
|
|
/// \param[in] file
|
|
/// A file spec that might point to a file in a bundle.
|
|
///
|
|
/// \param[out] bundle_directory
|
|
/// An object will be filled in with the bundle directory for
|
|
/// the bundle when \b true is returned. Otherwise \a file is
|
|
/// left untouched and \b false is returned.
|
|
///
|
|
/// \return
|
|
/// \b true if \a file was resolved in \a bundle_directory,
|
|
/// \b false otherwise.
|
|
static bool GetBundleDirectory(const FileSpec &file,
|
|
FileSpec &bundle_directory);
|
|
|
|
/// When executable files may live within a directory, where the directory
|
|
/// represents an executable bundle (like the MacOSX app bundles), then
|
|
/// locate the executable within the containing bundle.
|
|
///
|
|
/// \param[in,out] file
|
|
/// A file spec that currently points to the bundle that will
|
|
/// be filled in with the executable path within the bundle
|
|
/// if \b true is returned. Otherwise \a file is left untouched.
|
|
///
|
|
/// \return
|
|
/// \b true if \a file was resolved, \b false if this function
|
|
/// was not able to resolve the path.
|
|
static bool ResolveExecutableInBundle(FileSpec &file);
|
|
|
|
static uint32_t FindProcesses(const ProcessInstanceInfoMatch &match_info,
|
|
ProcessInstanceInfoList &proc_infos);
|
|
|
|
typedef std::map<lldb::pid_t, bool> TidMap;
|
|
typedef std::pair<lldb::pid_t, bool> TidPair;
|
|
static bool FindProcessThreads(const lldb::pid_t pid, TidMap &tids_to_attach);
|
|
|
|
static bool GetProcessInfo(lldb::pid_t pid, ProcessInstanceInfo &proc_info);
|
|
|
|
/// Launch the process specified in launch_info. The monitoring callback in
|
|
/// launch_info must be set, and it will be called when the process
|
|
/// terminates.
|
|
static Status LaunchProcess(ProcessLaunchInfo &launch_info);
|
|
|
|
/// Perform expansion of the command-line for this launch info This can
|
|
/// potentially involve wildcard expansion
|
|
/// environment variable replacement, and whatever other
|
|
/// argument magic the platform defines as part of its typical
|
|
/// user experience
|
|
static Status ShellExpandArguments(ProcessLaunchInfo &launch_info);
|
|
|
|
/// Run a shell command.
|
|
/// \arg command shouldn't be empty
|
|
/// \arg working_dir Pass empty FileSpec to use the current working directory
|
|
/// \arg status_ptr Pass NULL if you don't want the process exit status
|
|
/// \arg signo_ptr Pass NULL if you don't want the signal that caused the
|
|
/// process to exit
|
|
/// \arg command_output Pass NULL if you don't want the command output
|
|
/// \arg hide_stderr if this is false, redirect stderr to stdout
|
|
static Status RunShellCommand(llvm::StringRef command,
|
|
const FileSpec &working_dir, int *status_ptr,
|
|
int *signo_ptr, std::string *command_output,
|
|
const Timeout<std::micro> &timeout,
|
|
bool run_in_shell = true,
|
|
bool hide_stderr = false);
|
|
|
|
/// Run a shell command.
|
|
/// \arg shell Pass an empty string if you want to use the default shell
|
|
/// interpreter \arg command \arg working_dir Pass empty FileSpec to use the
|
|
/// current working directory \arg status_ptr Pass NULL if you don't want
|
|
/// the process exit status \arg signo_ptr Pass NULL if you don't want the
|
|
/// signal that caused
|
|
/// the process to exit
|
|
/// \arg command_output Pass NULL if you don't want the command output
|
|
/// \arg hide_stderr If this is \b false, redirect stderr to stdout
|
|
static Status RunShellCommand(llvm::StringRef shell, llvm::StringRef command,
|
|
const FileSpec &working_dir, int *status_ptr,
|
|
int *signo_ptr, std::string *command_output,
|
|
const Timeout<std::micro> &timeout,
|
|
bool run_in_shell = true,
|
|
bool hide_stderr = false);
|
|
|
|
/// Run a shell command.
|
|
/// \arg working_dir Pass empty FileSpec to use the current working directory
|
|
/// \arg status_ptr Pass NULL if you don't want the process exit status
|
|
/// \arg signo_ptr Pass NULL if you don't want the signal that caused the
|
|
/// process to exit
|
|
/// \arg command_output Pass NULL if you don't want the command output
|
|
/// \arg hide_stderr if this is false, redirect stderr to stdout
|
|
static Status RunShellCommand(const Args &args, const FileSpec &working_dir,
|
|
int *status_ptr, int *signo_ptr,
|
|
std::string *command_output,
|
|
const Timeout<std::micro> &timeout,
|
|
bool run_in_shell = true,
|
|
bool hide_stderr = false);
|
|
|
|
/// Run a shell command.
|
|
/// \arg shell Pass an empty string if you want to use the default
|
|
/// shell interpreter \arg command \arg working_dir Pass empty FileSpec to use
|
|
/// the current working directory \arg status_ptr Pass NULL if you don't
|
|
/// want the process exit status \arg signo_ptr Pass NULL if you don't
|
|
/// want the signal that caused the
|
|
/// process to exit
|
|
/// \arg command_output Pass NULL if you don't want the command output
|
|
/// \arg hide_stderr If this is \b false, redirect stderr to stdout
|
|
static Status RunShellCommand(llvm::StringRef shell, const Args &args,
|
|
const FileSpec &working_dir, int *status_ptr,
|
|
int *signo_ptr, std::string *command_output,
|
|
const Timeout<std::micro> &timeout,
|
|
bool run_in_shell = true,
|
|
bool hide_stderr = false);
|
|
|
|
static llvm::Error OpenFileInExternalEditor(llvm::StringRef editor,
|
|
const FileSpec &file_spec,
|
|
uint32_t line_no);
|
|
|
|
/// Check if we're running in an interactive graphical session.
|
|
///
|
|
/// \return
|
|
/// True if we're running in an interactive graphical session. False if
|
|
/// we're not or don't know.
|
|
static bool IsInteractiveGraphicSession();
|
|
|
|
static Environment GetEnvironment();
|
|
|
|
static std::unique_ptr<Connection>
|
|
CreateDefaultConnection(llvm::StringRef url);
|
|
|
|
protected:
|
|
static uint32_t FindProcessesImpl(const ProcessInstanceInfoMatch &match_info,
|
|
ProcessInstanceInfoList &proc_infos);
|
|
};
|
|
|
|
/// Log handler that emits log messages to the operating system log.
|
|
class SystemLogHandler : public LogHandler {
|
|
public:
|
|
SystemLogHandler();
|
|
void Emit(llvm::StringRef message) override;
|
|
|
|
bool isA(const void *ClassID) const override { return ClassID == &ID; }
|
|
static bool classof(const LogHandler *obj) { return obj->isA(&ID); }
|
|
|
|
private:
|
|
static char ID;
|
|
};
|
|
|
|
} // namespace lldb_private
|
|
|
|
namespace llvm {
|
|
template <> struct format_provider<lldb_private::WaitStatus> {
|
|
/// Options = "" gives a human readable description of the status Options =
|
|
/// "g" gives a gdb-remote protocol status (e.g., X09)
|
|
static void format(const lldb_private::WaitStatus &WS, raw_ostream &OS,
|
|
llvm::StringRef Options);
|
|
};
|
|
} // namespace llvm
|
|
|
|
#endif // LLDB_HOST_HOST_H
|