1*41ae8e74SKuba Mracek //===-- StackFrameRecognizer.cpp --------------------------------*- C++ -*-===// 2*41ae8e74SKuba Mracek // 3*41ae8e74SKuba Mracek // The LLVM Compiler Infrastructure 4*41ae8e74SKuba Mracek // 5*41ae8e74SKuba Mracek // This file is distributed under the University of Illinois Open Source 6*41ae8e74SKuba Mracek // License. See LICENSE.TXT for details. 7*41ae8e74SKuba Mracek // 8*41ae8e74SKuba Mracek //===----------------------------------------------------------------------===// 9*41ae8e74SKuba Mracek 10*41ae8e74SKuba Mracek // C Includes 11*41ae8e74SKuba Mracek // C++ Includes 12*41ae8e74SKuba Mracek #include <vector> 13*41ae8e74SKuba Mracek // Other libraries and framework includes 14*41ae8e74SKuba Mracek // Project includes 15*41ae8e74SKuba Mracek #include "lldb/Core/Module.h" 16*41ae8e74SKuba Mracek #include "lldb/Interpreter/ScriptInterpreter.h" 17*41ae8e74SKuba Mracek #include "lldb/Symbol/Symbol.h" 18*41ae8e74SKuba Mracek #include "lldb/Target/StackFrame.h" 19*41ae8e74SKuba Mracek #include "lldb/Target/StackFrameRecognizer.h" 20*41ae8e74SKuba Mracek #include "lldb/Utility/RegularExpression.h" 21*41ae8e74SKuba Mracek 22*41ae8e74SKuba Mracek using namespace lldb; 23*41ae8e74SKuba Mracek using namespace lldb_private; 24*41ae8e74SKuba Mracek 25*41ae8e74SKuba Mracek class ScriptedRecognizedStackFrame : public RecognizedStackFrame { 26*41ae8e74SKuba Mracek public: 27*41ae8e74SKuba Mracek ScriptedRecognizedStackFrame(ValueObjectListSP args) { 28*41ae8e74SKuba Mracek m_arguments = args; 29*41ae8e74SKuba Mracek } 30*41ae8e74SKuba Mracek }; 31*41ae8e74SKuba Mracek 32*41ae8e74SKuba Mracek ScriptedStackFrameRecognizer::ScriptedStackFrameRecognizer( 33*41ae8e74SKuba Mracek ScriptInterpreter *interpreter, const char *pclass) 34*41ae8e74SKuba Mracek : m_interpreter(interpreter), m_python_class(pclass) { 35*41ae8e74SKuba Mracek m_python_object_sp = 36*41ae8e74SKuba Mracek m_interpreter->CreateFrameRecognizer(m_python_class.c_str()); 37*41ae8e74SKuba Mracek } 38*41ae8e74SKuba Mracek 39*41ae8e74SKuba Mracek RecognizedStackFrameSP 40*41ae8e74SKuba Mracek ScriptedStackFrameRecognizer::RecognizeFrame(lldb::StackFrameSP frame) { 41*41ae8e74SKuba Mracek if (!m_python_object_sp || !m_interpreter) 42*41ae8e74SKuba Mracek return RecognizedStackFrameSP(); 43*41ae8e74SKuba Mracek 44*41ae8e74SKuba Mracek ValueObjectListSP args = 45*41ae8e74SKuba Mracek m_interpreter->GetRecognizedArguments(m_python_object_sp, frame); 46*41ae8e74SKuba Mracek 47*41ae8e74SKuba Mracek return RecognizedStackFrameSP(new ScriptedRecognizedStackFrame(args)); 48*41ae8e74SKuba Mracek } 49*41ae8e74SKuba Mracek 50*41ae8e74SKuba Mracek class StackFrameRecognizerManagerImpl { 51*41ae8e74SKuba Mracek public: 52*41ae8e74SKuba Mracek void AddRecognizer(StackFrameRecognizerSP recognizer, ConstString &module, 53*41ae8e74SKuba Mracek ConstString &symbol, bool first_instruction_only) { 54*41ae8e74SKuba Mracek m_recognizers.push_front({(uint32_t)m_recognizers.size(), false, recognizer, false, module, RegularExpressionSP(), 55*41ae8e74SKuba Mracek symbol, RegularExpressionSP(), 56*41ae8e74SKuba Mracek first_instruction_only}); 57*41ae8e74SKuba Mracek } 58*41ae8e74SKuba Mracek 59*41ae8e74SKuba Mracek void AddRecognizer(StackFrameRecognizerSP recognizer, 60*41ae8e74SKuba Mracek RegularExpressionSP module, RegularExpressionSP symbol, 61*41ae8e74SKuba Mracek bool first_instruction_only) { 62*41ae8e74SKuba Mracek m_recognizers.push_front({(uint32_t)m_recognizers.size(), false, recognizer, true, ConstString(), module, 63*41ae8e74SKuba Mracek ConstString(), symbol, first_instruction_only}); 64*41ae8e74SKuba Mracek } 65*41ae8e74SKuba Mracek 66*41ae8e74SKuba Mracek void ForEach( 67*41ae8e74SKuba Mracek std::function<void(uint32_t recognized_id, std::string recognizer_name, std::string module, 68*41ae8e74SKuba Mracek std::string symbol, bool regexp)> const &callback) { 69*41ae8e74SKuba Mracek for (auto entry : m_recognizers) { 70*41ae8e74SKuba Mracek if (entry.is_regexp) { 71*41ae8e74SKuba Mracek callback(entry.recognizer_id, entry.recognizer->GetName(), entry.module_regexp->GetText(), 72*41ae8e74SKuba Mracek entry.symbol_regexp->GetText(), true); 73*41ae8e74SKuba Mracek } else { 74*41ae8e74SKuba Mracek callback(entry.recognizer_id, entry.recognizer->GetName(), entry.module.GetCString(), 75*41ae8e74SKuba Mracek entry.symbol.GetCString(), false); 76*41ae8e74SKuba Mracek } 77*41ae8e74SKuba Mracek } 78*41ae8e74SKuba Mracek } 79*41ae8e74SKuba Mracek 80*41ae8e74SKuba Mracek bool RemoveRecognizerWithID(uint32_t recognizer_id) { 81*41ae8e74SKuba Mracek if (recognizer_id >= m_recognizers.size()) return false; 82*41ae8e74SKuba Mracek if (m_recognizers[recognizer_id].deleted) return false; 83*41ae8e74SKuba Mracek m_recognizers[recognizer_id].deleted = true; 84*41ae8e74SKuba Mracek return true; 85*41ae8e74SKuba Mracek } 86*41ae8e74SKuba Mracek 87*41ae8e74SKuba Mracek void RemoveAllRecognizers() { 88*41ae8e74SKuba Mracek m_recognizers.clear(); 89*41ae8e74SKuba Mracek } 90*41ae8e74SKuba Mracek 91*41ae8e74SKuba Mracek StackFrameRecognizerSP GetRecognizerForFrame(StackFrameSP frame) { 92*41ae8e74SKuba Mracek const SymbolContext &symctx = 93*41ae8e74SKuba Mracek frame->GetSymbolContext(eSymbolContextModule | eSymbolContextFunction); 94*41ae8e74SKuba Mracek ConstString function_name = symctx.GetFunctionName(); 95*41ae8e74SKuba Mracek ModuleSP module_sp = symctx.module_sp; 96*41ae8e74SKuba Mracek if (!module_sp) return StackFrameRecognizerSP(); 97*41ae8e74SKuba Mracek ConstString module_name = module_sp->GetFileSpec().GetFilename(); 98*41ae8e74SKuba Mracek Symbol *symbol = symctx.symbol; 99*41ae8e74SKuba Mracek if (!symbol) return StackFrameRecognizerSP(); 100*41ae8e74SKuba Mracek Address start_addr = symbol->GetAddress(); 101*41ae8e74SKuba Mracek Address current_addr = frame->GetFrameCodeAddress(); 102*41ae8e74SKuba Mracek 103*41ae8e74SKuba Mracek for (auto entry : m_recognizers) { 104*41ae8e74SKuba Mracek if (entry.deleted) continue; 105*41ae8e74SKuba Mracek if (entry.module) 106*41ae8e74SKuba Mracek if (entry.module != module_name) continue; 107*41ae8e74SKuba Mracek 108*41ae8e74SKuba Mracek if (entry.module_regexp) 109*41ae8e74SKuba Mracek if (!entry.module_regexp->Execute(module_name.GetStringRef())) continue; 110*41ae8e74SKuba Mracek 111*41ae8e74SKuba Mracek if (entry.symbol) 112*41ae8e74SKuba Mracek if (entry.symbol != function_name) continue; 113*41ae8e74SKuba Mracek 114*41ae8e74SKuba Mracek if (entry.symbol_regexp) 115*41ae8e74SKuba Mracek if (!entry.symbol_regexp->Execute(function_name.GetStringRef())) 116*41ae8e74SKuba Mracek continue; 117*41ae8e74SKuba Mracek 118*41ae8e74SKuba Mracek if (entry.first_instruction_only) 119*41ae8e74SKuba Mracek if (start_addr != current_addr) continue; 120*41ae8e74SKuba Mracek 121*41ae8e74SKuba Mracek return entry.recognizer; 122*41ae8e74SKuba Mracek } 123*41ae8e74SKuba Mracek return StackFrameRecognizerSP(); 124*41ae8e74SKuba Mracek } 125*41ae8e74SKuba Mracek 126*41ae8e74SKuba Mracek RecognizedStackFrameSP RecognizeFrame(StackFrameSP frame) { 127*41ae8e74SKuba Mracek auto recognizer = GetRecognizerForFrame(frame); 128*41ae8e74SKuba Mracek if (!recognizer) return RecognizedStackFrameSP(); 129*41ae8e74SKuba Mracek return recognizer->RecognizeFrame(frame); 130*41ae8e74SKuba Mracek } 131*41ae8e74SKuba Mracek 132*41ae8e74SKuba Mracek private: 133*41ae8e74SKuba Mracek struct RegisteredEntry { 134*41ae8e74SKuba Mracek uint32_t recognizer_id; 135*41ae8e74SKuba Mracek bool deleted; 136*41ae8e74SKuba Mracek StackFrameRecognizerSP recognizer; 137*41ae8e74SKuba Mracek bool is_regexp; 138*41ae8e74SKuba Mracek ConstString module; 139*41ae8e74SKuba Mracek RegularExpressionSP module_regexp; 140*41ae8e74SKuba Mracek ConstString symbol; 141*41ae8e74SKuba Mracek RegularExpressionSP symbol_regexp; 142*41ae8e74SKuba Mracek bool first_instruction_only; 143*41ae8e74SKuba Mracek }; 144*41ae8e74SKuba Mracek 145*41ae8e74SKuba Mracek std::deque<RegisteredEntry> m_recognizers; 146*41ae8e74SKuba Mracek }; 147*41ae8e74SKuba Mracek 148*41ae8e74SKuba Mracek StackFrameRecognizerManagerImpl &GetStackFrameRecognizerManagerImpl() { 149*41ae8e74SKuba Mracek static StackFrameRecognizerManagerImpl instance = 150*41ae8e74SKuba Mracek StackFrameRecognizerManagerImpl(); 151*41ae8e74SKuba Mracek return instance; 152*41ae8e74SKuba Mracek } 153*41ae8e74SKuba Mracek 154*41ae8e74SKuba Mracek void StackFrameRecognizerManager::AddRecognizer( 155*41ae8e74SKuba Mracek StackFrameRecognizerSP recognizer, ConstString &module, ConstString &symbol, 156*41ae8e74SKuba Mracek bool first_instruction_only) { 157*41ae8e74SKuba Mracek GetStackFrameRecognizerManagerImpl().AddRecognizer(recognizer, module, symbol, 158*41ae8e74SKuba Mracek first_instruction_only); 159*41ae8e74SKuba Mracek } 160*41ae8e74SKuba Mracek 161*41ae8e74SKuba Mracek void StackFrameRecognizerManager::AddRecognizer( 162*41ae8e74SKuba Mracek StackFrameRecognizerSP recognizer, RegularExpressionSP module, 163*41ae8e74SKuba Mracek RegularExpressionSP symbol, bool first_instruction_only) { 164*41ae8e74SKuba Mracek GetStackFrameRecognizerManagerImpl().AddRecognizer(recognizer, module, symbol, 165*41ae8e74SKuba Mracek first_instruction_only); 166*41ae8e74SKuba Mracek } 167*41ae8e74SKuba Mracek 168*41ae8e74SKuba Mracek void StackFrameRecognizerManager::ForEach( 169*41ae8e74SKuba Mracek std::function<void(uint32_t recognized_id, std::string recognizer_name, std::string module, 170*41ae8e74SKuba Mracek std::string symbol, bool regexp)> const &callback) { 171*41ae8e74SKuba Mracek GetStackFrameRecognizerManagerImpl().ForEach(callback); 172*41ae8e74SKuba Mracek } 173*41ae8e74SKuba Mracek 174*41ae8e74SKuba Mracek void StackFrameRecognizerManager::RemoveAllRecognizers() { 175*41ae8e74SKuba Mracek GetStackFrameRecognizerManagerImpl().RemoveAllRecognizers(); 176*41ae8e74SKuba Mracek } 177*41ae8e74SKuba Mracek 178*41ae8e74SKuba Mracek bool StackFrameRecognizerManager::RemoveRecognizerWithID(uint32_t recognizer_id) { 179*41ae8e74SKuba Mracek return GetStackFrameRecognizerManagerImpl().RemoveRecognizerWithID(recognizer_id); 180*41ae8e74SKuba Mracek } 181*41ae8e74SKuba Mracek 182*41ae8e74SKuba Mracek RecognizedStackFrameSP StackFrameRecognizerManager::RecognizeFrame( 183*41ae8e74SKuba Mracek StackFrameSP frame) { 184*41ae8e74SKuba Mracek return GetStackFrameRecognizerManagerImpl().RecognizeFrame(frame); 185*41ae8e74SKuba Mracek } 186*41ae8e74SKuba Mracek 187*41ae8e74SKuba Mracek StackFrameRecognizerSP StackFrameRecognizerManager::GetRecognizerForFrame( 188*41ae8e74SKuba Mracek lldb::StackFrameSP frame) { 189*41ae8e74SKuba Mracek return GetStackFrameRecognizerManagerImpl().GetRecognizerForFrame(frame); 190*41ae8e74SKuba Mracek } 191