[Lldb-commits] [lldb] 2bc38ab - [lldb/Breakpoint] Recogize hardware breakpoints as such

Jonas Devlieghere via lldb-commits lldb-commits at lists.llvm.org
Fri Jan 24 19:24:36 PST 2020


Author: Jonas Devlieghere
Date: 2020-01-24T19:24:25-08:00
New Revision: 2bc38ab3d038344317b7299e4a562f5724180f5a

URL: https://github.com/llvm/llvm-project/commit/2bc38ab3d038344317b7299e4a562f5724180f5a
DIFF: https://github.com/llvm/llvm-project/commit/2bc38ab3d038344317b7299e4a562f5724180f5a.diff

LOG: [lldb/Breakpoint] Recogize hardware breakpoints as such

Recognize hardware breakpoints as breakpoints instead of just mach
exceptions. The mach exception is the same for watch and breakpoints, so
we have to try each to figure out which is which.

Differential revision: https://reviews.llvm.org/D73401

Added: 
    

Modified: 
    lldb/include/lldb/Breakpoint/BreakpointSite.h
    lldb/include/lldb/Breakpoint/StoppointLocation.h
    lldb/packages/Python/lldbsuite/test/functionalities/breakpoint/hardware_breakpoints/hardware_breakpoint_on_multiple_threads/TestHWBreakMultiThread.py
    lldb/source/Breakpoint/BreakpointSite.cpp
    lldb/source/Plugins/Process/Utility/StopInfoMachException.cpp

Removed: 
    


################################################################################
diff  --git a/lldb/include/lldb/Breakpoint/BreakpointSite.h b/lldb/include/lldb/Breakpoint/BreakpointSite.h
index 5c9f79a9ab1c..eef2e295c1ff 100644
--- a/lldb/include/lldb/Breakpoint/BreakpointSite.h
+++ b/lldb/include/lldb/Breakpoint/BreakpointSite.h
@@ -61,6 +61,8 @@ class BreakpointSite : public std::enable_shared_from_this<BreakpointSite>,
   /// Sets the trap opcode
   bool SetTrapOpcode(const uint8_t *trap_opcode, uint32_t trap_opcode_size);
 
+  void SetHardwareIndex(uint32_t index) override;
+
   /// Gets the original instruction bytes that were overwritten by the trap
   uint8_t *GetSavedOpcodeBytes();
 

