CodeQL / Analyze (actions) (push) Canceled after 0s
CodeQL / Analyze (python) (push) Canceled after 0s
pre-commit / pre-commit (push) Canceled after 0s
Multi-Arch CI / setup (push) Canceled after 0s
Publish build_manylinux_x86_64 images / publish_build_manylinux_x86_64 (push) Canceled after 0s
Setup (Multi-Arch) / setup (push) Canceled after 0s
Multi-Arch CI / Linux::${{ fromJSON(needs.setup.outputs.linux_build_config || '{}').build_variant_label || 'skip' }} (push) Canceled after 0s
Publish TheRock Docker image / build-and-push-image (push) Canceled after 0s
Publish no_rocm_image_ubi10 image / publish_no_rocm_image_ubi10 (push) Canceled after 0s
Multi-Arch CI / Windows::${{ fromJSON(needs.setup.outputs.windows_build_config || '{}').build_variant_label || 'skip' }} (push) Canceled after 0s
Publish TheRock Docker image / build-and-push-image (push) Canceled after 0s
Multi-Arch CI / Manifest Diff (push) Canceled after 0s
TheRock Manifest Diff Report / Generate Manifest Diff Report (push) Canceled after 0s
Multi-Arch CI / CI Summary (push) Canceled after 0s
Publish no_rocm_image_ubuntu24_04 images / publish_no_rocm_image_ubuntu24_04 (push) Canceled after 0s
Publish no_rocm_image_ubuntu24_04_ocl_rt images / publish_no_rocm_image_ubuntu24_04_ocl_rt (push) Canceled after 0s
Publish TheRock Docker image / build-and-push-image (push) Canceled after 0s
Publish TheRock Docker image / build-and-push-image (push) Canceled after 0s
Publish no_rocm_image_ubuntu24_04 images / publish_no_rocm_image_ubuntu24_04_rocgdb (push) Canceled after 0s
Publish no_rocm_image_ubuntu24_04_rocgdb images / publish_no_rocm_image_ubuntu24_04_rocgdb (push) Canceled after 0s
Publish no_rocm_image_ubuntu24_04 images / publish_no_rocm_image_ubuntu24_04_ocl_rt (push) Canceled after 0s
Publish TheRock Docker image / build-and-push-image (push) Canceled after 0s
Unit Tests / Unit Tests :: ubuntu-24.04 (push) Canceled after 0s
Unit Tests / Unit Tests :: windows-2022 (push) Canceled after 0s
Publish no_rocm_image_ubuntu24_04 images / publish_no_rocm_image_ubuntu24_04_media (push) Canceled after 0s
Unit Tests / Unit Tests Summary (push) Canceled after 0s
Publish no_rocm_image_ubuntu24_04 images / publish_no_rocm_image_ubuntu24_04_openmpi (push) Canceled after 0s
223 lines
7.7 KiB
C++
223 lines
7.7 KiB
C++
//===-- BreakpointLocationCollection.cpp ----------------------------------===//
|
|
//
|
|
// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
|
|
// See https://llvm.org/LICENSE.txt for license information.
|
|
// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
|
|
//
|
|
//===----------------------------------------------------------------------===//
|
|
|
|
#include "lldb/Breakpoint/BreakpointLocationCollection.h"
|
|
#include "lldb/Breakpoint/Breakpoint.h"
|
|
#include "lldb/Breakpoint/BreakpointLocation.h"
|
|
#include "lldb/Core/ModuleList.h"
|
|
#include "lldb/Target/Thread.h"
|
|
#include "lldb/Target/ThreadSpec.h"
|
|
|
|
using namespace lldb;
|
|
using namespace lldb_private;
|
|
|
|
// BreakpointLocationCollection constructor
|
|
BreakpointLocationCollection::BreakpointLocationCollection(bool preserving)
|
|
: m_preserving_bkpts(preserving) {}
|
|
|
|
// Destructor
|
|
BreakpointLocationCollection::~BreakpointLocationCollection() = default;
|
|
|
|
void BreakpointLocationCollection::Add(const BreakpointLocationSP &bp_loc) {
|
|
std::lock_guard<std::recursive_mutex> guard(m_collection_mutex);
|
|
BreakpointLocationSP old_bp_loc =
|
|
FindByIDPair(bp_loc->GetBreakpoint().GetID(), bp_loc->GetID());
|
|
if (!old_bp_loc.get()) {
|
|
m_break_loc_collection.push_back(bp_loc);
|
|
if (m_preserving_bkpts) {
|
|
lldb::break_id_t bp_loc_id = bp_loc->GetID();
|
|
Breakpoint &bkpt = bp_loc->GetBreakpoint();
|
|
lldb::break_id_t bp_id = bkpt.GetID();
|
|
std::pair<lldb::break_id_t, lldb::break_id_t> key =
|
|
std::make_pair(bp_id, bp_loc_id);
|
|
auto entry = m_preserved_bps.find(key);
|
|
if (entry == m_preserved_bps.end())
|
|
m_preserved_bps.emplace(key, bkpt.shared_from_this());
|
|
}
|
|
}
|
|
}
|
|
|
|
bool BreakpointLocationCollection::Remove(lldb::break_id_t bp_id,
|
|
lldb::break_id_t bp_loc_id) {
|
|
std::lock_guard<std::recursive_mutex> guard(m_collection_mutex);
|
|
collection::iterator pos = GetIDPairIterator(bp_id, bp_loc_id); // Predicate
|
|
if (pos != m_break_loc_collection.end()) {
|
|
if (m_preserving_bkpts) {
|
|
std::pair<lldb::break_id_t, lldb::break_id_t> key =
|
|
std::make_pair(bp_id, bp_loc_id);
|
|
auto entry = m_preserved_bps.find(key);
|
|
if (entry == m_preserved_bps.end())
|
|
assert(0 && "Breakpoint added to collection but not preserving map.");
|
|
else
|
|
m_preserved_bps.erase(entry);
|
|
}
|
|
m_break_loc_collection.erase(pos);
|
|
return true;
|
|
}
|
|
return false;
|
|
}
|
|
|
|
class BreakpointIDPairMatches {
|
|
public:
|
|
BreakpointIDPairMatches(lldb::break_id_t break_id,
|
|
lldb::break_id_t break_loc_id)
|
|
: m_break_id(break_id), m_break_loc_id(break_loc_id) {}
|
|
|
|
bool operator()(const BreakpointLocationSP &bp_loc) const {
|
|
return m_break_id == bp_loc->GetBreakpoint().GetID() &&
|
|
m_break_loc_id == bp_loc->GetID();
|
|
}
|
|
|
|
private:
|
|
const lldb::break_id_t m_break_id;
|
|
const lldb::break_id_t m_break_loc_id;
|
|
};
|
|
|
|
BreakpointLocationCollection::collection::iterator
|
|
BreakpointLocationCollection::GetIDPairIterator(lldb::break_id_t break_id,
|
|
lldb::break_id_t break_loc_id) {
|
|
return llvm::find_if(
|
|
m_break_loc_collection, // Search full range
|
|
BreakpointIDPairMatches(break_id, break_loc_id)); // Predicate
|
|
}
|
|
|
|
BreakpointLocationCollection::collection::const_iterator
|
|
BreakpointLocationCollection::GetIDPairConstIterator(
|
|
lldb::break_id_t break_id, lldb::break_id_t break_loc_id) const {
|
|
return llvm::find_if(
|
|
m_break_loc_collection, // Search full range
|
|
BreakpointIDPairMatches(break_id, break_loc_id)); // Predicate
|
|
}
|
|
|
|
BreakpointLocationSP
|
|
BreakpointLocationCollection::FindByIDPair(lldb::break_id_t break_id,
|
|
lldb::break_id_t break_loc_id) {
|
|
BreakpointLocationSP stop_sp;
|
|
collection::iterator pos = GetIDPairIterator(break_id, break_loc_id);
|
|
if (pos != m_break_loc_collection.end())
|
|
stop_sp = *pos;
|
|
|
|
return stop_sp;
|
|
}
|
|
|
|
const BreakpointLocationSP BreakpointLocationCollection::FindByIDPair(
|
|
lldb::break_id_t break_id, lldb::break_id_t break_loc_id) const {
|
|
BreakpointLocationSP stop_sp;
|
|
collection::const_iterator pos =
|
|
GetIDPairConstIterator(break_id, break_loc_id);
|
|
if (pos != m_break_loc_collection.end())
|
|
stop_sp = *pos;
|
|
|
|
return stop_sp;
|
|
}
|
|
|
|
BreakpointLocationSP BreakpointLocationCollection::GetByIndex(size_t i) {
|
|
std::lock_guard<std::recursive_mutex> guard(m_collection_mutex);
|
|
BreakpointLocationSP stop_sp;
|
|
if (i < m_break_loc_collection.size())
|
|
stop_sp = m_break_loc_collection[i];
|
|
|
|
return stop_sp;
|
|
}
|
|
|
|
const BreakpointLocationSP
|
|
BreakpointLocationCollection::GetByIndex(size_t i) const {
|
|
std::lock_guard<std::recursive_mutex> guard(m_collection_mutex);
|
|
BreakpointLocationSP stop_sp;
|
|
if (i < m_break_loc_collection.size())
|
|
stop_sp = m_break_loc_collection[i];
|
|
|
|
return stop_sp;
|
|
}
|
|
|
|
bool BreakpointLocationCollection::ShouldStop(
|
|
StoppointCallbackContext *context,
|
|
BreakpointLocationCollection &stopped_bp_locs) {
|
|
bool shouldStop = false;
|
|
size_t i = 0;
|
|
size_t prev_size = GetSize();
|
|
while (i < prev_size) {
|
|
// ShouldStop can remove the breakpoint from the list, or even delete
|
|
// it, so we should
|
|
BreakpointLocationSP cur_loc_sp = GetByIndex(i);
|
|
BreakpointLocationSP reported_loc_sp;
|
|
BreakpointSP keep_bkpt_alive_sp = cur_loc_sp->GetBreakpoint().shared_from_this();
|
|
// We're building up the list or which locations claim responsibility for
|
|
// this stop. If the location's ShouldStop defers to a facade location by
|
|
// returning a non-null reported location, we want to use that. Otherwise
|
|
// use the original location.
|
|
if (cur_loc_sp->ShouldStop(context, reported_loc_sp)) {
|
|
if (reported_loc_sp)
|
|
stopped_bp_locs.Add(reported_loc_sp);
|
|
else
|
|
stopped_bp_locs.Add(cur_loc_sp);
|
|
|
|
shouldStop = true;
|
|
}
|
|
|
|
if (prev_size == GetSize())
|
|
i++;
|
|
prev_size = GetSize();
|
|
}
|
|
return shouldStop;
|
|
}
|
|
|
|
bool BreakpointLocationCollection::ValidForThisThread(Thread &thread) {
|
|
std::lock_guard<std::recursive_mutex> guard(m_collection_mutex);
|
|
collection::iterator pos, begin = m_break_loc_collection.begin(),
|
|
end = m_break_loc_collection.end();
|
|
|
|
for (pos = begin; pos != end; ++pos) {
|
|
if ((*pos)->ValidForThisThread(thread))
|
|
return true;
|
|
}
|
|
return false;
|
|
}
|
|
|
|
bool BreakpointLocationCollection::IsInternal() const {
|
|
std::lock_guard<std::recursive_mutex> guard(m_collection_mutex);
|
|
collection::const_iterator pos, begin = m_break_loc_collection.begin(),
|
|
end = m_break_loc_collection.end();
|
|
|
|
bool is_internal = true;
|
|
|
|
for (pos = begin; pos != end; ++pos) {
|
|
if (!(*pos)->GetBreakpoint().IsInternal()) {
|
|
is_internal = false;
|
|
break;
|
|
}
|
|
}
|
|
return is_internal;
|
|
}
|
|
|
|
void BreakpointLocationCollection::GetDescription(
|
|
Stream *s, lldb::DescriptionLevel level) {
|
|
std::lock_guard<std::recursive_mutex> guard(m_collection_mutex);
|
|
collection::iterator pos, begin = m_break_loc_collection.begin(),
|
|
end = m_break_loc_collection.end();
|
|
|
|
for (pos = begin; pos != end; ++pos) {
|
|
if (pos != begin)
|
|
s->PutChar(' ');
|
|
(*pos)->GetDescription(s, level);
|
|
}
|
|
}
|
|
|
|
BreakpointLocationCollection &BreakpointLocationCollection::operator=(
|
|
const BreakpointLocationCollection &rhs) {
|
|
if (this != &rhs) {
|
|
std::lock(m_collection_mutex, rhs.m_collection_mutex);
|
|
std::lock_guard<std::recursive_mutex> lhs_guard(m_collection_mutex,
|
|
std::adopt_lock);
|
|
std::lock_guard<std::recursive_mutex> rhs_guard(rhs.m_collection_mutex,
|
|
std::adopt_lock);
|
|
m_break_loc_collection = rhs.m_break_loc_collection;
|
|
}
|
|
return *this;
|
|
}
|