1 //===-- ScriptedProcessPythonInterface.cpp --------------------------------===//
3 // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
4 // See https://llvm.org/LICENSE.txt for license information.
5 // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
7 //===----------------------------------------------------------------------===//
9 #include "lldb/Core/PluginManager.h"
10 #include "lldb/Host/Config.h"
11 #include "lldb/Utility/Log.h"
12 #include "lldb/Utility/Status.h"
13 #include "lldb/lldb-enumerations.h"
15 #if LLDB_ENABLE_PYTHON
18 // LLDB Python header must be included first
19 #include "../lldb-python.h"
21 #include "../SWIGPythonBridge.h"
22 #include "../ScriptInterpreterPythonImpl.h"
23 #include "ScriptedThreadPythonInterface.h"
24 #include "ScriptedProcessPythonInterface.h"
26 // Included in this position to prevent redefinition of pid_t on Windows.
27 #include "lldb/Target/Process.h"
33 using namespace lldb_private
;
34 using namespace lldb_private::python
;
35 using Locker
= ScriptInterpreterPythonImpl::Locker
;
37 ScriptedProcessPythonInterface::ScriptedProcessPythonInterface(
38 ScriptInterpreterPythonImpl
&interpreter
)
39 : ScriptedProcessInterface(), ScriptedPythonInterface(interpreter
) {}
41 llvm::Expected
<StructuredData::GenericSP
>
42 ScriptedProcessPythonInterface::CreatePluginObject(
43 llvm::StringRef class_name
, ExecutionContext
&exe_ctx
,
44 StructuredData::DictionarySP args_sp
, StructuredData::Generic
*script_obj
) {
45 ExecutionContextRefSP exe_ctx_ref_sp
=
46 std::make_shared
<ExecutionContextRef
>(exe_ctx
);
47 StructuredDataImpl
sd_impl(args_sp
);
48 return ScriptedPythonInterface::CreatePluginObject(class_name
, script_obj
,
49 exe_ctx_ref_sp
, sd_impl
);
52 StructuredData::DictionarySP
ScriptedProcessPythonInterface::GetCapabilities() {
54 StructuredData::DictionarySP dict
=
55 Dispatch
<StructuredData::DictionarySP
>("get_capabilities", error
);
57 if (!ScriptedInterface::CheckStructuredDataObject(LLVM_PRETTY_FUNCTION
, dict
,
65 ScriptedProcessPythonInterface::Attach(const ProcessAttachInfo
&attach_info
) {
66 lldb::ProcessAttachInfoSP attach_info_sp
=
67 std::make_shared
<ProcessAttachInfo
>(attach_info
);
68 return GetStatusFromMethod("attach", attach_info_sp
);
71 Status
ScriptedProcessPythonInterface::Launch() {
72 return GetStatusFromMethod("launch");
75 Status
ScriptedProcessPythonInterface::Resume() {
76 // When calling ScriptedProcess.Resume from lldb we should always stop.
77 return GetStatusFromMethod("resume", /*should_stop=*/true);
80 std::optional
<MemoryRegionInfo
>
81 ScriptedProcessPythonInterface::GetMemoryRegionContainingAddress(
82 lldb::addr_t address
, Status
&error
) {
83 auto mem_region
= Dispatch
<std::optional
<MemoryRegionInfo
>>(
84 "get_memory_region_containing_address", error
, address
);
87 return ErrorWithMessage
<MemoryRegionInfo
>(LLVM_PRETTY_FUNCTION
,
88 error
.AsCString(), error
);
94 StructuredData::DictionarySP
ScriptedProcessPythonInterface::GetThreadsInfo() {
96 StructuredData::DictionarySP dict
=
97 Dispatch
<StructuredData::DictionarySP
>("get_threads_info", error
);
99 if (!ScriptedInterface::CheckStructuredDataObject(LLVM_PRETTY_FUNCTION
, dict
,
106 bool ScriptedProcessPythonInterface::CreateBreakpoint(lldb::addr_t addr
,
109 StructuredData::ObjectSP obj
=
110 Dispatch("create_breakpoint", py_error
, addr
, error
);
112 // If there was an error on the python call, surface it to the user.
114 error
= std::move(py_error
);
116 if (!ScriptedInterface::CheckStructuredDataObject(LLVM_PRETTY_FUNCTION
, obj
,
120 return obj
->GetBooleanValue();
123 lldb::DataExtractorSP
ScriptedProcessPythonInterface::ReadMemoryAtAddress(
124 lldb::addr_t address
, size_t size
, Status
&error
) {
126 lldb::DataExtractorSP data_sp
= Dispatch
<lldb::DataExtractorSP
>(
127 "read_memory_at_address", py_error
, address
, size
, error
);
129 // If there was an error on the python call, surface it to the user.
131 error
= std::move(py_error
);
136 lldb::offset_t
ScriptedProcessPythonInterface::WriteMemoryAtAddress(
137 lldb::addr_t addr
, lldb::DataExtractorSP data_sp
, Status
&error
) {
139 StructuredData::ObjectSP obj
=
140 Dispatch("write_memory_at_address", py_error
, addr
, data_sp
, error
);
142 if (!ScriptedInterface::CheckStructuredDataObject(LLVM_PRETTY_FUNCTION
, obj
,
144 return LLDB_INVALID_OFFSET
;
146 // If there was an error on the python call, surface it to the user.
148 error
= std::move(py_error
);
150 return obj
->GetUnsignedIntegerValue(LLDB_INVALID_OFFSET
);
153 StructuredData::ArraySP
ScriptedProcessPythonInterface::GetLoadedImages() {
155 StructuredData::ArraySP array
=
156 Dispatch
<StructuredData::ArraySP
>("get_loaded_images", error
);
158 if (!ScriptedInterface::CheckStructuredDataObject(LLVM_PRETTY_FUNCTION
, array
,
165 lldb::pid_t
ScriptedProcessPythonInterface::GetProcessID() {
167 StructuredData::ObjectSP obj
= Dispatch("get_process_id", error
);
169 if (!ScriptedInterface::CheckStructuredDataObject(LLVM_PRETTY_FUNCTION
, obj
,
171 return LLDB_INVALID_PROCESS_ID
;
173 return obj
->GetUnsignedIntegerValue(LLDB_INVALID_PROCESS_ID
);
176 bool ScriptedProcessPythonInterface::IsAlive() {
178 StructuredData::ObjectSP obj
= Dispatch("is_alive", error
);
180 if (!ScriptedInterface::CheckStructuredDataObject(LLVM_PRETTY_FUNCTION
, obj
,
184 return obj
->GetBooleanValue();
187 std::optional
<std::string
>
188 ScriptedProcessPythonInterface::GetScriptedThreadPluginName() {
190 StructuredData::ObjectSP obj
= Dispatch("get_scripted_thread_plugin", error
);
192 if (!ScriptedInterface::CheckStructuredDataObject(LLVM_PRETTY_FUNCTION
, obj
,
196 return obj
->GetStringValue().str();
199 lldb::ScriptedThreadInterfaceSP
200 ScriptedProcessPythonInterface::CreateScriptedThreadInterface() {
201 return m_interpreter
.CreateScriptedThreadInterface();
204 StructuredData::DictionarySP
ScriptedProcessPythonInterface::GetMetadata() {
206 StructuredData::DictionarySP dict
=
207 Dispatch
<StructuredData::DictionarySP
>("get_process_metadata", error
);
209 if (!ScriptedInterface::CheckStructuredDataObject(LLVM_PRETTY_FUNCTION
, dict
,
216 void ScriptedProcessPythonInterface::Initialize() {
217 const std::vector
<llvm::StringRef
> ci_usages
= {
218 "process attach -C <script-name> [-k key -v value ...]",
219 "process launch -C <script-name> [-k key -v value ...]"};
220 const std::vector
<llvm::StringRef
> api_usages
= {
221 "SBAttachInfo.SetScriptedProcessClassName",
222 "SBAttachInfo.SetScriptedProcessDictionary",
224 "SBLaunchInfo.SetScriptedProcessClassName",
225 "SBLaunchInfo.SetScriptedProcessDictionary",
227 PluginManager::RegisterPlugin(
228 GetPluginNameStatic(), llvm::StringRef("Mock process state"),
229 CreateInstance
, eScriptLanguagePython
, {ci_usages
, api_usages
});
232 void ScriptedProcessPythonInterface::Terminate() {
233 PluginManager::UnregisterPlugin(CreateInstance
);