Home | History | Annotate | Download | only in Breakpoint
      1 //===-- BreakpointList.cpp --------------------------------------*- C++ -*-===//
      2 //
      3 //                     The LLVM Compiler Infrastructure
      4 //
      5 // This file is distributed under the University of Illinois Open Source
      6 // License. See LICENSE.TXT for details.
      7 //
      8 //===----------------------------------------------------------------------===//
      9 
     10 #include "lldb/Breakpoint/BreakpointList.h"
     11 
     12 // C Includes
     13 // C++ Includes
     14 // Other libraries and framework includes
     15 // Project includes
     16 #include "lldb/Target/Target.h"
     17 
     18 using namespace lldb;
     19 using namespace lldb_private;
     20 
     21 BreakpointList::BreakpointList (bool is_internal) :
     22     m_mutex (Mutex::eMutexTypeRecursive),
     23     m_breakpoints(),
     24     m_next_break_id (0),
     25     m_is_internal (is_internal)
     26 {
     27 }
     28 
     29 BreakpointList::~BreakpointList()
     30 {
     31 }
     32 
     33 
     34 break_id_t
     35 BreakpointList::Add (BreakpointSP &bp_sp, bool notify)
     36 {
     37     Mutex::Locker locker(m_mutex);
     38     // Internal breakpoint IDs are negative, normal ones are positive
     39     bp_sp->SetID (m_is_internal ? --m_next_break_id : ++m_next_break_id);
     40 
     41     m_breakpoints.push_back(bp_sp);
     42     if (notify)
     43     {
     44         if (bp_sp->GetTarget().EventTypeHasListeners(Target::eBroadcastBitBreakpointChanged))
     45             bp_sp->GetTarget().BroadcastEvent (Target::eBroadcastBitBreakpointChanged,
     46                                                new Breakpoint::BreakpointEventData (eBreakpointEventTypeAdded, bp_sp));
     47     }
     48     return bp_sp->GetID();
     49 }
     50 
     51 bool
     52 BreakpointList::Remove (break_id_t break_id, bool notify)
     53 {
     54     Mutex::Locker locker(m_mutex);
     55     bp_collection::iterator pos = GetBreakpointIDIterator(break_id);    // Predicate
     56     if (pos != m_breakpoints.end())
     57     {
     58         BreakpointSP bp_sp (*pos);
     59         m_breakpoints.erase(pos);
     60         if (notify)
     61         {
     62             if (bp_sp->GetTarget().EventTypeHasListeners(Target::eBroadcastBitBreakpointChanged))
     63                 bp_sp->GetTarget().BroadcastEvent (Target::eBroadcastBitBreakpointChanged,
     64                                                    new Breakpoint::BreakpointEventData (eBreakpointEventTypeRemoved, bp_sp));
     65         }
     66         return true;
     67     }
     68     return false;
     69 }
     70 
     71 void
     72 BreakpointList::SetEnabledAll (bool enabled)
     73 {
     74     Mutex::Locker locker(m_mutex);
     75     bp_collection::iterator pos, end = m_breakpoints.end();
     76     for (pos = m_breakpoints.begin(); pos != end; ++pos)
     77         (*pos)->SetEnabled (enabled);
     78 }
     79 
     80 
     81 void
     82 BreakpointList::RemoveAll (bool notify)
     83 {
     84     Mutex::Locker locker(m_mutex);
     85     ClearAllBreakpointSites ();
     86 
     87     if (notify)
     88     {
     89         bp_collection::iterator pos, end = m_breakpoints.end();
     90         for (pos = m_breakpoints.begin(); pos != end; ++pos)
     91         {
     92             if ((*pos)->GetTarget().EventTypeHasListeners(Target::eBroadcastBitBreakpointChanged))
     93             {
     94                 (*pos)->GetTarget().BroadcastEvent (Target::eBroadcastBitBreakpointChanged,
     95                                                     new Breakpoint::BreakpointEventData (eBreakpointEventTypeRemoved,
     96                                                                                          *pos));
     97             }
     98         }
     99     }
    100     m_breakpoints.erase (m_breakpoints.begin(), m_breakpoints.end());
    101 }
    102 
    103 class BreakpointIDMatches
    104 {
    105 public:
    106     BreakpointIDMatches (break_id_t break_id) :
    107         m_break_id(break_id)
    108     {
    109     }
    110 
    111     bool operator() (const BreakpointSP &bp) const
    112     {
    113         return m_break_id == bp->GetID();
    114     }
    115 
    116 private:
    117    const break_id_t m_break_id;
    118 };
    119 
    120 BreakpointList::bp_collection::iterator
    121 BreakpointList::GetBreakpointIDIterator (break_id_t break_id)
    122 {
    123     return std::find_if(m_breakpoints.begin(), m_breakpoints.end(), // Search full range
    124                         BreakpointIDMatches(break_id));             // Predicate
    125 }
    126 
    127 BreakpointList::bp_collection::const_iterator
    128 BreakpointList::GetBreakpointIDConstIterator (break_id_t break_id) const
    129 {
    130     return std::find_if(m_breakpoints.begin(), m_breakpoints.end(), // Search full range
    131                         BreakpointIDMatches(break_id));             // Predicate
    132 }
    133 
    134 BreakpointSP
    135 BreakpointList::FindBreakpointByID (break_id_t break_id)
    136 {
    137     Mutex::Locker locker(m_mutex);
    138     BreakpointSP stop_sp;
    139     bp_collection::iterator pos = GetBreakpointIDIterator(break_id);
    140     if (pos != m_breakpoints.end())
    141         stop_sp = *pos;
    142 
    143     return stop_sp;
    144 }
    145 
    146 const BreakpointSP
    147 BreakpointList::FindBreakpointByID (break_id_t break_id) const
    148 {
    149     Mutex::Locker locker(m_mutex);
    150     BreakpointSP stop_sp;
    151     bp_collection::const_iterator pos = GetBreakpointIDConstIterator(break_id);
    152     if (pos != m_breakpoints.end())
    153         stop_sp = *pos;
    154 
    155     return stop_sp;
    156 }
    157 
    158 void
    159 BreakpointList::Dump (Stream *s) const
    160 {
    161     Mutex::Locker locker(m_mutex);
    162     s->Printf("%p: ", this);
    163     s->Indent();
    164     s->Printf("BreakpointList with %u Breakpoints:\n", (uint32_t)m_breakpoints.size());
    165     s->IndentMore();
    166     bp_collection::const_iterator pos;
    167     bp_collection::const_iterator end = m_breakpoints.end();
    168     for (pos = m_breakpoints.begin(); pos != end; ++pos)
    169         (*pos)->Dump(s);
    170     s->IndentLess();
    171 }
    172 
    173 
    174 BreakpointSP
    175 BreakpointList::GetBreakpointAtIndex (size_t i)
    176 {
    177     Mutex::Locker locker(m_mutex);
    178     BreakpointSP stop_sp;
    179     bp_collection::iterator end = m_breakpoints.end();
    180     bp_collection::iterator pos;
    181     size_t curr_i = 0;
    182     for (pos = m_breakpoints.begin(), curr_i = 0; pos != end; ++pos, ++curr_i)
    183     {
    184         if (curr_i == i)
    185             stop_sp = *pos;
    186     }
    187     return stop_sp;
    188 }
    189 
    190 const BreakpointSP
    191 BreakpointList::GetBreakpointAtIndex (size_t i) const
    192 {
    193     Mutex::Locker locker(m_mutex);
    194     BreakpointSP stop_sp;
    195     bp_collection::const_iterator end = m_breakpoints.end();
    196     bp_collection::const_iterator pos;
    197     size_t curr_i = 0;
    198     for (pos = m_breakpoints.begin(), curr_i = 0; pos != end; ++pos, ++curr_i)
    199     {
    200         if (curr_i == i)
    201             stop_sp = *pos;
    202     }
    203     return stop_sp;
    204 }
    205 
    206 void
    207 BreakpointList::UpdateBreakpoints (ModuleList& module_list, bool added)
    208 {
    209     Mutex::Locker locker(m_mutex);
    210     bp_collection::iterator end = m_breakpoints.end();
    211     bp_collection::iterator pos;
    212     for (pos = m_breakpoints.begin(); pos != end; ++pos)
    213         (*pos)->ModulesChanged (module_list, added);
    214 
    215 }
    216 
    217 void
    218 BreakpointList::UpdateBreakpointsWhenModuleIsReplaced (ModuleSP old_module_sp, ModuleSP new_module_sp)
    219 {
    220     Mutex::Locker locker(m_mutex);
    221     bp_collection::iterator end = m_breakpoints.end();
    222     bp_collection::iterator pos;
    223     for (pos = m_breakpoints.begin(); pos != end; ++pos)
    224         (*pos)->ModuleReplaced (old_module_sp, new_module_sp);
    225 
    226 }
    227 
    228 void
    229 BreakpointList::ClearAllBreakpointSites ()
    230 {
    231     Mutex::Locker locker(m_mutex);
    232     bp_collection::iterator end = m_breakpoints.end();
    233     bp_collection::iterator pos;
    234     for (pos = m_breakpoints.begin(); pos != end; ++pos)
    235         (*pos)->ClearAllBreakpointSites ();
    236 
    237 }
    238 
    239 void
    240 BreakpointList::GetListMutex (Mutex::Locker &locker)
    241 {
    242     return locker.Lock (m_mutex);
    243 }
    244