LLDB  mainline
StackFrameRecognizer.cpp
Go to the documentation of this file.
1 //===-- StackFrameRecognizer.cpp ------------------------------------------===//
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) {
32 }
33 
34 RecognizedStackFrameSP
37  return RecognizedStackFrameSP();
38 
39  ValueObjectListSP args =
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, ConstString module,
54  llvm::ArrayRef<ConstString> symbols,
55  bool first_instruction_only) {
56  m_recognizers.push_front({(uint32_t)m_recognizers.size(), false, recognizer,
57  false, module, RegularExpressionSP(), symbols,
58  RegularExpressionSP(), 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(
65  {(uint32_t)m_recognizers.size(), false, recognizer, true, ConstString(),
66  module, std::vector<ConstString>(), symbol, first_instruction_only});
67  }
68 
69  void ForEach(std::function<
70  void(uint32_t recognized_id, std::string recognizer_name,
71  std::string module, llvm::ArrayRef<ConstString> symbols,
72  bool regexp)> const &callback) {
73  for (auto entry : m_recognizers) {
74  if (entry.is_regexp) {
75  std::string module_name;
76  std::string symbol_name;
77 
78  if (entry.module_regexp)
79  module_name = entry.module_regexp->GetText().str();
80  if (entry.symbol_regexp)
81  symbol_name = entry.symbol_regexp->GetText().str();
82 
83  callback(entry.recognizer_id, entry.recognizer->GetName(), module_name,
84  llvm::makeArrayRef(ConstString(symbol_name)), true);
85 
86  } else {
87  callback(entry.recognizer_id, entry.recognizer->GetName(),
88  entry.module.GetCString(), entry.symbols, false);
89  }
90  }
91  }
92 
93  bool RemoveRecognizerWithID(uint32_t recognizer_id) {
94  if (recognizer_id >= m_recognizers.size()) return false;
95  if (m_recognizers[recognizer_id].deleted) return false;
96  m_recognizers[recognizer_id].deleted = true;
97  return true;
98  }
99 
101  m_recognizers.clear();
102  }
103 
104  StackFrameRecognizerSP GetRecognizerForFrame(StackFrameSP frame) {
105  const SymbolContext &symctx = frame->GetSymbolContext(
106  eSymbolContextModule | eSymbolContextFunction | eSymbolContextSymbol);
107  ConstString function_name = symctx.GetFunctionName();
108  ModuleSP module_sp = symctx.module_sp;
109  if (!module_sp) return StackFrameRecognizerSP();
110  ConstString module_name = module_sp->GetFileSpec().GetFilename();
111  Symbol *symbol = symctx.symbol;
112  if (!symbol) return StackFrameRecognizerSP();
113  Address start_addr = symbol->GetAddress();
114  Address current_addr = frame->GetFrameCodeAddress();
115 
116  for (auto entry : m_recognizers) {
117  if (entry.deleted) continue;
118  if (entry.module)
119  if (entry.module != module_name) continue;
120 
121  if (entry.module_regexp)
122  if (!entry.module_regexp->Execute(module_name.GetStringRef())) continue;
123 
124  if (!entry.symbols.empty())
125  if (!llvm::is_contained(entry.symbols, function_name))
126  continue;
127 
128  if (entry.symbol_regexp)
129  if (!entry.symbol_regexp->Execute(function_name.GetStringRef()))
130  continue;
131 
132  if (entry.first_instruction_only)
133  if (start_addr != current_addr) continue;
134 
135  return entry.recognizer;
136  }
137  return StackFrameRecognizerSP();
138  }
139 
140  RecognizedStackFrameSP RecognizeFrame(StackFrameSP frame) {
141  auto recognizer = GetRecognizerForFrame(frame);
142  if (!recognizer) return RecognizedStackFrameSP();
143  return recognizer->RecognizeFrame(frame);
144  }
145 
146  private:
149  bool deleted;
150  StackFrameRecognizerSP recognizer;
151  bool is_regexp;
153  RegularExpressionSP module_regexp;
154  std::vector<ConstString> symbols;
155  RegularExpressionSP symbol_regexp;
157  };
158 
159  std::deque<RegisteredEntry> m_recognizers;
160 };
161 
163  static StackFrameRecognizerManagerImpl instance =
165  return instance;
166 }
167 
169  StackFrameRecognizerSP recognizer, ConstString module,
170  llvm::ArrayRef<ConstString> symbols, bool first_instruction_only) {
172  recognizer, module, symbols, first_instruction_only);
173 }
174 
176  StackFrameRecognizerSP recognizer, RegularExpressionSP module,
177  RegularExpressionSP symbol, bool first_instruction_only) {
178  GetStackFrameRecognizerManagerImpl().AddRecognizer(recognizer, module, symbol,
179  first_instruction_only);
180 }
181 
183  std::function<void(uint32_t recognized_id, std::string recognizer_name,
184  std::string module, llvm::ArrayRef<ConstString> symbols,
185  bool regexp)> const &callback) {
187 }
188 
191 }
192 
195 }
196 
198  StackFrameSP frame) {
200 }
201 
203  lldb::StackFrameSP frame) {
205 }
static void ForEach(std::function< void(uint32_t recognizer_id, std::string recognizer_name, std::string module, llvm::ArrayRef< ConstString > symbols, bool regexp)> const &callback)
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)
A class that represents a running process on the host machine.
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)
Defines a symbol context baton that can be handed other debug core functions.
Definition: SymbolContext.h:33
lldb_private::StructuredData::ObjectSP m_python_object_sp
Address GetAddress() const
Definition: Symbol.h:73
static lldb::ValueObjectSP Create(ValueObject &parent, lldb::ValueType type)
virtual lldb::ValueObjectListSP GetRecognizedArguments(const StructuredData::ObjectSP &implementor, lldb::StackFrameSP frame_sp)
Symbol * symbol
The Symbol for a given query.
ScriptedRecognizedStackFrame(ValueObjectListSP args)
static void AddRecognizer(lldb::StackFrameRecognizerSP recognizer, ConstString module, llvm::ArrayRef< ConstString > symbols, bool first_instruction_only=true)
StackFrameRecognizerSP GetRecognizerForFrame(StackFrameSP frame)
lldb::RecognizedStackFrameSP RecognizeFrame(lldb::StackFrameSP frame) override
static bool RemoveRecognizerWithID(uint32_t recognizer_id)
void ForEach(std::function< void(uint32_t recognized_id, std::string recognizer_name, std::string module, llvm::ArrayRef< ConstString > symbols, bool regexp)> const &callback)
llvm::StringRef GetStringRef() const
Get the string value as a llvm::StringRef.
Definition: ConstString.h:232
lldb_private::ScriptInterpreter * m_interpreter
std::deque< RegisteredEntry > m_recognizers
A section + offset based address class.
Definition: Address.h:59
function argument variables
RecognizedStackFrameSP RecognizeFrame(StackFrameSP frame)
A uniqued constant string class.
Definition: ConstString.h:40
lldb::ModuleSP module_sp
The Module for a given query.
StackFrameRecognizerManagerImpl & GetStackFrameRecognizerManagerImpl()
Definition: SBAddress.h:15
void AddRecognizer(StackFrameRecognizerSP recognizer, ConstString module, llvm::ArrayRef< ConstString > symbols, bool first_instruction_only)
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...