Back to home page

EIC code displayed by LXR

 
 

    


File indexing completed on 2026-05-10 08:42:49

0001 //===-- Host.h --------------------------------------------------*- C++ -*-===//
0002 //
0003 // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
0004 // See https://llvm.org/LICENSE.txt for license information.
0005 // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
0006 //
0007 //===----------------------------------------------------------------------===//
0008 
0009 #ifndef LLDB_HOST_HOST_H
0010 #define LLDB_HOST_HOST_H
0011 
0012 #include "lldb/Host/File.h"
0013 #include "lldb/Host/HostThread.h"
0014 #include "lldb/Utility/Environment.h"
0015 #include "lldb/Utility/FileSpec.h"
0016 #include "lldb/Utility/Log.h"
0017 #include "lldb/Utility/Timeout.h"
0018 #include "lldb/lldb-private-forward.h"
0019 #include "lldb/lldb-private.h"
0020 #include <cerrno>
0021 #include <cstdarg>
0022 #include <map>
0023 #include <string>
0024 #include <type_traits>
0025 
0026 namespace lldb_private {
0027 
0028 class FileAction;
0029 class ProcessLaunchInfo;
0030 class ProcessInstanceInfo;
0031 class ProcessInstanceInfoMatch;
0032 typedef std::vector<ProcessInstanceInfo> ProcessInstanceInfoList;
0033 
0034 // System log category and channel. This log channel is always enabled and
0035 // therefore is supposed to be used sparsely. Use this log channel to log
0036 // critical information that is expected to be relevant to the majority of bug
0037 // reports.
0038 enum class SystemLog : Log::MaskType {
0039   System = Log::ChannelFlag<0>,
0040   LLVM_MARK_AS_BITMASK_ENUM(System)
0041 };
0042 
0043 LLVM_ENABLE_BITMASK_ENUMS_IN_NAMESPACE();
0044 
0045 class LogChannelSystem {
0046 public:
0047   static void Initialize();
0048   static void Terminate();
0049 };
0050 
0051 template <> Log::Channel &LogChannelFor<SystemLog>();
0052 
0053 // Exit Type for inferior processes
0054 struct WaitStatus {
0055   enum Type : uint8_t {
0056     Exit,   // The status represents the return code from normal
0057             // program exit (i.e. WIFEXITED() was true)
0058     Signal, // The status represents the signal number that caused
0059             // the program to exit (i.e. WIFSIGNALED() was true)
0060     Stop,   // The status represents the signal number that caused the
0061             // program to stop (i.e. WIFSTOPPED() was true)
0062   };
0063 
0064   Type type;
0065   uint8_t status;
0066 
0067   WaitStatus(Type type, uint8_t status) : type(type), status(status) {}
0068 
0069   static WaitStatus Decode(int wstatus);
0070 };
0071 
0072 inline bool operator==(WaitStatus a, WaitStatus b) {
0073   return a.type == b.type && a.status == b.status;
0074 }
0075 
0076 inline bool operator!=(WaitStatus a, WaitStatus b) { return !(a == b); }
0077 
0078 /// \class Host Host.h "lldb/Host/Host.h"
0079 /// A class that provides host computer information.
0080 ///
0081 /// Host is a class that answers information about the host operating system.
0082 class Host {
0083 public:
0084   typedef std::function<void(lldb::pid_t pid,
0085                              int signal,  // Zero for no signal
0086                              int status)> // Exit value of process if signal is
0087                                           // zero
0088       MonitorChildProcessCallback;
0089 
0090   /// Start monitoring a child process.
0091   ///
0092   /// Allows easy monitoring of child processes. \a callback will be called
0093   /// when the child process exits or if it dies from a signal.
0094   ///
0095   /// \param[in] callback
0096   ///     A function callback to call when a child receives a signal
0097   ///     or exits.
0098   ///
0099   /// \param[in] pid
0100   ///     The process ID of a child process to monitor.
0101   ///
0102   /// \return
0103   ///     A thread handle that can be used to cancel the thread that
0104   ///     was spawned to monitor \a pid.
0105   static llvm::Expected<HostThread>
0106   StartMonitoringChildProcess(const MonitorChildProcessCallback &callback,
0107                               lldb::pid_t pid);
0108 
0109   /// Emit the given message to the operating system log.
0110   static void SystemLog(lldb::Severity severity, llvm::StringRef message);
0111 
0112   /// Get the process ID for the calling process.
0113   ///
0114   /// \return
0115   ///     The process ID for the current process.
0116   static lldb::pid_t GetCurrentProcessID();
0117 
0118   static void Kill(lldb::pid_t pid, int signo);
0119 
0120   /// Get the thread token (the one returned by ThreadCreate when the thread
0121   /// was created) for the calling thread in the current process.
0122   ///
0123   /// \return
0124   ///     The thread token for the calling thread in the current process.
0125   static lldb::thread_t GetCurrentThread();
0126 
0127   static const char *GetSignalAsCString(int signo);
0128 
0129   /// Given an address in the current process (the process that is running the
0130   /// LLDB code), return the name of the module that it comes from. This can
0131   /// be useful when you need to know the path to the shared library that your
0132   /// code is running in for loading resources that are relative to your
0133   /// binary.
0134   ///
0135   /// \param[in] host_addr
0136   ///     The pointer to some code in the current process.
0137   ///
0138   /// \return
0139   ///     \b A file spec with the module that contains \a host_addr,
0140   ///     which may be invalid if \a host_addr doesn't fall into
0141   ///     any valid module address range.
0142   static FileSpec GetModuleFileSpecForHostAddress(const void *host_addr);
0143 
0144   /// If you have an executable that is in a bundle and want to get back to
0145   /// the bundle directory from the path itself, this function will change a
0146   /// path to a file within a bundle to the bundle directory itself.
0147   ///
0148   /// \param[in] file
0149   ///     A file spec that might point to a file in a bundle.
0150   ///
0151   /// \param[out] bundle_directory
0152   ///     An object will be filled in with the bundle directory for
0153   ///     the bundle when \b true is returned. Otherwise \a file is
0154   ///     left untouched and \b false is returned.
0155   ///
0156   /// \return
0157   ///     \b true if \a file was resolved in \a bundle_directory,
0158   ///     \b false otherwise.
0159   static bool GetBundleDirectory(const FileSpec &file,
0160                                  FileSpec &bundle_directory);
0161 
0162   /// When executable files may live within a directory, where the directory
0163   /// represents an executable bundle (like the MacOSX app bundles), then
0164   /// locate the executable within the containing bundle.
0165   ///
0166   /// \param[in,out] file
0167   ///     A file spec that currently points to the bundle that will
0168   ///     be filled in with the executable path within the bundle
0169   ///     if \b true is returned. Otherwise \a file is left untouched.
0170   ///
0171   /// \return
0172   ///     \b true if \a file was resolved, \b false if this function
0173   ///     was not able to resolve the path.
0174   static bool ResolveExecutableInBundle(FileSpec &file);
0175 
0176   static uint32_t FindProcesses(const ProcessInstanceInfoMatch &match_info,
0177                                 ProcessInstanceInfoList &proc_infos);
0178 
0179   typedef std::map<lldb::pid_t, bool> TidMap;
0180   typedef std::pair<lldb::pid_t, bool> TidPair;
0181   static bool FindProcessThreads(const lldb::pid_t pid, TidMap &tids_to_attach);
0182 
0183   static bool GetProcessInfo(lldb::pid_t pid, ProcessInstanceInfo &proc_info);
0184 
0185   /// Launch the process specified in launch_info. The monitoring callback in
0186   /// launch_info must be set, and it will be called when the process
0187   /// terminates.
0188   static Status LaunchProcess(ProcessLaunchInfo &launch_info);
0189 
0190   /// Perform expansion of the command-line for this launch info This can
0191   /// potentially involve wildcard expansion
0192   /// environment variable replacement, and whatever other
0193   /// argument magic the platform defines as part of its typical
0194   /// user experience
0195   static Status ShellExpandArguments(ProcessLaunchInfo &launch_info);
0196 
0197   /// Run a shell command.
0198   /// \arg command  shouldn't be empty
0199   /// \arg working_dir Pass empty FileSpec to use the current working directory
0200   /// \arg status_ptr  Pass NULL if you don't want the process exit status
0201   /// \arg signo_ptr   Pass NULL if you don't want the signal that caused the
0202   ///                  process to exit
0203   /// \arg command_output  Pass NULL if you don't want the command output
0204   /// \arg hide_stderr if this is false, redirect stderr to stdout
0205   static Status RunShellCommand(llvm::StringRef command,
0206                                 const FileSpec &working_dir, int *status_ptr,
0207                                 int *signo_ptr, std::string *command_output,
0208                                 const Timeout<std::micro> &timeout,
0209                                 bool run_in_shell = true,
0210                                 bool hide_stderr = false);
0211 
0212   /// Run a shell command.
0213   /// \arg shell  Pass an empty string if you want to use the default shell
0214   /// interpreter \arg command \arg working_dir  Pass empty FileSpec to use the
0215   /// current working directory \arg status_ptr   Pass NULL if you don't want
0216   /// the process exit status \arg signo_ptr    Pass NULL if you don't want the
0217   /// signal that caused
0218   ///                   the process to exit
0219   /// \arg command_output  Pass NULL if you don't want the command output
0220   /// \arg hide_stderr  If this is \b false, redirect stderr to stdout
0221   static Status RunShellCommand(llvm::StringRef shell, llvm::StringRef command,
0222                                 const FileSpec &working_dir, int *status_ptr,
0223                                 int *signo_ptr, std::string *command_output,
0224                                 const Timeout<std::micro> &timeout,
0225                                 bool run_in_shell = true,
0226                                 bool hide_stderr = false);
0227 
0228   /// Run a shell command.
0229   /// \arg working_dir Pass empty FileSpec to use the current working directory
0230   /// \arg status_ptr  Pass NULL if you don't want the process exit status
0231   /// \arg signo_ptr   Pass NULL if you don't want the signal that caused the
0232   ///                  process to exit
0233   /// \arg command_output  Pass NULL if you don't want the command output
0234   /// \arg hide_stderr if this is false, redirect stderr to stdout
0235   static Status RunShellCommand(const Args &args, const FileSpec &working_dir,
0236                                 int *status_ptr, int *signo_ptr,
0237                                 std::string *command_output,
0238                                 const Timeout<std::micro> &timeout,
0239                                 bool run_in_shell = true,
0240                                 bool hide_stderr = false);
0241 
0242   /// Run a shell command.
0243   /// \arg shell            Pass an empty string if you want to use the default
0244   /// shell interpreter \arg command \arg working_dir Pass empty FileSpec to use
0245   /// the current working directory \arg status_ptr    Pass NULL if you don't
0246   /// want the process exit status \arg signo_ptr     Pass NULL if you don't
0247   /// want the signal that caused the
0248   ///               process to exit
0249   /// \arg command_output  Pass NULL if you don't want the command output
0250   /// \arg hide_stderr If this is \b false, redirect stderr to stdout
0251   static Status RunShellCommand(llvm::StringRef shell, const Args &args,
0252                                 const FileSpec &working_dir, int *status_ptr,
0253                                 int *signo_ptr, std::string *command_output,
0254                                 const Timeout<std::micro> &timeout,
0255                                 bool run_in_shell = true,
0256                                 bool hide_stderr = false);
0257 
0258   static llvm::Error OpenFileInExternalEditor(llvm::StringRef editor,
0259                                               const FileSpec &file_spec,
0260                                               uint32_t line_no);
0261 
0262   /// Check if we're running in an interactive graphical session.
0263   ///
0264   /// \return
0265   ///     True if we're running in an interactive graphical session. False if
0266   ///     we're not or don't know.
0267   static bool IsInteractiveGraphicSession();
0268 
0269   static Environment GetEnvironment();
0270 
0271   static std::unique_ptr<Connection>
0272   CreateDefaultConnection(llvm::StringRef url);
0273 
0274 protected:
0275   static uint32_t FindProcessesImpl(const ProcessInstanceInfoMatch &match_info,
0276                                     ProcessInstanceInfoList &proc_infos);
0277 };
0278 
0279 /// Log handler that emits log messages to the operating system log.
0280 class SystemLogHandler : public LogHandler {
0281 public:
0282   SystemLogHandler();
0283   void Emit(llvm::StringRef message) override;
0284 
0285   bool isA(const void *ClassID) const override { return ClassID == &ID; }
0286   static bool classof(const LogHandler *obj) { return obj->isA(&ID); }
0287 
0288 private:
0289   static char ID;
0290 };
0291 
0292 } // namespace lldb_private
0293 
0294 namespace llvm {
0295 template <> struct format_provider<lldb_private::WaitStatus> {
0296   /// Options = "" gives a human readable description of the status Options =
0297   /// "g" gives a gdb-remote protocol status (e.g., X09)
0298   static void format(const lldb_private::WaitStatus &WS, raw_ostream &OS,
0299                      llvm::StringRef Options);
0300 };
0301 } // namespace llvm
0302 
0303 #endif // LLDB_HOST_HOST_H