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 (!CheckStructuredDataObject(LLVM_PRETTY_FUNCTION, dict, error)) 53 return {}; 54 55 return dict; 56 } 57 58 Status 59 ScriptedProcessPythonInterface::Attach(const ProcessAttachInfo &attach_info) { 60 lldb::ProcessAttachInfoSP attach_info_sp = 61 std::make_shared<ProcessAttachInfo>(attach_info); 62 return GetStatusFromMethod("attach", attach_info_sp); 63 } 64 65 Status ScriptedProcessPythonInterface::Launch() { 66 return GetStatusFromMethod("launch"); 67 } 68 69 Status ScriptedProcessPythonInterface::Resume() { 70 // When calling ScriptedProcess.Resume from lldb we should always stop. 71 return GetStatusFromMethod("resume", /*should_stop=*/true); 72 } 73 74 std::optional<MemoryRegionInfo> 75 ScriptedProcessPythonInterface::GetMemoryRegionContainingAddress( 76 lldb::addr_t address, Status &error) { 77 auto mem_region = Dispatch<std::optional<MemoryRegionInfo>>( 78 "get_memory_region_containing_address", error, address); 79 80 if (error.Fail()) { 81 return ErrorWithMessage<MemoryRegionInfo>(LLVM_PRETTY_FUNCTION, 82 error.AsCString(), error); 83 } 84 85 return mem_region; 86 } 87 88 StructuredData::DictionarySP ScriptedProcessPythonInterface::GetThreadsInfo() { 89 Status error; 90 StructuredData::DictionarySP dict = 91 Dispatch<StructuredData::DictionarySP>("get_threads_info", error); 92 93 if (!CheckStructuredDataObject(LLVM_PRETTY_FUNCTION, dict, error)) 94 return {}; 95 96 return dict; 97 } 98 99 bool ScriptedProcessPythonInterface::CreateBreakpoint(lldb::addr_t addr, 100 Status &error) { 101 Status py_error; 102 StructuredData::ObjectSP obj = 103 Dispatch("create_breakpoint", py_error, addr, 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 115 lldb::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 "read_memory_at_address", py_error, address, size, 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 128 lldb::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("write_memory_at_address", py_error, addr, data_sp, 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 144 StructuredData::ArraySP ScriptedProcessPythonInterface::GetLoadedImages() { 145 Status error; 146 StructuredData::ArraySP array = 147 Dispatch<StructuredData::ArraySP>("get_loaded_images", error); 148 149 if (!CheckStructuredDataObject(LLVM_PRETTY_FUNCTION, array, error)) 150 return {}; 151 152 return array; 153 } 154 155 lldb::pid_t ScriptedProcessPythonInterface::GetProcessID() { 156 Status error; 157 StructuredData::ObjectSP obj = Dispatch("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 165 bool ScriptedProcessPythonInterface::IsAlive() { 166 Status error; 167 StructuredData::ObjectSP obj = Dispatch("is_alive", error); 168 169 if (!CheckStructuredDataObject(LLVM_PRETTY_FUNCTION, obj, error)) 170 return {}; 171 172 return obj->GetBooleanValue(); 173 } 174 175 std::optional<std::string> 176 ScriptedProcessPythonInterface::GetScriptedThreadPluginName() { 177 Status error; 178 StructuredData::ObjectSP obj = Dispatch("get_scripted_thread_plugin", error); 179 180 if (!CheckStructuredDataObject(LLVM_PRETTY_FUNCTION, obj, error)) 181 return {}; 182 183 return obj->GetStringValue().str(); 184 } 185 186 lldb::ScriptedThreadInterfaceSP 187 ScriptedProcessPythonInterface::CreateScriptedThreadInterface() { 188 return m_interpreter.CreateScriptedThreadInterface(); 189 } 190 191 StructuredData::DictionarySP ScriptedProcessPythonInterface::GetMetadata() { 192 Status error; 193 StructuredData::DictionarySP dict = 194 Dispatch<StructuredData::DictionarySP>("get_process_metadata", error); 195 196 if (!CheckStructuredDataObject(LLVM_PRETTY_FUNCTION, dict, error)) 197 return {}; 198 199 return dict; 200 } 201 202 #endif 203