LLDB  mainline
StackFrameRecognizer.cpp
Go to the documentation of this file.
1 //===-- StackFrameRecognizer.cpp --------------------------------*- 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 #include <vector>
10 #include "lldb/Core/Module.h"
12 #include "lldb/Symbol/Symbol.h"
13 #include "lldb/Target/StackFrame.h"
16 
17 using namespace lldb;
18 using namespace lldb_private;
19 
21 public:
22  ScriptedRecognizedStackFrame(ValueObjectListSP args) {
23  m_arguments = args;
24  }
25 };
26 
27 ScriptedStackFrameRecognizer::ScriptedStackFrameRecognizer(
28  ScriptInterpreter *interpreter, const char *pclass)
29  : m_interpreter(interpreter), m_python_class(pclass) {
30  m_python_object_sp =
31  m_interpreter->CreateFrameRecognizer(m_python_class.c_str());
32 }
33 
34 RecognizedStackFrameSP
36  if (!m_python_object_sp || !m_interpreter)
37  return RecognizedStackFrameSP();
38 
39  ValueObjectListSP args =
40  m_interpreter->GetRecognizedArguments(m_python_object_sp, frame);
41  auto args_synthesized = ValueObjectListSP(new ValueObjectList());
42  for (const auto o : args->GetObjects()) {
43  args_synthesized->Append(ValueObjectRecognizerSynthesizedValue::Create(
45  }
46 
47  return RecognizedStackFrameSP(
48  new ScriptedRecognizedStackFrame(args_synthesized));
49 }
50 
52 public:
53  void AddRecognizer(StackFrameRecognizerSP recognizer,
54  ConstString module, ConstString symbol,
55  bool first_instruction_only) {
56  m_recognizers.push_front({(uint32_t)m_recognizers.size(), false, recognizer, false, module, RegularExpressionSP(),
57  symbol, RegularExpressionSP(),
58  first_instruction_only});
59  }
60 
61  void AddRecognizer(StackFrameRecognizerSP recognizer,
62  RegularExpressionSP module, RegularExpressionSP symbol,
63  bool first_instruction_only) {
64  m_recognizers.push_front({(uint32_t)m_recognizers.size(), false, recognizer, true, ConstString(), module,
65  ConstString(), symbol, first_instruction_only});
66  }
67 
68  void ForEach(
69  std::function<void(uint32_t recognized_id, std::string recognizer_name, std::string module,
70  std::string symbol, bool regexp)> const &callback) {
71  for (auto entry : m_recognizers) {
72  if (entry.is_regexp) {
73  callback(entry.recognizer_id, entry.recognizer->GetName(), entry.module_regexp->GetText(),
74  entry.symbol_regexp->GetText(), true);
75  } else {
76  callback(entry.recognizer_id, entry.recognizer->GetName(), entry.module.GetCString(),
77  entry.symbol.GetCString(), false);
78  }
79  }
80  }
81 
82  bool RemoveRecognizerWithID(uint32_t recognizer_id) {
83  if (recognizer_id >= m_recognizers.size()) return false;
84  if (m_recognizers[recognizer_id].deleted) return false;
85  m_recognizers[recognizer_id].deleted = true;
86  return true;
87  }
88 
90  m_recognizers.clear();
91  }
92 
93  StackFrameRecognizerSP GetRecognizerForFrame(StackFrameSP frame) {
94  const SymbolContext &symctx =
95  frame->GetSymbolContext(eSymbolContextModule | eSymbolContextFunction);
96  ConstString function_name = symctx.GetFunctionName();
97  ModuleSP module_sp = symctx.module_sp;
98  if (!module_sp) return StackFrameRecognizerSP();
99  ConstString module_name = module_sp->GetFileSpec().GetFilename();
100  Symbol *symbol = symctx.symbol;
101  if (!symbol) return StackFrameRecognizerSP();
102  Address start_addr = symbol->GetAddress();
103  Address current_addr = frame->GetFrameCodeAddress();
104 
105  for (auto entry : m_recognizers) {
106  if (entry.deleted) continue;
107  if (entry.module)
108  if (entry.module != module_name) continue;
109 
110  if (entry.module_regexp)
111  if (!entry.module_regexp->Execute(module_name.GetStringRef())) continue;
112 
113  if (entry.symbol)
114  if (entry.symbol != function_name) continue;
115 
116  if (entry.symbol_regexp)
117  if (!entry.symbol_regexp->Execute(function_name.GetStringRef()))
118  continue;
119 
120  if (entry.first_instruction_only)
121  if (start_addr != current_addr) continue;
122 
123  return entry.recognizer;
124  }
125  return StackFrameRecognizerSP();
126  }
127 
128  RecognizedStackFrameSP RecognizeFrame(StackFrameSP frame) {
129  auto recognizer = GetRecognizerForFrame(frame);
130  if (!recognizer) return RecognizedStackFrameSP();
131  return recognizer->RecognizeFrame(frame);
132  }
133 
134  private:
135  struct RegisteredEntry {
136  uint32_t recognizer_id;
137  bool deleted;
138  StackFrameRecognizerSP recognizer;
139  bool is_regexp;
140  ConstString module;
141  RegularExpressionSP module_regexp;
142  ConstString symbol;
143  RegularExpressionSP symbol_regexp;
144  bool first_instruction_only;
145  };
146 
147  std::deque<RegisteredEntry> m_recognizers;
148 };
149 
151  static StackFrameRecognizerManagerImpl instance =
153  return instance;
154 }
155 
157  StackFrameRecognizerSP recognizer, ConstString module,
158  ConstString symbol, bool first_instruction_only) {
159  GetStackFrameRecognizerManagerImpl().AddRecognizer(recognizer, module, symbol,
160  first_instruction_only);
161 }
162 
164  StackFrameRecognizerSP recognizer, RegularExpressionSP module,
165  RegularExpressionSP symbol, bool first_instruction_only) {
166  GetStackFrameRecognizerManagerImpl().AddRecognizer(recognizer, module, symbol,
167  first_instruction_only);
168 }
169 
171  std::function<void(uint32_t recognized_id, std::string recognizer_name, std::string module,
172  std::string symbol, bool regexp)> const &callback) {
174 }
175 
178 }
179 
182 }
183 
185  StackFrameSP frame) {
187 }
188 
190  lldb::StackFrameSP frame) {
192 }
ConstString GetFunctionName(Mangled::NamePreference preference=Mangled::ePreferDemangled) const
Find a name of the innermost function for the symbol context.
bool RemoveRecognizerWithID(uint32_t recognizer_id)
Enumerations for broadcasting.
Definition: SBLaunchInfo.h:14
static lldb::RecognizedStackFrameSP RecognizeFrame(lldb::StackFrameSP frame)
static lldb::StackFrameRecognizerSP GetRecognizerForFrame(lldb::StackFrameSP frame)
void AddRecognizer(StackFrameRecognizerSP recognizer, RegularExpressionSP module, RegularExpressionSP symbol, bool first_instruction_only)
void ForEach(std::function< void(uint32_t recognized_id, std::string recognizer_name, std::string module, std::string symbol, bool regexp)> const &callback)
Defines a symbol context baton that can be handed other debug core functions.
Definition: SymbolContext.h:33
Address GetAddress() const
Definition: Symbol.h:72
static lldb::ValueObjectSP Create(ValueObject &parent, lldb::ValueType type)
static void AddRecognizer(lldb::StackFrameRecognizerSP recognizer, ConstString module, ConstString symbol, bool first_instruction_only=true)
virtual lldb::ValueObjectListSP GetRecognizedArguments(const StructuredData::ObjectSP &implementor, lldb::StackFrameSP frame_sp)
Symbol * symbol
The Symbol for a given query.
ScriptedRecognizedStackFrame(ValueObjectListSP args)
StackFrameRecognizerSP GetRecognizerForFrame(StackFrameSP frame)
static void ForEach(std::function< void(uint32_t recognizer_id, std::string recognizer_name, std::string module, std::string symbol, bool regexp)> const &callback)
lldb::RecognizedStackFrameSP RecognizeFrame(lldb::StackFrameSP frame) override
void AddRecognizer(StackFrameRecognizerSP recognizer, ConstString module, ConstString symbol, bool first_instruction_only)
static bool RemoveRecognizerWithID(uint32_t recognizer_id)
llvm::StringRef GetStringRef() const
Get the string value as a llvm::StringRef.
Definition: ConstString.h:233
A section + offset based address class.
Definition: Address.h:80
RecognizedStackFrameSP RecognizeFrame(StackFrameSP frame)
A uniqued constant string class.
Definition: ConstString.h:38
lldb::ModuleSP module_sp
The Module for a given query.
StackFrameRecognizerManagerImpl & GetStackFrameRecognizerManagerImpl()
Definition: SBAddress.h:15
virtual StructuredData::GenericSP CreateFrameRecognizer(const char *class_name)
This class provides extra information about a stack frame that was provided by a specific stack frame...