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