[Lldb-commits] [lldb] f7ec3e3 - [lldb] Skip overlapping hardware and external breakpoints when writing memory
Tatyana Krasnukha via lldb-commits
lldb-commits at lists.llvm.org
Wed Jul 29 11:27:40 PDT 2020
Author: Tatyana Krasnukha
Date: 2020-07-29T21:27:23+03:00
New Revision: f7ec3e3be70d10a630ac22c64073a845b168c829
URL: https://github.com/llvm/llvm-project/commit/f7ec3e3be70d10a630ac22c64073a845b168c829
DIFF: https://github.com/llvm/llvm-project/commit/f7ec3e3be70d10a630ac22c64073a845b168c829.diff
LOG: [lldb] Skip overlapping hardware and external breakpoints when writing memory
This fixes the assertion `assert(intersects);` in the Process::WriteMemory function.
Differential Revision: https://reviews.llvm.org/D84254
Added:
lldb/test/API/functionalities/breakpoint/hardware_breakpoints/write_memory_with_hw_breakpoint/Makefile
lldb/test/API/functionalities/breakpoint/hardware_breakpoints/write_memory_with_hw_breakpoint/TestWriteMemoryWithHWBreakpoint.py
lldb/test/API/functionalities/breakpoint/hardware_breakpoints/write_memory_with_hw_breakpoint/main.cpp
Modified:
lldb/source/Breakpoint/BreakpointSite.cpp
lldb/source/Target/Process.cpp
Removed:
################################################################################
diff --git a/lldb/source/Breakpoint/BreakpointSite.cpp b/lldb/source/Breakpoint/BreakpointSite.cpp
index a33fd0a1c462..bdcabd7cce5e 100644
--- a/lldb/source/Breakpoint/BreakpointSite.cpp
+++ b/lldb/source/Breakpoint/BreakpointSite.cpp
@@ -167,40 +167,39 @@ bool BreakpointSite::IntersectsRange(lldb::addr_t addr, size_t size,
lldb::addr_t *intersect_addr,
size_t *intersect_size,
size_t *opcode_offset) const {
- // We only use software traps for software breakpoints
- if (!IsHardware()) {
- if (m_byte_size > 0) {
- const lldb::addr_t bp_end_addr = m_addr + m_byte_size;
- const lldb::addr_t end_addr = addr + size;
- // Is the breakpoint end address before the passed in start address?
- if (bp_end_addr <= addr)
- return false;
- // Is the breakpoint start address after passed in end address?
- if (end_addr <= m_addr)
- return false;
- if (intersect_addr || intersect_size || opcode_offset) {
- if (m_addr < addr) {
- if (intersect_addr)
- *intersect_addr = addr;
- if (intersect_size)
- *intersect_size =
- std::min<lldb::addr_t>(bp_end_addr, end_addr) - addr;
- if (opcode_offset)
- *opcode_offset = addr - m_addr;
- } else {
- if (intersect_addr)
- *intersect_addr = m_addr;
- if (intersect_size)
- *intersect_size =
- std::min<lldb::addr_t>(bp_end_addr, end_addr) - m_addr;
- if (opcode_offset)
- *opcode_offset = 0;
- }
+ // The function should be called only for software breakpoints.
+ lldbassert(GetType() == Type::eSoftware);
+
+ if (m_byte_size > 0) {
+ const lldb::addr_t bp_end_addr = m_addr + m_byte_size;
+ const lldb::addr_t end_addr = addr + size;
+ // Is the breakpoint end address before the passed in start address?
+ if (bp_end_addr <= addr)
+ return false;
+ // Is the breakpoint start address after passed in end address?
+ if (end_addr <= m_addr)
+ return false;
+ if (intersect_addr || intersect_size || opcode_offset) {
+ if (m_addr < addr) {
+ if (intersect_addr)
+ *intersect_addr = addr;
+ if (intersect_size)
+ *intersect_size =
+ std::min<lldb::addr_t>(bp_end_addr, end_addr) - addr;
+ if (opcode_offset)
+ *opcode_offset = addr - m_addr;
+ } else {
+ if (intersect_addr)
+ *intersect_addr = m_addr;
+ if (intersect_size)
+ *intersect_size =
+ std::min<lldb::addr_t>(bp_end_addr, end_addr) - m_addr;
+ if (opcode_offset)
+ *opcode_offset = 0;
}
- return true;
}
+ return true;
}
- return false;
}
size_t
diff --git a/lldb/source/Target/Process.cpp b/lldb/source/Target/Process.cpp
index 3776a90e546a..36a2930f7915 100644
--- a/lldb/source/Target/Process.cpp
+++ b/lldb/source/Target/Process.cpp
@@ -2291,6 +2291,9 @@ size_t Process::WriteMemory(addr_t addr, const void *buf, size_t size,
if (error.Fail())
return;
+ if (bp->GetType() != BreakpointSite::eSoftware)
+ return;
+
addr_t intersect_addr;
size_t intersect_size;
size_t opcode_offset;
diff --git a/lldb/test/API/functionalities/breakpoint/hardware_breakpoints/write_memory_with_hw_breakpoint/Makefile b/lldb/test/API/functionalities/breakpoint/hardware_breakpoints/write_memory_with_hw_breakpoint/Makefile
new file mode 100644
index 000000000000..99998b20bcb0
--- /dev/null
+++ b/lldb/test/API/functionalities/breakpoint/hardware_breakpoints/write_memory_with_hw_breakpoint/Makefile
@@ -0,0 +1,3 @@
+CXX_SOURCES := main.cpp
+
+include Makefile.rules
diff --git a/lldb/test/API/functionalities/breakpoint/hardware_breakpoints/write_memory_with_hw_breakpoint/TestWriteMemoryWithHWBreakpoint.py b/lldb/test/API/functionalities/breakpoint/hardware_breakpoints/write_memory_with_hw_breakpoint/TestWriteMemoryWithHWBreakpoint.py
new file mode 100644
index 000000000000..842519be6f89
--- /dev/null
+++ b/lldb/test/API/functionalities/breakpoint/hardware_breakpoints/write_memory_with_hw_breakpoint/TestWriteMemoryWithHWBreakpoint.py
@@ -0,0 +1,51 @@
+"""
+Test that writing memory does't affect hardware breakpoints.
+"""
+
+
+
+import lldb
+from lldbsuite.test.decorators import *
+from lldbsuite.test.lldbtest import *
+from lldbsuite.test import lldbutil
+
+from functionalities.breakpoint.hardware_breakpoints.base import *
+
+class WriteMemoryWithHWBreakpoint(HardwareBreakpointTestBase):
+ mydir = TestBase.compute_mydir(__file__)
+
+ def does_not_support_hw_breakpoints(self):
+ return not super().supports_hw_breakpoints()
+
+ @skipTestIfFn(does_not_support_hw_breakpoints)
+ def test_copy_memory_with_hw_break(self):
+ self.build()
+ exe = self.getBuildArtifact("a.out")
+
+ # Create a target by the debugger.
+ target = self.dbg.CreateTarget(exe)
+ self.assertTrue(target, VALID_TARGET)
+
+ # Run the program and stop at entry.
+ self.expect("process launch --stop-at-entry",
+ patterns=["Process .* launched: .*a.out"])
+
+ process = target.GetProcess()
+ self.assertTrue(process, PROCESS_IS_VALID)
+
+ # Set a hardware breakpoint.
+ bp_id = lldbutil.run_break_set_by_symbol(self, "hw_break_function",
+ extra_options="--hardware")
+
+ # Get breakpoint location from the breakpoint.
+ location = target.FindBreakpointByID(bp_id).GetLocationAtIndex(0)
+ self.assertTrue(location and location.IsResolved(),
+ VALID_BREAKPOINT_LOCATION)
+
+ # Check that writing overlapping memory doesn't crash.
+ address = location.GetLoadAddress()
+ data = str("\x01\x02\x03\x04")
+ error = lldb.SBError()
+
+ result = process.WriteMemory(address, data, error)
+ self.assertTrue(error.Success() and result == len(bytes))
diff --git a/lldb/test/API/functionalities/breakpoint/hardware_breakpoints/write_memory_with_hw_breakpoint/main.cpp b/lldb/test/API/functionalities/breakpoint/hardware_breakpoints/write_memory_with_hw_breakpoint/main.cpp
new file mode 100644
index 000000000000..bad219082caf
--- /dev/null
+++ b/lldb/test/API/functionalities/breakpoint/hardware_breakpoints/write_memory_with_hw_breakpoint/main.cpp
@@ -0,0 +1,9 @@
+static volatile int num = 1;
+
+bool hw_break_function (int i) {
+ return num == i;
+}
+
+int main (int argc, char const *argv[]) {
+ return hw_break_function(argc) ? 0 : 1;
+}
More information about the lldb-commits
mailing list