llvm-project/lldb/source/Breakpoint/BreakpointLocationCollectio...

214 lines
6.1 KiB
C++

//===-- BreakpointLocationCollection.cpp ------------------------*- C++ -*-===//
//
// The LLVM Compiler Infrastructure
//
// This file is distributed under the University of Illinois Open Source
// License. See LICENSE.TXT for details.
//
//===----------------------------------------------------------------------===//
// C Includes
// C++ Includes
// Other libraries and framework includes
// Project includes
#include "lldb/Breakpoint/BreakpointLocationCollection.h"
#include "lldb/Core/ModuleList.h"
#include "lldb/Breakpoint/Breakpoint.h"
#include "lldb/Breakpoint/BreakpointLocation.h"
#include "lldb/Target/Thread.h"
#include "lldb/Target/ThreadSpec.h"
using namespace lldb;
using namespace lldb_private;
//----------------------------------------------------------------------
// BreakpointLocationCollection constructor
//----------------------------------------------------------------------
BreakpointLocationCollection::BreakpointLocationCollection() :
m_break_loc_collection(),
m_collection_mutex()
{
}
//----------------------------------------------------------------------
// Destructor
//----------------------------------------------------------------------
BreakpointLocationCollection::~BreakpointLocationCollection()
{
}
void
BreakpointLocationCollection::Add(const BreakpointLocationSP &bp_loc)
{
std::lock_guard<std::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);
}
bool
BreakpointLocationCollection::Remove (lldb::break_id_t bp_id, lldb::break_id_t bp_loc_id)
{
std::lock_guard<std::mutex> guard(m_collection_mutex);
collection::iterator pos = GetIDPairIterator(bp_id, bp_loc_id); // Predicate
if (pos != m_break_loc_collection.end())
{
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 std::find_if(m_break_loc_collection.begin(), m_break_loc_collection.end(), // 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 std::find_if(m_break_loc_collection.begin(), m_break_loc_collection.end(), // 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::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::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)
{
bool shouldStop = false;
size_t i = 0;
size_t prev_size = GetSize();
while (i < prev_size)
{
// ShouldStop can remove the breakpoint from the list
if (GetByIndex(i)->ShouldStop(context))
shouldStop = true;
if (prev_size == GetSize())
i++;
prev_size = GetSize();
}
return shouldStop;
}
bool
BreakpointLocationCollection::ValidForThisThread (Thread *thread)
{
std::lock_guard<std::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::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::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);
}
}