[Lldb-commits] [lldb] r330028 - Allow relative file paths when settings source breakpoints

Greg Clayton via lldb-commits lldb-commits at lists.llvm.org
Fri Apr 13 07:52:54 PDT 2018


Author: gclayton
Date: Fri Apr 13 07:52:54 2018
New Revision: 330028

URL: http://llvm.org/viewvc/llvm-project?rev=330028&view=rev
Log:
Allow relative file paths when settings source breakpoints


Many IDEs set breakpoints using absolute paths and this causes problems when the full path of the source file path doesn't match what is in the debug info. This can be due to different build systems and do or do not resolve symlinks. This patch allows relative breakpoint to be set correctly without needing to do any target.source-map tricks. If IDEs want to, they can send down relative paths like:

./main.c
./src/main.c
src/main.c
foo/bar/src/main.c

I used the breakpoint resolver to match on the file basename and then we weed out anything whose relative paths don't match. This will be a huge improvement for IDEs as they can specify as much of a relative path as desired to uniquely identify a source file in the current project.



Differential Revision: https://reviews.llvm.org/D45592


Modified:
    lldb/trunk/include/lldb/Breakpoint/BreakpointResolverFileLine.h
    lldb/trunk/packages/Python/lldbsuite/test/functionalities/breakpoint/breakpoint_command/TestBreakpointCommand.py
    lldb/trunk/packages/Python/lldbsuite/test/lldbutil.py
    lldb/trunk/source/Breakpoint/BreakpointResolverFileLine.cpp

Modified: lldb/trunk/include/lldb/Breakpoint/BreakpointResolverFileLine.h
URL: http://llvm.org/viewvc/llvm-project/lldb/trunk/include/lldb/Breakpoint/BreakpointResolverFileLine.h?rev=330028&r1=330027&r2=330028&view=diff
==============================================================================
--- lldb/trunk/include/lldb/Breakpoint/BreakpointResolverFileLine.h (original)
+++ lldb/trunk/include/lldb/Breakpoint/BreakpointResolverFileLine.h Fri Apr 13 07:52:54 2018
@@ -63,7 +63,7 @@ public:
   lldb::BreakpointResolverSP CopyForBreakpoint(Breakpoint &breakpoint) override;
 
 protected:
-  void FilterContexts(SymbolContextList &sc_list);
+  void FilterContexts(SymbolContextList &sc_list, bool is_relative);
 
   friend class Breakpoint;
   FileSpec m_file_spec;   // This is the file spec we are looking for.

