diff --git a/lldb/bindings/python/python-wrapper.swig b/lldb/bindings/python/python-wrapper.swig index 84fb3a95c0942..3a0995e84f643 100644 --- a/lldb/bindings/python/python-wrapper.swig +++ b/lldb/bindings/python/python-wrapper.swig @@ -422,18 +422,6 @@ void *lldb_private::python::LLDBSWIGPython_CastPyObjectToSBBreakpoint(PyObject * return sb_ptr; } -void *lldb_private::python::LLDBSWIGPython_CastPyObjectToSBThread(PyObject * data) { - lldb::SBThread *sb_ptr = nullptr; - - int valid_cast = - SWIG_ConvertPtr(data, (void **)&sb_ptr, SWIGTYPE_p_lldb__SBThread, 0); - - if (valid_cast == -1) - return NULL; - - return sb_ptr; -} - void *lldb_private::python::LLDBSWIGPython_CastPyObjectToSBFrame(PyObject * data) { lldb::SBFrame *sb_ptr = nullptr; diff --git a/lldb/examples/python/templates/scripted_frame_provider.py b/lldb/examples/python/templates/scripted_frame_provider.py index 7a72f1a24c9da..20f4d76d188c2 100644 --- a/lldb/examples/python/templates/scripted_frame_provider.py +++ b/lldb/examples/python/templates/scripted_frame_provider.py @@ -31,54 +31,7 @@ class ScriptedFrameProvider(metaclass=ABCMeta): ) """ - @staticmethod - def applies_to_thread(thread): - """Determine if this frame provider should be used for a given thread. - - This static method is called before creating an instance of the frame - provider to determine if it should be applied to a specific thread. - Override this method to provide custom filtering logic. - - Args: - thread (lldb.SBThread): The thread to check. - - Returns: - bool: True if this frame provider should be used for the thread, - False otherwise. The default implementation returns True for - all threads. - - Example: - - .. code-block:: python - - @staticmethod - def applies_to_thread(thread): - # Only apply to thread 1 - return thread.GetIndexID() == 1 - """ - return True - - @staticmethod @abstractmethod - def get_description(): - """Get a description of this frame provider. - - This method should return a human-readable string describing what - this frame provider does. The description is used for debugging - and display purposes. - - Returns: - str: A description of the frame provider. - - Example: - - .. code-block:: python - - def get_description(self): - return "Crash log frame provider for thread 1" - """ - pass - def __init__(self, input_frames, args): """Construct a scripted frame provider. diff --git a/lldb/examples/python/templates/scripted_process.py b/lldb/examples/python/templates/scripted_process.py index 136edce165140..49059d533f38a 100644 --- a/lldb/examples/python/templates/scripted_process.py +++ b/lldb/examples/python/templates/scripted_process.py @@ -245,7 +245,6 @@ def __init__(self, process, args): key/value pairs used by the scripted thread. """ self.target = None - self.arch = None self.originating_process = None self.process = None self.args = None @@ -267,9 +266,6 @@ def __init__(self, process, args): and process.IsValid() ): self.target = process.target - triple = self.target.triple - if triple: - self.arch = triple.split("-")[0] self.originating_process = process self.process = self.target.GetProcess() self.get_register_info() @@ -356,14 +352,17 @@ def get_stackframes(self): def get_register_info(self): if self.register_info is None: self.register_info = dict() - if "x86_64" in self.arch: + if "x86_64" in self.originating_process.arch: self.register_info["sets"] = ["General Purpose Registers"] self.register_info["registers"] = INTEL64_GPR - elif "arm64" in self.arch or self.arch == "aarch64": + elif ( + "arm64" in self.originating_process.arch + or self.originating_process.arch == "aarch64" + ): self.register_info["sets"] = ["General Purpose Registers"] self.register_info["registers"] = ARM64_GPR else: - raise ValueError("Unknown architecture", self.arch) + raise ValueError("Unknown architecture", self.originating_process.arch) return self.register_info @abstractmethod @@ -406,12 +405,11 @@ def __init__(self, thread, args): """Construct a scripted frame. Args: - thread (ScriptedThread/lldb.SBThread): The thread owning this frame. + thread (ScriptedThread): The thread owning this frame. args (lldb.SBStructuredData): A Dictionary holding arbitrary key/value pairs used by the scripted frame. """ self.target = None - self.arch = None self.originating_thread = None self.thread = None self.args = None @@ -421,17 +419,15 @@ def __init__(self, thread, args): self.register_ctx = {} self.variables = [] - if isinstance(thread, ScriptedThread) or ( - isinstance(thread, lldb.SBThread) and thread.IsValid() + if ( + isinstance(thread, ScriptedThread) + or isinstance(thread, lldb.SBThread) + and thread.IsValid() ): + self.target = thread.target self.process = thread.process - self.target = self.process.target - triple = self.target.triple - if triple: - self.arch = triple.split("-")[0] - tid = thread.tid if isinstance(thread, ScriptedThread) else thread.id self.originating_thread = thread - self.thread = self.process.GetThreadByIndexID(tid) + self.thread = self.process.GetThreadByIndexID(thread.tid) self.get_register_info() @abstractmethod @@ -512,18 +508,7 @@ def get_variables(self, filters): def get_register_info(self): if self.register_info is None: - if isinstance(self.originating_thread, ScriptedThread): - self.register_info = self.originating_thread.get_register_info() - elif isinstance(self.originating_thread, lldb.SBThread): - self.register_info = dict() - if "x86_64" in self.arch: - self.register_info["sets"] = ["General Purpose Registers"] - self.register_info["registers"] = INTEL64_GPR - elif "arm64" in self.arch or self.arch == "aarch64": - self.register_info["sets"] = ["General Purpose Registers"] - self.register_info["registers"] = ARM64_GPR - else: - raise ValueError("Unknown architecture", self.arch) + self.register_info = self.originating_thread.get_register_info() return self.register_info @abstractmethod @@ -657,12 +642,12 @@ def get_stop_reason(self): # TODO: Passthrough stop reason from driving process if self.driving_thread.GetStopReason() != lldb.eStopReasonNone: - if "arm64" in self.arch: + if "arm64" in self.originating_process.arch: stop_reason["type"] = lldb.eStopReasonException stop_reason["data"]["desc"] = ( self.driving_thread.GetStopDescription(100) ) - elif self.arch == "x86_64": + elif self.originating_process.arch == "x86_64": stop_reason["type"] = lldb.eStopReasonSignal stop_reason["data"]["signal"] = signal.SIGTRAP else: diff --git a/lldb/include/lldb/API/SBTarget.h b/lldb/include/lldb/API/SBTarget.h index c2fd3e2f50e3b..379a0bb7e9513 100644 --- a/lldb/include/lldb/API/SBTarget.h +++ b/lldb/include/lldb/API/SBTarget.h @@ -19,7 +19,6 @@ #include "lldb/API/SBLaunchInfo.h" #include "lldb/API/SBStatisticsOptions.h" #include "lldb/API/SBSymbolContextList.h" -#include "lldb/API/SBThreadCollection.h" #include "lldb/API/SBType.h" #include "lldb/API/SBValue.h" #include "lldb/API/SBWatchpoint.h" @@ -987,35 +986,6 @@ class LLDB_API SBTarget { lldb::SBMutex GetAPIMutex() const; - /// Register a scripted frame provider for this target. - /// If a scripted frame provider with the same name and same argument - /// dictionary is already registered on this target, it will be overwritten. - /// - /// \param[in] class_name - /// The name of the Python class that implements the frame provider. - /// - /// \param[in] args_dict - /// A dictionary of arguments to pass to the frame provider class. - /// - /// \param[out] error - /// An error object indicating success or failure. - /// - /// \return - /// A unique identifier for the frame provider descriptor that was - /// registered. 0 if the registration failed. - uint32_t RegisterScriptedFrameProvider(const char *class_name, - lldb::SBStructuredData args_dict, - lldb::SBError &error); - - /// Remove a scripted frame provider from this target by name. - /// - /// \param[in] provider_id - /// The id of the frame provider class to remove. - /// - /// \return - /// An error object indicating success or failure. - lldb::SBError RemoveScriptedFrameProvider(uint32_t provider_id); - protected: friend class SBAddress; friend class SBAddressRange; diff --git a/lldb/include/lldb/API/SBThread.h b/lldb/include/lldb/API/SBThread.h index 639e7a0a1a5c0..f6a6d19935b83 100644 --- a/lldb/include/lldb/API/SBThread.h +++ b/lldb/include/lldb/API/SBThread.h @@ -256,7 +256,6 @@ class LLDB_API SBThread { friend class SBThreadPlan; friend class SBTrace; - friend class lldb_private::ScriptInterpreter; friend class lldb_private::python::SWIGBridge; SBThread(const lldb::ThreadSP &lldb_object_sp); diff --git a/lldb/include/lldb/API/SBThreadCollection.h b/lldb/include/lldb/API/SBThreadCollection.h index d13dea0f11cd2..5a052e6246026 100644 --- a/lldb/include/lldb/API/SBThreadCollection.h +++ b/lldb/include/lldb/API/SBThreadCollection.h @@ -46,7 +46,6 @@ class LLDB_API SBThreadCollection { void SetOpaque(const lldb::ThreadCollectionSP &threads); private: - friend class SBTarget; friend class SBProcess; friend class SBThread; friend class SBSaveCoreOptions; diff --git a/lldb/include/lldb/Interpreter/Interfaces/ScriptedFrameProviderInterface.h b/lldb/include/lldb/Interpreter/Interfaces/ScriptedFrameProviderInterface.h index 49b60131399d5..2d9f713676f90 100644 --- a/lldb/include/lldb/Interpreter/Interfaces/ScriptedFrameProviderInterface.h +++ b/lldb/include/lldb/Interpreter/Interfaces/ScriptedFrameProviderInterface.h @@ -16,29 +16,11 @@ namespace lldb_private { class ScriptedFrameProviderInterface : public ScriptedInterface { public: - virtual bool AppliesToThread(llvm::StringRef class_name, - lldb::ThreadSP thread_sp) { - return true; - } - virtual llvm::Expected CreatePluginObject(llvm::StringRef class_name, lldb::StackFrameListSP input_frames, StructuredData::DictionarySP args_sp) = 0; - /// Get a description string for the frame provider. - /// - /// This is called by the descriptor to fetch a description from the - /// scripted implementation. Implementations should call a static method - /// on the scripting class to retrieve the description. - /// - /// \param class_name The name of the scripting class implementing the - /// provider. - /// - /// \return A string describing what this frame provider does, or an - /// empty string if no description is available. - virtual std::string GetDescription(llvm::StringRef class_name) { return {}; } - virtual StructuredData::ObjectSP GetFrameAtIndex(uint32_t index) { return {}; } diff --git a/lldb/include/lldb/Interpreter/ScriptInterpreter.h b/lldb/include/lldb/Interpreter/ScriptInterpreter.h index 0b91d6756552d..7fed4940b85bf 100644 --- a/lldb/include/lldb/Interpreter/ScriptInterpreter.h +++ b/lldb/include/lldb/Interpreter/ScriptInterpreter.h @@ -21,7 +21,6 @@ #include "lldb/API/SBMemoryRegionInfo.h" #include "lldb/API/SBStream.h" #include "lldb/API/SBSymbolContext.h" -#include "lldb/API/SBThread.h" #include "lldb/Breakpoint/BreakpointOptions.h" #include "lldb/Core/PluginInterface.h" #include "lldb/Core/SearchFilter.h" @@ -581,8 +580,6 @@ class ScriptInterpreter : public PluginInterface { lldb::StreamSP GetOpaqueTypeFromSBStream(const lldb::SBStream &stream) const; - lldb::ThreadSP GetOpaqueTypeFromSBThread(const lldb::SBThread &exe_ctx) const; - lldb::StackFrameSP GetOpaqueTypeFromSBFrame(const lldb::SBFrame &frame) const; SymbolContext diff --git a/lldb/include/lldb/Target/StackFrame.h b/lldb/include/lldb/Target/StackFrame.h index af2e49b4a67da..cdbe8ae3c6779 100644 --- a/lldb/include/lldb/Target/StackFrame.h +++ b/lldb/include/lldb/Target/StackFrame.h @@ -441,11 +441,8 @@ class StackFrame : public ExecutionContextScope, /// frames are included in this frame index count. uint32_t GetFrameIndex() const; - /// Set this frame's frame index. - void SetFrameIndex(uint32_t index) { - m_frame_index = index; - m_concrete_frame_index = index; - } + /// Set this frame's synthetic frame index. + void SetFrameIndex(uint32_t index) { m_frame_index = index; } /// Query this frame to find what frame it is in this Thread's /// StackFrameList, not counting inlined frames. diff --git a/lldb/include/lldb/Target/StackFrameList.h b/lldb/include/lldb/Target/StackFrameList.h index 539c070ff0f4b..5b0df0ddb3e29 100644 --- a/lldb/include/lldb/Target/StackFrameList.h +++ b/lldb/include/lldb/Target/StackFrameList.h @@ -20,13 +20,13 @@ namespace lldb_private { class ScriptedThread; -class StackFrameList : public std::enable_shared_from_this { +class StackFrameList { public: // Constructors and Destructors StackFrameList(Thread &thread, const lldb::StackFrameListSP &prev_frames_sp, bool show_inline_frames); - virtual ~StackFrameList(); + ~StackFrameList(); /// Get the number of visible frames. Frames may be created if \p can_create /// is true. Synthetic (inline) frames expanded from the concrete frame #0 @@ -106,7 +106,6 @@ class StackFrameList : public std::enable_shared_from_this { protected: friend class Thread; - friend class ScriptedFrameProvider; friend class ScriptedThread; /// Use this API to build a stack frame list (used for scripted threads, for @@ -212,23 +211,19 @@ class StackFrameList : public std::enable_shared_from_this { /// Whether or not to show synthetic (inline) frames. Immutable. const bool m_show_inlined_frames; - /// Returns true if fetching frames was interrupted, false otherwise. - virtual bool FetchFramesUpTo(uint32_t end_idx, - InterruptionControl allow_interrupt); - private: uint32_t SetSelectedFrameNoLock(lldb_private::StackFrame *frame); lldb::StackFrameSP GetFrameAtIndexNoLock(uint32_t idx, std::shared_lock &guard); - /// @{ /// These two Fetch frames APIs and SynthesizeTailCallFrames are called in /// GetFramesUpTo, they are the ones that actually add frames. They must be /// called with the writer end of the list mutex held. - /// + + /// Returns true if fetching frames was interrupted, false otherwise. + bool FetchFramesUpTo(uint32_t end_idx, InterruptionControl allow_interrupt); /// Not currently interruptible so returns void. - /// }@ void FetchOnlyConcreteFramesUpTo(uint32_t end_idx); void SynthesizeTailCallFrames(StackFrame &next_frame); @@ -236,27 +231,6 @@ class StackFrameList : public std::enable_shared_from_this { const StackFrameList &operator=(const StackFrameList &) = delete; }; -/// A StackFrameList that wraps another StackFrameList and uses a -/// SyntheticFrameProvider to lazily provide frames from either the provider -/// or the underlying real stack frame list. -class SyntheticStackFrameList : public StackFrameList { -public: - SyntheticStackFrameList(Thread &thread, lldb::StackFrameListSP input_frames, - const lldb::StackFrameListSP &prev_frames_sp, - bool show_inline_frames); - -protected: - /// Override FetchFramesUpTo to lazily return frames from the provider - /// or from the actual stack frame list. - bool FetchFramesUpTo(uint32_t end_idx, - InterruptionControl allow_interrupt) override; - -private: - /// The input stack frame list that the provider transforms. - /// This could be a real StackFrameList or another SyntheticStackFrameList. - lldb::StackFrameListSP m_input_frames; -}; - } // namespace lldb_private #endif // LLDB_TARGET_STACKFRAMELIST_H diff --git a/lldb/include/lldb/Target/SyntheticFrameProvider.h b/lldb/include/lldb/Target/SyntheticFrameProvider.h index 2d5330cb03105..61a492f356ece 100644 --- a/lldb/include/lldb/Target/SyntheticFrameProvider.h +++ b/lldb/include/lldb/Target/SyntheticFrameProvider.h @@ -24,25 +24,22 @@ namespace lldb_private { /// This struct contains the metadata needed to instantiate a frame provider /// and optional filters to control which threads it applies to. -struct ScriptedFrameProviderDescriptor { +struct SyntheticFrameProviderDescriptor { /// Metadata for instantiating the provider (e.g. script class name and args). lldb::ScriptedMetadataSP scripted_metadata_sp; - /// Interface for calling static methods on the provider class. - lldb::ScriptedFrameProviderInterfaceSP interface_sp; - /// Optional list of thread specifications to which this provider applies. /// If empty, the provider applies to all threads. A thread matches if it /// satisfies ANY of the specs in this vector (OR logic). std::vector thread_specs; - ScriptedFrameProviderDescriptor() = default; + SyntheticFrameProviderDescriptor() = default; - ScriptedFrameProviderDescriptor(lldb::ScriptedMetadataSP metadata_sp) + SyntheticFrameProviderDescriptor(lldb::ScriptedMetadataSP metadata_sp) : scripted_metadata_sp(metadata_sp) {} - ScriptedFrameProviderDescriptor(lldb::ScriptedMetadataSP metadata_sp, - const std::vector &specs) + SyntheticFrameProviderDescriptor(lldb::ScriptedMetadataSP metadata_sp, + const std::vector &specs) : scripted_metadata_sp(metadata_sp), thread_specs(specs) {} /// Get the name of this descriptor (the scripted class name). @@ -50,12 +47,6 @@ struct ScriptedFrameProviderDescriptor { return scripted_metadata_sp ? scripted_metadata_sp->GetClassName() : ""; } - /// Get the description of this frame provider. - /// - /// \return A string describing what this frame provider does, or an - /// empty string if no description is available. - std::string GetDescription() const; - /// Check if this descriptor applies to the given thread. bool AppliesToThread(Thread &thread) const { // If no thread specs specified, applies to all threads. @@ -73,13 +64,6 @@ struct ScriptedFrameProviderDescriptor { /// Check if this descriptor has valid metadata for script-based providers. bool IsValid() const { return scripted_metadata_sp != nullptr; } - /// Get a unique identifier for this descriptor based on its contents. - /// The ID is computed from the class name and arguments dictionary, - /// not from the pointer address, so two descriptors with the same - /// contents will have the same ID. - uint32_t GetID() const; - - /// Dump a description of this descriptor to the given stream. void Dump(Stream *s) const; }; @@ -111,7 +95,7 @@ class SyntheticFrameProvider : public PluginInterface { /// otherwise an \a llvm::Error. static llvm::Expected CreateInstance(lldb::StackFrameListSP input_frames, - const ScriptedFrameProviderDescriptor &descriptor); + const SyntheticFrameProviderDescriptor &descriptor); /// Try to create a SyntheticFrameProvider instance for the given input /// frames using a specific C++ plugin. @@ -141,8 +125,6 @@ class SyntheticFrameProvider : public PluginInterface { ~SyntheticFrameProvider() override; - virtual std::string GetDescription() const = 0; - /// Get a single stack frame at the specified index. /// /// This method is called lazily - frames are only created when requested. diff --git a/lldb/include/lldb/Target/Target.h b/lldb/include/lldb/Target/Target.h index cbda1c835f6bd..40f9c9bea1c12 100644 --- a/lldb/include/lldb/Target/Target.h +++ b/lldb/include/lldb/Target/Target.h @@ -32,7 +32,6 @@ #include "lldb/Target/PathMappingList.h" #include "lldb/Target/SectionLoadHistory.h" #include "lldb/Target/Statistics.h" -#include "lldb/Target/SyntheticFrameProvider.h" #include "lldb/Target/ThreadSpec.h" #include "lldb/Utility/ArchSpec.h" #include "lldb/Utility/Broadcaster.h" @@ -698,36 +697,6 @@ class Target : public std::enable_shared_from_this, Status Attach(ProcessAttachInfo &attach_info, Stream *stream); // Optional stream to receive first stop info - /// Add or update a scripted frame provider descriptor for this target. - /// All new threads in this target will check if they match any descriptors - /// to create their frame providers. - /// - /// \param[in] descriptor - /// The descriptor to add or update. - /// - /// \return - /// The descriptor identifier if the registration succeeded, otherwise an - /// llvm::Error. - llvm::Expected AddScriptedFrameProviderDescriptor( - const ScriptedFrameProviderDescriptor &descriptor); - - /// Remove a scripted frame provider descriptor by id. - /// - /// \param[in] id - /// The id of the descriptor to remove. - /// - /// \return - /// True if a descriptor was removed, false if no descriptor with that - /// id existed. - bool RemoveScriptedFrameProviderDescriptor(uint32_t id); - - /// Clear all scripted frame provider descriptors for this target. - void ClearScriptedFrameProviderDescriptors(); - - /// Get all scripted frame provider descriptors for this target. - const llvm::DenseMap & - GetScriptedFrameProviderDescriptors() const; - // This part handles the breakpoints. BreakpointList &GetBreakpointList(bool internal = false); @@ -1720,13 +1689,6 @@ class Target : public std::enable_shared_from_this, PathMappingList m_image_search_paths; TypeSystemMap m_scratch_type_system_map; - /// Map of scripted frame provider descriptors for this target. - /// Keys are the provider descriptors ids, values are the descriptors. - /// Used to initialize frame providers for new threads. - llvm::DenseMap - m_frame_provider_descriptors; - mutable std::recursive_mutex m_frame_provider_descriptors_mutex; - typedef std::map REPLMap; REPLMap m_repl_map; diff --git a/lldb/include/lldb/Target/Thread.h b/lldb/include/lldb/Target/Thread.h index 46ce192556756..841f80cd1b1eb 100644 --- a/lldb/include/lldb/Target/Thread.h +++ b/lldb/include/lldb/Target/Thread.h @@ -1297,15 +1297,6 @@ class Thread : public std::enable_shared_from_this, lldb::StackFrameListSP GetStackFrameList(); - llvm::Error - LoadScriptedFrameProvider(const ScriptedFrameProviderDescriptor &descriptor); - - void ClearScriptedFrameProvider(); - - lldb::SyntheticFrameProviderSP GetFrameProvider() const { - return m_frame_provider_sp; - } - protected: friend class ThreadPlan; friend class ThreadList; @@ -1409,9 +1400,6 @@ class Thread : public std::enable_shared_from_this, /// The Thread backed by this thread, if any. lldb::ThreadWP m_backed_thread; - /// The Scripted Frame Provider, if any. - lldb::SyntheticFrameProviderSP m_frame_provider_sp; - private: bool m_extended_info_fetched; // Have we tried to retrieve the m_extended_info // for this thread? diff --git a/lldb/include/lldb/Target/ThreadSpec.h b/lldb/include/lldb/Target/ThreadSpec.h index 63f8f8b5ec181..7c7c832741196 100644 --- a/lldb/include/lldb/Target/ThreadSpec.h +++ b/lldb/include/lldb/Target/ThreadSpec.h @@ -34,8 +34,6 @@ class ThreadSpec { public: ThreadSpec(); - ThreadSpec(Thread &thread); - static std::unique_ptr CreateFromStructuredData(const StructuredData::Dictionary &data_dict, Status &error); diff --git a/lldb/include/lldb/Utility/ScriptedMetadata.h b/lldb/include/lldb/Utility/ScriptedMetadata.h index 8523c95429718..69c83edce909a 100644 --- a/lldb/include/lldb/Utility/ScriptedMetadata.h +++ b/lldb/include/lldb/Utility/ScriptedMetadata.h @@ -10,9 +10,7 @@ #define LLDB_INTERPRETER_SCRIPTEDMETADATA_H #include "lldb/Utility/ProcessInfo.h" -#include "lldb/Utility/StreamString.h" #include "lldb/Utility/StructuredData.h" -#include "llvm/ADT/Hashing.h" namespace lldb_private { class ScriptedMetadata { @@ -29,36 +27,11 @@ class ScriptedMetadata { } } - ScriptedMetadata(const ScriptedMetadata &other) - : m_class_name(other.m_class_name), m_args_sp(other.m_args_sp) {} - explicit operator bool() const { return !m_class_name.empty(); } llvm::StringRef GetClassName() const { return m_class_name; } StructuredData::DictionarySP GetArgsSP() const { return m_args_sp; } - /// Get a unique identifier for this metadata based on its contents. - /// The ID is computed from the class name and arguments dictionary, - /// not from the pointer address, so two metadata objects with the same - /// contents will have the same ID. - uint32_t GetID() const { - if (m_class_name.empty()) - return 0; - - // Hash the class name. - llvm::hash_code hash = llvm::hash_value(m_class_name); - - // Hash the arguments dictionary if present. - if (m_args_sp) { - StreamString ss; - m_args_sp->GetDescription(ss); - hash = llvm::hash_combine(hash, llvm::hash_value(ss.GetData())); - } - - // Return the lower 32 bits of the hash. - return static_cast(hash); - } - private: std::string m_class_name; StructuredData::DictionarySP m_args_sp; diff --git a/lldb/include/lldb/lldb-private-interfaces.h b/lldb/include/lldb/lldb-private-interfaces.h index 52806eea190a7..5fc5c14c52f9e 100644 --- a/lldb/include/lldb/lldb-private-interfaces.h +++ b/lldb/include/lldb/lldb-private-interfaces.h @@ -26,7 +26,7 @@ class Value; namespace lldb_private { class ScriptedInterfaceUsages; -struct ScriptedFrameProviderDescriptor; +struct SyntheticFrameProviderDescriptor; typedef lldb::ABISP (*ABICreateInstance)(lldb::ProcessSP process_sp, const ArchSpec &arch); typedef std::unique_ptr (*ArchitectureCreateInstance)( @@ -91,7 +91,7 @@ typedef lldb::ScriptInterpreterSP (*ScriptInterpreterCreateInstance)( typedef llvm::Expected ( *ScriptedFrameProviderCreateInstance)( lldb::StackFrameListSP input_frames, - const lldb_private::ScriptedFrameProviderDescriptor &descriptor); + const lldb_private::SyntheticFrameProviderDescriptor &descriptor); typedef llvm::Expected ( *SyntheticFrameProviderCreateInstance)( lldb::StackFrameListSP input_frames, diff --git a/lldb/source/API/SBTarget.cpp b/lldb/source/API/SBTarget.cpp index bb1d98b6e15c1..98d10aa07c53f 100644 --- a/lldb/source/API/SBTarget.cpp +++ b/lldb/source/API/SBTarget.cpp @@ -23,7 +23,6 @@ #include "lldb/API/SBStringList.h" #include "lldb/API/SBStructuredData.h" #include "lldb/API/SBSymbolContextList.h" -#include "lldb/API/SBThreadCollection.h" #include "lldb/API/SBTrace.h" #include "lldb/Breakpoint/BreakpointID.h" #include "lldb/Breakpoint/BreakpointIDList.h" @@ -40,7 +39,6 @@ #include "lldb/Core/Section.h" #include "lldb/Core/StructuredDataImpl.h" #include "lldb/Host/Host.h" -#include "lldb/Interpreter/Interfaces/ScriptedFrameProviderInterface.h" #include "lldb/Symbol/DeclVendor.h" #include "lldb/Symbol/ObjectFile.h" #include "lldb/Symbol/SymbolFile.h" @@ -52,7 +50,6 @@ #include "lldb/Target/LanguageRuntime.h" #include "lldb/Target/Process.h" #include "lldb/Target/StackFrame.h" -#include "lldb/Target/SyntheticFrameProvider.h" #include "lldb/Target/Target.h" #include "lldb/Target/TargetList.h" #include "lldb/Utility/ArchSpec.h" @@ -62,7 +59,6 @@ #include "lldb/Utility/LLDBLog.h" #include "lldb/Utility/ProcessInfo.h" #include "lldb/Utility/RegularExpression.h" -#include "lldb/Utility/ScriptedMetadata.h" #include "lldb/ValueObject/ValueObjectConstResult.h" #include "lldb/ValueObject/ValueObjectList.h" #include "lldb/ValueObject/ValueObjectVariable.h" @@ -2412,81 +2408,3 @@ lldb::SBMutex SBTarget::GetAPIMutex() const { return lldb::SBMutex(target_sp); return lldb::SBMutex(); } - -uint32_t -SBTarget::RegisterScriptedFrameProvider(const char *class_name, - lldb::SBStructuredData args_dict, - lldb::SBError &error) { - LLDB_INSTRUMENT_VA(this, class_name, args_dict, error); - - TargetSP target_sp = GetSP(); - if (!target_sp) { - error.SetErrorString("invalid target"); - return 0; - } - - if (!class_name || !class_name[0]) { - error.SetErrorString("invalid class name"); - return 0; - } - - // Extract the dictionary from SBStructuredData. - StructuredData::DictionarySP dict_sp; - if (args_dict.IsValid() && args_dict.m_impl_up) { - StructuredData::ObjectSP obj_sp = args_dict.m_impl_up->GetObjectSP(); - if (obj_sp && obj_sp->GetType() != lldb::eStructuredDataTypeDictionary) { - error.SetErrorString("SBStructuredData argument isn't a dictionary"); - return 0; - } - dict_sp = std::make_shared(obj_sp); - } - - // Create the ScriptedMetadata. - ScriptedMetadataSP metadata_sp = - std::make_shared(class_name, dict_sp); - - // Create the interface for calling static methods. - ScriptedFrameProviderInterfaceSP interface_sp = - target_sp->GetDebugger() - .GetScriptInterpreter() - ->CreateScriptedFrameProviderInterface(); - - // Create a descriptor (applies to all threads by default). - ScriptedFrameProviderDescriptor descriptor(metadata_sp); - descriptor.interface_sp = interface_sp; - - llvm::Expected descriptor_id_or_err = - target_sp->AddScriptedFrameProviderDescriptor(descriptor); - if (!descriptor_id_or_err) { - error.SetErrorString( - llvm::toString(descriptor_id_or_err.takeError()).c_str()); - return 0; - } - - // Register the descriptor with the target. - return *descriptor_id_or_err; -} - -lldb::SBError SBTarget::RemoveScriptedFrameProvider(uint32_t provider_id) { - LLDB_INSTRUMENT_VA(this, provider_id); - - SBError error; - TargetSP target_sp = GetSP(); - if (!target_sp) { - error.SetErrorString("invalid target"); - return error; - } - - if (!provider_id) { - error.SetErrorString("invalid provider id"); - return error; - } - - if (!target_sp->RemoveScriptedFrameProviderDescriptor(provider_id)) { - error.SetErrorStringWithFormat("no frame provider named '%u' found", - provider_id); - return error; - } - - return {}; -} diff --git a/lldb/source/Commands/CommandObjectTarget.cpp b/lldb/source/Commands/CommandObjectTarget.cpp index 86373f5280271..30bca639060e6 100644 --- a/lldb/source/Commands/CommandObjectTarget.cpp +++ b/lldb/source/Commands/CommandObjectTarget.cpp @@ -51,7 +51,6 @@ #include "lldb/Utility/ConstString.h" #include "lldb/Utility/FileSpec.h" #include "lldb/Utility/LLDBLog.h" -#include "lldb/Utility/ScriptedMetadata.h" #include "lldb/Utility/State.h" #include "lldb/Utility/Stream.h" #include "lldb/Utility/StructuredData.h" @@ -5402,202 +5401,6 @@ class CommandObjectTargetDump : public CommandObjectMultiword { ~CommandObjectTargetDump() override = default; }; -#pragma mark CommandObjectTargetFrameProvider - -#define LLDB_OPTIONS_target_frame_provider_register -#include "CommandOptions.inc" - -class CommandObjectTargetFrameProviderRegister : public CommandObjectParsed { -public: - CommandObjectTargetFrameProviderRegister(CommandInterpreter &interpreter) - : CommandObjectParsed( - interpreter, "target frame-provider register", - "Register frame provider for all threads in this target.", nullptr, - eCommandRequiresTarget), - - m_class_options("target frame-provider", true, 'C', 'k', 'v', 0) { - m_all_options.Append(&m_class_options, LLDB_OPT_SET_1 | LLDB_OPT_SET_2, - LLDB_OPT_SET_ALL); - m_all_options.Finalize(); - - AddSimpleArgumentList(eArgTypeRunArgs, eArgRepeatOptional); - } - - ~CommandObjectTargetFrameProviderRegister() override = default; - - Options *GetOptions() override { return &m_all_options; } - - std::optional GetRepeatCommand(Args ¤t_command_args, - uint32_t index) override { - return std::string(""); - } - -protected: - void DoExecute(Args &launch_args, CommandReturnObject &result) override { - ScriptedMetadataSP metadata_sp = std::make_shared( - m_class_options.GetName(), m_class_options.GetStructuredData()); - - Target *target = m_exe_ctx.GetTargetPtr(); - if (!target) - target = &GetDebugger().GetDummyTarget(); - - // Create the interface for calling static methods. - ScriptedFrameProviderInterfaceSP interface_sp = - GetDebugger() - .GetScriptInterpreter() - ->CreateScriptedFrameProviderInterface(); - - // Create a descriptor from the metadata (applies to all threads by - // default). - ScriptedFrameProviderDescriptor descriptor(metadata_sp); - descriptor.interface_sp = interface_sp; - - auto id_or_err = target->AddScriptedFrameProviderDescriptor(descriptor); - if (!id_or_err) { - result.SetError(id_or_err.takeError()); - return; - } - - result.AppendMessageWithFormat( - "successfully registered scripted frame provider '%s' for target\n", - m_class_options.GetName().c_str()); - } - - OptionGroupPythonClassWithDict m_class_options; - OptionGroupOptions m_all_options; -}; - -class CommandObjectTargetFrameProviderClear : public CommandObjectParsed { -public: - CommandObjectTargetFrameProviderClear(CommandInterpreter &interpreter) - : CommandObjectParsed( - interpreter, "target frame-provider clear", - "Clear all registered frame providers from this target.", nullptr, - eCommandRequiresTarget) {} - - ~CommandObjectTargetFrameProviderClear() override = default; - -protected: - void DoExecute(Args &command, CommandReturnObject &result) override { - Target *target = m_exe_ctx.GetTargetPtr(); - if (!target) { - result.AppendError("invalid target"); - return; - } - - target->ClearScriptedFrameProviderDescriptors(); - - result.SetStatus(eReturnStatusSuccessFinishResult); - } -}; - -class CommandObjectTargetFrameProviderList : public CommandObjectParsed { -public: - CommandObjectTargetFrameProviderList(CommandInterpreter &interpreter) - : CommandObjectParsed( - interpreter, "target frame-provider list", - "List all registered frame providers for the target.", nullptr, - eCommandRequiresTarget) {} - - ~CommandObjectTargetFrameProviderList() override = default; - -protected: - void DoExecute(Args &command, CommandReturnObject &result) override { - Target *target = m_exe_ctx.GetTargetPtr(); - if (!target) - target = &GetDebugger().GetDummyTarget(); - - const auto &descriptors = target->GetScriptedFrameProviderDescriptors(); - if (descriptors.empty()) { - result.AppendMessage("no frame providers registered for this target."); - result.SetStatus(eReturnStatusSuccessFinishResult); - return; - } - - result.AppendMessageWithFormat("%u frame provider(s) registered:\n\n", - descriptors.size()); - - for (const auto &entry : descriptors) { - const ScriptedFrameProviderDescriptor &descriptor = entry.second; - descriptor.Dump(&result.GetOutputStream()); - result.GetOutputStream().PutChar('\n'); - } - - result.SetStatus(eReturnStatusSuccessFinishResult); - } -}; - -class CommandObjectTargetFrameProviderRemove : public CommandObjectParsed { -public: - CommandObjectTargetFrameProviderRemove(CommandInterpreter &interpreter) - : CommandObjectParsed( - interpreter, "target frame-provider remove", - "Remove a registered frame provider from the target by id.", - "target frame-provider remove ", - eCommandRequiresTarget) { - AddSimpleArgumentList(eArgTypeUnsignedInteger, eArgRepeatPlus); - } - - ~CommandObjectTargetFrameProviderRemove() override = default; - -protected: - void DoExecute(Args &command, CommandReturnObject &result) override { - Target *target = m_exe_ctx.GetTargetPtr(); - if (!target) - target = &GetDebugger().GetDummyTarget(); - - std::vector removed_provider_ids; - for (size_t i = 0; i < command.GetArgumentCount(); i++) { - uint32_t provider_id = 0; - if (!llvm::to_integer(command[i].ref(), provider_id)) { - result.AppendError("target frame-provider remove requires integer " - "provider id argument"); - return; - } - - if (!target->RemoveScriptedFrameProviderDescriptor(provider_id)) { - result.AppendErrorWithFormat( - "no frame provider named '%u' found in target\n", provider_id); - return; - } - removed_provider_ids.push_back(provider_id); - } - - if (size_t num_removed_providers = removed_provider_ids.size()) { - result.AppendMessageWithFormat( - "Successfully removed %zu frame-providers.\n", num_removed_providers); - result.SetStatus(eReturnStatusSuccessFinishNoResult); - } else { - result.AppendError("0 frame providers removed.\n"); - } - } -}; - -class CommandObjectTargetFrameProvider : public CommandObjectMultiword { -public: - CommandObjectTargetFrameProvider(CommandInterpreter &interpreter) - : CommandObjectMultiword( - interpreter, "target frame-provider", - "Commands for registering and viewing frame providers for the " - "target.", - "target frame-provider [] ") { - LoadSubCommand("register", - CommandObjectSP(new CommandObjectTargetFrameProviderRegister( - interpreter))); - LoadSubCommand("clear", - CommandObjectSP( - new CommandObjectTargetFrameProviderClear(interpreter))); - LoadSubCommand( - "list", - CommandObjectSP(new CommandObjectTargetFrameProviderList(interpreter))); - LoadSubCommand( - "remove", CommandObjectSP( - new CommandObjectTargetFrameProviderRemove(interpreter))); - } - - ~CommandObjectTargetFrameProvider() override = default; -}; - #pragma mark CommandObjectMultiwordTarget // CommandObjectMultiwordTarget @@ -5613,9 +5416,6 @@ CommandObjectMultiwordTarget::CommandObjectMultiwordTarget( CommandObjectSP(new CommandObjectTargetDelete(interpreter))); LoadSubCommand("dump", CommandObjectSP(new CommandObjectTargetDump(interpreter))); - LoadSubCommand( - "frame-provider", - CommandObjectSP(new CommandObjectTargetFrameProvider(interpreter))); LoadSubCommand("list", CommandObjectSP(new CommandObjectTargetList(interpreter))); LoadSubCommand("select", diff --git a/lldb/source/Interpreter/ScriptInterpreter.cpp b/lldb/source/Interpreter/ScriptInterpreter.cpp index 69d8607a873f3..211868b51facb 100644 --- a/lldb/source/Interpreter/ScriptInterpreter.cpp +++ b/lldb/source/Interpreter/ScriptInterpreter.cpp @@ -106,13 +106,6 @@ ScriptInterpreter::GetStatusFromSBError(const lldb::SBError &error) const { return Status(); } -lldb::ThreadSP ScriptInterpreter::GetOpaqueTypeFromSBThread( - const lldb::SBThread &thread) const { - if (thread.m_opaque_sp) - return thread.m_opaque_sp->GetThreadSP(); - return nullptr; -} - lldb::StackFrameSP ScriptInterpreter::GetOpaqueTypeFromSBFrame(const lldb::SBFrame &frame) const { if (frame.m_opaque_sp) diff --git a/lldb/source/Plugins/CMakeLists.txt b/lldb/source/Plugins/CMakeLists.txt index b6878b21ff71a..08f444e7b15e8 100644 --- a/lldb/source/Plugins/CMakeLists.txt +++ b/lldb/source/Plugins/CMakeLists.txt @@ -22,7 +22,6 @@ add_subdirectory(SymbolFile) add_subdirectory(SystemRuntime) add_subdirectory(SymbolLocator) add_subdirectory(SymbolVendor) -add_subdirectory(SyntheticFrameProvider) add_subdirectory(Trace) add_subdirectory(TraceExporter) add_subdirectory(TypeSystem) diff --git a/lldb/source/Plugins/Process/scripted/ScriptedFrame.cpp b/lldb/source/Plugins/Process/scripted/ScriptedFrame.cpp index 53d0c22e62ad7..6519df9185df0 100644 --- a/lldb/source/Plugins/Process/scripted/ScriptedFrame.cpp +++ b/lldb/source/Plugins/Process/scripted/ScriptedFrame.cpp @@ -7,22 +7,8 @@ //===----------------------------------------------------------------------===// #include "ScriptedFrame.h" -#include "Plugins/Process/Utility/RegisterContextMemory.h" - -#include "lldb/Core/Address.h" -#include "lldb/Core/Debugger.h" -#include "lldb/Interpreter/Interfaces/ScriptedFrameInterface.h" -#include "lldb/Interpreter/Interfaces/ScriptedThreadInterface.h" -#include "lldb/Interpreter/ScriptInterpreter.h" -#include "lldb/Symbol/SymbolContext.h" -#include "lldb/Target/ExecutionContext.h" -#include "lldb/Target/Process.h" -#include "lldb/Target/RegisterContext.h" -#include "lldb/Target/Thread.h" + #include "lldb/Utility/DataBufferHeap.h" -#include "lldb/Utility/LLDBLog.h" -#include "lldb/Utility/Log.h" -#include "lldb/Utility/StructuredData.h" using namespace lldb; using namespace lldb_private; @@ -33,44 +19,30 @@ void ScriptedFrame::CheckInterpreterAndScriptObject() const { } llvm::Expected> -ScriptedFrame::Create(ThreadSP thread_sp, - ScriptedThreadInterfaceSP scripted_thread_interface_sp, +ScriptedFrame::Create(ScriptedThread &thread, StructuredData::DictionarySP args_sp, StructuredData::Generic *script_object) { - if (!thread_sp || !thread_sp->IsValid()) - return llvm::createStringError("invalid thread"); - - ProcessSP process_sp = thread_sp->GetProcess(); - if (!process_sp || !process_sp->IsValid()) - return llvm::createStringError("invalid process"); + if (!thread.IsValid()) + return llvm::createStringError("Invalid scripted thread."); - ScriptInterpreter *script_interp = - process_sp->GetTarget().GetDebugger().GetScriptInterpreter(); - if (!script_interp) - return llvm::createStringError("no script interpreter"); + thread.CheckInterpreterAndScriptObject(); - auto scripted_frame_interface = script_interp->CreateScriptedFrameInterface(); + auto scripted_frame_interface = + thread.GetInterface()->CreateScriptedFrameInterface(); if (!scripted_frame_interface) return llvm::createStringError("failed to create scripted frame interface"); llvm::StringRef frame_class_name; if (!script_object) { - // If no script object is provided and we have a scripted thread interface, - // try to get the frame class name from it. - if (scripted_thread_interface_sp) { - std::optional class_name = - scripted_thread_interface_sp->GetScriptedFramePluginName(); - if (!class_name || class_name->empty()) - return llvm::createStringError( - "failed to get scripted frame class name"); - frame_class_name = *class_name; - } else { + std::optional class_name = + thread.GetInterface()->GetScriptedFramePluginName(); + if (!class_name || class_name->empty()) return llvm::createStringError( - "no script object provided and no scripted thread interface"); - } + "failed to get scripted thread class name"); + frame_class_name = *class_name; } - ExecutionContext exe_ctx(thread_sp); + ExecutionContext exe_ctx(thread); auto obj_or_err = scripted_frame_interface->CreatePluginObject( frame_class_name, exe_ctx, args_sp, script_object); @@ -90,7 +62,7 @@ ScriptedFrame::Create(ThreadSP thread_sp, SymbolContext sc; Address symbol_addr; if (pc != LLDB_INVALID_ADDRESS) { - symbol_addr.SetLoadAddress(pc, &process_sp->GetTarget()); + symbol_addr.SetLoadAddress(pc, &thread.GetProcess()->GetTarget()); symbol_addr.CalculateSymbolContext(&sc); } @@ -105,11 +77,11 @@ ScriptedFrame::Create(ThreadSP thread_sp, if (!reg_info) return llvm::createStringError( - "failed to get scripted frame registers info"); + "failed to get scripted thread registers info"); std::shared_ptr register_info_sp = - DynamicRegisterInfo::Create(*reg_info, - process_sp->GetTarget().GetArchitecture()); + DynamicRegisterInfo::Create( + *reg_info, thread.GetProcess()->GetTarget().GetArchitecture()); lldb::RegisterContextSP reg_ctx_sp; @@ -124,35 +96,32 @@ ScriptedFrame::Create(ThreadSP thread_sp, std::shared_ptr reg_ctx_memory = std::make_shared( - *thread_sp, frame_id, *register_info_sp, LLDB_INVALID_ADDRESS); + thread, frame_id, *register_info_sp, LLDB_INVALID_ADDRESS); if (!reg_ctx_memory) - return llvm::createStringError("failed to create a register context"); + return llvm::createStringError("failed to create a register context."); reg_ctx_memory->SetAllRegisterData(data_sp); reg_ctx_sp = reg_ctx_memory; } return std::make_shared( - thread_sp, scripted_frame_interface, frame_id, pc, sc, reg_ctx_sp, + thread, scripted_frame_interface, frame_id, pc, sc, reg_ctx_sp, register_info_sp, owned_script_object_sp); } -ScriptedFrame::ScriptedFrame(ThreadSP thread_sp, +ScriptedFrame::ScriptedFrame(ScriptedThread &thread, ScriptedFrameInterfaceSP interface_sp, lldb::user_id_t id, lldb::addr_t pc, SymbolContext &sym_ctx, lldb::RegisterContextSP reg_ctx_sp, std::shared_ptr reg_info_sp, StructuredData::GenericSP script_object_sp) - : StackFrame(thread_sp, /*frame_idx=*/id, + : StackFrame(thread.shared_from_this(), /*frame_idx=*/id, /*concrete_frame_idx=*/id, /*reg_context_sp=*/reg_ctx_sp, /*cfa=*/0, /*pc=*/pc, /*behaves_like_zeroth_frame=*/!id, /*symbol_ctx=*/&sym_ctx), m_scripted_frame_interface_sp(interface_sp), - m_script_object_sp(script_object_sp), m_register_info_sp(reg_info_sp) { - // FIXME: This should be part of the base class constructor. - m_stack_frame_kind = StackFrame::Kind::Synthetic; -} + m_script_object_sp(script_object_sp), m_register_info_sp(reg_info_sp) {} ScriptedFrame::~ScriptedFrame() {} @@ -195,7 +164,7 @@ std::shared_ptr ScriptedFrame::GetDynamicRegisterInfo() { if (!reg_info) return ScriptedInterface::ErrorWithMessage< std::shared_ptr>( - LLVM_PRETTY_FUNCTION, "failed to get scripted frame registers info", + LLVM_PRETTY_FUNCTION, "Failed to get scripted frame registers info.", error, LLDBLog::Thread); ThreadSP thread_sp = m_thread_wp.lock(); @@ -203,7 +172,7 @@ std::shared_ptr ScriptedFrame::GetDynamicRegisterInfo() { return ScriptedInterface::ErrorWithMessage< std::shared_ptr>( LLVM_PRETTY_FUNCTION, - "failed to get scripted frame registers info: invalid thread", error, + "Failed to get scripted frame registers info: invalid thread.", error, LLDBLog::Thread); ProcessSP process_sp = thread_sp->GetProcess(); @@ -211,8 +180,8 @@ std::shared_ptr ScriptedFrame::GetDynamicRegisterInfo() { return ScriptedInterface::ErrorWithMessage< std::shared_ptr>( LLVM_PRETTY_FUNCTION, - "failed to get scripted frame registers info: invalid process", error, - LLDBLog::Thread); + "Failed to get scripted frame registers info: invalid process.", + error, LLDBLog::Thread); m_register_info_sp = DynamicRegisterInfo::Create( *reg_info, process_sp->GetTarget().GetArchitecture()); diff --git a/lldb/source/Plugins/Process/scripted/ScriptedFrame.h b/lldb/source/Plugins/Process/scripted/ScriptedFrame.h index e91e6160bac2f..b6b77c4a7d160 100644 --- a/lldb/source/Plugins/Process/scripted/ScriptedFrame.h +++ b/lldb/source/Plugins/Process/scripted/ScriptedFrame.h @@ -10,19 +10,21 @@ #define LLDB_SOURCE_PLUGINS_SCRIPTED_FRAME_H #include "ScriptedThread.h" +#include "lldb/Interpreter/ScriptInterpreter.h" #include "lldb/Target/DynamicRegisterInfo.h" #include "lldb/Target/StackFrame.h" -#include "lldb/lldb-forward.h" -#include "llvm/Support/Error.h" -#include #include +namespace lldb_private { +class ScriptedThread; +} + namespace lldb_private { class ScriptedFrame : public lldb_private::StackFrame { public: - ScriptedFrame(lldb::ThreadSP thread_sp, + ScriptedFrame(ScriptedThread &thread, lldb::ScriptedFrameInterfaceSP interface_sp, lldb::user_id_t frame_idx, lldb::addr_t pc, SymbolContext &sym_ctx, lldb::RegisterContextSP reg_ctx_sp, @@ -31,29 +33,8 @@ class ScriptedFrame : public lldb_private::StackFrame { ~ScriptedFrame() override; - /// Create a ScriptedFrame from a object instanciated in the script - /// interpreter. - /// - /// \param[in] thread_sp - /// The thread this frame belongs to. - /// - /// \param[in] scripted_thread_interface_sp - /// The scripted thread interface (needed for ScriptedThread - /// compatibility). Can be nullptr for frames on real threads. - /// - /// \param[in] args_sp - /// Arguments to pass to the frame creation. - /// - /// \param[in] script_object - /// The optional script object representing this frame. - /// - /// \return - /// An Expected containing the ScriptedFrame shared pointer if successful, - /// otherwise an error. static llvm::Expected> - Create(lldb::ThreadSP thread_sp, - lldb::ScriptedThreadInterfaceSP scripted_thread_interface_sp, - StructuredData::DictionarySP args_sp, + Create(ScriptedThread &thread, StructuredData::DictionarySP args_sp, StructuredData::Generic *script_object = nullptr); bool IsInlined() override; diff --git a/lldb/source/Plugins/Process/scripted/ScriptedThread.cpp b/lldb/source/Plugins/Process/scripted/ScriptedThread.cpp index 1dd9c48f56a59..491efac5aadef 100644 --- a/lldb/source/Plugins/Process/scripted/ScriptedThread.cpp +++ b/lldb/source/Plugins/Process/scripted/ScriptedThread.cpp @@ -210,7 +210,7 @@ bool ScriptedThread::LoadArtificialStackFrames() { SymbolContext sc; symbol_addr.CalculateSymbolContext(&sc); - return std::make_shared(shared_from_this(), idx, idx, cfa, + return std::make_shared(this->shared_from_this(), idx, idx, cfa, cfa_is_valid, pc, StackFrame::Kind::Synthetic, artificial, behaves_like_zeroth_frame, &sc); @@ -231,8 +231,8 @@ bool ScriptedThread::LoadArtificialStackFrames() { return error.ToError(); } - auto frame_or_error = ScriptedFrame::Create( - shared_from_this(), GetInterface(), nullptr, object_sp->GetAsGeneric()); + auto frame_or_error = + ScriptedFrame::Create(*this, nullptr, object_sp->GetAsGeneric()); if (!frame_or_error) { ScriptedInterface::ErrorWithMessage( diff --git a/lldb/source/Plugins/ScriptInterpreter/Python/Interfaces/ScriptInterpreterPythonInterfaces.cpp b/lldb/source/Plugins/ScriptInterpreter/Python/Interfaces/ScriptInterpreterPythonInterfaces.cpp index f6c707b2bd168..d43036d6fe544 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 3dde5036453f4..b866bf332b7b6 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 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 ci_usages = { - "target frame-provider register -C [-k key -v value ...]", - "target frame-provider list", - "target frame-provider remove ", - "target frame-provider clear"}; - const std::vector 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 97a5cc7c669ea..fd163984028d3 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 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 CreatePluginObject(llvm::StringRef class_name, lldb::StackFrameListSP input_frames, @@ -38,24 +33,10 @@ class ScriptedFrameProviderPythonInterface llvm::SmallVector GetAbstractMethodRequirements() const override { return llvm::SmallVector( - {{"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 ba4473cf9ec4d..af2e0b5df4d22 100644 --- a/lldb/source/Plugins/ScriptInterpreter/Python/Interfaces/ScriptedPythonInterface.cpp +++ b/lldb/source/Plugins/ScriptInterpreter/Python/Interfaces/ScriptedPythonInterface.cpp @@ -93,19 +93,6 @@ ScriptedPythonInterface::ExtractValueFromPythonObject( return nullptr; } -template <> -lldb::ThreadSP -ScriptedPythonInterface::ExtractValueFromPythonObject( - python::PythonObject &p, Status &error) { - if (lldb::SBThread *sb_thread = reinterpret_cast( - 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( diff --git a/lldb/source/Plugins/ScriptInterpreter/Python/Interfaces/ScriptedPythonInterface.h b/lldb/source/Plugins/ScriptInterpreter/Python/Interfaces/ScriptedPythonInterface.h index c460f58b4e721..af88a69e34a13 100644 --- a/lldb/source/Plugins/ScriptInterpreter/Python/Interfaces/ScriptedPythonInterface.h +++ b/lldb/source/Plugins/ScriptInterpreter/Python/Interfaces/ScriptedPythonInterface.h @@ -330,112 +330,6 @@ class ScriptedPythonInterface : virtual public ScriptedInterface { 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 - 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(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( - m_interpreter.GetDictionaryName()); - if (!dict.IsAllocated()) - return ErrorWithMessage( - caller_signature, - llvm::formatv("could not find interpreter dictionary: {0}", - m_interpreter.GetDictionaryName()) - .str(), - error); - - // Resolve the class. - auto class_obj = - PythonObject::ResolveNameWithDictionary( - class_name, dict); - if (!class_obj.IsAllocated()) - return ErrorWithMessage( - 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( - 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(); - if (!method.IsAllocated()) - return ErrorWithMessage(caller_signature, - llvm::formatv("method {0}.{1} is not callable", - class_name, method_name) - .str(), - error); - - // Transform the arguments. - std::tuple original_args = std::forward_as_tuple(args...); - auto transformed_args = TransformArgs(original_args); - - // Call the static method. - llvm::Expected expected_return_object = - llvm::make_error("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( - 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( - caller_signature, - "couldn't re-assign reference and pointer arguments", error); - - // Extract value from Python object (handles unallocated case). - return ExtractValueFromPythonObject(py_return, error); - } - protected: template T ExtractValueFromPythonObject(python::PythonObject &p, Status &error) { @@ -452,7 +346,7 @@ class ScriptedPythonInterface : virtual public ScriptedInterface { llvm::Twine(method_name) + llvm::Twine(")")) .str(); if (!m_object_instance_sp) - return ErrorWithMessage(caller_signature, "python object ill-formed", + return ErrorWithMessage(caller_signature, "Python object ill-formed", error); Locker py_lock(&m_interpreter, Locker::AcquireLock | Locker::NoSTDIN, @@ -464,7 +358,7 @@ class ScriptedPythonInterface : virtual public ScriptedInterface { if (!implementor.IsAllocated()) return llvm::is_contained(GetAbstractMethods(), method_name) ? ErrorWithMessage(caller_signature, - "python implementor not allocated", + "Python implementor not allocated.", error) : T{}; @@ -485,20 +379,20 @@ class ScriptedPythonInterface : virtual public ScriptedInterface { if (llvm::Error e = expected_return_object.takeError()) { error = Status::FromError(std::move(e)); return ErrorWithMessage(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( 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 {}; @@ -704,11 +598,6 @@ lldb::StreamSP ScriptedPythonInterface::ExtractValueFromPythonObject( python::PythonObject &p, Status &error); -template <> -lldb::ThreadSP -ScriptedPythonInterface::ExtractValueFromPythonObject( - python::PythonObject &p, Status &error); - template <> lldb::StackFrameSP ScriptedPythonInterface::ExtractValueFromPythonObject( diff --git a/lldb/source/Plugins/ScriptInterpreter/Python/SWIGPythonBridge.h b/lldb/source/Plugins/ScriptInterpreter/Python/SWIGPythonBridge.h index 32948ffd30023..2c971262fc34e 100644 --- a/lldb/source/Plugins/ScriptInterpreter/Python/SWIGPythonBridge.h +++ b/lldb/source/Plugins/ScriptInterpreter/Python/SWIGPythonBridge.h @@ -265,7 +265,6 @@ void *LLDBSWIGPython_CastPyObjectToSBLaunchInfo(PyObject *data); void *LLDBSWIGPython_CastPyObjectToSBError(PyObject *data); void *LLDBSWIGPython_CastPyObjectToSBEvent(PyObject *data); void *LLDBSWIGPython_CastPyObjectToSBStream(PyObject *data); -void *LLDBSWIGPython_CastPyObjectToSBThread(PyObject *data); void *LLDBSWIGPython_CastPyObjectToSBFrame(PyObject *data); void *LLDBSWIGPython_CastPyObjectToSBSymbolContext(PyObject *data); void *LLDBSWIGPython_CastPyObjectToSBValue(PyObject *data); diff --git a/lldb/source/Plugins/SyntheticFrameProvider/CMakeLists.txt b/lldb/source/Plugins/SyntheticFrameProvider/CMakeLists.txt deleted file mode 100644 index 85b405e648c1f..0000000000000 --- a/lldb/source/Plugins/SyntheticFrameProvider/CMakeLists.txt +++ /dev/null @@ -1 +0,0 @@ -add_subdirectory(ScriptedFrameProvider) diff --git a/lldb/source/Plugins/SyntheticFrameProvider/ScriptedFrameProvider/CMakeLists.txt b/lldb/source/Plugins/SyntheticFrameProvider/ScriptedFrameProvider/CMakeLists.txt deleted file mode 100644 index fe67d39efdf11..0000000000000 --- a/lldb/source/Plugins/SyntheticFrameProvider/ScriptedFrameProvider/CMakeLists.txt +++ /dev/null @@ -1,12 +0,0 @@ -add_lldb_library(lldbPluginScriptedFrameProvider PLUGIN - ScriptedFrameProvider.cpp - - LINK_COMPONENTS - Support - - LINK_LIBS - lldbCore - lldbInterpreter - lldbTarget - lldbUtility - ) diff --git a/lldb/source/Plugins/SyntheticFrameProvider/ScriptedFrameProvider/ScriptedFrameProvider.cpp b/lldb/source/Plugins/SyntheticFrameProvider/ScriptedFrameProvider/ScriptedFrameProvider.cpp deleted file mode 100644 index 17d0e925fadc6..0000000000000 --- a/lldb/source/Plugins/SyntheticFrameProvider/ScriptedFrameProvider/ScriptedFrameProvider.cpp +++ /dev/null @@ -1,215 +0,0 @@ -//===----------------------------------------------------------------------===// -// -// 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 "ScriptedFrameProvider.h" -#include "Plugins/Process/scripted/ScriptedFrame.h" -#include "lldb/Core/Debugger.h" -#include "lldb/Core/PluginManager.h" -#include "lldb/Interpreter/Interfaces/ScriptedFrameProviderInterface.h" -#include "lldb/Interpreter/ScriptInterpreter.h" -#include "lldb/Target/Process.h" -#include "lldb/Target/StackFrame.h" -#include "lldb/Target/Thread.h" -#include "lldb/Utility/ScriptedMetadata.h" -#include "lldb/Utility/Status.h" -#include "llvm/Support/Error.h" -#include - -using namespace lldb; -using namespace lldb_private; - -void ScriptedFrameProvider::Initialize() { - PluginManager::RegisterPlugin(GetPluginNameStatic(), - "Provides synthetic frames via scripting", - nullptr, ScriptedFrameProvider::CreateInstance); -} - -void ScriptedFrameProvider::Terminate() { - PluginManager::UnregisterPlugin(ScriptedFrameProvider::CreateInstance); -} - -llvm::Expected -ScriptedFrameProvider::CreateInstance( - lldb::StackFrameListSP input_frames, - const ScriptedFrameProviderDescriptor &descriptor) { - if (!input_frames) - return llvm::createStringError( - "failed to create scripted frame provider: invalid input frames"); - - Thread &thread = input_frames->GetThread(); - ProcessSP process_sp = thread.GetProcess(); - if (!process_sp) - return nullptr; - - if (!descriptor.IsValid()) - return llvm::createStringError( - "failed to create scripted frame provider: invalid scripted metadata"); - - if (!descriptor.AppliesToThread(thread)) - return nullptr; - - ScriptInterpreter *script_interp = - process_sp->GetTarget().GetDebugger().GetScriptInterpreter(); - if (!script_interp) - return llvm::createStringError("cannot create scripted frame provider: No " - "script interpreter installed"); - - ScriptedFrameProviderInterfaceSP interface_sp = - script_interp->CreateScriptedFrameProviderInterface(); - if (!interface_sp) - return llvm::createStringError( - "cannot create scripted frame provider: script interpreter couldn't " - "create Scripted Frame Provider Interface"); - - const ScriptedMetadataSP scripted_metadata = descriptor.scripted_metadata_sp; - - // If we shouldn't attach a frame provider to this thread, just exit early. - if (!interface_sp->AppliesToThread(scripted_metadata->GetClassName(), - thread.shared_from_this())) - return nullptr; - - auto obj_or_err = interface_sp->CreatePluginObject( - scripted_metadata->GetClassName(), input_frames, - scripted_metadata->GetArgsSP()); - if (!obj_or_err) - return obj_or_err.takeError(); - - StructuredData::ObjectSP object_sp = *obj_or_err; - if (!object_sp || !object_sp->IsValid()) - return llvm::createStringError( - "cannot create scripted frame provider: failed to create valid scripted" - "frame provider object"); - - return std::make_shared(input_frames, interface_sp, - descriptor); -} - -ScriptedFrameProvider::ScriptedFrameProvider( - StackFrameListSP input_frames, - lldb::ScriptedFrameProviderInterfaceSP interface_sp, - const ScriptedFrameProviderDescriptor &descriptor) - : SyntheticFrameProvider(input_frames), m_interface_sp(interface_sp), - m_descriptor(descriptor) {} - -ScriptedFrameProvider::~ScriptedFrameProvider() = default; - -std::string ScriptedFrameProvider::GetDescription() const { - if (!m_interface_sp) - return {}; - - return m_interface_sp->GetDescription(m_descriptor.GetName()); -} - -llvm::Expected -ScriptedFrameProvider::GetFrameAtIndex(uint32_t idx) { - if (!m_interface_sp) - return llvm::createStringError( - "cannot get stack frame: scripted frame provider not initialized"); - - auto create_frame_from_dict = - [this](StructuredData::Dictionary *dict, - uint32_t index) -> llvm::Expected { - lldb::addr_t pc; - if (!dict->GetValueForKeyAsInteger("pc", pc)) - return llvm::createStringError( - "missing 'pc' key from scripted frame dictionary"); - - Address symbol_addr; - symbol_addr.SetLoadAddress(pc, &GetThread().GetProcess()->GetTarget()); - - const lldb::addr_t cfa = LLDB_INVALID_ADDRESS; - const bool cfa_is_valid = false; - const bool artificial = false; - const bool behaves_like_zeroth_frame = false; - SymbolContext sc; - symbol_addr.CalculateSymbolContext(&sc); - - ThreadSP thread_sp = GetThread().shared_from_this(); - return std::make_shared(thread_sp, index, index, cfa, - cfa_is_valid, pc, - StackFrame::Kind::Synthetic, artificial, - behaves_like_zeroth_frame, &sc); - }; - - auto create_frame_from_script_object = - [this]( - StructuredData::ObjectSP object_sp) -> llvm::Expected { - Status error; - if (!object_sp || !object_sp->GetAsGeneric()) - return llvm::createStringError("invalid script object"); - - ThreadSP thread_sp = GetThread().shared_from_this(); - auto frame_or_error = ScriptedFrame::Create(thread_sp, nullptr, nullptr, - object_sp->GetAsGeneric()); - - if (!frame_or_error) { - ScriptedInterface::ErrorWithMessage( - LLVM_PRETTY_FUNCTION, toString(frame_or_error.takeError()), error); - return error.ToError(); - } - - return *frame_or_error; - }; - - StructuredData::ObjectSP obj_sp = m_interface_sp->GetFrameAtIndex(idx); - - // None/null means no more frames or error. - if (!obj_sp || !obj_sp->IsValid()) - return llvm::createStringError("invalid script object returned for frame " + - llvm::Twine(idx)); - - StackFrameSP synth_frame_sp = nullptr; - if (StructuredData::UnsignedInteger *int_obj = - obj_sp->GetAsUnsignedInteger()) { - uint32_t real_frame_index = int_obj->GetValue(); - if (real_frame_index < m_input_frames->GetNumFrames()) { - synth_frame_sp = m_input_frames->GetFrameAtIndex(real_frame_index); - } - } else if (StructuredData::Dictionary *dict = obj_sp->GetAsDictionary()) { - // Check if it's a dictionary describing a frame. - auto frame_from_dict_or_err = create_frame_from_dict(dict, idx); - if (!frame_from_dict_or_err) { - return llvm::createStringError(llvm::Twine( - "couldn't create frame from dictionary at index " + llvm::Twine(idx) + - ": " + toString(frame_from_dict_or_err.takeError()))); - } - synth_frame_sp = *frame_from_dict_or_err; - } else if (obj_sp->GetAsGeneric()) { - // It's a ScriptedFrame object. - auto frame_from_script_obj_or_err = create_frame_from_script_object(obj_sp); - if (!frame_from_script_obj_or_err) { - return llvm::createStringError( - llvm::Twine("couldn't create frame from script object at index " + - llvm::Twine(idx) + ": " + - toString(frame_from_script_obj_or_err.takeError()))); - } - synth_frame_sp = *frame_from_script_obj_or_err; - } else { - return llvm::createStringError( - llvm::Twine("invalid return type from get_frame_at_index at index " + - llvm::Twine(idx))); - } - - if (!synth_frame_sp) - return llvm::createStringError( - llvm::Twine("failed to create frame at index " + llvm::Twine(idx))); - - synth_frame_sp->SetFrameIndex(idx); - - return synth_frame_sp; -} - -namespace lldb_private { -void lldb_initialize_ScriptedFrameProvider() { - ScriptedFrameProvider::Initialize(); -} - -void lldb_terminate_ScriptedFrameProvider() { - ScriptedFrameProvider::Terminate(); -} -} // namespace lldb_private diff --git a/lldb/source/Plugins/SyntheticFrameProvider/ScriptedFrameProvider/ScriptedFrameProvider.h b/lldb/source/Plugins/SyntheticFrameProvider/ScriptedFrameProvider/ScriptedFrameProvider.h deleted file mode 100644 index 3434bf26ade24..0000000000000 --- a/lldb/source/Plugins/SyntheticFrameProvider/ScriptedFrameProvider/ScriptedFrameProvider.h +++ /dev/null @@ -1,53 +0,0 @@ -//===----------------------------------------------------------------------===// -// -// 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 -// -//===----------------------------------------------------------------------===// - -#ifndef LLDB_PLUGINS_SYNTHETICFRAMEPROVIDER_SCRIPTEDFRAMEPROVIDER_SCRIPTEDFRAMEPROVIDER_H -#define LLDB_PLUGINS_SYNTHETICFRAMEPROVIDER_SCRIPTEDFRAMEPROVIDER_SCRIPTEDFRAMEPROVIDER_H - -#include "lldb/Target/SyntheticFrameProvider.h" -#include "lldb/Utility/ScriptedMetadata.h" -#include "lldb/Utility/Status.h" -#include "lldb/lldb-forward.h" -#include "llvm/Support/Error.h" - -namespace lldb_private { - -class ScriptedFrameProvider : public SyntheticFrameProvider { -public: - static llvm::StringRef GetPluginNameStatic() { - return "ScriptedFrameProvider"; - } - - static llvm::Expected - CreateInstance(lldb::StackFrameListSP input_frames, - const ScriptedFrameProviderDescriptor &descriptor); - - static void Initialize(); - - static void Terminate(); - - ScriptedFrameProvider(lldb::StackFrameListSP input_frames, - lldb::ScriptedFrameProviderInterfaceSP interface_sp, - const ScriptedFrameProviderDescriptor &descriptor); - ~ScriptedFrameProvider() override; - - llvm::StringRef GetPluginName() override { return GetPluginNameStatic(); } - - std::string GetDescription() const override; - - /// Get a single stack frame at the specified index. - llvm::Expected GetFrameAtIndex(uint32_t idx) override; - -private: - lldb::ScriptedFrameProviderInterfaceSP m_interface_sp; - const ScriptedFrameProviderDescriptor &m_descriptor; -}; - -} // namespace lldb_private - -#endif // LLDB_PLUGINS_SYNTHETICFRAMEPROVIDER_SCRIPTEDFRAMEPROVIDER_SCRIPTEDFRAMEPROVIDER_H diff --git a/lldb/source/Target/StackFrameList.cpp b/lldb/source/Target/StackFrameList.cpp index a661500ec862b..ccf874fc03ebd 100644 --- a/lldb/source/Target/StackFrameList.cpp +++ b/lldb/source/Target/StackFrameList.cpp @@ -20,7 +20,6 @@ #include "lldb/Target/StackFrame.h" #include "lldb/Target/StackFrameRecognizer.h" #include "lldb/Target/StopInfo.h" -#include "lldb/Target/SyntheticFrameProvider.h" #include "lldb/Target/Target.h" #include "lldb/Target/Thread.h" #include "lldb/Target/Unwind.h" @@ -56,40 +55,6 @@ StackFrameList::~StackFrameList() { Clear(); } -SyntheticStackFrameList::SyntheticStackFrameList( - Thread &thread, lldb::StackFrameListSP input_frames, - const lldb::StackFrameListSP &prev_frames_sp, bool show_inline_frames) - : StackFrameList(thread, prev_frames_sp, show_inline_frames), - m_input_frames(std::move(input_frames)) {} - -bool SyntheticStackFrameList::FetchFramesUpTo( - uint32_t end_idx, InterruptionControl allow_interrupt) { - // Check if the thread has a synthetic frame provider. - if (auto provider_sp = m_thread.GetFrameProvider()) { - // Use the synthetic frame provider to generate frames lazily. - // Keep fetching until we reach end_idx or the provider returns an error. - for (uint32_t idx = m_frames.size(); idx <= end_idx; idx++) { - if (allow_interrupt && - m_thread.GetProcess()->GetTarget().GetDebugger().InterruptRequested()) - return true; - auto frame_or_err = provider_sp->GetFrameAtIndex(idx); - if (!frame_or_err) { - // Provider returned error - we've reached the end. - LLDB_LOG_ERROR(GetLog(LLDBLog::Thread), frame_or_err.takeError(), - "Frame provider reached end at index {0}: {1}", idx); - SetAllFramesFetched(); - break; - } - m_frames.push_back(*frame_or_err); - } - - return false; // Not interrupted. - } - - // If no provider, fall back to the base implementation. - return StackFrameList::FetchFramesUpTo(end_idx, allow_interrupt); -} - void StackFrameList::CalculateCurrentInlinedDepth() { uint32_t cur_inlined_depth = GetCurrentInlinedDepth(); if (cur_inlined_depth == UINT32_MAX) { diff --git a/lldb/source/Target/SyntheticFrameProvider.cpp b/lldb/source/Target/SyntheticFrameProvider.cpp index 97ff42d1ed53e..241ce82c39be3 100644 --- a/lldb/source/Target/SyntheticFrameProvider.cpp +++ b/lldb/source/Target/SyntheticFrameProvider.cpp @@ -8,12 +8,10 @@ #include "lldb/Target/SyntheticFrameProvider.h" #include "lldb/Core/PluginManager.h" -#include "lldb/Interpreter/Interfaces/ScriptedFrameProviderInterface.h" #include "lldb/Target/Thread.h" #include "lldb/Utility/LLDBLog.h" #include "lldb/Utility/Log.h" #include "lldb/Utility/Status.h" -#include "lldb/Utility/Stream.h" using namespace lldb; using namespace lldb_private; @@ -23,17 +21,12 @@ SyntheticFrameProvider::SyntheticFrameProvider(StackFrameListSP input_frames) SyntheticFrameProvider::~SyntheticFrameProvider() = default; -void ScriptedFrameProviderDescriptor::Dump(Stream *s) const { +void SyntheticFrameProviderDescriptor::Dump(Stream *s) const { if (!s) return; - s->Format(" ID: {0:x}\n", GetID()); s->Printf(" Name: %s\n", GetName().str().c_str()); - std::string description = GetDescription(); - if (!description.empty()) - s->Printf(" Description: %s\n", description.c_str()); - // Show thread filter information. if (thread_specs.empty()) { s->PutCString(" Thread Filter: (applies to all threads)\n"); @@ -48,23 +41,9 @@ void ScriptedFrameProviderDescriptor::Dump(Stream *s) const { } } -uint32_t ScriptedFrameProviderDescriptor::GetID() const { - if (!scripted_metadata_sp) - return 0; - - return scripted_metadata_sp->GetID(); -} - -std::string ScriptedFrameProviderDescriptor::GetDescription() const { - // If we have an interface, call get_description() to fetch it. - if (interface_sp && scripted_metadata_sp) - return interface_sp->GetDescription(scripted_metadata_sp->GetClassName()); - return {}; -} - llvm::Expected SyntheticFrameProvider::CreateInstance( StackFrameListSP input_frames, - const ScriptedFrameProviderDescriptor &descriptor) { + const SyntheticFrameProviderDescriptor &descriptor) { if (!input_frames) return llvm::createStringError( "cannot create synthetic frame provider: invalid input frames"); diff --git a/lldb/source/Target/Target.cpp b/lldb/source/Target/Target.cpp index 3f182bc61392b..3b51e17d1c4e0 100644 --- a/lldb/source/Target/Target.cpp +++ b/lldb/source/Target/Target.cpp @@ -3718,61 +3718,6 @@ Status Target::Attach(ProcessAttachInfo &attach_info, Stream *stream) { return error; } -llvm::Expected Target::AddScriptedFrameProviderDescriptor( - const ScriptedFrameProviderDescriptor &descriptor) { - if (!descriptor.IsValid()) - return llvm::createStringError("invalid frame provider descriptor"); - - llvm::StringRef name = descriptor.GetName(); - if (name.empty()) - return llvm::createStringError( - "frame provider descriptor has no class name"); - - std::lock_guard guard( - m_frame_provider_descriptors_mutex); - - uint32_t descriptor_id = descriptor.GetID(); - m_frame_provider_descriptors[descriptor_id] = descriptor; - - // Clear frame providers on existing threads so they reload with new config. - if (ProcessSP process_sp = GetProcessSP()) - for (ThreadSP thread_sp : process_sp->Threads()) - thread_sp->ClearScriptedFrameProvider(); - - return descriptor_id; -} - -bool Target::RemoveScriptedFrameProviderDescriptor(uint32_t id) { - std::lock_guard guard( - m_frame_provider_descriptors_mutex); - bool removed = m_frame_provider_descriptors.erase(id); - - if (removed) - if (ProcessSP process_sp = GetProcessSP()) - for (ThreadSP thread_sp : process_sp->Threads()) - thread_sp->ClearScriptedFrameProvider(); - - return removed; -} - -void Target::ClearScriptedFrameProviderDescriptors() { - std::lock_guard guard( - m_frame_provider_descriptors_mutex); - - m_frame_provider_descriptors.clear(); - - if (ProcessSP process_sp = GetProcessSP()) - for (ThreadSP thread_sp : process_sp->Threads()) - thread_sp->ClearScriptedFrameProvider(); -} - -const llvm::DenseMap & -Target::GetScriptedFrameProviderDescriptors() const { - std::lock_guard guard( - m_frame_provider_descriptors_mutex); - return m_frame_provider_descriptors; -} - void Target::FinalizeFileActions(ProcessLaunchInfo &info) { Log *log = GetLog(LLDBLog::Process); diff --git a/lldb/source/Target/Thread.cpp b/lldb/source/Target/Thread.cpp index b40e753aca1e9..8c3e19725f8cb 100644 --- a/lldb/source/Target/Thread.cpp +++ b/lldb/source/Target/Thread.cpp @@ -13,12 +13,9 @@ #include "lldb/Core/Module.h" #include "lldb/Core/StructuredDataImpl.h" #include "lldb/Host/Host.h" -#include "lldb/Interpreter/Interfaces/ScriptedFrameInterface.h" -#include "lldb/Interpreter/Interfaces/ScriptedFrameProviderInterface.h" #include "lldb/Interpreter/OptionValueFileSpecList.h" #include "lldb/Interpreter/OptionValueProperties.h" #include "lldb/Interpreter/Property.h" -#include "lldb/Interpreter/ScriptInterpreter.h" #include "lldb/Symbol/Function.h" #include "lldb/Target/ABI.h" #include "lldb/Target/DynamicLoader.h" @@ -29,7 +26,6 @@ #include "lldb/Target/ScriptedThreadPlan.h" #include "lldb/Target/StackFrameRecognizer.h" #include "lldb/Target/StopInfo.h" -#include "lldb/Target/SyntheticFrameProvider.h" #include "lldb/Target/SystemRuntime.h" #include "lldb/Target/Target.h" #include "lldb/Target/ThreadPlan.h" @@ -49,7 +45,6 @@ #include "lldb/Utility/LLDBLog.h" #include "lldb/Utility/Log.h" #include "lldb/Utility/RegularExpression.h" -#include "lldb/Utility/ScriptedMetadata.h" #include "lldb/Utility/State.h" #include "lldb/Utility/Stream.h" #include "lldb/Utility/StreamString.h" @@ -262,7 +257,6 @@ void Thread::DestroyThread() { std::lock_guard guard(m_frame_mutex); m_curr_frames_sp.reset(); m_prev_frames_sp.reset(); - m_frame_provider_sp.reset(); m_prev_framezero_pc.reset(); } @@ -1445,76 +1439,13 @@ void Thread::CalculateExecutionContext(ExecutionContext &exe_ctx) { StackFrameListSP Thread::GetStackFrameList() { std::lock_guard guard(m_frame_mutex); - if (m_curr_frames_sp) - return m_curr_frames_sp; - - // First, try to load a frame provider if we don't have one yet. - if (!m_frame_provider_sp) { - ProcessSP process_sp = GetProcess(); - if (process_sp) { - Target &target = process_sp->GetTarget(); - const auto &descriptors = target.GetScriptedFrameProviderDescriptors(); - - // Find first descriptor that applies to this thread. - for (const auto &entry : descriptors) { - const ScriptedFrameProviderDescriptor &descriptor = entry.second; - if (descriptor.IsValid() && descriptor.AppliesToThread(*this)) { - if (llvm::Error error = LoadScriptedFrameProvider(descriptor)) { - LLDB_LOG_ERROR(GetLog(LLDBLog::Thread), std::move(error), - "Failed to load scripted frame provider: {0}"); - } - break; // Use first matching descriptor (success or failure). - } - } - } - } - - // Create the frame list based on whether we have a provider. - if (m_frame_provider_sp) { - // We have a provider - create synthetic frame list. - StackFrameListSP input_frames = m_frame_provider_sp->GetInputFrames(); - m_curr_frames_sp = std::make_shared( - *this, input_frames, m_prev_frames_sp, true); - } else { - // No provider - use normal unwinder frames. + if (!m_curr_frames_sp) m_curr_frames_sp = std::make_shared(*this, m_prev_frames_sp, true); - } return m_curr_frames_sp; } -llvm::Error Thread::LoadScriptedFrameProvider( - const ScriptedFrameProviderDescriptor &descriptor) { - std::lock_guard guard(m_frame_mutex); - - // Note: We don't create input_frames here - it will be created lazily - // by SyntheticStackFrameList when frames are first fetched. - // Creating them too early can cause crashes during thread initialization. - - // Create a temporary StackFrameList just to get the thread reference for the - // provider. The provider won't actually use this - it will get real input - // frames from SyntheticStackFrameList later. - StackFrameListSP temp_frames = - std::make_shared(*this, m_prev_frames_sp, true); - - auto provider_or_err = - SyntheticFrameProvider::CreateInstance(temp_frames, descriptor); - if (!provider_or_err) - return provider_or_err.takeError(); - - ClearScriptedFrameProvider(); - m_frame_provider_sp = *provider_or_err; - return llvm::Error::success(); -} - -void Thread::ClearScriptedFrameProvider() { - std::lock_guard guard(m_frame_mutex); - m_frame_provider_sp.reset(); - m_curr_frames_sp.reset(); - m_prev_frames_sp.reset(); -} - std::optional Thread::GetPreviousFrameZeroPC() { return m_prev_framezero_pc; } @@ -1535,7 +1466,6 @@ void Thread::ClearStackFrames() { m_prev_frames_sp.swap(m_curr_frames_sp); m_curr_frames_sp.reset(); - m_frame_provider_sp.reset(); m_extended_info.reset(); m_extended_info_fetched = false; } diff --git a/lldb/source/Target/ThreadSpec.cpp b/lldb/source/Target/ThreadSpec.cpp index 624f64e3af800..ba4c3aa894553 100644 --- a/lldb/source/Target/ThreadSpec.cpp +++ b/lldb/source/Target/ThreadSpec.cpp @@ -19,10 +19,6 @@ const char *ThreadSpec::g_option_names[static_cast( ThreadSpec::ThreadSpec() : m_name(), m_queue_name() {} -ThreadSpec::ThreadSpec(Thread &thread) - : m_index(thread.GetIndexID()), m_tid(thread.GetID()), - m_name(thread.GetName()), m_queue_name(thread.GetQueueName()) {} - std::unique_ptr ThreadSpec::CreateFromStructuredData( const StructuredData::Dictionary &spec_dict, Status &error) { uint32_t index = UINT32_MAX; diff --git a/lldb/test/API/functionalities/scripted_frame_provider/Makefile b/lldb/test/API/functionalities/scripted_frame_provider/Makefile deleted file mode 100644 index 99998b20bcb05..0000000000000 --- a/lldb/test/API/functionalities/scripted_frame_provider/Makefile +++ /dev/null @@ -1,3 +0,0 @@ -CXX_SOURCES := main.cpp - -include Makefile.rules diff --git a/lldb/test/API/functionalities/scripted_frame_provider/TestScriptedFrameProvider.py b/lldb/test/API/functionalities/scripted_frame_provider/TestScriptedFrameProvider.py deleted file mode 100644 index 189ca2f147f9d..0000000000000 --- a/lldb/test/API/functionalities/scripted_frame_provider/TestScriptedFrameProvider.py +++ /dev/null @@ -1,339 +0,0 @@ -""" -Test scripted frame provider functionality. -""" - -import os - -import lldb -from lldbsuite.test.lldbtest import TestBase -from lldbsuite.test import lldbutil - - -class ScriptedFrameProviderTestCase(TestBase): - NO_DEBUG_INFO_TESTCASE = True - - def setUp(self): - TestBase.setUp(self) - self.source = "main.cpp" - - def test_replace_all_frames(self): - """Test that we can replace the entire stack.""" - self.build() - target, process, thread, bkpt = lldbutil.run_to_source_breakpoint( - self, "Break here", lldb.SBFileSpec(self.source), only_one_thread=False - ) - - # Import the test frame provider - script_path = os.path.join(self.getSourceDir(), "test_frame_providers.py") - self.runCmd("command script import " + script_path) - - # Attach the Replace provider - error = lldb.SBError() - provider_id = target.RegisterScriptedFrameProvider( - "test_frame_providers.ReplaceFrameProvider", - lldb.SBStructuredData(), - error, - ) - self.assertTrue(error.Success(), f"Failed to register provider: {error}") - self.assertNotEqual(provider_id, 0, "Provider ID should be non-zero") - - # Verify we have exactly 3 synthetic frames - self.assertEqual(thread.GetNumFrames(), 3, "Should have 3 synthetic frames") - - # Verify frame indices and PCs (dictionary-based frames don't have custom function names) - frame0 = thread.GetFrameAtIndex(0) - self.assertIsNotNone(frame0) - self.assertEqual(frame0.GetPC(), 0x1000) - - frame1 = thread.GetFrameAtIndex(1) - self.assertIsNotNone(frame1) - self.assertIn("thread_func", frame1.GetFunctionName()) - - frame2 = thread.GetFrameAtIndex(2) - self.assertIsNotNone(frame2) - self.assertEqual(frame2.GetPC(), 0x3000) - - def test_prepend_frames(self): - """Test that we can add frames before real stack.""" - self.build() - target, process, thread, bkpt = lldbutil.run_to_source_breakpoint( - self, "Break here", lldb.SBFileSpec(self.source), only_one_thread=False - ) - - # Get original frame count and PC - original_frame_count = thread.GetNumFrames() - self.assertGreaterEqual( - original_frame_count, 2, "Should have at least 2 real frames" - ) - - # Import and attach Prepend provider - script_path = os.path.join(self.getSourceDir(), "test_frame_providers.py") - self.runCmd("command script import " + script_path) - - error = lldb.SBError() - provider_id = target.RegisterScriptedFrameProvider( - "test_frame_providers.PrependFrameProvider", - lldb.SBStructuredData(), - error, - ) - self.assertTrue(error.Success(), f"Failed to register provider: {error}") - self.assertNotEqual(provider_id, 0, "Provider ID should be non-zero") - - # Verify we have 2 more frames - new_frame_count = thread.GetNumFrames() - self.assertEqual(new_frame_count, original_frame_count + 2) - - # Verify first 2 frames are synthetic (check PCs, not function names) - frame0 = thread.GetFrameAtIndex(0) - self.assertEqual(frame0.GetPC(), 0x9000) - - frame1 = thread.GetFrameAtIndex(1) - self.assertEqual(frame1.GetPC(), 0xA000) - - # Verify frame 2 is the original real frame 0 - frame2 = thread.GetFrameAtIndex(2) - self.assertIn("thread_func", frame2.GetFunctionName()) - - def test_append_frames(self): - """Test that we can add frames after real stack.""" - self.build() - target, process, thread, bkpt = lldbutil.run_to_source_breakpoint( - self, "Break here", lldb.SBFileSpec(self.source), only_one_thread=False - ) - - # Get original frame count - original_frame_count = thread.GetNumFrames() - - # Import and attach Append provider - script_path = os.path.join(self.getSourceDir(), "test_frame_providers.py") - self.runCmd("command script import " + script_path) - - error = lldb.SBError() - provider_id = target.RegisterScriptedFrameProvider( - "test_frame_providers.AppendFrameProvider", - lldb.SBStructuredData(), - error, - ) - self.assertTrue(error.Success(), f"Failed to register provider: {error}") - self.assertNotEqual(provider_id, 0, "Provider ID should be non-zero") - - # Verify we have 1 more frame - new_frame_count = thread.GetNumFrames() - self.assertEqual(new_frame_count, original_frame_count + 1) - - # Verify first frames are still real - frame0 = thread.GetFrameAtIndex(0) - self.assertIn("thread_func", frame0.GetFunctionName()) - - frame_n_plus_1 = thread.GetFrameAtIndex(new_frame_count - 1) - self.assertEqual(frame_n_plus_1.GetPC(), 0x10) - - def test_scripted_frame_objects(self): - """Test that provider can return ScriptedFrame objects.""" - self.build() - target, process, thread, bkpt = lldbutil.run_to_source_breakpoint( - self, "Break here", lldb.SBFileSpec(self.source), only_one_thread=False - ) - - # Import the provider that returns ScriptedFrame objects - script_path = os.path.join(self.getSourceDir(), "test_frame_providers.py") - self.runCmd("command script import " + script_path) - - error = lldb.SBError() - provider_id = target.RegisterScriptedFrameProvider( - "test_frame_providers.ScriptedFrameObjectProvider", - lldb.SBStructuredData(), - error, - ) - self.assertTrue(error.Success(), f"Failed to register provider: {error}") - self.assertNotEqual(provider_id, 0, "Provider ID should be non-zero") - - # Verify we have 5 frames - self.assertEqual( - thread.GetNumFrames(), 5, "Should have 5 custom scripted frames" - ) - - # Verify frame properties from CustomScriptedFrame - frame0 = thread.GetFrameAtIndex(0) - self.assertIsNotNone(frame0) - self.assertEqual(frame0.GetFunctionName(), "custom_scripted_frame_0") - self.assertEqual(frame0.GetPC(), 0x5000) - self.assertTrue(frame0.IsSynthetic(), "Frame should be marked as synthetic") - - frame1 = thread.GetFrameAtIndex(1) - self.assertIsNotNone(frame1) - self.assertEqual(frame1.GetPC(), 0x6000) - - frame2 = thread.GetFrameAtIndex(2) - self.assertIsNotNone(frame2) - self.assertEqual(frame2.GetFunctionName(), "custom_scripted_frame_2") - self.assertEqual(frame2.GetPC(), 0x7000) - self.assertTrue(frame2.IsSynthetic(), "Frame should be marked as synthetic") - - def test_applies_to_thread(self): - """Test that applies_to_thread filters which threads get the provider.""" - self.build() - target, process, thread, bkpt = lldbutil.run_to_source_breakpoint( - self, "Break here", lldb.SBFileSpec(self.source), only_one_thread=False - ) - - # We should have at least 2 threads (worker threads) at the breakpoint - num_threads = process.GetNumThreads() - self.assertGreaterEqual( - num_threads, 2, "Should have at least 2 threads at breakpoint" - ) - - # Import the test frame provider - script_path = os.path.join(self.getSourceDir(), "test_frame_providers.py") - self.runCmd("command script import " + script_path) - - # Collect original thread info before applying provider - thread_info = {} - for i in range(num_threads): - t = process.GetThreadAtIndex(i) - thread_info[t.GetIndexID()] = { - "frame_count": t.GetNumFrames(), - "pc": t.GetFrameAtIndex(0).GetPC(), - } - - # Register the ThreadFilterFrameProvider which only applies to thread ID 1 - error = lldb.SBError() - provider_id = target.RegisterScriptedFrameProvider( - "test_frame_providers.ThreadFilterFrameProvider", - lldb.SBStructuredData(), - error, - ) - self.assertTrue(error.Success(), f"Failed to register provider: {error}") - self.assertNotEqual(provider_id, 0, "Provider ID should be non-zero") - - # Check each thread - thread_id_1_found = False - for i in range(num_threads): - t = process.GetThreadAtIndex(i) - thread_id = t.GetIndexID() - - if thread_id == 1: - # Thread with ID 1 should have synthetic frame - thread_id_1_found = True - self.assertEqual( - t.GetNumFrames(), - 1, - f"Thread with ID 1 should have 1 synthetic frame", - ) - self.assertEqual( - t.GetFrameAtIndex(0).GetPC(), - 0xFFFF, - f"Thread with ID 1 should have synthetic PC 0xFFFF", - ) - else: - # Other threads should keep their original frames - self.assertEqual( - t.GetNumFrames(), - thread_info[thread_id]["frame_count"], - f"Thread with ID {thread_id} should not be affected by provider", - ) - self.assertEqual( - t.GetFrameAtIndex(0).GetPC(), - thread_info[thread_id]["pc"], - f"Thread with ID {thread_id} should have its original PC", - ) - - # We should have found at least one thread with ID 1 - self.assertTrue( - thread_id_1_found, - "Should have found a thread with ID 1 to test filtering", - ) - - def test_remove_frame_provider_by_id(self): - """Test that RemoveScriptedFrameProvider removes a specific provider by ID.""" - self.build() - target, process, thread, bkpt = lldbutil.run_to_source_breakpoint( - self, "Break here", lldb.SBFileSpec(self.source), only_one_thread=False - ) - - # Import the test frame providers - script_path = os.path.join(self.getSourceDir(), "test_frame_providers.py") - self.runCmd("command script import " + script_path) - - # Get original frame count - original_frame_count = thread.GetNumFrames() - original_pc = thread.GetFrameAtIndex(0).GetPC() - - # Register the first provider and get its ID - error = lldb.SBError() - provider_id_1 = target.RegisterScriptedFrameProvider( - "test_frame_providers.ReplaceFrameProvider", - lldb.SBStructuredData(), - error, - ) - self.assertTrue(error.Success(), f"Failed to register provider 1: {error}") - - # Verify first provider is active (3 synthetic frames) - self.assertEqual(thread.GetNumFrames(), 3, "Should have 3 synthetic frames") - self.assertEqual( - thread.GetFrameAtIndex(0).GetPC(), 0x1000, "Should have first provider's PC" - ) - - # Register a second provider and get its ID - provider_id_2 = target.RegisterScriptedFrameProvider( - "test_frame_providers.PrependFrameProvider", - lldb.SBStructuredData(), - error, - ) - self.assertTrue(error.Success(), f"Failed to register provider 2: {error}") - - # Verify IDs are different - self.assertNotEqual( - provider_id_1, provider_id_2, "Provider IDs should be unique" - ) - - # Now remove the first provider by ID - result = target.RemoveScriptedFrameProvider(provider_id_1) - self.assertSuccess( - result, f"Should successfully remove provider with ID {provider_id_1}" - ) - - # After removing the first provider, the second provider should still be active - # The PrependFrameProvider adds 2 frames before the real stack - # Since ReplaceFrameProvider had 3 frames, and we removed it, we should now - # have the original frames (from real stack) with PrependFrameProvider applied - new_frame_count = thread.GetNumFrames() - self.assertEqual( - new_frame_count, - original_frame_count + 2, - "Should have original frames + 2 prepended frames", - ) - - # First two frames should be from PrependFrameProvider - self.assertEqual( - thread.GetFrameAtIndex(0).GetPC(), - 0x9000, - "First frame should be from PrependFrameProvider", - ) - self.assertEqual( - thread.GetFrameAtIndex(1).GetPC(), - 0xA000, - "Second frame should be from PrependFrameProvider", - ) - - # Remove the second provider - result = target.RemoveScriptedFrameProvider(provider_id_2) - self.assertSuccess( - result, f"Should successfully remove provider with ID {provider_id_2}" - ) - - # After removing both providers, frames should be back to original - self.assertEqual( - thread.GetNumFrames(), - original_frame_count, - "Should restore original frame count", - ) - self.assertEqual( - thread.GetFrameAtIndex(0).GetPC(), - original_pc, - "Should restore original PC", - ) - - # Try to remove a provider that doesn't exist - result = target.RemoveScriptedFrameProvider(999999) - self.assertTrue(result.Fail(), "Should fail to remove non-existent provider") diff --git a/lldb/test/API/functionalities/scripted_frame_provider/main.cpp b/lldb/test/API/functionalities/scripted_frame_provider/main.cpp deleted file mode 100644 index f15cb282f9d25..0000000000000 --- a/lldb/test/API/functionalities/scripted_frame_provider/main.cpp +++ /dev/null @@ -1,55 +0,0 @@ -// Multi-threaded test program for testing frame providers. - -#include -#include -#include -#include - -std::mutex mtx; -std::condition_variable cv; -int ready_count = 0; -constexpr int NUM_THREADS = 2; - -void thread_func(int thread_num) { - std::cout << "Thread " << thread_num << " started\n"; - - { - std::unique_lock lock(mtx); - ready_count++; - if (ready_count == NUM_THREADS + 1) { - cv.notify_all(); - } else { - cv.wait(lock, [] { return ready_count == NUM_THREADS + 1; }); - } - } - - std::cout << "Thread " << thread_num << " at breakpoint\n"; // Break here -} - -int main(int argc, char **argv) { - std::thread threads[NUM_THREADS]; - - for (int i = 0; i < NUM_THREADS; i++) { - threads[i] = std::thread(thread_func, i); - } - - { - std::unique_lock lock(mtx); - ready_count++; - if (ready_count == NUM_THREADS + 1) { - cv.notify_all(); - } else { - cv.wait(lock, [] { return ready_count == NUM_THREADS + 1; }); - } - } - - std::cout << "Main thread at barrier\n"; - - // Join threads - for (int i = 0; i < NUM_THREADS; i++) { - threads[i].join(); - } - - std::cout << "All threads completed\n"; - return 0; -} diff --git a/lldb/test/API/functionalities/scripted_frame_provider/test_frame_providers.py b/lldb/test/API/functionalities/scripted_frame_provider/test_frame_providers.py deleted file mode 100644 index 91aa13e44339a..0000000000000 --- a/lldb/test/API/functionalities/scripted_frame_provider/test_frame_providers.py +++ /dev/null @@ -1,176 +0,0 @@ -""" -Test frame providers for scripted frame provider functionality. - -These providers demonstrate various merge strategies: -- Replace: Replace entire stack -- Prepend: Add frames before real stack -- Append: Add frames after real stack - -It also shows the ability to mix a dictionary, a ScriptedFrame or an SBFrame -index to create stackframes -""" - -import lldb -from lldb.plugins.scripted_process import ScriptedFrame -from lldb.plugins.scripted_frame_provider import ScriptedFrameProvider - - -class ReplaceFrameProvider(ScriptedFrameProvider): - """Replace entire stack with custom frames.""" - - def __init__(self, input_frames, args): - super().__init__(input_frames, args) - self.frames = [ - { - "idx": 0, - "pc": 0x1000, - }, - 0, - { - "idx": 2, - "pc": 0x3000, - }, - ] - - @staticmethod - def get_description(): - """Return a description of this provider.""" - return "Replace entire stack with 3 custom frames" - - def get_frame_at_index(self, index): - if index >= len(self.frames): - return None - return self.frames[index] - - -class PrependFrameProvider(ScriptedFrameProvider): - """Prepend synthetic frames before real stack.""" - - def __init__(self, input_frames, args): - super().__init__(input_frames, args) - - @staticmethod - def get_description(): - """Return a description of this provider.""" - return "Prepend 2 synthetic frames before real stack" - - def get_frame_at_index(self, index): - if index == 0: - return {"pc": 0x9000} - elif index == 1: - return {"pc": 0xA000} - elif index - 2 < len(self.input_frames): - return index - 2 # Return real frame index - return None - - -class AppendFrameProvider(ScriptedFrameProvider): - """Append synthetic frames after real stack.""" - - def __init__(self, input_frames, args): - super().__init__(input_frames, args) - - @staticmethod - def get_description(): - """Return a description of this provider.""" - return "Append 1 synthetic frame after real stack" - - def get_frame_at_index(self, index): - if index < len(self.input_frames): - return index # Return real frame index - elif index == len(self.input_frames): - return { - "idx": 1, - "pc": 0x10, - } - return None - - -class CustomScriptedFrame(ScriptedFrame): - """Custom scripted frame with full control over frame behavior.""" - - def __init__(self, thread, idx, pc, function_name): - # Initialize structured data args - args = lldb.SBStructuredData() - super().__init__(thread, args) - - self.idx = idx - self.pc = pc - self.function_name = function_name - - def get_id(self): - """Return the frame index.""" - return self.idx - - def get_pc(self): - """Return the program counter.""" - return self.pc - - def get_function_name(self): - """Return the function name.""" - return self.function_name - - def is_artificial(self): - """Mark as artificial frame.""" - return False - - def is_hidden(self): - """Not hidden.""" - return False - - def get_register_context(self): - """No register context for this test.""" - return None - - -class ScriptedFrameObjectProvider(ScriptedFrameProvider): - """Provider that returns ScriptedFrame objects instead of dictionaries.""" - - def __init__(self, input_frames, args): - super().__init__(input_frames, args) - - @staticmethod - def get_description(): - """Return a description of this provider.""" - return "Provider returning custom ScriptedFrame objects" - - def get_frame_at_index(self, index): - """Return ScriptedFrame objects or dictionaries based on index.""" - if index == 0: - return CustomScriptedFrame( - self.thread, 0, 0x5000, "custom_scripted_frame_0" - ) - elif index == 1: - return {"pc": 0x6000} - elif index == 2: - return CustomScriptedFrame( - self.thread, 2, 0x7000, "custom_scripted_frame_2" - ) - elif index == 3: - return len(self.input_frames) - 2 # Real frame index - elif index == 4: - return len(self.input_frames) - 1 # Real frame index - return None - - -class ThreadFilterFrameProvider(ScriptedFrameProvider): - """Provider that only applies to thread with ID 1.""" - - @staticmethod - def applies_to_thread(thread): - """Only apply to thread with index ID 1.""" - return thread.GetIndexID() == 1 - - def __init__(self, input_frames, args): - super().__init__(input_frames, args) - - @staticmethod - def get_description(): - """Return a description of this provider.""" - return "Provider that only applies to thread ID 1" - - def get_frame_at_index(self, index): - """Return a single synthetic frame.""" - if index == 0: - return {"pc": 0xFFFF} - return None diff --git a/lldb/unittests/ScriptInterpreter/Python/PythonTestSuite.cpp b/lldb/unittests/ScriptInterpreter/Python/PythonTestSuite.cpp index 5694aeeff3e5b..a63b740d9472f 100644 --- a/lldb/unittests/ScriptInterpreter/Python/PythonTestSuite.cpp +++ b/lldb/unittests/ScriptInterpreter/Python/PythonTestSuite.cpp @@ -136,11 +136,6 @@ lldb_private::python::LLDBSWIGPython_CastPyObjectToSBStream(PyObject *data) { return nullptr; } -void * -lldb_private::python::LLDBSWIGPython_CastPyObjectToSBThread(PyObject *data) { - return nullptr; -} - void * lldb_private::python::LLDBSWIGPython_CastPyObjectToSBFrame(PyObject *data) { return nullptr;