diff  --git a/lldb/include/lldb/Breakpoint/StoppointLocation.h b/lldb/include/lldb/Breakpoint/StoppointLocation.h
index 3926f452e564..3c22813f7e19 100644
--- a/lldb/include/lldb/Breakpoint/StoppointLocation.h
+++ b/lldb/include/lldb/Breakpoint/StoppointLocation.h
@@ -48,7 +48,7 @@ class StoppointLocation {
 
   virtual void Dump(Stream *stream) const {}
 
-  void SetHardwareIndex(uint32_t index) { m_hardware_index = index; }
+  virtual void SetHardwareIndex(uint32_t index) { m_hardware_index = index; }
 
   lldb::break_id_t GetID() const { return m_loc_id; }
 

diff  --git a/lldb/packages/Python/lldbsuite/test/functionalities/breakpoint/hardware_breakpoints/hardware_breakpoint_on_multiple_threads/TestHWBreakMultiThread.py b/lldb/packages/Python/lldbsuite/test/functionalities/breakpoint/hardware_breakpoints/hardware_breakpoint_on_multiple_threads/TestHWBreakMultiThread.py
index 16c63b9ced1c..0ea8e042c5d9 100644
--- a/lldb/packages/Python/lldbsuite/test/functionalities/breakpoint/hardware_breakpoints/hardware_breakpoint_on_multiple_threads/TestHWBreakMultiThread.py
+++ b/lldb/packages/Python/lldbsuite/test/functionalities/breakpoint/hardware_breakpoints/hardware_breakpoint_on_multiple_threads/TestHWBreakMultiThread.py
@@ -21,7 +21,7 @@ class HardwareBreakpointMultiThreadTestCase(TestBase):
     def test_hw_break_set_delete_multi_thread_linux(self):
         self.build()
         self.setTearDownCleanup()
-        self.break_multi_thread('delete', 'breakpoint')
+        self.break_multi_thread('delete')
 
     # LLDB on linux supports hardware breakpoints for arm and aarch64
     # architectures.
@@ -30,7 +30,7 @@ def test_hw_break_set_delete_multi_thread_linux(self):
     def test_hw_break_set_disable_multi_thread_linux(self):
         self.build()
         self.setTearDownCleanup()
-        self.break_multi_thread('disable', 'breakpoint')
+        self.break_multi_thread('disable')
 
     # LLDB on darwin supports hardware breakpoints for arm, aarch64, x86_64 and
     # i386 architectures.
@@ -39,7 +39,7 @@ def test_hw_break_set_disable_multi_thread_linux(self):
     def test_hw_break_set_delete_multi_thread_macos(self):
         self.build()
         self.setTearDownCleanup()
-        self.break_multi_thread('delete', 'EXC_BREAKPOINT')
+        self.break_multi_thread('delete')
 
     # LLDB on darwin supports hardware breakpoints for arm, aarch64, x86_64 and
     # i386 architectures.
@@ -48,7 +48,7 @@ def test_hw_break_set_delete_multi_thread_macos(self):
     def test_hw_break_set_disable_multi_thread_macos(self):
         self.build()
         self.setTearDownCleanup()
-        self.break_multi_thread('disable', 'EXC_BREAKPOINT')
+        self.break_multi_thread('disable')
 
 
     def setUp(self):
@@ -60,7 +60,7 @@ def setUp(self):
         self.first_stop = line_number(
             self.source, 'Starting thread creation with hardware breakpoint set')
 
-    def break_multi_thread(self, removal_type, stop_reason):
+    def break_multi_thread(self, removal_type):
         """Test that lldb hardware breakpoints work for multiple threads."""
         self.runCmd("file " + self.getBuildArtifact("a.out"),
                     CURRENT_EXECUTABLE_SET)
@@ -95,7 +95,7 @@ def break_multi_thread(self, removal_type, stop_reason):
             # The stop reason of the thread should be breakpoint.
             self.expect("thread list", STOPPED_DUE_TO_BREAKPOINT,
                 substrs=[
-                    'stop reason = {}'.format(stop_reason),
+                    'stop reason = breakpoint',
                     'hw_break_function'])
 
             # Continue the loop and test that we are stopped 4 times.

diff  --git a/lldb/source/Breakpoint/BreakpointSite.cpp b/lldb/source/Breakpoint/BreakpointSite.cpp
index 7ffbe28ffb3d..a33fd0a1c462 100644
--- a/lldb/source/Breakpoint/BreakpointSite.cpp
+++ b/lldb/source/Breakpoint/BreakpointSite.cpp
@@ -156,6 +156,13 @@ void BreakpointSite::BumpHitCounts() {
   }
 }
 
