Added needed breakpoint functionality to the public API that includes:

SBTarget:
    - get breakpoint count
    - get breakpoint at index
  SBBreakpoint:
    - Extract data from breakpoint events

llvm-svn: 109289
This commit is contained in:
Greg Clayton 2010-07-23 23:33:17 +00:00
parent 893483000d
commit 9fed0d85b2
15 changed files with 208 additions and 92 deletions

View File

@ -68,6 +68,9 @@ public:
bool
IsEnabled ();
uint32_t
GetHitCount () const;
void
SetIgnoreCount (uint32_t count);
@ -110,7 +113,14 @@ public:
void
GetDescription (FILE *, const char *description_level, bool describe_locations = false);
static lldb::BreakpointEventType
GetBreakpointEventTypeFromEvent (const lldb::SBEvent& event);
static lldb::SBBreakpoint
GetBreakpointFromEvent (const lldb::SBEvent& event);
static lldb::SBBreakpointLocation
GetBreakpointLocationAtIndexFromEvent (const lldb::SBEvent& event, uint32_t loc_idx);
private:
friend class SBBreakpointLocation;

View File

@ -59,6 +59,7 @@ public:
protected:
friend class SBListener;
friend class SBBroadcaster;
friend class SBBreakpoint;
friend class SBDebugger;
friend class SBProcess;

View File

@ -97,12 +97,15 @@ public:
lldb::SBBreakpoint
BreakpointCreateByAddress (addr_t address);
uint32_t
GetNumBreakpoints () const;
lldb::SBBreakpoint
GetBreakpointAtIndex (uint32_t idx) const;
bool
BreakpointDelete (break_id_t break_id);
void
ListAllBreakpoints ();
lldb::SBBreakpoint
FindBreakpointByID (break_id_t break_id);

View File

