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/Logging.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 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) { 35 if (class_name.empty()) 36 return {}; 37 38 TargetSP target_sp = exe_ctx.GetTargetSP(); 39 StructuredDataImpl *args_impl = nullptr; 40 if (args_sp) { 41 args_impl = new StructuredDataImpl(); 42 args_impl->SetObjectSP(args_sp); 43 } 44 std::string error_string; 45 46 Locker py_lock(&m_interpreter, Locker::AcquireLock | Locker::NoSTDIN, 47 Locker::FreeLock); 48 49 void *ret_val = LLDBSwigPythonCreateScriptedProcess( 50 class_name.str().c_str(), m_interpreter.GetDictionaryName(), target_sp, 51 args_impl, error_string); 52 53 if (!ret_val) 54 return {}; 55 56 m_object_instance_sp = 57 StructuredData::GenericSP(new StructuredPythonObject(ret_val)); 58 59 return m_object_instance_sp; 60 } 61 62 Status ScriptedProcessPythonInterface::Launch() { 63 return GetStatusFromMethod("launch"); 64 } 65 66 Status ScriptedProcessPythonInterface::Resume() { 67 return GetStatusFromMethod("resume"); 68 } 69 70 bool ScriptedProcessPythonInterface::ShouldStop() { 71 Status error; 72 StructuredData::ObjectSP obj = Dispatch("is_alive", error); 73 74 auto error_with_message = [](llvm::StringRef message) { 75 LLDB_LOGF(GetLogIfAllCategoriesSet(LIBLLDB_LOG_PROCESS), 76 "ScriptedProcess::%s ERROR = %s", __FUNCTION__, message.data()); 77 return false; 78 }; 79 80 if (!obj || !obj->IsValid() || error.Fail()) { 81 return error_with_message(llvm::Twine("Null or invalid object (" + 82 llvm::Twine(error.AsCString()) + 83 llvm::Twine(").")) 84 .str()); 85 } 86 87 return obj->GetBooleanValue(); 88 } 89 90 Status ScriptedProcessPythonInterface::Stop() { 91 return GetStatusFromMethod("stop"); 92 } 93 94 lldb::MemoryRegionInfoSP 95 ScriptedProcessPythonInterface::GetMemoryRegionContainingAddress( 96 lldb::addr_t address) { 97 // TODO: Implement 98 return {}; 99 } 100 101 StructuredData::DictionarySP 102 ScriptedProcessPythonInterface::GetThreadWithID(lldb::tid_t tid) { 103 Locker py_lock(&m_interpreter, Locker::AcquireLock | Locker::NoSTDIN, 104 Locker::FreeLock); 105 106 auto error_with_message = [](llvm::StringRef message) { 107 LLDB_LOGF(GetLogIfAllCategoriesSet(LIBLLDB_LOG_PROCESS), 108 "ScriptedProcess::%s ERROR = %s", __FUNCTION__, message.data()); 109 return StructuredData::DictionarySP(); 110 }; 111 112 Status error; 113 StructuredData::ObjectSP obj = Dispatch("get_thread_with_id", error, tid); 114 115 if (!obj || !obj->IsValid() || error.Fail()) { 116 return error_with_message(llvm::Twine("Null or invalid object (" + 117 llvm::Twine(error.AsCString()) + 118 llvm::Twine(").")) 119 .str()); 120 } 121 122 StructuredData::DictionarySP dict{obj->GetAsDictionary()}; 123 124 return dict; 125 } 126 127 StructuredData::DictionarySP 128 ScriptedProcessPythonInterface::GetRegistersForThread(lldb::tid_t tid) { 129 // TODO: Implement 130 return {}; 131 } 132 133 lldb::DataExtractorSP ScriptedProcessPythonInterface::ReadMemoryAtAddress( 134 lldb::addr_t address, size_t size, Status &error) { 135 return Dispatch<lldb::DataExtractorSP>("read_memory_at_address", error, 136 address, size); 137 } 138 139 StructuredData::DictionarySP ScriptedProcessPythonInterface::GetLoadedImages() { 140 // TODO: Implement 141 return {}; 142 } 143 144 lldb::pid_t ScriptedProcessPythonInterface::GetProcessID() { 145 Status error; 146 StructuredData::ObjectSP obj = Dispatch("get_process_id", error); 147 148 auto error_with_message = [](llvm::StringRef message) { 149 LLDB_LOGF(GetLogIfAllCategoriesSet(LIBLLDB_LOG_PROCESS), 150 "ScriptedProcess::%s ERROR = %s", __FUNCTION__, message.data()); 151 return LLDB_INVALID_PROCESS_ID; 152 }; 153 154 if (!obj || !obj->IsValid() || error.Fail()) { 155 return error_with_message(llvm::Twine("Null or invalid object (" + 156 llvm::Twine(error.AsCString()) + 157 llvm::Twine(").")) 158 .str()); 159 } 160 161 return obj->GetIntegerValue(LLDB_INVALID_PROCESS_ID); 162 } 163 164 bool ScriptedProcessPythonInterface::IsAlive() { 165 Status error; 166 StructuredData::ObjectSP obj = Dispatch("is_alive", error); 167 168 auto error_with_message = [](llvm::StringRef message) { 169 LLDB_LOGF(GetLogIfAllCategoriesSet(LIBLLDB_LOG_PROCESS), 170 "ScriptedProcess::%s ERROR = %s", __FUNCTION__, message.data()); 171 return false; 172 }; 173 174 if (!obj || !obj->IsValid() || error.Fail()) { 175 return error_with_message(llvm::Twine("Null or invalid object (" + 176 llvm::Twine(error.AsCString()) + 177 llvm::Twine(").")) 178 .str()); 179 } 180 181 return obj->GetBooleanValue(); 182 } 183 184 #endif 185