LLDB mainline
Host.h
Go to the documentation of this file.
1//===-- Host.h --------------------------------------------------*- C++ -*-===//
2//
3// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
4// See https://llvm.org/LICENSE.txt for license information.
5// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
6//
7//===----------------------------------------------------------------------===//
8
9#ifndef LLDB_HOST_HOST_H
10#define LLDB_HOST_HOST_H
11
12#include "lldb/Host/File.h"
16#include "lldb/Utility/Log.h"
19#include "lldb/lldb-private.h"
20#include <cerrno>
21#include <cstdarg>
22#include <map>
23#include <string>
24#include <type_traits>
25
26namespace lldb_private {
27
28class FileAction;
32typedef std::vector<ProcessInstanceInfo> ProcessInstanceInfoList;
33
34// System log category and channel. This log channel is always enabled and
35// therefore is supposed to be used sparsely. Use this log channel to log
36// critical information that is expected to be relevant to the majority of bug
37// reports.
42
44
46public:
47 static void Initialize();
48 static void Terminate();
49};
50
52
53// Exit Type for inferior processes
54struct WaitStatus {
55 enum Type : uint8_t {
56 Exit, // The status represents the return code from normal
57 // program exit (i.e. WIFEXITED() was true)
58 Signal, // The status represents the signal number that caused
59 // the program to exit (i.e. WIFSIGNALED() was true)
60 Stop, // The status represents the signal number that caused the
61 // program to stop (i.e. WIFSTOPPED() was true)
62 };
63
65 uint8_t status;
66
68
69 static WaitStatus Decode(int wstatus);
70};
71
72inline bool operator==(WaitStatus a, WaitStatus b) {
73 return a.type == b.type && a.status == b.status;
74}
75
76inline bool operator!=(WaitStatus a, WaitStatus b) { return !(a == b); }
77
78/// \class Host Host.h "lldb/Host/Host.h"
79/// A class that provides host computer information.
80///
81/// Host is a class that answers information about the host operating system.
82class Host {
83public:
84 typedef std::function<void(lldb::pid_t pid,
85 int signal, // Zero for no signal
86 int status)> // Exit value of process if signal is
87 // zero
89
90 /// Start monitoring a child process.
91 ///
92 /// Allows easy monitoring of child processes. \a callback will be called
93 /// when the child process exits or if it dies from a signal.
94 ///
95 /// \param[in] callback
96 /// A function callback to call when a child receives a signal
97 /// or exits.
98 ///
99 /// \param[in] pid
100 /// The process ID of a child process to monitor.
101 ///
102 /// \return
103 /// A thread handle that can be used to cancel the thread that
104 /// was spawned to monitor \a pid.
105 static llvm::Expected<HostThread>
107 lldb::pid_t pid);
108
109 /// Emit the given message to the operating system log.
110 static void SystemLog(lldb::Severity severity, llvm::StringRef message);
111
112 /// Get the process ID for the calling process.
113 ///
114 /// \return
115 /// The process ID for the current process.
117
118 static void Kill(lldb::pid_t pid, int signo);
119
120 /// Get the thread token (the one returned by ThreadCreate when the thread
121 /// was created) for the calling thread in the current process.
122 ///
123 /// \return
124 /// The thread token for the calling thread in the current process.
126
127 static const char *GetSignalAsCString(int signo);
128
129 /// Given an address in the current process (the process that is running the
130 /// LLDB code), return the name of the module that it comes from. This can
131 /// be useful when you need to know the path to the shared library that your
132 /// code is running in for loading resources that are relative to your
133 /// binary.
134 ///
135 /// \param[in] host_addr
136 /// The pointer to some code in the current process.
137 ///
138 /// \return
139 /// \b A file spec with the module that contains \a host_addr,
140 /// which may be invalid if \a host_addr doesn't fall into
141 /// any valid module address range.
142 static FileSpec GetModuleFileSpecForHostAddress(const void *host_addr);
143
144 /// If you have an executable that is in a bundle and want to get back to
145 /// the bundle directory from the path itself, this function will change a
146 /// path to a file within a bundle to the bundle directory itself.
147 ///
148 /// \param[in] file
149 /// A file spec that might point to a file in a bundle.
150 ///
151 /// \param[out] bundle_directory
152 /// An object will be filled in with the bundle directory for
153 /// the bundle when \b true is returned. Otherwise \a file is
154 /// left untouched and \b false is returned.
155 ///
156 /// \return
157 /// \b true if \a file was resolved in \a bundle_directory,
158 /// \b false otherwise.
159 static bool GetBundleDirectory(const FileSpec &file,
160 FileSpec &bundle_directory);
161
162 /// When executable files may live within a directory, where the directory
163 /// represents an executable bundle (like the MacOSX app bundles), then
164 /// locate the executable within the containing bundle.
165 ///
166 /// \param[in,out] file
167 /// A file spec that currently points to the bundle that will
168 /// be filled in with the executable path within the bundle
169 /// if \b true is returned. Otherwise \a file is left untouched.
170 ///
171 /// \return
172 /// \b true if \a file was resolved, \b false if this function
173 /// was not able to resolve the path.
174 static bool ResolveExecutableInBundle(FileSpec &file);
175
176 static uint32_t FindProcesses(const ProcessInstanceInfoMatch &match_info,
177 ProcessInstanceInfoList &proc_infos);
178
179 typedef std::map<lldb::pid_t, bool> TidMap;
180 typedef std::pair<lldb::pid_t, bool> TidPair;
181 static bool FindProcessThreads(const lldb::pid_t pid, TidMap &tids_to_attach);
182
183 static bool GetProcessInfo(lldb::pid_t pid, ProcessInstanceInfo &proc_info);
184
185 /// Launch the process specified in launch_info. The monitoring callback in
186 /// launch_info must be set, and it will be called when the process
187 /// terminates.
188 static Status LaunchProcess(ProcessLaunchInfo &launch_info);
189
190 /// Perform expansion of the command-line for this launch info This can
191 /// potentially involve wildcard expansion
192 /// environment variable replacement, and whatever other
193 /// argument magic the platform defines as part of its typical
194 /// user experience
195 ///
196 /// \param[in] timeout
197 /// The maximum time to wait for the shell expansion to
198 /// complete. A value of std::nullopt means wait forever.
200 const Timeout<std::micro> &timeout);
201
202 /// Run a shell command.
203 /// \param[in] command
204 /// Command to execute, should not be empty.
205 /// \param[in] working_dir
206 /// Pass empty FileSpec to use the current working directory
207 /// \param[out] status_ptr
208 /// Pass nullptr if you don't want the process exit status
209 /// \param[out] signo_ptr
210 /// Pass nullptr if you don't want the signal that caused the
211 /// process to exit
212 /// \param[out] command_output
213 /// Pass nullptr if you don't want the command output
214 /// \param[out] separated_error_output
215 /// If a std::string is specified, error output is routed
216 /// into a separate string. If nullptr is provided,
217 /// command output and error text will be returned combined
218 /// in \a command_output.
219 /// \param[in] timeout
220 /// Timeout duration to enforce
221 /// \param[in] run_in_shell
222 /// Run in a subshell, with glob expansion of args
223 static Status RunShellCommand(llvm::StringRef command,
224 const FileSpec &working_dir, int *status_ptr,
225 int *signo_ptr, std::string *command_output,
226 std::string *error_output,
227 const Timeout<std::micro> &timeout,
228 bool run_in_shell = true);
229
230 /// Run a shell command.
231 /// \param[in] shell
232 /// Pass an empty string to use the default shell
233 /// \param[in] command
234 /// Command to execute, should not be empty.
235 /// \param[in] working_dir
236 /// Pass empty FileSpec to use the current working directory
237 /// \param[out] status_ptr
238 /// Pass nullptr if you don't want the process exit status
239 /// \param[out] signo_ptr
240 /// Pass nullptr if you don't want the signal that caused the
241 /// process to exit
242 /// \param[out] command_output
243 /// Pass nullptr if you don't want the command output
244 /// \param[out] separated_error_output
245 /// If a std::string is specified, error output is routed
246 /// into a separate string. If nullptr is provided,
247 /// command output and error text will be returned combined
248 /// \param[in] timeout
249 /// Timeout duration to enforce
250 /// \param[in] run_in_shell
251 /// Run in a subshell, with glob expansion of args
252 static Status RunShellCommand(llvm::StringRef shell, llvm::StringRef command,
253 const FileSpec &working_dir, int *status_ptr,
254 int *signo_ptr, std::string *command_output,
255 std::string *separated_error_output,
256 const Timeout<std::micro> &timeout,
257 bool run_in_shell = true);
258
259 /// Run a shell command.
260 /// \param[in] args
261 /// Command to execute
262 /// \param[in] working_dir
263 /// Pass empty FileSpec to use the current working directory
264 /// \param[out] status_ptr
265 /// Pass nullptr if you don't want the process exit status
266 /// \param[out] signo_ptr
267 /// Pass nullptr if you don't want the signal that caused the
268 /// process to exit
269 /// \param[out] command_output
270 /// Pass nullptr if you don't want the command output
271 /// \param[out] separated_error_output
272 /// If a std::string is specified, error output is routed
273 /// into a separate string. If nullptr is provided,
274 /// command output and error text will be returned combined
275 /// \param[in] timeout
276 /// Timeout duration to enforce
277 /// \param[in] run_in_shell
278 /// Run in a subshell, with glob expansion of args
279 static Status RunShellCommand(const Args &args, const FileSpec &working_dir,
280 int *status_ptr, int *signo_ptr,
281 std::string *command_output,
282 std::string *separated_error_output,
283 const Timeout<std::micro> &timeout,
284 bool run_in_shell = true);
285
286 /// Run a shell command.
287 /// \param[in] shell
288 /// Pass an empty string to use the default shell
289 /// \param[in] args
290 /// Command to execute
291 /// \param[in] working_dir
292 /// Pass empty FileSpec to use the current working directory
293 /// \param[out] status_ptr
294 /// Pass nullptr if you don't want the process exit status
295 /// \param[out] signo_ptr
296 /// Pass nullptr if you don't want the signal that caused the
297 /// process to exit
298 /// \param[out] command_output
299 /// Pass nullptr if you don't want the command output
300 /// \param[out] separated_error_output
301 /// If a std::string is specified, error output is routed
302 /// into a separate string. If nullptr is provided,
303 /// command output and error text will be returned combined
304 /// \param[in] timeout
305 /// Timeout duration to enforce
306 /// \param[in] run_in_shell
307 /// Run in a subshell, with glob expansion of args
308 static Status RunShellCommand(llvm::StringRef shell, const Args &args,
309 const FileSpec &working_dir, int *status_ptr,
310 int *signo_ptr, std::string *command_output,
311 std::string *separated_error_output,
312 const Timeout<std::micro> &timeout,
313 bool run_in_shell = true);
314
315 static llvm::Error OpenFileInExternalEditor(llvm::StringRef editor,
316 const FileSpec &file_spec,
317 uint32_t line_no,
318 bool foreground = false);
319
320 /// Open a URL with the host's default handler (Launch Services on macOS,
321 /// xdg-open on other Unix). Returns an error if opening fails or the platform
322 /// has no implementation (e.g. Windows).
323 static llvm::Error OpenURL(llvm::StringRef url);
324
325 /// Percent-encode a string for use in a URL query component, per RFC 3986
326 /// (alphanumerics and "-_.~" are kept literal; everything else becomes %HH).
327 static std::string URLEncode(llvm::StringRef str);
328
329 /// Check if we're running in an interactive graphical session.
330 ///
331 /// \return
332 /// True if we're running in an interactive graphical session. False if
333 /// we're not or don't know.
334 static bool IsInteractiveGraphicSession();
335
337
338 static std::unique_ptr<Connection>
339 CreateDefaultConnection(llvm::StringRef url);
340
341protected:
342 static uint32_t FindProcessesImpl(const ProcessInstanceInfoMatch &match_info,
343 ProcessInstanceInfoList &proc_infos);
344};
345
346/// Log handler that emits log messages to the operating system log.
348public:
350 void Emit(llvm::StringRef message) override;
351
352 bool isA(const void *ClassID) const override { return ClassID == &ID; }
353 static bool classof(const LogHandler *obj) { return obj->isA(&ID); }
354
355private:
356 static char ID;
357};
358
359} // namespace lldb_private
360
361namespace llvm {
362template <> struct format_provider<lldb_private::WaitStatus> {
363 /// Options = "" gives a human readable description of the status Options =
364 /// "g" gives a gdb-remote protocol status (e.g., X09)
365 static void format(const lldb_private::WaitStatus &WS, raw_ostream &OS,
366 llvm::StringRef Options);
367};
368} // namespace llvm
369
370#endif // LLDB_HOST_HOST_H
A command line argument class.
Definition Args.h:33
Represents a file descriptor action to be performed during process launch.
Definition FileAction.h:21
A file utility class.
Definition FileSpec.h:56
A class that provides host computer information.
Definition Host.h:82
static Status LaunchProcess(ProcessLaunchInfo &launch_info)
Launch the process specified in launch_info.
static bool FindProcessThreads(const lldb::pid_t pid, TidMap &tids_to_attach)
static bool ResolveExecutableInBundle(FileSpec &file)
When executable files may live within a directory, where the directory represents an executable bundl...
std::map< lldb::pid_t, bool > TidMap
Definition Host.h:179
static llvm::Error OpenURL(llvm::StringRef url)
Open a URL with the host's default handler (Launch Services on macOS, xdg-open on other Unix).
static std::string URLEncode(llvm::StringRef str)
Percent-encode a string for use in a URL query component, per RFC 3986 (alphanumerics and "-_....
static llvm::Error OpenFileInExternalEditor(llvm::StringRef editor, const FileSpec &file_spec, uint32_t line_no, bool foreground=false)
static lldb::thread_t GetCurrentThread()
Get the thread token (the one returned by ThreadCreate when the thread was created) for the calling t...
static Status ShellExpandArguments(ProcessLaunchInfo &launch_info, const Timeout< std::micro > &timeout)
Perform expansion of the command-line for this launch info This can potentially involve wildcard expa...
Definition aix/Host.cpp:216
static Environment GetEnvironment()
static lldb::pid_t GetCurrentProcessID()
Get the process ID for the calling process.
static Status RunShellCommand(llvm::StringRef command, const FileSpec &working_dir, int *status_ptr, int *signo_ptr, std::string *command_output, std::string *error_output, const Timeout< std::micro > &timeout, bool run_in_shell=true)
Run a shell command.
static uint32_t FindProcessesImpl(const ProcessInstanceInfoMatch &match_info, ProcessInstanceInfoList &proc_infos)
Definition aix/Host.cpp:169
static bool GetProcessInfo(lldb::pid_t pid, ProcessInstanceInfo &proc_info)
Definition aix/Host.cpp:211
static FileSpec GetModuleFileSpecForHostAddress(const void *host_addr)
Given an address in the current process (the process that is running the LLDB code),...
std::function< void(lldb::pid_t pid, int signal, int status)> MonitorChildProcessCallback
Definition Host.h:88
static uint32_t FindProcesses(const ProcessInstanceInfoMatch &match_info, ProcessInstanceInfoList &proc_infos)
static std::unique_ptr< Connection > CreateDefaultConnection(llvm::StringRef url)
std::pair< lldb::pid_t, bool > TidPair
Definition Host.h:180
static llvm::Expected< HostThread > StartMonitoringChildProcess(const MonitorChildProcessCallback &callback, lldb::pid_t pid)
Start monitoring a child process.
static void Kill(lldb::pid_t pid, int signo)
static const char * GetSignalAsCString(int signo)
static bool IsInteractiveGraphicSession()
Check if we're running in an interactive graphical session.
static bool GetBundleDirectory(const FileSpec &file, FileSpec &bundle_directory)
If you have an executable that is in a bundle and want to get back to the bundle directory from the p...
virtual bool isA(const void *ClassID) const
Definition Log.h:57
static constexpr MaskType ChannelFlag
Definition Log.h:148
uint64_t MaskType
The underlying type of all log channel enums.
Definition Log.h:145
An error handling class.
Definition Status.h:118
static bool classof(const LogHandler *obj)
Definition Host.h:353
bool isA(const void *ClassID) const override
Definition Host.h:352
void Emit(llvm::StringRef message) override
A class that represents a running process on the host machine.
bool operator!=(const Address &lhs, const Address &rhs)
Definition Address.cpp:1011
Log::Channel & LogChannelFor< SystemLog >()
LLVM_ENABLE_BITMASK_ENUMS_IN_NAMESPACE()
bool operator==(const Address &lhs, const Address &rhs)
Definition Address.cpp:1005
std::vector< ProcessInstanceInfo > ProcessInstanceInfoList
Definition Host.h:32
Severity
Used for expressing severity in logs and diagnostics.
pthread_t thread_t
Definition lldb-types.h:58
uint64_t pid_t
Definition lldb-types.h:84
WaitStatus(Type type, uint8_t status)
Definition Host.h:67
static WaitStatus Decode(int wstatus)
static void format(const lldb_private::WaitStatus &WS, raw_ostream &OS, llvm::StringRef Options)
Options = "" gives a human readable description of the status Options = "g" gives a gdb-remote protoc...