1 //===-- Host.h --------------------------------------------------*- C++ -*-===// 2 // 3 // The LLVM Compiler Infrastructure 4 // 5 // This file is distributed under the University of Illinois Open Source 6 // License. See LICENSE.TXT for details. 7 // 8 //===----------------------------------------------------------------------===// 9 10 #ifndef LLDB_HOST_HOST_H 11 #define LLDB_HOST_HOST_H 12 13 #include "lldb/Host/File.h" 14 #include "lldb/Host/HostThread.h" 15 #include "lldb/Utility/Environment.h" 16 #include "lldb/Utility/FileSpec.h" 17 #include "lldb/Utility/Timeout.h" 18 #include "lldb/lldb-private-forward.h" 19 #include "lldb/lldb-private.h" 20 #include <cerrno> 21 #include <map> 22 #include <stdarg.h> 23 #include <string> 24 #include <type_traits> 25 26 namespace lldb_private { 27 28 class FileAction; 29 class ProcessLaunchInfo; 30 31 //---------------------------------------------------------------------- 32 // Exit Type for inferior processes 33 //---------------------------------------------------------------------- 34 struct WaitStatus { 35 enum Type : uint8_t { 36 Exit, // The status represents the return code from normal 37 // program exit (i.e. WIFEXITED() was true) 38 Signal, // The status represents the signal number that caused 39 // the program to exit (i.e. WIFSIGNALED() was true) 40 Stop, // The status represents the signal number that caused the 41 // program to stop (i.e. WIFSTOPPED() was true) 42 }; 43 44 Type type; 45 uint8_t status; 46 WaitStatusWaitStatus47 WaitStatus(Type type, uint8_t status) : type(type), status(status) {} 48 49 static WaitStatus Decode(int wstatus); 50 }; 51 52 inline bool operator==(WaitStatus a, WaitStatus b) { 53 return a.type == b.type && a.status == b.status; 54 } 55 56 inline bool operator!=(WaitStatus a, WaitStatus b) { return !(a == b); } 57 58 //---------------------------------------------------------------------- 59 /// @class Host Host.h "lldb/Host/Host.h" 60 /// A class that provides host computer information. 61 /// 62 /// Host is a class that answers information about the host operating system. 63 //---------------------------------------------------------------------- 64 class Host { 65 public: 66 typedef std::function<bool( 67 lldb::pid_t pid, bool exited, 68 int signal, // Zero for no signal 69 int status)> // Exit value of process if signal is zero 70 MonitorChildProcessCallback; 71 72 //------------------------------------------------------------------ 73 /// Start monitoring a child process. 74 /// 75 /// Allows easy monitoring of child processes. \a callback will be called 76 /// when the child process exits or if it gets a signal. The callback will 77 /// only be called with signals if \a monitor_signals is \b true. \a 78 /// callback will usually be called from another thread so the callback 79 /// function must be thread safe. 80 /// 81 /// When the callback gets called, the return value indicates if monitoring 82 /// should stop. If \b true is returned from \a callback the information 83 /// will be removed. If \b false is returned then monitoring will continue. 84 /// If the child process exits, the monitoring will automatically stop after 85 /// the callback returned regardless of the callback return value. 86 /// 87 /// @param[in] callback 88 /// A function callback to call when a child receives a signal 89 /// (if \a monitor_signals is true) or a child exits. 90 /// 91 /// @param[in] pid 92 /// The process ID of a child process to monitor, -1 for all 93 /// processes. 94 /// 95 /// @param[in] monitor_signals 96 /// If \b true the callback will get called when the child 97 /// process gets a signal. If \b false, the callback will only 98 /// get called if the child process exits. 99 /// 100 /// @return 101 /// A thread handle that can be used to cancel the thread that 102 /// was spawned to monitor \a pid. 103 /// 104 /// @see static void Host::StopMonitoringChildProcess (uint32_t) 105 //------------------------------------------------------------------ 106 static HostThread 107 StartMonitoringChildProcess(const MonitorChildProcessCallback &callback, 108 lldb::pid_t pid, bool monitor_signals); 109 110 enum SystemLogType { eSystemLogWarning, eSystemLogError }; 111 112 static void SystemLog(SystemLogType type, const char *format, ...) 113 __attribute__((format(printf, 2, 3))); 114 115 static void SystemLog(SystemLogType type, const char *format, va_list args); 116 117 //------------------------------------------------------------------ 118 /// Get the process ID for the calling process. 119 /// 120 /// @return 121 /// The process ID for the current process. 122 //------------------------------------------------------------------ 123 static lldb::pid_t GetCurrentProcessID(); 124 125 static void Kill(lldb::pid_t pid, int signo); 126 127 //------------------------------------------------------------------ 128 /// Get the thread token (the one returned by ThreadCreate when the thread 129 /// was created) for the calling thread in the current process. 130 /// 131 /// @return 132 /// The thread token for the calling thread in the current process. 133 //------------------------------------------------------------------ 134 static lldb::thread_t GetCurrentThread(); 135 136 static const char *GetSignalAsCString(int signo); 137 138 //------------------------------------------------------------------ 139 /// Given an address in the current process (the process that is running the 140 /// LLDB code), return the name of the module that it comes from. This can 141 /// be useful when you need to know the path to the shared library that your 142 /// code is running in for loading resources that are relative to your 143 /// binary. 144 /// 145 /// @param[in] host_addr 146 /// The pointer to some code in the current process. 147 /// 148 /// @return 149 /// \b A file spec with the module that contains \a host_addr, 150 /// which may be invalid if \a host_addr doesn't fall into 151 /// any valid module address range. 152 //------------------------------------------------------------------ 153 static FileSpec GetModuleFileSpecForHostAddress(const void *host_addr); 154 155 //------------------------------------------------------------------ 156 /// If you have an executable that is in a bundle and want to get back to 157 /// the bundle directory from the path itself, this function will change a 158 /// path to a file within a bundle to the bundle directory itself. 159 /// 160 /// @param[in] file 161 /// A file spec that might point to a file in a bundle. 162 /// 163 /// @param[out] bundle_directory 164 /// An object will be filled in with the bundle directory for 165 /// the bundle when \b true is returned. Otherwise \a file is 166 /// left untouched and \b false is returned. 167 /// 168 /// @return 169 /// \b true if \a file was resolved in \a bundle_directory, 170 /// \b false otherwise. 171 //------------------------------------------------------------------ 172 static bool GetBundleDirectory(const FileSpec &file, 173 FileSpec &bundle_directory); 174 175 //------------------------------------------------------------------ 176 /// When executable files may live within a directory, where the directory 177 /// represents an executable bundle (like the MacOSX app bundles), then 178 /// locate the executable within the containing bundle. 179 /// 180 /// @param[in,out] file 181 /// A file spec that currently points to the bundle that will 182 /// be filled in with the executable path within the bundle 183 /// if \b true is returned. Otherwise \a file is left untouched. 184 /// 185 /// @return 186 /// \b true if \a file was resolved, \b false if this function 187 /// was not able to resolve the path. 188 //------------------------------------------------------------------ 189 static bool ResolveExecutableInBundle(FileSpec &file); 190 191 static uint32_t FindProcesses(const ProcessInstanceInfoMatch &match_info, 192 ProcessInstanceInfoList &proc_infos); 193 194 typedef std::map<lldb::pid_t, bool> TidMap; 195 typedef std::pair<lldb::pid_t, bool> TidPair; 196 static bool FindProcessThreads(const lldb::pid_t pid, TidMap &tids_to_attach); 197 198 static bool GetProcessInfo(lldb::pid_t pid, ProcessInstanceInfo &proc_info); 199 200 static const lldb::UnixSignalsSP &GetUnixSignals(); 201 202 /// Launch the process specified in launch_info. The monitoring callback in 203 /// launch_info must be set, and it will be called when the process 204 /// terminates. 205 static Status LaunchProcess(ProcessLaunchInfo &launch_info); 206 207 //------------------------------------------------------------------ 208 /// Perform expansion of the command-line for this launch info This can 209 /// potentially involve wildcard expansion 210 // environment variable replacement, and whatever other 211 // argument magic the platform defines as part of its typical 212 // user experience 213 //------------------------------------------------------------------ 214 static Status ShellExpandArguments(ProcessLaunchInfo &launch_info); 215 216 // TODO: Convert this function to take a StringRef. 217 static Status RunShellCommand( 218 const char *command, // Shouldn't be NULL 219 const FileSpec &working_dir, // Pass empty FileSpec to use the current 220 // working directory 221 int *status_ptr, // Pass NULL if you don't want the process exit status 222 int *signo_ptr, // Pass NULL if you don't want the signal that caused the 223 // process to exit 224 std::string 225 *command_output, // Pass NULL if you don't want the command output 226 const Timeout<std::micro> &timeout, bool run_in_default_shell = true); 227 228 static Status RunShellCommand( 229 const Args &args, 230 const FileSpec &working_dir, // Pass empty FileSpec to use the current 231 // working directory 232 int *status_ptr, // Pass NULL if you don't want the process exit status 233 int *signo_ptr, // Pass NULL if you don't want the signal that caused the 234 // process to exit 235 std::string 236 *command_output, // Pass NULL if you don't want the command output 237 const Timeout<std::micro> &timeout, bool run_in_default_shell = true); 238 239 static bool OpenFileInExternalEditor(const FileSpec &file_spec, 240 uint32_t line_no); 241 242 static Environment GetEnvironment(); 243 244 static std::unique_ptr<Connection> 245 CreateDefaultConnection(llvm::StringRef url); 246 }; 247 248 } // namespace lldb_private 249 250 namespace llvm { 251 template <> struct format_provider<lldb_private::WaitStatus> { 252 /// Options = "" gives a human readable description of the status Options = 253 /// "g" gives a gdb-remote protocol status (e.g., X09) 254 static void format(const lldb_private::WaitStatus &WS, raw_ostream &OS, 255 llvm::StringRef Options); 256 }; 257 } // namespace llvm 258 259 #endif // LLDB_HOST_HOST_H 260