1 //===-- NativeBreakpointList.h ----------------------------------*- C++ -*-===//
3 // The LLVM Compiler Infrastructure
5 // This file is distributed under the University of Illinois Open Source
6 // License. See LICENSE.TXT for details.
8 //===----------------------------------------------------------------------===//
10 #include "NativeBreakpointList.h"
12 #include "lldb/Core/Log.h"
14 #include "NativeBreakpoint.h"
17 using namespace lldb_private;
19 NativeBreakpointList::NativeBreakpointList () :
20 m_mutex (Mutex::eMutexTypeRecursive)
25 NativeBreakpointList::AddRef (lldb::addr_t addr, size_t size_hint, bool hardware, CreateBreakpointFunc create_func)
27 Log *log (GetLogIfAnyCategoriesSet (LIBLLDB_LOG_BREAKPOINTS));
29 log->Printf ("NativeBreakpointList::%s addr = 0x%" PRIx64 ", size_hint = %lu, hardware = %s", __FUNCTION__, addr, size_hint, hardware ? "true" : "false");
31 Mutex::Locker locker (m_mutex);
33 // Check if the breakpoint is already set.
34 auto iter = m_breakpoints.find (addr);
35 if (iter != m_breakpoints.end ())
37 // Yes - bump up ref count.
39 log->Printf ("NativeBreakpointList::%s addr = 0x%" PRIx64 " -- already enabled, upping ref count", __FUNCTION__, addr);
41 iter->second->AddRef ();
45 // Create a new breakpoint using the given create func.
47 log->Printf ("NativeBreakpointList::%s creating breakpoint for addr = 0x%" PRIx64 ", size_hint = %lu, hardware = %s", __FUNCTION__, addr, size_hint, hardware ? "true" : "false");
49 NativeBreakpointSP breakpoint_sp;
50 Error error = create_func (addr, size_hint, hardware, breakpoint_sp);
54 log->Printf ("NativeBreakpointList::%s creating breakpoint for addr = 0x%" PRIx64 ", size_hint = %lu, hardware = %s -- FAILED: %s", __FUNCTION__, addr, size_hint, hardware ? "true" : "false", error.AsCString ());
58 // Remember the breakpoint.
59 assert (breakpoint_sp && "NativeBreakpoint create function succeeded but returned NULL breakpoint");
60 m_breakpoints.insert (BreakpointMap::value_type (addr, breakpoint_sp));
66 NativeBreakpointList::DecRef (lldb::addr_t addr)
70 Log *log (GetLogIfAnyCategoriesSet (LIBLLDB_LOG_BREAKPOINTS));
72 log->Printf ("NativeBreakpointList::%s addr = 0x%" PRIx64, __FUNCTION__, addr);
74 Mutex::Locker locker (m_mutex);
76 // Check if the breakpoint is already set.
77 auto iter = m_breakpoints.find (addr);
78 if (iter == m_breakpoints.end ())
82 log->Printf ("NativeBreakpointList::%s addr = 0x%" PRIx64 " -- NOT FOUND", __FUNCTION__, addr);
83 error.SetErrorString ("breakpoint not found");
87 // Decrement ref count.
88 const int32_t new_ref_count = iter->second->DecRef ();
89 assert (new_ref_count >= 0 && "NativeBreakpoint ref count went negative");
91 if (new_ref_count > 0)
93 // Still references to this breakpoint. Leave it alone.
95 log->Printf ("NativeBreakpointList::%s addr = 0x%" PRIx64 " -- new breakpoint ref count %" PRIu32, __FUNCTION__, addr, new_ref_count);
99 // Breakpoint has no more references. Disable it if it's not
102 log->Printf ("NativeBreakpointList::%s addr = 0x%" PRIx64 " -- removing due to no remaining references", __FUNCTION__, addr);
104 // If it's enabled, we need to disable it.
105 if (iter->second->IsEnabled ())
108 log->Printf ("NativeBreakpointList::%s addr = 0x%" PRIx64 " -- currently enabled, now disabling", __FUNCTION__, addr);
109 error = iter->second->Disable ();
113 log->Printf ("NativeBreakpointList::%s addr = 0x%" PRIx64 " -- removal FAILED: %s", __FUNCTION__, addr, error.AsCString ());
114 // Continue since we still want to take it out of the breakpoint list.
120 log->Printf ("NativeBreakpointList::%s addr = 0x%" PRIx64 " -- already disabled, nothing to do", __FUNCTION__, addr);
123 // Take the breakpoint out of the list.
125 log->Printf ("NativeBreakpointList::%s addr = 0x%" PRIx64 " -- removed from breakpoint map", __FUNCTION__, addr);
127 m_breakpoints.erase (iter);
132 NativeBreakpointList::EnableBreakpoint (lldb::addr_t addr)
134 Log *log (GetLogIfAnyCategoriesSet (LIBLLDB_LOG_BREAKPOINTS));
136 log->Printf ("NativeBreakpointList::%s addr = 0x%" PRIx64, __FUNCTION__, addr);
138 Mutex::Locker locker (m_mutex);
140 // Ensure we have said breakpoint.
141 auto iter = m_breakpoints.find (addr);
142 if (iter == m_breakpoints.end ())
146 log->Printf ("NativeBreakpointList::%s addr = 0x%" PRIx64 " -- NOT FOUND", __FUNCTION__, addr);
147 return Error ("breakpoint not found");
151 return iter->second->Enable ();
155 NativeBreakpointList::DisableBreakpoint (lldb::addr_t addr)
157 Log *log (GetLogIfAnyCategoriesSet (LIBLLDB_LOG_BREAKPOINTS));
159 log->Printf ("NativeBreakpointList::%s addr = 0x%" PRIx64, __FUNCTION__, addr);
161 Mutex::Locker locker (m_mutex);
163 // Ensure we have said breakpoint.
164 auto iter = m_breakpoints.find (addr);
165 if (iter == m_breakpoints.end ())
169 log->Printf ("NativeBreakpointList::%s addr = 0x%" PRIx64 " -- NOT FOUND", __FUNCTION__, addr);
170 return Error ("breakpoint not found");
174 return iter->second->Disable ();
178 NativeBreakpointList::GetBreakpoint (lldb::addr_t addr, NativeBreakpointSP &breakpoint_sp)
180 Log *log (GetLogIfAnyCategoriesSet (LIBLLDB_LOG_BREAKPOINTS));
182 log->Printf ("NativeBreakpointList::%s addr = 0x%" PRIx64, __FUNCTION__, addr);
184 Mutex::Locker locker (m_mutex);
186 // Ensure we have said breakpoint.
187 auto iter = m_breakpoints.find (addr);
188 if (iter == m_breakpoints.end ())
191 breakpoint_sp.reset ();
192 return Error ("breakpoint not found");
196 breakpoint_sp = iter->second;