180814287SRaphael Isemann //===-- CommandObjectProcess.cpp ------------------------------------------===//
230fdc8d8SChris Lattner //
32946cd70SChandler Carruth // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
42946cd70SChandler Carruth // See https://llvm.org/LICENSE.txt for license information.
52946cd70SChandler Carruth // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
630fdc8d8SChris Lattner //
730fdc8d8SChris Lattner //===----------------------------------------------------------------------===//
830fdc8d8SChris Lattner
949bcfd80SEugene Zelenko #include "CommandObjectProcess.h"
104298b1b8SJim Ingham #include "CommandObjectBreakpoint.h"
11*7ced9fffSJonas Devlieghere #include "CommandObjectTrace.h"
127169d3a3SMed Ismail Bennani #include "CommandOptionsProcessLaunch.h"
130e41084aSJim Ingham #include "lldb/Breakpoint/Breakpoint.h"
144298b1b8SJim Ingham #include "lldb/Breakpoint/BreakpointIDList.h"
150e41084aSJim Ingham #include "lldb/Breakpoint/BreakpointLocation.h"
164298b1b8SJim Ingham #include "lldb/Breakpoint/BreakpointName.h"
170e41084aSJim Ingham #include "lldb/Breakpoint/BreakpointSite.h"
181f746071SGreg Clayton #include "lldb/Core/Module.h"
19a2715cf1SGreg Clayton #include "lldb/Core/PluginManager.h"
203eb2b44dSZachary Turner #include "lldb/Host/OptionParser.h"
2130fdc8d8SChris Lattner #include "lldb/Interpreter/CommandInterpreter.h"
22*7ced9fffSJonas Devlieghere #include "lldb/Interpreter/CommandOptionArgumentTable.h"
2330fdc8d8SChris Lattner #include "lldb/Interpreter/CommandReturnObject.h"
2447cbf4a0SPavel Labath #include "lldb/Interpreter/OptionArgParser.h"
253e0ad115SMed Ismail Bennani #include "lldb/Interpreter/OptionGroupPythonClassWithDict.h"
26b9c1b51eSKate Stone #include "lldb/Interpreter/Options.h"
27e996fd30SGreg Clayton #include "lldb/Target/Platform.h"
2830fdc8d8SChris Lattner #include "lldb/Target/Process.h"
290e41084aSJim Ingham #include "lldb/Target/StopInfo.h"
3030fdc8d8SChris Lattner #include "lldb/Target/Target.h"
3130fdc8d8SChris Lattner #include "lldb/Target/Thread.h"
3293749ab3SZachary Turner #include "lldb/Target/UnixSignals.h"
33145d95c9SPavel Labath #include "lldb/Utility/Args.h"
34d821c997SPavel Labath #include "lldb/Utility/State.h"
3530fdc8d8SChris Lattner
364298b1b8SJim Ingham #include "llvm/ADT/ScopeExit.h"
374298b1b8SJim Ingham
38cdc6f8d7SJason Molenda #include <bitset>
39cdc6f8d7SJason Molenda
4030fdc8d8SChris Lattner using namespace lldb;
4130fdc8d8SChris Lattner using namespace lldb_private;
4230fdc8d8SChris Lattner
43b9c1b51eSKate Stone class CommandObjectProcessLaunchOrAttach : public CommandObjectParsed {
44dcb1d856SJim Ingham public:
CommandObjectProcessLaunchOrAttach(CommandInterpreter & interpreter,const char * name,const char * help,const char * syntax,uint32_t flags,const char * new_process_action)45dcb1d856SJim Ingham CommandObjectProcessLaunchOrAttach(CommandInterpreter &interpreter,
46b9c1b51eSKate Stone const char *name, const char *help,
47b9c1b51eSKate Stone const char *syntax, uint32_t flags,
48b9c1b51eSKate Stone const char *new_process_action)
49b9c1b51eSKate Stone : CommandObjectParsed(interpreter, name, help, syntax, flags),
50dcb1d856SJim Ingham m_new_process_action(new_process_action) {}
51dcb1d856SJim Ingham
5249bcfd80SEugene Zelenko ~CommandObjectProcessLaunchOrAttach() override = default;
5349bcfd80SEugene Zelenko
54dcb1d856SJim Ingham protected:
StopProcessIfNecessary(Process * process,StateType & state,CommandReturnObject & result)55b9c1b51eSKate Stone bool StopProcessIfNecessary(Process *process, StateType &state,
56b9c1b51eSKate Stone CommandReturnObject &result) {
57dcb1d856SJim Ingham state = eStateInvalid;
58b9c1b51eSKate Stone if (process) {
59dcb1d856SJim Ingham state = process->GetState();
60dcb1d856SJim Ingham
61b9c1b51eSKate Stone if (process->IsAlive() && state != eStateConnected) {
62db203e02SRaphael Isemann std::string message;
63dcb1d856SJim Ingham if (process->GetState() == eStateAttaching)
64db203e02SRaphael Isemann message =
65db203e02SRaphael Isemann llvm::formatv("There is a pending attach, abort it and {0}?",
66db203e02SRaphael Isemann m_new_process_action);
67dcb1d856SJim Ingham else if (process->GetShouldDetach())
68db203e02SRaphael Isemann message = llvm::formatv(
69db203e02SRaphael Isemann "There is a running process, detach from it and {0}?",
70db203e02SRaphael Isemann m_new_process_action);
71dcb1d856SJim Ingham else
72db203e02SRaphael Isemann message =
73db203e02SRaphael Isemann llvm::formatv("There is a running process, kill it and {0}?",
74db203e02SRaphael Isemann m_new_process_action);
75dcb1d856SJim Ingham
76b9c1b51eSKate Stone if (!m_interpreter.Confirm(message, true)) {
77dcb1d856SJim Ingham result.SetStatus(eReturnStatusFailed);
78dcb1d856SJim Ingham return false;
79b9c1b51eSKate Stone } else {
80b9c1b51eSKate Stone if (process->GetShouldDetach()) {
81acff8950SJim Ingham bool keep_stopped = false;
8297206d57SZachary Turner Status detach_error(process->Detach(keep_stopped));
83b9c1b51eSKate Stone if (detach_error.Success()) {
84dcb1d856SJim Ingham result.SetStatus(eReturnStatusSuccessFinishResult);
8549bcfd80SEugene Zelenko process = nullptr;
86b9c1b51eSKate Stone } else {
87b9c1b51eSKate Stone result.AppendErrorWithFormat(
88b9c1b51eSKate Stone "Failed to detach from process: %s\n",
89b9c1b51eSKate Stone detach_error.AsCString());
90dcb1d856SJim Ingham }
91b9c1b51eSKate Stone } else {
9297206d57SZachary Turner Status destroy_error(process->Destroy(false));
93b9c1b51eSKate Stone if (destroy_error.Success()) {
94dcb1d856SJim Ingham result.SetStatus(eReturnStatusSuccessFinishResult);
9549bcfd80SEugene Zelenko process = nullptr;
96b9c1b51eSKate Stone } else {
97b9c1b51eSKate Stone result.AppendErrorWithFormat("Failed to kill process: %s\n",
98b9c1b51eSKate Stone destroy_error.AsCString());
99dcb1d856SJim Ingham }
100dcb1d856SJim Ingham }
101dcb1d856SJim Ingham }
102dcb1d856SJim Ingham }
103dcb1d856SJim Ingham }
104dcb1d856SJim Ingham return result.Succeeded();
105dcb1d856SJim Ingham }
10649bcfd80SEugene Zelenko
107dcb1d856SJim Ingham std::string m_new_process_action;
108dcb1d856SJim Ingham };
10949bcfd80SEugene Zelenko
11030fdc8d8SChris Lattner // CommandObjectProcessLaunch
1114bddaeb5SJim Ingham #pragma mark CommandObjectProcessLaunch
112b9c1b51eSKate Stone class CommandObjectProcessLaunch : public CommandObjectProcessLaunchOrAttach {
11330fdc8d8SChris Lattner public:
CommandObjectProcessLaunch(CommandInterpreter & interpreter)114b9c1b51eSKate Stone CommandObjectProcessLaunch(CommandInterpreter &interpreter)
115b9c1b51eSKate Stone : CommandObjectProcessLaunchOrAttach(
116b9c1b51eSKate Stone interpreter, "process launch",
117b9c1b51eSKate Stone "Launch the executable in the debugger.", nullptr,
118b9c1b51eSKate Stone eCommandRequiresTarget, "restart"),
119abb0ed44SKazu Hirata
120abb0ed44SKazu Hirata m_class_options("scripted process", true, 'C', 'k', 'v', 0) {
1213e0ad115SMed Ismail Bennani m_all_options.Append(&m_options);
1223e0ad115SMed Ismail Bennani m_all_options.Append(&m_class_options, LLDB_OPT_SET_1 | LLDB_OPT_SET_2,
1233e0ad115SMed Ismail Bennani LLDB_OPT_SET_ALL);
1243e0ad115SMed Ismail Bennani m_all_options.Finalize();
1253e0ad115SMed Ismail Bennani
126405fe67fSCaroline Tice CommandArgumentEntry arg;
127405fe67fSCaroline Tice CommandArgumentData run_args_arg;
128405fe67fSCaroline Tice
129405fe67fSCaroline Tice // Define the first (and only) variant of this arg.
130405fe67fSCaroline Tice run_args_arg.arg_type = eArgTypeRunArgs;
131405fe67fSCaroline Tice run_args_arg.arg_repetition = eArgRepeatOptional;
132405fe67fSCaroline Tice
133b9c1b51eSKate Stone // There is only one variant this argument could be; put it into the
134b9c1b51eSKate Stone // argument entry.
135405fe67fSCaroline Tice arg.push_back(run_args_arg);
136405fe67fSCaroline Tice
137405fe67fSCaroline Tice // Push the data for the first argument into the m_arguments vector.
138405fe67fSCaroline Tice m_arguments.push_back(arg);
13930fdc8d8SChris Lattner }
14030fdc8d8SChris Lattner
14149bcfd80SEugene Zelenko ~CommandObjectProcessLaunch() override = default;
14230fdc8d8SChris Lattner
143ae34ed2cSRaphael Isemann void
HandleArgumentCompletion(CompletionRequest & request,OptionElementVector & opt_element_vector)144ae34ed2cSRaphael Isemann HandleArgumentCompletion(CompletionRequest &request,
1452443bbd4SRaphael Isemann OptionElementVector &opt_element_vector) override {
146e9ce62b6SJim Ingham
147b9c1b51eSKate Stone CommandCompletions::InvokeCommonCompletionCallbacks(
148b9c1b51eSKate Stone GetCommandInterpreter(), CommandCompletions::eDiskFileCompletion,
149a2e76c0bSRaphael Isemann request, nullptr);
150e9ce62b6SJim Ingham }
151e9ce62b6SJim Ingham
GetOptions()1523e0ad115SMed Ismail Bennani Options *GetOptions() override { return &m_all_options; }
15330fdc8d8SChris Lattner
GetRepeatCommand(Args & current_command_args,uint32_t index)154635f03feSJim Ingham llvm::Optional<std::string> GetRepeatCommand(Args ¤t_command_args,
155b9c1b51eSKate Stone uint32_t index) override {
1565a988416SJim Ingham // No repeat for "process launch"...
157635f03feSJim Ingham return std::string("");
1585a988416SJim Ingham }
1595a988416SJim Ingham
1605a988416SJim Ingham protected:
DoExecute(Args & launch_args,CommandReturnObject & result)161b9c1b51eSKate Stone bool DoExecute(Args &launch_args, CommandReturnObject &result) override {
16257179860SJonas Devlieghere Debugger &debugger = GetDebugger();
1631d885966SGreg Clayton Target *target = debugger.GetSelectedTarget().get();
16449bcfd80SEugene Zelenko // If our listener is nullptr, users aren't allows to launch
165b09c5384SGreg Clayton ModuleSP exe_module_sp = target->GetExecutableModule();
16671337622SGreg Clayton
16792eaad2dSJim Ingham // If the target already has an executable module, then use that. If it
16892eaad2dSJim Ingham // doesn't then someone must be trying to launch using a path that will
16992eaad2dSJim Ingham // make sense to the remote stub, but doesn't exist on the local host.
17092eaad2dSJim Ingham // In that case use the ExecutableFile that was set in the target's
17192eaad2dSJim Ingham // ProcessLaunchInfo.
17292eaad2dSJim Ingham if (exe_module_sp == nullptr && !target->GetProcessLaunchInfo().GetExecutableFile()) {
173b9c1b51eSKate Stone result.AppendError("no file in target, create a debug target using the "
174b9c1b51eSKate Stone "'target create' command");
17571337622SGreg Clayton return false;
17671337622SGreg Clayton }
17771337622SGreg Clayton
17871337622SGreg Clayton StateType state = eStateInvalid;
17971337622SGreg Clayton
180b09c5384SGreg Clayton if (!StopProcessIfNecessary(m_exe_ctx.GetProcessPtr(), state, result))
18130fdc8d8SChris Lattner return false;
18230fdc8d8SChris Lattner
183b9c1b51eSKate Stone // Determine whether we will disable ASLR or leave it in the default state
18405097246SAdrian Prantl // (i.e. enabled if the platform supports it). First check if the process
18505097246SAdrian Prantl // launch options explicitly turn on/off
186b9c1b51eSKate Stone // disabling ASLR. If so, use that setting;
1875163792bSTodd Fiala // otherwise, use the 'settings target.disable-aslr' setting.
1885163792bSTodd Fiala bool disable_aslr = false;
189b9c1b51eSKate Stone if (m_options.disable_aslr != eLazyBoolCalculate) {
19005097246SAdrian Prantl // The user specified an explicit setting on the process launch line.
19105097246SAdrian Prantl // Use it.
1925163792bSTodd Fiala disable_aslr = (m_options.disable_aslr == eLazyBoolYes);
193b9c1b51eSKate Stone } else {
19405097246SAdrian Prantl // The user did not explicitly specify whether to disable ASLR. Fall
19505097246SAdrian Prantl // back to the target.disable-aslr setting.
1965163792bSTodd Fiala disable_aslr = target->GetDisableASLR();
1975163792bSTodd Fiala }
1985163792bSTodd Fiala
1993e0ad115SMed Ismail Bennani if (!m_class_options.GetName().empty()) {
2003e0ad115SMed Ismail Bennani m_options.launch_info.SetProcessPluginName("ScriptedProcess");
2013e0ad115SMed Ismail Bennani m_options.launch_info.SetScriptedProcessClassName(
2023e0ad115SMed Ismail Bennani m_class_options.GetName());
2033e0ad115SMed Ismail Bennani m_options.launch_info.SetScriptedProcessDictionarySP(
2043e0ad115SMed Ismail Bennani m_class_options.GetStructuredData());
2053e0ad115SMed Ismail Bennani target->SetProcessLaunchInfo(m_options.launch_info);
2063e0ad115SMed Ismail Bennani }
2073e0ad115SMed Ismail Bennani
2085163792bSTodd Fiala if (disable_aslr)
209b09c5384SGreg Clayton m_options.launch_info.GetFlags().Set(eLaunchFlagDisableASLR);
2105163792bSTodd Fiala else
2115163792bSTodd Fiala m_options.launch_info.GetFlags().Clear(eLaunchFlagDisableASLR);
212b09c5384SGreg Clayton
213249a1d4fSJonas Devlieghere if (target->GetInheritTCC())
214249a1d4fSJonas Devlieghere m_options.launch_info.GetFlags().Set(eLaunchFlagInheritTCCFromParent);
215249a1d4fSJonas Devlieghere
216106d0286SJim Ingham if (target->GetDetachOnError())
217106d0286SJim Ingham m_options.launch_info.GetFlags().Set(eLaunchFlagDetachOnError);
218106d0286SJim Ingham
219b09c5384SGreg Clayton if (target->GetDisableSTDIO())
220b09c5384SGreg Clayton m_options.launch_info.GetFlags().Set(eLaunchFlagDisableSTDIO);
221b09c5384SGreg Clayton
222ae54fc9fSJonas Devlieghere // Merge the launch info environment with the target environment.
223ae54fc9fSJonas Devlieghere Environment target_env = target->GetEnvironment();
224ae54fc9fSJonas Devlieghere m_options.launch_info.GetEnvironment().insert(target_env.begin(),
225ae54fc9fSJonas Devlieghere target_env.end());
22645392553SGreg Clayton
227be556d51SMed Ismail Bennani llvm::StringRef target_settings_argv0 = target->GetArg0();
228be556d51SMed Ismail Bennani
22931d97a5cSZachary Turner if (!target_settings_argv0.empty()) {
230b9c1b51eSKate Stone m_options.launch_info.GetArguments().AppendArgument(
23131d97a5cSZachary Turner target_settings_argv0);
23292eaad2dSJim Ingham if (exe_module_sp)
233b9c1b51eSKate Stone m_options.launch_info.SetExecutableFile(
234b9c1b51eSKate Stone exe_module_sp->GetPlatformFileSpec(), false);
23592eaad2dSJim Ingham else
23692eaad2dSJim Ingham m_options.launch_info.SetExecutableFile(target->GetProcessLaunchInfo().GetExecutableFile(), false);
237b9c1b51eSKate Stone } else {
23892eaad2dSJim Ingham if (exe_module_sp)
239b9c1b51eSKate Stone m_options.launch_info.SetExecutableFile(
240b9c1b51eSKate Stone exe_module_sp->GetPlatformFileSpec(), true);
24192eaad2dSJim Ingham else
24292eaad2dSJim Ingham m_options.launch_info.SetExecutableFile(target->GetProcessLaunchInfo().GetExecutableFile(), true);
24345392553SGreg Clayton }
24445392553SGreg Clayton
245b9c1b51eSKate Stone if (launch_args.GetArgumentCount() == 0) {
246b9c1b51eSKate Stone m_options.launch_info.GetArguments().AppendArguments(
247b9c1b51eSKate Stone target->GetProcessLaunchInfo().GetArguments());
248b9c1b51eSKate Stone } else {
24945392553SGreg Clayton m_options.launch_info.GetArguments().AppendArguments(launch_args);
250162b597cSGreg Clayton // Save the arguments for subsequent runs in the current target.
251162b597cSGreg Clayton target->SetRunArguments(launch_args);
252982c9762SGreg Clayton }
2531d885966SGreg Clayton
254dc6224e0SGreg Clayton StreamString stream;
25597206d57SZachary Turner Status error = target->Launch(m_options.launch_info, &stream);
25630fdc8d8SChris Lattner
257b9c1b51eSKate Stone if (error.Success()) {
258b09c5384SGreg Clayton ProcessSP process_sp(target->GetProcessSP());
259b9c1b51eSKate Stone if (process_sp) {
260b9c1b51eSKate Stone // There is a race condition where this thread will return up the call
26105097246SAdrian Prantl // stack to the main command handler and show an (lldb) prompt before
26205097246SAdrian Prantl // HandlePrivateEvent (from PrivateStateThread) has a chance to call
26305097246SAdrian Prantl // PushProcessIOHandler().
2643879fe00SPavel Labath process_sp->SyncIOHandler(0, std::chrono::seconds(2));
2658f0db3e1SIlia K
266c156427dSZachary Turner llvm::StringRef data = stream.GetString();
267c156427dSZachary Turner if (!data.empty())
268c156427dSZachary Turner result.AppendMessage(data);
26992eaad2dSJim Ingham // If we didn't have a local executable, then we wouldn't have had an
27092eaad2dSJim Ingham // executable module before launch.
27192eaad2dSJim Ingham if (!exe_module_sp)
27292eaad2dSJim Ingham exe_module_sp = target->GetExecutableModule();
27392eaad2dSJim Ingham if (!exe_module_sp) {
27492eaad2dSJim Ingham result.AppendWarning("Could not get executable module after launch.");
27592eaad2dSJim Ingham } else {
27692eaad2dSJim Ingham
277b9c1b51eSKate Stone const char *archname =
278b9c1b51eSKate Stone exe_module_sp->GetArchitecture().GetArchitectureName();
279b9c1b51eSKate Stone result.AppendMessageWithFormat(
280b9c1b51eSKate Stone "Process %" PRIu64 " launched: '%s' (%s)\n", process_sp->GetID(),
281b9c1b51eSKate Stone exe_module_sp->GetFileSpec().GetPath().c_str(), archname);
28292eaad2dSJim Ingham }
28305faeb71SGreg Clayton result.SetStatus(eReturnStatusSuccessFinishResult);
284b09c5384SGreg Clayton result.SetDidChangeProcessState(true);
285b9c1b51eSKate Stone } else {
286b9c1b51eSKate Stone result.AppendError(
287b9c1b51eSKate Stone "no error returned from Target::Launch, and target has no process");
28830fdc8d8SChris Lattner }
289b9c1b51eSKate Stone } else {
290b09c5384SGreg Clayton result.AppendError(error.AsCString());
291514487e8SGreg Clayton }
29230fdc8d8SChris Lattner return result.Succeeded();
29330fdc8d8SChris Lattner }
29430fdc8d8SChris Lattner
2957169d3a3SMed Ismail Bennani CommandOptionsProcessLaunch m_options;
2963e0ad115SMed Ismail Bennani OptionGroupPythonClassWithDict m_class_options;
2973e0ad115SMed Ismail Bennani OptionGroupOptions m_all_options;
29830fdc8d8SChris Lattner };
29930fdc8d8SChris Lattner
300438dfcffSRaphael Isemann #define LLDB_OPTIONS_process_attach
301438dfcffSRaphael Isemann #include "CommandOptions.inc"
3021f0f5b5bSZachary Turner
303bb9caf73SJim Ingham #pragma mark CommandObjectProcessAttach
304b9c1b51eSKate Stone class CommandObjectProcessAttach : public CommandObjectProcessLaunchOrAttach {
30530fdc8d8SChris Lattner public:
306b9c1b51eSKate Stone class CommandOptions : public Options {
30730fdc8d8SChris Lattner public:
CommandOptions()308abb0ed44SKazu Hirata CommandOptions() {
309b9c1b51eSKate Stone // Keep default values of all options in one place: OptionParsingStarting
310b9c1b51eSKate Stone // ()
311e1cfbc79STodd Fiala OptionParsingStarting(nullptr);
31230fdc8d8SChris Lattner }
31330fdc8d8SChris Lattner
31449bcfd80SEugene Zelenko ~CommandOptions() override = default;
31530fdc8d8SChris Lattner
SetOptionValue(uint32_t option_idx,llvm::StringRef option_arg,ExecutionContext * execution_context)31697206d57SZachary Turner Status SetOptionValue(uint32_t option_idx, llvm::StringRef option_arg,
317b9c1b51eSKate Stone ExecutionContext *execution_context) override {
31897206d57SZachary Turner Status error;
3193bcdfc0eSGreg Clayton const int short_option = m_getopt_table[option_idx].val;
320b9c1b51eSKate Stone switch (short_option) {
321a95ce623SJohnny Chen case 'c':
322a95ce623SJohnny Chen attach_info.SetContinueOnceAttached(true);
323a95ce623SJohnny Chen break;
324a95ce623SJohnny Chen
325b9c1b51eSKate Stone case 'p': {
326fe11483bSZachary Turner lldb::pid_t pid;
327fe11483bSZachary Turner if (option_arg.getAsInteger(0, pid)) {
328fe11483bSZachary Turner error.SetErrorStringWithFormat("invalid process ID '%s'",
329fe11483bSZachary Turner option_arg.str().c_str());
330b9c1b51eSKate Stone } else {
331144f3a9cSGreg Clayton attach_info.SetProcessID(pid);
332144f3a9cSGreg Clayton }
333b9c1b51eSKate Stone } break;
33430fdc8d8SChris Lattner
33530fdc8d8SChris Lattner case 'P':
336144f3a9cSGreg Clayton attach_info.SetProcessPluginName(option_arg);
33730fdc8d8SChris Lattner break;
33830fdc8d8SChris Lattner
33930fdc8d8SChris Lattner case 'n':
3408f3be7a3SJonas Devlieghere attach_info.GetExecutableFile().SetFile(option_arg,
341937348cdSJonas Devlieghere FileSpec::Style::native);
34230fdc8d8SChris Lattner break;
34330fdc8d8SChris Lattner
34430fdc8d8SChris Lattner case 'w':
345144f3a9cSGreg Clayton attach_info.SetWaitForLaunch(true);
34630fdc8d8SChris Lattner break;
34730fdc8d8SChris Lattner
348cd16df91SJim Ingham case 'i':
349cd16df91SJim Ingham attach_info.SetIgnoreExisting(false);
350cd16df91SJim Ingham break;
351cd16df91SJim Ingham
35230fdc8d8SChris Lattner default:
35336162014SRaphael Isemann llvm_unreachable("Unimplemented option");
35430fdc8d8SChris Lattner }
35530fdc8d8SChris Lattner return error;
35630fdc8d8SChris Lattner }
35730fdc8d8SChris Lattner
OptionParsingStarting(ExecutionContext * execution_context)358b9c1b51eSKate Stone void OptionParsingStarting(ExecutionContext *execution_context) override {
359144f3a9cSGreg Clayton attach_info.Clear();
36030fdc8d8SChris Lattner }
36130fdc8d8SChris Lattner
GetDefinitions()3621f0f5b5bSZachary Turner llvm::ArrayRef<OptionDefinition> GetDefinitions() override {
36370602439SZachary Turner return llvm::makeArrayRef(g_process_attach_options);
3641f0f5b5bSZachary Turner }
36530fdc8d8SChris Lattner
366144f3a9cSGreg Clayton ProcessAttachInfo attach_info;
36730fdc8d8SChris Lattner };
36830fdc8d8SChris Lattner
CommandObjectProcessAttach(CommandInterpreter & interpreter)369b9c1b51eSKate Stone CommandObjectProcessAttach(CommandInterpreter &interpreter)
370b9c1b51eSKate Stone : CommandObjectProcessLaunchOrAttach(
371b9c1b51eSKate Stone interpreter, "process attach", "Attach to a process.",
372abb0ed44SKazu Hirata "process attach <cmd-options>", 0, "attach") {}
3735aee162fSJim Ingham
37449bcfd80SEugene Zelenko ~CommandObjectProcessAttach() override = default;
3755aee162fSJim Ingham
GetOptions()376b9c1b51eSKate Stone Options *GetOptions() override { return &m_options; }
3775a988416SJim Ingham
3785a988416SJim Ingham protected:
DoExecute(Args & command,CommandReturnObject & result)379b9c1b51eSKate Stone bool DoExecute(Args &command, CommandReturnObject &result) override {
380b9c1b51eSKate Stone PlatformSP platform_sp(
38157179860SJonas Devlieghere GetDebugger().GetPlatformList().GetSelectedPlatform());
382926af0cdSOleksiy Vyalov
38357179860SJonas Devlieghere Target *target = GetDebugger().GetSelectedTarget().get();
384b9c1b51eSKate Stone // N.B. The attach should be synchronous. It doesn't help much to get the
38505097246SAdrian Prantl // prompt back between initiating the attach and the target actually
38605097246SAdrian Prantl // stopping. So even if the interpreter is set to be asynchronous, we wait
38705097246SAdrian Prantl // for the stop ourselves here.
3885aee162fSJim Ingham
38971337622SGreg Clayton StateType state = eStateInvalid;
390dcb1d856SJim Ingham Process *process = m_exe_ctx.GetProcessPtr();
391dcb1d856SJim Ingham
392dcb1d856SJim Ingham if (!StopProcessIfNecessary(process, state, result))
3935aee162fSJim Ingham return false;
3945aee162fSJim Ingham
395b9c1b51eSKate Stone if (target == nullptr) {
3965aee162fSJim Ingham // If there isn't a current target create one.
3975aee162fSJim Ingham TargetSP new_target_sp;
39897206d57SZachary Turner Status error;
3995aee162fSJim Ingham
40057179860SJonas Devlieghere error = GetDebugger().GetTargetList().CreateTarget(
40157179860SJonas Devlieghere GetDebugger(), "", "", eLoadDependentsNo,
40249bcfd80SEugene Zelenko nullptr, // No platform options
4035aee162fSJim Ingham new_target_sp);
4045aee162fSJim Ingham target = new_target_sp.get();
405b9c1b51eSKate Stone if (target == nullptr || error.Fail()) {
406b766a73dSGreg Clayton result.AppendError(error.AsCString("Error creating target"));
4075aee162fSJim Ingham return false;
4085aee162fSJim Ingham }
4095aee162fSJim Ingham }
4105aee162fSJim Ingham
411b9c1b51eSKate Stone // Record the old executable module, we want to issue a warning if the
41205097246SAdrian Prantl // process of attaching changed the current executable (like somebody said
41305097246SAdrian Prantl // "file foo" then attached to a PID whose executable was bar.)
4145aee162fSJim Ingham
4155aee162fSJim Ingham ModuleSP old_exec_module_sp = target->GetExecutableModule();
4165aee162fSJim Ingham ArchSpec old_arch_spec = target->GetArchitecture();
4175aee162fSJim Ingham
41837386143SOleksiy Vyalov StreamString stream;
4192303391dSJim Ingham ProcessSP process_sp;
42037386143SOleksiy Vyalov const auto error = target->Attach(m_options.attach_info, &stream);
421b9c1b51eSKate Stone if (error.Success()) {
4222303391dSJim Ingham process_sp = target->GetProcessSP();
423b9c1b51eSKate Stone if (process_sp) {
424c156427dSZachary Turner result.AppendMessage(stream.GetString());
425bb3a283bSJim Ingham result.SetStatus(eReturnStatusSuccessFinishNoResult);
42637386143SOleksiy Vyalov result.SetDidChangeProcessState(true);
427b9c1b51eSKate Stone } else {
428b9c1b51eSKate Stone result.AppendError(
429b9c1b51eSKate Stone "no error returned from Target::Attach, and target has no process");
43044d93782SGreg Clayton }
431b9c1b51eSKate Stone } else {
43244d93782SGreg Clayton result.AppendErrorWithFormat("attach failed: %s\n", error.AsCString());
433aa739093SJohnny Chen }
4345aee162fSJim Ingham
435926af0cdSOleksiy Vyalov if (!result.Succeeded())
436926af0cdSOleksiy Vyalov return false;
437926af0cdSOleksiy Vyalov
438b9c1b51eSKate Stone // Okay, we're done. Last step is to warn if the executable module has
439b9c1b51eSKate Stone // changed:
440513c26ceSGreg Clayton char new_path[PATH_MAX];
441aa149cbdSGreg Clayton ModuleSP new_exec_module_sp(target->GetExecutableModule());
442b9c1b51eSKate Stone if (!old_exec_module_sp) {
443513c26ceSGreg Clayton // We might not have a module if we attached to a raw pid...
444b9c1b51eSKate Stone if (new_exec_module_sp) {
445aa149cbdSGreg Clayton new_exec_module_sp->GetFileSpec().GetPath(new_path, PATH_MAX);
446b9c1b51eSKate Stone result.AppendMessageWithFormat("Executable module set to \"%s\".\n",
447b9c1b51eSKate Stone new_path);
448513c26ceSGreg Clayton }
449b9c1b51eSKate Stone } else if (old_exec_module_sp->GetFileSpec() !=
450b9c1b51eSKate Stone new_exec_module_sp->GetFileSpec()) {
451513c26ceSGreg Clayton char old_path[PATH_MAX];
4525aee162fSJim Ingham
4535aee162fSJim Ingham old_exec_module_sp->GetFileSpec().GetPath(old_path, PATH_MAX);
454aa149cbdSGreg Clayton new_exec_module_sp->GetFileSpec().GetPath(new_path, PATH_MAX);
4555aee162fSJim Ingham
456b9c1b51eSKate Stone result.AppendWarningWithFormat(
457b9c1b51eSKate Stone "Executable module changed from \"%s\" to \"%s\".\n", old_path,
458b9c1b51eSKate Stone new_path);
4595aee162fSJim Ingham }
4605aee162fSJim Ingham
461b9c1b51eSKate Stone if (!old_arch_spec.IsValid()) {
462b9c1b51eSKate Stone result.AppendMessageWithFormat(
463b9c1b51eSKate Stone "Architecture set to: %s.\n",
464b9c1b51eSKate Stone target->GetArchitecture().GetTriple().getTriple().c_str());
465b9c1b51eSKate Stone } else if (!old_arch_spec.IsExactMatch(target->GetArchitecture())) {
466b9c1b51eSKate Stone result.AppendWarningWithFormat(
467b9c1b51eSKate Stone "Architecture changed from %s to %s.\n",
468c1b1f1eaSGreg Clayton old_arch_spec.GetTriple().getTriple().c_str(),
469c1b1f1eaSGreg Clayton target->GetArchitecture().GetTriple().getTriple().c_str());
4705aee162fSJim Ingham }
471a95ce623SJohnny Chen
47205097246SAdrian Prantl // This supports the use-case scenario of immediately continuing the
47305097246SAdrian Prantl // process once attached.
4742303391dSJim Ingham if (m_options.attach_info.GetContinueOnceAttached()) {
4752303391dSJim Ingham // We have made a process but haven't told the interpreter about it yet,
4762303391dSJim Ingham // so CheckRequirements will fail for "process continue". Set the override
4772303391dSJim Ingham // here:
4782303391dSJim Ingham ExecutionContext exe_ctx(process_sp);
4792303391dSJim Ingham m_interpreter.HandleCommand("process continue", eLazyBoolNo, exe_ctx, result);
4802303391dSJim Ingham }
481926af0cdSOleksiy Vyalov
4825aee162fSJim Ingham return result.Succeeded();
4835aee162fSJim Ingham }
4845aee162fSJim Ingham
48530fdc8d8SChris Lattner CommandOptions m_options;
48630fdc8d8SChris Lattner };
48730fdc8d8SChris Lattner
48830fdc8d8SChris Lattner // CommandObjectProcessContinue
4891f0f5b5bSZachary Turner
490438dfcffSRaphael Isemann #define LLDB_OPTIONS_process_continue
491438dfcffSRaphael Isemann #include "CommandOptions.inc"
4921f0f5b5bSZachary Turner
493bb9caf73SJim Ingham #pragma mark CommandObjectProcessContinue
49430fdc8d8SChris Lattner
495b9c1b51eSKate Stone class CommandObjectProcessContinue : public CommandObjectParsed {
49630fdc8d8SChris Lattner public:
CommandObjectProcessContinue(CommandInterpreter & interpreter)497b9c1b51eSKate Stone CommandObjectProcessContinue(CommandInterpreter &interpreter)
498b9c1b51eSKate Stone : CommandObjectParsed(
499b9c1b51eSKate Stone interpreter, "process continue",
500e3d26315SCaroline Tice "Continue execution of all threads in the current process.",
50130fdc8d8SChris Lattner "process continue",
502b9c1b51eSKate Stone eCommandRequiresProcess | eCommandTryTargetAPILock |
503abb0ed44SKazu Hirata eCommandProcessMustBeLaunched | eCommandProcessMustBePaused) {}
50430fdc8d8SChris Lattner
50549bcfd80SEugene Zelenko ~CommandObjectProcessContinue() override = default;
50630fdc8d8SChris Lattner
5075a988416SJim Ingham protected:
508b9c1b51eSKate Stone class CommandOptions : public Options {
5090e41084aSJim Ingham public:
CommandOptions()510abb0ed44SKazu Hirata CommandOptions() {
511b9c1b51eSKate Stone // Keep default values of all options in one place: OptionParsingStarting
512b9c1b51eSKate Stone // ()
513e1cfbc79STodd Fiala OptionParsingStarting(nullptr);
5140e41084aSJim Ingham }
5150e41084aSJim Ingham
51649bcfd80SEugene Zelenko ~CommandOptions() override = default;
5170e41084aSJim Ingham
SetOptionValue(uint32_t option_idx,llvm::StringRef option_arg,ExecutionContext * exe_ctx)51897206d57SZachary Turner Status SetOptionValue(uint32_t option_idx, llvm::StringRef option_arg,
5194298b1b8SJim Ingham ExecutionContext *exe_ctx) override {
52097206d57SZachary Turner Status error;
5213bcdfc0eSGreg Clayton const int short_option = m_getopt_table[option_idx].val;
522b9c1b51eSKate Stone switch (short_option) {
5230e41084aSJim Ingham case 'i':
524fe11483bSZachary Turner if (option_arg.getAsInteger(0, m_ignore))
525b9c1b51eSKate Stone error.SetErrorStringWithFormat(
526b9c1b51eSKate Stone "invalid value for ignore option: \"%s\", should be a number.",
527fe11483bSZachary Turner option_arg.str().c_str());
5280e41084aSJim Ingham break;
5294298b1b8SJim Ingham case 'b':
5304298b1b8SJim Ingham m_run_to_bkpt_args.AppendArgument(option_arg);
5314298b1b8SJim Ingham m_any_bkpts_specified = true;
5324298b1b8SJim Ingham break;
5330e41084aSJim Ingham default:
53436162014SRaphael Isemann llvm_unreachable("Unimplemented option");
5350e41084aSJim Ingham }
5360e41084aSJim Ingham return error;
5370e41084aSJim Ingham }
5380e41084aSJim Ingham
OptionParsingStarting(ExecutionContext * execution_context)539b9c1b51eSKate Stone void OptionParsingStarting(ExecutionContext *execution_context) override {
5400e41084aSJim Ingham m_ignore = 0;
5414298b1b8SJim Ingham m_run_to_bkpt_args.Clear();
5424298b1b8SJim Ingham m_any_bkpts_specified = false;
5430e41084aSJim Ingham }
5440e41084aSJim Ingham
GetDefinitions()5451f0f5b5bSZachary Turner llvm::ArrayRef<OptionDefinition> GetDefinitions() override {
54670602439SZachary Turner return llvm::makeArrayRef(g_process_continue_options);
5471f0f5b5bSZachary Turner }
5480e41084aSJim Ingham
5494298b1b8SJim Ingham uint32_t m_ignore = 0;
5504298b1b8SJim Ingham Args m_run_to_bkpt_args;
5514298b1b8SJim Ingham bool m_any_bkpts_specified = false;
5520e41084aSJim Ingham };
5530e41084aSJim Ingham
5544298b1b8SJim Ingham
DoExecute(Args & command,CommandReturnObject & result)555b9c1b51eSKate Stone bool DoExecute(Args &command, CommandReturnObject &result) override {
556f9fc609fSGreg Clayton Process *process = m_exe_ctx.GetProcessPtr();
557a7015092SGreg Clayton bool synchronous_execution = m_interpreter.GetSynchronous();
55830fdc8d8SChris Lattner StateType state = process->GetState();
559b9c1b51eSKate Stone if (state == eStateStopped) {
560b9c1b51eSKate Stone if (m_options.m_ignore > 0) {
5618d94ba0fSJim Ingham ThreadSP sel_thread_sp(GetDefaultThread()->shared_from_this());
562b9c1b51eSKate Stone if (sel_thread_sp) {
5630e41084aSJim Ingham StopInfoSP stop_info_sp = sel_thread_sp->GetStopInfo();
564b9c1b51eSKate Stone if (stop_info_sp &&
565b9c1b51eSKate Stone stop_info_sp->GetStopReason() == eStopReasonBreakpoint) {
566b9c1b51eSKate Stone lldb::break_id_t bp_site_id =
567b9c1b51eSKate Stone (lldb::break_id_t)stop_info_sp->GetValue();
568b9c1b51eSKate Stone BreakpointSiteSP bp_site_sp(
569b9c1b51eSKate Stone process->GetBreakpointSiteList().FindByID(bp_site_id));
570b9c1b51eSKate Stone if (bp_site_sp) {
571c7bece56SGreg Clayton const size_t num_owners = bp_site_sp->GetNumberOfOwners();
572b9c1b51eSKate Stone for (size_t i = 0; i < num_owners; i++) {
573b9c1b51eSKate Stone Breakpoint &bp_ref =
574b9c1b51eSKate Stone bp_site_sp->GetOwnerAtIndex(i)->GetBreakpoint();
575b9c1b51eSKate Stone if (!bp_ref.IsInternal()) {
5760e41084aSJim Ingham bp_ref.SetIgnoreCount(m_options.m_ignore);
5770e41084aSJim Ingham }
5780e41084aSJim Ingham }
5790e41084aSJim Ingham }
5800e41084aSJim Ingham }
5810e41084aSJim Ingham }
5820e41084aSJim Ingham }
5830e41084aSJim Ingham
5844298b1b8SJim Ingham Target *target = m_exe_ctx.GetTargetPtr();
5854298b1b8SJim Ingham BreakpointIDList run_to_bkpt_ids;
586bae10a6bSJim Ingham // Don't pass an empty run_to_breakpoint list, as Verify will look for the
587bae10a6bSJim Ingham // default breakpoint.
588bae10a6bSJim Ingham if (m_options.m_run_to_bkpt_args.GetArgumentCount() > 0)
5894298b1b8SJim Ingham CommandObjectMultiwordBreakpoint::VerifyBreakpointOrLocationIDs(
5904298b1b8SJim Ingham m_options.m_run_to_bkpt_args, target, result, &run_to_bkpt_ids,
5914298b1b8SJim Ingham BreakpointName::Permissions::disablePerm);
5924298b1b8SJim Ingham if (!result.Succeeded()) {
5934298b1b8SJim Ingham return false;
5944298b1b8SJim Ingham }
5954298b1b8SJim Ingham result.Clear();
5964298b1b8SJim Ingham if (m_options.m_any_bkpts_specified && run_to_bkpt_ids.GetSize() == 0) {
5974298b1b8SJim Ingham result.AppendError("continue-to breakpoints did not specify any actual "
5984298b1b8SJim Ingham "breakpoints or locations");
5994298b1b8SJim Ingham return false;
6004298b1b8SJim Ingham }
6014298b1b8SJim Ingham
6024298b1b8SJim Ingham // First figure out which breakpoints & locations were specified by the
6034298b1b8SJim Ingham // user:
6044298b1b8SJim Ingham size_t num_run_to_bkpt_ids = run_to_bkpt_ids.GetSize();
6054298b1b8SJim Ingham std::vector<break_id_t> bkpts_disabled;
6064298b1b8SJim Ingham std::vector<BreakpointID> locs_disabled;
6074298b1b8SJim Ingham if (num_run_to_bkpt_ids != 0) {
6084298b1b8SJim Ingham // Go through the ID's specified, and separate the breakpoints from are
6094298b1b8SJim Ingham // the breakpoint.location specifications since the latter require
6104298b1b8SJim Ingham // special handling. We also figure out whether there's at least one
6114298b1b8SJim Ingham // specifier in the set that is enabled.
6124298b1b8SJim Ingham BreakpointList &bkpt_list = target->GetBreakpointList();
6134298b1b8SJim Ingham std::unordered_set<break_id_t> bkpts_seen;
6144298b1b8SJim Ingham std::unordered_set<break_id_t> bkpts_with_locs_seen;
6154298b1b8SJim Ingham BreakpointIDList with_locs;
6164298b1b8SJim Ingham bool any_enabled = false;
6174298b1b8SJim Ingham
6184298b1b8SJim Ingham for (size_t idx = 0; idx < num_run_to_bkpt_ids; idx++) {
6194298b1b8SJim Ingham BreakpointID bkpt_id = run_to_bkpt_ids.GetBreakpointIDAtIndex(idx);
6204298b1b8SJim Ingham break_id_t bp_id = bkpt_id.GetBreakpointID();
6214298b1b8SJim Ingham break_id_t loc_id = bkpt_id.GetLocationID();
6224298b1b8SJim Ingham BreakpointSP bp_sp
6234298b1b8SJim Ingham = bkpt_list.FindBreakpointByID(bp_id);
6244298b1b8SJim Ingham // Note, VerifyBreakpointOrLocationIDs checks for existence, so we
6254298b1b8SJim Ingham // don't need to do it again here.
6264298b1b8SJim Ingham if (bp_sp->IsEnabled()) {
6274298b1b8SJim Ingham if (loc_id == LLDB_INVALID_BREAK_ID) {
6284298b1b8SJim Ingham // A breakpoint (without location) was specified. Make sure that
6294298b1b8SJim Ingham // at least one of the locations is enabled.
6304298b1b8SJim Ingham size_t num_locations = bp_sp->GetNumLocations();
6314298b1b8SJim Ingham for (size_t loc_idx = 0; loc_idx < num_locations; loc_idx++) {
6324298b1b8SJim Ingham BreakpointLocationSP loc_sp
6334298b1b8SJim Ingham = bp_sp->GetLocationAtIndex(loc_idx);
6344298b1b8SJim Ingham if (loc_sp->IsEnabled()) {
6354298b1b8SJim Ingham any_enabled = true;
6364298b1b8SJim Ingham break;
6374298b1b8SJim Ingham }
6384298b1b8SJim Ingham }
6394298b1b8SJim Ingham } else {
6404298b1b8SJim Ingham // A location was specified, check if it was enabled:
6414298b1b8SJim Ingham BreakpointLocationSP loc_sp = bp_sp->FindLocationByID(loc_id);
6424298b1b8SJim Ingham if (loc_sp->IsEnabled())
6434298b1b8SJim Ingham any_enabled = true;
6444298b1b8SJim Ingham }
6454298b1b8SJim Ingham
6464298b1b8SJim Ingham // Then sort the bp & bp.loc entries for later use:
6474298b1b8SJim Ingham if (bkpt_id.GetLocationID() == LLDB_INVALID_BREAK_ID)
6484298b1b8SJim Ingham bkpts_seen.insert(bkpt_id.GetBreakpointID());
6494298b1b8SJim Ingham else {
6504298b1b8SJim Ingham bkpts_with_locs_seen.insert(bkpt_id.GetBreakpointID());
6514298b1b8SJim Ingham with_locs.AddBreakpointID(bkpt_id);
6524298b1b8SJim Ingham }
6534298b1b8SJim Ingham }
6544298b1b8SJim Ingham }
6554298b1b8SJim Ingham // Do all the error checking here so once we start disabling we don't
6564298b1b8SJim Ingham // have to back out half-way through.
6574298b1b8SJim Ingham
6584298b1b8SJim Ingham // Make sure at least one of the specified breakpoints is enabled.
6594298b1b8SJim Ingham if (!any_enabled) {
6604298b1b8SJim Ingham result.AppendError("at least one of the continue-to breakpoints must "
6614298b1b8SJim Ingham "be enabled.");
6624298b1b8SJim Ingham return false;
6634298b1b8SJim Ingham }
6644298b1b8SJim Ingham
6654298b1b8SJim Ingham // Also, if you specify BOTH a breakpoint and one of it's locations,
6664298b1b8SJim Ingham // we flag that as an error, since it won't do what you expect, the
6674298b1b8SJim Ingham // breakpoint directive will mean "run to all locations", which is not
6684298b1b8SJim Ingham // what the location directive means...
6694298b1b8SJim Ingham for (break_id_t bp_id : bkpts_with_locs_seen) {
6704298b1b8SJim Ingham if (bkpts_seen.count(bp_id)) {
6714298b1b8SJim Ingham result.AppendErrorWithFormatv("can't specify both a breakpoint and "
6724298b1b8SJim Ingham "one of its locations: {0}", bp_id);
6734298b1b8SJim Ingham }
6744298b1b8SJim Ingham }
6754298b1b8SJim Ingham
6764298b1b8SJim Ingham // Now go through the breakpoints in the target, disabling all the ones
6774298b1b8SJim Ingham // that the user didn't mention:
6784298b1b8SJim Ingham for (BreakpointSP bp_sp : bkpt_list.Breakpoints()) {
6794298b1b8SJim Ingham break_id_t bp_id = bp_sp->GetID();
6804298b1b8SJim Ingham // Handle the case where no locations were specified. Note we don't
6814298b1b8SJim Ingham // have to worry about the case where a breakpoint and one of its
6824298b1b8SJim Ingham // locations are both in the lists, we've already disallowed that.
6834298b1b8SJim Ingham if (!bkpts_with_locs_seen.count(bp_id)) {
6844298b1b8SJim Ingham if (!bkpts_seen.count(bp_id) && bp_sp->IsEnabled()) {
6854298b1b8SJim Ingham bkpts_disabled.push_back(bp_id);
6864298b1b8SJim Ingham bp_sp->SetEnabled(false);
6874298b1b8SJim Ingham }
6884298b1b8SJim Ingham continue;
6894298b1b8SJim Ingham }
6904298b1b8SJim Ingham // Next, handle the case where a location was specified:
6914298b1b8SJim Ingham // Run through all the locations of this breakpoint and disable
6924298b1b8SJim Ingham // the ones that aren't on our "with locations" BreakpointID list:
6934298b1b8SJim Ingham size_t num_locations = bp_sp->GetNumLocations();
6944298b1b8SJim Ingham BreakpointID tmp_id(bp_id, LLDB_INVALID_BREAK_ID);
6954298b1b8SJim Ingham for (size_t loc_idx = 0; loc_idx < num_locations; loc_idx++) {
6964298b1b8SJim Ingham BreakpointLocationSP loc_sp = bp_sp->GetLocationAtIndex(loc_idx);
6974298b1b8SJim Ingham tmp_id.SetBreakpointLocationID(loc_idx);
6984298b1b8SJim Ingham size_t position = 0;
6994298b1b8SJim Ingham if (!with_locs.FindBreakpointID(tmp_id, &position)
7004298b1b8SJim Ingham && loc_sp->IsEnabled()) {
7014298b1b8SJim Ingham locs_disabled.push_back(tmp_id);
7024298b1b8SJim Ingham loc_sp->SetEnabled(false);
7034298b1b8SJim Ingham }
7044298b1b8SJim Ingham }
7054298b1b8SJim Ingham }
7064298b1b8SJim Ingham }
7074298b1b8SJim Ingham
70841f2b940SJim Ingham { // Scope for thread list mutex:
709b9c1b51eSKate Stone std::lock_guard<std::recursive_mutex> guard(
710b9c1b51eSKate Stone process->GetThreadList().GetMutex());
71130fdc8d8SChris Lattner const uint32_t num_threads = process->GetThreadList().GetSize();
71230fdc8d8SChris Lattner
71330fdc8d8SChris Lattner // Set the actions that the threads should each take when resuming
714b9c1b51eSKate Stone for (uint32_t idx = 0; idx < num_threads; ++idx) {
7156c9ed91cSJim Ingham const bool override_suspend = false;
716b9c1b51eSKate Stone process->GetThreadList().GetThreadAtIndex(idx)->SetResumeState(
717b9c1b51eSKate Stone eStateRunning, override_suspend);
71830fdc8d8SChris Lattner }
71941f2b940SJim Ingham }
72030fdc8d8SChris Lattner
7214446487dSPavel Labath const uint32_t iohandler_id = process->GetIOHandlerID();
7224446487dSPavel Labath
723dc6224e0SGreg Clayton StreamString stream;
72497206d57SZachary Turner Status error;
7254298b1b8SJim Ingham // For now we can only do -b with synchronous:
7264298b1b8SJim Ingham bool old_sync = GetDebugger().GetAsyncExecution();
7274298b1b8SJim Ingham
7284298b1b8SJim Ingham if (run_to_bkpt_ids.GetSize() != 0) {
7294298b1b8SJim Ingham GetDebugger().SetAsyncExecution(false);
7304298b1b8SJim Ingham synchronous_execution = true;
7314298b1b8SJim Ingham }
732dc6224e0SGreg Clayton if (synchronous_execution)
733dc6224e0SGreg Clayton error = process->ResumeSynchronous(&stream);
734dc6224e0SGreg Clayton else
735dc6224e0SGreg Clayton error = process->Resume();
736a3b89e27STodd Fiala
7374298b1b8SJim Ingham if (run_to_bkpt_ids.GetSize() != 0) {
7384298b1b8SJim Ingham GetDebugger().SetAsyncExecution(old_sync);
7394298b1b8SJim Ingham }
7404298b1b8SJim Ingham
7414298b1b8SJim Ingham // Now re-enable the breakpoints we disabled:
7424298b1b8SJim Ingham BreakpointList &bkpt_list = target->GetBreakpointList();
7434298b1b8SJim Ingham for (break_id_t bp_id : bkpts_disabled) {
7444298b1b8SJim Ingham BreakpointSP bp_sp = bkpt_list.FindBreakpointByID(bp_id);
7454298b1b8SJim Ingham if (bp_sp)
7464298b1b8SJim Ingham bp_sp->SetEnabled(true);
7474298b1b8SJim Ingham }
7484298b1b8SJim Ingham for (const BreakpointID &bkpt_id : locs_disabled) {
7494298b1b8SJim Ingham BreakpointSP bp_sp
7504298b1b8SJim Ingham = bkpt_list.FindBreakpointByID(bkpt_id.GetBreakpointID());
7514298b1b8SJim Ingham if (bp_sp) {
7524298b1b8SJim Ingham BreakpointLocationSP loc_sp
7534298b1b8SJim Ingham = bp_sp->FindLocationByID(bkpt_id.GetLocationID());
7544298b1b8SJim Ingham if (loc_sp)
7554298b1b8SJim Ingham loc_sp->SetEnabled(true);
7564298b1b8SJim Ingham }
7574298b1b8SJim Ingham }
7584298b1b8SJim Ingham
759b9c1b51eSKate Stone if (error.Success()) {
760b9c1b51eSKate Stone // There is a race condition where this thread will return up the call
76105097246SAdrian Prantl // stack to the main command handler and show an (lldb) prompt before
76205097246SAdrian Prantl // HandlePrivateEvent (from PrivateStateThread) has a chance to call
76305097246SAdrian Prantl // PushProcessIOHandler().
7643879fe00SPavel Labath process->SyncIOHandler(iohandler_id, std::chrono::seconds(2));
765a3b89e27STodd Fiala
766b9c1b51eSKate Stone result.AppendMessageWithFormat("Process %" PRIu64 " resuming\n",
767b9c1b51eSKate Stone process->GetID());
768b9c1b51eSKate Stone if (synchronous_execution) {
769b9c1b51eSKate Stone // If any state changed events had anything to say, add that to the
770b9c1b51eSKate Stone // result
771c156427dSZachary Turner result.AppendMessage(stream.GetString());
77230fdc8d8SChris Lattner
77330fdc8d8SChris Lattner result.SetDidChangeProcessState(true);
77430fdc8d8SChris Lattner result.SetStatus(eReturnStatusSuccessFinishNoResult);
775b9c1b51eSKate Stone } else {
77630fdc8d8SChris Lattner result.SetStatus(eReturnStatusSuccessContinuingNoResult);
77730fdc8d8SChris Lattner }
778b9c1b51eSKate Stone } else {
779b9c1b51eSKate Stone result.AppendErrorWithFormat("Failed to resume process: %s.\n",
780b9c1b51eSKate Stone error.AsCString());
78130fdc8d8SChris Lattner }
782b9c1b51eSKate Stone } else {
783b9c1b51eSKate Stone result.AppendErrorWithFormat(
784b9c1b51eSKate Stone "Process cannot be continued from its current state (%s).\n",
78530fdc8d8SChris Lattner StateAsCString(state));
78630fdc8d8SChris Lattner }
78730fdc8d8SChris Lattner return result.Succeeded();
78830fdc8d8SChris Lattner }
7890e41084aSJim Ingham
GetOptions()790b9c1b51eSKate Stone Options *GetOptions() override { return &m_options; }
7910e41084aSJim Ingham
7920e41084aSJim Ingham CommandOptions m_options;
7930e41084aSJim Ingham };
7940e41084aSJim Ingham
79530fdc8d8SChris Lattner // CommandObjectProcessDetach
796438dfcffSRaphael Isemann #define LLDB_OPTIONS_process_detach
797438dfcffSRaphael Isemann #include "CommandOptions.inc"
7981f0f5b5bSZachary Turner
799bb9caf73SJim Ingham #pragma mark CommandObjectProcessDetach
80030fdc8d8SChris Lattner
801b9c1b51eSKate Stone class CommandObjectProcessDetach : public CommandObjectParsed {
80230fdc8d8SChris Lattner public:
803b9c1b51eSKate Stone class CommandOptions : public Options {
804acff8950SJim Ingham public:
CommandOptions()805abb0ed44SKazu Hirata CommandOptions() { OptionParsingStarting(nullptr); }
806acff8950SJim Ingham
80749bcfd80SEugene Zelenko ~CommandOptions() override = default;
808acff8950SJim Ingham
SetOptionValue(uint32_t option_idx,llvm::StringRef option_arg,ExecutionContext * execution_context)80997206d57SZachary Turner Status SetOptionValue(uint32_t option_idx, llvm::StringRef option_arg,
810b9c1b51eSKate Stone ExecutionContext *execution_context) override {
81197206d57SZachary Turner Status error;
812acff8950SJim Ingham const int short_option = m_getopt_table[option_idx].val;
813acff8950SJim Ingham
814b9c1b51eSKate Stone switch (short_option) {
815acff8950SJim Ingham case 's':
816acff8950SJim Ingham bool tmp_result;
817acff8950SJim Ingham bool success;
81847cbf4a0SPavel Labath tmp_result = OptionArgParser::ToBoolean(option_arg, false, &success);
819acff8950SJim Ingham if (!success)
820b9c1b51eSKate Stone error.SetErrorStringWithFormat("invalid boolean option: \"%s\"",
821fe11483bSZachary Turner option_arg.str().c_str());
822b9c1b51eSKate Stone else {
823acff8950SJim Ingham if (tmp_result)
824acff8950SJim Ingham m_keep_stopped = eLazyBoolYes;
825acff8950SJim Ingham else
826acff8950SJim Ingham m_keep_stopped = eLazyBoolNo;
827acff8950SJim Ingham }
828acff8950SJim Ingham break;
829acff8950SJim Ingham default:
83036162014SRaphael Isemann llvm_unreachable("Unimplemented option");
831acff8950SJim Ingham }
832acff8950SJim Ingham return error;
833acff8950SJim Ingham }
834acff8950SJim Ingham
OptionParsingStarting(ExecutionContext * execution_context)835b9c1b51eSKate Stone void OptionParsingStarting(ExecutionContext *execution_context) override {
836acff8950SJim Ingham m_keep_stopped = eLazyBoolCalculate;
837acff8950SJim Ingham }
838acff8950SJim Ingham
GetDefinitions()8391f0f5b5bSZachary Turner llvm::ArrayRef<OptionDefinition> GetDefinitions() override {
84070602439SZachary Turner return llvm::makeArrayRef(g_process_detach_options);
8411f0f5b5bSZachary Turner }
842acff8950SJim Ingham
843acff8950SJim Ingham // Instance variables to hold the values for command options.
844acff8950SJim Ingham LazyBool m_keep_stopped;
845acff8950SJim Ingham };
84630fdc8d8SChris Lattner
CommandObjectProcessDetach(CommandInterpreter & interpreter)8477428a18cSKate Stone CommandObjectProcessDetach(CommandInterpreter &interpreter)
848b9c1b51eSKate Stone : CommandObjectParsed(interpreter, "process detach",
849b9c1b51eSKate Stone "Detach from the current target process.",
850a7015092SGreg Clayton "process detach",
851b9c1b51eSKate Stone eCommandRequiresProcess | eCommandTryTargetAPILock |
852abb0ed44SKazu Hirata eCommandProcessMustBeLaunched) {}
85330fdc8d8SChris Lattner
85449bcfd80SEugene Zelenko ~CommandObjectProcessDetach() override = default;
85530fdc8d8SChris Lattner
GetOptions()856b9c1b51eSKate Stone Options *GetOptions() override { return &m_options; }
857acff8950SJim Ingham
8585a988416SJim Ingham protected:
DoExecute(Args & command,CommandReturnObject & result)859b9c1b51eSKate Stone bool DoExecute(Args &command, CommandReturnObject &result) override {
860f9fc609fSGreg Clayton Process *process = m_exe_ctx.GetProcessPtr();
861acff8950SJim Ingham // FIXME: This will be a Command Option:
862acff8950SJim Ingham bool keep_stopped;
863b9c1b51eSKate Stone if (m_options.m_keep_stopped == eLazyBoolCalculate) {
864acff8950SJim Ingham // Check the process default:
86549bcfd80SEugene Zelenko keep_stopped = process->GetDetachKeepsStopped();
866b9c1b51eSKate Stone } else if (m_options.m_keep_stopped == eLazyBoolYes)
867acff8950SJim Ingham keep_stopped = true;
868acff8950SJim Ingham else
869acff8950SJim Ingham keep_stopped = false;
870acff8950SJim Ingham
87197206d57SZachary Turner Status error(process->Detach(keep_stopped));
872b9c1b51eSKate Stone if (error.Success()) {
87330fdc8d8SChris Lattner result.SetStatus(eReturnStatusSuccessFinishResult);
874b9c1b51eSKate Stone } else {
87530fdc8d8SChris Lattner result.AppendErrorWithFormat("Detach failed: %s\n", error.AsCString());
87630fdc8d8SChris Lattner return false;
87730fdc8d8SChris Lattner }
87830fdc8d8SChris Lattner return result.Succeeded();
87930fdc8d8SChris Lattner }
880acff8950SJim Ingham
881acff8950SJim Ingham CommandOptions m_options;
882acff8950SJim Ingham };
883acff8950SJim Ingham
884b766a73dSGreg Clayton // CommandObjectProcessConnect
885438dfcffSRaphael Isemann #define LLDB_OPTIONS_process_connect
886438dfcffSRaphael Isemann #include "CommandOptions.inc"
8871f0f5b5bSZachary Turner
888b766a73dSGreg Clayton #pragma mark CommandObjectProcessConnect
889b766a73dSGreg Clayton
890b9c1b51eSKate Stone class CommandObjectProcessConnect : public CommandObjectParsed {
891b766a73dSGreg Clayton public:
892b9c1b51eSKate Stone class CommandOptions : public Options {
893b766a73dSGreg Clayton public:
CommandOptions()894abb0ed44SKazu Hirata CommandOptions() {
895b9c1b51eSKate Stone // Keep default values of all options in one place: OptionParsingStarting
896b9c1b51eSKate Stone // ()
897e1cfbc79STodd Fiala OptionParsingStarting(nullptr);
898b766a73dSGreg Clayton }
899b766a73dSGreg Clayton
90049bcfd80SEugene Zelenko ~CommandOptions() override = default;
901b766a73dSGreg Clayton
SetOptionValue(uint32_t option_idx,llvm::StringRef option_arg,ExecutionContext * execution_context)90297206d57SZachary Turner Status SetOptionValue(uint32_t option_idx, llvm::StringRef option_arg,
903b9c1b51eSKate Stone ExecutionContext *execution_context) override {
90497206d57SZachary Turner Status error;
9053bcdfc0eSGreg Clayton const int short_option = m_getopt_table[option_idx].val;
906b766a73dSGreg Clayton
907b9c1b51eSKate Stone switch (short_option) {
908b766a73dSGreg Clayton case 'p':
909adcd0268SBenjamin Kramer plugin_name.assign(std::string(option_arg));
910b766a73dSGreg Clayton break;
911b766a73dSGreg Clayton
912b766a73dSGreg Clayton default:
91336162014SRaphael Isemann llvm_unreachable("Unimplemented option");
914b766a73dSGreg Clayton }
915b766a73dSGreg Clayton return error;
916b766a73dSGreg Clayton }
917b766a73dSGreg Clayton
OptionParsingStarting(ExecutionContext * execution_context)918b9c1b51eSKate Stone void OptionParsingStarting(ExecutionContext *execution_context) override {
919b766a73dSGreg Clayton plugin_name.clear();
920b766a73dSGreg Clayton }
921b766a73dSGreg Clayton
GetDefinitions()9221f0f5b5bSZachary Turner llvm::ArrayRef<OptionDefinition> GetDefinitions() override {
92370602439SZachary Turner return llvm::makeArrayRef(g_process_connect_options);
9241f0f5b5bSZachary Turner }
925b766a73dSGreg Clayton
926b766a73dSGreg Clayton // Instance variables to hold the values for command options.
927b766a73dSGreg Clayton
928b766a73dSGreg Clayton std::string plugin_name;
929b766a73dSGreg Clayton };
930b766a73dSGreg Clayton
CommandObjectProcessConnect(CommandInterpreter & interpreter)931b9c1b51eSKate Stone CommandObjectProcessConnect(CommandInterpreter &interpreter)
932b9c1b51eSKate Stone : CommandObjectParsed(interpreter, "process connect",
933b766a73dSGreg Clayton "Connect to a remote debug service.",
934c1b07d61SJim Ingham "process connect <remote-url>", 0) {
935c1b07d61SJim Ingham CommandArgumentData connect_arg{eArgTypeConnectURL, eArgRepeatPlain};
936c1b07d61SJim Ingham m_arguments.push_back({connect_arg});
937c1b07d61SJim Ingham }
938b766a73dSGreg Clayton
93949bcfd80SEugene Zelenko ~CommandObjectProcessConnect() override = default;
940b766a73dSGreg Clayton
GetOptions()941b9c1b51eSKate Stone Options *GetOptions() override { return &m_options; }
9425a988416SJim Ingham
9435a988416SJim Ingham protected:
DoExecute(Args & command,CommandReturnObject & result)944b9c1b51eSKate Stone bool DoExecute(Args &command, CommandReturnObject &result) override {
945b9c1b51eSKate Stone if (command.GetArgumentCount() != 1) {
946b9c1b51eSKate Stone result.AppendErrorWithFormat(
947b9c1b51eSKate Stone "'%s' takes exactly one argument:\nUsage: %s\n", m_cmd_name.c_str(),
948ccd6cffbSTamas Berghammer m_cmd_syntax.c_str());
949ccd6cffbSTamas Berghammer return false;
950ccd6cffbSTamas Berghammer }
951ccd6cffbSTamas Berghammer
952ccd6cffbSTamas Berghammer Process *process = m_exe_ctx.GetProcessPtr();
953b9c1b51eSKate Stone if (process && process->IsAlive()) {
954b9c1b51eSKate Stone result.AppendErrorWithFormat(
955b9c1b51eSKate Stone "Process %" PRIu64
956b9c1b51eSKate Stone " is currently being debugged, kill the process before connecting.\n",
957b766a73dSGreg Clayton process->GetID());
958b766a73dSGreg Clayton return false;
959b766a73dSGreg Clayton }
960b766a73dSGreg Clayton
961ccd6cffbSTamas Berghammer const char *plugin_name = nullptr;
962b766a73dSGreg Clayton if (!m_options.plugin_name.empty())
963b766a73dSGreg Clayton plugin_name = m_options.plugin_name.c_str();
964b766a73dSGreg Clayton
96597206d57SZachary Turner Status error;
96657179860SJonas Devlieghere Debugger &debugger = GetDebugger();
967ccd6cffbSTamas Berghammer PlatformSP platform_sp = m_interpreter.GetPlatform(true);
968706cccb8SJonas Devlieghere ProcessSP process_sp =
969706cccb8SJonas Devlieghere debugger.GetAsyncExecution()
970706cccb8SJonas Devlieghere ? platform_sp->ConnectProcess(
971b9c1b51eSKate Stone command.GetArgumentAtIndex(0), plugin_name, debugger,
972706cccb8SJonas Devlieghere debugger.GetSelectedTarget().get(), error)
973706cccb8SJonas Devlieghere : platform_sp->ConnectProcessSynchronous(
974706cccb8SJonas Devlieghere command.GetArgumentAtIndex(0), plugin_name, debugger,
975706cccb8SJonas Devlieghere result.GetOutputStream(), debugger.GetSelectedTarget().get(),
976706cccb8SJonas Devlieghere error);
977b9c1b51eSKate Stone if (error.Fail() || process_sp == nullptr) {
978ccd6cffbSTamas Berghammer result.AppendError(error.AsCString("Error connecting to the process"));
979b766a73dSGreg Clayton return false;
980b766a73dSGreg Clayton }
981ccd6cffbSTamas Berghammer return true;
982b766a73dSGreg Clayton }
983b766a73dSGreg Clayton
984b766a73dSGreg Clayton CommandOptions m_options;
985b766a73dSGreg Clayton };
986b766a73dSGreg Clayton
987998255bfSGreg Clayton // CommandObjectProcessPlugin
988998255bfSGreg Clayton #pragma mark CommandObjectProcessPlugin
989998255bfSGreg Clayton
990b9c1b51eSKate Stone class CommandObjectProcessPlugin : public CommandObjectProxy {
991998255bfSGreg Clayton public:
CommandObjectProcessPlugin(CommandInterpreter & interpreter)9927428a18cSKate Stone CommandObjectProcessPlugin(CommandInterpreter &interpreter)
993b9c1b51eSKate Stone : CommandObjectProxy(
994b9c1b51eSKate Stone interpreter, "process plugin",
995b9c1b51eSKate Stone "Send a custom command to the current target process plug-in.",
996b9c1b51eSKate Stone "process plugin <args>", 0) {}
997998255bfSGreg Clayton
99849bcfd80SEugene Zelenko ~CommandObjectProcessPlugin() override = default;
999998255bfSGreg Clayton
GetProxyCommandObject()1000b9c1b51eSKate Stone CommandObject *GetProxyCommandObject() override {
1001e05b2efeSGreg Clayton Process *process = m_interpreter.GetExecutionContext().GetProcessPtr();
1002998255bfSGreg Clayton if (process)
1003998255bfSGreg Clayton return process->GetPluginCommandObject();
100449bcfd80SEugene Zelenko return nullptr;
1005998255bfSGreg Clayton }
1006998255bfSGreg Clayton };
1007998255bfSGreg Clayton
10088f343b09SGreg Clayton // CommandObjectProcessLoad
1009438dfcffSRaphael Isemann #define LLDB_OPTIONS_process_load
1010438dfcffSRaphael Isemann #include "CommandOptions.inc"
10111f0f5b5bSZachary Turner
1012bb9caf73SJim Ingham #pragma mark CommandObjectProcessLoad
10138f343b09SGreg Clayton
1014b9c1b51eSKate Stone class CommandObjectProcessLoad : public CommandObjectParsed {
10158f343b09SGreg Clayton public:
1016b9c1b51eSKate Stone class CommandOptions : public Options {
10174fbd67acSTamas Berghammer public:
CommandOptions()1018abb0ed44SKazu Hirata CommandOptions() {
1019b9c1b51eSKate Stone // Keep default values of all options in one place: OptionParsingStarting
1020b9c1b51eSKate Stone // ()
1021e1cfbc79STodd Fiala OptionParsingStarting(nullptr);
10224fbd67acSTamas Berghammer }
10234fbd67acSTamas Berghammer
10244fbd67acSTamas Berghammer ~CommandOptions() override = default;
10254fbd67acSTamas Berghammer
SetOptionValue(uint32_t option_idx,llvm::StringRef option_arg,ExecutionContext * execution_context)102697206d57SZachary Turner Status SetOptionValue(uint32_t option_idx, llvm::StringRef option_arg,
1027b9c1b51eSKate Stone ExecutionContext *execution_context) override {
102897206d57SZachary Turner Status error;
10294fbd67acSTamas Berghammer const int short_option = m_getopt_table[option_idx].val;
1030b9c1b51eSKate Stone switch (short_option) {
10314fbd67acSTamas Berghammer case 'i':
10324fbd67acSTamas Berghammer do_install = true;
1033fe11483bSZachary Turner if (!option_arg.empty())
10348f3be7a3SJonas Devlieghere install_path.SetFile(option_arg, FileSpec::Style::native);
10354fbd67acSTamas Berghammer break;
10364fbd67acSTamas Berghammer default:
103736162014SRaphael Isemann llvm_unreachable("Unimplemented option");
10384fbd67acSTamas Berghammer }
10394fbd67acSTamas Berghammer return error;
10404fbd67acSTamas Berghammer }
10414fbd67acSTamas Berghammer
OptionParsingStarting(ExecutionContext * execution_context)1042b9c1b51eSKate Stone void OptionParsingStarting(ExecutionContext *execution_context) override {
10434fbd67acSTamas Berghammer do_install = false;
10444fbd67acSTamas Berghammer install_path.Clear();
10454fbd67acSTamas Berghammer }
10464fbd67acSTamas Berghammer
GetDefinitions()10471f0f5b5bSZachary Turner llvm::ArrayRef<OptionDefinition> GetDefinitions() override {
104870602439SZachary Turner return llvm::makeArrayRef(g_process_load_options);
10491f0f5b5bSZachary Turner }
10504fbd67acSTamas Berghammer
10514fbd67acSTamas Berghammer // Instance variables to hold the values for command options.
10524fbd67acSTamas Berghammer bool do_install;
10534fbd67acSTamas Berghammer FileSpec install_path;
10544fbd67acSTamas Berghammer };
10558f343b09SGreg Clayton
CommandObjectProcessLoad(CommandInterpreter & interpreter)1056b9c1b51eSKate Stone CommandObjectProcessLoad(CommandInterpreter &interpreter)
1057b9c1b51eSKate Stone : CommandObjectParsed(interpreter, "process load",
10588f343b09SGreg Clayton "Load a shared library into the current process.",
10598f343b09SGreg Clayton "process load <filename> [<filename> ...]",
1060b9c1b51eSKate Stone eCommandRequiresProcess | eCommandTryTargetAPILock |
1061e87764f2SEnrico Granata eCommandProcessMustBeLaunched |
1062c1b07d61SJim Ingham eCommandProcessMustBePaused) {
1063c1b07d61SJim Ingham CommandArgumentData file_arg{eArgTypePath, eArgRepeatPlus};
1064c1b07d61SJim Ingham m_arguments.push_back({file_arg});
1065c1b07d61SJim Ingham }
10668f343b09SGreg Clayton
10674fbd67acSTamas Berghammer ~CommandObjectProcessLoad() override = default;
10684fbd67acSTamas Berghammer
1069e1cd7cacSGongyu Deng void
HandleArgumentCompletion(CompletionRequest & request,OptionElementVector & opt_element_vector)1070e1cd7cacSGongyu Deng HandleArgumentCompletion(CompletionRequest &request,
1071e1cd7cacSGongyu Deng OptionElementVector &opt_element_vector) override {
1072e1cd7cacSGongyu Deng if (!m_exe_ctx.HasProcessScope())
1073e1cd7cacSGongyu Deng return;
1074e1cd7cacSGongyu Deng
1075e1cd7cacSGongyu Deng CommandCompletions::InvokeCommonCompletionCallbacks(
1076e1cd7cacSGongyu Deng GetCommandInterpreter(), CommandCompletions::eDiskFileCompletion,
1077e1cd7cacSGongyu Deng request, nullptr);
1078e1cd7cacSGongyu Deng }
1079e1cd7cacSGongyu Deng
GetOptions()1080b9c1b51eSKate Stone Options *GetOptions() override { return &m_options; }
10818f343b09SGreg Clayton
10825a988416SJim Ingham protected:
DoExecute(Args & command,CommandReturnObject & result)1083b9c1b51eSKate Stone bool DoExecute(Args &command, CommandReturnObject &result) override {
1084f9fc609fSGreg Clayton Process *process = m_exe_ctx.GetProcessPtr();
10858f343b09SGreg Clayton
108697d2c401SZachary Turner for (auto &entry : command.entries()) {
108797206d57SZachary Turner Status error;
10883cb132a0STamas Berghammer PlatformSP platform = process->GetTarget().GetPlatform();
10890d9a201eSRaphael Isemann llvm::StringRef image_path = entry.ref();
10904fbd67acSTamas Berghammer uint32_t image_token = LLDB_INVALID_IMAGE_TOKEN;
10914fbd67acSTamas Berghammer
1092b9c1b51eSKate Stone if (!m_options.do_install) {
10938f3be7a3SJonas Devlieghere FileSpec image_spec(image_path);
10943cb132a0STamas Berghammer platform->ResolveRemotePath(image_spec, image_spec);
1095b9c1b51eSKate Stone image_token =
1096b9c1b51eSKate Stone platform->LoadImage(process, FileSpec(), image_spec, error);
1097b9c1b51eSKate Stone } else if (m_options.install_path) {
10988f3be7a3SJonas Devlieghere FileSpec image_spec(image_path);
10998f3be7a3SJonas Devlieghere FileSystem::Instance().Resolve(image_spec);
1100b9c1b51eSKate Stone platform->ResolveRemotePath(m_options.install_path,
1101b9c1b51eSKate Stone m_options.install_path);
1102b9c1b51eSKate Stone image_token = platform->LoadImage(process, image_spec,
1103b9c1b51eSKate Stone m_options.install_path, error);
1104b9c1b51eSKate Stone } else {
11058f3be7a3SJonas Devlieghere FileSpec image_spec(image_path);
11068f3be7a3SJonas Devlieghere FileSystem::Instance().Resolve(image_spec);
1107b9c1b51eSKate Stone image_token =
1108b9c1b51eSKate Stone platform->LoadImage(process, image_spec, FileSpec(), error);
11094fbd67acSTamas Berghammer }
11104fbd67acSTamas Berghammer
1111b9c1b51eSKate Stone if (image_token != LLDB_INVALID_IMAGE_TOKEN) {
1112b9c1b51eSKate Stone result.AppendMessageWithFormat(
111397d2c401SZachary Turner "Loading \"%s\"...ok\nImage %u loaded.\n", image_path.str().c_str(),
111497d2c401SZachary Turner image_token);
11158f343b09SGreg Clayton result.SetStatus(eReturnStatusSuccessFinishResult);
1116b9c1b51eSKate Stone } else {
111797d2c401SZachary Turner result.AppendErrorWithFormat("failed to load '%s': %s",
111897d2c401SZachary Turner image_path.str().c_str(),
1119b9c1b51eSKate Stone error.AsCString());
11208f343b09SGreg Clayton }
11218f343b09SGreg Clayton }
11228f343b09SGreg Clayton return result.Succeeded();
11238f343b09SGreg Clayton }
11244fbd67acSTamas Berghammer
11254fbd67acSTamas Berghammer CommandOptions m_options;
11268f343b09SGreg Clayton };
11278f343b09SGreg Clayton
11288f343b09SGreg Clayton // CommandObjectProcessUnload
1129bb9caf73SJim Ingham #pragma mark CommandObjectProcessUnload
11308f343b09SGreg Clayton
1131b9c1b51eSKate Stone class CommandObjectProcessUnload : public CommandObjectParsed {
11328f343b09SGreg Clayton public:
CommandObjectProcessUnload(CommandInterpreter & interpreter)1133b9c1b51eSKate Stone CommandObjectProcessUnload(CommandInterpreter &interpreter)
1134b9c1b51eSKate Stone : CommandObjectParsed(
1135b9c1b51eSKate Stone interpreter, "process unload",
1136b9c1b51eSKate Stone "Unload a shared library from the current process using the index "
1137b9c1b51eSKate Stone "returned by a previous call to \"process load\".",
11388f343b09SGreg Clayton "process unload <index>",
1139b9c1b51eSKate Stone eCommandRequiresProcess | eCommandTryTargetAPILock |
1140c1b07d61SJim Ingham eCommandProcessMustBeLaunched | eCommandProcessMustBePaused) {
1141c1b07d61SJim Ingham CommandArgumentData load_idx_arg{eArgTypeUnsignedInteger, eArgRepeatPlain};
1142c1b07d61SJim Ingham m_arguments.push_back({load_idx_arg});
1143c1b07d61SJim Ingham }
11448f343b09SGreg Clayton
114549bcfd80SEugene Zelenko ~CommandObjectProcessUnload() override = default;
11468f343b09SGreg Clayton
1147e1cd7cacSGongyu Deng void
HandleArgumentCompletion(CompletionRequest & request,OptionElementVector & opt_element_vector)1148e1cd7cacSGongyu Deng HandleArgumentCompletion(CompletionRequest &request,
1149e1cd7cacSGongyu Deng OptionElementVector &opt_element_vector) override {
1150e1cd7cacSGongyu Deng
1151e1cd7cacSGongyu Deng if (request.GetCursorIndex() || !m_exe_ctx.HasProcessScope())
1152e1cd7cacSGongyu Deng return;
1153e1cd7cacSGongyu Deng
1154e1cd7cacSGongyu Deng Process *process = m_exe_ctx.GetProcessPtr();
1155e1cd7cacSGongyu Deng
1156e1cd7cacSGongyu Deng const std::vector<lldb::addr_t> &tokens = process->GetImageTokens();
1157e1cd7cacSGongyu Deng const size_t token_num = tokens.size();
1158e1cd7cacSGongyu Deng for (size_t i = 0; i < token_num; ++i) {
1159e1cd7cacSGongyu Deng if (tokens[i] == LLDB_INVALID_IMAGE_TOKEN)
1160e1cd7cacSGongyu Deng continue;
1161e1cd7cacSGongyu Deng request.TryCompleteCurrentArg(std::to_string(i));
1162e1cd7cacSGongyu Deng }
1163e1cd7cacSGongyu Deng }
1164e1cd7cacSGongyu Deng
11655a988416SJim Ingham protected:
DoExecute(Args & command,CommandReturnObject & result)1166b9c1b51eSKate Stone bool DoExecute(Args &command, CommandReturnObject &result) override {
1167f9fc609fSGreg Clayton Process *process = m_exe_ctx.GetProcessPtr();
11688f343b09SGreg Clayton
116997d2c401SZachary Turner for (auto &entry : command.entries()) {
117097d2c401SZachary Turner uint32_t image_token;
11710d9a201eSRaphael Isemann if (entry.ref().getAsInteger(0, image_token)) {
1172b9c1b51eSKate Stone result.AppendErrorWithFormat("invalid image index argument '%s'",
11730d9a201eSRaphael Isemann entry.ref().str().c_str());
11748f343b09SGreg Clayton break;
1175b9c1b51eSKate Stone } else {
117697206d57SZachary Turner Status error(process->GetTarget().GetPlatform()->UnloadImage(
1177b9c1b51eSKate Stone process, image_token));
1178b9c1b51eSKate Stone if (error.Success()) {
1179b9c1b51eSKate Stone result.AppendMessageWithFormat(
1180b9c1b51eSKate Stone "Unloading shared library with index %u...ok\n", image_token);
11818f343b09SGreg Clayton result.SetStatus(eReturnStatusSuccessFinishResult);
1182b9c1b51eSKate Stone } else {
1183b9c1b51eSKate Stone result.AppendErrorWithFormat("failed to unload image: %s",
1184b9c1b51eSKate Stone error.AsCString());
11858f343b09SGreg Clayton break;
11868f343b09SGreg Clayton }
11878f343b09SGreg Clayton }
11888f343b09SGreg Clayton }
11898f343b09SGreg Clayton return result.Succeeded();
11908f343b09SGreg Clayton }
11918f343b09SGreg Clayton };
11928f343b09SGreg Clayton
119330fdc8d8SChris Lattner // CommandObjectProcessSignal
1194bb9caf73SJim Ingham #pragma mark CommandObjectProcessSignal
119530fdc8d8SChris Lattner
1196b9c1b51eSKate Stone class CommandObjectProcessSignal : public CommandObjectParsed {
119730fdc8d8SChris Lattner public:
CommandObjectProcessSignal(CommandInterpreter & interpreter)11987428a18cSKate Stone CommandObjectProcessSignal(CommandInterpreter &interpreter)
1199a925974bSAdrian Prantl : CommandObjectParsed(
1200a925974bSAdrian Prantl interpreter, "process signal",
1201a925974bSAdrian Prantl "Send a UNIX signal to the current target process.", nullptr,
1202a925974bSAdrian Prantl eCommandRequiresProcess | eCommandTryTargetAPILock) {
1203405fe67fSCaroline Tice CommandArgumentEntry arg;
1204405fe67fSCaroline Tice CommandArgumentData signal_arg;
1205405fe67fSCaroline Tice
1206405fe67fSCaroline Tice // Define the first (and only) variant of this arg.
1207c0dbdfb6SCaroline Tice signal_arg.arg_type = eArgTypeUnixSignal;
1208405fe67fSCaroline Tice signal_arg.arg_repetition = eArgRepeatPlain;
1209405fe67fSCaroline Tice
1210b9c1b51eSKate Stone // There is only one variant this argument could be; put it into the
1211b9c1b51eSKate Stone // argument entry.
1212405fe67fSCaroline Tice arg.push_back(signal_arg);
1213405fe67fSCaroline Tice
1214405fe67fSCaroline Tice // Push the data for the first argument into the m_arguments vector.
1215405fe67fSCaroline Tice m_arguments.push_back(arg);
121630fdc8d8SChris Lattner }
121730fdc8d8SChris Lattner
121849bcfd80SEugene Zelenko ~CommandObjectProcessSignal() override = default;
121930fdc8d8SChris Lattner
12202bba1c22SRaphael Isemann void
HandleArgumentCompletion(CompletionRequest & request,OptionElementVector & opt_element_vector)12212bba1c22SRaphael Isemann HandleArgumentCompletion(CompletionRequest &request,
12222bba1c22SRaphael Isemann OptionElementVector &opt_element_vector) override {
12232bba1c22SRaphael Isemann if (!m_exe_ctx.HasProcessScope() || request.GetCursorIndex() != 0)
12242bba1c22SRaphael Isemann return;
12252bba1c22SRaphael Isemann
12262bba1c22SRaphael Isemann UnixSignalsSP signals = m_exe_ctx.GetProcessPtr()->GetUnixSignals();
12272bba1c22SRaphael Isemann int signo = signals->GetFirstSignalNumber();
12282bba1c22SRaphael Isemann while (signo != LLDB_INVALID_SIGNAL_NUMBER) {
122907800348SRaphael Isemann request.TryCompleteCurrentArg(signals->GetSignalAsCString(signo));
12302bba1c22SRaphael Isemann signo = signals->GetNextSignalNumber(signo);
12312bba1c22SRaphael Isemann }
12322bba1c22SRaphael Isemann }
12332bba1c22SRaphael Isemann
12345a988416SJim Ingham protected:
DoExecute(Args & command,CommandReturnObject & result)1235b9c1b51eSKate Stone bool DoExecute(Args &command, CommandReturnObject &result) override {
1236f9fc609fSGreg Clayton Process *process = m_exe_ctx.GetProcessPtr();
123730fdc8d8SChris Lattner
1238b9c1b51eSKate Stone if (command.GetArgumentCount() == 1) {
1239237cd906SGreg Clayton int signo = LLDB_INVALID_SIGNAL_NUMBER;
1240237cd906SGreg Clayton
1241237cd906SGreg Clayton const char *signal_name = command.GetArgumentAtIndex(0);
12429010cef2SRaphael Isemann if (::isxdigit(signal_name[0])) {
12439010cef2SRaphael Isemann if (!llvm::to_integer(signal_name, signo))
12449010cef2SRaphael Isemann signo = LLDB_INVALID_SIGNAL_NUMBER;
12459010cef2SRaphael Isemann } else
124698d0a4b3SChaoren Lin signo = process->GetUnixSignals()->GetSignalNumberFromName(signal_name);
1247237cd906SGreg Clayton
1248b9c1b51eSKate Stone if (signo == LLDB_INVALID_SIGNAL_NUMBER) {
1249b9c1b51eSKate Stone result.AppendErrorWithFormat("Invalid signal argument '%s'.\n",
1250b9c1b51eSKate Stone command.GetArgumentAtIndex(0));
1251b9c1b51eSKate Stone } else {
125297206d57SZachary Turner Status error(process->Signal(signo));
1253b9c1b51eSKate Stone if (error.Success()) {
125430fdc8d8SChris Lattner result.SetStatus(eReturnStatusSuccessFinishResult);
1255b9c1b51eSKate Stone } else {
1256b9c1b51eSKate Stone result.AppendErrorWithFormat("Failed to send signal %i: %s\n", signo,
1257b9c1b51eSKate Stone error.AsCString());
125830fdc8d8SChris Lattner }
125930fdc8d8SChris Lattner }
1260b9c1b51eSKate Stone } else {
1261b9c1b51eSKate Stone result.AppendErrorWithFormat(
1262b9c1b51eSKate Stone "'%s' takes exactly one signal number argument:\nUsage: %s\n",
1263b9c1b51eSKate Stone m_cmd_name.c_str(), m_cmd_syntax.c_str());
126430fdc8d8SChris Lattner }
126530fdc8d8SChris Lattner return result.Succeeded();
126630fdc8d8SChris Lattner }
126730fdc8d8SChris Lattner };
126830fdc8d8SChris Lattner
126930fdc8d8SChris Lattner // CommandObjectProcessInterrupt
1270bb9caf73SJim Ingham #pragma mark CommandObjectProcessInterrupt
127130fdc8d8SChris Lattner
1272b9c1b51eSKate Stone class CommandObjectProcessInterrupt : public CommandObjectParsed {
127330fdc8d8SChris Lattner public:
CommandObjectProcessInterrupt(CommandInterpreter & interpreter)12747428a18cSKate Stone CommandObjectProcessInterrupt(CommandInterpreter &interpreter)
1275b9c1b51eSKate Stone : CommandObjectParsed(interpreter, "process interrupt",
1276b9c1b51eSKate Stone "Interrupt the current target process.",
1277a7015092SGreg Clayton "process interrupt",
1278b9c1b51eSKate Stone eCommandRequiresProcess | eCommandTryTargetAPILock |
1279b9c1b51eSKate Stone eCommandProcessMustBeLaunched) {}
128030fdc8d8SChris Lattner
128149bcfd80SEugene Zelenko ~CommandObjectProcessInterrupt() override = default;
128230fdc8d8SChris Lattner
12835a988416SJim Ingham protected:
DoExecute(Args & command,CommandReturnObject & result)1284b9c1b51eSKate Stone bool DoExecute(Args &command, CommandReturnObject &result) override {
1285f9fc609fSGreg Clayton Process *process = m_exe_ctx.GetProcessPtr();
1286b9c1b51eSKate Stone if (process == nullptr) {
128730fdc8d8SChris Lattner result.AppendError("no process to halt");
128830fdc8d8SChris Lattner return false;
128930fdc8d8SChris Lattner }
129030fdc8d8SChris Lattner
1291f9b57b9dSGreg Clayton bool clear_thread_plans = true;
129297206d57SZachary Turner Status error(process->Halt(clear_thread_plans));
1293b9c1b51eSKate Stone if (error.Success()) {
129430fdc8d8SChris Lattner result.SetStatus(eReturnStatusSuccessFinishResult);
1295b9c1b51eSKate Stone } else {
1296b9c1b51eSKate Stone result.AppendErrorWithFormat("Failed to halt process: %s\n",
1297b9c1b51eSKate Stone error.AsCString());
129830fdc8d8SChris Lattner }
129930fdc8d8SChris Lattner return result.Succeeded();
130030fdc8d8SChris Lattner }
130130fdc8d8SChris Lattner };
130230fdc8d8SChris Lattner
130330fdc8d8SChris Lattner // CommandObjectProcessKill
1304bb9caf73SJim Ingham #pragma mark CommandObjectProcessKill
130530fdc8d8SChris Lattner
1306b9c1b51eSKate Stone class CommandObjectProcessKill : public CommandObjectParsed {
130730fdc8d8SChris Lattner public:
CommandObjectProcessKill(CommandInterpreter & interpreter)13087428a18cSKate Stone CommandObjectProcessKill(CommandInterpreter &interpreter)
1309b9c1b51eSKate Stone : CommandObjectParsed(interpreter, "process kill",
1310b9c1b51eSKate Stone "Terminate the current target process.",
1311b9c1b51eSKate Stone "process kill",
1312b9c1b51eSKate Stone eCommandRequiresProcess | eCommandTryTargetAPILock |
1313b9c1b51eSKate Stone eCommandProcessMustBeLaunched) {}
131430fdc8d8SChris Lattner
131549bcfd80SEugene Zelenko ~CommandObjectProcessKill() override = default;
131630fdc8d8SChris Lattner
13175a988416SJim Ingham protected:
DoExecute(Args & command,CommandReturnObject & result)1318b9c1b51eSKate Stone bool DoExecute(Args &command, CommandReturnObject &result) override {
1319f9fc609fSGreg Clayton Process *process = m_exe_ctx.GetProcessPtr();
1320b9c1b51eSKate Stone if (process == nullptr) {
132130fdc8d8SChris Lattner result.AppendError("no process to kill");
132230fdc8d8SChris Lattner return false;
132330fdc8d8SChris Lattner }
132430fdc8d8SChris Lattner
132597206d57SZachary Turner Status error(process->Destroy(true));
1326b9c1b51eSKate Stone if (error.Success()) {
132730fdc8d8SChris Lattner result.SetStatus(eReturnStatusSuccessFinishResult);
1328b9c1b51eSKate Stone } else {
1329b9c1b51eSKate Stone result.AppendErrorWithFormat("Failed to kill process: %s\n",
1330b9c1b51eSKate Stone error.AsCString());
133130fdc8d8SChris Lattner }
133230fdc8d8SChris Lattner return result.Succeeded();
133330fdc8d8SChris Lattner }
133430fdc8d8SChris Lattner };
133530fdc8d8SChris Lattner
13369ea6dd5cSJason Molenda #define LLDB_OPTIONS_process_save_core
13379ea6dd5cSJason Molenda #include "CommandOptions.inc"
13389ea6dd5cSJason Molenda
1339b9c1b51eSKate Stone class CommandObjectProcessSaveCore : public CommandObjectParsed {
1340a2715cf1SGreg Clayton public:
CommandObjectProcessSaveCore(CommandInterpreter & interpreter)1341b9c1b51eSKate Stone CommandObjectProcessSaveCore(CommandInterpreter &interpreter)
1342eee687a6SAndrej Korman : CommandObjectParsed(
1343eee687a6SAndrej Korman interpreter, "process save-core",
1344b9c1b51eSKate Stone "Save the current process as a core file using an "
1345b9c1b51eSKate Stone "appropriate file type.",
1346eee687a6SAndrej Korman "process save-core [-s corefile-style -p plugin-name] FILE",
1347b9c1b51eSKate Stone eCommandRequiresProcess | eCommandTryTargetAPILock |
1348c1b07d61SJim Ingham eCommandProcessMustBeLaunched) {
1349c1b07d61SJim Ingham CommandArgumentData file_arg{eArgTypePath, eArgRepeatPlain};
1350c1b07d61SJim Ingham m_arguments.push_back({file_arg});
1351c1b07d61SJim Ingham }
1352a2715cf1SGreg Clayton
135349bcfd80SEugene Zelenko ~CommandObjectProcessSaveCore() override = default;
1354a2715cf1SGreg Clayton
GetOptions()13559ea6dd5cSJason Molenda Options *GetOptions() override { return &m_options; }
13569ea6dd5cSJason Molenda
13579ea6dd5cSJason Molenda class CommandOptions : public Options {
13589ea6dd5cSJason Molenda public:
135924f9a2f5SShafik Yaghmour CommandOptions() = default;
13609ea6dd5cSJason Molenda
13619ea6dd5cSJason Molenda ~CommandOptions() override = default;
13629ea6dd5cSJason Molenda
GetDefinitions()13639ea6dd5cSJason Molenda llvm::ArrayRef<OptionDefinition> GetDefinitions() override {
13649ea6dd5cSJason Molenda return llvm::makeArrayRef(g_process_save_core_options);
13659ea6dd5cSJason Molenda }
13669ea6dd5cSJason Molenda
SetOptionValue(uint32_t option_idx,llvm::StringRef option_arg,ExecutionContext * execution_context)13679ea6dd5cSJason Molenda Status SetOptionValue(uint32_t option_idx, llvm::StringRef option_arg,
13689ea6dd5cSJason Molenda ExecutionContext *execution_context) override {
13699ea6dd5cSJason Molenda const int short_option = m_getopt_table[option_idx].val;
13709ea6dd5cSJason Molenda Status error;
13719ea6dd5cSJason Molenda
13729ea6dd5cSJason Molenda switch (short_option) {
1373eee687a6SAndrej Korman case 'p':
13742ace1e57SPavel Labath m_requested_plugin_name = option_arg.str();
1375eee687a6SAndrej Korman break;
13769ea6dd5cSJason Molenda case 's':
13779ea6dd5cSJason Molenda m_requested_save_core_style =
13789ea6dd5cSJason Molenda (lldb::SaveCoreStyle)OptionArgParser::ToOptionEnum(
13799ea6dd5cSJason Molenda option_arg, GetDefinitions()[option_idx].enum_values,
13809ea6dd5cSJason Molenda eSaveCoreUnspecified, error);
13819ea6dd5cSJason Molenda break;
13829ea6dd5cSJason Molenda default:
13839ea6dd5cSJason Molenda llvm_unreachable("Unimplemented option");
13849ea6dd5cSJason Molenda }
13859ea6dd5cSJason Molenda
13869ea6dd5cSJason Molenda return {};
13879ea6dd5cSJason Molenda }
13889ea6dd5cSJason Molenda
OptionParsingStarting(ExecutionContext * execution_context)13899ea6dd5cSJason Molenda void OptionParsingStarting(ExecutionContext *execution_context) override {
13909ea6dd5cSJason Molenda m_requested_save_core_style = eSaveCoreUnspecified;
13912ace1e57SPavel Labath m_requested_plugin_name.clear();
13929ea6dd5cSJason Molenda }
13939ea6dd5cSJason Molenda
13949ea6dd5cSJason Molenda // Instance variables to hold the values for command options.
139528c878aeSShafik Yaghmour SaveCoreStyle m_requested_save_core_style = eSaveCoreUnspecified;
13962ace1e57SPavel Labath std::string m_requested_plugin_name;
13979ea6dd5cSJason Molenda };
13989ea6dd5cSJason Molenda
1399a2715cf1SGreg Clayton protected:
DoExecute(Args & command,CommandReturnObject & result)1400b9c1b51eSKate Stone bool DoExecute(Args &command, CommandReturnObject &result) override {
1401a2715cf1SGreg Clayton ProcessSP process_sp = m_exe_ctx.GetProcessSP();
1402b9c1b51eSKate Stone if (process_sp) {
1403b9c1b51eSKate Stone if (command.GetArgumentCount() == 1) {
14048f3be7a3SJonas Devlieghere FileSpec output_file(command.GetArgumentAtIndex(0));
14059ea6dd5cSJason Molenda SaveCoreStyle corefile_style = m_options.m_requested_save_core_style;
14069ea6dd5cSJason Molenda Status error =
1407eee687a6SAndrej Korman PluginManager::SaveCore(process_sp, output_file, corefile_style,
1408eee687a6SAndrej Korman m_options.m_requested_plugin_name);
1409b9c1b51eSKate Stone if (error.Success()) {
14108c31efeeSJason Molenda if (corefile_style == SaveCoreStyle::eSaveCoreDirtyOnly ||
14118c31efeeSJason Molenda corefile_style == SaveCoreStyle::eSaveCoreStackOnly) {
14129ea6dd5cSJason Molenda result.AppendMessageWithFormat(
14138c31efeeSJason Molenda "\nModified-memory or stack-memory only corefile "
14148c31efeeSJason Molenda "created. This corefile may \n"
14158c31efeeSJason Molenda "not show library/framework/app binaries "
14169ea6dd5cSJason Molenda "on a different system, or when \n"
14179ea6dd5cSJason Molenda "those binaries have "
14189ea6dd5cSJason Molenda "been updated/modified. Copies are not included\n"
14199ea6dd5cSJason Molenda "in this corefile. Use --style full to include all "
14209ea6dd5cSJason Molenda "process memory.\n");
14219ea6dd5cSJason Molenda }
1422a2715cf1SGreg Clayton result.SetStatus(eReturnStatusSuccessFinishResult);
1423b9c1b51eSKate Stone } else {
1424b9c1b51eSKate Stone result.AppendErrorWithFormat(
1425b9c1b51eSKate Stone "Failed to save core file for process: %s\n", error.AsCString());
1426a2715cf1SGreg Clayton }
1427b9c1b51eSKate Stone } else {
1428a2715cf1SGreg Clayton result.AppendErrorWithFormat("'%s' takes one arguments:\nUsage: %s\n",
1429b9c1b51eSKate Stone m_cmd_name.c_str(), m_cmd_syntax.c_str());
1430a2715cf1SGreg Clayton }
1431b9c1b51eSKate Stone } else {
1432a2715cf1SGreg Clayton result.AppendError("invalid process");
1433a2715cf1SGreg Clayton return false;
1434a2715cf1SGreg Clayton }
1435a2715cf1SGreg Clayton
1436a2715cf1SGreg Clayton return result.Succeeded();
1437a2715cf1SGreg Clayton }
14389ea6dd5cSJason Molenda
14399ea6dd5cSJason Molenda CommandOptions m_options;
1440a2715cf1SGreg Clayton };
1441a2715cf1SGreg Clayton
14424b9bea87SJim Ingham // CommandObjectProcessStatus
1443bb9caf73SJim Ingham #pragma mark CommandObjectProcessStatus
1444d7c403e6SMed Ismail Bennani #define LLDB_OPTIONS_process_status
1445d7c403e6SMed Ismail Bennani #include "CommandOptions.inc"
1446bb9caf73SJim Ingham
1447b9c1b51eSKate Stone class CommandObjectProcessStatus : public CommandObjectParsed {
14484b9bea87SJim Ingham public:
CommandObjectProcessStatus(CommandInterpreter & interpreter)14497428a18cSKate Stone CommandObjectProcessStatus(CommandInterpreter &interpreter)
1450b9c1b51eSKate Stone : CommandObjectParsed(
1451b9c1b51eSKate Stone interpreter, "process status",
1452b9c1b51eSKate Stone "Show status and stop location for the current target process.",
1453b9c1b51eSKate Stone "process status",
1454abb0ed44SKazu Hirata eCommandRequiresProcess | eCommandTryTargetAPILock) {}
14554b9bea87SJim Ingham
145649bcfd80SEugene Zelenko ~CommandObjectProcessStatus() override = default;
14574b9bea87SJim Ingham
GetOptions()1458d7c403e6SMed Ismail Bennani Options *GetOptions() override { return &m_options; }
1459d7c403e6SMed Ismail Bennani
1460d7c403e6SMed Ismail Bennani class CommandOptions : public Options {
1461d7c403e6SMed Ismail Bennani public:
146224f9a2f5SShafik Yaghmour CommandOptions() = default;
1463d7c403e6SMed Ismail Bennani
1464d7c403e6SMed Ismail Bennani ~CommandOptions() override = default;
1465d7c403e6SMed Ismail Bennani
SetOptionValue(uint32_t option_idx,llvm::StringRef option_arg,ExecutionContext * execution_context)1466d7c403e6SMed Ismail Bennani Status SetOptionValue(uint32_t option_idx, llvm::StringRef option_arg,
1467d7c403e6SMed Ismail Bennani ExecutionContext *execution_context) override {
1468d7c403e6SMed Ismail Bennani const int short_option = m_getopt_table[option_idx].val;
1469d7c403e6SMed Ismail Bennani
1470d7c403e6SMed Ismail Bennani switch (short_option) {
1471d7c403e6SMed Ismail Bennani case 'v':
1472d7c403e6SMed Ismail Bennani m_verbose = true;
1473d7c403e6SMed Ismail Bennani break;
1474d7c403e6SMed Ismail Bennani default:
1475d7c403e6SMed Ismail Bennani llvm_unreachable("Unimplemented option");
1476d7c403e6SMed Ismail Bennani }
1477d7c403e6SMed Ismail Bennani
1478d7c403e6SMed Ismail Bennani return {};
1479d7c403e6SMed Ismail Bennani }
1480d7c403e6SMed Ismail Bennani
OptionParsingStarting(ExecutionContext * execution_context)1481d7c403e6SMed Ismail Bennani void OptionParsingStarting(ExecutionContext *execution_context) override {
1482d7c403e6SMed Ismail Bennani m_verbose = false;
1483d7c403e6SMed Ismail Bennani }
1484d7c403e6SMed Ismail Bennani
GetDefinitions()1485d7c403e6SMed Ismail Bennani llvm::ArrayRef<OptionDefinition> GetDefinitions() override {
1486d7c403e6SMed Ismail Bennani return llvm::makeArrayRef(g_process_status_options);
1487d7c403e6SMed Ismail Bennani }
1488d7c403e6SMed Ismail Bennani
1489d7c403e6SMed Ismail Bennani // Instance variables to hold the values for command options.
14909494c510SJonas Devlieghere bool m_verbose = false;
1491d7c403e6SMed Ismail Bennani };
1492d7c403e6SMed Ismail Bennani
1493d7c403e6SMed Ismail Bennani protected:
DoExecute(Args & command,CommandReturnObject & result)1494b9c1b51eSKate Stone bool DoExecute(Args &command, CommandReturnObject &result) override {
14957260f620SGreg Clayton Stream &strm = result.GetOutputStream();
14964b9bea87SJim Ingham result.SetStatus(eReturnStatusSuccessFinishNoResult);
1497d7c403e6SMed Ismail Bennani
1498b9c1b51eSKate Stone // No need to check "process" for validity as eCommandRequiresProcess
1499b9c1b51eSKate Stone // ensures it is valid
1500f9fc609fSGreg Clayton Process *process = m_exe_ctx.GetProcessPtr();
15017260f620SGreg Clayton const bool only_threads_with_stop_reason = true;
15027260f620SGreg Clayton const uint32_t start_frame = 0;
15037260f620SGreg Clayton const uint32_t num_frames = 1;
15047260f620SGreg Clayton const uint32_t num_frames_with_source = 1;
15056a9767c7SJim Ingham const bool stop_format = true;
1506c14ee32dSGreg Clayton process->GetStatus(strm);
1507b9c1b51eSKate Stone process->GetThreadStatus(strm, only_threads_with_stop_reason, start_frame,
15086a9767c7SJim Ingham num_frames, num_frames_with_source, stop_format);
1509d7c403e6SMed Ismail Bennani
1510d7c403e6SMed Ismail Bennani if (m_options.m_verbose) {
1511cdc6f8d7SJason Molenda addr_t code_mask = process->GetCodeAddressMask();
1512cdc6f8d7SJason Molenda addr_t data_mask = process->GetDataAddressMask();
1513cdc6f8d7SJason Molenda if (code_mask != 0) {
1514cdc6f8d7SJason Molenda int bits = std::bitset<64>(~code_mask).count();
1515cdc6f8d7SJason Molenda result.AppendMessageWithFormat(
1516cdc6f8d7SJason Molenda "Addressable code address mask: 0x%" PRIx64 "\n", code_mask);
1517cdc6f8d7SJason Molenda result.AppendMessageWithFormat(
1518cdc6f8d7SJason Molenda "Addressable data address mask: 0x%" PRIx64 "\n", data_mask);
1519cdc6f8d7SJason Molenda result.AppendMessageWithFormat(
1520cdc6f8d7SJason Molenda "Number of bits used in addressing (code): %d\n", bits);
1521cdc6f8d7SJason Molenda }
1522cdc6f8d7SJason Molenda
1523d7c403e6SMed Ismail Bennani PlatformSP platform_sp = process->GetTarget().GetPlatform();
1524d7c403e6SMed Ismail Bennani if (!platform_sp) {
1525d7c403e6SMed Ismail Bennani result.AppendError("Couldn'retrieve the target's platform");
15264b9bea87SJim Ingham return result.Succeeded();
15274b9bea87SJim Ingham }
1528d7c403e6SMed Ismail Bennani
1529d7c403e6SMed Ismail Bennani auto expected_crash_info =
1530eefda182SMed Ismail Bennani platform_sp->FetchExtendedCrashInformation(*process);
1531d7c403e6SMed Ismail Bennani
1532d7c403e6SMed Ismail Bennani if (!expected_crash_info) {
1533d7c403e6SMed Ismail Bennani result.AppendError(llvm::toString(expected_crash_info.takeError()));
1534d7c403e6SMed Ismail Bennani return result.Succeeded();
1535d7c403e6SMed Ismail Bennani }
1536d7c403e6SMed Ismail Bennani
1537d7c403e6SMed Ismail Bennani StructuredData::DictionarySP crash_info_sp = *expected_crash_info;
1538d7c403e6SMed Ismail Bennani
1539d7c403e6SMed Ismail Bennani if (crash_info_sp) {
1540d7c403e6SMed Ismail Bennani strm.PutCString("Extended Crash Information:\n");
1541d7c403e6SMed Ismail Bennani crash_info_sp->Dump(strm);
1542d7c403e6SMed Ismail Bennani }
1543d7c403e6SMed Ismail Bennani }
1544d7c403e6SMed Ismail Bennani
1545d7c403e6SMed Ismail Bennani return result.Succeeded();
1546d7c403e6SMed Ismail Bennani }
1547d7c403e6SMed Ismail Bennani
1548d7c403e6SMed Ismail Bennani private:
1549d7c403e6SMed Ismail Bennani CommandOptions m_options;
15504b9bea87SJim Ingham };
15514b9bea87SJim Ingham
155235731357SCaroline Tice // CommandObjectProcessHandle
1553438dfcffSRaphael Isemann #define LLDB_OPTIONS_process_handle
1554438dfcffSRaphael Isemann #include "CommandOptions.inc"
15551f0f5b5bSZachary Turner
1556bb9caf73SJim Ingham #pragma mark CommandObjectProcessHandle
155735731357SCaroline Tice
1558b9c1b51eSKate Stone class CommandObjectProcessHandle : public CommandObjectParsed {
155935731357SCaroline Tice public:
1560b9c1b51eSKate Stone class CommandOptions : public Options {
156135731357SCaroline Tice public:
CommandOptions()1562abb0ed44SKazu Hirata CommandOptions() { OptionParsingStarting(nullptr); }
156335731357SCaroline Tice
156449bcfd80SEugene Zelenko ~CommandOptions() override = default;
156535731357SCaroline Tice
SetOptionValue(uint32_t option_idx,llvm::StringRef option_arg,ExecutionContext * execution_context)156697206d57SZachary Turner Status SetOptionValue(uint32_t option_idx, llvm::StringRef option_arg,
1567b9c1b51eSKate Stone ExecutionContext *execution_context) override {
156897206d57SZachary Turner Status error;
15693bcdfc0eSGreg Clayton const int short_option = m_getopt_table[option_idx].val;
157035731357SCaroline Tice
1571b9c1b51eSKate Stone switch (short_option) {
1572134d7f9aSJim Ingham case 'c':
1573134d7f9aSJim Ingham do_clear = true;
1574134d7f9aSJim Ingham break;
1575134d7f9aSJim Ingham case 'd':
1576134d7f9aSJim Ingham dummy = true;
1577134d7f9aSJim Ingham break;
157835731357SCaroline Tice case 's':
1579adcd0268SBenjamin Kramer stop = std::string(option_arg);
158035731357SCaroline Tice break;
158135731357SCaroline Tice case 'n':
1582adcd0268SBenjamin Kramer notify = std::string(option_arg);
158335731357SCaroline Tice break;
158435731357SCaroline Tice case 'p':
1585adcd0268SBenjamin Kramer pass = std::string(option_arg);
158635731357SCaroline Tice break;
1587134d7f9aSJim Ingham case 't':
1588134d7f9aSJim Ingham only_target_values = true;
1589134d7f9aSJim Ingham break;
159035731357SCaroline Tice default:
159136162014SRaphael Isemann llvm_unreachable("Unimplemented option");
159235731357SCaroline Tice }
159335731357SCaroline Tice return error;
159435731357SCaroline Tice }
159535731357SCaroline Tice
OptionParsingStarting(ExecutionContext * execution_context)1596b9c1b51eSKate Stone void OptionParsingStarting(ExecutionContext *execution_context) override {
159735731357SCaroline Tice stop.clear();
159835731357SCaroline Tice notify.clear();
159935731357SCaroline Tice pass.clear();
1600134d7f9aSJim Ingham only_target_values = false;
1601134d7f9aSJim Ingham do_clear = false;
1602134d7f9aSJim Ingham dummy = false;
160335731357SCaroline Tice }
160435731357SCaroline Tice
GetDefinitions()16051f0f5b5bSZachary Turner llvm::ArrayRef<OptionDefinition> GetDefinitions() override {
160670602439SZachary Turner return llvm::makeArrayRef(g_process_handle_options);
16071f0f5b5bSZachary Turner }
160835731357SCaroline Tice
160935731357SCaroline Tice // Instance variables to hold the values for command options.
161035731357SCaroline Tice
161135731357SCaroline Tice std::string stop;
161235731357SCaroline Tice std::string notify;
161335731357SCaroline Tice std::string pass;
1614134d7f9aSJim Ingham bool only_target_values = false;
1615134d7f9aSJim Ingham bool do_clear = false;
1616134d7f9aSJim Ingham bool dummy = false;
161735731357SCaroline Tice };
161835731357SCaroline Tice
CommandObjectProcessHandle(CommandInterpreter & interpreter)16197428a18cSKate Stone CommandObjectProcessHandle(CommandInterpreter &interpreter)
1620b9c1b51eSKate Stone : CommandObjectParsed(interpreter, "process handle",
1621b9c1b51eSKate Stone "Manage LLDB handling of OS signals for the "
1622b9c1b51eSKate Stone "current target process. Defaults to showing "
1623b9c1b51eSKate Stone "current policy.",
1624134d7f9aSJim Ingham nullptr) {
1625134d7f9aSJim Ingham SetHelpLong("\nIf no signals are specified but one or more actions are, "
1626134d7f9aSJim Ingham "and there is a live process, update them all. If no action "
1627134d7f9aSJim Ingham "is specified, list the current values.\n"
1628134d7f9aSJim Ingham "If you specify actions with no target (e.g. in an init file) "
1629134d7f9aSJim Ingham "or in a target with no process "
1630134d7f9aSJim Ingham "the values will get copied into subsequent targets, but "
1631134d7f9aSJim Ingham "lldb won't be able to spell-check the options since it can't "
1632134d7f9aSJim Ingham "know which signal set will later be in force."
1633134d7f9aSJim Ingham "\nYou can see the signal modifications held by the target"
1634134d7f9aSJim Ingham "by passing the -t option."
1635134d7f9aSJim Ingham "\nYou can also clear the target modification for a signal"
1636134d7f9aSJim Ingham "by passing the -c option");
163735731357SCaroline Tice CommandArgumentEntry arg;
1638c0dbdfb6SCaroline Tice CommandArgumentData signal_arg;
163935731357SCaroline Tice
1640c0dbdfb6SCaroline Tice signal_arg.arg_type = eArgTypeUnixSignal;
1641c0dbdfb6SCaroline Tice signal_arg.arg_repetition = eArgRepeatStar;
164235731357SCaroline Tice
1643c0dbdfb6SCaroline Tice arg.push_back(signal_arg);
164435731357SCaroline Tice
164535731357SCaroline Tice m_arguments.push_back(arg);
164635731357SCaroline Tice }
164735731357SCaroline Tice
164849bcfd80SEugene Zelenko ~CommandObjectProcessHandle() override = default;
164935731357SCaroline Tice
GetOptions()1650b9c1b51eSKate Stone Options *GetOptions() override { return &m_options; }
165135731357SCaroline Tice
VerifyCommandOptionValue(const std::string & option,int & real_value)1652b9c1b51eSKate Stone bool VerifyCommandOptionValue(const std::string &option, int &real_value) {
165335731357SCaroline Tice bool okay = true;
165410ad7993SCaroline Tice bool success = false;
165547cbf4a0SPavel Labath bool tmp_value = OptionArgParser::ToBoolean(option, false, &success);
165610ad7993SCaroline Tice
165710ad7993SCaroline Tice if (success && tmp_value)
165810ad7993SCaroline Tice real_value = 1;
165910ad7993SCaroline Tice else if (success && !tmp_value)
166010ad7993SCaroline Tice real_value = 0;
1661b9c1b51eSKate Stone else {
166235731357SCaroline Tice // If the value isn't 'true' or 'false', it had better be 0 or 1.
16639010cef2SRaphael Isemann if (!llvm::to_integer(option, real_value))
16649010cef2SRaphael Isemann real_value = 3;
166510ad7993SCaroline Tice if (real_value != 0 && real_value != 1)
166635731357SCaroline Tice okay = false;
166735731357SCaroline Tice }
166835731357SCaroline Tice
166935731357SCaroline Tice return okay;
167035731357SCaroline Tice }
167135731357SCaroline Tice
PrintSignalHeader(Stream & str)1672b9c1b51eSKate Stone void PrintSignalHeader(Stream &str) {
167310ad7993SCaroline Tice str.Printf("NAME PASS STOP NOTIFY\n");
1674b84141a6SPavel Labath str.Printf("=========== ===== ===== ======\n");
167510ad7993SCaroline Tice }
167610ad7993SCaroline Tice
PrintSignal(Stream & str,int32_t signo,const char * sig_name,const UnixSignalsSP & signals_sp)1677b9c1b51eSKate Stone void PrintSignal(Stream &str, int32_t signo, const char *sig_name,
1678b9c1b51eSKate Stone const UnixSignalsSP &signals_sp) {
167910ad7993SCaroline Tice bool stop;
168010ad7993SCaroline Tice bool suppress;
168110ad7993SCaroline Tice bool notify;
168210ad7993SCaroline Tice
1683b84141a6SPavel Labath str.Printf("%-11s ", sig_name);
1684b9c1b51eSKate Stone if (signals_sp->GetSignalInfo(signo, suppress, stop, notify)) {
168510ad7993SCaroline Tice bool pass = !suppress;
1686b9c1b51eSKate Stone str.Printf("%s %s %s", (pass ? "true " : "false"),
1687b9c1b51eSKate Stone (stop ? "true " : "false"), (notify ? "true " : "false"));
168810ad7993SCaroline Tice }
168910ad7993SCaroline Tice str.Printf("\n");
169010ad7993SCaroline Tice }
169110ad7993SCaroline Tice
PrintSignalInformation(Stream & str,Args & signal_args,int num_valid_signals,const UnixSignalsSP & signals_sp)1692b9c1b51eSKate Stone void PrintSignalInformation(Stream &str, Args &signal_args,
1693b9c1b51eSKate Stone int num_valid_signals,
1694b9c1b51eSKate Stone const UnixSignalsSP &signals_sp) {
169510ad7993SCaroline Tice PrintSignalHeader(str);
169610ad7993SCaroline Tice
1697b9c1b51eSKate Stone if (num_valid_signals > 0) {
169810ad7993SCaroline Tice size_t num_args = signal_args.GetArgumentCount();
1699b9c1b51eSKate Stone for (size_t i = 0; i < num_args; ++i) {
1700b9c1b51eSKate Stone int32_t signo = signals_sp->GetSignalNumberFromName(
1701b9c1b51eSKate Stone signal_args.GetArgumentAtIndex(i));
170210ad7993SCaroline Tice if (signo != LLDB_INVALID_SIGNAL_NUMBER)
1703b9c1b51eSKate Stone PrintSignal(str, signo, signal_args.GetArgumentAtIndex(i),
1704b9c1b51eSKate Stone signals_sp);
170510ad7993SCaroline Tice }
1706b9c1b51eSKate Stone } else // Print info for ALL signals
170710ad7993SCaroline Tice {
170898d0a4b3SChaoren Lin int32_t signo = signals_sp->GetFirstSignalNumber();
1709b9c1b51eSKate Stone while (signo != LLDB_INVALID_SIGNAL_NUMBER) {
1710b9c1b51eSKate Stone PrintSignal(str, signo, signals_sp->GetSignalAsCString(signo),
1711b9c1b51eSKate Stone signals_sp);
171298d0a4b3SChaoren Lin signo = signals_sp->GetNextSignalNumber(signo);
171310ad7993SCaroline Tice }
171410ad7993SCaroline Tice }
171510ad7993SCaroline Tice }
171610ad7993SCaroline Tice
17175a988416SJim Ingham protected:
DoExecute(Args & signal_args,CommandReturnObject & result)1718b9c1b51eSKate Stone bool DoExecute(Args &signal_args, CommandReturnObject &result) override {
1719134d7f9aSJim Ingham Target &target = GetSelectedOrDummyTarget();
172035731357SCaroline Tice
1721134d7f9aSJim Ingham // Any signals that are being set should be added to the Target's
1722134d7f9aSJim Ingham // DummySignals so they will get applied on rerun, etc.
1723134d7f9aSJim Ingham // If we have a process, however, we can do a more accurate job of vetting
1724134d7f9aSJim Ingham // the user's options.
1725134d7f9aSJim Ingham ProcessSP process_sp = target.GetProcessSP();
172635731357SCaroline Tice
172735731357SCaroline Tice int stop_action = -1; // -1 means leave the current setting alone
172835731357SCaroline Tice int pass_action = -1; // -1 means leave the current setting alone
172935731357SCaroline Tice int notify_action = -1; // -1 means leave the current setting alone
173035731357SCaroline Tice
1731b9c1b51eSKate Stone if (!m_options.stop.empty() &&
1732b9c1b51eSKate Stone !VerifyCommandOptionValue(m_options.stop, stop_action)) {
1733b9c1b51eSKate Stone result.AppendError("Invalid argument for command option --stop; must be "
1734b9c1b51eSKate Stone "true or false.\n");
173535731357SCaroline Tice return false;
173635731357SCaroline Tice }
173735731357SCaroline Tice
1738b9c1b51eSKate Stone if (!m_options.notify.empty() &&
1739b9c1b51eSKate Stone !VerifyCommandOptionValue(m_options.notify, notify_action)) {
1740b9c1b51eSKate Stone result.AppendError("Invalid argument for command option --notify; must "
1741b9c1b51eSKate Stone "be true or false.\n");
174235731357SCaroline Tice return false;
174335731357SCaroline Tice }
174435731357SCaroline Tice
1745b9c1b51eSKate Stone if (!m_options.pass.empty() &&
1746b9c1b51eSKate Stone !VerifyCommandOptionValue(m_options.pass, pass_action)) {
1747b9c1b51eSKate Stone result.AppendError("Invalid argument for command option --pass; must be "
1748b9c1b51eSKate Stone "true or false.\n");
174935731357SCaroline Tice return false;
175035731357SCaroline Tice }
175135731357SCaroline Tice
1752134d7f9aSJim Ingham bool no_actions = (stop_action == -1 && pass_action == -1
1753134d7f9aSJim Ingham && notify_action == -1);
1754134d7f9aSJim Ingham if (m_options.only_target_values && !no_actions) {
1755134d7f9aSJim Ingham result.AppendError("-t is for reporting, not setting, target values.");
1756134d7f9aSJim Ingham return false;
1757134d7f9aSJim Ingham }
1758134d7f9aSJim Ingham
175935731357SCaroline Tice size_t num_args = signal_args.GetArgumentCount();
1760134d7f9aSJim Ingham UnixSignalsSP signals_sp;
1761134d7f9aSJim Ingham if (process_sp)
1762134d7f9aSJim Ingham signals_sp = process_sp->GetUnixSignals();
1763134d7f9aSJim Ingham
176435731357SCaroline Tice int num_signals_set = 0;
176535731357SCaroline Tice
1766134d7f9aSJim Ingham // If we were just asked to print the target values, do that here and
1767134d7f9aSJim Ingham // return:
1768134d7f9aSJim Ingham if (m_options.only_target_values) {
1769134d7f9aSJim Ingham target.PrintDummySignals(result.GetOutputStream(), signal_args);
1770134d7f9aSJim Ingham result.SetStatus(eReturnStatusSuccessFinishResult);
1771134d7f9aSJim Ingham return true;
1772134d7f9aSJim Ingham }
1773134d7f9aSJim Ingham
1774134d7f9aSJim Ingham // This handles clearing values:
1775134d7f9aSJim Ingham if (m_options.do_clear) {
1776134d7f9aSJim Ingham target.ClearDummySignals(signal_args);
1777134d7f9aSJim Ingham if (m_options.dummy)
1778134d7f9aSJim Ingham GetDummyTarget().ClearDummySignals(signal_args);
1779134d7f9aSJim Ingham result.SetStatus(eReturnStatusSuccessFinishNoResult);
1780134d7f9aSJim Ingham return true;
1781134d7f9aSJim Ingham }
1782134d7f9aSJim Ingham
1783134d7f9aSJim Ingham // This rest handles setting values:
1784b9c1b51eSKate Stone if (num_args > 0) {
1785d6a24757SZachary Turner for (const auto &arg : signal_args) {
1786134d7f9aSJim Ingham // Do the process first. If we have a process we can catch
1787134d7f9aSJim Ingham // invalid signal names, which we do here.
1788134d7f9aSJim Ingham if (signals_sp) {
1789d6a24757SZachary Turner int32_t signo = signals_sp->GetSignalNumberFromName(arg.c_str());
1790b9c1b51eSKate Stone if (signo != LLDB_INVALID_SIGNAL_NUMBER) {
1791b9c1b51eSKate Stone // Casting the actions as bools here should be okay, because
179205097246SAdrian Prantl // VerifyCommandOptionValue guarantees the value is either 0 or 1.
179335731357SCaroline Tice if (stop_action != -1)
179498d0a4b3SChaoren Lin signals_sp->SetShouldStop(signo, stop_action);
1795b9c1b51eSKate Stone if (pass_action != -1) {
179698d0a4b3SChaoren Lin bool suppress = !pass_action;
179798d0a4b3SChaoren Lin signals_sp->SetShouldSuppress(signo, suppress);
179835731357SCaroline Tice }
179935731357SCaroline Tice if (notify_action != -1)
180098d0a4b3SChaoren Lin signals_sp->SetShouldNotify(signo, notify_action);
180135731357SCaroline Tice ++num_signals_set;
1802b9c1b51eSKate Stone } else {
1803b9c1b51eSKate Stone result.AppendErrorWithFormat("Invalid signal name '%s'\n",
1804d6a24757SZachary Turner arg.c_str());
1805134d7f9aSJim Ingham continue;
180635731357SCaroline Tice }
1807134d7f9aSJim Ingham } else {
1808134d7f9aSJim Ingham // If there's no process we can't check, so we just set them all.
1809134d7f9aSJim Ingham // But since the map signal name -> signal number across all platforms
1810134d7f9aSJim Ingham // is not 1-1, we can't sensibly set signal actions by number before
1811134d7f9aSJim Ingham // we have a process. Check that here:
1812134d7f9aSJim Ingham int32_t signo;
1813134d7f9aSJim Ingham if (llvm::to_integer(arg.c_str(), signo)) {
1814134d7f9aSJim Ingham result.AppendErrorWithFormat("Can't set signal handling by signal "
1815134d7f9aSJim Ingham "number with no process");
1816134d7f9aSJim Ingham return false;
1817134d7f9aSJim Ingham }
1818134d7f9aSJim Ingham num_signals_set = num_args;
1819134d7f9aSJim Ingham }
1820134d7f9aSJim Ingham auto set_lazy_bool = [] (int action) -> LazyBool {
1821134d7f9aSJim Ingham LazyBool lazy;
1822134d7f9aSJim Ingham if (action == -1)
1823134d7f9aSJim Ingham lazy = eLazyBoolCalculate;
1824134d7f9aSJim Ingham else if (action)
1825134d7f9aSJim Ingham lazy = eLazyBoolYes;
1826134d7f9aSJim Ingham else
1827134d7f9aSJim Ingham lazy = eLazyBoolNo;
1828134d7f9aSJim Ingham return lazy;
1829134d7f9aSJim Ingham };
1830134d7f9aSJim Ingham
1831134d7f9aSJim Ingham // If there were no actions, we're just listing, don't add the dummy:
1832134d7f9aSJim Ingham if (!no_actions)
1833134d7f9aSJim Ingham target.AddDummySignal(arg.ref(),
1834134d7f9aSJim Ingham set_lazy_bool(pass_action),
1835134d7f9aSJim Ingham set_lazy_bool(notify_action),
1836134d7f9aSJim Ingham set_lazy_bool(stop_action));
183735731357SCaroline Tice }
1838b9c1b51eSKate Stone } else {
1839b9c1b51eSKate Stone // No signal specified, if any command options were specified, update ALL
1840134d7f9aSJim Ingham // signals. But we can't do this without a process since we don't know
1841134d7f9aSJim Ingham // all the possible signals that might be valid for this target.
1842134d7f9aSJim Ingham if (((notify_action != -1) || (stop_action != -1) || (pass_action != -1))
1843134d7f9aSJim Ingham && process_sp) {
1844b9c1b51eSKate Stone if (m_interpreter.Confirm(
1845b9c1b51eSKate Stone "Do you really want to update all the signals?", false)) {
184698d0a4b3SChaoren Lin int32_t signo = signals_sp->GetFirstSignalNumber();
1847b9c1b51eSKate Stone while (signo != LLDB_INVALID_SIGNAL_NUMBER) {
184810ad7993SCaroline Tice if (notify_action != -1)
184998d0a4b3SChaoren Lin signals_sp->SetShouldNotify(signo, notify_action);
185010ad7993SCaroline Tice if (stop_action != -1)
185198d0a4b3SChaoren Lin signals_sp->SetShouldStop(signo, stop_action);
1852b9c1b51eSKate Stone if (pass_action != -1) {
185398d0a4b3SChaoren Lin bool suppress = !pass_action;
185498d0a4b3SChaoren Lin signals_sp->SetShouldSuppress(signo, suppress);
185510ad7993SCaroline Tice }
185698d0a4b3SChaoren Lin signo = signals_sp->GetNextSignalNumber(signo);
185710ad7993SCaroline Tice }
185810ad7993SCaroline Tice }
185910ad7993SCaroline Tice }
186010ad7993SCaroline Tice }
186110ad7993SCaroline Tice
1862134d7f9aSJim Ingham if (signals_sp)
1863b9c1b51eSKate Stone PrintSignalInformation(result.GetOutputStream(), signal_args,
1864b9c1b51eSKate Stone num_signals_set, signals_sp);
1865134d7f9aSJim Ingham else
1866134d7f9aSJim Ingham target.PrintDummySignals(result.GetOutputStream(),
1867134d7f9aSJim Ingham signal_args);
186835731357SCaroline Tice
186935731357SCaroline Tice if (num_signals_set > 0)
1870134d7f9aSJim Ingham result.SetStatus(eReturnStatusSuccessFinishResult);
187135731357SCaroline Tice else
187235731357SCaroline Tice result.SetStatus(eReturnStatusFailed);
187335731357SCaroline Tice
187435731357SCaroline Tice return result.Succeeded();
187535731357SCaroline Tice }
187635731357SCaroline Tice
187735731357SCaroline Tice CommandOptions m_options;
187835731357SCaroline Tice };
187935731357SCaroline Tice
18800b697561SWalter Erquinigo // Next are the subcommands of CommandObjectMultiwordProcessTrace
18810b697561SWalter Erquinigo
18820b697561SWalter Erquinigo // CommandObjectProcessTraceStart
18830b697561SWalter Erquinigo class CommandObjectProcessTraceStart : public CommandObjectTraceProxy {
18840b697561SWalter Erquinigo public:
CommandObjectProcessTraceStart(CommandInterpreter & interpreter)18850b697561SWalter Erquinigo CommandObjectProcessTraceStart(CommandInterpreter &interpreter)
18860b697561SWalter Erquinigo : CommandObjectTraceProxy(
18870b697561SWalter Erquinigo /*live_debug_session_only*/ true, interpreter,
18880b697561SWalter Erquinigo "process trace start",
18890b697561SWalter Erquinigo "Start tracing this process with the corresponding trace "
18900b697561SWalter Erquinigo "plug-in.",
18910b697561SWalter Erquinigo "process trace start [<trace-options>]") {}
18920b697561SWalter Erquinigo
18930b697561SWalter Erquinigo protected:
GetDelegateCommand(Trace & trace)18940b697561SWalter Erquinigo lldb::CommandObjectSP GetDelegateCommand(Trace &trace) override {
18950b697561SWalter Erquinigo return trace.GetProcessTraceStartCommand(m_interpreter);
18960b697561SWalter Erquinigo }
18970b697561SWalter Erquinigo };
18980b697561SWalter Erquinigo
18990b697561SWalter Erquinigo // CommandObjectProcessTraceStop
19000b697561SWalter Erquinigo class CommandObjectProcessTraceStop : public CommandObjectParsed {
19010b697561SWalter Erquinigo public:
CommandObjectProcessTraceStop(CommandInterpreter & interpreter)19020b697561SWalter Erquinigo CommandObjectProcessTraceStop(CommandInterpreter &interpreter)
19030b697561SWalter Erquinigo : CommandObjectParsed(interpreter, "process trace stop",
19040b697561SWalter Erquinigo "Stop tracing this process. This does not affect "
19050b697561SWalter Erquinigo "traces started with the "
19060b697561SWalter Erquinigo "\"thread trace start\" command.",
19070b697561SWalter Erquinigo "process trace stop",
19080b697561SWalter Erquinigo eCommandRequiresProcess | eCommandTryTargetAPILock |
19090b697561SWalter Erquinigo eCommandProcessMustBeLaunched |
19100b697561SWalter Erquinigo eCommandProcessMustBePaused |
19110b697561SWalter Erquinigo eCommandProcessMustBeTraced) {}
19120b697561SWalter Erquinigo
19130b697561SWalter Erquinigo ~CommandObjectProcessTraceStop() override = default;
19140b697561SWalter Erquinigo
DoExecute(Args & command,CommandReturnObject & result)19150b697561SWalter Erquinigo bool DoExecute(Args &command, CommandReturnObject &result) override {
19160b697561SWalter Erquinigo ProcessSP process_sp = m_exe_ctx.GetProcessSP();
19170b697561SWalter Erquinigo
19180b697561SWalter Erquinigo TraceSP trace_sp = process_sp->GetTarget().GetTrace();
19190b697561SWalter Erquinigo
1920bf9f21a2SWalter Erquinigo if (llvm::Error err = trace_sp->Stop())
19211b1c8e4aSDavid Spickett result.AppendError(toString(std::move(err)));
19220b697561SWalter Erquinigo else
19230b697561SWalter Erquinigo result.SetStatus(eReturnStatusSuccessFinishResult);
19240b697561SWalter Erquinigo
19250b697561SWalter Erquinigo return result.Succeeded();
19260b697561SWalter Erquinigo }
19270b697561SWalter Erquinigo };
19280b697561SWalter Erquinigo
19290b697561SWalter Erquinigo // CommandObjectMultiwordProcessTrace
19300b697561SWalter Erquinigo class CommandObjectMultiwordProcessTrace : public CommandObjectMultiword {
19310b697561SWalter Erquinigo public:
CommandObjectMultiwordProcessTrace(CommandInterpreter & interpreter)19320b697561SWalter Erquinigo CommandObjectMultiwordProcessTrace(CommandInterpreter &interpreter)
19330b697561SWalter Erquinigo : CommandObjectMultiword(
19340b697561SWalter Erquinigo interpreter, "trace", "Commands for tracing the current process.",
19350b697561SWalter Erquinigo "process trace <subcommand> [<subcommand objects>]") {
19360b697561SWalter Erquinigo LoadSubCommand("start", CommandObjectSP(new CommandObjectProcessTraceStart(
19370b697561SWalter Erquinigo interpreter)));
19380b697561SWalter Erquinigo LoadSubCommand("stop", CommandObjectSP(
19390b697561SWalter Erquinigo new CommandObjectProcessTraceStop(interpreter)));
19400b697561SWalter Erquinigo }
19410b697561SWalter Erquinigo
19420b697561SWalter Erquinigo ~CommandObjectMultiwordProcessTrace() override = default;
19430b697561SWalter Erquinigo };
19440b697561SWalter Erquinigo
194530fdc8d8SChris Lattner // CommandObjectMultiwordProcess
194630fdc8d8SChris Lattner
CommandObjectMultiwordProcess(CommandInterpreter & interpreter)1947b9c1b51eSKate Stone CommandObjectMultiwordProcess::CommandObjectMultiwordProcess(
1948b9c1b51eSKate Stone CommandInterpreter &interpreter)
1949b9c1b51eSKate Stone : CommandObjectMultiword(
1950b9c1b51eSKate Stone interpreter, "process",
1951b9c1b51eSKate Stone "Commands for interacting with processes on the current platform.",
1952b9c1b51eSKate Stone "process <subcommand> [<subcommand-options>]") {
1953b9c1b51eSKate Stone LoadSubCommand("attach",
1954b9c1b51eSKate Stone CommandObjectSP(new CommandObjectProcessAttach(interpreter)));
1955b9c1b51eSKate Stone LoadSubCommand("launch",
1956b9c1b51eSKate Stone CommandObjectSP(new CommandObjectProcessLaunch(interpreter)));
1957b9c1b51eSKate Stone LoadSubCommand("continue", CommandObjectSP(new CommandObjectProcessContinue(
1958b9c1b51eSKate Stone interpreter)));
1959b9c1b51eSKate Stone LoadSubCommand("connect",
1960b9c1b51eSKate Stone CommandObjectSP(new CommandObjectProcessConnect(interpreter)));
1961b9c1b51eSKate Stone LoadSubCommand("detach",
1962b9c1b51eSKate Stone CommandObjectSP(new CommandObjectProcessDetach(interpreter)));
1963b9c1b51eSKate Stone LoadSubCommand("load",
1964b9c1b51eSKate Stone CommandObjectSP(new CommandObjectProcessLoad(interpreter)));
1965b9c1b51eSKate Stone LoadSubCommand("unload",
1966b9c1b51eSKate Stone CommandObjectSP(new CommandObjectProcessUnload(interpreter)));
1967b9c1b51eSKate Stone LoadSubCommand("signal",
1968b9c1b51eSKate Stone CommandObjectSP(new CommandObjectProcessSignal(interpreter)));
1969b9c1b51eSKate Stone LoadSubCommand("handle",
1970b9c1b51eSKate Stone CommandObjectSP(new CommandObjectProcessHandle(interpreter)));
1971b9c1b51eSKate Stone LoadSubCommand("status",
1972b9c1b51eSKate Stone CommandObjectSP(new CommandObjectProcessStatus(interpreter)));
1973b9c1b51eSKate Stone LoadSubCommand("interrupt", CommandObjectSP(new CommandObjectProcessInterrupt(
1974b9c1b51eSKate Stone interpreter)));
1975b9c1b51eSKate Stone LoadSubCommand("kill",
1976b9c1b51eSKate Stone CommandObjectSP(new CommandObjectProcessKill(interpreter)));
1977b9c1b51eSKate Stone LoadSubCommand("plugin",
1978b9c1b51eSKate Stone CommandObjectSP(new CommandObjectProcessPlugin(interpreter)));
1979b9c1b51eSKate Stone LoadSubCommand("save-core", CommandObjectSP(new CommandObjectProcessSaveCore(
1980b9c1b51eSKate Stone interpreter)));
19810b697561SWalter Erquinigo LoadSubCommand(
19820b697561SWalter Erquinigo "trace",
19830b697561SWalter Erquinigo CommandObjectSP(new CommandObjectMultiwordProcessTrace(interpreter)));
198430fdc8d8SChris Lattner }
198530fdc8d8SChris Lattner
198649bcfd80SEugene Zelenko CommandObjectMultiwordProcess::~CommandObjectMultiwordProcess() = default;
1987