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