Files
clang-p2996/lldb/source/Breakpoint/BreakpointLocationCollection.cpp
Jim Ingham 1b54c88cc4 Add a "thread specification" class that specifies thread specific breakpoints by name, index, queue or TID.
Push this through all the breakpoint management code.  Allow this to be set when the breakpoint is created.
Fix the Process classes so that a breakpoint hit that is not for a particular thread is not reported as a 
breakpoint hit event for that thread.
Added a "breakpoint configure" command to allow you to reset any of the thread 
specific options (or the ignore count.)

llvm-svn: 106078
2010-06-16 02:00:15 +00:00

180 lines
5.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/BreakpointLocation.h"
#include "lldb/Breakpoint/BreakpointLocationList.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()
{
}
//----------------------------------------------------------------------
// Destructor
//----------------------------------------------------------------------
BreakpointLocationCollection::~BreakpointLocationCollection()
{
}
void
BreakpointLocationCollection::Add(const BreakpointLocationSP &bp_loc)
{
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::user_id_t bp_id, lldb::user_id_t bp_loc_id)
{
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::user_id_t break_id, lldb::user_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::user_id_t m_break_id;
const lldb::user_id_t m_break_loc_id;
};
BreakpointLocationCollection::collection::iterator
BreakpointLocationCollection::GetIDPairIterator (lldb::user_id_t break_id, lldb::user_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::user_id_t break_id, lldb::user_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::user_id_t break_id, lldb::user_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::user_id_t break_id, lldb::user_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 (uint32_t i)
{
BreakpointLocationSP stop_sp;
if (i >= 0 && i < m_break_loc_collection.size())
stop_sp = m_break_loc_collection[i];
return stop_sp;
}
const BreakpointLocationSP
BreakpointLocationCollection::GetByIndex (uint32_t i) const
{
BreakpointLocationSP stop_sp;
if (i >= 0 && i < m_break_loc_collection.size())
stop_sp = m_break_loc_collection[i];
return stop_sp;
}
bool
BreakpointLocationCollection::ShouldStop (StoppointCallbackContext *context)
{
bool shouldStop = false;
for (int i = 0; i < GetSize(); i++) {
bool one_result = GetByIndex(i)->ShouldStop(context);
if (one_result)
shouldStop = true;
}
return shouldStop;
}
bool
BreakpointLocationCollection::ValidForThisThread (Thread *thread)
{
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;
}
void
BreakpointLocationCollection::GetDescription (Stream *s, lldb::DescriptionLevel level)
{
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);
}
}