diff options
| author | Dimitry Andric <dim@FreeBSD.org> | 2023-02-11 12:38:04 +0000 |
|---|---|---|
| committer | Dimitry Andric <dim@FreeBSD.org> | 2023-02-11 12:38:11 +0000 |
| commit | e3b557809604d036af6e00c60f012c2025b59a5e (patch) | |
| tree | 8a11ba2269a3b669601e2fd41145b174008f4da8 /lldb/source/Breakpoint/BreakpointResolverFileLine.cpp | |
| parent | 08e8dd7b9db7bb4a9de26d44c1cbfd24e869c014 (diff) | |
Diffstat (limited to 'lldb/source/Breakpoint/BreakpointResolverFileLine.cpp')
| -rw-r--r-- | lldb/source/Breakpoint/BreakpointResolverFileLine.cpp | 131 |
1 files changed, 92 insertions, 39 deletions
diff --git a/lldb/source/Breakpoint/BreakpointResolverFileLine.cpp b/lldb/source/Breakpoint/BreakpointResolverFileLine.cpp index ff044526799c..890b38af5c88 100644 --- a/lldb/source/Breakpoint/BreakpointResolverFileLine.cpp +++ b/lldb/source/Breakpoint/BreakpointResolverFileLine.cpp @@ -12,9 +12,11 @@ #include "lldb/Core/Module.h" #include "lldb/Symbol/CompileUnit.h" #include "lldb/Symbol/Function.h" +#include "lldb/Target/Target.h" #include "lldb/Utility/LLDBLog.h" #include "lldb/Utility/Log.h" #include "lldb/Utility/StreamString.h" +#include <optional> using namespace lldb; using namespace lldb_private; @@ -22,9 +24,11 @@ using namespace lldb_private; // BreakpointResolverFileLine: BreakpointResolverFileLine::BreakpointResolverFileLine( const BreakpointSP &bkpt, lldb::addr_t offset, bool skip_prologue, - const SourceLocationSpec &location_spec) + const SourceLocationSpec &location_spec, + std::optional<llvm::StringRef> removed_prefix_opt) : BreakpointResolver(bkpt, BreakpointResolver::FileLineResolver, offset), - m_location_spec(location_spec), m_skip_prologue(skip_prologue) {} + m_location_spec(location_spec), m_skip_prologue(skip_prologue), + m_removed_prefix_opt(removed_prefix_opt) {} BreakpointResolver *BreakpointResolverFileLine::CreateFromStructuredData( const BreakpointSP &bkpt, const StructuredData::Dictionary &options_dict, @@ -119,34 +123,14 @@ BreakpointResolverFileLine::SerializeToStructuredData() { // handling inlined functions -- in this case we need to make sure we look at // the declaration line of the inlined function, NOT the function it was // inlined into. -void BreakpointResolverFileLine::FilterContexts(SymbolContextList &sc_list, - bool is_relative) { +void BreakpointResolverFileLine::FilterContexts(SymbolContextList &sc_list) { if (m_location_spec.GetExactMatch()) return; // Nothing to do. Contexts are precise. - llvm::StringRef relative_path; - if (is_relative) - relative_path = m_location_spec.GetFileSpec().GetDirectory().GetStringRef(); - Log *log = GetLog(LLDBLog::Breakpoints); for(uint32_t i = 0; i < sc_list.GetSize(); ++i) { SymbolContext sc; sc_list.GetContextAtIndex(i, sc); - if (is_relative) { - // If the path was relative, make sure any matches match as long as the - // relative parts of the path match the path from support files - auto sc_dir = sc.line_entry.file.GetDirectory().GetStringRef(); - if (!sc_dir.endswith(relative_path)) { - // We had a relative path specified and the relative directory doesn't - // match so remove this one - LLDB_LOG(log, "removing not matching relative path {0} since it " - "doesn't end with {1}", sc_dir, relative_path); - sc_list.RemoveContextAtIndex(i); - --i; - continue; - } - } - if (!sc.block) continue; @@ -207,6 +191,85 @@ void BreakpointResolverFileLine::FilterContexts(SymbolContextList &sc_list, } } +void BreakpointResolverFileLine::DeduceSourceMapping( + SymbolContextList &sc_list) { + Target &target = GetBreakpoint()->GetTarget(); + if (!target.GetAutoSourceMapRelative()) + return; + + Log *log = GetLog(LLDBLog::Breakpoints); + const llvm::StringRef path_separator = llvm::sys::path::get_separator( + m_location_spec.GetFileSpec().GetPathStyle()); + // Check if "b" is a suffix of "a". + // And return std::nullopt if not or the new path + // of "a" after consuming "b" from the back. + auto check_suffix = + [path_separator](llvm::StringRef a, llvm::StringRef b, + bool case_sensitive) -> std::optional<llvm::StringRef> { + if (case_sensitive ? a.consume_back(b) : a.consume_back_insensitive(b)) { + if (a.empty() || a.endswith(path_separator)) { + return a; + } + } + return std::nullopt; + }; + + FileSpec request_file = m_location_spec.GetFileSpec(); + + // Only auto deduce source map if breakpoint is full path. + // Note: an existing source map reverse mapping (m_removed_prefix_opt has + // value) may make request_file relative. + if (!m_removed_prefix_opt.has_value() && request_file.IsRelative()) + return; + + const bool case_sensitive = request_file.IsCaseSensitive(); + for (uint32_t i = 0; i < sc_list.GetSize(); ++i) { + SymbolContext sc; + sc_list.GetContextAtIndex(i, sc); + + FileSpec sc_file = sc.line_entry.file; + + if (FileSpec::Equal(sc_file, request_file, /*full*/true)) + continue; + + llvm::StringRef sc_file_dir = sc_file.GetDirectory().GetStringRef(); + llvm::StringRef request_file_dir = + request_file.GetDirectory().GetStringRef(); + + llvm::StringRef new_mapping_from; + llvm::SmallString<256> new_mapping_to; + + // Adding back any potentially reverse mapping stripped prefix. + // for new_mapping_to. + if (m_removed_prefix_opt.has_value()) + llvm::sys::path::append(new_mapping_to, *m_removed_prefix_opt); + + std::optional<llvm::StringRef> new_mapping_from_opt = + check_suffix(sc_file_dir, request_file_dir, case_sensitive); + if (new_mapping_from_opt) { + new_mapping_from = *new_mapping_from_opt; + if (new_mapping_to.empty()) + new_mapping_to = "."; + } else { + std::optional<llvm::StringRef> new_mapping_to_opt = + check_suffix(request_file_dir, sc_file_dir, case_sensitive); + if (new_mapping_to_opt) { + new_mapping_from = "."; + llvm::sys::path::append(new_mapping_to, *new_mapping_to_opt); + } + } + + if (!new_mapping_from.empty() && !new_mapping_to.empty()) { + LLDB_LOG(log, "generating auto source map from {0} to {1}", + new_mapping_from, new_mapping_to); + if (target.GetSourcePathMap().AppendUnique(new_mapping_from, + new_mapping_to, + /*notify*/ true)) + target.GetStatistics().IncreaseSourceMapDeduceCount(); + } + } +} + Searcher::CallbackReturn BreakpointResolverFileLine::SearchCallback( SearchFilter &filter, SymbolContext &context, Address *addr) { SymbolContextList sc_list; @@ -228,31 +291,21 @@ Searcher::CallbackReturn BreakpointResolverFileLine::SearchCallback( // same file spec in their line_entry and treat each set separately. const uint32_t line = m_location_spec.GetLine().value_or(0); - const llvm::Optional<uint16_t> column = m_location_spec.GetColumn(); - - // We'll create a new SourceLocationSpec that can take into account the - // relative path case, and we'll use it to resolve the symbol context - // of the CUs. - FileSpec search_file_spec = m_location_spec.GetFileSpec(); - const bool is_relative = search_file_spec.IsRelative(); - if (is_relative) - search_file_spec.GetDirectory().Clear(); - SourceLocationSpec search_location_spec( - search_file_spec, m_location_spec.GetLine().value_or(0), - m_location_spec.GetColumn(), m_location_spec.GetCheckInlines(), - m_location_spec.GetExactMatch()); + const std::optional<uint16_t> column = m_location_spec.GetColumn(); const size_t num_comp_units = context.module_sp->GetNumCompileUnits(); for (size_t i = 0; i < num_comp_units; i++) { CompUnitSP cu_sp(context.module_sp->GetCompileUnitAtIndex(i)); if (cu_sp) { if (filter.CompUnitPasses(*cu_sp)) - cu_sp->ResolveSymbolContext(search_location_spec, - eSymbolContextEverything, sc_list); + cu_sp->ResolveSymbolContext(m_location_spec, eSymbolContextEverything, + sc_list); } } - FilterContexts(sc_list, is_relative); + FilterContexts(sc_list); + + DeduceSourceMapping(sc_list); StreamString s; s.Printf("for %s:%d ", |
