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/Host/Config.h"
10#if LLDB_ENABLE_PYTHON
11// LLDB Python header must be included first
12#include "../lldb-python.h"
13#endif
14#include "lldb/Target/Process.h"
15#include "lldb/Utility/Log.h"
16#include "lldb/Utility/Status.h"
17#include "lldb/lldb-enumerations.h"
18
19#if LLDB_ENABLE_PYTHON
20
21#include "../SWIGPythonBridge.h"
22#include "../ScriptInterpreterPythonImpl.h"
23#include "ScriptedProcessPythonInterface.h"
24#include "ScriptedThreadPythonInterface.h"
25#include <optional>
26
27using namespace lldb;
28using namespace lldb_private;
29using namespace lldb_private::python;
30using Locker = ScriptInterpreterPythonImpl::Locker;
31
32ScriptedProcessPythonInterface::ScriptedProcessPythonInterface(
33 ScriptInterpreterPythonImpl &interpreter)
34 : ScriptedProcessInterface(), ScriptedPythonInterface(interpreter) {}
35
36llvm::Expected<StructuredData::GenericSP>
37ScriptedProcessPythonInterface::CreatePluginObject(
38 llvm::StringRef class_name, ExecutionContext &exe_ctx,
39 StructuredData::DictionarySP args_sp, StructuredData::Generic *script_obj) {
40 ExecutionContextRefSP exe_ctx_ref_sp =
41 std::make_shared<ExecutionContextRef>(args&: exe_ctx);
42 StructuredDataImpl sd_impl(args_sp);
43 return ScriptedPythonInterface::CreatePluginObject(class_name, script_obj,
44 args: exe_ctx_ref_sp, args: sd_impl);
45}
46
47StructuredData::DictionarySP ScriptedProcessPythonInterface::GetCapabilities() {
48 Status error;
49 StructuredData::DictionarySP dict =
50 Dispatch<StructuredData::DictionarySP>(method_name: "get_capabilities", error);
51
52 if (!CheckStructuredDataObject(LLVM_PRETTY_FUNCTION, obj: dict, error))
53 return {};
54
55 return dict;
56}
57
58Status
59ScriptedProcessPythonInterface::Attach(const ProcessAttachInfo &attach_info) {
60 lldb::ProcessAttachInfoSP attach_info_sp =
61 std::make_shared<ProcessAttachInfo>(args: attach_info);
62 return GetStatusFromMethod(method_name: "attach", args&: attach_info_sp);
63}
64
65Status ScriptedProcessPythonInterface::Launch() {
66 return GetStatusFromMethod(method_name: "launch");
67}
68
69Status ScriptedProcessPythonInterface::Resume() {
70 // When calling ScriptedProcess.Resume from lldb we should always stop.
71 return GetStatusFromMethod(method_name: "resume", /*should_stop=*/args: true);
72}
73
74std::optional<MemoryRegionInfo>
75ScriptedProcessPythonInterface::GetMemoryRegionContainingAddress(
76 lldb::addr_t address, Status &error) {
77 auto mem_region = Dispatch<std::optional<MemoryRegionInfo>>(
78 method_name: "get_memory_region_containing_address", error, args&: address);
79
80 if (error.Fail()) {
81 return ErrorWithMessage<MemoryRegionInfo>(LLVM_PRETTY_FUNCTION,
82 error_msg: error.AsCString(), error);
83 }
84
85 return mem_region;
86}
87
88StructuredData::DictionarySP ScriptedProcessPythonInterface::GetThreadsInfo() {
89 Status error;
90 StructuredData::DictionarySP dict =
91 Dispatch<StructuredData::DictionarySP>(method_name: "get_threads_info", error);
92
93 if (!CheckStructuredDataObject(LLVM_PRETTY_FUNCTION, obj: dict, error))
94 return {};
95
96 return dict;
97}
98
99bool ScriptedProcessPythonInterface::CreateBreakpoint(lldb::addr_t addr,
100 Status &error) {
101 Status py_error;
102 StructuredData::ObjectSP obj =
103 Dispatch(method_name: "create_breakpoint", error&: py_error, args&: addr, args&: error);
104
105 // If there was an error on the python call, surface it to the user.
106 if (py_error.Fail())
107 error = py_error;
108
109 if (!CheckStructuredDataObject(LLVM_PRETTY_FUNCTION, obj, error))
110 return {};
111
112 return obj->GetBooleanValue();
113}
114
115lldb::DataExtractorSP ScriptedProcessPythonInterface::ReadMemoryAtAddress(
116 lldb::addr_t address, size_t size, Status &error) {
117 Status py_error;
118 lldb::DataExtractorSP data_sp = Dispatch<lldb::DataExtractorSP>(
119 method_name: "read_memory_at_address", error&: py_error, args&: address, args&: size, args&: error);
120
121 // If there was an error on the python call, surface it to the user.
122 if (py_error.Fail())
123 error = py_error;
124
125 return data_sp;
126}
127
128lldb::offset_t ScriptedProcessPythonInterface::WriteMemoryAtAddress(
129 lldb::addr_t addr, lldb::DataExtractorSP data_sp, Status &error) {
130 Status py_error;
131 StructuredData::ObjectSP obj =
132 Dispatch(method_name: "write_memory_at_address", error&: py_error, args&: addr, args&: data_sp, args&: error);
133
134 if (!CheckStructuredDataObject(LLVM_PRETTY_FUNCTION, obj, error))
135 return LLDB_INVALID_OFFSET;
136
137 // If there was an error on the python call, surface it to the user.
138 if (py_error.Fail())
139 error = py_error;
140
141 return obj->GetUnsignedIntegerValue(LLDB_INVALID_OFFSET);
142}
143
144StructuredData::ArraySP ScriptedProcessPythonInterface::GetLoadedImages() {
145 Status error;
146 StructuredData::ArraySP array =
147 Dispatch<StructuredData::ArraySP>(method_name: "get_loaded_images", error);
148
149 if (!CheckStructuredDataObject(LLVM_PRETTY_FUNCTION, obj: array, error))
150 return {};
151
152 return array;
153}
154
155lldb::pid_t ScriptedProcessPythonInterface::GetProcessID() {
156 Status error;
157 StructuredData::ObjectSP obj = Dispatch(method_name: "get_process_id", error);
158
159 if (!CheckStructuredDataObject(LLVM_PRETTY_FUNCTION, obj, error))
160 return LLDB_INVALID_PROCESS_ID;
161
162 return obj->GetUnsignedIntegerValue(LLDB_INVALID_PROCESS_ID);
163}
164
165bool ScriptedProcessPythonInterface::IsAlive() {
166 Status error;
167 StructuredData::ObjectSP obj = Dispatch(method_name: "is_alive", error);
168
169 if (!CheckStructuredDataObject(LLVM_PRETTY_FUNCTION, obj, error))
170 return {};
171
172 return obj->GetBooleanValue();
173}
174
175std::optional<std::string>
176ScriptedProcessPythonInterface::GetScriptedThreadPluginName() {
177 Status error;
178 StructuredData::ObjectSP obj = Dispatch(method_name: "get_scripted_thread_plugin", error);
179
180 if (!CheckStructuredDataObject(LLVM_PRETTY_FUNCTION, obj, error))
181 return {};
182
183 return obj->GetStringValue().str();
184}
185
186lldb::ScriptedThreadInterfaceSP
187ScriptedProcessPythonInterface::CreateScriptedThreadInterface() {
188 return m_interpreter.CreateScriptedThreadInterface();
189}
190
191StructuredData::DictionarySP ScriptedProcessPythonInterface::GetMetadata() {
192 Status error;
193 StructuredData::DictionarySP dict =
194 Dispatch<StructuredData::DictionarySP>(method_name: "get_process_metadata", error);
195
196 if (!CheckStructuredDataObject(LLVM_PRETTY_FUNCTION, obj: dict, error))
197 return {};
198
199 return dict;
200}
201
202#endif
203

source code of lldb/source/Plugins/ScriptInterpreter/Python/Interfaces/ScriptedProcessPythonInterface.cpp