diff options
| author | Michael Buch <michaelbuch12@gmail.com> | 2025-11-12 10:13:43 +0000 |
|---|---|---|
| committer | GitHub <noreply@github.com> | 2025-11-12 10:13:43 +0000 |
| commit | b7bc4a2103a77328f50f7e0b08ca073e34673755 (patch) | |
| tree | c33b48b04c50902c8d69cff1cbe31cd91ce6fce6 /lldb/source/Plugins/ScriptInterpreter/Python/Interfaces | |
| parent | 5e4f17714259361ca3b355085ff61288aad6f30f (diff) | |
| download | llvm-b7bc4a2103a77328f50f7e0b08ca073e34673755.tar.gz llvm-b7bc4a2103a77328f50f7e0b08ca073e34673755.tar.bz2 llvm-b7bc4a2103a77328f50f7e0b08ca073e34673755.zip | |
Revert "[lldb] Introduce ScriptedFrameProvider for real threads" (#167662)
The new test fails on x86 and arm64 public macOS bots:
```
09:27:59 ======================================================================
09:27:59 FAIL: test_append_frames (TestScriptedFrameProvider.ScriptedFrameProviderTestCase)
09:27:59 Test that we can add frames after real stack.
09:27:59 ----------------------------------------------------------------------
09:27:59 Traceback (most recent call last):
09:27:59 File "/Users/ec2-user/jenkins/workspace/llvm.org/as-lldb-cmake/llvm-project/lldb/test/API/functionalities/scripted_frame_provider/TestScriptedFrameProvider.py", line 122, in test_append_frames
09:27:59 self.assertEqual(new_frame_count, original_frame_count + 1)
09:27:59 AssertionError: 5 != 6
09:27:59 Config=arm64-/Users/ec2-user/jenkins/workspace/llvm.org/as-lldb-cmake/lldb-build/bin/clang
09:27:59 ======================================================================
09:27:59 FAIL: test_applies_to_thread (TestScriptedFrameProvider.ScriptedFrameProviderTestCase)
09:27:59 Test that applies_to_thread filters which threads get the provider.
09:27:59 ----------------------------------------------------------------------
09:27:59 Traceback (most recent call last):
09:27:59 File "/Users/ec2-user/jenkins/workspace/llvm.org/as-lldb-cmake/llvm-project/lldb/test/API/functionalities/scripted_frame_provider/TestScriptedFrameProvider.py", line 218, in test_applies_to_thread
09:27:59 self.assertEqual(
09:27:59 AssertionError: 5 != 1 : Thread with ID 1 should have 1 synthetic frame
09:27:59 Config=arm64-/Users/ec2-user/jenkins/workspace/llvm.org/as-lldb-cmake/lldb-build/bin/clang
09:27:59 ======================================================================
09:27:59 FAIL: test_prepend_frames (TestScriptedFrameProvider.ScriptedFrameProviderTestCase)
09:27:59 Test that we can add frames before real stack.
09:27:59 ----------------------------------------------------------------------
09:27:59 Traceback (most recent call last):
09:27:59 File "/Users/ec2-user/jenkins/workspace/llvm.org/as-lldb-cmake/llvm-project/lldb/test/API/functionalities/scripted_frame_provider/TestScriptedFrameProvider.py", line 84, in test_prepend_frames
09:27:59 self.assertEqual(new_frame_count, original_frame_count + 2)
09:27:59 AssertionError: 5 != 7
09:27:59 Config=arm64-/Users/ec2-user/jenkins/workspace/llvm.org/as-lldb-cmake/lldb-build/bin/clang
09:27:59 ======================================================================
09:27:59 FAIL: test_remove_frame_provider_by_id (TestScriptedFrameProvider.ScriptedFrameProviderTestCase)
09:27:59 Test that RemoveScriptedFrameProvider removes a specific provider by ID.
09:27:59 ----------------------------------------------------------------------
09:27:59 Traceback (most recent call last):
09:27:59 File "/Users/ec2-user/jenkins/workspace/llvm.org/as-lldb-cmake/llvm-project/lldb/test/API/functionalities/scripted_frame_provider/TestScriptedFrameProvider.py", line 272, in test_remove_frame_provider_by_id
09:27:59 self.assertEqual(thread.GetNumFrames(), 3, "Should have 3 synthetic frames")
09:27:59 AssertionError: 5 != 3 : Should have 3 synthetic frames
09:27:59 Config=arm64-/Users/ec2-user/jenkins/workspace/llvm.org/as-lldb-cmake/lldb-build/bin/clang
09:27:59 ======================================================================
09:27:59 FAIL: test_replace_all_frames (TestScriptedFrameProvider.ScriptedFrameProviderTestCase)
09:27:59 Test that we can replace the entire stack.
09:27:59 ----------------------------------------------------------------------
09:27:59 Traceback (most recent call last):
09:27:59 File "/Users/ec2-user/jenkins/workspace/llvm.org/as-lldb-cmake/llvm-project/lldb/test/API/functionalities/scripted_frame_provider/TestScriptedFrameProvider.py", line 41, in test_replace_all_frames
09:27:59 self.assertEqual(thread.GetNumFrames(), 3, "Should have 3 synthetic frames")
09:27:59 AssertionError: 5 != 3 : Should have 3 synthetic frames
09:27:59 Config=arm64-/Users/ec2-user/jenkins/workspace/llvm.org/as-lldb-cmake/lldb-build/bin/clang
09:27:59 ======================================================================
09:27:59 FAIL: test_scripted_frame_objects (TestScriptedFrameProvider.ScriptedFrameProviderTestCase)
09:27:59 Test that provider can return ScriptedFrame objects.
09:27:59 ----------------------------------------------------------------------
09:27:59 Traceback (most recent call last):
09:27:59 File "/Users/ec2-user/jenkins/workspace/llvm.org/as-lldb-cmake/llvm-project/lldb/test/API/functionalities/scripted_frame_provider/TestScriptedFrameProvider.py", line 159, in test_scripted_frame_objects
09:27:59 self.assertEqual(frame0.GetFunctionName(), "custom_scripted_frame_0")
09:27:59 AssertionError: 'thread_func(int)' != 'custom_scripted_frame_0'
09:27:59 - thread_func(int)
09:27:59 + custom_scripted_frame_0
09:27:59
09:27:59 Config=arm64-/Users/ec2-user/jenkins/workspace/llvm.org/as-lldb-cmake/lldb-build/bin/clang
09:27:59 ----------------------------------------------------------------------
09:27:59 Ran 6 tests in 14.242s
09:27:59
09:27:59 FAILED (failures=6)
```
Reverts llvm/llvm-project#161870
Diffstat (limited to 'lldb/source/Plugins/ScriptInterpreter/Python/Interfaces')
5 files changed, 8 insertions, 209 deletions
diff --git a/lldb/source/Plugins/ScriptInterpreter/Python/Interfaces/ScriptInterpreterPythonInterfaces.cpp b/lldb/source/Plugins/ScriptInterpreter/Python/Interfaces/ScriptInterpreterPythonInterfaces.cpp index f6c707b2bd16..d43036d6fe54 100644 --- a/lldb/source/Plugins/ScriptInterpreter/Python/Interfaces/ScriptInterpreterPythonInterfaces.cpp +++ b/lldb/source/Plugins/ScriptInterpreter/Python/Interfaces/ScriptInterpreterPythonInterfaces.cpp @@ -31,7 +31,6 @@ void ScriptInterpreterPythonInterfaces::Initialize() { ScriptedStopHookPythonInterface::Initialize(); ScriptedBreakpointPythonInterface::Initialize(); ScriptedThreadPlanPythonInterface::Initialize(); - ScriptedFrameProviderPythonInterface::Initialize(); } void ScriptInterpreterPythonInterfaces::Terminate() { @@ -41,7 +40,6 @@ void ScriptInterpreterPythonInterfaces::Terminate() { ScriptedStopHookPythonInterface::Terminate(); ScriptedBreakpointPythonInterface::Terminate(); ScriptedThreadPlanPythonInterface::Terminate(); - ScriptedFrameProviderPythonInterface::Terminate(); } #endif diff --git a/lldb/source/Plugins/ScriptInterpreter/Python/Interfaces/ScriptedFrameProviderPythonInterface.cpp b/lldb/source/Plugins/ScriptInterpreter/Python/Interfaces/ScriptedFrameProviderPythonInterface.cpp index 3dde5036453f..b866bf332b7b 100644 --- a/lldb/source/Plugins/ScriptInterpreter/Python/Interfaces/ScriptedFrameProviderPythonInterface.cpp +++ b/lldb/source/Plugins/ScriptInterpreter/Python/Interfaces/ScriptedFrameProviderPythonInterface.cpp @@ -6,7 +6,6 @@ // //===----------------------------------------------------------------------===// -#include "lldb/Core/PluginManager.h" #include "lldb/Host/Config.h" #include "lldb/Target/Thread.h" #include "lldb/Utility/Log.h" @@ -31,45 +30,18 @@ ScriptedFrameProviderPythonInterface::ScriptedFrameProviderPythonInterface( ScriptInterpreterPythonImpl &interpreter) : ScriptedFrameProviderInterface(), ScriptedPythonInterface(interpreter) {} -bool ScriptedFrameProviderPythonInterface::AppliesToThread( - llvm::StringRef class_name, lldb::ThreadSP thread_sp) { - // If there is any issue with this method, we will just assume it also applies - // to this thread which is the default behavior. - constexpr bool fail_value = true; - Status error; - StructuredData::ObjectSP obj = - CallStaticMethod(class_name, "applies_to_thread", error, thread_sp); - if (!ScriptedInterface::CheckStructuredDataObject(LLVM_PRETTY_FUNCTION, obj, - error)) - return fail_value; - - return obj->GetBooleanValue(fail_value); -} - llvm::Expected<StructuredData::GenericSP> ScriptedFrameProviderPythonInterface::CreatePluginObject( const llvm::StringRef class_name, lldb::StackFrameListSP input_frames, StructuredData::DictionarySP args_sp) { if (!input_frames) - return llvm::createStringError("invalid frame list"); + return llvm::createStringError("Invalid frame list"); StructuredDataImpl sd_impl(args_sp); return ScriptedPythonInterface::CreatePluginObject(class_name, nullptr, input_frames, sd_impl); } -std::string ScriptedFrameProviderPythonInterface::GetDescription( - llvm::StringRef class_name) { - Status error; - StructuredData::ObjectSP obj = - CallStaticMethod(class_name, "get_description", error); - if (!ScriptedInterface::CheckStructuredDataObject(LLVM_PRETTY_FUNCTION, obj, - error)) - return {}; - - return obj->GetStringValue().str(); -} - StructuredData::ObjectSP ScriptedFrameProviderPythonInterface::GetFrameAtIndex(uint32_t index) { Status error; @@ -82,32 +54,4 @@ ScriptedFrameProviderPythonInterface::GetFrameAtIndex(uint32_t index) { return obj; } -bool ScriptedFrameProviderPythonInterface::CreateInstance( - lldb::ScriptLanguage language, ScriptedInterfaceUsages usages) { - if (language != eScriptLanguagePython) - return false; - - return true; -} - -void ScriptedFrameProviderPythonInterface::Initialize() { - const std::vector<llvm::StringRef> ci_usages = { - "target frame-provider register -C <script-name> [-k key -v value ...]", - "target frame-provider list", - "target frame-provider remove <provider-name>", - "target frame-provider clear"}; - const std::vector<llvm::StringRef> api_usages = { - "SBTarget.RegisterScriptedFrameProvider", - "SBTarget.RemoveScriptedFrameProvider", - "SBTarget.ClearScriptedFrameProvider"}; - PluginManager::RegisterPlugin( - GetPluginNameStatic(), - llvm::StringRef("Provide scripted stack frames for threads"), - CreateInstance, eScriptLanguagePython, {ci_usages, api_usages}); -} - -void ScriptedFrameProviderPythonInterface::Terminate() { - PluginManager::UnregisterPlugin(CreateInstance); -} - #endif diff --git a/lldb/source/Plugins/ScriptInterpreter/Python/Interfaces/ScriptedFrameProviderPythonInterface.h b/lldb/source/Plugins/ScriptInterpreter/Python/Interfaces/ScriptedFrameProviderPythonInterface.h index 97a5cc7c669e..fd163984028d 100644 --- a/lldb/source/Plugins/ScriptInterpreter/Python/Interfaces/ScriptedFrameProviderPythonInterface.h +++ b/lldb/source/Plugins/ScriptInterpreter/Python/Interfaces/ScriptedFrameProviderPythonInterface.h @@ -14,22 +14,17 @@ #if LLDB_ENABLE_PYTHON #include "ScriptedPythonInterface.h" -#include "lldb/Core/PluginInterface.h" #include "lldb/Interpreter/Interfaces/ScriptedFrameProviderInterface.h" #include <optional> namespace lldb_private { class ScriptedFrameProviderPythonInterface : public ScriptedFrameProviderInterface, - public ScriptedPythonInterface, - public PluginInterface { + public ScriptedPythonInterface { public: ScriptedFrameProviderPythonInterface( ScriptInterpreterPythonImpl &interpreter); - bool AppliesToThread(llvm::StringRef class_name, - lldb::ThreadSP thread_sp) override; - llvm::Expected<StructuredData::GenericSP> CreatePluginObject(llvm::StringRef class_name, lldb::StackFrameListSP input_frames, @@ -38,24 +33,10 @@ public: llvm::SmallVector<AbstractMethodRequirement> GetAbstractMethodRequirements() const override { return llvm::SmallVector<AbstractMethodRequirement>( - {{"get_description"}, {"get_frame_at_index"}}); + {{"get_frame_at_index"}}); } - std::string GetDescription(llvm::StringRef class_name) override; - StructuredData::ObjectSP GetFrameAtIndex(uint32_t index) override; - - static void Initialize(); - static void Terminate(); - - static bool CreateInstance(lldb::ScriptLanguage language, - ScriptedInterfaceUsages usages); - - static llvm::StringRef GetPluginNameStatic() { - return "ScriptedFrameProviderPythonInterface"; - } - - llvm::StringRef GetPluginName() override { return GetPluginNameStatic(); } }; } // namespace lldb_private diff --git a/lldb/source/Plugins/ScriptInterpreter/Python/Interfaces/ScriptedPythonInterface.cpp b/lldb/source/Plugins/ScriptInterpreter/Python/Interfaces/ScriptedPythonInterface.cpp index ba4473cf9ec4..af2e0b5df4d2 100644 --- a/lldb/source/Plugins/ScriptInterpreter/Python/Interfaces/ScriptedPythonInterface.cpp +++ b/lldb/source/Plugins/ScriptInterpreter/Python/Interfaces/ScriptedPythonInterface.cpp @@ -94,19 +94,6 @@ ScriptedPythonInterface::ExtractValueFromPythonObject<lldb::StackFrameSP>( } template <> -lldb::ThreadSP -ScriptedPythonInterface::ExtractValueFromPythonObject<lldb::ThreadSP>( - python::PythonObject &p, Status &error) { - if (lldb::SBThread *sb_thread = reinterpret_cast<lldb::SBThread *>( - python::LLDBSWIGPython_CastPyObjectToSBThread(p.get()))) - return m_interpreter.GetOpaqueTypeFromSBThread(*sb_thread); - error = Status::FromErrorString( - "Couldn't cast lldb::SBThread to lldb_private::Thread."); - - return nullptr; -} - -template <> SymbolContext ScriptedPythonInterface::ExtractValueFromPythonObject<SymbolContext>( python::PythonObject &p, Status &error) { diff --git a/lldb/source/Plugins/ScriptInterpreter/Python/Interfaces/ScriptedPythonInterface.h b/lldb/source/Plugins/ScriptInterpreter/Python/Interfaces/ScriptedPythonInterface.h index c460f58b4e72..af88a69e34a1 100644 --- a/lldb/source/Plugins/ScriptInterpreter/Python/Interfaces/ScriptedPythonInterface.h +++ b/lldb/source/Plugins/ScriptInterpreter/Python/Interfaces/ScriptedPythonInterface.h @@ -330,112 +330,6 @@ public: return m_object_instance_sp; } - /// Call a static method on a Python class without creating an instance. - /// - /// This method resolves a Python class by name and calls a static method - /// on it, returning the result. This is useful for calling class-level - /// methods that don't require an instance. - /// - /// \param class_name The fully-qualified name of the Python class. - /// \param method_name The name of the static method to call. - /// \param error Output parameter to receive error information if the call - /// fails. - /// \param args Arguments to pass to the static method. - /// - /// \return The return value of the static method call, or an error value. - template <typename T = StructuredData::ObjectSP, typename... Args> - T CallStaticMethod(llvm::StringRef class_name, llvm::StringRef method_name, - Status &error, Args &&...args) { - using namespace python; - using Locker = ScriptInterpreterPythonImpl::Locker; - - std::string caller_signature = - llvm::Twine(LLVM_PRETTY_FUNCTION + llvm::Twine(" (") + - llvm::Twine(class_name) + llvm::Twine(".") + - llvm::Twine(method_name) + llvm::Twine(")")) - .str(); - - if (class_name.empty()) - return ErrorWithMessage<T>(caller_signature, "missing script class name", - error); - - Locker py_lock(&m_interpreter, Locker::AcquireLock | Locker::NoSTDIN, - Locker::FreeLock); - - // Get the interpreter dictionary. - auto dict = - PythonModule::MainModule().ResolveName<python::PythonDictionary>( - m_interpreter.GetDictionaryName()); - if (!dict.IsAllocated()) - return ErrorWithMessage<T>( - caller_signature, - llvm::formatv("could not find interpreter dictionary: {0}", - m_interpreter.GetDictionaryName()) - .str(), - error); - - // Resolve the class. - auto class_obj = - PythonObject::ResolveNameWithDictionary<python::PythonCallable>( - class_name, dict); - if (!class_obj.IsAllocated()) - return ErrorWithMessage<T>( - caller_signature, - llvm::formatv("could not find script class: {0}", class_name).str(), - error); - - // Get the static method from the class. - if (!class_obj.HasAttribute(method_name)) - return ErrorWithMessage<T>( - caller_signature, - llvm::formatv("class {0} does not have method {1}", class_name, - method_name) - .str(), - error); - - PythonCallable method = - class_obj.GetAttributeValue(method_name).AsType<PythonCallable>(); - if (!method.IsAllocated()) - return ErrorWithMessage<T>(caller_signature, - llvm::formatv("method {0}.{1} is not callable", - class_name, method_name) - .str(), - error); - - // Transform the arguments. - std::tuple<Args...> original_args = std::forward_as_tuple(args...); - auto transformed_args = TransformArgs(original_args); - - // Call the static method. - llvm::Expected<PythonObject> expected_return_object = - llvm::make_error<llvm::StringError>("Not initialized.", - llvm::inconvertibleErrorCode()); - std::apply( - [&method, &expected_return_object](auto &&...args) { - llvm::consumeError(expected_return_object.takeError()); - expected_return_object = method(args...); - }, - transformed_args); - - if (llvm::Error e = expected_return_object.takeError()) { - error = Status::FromError(std::move(e)); - return ErrorWithMessage<T>( - caller_signature, "python static method could not be called", error); - } - - PythonObject py_return = std::move(expected_return_object.get()); - - // Re-assign reference and pointer arguments if needed. - if (sizeof...(Args) > 0) - if (!ReassignPtrsOrRefsArgs(original_args, transformed_args)) - return ErrorWithMessage<T>( - caller_signature, - "couldn't re-assign reference and pointer arguments", error); - - // Extract value from Python object (handles unallocated case). - return ExtractValueFromPythonObject<T>(py_return, error); - } - protected: template <typename T = StructuredData::ObjectSP> T ExtractValueFromPythonObject(python::PythonObject &p, Status &error) { @@ -452,7 +346,7 @@ protected: llvm::Twine(method_name) + llvm::Twine(")")) .str(); if (!m_object_instance_sp) - return ErrorWithMessage<T>(caller_signature, "python object ill-formed", + return ErrorWithMessage<T>(caller_signature, "Python object ill-formed", error); Locker py_lock(&m_interpreter, Locker::AcquireLock | Locker::NoSTDIN, @@ -464,7 +358,7 @@ protected: if (!implementor.IsAllocated()) return llvm::is_contained(GetAbstractMethods(), method_name) ? ErrorWithMessage<T>(caller_signature, - "python implementor not allocated", + "Python implementor not allocated.", error) : T{}; @@ -485,20 +379,20 @@ protected: if (llvm::Error e = expected_return_object.takeError()) { error = Status::FromError(std::move(e)); return ErrorWithMessage<T>(caller_signature, - "python method could not be called", error); + "Python method could not be called.", error); } PythonObject py_return = std::move(expected_return_object.get()); // Now that we called the python method with the transformed arguments, - // we need to iterate again over both the original and transformed + // we need to interate again over both the original and transformed // parameter pack, and transform back the parameter that were passed in // the original parameter pack as references or pointers. if (sizeof...(Args) > 0) if (!ReassignPtrsOrRefsArgs(original_args, transformed_args)) return ErrorWithMessage<T>( caller_signature, - "couldn't re-assign reference and pointer arguments", error); + "Couldn't re-assign reference and pointer arguments.", error); if (!py_return.IsAllocated()) return {}; @@ -705,11 +599,6 @@ ScriptedPythonInterface::ExtractValueFromPythonObject<lldb::StreamSP>( python::PythonObject &p, Status &error); template <> -lldb::ThreadSP -ScriptedPythonInterface::ExtractValueFromPythonObject<lldb::ThreadSP>( - python::PythonObject &p, Status &error); - -template <> lldb::StackFrameSP ScriptedPythonInterface::ExtractValueFromPythonObject<lldb::StackFrameSP>( python::PythonObject &p, Status &error); |
