Coverage Report

Created: 2022-01-25 06:29

/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/Timeout.h"
17
#include "lldb/lldb-private-forward.h"
18
#include "lldb/lldb-private.h"
19
#include <cerrno>
20
#include <cstdarg>
21
#include <map>
22
#include <string>
23
#include <type_traits>
24
25
namespace lldb_private {
26
27
class FileAction;
28
class ProcessLaunchInfo;
29
class ProcessInstanceInfo;
30
class ProcessInstanceInfoMatch;
31
typedef std::vector<ProcessInstanceInfo> ProcessInstanceInfoList;
32
33
// Exit Type for inferior processes
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
47
14
  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
0
inline bool operator!=(WaitStatus a, WaitStatus b) { return !(a == b); }
57
58
/// \class Host Host.h "lldb/Host/Host.h"
59
/// A class that provides host computer information.
60
///
61
/// Host is a class that answers information about the host operating system.
62
class Host {
63
public:
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;
69
70
  /// Start monitoring a child process.
71
  ///
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.
77
  ///
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.
83
  ///
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.
87
  ///
88
  /// \param[in] pid
89
  ///     The process ID of a child process to monitor, -1 for all
90
  ///     processes.
91
  ///
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.
96
  ///
97
  /// \return
98
  ///     A thread handle that can be used to cancel the thread that
99
  ///     was spawned to monitor \a pid.
100
  ///
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);
105
106
  enum SystemLogType { eSystemLogWarning, eSystemLogError };
107
108
  static void SystemLog(SystemLogType type, const char *format, ...)
109
      __attribute__((format(printf, 2, 3)));
110
111
  static void SystemLog(SystemLogType type, const char *format, va_list args);
112
113
  /// Get the process ID for the calling process.
114
  ///
115
  /// \return
116
  ///     The process ID for the current process.
117
  static lldb::pid_t GetCurrentProcessID();
118
119
  static void Kill(lldb::pid_t pid, int signo);
120
121
  /// Get the thread token (the one returned by ThreadCreate when the thread
122
  /// was created) for the calling thread in the current process.
123
  ///
124
  /// \return
125
  ///     The thread token for the calling thread in the current process.
126
  static lldb::thread_t GetCurrentThread();
127
128
  static const char *GetSignalAsCString(int signo);
129
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
134
  /// binary.
135
  ///
136
  /// \param[in] host_addr
137
  ///     The pointer to some code in the current process.
138
  ///
139
  /// \return
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);
144
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.
148
  ///
149
  /// \param[in] file
150
  ///     A file spec that might point to a file in a bundle.
151
  ///
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.
156
  ///
157
  /// \return
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);
162
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.
166
  ///
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.
171
  ///
172
  /// \return
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);
176
177
  static uint32_t FindProcesses(const ProcessInstanceInfoMatch &match_info,
178
                                ProcessInstanceInfoList &proc_infos);
179
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);
183
184
  static bool GetProcessInfo(lldb::pid_t pid, ProcessInstanceInfo &proc_info);
185
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
188
  /// terminates.
189
  static Status LaunchProcess(ProcessLaunchInfo &launch_info);
190
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
195
  /// user experience
196
  static Status ShellExpandArguments(ProcessLaunchInfo &launch_info);
197
198
  /// Run a shell command.
199
  /// \arg command  shouldn't be empty
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
203
  ///                  process to exit
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
  static Status RunShellCommand(llvm::StringRef command,
207
                                const FileSpec &working_dir, int *status_ptr,
208
                                int *signo_ptr, std::string *command_output,
209
                                const Timeout<std::micro> &timeout,
210
                                bool run_in_shell = true,
211
                                bool hide_stderr = false);
212
213
  /// Run a shell command.
214
  /// \arg shell  Pass an empty string if you want to use the default shell
215
  /// interpreter \arg command \arg working_dir  Pass empty FileSpec to use the
216
  /// current working directory \arg status_ptr   Pass NULL if you don't want
217
  /// the process exit status \arg signo_ptr    Pass NULL if you don't want the
218
  /// signal that caused
219
  ///                   the process to exit
220
  /// \arg command_output  Pass NULL if you don't want the command output
221
  /// \arg hide_stderr  If this is \b false, redirect stderr to stdout
222
  static Status RunShellCommand(llvm::StringRef shell, llvm::StringRef command,
223
                                const FileSpec &working_dir, int *status_ptr,
224
                                int *signo_ptr, std::string *command_output,
225
                                const Timeout<std::micro> &timeout,
226
                                bool run_in_shell = true,
227
                                bool hide_stderr = false);
228
229
  /// Run a shell command.
230
  /// \arg working_dir Pass empty FileSpec to use the current working directory
231
  /// \arg status_ptr  Pass NULL if you don't want the process exit status
232
  /// \arg signo_ptr   Pass NULL if you don't want the signal that caused the
233
  ///                  process to exit
234
  /// \arg command_output  Pass NULL if you don't want the command output
235
  /// \arg hide_stderr if this is false, redirect stderr to stdout
236
  static Status RunShellCommand(const Args &args, const FileSpec &working_dir,
237
                                int *status_ptr, int *signo_ptr,
238
                                std::string *command_output,
239
                                const Timeout<std::micro> &timeout,
240
                                bool run_in_shell = true,
241
                                bool hide_stderr = false);
242
243
  /// Run a shell command.
244
  /// \arg shell            Pass an empty string if you want to use the default
245
  /// shell interpreter \arg command \arg working_dir Pass empty FileSpec to use
246
  /// the current working directory \arg status_ptr    Pass NULL if you don't
247
  /// want the process exit status \arg signo_ptr     Pass NULL if you don't
248
  /// want the signal that caused the
249
  ///               process to exit
250
  /// \arg command_output  Pass NULL if you don't want the command output
251
  /// \arg hide_stderr If this is \b false, redirect stderr to stdout
252
  static Status RunShellCommand(llvm::StringRef shell, const Args &args,
253
                                const FileSpec &working_dir, int *status_ptr,
254
                                int *signo_ptr, std::string *command_output,
255
                                const Timeout<std::micro> &timeout,
256
                                bool run_in_shell = true,
257
                                bool hide_stderr = false);
258
259
  static bool OpenFileInExternalEditor(const FileSpec &file_spec,
260
                                       uint32_t line_no);
261
262
  static Environment GetEnvironment();
263
264
  static std::unique_ptr<Connection>
265
  CreateDefaultConnection(llvm::StringRef url);
266
267
protected:
268
  static uint32_t FindProcessesImpl(const ProcessInstanceInfoMatch &match_info,
269
                                    ProcessInstanceInfoList &proc_infos);
270
};
271
272
} // namespace lldb_private
273
274
namespace llvm {
275
template <> struct format_provider<lldb_private::WaitStatus> {
276
  /// Options = "" gives a human readable description of the status Options =
277
  /// "g" gives a gdb-remote protocol status (e.g., X09)
278
  static void format(const lldb_private::WaitStatus &WS, raw_ostream &OS,
279
                     llvm::StringRef Options);
280
};
281
} // namespace llvm
282
283
#endif // LLDB_HOST_HOST_H