1 //===-- Host.h --------------------------------------------------*- C++ -*-===//
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
7 //===----------------------------------------------------------------------===//
9 #ifndef LLDB_HOST_HOST_H
10 #define LLDB_HOST_HOST_H
12 #include "lldb/Host/File.h"
13 #include "lldb/Host/HostThread.h"
14 #include "lldb/Utility/Environment.h"
15 #include "lldb/Utility/FileSpec.h"
16 #include "lldb/Utility/Timeout.h"
17 #include "lldb/lldb-private-forward.h"
18 #include "lldb/lldb-private.h"
23 #include <type_traits>
25 namespace lldb_private {
28 class ProcessLaunchInfo;
29 class ProcessInstanceInfo;
30 class ProcessInstanceInfoList;
31 class ProcessInstanceInfoMatch;
33 // Exit Type for inferior processes
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)
47 WaitStatus(Type type, uint8_t status) : type(type), status(status) {}
49 static WaitStatus Decode(int wstatus);
52 inline bool operator==(WaitStatus a, WaitStatus b) {
53 return a.type == b.type && a.status == b.status;
56 inline bool operator!=(WaitStatus a, WaitStatus b) { return !(a == b); }
58 /// \class Host Host.h "lldb/Host/Host.h"
59 /// A class that provides host computer information.
61 /// Host is a class that answers information about the host operating system.
64 typedef std::function<bool(
65 lldb::pid_t pid, bool exited,
66 int signal, // Zero for no signal
67 int status)> // Exit value of process if signal is zero
68 MonitorChildProcessCallback;
70 /// Start monitoring a child process.
72 /// Allows easy monitoring of child processes. \a callback will be called
73 /// when the child process exits or if it gets a signal. The callback will
74 /// only be called with signals if \a monitor_signals is \b true. \a
75 /// callback will usually be called from another thread so the callback
76 /// function must be thread safe.
78 /// When the callback gets called, the return value indicates if monitoring
79 /// should stop. If \b true is returned from \a callback the information
80 /// will be removed. If \b false is returned then monitoring will continue.
81 /// If the child process exits, the monitoring will automatically stop after
82 /// the callback returned regardless of the callback return value.
84 /// \param[in] callback
85 /// A function callback to call when a child receives a signal
86 /// (if \a monitor_signals is true) or a child exits.
89 /// The process ID of a child process to monitor, -1 for all
92 /// \param[in] monitor_signals
93 /// If \b true the callback will get called when the child
94 /// process gets a signal. If \b false, the callback will only
95 /// get called if the child process exits.
98 /// A thread handle that can be used to cancel the thread that
99 /// was spawned to monitor \a pid.
101 /// \see static void Host::StopMonitoringChildProcess (uint32_t)
102 static llvm::Expected<HostThread>
103 StartMonitoringChildProcess(const MonitorChildProcessCallback &callback,
104 lldb::pid_t pid, bool monitor_signals);
106 enum SystemLogType { eSystemLogWarning, eSystemLogError };
108 static void SystemLog(SystemLogType type, const char *format, ...)
109 __attribute__((format(printf, 2, 3)));
111 static void SystemLog(SystemLogType type, const char *format, va_list args);
113 /// Get the process ID for the calling process.
116 /// The process ID for the current process.
117 static lldb::pid_t GetCurrentProcessID();
119 static void Kill(lldb::pid_t pid, int signo);
121 /// Get the thread token (the one returned by ThreadCreate when the thread
122 /// was created) for the calling thread in the current process.
125 /// The thread token for the calling thread in the current process.
126 static lldb::thread_t GetCurrentThread();
128 static const char *GetSignalAsCString(int signo);
130 /// Given an address in the current process (the process that is running the
131 /// LLDB code), return the name of the module that it comes from. This can
132 /// be useful when you need to know the path to the shared library that your
133 /// code is running in for loading resources that are relative to your
136 /// \param[in] host_addr
137 /// The pointer to some code in the current process.
140 /// \b A file spec with the module that contains \a host_addr,
141 /// which may be invalid if \a host_addr doesn't fall into
142 /// any valid module address range.
143 static FileSpec GetModuleFileSpecForHostAddress(const void *host_addr);
145 /// If you have an executable that is in a bundle and want to get back to
146 /// the bundle directory from the path itself, this function will change a
147 /// path to a file within a bundle to the bundle directory itself.
150 /// A file spec that might point to a file in a bundle.
152 /// \param[out] bundle_directory
153 /// An object will be filled in with the bundle directory for
154 /// the bundle when \b true is returned. Otherwise \a file is
155 /// left untouched and \b false is returned.
158 /// \b true if \a file was resolved in \a bundle_directory,
159 /// \b false otherwise.
160 static bool GetBundleDirectory(const FileSpec &file,
161 FileSpec &bundle_directory);
163 /// When executable files may live within a directory, where the directory
164 /// represents an executable bundle (like the MacOSX app bundles), then
165 /// locate the executable within the containing bundle.
167 /// \param[in,out] file
168 /// A file spec that currently points to the bundle that will
169 /// be filled in with the executable path within the bundle
170 /// if \b true is returned. Otherwise \a file is left untouched.
173 /// \b true if \a file was resolved, \b false if this function
174 /// was not able to resolve the path.
175 static bool ResolveExecutableInBundle(FileSpec &file);
177 static uint32_t FindProcesses(const ProcessInstanceInfoMatch &match_info,
178 ProcessInstanceInfoList &proc_infos);
180 typedef std::map<lldb::pid_t, bool> TidMap;
181 typedef std::pair<lldb::pid_t, bool> TidPair;
182 static bool FindProcessThreads(const lldb::pid_t pid, TidMap &tids_to_attach);
184 static bool GetProcessInfo(lldb::pid_t pid, ProcessInstanceInfo &proc_info);
186 /// Launch the process specified in launch_info. The monitoring callback in
187 /// launch_info must be set, and it will be called when the process
189 static Status LaunchProcess(ProcessLaunchInfo &launch_info);
191 /// Perform expansion of the command-line for this launch info This can
192 /// potentially involve wildcard expansion
193 /// environment variable replacement, and whatever other
194 /// argument magic the platform defines as part of its typical
196 static Status ShellExpandArguments(ProcessLaunchInfo &launch_info);
198 /// Run a shell command.
199 /// \arg command shouldn't be NULL
200 /// \arg working_dir Pass empty FileSpec to use the current working directory
201 /// \arg status_ptr Pass NULL if you don't want the process exit status
202 /// \arg signo_ptr Pass NULL if you don't want the signal that caused the
204 /// \arg command_output Pass NULL if you don't want the command output
205 /// \arg hide_stderr if this is false, redirect stderr to stdout
206 /// TODO: Convert this function to take a StringRef.
207 static Status RunShellCommand(const char *command,
208 const FileSpec &working_dir, int *status_ptr,
209 int *signo_ptr, std::string *command_output,
210 const Timeout<std::micro> &timeout,
211 bool run_in_default_shell = true,
212 bool hide_stderr = false);
214 /// Run a shell command.
215 /// \arg working_dir Pass empty FileSpec to use the current working directory
216 /// \arg status_ptr Pass NULL if you don't want the process exit status
217 /// \arg signo_ptr Pass NULL if you don't want the signal that caused the
219 /// \arg command_output Pass NULL if you don't want the command output
220 /// \arg hide_stderr if this is false, redirect stderr to stdout
221 static Status RunShellCommand(const Args &args, const FileSpec &working_dir,
222 int *status_ptr, int *signo_ptr,
223 std::string *command_output,
224 const Timeout<std::micro> &timeout,
225 bool run_in_default_shell = true,
226 bool hide_stderr = false);
228 static bool OpenFileInExternalEditor(const FileSpec &file_spec,
231 static Environment GetEnvironment();
233 static std::unique_ptr<Connection>
234 CreateDefaultConnection(llvm::StringRef url);
237 } // namespace lldb_private
240 template <> struct format_provider<lldb_private::WaitStatus> {
241 /// Options = "" gives a human readable description of the status Options =
242 /// "g" gives a gdb-remote protocol status (e.g., X09)
243 static void format(const lldb_private::WaitStatus &WS, raw_ostream &OS,
244 llvm::StringRef Options);
248 #endif // LLDB_HOST_HOST_H