Path: blob/main/contrib/llvm-project/lldb/source/Target/StackFrameRecognizer.cpp
39587 views
//===-- StackFrameRecognizer.cpp ------------------------------------------===//1//2// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.3// See https://llvm.org/LICENSE.txt for license information.4// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception5//6//===----------------------------------------------------------------------===//78#include "lldb/Target/StackFrameRecognizer.h"9#include "lldb/Core/Module.h"10#include "lldb/Interpreter/ScriptInterpreter.h"11#include "lldb/Symbol/Symbol.h"12#include "lldb/Target/StackFrame.h"13#include "lldb/Utility/RegularExpression.h"1415using namespace lldb;16using namespace lldb_private;1718class ScriptedRecognizedStackFrame : public RecognizedStackFrame {19public:20ScriptedRecognizedStackFrame(ValueObjectListSP args) {21m_arguments = args;22}23};2425ScriptedStackFrameRecognizer::ScriptedStackFrameRecognizer(26ScriptInterpreter *interpreter, const char *pclass)27: m_interpreter(interpreter), m_python_class(pclass) {28m_python_object_sp =29m_interpreter->CreateFrameRecognizer(m_python_class.c_str());30}3132RecognizedStackFrameSP33ScriptedStackFrameRecognizer::RecognizeFrame(lldb::StackFrameSP frame) {34if (!m_python_object_sp || !m_interpreter)35return RecognizedStackFrameSP();3637ValueObjectListSP args =38m_interpreter->GetRecognizedArguments(m_python_object_sp, frame);39auto args_synthesized = ValueObjectListSP(new ValueObjectList());40for (const auto &o : args->GetObjects()) {41args_synthesized->Append(ValueObjectRecognizerSynthesizedValue::Create(42*o, eValueTypeVariableArgument));43}4445return RecognizedStackFrameSP(46new ScriptedRecognizedStackFrame(args_synthesized));47}4849void StackFrameRecognizerManager::AddRecognizer(50StackFrameRecognizerSP recognizer, ConstString module,51llvm::ArrayRef<ConstString> symbols, bool first_instruction_only) {52m_recognizers.push_front({(uint32_t)m_recognizers.size(), recognizer, false,53module, RegularExpressionSP(), symbols,54RegularExpressionSP(), first_instruction_only});55}5657void StackFrameRecognizerManager::AddRecognizer(58StackFrameRecognizerSP recognizer, RegularExpressionSP module,59RegularExpressionSP symbol, bool first_instruction_only) {60m_recognizers.push_front({(uint32_t)m_recognizers.size(), recognizer, true,61ConstString(), module, std::vector<ConstString>(),62symbol, first_instruction_only});63}6465void StackFrameRecognizerManager::ForEach(66const std::function<void(uint32_t, std::string, std::string,67llvm::ArrayRef<ConstString>, bool)> &callback) {68for (auto entry : m_recognizers) {69if (entry.is_regexp) {70std::string module_name;71std::string symbol_name;7273if (entry.module_regexp)74module_name = entry.module_regexp->GetText().str();75if (entry.symbol_regexp)76symbol_name = entry.symbol_regexp->GetText().str();7778callback(entry.recognizer_id, entry.recognizer->GetName(), module_name,79llvm::ArrayRef(ConstString(symbol_name)), true);8081} else {82callback(entry.recognizer_id, entry.recognizer->GetName(),83entry.module.GetCString(), entry.symbols, false);84}85}86}8788bool StackFrameRecognizerManager::RemoveRecognizerWithID(89uint32_t recognizer_id) {90if (recognizer_id >= m_recognizers.size())91return false;92auto found =93llvm::find_if(m_recognizers, [recognizer_id](const RegisteredEntry &e) {94return e.recognizer_id == recognizer_id;95});96if (found == m_recognizers.end())97return false;98m_recognizers.erase(found);99return true;100}101102void StackFrameRecognizerManager::RemoveAllRecognizers() {103m_recognizers.clear();104}105106StackFrameRecognizerSP107StackFrameRecognizerManager::GetRecognizerForFrame(StackFrameSP frame) {108const SymbolContext &symctx = frame->GetSymbolContext(109eSymbolContextModule | eSymbolContextFunction | eSymbolContextSymbol);110ConstString function_name = symctx.GetFunctionName();111ModuleSP module_sp = symctx.module_sp;112if (!module_sp)113return StackFrameRecognizerSP();114ConstString module_name = module_sp->GetFileSpec().GetFilename();115Symbol *symbol = symctx.symbol;116if (!symbol)117return StackFrameRecognizerSP();118Address start_addr = symbol->GetAddress();119Address current_addr = frame->GetFrameCodeAddress();120121for (auto entry : m_recognizers) {122if (entry.module)123if (entry.module != module_name)124continue;125126if (entry.module_regexp)127if (!entry.module_regexp->Execute(module_name.GetStringRef()))128continue;129130if (!entry.symbols.empty())131if (!llvm::is_contained(entry.symbols, function_name))132continue;133134if (entry.symbol_regexp)135if (!entry.symbol_regexp->Execute(function_name.GetStringRef()))136continue;137138if (entry.first_instruction_only)139if (start_addr != current_addr)140continue;141142return entry.recognizer;143}144return StackFrameRecognizerSP();145}146147RecognizedStackFrameSP148StackFrameRecognizerManager::RecognizeFrame(StackFrameSP frame) {149auto recognizer = GetRecognizerForFrame(frame);150if (!recognizer)151return RecognizedStackFrameSP();152return recognizer->RecognizeFrame(frame);153}154155156