| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283 |
- //===-- 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/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<bool(
- lldb::pid_t pid, bool exited,
- 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 gets a signal. The callback will
- /// only be called with signals if \a monitor_signals is \b true. \a
- /// callback will usually be called from another thread so the callback
- /// function must be thread safe.
- ///
- /// When the callback gets called, the return value indicates if monitoring
- /// should stop. If \b true is returned from \a callback the information
- /// will be removed. If \b false is returned then monitoring will continue.
- /// If the child process exits, the monitoring will automatically stop after
- /// the callback returned regardless of the callback return value.
- ///
- /// \param[in] callback
- /// A function callback to call when a child receives a signal
- /// (if \a monitor_signals is true) or a child exits.
- ///
- /// \param[in] pid
- /// The process ID of a child process to monitor, -1 for all
- /// processes.
- ///
- /// \param[in] monitor_signals
- /// If \b true the callback will get called when the child
- /// process gets a signal. If \b false, the callback will only
- /// get called if the child process exits.
- ///
- /// \return
- /// A thread handle that can be used to cancel the thread that
- /// was spawned to monitor \a pid.
- ///
- /// \see static void Host::StopMonitoringChildProcess (uint32_t)
- static llvm::Expected<HostThread>
- StartMonitoringChildProcess(const MonitorChildProcessCallback &callback,
- lldb::pid_t pid, bool monitor_signals);
- enum SystemLogType { eSystemLogWarning, eSystemLogError };
- static void SystemLog(SystemLogType type, const char *format, ...)
- __attribute__((format(printf, 2, 3)));
- static void SystemLog(SystemLogType type, const char *format, va_list args);
- /// 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 bool OpenFileInExternalEditor(const FileSpec &file_spec,
- uint32_t line_no);
- static Environment GetEnvironment();
- static std::unique_ptr<Connection>
- CreateDefaultConnection(llvm::StringRef url);
- protected:
- static uint32_t FindProcessesImpl(const ProcessInstanceInfoMatch &match_info,
- ProcessInstanceInfoList &proc_infos);
- };
- } // 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
|