mib created this revision.
mib added reviewers: JDevlieghere, bulbazord.
mib added a project: LLDB.
Herald added a project: All.
mib requested review of this revision.
Herald added a subscriber: lldb-commits.
This patch adds process attach capabilities to the ScriptedProcess
plugin. This doesn't really expects a PID or process name, since the
process state is already script, however, this allows to create a
scripted process without requiring to have an executuble in the target.
In order to do so, this patch also moves the scripted process related
getters and setters from the `ProcessLaunchInfo` and
`ProcessAttachInfo` classes to the `ProcessInfo` class, so they can be
accessed interchangeably.
rdar://104577406
Signed-off-by: Med Ismail Bennani <[email protected]>
Repository:
rG LLVM Github Monorepo
https://reviews.llvm.org/D143104
Files:
lldb/examples/python/scripted_process/scripted_process.py
lldb/include/lldb/Host/ProcessLaunchInfo.h
lldb/include/lldb/Interpreter/ScriptedProcessInterface.h
lldb/include/lldb/Target/Process.h
lldb/include/lldb/Target/Target.h
lldb/include/lldb/Utility/ProcessInfo.h
lldb/source/Host/common/ProcessLaunchInfo.cpp
lldb/source/Plugins/Process/scripted/ScriptedProcess.cpp
lldb/source/Plugins/Process/scripted/ScriptedProcess.h
lldb/source/Plugins/ScriptInterpreter/Python/ScriptedProcessPythonInterface.cpp
lldb/source/Plugins/ScriptInterpreter/Python/ScriptedProcessPythonInterface.h
lldb/source/Target/Target.cpp
lldb/source/Utility/ProcessInfo.cpp
Index: lldb/source/Utility/ProcessInfo.cpp
===================================================================
--- lldb/source/Utility/ProcessInfo.cpp
+++ lldb/source/Utility/ProcessInfo.cpp
@@ -21,12 +21,14 @@
using namespace lldb_private;
ProcessInfo::ProcessInfo()
- : m_executable(), m_arguments(), m_environment(), m_arch() {}
+ : m_executable(), m_arguments(), m_environment(), m_arch(),
+ m_scripted_process_class_name(), m_scripted_process_dictionary_sp() {}
ProcessInfo::ProcessInfo(const char *name, const ArchSpec &arch,
lldb::pid_t pid)
: m_executable(name), m_arguments(), m_environment(), m_arch(arch),
- m_pid(pid) {}
+ m_pid(pid), m_scripted_process_class_name(),
+ m_scripted_process_dictionary_sp() {}
void ProcessInfo::Clear() {
m_executable.Clear();
@@ -36,6 +38,8 @@
m_gid = UINT32_MAX;
m_arch.Clear();
m_pid = LLDB_INVALID_PROCESS_ID;
+ m_scripted_process_class_name.clear();
+ m_scripted_process_dictionary_sp.reset();
}
const char *ProcessInfo::GetName() const {
Index: lldb/source/Target/Target.cpp
===================================================================
--- lldb/source/Target/Target.cpp
+++ lldb/source/Target/Target.cpp
@@ -3080,6 +3080,22 @@
void Target::ClearAllLoadedSections() { m_section_load_history.Clear(); }
+void Target::SaveScriptedLaunchInfo(lldb_private::ProcessInfo &process_info) {
+ if (process_info.IsScriptedProcess()) {
+ // Only copy scripted process launch options.
+ ProcessLaunchInfo &default_launch_info = const_cast<ProcessLaunchInfo &>(
+ GetGlobalProperties().GetProcessLaunchInfo());
+
+ default_launch_info.SetProcessPluginName("ScriptedProcess");
+ default_launch_info.SetScriptedProcessClassName(
+ process_info.GetScriptedProcessClassName());
+ default_launch_info.SetScriptedProcessDictionarySP(
+ process_info.GetScriptedProcessDictionarySP());
+
+ SetProcessLaunchInfo(default_launch_info);
+ }
+}
+
Status Target::Launch(ProcessLaunchInfo &launch_info, Stream *stream) {
m_stats.SetLaunchOrAttachTime();
Status error;
@@ -3109,19 +3125,7 @@
launch_info.GetFlags().Set(eLaunchFlagDebug);
- if (launch_info.IsScriptedProcess()) {
- // Only copy scripted process launch options.
- ProcessLaunchInfo &default_launch_info = const_cast<ProcessLaunchInfo &>(
- GetGlobalProperties().GetProcessLaunchInfo());
-
- default_launch_info.SetProcessPluginName("ScriptedProcess");
- default_launch_info.SetScriptedProcessClassName(
- launch_info.GetScriptedProcessClassName());
- default_launch_info.SetScriptedProcessDictionarySP(
- launch_info.GetScriptedProcessDictionarySP());
-
- SetProcessLaunchInfo(launch_info);
- }
+ SaveScriptedLaunchInfo(launch_info);
// Get the value of synchronous execution here. If you wait till after you
// have started to run, then you could have hit a breakpoint, whose command
@@ -3334,11 +3338,12 @@
Status error;
if (state != eStateConnected && platform_sp != nullptr &&
- platform_sp->CanDebugProcess()) {
+ platform_sp->CanDebugProcess() && !attach_info.IsScriptedProcess()) {
SetPlatform(platform_sp);
process_sp = platform_sp->Attach(attach_info, GetDebugger(), this, error);
} else {
if (state != eStateConnected) {
+ SaveScriptedLaunchInfo(attach_info);
const char *plugin_name = attach_info.GetProcessPluginName();
process_sp =
CreateProcess(attach_info.GetListenerForProcess(GetDebugger()),
Index: lldb/source/Plugins/ScriptInterpreter/Python/ScriptedProcessPythonInterface.h
===================================================================
--- lldb/source/Plugins/ScriptInterpreter/Python/ScriptedProcessPythonInterface.h
+++ lldb/source/Plugins/ScriptInterpreter/Python/ScriptedProcessPythonInterface.h
@@ -31,6 +31,8 @@
StructuredData::DictionarySP GetCapabilities() override;
+ Status Attach() override;
+
Status Launch() override;
Status Resume() override;
Index: lldb/source/Plugins/ScriptInterpreter/Python/ScriptedProcessPythonInterface.cpp
===================================================================
--- lldb/source/Plugins/ScriptInterpreter/Python/ScriptedProcessPythonInterface.cpp
+++ lldb/source/Plugins/ScriptInterpreter/Python/ScriptedProcessPythonInterface.cpp
@@ -67,6 +67,10 @@
return dict;
}
+Status ScriptedProcessPythonInterface::Attach() {
+ return GetStatusFromMethod("attach");
+}
+
Status ScriptedProcessPythonInterface::Launch() {
return GetStatusFromMethod("launch");
}
Index: lldb/source/Plugins/Process/scripted/ScriptedProcess.h
===================================================================
--- lldb/source/Plugins/Process/scripted/ScriptedProcess.h
+++ lldb/source/Plugins/Process/scripted/ScriptedProcess.h
@@ -51,6 +51,15 @@
Status DoResume() override;
+ Status DoAttachToProcessWithID(lldb::pid_t pid,
+ const ProcessAttachInfo &attach_info) override;
+
+ Status
+ DoAttachToProcessWithName(const char *process_name,
+ const ProcessAttachInfo &attach_info) override;
+
+ void DidAttach(ArchSpec &process_arch) override;
+
Status DoDestroy() override;
void RefreshStateAfterStop() override;
@@ -88,6 +97,8 @@
Status DoGetMemoryRegionInfo(lldb::addr_t load_addr,
MemoryRegionInfo &range_info) override;
+ Status DoAttach();
+
private:
friend class ScriptedThread;
Index: lldb/source/Plugins/Process/scripted/ScriptedProcess.cpp
===================================================================
--- lldb/source/Plugins/Process/scripted/ScriptedProcess.cpp
+++ lldb/source/Plugins/Process/scripted/ScriptedProcess.cpp
@@ -195,6 +195,38 @@
return error;
}
+Status ScriptedProcess::DoAttach() {
+ CheckInterpreterAndScriptObject();
+
+ Status error = GetInterface().Attach();
+ SetPrivateState(eStateRunning);
+
+ if (error.Fail())
+ return error;
+
+ SetPrivateState(eStateStopped);
+ // NOTE: We need to set the PID before finishing to attach otherwise we will
+ // hit an assert when calling the attach completion handler.
+ DidLaunch();
+
+ return {};
+}
+
+Status
+ScriptedProcess::DoAttachToProcessWithID(lldb::pid_t pid,
+ const ProcessAttachInfo &attach_info) {
+ return DoAttach();
+}
+
+Status ScriptedProcess::DoAttachToProcessWithName(
+ const char *process_name, const ProcessAttachInfo &attach_info) {
+ return DoAttach();
+}
+
+void ScriptedProcess::DidAttach(ArchSpec &process_arch) {
+ process_arch = GetArchitecture();
+}
+
Status ScriptedProcess::DoStop() {
CheckInterpreterAndScriptObject();
Index: lldb/source/Host/common/ProcessLaunchInfo.cpp
===================================================================
--- lldb/source/Host/common/ProcessLaunchInfo.cpp
+++ lldb/source/Host/common/ProcessLaunchInfo.cpp
@@ -32,8 +32,7 @@
ProcessLaunchInfo::ProcessLaunchInfo()
: ProcessInfo(), m_working_dir(), m_plugin_name(), m_flags(0),
m_file_actions(), m_pty(new PseudoTerminal), m_monitor_callback(nullptr),
- m_listener_sp(), m_hijack_listener_sp(), m_scripted_process_class_name(),
- m_scripted_process_dictionary_sp() {}
+ m_listener_sp(), m_hijack_listener_sp() {}
ProcessLaunchInfo::ProcessLaunchInfo(const FileSpec &stdin_file_spec,
const FileSpec &stdout_file_spec,
@@ -41,8 +40,7 @@
const FileSpec &working_directory,
uint32_t launch_flags)
: ProcessInfo(), m_working_dir(), m_plugin_name(), m_flags(launch_flags),
- m_file_actions(), m_pty(new PseudoTerminal),
- m_scripted_process_class_name(), m_scripted_process_dictionary_sp() {
+ m_file_actions(), m_pty(new PseudoTerminal) {
if (stdin_file_spec) {
FileAction file_action;
const bool read = true;
Index: lldb/include/lldb/Utility/ProcessInfo.h
===================================================================
--- lldb/include/lldb/Utility/ProcessInfo.h
+++ lldb/include/lldb/Utility/ProcessInfo.h
@@ -14,6 +14,7 @@
#include "lldb/Utility/Environment.h"
#include "lldb/Utility/FileSpec.h"
#include "lldb/Utility/NameMatches.h"
+#include "lldb/Utility/StructuredData.h"
#include <vector>
namespace lldb_private {
@@ -86,6 +87,28 @@
Environment &GetEnvironment() { return m_environment; }
const Environment &GetEnvironment() const { return m_environment; }
+ bool IsScriptedProcess() const {
+ return !m_scripted_process_class_name.empty();
+ }
+
+ std::string GetScriptedProcessClassName() const {
+ return m_scripted_process_class_name;
+ }
+
+ void SetScriptedProcessClassName(std::string name) {
+ m_scripted_process_class_name = name;
+ }
+
+ lldb_private::StructuredData::DictionarySP
+ GetScriptedProcessDictionarySP() const {
+ return m_scripted_process_dictionary_sp;
+ }
+
+ void SetScriptedProcessDictionarySP(
+ lldb_private::StructuredData::DictionarySP dictionary_sp) {
+ m_scripted_process_dictionary_sp = dictionary_sp;
+ }
+
protected:
FileSpec m_executable;
std::string m_arg0; // argv[0] if supported. If empty, then use m_executable.
@@ -97,6 +120,11 @@
uint32_t m_gid = UINT32_MAX;
ArchSpec m_arch;
lldb::pid_t m_pid = LLDB_INVALID_PROCESS_ID;
+ std::string m_scripted_process_class_name; // The name of the class that will
+ // manage a scripted process.
+ StructuredData::DictionarySP
+ m_scripted_process_dictionary_sp; // A dictionary that holds key/value
+ // pairs passed to the scripted process.
};
// ProcessInstanceInfo
Index: lldb/include/lldb/Target/Target.h
===================================================================
--- lldb/include/lldb/Target/Target.h
+++ lldb/include/lldb/Target/Target.h
@@ -1428,6 +1428,8 @@
return *m_frame_recognizer_manager_up;
}
+ void SaveScriptedLaunchInfo(lldb_private::ProcessInfo &process_info);
+
/// Add a signal for the target. This will get copied over to the process
/// if the signal exists on that target. Only the values with Yes and No are
/// set, Calculate values will be ignored.
Index: lldb/include/lldb/Target/Process.h
===================================================================
--- lldb/include/lldb/Target/Process.h
+++ lldb/include/lldb/Target/Process.h
@@ -192,28 +192,6 @@
lldb::ListenerSP GetListenerForProcess(Debugger &debugger);
- bool IsScriptedProcess() const {
- return !m_scripted_process_class_name.empty();
- }
-
- std::string GetScriptedProcessClassName() const {
- return m_scripted_process_class_name;
- }
-
- void SetScriptedProcessClassName(std::string name) {
- m_scripted_process_class_name = name;
- }
-
- lldb_private::StructuredData::DictionarySP
- GetScriptedProcessDictionarySP() const {
- return m_scripted_process_dictionary_sp;
- }
-
- void SetScriptedProcessDictionarySP(
- lldb_private::StructuredData::DictionarySP dictionary_sp) {
- m_scripted_process_dictionary_sp = dictionary_sp;
- }
-
protected:
lldb::ListenerSP m_listener_sp;
lldb::ListenerSP m_hijack_listener_sp;
@@ -231,11 +209,6 @@
false; // Use an async attach where we start the attach and return
// immediately (used by GUI programs with --waitfor so they can
// call SBProcess::Stop() to cancel attach)
- std::string m_scripted_process_class_name; // The name of the class that will
- // manage a scripted process.
- StructuredData::DictionarySP
- m_scripted_process_dictionary_sp; // A dictionary that holds key/value
- // pairs passed to the scripted process.
};
// This class tracks the Modification state of the process. Things that can
Index: lldb/include/lldb/Interpreter/ScriptedProcessInterface.h
===================================================================
--- lldb/include/lldb/Interpreter/ScriptedProcessInterface.h
+++ lldb/include/lldb/Interpreter/ScriptedProcessInterface.h
@@ -30,6 +30,8 @@
virtual StructuredData::DictionarySP GetCapabilities() { return {}; }
+ virtual Status Attach() { return Status("ScriptedProcess did not attach"); }
+
virtual Status Launch() { return Status("ScriptedProcess did not launch"); }
virtual Status Resume() { return Status("ScriptedProcess did not resume"); }
Index: lldb/include/lldb/Host/ProcessLaunchInfo.h
===================================================================
--- lldb/include/lldb/Host/ProcessLaunchInfo.h
+++ lldb/include/lldb/Host/ProcessLaunchInfo.h
@@ -20,7 +20,6 @@
#include "lldb/Host/PseudoTerminal.h"
#include "lldb/Utility/FileSpec.h"
#include "lldb/Utility/ProcessInfo.h"
-#include "lldb/Utility/StructuredData.h"
namespace lldb_private {
@@ -144,28 +143,6 @@
return m_flags.Test(lldb::eLaunchFlagDetachOnError);
}
- bool IsScriptedProcess() const {
- return !m_scripted_process_class_name.empty();
- }
-
- std::string GetScriptedProcessClassName() const {
- return m_scripted_process_class_name;
- }
-
- void SetScriptedProcessClassName(std::string name) {
- m_scripted_process_class_name = name;
- }
-
- lldb_private::StructuredData::DictionarySP
- GetScriptedProcessDictionarySP() const {
- return m_scripted_process_dictionary_sp;
- }
-
- void SetScriptedProcessDictionarySP(
- lldb_private::StructuredData::DictionarySP dictionary_sp) {
- m_scripted_process_dictionary_sp = dictionary_sp;
- }
-
protected:
FileSpec m_working_dir;
std::string m_plugin_name;
@@ -179,11 +156,6 @@
// meaning to the upper levels of lldb.
lldb::ListenerSP m_listener_sp;
lldb::ListenerSP m_hijack_listener_sp;
- std::string m_scripted_process_class_name; // The name of the class that will
- // manage a scripted process.
- StructuredData::DictionarySP
- m_scripted_process_dictionary_sp; // A dictionary that holds key/value
- // pairs passed to the scripted process.
};
}
Index: lldb/examples/python/scripted_process/scripted_process.py
===================================================================
--- lldb/examples/python/scripted_process/scripted_process.py
+++ lldb/examples/python/scripted_process/scripted_process.py
@@ -163,6 +163,14 @@
"""
return lldb.SBError()
+ def attach(self):
+ """ Simulate the scripted process attach.
+
+ Returns:
+ lldb.SBError: An `lldb.SBError` with error code 0.
+ """
+ return lldb.SBError()
+
def resume(self):
""" Simulate the scripted process resume.
_______________________________________________
lldb-commits mailing list
[email protected]
https://lists.llvm.org/cgi-bin/mailman/listinfo/lldb-commits