/Users/buildslave/jenkins/workspace/coverage/llvm-project/lldb/source/Plugins/ScriptInterpreter/Python/ScriptedProcessPythonInterface.cpp
Line | Count | Source (jump to first uncovered line) |
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 | | |
27 | | using namespace lldb; |
28 | | using namespace lldb_private; |
29 | | using namespace lldb_private::python; |
30 | | using Locker = ScriptInterpreterPythonImpl::Locker; |
31 | | |
32 | | ScriptedProcessPythonInterface::ScriptedProcessPythonInterface( |
33 | | ScriptInterpreterPythonImpl &interpreter) |
34 | 198 | : ScriptedProcessInterface(), ScriptedPythonInterface(interpreter) {} Unexecuted instantiation: lldb_private::ScriptedProcessPythonInterface::ScriptedProcessPythonInterface(lldb_private::ScriptInterpreterPythonImpl&) lldb_private::ScriptedProcessPythonInterface::ScriptedProcessPythonInterface(lldb_private::ScriptInterpreterPythonImpl&) Line | Count | Source | 34 | 198 | : ScriptedProcessInterface(), ScriptedPythonInterface(interpreter) {} |
|
35 | | |
36 | | StructuredData::GenericSP ScriptedProcessPythonInterface::CreatePluginObject( |
37 | | llvm::StringRef class_name, ExecutionContext &exe_ctx, |
38 | 198 | StructuredData::DictionarySP args_sp, StructuredData::Generic *script_obj) { |
39 | 198 | if (class_name.empty()) |
40 | 195 | return {}; |
41 | | |
42 | 3 | StructuredDataImpl args_impl(args_sp); |
43 | 3 | std::string error_string; |
44 | | |
45 | 3 | Locker py_lock(&m_interpreter, Locker::AcquireLock | Locker::NoSTDIN, |
46 | 3 | Locker::FreeLock); |
47 | | |
48 | 3 | lldb::ExecutionContextRefSP exe_ctx_ref_sp = |
49 | 3 | std::make_shared<ExecutionContextRef>(exe_ctx); |
50 | | |
51 | 3 | PythonObject ret_val = SWIGBridge::LLDBSwigPythonCreateScriptedObject( |
52 | 3 | class_name.str().c_str(), m_interpreter.GetDictionaryName(), |
53 | 3 | exe_ctx_ref_sp, args_impl, error_string); |
54 | | |
55 | 3 | m_object_instance_sp = |
56 | 3 | StructuredData::GenericSP(new StructuredPythonObject(std::move(ret_val))); |
57 | | |
58 | 3 | return m_object_instance_sp; |
59 | 198 | } |
60 | | |
61 | 0 | StructuredData::DictionarySP ScriptedProcessPythonInterface::GetCapabilities() { |
62 | 0 | Status error; |
63 | 0 | StructuredData::DictionarySP dict = |
64 | 0 | Dispatch<StructuredData::DictionarySP>("get_capabilities", error); |
65 | |
|
66 | 0 | if (!CheckStructuredDataObject(LLVM_PRETTY_FUNCTION, dict, error)) |
67 | 0 | return {}; |
68 | | |
69 | 0 | return dict; |
70 | 0 | } |
71 | | |
72 | | Status |
73 | 1 | ScriptedProcessPythonInterface::Attach(const ProcessAttachInfo &attach_info) { |
74 | 1 | lldb::ProcessAttachInfoSP attach_info_sp = |
75 | 1 | std::make_shared<ProcessAttachInfo>(attach_info); |
76 | 1 | return GetStatusFromMethod("attach", attach_info_sp); |
77 | 1 | } |
78 | | |
79 | 2 | Status ScriptedProcessPythonInterface::Launch() { |
80 | 2 | return GetStatusFromMethod("launch"); |
81 | 2 | } |
82 | | |
83 | 2 | Status ScriptedProcessPythonInterface::Resume() { |
84 | | // When calling ScriptedProcess.Resume from lldb we should always stop. |
85 | 2 | return GetStatusFromMethod("resume", /*should_stop=*/true); |
86 | 2 | } |
87 | | |
88 | | std::optional<MemoryRegionInfo> |
89 | | ScriptedProcessPythonInterface::GetMemoryRegionContainingAddress( |
90 | 1 | lldb::addr_t address, Status &error) { |
91 | 1 | auto mem_region = Dispatch<std::optional<MemoryRegionInfo>>( |
92 | 1 | "get_memory_region_containing_address", error, address); |
93 | | |
94 | 1 | if (error.Fail()) { |
95 | 1 | return ErrorWithMessage<MemoryRegionInfo>(LLVM_PRETTY_FUNCTION, |
96 | 1 | error.AsCString(), error); |
97 | 1 | } |
98 | | |
99 | 0 | return mem_region; |
100 | 1 | } |
101 | | |
102 | 15 | StructuredData::DictionarySP ScriptedProcessPythonInterface::GetThreadsInfo() { |
103 | 15 | Status error; |
104 | 15 | StructuredData::DictionarySP dict = |
105 | 15 | Dispatch<StructuredData::DictionarySP>("get_threads_info", error); |
106 | | |
107 | 15 | if (!CheckStructuredDataObject(LLVM_PRETTY_FUNCTION, dict, error)) |
108 | 0 | return {}; |
109 | | |
110 | 15 | return dict; |
111 | 15 | } |
112 | | |
113 | | bool ScriptedProcessPythonInterface::CreateBreakpoint(lldb::addr_t addr, |
114 | 0 | Status &error) { |
115 | 0 | Status py_error; |
116 | 0 | StructuredData::ObjectSP obj = |
117 | 0 | Dispatch("create_breakpoint", py_error, addr, error); |
118 | | |
119 | | // If there was an error on the python call, surface it to the user. |
120 | 0 | if (py_error.Fail()) |
121 | 0 | error = py_error; |
122 | |
|
123 | 0 | if (!CheckStructuredDataObject(LLVM_PRETTY_FUNCTION, obj, error)) |
124 | 0 | return {}; |
125 | | |
126 | 0 | return obj->GetBooleanValue(); |
127 | 0 | } |
128 | | |
129 | | lldb::DataExtractorSP ScriptedProcessPythonInterface::ReadMemoryAtAddress( |
130 | 9 | lldb::addr_t address, size_t size, Status &error) { |
131 | 9 | Status py_error; |
132 | 9 | lldb::DataExtractorSP data_sp = Dispatch<lldb::DataExtractorSP>( |
133 | 9 | "read_memory_at_address", py_error, address, size, error); |
134 | | |
135 | | // If there was an error on the python call, surface it to the user. |
136 | 9 | if (py_error.Fail()) |
137 | 5 | error = py_error; |
138 | | |
139 | 9 | return data_sp; |
140 | 9 | } |
141 | | |
142 | | lldb::offset_t ScriptedProcessPythonInterface::WriteMemoryAtAddress( |
143 | 1 | lldb::addr_t addr, lldb::DataExtractorSP data_sp, Status &error) { |
144 | 1 | Status py_error; |
145 | 1 | StructuredData::ObjectSP obj = |
146 | 1 | Dispatch("write_memory_at_address", py_error, addr, data_sp, error); |
147 | | |
148 | 1 | if (!CheckStructuredDataObject(LLVM_PRETTY_FUNCTION, obj, error)) |
149 | 0 | return LLDB_INVALID_OFFSET; |
150 | | |
151 | | // If there was an error on the python call, surface it to the user. |
152 | 1 | if (py_error.Fail()) |
153 | 0 | error = py_error; |
154 | | |
155 | 1 | return obj->GetUnsignedIntegerValue(LLDB_INVALID_OFFSET); |
156 | 1 | } |
157 | | |
158 | 2 | StructuredData::ArraySP ScriptedProcessPythonInterface::GetLoadedImages() { |
159 | 2 | Status error; |
160 | 2 | StructuredData::ArraySP array = |
161 | 2 | Dispatch<StructuredData::ArraySP>("get_loaded_images", error); |
162 | | |
163 | 2 | if (!CheckStructuredDataObject(LLVM_PRETTY_FUNCTION, array, error)) |
164 | 0 | return {}; |
165 | | |
166 | 2 | return array; |
167 | 2 | } |
168 | | |
169 | 5 | lldb::pid_t ScriptedProcessPythonInterface::GetProcessID() { |
170 | 5 | Status error; |
171 | 5 | StructuredData::ObjectSP obj = Dispatch("get_process_id", error); |
172 | | |
173 | 5 | if (!CheckStructuredDataObject(LLVM_PRETTY_FUNCTION, obj, error)) |
174 | 0 | return LLDB_INVALID_PROCESS_ID; |
175 | | |
176 | 5 | return obj->GetUnsignedIntegerValue(LLDB_INVALID_PROCESS_ID); |
177 | 5 | } |
178 | | |
179 | 204 | bool ScriptedProcessPythonInterface::IsAlive() { |
180 | 204 | Status error; |
181 | 204 | StructuredData::ObjectSP obj = Dispatch("is_alive", error); |
182 | | |
183 | 204 | if (!CheckStructuredDataObject(LLVM_PRETTY_FUNCTION, obj, error)) |
184 | 195 | return {}; |
185 | | |
186 | 9 | return obj->GetBooleanValue(); |
187 | 204 | } |
188 | | |
189 | | std::optional<std::string> |
190 | 0 | ScriptedProcessPythonInterface::GetScriptedThreadPluginName() { |
191 | 0 | Status error; |
192 | 0 | StructuredData::ObjectSP obj = Dispatch("get_scripted_thread_plugin", error); |
193 | |
|
194 | 0 | if (!CheckStructuredDataObject(LLVM_PRETTY_FUNCTION, obj, error)) |
195 | 0 | return {}; |
196 | | |
197 | 0 | return obj->GetStringValue().str(); |
198 | 0 | } |
199 | | |
200 | | lldb::ScriptedThreadInterfaceSP |
201 | 15 | ScriptedProcessPythonInterface::CreateScriptedThreadInterface() { |
202 | 15 | return std::make_shared<ScriptedThreadPythonInterface>(m_interpreter); |
203 | 15 | } |
204 | | |
205 | 0 | StructuredData::DictionarySP ScriptedProcessPythonInterface::GetMetadata() { |
206 | 0 | Status error; |
207 | 0 | StructuredData::DictionarySP dict = |
208 | 0 | Dispatch<StructuredData::DictionarySP>("get_process_metadata", error); |
209 | |
|
210 | 0 | if (!CheckStructuredDataObject(LLVM_PRETTY_FUNCTION, dict, error)) |
211 | 0 | return {}; |
212 | | |
213 | 0 | return dict; |
214 | 0 | } |
215 | | |
216 | | #endif |