summaryrefslogtreecommitdiffstats
path: root/lldb/tools/debugserver/source
diff options
context:
space:
mode:
Diffstat (limited to 'lldb/tools/debugserver/source')
-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
14 files changed, 312 insertions, 815 deletions
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