summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--lldb/include/lldb/Breakpoint/BreakpointSiteList.h51
-rw-r--r--lldb/include/lldb/Symbol/SymbolContext.h29
-rw-r--r--lldb/source/Breakpoint/BreakpointResolverName.cpp100
-rw-r--r--lldb/source/Breakpoint/BreakpointSiteList.cpp67
-rw-r--r--lldb/source/Core/Module.cpp49
-rw-r--r--lldb/source/Symbol/SymbolContext.cpp47
-rw-r--r--lldb/source/Target/Process.cpp144
-rw-r--r--lldb/tools/debugserver/source/DNB.cpp205
-rw-r--r--lldb/tools/debugserver/source/DNB.h18
-rw-r--r--lldb/tools/debugserver/source/DNBBreakpoint.cpp292
-rw-r--r--lldb/tools/debugserver/source/DNBBreakpoint.h75
-rw-r--r--lldb/tools/debugserver/source/DNBDefs.h7
-rw-r--r--lldb/tools/debugserver/source/MacOSX/MachProcess.cpp295
-rw-r--r--lldb/tools/debugserver/source/MacOSX/MachProcess.h19
-rw-r--r--lldb/tools/debugserver/source/MacOSX/MachThread.cpp26
-rw-r--r--lldb/tools/debugserver/source/MacOSX/MachThread.h3
-rw-r--r--lldb/tools/debugserver/source/MacOSX/MachThreadList.cpp12
-rw-r--r--lldb/tools/debugserver/source/MacOSX/i386/DNBArchImplI386.cpp4
-rw-r--r--lldb/tools/debugserver/source/MacOSX/x86_64/DNBArchImplX86_64.cpp4
-rw-r--r--lldb/tools/debugserver/source/RNBRemote.cpp132
-rw-r--r--lldb/tools/debugserver/source/RNBRemote.h35
21 files changed, 554 insertions, 1060 deletions
diff --git a/lldb/include/lldb/Breakpoint/BreakpointSiteList.h b/lldb/include/lldb/Breakpoint/BreakpointSiteList.h
index 76c1f52b058..0d4dafc4baa 100644
--- a/lldb/include/lldb/Breakpoint/BreakpointSiteList.h
+++ b/lldb/include/lldb/Breakpoint/BreakpointSiteList.h
@@ -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.
};
diff --git a/lldb/include/lldb/Symbol/SymbolContext.h b/lldb/include/lldb/Symbol/SymbolContext.h
index 4ba9cd90f0e..5b12adebf5f 100644
--- a/lldb/include/lldb/Symbol/SymbolContext.h
+++ b/lldb/include/lldb/Symbol/SymbolContext.h
@@ -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
diff --git a/lldb/source/Breakpoint/BreakpointResolverName.cpp b/lldb/source/Breakpoint/BreakpointResolverName.cpp
index 4557abb37a7..27f85653d64 100644
--- a/lldb/source/Breakpoint/BreakpointResolverName.cpp
+++ b/lldb/source/Breakpoint/BreakpointResolverName.cpp
@@ -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;
}
diff --git a/lldb/source/Breakpoint/BreakpointSiteList.cpp b/lldb/source/Breakpoint/BreakpointSiteList.cpp
index 22f7d4502c0..68c4af18ec5 100644
--- a/lldb/source/Breakpoint/BreakpointSiteList.cpp
+++ b/lldb/source/Breakpoint/BreakpointSiteList.cpp
@@ -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 (lldb::addr_t addr)
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_id_t break_id)
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::break_id_t break_id)
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 (lldb::break_id_t break_id) const
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::break_id_t break_id)
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::addr_t addr)
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) const
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::addr_t lower_bound, lldb::addr_t upper_bo
}
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;
-}
diff --git a/lldb/source/Core/Module.cpp b/lldb/source/Core/Module.cpp
index d8420ab8af1..205d2d9fb22 100644
--- a/lldb/source/Core/Module.cpp
+++ b/lldb/source/Core/Module.cpp
@@ -704,15 +704,50 @@ Module::FindFunctions (const RegularExpression& regex,
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;
+ }
+ }
}
}
}
diff --git a/lldb/source/Symbol/SymbolContext.cpp b/lldb/source/Symbol/SymbolContext.cpp
index b2beb912f43..ac91161f7d6 100644
--- a/lldb/source/Symbol/SymbolContext.cpp
+++ b/lldb/source/Symbol/SymbolContext.cpp
@@ -1023,6 +1023,10 @@ SymbolContextList::AppendIfUnique (const SymbolContext& sc, bool merge_symbol_in
{
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 SymbolContext& sc, bool merge_symbol_in
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()
{
diff --git a/lldb/source/Target/Process.cpp b/lldb/source/Target/Process.cpp
index 1127446be51..92107d60802 100644
--- a/lldb/source/Target/Process.cpp
+++ b/lldb/source/Target/Process.cpp
@@ -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 void *buf, size_t size, Error &error)
// (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)
+ BreakpointSiteList bp_sites_in_range;
+
+ if (m_breakpoint_site_list.FindInRange (addr, addr + size, bp_sites_in_range))
{
- 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)
+ // 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
diff --git a/lldb/tools/debugserver/source/DNB.cpp b/lldb/tools/debugserver/source/DNB.cpp
index b91452a28c1..bcbcf983ff7 100644
--- a/lldb/tools/debugserver/source/DNB.cpp
+++ b/lldb/tools/debugserver/source/DNB.cpp
@@ -901,227 +901,44 @@ DNBProcessResetEvents (nub_process_t pid, nub_event_t event_mask)
}
// 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
}
//----------------------------------------------------------------------
diff --git a/lldb/tools/debugserver/source/DNB.h b/lldb/tools/debugserver/source/DNB.h
index 54a462015b9..986cab9becb 100644
--- a/lldb/tools/debugserver/source/DNB.h
+++ b/lldb/tools/debugserver/source/DNB.h
@@ -121,24 +121,14 @@ const char * DNBThreadGetInfo (nub_process_t pid, nub_thread_t
//----------------------------------------------------------------------
// 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 *
diff --git a/lldb/tools/debugserver/source/DNBBreakpoint.cpp b/lldb/tools/debugserver/source/DNBBreakpoint.cpp
index 66706870305..246797c8dae 100644
--- a/lldb/tools/debugserver/source/DNBBreakpoint.cpp
+++ b/lldb/tools/debugserver/source/DNBBreakpoint.cpp
@@ -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 addr, nub_size_t byte_size, nub_thread_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 breakID)
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
+ // Find the first breakpoint with an address >= to "addr"
+ iterator pos = m_breakpoints.lower_bound(addr);
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
- 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;
}
-
diff --git a/lldb/tools/debugserver/source/DNBBreakpoint.h b/lldb/tools/debugserver/source/DNBBreakpoint.h
index e6a340614bb..c764dbd6cf2 100644
--- a/lldb/tools/debugserver/source/DNBBreakpoint.h
+++ b/lldb/tools/debugserver/source/DNBBreakpoint.h
@@ -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;
};
diff --git a/lldb/tools/debugserver/source/DNBDefs.h b/lldb/tools/debugserver/source/DNBDefs.h
index e4c95a90d49..78364e782dd 100644
--- a/lldb/tools/debugserver/source/DNBDefs.h
+++ b/lldb/tools/debugserver/source/DNBDefs.h
@@ -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);
diff --git a/lldb/tools/debugserver/source/MacOSX/MachProcess.cpp b/lldb/tools/debugserver/source/MacOSX/MachProcess.cpp
index 7397fe94aca..2eab3784e19 100644
--- a/lldb/tools/debugserver/source/MacOSX/MachProcess.cpp
+++ b/lldb/tools/debugserver/source/MacOSX/MachProcess.cpp
@@ -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, nub_size_t size, void *buf)
// 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 addr, nub_size_t size, const void *buf)
// (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 addr, nub_size_t size, const void *buf)
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();
+ DNBLogThreadedIf(LOG_BREAKPOINTS, "MachProcess::CreateBreakpoint ( addr = 0x%8.8llx, length = %llu, hardware = %i)", (uint64_t)addr, (uint64_t)length, hardware);
- DNBBreakpoint bp(addr, length, tid, hardware);
- nub_break_t breakID = m_breakpoints.Add(bp);
- if (EnableBreakpoint(breakID))
+ 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;
+ }
- 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);
+ // 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;
+
+ 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_t breakID, bool remove)
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_t breakID, bool remove)
}
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_t breakID, bool remove)
// 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_t breakID, bool remove)
}
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_t watchID, bool remove)
{
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_t watchID, bool remove)
}
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::GetNumSupportedHardwareWatchpoints () const
}
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_t breakID)
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_t breakID)
}
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
diff --git a/lldb/tools/debugserver/source/MacOSX/MachProcess.h b/lldb/tools/debugserver/source/MacOSX/MachProcess.h
index ee2642ee474..7a52eaa54ae 100644
--- a/lldb/tools/debugserver/source/MacOSX/MachProcess.h
+++ b/lldb/tools/debugserver/source/MacOSX/MachProcess.h
@@ -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);
diff --git a/lldb/tools/debugserver/source/MacOSX/MachThread.cpp b/lldb/tools/debugserver/source/MacOSX/MachThread.cpp
index 61f5b21af14..a32161f4eb0 100644
--- a/lldb/tools/debugserver/source/MacOSX/MachThread.cpp
+++ b/lldb/tools/debugserver/source/MacOSX/MachThread.cpp
@@ -31,7 +31,6 @@ MachThread::MachThread (MachProcess *process, uint64_t unique_thread_id, thread_
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 DNBThreadResumeAction *thread_action, bool ot
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
{
diff --git a/lldb/tools/debugserver/source/MacOSX/MachThread.h b/lldb/tools/debugserver/source/MacOSX/MachThread.h
index c6d7b312769..bf96e68bc6c 100644
--- a/lldb/tools/debugserver/source/MacOSX/MachThread.h
+++ b/lldb/tools/debugserver/source/MacOSX/MachThread.h
@@ -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.
diff --git a/lldb/tools/debugserver/source/MacOSX/MachThreadList.cpp b/lldb/tools/debugserver/source/MacOSX/MachThreadList.cpp
index 2ac171374f1..f549b4707d9 100644
--- a/lldb/tools/debugserver/source/MacOSX/MachThreadList.cpp
+++ b/lldb/tools/debugserver/source/MacOSX/MachThreadList.cpp
@@ -499,9 +499,9 @@ MachThreadList::EnableHardwareBreakpoint (const DNBBreakpoint* bp) const
{
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::DisableHardwareBreakpoint (const DNBBreakpoint* bp) const
{
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;
}
diff --git a/lldb/tools/debugserver/source/MacOSX/i386/DNBArchImplI386.cpp b/lldb/tools/debugserver/source/MacOSX/i386/DNBArchImplI386.cpp
index 1d4a98fb742..4376e80b653 100644
--- a/lldb/tools/debugserver/source/MacOSX/i386/DNBArchImplI386.cpp
+++ b/lldb/tools/debugserver/source/MacOSX/i386/DNBArchImplI386.cpp
@@ -647,8 +647,8 @@ DNBArchImplI386::NotifyException(MachException::Data& exc)
// 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.
diff --git a/lldb/tools/debugserver/source/MacOSX/x86_64/DNBArchImplX86_64.cpp b/lldb/tools/debugserver/source/MacOSX/x86_64/DNBArchImplX86_64.cpp
index 4a87aa2ce1a..aff76d881f1 100644
--- a/lldb/tools/debugserver/source/MacOSX/x86_64/DNBArchImplX86_64.cpp
+++ b/lldb/tools/debugserver/source/MacOSX/x86_64/DNBArchImplX86_64.cpp
@@ -602,8 +602,8 @@ DNBArchImplX86_64::NotifyException(MachException::Data& exc)
// 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.
diff --git a/lldb/tools/debugserver/source/RNBRemote.cpp b/lldb/tools/debugserver/source/RNBRemote.cpp
index d711a9710f4..e6b03033290 100644
--- a/lldb/tools/debugserver/source/RNBRemote.cpp
+++ b/lldb/tools/debugserver/source/RNBRemote.cpp
@@ -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())
+ if (DNBBreakpointClear (pid, addr))
{
- // 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");
- }
+ 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())
+ if (DNBWatchpointClear (pid, addr))
{
- // 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");
- }
+ return SendPacket ("OK");
}
else
{
- // We don't know about any watchpoints at this address
return SendPacket ("E08");
}
- }
break;
default:
diff --git a/lldb/tools/debugserver/source/RNBRemote.h b/lldb/tools/debugserver/source/RNBRemote.h
index b8b3b255f4f..15d725ce4cd 100644
--- a/lldb/tools/debugserver/source/RNBRemote.h
+++ b/lldb/tools/debugserver/source/RNBRemote.h
@@ -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?
OpenPOWER on IntegriCloud