[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 <medismail.bennani@gmail.com>
This commit is contained in:
parent
3675e0bb67
commit
3c33d72e7f
|
@ -160,30 +160,24 @@ class ScriptedProcess(metaclass=ABCMeta):
|
|||
"""
|
||||
return lldb.SBError()
|
||||
|
||||
def resume(self):
|
||||
def resume(self, should_stop=True):
|
||||
""" Simulate the scripted process resume.
|
||||
|
||||
Returns:
|
||||
lldb.SBError: An `lldb.SBError` with error code 0.
|
||||
"""
|
||||
return lldb.SBError()
|
||||
|
||||
@abstractmethod
|
||||
def should_stop(self):
|
||||
""" Check if the scripted process plugin should produce the stop event.
|
||||
|
||||
Returns:
|
||||
bool: True if scripted process should broadcast a stop event.
|
||||
False otherwise.
|
||||
"""
|
||||
pass
|
||||
|
||||
def stop(self):
|
||||
""" Trigger the scripted process stop.
|
||||
Args:
|
||||
should_stop (bool): If True, resume will also
|
||||
|
||||
Returns:
|
||||
lldb.SBError: An `lldb.SBError` with error code 0.
|
||||
"""
|
||||
process = self.target.GetProcess()
|
||||
if not process:
|
||||
error = lldb.SBError()
|
||||
error.SetErrorString("Invalid process.")
|
||||
return error
|
||||
|
||||
process.ForceScriptedState(lldb.eStateRunning);
|
||||
if (should_stop):
|
||||
process.ForceScriptedState(lldb.eStateStopped);
|
||||
return lldb.SBError()
|
||||
|
||||
@abstractmethod
|
||||
|
|
|
@ -38,10 +38,6 @@ public:
|
|||
|
||||
virtual Status Resume() { return Status("ScriptedProcess did not resume"); }
|
||||
|
||||
virtual bool ShouldStop() { return true; }
|
||||
|
||||
virtual Status Stop() { return Status("ScriptedProcess did not stop"); }
|
||||
|
||||
virtual std::optional<MemoryRegionInfo>
|
||||
GetMemoryRegionContainingAddress(lldb::addr_t address, Status &error) {
|
||||
error.SetErrorString("ScriptedProcess have no memory region.");
|
||||
|
|
|
@ -187,8 +187,6 @@ Status ScriptedProcess::DoResume() {
|
|||
if (resume) {
|
||||
LLDB_LOGF(log, "ScriptedProcess::%s sending resume", __FUNCTION__);
|
||||
|
||||
SetPrivateState(eStateRunning);
|
||||
SetPrivateState(eStateStopped);
|
||||
error = GetInterface().Resume();
|
||||
}
|
||||
|
||||
|
@ -223,19 +221,6 @@ void ScriptedProcess::DidAttach(ArchSpec &process_arch) {
|
|||
process_arch = GetArchitecture();
|
||||
}
|
||||
|
||||
Status ScriptedProcess::DoStop() {
|
||||
Log *log = GetLog(LLDBLog::Process);
|
||||
|
||||
if (GetInterface().ShouldStop()) {
|
||||
SetPrivateState(eStateStopped);
|
||||
LLDB_LOGF(log, "ScriptedProcess::%s Immediate stop", __FUNCTION__);
|
||||
return {};
|
||||
}
|
||||
|
||||
LLDB_LOGF(log, "ScriptedProcess::%s Delayed stop", __FUNCTION__);
|
||||
return GetInterface().Stop();
|
||||
}
|
||||
|
||||
Status ScriptedProcess::DoDestroy() { return Status(); }
|
||||
|
||||
bool ScriptedProcess::IsAlive() { return GetInterface().IsAlive(); }
|
||||
|
|
|
@ -96,8 +96,6 @@ protected:
|
|||
ScriptedProcess(lldb::TargetSP target_sp, lldb::ListenerSP listener_sp,
|
||||
const ScriptedMetadata &scripted_metadata, Status &error);
|
||||
|
||||
Status DoStop();
|
||||
|
||||
void Clear();
|
||||
|
||||
bool DoUpdateThreadList(ThreadList &old_thread_list,
|
||||
|
|
|
@ -201,6 +201,7 @@ template <> struct PythonFormat<short> : PassthroughFormat<short, 'h'> {};
|
|||
template <>
|
||||
struct PythonFormat<unsigned short> : PassthroughFormat<unsigned short, 'H'> {};
|
||||
template <> struct PythonFormat<int> : PassthroughFormat<int, 'i'> {};
|
||||
template <> struct PythonFormat<bool> : PassthroughFormat<bool, 'p'> {};
|
||||
template <>
|
||||
struct PythonFormat<unsigned int> : PassthroughFormat<unsigned int, 'I'> {};
|
||||
template <> struct PythonFormat<long> : PassthroughFormat<long, 'l'> {};
|
||||
|
|
|
@ -80,21 +80,8 @@ Status ScriptedProcessPythonInterface::Launch() {
|
|||
}
|
||||
|
||||
Status ScriptedProcessPythonInterface::Resume() {
|
||||
return GetStatusFromMethod("resume");
|
||||
}
|
||||
|
||||
bool ScriptedProcessPythonInterface::ShouldStop() {
|
||||
Status error;
|
||||
StructuredData::ObjectSP obj = Dispatch("is_alive", error);
|
||||
|
||||
if (!CheckStructuredDataObject(LLVM_PRETTY_FUNCTION, obj, error))
|
||||
return {};
|
||||
|
||||
return obj->GetBooleanValue();
|
||||
}
|
||||
|
||||
Status ScriptedProcessPythonInterface::Stop() {
|
||||
return GetStatusFromMethod("stop");
|
||||
// When calling ScriptedProcess.Resume from lldb we should always stop.
|
||||
return GetStatusFromMethod("resume", /*should_stop=*/true);
|
||||
}
|
||||
|
||||
std::optional<MemoryRegionInfo>
|
||||
|
|
|
@ -37,10 +37,6 @@ public:
|
|||
|
||||
Status Resume() override;
|
||||
|
||||
bool ShouldStop() override;
|
||||
|
||||
Status Stop() override;
|
||||
|
||||
std::optional<MemoryRegionInfo>
|
||||
GetMemoryRegionContainingAddress(lldb::addr_t address,
|
||||
Status &error) override;
|
||||
|
|
|
@ -113,6 +113,11 @@ protected:
|
|||
return {object};
|
||||
}
|
||||
|
||||
python::PythonObject Transform(bool arg) {
|
||||
// Boolean arguments need to be turned into python objects.
|
||||
return python::PythonBoolean(arg);
|
||||
}
|
||||
|
||||
python::PythonObject Transform(Status arg) {
|
||||
return python::ToSWIGWrapper(arg);
|
||||
}
|
||||
|
@ -141,6 +146,15 @@ protected:
|
|||
original_arg = ExtractValueFromPythonObject<T>(transformed_arg, error);
|
||||
}
|
||||
|
||||
template <>
|
||||
void ReverseTransform(bool &original_arg,
|
||||
python::PythonObject transformed_arg, Status &error) {
|
||||
python::PythonBoolean boolean_arg = python::PythonBoolean(
|
||||
python::PyRefType::Borrowed, transformed_arg.get());
|
||||
if (boolean_arg.IsValid())
|
||||
original_arg = boolean_arg.GetValue();
|
||||
}
|
||||
|
||||
template <std::size_t... I, typename... Args>
|
||||
auto TransformTuple(const std::tuple<Args...> &args,
|
||||
std::index_sequence<I...>) {
|
||||
|
|
Loading…
Reference in New Issue
Block a user