Skip to content

Commit f7ebc7b

Browse files
committed
[lldb] Move ScriptedProcess private state update to implementation
While debugging a Scripted Process, in order to update its state and work nicely with lldb's execution model, it needs to toggle its private state from running to stopped, which will result in broadcasting a process state changed event to the debugger listener. Originally, this state update was done systematically in the Scripted Process C++ plugin, however in order to make scripted process interactive, we need to be able to update their state dynamically. This patch makes use of the recent addition of the SBProcess::ForceScriptedState to programatically, and moves the process private state update to the python implementation of the resume method instead of doing it in ScriptedProcess::DoResume. This patch also removes the unused ShouldStop & Stop scripted process APIs, and adds new ScriptedInterface transform methods for boolean arguments. This allow the user to programmatically decide if after running the process, we should stop it (which is the default setting). Differential Revision: https://reviews.llvm.org/D145295 Signed-off-by: Med Ismail Bennani <[email protected]>
1 parent 82252b6 commit f7ebc7b

File tree

8 files changed

+43
-88
lines changed

8 files changed

+43
-88
lines changed

lldb/examples/python/scripted_process/scripted_process.py

Lines changed: 13 additions & 18 deletions
Original file line numberDiff line numberDiff line change
@@ -160,30 +160,25 @@ def attach(self, attach_info):
160160
"""
161161
return lldb.SBError()
162162

163-
def resume(self):
163+
def resume(self, should_stop=True):
164164
""" Simulate the scripted process resume.
165165
166-
Returns:
167-
lldb.SBError: An `lldb.SBError` with error code 0.
168-
"""
169-
return lldb.SBError()
170-
171-
@abstractmethod
172-
def should_stop(self):
173-
""" Check if the scripted process plugin should produce the stop event.
174-
175-
Returns:
176-
bool: True if scripted process should broadcast a stop event.
177-
False otherwise.
178-
"""
179-
pass
180-
181-
def stop(self):
182-
""" Trigger the scripted process stop.
166+
Args:
167+
should_stop (bool): If True, resume will also force the process
168+
state to stopped after running it.
183169
184170
Returns:
185171
lldb.SBError: An `lldb.SBError` with error code 0.
186172
"""
173+
process = self.target.GetProcess()
174+
if not process:
175+
error = lldb.SBError()
176+
error.SetErrorString("Invalid process.")
177+
return error
178+
179+
process.ForceScriptedState(lldb.eStateRunning);
180+
if (should_stop):
181+
process.ForceScriptedState(lldb.eStateStopped);
187182
return lldb.SBError()
188183

189184
@abstractmethod

lldb/include/lldb/Interpreter/ScriptedProcessInterface.h

Lines changed: 0 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -37,10 +37,6 @@ class ScriptedProcessInterface : virtual public ScriptedInterface {
3737

3838
virtual Status Resume() { return Status("ScriptedProcess did not resume"); }
3939

40-
virtual bool ShouldStop() { return true; }
41-
42-
virtual Status Stop() { return Status("ScriptedProcess did not stop"); }
43-
4440
virtual llvm::Optional<MemoryRegionInfo>
4541
GetMemoryRegionContainingAddress(lldb::addr_t address, Status &error) {
4642
error.SetErrorString("ScriptedProcess have no memory region.");

lldb/source/Plugins/Process/scripted/ScriptedProcess.cpp

Lines changed: 9 additions & 45 deletions
Original file line numberDiff line numberDiff line change
@@ -150,22 +150,15 @@ Status ScriptedProcess::DoLoadCore() {
150150

151151
Status ScriptedProcess::DoLaunch(Module *exe_module,
152152
ProcessLaunchInfo &launch_info) {
153-
/* FIXME: This doesn't reflect how lldb actually launches a process.
154-
In reality, it attaches to debugserver, then resume the process. */
153+
LLDB_LOGF(GetLog(LLDBLog::Process), "ScriptedProcess::%s launching process", __FUNCTION__);
154+
155+
/* MARK: This doesn't reflect how lldb actually launches a process.
156+
In reality, it attaches to debugserver, then resume the process.
157+
That's not true in all cases. If debugserver is remote, lldb
158+
asks debugserver to launch the process for it. */
155159
Status error = GetInterface().Launch();
156-
SetPrivateState(eStateRunning);
157-
158-
if (error.Fail())
159-
return error;
160-
161-
// TODO: Fetch next state from stopped event queue then send stop event
162-
// const StateType state = SetThreadStopInfo(response);
163-
// if (state != eStateInvalid) {
164-
// SetPrivateState(state);
165-
166160
SetPrivateState(eStateStopped);
167-
168-
return {};
161+
return error;
169162
}
170163

171164
void ScriptedProcess::DidLaunch() {
@@ -174,25 +167,9 @@ void ScriptedProcess::DidLaunch() {
174167
}
175168

176169
Status ScriptedProcess::DoResume() {
177-
Log *log = GetLog(LLDBLog::Process);
178-
// FIXME: Fetch data from thread.
179-
const StateType thread_resume_state = eStateRunning;
180-
LLDB_LOGF(log, "ScriptedProcess::%s thread_resume_state = %s", __FUNCTION__,
181-
StateAsCString(thread_resume_state));
182-
183-
bool resume = (thread_resume_state == eStateRunning);
184-
assert(thread_resume_state == eStateRunning && "invalid thread resume state");
170+
LLDB_LOGF(GetLog(LLDBLog::Process), "ScriptedProcess::%s resuming process", __FUNCTION__);
185171

186-
Status error;
187-
if (resume) {
188-
LLDB_LOGF(log, "ScriptedProcess::%s sending resume", __FUNCTION__);
189-
190-
SetPrivateState(eStateRunning);
191-
SetPrivateState(eStateStopped);
192-
error = GetInterface().Resume();
193-
}
194-
195-
return error;
172+
return GetInterface().Resume();
196173
}
197174

198175
Status ScriptedProcess::DoAttach(const ProcessAttachInfo &attach_info) {
@@ -223,19 +200,6 @@ void ScriptedProcess::DidAttach(ArchSpec &process_arch) {
223200
process_arch = GetArchitecture();
224201
}
225202

226-
Status ScriptedProcess::DoStop() {
227-
Log *log = GetLog(LLDBLog::Process);
228-
229-
if (GetInterface().ShouldStop()) {
230-
SetPrivateState(eStateStopped);
231-
LLDB_LOGF(log, "ScriptedProcess::%s Immediate stop", __FUNCTION__);
232-
return {};
233-
}
234-
235-
LLDB_LOGF(log, "ScriptedProcess::%s Delayed stop", __FUNCTION__);
236-
return GetInterface().Stop();
237-
}
238-
239203
Status ScriptedProcess::DoDestroy() { return Status(); }
240204

241205
bool ScriptedProcess::IsAlive() { return GetInterface().IsAlive(); }

lldb/source/Plugins/Process/scripted/ScriptedProcess.h

Lines changed: 0 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -96,8 +96,6 @@ class ScriptedProcess : public Process {
9696
ScriptedProcess(lldb::TargetSP target_sp, lldb::ListenerSP listener_sp,
9797
const ScriptedMetadata &scripted_metadata, Status &error);
9898

99-
Status DoStop();
100-
10199
void Clear();
102100

103101
bool DoUpdateThreadList(ThreadList &old_thread_list,

lldb/source/Plugins/ScriptInterpreter/Python/PythonDataObjects.h

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -201,6 +201,7 @@ template <> struct PythonFormat<short> : PassthroughFormat<short, 'h'> {};
201201
template <>
202202
struct PythonFormat<unsigned short> : PassthroughFormat<unsigned short, 'H'> {};
203203
template <> struct PythonFormat<int> : PassthroughFormat<int, 'i'> {};
204+
template <> struct PythonFormat<bool> : PassthroughFormat<bool, 'p'> {};
204205
template <>
205206
struct PythonFormat<unsigned int> : PassthroughFormat<unsigned int, 'I'> {};
206207
template <> struct PythonFormat<long> : PassthroughFormat<long, 'l'> {};

lldb/source/Plugins/ScriptInterpreter/Python/ScriptedProcessPythonInterface.cpp

Lines changed: 2 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -80,21 +80,8 @@ Status ScriptedProcessPythonInterface::Launch() {
8080
}
8181

8282
Status ScriptedProcessPythonInterface::Resume() {
83-
return GetStatusFromMethod("resume");
84-
}
85-
86-
bool ScriptedProcessPythonInterface::ShouldStop() {
87-
Status error;
88-
StructuredData::ObjectSP obj = Dispatch("is_alive", error);
89-
90-
if (!CheckStructuredDataObject(LLVM_PRETTY_FUNCTION, obj, error))
91-
return {};
92-
93-
return obj->GetBooleanValue();
94-
}
95-
96-
Status ScriptedProcessPythonInterface::Stop() {
97-
return GetStatusFromMethod("stop");
83+
// When calling ScriptedProcess.Resume from lldb we should always stop.
84+
return GetStatusFromMethod("resume", /*should_stop=*/true);
9885
}
9986

10087
llvm::Optional<MemoryRegionInfo>

lldb/source/Plugins/ScriptInterpreter/Python/ScriptedProcessPythonInterface.h

Lines changed: 0 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -36,10 +36,6 @@ class ScriptedProcessPythonInterface : public ScriptedProcessInterface,
3636

3737
Status Resume() override;
3838

39-
bool ShouldStop() override;
40-
41-
Status Stop() override;
42-
4339
llvm::Optional<MemoryRegionInfo>
4440
GetMemoryRegionContainingAddress(lldb::addr_t address,
4541
Status &error) override;

lldb/source/Plugins/ScriptInterpreter/Python/ScriptedPythonInterface.h

Lines changed: 18 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -112,6 +112,11 @@ class ScriptedPythonInterface : virtual public ScriptedInterface {
112112
return {object};
113113
}
114114

115+
python::PythonObject Transform(bool arg) {
116+
// Boolean arguments need to be turned into python objects.
117+
return python::PythonBoolean(arg);
118+
}
119+
115120
python::PythonObject Transform(Status arg) {
116121
return python::ToSWIGWrapper(arg);
117122
}
@@ -140,6 +145,19 @@ class ScriptedPythonInterface : virtual public ScriptedInterface {
140145
original_arg = ExtractValueFromPythonObject<T>(transformed_arg, error);
141146
}
142147

148+
template <>
149+
void ReverseTransform(bool &original_arg,
150+
python::PythonObject transformed_arg, Status &error) {
151+
python::PythonBoolean boolean_arg = python::PythonBoolean(
152+
python::PyRefType::Borrowed, transformed_arg.get());
153+
if (boolean_arg.IsValid())
154+
original_arg = boolean_arg.GetValue();
155+
else
156+
error.SetErrorString(
157+
llvm::formatv("{}: Invalid boolean argument.", LLVM_PRETTY_FUNCTION)
158+
.str());
159+
}
160+
143161
template <std::size_t... I, typename... Args>
144162
auto TransformTuple(const std::tuple<Args...> &args,
145163
std::index_sequence<I...>) {

0 commit comments

Comments
 (0)