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 #include "lldb/Utility/Log.h" 11 #include "lldb/Utility/Status.h" 12 #include "lldb/lldb-enumerations.h" 13 14 #if LLDB_ENABLE_PYTHON 15 16 // LLDB Python header must be included first 17 #include "lldb-python.h" 18 19 #include "SWIGPythonBridge.h" 20 #include "ScriptInterpreterPythonImpl.h" 21 #include "ScriptedProcessPythonInterface.h" 22 #include "ScriptedThreadPythonInterface.h" 23 #include <optional> 24 25 using namespace lldb; 26 using namespace lldb_private; 27 using namespace lldb_private::python; 28 using Locker = ScriptInterpreterPythonImpl::Locker; 29 30 ScriptedProcessPythonInterface::ScriptedProcessPythonInterface( 31 ScriptInterpreterPythonImpl &interpreter) 32 : ScriptedProcessInterface(), ScriptedPythonInterface(interpreter) {} 33 34 StructuredData::GenericSP ScriptedProcessPythonInterface::CreatePluginObject( 35 llvm::StringRef class_name, ExecutionContext &exe_ctx, 36 StructuredData::DictionarySP args_sp, StructuredData::Generic *script_obj) { 37 if (class_name.empty()) 38 return {}; 39 40 StructuredDataImpl args_impl(args_sp); 41 std::string error_string; 42 43 Locker py_lock(&m_interpreter, Locker::AcquireLock | Locker::NoSTDIN, 44 Locker::FreeLock); 45 46 lldb::ExecutionContextRefSP exe_ctx_ref_sp = 47 std::make_shared<ExecutionContextRef>(exe_ctx); 48 49 PythonObject ret_val = LLDBSwigPythonCreateScriptedObject( 50 class_name.str().c_str(), m_interpreter.GetDictionaryName(), 51 exe_ctx_ref_sp, args_impl, error_string); 52 53 m_object_instance_sp = 54 StructuredData::GenericSP(new StructuredPythonObject(std::move(ret_val))); 55 56 return m_object_instance_sp; 57 } 58 59 Status ScriptedProcessPythonInterface::Launch() { 60 return GetStatusFromMethod("launch"); 61 } 62 63 Status ScriptedProcessPythonInterface::Resume() { 64 return GetStatusFromMethod("resume"); 65 } 66 67 bool ScriptedProcessPythonInterface::ShouldStop() { 68 Status error; 69 StructuredData::ObjectSP obj = Dispatch("is_alive", error); 70 71 if (!CheckStructuredDataObject(LLVM_PRETTY_FUNCTION, obj, error)) 72 return {}; 73 74 return obj->GetBooleanValue(); 75 } 76 77 Status ScriptedProcessPythonInterface::Stop() { 78 return GetStatusFromMethod("stop"); 79 } 80 81 std::optional<MemoryRegionInfo> 82 ScriptedProcessPythonInterface::GetMemoryRegionContainingAddress( 83 lldb::addr_t address, Status &error) { 84 auto mem_region = Dispatch<std::optional<MemoryRegionInfo>>( 85 "get_memory_region_containing_address", error, address); 86 87 if (error.Fail()) { 88 return ErrorWithMessage<MemoryRegionInfo>(LLVM_PRETTY_FUNCTION, 89 error.AsCString(), error); 90 } 91 92 return mem_region; 93 } 94 95 StructuredData::DictionarySP ScriptedProcessPythonInterface::GetThreadsInfo() { 96 Status error; 97 StructuredData::DictionarySP dict = 98 Dispatch<StructuredData::DictionarySP>("get_threads_info", error); 99 100 if (!CheckStructuredDataObject(LLVM_PRETTY_FUNCTION, dict, error)) 101 return {}; 102 103 return dict; 104 } 105 106 StructuredData::DictionarySP 107 ScriptedProcessPythonInterface::GetThreadWithID(lldb::tid_t tid) { 108 Status error; 109 StructuredData::ObjectSP obj = Dispatch("get_thread_with_id", error, tid); 110 111 if (!CheckStructuredDataObject(LLVM_PRETTY_FUNCTION, obj, error)) 112 return {}; 113 114 StructuredData::DictionarySP dict{obj->GetAsDictionary()}; 115 116 return dict; 117 } 118 119 StructuredData::DictionarySP 120 ScriptedProcessPythonInterface::GetRegistersForThread(lldb::tid_t tid) { 121 // TODO: Implement 122 return {}; 123 } 124 125 lldb::DataExtractorSP ScriptedProcessPythonInterface::ReadMemoryAtAddress( 126 lldb::addr_t address, size_t size, Status &error) { 127 Status py_error; 128 lldb::DataExtractorSP data_sp = Dispatch<lldb::DataExtractorSP>( 129 "read_memory_at_address", py_error, address, size, error); 130 131 // If there was an error on the python call, surface it to the user. 132 if (py_error.Fail()) 133 error = py_error; 134 135 return data_sp; 136 } 137 138 StructuredData::ArraySP ScriptedProcessPythonInterface::GetLoadedImages() { 139 Status error; 140 StructuredData::ArraySP array = 141 Dispatch<StructuredData::ArraySP>("get_loaded_images", error); 142 143 if (!array || !array->IsValid() || error.Fail()) { 144 return ScriptedInterface::ErrorWithMessage<StructuredData::ArraySP>( 145 LLVM_PRETTY_FUNCTION, 146 llvm::Twine("Null or invalid object (" + 147 llvm::Twine(error.AsCString()) + llvm::Twine(").")) 148 .str(), 149 error); 150 } 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->GetIntegerValue(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 std::make_shared<ScriptedThreadPythonInterface>(m_interpreter); 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