xref: /freebsd/contrib/llvm-project/lldb/include/lldb/Target/StackFrameRecognizer.h (revision 0fca6ea1d4eea4c934cfff25ac9ee8ad6fe95583)
1 //===-- StackFrameRecognizer.h ----------------------------------*- C++ -*-===//
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_STACKFRAMERECOGNIZER_H
10 #define LLDB_TARGET_STACKFRAMERECOGNIZER_H
11 
12 #include "lldb/Core/ValueObject.h"
13 #include "lldb/Core/ValueObjectList.h"
14 #include "lldb/Symbol/VariableList.h"
15 #include "lldb/Target/StopInfo.h"
16 #include "lldb/Utility/StructuredData.h"
17 #include "lldb/lldb-private-forward.h"
18 #include "lldb/lldb-public.h"
19 
20 #include <deque>
21 #include <optional>
22 #include <vector>
23 
24 namespace lldb_private {
25 
26 /// \class RecognizedStackFrame
27 ///
28 /// This class provides extra information about a stack frame that was
29 /// provided by a specific stack frame recognizer. Right now, this class only
30 /// holds recognized arguments (via GetRecognizedArguments).
31 
32 class RecognizedStackFrame
33     : public std::enable_shared_from_this<RecognizedStackFrame> {
34 public:
GetRecognizedArguments()35   virtual lldb::ValueObjectListSP GetRecognizedArguments() {
36     return m_arguments;
37   }
GetExceptionObject()38   virtual lldb::ValueObjectSP GetExceptionObject() {
39     return lldb::ValueObjectSP();
40   }
GetMostRelevantFrame()41   virtual lldb::StackFrameSP GetMostRelevantFrame() { return nullptr; };
42   virtual ~RecognizedStackFrame() = default;
43 
GetStopDescription()44   std::string GetStopDescription() { return m_stop_desc; }
45 
46 protected:
47   lldb::ValueObjectListSP m_arguments;
48   std::string m_stop_desc;
49 };
50 
51 /// \class StackFrameRecognizer
52 ///
53 /// A base class for frame recognizers. Subclasses (actual frame recognizers)
54 /// should implement RecognizeFrame to provide a RecognizedStackFrame for a
55 /// given stack frame.
56 
57 class StackFrameRecognizer
58     : public std::enable_shared_from_this<StackFrameRecognizer> {
59 public:
RecognizeFrame(lldb::StackFrameSP frame)60   virtual lldb::RecognizedStackFrameSP RecognizeFrame(
61       lldb::StackFrameSP frame) {
62     return lldb::RecognizedStackFrameSP();
63   };
GetName()64   virtual std::string GetName() {
65     return "";
66   }
67 
68   virtual ~StackFrameRecognizer() = default;
69 };
70 
71 /// \class ScriptedStackFrameRecognizer
72 ///
73 /// Python implementation for frame recognizers. An instance of this class
74 /// tracks a particular Python classobject, which will be asked to recognize
75 /// stack frames.
76 
77 class ScriptedStackFrameRecognizer : public StackFrameRecognizer {
78   lldb_private::ScriptInterpreter *m_interpreter;
79   lldb_private::StructuredData::ObjectSP m_python_object_sp;
80   std::string m_python_class;
81 
82 public:
83   ScriptedStackFrameRecognizer(lldb_private::ScriptInterpreter *interpreter,
84                                const char *pclass);
85   ~ScriptedStackFrameRecognizer() override = default;
86 
GetName()87   std::string GetName() override {
88     return GetPythonClassName();
89   }
90 
GetPythonClassName()91   const char *GetPythonClassName() { return m_python_class.c_str(); }
92 
93   lldb::RecognizedStackFrameSP RecognizeFrame(
94       lldb::StackFrameSP frame) override;
95 
96 private:
97   ScriptedStackFrameRecognizer(const ScriptedStackFrameRecognizer &) = delete;
98   const ScriptedStackFrameRecognizer &
99   operator=(const ScriptedStackFrameRecognizer &) = delete;
100 };
101 
102 /// Class that provides a registry of known stack frame recognizers.
103 class StackFrameRecognizerManager {
104 public:
105   void AddRecognizer(lldb::StackFrameRecognizerSP recognizer,
106                      ConstString module, llvm::ArrayRef<ConstString> symbols,
107                      bool first_instruction_only = true);
108 
109   void AddRecognizer(lldb::StackFrameRecognizerSP recognizer,
110                      lldb::RegularExpressionSP module,
111                      lldb::RegularExpressionSP symbol,
112                      bool first_instruction_only = true);
113 
114   void ForEach(std::function<
115                void(uint32_t recognizer_id, std::string recognizer_name,
116                     std::string module, llvm::ArrayRef<ConstString> symbols,
117                     bool regexp)> const &callback);
118 
119   bool RemoveRecognizerWithID(uint32_t recognizer_id);
120 
121   void RemoveAllRecognizers();
122 
123   lldb::StackFrameRecognizerSP GetRecognizerForFrame(lldb::StackFrameSP frame);
124 
125   lldb::RecognizedStackFrameSP RecognizeFrame(lldb::StackFrameSP frame);
126 
127 private:
128   struct RegisteredEntry {
129     uint32_t recognizer_id;
130     lldb::StackFrameRecognizerSP recognizer;
131     bool is_regexp;
132     ConstString module;
133     lldb::RegularExpressionSP module_regexp;
134     std::vector<ConstString> symbols;
135     lldb::RegularExpressionSP symbol_regexp;
136     bool first_instruction_only;
137   };
138 
139   std::deque<RegisteredEntry> m_recognizers;
140 };
141 
142 /// \class ValueObjectRecognizerSynthesizedValue
143 ///
144 /// ValueObject subclass that presents the passed ValueObject as a recognized
145 /// value with the specified ValueType. Frame recognizers should return
146 /// instances of this class as the returned objects in GetRecognizedArguments().
147 
148 class ValueObjectRecognizerSynthesizedValue : public ValueObject {
149  public:
Create(ValueObject & parent,lldb::ValueType type)150   static lldb::ValueObjectSP Create(ValueObject &parent, lldb::ValueType type) {
151     return (new ValueObjectRecognizerSynthesizedValue(parent, type))->GetSP();
152   }
ValueObjectRecognizerSynthesizedValue(ValueObject & parent,lldb::ValueType type)153   ValueObjectRecognizerSynthesizedValue(ValueObject &parent,
154                                         lldb::ValueType type)
155       : ValueObject(parent), m_type(type) {
156     SetName(parent.GetName());
157   }
158 
GetByteSize()159   std::optional<uint64_t> GetByteSize() override {
160     return m_parent->GetByteSize();
161   }
GetValueType()162   lldb::ValueType GetValueType() const override { return m_type; }
UpdateValue()163   bool UpdateValue() override {
164     if (!m_parent->UpdateValueIfNeeded()) return false;
165     m_value = m_parent->GetValue();
166     return true;
167   }
168   llvm::Expected<uint32_t>
169   CalculateNumChildren(uint32_t max = UINT32_MAX) override {
170     return m_parent->GetNumChildren(max);
171   }
GetCompilerTypeImpl()172   CompilerType GetCompilerTypeImpl() override {
173     return m_parent->GetCompilerType();
174   }
IsSynthetic()175   bool IsSynthetic() override { return true; }
176 
177  private:
178   lldb::ValueType m_type;
179 };
180 
181 } // namespace lldb_private
182 
183 #endif // LLDB_TARGET_STACKFRAMERECOGNIZER_H
184