diff options
Diffstat (limited to 'lldb/tools/debugserver/source')
| -rw-r--r-- | lldb/tools/debugserver/source/DNB.cpp | 205 | ||||
| -rw-r--r-- | lldb/tools/debugserver/source/DNB.h | 18 | ||||
| -rw-r--r-- | lldb/tools/debugserver/source/DNBBreakpoint.cpp | 292 | ||||
| -rw-r--r-- | lldb/tools/debugserver/source/DNBBreakpoint.h | 75 | ||||
| -rw-r--r-- | lldb/tools/debugserver/source/DNBDefs.h | 7 | ||||
| -rw-r--r-- | lldb/tools/debugserver/source/MacOSX/MachProcess.cpp | 295 | ||||
| -rw-r--r-- | lldb/tools/debugserver/source/MacOSX/MachProcess.h | 19 | ||||
| -rw-r--r-- | lldb/tools/debugserver/source/MacOSX/MachThread.cpp | 26 | ||||
| -rw-r--r-- | lldb/tools/debugserver/source/MacOSX/MachThread.h | 3 | ||||
| -rw-r--r-- | lldb/tools/debugserver/source/MacOSX/MachThreadList.cpp | 12 | ||||
| -rw-r--r-- | lldb/tools/debugserver/source/MacOSX/i386/DNBArchImplI386.cpp | 4 | ||||
| -rw-r--r-- | lldb/tools/debugserver/source/MacOSX/x86_64/DNBArchImplX86_64.cpp | 4 | ||||
| -rw-r--r-- | lldb/tools/debugserver/source/RNBRemote.cpp | 132 | ||||
| -rw-r--r-- | lldb/tools/debugserver/source/RNBRemote.h | 35 |
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? |

