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