diff options
author | Med Ismail Bennani <medismail.bennani@gmail.com> | 2021-10-06 00:09:20 +0000 |
---|---|---|
committer | Med Ismail Bennani <medismail.bennani@gmail.com> | 2021-10-08 14:54:07 +0200 |
commit | 59d8dd79e1f9dead2dc2756e139073083e487228 (patch) | |
tree | 4f45c1452f97e10655c8e69549ab146ee93d0d2c /lldb/source/Plugins/ScriptInterpreter/Python/ScriptedThreadPythonInterface.cpp | |
parent | 6393c21d476de2584b3ac010aace6a9b26d5bbec (diff) | |
download | llvm-59d8dd79e1f9dead2dc2756e139073083e487228.zip llvm-59d8dd79e1f9dead2dc2756e139073083e487228.tar.gz llvm-59d8dd79e1f9dead2dc2756e139073083e487228.tar.bz2 |
[lldb/Plugins] Add support for ScriptedThread in ScriptedProcess
This patch introduces the `ScriptedThread` class with its python
interface.
When used with `ScriptedProcess`, `ScriptedThreaad` can provide various
information such as the thread state, stop reason or even its register
context.
This can be used to reconstruct the program stack frames using lldb's unwinder.
rdar://74503836
Differential Revision: https://reviews.llvm.org/D107585
Signed-off-by: Med Ismail Bennani <medismail.bennani@gmail.com>
Diffstat (limited to 'lldb/source/Plugins/ScriptInterpreter/Python/ScriptedThreadPythonInterface.cpp')
-rw-r--r-- | lldb/source/Plugins/ScriptInterpreter/Python/ScriptedThreadPythonInterface.cpp | 136 |
1 files changed, 136 insertions, 0 deletions
diff --git a/lldb/source/Plugins/ScriptInterpreter/Python/ScriptedThreadPythonInterface.cpp b/lldb/source/Plugins/ScriptInterpreter/Python/ScriptedThreadPythonInterface.cpp new file mode 100644 index 0000000..c2aa438 --- /dev/null +++ b/lldb/source/Plugins/ScriptInterpreter/Python/ScriptedThreadPythonInterface.cpp @@ -0,0 +1,136 @@ +//===-- ScriptedThreadPythonInterface.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 "ScriptedThreadPythonInterface.h" + +using namespace lldb; +using namespace lldb_private; +using namespace lldb_private::python; +using Locker = ScriptInterpreterPythonImpl::Locker; + +ScriptedThreadPythonInterface::ScriptedThreadPythonInterface( + ScriptInterpreterPythonImpl &interpreter) + : ScriptedThreadInterface(), ScriptedPythonInterface(interpreter) {} + +StructuredData::GenericSP ScriptedThreadPythonInterface::CreatePluginObject( + const llvm::StringRef class_name, ExecutionContext &exe_ctx, + StructuredData::DictionarySP args_sp) { + + if (class_name.empty()) + return {}; + + Locker py_lock(&m_interpreter, Locker::AcquireLock | Locker::NoSTDIN, + Locker::FreeLock); + + std::string error_string; + + TargetSP target_sp = exe_ctx.GetTargetSP(); + + void *ret_val = LLDBSwigPythonCreateScriptedThread( + class_name.str().c_str(), m_interpreter.GetDictionaryName(), target_sp, + error_string); + + if (!ret_val) + return {}; + + m_object_instance_sp = + StructuredData::GenericSP(new StructuredPythonObject(ret_val)); + + return m_object_instance_sp; +} + +lldb::tid_t ScriptedThreadPythonInterface::GetThreadID() { + Status error; + StructuredData::ObjectSP obj = Dispatch("get_thread_id", error); + + if (!CheckStructuredDataObject(__PRETTY_FUNCTION__, obj, error)) + return LLDB_INVALID_THREAD_ID; + + return obj->GetIntegerValue(LLDB_INVALID_THREAD_ID); +} + +llvm::Optional<std::string> ScriptedThreadPythonInterface::GetName() { + Status error; + StructuredData::ObjectSP obj = Dispatch("get_name", error); + + if (!CheckStructuredDataObject(__PRETTY_FUNCTION__, obj, error)) + return {}; + + return obj->GetStringValue().str(); +} + +lldb::StateType ScriptedThreadPythonInterface::GetState() { + Status error; + StructuredData::ObjectSP obj = Dispatch("get_state", error); + + if (!CheckStructuredDataObject(__PRETTY_FUNCTION__, obj, error)) + return eStateInvalid; + + return static_cast<StateType>(obj->GetIntegerValue(eStateInvalid)); +} + +llvm::Optional<std::string> ScriptedThreadPythonInterface::GetQueue() { + Status error; + StructuredData::ObjectSP obj = Dispatch("get_queue", error); + + if (!CheckStructuredDataObject(__PRETTY_FUNCTION__, obj, error)) + return {}; + + return obj->GetStringValue().str(); +} + +StructuredData::DictionarySP ScriptedThreadPythonInterface::GetStopReason() { + Status error; + StructuredData::DictionarySP dict = + Dispatch<StructuredData::DictionarySP>("get_stop_reason", error); + + if (!CheckStructuredDataObject(__PRETTY_FUNCTION__, dict, error)) + return {}; + + return dict; +} + +StructuredData::ArraySP ScriptedThreadPythonInterface::GetStackFrames() { + return nullptr; +} + +StructuredData::DictionarySP ScriptedThreadPythonInterface::GetRegisterInfo() { + Status error; + StructuredData::DictionarySP dict = + Dispatch<StructuredData::DictionarySP>("get_register_info", error); + + if (!CheckStructuredDataObject(__PRETTY_FUNCTION__, dict, error)) + return {}; + + return dict; +} + +llvm::Optional<std::string> +ScriptedThreadPythonInterface::GetRegisterContext() { + Status error; + StructuredData::ObjectSP obj = Dispatch("get_register_context", error); + + if (!CheckStructuredDataObject(__PRETTY_FUNCTION__, obj, error)) + return {}; + + return obj->GetAsString()->GetValue().str(); +} + +#endif |