Book a Demo!
CoCalc Logo Icon
StoreFeaturesDocsShareSupportNewsAboutPoliciesSign UpSign In
freebsd
GitHub Repository: freebsd/freebsd-src
Path: blob/main/contrib/llvm-project/lldb/source/Commands/CommandObjectProcess.cpp
39587 views
1
//===-- CommandObjectProcess.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 "CommandObjectProcess.h"
10
#include "CommandObjectBreakpoint.h"
11
#include "CommandObjectTrace.h"
12
#include "CommandOptionsProcessAttach.h"
13
#include "CommandOptionsProcessLaunch.h"
14
#include "lldb/Breakpoint/Breakpoint.h"
15
#include "lldb/Breakpoint/BreakpointIDList.h"
16
#include "lldb/Breakpoint/BreakpointLocation.h"
17
#include "lldb/Breakpoint/BreakpointName.h"
18
#include "lldb/Breakpoint/BreakpointSite.h"
19
#include "lldb/Core/Module.h"
20
#include "lldb/Core/PluginManager.h"
21
#include "lldb/Host/OptionParser.h"
22
#include "lldb/Interpreter/CommandInterpreter.h"
23
#include "lldb/Interpreter/CommandOptionArgumentTable.h"
24
#include "lldb/Interpreter/CommandReturnObject.h"
25
#include "lldb/Interpreter/OptionArgParser.h"
26
#include "lldb/Interpreter/OptionGroupPythonClassWithDict.h"
27
#include "lldb/Interpreter/Options.h"
28
#include "lldb/Target/Platform.h"
29
#include "lldb/Target/Process.h"
30
#include "lldb/Target/StopInfo.h"
31
#include "lldb/Target/Target.h"
32
#include "lldb/Target/Thread.h"
33
#include "lldb/Target/UnixSignals.h"
34
#include "lldb/Utility/Args.h"
35
#include "lldb/Utility/ScriptedMetadata.h"
36
#include "lldb/Utility/State.h"
37
38
#include "llvm/ADT/ScopeExit.h"
39
40
#include <bitset>
41
#include <optional>
42
43
using namespace lldb;
44
using namespace lldb_private;
45
46
class CommandObjectProcessLaunchOrAttach : public CommandObjectParsed {
47
public:
48
CommandObjectProcessLaunchOrAttach(CommandInterpreter &interpreter,
49
const char *name, const char *help,
50
const char *syntax, uint32_t flags,
51
const char *new_process_action)
52
: CommandObjectParsed(interpreter, name, help, syntax, flags),
53
m_new_process_action(new_process_action) {}
54
55
~CommandObjectProcessLaunchOrAttach() override = default;
56
57
protected:
58
bool StopProcessIfNecessary(Process *process, StateType &state,
59
CommandReturnObject &result) {
60
state = eStateInvalid;
61
if (process) {
62
state = process->GetState();
63
64
if (process->IsAlive() && state != eStateConnected) {
65
std::string message;
66
if (process->GetState() == eStateAttaching)
67
message =
68
llvm::formatv("There is a pending attach, abort it and {0}?",
69
m_new_process_action);
70
else if (process->GetShouldDetach())
71
message = llvm::formatv(
72
"There is a running process, detach from it and {0}?",
73
m_new_process_action);
74
else
75
message =
76
llvm::formatv("There is a running process, kill it and {0}?",
77
m_new_process_action);
78
79
if (!m_interpreter.Confirm(message, true)) {
80
result.SetStatus(eReturnStatusFailed);
81
return false;
82
} else {
83
if (process->GetShouldDetach()) {
84
bool keep_stopped = false;
85
Status detach_error(process->Detach(keep_stopped));
86
if (detach_error.Success()) {
87
result.SetStatus(eReturnStatusSuccessFinishResult);
88
process = nullptr;
89
} else {
90
result.AppendErrorWithFormat(
91
"Failed to detach from process: %s\n",
92
detach_error.AsCString());
93
}
94
} else {
95
Status destroy_error(process->Destroy(false));
96
if (destroy_error.Success()) {
97
result.SetStatus(eReturnStatusSuccessFinishResult);
98
process = nullptr;
99
} else {
100
result.AppendErrorWithFormat("Failed to kill process: %s\n",
101
destroy_error.AsCString());
102
}
103
}
104
}
105
}
106
}
107
return result.Succeeded();
108
}
109
110
std::string m_new_process_action;
111
};
112
113
// CommandObjectProcessLaunch
114
#pragma mark CommandObjectProcessLaunch
115
class CommandObjectProcessLaunch : public CommandObjectProcessLaunchOrAttach {
116
public:
117
CommandObjectProcessLaunch(CommandInterpreter &interpreter)
118
: CommandObjectProcessLaunchOrAttach(
119
interpreter, "process launch",
120
"Launch the executable in the debugger.", nullptr,
121
eCommandRequiresTarget, "restart"),
122
123
m_class_options("scripted process", true, 'C', 'k', 'v', 0) {
124
m_all_options.Append(&m_options);
125
m_all_options.Append(&m_class_options, LLDB_OPT_SET_1 | LLDB_OPT_SET_2,
126
LLDB_OPT_SET_ALL);
127
m_all_options.Finalize();
128
129
AddSimpleArgumentList(eArgTypeRunArgs, eArgRepeatOptional);
130
}
131
132
~CommandObjectProcessLaunch() override = default;
133
134
Options *GetOptions() override { return &m_all_options; }
135
136
std::optional<std::string> GetRepeatCommand(Args &current_command_args,
137
uint32_t index) override {
138
// No repeat for "process launch"...
139
return std::string("");
140
}
141
142
protected:
143
void DoExecute(Args &launch_args, CommandReturnObject &result) override {
144
Debugger &debugger = GetDebugger();
145
Target *target = debugger.GetSelectedTarget().get();
146
// If our listener is nullptr, users aren't allows to launch
147
ModuleSP exe_module_sp = target->GetExecutableModule();
148
149
// If the target already has an executable module, then use that. If it
150
// doesn't then someone must be trying to launch using a path that will
151
// make sense to the remote stub, but doesn't exist on the local host.
152
// In that case use the ExecutableFile that was set in the target's
153
// ProcessLaunchInfo.
154
if (exe_module_sp == nullptr && !target->GetProcessLaunchInfo().GetExecutableFile()) {
155
result.AppendError("no file in target, create a debug target using the "
156
"'target create' command");
157
return;
158
}
159
160
StateType state = eStateInvalid;
161
162
if (!StopProcessIfNecessary(m_exe_ctx.GetProcessPtr(), state, result))
163
return;
164
165
// Determine whether we will disable ASLR or leave it in the default state
166
// (i.e. enabled if the platform supports it). First check if the process
167
// launch options explicitly turn on/off
168
// disabling ASLR. If so, use that setting;
169
// otherwise, use the 'settings target.disable-aslr' setting.
170
bool disable_aslr = false;
171
if (m_options.disable_aslr != eLazyBoolCalculate) {
172
// The user specified an explicit setting on the process launch line.
173
// Use it.
174
disable_aslr = (m_options.disable_aslr == eLazyBoolYes);
175
} else {
176
// The user did not explicitly specify whether to disable ASLR. Fall
177
// back to the target.disable-aslr setting.
178
disable_aslr = target->GetDisableASLR();
179
}
180
181
if (!m_class_options.GetName().empty()) {
182
m_options.launch_info.SetProcessPluginName("ScriptedProcess");
183
ScriptedMetadataSP metadata_sp = std::make_shared<ScriptedMetadata>(
184
m_class_options.GetName(), m_class_options.GetStructuredData());
185
m_options.launch_info.SetScriptedMetadata(metadata_sp);
186
target->SetProcessLaunchInfo(m_options.launch_info);
187
}
188
189
if (disable_aslr)
190
m_options.launch_info.GetFlags().Set(eLaunchFlagDisableASLR);
191
else
192
m_options.launch_info.GetFlags().Clear(eLaunchFlagDisableASLR);
193
194
if (target->GetInheritTCC())
195
m_options.launch_info.GetFlags().Set(eLaunchFlagInheritTCCFromParent);
196
197
if (target->GetDetachOnError())
198
m_options.launch_info.GetFlags().Set(eLaunchFlagDetachOnError);
199
200
if (target->GetDisableSTDIO())
201
m_options.launch_info.GetFlags().Set(eLaunchFlagDisableSTDIO);
202
203
// Merge the launch info environment with the target environment.
204
Environment target_env = target->GetEnvironment();
205
m_options.launch_info.GetEnvironment().insert(target_env.begin(),
206
target_env.end());
207
208
llvm::StringRef target_settings_argv0 = target->GetArg0();
209
210
if (!target_settings_argv0.empty()) {
211
m_options.launch_info.GetArguments().AppendArgument(
212
target_settings_argv0);
213
if (exe_module_sp)
214
m_options.launch_info.SetExecutableFile(
215
exe_module_sp->GetPlatformFileSpec(), false);
216
else
217
m_options.launch_info.SetExecutableFile(target->GetProcessLaunchInfo().GetExecutableFile(), false);
218
} else {
219
if (exe_module_sp)
220
m_options.launch_info.SetExecutableFile(
221
exe_module_sp->GetPlatformFileSpec(), true);
222
else
223
m_options.launch_info.SetExecutableFile(target->GetProcessLaunchInfo().GetExecutableFile(), true);
224
}
225
226
if (launch_args.GetArgumentCount() == 0) {
227
m_options.launch_info.GetArguments().AppendArguments(
228
target->GetProcessLaunchInfo().GetArguments());
229
} else {
230
m_options.launch_info.GetArguments().AppendArguments(launch_args);
231
// Save the arguments for subsequent runs in the current target.
232
target->SetRunArguments(launch_args);
233
}
234
235
StreamString stream;
236
Status error = target->Launch(m_options.launch_info, &stream);
237
238
if (error.Success()) {
239
ProcessSP process_sp(target->GetProcessSP());
240
if (process_sp) {
241
// There is a race condition where this thread will return up the call
242
// stack to the main command handler and show an (lldb) prompt before
243
// HandlePrivateEvent (from PrivateStateThread) has a chance to call
244
// PushProcessIOHandler().
245
process_sp->SyncIOHandler(0, std::chrono::seconds(2));
246
247
// If we didn't have a local executable, then we wouldn't have had an
248
// executable module before launch.
249
if (!exe_module_sp)
250
exe_module_sp = target->GetExecutableModule();
251
if (!exe_module_sp) {
252
result.AppendWarning("Could not get executable module after launch.");
253
} else {
254
255
const char *archname =
256
exe_module_sp->GetArchitecture().GetArchitectureName();
257
result.AppendMessageWithFormat(
258
"Process %" PRIu64 " launched: '%s' (%s)\n", process_sp->GetID(),
259
exe_module_sp->GetFileSpec().GetPath().c_str(), archname);
260
}
261
result.SetStatus(eReturnStatusSuccessFinishResult);
262
// This message will refer to an event that happened after the process
263
// launched.
264
llvm::StringRef data = stream.GetString();
265
if (!data.empty())
266
result.AppendMessage(data);
267
result.SetDidChangeProcessState(true);
268
} else {
269
result.AppendError(
270
"no error returned from Target::Launch, and target has no process");
271
}
272
} else {
273
result.AppendError(error.AsCString());
274
}
275
}
276
277
CommandOptionsProcessLaunch m_options;
278
OptionGroupPythonClassWithDict m_class_options;
279
OptionGroupOptions m_all_options;
280
};
281
282
#define LLDB_OPTIONS_process_attach
283
#include "CommandOptions.inc"
284
285
#pragma mark CommandObjectProcessAttach
286
class CommandObjectProcessAttach : public CommandObjectProcessLaunchOrAttach {
287
public:
288
CommandObjectProcessAttach(CommandInterpreter &interpreter)
289
: CommandObjectProcessLaunchOrAttach(
290
interpreter, "process attach", "Attach to a process.",
291
"process attach <cmd-options>", 0, "attach"),
292
m_class_options("scripted process", true, 'C', 'k', 'v', 0) {
293
m_all_options.Append(&m_options);
294
m_all_options.Append(&m_class_options, LLDB_OPT_SET_1 | LLDB_OPT_SET_2,
295
LLDB_OPT_SET_ALL);
296
m_all_options.Finalize();
297
}
298
299
~CommandObjectProcessAttach() override = default;
300
301
Options *GetOptions() override { return &m_all_options; }
302
303
protected:
304
void DoExecute(Args &command, CommandReturnObject &result) override {
305
PlatformSP platform_sp(
306
GetDebugger().GetPlatformList().GetSelectedPlatform());
307
308
Target *target = GetDebugger().GetSelectedTarget().get();
309
// N.B. The attach should be synchronous. It doesn't help much to get the
310
// prompt back between initiating the attach and the target actually
311
// stopping. So even if the interpreter is set to be asynchronous, we wait
312
// for the stop ourselves here.
313
314
StateType state = eStateInvalid;
315
Process *process = m_exe_ctx.GetProcessPtr();
316
317
if (!StopProcessIfNecessary(process, state, result))
318
return;
319
320
if (target == nullptr) {
321
// If there isn't a current target create one.
322
TargetSP new_target_sp;
323
Status error;
324
325
error = GetDebugger().GetTargetList().CreateTarget(
326
GetDebugger(), "", "", eLoadDependentsNo,
327
nullptr, // No platform options
328
new_target_sp);
329
target = new_target_sp.get();
330
if (target == nullptr || error.Fail()) {
331
result.AppendError(error.AsCString("Error creating target"));
332
return;
333
}
334
}
335
336
if (!m_class_options.GetName().empty()) {
337
m_options.attach_info.SetProcessPluginName("ScriptedProcess");
338
ScriptedMetadataSP metadata_sp = std::make_shared<ScriptedMetadata>(
339
m_class_options.GetName(), m_class_options.GetStructuredData());
340
m_options.attach_info.SetScriptedMetadata(metadata_sp);
341
}
342
343
// Record the old executable module, we want to issue a warning if the
344
// process of attaching changed the current executable (like somebody said
345
// "file foo" then attached to a PID whose executable was bar.)
346
347
ModuleSP old_exec_module_sp = target->GetExecutableModule();
348
ArchSpec old_arch_spec = target->GetArchitecture();
349
350
StreamString stream;
351
ProcessSP process_sp;
352
const auto error = target->Attach(m_options.attach_info, &stream);
353
if (error.Success()) {
354
process_sp = target->GetProcessSP();
355
if (process_sp) {
356
result.AppendMessage(stream.GetString());
357
result.SetStatus(eReturnStatusSuccessFinishNoResult);
358
result.SetDidChangeProcessState(true);
359
} else {
360
result.AppendError(
361
"no error returned from Target::Attach, and target has no process");
362
}
363
} else {
364
result.AppendErrorWithFormat("attach failed: %s\n", error.AsCString());
365
}
366
367
if (!result.Succeeded())
368
return;
369
370
// Okay, we're done. Last step is to warn if the executable module has
371
// changed:
372
char new_path[PATH_MAX];
373
ModuleSP new_exec_module_sp(target->GetExecutableModule());
374
if (!old_exec_module_sp) {
375
// We might not have a module if we attached to a raw pid...
376
if (new_exec_module_sp) {
377
new_exec_module_sp->GetFileSpec().GetPath(new_path, PATH_MAX);
378
result.AppendMessageWithFormat("Executable module set to \"%s\".\n",
379
new_path);
380
}
381
} else if (old_exec_module_sp->GetFileSpec() !=
382
new_exec_module_sp->GetFileSpec()) {
383
char old_path[PATH_MAX];
384
385
old_exec_module_sp->GetFileSpec().GetPath(old_path, PATH_MAX);
386
new_exec_module_sp->GetFileSpec().GetPath(new_path, PATH_MAX);
387
388
result.AppendWarningWithFormat(
389
"Executable module changed from \"%s\" to \"%s\".\n", old_path,
390
new_path);
391
}
392
393
if (!old_arch_spec.IsValid()) {
394
result.AppendMessageWithFormat(
395
"Architecture set to: %s.\n",
396
target->GetArchitecture().GetTriple().getTriple().c_str());
397
} else if (!old_arch_spec.IsExactMatch(target->GetArchitecture())) {
398
result.AppendWarningWithFormat(
399
"Architecture changed from %s to %s.\n",
400
old_arch_spec.GetTriple().getTriple().c_str(),
401
target->GetArchitecture().GetTriple().getTriple().c_str());
402
}
403
404
// This supports the use-case scenario of immediately continuing the
405
// process once attached.
406
if (m_options.attach_info.GetContinueOnceAttached()) {
407
// We have made a process but haven't told the interpreter about it yet,
408
// so CheckRequirements will fail for "process continue". Set the override
409
// here:
410
ExecutionContext exe_ctx(process_sp);
411
m_interpreter.HandleCommand("process continue", eLazyBoolNo, exe_ctx, result);
412
}
413
}
414
415
CommandOptionsProcessAttach m_options;
416
OptionGroupPythonClassWithDict m_class_options;
417
OptionGroupOptions m_all_options;
418
};
419
420
// CommandObjectProcessContinue
421
422
#define LLDB_OPTIONS_process_continue
423
#include "CommandOptions.inc"
424
425
#pragma mark CommandObjectProcessContinue
426
427
class CommandObjectProcessContinue : public CommandObjectParsed {
428
public:
429
CommandObjectProcessContinue(CommandInterpreter &interpreter)
430
: CommandObjectParsed(
431
interpreter, "process continue",
432
"Continue execution of all threads in the current process.",
433
"process continue",
434
eCommandRequiresProcess | eCommandTryTargetAPILock |
435
eCommandProcessMustBeLaunched | eCommandProcessMustBePaused) {}
436
437
~CommandObjectProcessContinue() override = default;
438
439
protected:
440
class CommandOptions : public Options {
441
public:
442
CommandOptions() {
443
// Keep default values of all options in one place: OptionParsingStarting
444
// ()
445
OptionParsingStarting(nullptr);
446
}
447
448
~CommandOptions() override = default;
449
450
Status SetOptionValue(uint32_t option_idx, llvm::StringRef option_arg,
451
ExecutionContext *exe_ctx) override {
452
Status error;
453
const int short_option = m_getopt_table[option_idx].val;
454
switch (short_option) {
455
case 'i':
456
if (option_arg.getAsInteger(0, m_ignore))
457
error.SetErrorStringWithFormat(
458
"invalid value for ignore option: \"%s\", should be a number.",
459
option_arg.str().c_str());
460
break;
461
case 'b':
462
m_run_to_bkpt_args.AppendArgument(option_arg);
463
m_any_bkpts_specified = true;
464
break;
465
default:
466
llvm_unreachable("Unimplemented option");
467
}
468
return error;
469
}
470
471
void OptionParsingStarting(ExecutionContext *execution_context) override {
472
m_ignore = 0;
473
m_run_to_bkpt_args.Clear();
474
m_any_bkpts_specified = false;
475
}
476
477
llvm::ArrayRef<OptionDefinition> GetDefinitions() override {
478
return llvm::ArrayRef(g_process_continue_options);
479
}
480
481
uint32_t m_ignore = 0;
482
Args m_run_to_bkpt_args;
483
bool m_any_bkpts_specified = false;
484
};
485
486
void DoExecute(Args &command, CommandReturnObject &result) override {
487
Process *process = m_exe_ctx.GetProcessPtr();
488
bool synchronous_execution = m_interpreter.GetSynchronous();
489
StateType state = process->GetState();
490
if (state == eStateStopped) {
491
if (m_options.m_ignore > 0) {
492
ThreadSP sel_thread_sp(GetDefaultThread()->shared_from_this());
493
if (sel_thread_sp) {
494
StopInfoSP stop_info_sp = sel_thread_sp->GetStopInfo();
495
if (stop_info_sp &&
496
stop_info_sp->GetStopReason() == eStopReasonBreakpoint) {
497
lldb::break_id_t bp_site_id =
498
(lldb::break_id_t)stop_info_sp->GetValue();
499
BreakpointSiteSP bp_site_sp(
500
process->GetBreakpointSiteList().FindByID(bp_site_id));
501
if (bp_site_sp) {
502
const size_t num_owners = bp_site_sp->GetNumberOfConstituents();
503
for (size_t i = 0; i < num_owners; i++) {
504
Breakpoint &bp_ref =
505
bp_site_sp->GetConstituentAtIndex(i)->GetBreakpoint();
506
if (!bp_ref.IsInternal()) {
507
bp_ref.SetIgnoreCount(m_options.m_ignore);
508
}
509
}
510
}
511
}
512
}
513
}
514
515
Target *target = m_exe_ctx.GetTargetPtr();
516
BreakpointIDList run_to_bkpt_ids;
517
// Don't pass an empty run_to_breakpoint list, as Verify will look for the
518
// default breakpoint.
519
if (m_options.m_run_to_bkpt_args.GetArgumentCount() > 0)
520
CommandObjectMultiwordBreakpoint::VerifyBreakpointOrLocationIDs(
521
m_options.m_run_to_bkpt_args, target, result, &run_to_bkpt_ids,
522
BreakpointName::Permissions::disablePerm);
523
if (!result.Succeeded()) {
524
return;
525
}
526
result.Clear();
527
if (m_options.m_any_bkpts_specified && run_to_bkpt_ids.GetSize() == 0) {
528
result.AppendError("continue-to breakpoints did not specify any actual "
529
"breakpoints or locations");
530
return;
531
}
532
533
// First figure out which breakpoints & locations were specified by the
534
// user:
535
size_t num_run_to_bkpt_ids = run_to_bkpt_ids.GetSize();
536
std::vector<break_id_t> bkpts_disabled;
537
std::vector<BreakpointID> locs_disabled;
538
if (num_run_to_bkpt_ids != 0) {
539
// Go through the ID's specified, and separate the breakpoints from are
540
// the breakpoint.location specifications since the latter require
541
// special handling. We also figure out whether there's at least one
542
// specifier in the set that is enabled.
543
BreakpointList &bkpt_list = target->GetBreakpointList();
544
std::unordered_set<break_id_t> bkpts_seen;
545
std::unordered_set<break_id_t> bkpts_with_locs_seen;
546
BreakpointIDList with_locs;
547
bool any_enabled = false;
548
549
for (size_t idx = 0; idx < num_run_to_bkpt_ids; idx++) {
550
BreakpointID bkpt_id = run_to_bkpt_ids.GetBreakpointIDAtIndex(idx);
551
break_id_t bp_id = bkpt_id.GetBreakpointID();
552
break_id_t loc_id = bkpt_id.GetLocationID();
553
BreakpointSP bp_sp
554
= bkpt_list.FindBreakpointByID(bp_id);
555
// Note, VerifyBreakpointOrLocationIDs checks for existence, so we
556
// don't need to do it again here.
557
if (bp_sp->IsEnabled()) {
558
if (loc_id == LLDB_INVALID_BREAK_ID) {
559
// A breakpoint (without location) was specified. Make sure that
560
// at least one of the locations is enabled.
561
size_t num_locations = bp_sp->GetNumLocations();
562
for (size_t loc_idx = 0; loc_idx < num_locations; loc_idx++) {
563
BreakpointLocationSP loc_sp
564
= bp_sp->GetLocationAtIndex(loc_idx);
565
if (loc_sp->IsEnabled()) {
566
any_enabled = true;
567
break;
568
}
569
}
570
} else {
571
// A location was specified, check if it was enabled:
572
BreakpointLocationSP loc_sp = bp_sp->FindLocationByID(loc_id);
573
if (loc_sp->IsEnabled())
574
any_enabled = true;
575
}
576
577
// Then sort the bp & bp.loc entries for later use:
578
if (bkpt_id.GetLocationID() == LLDB_INVALID_BREAK_ID)
579
bkpts_seen.insert(bkpt_id.GetBreakpointID());
580
else {
581
bkpts_with_locs_seen.insert(bkpt_id.GetBreakpointID());
582
with_locs.AddBreakpointID(bkpt_id);
583
}
584
}
585
}
586
// Do all the error checking here so once we start disabling we don't
587
// have to back out half-way through.
588
589
// Make sure at least one of the specified breakpoints is enabled.
590
if (!any_enabled) {
591
result.AppendError("at least one of the continue-to breakpoints must "
592
"be enabled.");
593
return;
594
}
595
596
// Also, if you specify BOTH a breakpoint and one of it's locations,
597
// we flag that as an error, since it won't do what you expect, the
598
// breakpoint directive will mean "run to all locations", which is not
599
// what the location directive means...
600
for (break_id_t bp_id : bkpts_with_locs_seen) {
601
if (bkpts_seen.count(bp_id)) {
602
result.AppendErrorWithFormatv("can't specify both a breakpoint and "
603
"one of its locations: {0}", bp_id);
604
}
605
}
606
607
// Now go through the breakpoints in the target, disabling all the ones
608
// that the user didn't mention:
609
for (BreakpointSP bp_sp : bkpt_list.Breakpoints()) {
610
break_id_t bp_id = bp_sp->GetID();
611
// Handle the case where no locations were specified. Note we don't
612
// have to worry about the case where a breakpoint and one of its
613
// locations are both in the lists, we've already disallowed that.
614
if (!bkpts_with_locs_seen.count(bp_id)) {
615
if (!bkpts_seen.count(bp_id) && bp_sp->IsEnabled()) {
616
bkpts_disabled.push_back(bp_id);
617
bp_sp->SetEnabled(false);
618
}
619
continue;
620
}
621
// Next, handle the case where a location was specified:
622
// Run through all the locations of this breakpoint and disable
623
// the ones that aren't on our "with locations" BreakpointID list:
624
size_t num_locations = bp_sp->GetNumLocations();
625
BreakpointID tmp_id(bp_id, LLDB_INVALID_BREAK_ID);
626
for (size_t loc_idx = 0; loc_idx < num_locations; loc_idx++) {
627
BreakpointLocationSP loc_sp = bp_sp->GetLocationAtIndex(loc_idx);
628
tmp_id.SetBreakpointLocationID(loc_idx);
629
if (!with_locs.Contains(tmp_id) && loc_sp->IsEnabled()) {
630
locs_disabled.push_back(tmp_id);
631
loc_sp->SetEnabled(false);
632
}
633
}
634
}
635
}
636
637
{ // Scope for thread list mutex:
638
std::lock_guard<std::recursive_mutex> guard(
639
process->GetThreadList().GetMutex());
640
const uint32_t num_threads = process->GetThreadList().GetSize();
641
642
// Set the actions that the threads should each take when resuming
643
for (uint32_t idx = 0; idx < num_threads; ++idx) {
644
const bool override_suspend = false;
645
process->GetThreadList().GetThreadAtIndex(idx)->SetResumeState(
646
eStateRunning, override_suspend);
647
}
648
}
649
650
const uint32_t iohandler_id = process->GetIOHandlerID();
651
652
StreamString stream;
653
Status error;
654
// For now we can only do -b with synchronous:
655
bool old_sync = GetDebugger().GetAsyncExecution();
656
657
if (run_to_bkpt_ids.GetSize() != 0) {
658
GetDebugger().SetAsyncExecution(false);
659
synchronous_execution = true;
660
}
661
if (synchronous_execution)
662
error = process->ResumeSynchronous(&stream);
663
else
664
error = process->Resume();
665
666
if (run_to_bkpt_ids.GetSize() != 0) {
667
GetDebugger().SetAsyncExecution(old_sync);
668
}
669
670
// Now re-enable the breakpoints we disabled:
671
BreakpointList &bkpt_list = target->GetBreakpointList();
672
for (break_id_t bp_id : bkpts_disabled) {
673
BreakpointSP bp_sp = bkpt_list.FindBreakpointByID(bp_id);
674
if (bp_sp)
675
bp_sp->SetEnabled(true);
676
}
677
for (const BreakpointID &bkpt_id : locs_disabled) {
678
BreakpointSP bp_sp
679
= bkpt_list.FindBreakpointByID(bkpt_id.GetBreakpointID());
680
if (bp_sp) {
681
BreakpointLocationSP loc_sp
682
= bp_sp->FindLocationByID(bkpt_id.GetLocationID());
683
if (loc_sp)
684
loc_sp->SetEnabled(true);
685
}
686
}
687
688
if (error.Success()) {
689
// There is a race condition where this thread will return up the call
690
// stack to the main command handler and show an (lldb) prompt before
691
// HandlePrivateEvent (from PrivateStateThread) has a chance to call
692
// PushProcessIOHandler().
693
process->SyncIOHandler(iohandler_id, std::chrono::seconds(2));
694
695
result.AppendMessageWithFormat("Process %" PRIu64 " resuming\n",
696
process->GetID());
697
if (synchronous_execution) {
698
// If any state changed events had anything to say, add that to the
699
// result
700
result.AppendMessage(stream.GetString());
701
702
result.SetDidChangeProcessState(true);
703
result.SetStatus(eReturnStatusSuccessFinishNoResult);
704
} else {
705
result.SetStatus(eReturnStatusSuccessContinuingNoResult);
706
}
707
} else {
708
result.AppendErrorWithFormat("Failed to resume process: %s.\n",
709
error.AsCString());
710
}
711
} else {
712
result.AppendErrorWithFormat(
713
"Process cannot be continued from its current state (%s).\n",
714
StateAsCString(state));
715
}
716
}
717
718
Options *GetOptions() override { return &m_options; }
719
720
CommandOptions m_options;
721
};
722
723
// CommandObjectProcessDetach
724
#define LLDB_OPTIONS_process_detach
725
#include "CommandOptions.inc"
726
727
#pragma mark CommandObjectProcessDetach
728
729
class CommandObjectProcessDetach : public CommandObjectParsed {
730
public:
731
class CommandOptions : public Options {
732
public:
733
CommandOptions() { OptionParsingStarting(nullptr); }
734
735
~CommandOptions() override = default;
736
737
Status SetOptionValue(uint32_t option_idx, llvm::StringRef option_arg,
738
ExecutionContext *execution_context) override {
739
Status error;
740
const int short_option = m_getopt_table[option_idx].val;
741
742
switch (short_option) {
743
case 's':
744
bool tmp_result;
745
bool success;
746
tmp_result = OptionArgParser::ToBoolean(option_arg, false, &success);
747
if (!success)
748
error.SetErrorStringWithFormat("invalid boolean option: \"%s\"",
749
option_arg.str().c_str());
750
else {
751
if (tmp_result)
752
m_keep_stopped = eLazyBoolYes;
753
else
754
m_keep_stopped = eLazyBoolNo;
755
}
756
break;
757
default:
758
llvm_unreachable("Unimplemented option");
759
}
760
return error;
761
}
762
763
void OptionParsingStarting(ExecutionContext *execution_context) override {
764
m_keep_stopped = eLazyBoolCalculate;
765
}
766
767
llvm::ArrayRef<OptionDefinition> GetDefinitions() override {
768
return llvm::ArrayRef(g_process_detach_options);
769
}
770
771
// Instance variables to hold the values for command options.
772
LazyBool m_keep_stopped;
773
};
774
775
CommandObjectProcessDetach(CommandInterpreter &interpreter)
776
: CommandObjectParsed(interpreter, "process detach",
777
"Detach from the current target process.",
778
"process detach",
779
eCommandRequiresProcess | eCommandTryTargetAPILock |
780
eCommandProcessMustBeLaunched) {}
781
782
~CommandObjectProcessDetach() override = default;
783
784
Options *GetOptions() override { return &m_options; }
785
786
protected:
787
void DoExecute(Args &command, CommandReturnObject &result) override {
788
Process *process = m_exe_ctx.GetProcessPtr();
789
// FIXME: This will be a Command Option:
790
bool keep_stopped;
791
if (m_options.m_keep_stopped == eLazyBoolCalculate) {
792
// Check the process default:
793
keep_stopped = process->GetDetachKeepsStopped();
794
} else if (m_options.m_keep_stopped == eLazyBoolYes)
795
keep_stopped = true;
796
else
797
keep_stopped = false;
798
799
Status error(process->Detach(keep_stopped));
800
if (error.Success()) {
801
result.SetStatus(eReturnStatusSuccessFinishResult);
802
} else {
803
result.AppendErrorWithFormat("Detach failed: %s\n", error.AsCString());
804
}
805
}
806
807
CommandOptions m_options;
808
};
809
810
// CommandObjectProcessConnect
811
#define LLDB_OPTIONS_process_connect
812
#include "CommandOptions.inc"
813
814
#pragma mark CommandObjectProcessConnect
815
816
class CommandObjectProcessConnect : public CommandObjectParsed {
817
public:
818
class CommandOptions : public Options {
819
public:
820
CommandOptions() {
821
// Keep default values of all options in one place: OptionParsingStarting
822
// ()
823
OptionParsingStarting(nullptr);
824
}
825
826
~CommandOptions() override = default;
827
828
Status SetOptionValue(uint32_t option_idx, llvm::StringRef option_arg,
829
ExecutionContext *execution_context) override {
830
Status error;
831
const int short_option = m_getopt_table[option_idx].val;
832
833
switch (short_option) {
834
case 'p':
835
plugin_name.assign(std::string(option_arg));
836
break;
837
838
default:
839
llvm_unreachable("Unimplemented option");
840
}
841
return error;
842
}
843
844
void OptionParsingStarting(ExecutionContext *execution_context) override {
845
plugin_name.clear();
846
}
847
848
llvm::ArrayRef<OptionDefinition> GetDefinitions() override {
849
return llvm::ArrayRef(g_process_connect_options);
850
}
851
852
// Instance variables to hold the values for command options.
853
854
std::string plugin_name;
855
};
856
857
CommandObjectProcessConnect(CommandInterpreter &interpreter)
858
: CommandObjectParsed(interpreter, "process connect",
859
"Connect to a remote debug service.",
860
"process connect <remote-url>", 0) {
861
AddSimpleArgumentList(eArgTypeConnectURL);
862
}
863
864
~CommandObjectProcessConnect() override = default;
865
866
Options *GetOptions() override { return &m_options; }
867
868
protected:
869
void DoExecute(Args &command, CommandReturnObject &result) override {
870
if (command.GetArgumentCount() != 1) {
871
result.AppendErrorWithFormat(
872
"'%s' takes exactly one argument:\nUsage: %s\n", m_cmd_name.c_str(),
873
m_cmd_syntax.c_str());
874
return;
875
}
876
877
Process *process = m_exe_ctx.GetProcessPtr();
878
if (process && process->IsAlive()) {
879
result.AppendErrorWithFormat(
880
"Process %" PRIu64
881
" is currently being debugged, kill the process before connecting.\n",
882
process->GetID());
883
return;
884
}
885
886
const char *plugin_name = nullptr;
887
if (!m_options.plugin_name.empty())
888
plugin_name = m_options.plugin_name.c_str();
889
890
Status error;
891
Debugger &debugger = GetDebugger();
892
PlatformSP platform_sp = m_interpreter.GetPlatform(true);
893
ProcessSP process_sp =
894
debugger.GetAsyncExecution()
895
? platform_sp->ConnectProcess(
896
command.GetArgumentAtIndex(0), plugin_name, debugger,
897
debugger.GetSelectedTarget().get(), error)
898
: platform_sp->ConnectProcessSynchronous(
899
command.GetArgumentAtIndex(0), plugin_name, debugger,
900
result.GetOutputStream(), debugger.GetSelectedTarget().get(),
901
error);
902
if (error.Fail() || process_sp == nullptr) {
903
result.AppendError(error.AsCString("Error connecting to the process"));
904
}
905
}
906
907
CommandOptions m_options;
908
};
909
910
// CommandObjectProcessPlugin
911
#pragma mark CommandObjectProcessPlugin
912
913
class CommandObjectProcessPlugin : public CommandObjectProxy {
914
public:
915
CommandObjectProcessPlugin(CommandInterpreter &interpreter)
916
: CommandObjectProxy(
917
interpreter, "process plugin",
918
"Send a custom command to the current target process plug-in.",
919
"process plugin <args>", 0) {}
920
921
~CommandObjectProcessPlugin() override = default;
922
923
CommandObject *GetProxyCommandObject() override {
924
Process *process = m_interpreter.GetExecutionContext().GetProcessPtr();
925
if (process)
926
return process->GetPluginCommandObject();
927
return nullptr;
928
}
929
};
930
931
// CommandObjectProcessLoad
932
#define LLDB_OPTIONS_process_load
933
#include "CommandOptions.inc"
934
935
#pragma mark CommandObjectProcessLoad
936
937
class CommandObjectProcessLoad : public CommandObjectParsed {
938
public:
939
class CommandOptions : public Options {
940
public:
941
CommandOptions() {
942
// Keep default values of all options in one place: OptionParsingStarting
943
// ()
944
OptionParsingStarting(nullptr);
945
}
946
947
~CommandOptions() override = default;
948
949
Status SetOptionValue(uint32_t option_idx, llvm::StringRef option_arg,
950
ExecutionContext *execution_context) override {
951
Status error;
952
const int short_option = m_getopt_table[option_idx].val;
953
ArchSpec arch =
954
execution_context->GetProcessPtr()->GetSystemArchitecture();
955
switch (short_option) {
956
case 'i':
957
do_install = true;
958
if (!option_arg.empty())
959
install_path.SetFile(option_arg, arch.GetTriple());
960
break;
961
default:
962
llvm_unreachable("Unimplemented option");
963
}
964
return error;
965
}
966
967
void OptionParsingStarting(ExecutionContext *execution_context) override {
968
do_install = false;
969
install_path.Clear();
970
}
971
972
llvm::ArrayRef<OptionDefinition> GetDefinitions() override {
973
return llvm::ArrayRef(g_process_load_options);
974
}
975
976
// Instance variables to hold the values for command options.
977
bool do_install;
978
FileSpec install_path;
979
};
980
981
CommandObjectProcessLoad(CommandInterpreter &interpreter)
982
: CommandObjectParsed(interpreter, "process load",
983
"Load a shared library into the current process.",
984
"process load <filename> [<filename> ...]",
985
eCommandRequiresProcess | eCommandTryTargetAPILock |
986
eCommandProcessMustBeLaunched |
987
eCommandProcessMustBePaused) {
988
AddSimpleArgumentList(eArgTypePath, eArgRepeatPlus);
989
}
990
991
~CommandObjectProcessLoad() override = default;
992
993
void
994
HandleArgumentCompletion(CompletionRequest &request,
995
OptionElementVector &opt_element_vector) override {
996
if (!m_exe_ctx.HasProcessScope())
997
return;
998
CommandObject::HandleArgumentCompletion(request, opt_element_vector);
999
}
1000
1001
Options *GetOptions() override { return &m_options; }
1002
1003
protected:
1004
void DoExecute(Args &command, CommandReturnObject &result) override {
1005
Process *process = m_exe_ctx.GetProcessPtr();
1006
1007
for (auto &entry : command.entries()) {
1008
Status error;
1009
PlatformSP platform = process->GetTarget().GetPlatform();
1010
llvm::StringRef image_path = entry.ref();
1011
uint32_t image_token = LLDB_INVALID_IMAGE_TOKEN;
1012
1013
if (!m_options.do_install) {
1014
FileSpec image_spec(image_path);
1015
platform->ResolveRemotePath(image_spec, image_spec);
1016
image_token =
1017
platform->LoadImage(process, FileSpec(), image_spec, error);
1018
} else if (m_options.install_path) {
1019
FileSpec image_spec(image_path);
1020
FileSystem::Instance().Resolve(image_spec);
1021
platform->ResolveRemotePath(m_options.install_path,
1022
m_options.install_path);
1023
image_token = platform->LoadImage(process, image_spec,
1024
m_options.install_path, error);
1025
} else {
1026
FileSpec image_spec(image_path);
1027
FileSystem::Instance().Resolve(image_spec);
1028
image_token =
1029
platform->LoadImage(process, image_spec, FileSpec(), error);
1030
}
1031
1032
if (image_token != LLDB_INVALID_IMAGE_TOKEN) {
1033
result.AppendMessageWithFormat(
1034
"Loading \"%s\"...ok\nImage %u loaded.\n", image_path.str().c_str(),
1035
image_token);
1036
result.SetStatus(eReturnStatusSuccessFinishResult);
1037
} else {
1038
result.AppendErrorWithFormat("failed to load '%s': %s",
1039
image_path.str().c_str(),
1040
error.AsCString());
1041
}
1042
}
1043
}
1044
1045
CommandOptions m_options;
1046
};
1047
1048
// CommandObjectProcessUnload
1049
#pragma mark CommandObjectProcessUnload
1050
1051
class CommandObjectProcessUnload : public CommandObjectParsed {
1052
public:
1053
CommandObjectProcessUnload(CommandInterpreter &interpreter)
1054
: CommandObjectParsed(
1055
interpreter, "process unload",
1056
"Unload a shared library from the current process using the index "
1057
"returned by a previous call to \"process load\".",
1058
"process unload <index>",
1059
eCommandRequiresProcess | eCommandTryTargetAPILock |
1060
eCommandProcessMustBeLaunched | eCommandProcessMustBePaused) {
1061
AddSimpleArgumentList(eArgTypeUnsignedInteger);
1062
}
1063
1064
~CommandObjectProcessUnload() override = default;
1065
1066
void
1067
HandleArgumentCompletion(CompletionRequest &request,
1068
OptionElementVector &opt_element_vector) override {
1069
1070
if (request.GetCursorIndex() || !m_exe_ctx.HasProcessScope())
1071
return;
1072
1073
Process *process = m_exe_ctx.GetProcessPtr();
1074
1075
const std::vector<lldb::addr_t> &tokens = process->GetImageTokens();
1076
const size_t token_num = tokens.size();
1077
for (size_t i = 0; i < token_num; ++i) {
1078
if (tokens[i] == LLDB_INVALID_IMAGE_TOKEN)
1079
continue;
1080
request.TryCompleteCurrentArg(std::to_string(i));
1081
}
1082
}
1083
1084
protected:
1085
void DoExecute(Args &command, CommandReturnObject &result) override {
1086
Process *process = m_exe_ctx.GetProcessPtr();
1087
1088
for (auto &entry : command.entries()) {
1089
uint32_t image_token;
1090
if (entry.ref().getAsInteger(0, image_token)) {
1091
result.AppendErrorWithFormat("invalid image index argument '%s'",
1092
entry.ref().str().c_str());
1093
break;
1094
} else {
1095
Status error(process->GetTarget().GetPlatform()->UnloadImage(
1096
process, image_token));
1097
if (error.Success()) {
1098
result.AppendMessageWithFormat(
1099
"Unloading shared library with index %u...ok\n", image_token);
1100
result.SetStatus(eReturnStatusSuccessFinishResult);
1101
} else {
1102
result.AppendErrorWithFormat("failed to unload image: %s",
1103
error.AsCString());
1104
break;
1105
}
1106
}
1107
}
1108
}
1109
};
1110
1111
// CommandObjectProcessSignal
1112
#pragma mark CommandObjectProcessSignal
1113
1114
class CommandObjectProcessSignal : public CommandObjectParsed {
1115
public:
1116
CommandObjectProcessSignal(CommandInterpreter &interpreter)
1117
: CommandObjectParsed(
1118
interpreter, "process signal",
1119
"Send a UNIX signal to the current target process.", nullptr,
1120
eCommandRequiresProcess | eCommandTryTargetAPILock) {
1121
AddSimpleArgumentList(eArgTypeUnixSignal);
1122
}
1123
1124
~CommandObjectProcessSignal() override = default;
1125
1126
void
1127
HandleArgumentCompletion(CompletionRequest &request,
1128
OptionElementVector &opt_element_vector) override {
1129
if (!m_exe_ctx.HasProcessScope() || request.GetCursorIndex() != 0)
1130
return;
1131
1132
UnixSignalsSP signals = m_exe_ctx.GetProcessPtr()->GetUnixSignals();
1133
int signo = signals->GetFirstSignalNumber();
1134
while (signo != LLDB_INVALID_SIGNAL_NUMBER) {
1135
request.TryCompleteCurrentArg(signals->GetSignalAsStringRef(signo));
1136
signo = signals->GetNextSignalNumber(signo);
1137
}
1138
}
1139
1140
protected:
1141
void DoExecute(Args &command, CommandReturnObject &result) override {
1142
Process *process = m_exe_ctx.GetProcessPtr();
1143
1144
if (command.GetArgumentCount() == 1) {
1145
int signo = LLDB_INVALID_SIGNAL_NUMBER;
1146
1147
const char *signal_name = command.GetArgumentAtIndex(0);
1148
if (::isxdigit(signal_name[0])) {
1149
if (!llvm::to_integer(signal_name, signo))
1150
signo = LLDB_INVALID_SIGNAL_NUMBER;
1151
} else
1152
signo = process->GetUnixSignals()->GetSignalNumberFromName(signal_name);
1153
1154
if (signo == LLDB_INVALID_SIGNAL_NUMBER) {
1155
result.AppendErrorWithFormat("Invalid signal argument '%s'.\n",
1156
command.GetArgumentAtIndex(0));
1157
} else {
1158
Status error(process->Signal(signo));
1159
if (error.Success()) {
1160
result.SetStatus(eReturnStatusSuccessFinishResult);
1161
} else {
1162
result.AppendErrorWithFormat("Failed to send signal %i: %s\n", signo,
1163
error.AsCString());
1164
}
1165
}
1166
} else {
1167
result.AppendErrorWithFormat(
1168
"'%s' takes exactly one signal number argument:\nUsage: %s\n",
1169
m_cmd_name.c_str(), m_cmd_syntax.c_str());
1170
}
1171
}
1172
};
1173
1174
// CommandObjectProcessInterrupt
1175
#pragma mark CommandObjectProcessInterrupt
1176
1177
class CommandObjectProcessInterrupt : public CommandObjectParsed {
1178
public:
1179
CommandObjectProcessInterrupt(CommandInterpreter &interpreter)
1180
: CommandObjectParsed(interpreter, "process interrupt",
1181
"Interrupt the current target process.",
1182
"process interrupt",
1183
eCommandRequiresProcess | eCommandTryTargetAPILock |
1184
eCommandProcessMustBeLaunched) {}
1185
1186
~CommandObjectProcessInterrupt() override = default;
1187
1188
protected:
1189
void DoExecute(Args &command, CommandReturnObject &result) override {
1190
Process *process = m_exe_ctx.GetProcessPtr();
1191
if (process == nullptr) {
1192
result.AppendError("no process to halt");
1193
return;
1194
}
1195
1196
bool clear_thread_plans = true;
1197
Status error(process->Halt(clear_thread_plans));
1198
if (error.Success()) {
1199
result.SetStatus(eReturnStatusSuccessFinishResult);
1200
} else {
1201
result.AppendErrorWithFormat("Failed to halt process: %s\n",
1202
error.AsCString());
1203
}
1204
}
1205
};
1206
1207
// CommandObjectProcessKill
1208
#pragma mark CommandObjectProcessKill
1209
1210
class CommandObjectProcessKill : public CommandObjectParsed {
1211
public:
1212
CommandObjectProcessKill(CommandInterpreter &interpreter)
1213
: CommandObjectParsed(interpreter, "process kill",
1214
"Terminate the current target process.",
1215
"process kill",
1216
eCommandRequiresProcess | eCommandTryTargetAPILock |
1217
eCommandProcessMustBeLaunched) {}
1218
1219
~CommandObjectProcessKill() override = default;
1220
1221
protected:
1222
void DoExecute(Args &command, CommandReturnObject &result) override {
1223
Process *process = m_exe_ctx.GetProcessPtr();
1224
if (process == nullptr) {
1225
result.AppendError("no process to kill");
1226
return;
1227
}
1228
1229
Status error(process->Destroy(true));
1230
if (error.Success()) {
1231
result.SetStatus(eReturnStatusSuccessFinishResult);
1232
} else {
1233
result.AppendErrorWithFormat("Failed to kill process: %s\n",
1234
error.AsCString());
1235
}
1236
}
1237
};
1238
1239
#define LLDB_OPTIONS_process_save_core
1240
#include "CommandOptions.inc"
1241
1242
class CommandObjectProcessSaveCore : public CommandObjectParsed {
1243
public:
1244
CommandObjectProcessSaveCore(CommandInterpreter &interpreter)
1245
: CommandObjectParsed(
1246
interpreter, "process save-core",
1247
"Save the current process as a core file using an "
1248
"appropriate file type.",
1249
"process save-core [-s corefile-style -p plugin-name] FILE",
1250
eCommandRequiresProcess | eCommandTryTargetAPILock |
1251
eCommandProcessMustBeLaunched) {
1252
AddSimpleArgumentList(eArgTypePath);
1253
}
1254
1255
~CommandObjectProcessSaveCore() override = default;
1256
1257
Options *GetOptions() override { return &m_options; }
1258
1259
class CommandOptions : public Options {
1260
public:
1261
CommandOptions() = default;
1262
1263
~CommandOptions() override = default;
1264
1265
llvm::ArrayRef<OptionDefinition> GetDefinitions() override {
1266
return llvm::ArrayRef(g_process_save_core_options);
1267
}
1268
1269
Status SetOptionValue(uint32_t option_idx, llvm::StringRef option_arg,
1270
ExecutionContext *execution_context) override {
1271
const int short_option = m_getopt_table[option_idx].val;
1272
Status error;
1273
1274
switch (short_option) {
1275
case 'p':
1276
error = m_core_dump_options.SetPluginName(option_arg.data());
1277
break;
1278
case 's':
1279
m_core_dump_options.SetStyle(
1280
(lldb::SaveCoreStyle)OptionArgParser::ToOptionEnum(
1281
option_arg, GetDefinitions()[option_idx].enum_values,
1282
eSaveCoreUnspecified, error));
1283
break;
1284
default:
1285
llvm_unreachable("Unimplemented option");
1286
}
1287
1288
return {};
1289
}
1290
1291
void OptionParsingStarting(ExecutionContext *execution_context) override {
1292
m_core_dump_options.Clear();
1293
}
1294
1295
// Instance variables to hold the values for command options.
1296
SaveCoreOptions m_core_dump_options;
1297
};
1298
1299
protected:
1300
void DoExecute(Args &command, CommandReturnObject &result) override {
1301
ProcessSP process_sp = m_exe_ctx.GetProcessSP();
1302
if (process_sp) {
1303
if (command.GetArgumentCount() == 1) {
1304
FileSpec output_file(command.GetArgumentAtIndex(0));
1305
FileSystem::Instance().Resolve(output_file);
1306
auto &core_dump_options = m_options.m_core_dump_options;
1307
core_dump_options.SetOutputFile(output_file);
1308
Status error = PluginManager::SaveCore(process_sp, core_dump_options);
1309
if (error.Success()) {
1310
if (core_dump_options.GetStyle() ==
1311
SaveCoreStyle::eSaveCoreDirtyOnly ||
1312
core_dump_options.GetStyle() ==
1313
SaveCoreStyle::eSaveCoreStackOnly) {
1314
result.AppendMessageWithFormat(
1315
"\nModified-memory or stack-memory only corefile "
1316
"created. This corefile may \n"
1317
"not show library/framework/app binaries "
1318
"on a different system, or when \n"
1319
"those binaries have "
1320
"been updated/modified. Copies are not included\n"
1321
"in this corefile. Use --style full to include all "
1322
"process memory.\n");
1323
}
1324
result.SetStatus(eReturnStatusSuccessFinishResult);
1325
} else {
1326
result.AppendErrorWithFormat(
1327
"Failed to save core file for process: %s\n", error.AsCString());
1328
}
1329
} else {
1330
result.AppendErrorWithFormat("'%s' takes one arguments:\nUsage: %s\n",
1331
m_cmd_name.c_str(), m_cmd_syntax.c_str());
1332
}
1333
} else {
1334
result.AppendError("invalid process");
1335
}
1336
}
1337
1338
CommandOptions m_options;
1339
};
1340
1341
// CommandObjectProcessStatus
1342
#pragma mark CommandObjectProcessStatus
1343
#define LLDB_OPTIONS_process_status
1344
#include "CommandOptions.inc"
1345
1346
class CommandObjectProcessStatus : public CommandObjectParsed {
1347
public:
1348
CommandObjectProcessStatus(CommandInterpreter &interpreter)
1349
: CommandObjectParsed(
1350
interpreter, "process status",
1351
"Show status and stop location for the current target process.",
1352
"process status",
1353
eCommandRequiresProcess | eCommandTryTargetAPILock) {}
1354
1355
~CommandObjectProcessStatus() override = default;
1356
1357
Options *GetOptions() override { return &m_options; }
1358
1359
class CommandOptions : public Options {
1360
public:
1361
CommandOptions() = default;
1362
1363
~CommandOptions() override = default;
1364
1365
Status SetOptionValue(uint32_t option_idx, llvm::StringRef option_arg,
1366
ExecutionContext *execution_context) override {
1367
const int short_option = m_getopt_table[option_idx].val;
1368
1369
switch (short_option) {
1370
case 'v':
1371
m_verbose = true;
1372
break;
1373
default:
1374
llvm_unreachable("Unimplemented option");
1375
}
1376
1377
return {};
1378
}
1379
1380
void OptionParsingStarting(ExecutionContext *execution_context) override {
1381
m_verbose = false;
1382
}
1383
1384
llvm::ArrayRef<OptionDefinition> GetDefinitions() override {
1385
return llvm::ArrayRef(g_process_status_options);
1386
}
1387
1388
// Instance variables to hold the values for command options.
1389
bool m_verbose = false;
1390
};
1391
1392
protected:
1393
void DoExecute(Args &command, CommandReturnObject &result) override {
1394
Stream &strm = result.GetOutputStream();
1395
result.SetStatus(eReturnStatusSuccessFinishNoResult);
1396
1397
// No need to check "process" for validity as eCommandRequiresProcess
1398
// ensures it is valid
1399
Process *process = m_exe_ctx.GetProcessPtr();
1400
const bool only_threads_with_stop_reason = true;
1401
const uint32_t start_frame = 0;
1402
const uint32_t num_frames = 1;
1403
const uint32_t num_frames_with_source = 1;
1404
const bool stop_format = true;
1405
process->GetStatus(strm);
1406
process->GetThreadStatus(strm, only_threads_with_stop_reason, start_frame,
1407
num_frames, num_frames_with_source, stop_format);
1408
1409
if (m_options.m_verbose) {
1410
addr_t code_mask = process->GetCodeAddressMask();
1411
addr_t data_mask = process->GetDataAddressMask();
1412
if (code_mask != LLDB_INVALID_ADDRESS_MASK) {
1413
int bits = std::bitset<64>(~code_mask).count();
1414
result.AppendMessageWithFormat(
1415
"Addressable code address mask: 0x%" PRIx64 "\n", code_mask);
1416
result.AppendMessageWithFormat(
1417
"Addressable data address mask: 0x%" PRIx64 "\n", data_mask);
1418
result.AppendMessageWithFormat(
1419
"Number of bits used in addressing (code): %d\n", bits);
1420
}
1421
1422
PlatformSP platform_sp = process->GetTarget().GetPlatform();
1423
if (!platform_sp) {
1424
result.AppendError("Couldn'retrieve the target's platform");
1425
return;
1426
}
1427
1428
auto expected_crash_info =
1429
platform_sp->FetchExtendedCrashInformation(*process);
1430
1431
if (!expected_crash_info) {
1432
result.AppendError(llvm::toString(expected_crash_info.takeError()));
1433
return;
1434
}
1435
1436
StructuredData::DictionarySP crash_info_sp = *expected_crash_info;
1437
1438
if (crash_info_sp) {
1439
strm.EOL();
1440
strm.PutCString("Extended Crash Information:\n");
1441
crash_info_sp->GetDescription(strm);
1442
}
1443
}
1444
}
1445
1446
private:
1447
CommandOptions m_options;
1448
};
1449
1450
// CommandObjectProcessHandle
1451
#define LLDB_OPTIONS_process_handle
1452
#include "CommandOptions.inc"
1453
1454
#pragma mark CommandObjectProcessHandle
1455
1456
class CommandObjectProcessHandle : public CommandObjectParsed {
1457
public:
1458
class CommandOptions : public Options {
1459
public:
1460
CommandOptions() { OptionParsingStarting(nullptr); }
1461
1462
~CommandOptions() override = default;
1463
1464
Status SetOptionValue(uint32_t option_idx, llvm::StringRef option_arg,
1465
ExecutionContext *execution_context) override {
1466
Status error;
1467
const int short_option = m_getopt_table[option_idx].val;
1468
1469
switch (short_option) {
1470
case 'c':
1471
do_clear = true;
1472
break;
1473
case 'd':
1474
dummy = true;
1475
break;
1476
case 's':
1477
stop = std::string(option_arg);
1478
break;
1479
case 'n':
1480
notify = std::string(option_arg);
1481
break;
1482
case 'p':
1483
pass = std::string(option_arg);
1484
break;
1485
case 't':
1486
only_target_values = true;
1487
break;
1488
default:
1489
llvm_unreachable("Unimplemented option");
1490
}
1491
return error;
1492
}
1493
1494
void OptionParsingStarting(ExecutionContext *execution_context) override {
1495
stop.clear();
1496
notify.clear();
1497
pass.clear();
1498
only_target_values = false;
1499
do_clear = false;
1500
dummy = false;
1501
}
1502
1503
llvm::ArrayRef<OptionDefinition> GetDefinitions() override {
1504
return llvm::ArrayRef(g_process_handle_options);
1505
}
1506
1507
// Instance variables to hold the values for command options.
1508
1509
std::string stop;
1510
std::string notify;
1511
std::string pass;
1512
bool only_target_values = false;
1513
bool do_clear = false;
1514
bool dummy = false;
1515
};
1516
1517
CommandObjectProcessHandle(CommandInterpreter &interpreter)
1518
: CommandObjectParsed(interpreter, "process handle",
1519
"Manage LLDB handling of OS signals for the "
1520
"current target process. Defaults to showing "
1521
"current policy.",
1522
nullptr) {
1523
SetHelpLong("\nIf no signals are specified but one or more actions are, "
1524
"and there is a live process, update them all. If no action "
1525
"is specified, list the current values.\n"
1526
"If you specify actions with no target (e.g. in an init file) "
1527
"or in a target with no process "
1528
"the values will get copied into subsequent targets, but "
1529
"lldb won't be able to spell-check the options since it can't "
1530
"know which signal set will later be in force."
1531
"\nYou can see the signal modifications held by the target"
1532
"by passing the -t option."
1533
"\nYou can also clear the target modification for a signal"
1534
"by passing the -c option");
1535
AddSimpleArgumentList(eArgTypeUnixSignal, eArgRepeatStar);
1536
}
1537
1538
~CommandObjectProcessHandle() override = default;
1539
1540
Options *GetOptions() override { return &m_options; }
1541
1542
void PrintSignalHeader(Stream &str) {
1543
str.Printf("NAME PASS STOP NOTIFY\n");
1544
str.Printf("=========== ===== ===== ======\n");
1545
}
1546
1547
void PrintSignal(Stream &str, int32_t signo, llvm::StringRef sig_name,
1548
const UnixSignalsSP &signals_sp) {
1549
bool stop;
1550
bool suppress;
1551
bool notify;
1552
1553
str.Format("{0, -11} ", sig_name);
1554
if (signals_sp->GetSignalInfo(signo, suppress, stop, notify)) {
1555
bool pass = !suppress;
1556
str.Printf("%s %s %s", (pass ? "true " : "false"),
1557
(stop ? "true " : "false"), (notify ? "true " : "false"));
1558
}
1559
str.Printf("\n");
1560
}
1561
1562
void PrintSignalInformation(Stream &str, Args &signal_args,
1563
int num_valid_signals,
1564
const UnixSignalsSP &signals_sp) {
1565
PrintSignalHeader(str);
1566
1567
if (num_valid_signals > 0) {
1568
size_t num_args = signal_args.GetArgumentCount();
1569
for (size_t i = 0; i < num_args; ++i) {
1570
int32_t signo = signals_sp->GetSignalNumberFromName(
1571
signal_args.GetArgumentAtIndex(i));
1572
if (signo != LLDB_INVALID_SIGNAL_NUMBER)
1573
PrintSignal(str, signo, signal_args.GetArgumentAtIndex(i),
1574
signals_sp);
1575
}
1576
} else // Print info for ALL signals
1577
{
1578
int32_t signo = signals_sp->GetFirstSignalNumber();
1579
while (signo != LLDB_INVALID_SIGNAL_NUMBER) {
1580
PrintSignal(str, signo, signals_sp->GetSignalAsStringRef(signo),
1581
signals_sp);
1582
signo = signals_sp->GetNextSignalNumber(signo);
1583
}
1584
}
1585
}
1586
1587
protected:
1588
void DoExecute(Args &signal_args, CommandReturnObject &result) override {
1589
Target &target = GetSelectedOrDummyTarget();
1590
1591
// Any signals that are being set should be added to the Target's
1592
// DummySignals so they will get applied on rerun, etc.
1593
// If we have a process, however, we can do a more accurate job of vetting
1594
// the user's options.
1595
ProcessSP process_sp = target.GetProcessSP();
1596
1597
std::optional<bool> stop_action = {};
1598
std::optional<bool> pass_action = {};
1599
std::optional<bool> notify_action = {};
1600
1601
if (!m_options.stop.empty()) {
1602
bool success = false;
1603
bool value = OptionArgParser::ToBoolean(m_options.stop, false, &success);
1604
if (!success) {
1605
result.AppendError(
1606
"Invalid argument for command option --stop; must be "
1607
"true or false.\n");
1608
return;
1609
}
1610
1611
stop_action = value;
1612
}
1613
1614
if (!m_options.pass.empty()) {
1615
bool success = false;
1616
bool value = OptionArgParser::ToBoolean(m_options.pass, false, &success);
1617
if (!success) {
1618
result.AppendError(
1619
"Invalid argument for command option --pass; must be "
1620
"true or false.\n");
1621
return;
1622
}
1623
pass_action = value;
1624
}
1625
1626
if (!m_options.notify.empty()) {
1627
bool success = false;
1628
bool value =
1629
OptionArgParser::ToBoolean(m_options.notify, false, &success);
1630
if (!success) {
1631
result.AppendError("Invalid argument for command option --notify; must "
1632
"be true or false.\n");
1633
return;
1634
}
1635
notify_action = value;
1636
}
1637
1638
if (!m_options.notify.empty() && !notify_action.has_value()) {
1639
}
1640
1641
bool no_actions = (!stop_action.has_value() && !pass_action.has_value() &&
1642
!notify_action.has_value());
1643
if (m_options.only_target_values && !no_actions) {
1644
result.AppendError("-t is for reporting, not setting, target values.");
1645
return;
1646
}
1647
1648
size_t num_args = signal_args.GetArgumentCount();
1649
UnixSignalsSP signals_sp;
1650
if (process_sp)
1651
signals_sp = process_sp->GetUnixSignals();
1652
1653
int num_signals_set = 0;
1654
1655
// If we were just asked to print the target values, do that here and
1656
// return:
1657
if (m_options.only_target_values) {
1658
target.PrintDummySignals(result.GetOutputStream(), signal_args);
1659
result.SetStatus(eReturnStatusSuccessFinishResult);
1660
return;
1661
}
1662
1663
// This handles clearing values:
1664
if (m_options.do_clear) {
1665
target.ClearDummySignals(signal_args);
1666
if (m_options.dummy)
1667
GetDummyTarget().ClearDummySignals(signal_args);
1668
result.SetStatus(eReturnStatusSuccessFinishNoResult);
1669
return;
1670
}
1671
1672
// This rest handles setting values:
1673
if (num_args > 0) {
1674
for (const auto &arg : signal_args) {
1675
// Do the process first. If we have a process we can catch
1676
// invalid signal names, which we do here.
1677
if (signals_sp) {
1678
int32_t signo = signals_sp->GetSignalNumberFromName(arg.c_str());
1679
if (signo != LLDB_INVALID_SIGNAL_NUMBER) {
1680
if (stop_action.has_value())
1681
signals_sp->SetShouldStop(signo, *stop_action);
1682
if (pass_action.has_value()) {
1683
bool suppress = !*pass_action;
1684
signals_sp->SetShouldSuppress(signo, suppress);
1685
}
1686
if (notify_action.has_value())
1687
signals_sp->SetShouldNotify(signo, *notify_action);
1688
++num_signals_set;
1689
} else {
1690
result.AppendErrorWithFormat("Invalid signal name '%s'\n",
1691
arg.c_str());
1692
continue;
1693
}
1694
} else {
1695
// If there's no process we can't check, so we just set them all.
1696
// But since the map signal name -> signal number across all platforms
1697
// is not 1-1, we can't sensibly set signal actions by number before
1698
// we have a process. Check that here:
1699
int32_t signo;
1700
if (llvm::to_integer(arg.c_str(), signo)) {
1701
result.AppendErrorWithFormat("Can't set signal handling by signal "
1702
"number with no process");
1703
return;
1704
}
1705
num_signals_set = num_args;
1706
}
1707
auto set_lazy_bool = [](std::optional<bool> action) -> LazyBool {
1708
if (!action.has_value())
1709
return eLazyBoolCalculate;
1710
return (*action) ? eLazyBoolYes : eLazyBoolNo;
1711
};
1712
1713
// If there were no actions, we're just listing, don't add the dummy:
1714
if (!no_actions)
1715
target.AddDummySignal(arg.ref(), set_lazy_bool(pass_action),
1716
set_lazy_bool(notify_action),
1717
set_lazy_bool(stop_action));
1718
}
1719
} else {
1720
// No signal specified, if any command options were specified, update ALL
1721
// signals. But we can't do this without a process since we don't know
1722
// all the possible signals that might be valid for this target.
1723
if ((notify_action.has_value() || stop_action.has_value() ||
1724
pass_action.has_value()) &&
1725
process_sp) {
1726
if (m_interpreter.Confirm(
1727
"Do you really want to update all the signals?", false)) {
1728
int32_t signo = signals_sp->GetFirstSignalNumber();
1729
while (signo != LLDB_INVALID_SIGNAL_NUMBER) {
1730
if (notify_action.has_value())
1731
signals_sp->SetShouldNotify(signo, *notify_action);
1732
if (stop_action.has_value())
1733
signals_sp->SetShouldStop(signo, *stop_action);
1734
if (pass_action.has_value()) {
1735
bool suppress = !*pass_action;
1736
signals_sp->SetShouldSuppress(signo, suppress);
1737
}
1738
signo = signals_sp->GetNextSignalNumber(signo);
1739
}
1740
}
1741
}
1742
}
1743
1744
if (signals_sp)
1745
PrintSignalInformation(result.GetOutputStream(), signal_args,
1746
num_signals_set, signals_sp);
1747
else
1748
target.PrintDummySignals(result.GetOutputStream(),
1749
signal_args);
1750
1751
if (num_signals_set > 0)
1752
result.SetStatus(eReturnStatusSuccessFinishResult);
1753
else
1754
result.SetStatus(eReturnStatusFailed);
1755
}
1756
1757
CommandOptions m_options;
1758
};
1759
1760
// Next are the subcommands of CommandObjectMultiwordProcessTrace
1761
1762
// CommandObjectProcessTraceStart
1763
class CommandObjectProcessTraceStart : public CommandObjectTraceProxy {
1764
public:
1765
CommandObjectProcessTraceStart(CommandInterpreter &interpreter)
1766
: CommandObjectTraceProxy(
1767
/*live_debug_session_only*/ true, interpreter,
1768
"process trace start",
1769
"Start tracing this process with the corresponding trace "
1770
"plug-in.",
1771
"process trace start [<trace-options>]") {}
1772
1773
protected:
1774
lldb::CommandObjectSP GetDelegateCommand(Trace &trace) override {
1775
return trace.GetProcessTraceStartCommand(m_interpreter);
1776
}
1777
};
1778
1779
// CommandObjectProcessTraceStop
1780
class CommandObjectProcessTraceStop : public CommandObjectParsed {
1781
public:
1782
CommandObjectProcessTraceStop(CommandInterpreter &interpreter)
1783
: CommandObjectParsed(interpreter, "process trace stop",
1784
"Stop tracing this process. This does not affect "
1785
"traces started with the "
1786
"\"thread trace start\" command.",
1787
"process trace stop",
1788
eCommandRequiresProcess | eCommandTryTargetAPILock |
1789
eCommandProcessMustBeLaunched |
1790
eCommandProcessMustBePaused |
1791
eCommandProcessMustBeTraced) {}
1792
1793
~CommandObjectProcessTraceStop() override = default;
1794
1795
void DoExecute(Args &command, CommandReturnObject &result) override {
1796
ProcessSP process_sp = m_exe_ctx.GetProcessSP();
1797
1798
TraceSP trace_sp = process_sp->GetTarget().GetTrace();
1799
1800
if (llvm::Error err = trace_sp->Stop())
1801
result.AppendError(toString(std::move(err)));
1802
else
1803
result.SetStatus(eReturnStatusSuccessFinishResult);
1804
}
1805
};
1806
1807
// CommandObjectMultiwordProcessTrace
1808
class CommandObjectMultiwordProcessTrace : public CommandObjectMultiword {
1809
public:
1810
CommandObjectMultiwordProcessTrace(CommandInterpreter &interpreter)
1811
: CommandObjectMultiword(
1812
interpreter, "trace", "Commands for tracing the current process.",
1813
"process trace <subcommand> [<subcommand objects>]") {
1814
LoadSubCommand("start", CommandObjectSP(new CommandObjectProcessTraceStart(
1815
interpreter)));
1816
LoadSubCommand("stop", CommandObjectSP(
1817
new CommandObjectProcessTraceStop(interpreter)));
1818
}
1819
1820
~CommandObjectMultiwordProcessTrace() override = default;
1821
};
1822
1823
// CommandObjectMultiwordProcess
1824
1825
CommandObjectMultiwordProcess::CommandObjectMultiwordProcess(
1826
CommandInterpreter &interpreter)
1827
: CommandObjectMultiword(
1828
interpreter, "process",
1829
"Commands for interacting with processes on the current platform.",
1830
"process <subcommand> [<subcommand-options>]") {
1831
LoadSubCommand("attach",
1832
CommandObjectSP(new CommandObjectProcessAttach(interpreter)));
1833
LoadSubCommand("launch",
1834
CommandObjectSP(new CommandObjectProcessLaunch(interpreter)));
1835
LoadSubCommand("continue", CommandObjectSP(new CommandObjectProcessContinue(
1836
interpreter)));
1837
LoadSubCommand("connect",
1838
CommandObjectSP(new CommandObjectProcessConnect(interpreter)));
1839
LoadSubCommand("detach",
1840
CommandObjectSP(new CommandObjectProcessDetach(interpreter)));
1841
LoadSubCommand("load",
1842
CommandObjectSP(new CommandObjectProcessLoad(interpreter)));
1843
LoadSubCommand("unload",
1844
CommandObjectSP(new CommandObjectProcessUnload(interpreter)));
1845
LoadSubCommand("signal",
1846
CommandObjectSP(new CommandObjectProcessSignal(interpreter)));
1847
LoadSubCommand("handle",
1848
CommandObjectSP(new CommandObjectProcessHandle(interpreter)));
1849
LoadSubCommand("status",
1850
CommandObjectSP(new CommandObjectProcessStatus(interpreter)));
1851
LoadSubCommand("interrupt", CommandObjectSP(new CommandObjectProcessInterrupt(
1852
interpreter)));
1853
LoadSubCommand("kill",
1854
CommandObjectSP(new CommandObjectProcessKill(interpreter)));
1855
LoadSubCommand("plugin",
1856
CommandObjectSP(new CommandObjectProcessPlugin(interpreter)));
1857
LoadSubCommand("save-core", CommandObjectSP(new CommandObjectProcessSaveCore(
1858
interpreter)));
1859
LoadSubCommand(
1860
"trace",
1861
CommandObjectSP(new CommandObjectMultiwordProcessTrace(interpreter)));
1862
}
1863
1864
CommandObjectMultiwordProcess::~CommandObjectMultiwordProcess() = default;
1865
1866