Book a Demo!
CoCalc Logo Icon
StoreFeaturesDocsShareSupportNewsAboutPoliciesSign UpSign In
freebsd
GitHub Repository: freebsd/freebsd-src
Path: blob/main/contrib/llvm-project/lldb/source/Utility/ProcessInfo.cpp
39587 views
1
//===-- ProcessInfo.cpp ---------------------------------------------------===//
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
#include "lldb/Utility/ProcessInfo.h"
10
11
#include "lldb/Utility/ArchSpec.h"
12
#include "lldb/Utility/ScriptedMetadata.h"
13
#include "lldb/Utility/Stream.h"
14
#include "lldb/Utility/StreamString.h"
15
#include "lldb/Utility/UserIDResolver.h"
16
#include "llvm/ADT/SmallString.h"
17
18
#include <climits>
19
#include <optional>
20
21
using namespace lldb;
22
using namespace lldb_private;
23
24
ProcessInfo::ProcessInfo()
25
: m_executable(), m_arguments(), m_environment(), m_arch(), m_listener_sp(),
26
m_hijack_listener_sp(), m_shadow_listener_sp() {}
27
28
ProcessInfo::ProcessInfo(const char *name, const ArchSpec &arch,
29
lldb::pid_t pid)
30
: m_executable(name), m_arguments(), m_environment(), m_arch(arch),
31
m_pid(pid), m_listener_sp(), m_hijack_listener_sp(),
32
m_shadow_listener_sp() {}
33
34
void ProcessInfo::Clear() {
35
m_executable.Clear();
36
m_arguments.Clear();
37
m_environment.clear();
38
m_uid = UINT32_MAX;
39
m_gid = UINT32_MAX;
40
m_arch.Clear();
41
m_pid = LLDB_INVALID_PROCESS_ID;
42
m_scripted_metadata_sp.reset();
43
}
44
45
const char *ProcessInfo::GetName() const {
46
return m_executable.GetFilename().GetCString();
47
}
48
49
llvm::StringRef ProcessInfo::GetNameAsStringRef() const {
50
return m_executable.GetFilename().GetStringRef();
51
}
52
53
void ProcessInfo::Dump(Stream &s, Platform *platform) const {
54
s << "Executable: " << GetName() << "\n";
55
s << "Triple: ";
56
m_arch.DumpTriple(s.AsRawOstream());
57
s << "\n";
58
59
s << "Arguments:\n";
60
m_arguments.Dump(s);
61
62
s.Format("Environment:\n{0}", m_environment);
63
}
64
65
void ProcessInfo::SetExecutableFile(const FileSpec &exe_file,
66
bool add_exe_file_as_first_arg) {
67
if (exe_file) {
68
m_executable = exe_file;
69
if (add_exe_file_as_first_arg) {
70
llvm::SmallString<128> filename;
71
exe_file.GetPath(filename);
72
if (!filename.empty())
73
m_arguments.InsertArgumentAtIndex(0, filename);
74
}
75
} else {
76
m_executable.Clear();
77
}
78
}
79
80
llvm::StringRef ProcessInfo::GetArg0() const { return m_arg0; }
81
82
void ProcessInfo::SetArg0(llvm::StringRef arg) { m_arg0 = std::string(arg); }
83
84
void ProcessInfo::SetArguments(char const **argv,
85
bool first_arg_is_executable) {
86
m_arguments.SetArguments(argv);
87
88
// Is the first argument the executable?
89
if (first_arg_is_executable) {
90
const char *first_arg = m_arguments.GetArgumentAtIndex(0);
91
if (first_arg) {
92
// Yes the first argument is an executable, set it as the executable in
93
// the launch options. Don't resolve the file path as the path could be a
94
// remote platform path
95
m_executable.SetFile(first_arg, FileSpec::Style::native);
96
}
97
}
98
}
99
100
void ProcessInfo::SetArguments(const Args &args, bool first_arg_is_executable) {
101
// Copy all arguments
102
m_arguments = args;
103
104
// Is the first argument the executable?
105
if (first_arg_is_executable) {
106
const char *first_arg = m_arguments.GetArgumentAtIndex(0);
107
if (first_arg) {
108
// Yes the first argument is an executable, set it as the executable in
109
// the launch options. Don't resolve the file path as the path could be a
110
// remote platform path
111
m_executable.SetFile(first_arg, FileSpec::Style::native);
112
}
113
}
114
}
115
116
bool ProcessInfo::IsScriptedProcess() const {
117
return m_scripted_metadata_sp && *m_scripted_metadata_sp;
118
}
119
120
void ProcessInstanceInfo::Dump(Stream &s, UserIDResolver &resolver) const {
121
if (m_pid != LLDB_INVALID_PROCESS_ID)
122
s.Printf(" pid = %" PRIu64 "\n", m_pid);
123
124
if (ParentProcessIDIsValid())
125
s.Printf(" parent = %" PRIu64 "\n", GetParentProcessID());
126
127
if (m_executable) {
128
s.Printf(" name = %s\n", m_executable.GetFilename().GetCString());
129
s.PutCString(" file = ");
130
m_executable.Dump(s.AsRawOstream());
131
s.EOL();
132
}
133
const uint32_t argc = m_arguments.GetArgumentCount();
134
if (argc > 0) {
135
for (uint32_t i = 0; i < argc; i++) {
136
const char *arg = m_arguments.GetArgumentAtIndex(i);
137
if (i < 10)
138
s.Printf(" arg[%u] = %s\n", i, arg);
139
else
140
s.Printf("arg[%u] = %s\n", i, arg);
141
}
142
}
143
144
s.Format("{0}", m_environment);
145
146
if (m_arch.IsValid()) {
147
s.Printf(" arch = ");
148
m_arch.DumpTriple(s.AsRawOstream());
149
s.EOL();
150
}
151
152
if (UserIDIsValid()) {
153
s.Format(" uid = {0,-5} ({1})\n", GetUserID(),
154
resolver.GetUserName(GetUserID()).value_or(""));
155
}
156
if (GroupIDIsValid()) {
157
s.Format(" gid = {0,-5} ({1})\n", GetGroupID(),
158
resolver.GetGroupName(GetGroupID()).value_or(""));
159
}
160
if (EffectiveUserIDIsValid()) {
161
s.Format(" euid = {0,-5} ({1})\n", GetEffectiveUserID(),
162
resolver.GetUserName(GetEffectiveUserID()).value_or(""));
163
}
164
if (EffectiveGroupIDIsValid()) {
165
s.Format(" egid = {0,-5} ({1})\n", GetEffectiveGroupID(),
166
resolver.GetGroupName(GetEffectiveGroupID()).value_or(""));
167
}
168
}
169
170
void ProcessInstanceInfo::DumpTableHeader(Stream &s, bool show_args,
171
bool verbose) {
172
const char *label;
173
if (show_args || verbose)
174
label = "ARGUMENTS";
175
else
176
label = "NAME";
177
178
if (verbose) {
179
s.Printf("PID PARENT USER GROUP EFF USER EFF GROUP TRIPLE "
180
" %s\n",
181
label);
182
s.PutCString(
183
"====== ====== ========== ========== ========== ========== "
184
"============================== ============================\n");
185
} else {
186
s.Printf("PID PARENT USER TRIPLE %s\n",
187
label);
188
s.PutCString("====== ====== ========== ============================== "
189
"============================\n");
190
}
191
}
192
193
void ProcessInstanceInfo::DumpAsTableRow(Stream &s, UserIDResolver &resolver,
194
bool show_args, bool verbose) const {
195
if (m_pid != LLDB_INVALID_PROCESS_ID) {
196
s.Printf("%-6" PRIu64 " %-6" PRIu64 " ", m_pid,
197
(ParentProcessIDIsValid()) ? GetParentProcessID() : 0);
198
199
StreamString arch_strm;
200
if (m_arch.IsValid())
201
m_arch.DumpTriple(arch_strm.AsRawOstream());
202
203
auto print = [&](bool (ProcessInstanceInfo::*isValid)() const,
204
uint32_t (ProcessInstanceInfo::*getID)() const,
205
std::optional<llvm::StringRef> (UserIDResolver::*getName)(
206
UserIDResolver::id_t id)) {
207
const char *format = "{0,-10} ";
208
if (!(this->*isValid)()) {
209
s.Format(format, "");
210
return;
211
}
212
uint32_t id = (this->*getID)();
213
if (auto name = (resolver.*getName)(id))
214
s.Format(format, *name);
215
else
216
s.Format(format, id);
217
};
218
if (verbose) {
219
print(&ProcessInstanceInfo::UserIDIsValid,
220
&ProcessInstanceInfo::GetUserID, &UserIDResolver::GetUserName);
221
print(&ProcessInstanceInfo::GroupIDIsValid,
222
&ProcessInstanceInfo::GetGroupID, &UserIDResolver::GetGroupName);
223
print(&ProcessInstanceInfo::EffectiveUserIDIsValid,
224
&ProcessInstanceInfo::GetEffectiveUserID,
225
&UserIDResolver::GetUserName);
226
print(&ProcessInstanceInfo::EffectiveGroupIDIsValid,
227
&ProcessInstanceInfo::GetEffectiveGroupID,
228
&UserIDResolver::GetGroupName);
229
230
s.Printf("%-30s ", arch_strm.GetData());
231
} else {
232
print(&ProcessInstanceInfo::EffectiveUserIDIsValid,
233
&ProcessInstanceInfo::GetEffectiveUserID,
234
&UserIDResolver::GetUserName);
235
s.Printf("%-30s ", arch_strm.GetData());
236
}
237
238
if (verbose || show_args) {
239
s.PutCString(m_arg0);
240
const uint32_t argc = m_arguments.GetArgumentCount();
241
for (uint32_t i = 0; i < argc; i++) {
242
s.PutChar(' ');
243
s.PutCString(m_arguments.GetArgumentAtIndex(i));
244
}
245
} else {
246
s.PutCString(GetName());
247
}
248
249
s.EOL();
250
}
251
}
252
253
bool ProcessInstanceInfoMatch::ArchitectureMatches(
254
const ArchSpec &arch_spec) const {
255
return !m_match_info.GetArchitecture().IsValid() ||
256
m_match_info.GetArchitecture().IsCompatibleMatch(arch_spec);
257
}
258
259
bool ProcessInstanceInfoMatch::NameMatches(const char *process_name) const {
260
if (m_name_match_type == NameMatch::Ignore)
261
return true;
262
const char *match_name = m_match_info.GetName();
263
if (!match_name)
264
return true;
265
266
return lldb_private::NameMatches(process_name, m_name_match_type, match_name);
267
}
268
269
bool ProcessInstanceInfoMatch::ProcessIDsMatch(
270
const ProcessInstanceInfo &proc_info) const {
271
if (m_match_info.ProcessIDIsValid() &&
272
m_match_info.GetProcessID() != proc_info.GetProcessID())
273
return false;
274
275
if (m_match_info.ParentProcessIDIsValid() &&
276
m_match_info.GetParentProcessID() != proc_info.GetParentProcessID())
277
return false;
278
return true;
279
}
280
281
bool ProcessInstanceInfoMatch::UserIDsMatch(
282
const ProcessInstanceInfo &proc_info) const {
283
if (m_match_info.UserIDIsValid() &&
284
m_match_info.GetUserID() != proc_info.GetUserID())
285
return false;
286
287
if (m_match_info.GroupIDIsValid() &&
288
m_match_info.GetGroupID() != proc_info.GetGroupID())
289
return false;
290
291
if (m_match_info.EffectiveUserIDIsValid() &&
292
m_match_info.GetEffectiveUserID() != proc_info.GetEffectiveUserID())
293
return false;
294
295
if (m_match_info.EffectiveGroupIDIsValid() &&
296
m_match_info.GetEffectiveGroupID() != proc_info.GetEffectiveGroupID())
297
return false;
298
return true;
299
}
300
bool ProcessInstanceInfoMatch::Matches(
301
const ProcessInstanceInfo &proc_info) const {
302
return ArchitectureMatches(proc_info.GetArchitecture()) &&
303
ProcessIDsMatch(proc_info) && UserIDsMatch(proc_info) &&
304
NameMatches(proc_info.GetName());
305
}
306
307
bool ProcessInstanceInfoMatch::MatchAllProcesses() const {
308
if (m_name_match_type != NameMatch::Ignore)
309
return false;
310
311
if (m_match_info.ProcessIDIsValid())
312
return false;
313
314
if (m_match_info.ParentProcessIDIsValid())
315
return false;
316
317
if (m_match_info.UserIDIsValid())
318
return false;
319
320
if (m_match_info.GroupIDIsValid())
321
return false;
322
323
if (m_match_info.EffectiveUserIDIsValid())
324
return false;
325
326
if (m_match_info.EffectiveGroupIDIsValid())
327
return false;
328
329
if (m_match_info.GetArchitecture().IsValid())
330
return false;
331
332
if (m_match_all_users)
333
return false;
334
335
return true;
336
}
337
338
void ProcessInstanceInfoMatch::Clear() {
339
m_match_info.Clear();
340
m_name_match_type = NameMatch::Ignore;
341
m_match_all_users = false;
342
}
343
344