2010-06-09 00:52:24 +08:00
|
|
|
//===-- 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
|
2010-07-24 07:33:17 +08:00
|
|
|
#include "lldb/Target/Target.h"
|
2010-06-09 00:52:24 +08:00
|
|
|
|
|
|
|
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
|
2010-07-24 07:33:17 +08:00
|
|
|
BreakpointList::Add (BreakpointSP &bp_sp, bool notify)
|
2010-06-09 00:52:24 +08:00
|
|
|
{
|
|
|
|
Mutex::Locker locker(m_mutex);
|
|
|
|
// Internal breakpoint IDs are negative, normal ones are positive
|
2010-07-24 07:33:17 +08:00
|
|
|
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();
|
2010-06-09 00:52:24 +08:00
|
|
|
}
|
|
|
|
|
|
|
|
bool
|
2010-07-24 07:33:17 +08:00
|
|
|
BreakpointList::Remove (break_id_t break_id, bool notify)
|
2010-06-09 00:52:24 +08:00
|
|
|
{
|
|
|
|
Mutex::Locker locker(m_mutex);
|
|
|
|
bp_collection::iterator pos = GetBreakpointIDIterator(break_id); // Predicate
|
|
|
|
if (pos != m_breakpoints.end())
|
|
|
|
{
|
2010-07-24 07:33:17 +08:00
|
|
|
BreakpointSP bp_sp (*pos);
|
2010-06-09 00:52:24 +08:00
|
|
|
m_breakpoints.erase(pos);
|
2010-07-24 07:33:17 +08:00
|
|
|
if (notify)
|
|
|
|
{
|
|
|
|
if (bp_sp->GetTarget().EventTypeHasListeners(Target::eBroadcastBitBreakpointChanged))
|
|
|
|
bp_sp->GetTarget().BroadcastEvent (Target::eBroadcastBitBreakpointChanged,
|
|
|
|
new Breakpoint::BreakpointEventData (eBreakpointEventTypeRemoved, bp_sp));
|
|
|
|
}
|
2010-06-09 00:52:24 +08:00
|
|
|
return true;
|
|
|
|
}
|
|
|
|
return false;
|
|
|
|
}
|
|
|
|
|
2013-11-09 08:03:31 +08:00
|
|
|
void
|
|
|
|
BreakpointList::RemoveInvalidLocations (const ArchSpec &arch)
|
|
|
|
{
|
|
|
|
Mutex::Locker locker(m_mutex);
|
|
|
|
for (const auto &bp_sp : m_breakpoints)
|
|
|
|
bp_sp->RemoveInvalidLocations(arch);
|
|
|
|
}
|
|
|
|
|
|
|
|
|
2010-06-09 00:52:24 +08:00
|
|
|
void
|
|
|
|
BreakpointList::SetEnabledAll (bool enabled)
|
|
|
|
{
|
|
|
|
Mutex::Locker locker(m_mutex);
|
2013-11-09 08:03:31 +08:00
|
|
|
for (const auto &bp_sp : m_breakpoints)
|
|
|
|
bp_sp->SetEnabled (enabled);
|
2010-06-09 00:52:24 +08:00
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
void
|
2010-07-24 07:33:17 +08:00
|
|
|
BreakpointList::RemoveAll (bool notify)
|
2010-06-09 00:52:24 +08:00
|
|
|
{
|
|
|
|
Mutex::Locker locker(m_mutex);
|
|
|
|
ClearAllBreakpointSites ();
|
|
|
|
|
2010-07-24 07:33:17 +08:00
|
|
|
if (notify)
|
|
|
|
{
|
|
|
|
bp_collection::iterator pos, end = m_breakpoints.end();
|
|
|
|
for (pos = m_breakpoints.begin(); pos != end; ++pos)
|
2012-12-18 10:03:49 +08:00
|
|
|
{
|
2010-07-24 07:33:17 +08:00
|
|
|
if ((*pos)->GetTarget().EventTypeHasListeners(Target::eBroadcastBitBreakpointChanged))
|
2012-12-18 10:03:49 +08:00
|
|
|
{
|
2010-07-24 07:33:17 +08:00
|
|
|
(*pos)->GetTarget().BroadcastEvent (Target::eBroadcastBitBreakpointChanged,
|
2012-12-18 10:03:49 +08:00
|
|
|
new Breakpoint::BreakpointEventData (eBreakpointEventTypeRemoved,
|
|
|
|
*pos));
|
|
|
|
}
|
|
|
|
}
|
2010-07-24 07:33:17 +08:00
|
|
|
}
|
2010-06-09 00:52:24 +08:00
|
|
|
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);
|
2014-04-04 12:06:10 +08:00
|
|
|
s->Printf("%p: ", static_cast<const void*>(this));
|
2010-06-09 00:52:24 +08:00
|
|
|
s->Indent();
|
|
|
|
s->Printf("BreakpointList with %u Breakpoints:\n", (uint32_t)m_breakpoints.size());
|
|
|
|
s->IndentMore();
|
2013-11-09 08:03:31 +08:00
|
|
|
for (const auto &bp_sp : m_breakpoints)
|
|
|
|
bp_sp->Dump(s);
|
2010-06-09 00:52:24 +08:00
|
|
|
s->IndentLess();
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
BreakpointSP
|
2013-01-26 02:06:21 +08:00
|
|
|
BreakpointList::GetBreakpointAtIndex (size_t i)
|
2010-06-09 00:52:24 +08:00
|
|
|
{
|
|
|
|
Mutex::Locker locker(m_mutex);
|
|
|
|
BreakpointSP stop_sp;
|
|
|
|
bp_collection::iterator end = m_breakpoints.end();
|
|
|
|
bp_collection::iterator pos;
|
2013-01-26 02:06:21 +08:00
|
|
|
size_t curr_i = 0;
|
2010-06-09 00:52:24 +08:00
|
|
|
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
|
2013-01-26 02:06:21 +08:00
|
|
|
BreakpointList::GetBreakpointAtIndex (size_t i) const
|
2010-06-09 00:52:24 +08:00
|
|
|
{
|
|
|
|
Mutex::Locker locker(m_mutex);
|
|
|
|
BreakpointSP stop_sp;
|
|
|
|
bp_collection::const_iterator end = m_breakpoints.end();
|
|
|
|
bp_collection::const_iterator pos;
|
2013-01-26 02:06:21 +08:00
|
|
|
size_t curr_i = 0;
|
2010-06-09 00:52:24 +08:00
|
|
|
for (pos = m_breakpoints.begin(), curr_i = 0; pos != end; ++pos, ++curr_i)
|
|
|
|
{
|
|
|
|
if (curr_i == i)
|
|
|
|
stop_sp = *pos;
|
|
|
|
}
|
|
|
|
return stop_sp;
|
|
|
|
}
|
|
|
|
|
|
|
|
void
|
2013-11-06 07:28:00 +08:00
|
|
|
BreakpointList::UpdateBreakpoints (ModuleList& module_list, bool added, bool delete_locations)
|
2010-06-09 00:52:24 +08:00
|
|
|
{
|
|
|
|
Mutex::Locker locker(m_mutex);
|
2013-11-09 08:03:31 +08:00
|
|
|
for (const auto &bp_sp : m_breakpoints)
|
|
|
|
bp_sp->ModulesChanged (module_list, added, delete_locations);
|
2010-06-09 00:52:24 +08:00
|
|
|
|
|
|
|
}
|
|
|
|
|
2012-05-18 02:38:42 +08:00
|
|
|
void
|
|
|
|
BreakpointList::UpdateBreakpointsWhenModuleIsReplaced (ModuleSP old_module_sp, ModuleSP new_module_sp)
|
|
|
|
{
|
|
|
|
Mutex::Locker locker(m_mutex);
|
2013-11-09 08:03:31 +08:00
|
|
|
for (const auto &bp_sp : m_breakpoints)
|
|
|
|
bp_sp->ModuleReplaced (old_module_sp, new_module_sp);
|
2012-05-18 02:38:42 +08:00
|
|
|
|
|
|
|
}
|
|
|
|
|
2010-06-09 00:52:24 +08:00
|
|
|
void
|
|
|
|
BreakpointList::ClearAllBreakpointSites ()
|
|
|
|
{
|
|
|
|
Mutex::Locker locker(m_mutex);
|
2013-11-09 08:03:31 +08:00
|
|
|
for (const auto &bp_sp : m_breakpoints)
|
|
|
|
bp_sp->ClearAllBreakpointSites ();
|
2010-06-09 00:52:24 +08:00
|
|
|
|
|
|
|
}
|
2010-06-16 10:00:15 +08:00
|
|
|
|
|
|
|
void
|
|
|
|
BreakpointList::GetListMutex (Mutex::Locker &locker)
|
|
|
|
{
|
2012-05-05 07:02:50 +08:00
|
|
|
return locker.Lock (m_mutex);
|
2010-06-16 10:00:15 +08:00
|
|
|
}
|