Coverage Report

Created: 2023-09-30 09:22

/Users/buildslave/jenkins/workspace/coverage/llvm-project/lldb/include/lldb/Host/Host.h
Line
Count
Source (jump to first uncovered line)
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"
13
#include "lldb/Host/HostThread.h"
14
#include "lldb/Utility/Environment.h"
15
#include "lldb/Utility/FileSpec.h"
16
#include "lldb/Utility/Log.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 <cstdarg>
22
#include <map>
23
#include <string>
24
#include <type_traits>
25
26
namespace lldb_private {
27
28
class FileAction;
29
class ProcessLaunchInfo;
30
class ProcessInstanceInfo;
31
class ProcessInstanceInfoMatch;
32
typedef std::vector<ProcessInstanceInfo> ProcessInstanceInfoList;
33
34
// Exit Type for inferior processes
35
struct WaitStatus {
36
  enum Type : uint8_t {
37
    Exit,   // The status represents the return code from normal
38
            // program exit (i.e. WIFEXITED() was true)
39
    Signal, // The status represents the signal number that caused
40
            // the program to exit (i.e. WIFSIGNALED() was true)
41
    Stop,   // The status represents the signal number that caused the
42
            // program to stop (i.e. WIFSTOPPED() was true)
43
  };
44
45
  Type type;
46
  uint8_t status;
47
48
12
  WaitStatus(Type type, uint8_t status) : type(type), status(status) {}
49
50
  static WaitStatus Decode(int wstatus);
51
};
52
53
inline bool operator==(WaitStatus a, WaitStatus b) {
54
  return a.type == b.type && a.status == b.status;
55
}
56
57
0
inline bool operator!=(WaitStatus a, WaitStatus b) { return !(a == b); }
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
class Host {
64
public:
65
  typedef std::function<void(lldb::pid_t pid,
66
                             int signal,  // Zero for no signal
67
                             int status)> // Exit value of process if signal is
68
                                          // zero
69
      MonitorChildProcessCallback;
70
71
  /// Start monitoring a child process.
72
  ///
73
  /// Allows easy monitoring of child processes. \a callback will be called
74
  /// when the child process exits or if it dies from a signal.
75
  ///
76
  /// \param[in] callback
77
  ///     A function callback to call when a child receives a signal
78
  ///     or exits.
79
  ///
80
  /// \param[in] pid
81
  ///     The process ID of a child process to monitor.
82
  ///
83
  /// \return
84
  ///     A thread handle that can be used to cancel the thread that
85
  ///     was spawned to monitor \a pid.
86
  static llvm::Expected<HostThread>
87
  StartMonitoringChildProcess(const MonitorChildProcessCallback &callback,
88
                              lldb::pid_t pid);
89
90
  /// Emit the given message to the operating system log.
91
  static void SystemLog(llvm::StringRef message);
92
93
  /// Get the process ID for the calling process.
94
  ///
95
  /// \return
96
  ///     The process ID for the current process.
97
  static lldb::pid_t GetCurrentProcessID();
98
99
  static void Kill(lldb::pid_t pid, int signo);
100
101
  /// Get the thread token (the one returned by ThreadCreate when the thread
102
  /// was created) for the calling thread in the current process.
103
  ///
104
  /// \return
105
  ///     The thread token for the calling thread in the current process.
106
  static lldb::thread_t GetCurrentThread();
107
108
  static const char *GetSignalAsCString(int signo);
109
110
  /// Given an address in the current process (the process that is running the
111
  /// LLDB code), return the name of the module that it comes from. This can
112
  /// be useful when you need to know the path to the shared library that your
113
  /// code is running in for loading resources that are relative to your
114
  /// binary.
115
  ///
116
  /// \param[in] host_addr
117
  ///     The pointer to some code in the current process.
118
  ///
119
  /// \return
120
  ///     \b A file spec with the module that contains \a host_addr,
121
  ///     which may be invalid if \a host_addr doesn't fall into
122
  ///     any valid module address range.
123
  static FileSpec GetModuleFileSpecForHostAddress(const void *host_addr);
124
125
  /// If you have an executable that is in a bundle and want to get back to
126
  /// the bundle directory from the path itself, this function will change a
127
  /// path to a file within a bundle to the bundle directory itself.
128
  ///
129
  /// \param[in] file
130
  ///     A file spec that might point to a file in a bundle.
131
  ///
132
  /// \param[out] bundle_directory
133
  ///     An object will be filled in with the bundle directory for
134
  ///     the bundle when \b true is returned. Otherwise \a file is
135
  ///     left untouched and \b false is returned.
136
  ///
137
  /// \return
138
  ///     \b true if \a file was resolved in \a bundle_directory,
139
  ///     \b false otherwise.
140
  static bool GetBundleDirectory(const FileSpec &file,
141
                                 FileSpec &bundle_directory);
142
143
  /// When executable files may live within a directory, where the directory
144
  /// represents an executable bundle (like the MacOSX app bundles), then
145
  /// locate the executable within the containing bundle.
146
  ///
147
  /// \param[in,out] file
148
  ///     A file spec that currently points to the bundle that will
149
  ///     be filled in with the executable path within the bundle
150
  ///     if \b true is returned. Otherwise \a file is left untouched.
151
  ///
152
  /// \return
153
  ///     \b true if \a file was resolved, \b false if this function
154
  ///     was not able to resolve the path.
155
  static bool ResolveExecutableInBundle(FileSpec &file);
156
157
  static uint32_t FindProcesses(const ProcessInstanceInfoMatch &match_info,
158
                                ProcessInstanceInfoList &proc_infos);
159
160
  typedef std::map<lldb::pid_t, bool> TidMap;
161
  typedef std::pair<lldb::pid_t, bool> TidPair;
162
  static bool FindProcessThreads(const lldb::pid_t pid, TidMap &tids_to_attach);
163
164
  static bool GetProcessInfo(lldb::pid_t pid, ProcessInstanceInfo &proc_info);
165
166
  /// Launch the process specified in launch_info. The monitoring callback in
167
  /// launch_info must be set, and it will be called when the process
168
  /// terminates.
169
  static Status LaunchProcess(ProcessLaunchInfo &launch_info);
170
171
  /// Perform expansion of the command-line for this launch info This can
172
  /// potentially involve wildcard expansion
173
  /// environment variable replacement, and whatever other
174
  /// argument magic the platform defines as part of its typical
175
  /// user experience
176
  static Status ShellExpandArguments(ProcessLaunchInfo &launch_info);
177
178
  /// Run a shell command.
179
  /// \arg command  shouldn't be empty
180
  /// \arg working_dir Pass empty FileSpec to use the current working directory
181
  /// \arg status_ptr  Pass NULL if you don't want the process exit status
182
  /// \arg signo_ptr   Pass NULL if you don't want the signal that caused the
183
  ///                  process to exit
184
  /// \arg command_output  Pass NULL if you don't want the command output
185
  /// \arg hide_stderr if this is false, redirect stderr to stdout
186
  static Status RunShellCommand(llvm::StringRef command,
187
                                const FileSpec &working_dir, int *status_ptr,
188
                                int *signo_ptr, std::string *command_output,
189
                                const Timeout<std::micro> &timeout,
190
                                bool run_in_shell = true,
191
                                bool hide_stderr = false);
192
193
  /// Run a shell command.
194
  /// \arg shell  Pass an empty string if you want to use the default shell
195
  /// interpreter \arg command \arg working_dir  Pass empty FileSpec to use the
196
  /// current working directory \arg status_ptr   Pass NULL if you don't want
197
  /// the process exit status \arg signo_ptr    Pass NULL if you don't want the
198
  /// signal that caused
199
  ///                   the process to exit
200
  /// \arg command_output  Pass NULL if you don't want the command output
201
  /// \arg hide_stderr  If this is \b false, redirect stderr to stdout
202
  static Status RunShellCommand(llvm::StringRef shell, llvm::StringRef command,
203
                                const FileSpec &working_dir, int *status_ptr,
204
                                int *signo_ptr, std::string *command_output,
205
                                const Timeout<std::micro> &timeout,
206
                                bool run_in_shell = true,
207
                                bool hide_stderr = false);
208
209
  /// Run a shell command.
210
  /// \arg working_dir Pass empty FileSpec to use the current working directory
211
  /// \arg status_ptr  Pass NULL if you don't want the process exit status
212
  /// \arg signo_ptr   Pass NULL if you don't want the signal that caused the
213
  ///                  process to exit
214
  /// \arg command_output  Pass NULL if you don't want the command output
215
  /// \arg hide_stderr if this is false, redirect stderr to stdout
216
  static Status RunShellCommand(const Args &args, const FileSpec &working_dir,
217
                                int *status_ptr, int *signo_ptr,
218
                                std::string *command_output,
219
                                const Timeout<std::micro> &timeout,
220
                                bool run_in_shell = true,
221
                                bool hide_stderr = false);
222
223
  /// Run a shell command.
224
  /// \arg shell            Pass an empty string if you want to use the default
225
  /// shell interpreter \arg command \arg working_dir Pass empty FileSpec to use
226
  /// the current working directory \arg status_ptr    Pass NULL if you don't
227
  /// want the process exit status \arg signo_ptr     Pass NULL if you don't
228
  /// want the signal that caused the
229
  ///               process to exit
230
  /// \arg command_output  Pass NULL if you don't want the command output
231
  /// \arg hide_stderr If this is \b false, redirect stderr to stdout
232
  static Status RunShellCommand(llvm::StringRef shell, const Args &args,
233
                                const FileSpec &working_dir, int *status_ptr,
234
                                int *signo_ptr, std::string *command_output,
235
                                const Timeout<std::micro> &timeout,
236
                                bool run_in_shell = true,
237
                                bool hide_stderr = false);
238
239
  static llvm::Error OpenFileInExternalEditor(llvm::StringRef editor,
240
                                              const FileSpec &file_spec,
241
                                              uint32_t line_no);
242
243
  /// Check if we're running in an interactive graphical session.
244
  ///
245
  /// \return
246
  ///     True if we're running in an interactive graphical session. False if
247
  ///     we're not or don't know.
248
  static bool IsInteractiveGraphicSession();
249
250
  static Environment GetEnvironment();
251
252
  static std::unique_ptr<Connection>
253
  CreateDefaultConnection(llvm::StringRef url);
254
255
protected:
256
  static uint32_t FindProcessesImpl(const ProcessInstanceInfoMatch &match_info,
257
                                    ProcessInstanceInfoList &proc_infos);
258
};
259
260
/// Log handler that emits log messages to the operating system log.
261
class SystemLogHandler : public LogHandler {
262
public:
263
  SystemLogHandler();
264
  void Emit(llvm::StringRef message) override;
265
266
0
  bool isA(const void *ClassID) const override { return ClassID == &ID; }
267
0
  static bool classof(const LogHandler *obj) { return obj->isA(&ID); }
268
269
private:
270
  static char ID;
271
};
272
273
} // namespace lldb_private
274
275
namespace llvm {
276
template <> struct format_provider<lldb_private::WaitStatus> {
277
  /// Options = "" gives a human readable description of the status Options =
278
  /// "g" gives a gdb-remote protocol status (e.g., X09)
279
  static void format(const lldb_private::WaitStatus &WS, raw_ostream &OS,
280
                     llvm::StringRef Options);
281
};
282
} // namespace llvm
283
284
#endif // LLDB_HOST_HOST_H