1 //===-- BreakpointLocationCollection.cpp ----------------------------------===//
3 // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
4 // See https://llvm.org/LICENSE.txt for license information.
5 // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
7 //===----------------------------------------------------------------------===//
9 #include "lldb/Breakpoint/BreakpointLocationCollection.h"
10 #include "lldb/Breakpoint/Breakpoint.h"
11 #include "lldb/Breakpoint/BreakpointLocation.h"
12 #include "lldb/Core/ModuleList.h"
13 #include "lldb/Target/Thread.h"
14 #include "lldb/Target/ThreadSpec.h"
17 using namespace lldb_private
;
19 // BreakpointLocationCollection constructor
20 BreakpointLocationCollection::BreakpointLocationCollection() = default;
23 BreakpointLocationCollection::~BreakpointLocationCollection() = default;
25 void BreakpointLocationCollection::Add(const BreakpointLocationSP
&bp_loc
) {
26 std::lock_guard
<std::mutex
> guard(m_collection_mutex
);
27 BreakpointLocationSP old_bp_loc
=
28 FindByIDPair(bp_loc
->GetBreakpoint().GetID(), bp_loc
->GetID());
29 if (!old_bp_loc
.get())
30 m_break_loc_collection
.push_back(bp_loc
);
33 bool BreakpointLocationCollection::Remove(lldb::break_id_t bp_id
,
34 lldb::break_id_t bp_loc_id
) {
35 std::lock_guard
<std::mutex
> guard(m_collection_mutex
);
36 collection::iterator pos
= GetIDPairIterator(bp_id
, bp_loc_id
); // Predicate
37 if (pos
!= m_break_loc_collection
.end()) {
38 m_break_loc_collection
.erase(pos
);
44 class BreakpointIDPairMatches
{
46 BreakpointIDPairMatches(lldb::break_id_t break_id
,
47 lldb::break_id_t break_loc_id
)
48 : m_break_id(break_id
), m_break_loc_id(break_loc_id
) {}
50 bool operator()(const BreakpointLocationSP
&bp_loc
) const {
51 return m_break_id
== bp_loc
->GetBreakpoint().GetID() &&
52 m_break_loc_id
== bp_loc
->GetID();
56 const lldb::break_id_t m_break_id
;
57 const lldb::break_id_t m_break_loc_id
;
60 BreakpointLocationCollection::collection::iterator
61 BreakpointLocationCollection::GetIDPairIterator(lldb::break_id_t break_id
,
62 lldb::break_id_t break_loc_id
) {
64 m_break_loc_collection
.begin(),
65 m_break_loc_collection
.end(), // Search full range
66 BreakpointIDPairMatches(break_id
, break_loc_id
)); // Predicate
69 BreakpointLocationCollection::collection::const_iterator
70 BreakpointLocationCollection::GetIDPairConstIterator(
71 lldb::break_id_t break_id
, lldb::break_id_t break_loc_id
) const {
73 m_break_loc_collection
.begin(),
74 m_break_loc_collection
.end(), // Search full range
75 BreakpointIDPairMatches(break_id
, break_loc_id
)); // Predicate
79 BreakpointLocationCollection::FindByIDPair(lldb::break_id_t break_id
,
80 lldb::break_id_t break_loc_id
) {
81 BreakpointLocationSP stop_sp
;
82 collection::iterator pos
= GetIDPairIterator(break_id
, break_loc_id
);
83 if (pos
!= m_break_loc_collection
.end())
89 const BreakpointLocationSP
BreakpointLocationCollection::FindByIDPair(
90 lldb::break_id_t break_id
, lldb::break_id_t break_loc_id
) const {
91 BreakpointLocationSP stop_sp
;
92 collection::const_iterator pos
=
93 GetIDPairConstIterator(break_id
, break_loc_id
);
94 if (pos
!= m_break_loc_collection
.end())
100 BreakpointLocationSP
BreakpointLocationCollection::GetByIndex(size_t i
) {
101 std::lock_guard
<std::mutex
> guard(m_collection_mutex
);
102 BreakpointLocationSP stop_sp
;
103 if (i
< m_break_loc_collection
.size())
104 stop_sp
= m_break_loc_collection
[i
];
109 const BreakpointLocationSP
110 BreakpointLocationCollection::GetByIndex(size_t i
) const {
111 std::lock_guard
<std::mutex
> guard(m_collection_mutex
);
112 BreakpointLocationSP stop_sp
;
113 if (i
< m_break_loc_collection
.size())
114 stop_sp
= m_break_loc_collection
[i
];
119 bool BreakpointLocationCollection::ShouldStop(
120 StoppointCallbackContext
*context
) {
121 bool shouldStop
= false;
123 size_t prev_size
= GetSize();
124 while (i
< prev_size
) {
125 // ShouldStop can remove the breakpoint from the list, or even delete
127 BreakpointLocationSP cur_loc_sp
= GetByIndex(i
);
128 BreakpointSP keep_bkpt_alive_sp
= cur_loc_sp
->GetBreakpoint().shared_from_this();
129 if (cur_loc_sp
->ShouldStop(context
))
132 if (prev_size
== GetSize())
134 prev_size
= GetSize();
139 bool BreakpointLocationCollection::ValidForThisThread(Thread
&thread
) {
140 std::lock_guard
<std::mutex
> guard(m_collection_mutex
);
141 collection::iterator pos
, begin
= m_break_loc_collection
.begin(),
142 end
= m_break_loc_collection
.end();
144 for (pos
= begin
; pos
!= end
; ++pos
) {
145 if ((*pos
)->ValidForThisThread(thread
))
151 bool BreakpointLocationCollection::IsInternal() const {
152 std::lock_guard
<std::mutex
> guard(m_collection_mutex
);
153 collection::const_iterator pos
, begin
= m_break_loc_collection
.begin(),
154 end
= m_break_loc_collection
.end();
156 bool is_internal
= true;
158 for (pos
= begin
; pos
!= end
; ++pos
) {
159 if (!(*pos
)->GetBreakpoint().IsInternal()) {
167 void BreakpointLocationCollection::GetDescription(
168 Stream
*s
, lldb::DescriptionLevel level
) {
169 std::lock_guard
<std::mutex
> guard(m_collection_mutex
);
170 collection::iterator pos
, begin
= m_break_loc_collection
.begin(),
171 end
= m_break_loc_collection
.end();
173 for (pos
= begin
; pos
!= end
; ++pos
) {
176 (*pos
)->GetDescription(s
, level
);
180 BreakpointLocationCollection
&BreakpointLocationCollection::operator=(
181 const BreakpointLocationCollection
&rhs
) {
183 std::lock(m_collection_mutex
, rhs
.m_collection_mutex
);
184 std::lock_guard
<std::mutex
> lhs_guard(m_collection_mutex
, std::adopt_lock
);
185 std::lock_guard
<std::mutex
> rhs_guard(rhs
.m_collection_mutex
, std::adopt_lock
);
186 m_break_loc_collection
= rhs
.m_break_loc_collection
;