[Lldb-commits] [lldb] r183820 - Huge performance improvements when one breakpoint contains many locations.

Greg Clayton gclayton at apple.com
Tue Jun 11 17:46:38 PDT 2013


Author: gclayton
Date: Tue Jun 11 19:46:38 2013
New Revision: 183820

URL: http://llvm.org/viewvc/llvm-project?rev=183820&view=rev
Log:
Huge performance improvements when one breakpoint contains many locations.

325,000 breakpoints for running "breakpoint set --func-regex ." on lldb itself (after hitting a breakpoint at main so that LLDB.framework is loaded) used to take up to an hour to set, now we are down under a minute. With warm file caches, we are at 40 seconds, and that is with setting 325,000 breakpoint through the GDB remote API. Linux and the native debuggers might be faster. I haven't timed what how much is debug info parsing and how much is the protocol traffic to/from GDB remote.

That there were many performance issues. Most of them were due to storing breakpoints in the wrong data structures, or using the wrong iterators to traverse the lists, traversing the lists in inefficient ways, and not optimizing certain function name lookups/symbol merges correctly.

Debugging after that is also now very efficient. There were issues with replacing the breakpoint opcodes in memory that was read, and those routines were also fixed.


Modified:
    lldb/trunk/include/lldb/Breakpoint/BreakpointSiteList.h
    lldb/trunk/include/lldb/Symbol/SymbolContext.h
    lldb/trunk/source/Breakpoint/BreakpointResolverName.cpp
    lldb/trunk/source/Breakpoint/BreakpointSiteList.cpp
    lldb/trunk/source/Core/Module.cpp
    lldb/trunk/source/Symbol/SymbolContext.cpp
    lldb/trunk/source/Target/Process.cpp
    lldb/trunk/tools/debugserver/source/DNB.cpp
    lldb/trunk/tools/debugserver/source/DNB.h
    lldb/trunk/tools/debugserver/source/DNBBreakpoint.cpp
    lldb/trunk/tools/debugserver/source/DNBBreakpoint.h
    lldb/trunk/tools/debugserver/source/DNBDefs.h
    lldb/trunk/tools/debugserver/source/MacOSX/MachProcess.cpp
    lldb/trunk/tools/debugserver/source/MacOSX/MachProcess.h
    lldb/trunk/tools/debugserver/source/MacOSX/MachThread.cpp
    lldb/trunk/tools/debugserver/source/MacOSX/MachThread.h
    lldb/trunk/tools/debugserver/source/MacOSX/MachThreadList.cpp
    lldb/trunk/tools/debugserver/source/MacOSX/i386/DNBArchImplI386.cpp
    lldb/trunk/tools/debugserver/source/MacOSX/x86_64/DNBArchImplX86_64.cpp
    lldb/trunk/tools/debugserver/source/RNBRemote.cpp
    lldb/trunk/tools/debugserver/source/RNBRemote.h

Modified: lldb/trunk/include/lldb/Breakpoint/BreakpointSiteList.h
URL: http://llvm.org/viewvc/llvm-project/lldb/trunk/include/lldb/Breakpoint/BreakpointSiteList.h?rev=183820&r1=183819&r2=183820&view=diff
==============================================================================
--- lldb/trunk/include/lldb/Breakpoint/BreakpointSiteList.h (original)
+++ lldb/trunk/include/lldb/Breakpoint/BreakpointSiteList.h Tue Jun 11 19:46:38 2013
@@ -16,6 +16,7 @@
 // Other libraries and framework includes
 // Project includes
 #include "lldb/Breakpoint/BreakpointSite.h"
+#include "lldb/Host/Mutex.h"
 
 namespace lldb_private {
 
@@ -130,31 +131,8 @@ public:
     bool
     BreakpointSiteContainsBreakpoint (lldb::break_id_t bp_site_id, lldb::break_id_t bp_id);
 
-    //------------------------------------------------------------------
-    /// Returns a shared pointer to the breakpoint site with index \a i.
-    ///
-    /// @param[in] i
-    ///   The breakpoint site index to seek for.
-    ///
-    /// @result
-    ///   A shared pointer to the breakpoint site.  May contain a NULL pointer if the
-    ///   breakpoint doesn't exist.
-    //------------------------------------------------------------------
-    lldb::BreakpointSiteSP
-    GetByIndex (uint32_t i);
-
-    //------------------------------------------------------------------
-    /// Returns a shared pointer to the breakpoint site with index \a i - const version.
-    ///
-    /// @param[in] i
-    ///   The breakpoint site index to seek for.
-    ///
-    /// @result
-    ///   A shared pointer to the breakpoint site.  May contain a NULL pointer if the
-    ///   breakpoint doesn't exist.
-    //------------------------------------------------------------------
-    const lldb::BreakpointSiteSP
-    GetByIndex (uint32_t i) const;
+    void
+    ForEach (std::function <void(BreakpointSite *)> const &callback);
 
     //------------------------------------------------------------------
     /// Removes the breakpoint site given by \b breakID from this list.
@@ -179,9 +157,6 @@ public:
     //------------------------------------------------------------------
     bool
     RemoveByAddress (lldb::addr_t addr);
-
-    void
-    SetEnabledForAll(const bool enable, const lldb::break_id_t except_id = LLDB_INVALID_BREAK_ID);
     
     bool
     FindInRange (lldb::addr_t lower_bound, lldb::addr_t upper_bound, BreakpointSiteList &bp_site_list) const;
@@ -211,8 +186,18 @@ public:
     ///   The number of elements.
     //------------------------------------------------------------------
     size_t
-    GetSize() const { return m_bp_site_list.size(); }
+    GetSize() const
+    {
+        Mutex::Locker locker(m_mutex);
+        return m_bp_site_list.size();
+    }
 
+    bool
+    IsEmpty() const
+    {
+        Mutex::Locker locker(m_mutex);
+        return m_bp_site_list.empty();
+    }
 protected:
     typedef std::map<lldb::addr_t, lldb::BreakpointSiteSP> collection;
 
@@ -222,13 +207,7 @@ protected:
     collection::const_iterator
     GetIDConstIterator(lldb::break_id_t breakID) const;
 
-    // This function exposes the m_bp_site_list.  I use the in Process because there
-    // are places there where you want to iterate over the list, and it is less efficient
-    // to do it by index.  FIXME: Find a better way to do this.
-
-    const collection *
-    GetMap ();
-
+    mutable Mutex m_mutex;
     collection m_bp_site_list;  // The breakpoint site list.
 };
 

Modified: lldb/trunk/include/lldb/Symbol/SymbolContext.h
URL: http://llvm.org/viewvc/llvm-project/lldb/trunk/include/lldb/Symbol/SymbolContext.h?rev=183820&r1=183819&r2=183820&view=diff
==============================================================================
--- lldb/trunk/include/lldb/Symbol/SymbolContext.h (original)
+++ lldb/trunk/include/lldb/Symbol/SymbolContext.h Tue Jun 11 19:46:38 2013
@@ -442,6 +442,11 @@ public:
     AppendIfUnique (const SymbolContext& sc, 
                     bool merge_symbol_into_function);
 
+    bool
+    MergeSymbolContextIntoFunctionContext (const SymbolContext& symbol_sc,
+                                           uint32_t start_idx = 0,
+                                           uint32_t stop_idx = UINT32_MAX);
+
     uint32_t
     AppendIfUnique (const SymbolContextList& sc_list, 
                     bool merge_symbol_into_function);
@@ -486,6 +491,30 @@ public:
     GetContextAtIndex(size_t idx, SymbolContext& sc) const;
 
     //------------------------------------------------------------------
+    /// Direct reference accessor for a symbol context at index \a idx.
+    ///
+    /// The index \a idx must be a valid index, no error checking will
+    /// be done to ensure that it is valid.
+    ///
+    /// @param[in] idx
+    ///     The zero based index into the symbol context list.
+    ///
+    /// @return
+    ///     A const reference to the symbol context to fill in.
+    //------------------------------------------------------------------
+    SymbolContext&
+    operator [] (size_t idx)
+    {
+        return m_symbol_contexts[idx];
+    }
+    
+    const SymbolContext&
+    operator [] (size_t idx) const
+    {
+        return m_symbol_contexts[idx];
+    }
+
+    //------------------------------------------------------------------
     /// Get accessor for the last symbol context in the list.
     ///
     /// @param[out] sc

Modified: lldb/trunk/source/Breakpoint/BreakpointResolverName.cpp
URL: http://llvm.org/viewvc/llvm-project/lldb/trunk/source/Breakpoint/BreakpointResolverName.cpp?rev=183820&r1=183819&r2=183820&view=diff
==============================================================================
--- lldb/trunk/source/Breakpoint/BreakpointResolverName.cpp (original)
+++ lldb/trunk/source/Breakpoint/BreakpointResolverName.cpp Tue Jun 11 19:46:38 2013
@@ -188,7 +188,7 @@ BreakpointResolverName::SearchCallback
 )
 {
     SymbolContextList func_list;
-    SymbolContextList sym_list;
+    //SymbolContextList sym_list;
     
     uint32_t i;
     bool new_location;
@@ -203,11 +203,10 @@ BreakpointResolverName::SearchCallback
             log->Warning ("Class/method function specification not supported yet.\n");
         return Searcher::eCallbackReturnStop;
     }
-    
-    const bool include_symbols = false;
+    bool filter_by_cu = (filter.GetFilterRequiredItems() & eSymbolContextCompUnit) != 0;
+    const bool include_symbols = filter_by_cu == false;
     const bool include_inlines = true;
     const bool append = true;
