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