Files
llvm/lldb/source/Breakpoint/BreakpointList.cpp
Jim Ingham 4a94c91077 If we notice that a module with a given file path is replaced by another with the same file
path on rerunning, evict the old module from the target module list, inform the breakpoints
about this so they can do something intelligent as well.

rdar://problem/11273043

llvm-svn: 157008
2012-05-17 18:38:42 +00:00

239 lines
6.6 KiB
C++

//===-- BreakpointList.cpp --------------------------------------*- C++ -*-===//
//
// The LLVM Compiler Infrastructure
//
// This file is distributed under the University of Illinois Open Source
// License. See LICENSE.TXT for details.
//
//===----------------------------------------------------------------------===//
#include "lldb/Breakpoint/BreakpointList.h"
// C Includes
// C++ Includes
// Other libraries and framework includes
// Project includes
#include "lldb/Target/Target.h"
using namespace lldb;
using namespace lldb_private;
BreakpointList::BreakpointList (bool is_internal) :
m_mutex (Mutex::eMutexTypeRecursive),
m_breakpoints(),
m_next_break_id (0),
m_is_internal (is_internal)
{
}
BreakpointList::~BreakpointList()
{
}
break_id_t
BreakpointList::Add (BreakpointSP &bp_sp, bool notify)
{
Mutex::Locker locker(m_mutex);
// Internal breakpoint IDs are negative, normal ones are positive
bp_sp->SetID (m_is_internal ? --m_next_break_id : ++m_next_break_id);
m_breakpoints.push_back(bp_sp);
if (notify)
{
if (bp_sp->GetTarget().EventTypeHasListeners(Target::eBroadcastBitBreakpointChanged))
bp_sp->GetTarget().BroadcastEvent (Target::eBroadcastBitBreakpointChanged,
new Breakpoint::BreakpointEventData (eBreakpointEventTypeAdded, bp_sp));
}
return bp_sp->GetID();
}
bool
BreakpointList::Remove (break_id_t break_id, bool notify)
{
Mutex::Locker locker(m_mutex);
bp_collection::iterator pos = GetBreakpointIDIterator(break_id); // Predicate
if (pos != m_breakpoints.end())
{
BreakpointSP bp_sp (*pos);
m_breakpoints.erase(pos);
if (notify)
{
if (bp_sp->GetTarget().EventTypeHasListeners(Target::eBroadcastBitBreakpointChanged))
bp_sp->GetTarget().BroadcastEvent (Target::eBroadcastBitBreakpointChanged,
new Breakpoint::BreakpointEventData (eBreakpointEventTypeRemoved, bp_sp));
}
return true;
}
return false;
}
void
BreakpointList::SetEnabledAll (bool enabled)
{
Mutex::Locker locker(m_mutex);
bp_collection::iterator pos, end = m_breakpoints.end();
for (pos = m_breakpoints.begin(); pos != end; ++pos)
(*pos)->SetEnabled (enabled);
}
void
BreakpointList::RemoveAll (bool notify)
{
Mutex::Locker locker(m_mutex);
ClearAllBreakpointSites ();
if (notify)
{
bp_collection::iterator pos, end = m_breakpoints.end();
for (pos = m_breakpoints.begin(); pos != end; ++pos)
if ((*pos)->GetTarget().EventTypeHasListeners(Target::eBroadcastBitBreakpointChanged))
(*pos)->GetTarget().BroadcastEvent (Target::eBroadcastBitBreakpointChanged,
new Breakpoint::BreakpointEventData (eBreakpointEventTypeRemoved, *pos));
}
m_breakpoints.erase (m_breakpoints.begin(), m_breakpoints.end());
}
class BreakpointIDMatches
{
public:
BreakpointIDMatches (break_id_t break_id) :
m_break_id(break_id)
{
}
bool operator() (const BreakpointSP &bp) const
{
return m_break_id == bp->GetID();
}
private:
const break_id_t m_break_id;
};
BreakpointList::bp_collection::iterator
BreakpointList::GetBreakpointIDIterator (break_id_t break_id)
{
return std::find_if(m_breakpoints.begin(), m_breakpoints.end(), // Search full range
BreakpointIDMatches(break_id)); // Predicate
}
BreakpointList::bp_collection::const_iterator
BreakpointList::GetBreakpointIDConstIterator (break_id_t break_id) const
{
return std::find_if(m_breakpoints.begin(), m_breakpoints.end(), // Search full range
BreakpointIDMatches(break_id)); // Predicate
}
BreakpointSP
BreakpointList::FindBreakpointByID (break_id_t break_id)
{
Mutex::Locker locker(m_mutex);
BreakpointSP stop_sp;
bp_collection::iterator pos = GetBreakpointIDIterator(break_id);
if (pos != m_breakpoints.end())
stop_sp = *pos;
return stop_sp;
}
const BreakpointSP
BreakpointList::FindBreakpointByID (break_id_t break_id) const
{
Mutex::Locker locker(m_mutex);
BreakpointSP stop_sp;
bp_collection::const_iterator pos = GetBreakpointIDConstIterator(break_id);
if (pos != m_breakpoints.end())
stop_sp = *pos;
return stop_sp;
}
void
BreakpointList::Dump (Stream *s) const
{
Mutex::Locker locker(m_mutex);
s->Printf("%p: ", this);
s->Indent();
s->Printf("BreakpointList with %u Breakpoints:\n", (uint32_t)m_breakpoints.size());
s->IndentMore();
bp_collection::const_iterator pos;
bp_collection::const_iterator end = m_breakpoints.end();
for (pos = m_breakpoints.begin(); pos != end; ++pos)
(*pos)->Dump(s);
s->IndentLess();
}
BreakpointSP
BreakpointList::GetBreakpointAtIndex (uint32_t i)
{
Mutex::Locker locker(m_mutex);
BreakpointSP stop_sp;
bp_collection::iterator end = m_breakpoints.end();
bp_collection::iterator pos;
uint32_t curr_i = 0;
for (pos = m_breakpoints.begin(), curr_i = 0; pos != end; ++pos, ++curr_i)
{
if (curr_i == i)
stop_sp = *pos;
}
return stop_sp;
}
const BreakpointSP
BreakpointList::GetBreakpointAtIndex (uint32_t i) const
{
Mutex::Locker locker(m_mutex);
BreakpointSP stop_sp;
bp_collection::const_iterator end = m_breakpoints.end();
bp_collection::const_iterator pos;
uint32_t curr_i = 0;
for (pos = m_breakpoints.begin(), curr_i = 0; pos != end; ++pos, ++curr_i)
{
if (curr_i == i)
stop_sp = *pos;
}
return stop_sp;
}
void
BreakpointList::UpdateBreakpoints (ModuleList& module_list, bool added)
{
Mutex::Locker locker(m_mutex);
bp_collection::iterator end = m_breakpoints.end();
bp_collection::iterator pos;
for (pos = m_breakpoints.begin(); pos != end; ++pos)
(*pos)->ModulesChanged (module_list, added);
}
void
BreakpointList::UpdateBreakpointsWhenModuleIsReplaced (ModuleSP old_module_sp, ModuleSP new_module_sp)
{
Mutex::Locker locker(m_mutex);
bp_collection::iterator end = m_breakpoints.end();
bp_collection::iterator pos;
for (pos = m_breakpoints.begin(); pos != end; ++pos)
(*pos)->ModuleReplaced (old_module_sp, new_module_sp);
}
void
BreakpointList::ClearAllBreakpointSites ()
{
Mutex::Locker locker(m_mutex);
bp_collection::iterator end = m_breakpoints.end();
bp_collection::iterator pos;
for (pos = m_breakpoints.begin(); pos != end; ++pos)
(*pos)->ClearAllBreakpointSites ();
}
void
BreakpointList::GetListMutex (Mutex::Locker &locker)
{
return locker.Lock (m_mutex);
}