Skip to content

Commit ebaa8b1

Browse files
committed
[lldb] Don't use hardware index to determine whether a breakpoint site is hardware
Most process plugins (if not all) don't set hardware index for breakpoints. They even are not able to determine this index. This patch makes StoppointLocation::IsHardware pure virtual and lets BreakpointSite override it using more accurate BreakpointSite::Type. It also adds assertions to be sure that a breakpoint site is hardware when this is required. Differential Revision: https://reviews.llvm.org/D84257
1 parent b352e62 commit ebaa8b1

File tree

7 files changed

+32
-42
lines changed

7 files changed

+32
-42
lines changed

lldb/include/lldb/Breakpoint/BreakpointLocation.h

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -76,6 +76,12 @@ class BreakpointLocation
7676
/// \b true if the breakpoint is enabled, \b false if disabled.
7777
bool IsEnabled() const;
7878

79+
/// Check if it is a hardware breakpoint.
80+
///
81+
/// \return
82+
/// \b true if the breakpoint is a harware breakpoint.
83+
bool IsHardware() const override;
84+
7985
/// If \a auto_continue is \b true, set the breakpoint to continue when hit.
8086
void SetAutoContinue(bool auto_continue);
8187

lldb/include/lldb/Breakpoint/BreakpointSite.h

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -15,6 +15,7 @@
1515

1616
#include "lldb/Breakpoint/BreakpointLocationCollection.h"
1717
#include "lldb/Breakpoint/StoppointLocation.h"
18+
#include "lldb/Utility/LLDBAssert.h"
1819
#include "lldb/Utility/UserID.h"
1920
#include "lldb/lldb-forward.h"
2021

@@ -184,6 +185,12 @@ class BreakpointSite : public std::enable_shared_from_this<BreakpointSite>,
184185
/// \b false otherwise.
185186
bool IsInternal() const;
186187

188+
bool IsHardware() const override {
189+
lldbassert(BreakpointSite::Type::eHardware == GetType() ||
190+
!HardwareRequired());
191+
return BreakpointSite::Type::eHardware == GetType();
192+
}
193+
187194
BreakpointSite::Type GetType() const { return m_type; }
188195

189196
void SetType(BreakpointSite::Type type) { m_type = type; }

lldb/include/lldb/Breakpoint/StoppointLocation.h

