LLDB mainline
ScriptedProcessPythonInterface.cpp
Go to the documentation of this file.
1//===-- ScriptedProcessPythonInterface.cpp --------------------------------===//
2//
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
6//
7//===----------------------------------------------------------------------===//
8
10#include "lldb/Utility/Log.h"
11#include "lldb/Utility/Status.h"
13
14// clang-format off
15// LLDB Python header must be included first
16#include "../lldb-python.h"
17
18#include "../SWIGPythonBridge.h"
22
23// Included in this position to prevent redefinition of pid_t on Windows.
24#include "lldb/Target/Process.h"
25//clang-format off
26
27#include <optional>
28
29using namespace lldb;
30using namespace lldb_private;
31using namespace lldb_private::python;
33
37
38llvm::Expected<StructuredData::GenericSP>
40 llvm::StringRef class_name, ExecutionContext &exe_ctx,
42 ExecutionContextRefSP exe_ctx_ref_sp =
43 std::make_shared<ExecutionContextRef>(exe_ctx);
44 StructuredDataImpl sd_impl(args_sp);
45 return ScriptedPythonInterface::CreatePluginObject(class_name, script_obj,
46 exe_ctx_ref_sp, sd_impl);
47}
48
60
63 lldb::ProcessAttachInfoSP attach_info_sp =
64 std::make_shared<ProcessAttachInfo>(attach_info);
65 return GetStatusFromMethod("attach", attach_info_sp);
66}
67
71
73 // When calling ScriptedProcess.Resume from lldb we should always stop.
74 return GetStatusFromMethod("resume", /*should_stop=*/true);
75}
76
77std::optional<MemoryRegionInfo>
79 lldb::addr_t address, Status &error) {
81 "get_memory_region_containing_address", error, address);
82
83 if (error.Fail()) {
84 return ErrorWithMessage<MemoryRegionInfo>(LLVM_PRETTY_FUNCTION,
85 error.AsCString(), error);
86 }
87
88 return mem_region;
89}
90
102
104 Status &error) {
105 Status py_error;
107 Dispatch("create_breakpoint", py_error, addr, error);
108
109 // If there was an error on the python call, surface it to the user.
110 if (py_error.Fail())
111 error = std::move(py_error);
112
113 if (!ScriptedInterface::CheckStructuredDataObject(LLVM_PRETTY_FUNCTION, obj,
114 error))
115 return {};
116
117 return obj->GetBooleanValue();
118}
119
121 lldb::addr_t address, size_t size, Status &error) {
122 Status py_error;
124 "read_memory_at_address", py_error, address, size, error);
125
126 // If there was an error on the python call, surface it to the user.
127 if (py_error.Fail())
128 error = std::move(py_error);
129
130 return data_sp;
131}
132
135 Status py_error;
137 Dispatch("write_memory_at_address", py_error, addr, data_sp, error);
138
139 if (!ScriptedInterface::CheckStructuredDataObject(LLVM_PRETTY_FUNCTION, obj,
140 error))
141 return LLDB_INVALID_OFFSET;
142
143 // If there was an error on the python call, surface it to the user.
144 if (py_error.Fail())
145 error = std::move(py_error);
146
147 return obj->GetUnsignedIntegerValue(LLDB_INVALID_OFFSET);
148}
149
153 Dispatch<StructuredData::ArraySP>("get_loaded_images", error);
154
155 if (!ScriptedInterface::CheckStructuredDataObject(LLVM_PRETTY_FUNCTION, array,
156 error))
157 return {};
158
159 return array;
160}
161
164 StructuredData::ObjectSP obj = Dispatch("get_process_id", error);
165
166 if (!ScriptedInterface::CheckStructuredDataObject(LLVM_PRETTY_FUNCTION, obj,
167 error))
169
170 return obj->GetUnsignedIntegerValue(LLDB_INVALID_PROCESS_ID);
171}
172
175 StructuredData::ObjectSP obj = Dispatch("is_alive", error);
176
177 if (!ScriptedInterface::CheckStructuredDataObject(LLVM_PRETTY_FUNCTION, obj,
178 error))
179 return {};
180
181 return obj->GetBooleanValue();
182}
183
184std::optional<std::string>
187 StructuredData::ObjectSP obj = Dispatch("get_scripted_thread_plugin", error);
188
189 if (!ScriptedInterface::CheckStructuredDataObject(LLVM_PRETTY_FUNCTION, obj,
190 error))
191 return {};
192
193 return obj->GetStringValue().str();
194}
195
198 return m_interpreter.CreateScriptedThreadInterface();
199}
200
204 Dispatch<StructuredData::DictionarySP>("get_process_metadata", error);
205
206 if (!ScriptedInterface::CheckStructuredDataObject(LLVM_PRETTY_FUNCTION, dict,
207 error))
208 return {};
209
210 return dict;
211}
212
214 const std::vector<llvm::StringRef> ci_usages = {
215 "process attach -C <script-name> [-k key -v value ...]",
216 "process launch -C <script-name> [-k key -v value ...]"};
217 const std::vector<llvm::StringRef> api_usages = {
218 "SBAttachInfo.SetScriptedProcessClassName",
219 "SBAttachInfo.SetScriptedProcessDictionary",
220 "SBTarget.Attach",
221 "SBLaunchInfo.SetScriptedProcessClassName",
222 "SBLaunchInfo.SetScriptedProcessDictionary",
223 "SBTarget.Launch"};
225 GetPluginNameStatic(), llvm::StringRef("Mock process state"),
226 CreateInstance, eScriptLanguagePython, {ci_usages, api_usages});
227}
228
static llvm::raw_ostream & error(Stream &strm)
ScriptInterpreterPythonImpl::Locker Locker
"lldb/Target/ExecutionContext.h" A class that contains an execution context.
static bool RegisterPlugin(llvm::StringRef name, llvm::StringRef description, ABICreateInstance create_callback)
static bool UnregisterPlugin(ABICreateInstance create_callback)
static Ret ErrorWithMessage(llvm::StringRef caller_name, llvm::StringRef error_msg, Status &error, LLDBLog log_category=LLDBLog::Process)
static bool CheckStructuredDataObject(llvm::StringRef caller, T obj, Status &error)
static bool CreateInstance(lldb::ScriptLanguage language, ScriptedInterfaceUsages usages)
StructuredData::DictionarySP GetThreadsInfo() override
llvm::Expected< StructuredData::GenericSP > CreatePluginObject(const llvm::StringRef class_name, ExecutionContext &exe_ctx, StructuredData::DictionarySP args_sp, StructuredData::Generic *script_obj=nullptr) override
lldb::ScriptedThreadInterfaceSP CreateScriptedThreadInterface() override
lldb::DataExtractorSP ReadMemoryAtAddress(lldb::addr_t address, size_t size, Status &error) override
std::optional< std::string > GetScriptedThreadPluginName() override
bool CreateBreakpoint(lldb::addr_t addr, Status &error) override
Status Attach(const ProcessAttachInfo &attach_info) override
std::optional< MemoryRegionInfo > GetMemoryRegionContainingAddress(lldb::addr_t address, Status &error) override
lldb::offset_t WriteMemoryAtAddress(lldb::addr_t addr, lldb::DataExtractorSP data_sp, Status &error) override
ScriptedProcessPythonInterface(ScriptInterpreterPythonImpl &interpreter)
StructuredData::DictionarySP GetCapabilities() override
Status GetStatusFromMethod(llvm::StringRef method_name, Args &&...args)
llvm::Expected< StructuredData::GenericSP > CreatePluginObject(llvm::StringRef class_name, StructuredData::Generic *script_obj, Args... args)
ScriptInterpreterPythonImpl & m_interpreter
ScriptedPythonInterface(ScriptInterpreterPythonImpl &interpreter)
T Dispatch(llvm::StringRef method_name, Status &error, Args &&...args)
An error handling class.
Definition Status.h:118
bool Fail() const
Test for error condition.
Definition Status.cpp:294
std::shared_ptr< Dictionary > DictionarySP
std::shared_ptr< Object > ObjectSP
std::shared_ptr< Array > ArraySP
#define LLDB_INVALID_OFFSET
#define LLDB_INVALID_PROCESS_ID
A class that represents a running process on the host machine.
@ eScriptLanguagePython
uint64_t offset_t
Definition lldb-types.h:85
std::shared_ptr< lldb_private::ProcessAttachInfo > ProcessAttachInfoSP
std::shared_ptr< lldb_private::ScriptedThreadInterface > ScriptedThreadInterfaceSP
uint64_t pid_t
Definition lldb-types.h:83
uint64_t addr_t
Definition lldb-types.h:80
std::shared_ptr< lldb_private::DataExtractor > DataExtractorSP
std::shared_ptr< lldb_private::ExecutionContextRef > ExecutionContextRefSP