Skip to content

Commit a3fe922

Browse files
authored
Remove hardware index from watchpoints and breakpoints (#72012)
The Watchpoint and Breakpoint objects try to track the hardware index that was used for them, if they are hardware wp/bp's. The majority of our debugging goes over the gdb remote serial protocol, and when we set the watchpoint/breakpoint, there is no (standard) way for the remote stub to communicate to lldb which hardware index was used. We have an lldb-extension packet to query the total number of watchpoint registers. When a watchpoint is hit, there is an lldb extension to the stop reply packet (documented in lldb-gdb-remote.txt) to describe the watchpoint including its actual hardware index, <addr within wp range> <wp hw index> <actual accessed address> (the third field is specifically needed for MIPS). At this point, if the stub reported these three fields (the stub is only required to provide the first), we can know the actual hardware index for this watchpoint. Breakpoints are worse; there's never any way for us to be notified about which hardware index was used. Breakpoints got this as a side effect of inherting from StoppointSite with Watchpoints. We expose the watchpoint hardware index through "watchpoint list -v" and through SBWatchpoint::GetHardwareIndex. With my large watchpoint support, there is no *single* hardware index that may be used for a watchpoint, it may need multiple resources. Also I don't see what a user is supposed to do with this information, or an IDE. Knowing the total number of watchpoint registers on the target, and knowing how many Watchpoint Resources are currently in use, is helpful. Knowing how many Watchpoint Resources a single user-specified watchpoint needed to be implemented is useful. But knowing which registers were used is an implementation detail and not available until we hit the watchpoint when using gdb remote serial protocol. So given all that, I'm removing watchpoint hardware index numbers. I'm changing the SB API to always return -1.
1 parent f00bade commit a3fe922

File tree

17 files changed

+30
-80
lines changed

17 files changed

+30
-80
lines changed

lldb/bindings/interface/SBTargetDocstrings.i

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -34,7 +34,7 @@ produces: ::
3434
3535
Watchpoint 1: addr = 0x1034ca048 size = 4 state = enabled type = rw
3636
declare @ '/Volumes/data/lldb/svn/trunk/test/python_api/watchpoint/main.c:12'
37-
hw_index = 0 hit_count = 2 ignore_count = 0"
37+
hit_count = 2 ignore_count = 0"
3838
) lldb::SBTarget;
3939

4040
%feature("docstring", "

lldb/bindings/interface/SBWatchpointDocstrings.i

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -9,7 +9,8 @@ watchpoints of the target."
99
) lldb::SBWatchpoint;
1010

1111
%feature("docstring", "
12-
With -1 representing an invalid hardware index."
12+
Deprecated. Previously: Return the hardware index of the
13+
watchpoint register. Now: -1 is always returned."
1314
) lldb::SBWatchpoint::GetHardwareIndex;
1415