+void BreakpointSite::SetHardwareIndex(uint32_t index) {
+  std::lock_guard<std::recursive_mutex> guard(m_owners_mutex);
+  for (BreakpointLocationSP loc_sp : m_owners.BreakpointLocations()) {
+    loc_sp->SetHardwareIndex(index);
+  }
+}
+
 bool BreakpointSite::IntersectsRange(lldb::addr_t addr, size_t size,
                                      lldb::addr_t *intersect_addr,
                                      size_t *intersect_size,

diff  --git a/lldb/source/Plugins/Process/Utility/StopInfoMachException.cpp b/lldb/source/Plugins/Process/Utility/StopInfoMachException.cpp
index c61941640b20..7331fc157ddf 100644
--- a/lldb/source/Plugins/Process/Utility/StopInfoMachException.cpp
+++ b/lldb/source/Plugins/Process/Utility/StopInfoMachException.cpp
@@ -8,6 +8,7 @@
 
 #include "StopInfoMachException.h"
 
+#include "lldb/lldb-forward.h"
 
 #if defined(__APPLE__)
 // Needed for the EXC_RESOURCE interpretation macros
@@ -293,6 +294,44 @@ const char *StopInfoMachException::GetDescription() {
   return m_description.c_str();
 }
 
+static StopInfoSP GetStopInfoForHardwareBP(Thread &thread, Target *target,
+                                           uint32_t exc_data_count,
+                                           uint64_t exc_sub_code,
+                                           uint64_t exc_sub_sub_code) {
+  // Try hardware watchpoint.
+  if (target) {
+    // The exc_sub_code indicates the data break address.
+    lldb::WatchpointSP wp_sp =
+        target->GetWatchpointList().FindByAddress((lldb::addr_t)exc_sub_code);
+    if (wp_sp && wp_sp->IsEnabled()) {
+      // Debugserver may piggyback the hardware index of the fired watchpoint
+      // in the exception data. Set the hardware index if that's the case.
+      if (exc_data_count >= 3)
+        wp_sp->SetHardwareIndex((uint32_t)exc_sub_sub_code);
+      return StopInfo::CreateStopReasonWithWatchpointID(thread, wp_sp->GetID());
+    }
+  }
+
+  // Try hardware breakpoint.
+  ProcessSP process_sp(thread.GetProcess());
+  if (process_sp) {
+    // The exc_sub_code indicates the data break address.
+    lldb::BreakpointSiteSP bp_sp =
+        process_sp->GetBreakpointSiteList().FindByAddress(
+            (lldb::addr_t)exc_sub_code);
+    if (bp_sp && bp_sp->IsEnabled()) {
+      // Debugserver may piggyback the hardware index of the fired breakpoint
+      // in the exception data. Set the hardware index if that's the case.
+      if (exc_data_count >= 3)
+        bp_sp->SetHardwareIndex((uint32_t)exc_sub_sub_code);
+      return StopInfo::CreateStopReasonWithBreakpointSiteID(thread,
+                                                            bp_sp->GetID());
+    }
+  }
+
+  return nullptr;
+}
+
 StopInfoSP StopInfoMachException::CreateStopReasonWithMachException(
     Thread &thread, uint32_t exc_type, uint32_t exc_data_count,
     uint64_t exc_code, uint64_t exc_sub_code, uint64_t exc_sub_sub_code,
@@ -350,22 +389,10 @@ StopInfoSP StopInfoMachException::CreateStopReasonWithMachException(
           is_actual_breakpoint = true;
           is_trace_if_actual_breakpoint_missing = true;
         } else {
-
-          // It's a watchpoint, then.
-          // The exc_sub_code indicates the data break address.
-          lldb::WatchpointSP wp_sp;
-          if (target)
-            wp_sp = target->GetWatchpointList().FindByAddress(
-                (lldb::addr_t)exc_sub_code);
-          if (wp_sp && wp_sp->IsEnabled()) {
-            // Debugserver may piggyback the hardware index of the fired
-            // watchpoint in the exception data. Set the hardware index if
-            // that's the case.
-            if (exc_data_count >= 3)
-              wp_sp->SetHardwareIndex((uint32_t)exc_sub_sub_code);
-            return StopInfo::CreateStopReasonWithWatchpointID(thread,
-                                                              wp_sp->GetID());
-          }
+          if (StopInfoSP stop_info =
+                  GetStopInfoForHardwareBP(thread, target, exc_data_count,
+                                           exc_sub_code, exc_sub_sub_code))
+            return stop_info;
         }
       } else if (exc_code == 2 || // EXC_I386_BPT
                  exc_code == 3)   // EXC_I386_BPTFLT


        


More information about the lldb-commits mailing list