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