Path: blob/main/contrib/llvm-project/lldb/source/Breakpoint/BreakpointResolverFileRegex.cpp
39587 views
//===-- BreakpointResolverFileRegex.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/Breakpoint/BreakpointResolverFileRegex.h"910#include "lldb/Breakpoint/BreakpointLocation.h"11#include "lldb/Core/SourceManager.h"12#include "lldb/Symbol/CompileUnit.h"13#include "lldb/Target/Target.h"14#include "lldb/Utility/Log.h"15#include "lldb/Utility/StreamString.h"1617using namespace lldb;18using namespace lldb_private;1920// BreakpointResolverFileRegex:21BreakpointResolverFileRegex::BreakpointResolverFileRegex(22const lldb::BreakpointSP &bkpt, RegularExpression regex,23const std::unordered_set<std::string> &func_names, bool exact_match)24: BreakpointResolver(bkpt, BreakpointResolver::FileRegexResolver),25m_regex(std::move(regex)), m_exact_match(exact_match),26m_function_names(func_names) {}2728BreakpointResolverSP BreakpointResolverFileRegex::CreateFromStructuredData(29const StructuredData::Dictionary &options_dict, Status &error) {30bool success;3132llvm::StringRef regex_string;33success = options_dict.GetValueForKeyAsString(34GetKey(OptionNames::RegexString), regex_string);35if (!success) {36error.SetErrorString("BRFR::CFSD: Couldn't find regex entry.");37return nullptr;38}39RegularExpression regex(regex_string);4041bool exact_match;42success = options_dict.GetValueForKeyAsBoolean(43GetKey(OptionNames::ExactMatch), exact_match);44if (!success) {45error.SetErrorString("BRFL::CFSD: Couldn't find exact match entry.");46return nullptr;47}4849// The names array is optional:50std::unordered_set<std::string> names_set;51StructuredData::Array *names_array;52success = options_dict.GetValueForKeyAsArray(53GetKey(OptionNames::SymbolNameArray), names_array);54if (success && names_array) {55size_t num_names = names_array->GetSize();56for (size_t i = 0; i < num_names; i++) {57std::optional<llvm::StringRef> maybe_name =58names_array->GetItemAtIndexAsString(i);59if (!maybe_name) {60error.SetErrorStringWithFormat(61"BRFR::CFSD: Malformed element %zu in the names array.", i);62return nullptr;63}64names_set.insert(std::string(*maybe_name));65}66}6768return std::make_shared<BreakpointResolverFileRegex>(69nullptr, std::move(regex), names_set, exact_match);70}7172StructuredData::ObjectSP73BreakpointResolverFileRegex::SerializeToStructuredData() {74StructuredData::DictionarySP options_dict_sp(75new StructuredData::Dictionary());7677options_dict_sp->AddStringItem(GetKey(OptionNames::RegexString),78m_regex.GetText());79options_dict_sp->AddBooleanItem(GetKey(OptionNames::ExactMatch),80m_exact_match);81if (!m_function_names.empty()) {82StructuredData::ArraySP names_array_sp(new StructuredData::Array());83for (std::string name : m_function_names) {84StructuredData::StringSP item(new StructuredData::String(name));85names_array_sp->AddItem(item);86}87options_dict_sp->AddItem(GetKey(OptionNames::LineNumber), names_array_sp);88}8990return WrapOptionsDict(options_dict_sp);91}9293Searcher::CallbackReturn BreakpointResolverFileRegex::SearchCallback(94SearchFilter &filter, SymbolContext &context, Address *addr) {9596if (!context.target_sp)97return eCallbackReturnContinue;9899CompileUnit *cu = context.comp_unit;100FileSpec cu_file_spec = cu->GetPrimaryFile();101std::vector<uint32_t> line_matches;102context.target_sp->GetSourceManager().FindLinesMatchingRegex(103cu_file_spec, m_regex, 1, UINT32_MAX, line_matches);104105uint32_t num_matches = line_matches.size();106for (uint32_t i = 0; i < num_matches; i++) {107SymbolContextList sc_list;108// TODO: Handle SourceLocationSpec column information109SourceLocationSpec location_spec(cu_file_spec, line_matches[i],110/*column=*/std::nullopt,111/*check_inlines=*/false, m_exact_match);112cu->ResolveSymbolContext(location_spec, eSymbolContextEverything, sc_list);113// Find all the function names:114if (!m_function_names.empty()) {115std::vector<size_t> sc_to_remove;116for (size_t i = 0; i < sc_list.GetSize(); i++) {117SymbolContext sc_ctx;118sc_list.GetContextAtIndex(i, sc_ctx);119std::string name(120sc_ctx121.GetFunctionName(122Mangled::NamePreference::ePreferDemangledWithoutArguments)123.AsCString());124if (!m_function_names.count(name)) {125sc_to_remove.push_back(i);126}127}128129if (!sc_to_remove.empty()) {130std::vector<size_t>::reverse_iterator iter;131std::vector<size_t>::reverse_iterator rend = sc_to_remove.rend();132for (iter = sc_to_remove.rbegin(); iter != rend; iter++) {133sc_list.RemoveContextAtIndex(*iter);134}135}136}137138const bool skip_prologue = true;139140BreakpointResolver::SetSCMatchesByLine(filter, sc_list, skip_prologue,141m_regex.GetText());142}143144return Searcher::eCallbackReturnContinue;145}146147lldb::SearchDepth BreakpointResolverFileRegex::GetDepth() {148return lldb::eSearchDepthCompUnit;149}150151void BreakpointResolverFileRegex::GetDescription(Stream *s) {152s->Printf("source regex = \"%s\", exact_match = %d",153m_regex.GetText().str().c_str(), m_exact_match);154}155156void BreakpointResolverFileRegex::Dump(Stream *s) const {}157158lldb::BreakpointResolverSP159BreakpointResolverFileRegex::CopyForBreakpoint(BreakpointSP &breakpoint) {160lldb::BreakpointResolverSP ret_sp(new BreakpointResolverFileRegex(161breakpoint, m_regex, m_function_names, m_exact_match));162return ret_sp;163}164165void BreakpointResolverFileRegex::AddFunctionName(const char *func_name) {166m_function_names.insert(func_name);167}168169170