aboutsummaryrefslogtreecommitdiff
path: root/lldb/source/Breakpoint/BreakpointResolverFileLine.cpp
diff options
context:
space:
mode:
authorDimitry Andric <dim@FreeBSD.org>2023-02-11 12:38:04 +0000
committerDimitry Andric <dim@FreeBSD.org>2023-02-11 12:38:11 +0000
commite3b557809604d036af6e00c60f012c2025b59a5e (patch)
tree8a11ba2269a3b669601e2fd41145b174008f4da8 /lldb/source/Breakpoint/BreakpointResolverFileLine.cpp
parent08e8dd7b9db7bb4a9de26d44c1cbfd24e869c014 (diff)
Diffstat (limited to 'lldb/source/Breakpoint/BreakpointResolverFileLine.cpp')
-rw-r--r--lldb/source/Breakpoint/BreakpointResolverFileLine.cpp131
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 ",