//===-- ScriptedProcessPythonInterface.cpp --------------------------------===// // // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. // See https://llvm.org/LICENSE.txt for license information. // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception // //===----------------------------------------------------------------------===// #include "lldb/Host/Config.h" #include "lldb/Utility/Log.h" #include "lldb/Utility/Logging.h" #include "lldb/lldb-enumerations.h" #if LLDB_ENABLE_PYTHON // LLDB Python header must be included first #include "lldb-python.h" #include "SWIGPythonBridge.h" #include "ScriptInterpreterPythonImpl.h" #include "ScriptedProcessPythonInterface.h" using namespace lldb; using namespace lldb_private; using namespace lldb_private::python; using Locker = ScriptInterpreterPythonImpl::Locker; ScriptedProcessPythonInterface::ScriptedProcessPythonInterface( ScriptInterpreterPythonImpl &interpreter) : ScriptedProcessInterface(), ScriptedPythonInterface(interpreter) {} StructuredData::GenericSP ScriptedProcessPythonInterface::CreatePluginObject( llvm::StringRef class_name, ExecutionContext &exe_ctx, StructuredData::DictionarySP args_sp) { if (class_name.empty()) return {}; TargetSP target_sp = exe_ctx.GetTargetSP(); StructuredDataImpl *args_impl = nullptr; if (args_sp) { args_impl = new StructuredDataImpl(); args_impl->SetObjectSP(args_sp); } std::string error_string; Locker py_lock(&m_interpreter, Locker::AcquireLock | Locker::NoSTDIN, Locker::FreeLock); void *ret_val = LLDBSwigPythonCreateScriptedProcess( class_name.str().c_str(), m_interpreter.GetDictionaryName(), target_sp, args_impl, error_string); if (!ret_val) return {}; m_object_instance_sp = StructuredData::GenericSP(new StructuredPythonObject(ret_val)); return m_object_instance_sp; } Status ScriptedProcessPythonInterface::Launch() { return GetStatusFromMethod("launch"); } Status ScriptedProcessPythonInterface::Resume() { return GetStatusFromMethod("resume"); } bool ScriptedProcessPythonInterface::ShouldStop() { Status error; StructuredData::ObjectSP obj = Dispatch("is_alive", error); auto error_with_message = [](llvm::StringRef message) { LLDB_LOGF(GetLogIfAllCategoriesSet(LIBLLDB_LOG_PROCESS), "ScriptedProcess::%s ERROR = %s", __FUNCTION__, message.data()); return false; }; if (!obj || !obj->IsValid() || error.Fail()) { return error_with_message(llvm::Twine("Null or invalid object (" + llvm::Twine(error.AsCString()) + llvm::Twine(").")) .str()); } return obj->GetBooleanValue(); } Status ScriptedProcessPythonInterface::Stop() { return GetStatusFromMethod("stop"); } lldb::MemoryRegionInfoSP ScriptedProcessPythonInterface::GetMemoryRegionContainingAddress( lldb::addr_t address) { // TODO: Implement return {}; } StructuredData::DictionarySP ScriptedProcessPythonInterface::GetThreadWithID(lldb::tid_t tid) { Locker py_lock(&m_interpreter, Locker::AcquireLock | Locker::NoSTDIN, Locker::FreeLock); auto error_with_message = [](llvm::StringRef message) { LLDB_LOGF(GetLogIfAllCategoriesSet(LIBLLDB_LOG_PROCESS), "ScriptedProcess::%s ERROR = %s", __FUNCTION__, message.data()); return StructuredData::DictionarySP(); }; Status error; StructuredData::ObjectSP obj = Dispatch("get_thread_with_id", error, tid); if (!obj || !obj->IsValid() || error.Fail()) { return error_with_message(llvm::Twine("Null or invalid object (" + llvm::Twine(error.AsCString()) + llvm::Twine(").")) .str()); } StructuredData::DictionarySP dict{obj->GetAsDictionary()}; return dict; } StructuredData::DictionarySP ScriptedProcessPythonInterface::GetRegistersForThread(lldb::tid_t tid) { // TODO: Implement return {}; } lldb::DataExtractorSP ScriptedProcessPythonInterface::ReadMemoryAtAddress( lldb::addr_t address, size_t size, Status &error) { return Dispatch("read_memory_at_address", error, address, size); } StructuredData::DictionarySP ScriptedProcessPythonInterface::GetLoadedImages() { // TODO: Implement return {}; } lldb::pid_t ScriptedProcessPythonInterface::GetProcessID() { Status error; StructuredData::ObjectSP obj = Dispatch("get_process_id", error); auto error_with_message = [](llvm::StringRef message) { LLDB_LOGF(GetLogIfAllCategoriesSet(LIBLLDB_LOG_PROCESS), "ScriptedProcess::%s ERROR = %s", __FUNCTION__, message.data()); return LLDB_INVALID_PROCESS_ID; }; if (!obj || !obj->IsValid() || error.Fail()) { return error_with_message(llvm::Twine("Null or invalid object (" + llvm::Twine(error.AsCString()) + llvm::Twine(").")) .str()); } return obj->GetIntegerValue(LLDB_INVALID_PROCESS_ID); } bool ScriptedProcessPythonInterface::IsAlive() { Status error; StructuredData::ObjectSP obj = Dispatch("is_alive", error); auto error_with_message = [](llvm::StringRef message) { LLDB_LOGF(GetLogIfAllCategoriesSet(LIBLLDB_LOG_PROCESS), "ScriptedProcess::%s ERROR = %s", __FUNCTION__, message.data()); return false; }; if (!obj || !obj->IsValid() || error.Fail()) { return error_with_message(llvm::Twine("Null or invalid object (" + llvm::Twine(error.AsCString()) + llvm::Twine(").")) .str()); } return obj->GetBooleanValue(); } #endif