@ -104,25 +104,14 @@ public:
virtual const ConstString &
GetFlavor () const;
enum EventSubType
{
eBreakpointInvalidType = (1 << 0),
eBreakpointAdded = (1 << 1),
eBreakpointRemoved = (1 << 2),
eBreakpointLocationsAdded = (1 << 3),
eBreakpointLocationsRemoved = (1 << 4),
eBreakpointLocationResolved = (1 << 5)
};
BreakpointEventData (EventSubType sub_type,
BreakpointEventData (lldb::BreakpointEventType sub_type,
lldb::BreakpointSP &new_breakpoint_sp);
virtual
~BreakpointEventData();
EventSubType
GetSubType () const;
lldb::BreakpointEventType
GetBreakpointEventType () const;
lldb::BreakpointSP &
GetBreakpoint ();
@ -131,17 +120,20 @@ public:
virtual void
Dump (Stream *s) const;
static BreakpointEventData *
GetEventDataFromEvent (const lldb::EventSP &event_sp);
static EventSubType
GetSubTypeFromEvent (const lldb::EventSP &event_sp);
static lldb::BreakpointEventType
GetBreakpointEventTypeFromEvent (const lldb::EventSP &event_sp);
static lldb::BreakpointSP
GetBreakpointFromEvent (const lldb::EventSP &event_sp);
static lldb::BreakpointLocationSP
GetBreakpointLocationAtIndexFromEvent (const lldb::EventSP &event_sp, uint32_t loc_idx);
private:
EventSubType m_sub_type;
static BreakpointEventData *
GetEventDataFromEvent (const lldb::EventSP &event_sp);
lldb::BreakpointEventType m_breakpoint_event;
lldb::BreakpointSP m_new_breakpoint_sp;
BreakpointLocationCollection m_locations;
@ -324,13 +316,22 @@ public:
SetIgnoreCount (uint32_t count);
//------------------------------------------------------------------
/// Return the current Ignore Count.
/// Return the current ignore count/
/// @return
/// The number of breakpoint hits to be ignored.
//------------------------------------------------------------------
uint32_t
GetIgnoreCount () const;
//------------------------------------------------------------------
/// Return the current hit count for all locations.
/// @return
/// The current hit count for all locations.
//------------------------------------------------------------------
uint32_t
GetHitCount () const;
//------------------------------------------------------------------
/// Set the valid thread to be checked when the breakpoint is hit.
/// @param[in] thread_id

View File

@ -47,7 +47,7 @@ public:
/// Returns breakpoint id.
//------------------------------------------------------------------
virtual lldb::break_id_t
Add (lldb::BreakpointSP& bp_sp);
Add (lldb::BreakpointSP& bp_sp, bool notify);
//------------------------------------------------------------------
/// Standard "Dump" method. At present it does nothing.
@ -92,7 +92,7 @@ public:
/// breakpoint doesn't exist.
//------------------------------------------------------------------
lldb::BreakpointSP
GetBreakpointByIndex (uint32_t i);
GetBreakpointAtIndex (uint32_t i);
//------------------------------------------------------------------
/// Returns a shared pointer to the breakpoint with index \a i, const version
@ -105,7 +105,7 @@ public:
/// breakpoint doesn't exist.
//------------------------------------------------------------------
const lldb::BreakpointSP
GetBreakpointByIndex (uint32_t i) const;
GetBreakpointAtIndex (uint32_t i) const;
//------------------------------------------------------------------
/// Returns the number of elements in this breakpoint list.
@ -126,7 +126,7 @@ public:
/// \b true if the breakpoint \a breakID was in the list.
//------------------------------------------------------------------
bool
Remove (lldb::break_id_t breakID);
Remove (lldb::break_id_t breakID, bool notify);
void
SetEnabledAll (bool enabled);
@ -135,7 +135,7 @@ public:
/// Removes all the breakpoints from this list.
//------------------------------------------------------------------
void
RemoveAll ();
RemoveAll (bool notify);
//------------------------------------------------------------------
/// Tell all the breakpoints to update themselves due to a change in the

View File

@ -172,6 +172,15 @@ public:
size_t
GetNumResolvedLocations() const;
//------------------------------------------------------------------
/// Returns the number hit count of all locations in this list.
///
/// @result
/// Hit count of all locations in this list.
//------------------------------------------------------------------
uint32_t
GetHitCount () const;
//------------------------------------------------------------------
/// Removes the breakpoint location given by \b breakID from this
/// list.

View File

@ -404,18 +404,30 @@ typedef enum ArchitectureType
typedef enum FunctionNameType
{
eFunctionNameTypeNone = 0,
eFunctionNameTypeFull = (1 << 1), // The function name.
eFunctionNameTypeNone = 0u,
eFunctionNameTypeFull = (1u << 1),// The function name.
// For C this is the same as just the name of the function
// For C++ this is the demangled version of the mangled name.
// For ObjC this is the full function signature with the + or
// - and the square brackets and the class and selector
eFunctionNameTypeBase = (1 << 2), // The function name only, no namespaces or arguments and no class
eFunctionNameTypeBase = (1u << 2),// The function name only, no namespaces or arguments and no class
// methods or selectors will be searched.
eFunctionNameTypeMethod = (1 << 3), // Find function by method name (C++) with no namespace or arguments
eFunctionNameTypeSelector = (1 << 4) // Find function by selector name (ObjC) names
eFunctionNameTypeMethod = (1u << 3),// Find function by method name (C++) with no namespace or arguments
eFunctionNameTypeSelector = (1u << 4) // Find function by selector name (ObjC) names
} FunctionNameType;
typedef enum BreakpointEventType
{
eBreakpointEventTypeInvalidType = (1u << 0),
eBreakpointEventTypeAdded = (1u << 1),
eBreakpointEventTypeRemoved = (1u << 2),
eBreakpointEventTypeLocationsAdded = (1u << 3),
eBreakpointEventTypeLocationsRemoved = (1u << 4),
eBreakpointEventTypeLocationsResolved = (1u << 5)
} BreakpointEventType;
} // namespace lldb

View File

