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