File indexing completed on 2026-05-10 08:42:44
0001
0002
0003
0004
0005
0006
0007
0008
0009 #ifndef LLDB_BREAKPOINT_STOPPOINTSITELIST_H
0010 #define LLDB_BREAKPOINT_STOPPOINTSITELIST_H
0011
0012 #include <functional>
0013 #include <map>
0014 #include <mutex>
0015
0016 #include <lldb/Breakpoint/BreakpointSite.h>
0017 #include <lldb/Utility/Iterable.h>
0018 #include <lldb/Utility/Stream.h>
0019
0020 namespace lldb_private {
0021
0022 template <typename StopPointSite> class StopPointSiteList {
0023
0024
0025
0026 friend class Process;
0027
0028 public:
0029 using StopPointSiteSP = std::shared_ptr<StopPointSite>;
0030
0031
0032
0033
0034
0035
0036
0037
0038 typename StopPointSite::SiteID Add(const StopPointSiteSP &site_sp) {
0039 lldb::addr_t site_load_addr = site_sp->GetLoadAddress();
0040 std::lock_guard<std::recursive_mutex> guard(m_mutex);
0041
0042
0043 bool inserted = m_site_list.try_emplace(site_load_addr, site_sp).second;
0044 return inserted ? site_sp->GetID() : UINT32_MAX;
0045 }
0046
0047
0048
0049
0050 void Dump(Stream *s) const {
0051 s->Printf("%p: ", static_cast<const void *>(this));
0052 s->Printf("StopPointSiteList with %u ConstituentSites:\n",
0053 (uint32_t)m_site_list.size());
0054 s->IndentMore();
0055 typename collection::const_iterator pos;
0056 typename collection::const_iterator end = m_site_list.end();
0057 for (pos = m_site_list.begin(); pos != end; ++pos)
0058 pos->second->Dump(s);
0059 s->IndentLess();
0060 }
0061
0062
0063
0064
0065
0066
0067
0068
0069
0070 StopPointSiteSP FindByAddress(lldb::addr_t addr) {
0071 StopPointSiteSP found_sp;
0072 std::lock_guard<std::recursive_mutex> guard(m_mutex);
0073 typename collection::iterator iter = m_site_list.find(addr);
0074 if (iter != m_site_list.end())
0075 found_sp = iter->second;
0076 return found_sp;
0077 }
0078
0079
0080
0081
0082
0083
0084
0085
0086 StopPointSiteSP FindByID(typename StopPointSite::SiteID site_id) {
0087 std::lock_guard<std::recursive_mutex> guard(m_mutex);
0088 StopPointSiteSP stop_sp;
0089 typename collection::iterator pos = GetIDIterator(site_id);
0090 if (pos != m_site_list.end())
0091 stop_sp = pos->second;
0092
0093 return stop_sp;
0094 }
0095
0096
0097
0098
0099
0100
0101
0102
0103
0104 const StopPointSiteSP FindByID(typename StopPointSite::SiteID site_id) const {
0105 std::lock_guard<std::recursive_mutex> guard(m_mutex);
0106 StopPointSiteSP stop_sp;
0107 typename collection::const_iterator pos = GetIDConstIterator(site_id);
0108 if (pos != m_site_list.end())
0109 stop_sp = pos->second;
0110
0111 return stop_sp;
0112 }
0113
0114
0115
0116
0117
0118
0119
0120
0121 typename StopPointSite::SiteID FindIDByAddress(lldb::addr_t addr) {
0122 if (StopPointSiteSP site = FindByAddress(addr))
0123 return site->GetID();
0124 return UINT32_MAX;
0125 }
0126
0127
0128
0129
0130
0131
0132
0133
0134
0135
0136
0137
0138
0139
0140
0141
0142 bool StopPointSiteContainsBreakpoint(typename StopPointSite::SiteID,
0143 lldb::break_id_t bp_id);
0144
0145 void ForEach(std::function<void(StopPointSite *)> const &callback) {
0146 std::lock_guard<std::recursive_mutex> guard(m_mutex);
0147 for (auto pair : m_site_list)
0148 callback(pair.second.get());
0149 }
0150
0151
0152
0153
0154
0155
0156
0157
0158 bool Remove(typename StopPointSite::SiteID site_id) {
0159 std::lock_guard<std::recursive_mutex> guard(m_mutex);
0160 typename collection::iterator pos = GetIDIterator(site_id);
0161 if (pos != m_site_list.end()) {
0162 m_site_list.erase(pos);
0163 return true;
0164 }
0165 return false;
0166 }
0167
0168
0169
0170
0171
0172
0173
0174
0175 bool RemoveByAddress(lldb::addr_t addr) {
0176 std::lock_guard<std::recursive_mutex> guard(m_mutex);
0177 typename collection::iterator pos = m_site_list.find(addr);
0178 if (pos != m_site_list.end()) {
0179 m_site_list.erase(pos);
0180 return true;
0181 }
0182 return false;
0183 }
0184
0185 bool FindInRange(lldb::addr_t lower_bound, lldb::addr_t upper_bound,
0186 StopPointSiteList &bp_site_list) const {
0187 if (lower_bound > upper_bound)
0188 return false;
0189
0190 std::lock_guard<std::recursive_mutex> guard(m_mutex);
0191 typename collection::const_iterator lower, upper, pos;
0192 lower = m_site_list.lower_bound(lower_bound);
0193 if (lower == m_site_list.end() || (*lower).first >= upper_bound)
0194 return false;
0195
0196
0197
0198
0199 if (lower != m_site_list.begin()) {
0200 typename collection::const_iterator prev_pos = lower;
0201 prev_pos--;
0202 const StopPointSiteSP &prev_site = (*prev_pos).second;
0203 if (prev_site->GetLoadAddress() + prev_site->GetByteSize() > lower_bound)
0204 bp_site_list.Add(prev_site);
0205 }
0206
0207 upper = m_site_list.upper_bound(upper_bound);
0208
0209 for (pos = lower; pos != upper; pos++)
0210 bp_site_list.Add((*pos).second);
0211 return true;
0212 }
0213
0214 typedef void (*StopPointSiteSPMapFunc)(StopPointSite &site, void *baton);
0215
0216
0217
0218
0219
0220
0221
0222
0223
0224
0225
0226
0227 bool ShouldStop(StoppointCallbackContext *context,
0228 typename StopPointSite::SiteID site_id) {
0229 if (StopPointSiteSP site_sp = FindByID(site_id)) {
0230
0231
0232
0233 return site_sp->ShouldStop(context);
0234 }
0235
0236
0237 return true;
0238 }
0239
0240
0241
0242
0243
0244 size_t GetSize() const {
0245 std::lock_guard<std::recursive_mutex> guard(m_mutex);
0246 return m_site_list.size();
0247 }
0248
0249 bool IsEmpty() const {
0250 std::lock_guard<std::recursive_mutex> guard(m_mutex);
0251 return m_site_list.empty();
0252 }
0253
0254 std::vector<StopPointSiteSP> Sites() {
0255 std::vector<StopPointSiteSP> sites;
0256 std::lock_guard<std::recursive_mutex> guard(m_mutex);
0257 typename collection::iterator iter = m_site_list.begin();
0258 while (iter != m_site_list.end()) {
0259 sites.push_back(iter->second);
0260 ++iter;
0261 }
0262
0263 return sites;
0264 }
0265
0266 void Clear() {
0267 std::lock_guard<std::recursive_mutex> guard(m_mutex);
0268 m_site_list.clear();
0269 }
0270
0271 protected:
0272 typedef std::map<lldb::addr_t, StopPointSiteSP> collection;
0273
0274 typename collection::iterator
0275 GetIDIterator(typename StopPointSite::SiteID site_id) {
0276 std::lock_guard<std::recursive_mutex> guard(m_mutex);
0277 auto id_matches =
0278 [site_id](const std::pair<lldb::addr_t, StopPointSiteSP> s) {
0279 return site_id == s.second->GetID();
0280 };
0281 return std::find_if(m_site_list.begin(),
0282 m_site_list.end(),
0283 id_matches);
0284 }
0285
0286 typename collection::const_iterator
0287 GetIDConstIterator(typename StopPointSite::SiteID site_id) const {
0288 std::lock_guard<std::recursive_mutex> guard(m_mutex);
0289 auto id_matches =
0290 [site_id](const std::pair<lldb::addr_t, StopPointSiteSP> s) {
0291 return site_id == s.second->GetID();
0292 };
0293 return std::find_if(m_site_list.begin(),
0294 m_site_list.end(),
0295 id_matches);
0296 }
0297
0298 mutable std::recursive_mutex m_mutex;
0299 collection m_site_list;
0300 };
0301
0302 }
0303
0304 #endif