-    bool filter_by_cu = (filter.GetFilterRequiredItems() & eSymbolContextCompUnit) != 0;
 
     switch (m_match_type)
     {
@@ -228,26 +227,14 @@ BreakpointResolverName::SearchCallback
 
                     if (start_func_idx < end_func_idx)
                         lookup.Prune (func_list, start_func_idx);
-                    // If the search filter specifies a Compilation Unit, then we don't need to bother to look in plain
-                    // symbols, since all the ones from a set compilation unit will have been found above already.
-                    else if (!filter_by_cu)
-                    {
-                        const size_t start_symbol_idx = sym_list.GetSize();
-                        context.module_sp->FindFunctionSymbols (lookup.lookup_name, lookup.name_type_mask, sym_list);
-                        const size_t end_symbol_idx = sym_list.GetSize();
-                        if (start_symbol_idx < end_symbol_idx)
-                            lookup.Prune (func_list, start_symbol_idx);
-                    }
                 }
             }
             break;
         case Breakpoint::Regexp:
             if (context.module_sp)
             {
-                if (!filter_by_cu)
-                    context.module_sp->FindSymbolsMatchingRegExAndType (m_regex, eSymbolTypeCode, sym_list);
-                context.module_sp->FindFunctions (m_regex, 
-                                                  include_symbols,
+                context.module_sp->FindFunctions (m_regex,
+                                                  !filter_by_cu, // include symbols only if we aren't filterning by CU
                                                   include_inlines, 
                                                   append, 
                                                   func_list);
@@ -283,33 +270,6 @@ BreakpointResolverName::SearchCallback
     {
         for (i = 0; i < func_list.GetSize(); i++)
         {
-            if (func_list.GetContextAtIndex(i, sc) == false)
-                continue;
-            
-            if (sc.function == NULL)
-                continue;
-            uint32_t j = 0;
-            while (j < sym_list.GetSize())
-            {
-                SymbolContext symbol_sc;
-                if (sym_list.GetContextAtIndex(j, symbol_sc))
-                {
-                    if (symbol_sc.symbol && symbol_sc.symbol->ValueIsAddress())
-                    {
-                        if (sc.function->GetAddressRange().GetBaseAddress() == symbol_sc.symbol->GetAddress())
-                        {
-                            sym_list.RemoveContextAtIndex(j);
-                            continue;   // Don't increment j
-                        }
-                    }
-                }
-                
-                j++;
-            }
-        }
-        
-        for (i = 0; i < func_list.GetSize(); i++)
-        {
             if (func_list.GetContextAtIndex(i, sc))
             {
                 if (sc.block && sc.block->GetInlinedFunctionInfo())
@@ -320,14 +280,21 @@ BreakpointResolverName::SearchCallback
                 else if (sc.function)
                 {
                     break_addr = sc.function->GetAddressRange().GetBaseAddress();
-                    if (m_skip_prologue)
+                    if (m_skip_prologue && break_addr.IsValid())
                     {
-                        if (break_addr.IsValid())
-                        {
-                            const uint32_t prologue_byte_size = sc.function->GetPrologueByteSize();
-                            if (prologue_byte_size)
-                                break_addr.SetOffset(break_addr.GetOffset() + prologue_byte_size);
-                        }
+                        const uint32_t prologue_byte_size = sc.function->GetPrologueByteSize();
+                        if (prologue_byte_size)
+                            break_addr.SetOffset(break_addr.GetOffset() + prologue_byte_size);
+                    }
+                }
+                else if (sc.symbol)
+                {
+                    break_addr = sc.symbol->GetAddress();
+                    if (m_skip_prologue && break_addr.IsValid())
+                    {
+                        const uint32_t prologue_byte_size = sc.symbol->GetPrologueByteSize();
+                        if (prologue_byte_size)
+                            break_addr.SetOffset(break_addr.GetOffset() + prologue_byte_size);
                     }
                 }
                 
@@ -351,35 +318,6 @@ BreakpointResolverName::SearchCallback
         }
     }
     
-    for (i = 0; i < sym_list.GetSize(); i++)
-    {
-        if (sym_list.GetContextAtIndex(i, sc))
-        {
-            if (sc.symbol && sc.symbol->ValueIsAddress())
-            {
-                break_addr = sc.symbol->GetAddress();
-                
-                if (m_skip_prologue)
-                {
-                    const uint32_t prologue_byte_size = sc.symbol->GetPrologueByteSize();
-                    if (prologue_byte_size)
-                        break_addr.SetOffset(break_addr.GetOffset() + prologue_byte_size);
-                }
-                
-                if (filter.AddressPasses(break_addr))
-                {
-                    BreakpointLocationSP bp_loc_sp (m_breakpoint->AddLocation(break_addr, &new_location));
-                    if (bp_loc_sp && new_location && !m_breakpoint->IsInternal())
-                    {
-                        StreamString s;
-                        bp_loc_sp->GetDescription(&s, lldb::eDescriptionLevelVerbose);
-                        if (log) 
-                            log->Printf ("Added location: %s\n", s.GetData());
-                    }
-                }
-            }
-        }
-    }
     return Searcher::eCallbackReturnContinue;
 }
 

Modified: lldb/trunk/source/Breakpoint/BreakpointSiteList.cpp
URL: http://llvm.org/viewvc/llvm-project/lldb/trunk/source/Breakpoint/BreakpointSiteList.cpp?rev=183820&r1=183819&r2=183820&view=diff
==============================================================================
--- lldb/trunk/source/Breakpoint/BreakpointSiteList.cpp (original)
+++ lldb/trunk/source/Breakpoint/BreakpointSiteList.cpp Tue Jun 11 19:46:38 2013
@@ -20,6 +20,7 @@ using namespace lldb;
 using namespace lldb_private;
 
 BreakpointSiteList::BreakpointSiteList() :
+    m_mutex (Mutex::eMutexTypeRecursive),
     m_bp_site_list()
 {
 }
@@ -35,6 +36,7 @@ lldb::break_id_t
 BreakpointSiteList::Add(const BreakpointSiteSP &bp)
 {
     lldb::addr_t bp_site_load_addr = bp->GetLoadAddress();
+    Mutex::Locker locker(m_mutex);
     collection::iterator iter = m_bp_site_list.find (bp_site_load_addr);
 
     if (iter == m_bp_site_list.end())
@@ -79,6 +81,7 @@ BreakpointSiteList::FindIDByAddress (lld
 bool
 BreakpointSiteList::Remove (lldb::break_id_t break_id)
 {
+    Mutex::Locker locker(m_mutex);
     collection::iterator pos = GetIDIterator(break_id);    // Predicate
     if (pos != m_bp_site_list.end())
     {
@@ -91,6 +94,7 @@ BreakpointSiteList::Remove (lldb::break_
 bool
 BreakpointSiteList::RemoveByAddress (lldb::addr_t address)
 {
+    Mutex::Locker locker(m_mutex);
     collection::iterator pos =  m_bp_site_list.find(address);
     if (pos != m_bp_site_list.end())
     {
@@ -120,6 +124,7 @@ private:
 BreakpointSiteList::collection::iterator
 BreakpointSiteList::GetIDIterator (lldb::break_id_t break_id)
 {
+    Mutex::Locker locker(m_mutex);
     return std::find_if(m_bp_site_list.begin(), m_bp_site_list.end(),   // Search full range
                         BreakpointSiteIDMatches(break_id));             // Predicate
 }
@@ -127,6 +132,7 @@ BreakpointSiteList::GetIDIterator (lldb:
 BreakpointSiteList::collection::const_iterator
 BreakpointSiteList::GetIDConstIterator (lldb::break_id_t break_id) const
 {
+    Mutex::Locker locker(m_mutex);
     return std::find_if(m_bp_site_list.begin(), m_bp_site_list.end(),   // Search full range
                         BreakpointSiteIDMatches(break_id));             // Predicate
 }
@@ -134,6 +140,7 @@ BreakpointSiteList::GetIDConstIterator (
 BreakpointSiteSP
 BreakpointSiteList::FindByID (lldb::break_id_t break_id)
 {
+    Mutex::Locker locker(m_mutex);
     BreakpointSiteSP stop_sp;
     collection::iterator pos = GetIDIterator(break_id);
     if (pos != m_bp_site_list.end())
@@ -145,6 +152,7 @@ BreakpointSiteList::FindByID (lldb::brea
 const BreakpointSiteSP
 BreakpointSiteList::FindByID (lldb::break_id_t break_id) const
 {
+    Mutex::Locker locker(m_mutex);
     BreakpointSiteSP stop_sp;
     collection::const_iterator pos = GetIDConstIterator(break_id);
     if (pos != m_bp_site_list.end())
@@ -157,7 +165,7 @@ BreakpointSiteSP
 BreakpointSiteList::FindByAddress (lldb::addr_t addr)
 {
     BreakpointSiteSP found_sp;
-
+    Mutex::Locker locker(m_mutex);
     collection::iterator iter =  m_bp_site_list.find(addr);
     if (iter != m_bp_site_list.end())
         found_sp = iter->second;
@@ -167,6 +175,7 @@ BreakpointSiteList::FindByAddress (lldb:
 bool
 BreakpointSiteList::BreakpointSiteContainsBreakpoint (lldb::break_id_t bp_site_id, lldb::break_id_t bp_id)
 {
+    Mutex::Locker locker(m_mutex);
     collection::const_iterator pos = GetIDConstIterator(bp_site_id);
     if (pos != m_bp_site_list.end())
         return pos->second->IsBreakpointAtThisSite (bp_id);
@@ -188,44 +197,21 @@ BreakpointSiteList::Dump (Stream *s) con
     s->IndentLess();
 }
 
-
-BreakpointSiteSP
-BreakpointSiteList::GetByIndex (uint32_t i)
-{
-    BreakpointSiteSP stop_sp;
-    collection::iterator end = m_bp_site_list.end();
-    collection::iterator pos;
-    uint32_t curr_i = 0;
-    for (pos = m_bp_site_list.begin(), curr_i = 0; pos != end; ++pos, ++curr_i)
-    {
-        if (curr_i == i)
-            stop_sp = pos->second;
-    }
-    return stop_sp;
-}
-
-const BreakpointSiteSP
-BreakpointSiteList::GetByIndex (uint32_t i) const
+void
+BreakpointSiteList::ForEach (std::function <void(BreakpointSite *)> const &callback)
 {
-    BreakpointSiteSP stop_sp;
-    collection::const_iterator end = m_bp_site_list.end();
-    collection::const_iterator pos;
-    uint32_t curr_i = 0;
-    for (pos = m_bp_site_list.begin(), curr_i = 0; pos != end; ++pos, ++curr_i)
-    {
-        if (curr_i == i)
-            stop_sp = pos->second;
-    }
-    return stop_sp;
+    Mutex::Locker locker(m_mutex);
+    for (auto pair : m_bp_site_list)
+        callback (pair.second.get());
 }
 
 bool
 BreakpointSiteList::FindInRange (lldb::addr_t lower_bound, lldb::addr_t upper_bound, BreakpointSiteList &bp_site_list) const
 {
-        
     if (lower_bound > upper_bound)
         return false;
     
+    Mutex::Locker locker(m_mutex);
     collection::const_iterator lower, upper, pos;
     lower = m_bp_site_list.lower_bound(lower_bound);
     if (lower == m_bp_site_list.end()
@@ -252,24 +238,3 @@ BreakpointSiteList::FindInRange (lldb::a
     }
     return true;
 }
-
-
-void
-BreakpointSiteList::SetEnabledForAll (const bool enabled, const lldb::break_id_t except_id)
-{
-    collection::iterator end = m_bp_site_list.end();
-    collection::iterator pos;
-    for (pos = m_bp_site_list.begin(); pos != end; ++pos)
-    {
-        if (except_id != LLDB_INVALID_BREAK_ID && except_id != pos->second->GetID())
-            pos->second->SetEnabled (enabled);
-        else
-            pos->second->SetEnabled (!enabled);
-    }
-}
-
-const BreakpointSiteList::collection *
-BreakpointSiteList::GetMap ()
-{
-    return &m_bp_site_list;
-}

Modified: lldb/trunk/source/Core/Module.cpp
URL: http://llvm.org/viewvc/llvm-project/lldb/trunk/source/Core/Module.cpp?rev=183820&r1=183819&r2=183820&view=diff
==============================================================================
--- lldb/trunk/source/Core/Module.cpp (original)
+++ lldb/trunk/source/Core/Module.cpp Tue Jun 11 19:46:38 2013
@@ -704,15 +704,50 @@ Module::FindFunctions (const RegularExpr
                 const size_t num_matches = symbol_indexes.size();
                 if (num_matches)
                 {
-                    const bool merge_symbol_into_function = true;
                     SymbolContext sc(this);
-                    for (size_t i=0; i<num_matches; i++)
+                    const size_t end_functions_added_index = sc_list.GetSize();
+                    size_t num_functions_added_to_sc_list = end_functions_added_index - start_size;
+                    if (num_functions_added_to_sc_list == 0)
                     {
-                        sc.symbol = symtab->SymbolAtIndex(symbol_indexes[i]);
-                        SymbolType sym_type = sc.symbol->GetType();
-                        if (sc.symbol && (sym_type == eSymbolTypeCode ||
-                                          sym_type == eSymbolTypeResolver))
-                            sc_list.AppendIfUnique (sc, merge_symbol_into_function);
+                        // No functions were added, just symbols, so we can just append them
+                        for (size_t i=0; i<num_matches; ++i)
+                        {
+                            sc.symbol = symtab->SymbolAtIndex(symbol_indexes[i]);
+                            SymbolType sym_type = sc.symbol->GetType();
+                            if (sc.symbol && (sym_type == eSymbolTypeCode ||
+                                              sym_type == eSymbolTypeResolver))
+                                sc_list.Append(sc);
+                        }
+                    }
+                    else
+                    {
+                        typedef std::map<lldb::addr_t, uint32_t> FileAddrToIndexMap;
+                        FileAddrToIndexMap file_addr_to_index;
+                        for (size_t i=start_size; i<end_functions_added_index; ++i)
+                        {
+                            const SymbolContext &sc = sc_list[i];
+                            if (sc.block)
+                                continue;
+                            file_addr_to_index[sc.function->GetAddressRange().GetBaseAddress().GetFileAddress()] = i;
+                        }
+
+                        FileAddrToIndexMap::const_iterator end = file_addr_to_index.end();
+                        // Functions were added so we need to merge symbols into any
+                        // existing function symbol contexts
+                        for (size_t i=start_size; i<num_matches; ++i)
+                        {
+                            sc.symbol = symtab->SymbolAtIndex(symbol_indexes[i]);
+                            SymbolType sym_type = sc.symbol->GetType();
+                            if (sc.symbol && (sym_type == eSymbolTypeCode ||
+                                              sym_type == eSymbolTypeResolver))
+                            {
+                                FileAddrToIndexMap::const_iterator pos = file_addr_to_index.find(sc.symbol->GetAddress().GetFileAddress());
+                                if (pos == end)
+                                    sc_list.Append(sc);
+                                else
+                                    sc_list[pos->second].symbol = sc.symbol;
+                            }
+                        }
                     }
                 }
             }

Modified: lldb/trunk/source/Symbol/SymbolContext.cpp
URL: http://llvm.org/viewvc/llvm-project/lldb/trunk/source/Symbol/SymbolContext.cpp?rev=183820&r1=183819&r2=183820&view=diff
==============================================================================
--- lldb/trunk/source/Symbol/SymbolContext.cpp (original)
+++ lldb/trunk/source/Symbol/SymbolContext.cpp Tue Jun 11 19:46:38 2013
@@ -1023,6 +1023,10 @@ SymbolContextList::AppendIfUnique (const
         {
             for (pos = m_symbol_contexts.begin(); pos != end; ++pos)
             {
+                // Don't merge symbols into inlined function symbol contexts
+                if (pos->block && pos->block->GetContainingInlinedBlock())
+                    continue;
+
                 if (pos->function)
                 {
                     if (pos->function->GetAddressRange().GetBaseAddress() == sc.symbol->GetAddress())
@@ -1044,6 +1048,49 @@ SymbolContextList::AppendIfUnique (const
     return true;
 }
 
+bool
+SymbolContextList::MergeSymbolContextIntoFunctionContext (const SymbolContext& symbol_sc,
+                                                          uint32_t start_idx,
+                                                          uint32_t stop_idx)
+{
+    if (symbol_sc.symbol    != NULL
+        && symbol_sc.comp_unit == NULL
+        && symbol_sc.function  == NULL
+        && symbol_sc.block     == NULL
+        && symbol_sc.line_entry.IsValid() == false)
+    {
+        if (symbol_sc.symbol->ValueIsAddress())
+        {
+            const size_t end = std::min<size_t>(m_symbol_contexts.size(), stop_idx);
+            for (size_t i=start_idx; i<end; ++i)
+            {
+                const SymbolContext &function_sc = m_symbol_contexts[i];
+                // Don't merge symbols into inlined function symbol contexts
+                if (function_sc.block && function_sc.block->GetContainingInlinedBlock())
+                    continue;
+                
+                if (function_sc.function)
+                {
+                    if (function_sc.function->GetAddressRange().GetBaseAddress() == symbol_sc.symbol->GetAddress())
+                    {
+                        // Do we already have a function with this symbol?
+                        if (function_sc.symbol == symbol_sc.symbol)
+                            return true; // Already have a symbol context with this symbol, return true
+
+                        if (function_sc.symbol == NULL)
+                        {
+                            // We successfully merged this symbol into an existing symbol context
+                            m_symbol_contexts[i].symbol = symbol_sc.symbol;
+                            return true;
+                        }
+                    }
+                }
+            }
+        }
+    }
+    return false;
+}
+
 void
 SymbolContextList::Clear()
 {

Modified: lldb/trunk/source/Target/Process.cpp
URL: http://llvm.org/viewvc/llvm-project/lldb/trunk/source/Target/Process.cpp?rev=183820&r1=183819&r2=183820&view=diff
==============================================================================
--- lldb/trunk/source/Target/Process.cpp (original)
+++ lldb/trunk/source/Target/Process.cpp Tue Jun 11 19:46:38 2013
@@ -2007,12 +2007,10 @@ Process::GetBreakpointSiteList() const
 void
 Process::DisableAllBreakpointSites ()
 {
-    m_breakpoint_site_list.SetEnabledForAll (false);
-    size_t num_sites = m_breakpoint_site_list.GetSize();
-    for (size_t i = 0; i < num_sites; i++)
-    {
-        DisableBreakpointSite (m_breakpoint_site_list.GetByIndex(i).get());
-    }
+    m_breakpoint_site_list.ForEach([this](BreakpointSite *bp_site) -> void {
+//        bp_site->SetEnabled(true);
+        DisableBreakpointSite(bp_site);
+    });
 }
 
 Error
@@ -2116,29 +2114,26 @@ size_t
 Process::RemoveBreakpointOpcodesFromBuffer (addr_t bp_addr, size_t size, uint8_t *buf) const
 {
     size_t bytes_removed = 0;
-    addr_t intersect_addr;
-    size_t intersect_size;
-    size_t opcode_offset;
-    size_t idx;
-    BreakpointSiteSP bp_sp;
     BreakpointSiteList bp_sites_in_range;
 
     if (m_breakpoint_site_list.FindInRange (bp_addr, bp_addr + size, bp_sites_in_range))
     {
-        for (idx = 0; (bp_sp = bp_sites_in_range.GetByIndex(idx)); ++idx)
-        {
-            if (bp_sp->GetType() == BreakpointSite::eSoftware)
+        bp_sites_in_range.ForEach([bp_addr, size, buf, &bytes_removed](BreakpointSite *bp_site) -> void {
+            if (bp_site->GetType() == BreakpointSite::eSoftware)
             {
-                if (bp_sp->IntersectsRange(bp_addr, size, &intersect_addr, &intersect_size, &opcode_offset))
+                addr_t intersect_addr;
+                size_t intersect_size;
+                size_t opcode_offset;
+                if (bp_site->IntersectsRange(bp_addr, size, &intersect_addr, &intersect_size, &opcode_offset))
                 {
                     assert(bp_addr <= intersect_addr && intersect_addr < bp_addr + size);
                     assert(bp_addr < intersect_addr + intersect_size && intersect_addr + intersect_size <= bp_addr + size);
-                    assert(opcode_offset + intersect_size <= bp_sp->GetByteSize());
+                    assert(opcode_offset + intersect_size <= bp_site->GetByteSize());
                     size_t buf_offset = intersect_addr - bp_addr;
-                    ::memcpy(buf + buf_offset, bp_sp->GetSavedOpcodeBytes() + opcode_offset, intersect_size);
+                    ::memcpy(buf + buf_offset, bp_site->GetSavedOpcodeBytes() + opcode_offset, intersect_size);
                 }
             }
-        }
+        });
     }
     return bytes_removed;
 }
@@ -2596,64 +2591,73 @@ Process::WriteMemory (addr_t addr, const
     // (enabled software breakpoints) any software traps (breakpoints) that we
     // may have placed in our tasks memory.
 
-    BreakpointSiteList::collection::const_iterator iter = m_breakpoint_site_list.GetMap()->lower_bound (addr);
-    BreakpointSiteList::collection::const_iterator end =  m_breakpoint_site_list.GetMap()->end();
-
-    if (iter == end || iter->second->GetLoadAddress() > addr + size)
-        return WriteMemoryPrivate (addr, buf, size, error);
-
-    BreakpointSiteList::collection::const_iterator pos;
-    size_t bytes_written = 0;
-    addr_t intersect_addr = 0;
-    size_t intersect_size = 0;
-    size_t opcode_offset = 0;
-    const uint8_t *ubuf = (const uint8_t *)buf;
-
-    for (pos = iter; pos != end; ++pos)
-    {
-        BreakpointSiteSP bp;
-        bp = pos->second;
-
-        assert(bp->IntersectsRange(addr, size, &intersect_addr, &intersect_size, &opcode_offset));
-        assert(addr <= intersect_addr && intersect_addr < addr + size);
-        assert(addr < intersect_addr + intersect_size && intersect_addr + intersect_size <= addr + size);
-        assert(opcode_offset + intersect_size <= bp->GetByteSize());
-
-        // Check for bytes before this breakpoint
-        const addr_t curr_addr = addr + bytes_written;
-        if (intersect_addr > curr_addr)
+    BreakpointSiteList bp_sites_in_range;
+    
+    if (m_breakpoint_site_list.FindInRange (addr, addr + size, bp_sites_in_range))
+    {
+        // No breakpoint sites overlap
+        if (bp_sites_in_range.IsEmpty())
+            return WriteMemoryPrivate (addr, buf, size, error);
+        else
         {
-            // There are some bytes before this breakpoint that we need to
-            // just write to memory
-            size_t curr_size = intersect_addr - curr_addr;
-            size_t curr_bytes_written = WriteMemoryPrivate (curr_addr, 
-                                                            ubuf + bytes_written, 
-                                                            curr_size, 
-                                                            error);
-            bytes_written += curr_bytes_written;
-            if (curr_bytes_written != curr_size)
-            {
-                // We weren't able to write all of the requested bytes, we
-                // are done looping and will return the number of bytes that
-                // we have written so far.
-                break;
-            }
-        }
+            const uint8_t *ubuf = (const uint8_t *)buf;
+            uint64_t bytes_written = 0;
 
-        // Now write any bytes that would cover up any software breakpoints
-        // directly into the breakpoint opcode buffer
-        ::memcpy(bp->GetSavedOpcodeBytes() + opcode_offset, ubuf + bytes_written, intersect_size);
-        bytes_written += intersect_size;
+            bp_sites_in_range.ForEach([this, addr, size, &bytes_written, &ubuf, &error](BreakpointSite *bp) -> void {
+                
+                if (error.Success())
+                {
+                    addr_t intersect_addr;
+                    size_t intersect_size;
+                    size_t opcode_offset;
+                    const bool intersects = bp->IntersectsRange(addr, size, &intersect_addr, &intersect_size, &opcode_offset);
+                    assert(intersects);
+                    assert(addr <= intersect_addr && intersect_addr < addr + size);
+                    assert(addr < intersect_addr + intersect_size && intersect_addr + intersect_size <= addr + size);
+                    assert(opcode_offset + intersect_size <= bp->GetByteSize());
+                    
+                    // Check for bytes before this breakpoint
+                    const addr_t curr_addr = addr + bytes_written;
+                    if (intersect_addr > curr_addr)
+                    {
+                        // There are some bytes before this breakpoint that we need to
+                        // just write to memory
+                        size_t curr_size = intersect_addr - curr_addr;
+                        size_t curr_bytes_written = WriteMemoryPrivate (curr_addr,
+                                                                        ubuf + bytes_written,
+                                                                        curr_size,
+                                                                        error);
+                        bytes_written += curr_bytes_written;
+                        if (curr_bytes_written != curr_size)
+                        {
+                            // We weren't able to write all of the requested bytes, we
+                            // are done looping and will return the number of bytes that
+                            // we have written so far.
+                            if (error.Success())
+                                error.SetErrorToGenericError();
+                        }
+                    }
+                    // Now write any bytes that would cover up any software breakpoints
+                    // directly into the breakpoint opcode buffer
+                    ::memcpy(bp->GetSavedOpcodeBytes() + opcode_offset, ubuf + bytes_written, intersect_size);
+                    bytes_written += intersect_size;
+                }
+            });
+            
+            if (bytes_written < size)
+                bytes_written += WriteMemoryPrivate (addr + bytes_written,
+                                                     ubuf + bytes_written,
+                                                     size - bytes_written,
+                                                     error);
+        }
+    }
+    else
+    {
+        return WriteMemoryPrivate (addr, buf, size, error);
     }
 
     // Write any remaining bytes after the last breakpoint if we have any left
-    if (bytes_written < size)
-        bytes_written += WriteMemoryPrivate (addr + bytes_written, 
-                                             ubuf + bytes_written, 
-                                             size - bytes_written, 
-                                             error);
-                                             
-    return bytes_written;
+    return 0; //bytes_written;
 }
 
 size_t

Modified: lldb/trunk/tools/debugserver/source/DNB.cpp
URL: http://llvm.org/viewvc/llvm-project/lldb/trunk/tools/debugserver/source/DNB.cpp?rev=183820&r1=183819&r2=183820&view=diff
==============================================================================
--- lldb/trunk/tools/debugserver/source/DNB.cpp (original)
+++ lldb/trunk/tools/debugserver/source/DNB.cpp Tue Jun 11 19:46:38 2013
@@ -901,227 +901,44 @@ DNBProcessResetEvents (nub_process_t pid
 }
 
 // Breakpoints
-nub_break_t
+nub_bool_t
 DNBBreakpointSet (nub_process_t pid, nub_addr_t addr, nub_size_t size, nub_bool_t hardware)
 {
     MachProcessSP procSP;
     if (GetProcessSP (pid, procSP))
-    {
-        return procSP->CreateBreakpoint(addr, size, hardware, THREAD_NULL);
-    }
-    return INVALID_NUB_BREAK_ID;
-}
-
-nub_bool_t
-DNBBreakpointClear (nub_process_t pid, nub_break_t breakID)
-{
-    if (NUB_BREAK_ID_IS_VALID(breakID))
-    {
-        MachProcessSP procSP;
-        if (GetProcessSP (pid, procSP))
-        {
-            return procSP->DisableBreakpoint(breakID, true);
-        }
-    }
-    return false; // Failed
-}
-
-nub_ssize_t
-DNBBreakpointGetHitCount (nub_process_t pid, nub_break_t breakID)
-{
-    if (NUB_BREAK_ID_IS_VALID(breakID))
-    {
-        MachProcessSP procSP;
-        if (GetProcessSP (pid, procSP))
-        {
-            DNBBreakpoint *bp = procSP->Breakpoints().FindByID(breakID);
-            if (bp)
-                return bp->GetHitCount();
-        }
-    }
-    return 0;
-}
-
-nub_ssize_t
-DNBBreakpointGetIgnoreCount (nub_process_t pid, nub_break_t breakID)
-{
-    if (NUB_BREAK_ID_IS_VALID(breakID))
-    {
-        MachProcessSP procSP;
-        if (GetProcessSP (pid, procSP))
-        {
-            DNBBreakpoint *bp = procSP->Breakpoints().FindByID(breakID);
-            if (bp)
-                return bp->GetIgnoreCount();
-        }
-    }
-    return 0;
-}
-
-nub_bool_t
-DNBBreakpointSetIgnoreCount (nub_process_t pid, nub_break_t breakID, nub_size_t ignore_count)
-{
-    if (NUB_BREAK_ID_IS_VALID(breakID))
-    {
-        MachProcessSP procSP;
-        if (GetProcessSP (pid, procSP))
-        {
-            DNBBreakpoint *bp = procSP->Breakpoints().FindByID(breakID);
-            if (bp)
-            {
-                bp->SetIgnoreCount(ignore_count);
-                return true;
-            }
-        }
-    }
+        return procSP->CreateBreakpoint(addr, size, hardware) != NULL;
     return false;
 }
 
-// Set the callback function for a given breakpoint. The callback function will
-// get called as soon as the breakpoint is hit. The function will be called
-// with the process ID, thread ID, breakpoint ID and the baton, and can return
-//
 nub_bool_t
-DNBBreakpointSetCallback (nub_process_t pid, nub_break_t breakID, DNBCallbackBreakpointHit callback, void *baton)
-{
-    if (NUB_BREAK_ID_IS_VALID(breakID))
-    {
-        MachProcessSP procSP;
-        if (GetProcessSP (pid, procSP))
-        {
-            DNBBreakpoint *bp = procSP->Breakpoints().FindByID(breakID);
-            if (bp)
-            {
-                bp->SetCallback(callback, baton);
-                return true;
-            }
-        }
-    }
-    return false;
-}
-
-//----------------------------------------------------------------------
-// Dump the breakpoints stats for process PID for a breakpoint by ID.
-//----------------------------------------------------------------------
-void
-DNBBreakpointPrint (nub_process_t pid, nub_break_t breakID)
+DNBBreakpointClear (nub_process_t pid, nub_addr_t addr)
 {
     MachProcessSP procSP;
     if (GetProcessSP (pid, procSP))
-        procSP->DumpBreakpoint(breakID);
+        return procSP->DisableBreakpoint(addr, true);
+    return false; // Failed
 }
 
+
 //----------------------------------------------------------------------
 // Watchpoints
 //----------------------------------------------------------------------
-nub_watch_t
+nub_bool_t
 DNBWatchpointSet (nub_process_t pid, nub_addr_t addr, nub_size_t size, uint32_t watch_flags, nub_bool_t hardware)
 {
     MachProcessSP procSP;
     if (GetProcessSP (pid, procSP))
-    {
-        return procSP->CreateWatchpoint(addr, size, watch_flags, hardware, THREAD_NULL);
-    }
-    return INVALID_NUB_WATCH_ID;
-}
-
-nub_bool_t
-DNBWatchpointClear (nub_process_t pid, nub_watch_t watchID)
-{
-    if (NUB_WATCH_ID_IS_VALID(watchID))
-    {
-        MachProcessSP procSP;
-        if (GetProcessSP (pid, procSP))
-        {
-            return procSP->DisableWatchpoint(watchID, true);
-        }
-    }
-    return false; // Failed
-}
-
-nub_ssize_t
-DNBWatchpointGetHitCount (nub_process_t pid, nub_watch_t watchID)
-{
-    if (NUB_WATCH_ID_IS_VALID(watchID))
-    {
-        MachProcessSP procSP;
-        if (GetProcessSP (pid, procSP))
-        {
-            DNBBreakpoint *bp = procSP->Watchpoints().FindByID(watchID);
-            if (bp)
-                return bp->GetHitCount();
-        }
-    }
-    return 0;
-}
-
-nub_ssize_t
-DNBWatchpointGetIgnoreCount (nub_process_t pid, nub_watch_t watchID)
-{
-    if (NUB_WATCH_ID_IS_VALID(watchID))
-    {
-        MachProcessSP procSP;
-        if (GetProcessSP (pid, procSP))
-        {
-            DNBBreakpoint *bp = procSP->Watchpoints().FindByID(watchID);
-            if (bp)
-                return bp->GetIgnoreCount();
-        }
-    }
-    return 0;
-}
-
-nub_bool_t
-DNBWatchpointSetIgnoreCount (nub_process_t pid, nub_watch_t watchID, nub_size_t ignore_count)
-{
-    if (NUB_WATCH_ID_IS_VALID(watchID))
-    {
-        MachProcessSP procSP;
-        if (GetProcessSP (pid, procSP))
-        {
-            DNBBreakpoint *bp = procSP->Watchpoints().FindByID(watchID);
-            if (bp)
-            {
-                bp->SetIgnoreCount(ignore_count);
-                return true;
-            }
-        }
-    }
+        return procSP->CreateWatchpoint(addr, size, watch_flags, hardware) != NULL;
     return false;
 }
 
-// Set the callback function for a given watchpoint. The callback function will
-// get called as soon as the watchpoint is hit. The function will be called
-// with the process ID, thread ID, watchpoint ID and the baton, and can return
-//
 nub_bool_t
-DNBWatchpointSetCallback (nub_process_t pid, nub_watch_t watchID, DNBCallbackBreakpointHit callback, void *baton)
-{
-    if (NUB_WATCH_ID_IS_VALID(watchID))
-    {
-        MachProcessSP procSP;
-        if (GetProcessSP (pid, procSP))
-        {
-            DNBBreakpoint *bp = procSP->Watchpoints().FindByID(watchID);
-            if (bp)
-            {
-                bp->SetCallback(callback, baton);
-                return true;
-            }
-        }
-    }
-    return false;
-}
-
-//----------------------------------------------------------------------
-// Dump the watchpoints stats for process PID for a watchpoint by ID.
-//----------------------------------------------------------------------
-void
-DNBWatchpointPrint (nub_process_t pid, nub_watch_t watchID)
+DNBWatchpointClear (nub_process_t pid, nub_addr_t addr)
 {
     MachProcessSP procSP;
     if (GetProcessSP (pid, procSP))
-        procSP->DumpWatchpoint(watchID);
+        return procSP->DisableWatchpoint(addr, true);
+    return false; // Failed
 }
 
 //----------------------------------------------------------------------

Modified: lldb/trunk/tools/debugserver/source/DNB.h
URL: http://llvm.org/viewvc/llvm-project/lldb/trunk/tools/debugserver/source/DNB.h?rev=183820&r1=183819&r2=183820&view=diff
==============================================================================
--- lldb/trunk/tools/debugserver/source/DNB.h (original)
+++ lldb/trunk/tools/debugserver/source/DNB.h Tue Jun 11 19:46:38 2013
@@ -121,24 +121,14 @@ const char *    DNBThreadGetInfo
 //----------------------------------------------------------------------
 // Breakpoint functions
 //----------------------------------------------------------------------
-nub_break_t     DNBBreakpointSet                (nub_process_t pid, nub_addr_t addr, nub_size_t size, nub_bool_t hardware) DNB_EXPORT;
-nub_bool_t      DNBBreakpointClear              (nub_process_t pid, nub_break_t breakID) DNB_EXPORT;
-nub_ssize_t     DNBBreakpointGetHitCount        (nub_process_t pid, nub_break_t breakID) DNB_EXPORT;
-nub_ssize_t     DNBBreakpointGetIgnoreCount     (nub_process_t pid, nub_break_t breakID) DNB_EXPORT;
-nub_bool_t      DNBBreakpointSetIgnoreCount     (nub_process_t pid, nub_break_t breakID, nub_size_t ignore_count) DNB_EXPORT;
-nub_bool_t      DNBBreakpointSetCallback        (nub_process_t pid, nub_break_t breakID, DNBCallbackBreakpointHit callback, void *baton) DNB_EXPORT;
-void            DNBBreakpointPrint              (nub_process_t pid, nub_break_t breakID) DNB_EXPORT;
+nub_bool_t      DNBBreakpointSet                (nub_process_t pid, nub_addr_t addr, nub_size_t size, nub_bool_t hardware) DNB_EXPORT;
+nub_bool_t      DNBBreakpointClear              (nub_process_t pid, nub_addr_t addr) DNB_EXPORT;
 
 //----------------------------------------------------------------------
 // Watchpoint functions
 //----------------------------------------------------------------------
-nub_watch_t     DNBWatchpointSet                (nub_process_t pid, nub_addr_t addr, nub_size_t size, uint32_t watch_flags, nub_bool_t hardware) DNB_EXPORT;
-nub_bool_t      DNBWatchpointClear              (nub_process_t pid, nub_watch_t watchID) DNB_EXPORT;
-nub_ssize_t     DNBWatchpointGetHitCount        (nub_process_t pid, nub_watch_t watchID) DNB_EXPORT;
-nub_ssize_t     DNBWatchpointGetIgnoreCount     (nub_process_t pid, nub_watch_t watchID) DNB_EXPORT;
-nub_bool_t      DNBWatchpointSetIgnoreCount     (nub_process_t pid, nub_watch_t watchID, nub_size_t ignore_count) DNB_EXPORT;
-nub_bool_t      DNBWatchpointSetCallback        (nub_process_t pid, nub_watch_t watchID, DNBCallbackBreakpointHit callback, void *baton) DNB_EXPORT;
-void            DNBWatchpointPrint              (nub_process_t pid, nub_watch_t watchID) DNB_EXPORT;
+nub_bool_t      DNBWatchpointSet                (nub_process_t pid, nub_addr_t addr, nub_size_t size, uint32_t watch_flags, nub_bool_t hardware) DNB_EXPORT;
+nub_bool_t      DNBWatchpointClear              (nub_process_t pid, nub_addr_t addr) DNB_EXPORT;
 uint32_t        DNBWatchpointGetNumSupportedHWP (nub_process_t pid) DNB_EXPORT; 
 
 const DNBRegisterSetInfo *

Modified: lldb/trunk/tools/debugserver/source/DNBBreakpoint.cpp
URL: http://llvm.org/viewvc/llvm-project/lldb/trunk/tools/debugserver/source/DNBBreakpoint.cpp?rev=183820&r1=183819&r2=183820&view=diff
==============================================================================
--- lldb/trunk/tools/debugserver/source/DNBBreakpoint.cpp (original)
+++ lldb/trunk/tools/debugserver/source/DNBBreakpoint.cpp Tue Jun 11 19:46:38 2013
@@ -12,16 +12,17 @@
 //===----------------------------------------------------------------------===//
 
 #include "DNBBreakpoint.h"
+#include "MachProcess.h"
+#include <assert.h>
 #include <algorithm>
 #include <inttypes.h>
 #include "DNBLog.h"
 
 
 #pragma mark -- DNBBreakpoint
-DNBBreakpoint::DNBBreakpoint(nub_addr_t addr, nub_size_t byte_size, nub_thread_t tid, bool hardware) :
-    m_breakID(GetNextID()),
-    m_tid(tid),
-    m_byte_size(byte_size),
+DNBBreakpoint::DNBBreakpoint(nub_addr_t addr, nub_size_t byte_size, bool hardware) :
+    m_retain_count (1),
+    m_byte_size (byte_size),
     m_opcode(),
     m_addr(addr),
     m_enabled(0),
@@ -29,11 +30,7 @@ DNBBreakpoint::DNBBreakpoint(nub_addr_t
     m_is_watchpoint(0),
     m_watch_read(0),
     m_watch_write(0),
-    m_hw_index(INVALID_NUB_HW_INDEX),
-    m_hit_count(0),
-    m_ignore_count(0),
-    m_callback(NULL),
-    m_callback_baton(NULL)
+    m_hw_index(INVALID_NUB_HW_INDEX)
 {
 }
 
@@ -41,71 +38,27 @@ DNBBreakpoint::~DNBBreakpoint()
 {
 }
 
-nub_break_t
-DNBBreakpoint::GetNextID()
-{
-    static uint32_t g_nextBreakID = 0;
-    return ++g_nextBreakID;
-}
-
-void
-DNBBreakpoint::SetCallback(DNBCallbackBreakpointHit callback, void *callback_baton)
-{
-    m_callback = callback;
-    m_callback_baton = callback_baton;
-}
-
-
-// RETURNS - true if we should stop at this breakpoint, false if we
-// should continue.
-
-bool
-DNBBreakpoint::BreakpointHit(nub_process_t pid, nub_thread_t tid)
-{
-    m_hit_count++;
-
-    if (m_hit_count > m_ignore_count)
-    {
-        if (m_callback)
-            return m_callback(pid, tid, GetID(), m_callback_baton);
-        return true;
-    }
-    return false;
-}
-
 void
 DNBBreakpoint::Dump() const
 {
     if (IsBreakpoint())
     {
-        DNBLog ("DNBBreakpoint %u: tid = %8.8" PRIx64 "  addr = 0x%llx  state = %s  type = %s breakpoint  hw_index = %i  hit_count = %-4u  ignore_count = %-4u  callback = %p baton = %p",
-                m_breakID,
-                m_tid,
+        DNBLog ("DNBBreakpoint addr = 0x%llx  state = %s  type = %s breakpoint  hw_index = %i",
                 (uint64_t)m_addr,
                 m_enabled ? "enabled " : "disabled",
                 IsHardware() ? "hardware" : "software",
-                GetHardwareIndex(),
-                GetHitCount(),
-                GetIgnoreCount(),
-                m_callback,
-                m_callback_baton);
+                GetHardwareIndex());
     }
     else
     {
-        DNBLog ("DNBBreakpoint %u: tid = %8.8" PRIx64 "  addr = 0x%llx  size = %llu  state = %s  type = %s watchpoint (%s%s)  hw_index = %i  hit_count = %-4u  ignore_count = %-4u  callback = %p baton = %p",
-                m_breakID,
-                m_tid,
+        DNBLog ("DNBBreakpoint addr = 0x%llx  size = %llu  state = %s  type = %s watchpoint (%s%s)  hw_index = %i",
                 (uint64_t)m_addr,
                 (uint64_t)m_byte_size,
                 m_enabled ? "enabled " : "disabled",
                 IsHardware() ? "hardware" : "software",
                 m_watch_read ? "r" : "",
                 m_watch_write ? "w" : "",
-                GetHardwareIndex(),
-                GetHitCount(),
-                GetIgnoreCount(),
-                m_callback,
-                m_callback_baton);
+                GetHardwareIndex());
     }
 }
 
@@ -120,46 +73,18 @@ DNBBreakpointList::~DNBBreakpointList()
 }
 
 
-nub_break_t
-DNBBreakpointList::Add(const DNBBreakpoint& bp)
-{
-    m_breakpoints.push_back(bp);
-    return m_breakpoints.back().GetID();
-}
-
-bool
-DNBBreakpointList::ShouldStop(nub_process_t pid, nub_thread_t tid, nub_break_t breakID)
-{
-    DNBBreakpoint *bp = FindByID (breakID);
-    if (bp)
-    {
-        // Let the breakpoint decide if it should stop here (could not have
-        // reached it's target hit count yet, or it could have a callback
-        // that decided it shouldn't stop (shared library loads/unloads).
-        return bp->BreakpointHit(pid, tid);
-    }
-    // We should stop here since this breakpoint isn't valid anymore or it
-    // doesn't exist.
-    return true;
-}
-
-nub_break_t
-DNBBreakpointList::FindIDByAddress (nub_addr_t addr)
+DNBBreakpoint *
+DNBBreakpointList::Add(nub_addr_t addr, nub_size_t length, bool hardware)
 {
-    DNBBreakpoint *bp = FindByAddress (addr);
-    if (bp)
-    {
-        DNBLogThreadedIf(LOG_BREAKPOINTS, "DNBBreakpointList::%s ( addr = 0x%16.16llx ) => %u", __FUNCTION__, (uint64_t)addr, bp->GetID());
-        return bp->GetID();
-    }
-    DNBLogThreadedIf(LOG_BREAKPOINTS, "DNBBreakpointList::%s ( addr = 0x%16.16llx ) => NONE", __FUNCTION__, (uint64_t)addr);
-    return INVALID_NUB_BREAK_ID;
+    m_breakpoints.insert(std::make_pair(addr, DNBBreakpoint(addr, length, hardware)));
+    iterator pos = m_breakpoints.find (addr);
+    return &pos->second;
 }
 
 bool
-DNBBreakpointList::Remove (nub_break_t breakID)
+DNBBreakpointList::Remove (nub_addr_t addr)
 {
-    iterator pos = GetBreakIDIterator(breakID);    // Predicate
+    iterator pos = m_breakpoints.find(addr);
     if (pos != m_breakpoints.end())
     {
         m_breakpoints.erase(pos);
@@ -168,146 +93,133 @@ DNBBreakpointList::Remove (nub_break_t b
     return false;
 }
 
-
-class BreakpointIDMatches
-{
-public:
-    BreakpointIDMatches (nub_break_t breakID) : m_breakID(breakID) {}
-    bool operator() (const DNBBreakpoint& bp) const
-    {
-        return m_breakID == bp.GetID();
-    }
- private:
-   const nub_break_t m_breakID;
-};
-
-class BreakpointAddressMatches
-{
-public:
-    BreakpointAddressMatches (nub_addr_t addr) : m_addr(addr) {}
-    bool operator() (const DNBBreakpoint& bp) const
-    {
-        return m_addr == bp.Address();
-    }
- private:
-   const nub_addr_t m_addr;
-};
-
-DNBBreakpointList::iterator
-DNBBreakpointList::GetBreakIDIterator (nub_break_t breakID)
-{
-    return std::find_if(m_breakpoints.begin(), m_breakpoints.end(), // Search full range
-                        BreakpointIDMatches(breakID));              // Predicate
-}
-
-DNBBreakpointList::const_iterator
-DNBBreakpointList::GetBreakIDConstIterator (nub_break_t breakID) const
-{
-    return std::find_if(m_breakpoints.begin(), m_breakpoints.end(), // Search full range
-                        BreakpointIDMatches(breakID));              // Predicate
-}
-
 DNBBreakpoint *
-DNBBreakpointList::FindByID (nub_break_t breakID)
+DNBBreakpointList::FindByAddress (nub_addr_t addr)
 {
-    iterator pos = GetBreakIDIterator(breakID);
+    iterator pos = m_breakpoints.find(addr);
     if (pos != m_breakpoints.end())
-        return &(*pos);
+        return &pos->second;
 
     return NULL;
 }
 
 const DNBBreakpoint *
-DNBBreakpointList::FindByID (nub_break_t breakID) const
+DNBBreakpointList::FindByAddress (nub_addr_t addr) const
 {
-    const_iterator pos = GetBreakIDConstIterator(breakID);
+    const_iterator pos = m_breakpoints.find(addr);
     if (pos != m_breakpoints.end())
-        return &(*pos);
-
+        return &pos->second;
+    
     return NULL;
 }
 
-DNBBreakpoint *
-DNBBreakpointList::FindByAddress (nub_addr_t addr)
+// Finds the next breakpoint at an address greater than or equal to "addr"
+size_t
+DNBBreakpointList::FindBreakpointsThatOverlapRange (nub_addr_t addr,
+                                                    nub_addr_t size,
+                                                    std::vector<DNBBreakpoint *> &bps)
 {
+    bps.clear();
     iterator end = m_breakpoints.end();
-    iterator pos = std::find_if(m_breakpoints.begin(), end,             // Search full range
-                                BreakpointAddressMatches(addr));        // Predicate
-    if (pos != end)
-        return &(*pos);
-
-    return NULL;
-}
-
-const DNBBreakpoint *
-DNBBreakpointList::FindByAddress (nub_addr_t addr) const
-{
-    const_iterator end = m_breakpoints.end();
-    const_iterator pos = std::find_if(m_breakpoints.begin(), end,       // Search full range
-                                      BreakpointAddressMatches(addr));  // Predicate
+    // Find the first breakpoint with an address >= to "addr"
+    iterator pos = m_breakpoints.lower_bound(addr);
     if (pos != end)
-        return &(*pos);
-
-    return NULL;
-}
-
-bool
-DNBBreakpointList::SetCallback(nub_break_t breakID, DNBCallbackBreakpointHit callback, void *callback_baton)
-{
-    DNBBreakpoint *bp = FindByID (breakID);
-    if (bp)
     {
-        bp->SetCallback(callback, callback_baton);
-        return true;
+        if (pos != m_breakpoints.begin())
+        {
+            // Watch out for a breakpoint at an address less than "addr" that might still overlap
+            iterator prev_pos = pos;
+            --prev_pos;
+            if (prev_pos->second.IntersectsRange (addr, size, NULL, NULL, NULL))
+                bps.push_back (&pos->second);
+            
+        }
+
+        while (pos != end)
+        {
+            // When we hit a breakpoint whose start address is greater than "addr + size" we are done.
+            // Do the math in a way that doesn't risk unsigned overflow with bad input.
+            if ((pos->second.Address() - addr) >= size)
+                break;
+                
+            // Check if this breakpoint overlaps, and if it does, add it to the list
+            if (pos->second.IntersectsRange (addr, size, NULL, NULL, NULL))
+            {
+                bps.push_back (&pos->second);
+                ++pos;
+            }
+        }
     }
-    return false;
+    return bps.size();
 }
 
-
 void
 DNBBreakpointList::Dump() const
 {
     const_iterator pos;
     const_iterator end = m_breakpoints.end();
     for (pos = m_breakpoints.begin(); pos != end; ++pos)
-        (*pos).Dump();
+        pos->second.Dump();
 }
 
+void
+DNBBreakpointList::DisableAll ()
+{
+    iterator pos, end = m_breakpoints.end();
+    for (pos = m_breakpoints.begin(); pos != end; ++pos)
+        pos->second.SetEnabled(false);
+}
 
-DNBBreakpoint *
-DNBBreakpointList::GetByIndex (uint32_t i)
+
+void
+DNBBreakpointList::RemoveTrapsFromBuffer (nub_addr_t addr, nub_size_t size, void *p) const
 {
-    iterator end = m_breakpoints.end();
-    iterator pos;
-    uint32_t curr_i = 0;
-    for (pos = m_breakpoints.begin(), curr_i = 0; pos != end; ++pos, ++curr_i)
+    uint8_t *buf = (uint8_t *)p;
+    const_iterator end = m_breakpoints.end();
+    const_iterator pos = m_breakpoints.lower_bound(addr);
+    while (pos != end && (pos->first < (addr + size)))
     {
-        if (curr_i == i)
-            return &(*pos);
+        nub_addr_t intersect_addr;
+        nub_size_t intersect_size;
+        nub_size_t opcode_offset;
+        const DNBBreakpoint &bp = pos->second;
+        if (bp.IntersectsRange(addr, size, &intersect_addr, &intersect_size, &opcode_offset))
+        {
+            assert(addr <= intersect_addr && intersect_addr < addr + size);
+            assert(addr < intersect_addr + intersect_size && intersect_addr + intersect_size <= addr + size);
+            assert(opcode_offset + intersect_size <= bp.ByteSize());
+            nub_size_t buf_offset = intersect_addr - addr;
+            ::memcpy(buf + buf_offset, bp.SavedOpcodeBytes() + opcode_offset, intersect_size);
+        }
+        ++pos;
     }
-    return NULL;
 }
 
 void
-DNBBreakpointList::DisableAll ()
+DNBBreakpointList::DisableAllBreakpoints(MachProcess *process)
 {
     iterator pos, end = m_breakpoints.end();
     for (pos = m_breakpoints.begin(); pos != end; ++pos)
-        (*pos).SetEnabled(false);
+        process->DisableBreakpoint(pos->second.Address(), false);    
 }
 
+void
+DNBBreakpointList::DisableAllWatchpoints(MachProcess *process)
+{
+    iterator pos, end = m_breakpoints.end();
+    for (pos = m_breakpoints.begin(); pos != end; ++pos)
+        process->DisableWatchpoint(pos->second.Address(), false);
+}
 
-const DNBBreakpoint *
-DNBBreakpointList::GetByIndex (uint32_t i) const
+void
+DNBBreakpointList::RemoveDisabled()
 {
-    const_iterator end = m_breakpoints.end();
-    const_iterator pos;
-    uint32_t curr_i = 0;
-    for (pos = m_breakpoints.begin(), curr_i = 0; pos != end; ++pos, ++curr_i)
+    iterator pos = m_breakpoints.begin();
+    while (pos != m_breakpoints.end())
     {
-        if (curr_i == i)
-            return &(*pos);
+        if (!pos->second.IsEnabled())
+            pos = m_breakpoints.erase(pos);
+        else
+            ++pos;
     }
-    return NULL;
 }
-

Modified: lldb/trunk/tools/debugserver/source/DNBBreakpoint.h
URL: http://llvm.org/viewvc/llvm-project/lldb/trunk/tools/debugserver/source/DNBBreakpoint.h?rev=183820&r1=183819&r2=183820&view=diff
==============================================================================
--- lldb/trunk/tools/debugserver/source/DNBBreakpoint.h (original)
+++ lldb/trunk/tools/debugserver/source/DNBBreakpoint.h Tue Jun 11 19:46:38 2013
@@ -14,25 +14,33 @@
 #ifndef __DNBBreakpoint_h__
 #define __DNBBreakpoint_h__
 
-#include <list>
+#include <mach/mach.h>
+
+#include <map>
+#include <vector>
 
 #include "DNBDefs.h"
 
+class MachProcess;
+
 class DNBBreakpoint
 {
 public:
-    DNBBreakpoint(nub_addr_t m_addr, nub_size_t byte_size, nub_thread_t tid, bool hardware);
+    DNBBreakpoint(nub_addr_t m_addr, nub_size_t byte_size, bool hardware);
     ~DNBBreakpoint();
 
-    nub_break_t GetID() const { return m_breakID; }
     nub_size_t  ByteSize() const { return m_byte_size; }
     uint8_t *   SavedOpcodeBytes() { return &m_opcode[0]; }
     const uint8_t *
                 SavedOpcodeBytes() const { return &m_opcode[0]; }
     nub_addr_t  Address() const { return m_addr; }
-    nub_thread_t ThreadID() const { return m_tid; }
+//    nub_thread_t ThreadID() const { return m_tid; }
     bool        IsEnabled() const { return m_enabled; }
-    bool        IntersectsRange(nub_addr_t addr, nub_size_t size, nub_addr_t *intersect_addr, nub_size_t *intersect_size, nub_size_t *opcode_offset) const
+    bool        IntersectsRange(nub_addr_t addr,
+                                nub_size_t size,
+                                nub_addr_t *intersect_addr,
+                                nub_size_t *intersect_size,
+                                nub_size_t *opcode_offset) const
                 {
                     // We only use software traps for software breakpoints
                     if (IsBreakpoint() && IsEnabled() && !IsHardware())
@@ -93,19 +101,21 @@ public:
     bool        IsHardware() const { return m_hw_index != INVALID_NUB_HW_INDEX; }
     uint32_t    GetHardwareIndex() const { return m_hw_index; }
     void        SetHardwareIndex(uint32_t hw_index) { m_hw_index = hw_index; }
-//  StateType   GetState() const { return m_state; }
-//  void        SetState(StateType newState) { m_state = newState; }
-    int32_t     GetHitCount() const { return m_hit_count; }
-    int32_t     GetIgnoreCount() const { return m_ignore_count; }
-    void        SetIgnoreCount(int32_t n) { m_ignore_count = n; }
-    bool        BreakpointHit(nub_process_t pid, nub_thread_t tid);
-    void        SetCallback(DNBCallbackBreakpointHit callback, void *callback_baton);
     void        Dump() const;
+    uint32_t    Retain ()
+                {
+                    return ++m_retain_count;
+                }
+    uint32_t    Release ()
+                {
+                    if (m_retain_count == 0)
+                        return 0;
+                    return --m_retain_count;
+                }
 
 private:
-    nub_break_t m_breakID;          // The unique identifier for this breakpoint
-    nub_thread_t m_tid;             // Thread ID for the breakpoint (can be INVALID_NUB_THREAD for all threads)
-    nub_size_t  m_byte_size;        // Length in bytes of the breakpoint if set in memory
+    uint32_t    m_retain_count;     // Each breakpoint is maintained by address and is ref counted in case multiple people set a breakpoint at the same address
+    uint32_t    m_byte_size;        // Length in bytes of the breakpoint if set in memory
     uint8_t     m_opcode[8];        // Saved opcode bytes
     nub_addr_t  m_addr;             // Address of this breakpoint
     uint32_t    m_enabled:1,        // Flags for this breakpoint
@@ -114,14 +124,6 @@ private:
                 m_watch_read:1,     // 1 if we stop when the watched data is read from
                 m_watch_write:1;    // 1 if we stop when the watched data is written to
     uint32_t    m_hw_index;         // The hardware resource index for this breakpoint/watchpoint
-    int32_t     m_hit_count;        // Number of times this breakpoint has been hit
-    int32_t     m_ignore_count;     // Number of times to ignore this breakpoint
-    DNBCallbackBreakpointHit
-                m_callback;         // Callback to call when this breakpoint gets hit
-    void *      m_callback_baton;   // Callback user data to pass to callback
-
-    static nub_break_t GetNextID();
-
 };
 
 
@@ -131,28 +133,31 @@ public:
                                 DNBBreakpointList();
                                 ~DNBBreakpointList();
 
-            nub_break_t         Add (const DNBBreakpoint& bp);
-            nub_break_t         FindIDByAddress (nub_addr_t addr);
-            bool                ShouldStop (nub_process_t pid, nub_thread_t tid, nub_break_t breakID);
-            bool                Remove (nub_break_t breakID);
-            bool                SetCallback (nub_break_t breakID, DNBCallbackBreakpointHit callback, void *callback_baton);
+            DNBBreakpoint *     Add (nub_addr_t addr, nub_size_t length, bool hardware);
+            bool                Remove (nub_addr_t addr);
             DNBBreakpoint *     FindByAddress (nub_addr_t addr);
     const   DNBBreakpoint *     FindByAddress (nub_addr_t addr) const;
-            DNBBreakpoint *     FindByID (nub_break_t breakID);
-    const   DNBBreakpoint *     FindByID (nub_break_t breakID) const;
+
+            size_t              FindBreakpointsThatOverlapRange (nub_addr_t addr,
+                                                                 nub_addr_t size,
+                                                                 std::vector<DNBBreakpoint *> &bps);
+
             void                Dump () const;
 
             size_t              Size() const { return m_breakpoints.size(); }
-            DNBBreakpoint *     GetByIndex (uint32_t i);
-    const   DNBBreakpoint *     GetByIndex (uint32_t i) const;
             void                DisableAll ();
 
+            void                RemoveTrapsFromBuffer (nub_addr_t addr,
+                                                       nub_size_t size,
+                                                       void *buf) const;
+
+            void                DisableAllBreakpoints (MachProcess *process);
+            void                DisableAllWatchpoints(MachProcess *process);
+            void                RemoveDisabled ();
 protected:
-    typedef std::list<DNBBreakpoint>    collection;
+    typedef std::map<nub_addr_t, DNBBreakpoint> collection;
     typedef collection::iterator        iterator;
     typedef collection::const_iterator  const_iterator;
-            iterator                    GetBreakIDIterator(nub_break_t breakID);
-            const_iterator              GetBreakIDConstIterator(nub_break_t breakID) const;
             collection                  m_breakpoints;
 };
 

Modified: lldb/trunk/tools/debugserver/source/DNBDefs.h
URL: http://llvm.org/viewvc/llvm-project/lldb/trunk/tools/debugserver/source/DNBDefs.h?rev=183820&r1=183819&r2=183820&view=diff
==============================================================================
--- lldb/trunk/tools/debugserver/source/DNBDefs.h (original)
+++ lldb/trunk/tools/debugserver/source/DNBDefs.h Tue Jun 11 19:46:38 2013
@@ -55,15 +55,12 @@ typedef uint64_t        nub_addr_t;
 
 typedef size_t          nub_size_t;
 typedef ssize_t         nub_ssize_t;
-typedef uint32_t        nub_break_t;
-typedef uint32_t        nub_watch_t;
 typedef uint32_t        nub_index_t;
 typedef pid_t           nub_process_t;
 typedef uint64_t        nub_thread_t;
 typedef uint32_t        nub_event_t;
 typedef uint32_t        nub_bool_t;
 
-#define INVALID_NUB_BREAK_ID    ((nub_break_t)0)
 #define INVALID_NUB_PROCESS     ((nub_process_t)0)
 #define INVALID_NUB_THREAD      ((nub_thread_t)0)
 #define INVALID_NUB_WATCH_ID    ((nub_watch_t)0)
@@ -71,9 +68,6 @@ typedef uint32_t        nub_bool_t;
 #define INVALID_NUB_REGNUM      UINT32_MAX
 #define NUB_GENERIC_ERROR       UINT32_MAX
 
-#define NUB_BREAK_ID_IS_VALID(breakID)    ((breakID) != (INVALID_NUB_BREAK_ID))
-#define NUB_WATCH_ID_IS_VALID(watchID)    ((watchID) != (INVALID_NUB_WATCH_ID))
-
 // Watchpoint types
 #define WATCH_TYPE_READ     (1u << 0)
 #define WATCH_TYPE_WRITE    (1u << 1)
@@ -361,7 +355,6 @@ enum DNBProfileDataScanType
     eProfileAll                 = 0xffffffff
 };
 
-typedef nub_bool_t (*DNBCallbackBreakpointHit)(nub_process_t pid, nub_thread_t tid, nub_break_t breakID, void *baton);
 typedef nub_addr_t (*DNBCallbackNameToAddress)(nub_process_t pid, const char *name, const char *shlib_regex, void *baton);
 typedef nub_size_t (*DNBCallbackCopyExecutableImageInfos)(nub_process_t pid, struct DNBExecutableImageInfo **image_infos, nub_bool_t only_changed, void *baton);
 typedef void (*DNBCallbackLog)(void *baton, uint32_t flags, const char *format, va_list args);

Modified: lldb/trunk/tools/debugserver/source/MacOSX/MachProcess.cpp
URL: http://llvm.org/viewvc/llvm-project/lldb/trunk/tools/debugserver/source/MacOSX/MachProcess.cpp?rev=183820&r1=183819&r2=183820&view=diff
==============================================================================
--- lldb/trunk/tools/debugserver/source/MacOSX/MachProcess.cpp (original)
+++ lldb/trunk/tools/debugserver/source/MacOSX/MachProcess.cpp Tue Jun 11 19:46:38 2013
@@ -557,29 +557,6 @@ MachProcess::Detach()
     return true;
 }
 
-nub_size_t
-MachProcess::RemoveTrapsFromBuffer (nub_addr_t addr, nub_size_t size, uint8_t *buf) const
-{
-    nub_size_t bytes_removed = 0;
-    const DNBBreakpoint *bp;
-    nub_addr_t intersect_addr;
-    nub_size_t intersect_size;
-    nub_size_t opcode_offset;
-    nub_size_t idx;
-    for (idx = 0; (bp = m_breakpoints.GetByIndex(idx)) != NULL; ++idx)
-    {
-        if (bp->IntersectsRange(addr, size, &intersect_addr, &intersect_size, &opcode_offset))
-        {
-            assert(addr <= intersect_addr && intersect_addr < addr + size);
-            assert(addr < intersect_addr + intersect_size && intersect_addr + intersect_size <= addr + size);
-            assert(opcode_offset + intersect_size <= bp->ByteSize());
-            nub_size_t buf_offset = intersect_addr - addr;
-            ::memcpy(buf + buf_offset, bp->SavedOpcodeBytes() + opcode_offset, intersect_size);
-        }
-    }
-    return bytes_removed;
-}
-
 //----------------------------------------------------------------------
 // ReadMemory from the MachProcess level will always remove any software
 // breakpoints from the memory buffer before returning. If you wish to
@@ -599,7 +576,7 @@ MachProcess::ReadMemory (nub_addr_t addr
     // Then place any opcodes that fall into this range back into the buffer
     // before we return this to callers.
     if (bytes_read > 0)
-        RemoveTrapsFromBuffer (addr, size, (uint8_t *)buf);
+        m_breakpoints.RemoveTrapsFromBuffer (addr, bytes_read, buf);
     return bytes_read;
 }
 
@@ -619,38 +596,28 @@ MachProcess::WriteMemory (nub_addr_t add
     // (enabled software breakpoints) any software traps (breakpoints) that we
     // may have placed in our tasks memory.
 
-    std::map<nub_addr_t, DNBBreakpoint *> addr_to_bp_map;
-    DNBBreakpoint *bp;
-    nub_size_t idx;
-    for (idx = 0; (bp = m_breakpoints.GetByIndex(idx)) != NULL; ++idx)
-    {
-        if (bp->IntersectsRange(addr, size, NULL, NULL, NULL))
-            addr_to_bp_map[bp->Address()] = bp;
-    }
-
-    // If we don't have any software breakpoints that are in this buffer, then
-    // we can just write memory and be done with it.
-    if (addr_to_bp_map.empty())
+    std::vector<DNBBreakpoint *> bps;
+    
+    const size_t num_bps = m_breakpoints.FindBreakpointsThatOverlapRange(addr, size, bps);
+    if (num_bps == 0)
         return m_task.WriteMemory(addr, size, buf);
 
-    // If we make it here, we have some breakpoints that overlap and we need
-    // to work around them.
-
     nub_size_t bytes_written = 0;
     nub_addr_t intersect_addr;
     nub_size_t intersect_size;
     nub_size_t opcode_offset;
     const uint8_t *ubuf = (const uint8_t *)buf;
-    std::map<nub_addr_t, DNBBreakpoint *>::iterator pos, end = addr_to_bp_map.end();
-    for (pos = addr_to_bp_map.begin(); pos != end; ++pos)
+
+    for (size_t i=0; i<num_bps; ++i)
     {
-        bp = pos->second;
+        DNBBreakpoint *bp = bps[i];
 
-        assert(bp->IntersectsRange(addr, size, &intersect_addr, &intersect_size, &opcode_offset));
+        const bool intersects = bp->IntersectsRange(addr, size, &intersect_addr, &intersect_size, &opcode_offset);
+        assert(intersects);
         assert(addr <= intersect_addr && intersect_addr < addr + size);
         assert(addr < intersect_addr + intersect_size && intersect_addr + intersect_size <= addr + size);
         assert(opcode_offset + intersect_size <= bp->ByteSize());
-
+        
         // Check for bytes before this breakpoint
         const nub_addr_t curr_addr = addr + bytes_written;
         if (intersect_addr > curr_addr)
@@ -668,17 +635,17 @@ MachProcess::WriteMemory (nub_addr_t add
                 break;
             }
         }
-
+        
         // Now write any bytes that would cover up any software breakpoints
         // directly into the breakpoint opcode buffer
         ::memcpy(bp->SavedOpcodeBytes() + opcode_offset, ubuf + bytes_written, intersect_size);
         bytes_written += intersect_size;
     }
-
+    
     // Write any remaining bytes after the last breakpoint if we have any left
     if (bytes_written < size)
         bytes_written += m_task.WriteMemory(addr + bytes_written, size - bytes_written, ubuf + bytes_written);
-
+    
     return bytes_written;
 }
 
@@ -743,110 +710,105 @@ MachProcess::PrivateResume ()
     m_task.Resume();
 }
 
-nub_break_t
-MachProcess::CreateBreakpoint(nub_addr_t addr, nub_size_t length, bool hardware, thread_t tid)
+DNBBreakpoint *
+MachProcess::CreateBreakpoint(nub_addr_t addr, nub_size_t length, bool hardware)
 {
-    DNBLogThreadedIf(LOG_BREAKPOINTS, "MachProcess::CreateBreakpoint ( addr = 0x%8.8llx, length = %llu, hardware = %i, tid = 0x%4.4x )", (uint64_t)addr, (uint64_t)length, hardware, tid);
-    if (hardware && tid == INVALID_NUB_THREAD)
-        tid = GetCurrentThread();
-
-    DNBBreakpoint bp(addr, length, tid, hardware);
-    nub_break_t breakID = m_breakpoints.Add(bp);
-    if (EnableBreakpoint(breakID))
+    DNBLogThreadedIf(LOG_BREAKPOINTS, "MachProcess::CreateBreakpoint ( addr = 0x%8.8llx, length = %llu, hardware = %i)", (uint64_t)addr, (uint64_t)length, hardware);
+
+    DNBBreakpoint *bp = m_breakpoints.FindByAddress(addr);
+    if (bp)
+        bp->Retain();
+    else
+        bp =  m_breakpoints.Add(addr, length, hardware);
+
+    if (EnableBreakpoint(addr))
     {
-        DNBLogThreadedIf(LOG_BREAKPOINTS, "MachProcess::CreateBreakpoint ( addr = 0x%8.8llx, length = %llu, tid = 0x%4.4x ) => %u", (uint64_t)addr, (uint64_t)length, tid, breakID);
-        return breakID;
+        DNBLogThreadedIf(LOG_BREAKPOINTS, "MachProcess::CreateBreakpoint ( addr = 0x%8.8llx, length = %llu) => %p", (uint64_t)addr, (uint64_t)length, bp);
+        return bp;
     }
-    else
+    else if (bp->Release() == 0)
     {
-        m_breakpoints.Remove(breakID);
+        m_breakpoints.Remove(addr);
     }
     // We failed to enable the breakpoint
-    return INVALID_NUB_BREAK_ID;
+    return NULL;
 }
 
-nub_watch_t
-MachProcess::CreateWatchpoint(nub_addr_t addr, nub_size_t length, uint32_t watch_flags, bool hardware, thread_t tid)
+DNBBreakpoint *
+MachProcess::CreateWatchpoint(nub_addr_t addr, nub_size_t length, uint32_t watch_flags, bool hardware)
 {
-    DNBLogThreadedIf(LOG_WATCHPOINTS, "MachProcess::CreateWatchpoint ( addr = 0x%8.8llx, length = %llu, flags = 0x%8.8x, hardware = %i, tid = 0x%4.4x )", (uint64_t)addr, (uint64_t)length, watch_flags, hardware, tid);
-    if (hardware && tid == INVALID_NUB_THREAD)
-        tid = GetCurrentThread();
+    DNBLogThreadedIf(LOG_WATCHPOINTS, "MachProcess::CreateWatchpoint ( addr = 0x%8.8llx, length = %llu, flags = 0x%8.8x, hardware = %i)", (uint64_t)addr, (uint64_t)length, watch_flags, hardware);
 
-    DNBBreakpoint watch(addr, length, tid, hardware);
-    watch.SetIsWatchpoint(watch_flags);
+    DNBBreakpoint *wp = m_watchpoints.FindByAddress(addr);
+    // since the Z packets only send an address, we can only have one watchpoint at
+    // an address. If there is already one, we must refuse to create another watchpoint
+    if (wp)
+        return NULL;
+    
+    wp = m_watchpoints.Add(addr, length, hardware);
+    wp->SetIsWatchpoint(watch_flags);
 
-    nub_watch_t watchID = m_watchpoints.Add(watch);
-    if (EnableWatchpoint(watchID))
+    if (EnableWatchpoint(addr))
     {
-        DNBLogThreadedIf(LOG_WATCHPOINTS, "MachProcess::CreateWatchpoint ( addr = 0x%8.8llx, length = %llu, tid = 0x%x) => %u", (uint64_t)addr, (uint64_t)length, tid, watchID);
-        return watchID;
+        DNBLogThreadedIf(LOG_WATCHPOINTS, "MachProcess::CreateWatchpoint ( addr = 0x%8.8llx, length = %llu) => %p", (uint64_t)addr, (uint64_t)length, wp);
+        return wp;
     }
     else
     {
-        DNBLogThreadedIf(LOG_WATCHPOINTS, "MachProcess::CreateWatchpoint ( addr = 0x%8.8llx, length = %llu, tid = 0x%x) => FAILED (%u)", (uint64_t)addr, (uint64_t)length, tid, watchID);
-        m_watchpoints.Remove(watchID);
+        DNBLogThreadedIf(LOG_WATCHPOINTS, "MachProcess::CreateWatchpoint ( addr = 0x%8.8llx, length = %llu) => FAILED", (uint64_t)addr, (uint64_t)length);
+        m_watchpoints.Remove(addr);
     }
     // We failed to enable the watchpoint
-    return INVALID_NUB_BREAK_ID;
+    return NULL;
 }
 
-nub_size_t
-MachProcess::DisableAllBreakpoints(bool remove)
+void
+MachProcess::DisableAllBreakpoints (bool remove)
 {
     DNBLogThreadedIf(LOG_BREAKPOINTS, "MachProcess::%s (remove = %d )", __FUNCTION__, remove);
-    DNBBreakpoint *bp;
-    nub_size_t disabled_count = 0;
-    nub_size_t idx = 0;
-    while ((bp = m_breakpoints.GetByIndex(idx)) != NULL)
-    {
-        bool success = DisableBreakpoint(bp->GetID(), remove);
-
-        if (success)
-            disabled_count++;
-        // If we failed to disable the breakpoint or we aren't removing the breakpoint
-        // increment the breakpoint index. Otherwise DisableBreakpoint will have removed
-        // the breakpoint at this index and we don't need to change it.
-        if ((success == false) || (remove == false))
-            idx++;
-    }
-    return disabled_count;
+    
+    m_breakpoints.DisableAllBreakpoints (this);
+    
+    if (remove)
+        m_breakpoints.RemoveDisabled();
 }
 
-nub_size_t
+void
 MachProcess::DisableAllWatchpoints(bool remove)
 {
     DNBLogThreadedIf(LOG_WATCHPOINTS, "MachProcess::%s (remove = %d )", __FUNCTION__, remove);
-    DNBBreakpoint *wp;
-    nub_size_t disabled_count = 0;
-    nub_size_t idx = 0;
-    while ((wp = m_watchpoints.GetByIndex(idx)) != NULL)
-    {
-        bool success = DisableWatchpoint(wp->GetID(), remove);
-
-        if (success)
-            disabled_count++;
-        // If we failed to disable the watchpoint or we aren't removing the watchpoint
-        // increment the watchpoint index. Otherwise DisableWatchpoint will have removed
-        // the watchpoint at this index and we don't need to change it.
-        if ((success == false) || (remove == false))
-            idx++;
-    }
-    return disabled_count;
+    
+    m_watchpoints.DisableAllWatchpoints(this);
+    
+    if (remove)
+        m_watchpoints.RemoveDisabled();
 }
 
 bool
-MachProcess::DisableBreakpoint(nub_break_t breakID, bool remove)
+MachProcess::DisableBreakpoint(nub_addr_t addr, bool remove)
 {
-    DNBBreakpoint *bp = m_breakpoints.FindByID (breakID);
+    DNBBreakpoint *bp = m_breakpoints.FindByAddress(addr);
     if (bp)
     {
         // After "exec" we might end up with a bunch of breakpoints that were disabled
         // manually, just ignore them
         if (!bp->IsEnabled())
+        {
+            // Breakpoint might have been disabled by an exec
+            if (remove && bp->Release() == 0)
+            {
+                m_thread_list.NotifyBreakpointChanged(bp);
+                m_breakpoints.Remove(addr);
+            }
+            return true;
+        }
+
+        // We have multiple references to this breakpoint, decrement the ref count
+        // and if it isn't zero, then return true;
+        if (remove && bp->Release() > 0)
             return true;
 
-        nub_addr_t addr = bp->Address();
-        DNBLogThreadedIf(LOG_BREAKPOINTS | LOG_VERBOSE, "MachProcess::DisableBreakpoint ( breakID = %d, remove = %d ) addr = 0x%8.8llx", breakID, remove, (uint64_t)addr);
+        DNBLogThreadedIf(LOG_BREAKPOINTS | LOG_VERBOSE, "MachProcess::DisableBreakpoint ( addr = 0x%8.8llx, remove = %d )", (uint64_t)addr, remove);
 
         if (bp->IsHardware())
         {
@@ -859,9 +821,9 @@ MachProcess::DisableBreakpoint(nub_break
                 if (remove)
                 {
                     m_thread_list.NotifyBreakpointChanged(bp);
-                    m_breakpoints.Remove(breakID);
+                    m_breakpoints.Remove(addr);
                 }
-                DNBLogThreadedIf(LOG_BREAKPOINTS, "MachProcess::DisableBreakpoint ( breakID = %d, remove = %d ) addr = 0x%8.8llx (hardware) => success", breakID, remove, (uint64_t)addr);
+                DNBLogThreadedIf(LOG_BREAKPOINTS, "MachProcess::DisableBreakpoint ( addr = 0x%8.8llx, remove = %d ) (hardware) => success", (uint64_t)addr, remove);
                 return true;
             }
 
@@ -895,19 +857,19 @@ MachProcess::DisableBreakpoint(nub_break
                         }
                         else
                         {
-                            DNBLogError("MachProcess::DisableBreakpoint ( breakID = %d, remove = %d ) addr = 0x%8.8llx memory write failed when restoring original opcode", breakID, remove, (uint64_t)addr);
+                            DNBLogError("MachProcess::DisableBreakpoint ( addr = 0x%8.8llx, remove = %d ) memory write failed when restoring original opcode", addr, remove);
                         }
                     }
                     else
                     {
-                        DNBLogWarning("MachProcess::DisableBreakpoint ( breakID = %d, remove = %d ) addr = 0x%8.8llx expected a breakpoint opcode but didn't find one.", breakID, remove, (uint64_t)addr);
+                        DNBLogWarning("MachProcess::DisableBreakpoint ( addr = 0x%8.8llx, remove = %d ) expected a breakpoint opcode but didn't find one.", addr, remove);
                         // Set verify to true and so we can check if the original opcode has already been restored
                         verify = true;
                     }
                 }
                 else
                 {
-                    DNBLogThreadedIf(LOG_BREAKPOINTS | LOG_VERBOSE, "MachProcess::DisableBreakpoint ( breakID = %d, remove = %d ) addr = 0x%8.8llx is not enabled", breakID, remove, (uint64_t)addr);
+                    DNBLogThreadedIf(LOG_BREAKPOINTS | LOG_VERBOSE, "MachProcess::DisableBreakpoint ( addr = 0x%8.8llx, remove = %d ) is not enabled", addr, remove);
                     // Set verify to true and so we can check if the original opcode is there
                     verify = true;
                 }
@@ -924,20 +886,20 @@ MachProcess::DisableBreakpoint(nub_break
                             // SUCCESS
                             bp->SetEnabled(false);
                             // Let the thread list know that a breakpoint has been modified
-                            if (remove)
+                            if (remove && bp->Release() == 0)
                             {
                                 m_thread_list.NotifyBreakpointChanged(bp);
-                                m_breakpoints.Remove(breakID);
+                                m_breakpoints.Remove(addr);
                             }
-                            DNBLogThreadedIf(LOG_BREAKPOINTS, "MachProcess::DisableBreakpoint ( breakID = %d, remove = %d ) addr = 0x%8.8llx => success", breakID, remove, (uint64_t)addr);
+                            DNBLogThreadedIf(LOG_BREAKPOINTS, "MachProcess::DisableBreakpoint ( addr = 0x%8.8llx, remove = %d ) => success", (uint64_t)addr, remove);
                             return true;
                         }
                         else
                         {
                             if (break_op_found)
-                                DNBLogError("MachProcess::DisableBreakpoint ( breakID = %d, remove = %d ) addr = 0x%8.8llx: failed to restore original opcode", breakID, remove, (uint64_t)addr);
+                                DNBLogError("MachProcess::DisableBreakpoint ( addr = 0x%8.8llx, remove = %d ) : failed to restore original opcode", (uint64_t)addr, remove);
                             else
-                                DNBLogError("MachProcess::DisableBreakpoint ( breakID = %d, remove = %d ) addr = 0x%8.8llx: opcode changed", breakID, remove, (uint64_t)addr);
+                                DNBLogError("MachProcess::DisableBreakpoint ( addr = 0x%8.8llx, remove = %d ) : opcode changed", (uint64_t)addr, remove);
                         }
                     }
                     else
@@ -954,20 +916,24 @@ MachProcess::DisableBreakpoint(nub_break
     }
     else
     {
-        DNBLogError("MachProcess::DisableBreakpoint ( breakID = %d, remove = %d ) invalid breakpoint ID", breakID, remove);
+        DNBLogError("MachProcess::DisableBreakpoint ( addr = 0x%8.8llx, remove = %d ) invalid breakpoint address", (uint64_t)addr, remove);
     }
     return false;
 }
 
 bool
-MachProcess::DisableWatchpoint(nub_watch_t watchID, bool remove)
+MachProcess::DisableWatchpoint(nub_addr_t addr, bool remove)
 {
-    DNBLogThreadedIf(LOG_WATCHPOINTS, "MachProcess::%s(watchID = %d, remove = %d)", __FUNCTION__, watchID, remove);
-    DNBBreakpoint *wp = m_watchpoints.FindByID (watchID);
+    DNBLogThreadedIf(LOG_WATCHPOINTS, "MachProcess::%s(addr = 0x%8.8llx, remove = %d)", __FUNCTION__, (uint64_t)addr, remove);
+    DNBBreakpoint *wp = m_watchpoints.FindByAddress(addr);
     if (wp)
     {
+        // If we have multiple references to a watchpoint, removing the watchpoint shouldn't clear it
+        if (remove && wp->Release() > 0)
+            return true;
+
         nub_addr_t addr = wp->Address();
-        DNBLogThreadedIf(LOG_WATCHPOINTS, "MachProcess::DisableWatchpoint ( watchID = %d, remove = %d ) addr = 0x%8.8llx", watchID, remove, (uint64_t)addr);
+        DNBLogThreadedIf(LOG_WATCHPOINTS, "MachProcess::DisableWatchpoint ( addr = 0x%8.8llx, remove = %d )", (uint64_t)addr, remove);
 
         if (wp->IsHardware())
         {
@@ -977,8 +943,8 @@ MachProcess::DisableWatchpoint(nub_watch
             {
                 wp->SetEnabled(false);
                 if (remove)
-                    m_watchpoints.Remove(watchID);
-                DNBLogThreadedIf(LOG_WATCHPOINTS, "MachProcess::Disablewatchpoint ( watchID = %d, remove = %d ) addr = 0x%8.8llx (hardware) => success", watchID, remove, (uint64_t)addr);
+                    m_watchpoints.Remove(addr);
+                DNBLogThreadedIf(LOG_WATCHPOINTS, "MachProcess::Disablewatchpoint ( addr = 0x%8.8llx, remove = %d ) (hardware) => success", (uint64_t)addr, remove);
                 return true;
             }
         }
@@ -987,50 +953,12 @@ MachProcess::DisableWatchpoint(nub_watch
     }
     else
     {
-        DNBLogError("MachProcess::DisableWatchpoint ( watchID = %d, remove = %d ) invalid watchpoint ID", watchID, remove);
+        DNBLogError("MachProcess::DisableWatchpoint ( addr = 0x%8.8llx, remove = %d ) invalid watchpoint ID", (uint64_t)addr, remove);
     }
     return false;
 }
 
 
-void
-MachProcess::DumpBreakpoint(nub_break_t breakID) const
-{
-    DNBLogThreaded("MachProcess::DumpBreakpoint(breakID = %d)", breakID);
-
-    if (NUB_BREAK_ID_IS_VALID(breakID))
-    {
-        const DNBBreakpoint *bp = m_breakpoints.FindByID(breakID);
-        if (bp)
-            bp->Dump();
-        else
-            DNBLog("MachProcess::DumpBreakpoint(breakID = %d): invalid breakID", breakID);
-    }
-    else
-    {
-        m_breakpoints.Dump();
-    }
-}
-
-void
-MachProcess::DumpWatchpoint(nub_watch_t watchID) const
-{
-    DNBLogThreaded("MachProcess::DumpWatchpoint(watchID = %d)", watchID);
-
-    if (NUB_BREAK_ID_IS_VALID(watchID))
-    {
-        const DNBBreakpoint *wp = m_watchpoints.FindByID(watchID);
-        if (wp)
-            wp->Dump();
-        else
-            DNBLog("MachProcess::DumpWatchpoint(watchID = %d): invalid watchID", watchID);
-    }
-    else
-    {
-        m_watchpoints.Dump();
-    }
-}
-
 uint32_t
 MachProcess::GetNumSupportedHardwareWatchpoints () const
 {
@@ -1038,16 +966,15 @@ MachProcess::GetNumSupportedHardwareWatc
 }
 
 bool
-MachProcess::EnableBreakpoint(nub_break_t breakID)
+MachProcess::EnableBreakpoint(nub_addr_t addr)
 {
-    DNBLogThreadedIf(LOG_BREAKPOINTS, "MachProcess::EnableBreakpoint ( breakID = %d )", breakID);
-    DNBBreakpoint *bp = m_breakpoints.FindByID (breakID);
+    DNBLogThreadedIf(LOG_BREAKPOINTS, "MachProcess::EnableBreakpoint ( addr = 0x%8.8llx )", (uint64_t)addr);
+    DNBBreakpoint *bp = m_breakpoints.FindByAddress(addr);
     if (bp)
     {
-        nub_addr_t addr = bp->Address();
         if (bp->IsEnabled())
         {
-            DNBLogWarning("MachProcess::EnableBreakpoint ( breakID = %d ) addr = 0x%8.8llx: breakpoint already enabled.", breakID, (uint64_t)addr);
+            DNBLogWarning("MachProcess::EnableBreakpoint ( addr = 0x%8.8llx ): breakpoint already enabled.", (uint64_t)addr);
             return true;
         }
         else
@@ -1081,32 +1008,32 @@ MachProcess::EnableBreakpoint(nub_break_
                                 bp->SetEnabled(true);
                                 // Let the thread list know that a breakpoint has been modified
                                 m_thread_list.NotifyBreakpointChanged(bp);
-                                DNBLogThreadedIf(LOG_BREAKPOINTS, "MachProcess::EnableBreakpoint ( breakID = %d ) addr = 0x%8.8llx: SUCCESS.", breakID, (uint64_t)addr);
+                                DNBLogThreadedIf(LOG_BREAKPOINTS, "MachProcess::EnableBreakpoint ( addr = 0x%8.8llx ) : SUCCESS.", (uint64_t)addr);
                                 return true;
                             }
                             else
                             {
-                                DNBLogError("MachProcess::EnableBreakpoint ( breakID = %d ) addr = 0x%8.8llx: breakpoint opcode verification failed.", breakID, (uint64_t)addr);
+                                DNBLogError("MachProcess::EnableBreakpoint ( addr = 0x%8.8llx ): breakpoint opcode verification failed.", (uint64_t)addr);
                             }
                         }
                         else
                         {
-                            DNBLogError("MachProcess::EnableBreakpoint ( breakID = %d ) addr = 0x%8.8llx: unable to read memory to verify breakpoint opcode.", breakID, (uint64_t)addr);
+                            DNBLogError("MachProcess::EnableBreakpoint ( addr = 0x%8.8llx ): unable to read memory to verify breakpoint opcode.", (uint64_t)addr);
                         }
                     }
                     else
                     {
-                        DNBLogError("MachProcess::EnableBreakpoint ( breakID = %d ) addr = 0x%8.8llx: unable to write breakpoint opcode to memory.", breakID, (uint64_t)addr);
+                        DNBLogError("MachProcess::EnableBreakpoint ( addr = 0x%8.8llx ): unable to write breakpoint opcode to memory.", (uint64_t)addr);
                     }
                 }
                 else
                 {
-                    DNBLogError("MachProcess::EnableBreakpoint ( breakID = %d ) addr = 0x%8.8llx: unable to read memory at breakpoint address.", breakID, (uint64_t)addr);
+                    DNBLogError("MachProcess::EnableBreakpoint ( addr = 0x%8.8llx ): unable to read memory at breakpoint address.", (uint64_t)addr);
                 }
             }
             else
             {
-                DNBLogError("MachProcess::EnableBreakpoint ( breakID = %d ) no software breakpoint opcode for current architecture.", breakID);
+                DNBLogError("MachProcess::EnableBreakpoint ( addr = 0x%8.8llx ) no software breakpoint opcode for current architecture.", (uint64_t)addr);
             }
         }
     }
@@ -1114,16 +1041,16 @@ MachProcess::EnableBreakpoint(nub_break_
 }
 
 bool
-MachProcess::EnableWatchpoint(nub_watch_t watchID)
+MachProcess::EnableWatchpoint(nub_addr_t addr)
 {
-    DNBLogThreadedIf(LOG_WATCHPOINTS, "MachProcess::EnableWatchpoint(watchID = %d)", watchID);
-    DNBBreakpoint *wp = m_watchpoints.FindByID (watchID);
+    DNBLogThreadedIf(LOG_WATCHPOINTS, "MachProcess::EnableWatchpoint(addr = 0x%8.8llx)", (uint64_t)addr);
+    DNBBreakpoint *wp = m_watchpoints.FindByAddress(addr);
     if (wp)
     {
         nub_addr_t addr = wp->Address();
         if (wp->IsEnabled())
         {
-            DNBLogWarning("MachProcess::EnableWatchpoint(watchID = %d) addr = 0x%8.8llx: watchpoint already enabled.", watchID, (uint64_t)addr);
+            DNBLogWarning("MachProcess::EnableWatchpoint(addr = 0x%8.8llx): watchpoint already enabled.", (uint64_t)addr);
             return true;
         }
         else

Modified: lldb/trunk/tools/debugserver/source/MacOSX/MachProcess.h
URL: http://llvm.org/viewvc/llvm-project/lldb/trunk/tools/debugserver/source/MacOSX/MachProcess.h?rev=183820&r1=183819&r2=183820&view=diff
==============================================================================
--- lldb/trunk/tools/debugserver/source/MacOSX/MachProcess.h (original)
+++ lldb/trunk/tools/debugserver/source/MacOSX/MachProcess.h Tue Jun 11 19:46:38 2013
@@ -114,22 +114,20 @@ public:
     //----------------------------------------------------------------------
     // Breakpoint functions
     //----------------------------------------------------------------------
-    nub_break_t             CreateBreakpoint (nub_addr_t addr, nub_size_t length, bool hardware, thread_t thread);
-    bool                    DisableBreakpoint (nub_break_t breakID, bool remove);
-    nub_size_t              DisableAllBreakpoints (bool remove);
-    bool                    EnableBreakpoint (nub_break_t breakID);
-    void                    DumpBreakpoint(nub_break_t breakID) const;
+    DNBBreakpoint *         CreateBreakpoint (nub_addr_t addr, nub_size_t length, bool hardware);
+    bool                    DisableBreakpoint (nub_addr_t addr, bool remove);
+    void                    DisableAllBreakpoints (bool remove);
+    bool                    EnableBreakpoint (nub_addr_t addr);
     DNBBreakpointList&      Breakpoints() { return m_breakpoints; }
     const DNBBreakpointList& Breakpoints() const { return m_breakpoints; }
 
     //----------------------------------------------------------------------
     // Watchpoint functions
     //----------------------------------------------------------------------
-    nub_watch_t             CreateWatchpoint (nub_addr_t addr, nub_size_t length, uint32_t watch_type, bool hardware, thread_t thread);
-    bool                    DisableWatchpoint (nub_watch_t watchID, bool remove);
-    nub_size_t              DisableAllWatchpoints (bool remove);
-    bool                    EnableWatchpoint (nub_watch_t watchID);
-    void                    DumpWatchpoint(nub_watch_t watchID) const;
+    DNBBreakpoint *         CreateWatchpoint (nub_addr_t addr, nub_size_t length, uint32_t watch_type, bool hardware);
+    bool                    DisableWatchpoint (nub_addr_t addr, bool remove);
+    void                    DisableAllWatchpoints (bool remove);
+    bool                    EnableWatchpoint (nub_addr_t addr);
     uint32_t                GetNumSupportedHardwareWatchpoints () const;
     DNBBreakpointList&      Watchpoints() { return m_watchpoints; }
     const DNBBreakpointList& Watchpoints() const { return m_watchpoints; }
@@ -263,7 +261,6 @@ private:
     void                    Clear ();
     void                    ReplyToAllExceptions ();
     void                    PrivateResume ();
-    nub_size_t              RemoveTrapsFromBuffer (nub_addr_t addr, nub_size_t size, uint8_t *buf) const;
 
     uint32_t                Flags () const { return m_flags; }
     nub_state_t             DoSIGSTOP (bool clear_bps_and_wps, bool allow_running, uint32_t *thread_idx_ptr);

Modified: lldb/trunk/tools/debugserver/source/MacOSX/MachThread.cpp
URL: http://llvm.org/viewvc/llvm-project/lldb/trunk/tools/debugserver/source/MacOSX/MachThread.cpp?rev=183820&r1=183819&r2=183820&view=diff
==============================================================================
--- lldb/trunk/tools/debugserver/source/MacOSX/MachThread.cpp (original)
+++ lldb/trunk/tools/debugserver/source/MacOSX/MachThread.cpp Tue Jun 11 19:46:38 2013
@@ -31,7 +31,6 @@ MachThread::MachThread (MachProcess *pro
     m_seq_id (GetSequenceID()),
     m_state (eStateUnloaded),
     m_state_mutex (PTHREAD_MUTEX_RECURSIVE),
-    m_break_id (INVALID_NUB_BREAK_ID),
     m_suspend_count (0),
     m_stop_exception (),
     m_arch_ap (DNBArchProtocol::Create (this)),
@@ -361,13 +360,12 @@ MachThread::Dump(uint32_t index)
     default:                        thread_run_state = "???"; break;
     }
 
-    DNBLogThreaded("[%3u] #%3u tid: 0x%8.8" PRIx64 ", pc: 0x%16.16" PRIx64 ", sp: 0x%16.16" PRIx64 ", breakID: %3d, user: %d.%6.6d, system: %d.%6.6d, cpu: %2d, policy: %2d, run_state: %2d (%s), flags: %2d, suspend_count: %2d (current %2d), sleep_time: %d",
+    DNBLogThreaded("[%3u] #%3u tid: 0x%8.8" PRIx64 ", pc: 0x%16.16" PRIx64 ", sp: 0x%16.16" PRIx64 ", user: %d.%6.6d, system: %d.%6.6d, cpu: %2d, policy: %2d, run_state: %2d (%s), flags: %2d, suspend_count: %2d (current %2d), sleep_time: %d",
         index,
         m_seq_id,
         m_unique_id,
         GetPC(INVALID_NUB_ADDRESS),
         GetSP(INVALID_NUB_ADDRESS),
-        m_break_id,
         m_basic_info.user_time.seconds,      m_basic_info.user_time.microseconds,
         m_basic_info.system_time.seconds,    m_basic_info.system_time.microseconds,
         m_basic_info.cpu_usage,
@@ -406,35 +404,23 @@ MachThread::ThreadWillResume(const DNBTh
     m_stop_exception.Clear();
 }
 
-nub_break_t
+DNBBreakpoint *
 MachThread::CurrentBreakpoint()
 {
-    return m_process->Breakpoints().FindIDByAddress(GetPC());
+    return m_process->Breakpoints().FindByAddress(GetPC());
 }
 
 bool
 MachThread::ShouldStop(bool &step_more)
 {
     // See if this thread is at a breakpoint?
-    nub_break_t breakID = CurrentBreakpoint();
+    DNBBreakpoint *bp = CurrentBreakpoint();
 
-    if (NUB_BREAK_ID_IS_VALID(breakID))
+    if (bp)
     {
         // This thread is sitting at a breakpoint, ask the breakpoint
         // if we should be stopping here.
-        if (Process()->Breakpoints().ShouldStop(ProcessID(), ThreadID(), breakID))
-            return true;
-        else
-        {
-            // The breakpoint said we shouldn't stop, but we may have gotten
-            // a signal or the user may have requested to stop in some other
-            // way. Stop if we have a valid exception (this thread won't if
-            // another thread was the reason this process stopped) and that
-            // exception, is NOT a breakpoint exception (a common case would
-            // be a SIGINT signal).
-            if (GetStopException().IsValid() && !GetStopException().IsBreakpoint())
-                return true;
-        }
+        return true;
     }
     else
     {

Modified: lldb/trunk/tools/debugserver/source/MacOSX/MachThread.h
URL: http://llvm.org/viewvc/llvm-project/lldb/trunk/tools/debugserver/source/MacOSX/MachThread.h?rev=183820&r1=183819&r2=183820&view=diff
==============================================================================
--- lldb/trunk/tools/debugserver/source/MacOSX/MachThread.h (original)
+++ lldb/trunk/tools/debugserver/source/MacOSX/MachThread.h Tue Jun 11 19:46:38 2013
@@ -62,7 +62,7 @@ public:
     bool            SetPC(uint64_t value);                              // Set program counter
     uint64_t        GetSP(uint64_t failValue = INVALID_NUB_ADDRESS);    // Get stack pointer
 
-    nub_break_t     CurrentBreakpoint();
+    DNBBreakpoint * CurrentBreakpoint();
     uint32_t        EnableHardwareBreakpoint (const DNBBreakpoint *breakpoint);
     uint32_t        EnableHardwareWatchpoint (const DNBBreakpoint *watchpoint);
     bool            DisableHardwareBreakpoint (const DNBBreakpoint *breakpoint);
@@ -125,7 +125,6 @@ protected:
     uint32_t                        m_seq_id;       // A Sequential ID that increments with each new thread
     nub_state_t                     m_state;        // The state of our process
     PThreadMutex                    m_state_mutex;  // Multithreaded protection for m_state
-    nub_break_t                     m_break_id;     // Breakpoint that this thread is (stopped)/was(running) at (NULL for none)
     struct thread_basic_info        m_basic_info;   // Basic information for a thread used to see if a thread is valid
     int32_t                         m_suspend_count; // The current suspend count > 0 means we have suspended m_suspendCount times,
                                                     //                           < 0 means we have resumed it m_suspendCount times.

Modified: lldb/trunk/tools/debugserver/source/MacOSX/MachThreadList.cpp
URL: http://llvm.org/viewvc/llvm-project/lldb/trunk/tools/debugserver/source/MacOSX/MachThreadList.cpp?rev=183820&r1=183819&r2=183820&view=diff
==============================================================================
--- lldb/trunk/tools/debugserver/source/MacOSX/MachThreadList.cpp (original)
+++ lldb/trunk/tools/debugserver/source/MacOSX/MachThreadList.cpp Tue Jun 11 19:46:38 2013
@@ -499,9 +499,9 @@ MachThreadList::EnableHardwareBreakpoint
 {
     if (bp != NULL)
     {
-        MachThreadSP thread_sp (GetThreadByID (bp->ThreadID()));
-        if (thread_sp)
-            return thread_sp->EnableHardwareBreakpoint(bp);
+        const uint32_t num_threads = m_threads.size();
+        for (uint32_t idx = 0; idx < num_threads; ++idx)
+            m_threads[idx]->EnableHardwareBreakpoint(bp);
     }
     return INVALID_NUB_HW_INDEX;
 }
@@ -511,9 +511,9 @@ MachThreadList::DisableHardwareBreakpoin
 {
     if (bp != NULL)
     {
-        MachThreadSP thread_sp (GetThreadByID (bp->ThreadID()));
-        if (thread_sp)
-            return thread_sp->DisableHardwareBreakpoint(bp);
+        const uint32_t num_threads = m_threads.size();
+        for (uint32_t idx = 0; idx < num_threads; ++idx)
+            m_threads[idx]->DisableHardwareBreakpoint(bp);
     }
     return false;
 }

Modified: lldb/trunk/tools/debugserver/source/MacOSX/i386/DNBArchImplI386.cpp
URL: http://llvm.org/viewvc/llvm-project/lldb/trunk/tools/debugserver/source/MacOSX/i386/DNBArchImplI386.cpp?rev=183820&r1=183819&r2=183820&view=diff
==============================================================================
--- lldb/trunk/tools/debugserver/source/MacOSX/i386/DNBArchImplI386.cpp (original)
+++ lldb/trunk/tools/debugserver/source/MacOSX/i386/DNBArchImplI386.cpp Tue Jun 11 19:46:38 2013
@@ -647,8 +647,8 @@ DNBArchImplI386::NotifyException(MachExc
                 // Check for a breakpoint at one byte prior to the current PC value
                 // since the PC will be just past the trap.
 
-                nub_break_t breakID = m_thread->Process()->Breakpoints().FindIDByAddress(pc);
-                if (NUB_BREAK_ID_IS_VALID(breakID))
+                DNBBreakpoint *bp = m_thread->Process()->Breakpoints().FindByAddress(pc);
+                if (bp)
                 {
                     // Backup the PC for i386 since the trap was taken and the PC
                     // is at the address following the single byte trap instruction.

Modified: lldb/trunk/tools/debugserver/source/MacOSX/x86_64/DNBArchImplX86_64.cpp
URL: http://llvm.org/viewvc/llvm-project/lldb/trunk/tools/debugserver/source/MacOSX/x86_64/DNBArchImplX86_64.cpp?rev=183820&r1=183819&r2=183820&view=diff
==============================================================================
--- lldb/trunk/tools/debugserver/source/MacOSX/x86_64/DNBArchImplX86_64.cpp (original)
+++ lldb/trunk/tools/debugserver/source/MacOSX/x86_64/DNBArchImplX86_64.cpp Tue Jun 11 19:46:38 2013
@@ -602,8 +602,8 @@ DNBArchImplX86_64::NotifyException(MachE
                     // Check for a breakpoint at one byte prior to the current PC value
                     // since the PC will be just past the trap.
                     
-                    nub_break_t breakID = m_thread->Process()->Breakpoints().FindIDByAddress(pc);
-                    if (NUB_BREAK_ID_IS_VALID(breakID))
+                    DNBBreakpoint *bp = m_thread->Process()->Breakpoints().FindByAddress(pc);
+                    if (bp)
                     {
                         // Backup the PC for i386 since the trap was taken and the PC
                         // is at the address following the single byte trap instruction.

Modified: lldb/trunk/tools/debugserver/source/RNBRemote.cpp
URL: http://llvm.org/viewvc/llvm-project/lldb/trunk/tools/debugserver/source/RNBRemote.cpp?rev=183820&r1=183819&r2=183820&view=diff
==============================================================================
--- lldb/trunk/tools/debugserver/source/RNBRemote.cpp (original)
+++ lldb/trunk/tools/debugserver/source/RNBRemote.cpp Tue Jun 11 19:46:38 2013
@@ -71,7 +71,6 @@ RNBRemote::RNBRemote () :
     m_rx_packets(),
     m_rx_partial_data(),
     m_rx_pthread(0),
-    m_breakpoints(),
     m_max_payload_size(DEFAULT_GDB_REMOTE_PROTOCOL_BUFSIZE - 4),
     m_extended_mode(false),
     m_noack_mode(false),
@@ -3252,32 +3251,16 @@ RNBRemote::HandlePacket_z (const char *p
         {
             case '0':   // set software breakpoint
             case '1':   // set hardware breakpoint
-            {
-                // gdb can send multiple Z packets for the same address and
-                // these calls must be ref counted.
-                bool hardware = (break_type == '1');
-
-                // Check if we currently have a breakpoint already set at this address
-                BreakpointMapIter pos = m_breakpoints.find(addr);
-                if (pos != m_breakpoints.end())
-                {
-                    // We do already have a breakpoint at this address, increment
-                    // its reference count and return OK
-                    pos->second.Retain();
-                    return SendPacket ("OK");
-                }
-                else
                 {
-                    // We do NOT already have a breakpoint at this address, So lets
-                    // create one.
-                    nub_break_t break_id = DNBBreakpointSet (pid, addr, byte_size, hardware);
-                    if (NUB_BREAK_ID_IS_VALID(break_id))
+                    // gdb can send multiple Z packets for the same address and
+                    // these calls must be ref counted.
+                    bool hardware = (break_type == '1');
+
+                    if (DNBBreakpointSet (pid, addr, byte_size, hardware))
                     {
                         // We successfully created a breakpoint, now lets full out
                         // a ref count structure with the breakID and add it to our
                         // map.
-                        Breakpoint rnbBreakpoint(break_id);
-                        m_breakpoints[addr] = rnbBreakpoint;
                         return SendPacket ("OK");
                     }
                     else
@@ -3286,43 +3269,23 @@ RNBRemote::HandlePacket_z (const char *p
                         return SendPacket ("E09");
                     }
                 }
-            }
                 break;
 
             case '2':   // set write watchpoint
             case '3':   // set read watchpoint
             case '4':   // set access watchpoint
-            {
-                bool hardware = true;
-                uint32_t watch_flags = 0;
-                if (break_type == '2')
-                    watch_flags = WATCH_TYPE_WRITE;
-                else if (break_type == '3')
-                    watch_flags = WATCH_TYPE_READ;
-                else
-                    watch_flags = WATCH_TYPE_READ | WATCH_TYPE_WRITE;
-
-                // Check if we currently have a watchpoint already set at this address
-                BreakpointMapIter pos = m_watchpoints.find(addr);
-                if (pos != m_watchpoints.end())
-                {
-                    // We do already have a watchpoint at this address, increment
-                    // its reference count and return OK
-                    pos->second.Retain();
-                    return SendPacket ("OK");
-                }
-                else
                 {
-                    // We do NOT already have a watchpoint at this address, So lets
-                    // create one.
-                    nub_watch_t watch_id = DNBWatchpointSet (pid, addr, byte_size, watch_flags, hardware);
-                    if (NUB_WATCH_ID_IS_VALID(watch_id))
+                    bool hardware = true;
+                    uint32_t watch_flags = 0;
+                    if (break_type == '2')
+                        watch_flags = WATCH_TYPE_WRITE;
+                    else if (break_type == '3')
+                        watch_flags = WATCH_TYPE_READ;
+                    else
+                        watch_flags = WATCH_TYPE_READ | WATCH_TYPE_WRITE;
+
+                    if (DNBWatchpointSet (pid, addr, byte_size, watch_flags, hardware))
                     {
-                        // We successfully created a watchpoint, now lets full out
-                        // a ref count structure with the watch_id and add it to our
-                        // map.
-                        Breakpoint rnbWatchpoint(watch_id);
-                        m_watchpoints[addr] = rnbWatchpoint;
                         return SendPacket ("OK");
                     }
                     else
@@ -3331,7 +3294,6 @@ RNBRemote::HandlePacket_z (const char *p
                         return SendPacket ("E09");
                     }
                 }
-            }
                 break;
 
             default:
@@ -3345,83 +3307,27 @@ RNBRemote::HandlePacket_z (const char *p
         {
             case '0':   // remove software breakpoint
             case '1':   // remove hardware breakpoint
-            {
-                // gdb can send multiple z packets for the same address and
-                // these calls must be ref counted.
-                BreakpointMapIter pos = m_breakpoints.find(addr);
-                if (pos != m_breakpoints.end())
-                {
-                    // We currently have a breakpoint at address ADDR. Decrement
-                    // its reference count, and it that count is now zero we
-                    // can clear the breakpoint.
-                    pos->second.Release();
-                    if (pos->second.RefCount() == 0)
-                    {
-                        if (DNBBreakpointClear (pid, pos->second.BreakID()))
-                        {
-                            m_breakpoints.erase(pos);
-                            return SendPacket ("OK");
-                        }
-                        else
-                        {
-                            return SendPacket ("E08");
-                        }
-                    }
-                    else
-                    {
-                        // We still have references to this breakpoint don't
-                        // delete it, just decrementing the reference count
-                        // is enough.
-                        return SendPacket ("OK");
-                    }
+                if (DNBBreakpointClear (pid, addr))
+                {
+                    return SendPacket ("OK");
                 }
                 else
                 {
-                    // We don't know about any breakpoints at this address
                     return SendPacket ("E08");
                 }
-            }
                 break;
 
             case '2':   // remove write watchpoint
             case '3':   // remove read watchpoint
             case '4':   // remove access watchpoint
-            {
-                // gdb can send multiple z packets for the same address and
-                // these calls must be ref counted.
-                BreakpointMapIter pos = m_watchpoints.find(addr);
-                if (pos != m_watchpoints.end())
-                {
-                    // We currently have a watchpoint at address ADDR. Decrement
-                    // its reference count, and it that count is now zero we
-                    // can clear the watchpoint.
-                    pos->second.Release();
-                    if (pos->second.RefCount() == 0)
-                    {
-                        if (DNBWatchpointClear (pid, pos->second.BreakID()))
-                        {
-                            m_watchpoints.erase(pos);
-                            return SendPacket ("OK");
-                        }
-                        else
-                        {
-                            return SendPacket ("E08");
-                        }
-                    }
-                    else
-                    {
-                        // We still have references to this watchpoint don't
-                        // delete it, just decrementing the reference count
-                        // is enough.
-                        return SendPacket ("OK");
-                    }
+                if (DNBWatchpointClear (pid, addr))
+                {
+                    return SendPacket ("OK");
                 }
                 else
                 {
-                    // We don't know about any watchpoints at this address
                     return SendPacket ("E08");
                 }
-            }
                 break;
 
             default:

Modified: lldb/trunk/tools/debugserver/source/RNBRemote.h
URL: http://llvm.org/viewvc/llvm-project/lldb/trunk/tools/debugserver/source/RNBRemote.h?rev=183820&r1=183819&r2=183820&view=diff
==============================================================================
--- lldb/trunk/tools/debugserver/source/RNBRemote.h (original)
+++ lldb/trunk/tools/debugserver/source/RNBRemote.h Tue Jun 11 19:46:38 2013
@@ -301,39 +301,6 @@ protected:
     nub_thread_t
     ExtractThreadIDFromThreadSuffix (const char *p);
 
-    // gdb can send multiple Z/z packets for the same address and
-    // these calls must be ref counted.
-    struct Breakpoint
-    {
-        Breakpoint(nub_break_t breakID) :
-            m_breakID(breakID),
-            m_refCount(1)
-        {
-        }
-
-        Breakpoint() :
-            m_breakID(INVALID_NUB_BREAK_ID),
-            m_refCount(0)
-        {
-        }
-
-        Breakpoint(const Breakpoint& rhs) :
-            m_breakID(rhs.m_breakID),
-            m_refCount(rhs.m_refCount)
-        {
-        }
-
-        nub_break_t BreakID() const { return m_breakID; }
-        uint32_t RefCount() const { return m_refCount; }
-        void Release() { if (m_refCount > 0) --m_refCount; }
-        void Retain() { ++m_refCount; }
-
-        nub_break_t m_breakID;
-        uint32_t m_refCount;
-    };
-    typedef std::map<nub_addr_t, Breakpoint> BreakpointMap;
-    typedef BreakpointMap::iterator          BreakpointMapIter;
-    typedef BreakpointMap::const_iterator    BreakpointMapConstIter;
     RNBContext      m_ctx;              // process context
     RNBSocket       m_comm;             // communication port
     std::string     m_arch;
@@ -345,8 +312,6 @@ protected:
     std::deque<std::string> m_rx_packets;
     std::string     m_rx_partial_data;  // For packets that may come in more than one batch, anything left over can be left here
     pthread_t       m_rx_pthread;
-    BreakpointMap   m_breakpoints;
-    BreakpointMap   m_watchpoints;
     uint32_t        m_max_payload_size;  // the maximum sized payload we should send to gdb
     bool            m_extended_mode;   // are we in extended mode?
     bool            m_noack_mode;      // are we in no-ack mode?





More information about the lldb-commits mailing list