Lines changed: 1 addition & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -40,9 +40,7 @@ class StoppointLocation {
4040

4141
bool HardwareRequired() const { return m_hardware; }
4242

43-
virtual bool IsHardware() const {
44-
return m_hardware_index != LLDB_INVALID_INDEX32;
45-
}
43+
virtual bool IsHardware() const = 0;
4644

4745
virtual bool ShouldStop(StoppointCallbackContext *context) { return true; }
4846

lldb/source/Breakpoint/BreakpointLocation.cpp

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -68,6 +68,14 @@ Breakpoint &BreakpointLocation::GetBreakpoint() { return m_owner; }
6868

6969
Target &BreakpointLocation::GetTarget() { return m_owner.GetTarget(); }
7070

71+
bool BreakpointLocation::IsHardware() const {
72+
if (m_bp_site_sp)
73+
return m_bp_site_sp->IsHardware();
74+
75+
// If breakpoint location is not resolved yet, it cannot be hardware.
76+
return false;
77+
}
78+
7179
bool BreakpointLocation::IsEnabled() const {
7280
if (!m_owner.IsEnabled())
7381
return false;

lldb/source/Breakpoint/Watchpoint.cpp

Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -95,7 +95,10 @@ void Watchpoint::SetWatchSpec(const std::string &str) {
9595

9696
// Override default impl of StoppointLocation::IsHardware() since m_is_hardware
9797
// member field is more accurate.
98-
bool Watchpoint::IsHardware() const { return m_is_hardware; }
98+
bool Watchpoint::IsHardware() const {
99+
lldbassert(m_is_hardware || !HardwareRequired());
100+
return m_is_hardware;
101+
}
99102

100103
bool Watchpoint::IsWatchVariable() const { return m_is_watch_variable; }
101104

lldb/source/Plugins/Process/gdb-remote/ProcessGDBRemote.cpp

Lines changed: 2 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -3204,14 +3204,8 @@ Status ProcessGDBRemote::DisableBreakpointSite(BreakpointSite *bp_site) {
32043204
break;
32053205

32063206
case BreakpointSite::eExternal: {
3207-
GDBStoppointType stoppoint_type;
3208-
if (bp_site->IsHardware())
3209-
stoppoint_type = eBreakpointHardware;
3210-
else
3211-
stoppoint_type = eBreakpointSoftware;
3212-
3213-
if (m_gdb_comm.SendGDBStoppointTypePacket(stoppoint_type, false, addr,
3214-
bp_op_size))
3207+
if (m_gdb_comm.SendGDBStoppointTypePacket(eBreakpointSoftware, false,
3208+
addr, bp_op_size))
32153209
error.SetErrorToGenericError();
32163210
} break;
32173211
}

lldb/test/API/functionalities/breakpoint/hardware_breakpoints/hardware_breakpoint_on_multiple_threads/TestHWBreakMultiThread.py

Lines changed: 4 additions & 30 deletions
Original file line numberDiff line numberDiff line change
@@ -17,45 +17,20 @@ class HardwareBreakpointMultiThreadTestCase(HardwareBreakpointTestBase):
1717
def does_not_support_hw_breakpoints(self):
1818
return not super().supports_hw_breakpoints()
1919

20-
# LLDB on linux supports hardware breakpoints for arm and aarch64
21-
# architectures.
22-
@skipUnlessPlatform(oslist=['linux'])
23-
@skipTestIfFn(does_not_support_hw_breakpoints)
24-
def test_hw_break_set_delete_multi_thread_linux(self):
25-
self.build()
26-
self.setTearDownCleanup()
27-
self.break_multi_thread('delete', False) # llvm.org/PR44659
28-
29-
# LLDB on linux supports hardware breakpoints for arm and aarch64
30-
# architectures.
31-
@skipUnlessPlatform(oslist=['linux'])
32-
@skipTestIfFn(does_not_support_hw_breakpoints)
33-
def test_hw_break_set_disable_multi_thread_linux(self):
34-
self.build()
35-
self.setTearDownCleanup()
36-
self.break_multi_thread('disable', False) # llvm.org/PR44659
37-
38-
# LLDB on darwin supports hardware breakpoints for x86_64 and i386
39-
# architectures.
40-
@skipUnlessDarwin
4120
@skipIfOutOfTreeDebugserver
4221
@skipTestIfFn(does_not_support_hw_breakpoints)
4322
def test_hw_break_set_delete_multi_thread_macos(self):
4423
self.build()
4524
self.setTearDownCleanup()
4625
self.break_multi_thread('delete')
4726

48-
# LLDB on darwin supports hardware breakpoints for x86_64 and i386
49-
# architectures.
50-
@skipUnlessDarwin
5127
@skipIfOutOfTreeDebugserver
5228
@skipTestIfFn(does_not_support_hw_breakpoints)
5329
def test_hw_break_set_disable_multi_thread_macos(self):
5430
self.build()
5531
self.setTearDownCleanup()
5632
self.break_multi_thread('disable')
5733

58-
5934
def setUp(self):
6035
# Call super's setUp().
6136
TestBase.setUp(self)
@@ -65,7 +40,7 @@ def setUp(self):
6540
self.first_stop = line_number(
6641
self.source, 'Starting thread creation with hardware breakpoint set')
6742

68-
def break_multi_thread(self, removal_type, check_hw_bp=True):
43+
def break_multi_thread(self, removal_type):
6944
"""Test that lldb hardware breakpoints work for multiple threads."""
7045
self.runCmd("file " + self.getBuildArtifact("a.out"),
7146
CURRENT_EXECUTABLE_SET)
@@ -109,10 +84,9 @@ def break_multi_thread(self, removal_type, check_hw_bp=True):
10984
# Continue the loop and test that we are stopped 4 times.
11085
count += 1
11186

112-
if check_hw_bp:
113-
# Check the breakpoint list.
114-
self.expect("breakpoint list", substrs=['hw_break_function', 'hardware'])
115-
self.expect("breakpoint list -v", substrs=['function = hw_break_function', 'hardware = true'])
87+
# Check the breakpoint list.
88+
self.expect("breakpoint list", substrs=['hw_break_function', 'hardware'])
89+
self.expect("breakpoint list -v", substrs=['function = hw_break_function', 'hardware = true'])
11690

11791
if removal_type == 'delete':
11892
self.runCmd("settings set auto-confirm true")

0 commit comments

Comments
 (0)