Skip to content

Commit d62a53a

Browse files
committed
[lldb/Commands] Add command options for ScriptedProcess to ProcessLaunch
This patch adds a new command options to the CommandObjectProcessLaunch for scripted processes. Among the options, the user need to specify the class name managing the scripted process. The user can also use a key-value dictionary holding arbitrary data that will be passed to the managing class. This patch also adds getters and setters to `SBLaunchInfo` for the class name managing the scripted process and the dictionary. rdar://65508855 Differential Review: https://reviews.llvm.org/D95710 Signed-off-by: Med Ismail Bennani <[email protected]>
1 parent 103ad3f commit d62a53a

File tree

12 files changed

+143
-10
lines changed

12 files changed

+143
-10
lines changed

lldb/bindings/interface/SBLaunchInfo.i

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -135,6 +135,16 @@ public:
135135

136136
void
137137
SetDetachOnError(bool enable);
138+
139+
const char *
140+
GetScriptedProcessClassName() const;
141+
142+
void SetScriptedProcessClassName(const char *class_name);
143+
144+
lldb::SBStructuredData
145+
GetScriptedProcessDictionary() const;
146+
147+
void SetScriptedProcessDictionary(lldb::SBStructuredData dict);
138148
};
139149

140150
} // namespace lldb

lldb/include/lldb/API/SBLaunchInfo.h

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -171,6 +171,14 @@ class LLDB_API SBLaunchInfo {
171171

172172
void SetDetachOnError(bool enable);
173173

174+
const char *GetScriptedProcessClassName() const;
175+
176+
void SetScriptedProcessClassName(const char *class_name);
177+
178+
lldb::SBStructuredData GetScriptedProcessDictionary() const;
179+
180+
void SetScriptedProcessDictionary(lldb::SBStructuredData dict);
181+
174182
protected:
175183
friend class SBPlatform;
176184
friend class SBTarget;

lldb/include/lldb/API/SBStream.h

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -72,6 +72,7 @@ class LLDB_API SBStream {
7272
friend class SBFunction;
7373
friend class SBInstruction;
7474
friend class SBInstructionList;
75+
friend class SBLaunchInfo;
7576
friend class SBLineEntry;
7677
friend class SBMemoryRegionInfo;
7778
friend class SBModule;

lldb/include/lldb/API/SBStructuredData.h

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -88,6 +88,7 @@ class SBStructuredData {
8888
size_t GetStringValue(char *dst, size_t dst_len) const;
8989

9090
protected:
91+
friend class SBLaunchInfo;
9192
friend class SBTraceOptions;
9293
friend class SBDebugger;
9394
friend class SBTarget;

lldb/include/lldb/Host/ProcessLaunchInfo.h

Lines changed: 28 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -20,6 +20,7 @@
2020
#include "lldb/Host/PseudoTerminal.h"
2121
#include "lldb/Utility/FileSpec.h"
2222
#include "lldb/Utility/ProcessInfo.h"
23+
#include "lldb/Utility/StructuredData.h"
2324

2425
namespace lldb_private {
2526

@@ -146,6 +147,28 @@ class ProcessLaunchInfo : public ProcessInfo {
146147
return m_flags.Test(lldb::eLaunchFlagDetachOnError);
147148
}
148149

150+
bool IsScriptedProcess() const {
151+
return !m_scripted_process_class_name.empty();
152+
}
153+
154+
std::string GetScriptedProcessClassName() const {
155+
return m_scripted_process_class_name;
156+
}
157+
158+
void SetScriptedProcessClassName(std::string name) {
159+
m_scripted_process_class_name = name;
160+
}
161+
162+
lldb_private::StructuredData::DictionarySP
163+
GetScriptedProcessDictionarySP() const {
164+
return m_scripted_process_dictionary_sp;
165+
}
166+
167+
void SetScriptedProcessDictionarySP(
168+
lldb_private::StructuredData::DictionarySP dictionary_sp) {
169+
m_scripted_process_dictionary_sp = dictionary_sp;
170+
}
171+
149172
protected:
150173
FileSpec m_working_dir;
151174
std::string m_plugin_name;
@@ -161,6 +184,11 @@ class ProcessLaunchInfo : public ProcessInfo {
161184
// meaning to the upper levels of lldb.
162185
lldb::ListenerSP m_listener_sp;
163186
lldb::ListenerSP m_hijack_listener_sp;
187+
std::string m_scripted_process_class_name; // The name of the class that will
188+
// manage a scripted process.
189+
StructuredData::DictionarySP
190+
m_scripted_process_dictionary_sp; // A dictionary that holds key/value
191+
// pairs passed to the scripted process.
164192
};
165193
}
166194

lldb/source/API/SBLaunchInfo.cpp

Lines changed: 59 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -10,8 +10,12 @@
1010
#include "SBReproducerPrivate.h"
1111

1212
#include "lldb/API/SBEnvironment.h"
13+
#include "lldb/API/SBError.h"
1314
#include "lldb/API/SBFileSpec.h"
1415
#include "lldb/API/SBListener.h"
16+
#include "lldb/API/SBStream.h"
17+
#include "lldb/API/SBStructuredData.h"
18+
#include "lldb/Core/StructuredDataImpl.h"
1519
#include "lldb/Host/ProcessLaunchInfo.h"
1620

1721
using namespace lldb;
@@ -343,6 +347,53 @@ bool SBLaunchInfo::GetDetachOnError() const {
343347
return m_opaque_sp->GetDetachOnError();
344348
}
345349

350+
const char *SBLaunchInfo::GetScriptedProcessClassName() const {
351+
LLDB_RECORD_METHOD_CONST_NO_ARGS(const char *, SBLaunchInfo,
352+
GetScriptedProcessClassName);
353+
354+
// Constify this string so that it is saved in the string pool. Otherwise it
355+
// would be freed when this function goes out of scope.
356+
ConstString class_name(m_opaque_sp->GetScriptedProcessClassName().c_str());
357+
return class_name.AsCString();
358+
}
359+
360+
void SBLaunchInfo::SetScriptedProcessClassName(const char *class_name) {
361+
LLDB_RECORD_METHOD(void, SBLaunchInfo, SetScriptedProcessClassName,
362+
(const char *), class_name);
363+
364+
m_opaque_sp->SetScriptedProcessClassName(class_name);
365+
}
366+
367+
lldb::SBStructuredData SBLaunchInfo::GetScriptedProcessDictionary() const {
368+
LLDB_RECORD_METHOD_CONST_NO_ARGS(lldb::SBStructuredData, SBLaunchInfo,
369+
GetScriptedProcessDictionary);
370+
371+
lldb_private::StructuredData::DictionarySP dict_sp =
372+
m_opaque_sp->GetScriptedProcessDictionarySP();
373+
374+
SBStructuredData data;
375+
data.m_impl_up->SetObjectSP(dict_sp);
376+
377+
return LLDB_RECORD_RESULT(data);
378+
}
379+
380+
void SBLaunchInfo::SetScriptedProcessDictionary(lldb::SBStructuredData dict) {
381+
LLDB_RECORD_METHOD(void, SBLaunchInfo, SetScriptedProcessDictionary,
382+
(lldb::SBStructuredData), dict);
383+
384+
SBStream stream;
385+
SBError error = dict.GetAsJSON(stream);
386+
387+
if (error.Fail())
388+
return;
389+
390+
StructuredData::DictionarySP dict_sp;
391+
llvm::json::OStream s(stream.ref().AsRawOstream());
392+
dict_sp->Serialize(s);
393+
394+
m_opaque_sp->SetScriptedProcessDictionarySP(dict_sp);
395+
}
396+
346397
namespace lldb_private {
347398
namespace repro {
348399

@@ -403,6 +454,14 @@ void RegisterMethods<SBLaunchInfo>(Registry &R) {
403454
());
404455
LLDB_REGISTER_METHOD(void, SBLaunchInfo, SetDetachOnError, (bool));
405456
LLDB_REGISTER_METHOD_CONST(bool, SBLaunchInfo, GetDetachOnError, ());
457+
LLDB_REGISTER_METHOD_CONST(const char *, SBLaunchInfo,
458+
GetScriptedProcessClassName, ());
459+
LLDB_REGISTER_METHOD(void, SBLaunchInfo, SetScriptedProcessClassName,
460+
(const char *));
461+
LLDB_REGISTER_METHOD_CONST(lldb::SBStructuredData, SBLaunchInfo,
462+
GetScriptedProcessDictionary, ());
463+
LLDB_REGISTER_METHOD(void, SBLaunchInfo, SetScriptedProcessDictionary,
464+
(lldb::SBStructuredData));
406465
LLDB_REGISTER_METHOD(void, SBLaunchInfo, SetEnvironment,
407466
(const lldb::SBEnvironment &, bool));
408467
LLDB_REGISTER_METHOD(lldb::SBEnvironment, SBLaunchInfo, GetEnvironment, ());

lldb/source/API/SBTarget.cpp

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -446,6 +446,7 @@ SBProcess SBTarget::Launch(SBLaunchInfo &sb_launch_info, SBError &error) {
446446
if (arch_spec.IsValid())
447447
launch_info.GetArchitecture() = arch_spec;
448448

449+
target_sp->SetProcessLaunchInfo(launch_info);
449450
error.SetError(target_sp->Launch(launch_info, nullptr));
450451
sb_launch_info.set_ref(launch_info);
451452
sb_process.SetSP(target_sp->GetProcessSP());

lldb/source/Commands/CommandObjectPlatform.cpp

Lines changed: 6 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1009,11 +1009,14 @@ class CommandObjectPlatformProcessLaunch : public CommandObjectParsed {
10091009
"Launch a new process on a remote platform.",
10101010
"platform process launch program",
10111011
eCommandRequiresTarget | eCommandTryTargetAPILock),
1012-
m_options() {}
1012+
m_options(), m_all_options() {
1013+
m_all_options.Append(&m_options);
1014+
m_all_options.Finalize();
1015+
}
10131016

10141017
~CommandObjectPlatformProcessLaunch() override = default;
10151018

1016-
Options *GetOptions() override { return &m_options; }
1019+
Options *GetOptions() override { return &m_all_options; }
10171020

10181021
protected:
10191022
bool DoExecute(Args &args, CommandReturnObject &result) override {
@@ -1085,6 +1088,7 @@ class CommandObjectPlatformProcessLaunch : public CommandObjectParsed {
10851088
}
10861089

10871090
CommandOptionsProcessLaunch m_options;
1091+
OptionGroupOptions m_all_options;
10881092
};
10891093

10901094
// "platform process list"

lldb/source/Commands/CommandObjectProcess.cpp

Lines changed: 19 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -17,6 +17,7 @@
1717
#include "lldb/Interpreter/CommandInterpreter.h"
1818
#include "lldb/Interpreter/CommandReturnObject.h"
1919
#include "lldb/Interpreter/OptionArgParser.h"
20+
#include "lldb/Interpreter/OptionGroupPythonClassWithDict.h"
2021
#include "lldb/Interpreter/Options.h"
2122
#include "lldb/Target/Platform.h"
2223
#include "lldb/Target/Process.h"
@@ -108,7 +109,12 @@ class CommandObjectProcessLaunch : public CommandObjectProcessLaunchOrAttach {
108109
interpreter, "process launch",
109110
"Launch the executable in the debugger.", nullptr,
110111
eCommandRequiresTarget, "restart"),
111-
m_options() {
112+
m_options(), m_class_options("scripted process"), m_all_options() {
113+
m_all_options.Append(&m_options);
114+
m_all_options.Append(&m_class_options, LLDB_OPT_SET_1 | LLDB_OPT_SET_2,
115+
LLDB_OPT_SET_1);
116+
m_all_options.Finalize();
117+
112118
CommandArgumentEntry arg;
113119
CommandArgumentData run_args_arg;
114120

@@ -135,7 +141,7 @@ class CommandObjectProcessLaunch : public CommandObjectProcessLaunchOrAttach {
135141
request, nullptr);
136142
}
137143

138-
Options *GetOptions() override { return &m_options; }
144+
Options *GetOptions() override { return &m_all_options; }
139145

140146
const char *GetRepeatCommand(Args &current_command_args,
141147
uint32_t index) override {
@@ -180,6 +186,15 @@ class CommandObjectProcessLaunch : public CommandObjectProcessLaunchOrAttach {
180186
disable_aslr = target->GetDisableASLR();
181187
}
182188

189+
if (!m_class_options.GetName().empty()) {
190+
m_options.launch_info.SetProcessPluginName("ScriptedProcess");
191+
m_options.launch_info.SetScriptedProcessClassName(
192+
m_class_options.GetName());
193+
m_options.launch_info.SetScriptedProcessDictionarySP(
194+
m_class_options.GetStructuredData());
195+
target->SetProcessLaunchInfo(m_options.launch_info);
196+
}
197+
183198
if (disable_aslr)
184199
m_options.launch_info.GetFlags().Set(eLaunchFlagDisableASLR);
185200
else
@@ -253,6 +268,8 @@ class CommandObjectProcessLaunch : public CommandObjectProcessLaunchOrAttach {
253268
}
254269

255270
CommandOptionsProcessLaunch m_options;
271+
OptionGroupPythonClassWithDict m_class_options;
272+
OptionGroupOptions m_all_options;
256273
};
257274

258275
#define LLDB_OPTIONS_process_attach

lldb/source/Commands/CommandOptionsProcessLaunch.cpp

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -30,7 +30,7 @@ Status CommandOptionsProcessLaunch::SetOptionValue(
3030
uint32_t option_idx, llvm::StringRef option_arg,
3131
ExecutionContext *execution_context) {
3232
Status error;
33-
const int short_option = m_getopt_table[option_idx].val;
33+
const int short_option = g_process_launch_options[option_idx].short_option;
3434

3535
switch (short_option) {
3636
case 's': // Stop at program entry point

lldb/source/Commands/CommandOptionsProcessLaunch.h

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
1-
//===-- CommandOptionsProcessLaunch.h -------------------------------------===//
1+
//===-- CommandOptionsProcessLaunch.h ---------------------------*- C++ -*-===//
22
//
33
// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
44
// See https://llvm.org/LICENSE.txt for license information.
@@ -16,9 +16,9 @@ namespace lldb_private {
1616

1717
// CommandOptionsProcessLaunch
1818

19-
class CommandOptionsProcessLaunch : public lldb_private::Options {
19+
class CommandOptionsProcessLaunch : public lldb_private::OptionGroup {
2020
public:
21-
CommandOptionsProcessLaunch() : lldb_private::Options() {
21+
CommandOptionsProcessLaunch() : lldb_private::OptionGroup() {
2222
// Keep default values of all options in one place: OptionParsingStarting
2323
// ()
2424
OptionParsingStarting(nullptr);

lldb/source/Host/common/ProcessLaunchInfo.cpp

Lines changed: 6 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -32,7 +32,8 @@ ProcessLaunchInfo::ProcessLaunchInfo()
3232
: ProcessInfo(), m_working_dir(), m_plugin_name(), m_flags(0),
3333
m_file_actions(), m_pty(new PseudoTerminal), m_resume_count(0),
3434
m_monitor_callback(nullptr), m_monitor_callback_baton(nullptr),
35-
m_monitor_signals(false), m_listener_sp(), m_hijack_listener_sp() {}
35+
m_monitor_signals(false), m_listener_sp(), m_hijack_listener_sp(),
36+
m_scripted_process_class_name(), m_scripted_process_dictionary_sp() {}
3637

3738
ProcessLaunchInfo::ProcessLaunchInfo(const FileSpec &stdin_file_spec,
3839
const FileSpec &stdout_file_spec,
@@ -42,7 +43,8 @@ ProcessLaunchInfo::ProcessLaunchInfo(const FileSpec &stdin_file_spec,
4243
: ProcessInfo(), m_working_dir(), m_plugin_name(), m_flags(launch_flags),
4344
m_file_actions(), m_pty(new PseudoTerminal), m_resume_count(0),
4445
m_monitor_callback(nullptr), m_monitor_callback_baton(nullptr),
45-
m_monitor_signals(false), m_listener_sp(), m_hijack_listener_sp() {
46+
m_monitor_signals(false), m_listener_sp(), m_hijack_listener_sp(),
47+
m_scripted_process_class_name(), m_scripted_process_dictionary_sp() {
4648
if (stdin_file_spec) {
4749
FileAction file_action;
4850
const bool read = true;
@@ -171,6 +173,8 @@ void ProcessLaunchInfo::Clear() {
171173
m_resume_count = 0;
172174
m_listener_sp.reset();
173175
m_hijack_listener_sp.reset();
176+
m_scripted_process_class_name.clear();
177+
m_scripted_process_dictionary_sp.reset();
174178
}
175179

176180
void ProcessLaunchInfo::SetMonitorProcessCallback(

0 commit comments

Comments
 (0)