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