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 23namespace 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 31class RecognizedStackFrame 32 : public std::enable_shared_from_this<RecognizedStackFrame> { 33public: 34 virtual lldb::ValueObjectListSP GetRecognizedArguments() { 35 return m_arguments; 36 } 37 virtual lldb::ValueObjectSP GetExceptionObject() { 38 return lldb::ValueObjectSP(); 39 } 40 virtual lldb::StackFrameSP GetMostRelevantFrame() { return nullptr; }; 41 virtual ~RecognizedStackFrame() = default; 42 43 std::string GetStopDescription() { return m_stop_desc; } 44 45protected: 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 56class StackFrameRecognizer 57 : public std::enable_shared_from_this<StackFrameRecognizer> { 58public: 59 virtual lldb::RecognizedStackFrameSP RecognizeFrame( 60 lldb::StackFrameSP frame) { 61 return lldb::RecognizedStackFrameSP(); 62 }; 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 76class 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 81public: 82 ScriptedStackFrameRecognizer(lldb_private::ScriptInterpreter *interpreter, 83 const char *pclass); 84 ~ScriptedStackFrameRecognizer() override = default; 85 86 std::string GetName() override { 87 return GetPythonClassName(); 88 } 89 90 const char *GetPythonClassName() { return m_python_class.c_str(); } 91 92 lldb::RecognizedStackFrameSP RecognizeFrame( 93 lldb::StackFrameSP frame) override; 94 95private: 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. 102class StackFrameRecognizerManager { 103public: 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 126private: 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 147class ValueObjectRecognizerSynthesizedValue : public ValueObject { 148 public: 149 static lldb::ValueObjectSP Create(ValueObject &parent, lldb::ValueType type) { 150 return (new ValueObjectRecognizerSynthesizedValue(parent, type))->GetSP(); 151 } 152 ValueObjectRecognizerSynthesizedValue(ValueObject &parent, 153 lldb::ValueType type) 154 : ValueObject(parent), m_type(type) { 155 SetName(parent.GetName()); 156 } 157 158 std::optional<uint64_t> GetByteSize() override { 159 return m_parent->GetByteSize(); 160 } 161 lldb::ValueType GetValueType() const override { return m_type; } 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 } 170 CompilerType GetCompilerTypeImpl() override { 171 return m_parent->GetCompilerType(); 172 } 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