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
9#include "../lldb-python.h"
10
12#include "lldb/Target/Process.h"
13#include "lldb/Utility/Log.h"
14#include "lldb/Utility/Status.h"
16
17#include "../SWIGPythonBridge.h"
21
22#include <optional>
23
24using namespace lldb;
25using namespace lldb_private;
26using namespace lldb_private::python;
28
32
33llvm::Expected<StructuredData::GenericSP>
35 const ScriptedMetadata &scripted_metadata, ExecutionContext &exe_ctx,
36 StructuredData::Generic *script_obj) {
37 ExecutionContextRefSP exe_ctx_ref_sp =
38 std::make_shared<ExecutionContextRef>(exe_ctx);
40 scripted_metadata, script_obj, exe_ctx_ref_sp,
41 scripted_metadata.GetArgsSP());
42}
43
47 LLVM_PRETTY_FUNCTION);
48 if (!dict)
49 return {};
50
51 return dict;
52}
53
56 lldb::ProcessAttachInfoSP attach_info_sp =
57 std::make_shared<ProcessAttachInfo>(attach_info);
58 return GetStatusFromMethod("attach", attach_info_sp);
59}
60
64
66 // When calling ScriptedProcess.Resume from lldb we should always stop.
67 return GetStatusFromMethod("resume", /*should_stop=*/true);
68}
69
70std::optional<MemoryRegionInfo>
72 lldb::addr_t address, Status &error) {
73 llvm::Expected<std::optional<MemoryRegionInfo>> mem_region_or_err =
75 "get_memory_region_containing_address", address);
76 if (!mem_region_or_err) {
77 error = Status::FromError(mem_region_or_err.takeError());
78 return {};
79 }
80
81 return *mem_region_or_err;
82}
83
87 LLVM_PRETTY_FUNCTION);
88 if (!dict)
89 return {};
90
91 return dict;
92}
93
95 Status &error) {
96 llvm::Expected<StructuredData::ObjectSP> obj_or_err =
97 Dispatch("create_breakpoint", addr, error);
98 // If there was an error on the python call, surface it to the user.
99 if (!obj_or_err) {
100 error = Status::FromError(obj_or_err.takeError());
101 return {};
102 }
103
104 StructuredData::ObjectSP obj = *obj_or_err;
105 if (!obj || !obj->IsValid())
106 return {};
107
108 return obj->GetBooleanValue();
109}
110
112 lldb::addr_t address, size_t size, Status &error) {
113 llvm::Expected<lldb::DataExtractorSP> data_or_err =
114 Dispatch<lldb::DataExtractorSP>("read_memory_at_address", address, size,
115 error);
116 // If there was an error on the python call, surface it to the user.
117 if (!data_or_err) {
118 error = Status::FromError(data_or_err.takeError());
119 return {};
120 }
121
122 return *data_or_err;
123}
124
127 llvm::Expected<StructuredData::ObjectSP> obj_or_err =
128 Dispatch("write_memory_at_address", addr, data_sp, error);
129 // If there was an error on the python call, surface it to the user.
130 if (!obj_or_err) {
131 error = Status::FromError(obj_or_err.takeError());
132 return LLDB_INVALID_OFFSET;
133 }
134
135 StructuredData::ObjectSP obj = *obj_or_err;
136 if (!obj || !obj->IsValid())
137 return LLDB_INVALID_OFFSET;
138
139 return obj->GetUnsignedIntegerValue(LLDB_INVALID_OFFSET);
140}
141
145 LLVM_PRETTY_FUNCTION);
146 if (!array)
147 return {};
148
149 return array;
150}
151
154 LogAndDefault(Dispatch("get_process_id"), LLVM_PRETTY_FUNCTION);
155 if (!obj)
157
158 return obj->GetUnsignedIntegerValue(LLDB_INVALID_PROCESS_ID);
159}
160
163 LogAndDefault(Dispatch("is_alive"), LLVM_PRETTY_FUNCTION);
164 if (!obj)
165 return {};
166
167 return obj->GetBooleanValue();
168}
169
170std::optional<std::string>
173 Dispatch("get_scripted_thread_plugin"), LLVM_PRETTY_FUNCTION);
174 if (!obj)
175 return {};
176
177 return obj->GetStringValue().str();
178}
179
182 return m_interpreter.CreateScriptedThreadInterface();
183}
184
187 Dispatch<StructuredData::DictionarySP>("get_process_metadata"),
188 LLVM_PRETTY_FUNCTION);
189 if (!dict)
190 return {};
191
192 return dict;
193}
194
196 const std::vector<llvm::StringRef> ci_usages = {
197 "process attach -C <script-name> [-k key -v value ...]",
198 "process launch -C <script-name> [-k key -v value ...]"};
199 const std::vector<llvm::StringRef> api_usages = {
200 "SBAttachInfo.SetScriptedProcessClassName",
201 "SBAttachInfo.SetScriptedProcessDictionary",
202 "SBTarget.Attach",
203 "SBLaunchInfo.SetScriptedProcessClassName",
204 "SBLaunchInfo.SetScriptedProcessDictionary",
205 "SBTarget.Launch"};
207 GetPluginNameStatic(), llvm::StringRef("Mock process state"),
209 {ci_usages, api_usages});
210}
211
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 bool CreateInstance(lldb::ScriptLanguage language, ScriptedInterfaceUsages usages)
StructuredData::DictionarySP GetArgsSP() const
StructuredData::DictionarySP GetThreadsInfo() override
lldb::ScriptedThreadInterfaceSP CreateScriptedThreadInterface() override
lldb::DataExtractorSP ReadMemoryAtAddress(lldb::addr_t address, size_t size, Status &error) override
std::optional< std::string > GetScriptedThreadPluginName() override
llvm::Expected< StructuredData::GenericSP > CreatePluginObject(const ScriptedMetadata &scripted_metadata, ExecutionContext &exe_ctx, StructuredData::Generic *script_obj=nullptr) 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)
Call method_name and fold both failure channels into one Status: a failure to call the method at all,...
ScriptInterpreterPythonImpl & m_interpreter
static T LogAndDefault(llvm::Expected< T > value_or_err, llvm::StringRef caller)
Log the failure in value_or_err and fall back to a default-constructed T.
ScriptedPythonInterface(ScriptInterpreterPythonImpl &interpreter)
llvm::Expected< T > Dispatch(llvm::StringRef method_name, Args &&...args)
Call method_name on the scripted object.
llvm::Expected< StructuredData::GenericSP > CreatePluginObject(const ScriptedMetadata &scripted_metadata, StructuredData::Generic *script_obj, Args... args)
An error handling class.
Definition Status.h:118
static Status FromError(llvm::Error error)
Avoid using this in new code. Migrate APIs to llvm::Expected instead.
Definition Status.cpp:136
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
@ eScriptedExtensionScriptedProcess
uint64_t offset_t
Definition lldb-types.h:86
std::shared_ptr< lldb_private::ProcessAttachInfo > ProcessAttachInfoSP
std::shared_ptr< lldb_private::ScriptedThreadInterface > ScriptedThreadInterfaceSP
uint64_t pid_t
Definition lldb-types.h:84
uint64_t addr_t
Definition lldb-types.h:80
std::shared_ptr< lldb_private::DataExtractor > DataExtractorSP
std::shared_ptr< lldb_private::ExecutionContextRef > ExecutionContextRefSP