@ -10,6 +10,7 @@
#include "lldb/API/SBBreakpoint.h"
#include "lldb/API/SBBreakpointLocation.h"
#include "lldb/API/SBDebugger.h"
#include "lldb/API/SBEvent.h"
#include "lldb/API/SBProcess.h"
#include "lldb/API/SBThread.h"
@ -241,6 +242,15 @@ SBBreakpoint::SetIgnoreCount (uint32_t count)
m_opaque_sp->SetIgnoreCount (count);
}
uint32_t
SBBreakpoint::GetHitCount () const
{
if (m_opaque_sp)
return m_opaque_sp->GetHitCount();
else
return 0;
}
uint32_t
SBBreakpoint::GetIgnoreCount () const
{
@ -457,3 +467,30 @@ SBBreakpoint::operator *() const
return m_opaque_sp;
}
BreakpointEventType
SBBreakpoint::GetBreakpointEventTypeFromEvent (const SBEvent& event)
{
if (event.IsValid())
return Breakpoint::BreakpointEventData::GetBreakpointEventTypeFromEvent (event.GetSP());
return eBreakpointEventTypeInvalidType;
}
SBBreakpoint
SBBreakpoint::GetBreakpointFromEvent (const lldb::SBEvent& event)
{
SBBreakpoint sb_breakpoint;
if (event.IsValid())
sb_breakpoint.m_opaque_sp = Breakpoint::BreakpointEventData::GetBreakpointFromEvent (event.GetSP());
return sb_breakpoint;
}
SBBreakpointLocation
SBBreakpoint::GetBreakpointLocationAtIndexFromEvent (const lldb::SBEvent& event, uint32_t loc_idx)
{
SBBreakpointLocation sb_breakpoint_loc;
if (event.IsValid())
sb_breakpoint_loc.SetLocation (Breakpoint::BreakpointEventData::GetBreakpointLocationAtIndexFromEvent (event.GetSP(), loc_idx));
return sb_breakpoint_loc;
}

View File

@ -277,26 +277,6 @@ SBTarget::BreakpointCreateByAddress (addr_t address)
return sb_bp;
}
void
SBTarget::ListAllBreakpoints ()
{
FILE *out_file = m_opaque_sp->GetDebugger().GetOutputFileHandle();
if (out_file == NULL)
return;
if (m_opaque_sp)
{
const BreakpointList &bp_list = m_opaque_sp->GetBreakpointList();
size_t num_bps = bp_list.GetSize();
for (size_t i = 0; i < num_bps; ++i)
{
SBBreakpoint sb_breakpoint (bp_list.GetBreakpointByIndex (i));
sb_breakpoint.GetDescription (out_file, "full");
}
}
}
SBBreakpoint
SBTarget::FindBreakpointByID (break_id_t bp_id)
{
@ -306,6 +286,22 @@ SBTarget::FindBreakpointByID (break_id_t bp_id)
return sb_breakpoint;
}
uint32_t
SBTarget::GetNumBreakpoints () const
{
if (m_opaque_sp)
return m_opaque_sp->GetBreakpointList().GetSize();
return 0;
}
SBBreakpoint
SBTarget::GetBreakpointAtIndex (uint32_t idx) const
{
SBBreakpoint sb_breakpoint;
if (m_opaque_sp)
*sb_breakpoint = m_opaque_sp->GetBreakpointList().GetBreakpointAtIndex(idx);
return sb_breakpoint;
}
bool
SBTarget::BreakpointDelete (break_id_t bp_id)

View File

@ -164,6 +164,12 @@ Breakpoint::GetIgnoreCount () const
return m_options.GetIgnoreCount();
}
uint32_t
Breakpoint::GetHitCount () const
{
return m_locations.GetHitCount();
}
void
Breakpoint::SetThreadID (lldb::tid_t thread_id)
{
@ -405,10 +411,10 @@ Breakpoint::GetDescription (Stream *s, lldb::DescriptionLevel level, bool show_l
}
}
Breakpoint::BreakpointEventData::BreakpointEventData (Breakpoint::BreakpointEventData::EventSubType sub_type,
Breakpoint::BreakpointEventData::BreakpointEventData (BreakpointEventType sub_type,
BreakpointSP &new_breakpoint_sp) :
EventData (),
m_sub_type (sub_type),
m_breakpoint_event (sub_type),
m_new_breakpoint_sp (new_breakpoint_sp)
{
}
@ -437,10 +443,10 @@ Breakpoint::BreakpointEventData::GetBreakpoint ()
return m_new_breakpoint_sp;
}
Breakpoint::BreakpointEventData::EventSubType
Breakpoint::BreakpointEventData::GetSubType () const
BreakpointEventType
Breakpoint::BreakpointEventData::GetBreakpointEventType () const
{
return m_sub_type;
return m_breakpoint_event;
}
void
@ -460,29 +466,43 @@ Breakpoint::BreakpointEventData::GetEventDataFromEvent (const EventSP &event_sp)
return NULL;
}
Breakpoint::BreakpointEventData::EventSubType
Breakpoint::BreakpointEventData::GetSubTypeFromEvent (const EventSP &event_sp)
BreakpointEventType
Breakpoint::BreakpointEventData::GetBreakpointEventTypeFromEvent (const EventSP &event_sp)
{
BreakpointEventData *data = GetEventDataFromEvent (event_sp);
if (data == NULL)
return eBreakpointInvalidType;
return eBreakpointEventTypeInvalidType;
else
return data->GetSubType();
return data->GetBreakpointEventType();
}
BreakpointSP
Breakpoint::BreakpointEventData::GetBreakpointFromEvent (const EventSP &event_sp)
{
BreakpointEventData *data = GetEventDataFromEvent (event_sp);
BreakpointSP bp_sp;
if (data == NULL)
BreakpointEventData *data = GetEventDataFromEvent (event_sp);
if (data)
bp_sp = data->GetBreakpoint();
return bp_sp;
}
lldb::BreakpointLocationSP
Breakpoint::BreakpointEventData::GetBreakpointLocationAtIndexFromEvent (const lldb::EventSP &event_sp, uint32_t bp_loc_idx)
{
lldb::BreakpointLocationSP bp_loc_sp;
BreakpointEventData *data = GetEventDataFromEvent (event_sp);
if (data)
{
BreakpointSP ret_val;
return ret_val;
Breakpoint *bp = data->GetBreakpoint().get();
if (bp)
bp_loc_sp = bp->GetLocationAtIndex(bp_loc_idx);
}
else
return data->GetBreakpoint();
return bp_loc_sp;
}