1516
%feature("docstring", "

lldb/docs/use/tutorial.rst

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -431,7 +431,7 @@ a variable called 'global' for write operation, but only stop if the condition
431431
Watchpoint 1: addr = 0x100001018 size = 4 state = enabled type = w
432432
declare @ '/Volumes/data/lldb/svn/ToT/test/functionalities/watchpoint/watchpoint_commands/condition/main.cpp:12'
433433
condition = '(global==5)'
434-
hw_index = 0 hit_count = 5 ignore_count = 0
434+
hit_count = 5 ignore_count = 0
435435
(lldb)
436436

437437
Starting or Attaching to Your Program

lldb/include/lldb/API/SBWatchpoint.h

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -45,7 +45,7 @@ class LLDB_API SBWatchpoint {
4545

4646
watch_id_t GetID();
4747

48-
/// With -1 representing an invalid hardware index.
48+
LLDB_DEPRECATED("Hardware index is not available, always returns -1")
4949
int32_t GetHardwareIndex();
5050

5151
lldb::addr_t GetWatchAddress();

lldb/include/lldb/Breakpoint/StoppointSite.h

Lines changed: 0 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -38,10 +38,6 @@ class StoppointSite {
3838

3939
virtual bool IsHardware() const = 0;
4040

41-
uint32_t GetHardwareIndex() const { return m_hardware_index; }
42-
43-
void SetHardwareIndex(uint32_t index) { m_hardware_index = index; }
44-
4541
virtual bool ShouldStop(StoppointCallbackContext* context) = 0;
4642

4743
virtual void Dump(Stream* stream) const = 0;
@@ -59,9 +55,6 @@ class StoppointSite {
5955
/// the lack of resources).
6056
bool m_is_hardware_required;
6157

62-
/// The hardware resource index for this breakpoint/watchpoint.
63-
uint32_t m_hardware_index;
64-
6558
/// The size in bytes of stoppoint, e.g. the length of the trap opcode for
6659
/// software breakpoints, or the optional length in bytes for hardware
6760
/// breakpoints, or the length of the watchpoint.

lldb/source/API/SBWatchpoint.cpp

Lines changed: 5 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -94,16 +94,11 @@ SBError SBWatchpoint::GetError() {
9494
int32_t SBWatchpoint::GetHardwareIndex() {
9595
LLDB_INSTRUMENT_VA(this);
9696

97-
int32_t hw_index = -1;
98-
99-
lldb::WatchpointSP watchpoint_sp(GetSP());
100-
if (watchpoint_sp) {
101-
std::lock_guard<std::recursive_mutex> guard(
102-
watchpoint_sp->GetTarget().GetAPIMutex());
103-
hw_index = watchpoint_sp->GetHardwareIndex();
104-
}
105-
106-
return hw_index;
97+
// For processes using gdb remote protocol,
98+
// we cannot determine the hardware breakpoint
99+
// index reliably; providing possibly correct
100+
// guesses is not useful to anyone.
101+
return -1;
107102
}
108103

109104
addr_t SBWatchpoint::GetWatchAddress() {

lldb/source/Breakpoint/BreakpointLocation.cpp

Lines changed: 2 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -626,22 +626,19 @@ void BreakpointLocation::Dump(Stream *s) const {
626626

627627
bool is_resolved = IsResolved();
628628
bool is_hardware = is_resolved && m_bp_site_sp->IsHardware();
629-
auto hardware_index = is_resolved ?
630-
m_bp_site_sp->GetHardwareIndex() : LLDB_INVALID_INDEX32;
631629

632630
lldb::tid_t tid = GetOptionsSpecifyingKind(BreakpointOptions::eThreadSpec)
633631
.GetThreadSpecNoCreate()
634632
->GetTID();
635633
s->Printf("BreakpointLocation %u: tid = %4.4" PRIx64
636634
" load addr = 0x%8.8" PRIx64 " state = %s type = %s breakpoint "
637-
"hw_index = %i hit_count = %-4u ignore_count = %-4u",
635+
"hit_count = %-4u ignore_count = %-4u",
638636
GetID(), tid,
639637
(uint64_t)m_address.GetOpcodeLoadAddress(&m_owner.GetTarget()),
640638
(m_options_up ? m_options_up->IsEnabled() : m_owner.IsEnabled())
641639
? "enabled "
642640
: "disabled",
643-
is_hardware ? "hardware" : "software", hardware_index,
644-
GetHitCount(),
641+
is_hardware ? "hardware" : "software", GetHitCount(),
645642
GetOptionsSpecifyingKind(BreakpointOptions::eIgnoreCount)
646643
.GetIgnoreCount());
647644
}

lldb/source/Breakpoint/BreakpointSite.cpp

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -76,9 +76,9 @@ void BreakpointSite::Dump(Stream *s) const {
7676
return;
7777

7878
s->Printf("BreakpointSite %u: addr = 0x%8.8" PRIx64
79-
" type = %s breakpoint hw_index = %i hit_count = %-4u",
79+
" type = %s breakpoint hit_count = %-4u",
8080
GetID(), (uint64_t)m_addr, IsHardware() ? "hardware" : "software",
81-
GetHardwareIndex(), GetHitCount());
81+
GetHitCount());
8282
}
8383

8484
void BreakpointSite::GetDescription(Stream *s, lldb::DescriptionLevel level) {

lldb/source/Breakpoint/StoppointSite.cpp

Lines changed: 5 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -13,11 +13,10 @@ using namespace lldb;
1313
using namespace lldb_private;
1414

1515
StoppointSite::StoppointSite(break_id_t id, addr_t addr, bool hardware)
16-
: m_id(id), m_addr(addr), m_is_hardware_required(hardware),
17-
m_hardware_index(LLDB_INVALID_INDEX32), m_byte_size(0), m_hit_counter() {}
16+
: m_id(id), m_addr(addr), m_is_hardware_required(hardware), m_byte_size(0),
17+
m_hit_counter() {}
1818

19-
StoppointSite::StoppointSite(break_id_t id, addr_t addr,
20-
uint32_t byte_size, bool hardware)
19+
StoppointSite::StoppointSite(break_id_t id, addr_t addr, uint32_t byte_size,
20+
bool hardware)
2121
: m_id(id), m_addr(addr), m_is_hardware_required(hardware),
22-
m_hardware_index(LLDB_INVALID_INDEX32), m_byte_size(byte_size),
23-
m_hit_counter() {}
22+
m_byte_size(byte_size), m_hit_counter() {}

lldb/source/Breakpoint/Watchpoint.cpp

Lines changed: 3 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -324,8 +324,8 @@ void Watchpoint::DumpWithLevel(Stream *s,
324324
}
325325

326326
if (description_level >= lldb::eDescriptionLevelVerbose) {
327-
s->Printf("\n hw_index = %i hit_count = %-4u ignore_count = %-4u",
328-
GetHardwareIndex(), GetHitCount(), GetIgnoreCount());
327+
s->Printf("\n hit_count = %-4u ignore_count = %-4u", GetHitCount(),
328+
GetIgnoreCount());
329329
}
330330
}
331331

@@ -350,9 +350,7 @@ bool Watchpoint::IsDisabledDuringEphemeralMode() {
350350

351351
void Watchpoint::SetEnabled(bool enabled, bool notify) {
352352
if (!enabled) {
353-
if (!m_is_ephemeral)
354-
SetHardwareIndex(LLDB_INVALID_INDEX32);
355-
else
353+
if (m_is_ephemeral)
356354
++m_disabled_count;
357355

358356
// Don't clear the snapshots for now.

lldb/source/Plugins/Process/Utility/StopInfoMachException.cpp

Lines changed: 0 additions & 18 deletions
Original file line numberDiff line numberDiff line change
@@ -495,10 +495,6 @@ static StopInfoSP GetStopInfoForHardwareBP(Thread &thread, Target *target,
495495
lldb::WatchpointSP wp_sp =
496496
target->GetWatchpointList().FindByAddress((lldb::addr_t)exc_sub_code);
497497
if (wp_sp && wp_sp->IsEnabled()) {
498-
// Debugserver may piggyback the hardware index of the fired watchpoint
499-
// in the exception data. Set the hardware index if that's the case.
500-
if (exc_data_count >= 3)
501-
wp_sp->SetHardwareIndex((uint32_t)exc_sub_sub_code);
502498
return StopInfo::CreateStopReasonWithWatchpointID(thread, wp_sp->GetID());
503499
}
504500
}
@@ -511,10 +507,6 @@ static StopInfoSP GetStopInfoForHardwareBP(Thread &thread, Target *target,
511507
process_sp->GetBreakpointSiteList().FindByAddress(
512508
(lldb::addr_t)exc_sub_code);
513509
if (bp_sp && bp_sp->IsEnabled()) {
514-
// Debugserver may piggyback the hardware index of the fired breakpoint
515-
// in the exception data. Set the hardware index if that's the case.
516-
if (exc_data_count >= 3)
517-
bp_sp->SetHardwareIndex((uint32_t)exc_sub_sub_code);
518510
return StopInfo::CreateStopReasonWithBreakpointSiteID(thread,
519511
bp_sp->GetID());
520512
}
@@ -681,11 +673,6 @@ StopInfoSP StopInfoMachException::CreateStopReasonWithMachException(
681673
wp_sp = target->GetWatchpointList().FindByAddress(
682674
(lldb::addr_t)exc_sub_code);
683675
if (wp_sp && wp_sp->IsEnabled()) {
684-
// Debugserver may piggyback the hardware index of the fired
685-
// watchpoint in the exception data. Set the hardware index if
686-
// that's the case.
687-
if (exc_data_count >= 3)
688-
wp_sp->SetHardwareIndex((uint32_t)exc_sub_sub_code);
689676
return StopInfo::CreateStopReasonWithWatchpointID(thread,
690677
wp_sp->GetID());
691678
} else {
@@ -762,11 +749,6 @@ StopInfoSP StopInfoMachException::CreateStopReasonWithMachException(
762749
wp_sp = target->GetWatchpointList().FindByAddress(
763750
(lldb::addr_t)exc_sub_code);
764751
if (wp_sp && wp_sp->IsEnabled()) {
765-
// Debugserver may piggyback the hardware index of the fired
766-
// watchpoint in the exception data. Set the hardware index if
767-
// that's the case.
768-
if (exc_data_count >= 3)
769-
wp_sp->SetHardwareIndex((uint32_t)exc_sub_sub_code);
770752
return StopInfo::CreateStopReasonWithWatchpointID(thread,
771753
wp_sp->GetID());
772754
}

lldb/source/Plugins/Process/Windows/Common/ProcessWindows.cpp

Lines changed: 0 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -405,10 +405,6 @@ void ProcessWindows::RefreshStateAfterStop() {
405405
"{1:x} with watchpoint {2}",
406406
m_session_data->m_debugger->GetProcess().GetProcessId(), pc, id);
407407

408-
if (lldb::WatchpointSP wp_sp =
409-
GetTarget().GetWatchpointList().FindByID(id))
410-
wp_sp->SetHardwareIndex(slot_id);
411-
412408
stop_info = StopInfo::CreateStopReasonWithWatchpointID(
413409
*stop_thread, id, m_watchpoints[id].address);
414410
stop_thread->SetStopInfo(stop_info);

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

Lines changed: 6 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -1789,8 +1789,12 @@ ThreadSP ProcessGDBRemote::SetThreadStopInfo(
17891789
// disable/step/re-enable it, so one of the valid watchpoint
17901790
// addresses should be provided as \a wp_addr.
17911791
StringExtractor desc_extractor(description.c_str());
1792+
// FIXME NativeThreadLinux::SetStoppedByWatchpoint sends this
1793+
// up as
1794+
// <address within wp range> <wp hw index> <actual accessed addr>
1795+
// but this is not reading the <wp hw index>. Seems like it
1796+
// wouldn't work on MIPS, where that third field is important.
17921797
addr_t wp_addr = desc_extractor.GetU64(LLDB_INVALID_ADDRESS);
1793-
uint32_t wp_index = desc_extractor.GetU32(LLDB_INVALID_INDEX32);
17941798
addr_t wp_hit_addr = desc_extractor.GetU64(LLDB_INVALID_ADDRESS);
17951799
watch_id_t watch_id = LLDB_INVALID_WATCH_ID;
17961800
bool silently_continue = false;
@@ -1807,7 +1811,6 @@ ThreadSP ProcessGDBRemote::SetThreadStopInfo(
18071811
if (!wp_sp && wp_addr != LLDB_INVALID_ADDRESS)
18081812
wp_sp = GetTarget().GetWatchpointList().FindByAddress(wp_addr);
18091813
if (wp_sp) {
1810-
wp_sp->SetHardwareIndex(wp_index);
18111814
watch_id = wp_sp->GetID();
18121815
}
18131816
if (watch_id == LLDB_INVALID_WATCH_ID) {
@@ -2238,17 +2241,13 @@ StateType ProcessGDBRemote::SetThreadStopInfo(StringExtractor &stop_packet) {
22382241

22392242
WatchpointSP wp_sp =
22402243
GetTarget().GetWatchpointList().FindByAddress(wp_addr);
2241-
uint32_t wp_index = LLDB_INVALID_INDEX32;
2242-
2243-
if (wp_sp)
2244-
wp_index = wp_sp->GetHardwareIndex();
22452244

22462245
// Rewrite gdb standard watch/rwatch/awatch to
22472246
// "reason:watchpoint" + "description:ADDR",
22482247
// which is parsed in SetThreadStopInfo.
22492248
reason = "watchpoint";
22502249
StreamString ostr;
2251-
ostr.Printf("%" PRIu64 " %" PRIu32, wp_addr, wp_index);
2250+
ostr.Printf("%" PRIu64, wp_addr);
22522251
description = std::string(ostr.GetString());
22532252
} else if (key.compare("library") == 0) {
22542253
auto error = LoadModules();

lldb/source/Target/StopInfo.cpp

Lines changed: 0 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -699,7 +699,6 @@ class StopInfoWatchpoint : public StopInfo {
699699
eVoteNoOpinion),
700700
m_stop_info_sp(stop_info_sp), m_watch_sp(watch_sp) {
701701
assert(watch_sp);
702-
m_watch_index = watch_sp->GetHardwareIndex();
703702
}
704703

705704
bool DoWillResume(lldb::StateType resume_state,
@@ -753,13 +752,11 @@ class StopInfoWatchpoint : public StopInfo {
753752
return;
754753
m_did_disable_wp = true;
755754
GetThread().GetProcess()->EnableWatchpoint(m_watch_sp.get(), true);
756-
m_watch_sp->SetHardwareIndex(m_watch_index);
757755
}
758756

759757
private:
760758
StopInfoWatchpointSP m_stop_info_sp;
761759
WatchpointSP m_watch_sp;
762-
uint32_t m_watch_index = LLDB_INVALID_INDEX32;
763760
bool m_did_disable_wp = false;
764761
};
765762

lldb/test/API/python_api/default-constructor/sb_watchpoint.py

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -8,7 +8,6 @@
88
def fuzz_obj(obj):
99
obj.GetID()
1010
obj.IsValid()
11-
obj.GetHardwareIndex()
1211
obj.GetWatchAddress()
1312
obj.GetWatchSize()
1413
obj.SetEnabled(True)

lldb/test/API/python_api/watchpoint/TestWatchpointIter.py

Lines changed: 0 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -83,20 +83,12 @@ def test_watch_iter(self):
8383
self.assertTrue(thread, "The thread stopped due to watchpoint")
8484
self.DebugSBValue(value)
8585

86-
# We currently only support hardware watchpoint. Verify that we have a
87-
# meaningful hardware index at this point. Exercise the printed repr of
88-
# SBWatchpointLocation.
89-
print(watchpoint)
90-
if not self.affected_by_radar_34564183():
91-
self.assertTrue(watchpoint.GetHardwareIndex() != -1)
92-
9386
# SBWatchpoint.GetDescription() takes a description level arg.
9487
print(lldbutil.get_description(watchpoint, lldb.eDescriptionLevelFull))
9588

9689
# Now disable the 'rw' watchpoint. The program won't stop when it reads
9790
# 'global' next.
9891
watchpoint.SetEnabled(False)
99-
self.assertEqual(watchpoint.GetHardwareIndex(), -1)
10092
self.assertFalse(watchpoint.IsEnabled())
10193

10294
# Continue. The program does not stop again when the variable is being

llvm/docs/ReleaseNotes.rst

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -230,6 +230,8 @@ Changes to the LLVM tools
230230
Changes to LLDB
231231
---------------------------------
232232

233+
* ``SBWatchpoint::GetHardwareIndex`` is deprecated and now returns -1
234+
to indicate the index is unavailable.
233235
* Methods in SBHostOS related to threads have had their implementations
234236
removed. These methods will return a value indicating failure.
235237
* ``SBType::FindDirectNestedType`` function is added. It's useful

0 commit comments

Comments
 (0)