LLDB mainline
SyntheticFrameProvider.h
Go to the documentation of this file.
1//===----------------------------------------------------------------------===//
2//
3// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
4// See https://llvm.org/LICENSE.txt for license information.
5// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
6//
7//===----------------------------------------------------------------------===//
8
9#ifndef LLDB_TARGET_SYNTHETICFRAMEPROVIDER_H
10#define LLDB_TARGET_SYNTHETICFRAMEPROVIDER_H
11
16#include "lldb/Utility/Status.h"
17#include "lldb/lldb-forward.h"
18#include "llvm/Support/Error.h"
19
20#include <optional>
21#include <vector>
22
23namespace lldb_private {
24
25/// This struct contains the metadata needed to instantiate a frame provider
26/// and optional filters to control which threads it applies to.
28 /// Metadata for instantiating the provider (e.g. script class name and args).
30
31 /// Interface for calling static methods on the provider class.
33
34 /// Optional list of thread specifications to which this provider applies.
35 /// If empty, the provider applies to all threads. A thread matches if it
36 /// satisfies ANY of the specs in this vector (OR logic).
37 std::vector<ThreadSpec> thread_specs;
38
39 /// Monotonically increasing ID assigned by Target when this descriptor is
40 /// registered. LLDB_INVALID_FRAME_PROVIDER_ID (UINT32_MAX) means no ID has
41 /// been assigned yet.
43
45
48
50 const std::vector<ThreadSpec> &specs)
51 : scripted_metadata_sp(metadata_sp), thread_specs(specs) {}
52
53 /// Get the name of this descriptor (the scripted class name).
54 llvm::StringRef GetName() const {
55 return scripted_metadata_sp ? scripted_metadata_sp->GetClassName() : "";
56 }
57
58 /// Get the description of this frame provider.
59 ///
60 /// \return A string describing what this frame provider does, or an
61 /// empty string if no description is available.
62 std::string GetDescription() const;
63
64 /// Get the priority of this frame provider.
65 ///
66 /// Priority determines the order in which providers are evaluated when
67 /// multiple providers could apply to the same thread. Lower numbers indicate
68 /// higher priority (like Unix nice values).
69 ///
70 /// \return Priority value where 0 is highest priority, or std::nullopt for
71 /// default priority (UINT32_MAX - lowest priority).
72 std::optional<uint32_t> GetPriority() const;
73
74 /// Check if this descriptor applies to the given thread.
75 bool AppliesToThread(Thread &thread) const {
76 // If no thread specs specified, applies to all threads.
77 if (thread_specs.empty())
78 return true;
79
80 // Check if the thread matches any of the specs (OR logic).
81 for (const auto &spec : thread_specs) {
82 if (spec.ThreadPassesBasicTests(thread))
83 return true;
84 }
85 return false;
86 }
87
88 /// Check if this descriptor has valid metadata for script-based providers.
89 bool IsValid() const { return scripted_metadata_sp != nullptr; }
90
91 /// Get a unique identifier for this descriptor.
92 /// Returns the monotonically increasing ID assigned by Target if set,
93 /// otherwise returns LLDB_INVALID_FRAME_PROVIDER_ID (UINT32_MAX).
94 uint32_t GetID() const { return m_id; }
95
96 /// Set the monotonically increasing ID for this descriptor. Called by Target
97 /// when the descriptor is registered.
98 void SetID(uint32_t id) { m_id = id; }
99
100 /// Get the content-based hash from ScriptedMetadata.
101 /// Used for duplicate detection (same class name + args).
102 uint32_t GetHash() const;
103
104 /// Dump a description of this descriptor to the given stream.
105 void Dump(Stream *s) const;
106};
107
108/// Base class for all synthetic frame providers.
109///
110/// Synthetic frame providers allow modifying or replacing the stack frames
111/// shown for a thread. This is useful for:
112/// - Providing frames for custom calling conventions or languages.
113/// - Reconstructing missing frames from crash dumps or core files.
114/// - Adding diagnostic or synthetic frames for debugging.
115/// - Visualizing state machines or async execution contexts.
117public:
118 /// Try to create a SyntheticFrameProvider instance for the given input
119 /// frames and descriptor.
120 ///
121 /// This method iterates through all registered SyntheticFrameProvider
122 /// plugins and returns the first one that can handle the given descriptor.
123 ///
124 /// \param[in] input_frames
125 /// The input stack frame list that this provider will transform.
126 /// This could be real unwound frames or output from another provider.
127 ///
128 /// \param[in] descriptor
129 /// The descriptor containing metadata for the provider.
130 ///
131 /// \return
132 /// A shared pointer to a SyntheticFrameProvider if one could be created,
133 /// otherwise an \a llvm::Error.
134 static llvm::Expected<lldb::SyntheticFrameProviderSP>
136 const ScriptedFrameProviderDescriptor &descriptor);
137
138 /// Try to create a SyntheticFrameProvider instance for the given input
139 /// frames using a specific C++ plugin.
140 ///
141 /// This method directly invokes a specific SyntheticFrameProvider plugin
142 /// by name, bypassing the descriptor-based plugin iteration. This is useful
143 /// for C++ plugins that don't require scripted metadata.
144 ///
145 /// \param[in] input_frames
146 /// The input stack frame list that this provider will transform.
147 /// This could be real unwound frames or output from another provider.
148 ///
149 /// \param[in] plugin_name
150 /// The name of the plugin to use for creating the provider.
151 ///
152 /// \param[in] thread_specs
153 /// Optional list of thread specifications to which this provider applies.
154 /// If empty, the provider applies to all threads.
155 ///
156 /// \return
157 /// A shared pointer to a SyntheticFrameProvider if one could be created,
158 /// otherwise an \a llvm::Error.
159 static llvm::Expected<lldb::SyntheticFrameProviderSP>
161 llvm::StringRef plugin_name,
162 const std::vector<ThreadSpec> &thread_specs = {});
163
165
166 virtual std::string GetDescription() const = 0;
167
168 /// Get the priority of this frame provider.
169 ///
170 /// Priority determines the order in which providers are evaluated when
171 /// multiple providers could apply to the same thread. Lower numbers indicate
172 /// higher priority (like Unix nice values).
173 ///
174 /// \return
175 /// Priority value where 0 is highest priority, or std::nullopt for
176 /// default priority (UINT32_MAX - lowest priority).
177 virtual std::optional<uint32_t> GetPriority() const { return std::nullopt; }
178
179 /// Get a single stack frame at the specified index.
180 ///
181 /// This method is called lazily - frames are only created when requested.
182 /// The provider can access its input frames via GetInputFrames() if needed.
183 ///
184 /// \param[in] idx
185 /// The index of the frame to create.
186 ///
187 /// \return
188 /// An Expected containing the StackFrameSP if successful. Returns an
189 /// error when the index is beyond the last frame to signal the end of
190 /// the frame list.
191 virtual llvm::Expected<lldb::StackFrameSP> GetFrameAtIndex(uint32_t idx) = 0;
192
193 /// Get the thread associated with this provider.
194 Thread &GetThread() { return m_input_frames->GetThread(); }
195
196 /// Get the input frames that this provider transforms.
198
199protected:
201
203};
204
205} // namespace lldb_private
206
207#endif // LLDB_TARGET_SYNTHETICFRAMEPROVIDER_H
A stream class that can stream formatted output to a file.
Definition Stream.h:28
Thread & GetThread()
Get the thread associated with this provider.
lldb::StackFrameListSP GetInputFrames() const
Get the input frames that this provider transforms.
virtual std::string GetDescription() const =0
static llvm::Expected< lldb::SyntheticFrameProviderSP > CreateInstance(lldb::StackFrameListSP input_frames, const ScriptedFrameProviderDescriptor &descriptor)
Try to create a SyntheticFrameProvider instance for the given input frames and descriptor.
virtual llvm::Expected< lldb::StackFrameSP > GetFrameAtIndex(uint32_t idx)=0
Get a single stack frame at the specified index.
SyntheticFrameProvider(lldb::StackFrameListSP input_frames)
virtual std::optional< uint32_t > GetPriority() const
Get the priority of this frame provider.
#define LLDB_INVALID_FRAME_PROVIDER_ID
A class that represents a running process on the host machine.
std::shared_ptr< lldb_private::ScriptedMetadata > ScriptedMetadataSP
std::shared_ptr< lldb_private::ScriptedFrameProviderInterface > ScriptedFrameProviderInterfaceSP
std::shared_ptr< lldb_private::StackFrameList > StackFrameListSP
This struct contains the metadata needed to instantiate a frame provider and optional filters to cont...
ScriptedFrameProviderDescriptor(lldb::ScriptedMetadataSP metadata_sp)
std::vector< ThreadSpec > thread_specs
Optional list of thread specifications to which this provider applies.
uint32_t GetID() const
Get a unique identifier for this descriptor.
lldb::ScriptedMetadataSP scripted_metadata_sp
Metadata for instantiating the provider (e.g. script class name and args).
void Dump(Stream *s) const
Dump a description of this descriptor to the given stream.
llvm::StringRef GetName() const
Get the name of this descriptor (the scripted class name).
lldb::ScriptedFrameProviderInterfaceSP interface_sp
Interface for calling static methods on the provider class.
ScriptedFrameProviderDescriptor(lldb::ScriptedMetadataSP metadata_sp, const std::vector< ThreadSpec > &specs)
uint32_t GetHash() const
Get the content-based hash from ScriptedMetadata.
std::string GetDescription() const
Get the description of this frame provider.
uint32_t m_id
Monotonically increasing ID assigned by Target when this descriptor is registered.
bool AppliesToThread(Thread &thread) const
Check if this descriptor applies to the given thread.
void SetID(uint32_t id)
Set the monotonically increasing ID for this descriptor.
bool IsValid() const
Check if this descriptor has valid metadata for script-based providers.
std::optional< uint32_t > GetPriority() const
Get the priority of this frame provider.