Modified: lldb/trunk/packages/Python/lldbsuite/test/functionalities/breakpoint/breakpoint_command/TestBreakpointCommand.py
URL: http://llvm.org/viewvc/llvm-project/lldb/trunk/packages/Python/lldbsuite/test/functionalities/breakpoint/breakpoint_command/TestBreakpointCommand.py?rev=330028&r1=330027&r2=330028&view=diff
==============================================================================
--- lldb/trunk/packages/Python/lldbsuite/test/functionalities/breakpoint/breakpoint_command/TestBreakpointCommand.py (original)
+++ lldb/trunk/packages/Python/lldbsuite/test/functionalities/breakpoint/breakpoint_command/TestBreakpointCommand.py Fri Apr 13 07:52:54 2018
@@ -62,7 +62,31 @@ class BreakpointCommandTestCase(TestBase
         # setting breakpoint commands on two breakpoints at a time
         lldbutil.run_break_set_by_file_and_line(
             self, None, self.line, num_expected_locations=1, loc_exact=True)
-
+        # Make sure relative path source breakpoints work as expected. We test
+        # with partial paths with and without "./" prefixes.
+        lldbutil.run_break_set_by_file_and_line(
+            self, "./main.c", self.line,
+            num_expected_locations=1, loc_exact=True)
+        lldbutil.run_break_set_by_file_and_line(
+            self, "breakpoint_command/main.c", self.line,
+            num_expected_locations=1, loc_exact=True)
+        lldbutil.run_break_set_by_file_and_line(
+            self, "./breakpoint_command/main.c", self.line,
+            num_expected_locations=1, loc_exact=True)
+        lldbutil.run_break_set_by_file_and_line(
+            self, "breakpoint/breakpoint_command/main.c", self.line,
+            num_expected_locations=1, loc_exact=True)
+        lldbutil.run_break_set_by_file_and_line(
+            self, "./breakpoint/breakpoint_command/main.c", self.line,
+            num_expected_locations=1, loc_exact=True)
+        # Test relative breakpoints with incorrect paths and make sure we get
+        # no breakpoint locations
+        lldbutil.run_break_set_by_file_and_line(
+            self, "invalid/main.c", self.line,
+            num_expected_locations=0, loc_exact=True)
+        lldbutil.run_break_set_by_file_and_line(
+            self, "./invalid/main.c", self.line,
+            num_expected_locations=0, loc_exact=True)
         # Now add callbacks for the breakpoints just created.
         self.runCmd(
             "breakpoint command add -s command -o 'frame variable --show-types --scope' 1 4")

Modified: lldb/trunk/packages/Python/lldbsuite/test/lldbutil.py
URL: http://llvm.org/viewvc/llvm-project/lldb/trunk/packages/Python/lldbsuite/test/lldbutil.py?rev=330028&r1=330027&r2=330028&view=diff
==============================================================================
--- lldb/trunk/packages/Python/lldbsuite/test/lldbutil.py (original)
+++ lldb/trunk/packages/Python/lldbsuite/test/lldbutil.py Fri Apr 13 07:52:54 2018
@@ -576,7 +576,7 @@ def check_breakpoint_result(
         if 'file' in break_results:
             out_file_name = break_results['file']
         test.assertTrue(
-            file_name == out_file_name,
+            file_name.endswith(out_file_name),
             "Breakpoint file name '%s' doesn't match resultant name '%s'." %
             (file_name,
              out_file_name))

Modified: lldb/trunk/source/Breakpoint/BreakpointResolverFileLine.cpp
URL: http://llvm.org/viewvc/llvm-project/lldb/trunk/source/Breakpoint/BreakpointResolverFileLine.cpp?rev=330028&r1=330027&r2=330028&view=diff
==============================================================================
--- lldb/trunk/source/Breakpoint/BreakpointResolverFileLine.cpp (original)
+++ lldb/trunk/source/Breakpoint/BreakpointResolverFileLine.cpp Fri Apr 13 07:52:54 2018
@@ -115,15 +115,35 @@ BreakpointResolverFileLine::SerializeToS
 // here is 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) {
+void BreakpointResolverFileLine::FilterContexts(SymbolContextList &sc_list,
+                                                bool is_relative) {
   if (m_exact_match)
     return; // Nothing to do. Contexts are precise.
 
+  llvm::StringRef relative_path;
+  if (is_relative)
+    relative_path = m_file_spec.GetNormalizedPath().GetDirectory().GetStringRef();
+
   Log * log = GetLogIfAllCategoriesSet(LIBLLDB_LOG_BREAKPOINTS);
   for(uint32_t i = 0; i < sc_list.GetSize(); ++i) {
     SymbolContext sc;
     sc_list.GetContextAtIndex(i, sc);
-    if (! sc.block)
+    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;
 
     FileSpec file;
@@ -194,18 +214,23 @@ BreakpointResolverFileLine::SearchCallba
   // through the match list and pull out the sets that have the same file spec
   // in their line_entry and treat each set separately.
 
+  FileSpec search_file_spec = m_file_spec;
+  const bool is_relative = m_file_spec.IsRelative();
+  if (is_relative)
+    search_file_spec.GetDirectory().Clear();
+
   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(m_file_spec, m_line_number, m_inlines,
+        cu_sp->ResolveSymbolContext(search_file_spec, m_line_number, m_inlines,
                                     m_exact_match, eSymbolContextEverything,
                                     sc_list);
     }
   }
 
-  FilterContexts(sc_list);
+  FilterContexts(sc_list, is_relative);
 
   StreamString s;
   s.Printf("for %s:%d ", m_file_spec.GetFilename().AsCString("<Unknown>"),




More information about the lldb-commits mailing list