View File

@ -231,7 +231,7 @@ BreakpointIDList::FindAndReplaceIDRanges (Args &old_args, Target *target, Comman
const size_t num_breakpoints = breakpoints.GetSize();
for (size_t j = 0; j < num_breakpoints; ++j)
{
Breakpoint *breakpoint = breakpoints.GetBreakpointByIndex (j).get();
Breakpoint *breakpoint = breakpoints.GetBreakpointAtIndex (j).get();
break_id_t cur_bp_id = breakpoint->GetID();
if ((cur_bp_id < start_bp_id) || (cur_bp_id > end_bp_id))

View File

@ -13,6 +13,7 @@
// C++ Includes
// Other libraries and framework includes
// Project includes
#include "lldb/Target/Target.h"
using namespace lldb;
using namespace lldb_private;
@ -31,23 +32,37 @@ BreakpointList::~BreakpointList()
break_id_t
BreakpointList::Add (BreakpointSP &bp)
BreakpointList::Add (BreakpointSP &bp_sp, bool notify)
{
Mutex::Locker locker(m_mutex);
// Internal breakpoint IDs are negative, normal ones are positive
bp->SetID (m_is_internal ? --m_next_break_id : ++m_next_break_id);
m_breakpoints.push_back(bp);
return bp->GetID();
bp_sp->SetID (m_is_internal ? --m_next_break_id : ++m_next_break_id);
m_breakpoints.push_back(bp_sp);
if (notify)
{
if (bp_sp->GetTarget().EventTypeHasListeners(Target::eBroadcastBitBreakpointChanged))
bp_sp->GetTarget().BroadcastEvent (Target::eBroadcastBitBreakpointChanged,
new Breakpoint::BreakpointEventData (eBreakpointEventTypeAdded, bp_sp));
}
return bp_sp->GetID();
}
bool
BreakpointList::Remove (break_id_t break_id)
BreakpointList::Remove (break_id_t break_id, bool notify)
{
Mutex::Locker locker(m_mutex);
bp_collection::iterator pos = GetBreakpointIDIterator(break_id); // Predicate
if (pos != m_breakpoints.end())
{
BreakpointSP bp_sp (*pos);
m_breakpoints.erase(pos);
if (notify)
{
if (bp_sp->GetTarget().EventTypeHasListeners(Target::eBroadcastBitBreakpointChanged))
bp_sp->GetTarget().BroadcastEvent (Target::eBroadcastBitBreakpointChanged,
new Breakpoint::BreakpointEventData (eBreakpointEventTypeRemoved, bp_sp));
}
return true;
}
return false;
@ -64,11 +79,19 @@ BreakpointList::SetEnabledAll (bool enabled)
void
BreakpointList::RemoveAll ()
BreakpointList::RemoveAll (bool notify)
{
Mutex::Locker locker(m_mutex);
ClearAllBreakpointSites ();
if (notify)
{
bp_collection::iterator pos, end = m_breakpoints.end();
for (pos = m_breakpoints.begin(); pos != end; ++pos)
if ((*pos)->GetTarget().EventTypeHasListeners(Target::eBroadcastBitBreakpointChanged))
(*pos)->GetTarget().BroadcastEvent (Target::eBroadcastBitBreakpointChanged,
new Breakpoint::BreakpointEventData (eBreakpointEventTypeRemoved, *pos));
}
m_breakpoints.erase (m_breakpoints.begin(), m_breakpoints.end());
}
@ -144,7 +167,7 @@ BreakpointList::Dump (Stream *s) const
BreakpointSP
BreakpointList::GetBreakpointByIndex (uint32_t i)
BreakpointList::GetBreakpointAtIndex (uint32_t i)
{
Mutex::Locker locker(m_mutex);
BreakpointSP stop_sp;
@ -160,7 +183,7 @@ BreakpointList::GetBreakpointByIndex (uint32_t i)
}
const BreakpointSP
BreakpointList::GetBreakpointByIndex (uint32_t i) const
BreakpointList::GetBreakpointAtIndex (uint32_t i) const
{
Mutex::Locker locker(m_mutex);
BreakpointSP stop_sp;

View File

@ -263,6 +263,17 @@ BreakpointLocationList::ResolveAllBreakpointSites ()
(*pos)->ResolveBreakpointSite();
}
uint32_t
BreakpointLocationList::GetHitCount () const
{
uint32_t hit_count = 0;
Mutex::Locker locker (m_mutex);
collection::const_iterator pos, end = m_locations.end();
for (pos = m_locations.begin(); pos != end; ++pos)
hit_count += (*pos)->GetHitCount();
return hit_count;
}
size_t
BreakpointLocationList::GetNumResolvedLocations() const
{

View File

@ -735,7 +735,7 @@ CommandObjectBreakpointList::Execute
result.AppendMessage ("Current breakpoints:");
for (size_t i = 0; i < num_breakpoints; ++i)
{
Breakpoint *breakpoint = breakpoints.GetBreakpointByIndex (i).get();
Breakpoint *breakpoint = breakpoints.GetBreakpointAtIndex (i).get();
AddBreakpointDescription (&output_stream, breakpoint, m_options.m_level);
}
result.SetStatus (eReturnStatusSuccessFinishNoResult);

View File

@ -231,9 +231,9 @@ Target::CreateBreakpoint (SearchFilterSP &filter_sp, BreakpointResolverSP &resol
resolver_sp->SetBreakpoint (bp_sp.get());
if (internal)
m_internal_breakpoint_list.Add (bp_sp);
m_internal_breakpoint_list.Add (bp_sp, false);
else
m_breakpoint_list.Add (bp_sp);
m_breakpoint_list.Add (bp_sp, true);
Log *log = lldb_private::GetLogIfAllCategoriesSet (LIBLLDB_LOG_BREAKPOINTS);
if (log)
@ -243,13 +243,6 @@ Target::CreateBreakpoint (SearchFilterSP &filter_sp, BreakpointResolverSP &resol
log->Printf ("Target::%s (internal = %s) => break_id = %s\n", __FUNCTION__, internal ? "yes" : "no", s.GetData());
}
// Broadcast the breakpoint creation event.
if (!internal && EventTypeHasListeners(eBroadcastBitBreakpointChanged))
{
BroadcastEvent (eBroadcastBitBreakpointChanged,
new Breakpoint::BreakpointEventData (Breakpoint::BreakpointEventData::eBreakpointAdded, bp_sp));
}
bp_sp->ResolveBreakpoint();
}
return bp_sp;
@ -262,9 +255,9 @@ Target::RemoveAllBreakpoints (bool internal_also)
if (log)
log->Printf ("Target::%s (internal_also = %s)\n", __FUNCTION__, internal_also ? "yes" : "no");
m_breakpoint_list.RemoveAll();
m_breakpoint_list.RemoveAll (true);
if (internal_also)
m_internal_breakpoint_list.RemoveAll();
m_internal_breakpoint_list.RemoveAll (false);
}
void
@ -301,9 +294,9 @@ Target::RemoveBreakpointByID (break_id_t break_id)
if (DisableBreakpointByID (break_id))
{
if (LLDB_BREAK_ID_IS_INTERNAL (break_id))
m_internal_breakpoint_list.Remove(break_id);
m_internal_breakpoint_list.Remove(break_id, false);
else
m_breakpoint_list.Remove(break_id);
m_breakpoint_list.Remove(break_id, true);
return true;
}
return false;