|
|
|||
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
| [ Source navigation ] | [ Diff markup ] | [ Identifier search ] | [ general search ] |
|
This page was automatically generated by the 2.3.7 LXR engine. The LXR team |
|