Send Breakpoint Changed events for all the relevant changes to breakpoints.

Also, provide and use accessors for the thread options on breakpoints so we
can control sending the appropriate events.

llvm-svn: 150057
This commit is contained in:
Jim Ingham 2012-02-08 05:23:15 +00:00
parent fec9f8edb7
commit e6bc6cb96f
19 changed files with 511 additions and 71 deletions

View File

@ -115,6 +115,9 @@ public:
bool
GetDescription (lldb::SBStream &description);
static bool
EventIsBreakpointEvent (const lldb::SBEvent &event);
static lldb::BreakpointEventType
GetBreakpointEventTypeFromEvent (const lldb::SBEvent& event);
@ -124,6 +127,10 @@ public:
static lldb::SBBreakpointLocation
GetBreakpointLocationAtIndexFromEvent (const lldb::SBEvent& event, uint32_t loc_idx);
static uint32_t
GetNumBreakpointLocationsFromEvent (const lldb::SBEvent &event_sp);
private:
friend class SBBreakpointLocation;
friend class SBTarget;

View File

@ -172,6 +172,9 @@ public:
static lldb::SBProcess
GetProcessFromEvent (const lldb::SBEvent &event);
static bool
EventIsProcessEvent (const lldb::SBEvent &event);
lldb::SBBroadcaster
GetBroadcaster () const;

View File

@ -106,7 +106,7 @@ public:
GetFlavor () const;
BreakpointEventData (lldb::BreakpointEventType sub_type,
lldb::BreakpointSP &new_breakpoint_sp);
const lldb::BreakpointSP &new_breakpoint_sp);
virtual
~BreakpointEventData();
@ -117,6 +117,12 @@ public:
lldb::BreakpointSP &
GetBreakpoint ();
BreakpointLocationCollection &
GetBreakpointLocationCollection()
{
return m_locations;
}
virtual void
Dump (Stream *s) const;
@ -130,9 +136,13 @@ public:
static lldb::BreakpointLocationSP
GetBreakpointLocationAtIndexFromEvent (const lldb::EventSP &event_sp, uint32_t loc_idx);
static uint32_t
GetNumBreakpointLocationsFromEvent (const lldb::EventSP &event_sp);
static const BreakpointEventData *
GetEventDataFromEvent (const Event *event_sp);
private:
static BreakpointEventData *
GetEventDataFromEvent (const lldb::EventSP &event_sp);
lldb::BreakpointEventType m_breakpoint_event;
lldb::BreakpointSP m_new_breakpoint_sp;
@ -343,7 +353,25 @@ public:
/// The thread id for which the breakpoint hit will stop, LLDB_INVALID_THREAD_ID for all threads.
//------------------------------------------------------------------
lldb::tid_t
GetThreadID ();
GetThreadID () const;
void
SetThreadIndex (uint32_t index);
uint32_t
GetThreadIndex() const;
void
SetThreadName (const char *thread_name);
const char *
GetThreadName () const;
void
SetQueueName (const char *queue_name);
const char *
GetQueueName () const;
//------------------------------------------------------------------
/// Set the callback action invoked when the breakpoint is hit.
@ -531,12 +559,19 @@ private:
//------------------------------------------------------------------
// For Breakpoint only
//------------------------------------------------------------------
bool m_being_created;
Target &m_target; // The target that holds this breakpoint.
lldb::SearchFilterSP m_filter_sp; // The filter that constrains the breakpoint's domain.
lldb::BreakpointResolverSP m_resolver_sp; // The resolver that defines this breakpoint.
BreakpointOptions m_options; // Settable breakpoint options
BreakpointLocationList m_locations; // The list of locations currently found for this breakpoint.
void
SendBreakpointChangedEvent (lldb::BreakpointEventType eventKind);
void
SendBreakpointChangedEvent (BreakpointEventData *data);
DISALLOW_COPY_AND_ASSIGN(Breakpoint);
};

View File

@ -204,6 +204,27 @@ public:
void
SetThreadID (lldb::tid_t thread_id);
lldb::tid_t
GetThreadID ();
void
SetThreadIndex (uint32_t index);
uint32_t
GetThreadIndex() const;
void
SetThreadName (const char *thread_name);
const char *
GetThreadName () const;
void
SetQueueName (const char *queue_name);
const char *
GetQueueName () const;
//------------------------------------------------------------------
// The next section deals with this location's breakpoint sites.
//------------------------------------------------------------------
@ -366,11 +387,15 @@ private:
//------------------------------------------------------------------
// Data members:
//------------------------------------------------------------------
bool m_being_created;
Address m_address; ///< The address defining this location.
Breakpoint &m_owner; ///< The breakpoint that produced this object.
std::auto_ptr<BreakpointOptions> m_options_ap; ///< Breakpoint options pointer, NULL if we're using our breakpoint's options.
lldb::BreakpointSiteSP m_bp_site_sp; ///< Our breakpoint site (it may be shared by more than one location.)
void
SendBreakpointLocationChangedEvent (lldb::BreakpointEventType eventKind);
DISALLOW_COPY_AND_ASSIGN (BreakpointLocation);
};

View File

@ -223,7 +223,7 @@ protected:
/// here because only Breakpoints are allowed to create the
/// breakpoint location list.
//------------------------------------------------------------------
BreakpointLocationList();
BreakpointLocationList(Breakpoint &owner);
//------------------------------------------------------------------
/// Add the breakpoint \a bp_loc_sp to the list.
@ -236,18 +236,29 @@ protected:
/// Returns breakpoint location id.
//------------------------------------------------------------------
lldb::BreakpointLocationSP
Create (Breakpoint &owner, const Address &addr);
// Add (lldb::BreakpointLocationSP& bp_loc_sp);
Create (const Address &addr);
void
StartRecordingNewLocations(BreakpointLocationCollection &new_locations);
void
StopRecordingNewLocations();
lldb::BreakpointLocationSP
AddLocation (const Address &addr,
bool *new_location = NULL);
typedef std::vector<lldb::BreakpointLocationSP> collection;
typedef std::map<lldb_private::Address,
lldb::BreakpointLocationSP,
Address::ModulePointerAndOffsetLessThanFunctionObject> addr_map;
Breakpoint &m_owner;
collection m_locations;
addr_map m_address_to_location;
mutable Mutex m_mutex;
lldb::break_id_t m_next_id;
BreakpointLocationCollection *m_new_location_recorder;
};
} // namespace lldb_private

View File

@ -284,9 +284,15 @@ namespace lldb {
eBreakpointEventTypeInvalidType = (1u << 0),
eBreakpointEventTypeAdded = (1u << 1),
eBreakpointEventTypeRemoved = (1u << 2),
eBreakpointEventTypeLocationsAdded = (1u << 3),
eBreakpointEventTypeLocationsAdded = (1u << 3), // Locations added doesn't get sent when the breakpoint is created
eBreakpointEventTypeLocationsRemoved = (1u << 4),
eBreakpointEventTypeLocationsResolved = (1u << 5)
eBreakpointEventTypeLocationsResolved = (1u << 5),
eBreakpointEventTypeEnabled = (1u << 6),
eBreakpointEventTypeDisabled = (1u << 7),
eBreakpointEventTypeCommandChanged = (1u << 8),
eBreakpointEventTypeConditionChanged = (1u << 9),
eBreakpointEventTypeIgnoreChanged = (1u << 10),
eBreakpointEventTypeThreadChanged = (1u << 11)
} BreakpointEventType;

View File

@ -180,6 +180,9 @@ public:
bool
GetDescription (lldb::SBStream &description);
static bool
EventIsBreakpointEvent (const lldb::SBEvent &event);
static lldb::BreakpointEventType
GetBreakpointEventTypeFromEvent (const lldb::SBEvent& event);
@ -188,6 +191,9 @@ public:
static lldb::SBBreakpointLocation
GetBreakpointLocationAtIndexFromEvent (const lldb::SBEvent& event, uint32_t loc_idx);
static uint32_t
GetNumBreakpointLocationsFromEvent (const lldb::SBEvent &event_sp);
};
} // namespace lldb

View File

@ -269,6 +269,9 @@ public:
static lldb::SBProcess
GetProcessFromEvent (const lldb::SBEvent &event);
static bool
EventIsProcessEvent (const lldb::SBEvent &event);
lldb::SBBroadcaster
GetBroadcaster () const;

View File

@ -557,6 +557,13 @@ SBBreakpoint::operator *() const
return m_opaque_sp;
}
bool
SBBreakpoint::EventIsBreakpointEvent (const lldb::SBEvent &event)
{
return Breakpoint::BreakpointEventData::GetEventDataFromEvent(event.get()) != NULL;
}
BreakpointEventType
SBBreakpoint::GetBreakpointEventTypeFromEvent (const SBEvent& event)
{
@ -583,4 +590,13 @@ SBBreakpoint::GetBreakpointLocationAtIndexFromEvent (const lldb::SBEvent& event,
return sb_breakpoint_loc;
}
uint32_t
SBBreakpoint::GetNumBreakpointLocationsFromEvent (const lldb::SBEvent &event)
{
uint32_t num_locations = 0;
if (event.IsValid())
num_locations = (Breakpoint::BreakpointEventData::GetNumBreakpointLocationsFromEvent (event.GetSP()));
return num_locations;
}

View File

@ -176,9 +176,7 @@ SBBreakpointLocation::GetThreadID ()
if (m_opaque_sp)
{
Mutex::Locker api_locker (m_opaque_sp->GetBreakpoint().GetTarget().GetAPIMutex());
const ThreadSpec *thread_spec = m_opaque_sp->GetLocationOptions()->GetThreadSpecNoCreate();
if (thread_spec)
tid = thread_spec->GetTID();
return m_opaque_sp->GetThreadID();
}
return tid;
}
@ -189,7 +187,7 @@ SBBreakpointLocation::SetThreadIndex (uint32_t index)
if (m_opaque_sp)
{
Mutex::Locker api_locker (m_opaque_sp->GetBreakpoint().GetTarget().GetAPIMutex());
m_opaque_sp->GetLocationOptions()->GetThreadSpec()->SetIndex (index);
m_opaque_sp->SetThreadIndex (index);
}
}
@ -200,9 +198,7 @@ SBBreakpointLocation::GetThreadIndex() const
if (m_opaque_sp)
{
Mutex::Locker api_locker (m_opaque_sp->GetBreakpoint().GetTarget().GetAPIMutex());
const ThreadSpec *thread_spec = m_opaque_sp->GetOptionsNoCreate()->GetThreadSpecNoCreate();
if (thread_spec)
thread_idx = thread_spec->GetIndex();
return m_opaque_sp->GetThreadIndex();
}
return thread_idx;
}
@ -214,7 +210,7 @@ SBBreakpointLocation::SetThreadName (const char *thread_name)
if (m_opaque_sp)
{
Mutex::Locker api_locker (m_opaque_sp->GetBreakpoint().GetTarget().GetAPIMutex());
m_opaque_sp->GetLocationOptions()->GetThreadSpec()->SetName (thread_name);
m_opaque_sp->SetThreadName (thread_name);
}
}
@ -224,9 +220,7 @@ SBBreakpointLocation::GetThreadName () const
if (m_opaque_sp)
{
Mutex::Locker api_locker (m_opaque_sp->GetBreakpoint().GetTarget().GetAPIMutex());
const ThreadSpec *thread_spec = m_opaque_sp->GetOptionsNoCreate()->GetThreadSpecNoCreate();
if (thread_spec)
return thread_spec->GetName();
return m_opaque_sp->GetThreadName();
}
return NULL;
}
@ -237,7 +231,7 @@ SBBreakpointLocation::SetQueueName (const char *queue_name)
if (m_opaque_sp)
{
Mutex::Locker api_locker (m_opaque_sp->GetBreakpoint().GetTarget().GetAPIMutex());
m_opaque_sp->GetLocationOptions()->GetThreadSpec()->SetQueueName (queue_name);
m_opaque_sp->SetQueueName (queue_name);
}
}
@ -247,9 +241,7 @@ SBBreakpointLocation::GetQueueName () const
if (m_opaque_sp)
{
Mutex::Locker api_locker (m_opaque_sp->GetBreakpoint().GetTarget().GetAPIMutex());
const ThreadSpec *thread_spec = m_opaque_sp->GetOptionsNoCreate()->GetThreadSpecNoCreate();
if (thread_spec)
return thread_spec->GetQueueName();
m_opaque_sp->GetQueueName ();
}
return NULL;
}

View File

@ -740,6 +740,11 @@ SBProcess::GetProcessFromEvent (const SBEvent &event)
return process;
}
bool
SBProcess::EventIsProcessEvent (const SBEvent &event)
{
return Process::ProcessEventData::GetEventDataFromEvent(event.get()) != NULL;
}
SBBroadcaster
SBProcess::GetBroadcaster () const

View File

@ -45,12 +45,14 @@ Breakpoint::GetEventIdentifier ()
// Breakpoint constructor
//----------------------------------------------------------------------
Breakpoint::Breakpoint(Target &target, SearchFilterSP &filter_sp, BreakpointResolverSP &resolver_sp) :
m_being_created(true),
m_target (target),
m_filter_sp (filter_sp),
m_resolver_sp (resolver_sp),
m_options (),
m_locations ()
m_locations (*this)
{
m_being_created = false;
}
//----------------------------------------------------------------------
@ -83,21 +85,7 @@ Breakpoint::GetTarget () const
BreakpointLocationSP
Breakpoint::AddLocation (const Address &addr, bool *new_location)
{
if (new_location)
*new_location = false;
BreakpointLocationSP bp_loc_sp (m_locations.FindByAddress(addr));
if (!bp_loc_sp)
{
bp_loc_sp = m_locations.Create (*this, addr);
if (bp_loc_sp)
{
bp_loc_sp->ResolveBreakpointSite();
if (new_location)
*new_location = true;
}
}
return bp_loc_sp;
return m_locations.AddLocation (addr, new_location);
}
BreakpointLocationSP
@ -135,11 +123,17 @@ Breakpoint::GetLocationAtIndex (uint32_t index)
void
Breakpoint::SetEnabled (bool enable)
{
if (enable == m_options.IsEnabled())
return;
m_options.SetEnabled(enable);
if (enable)
m_locations.ResolveAllBreakpointSites();
else
m_locations.ClearAllBreakpointSites();
SendBreakpointChangedEvent (enable ? eBreakpointEventTypeEnabled : eBreakpointEventTypeDisabled);
}
bool
@ -151,7 +145,11 @@ Breakpoint::IsEnabled ()
void
Breakpoint::SetIgnoreCount (uint32_t n)
{
if (m_options.GetIgnoreCount() == n)
return;
m_options.SetIgnoreCount(n);
SendBreakpointChangedEvent (eBreakpointEventTypeIgnoreChanged);
}
uint32_t
@ -169,22 +167,84 @@ Breakpoint::GetHitCount () const
void
Breakpoint::SetThreadID (lldb::tid_t thread_id)
{
if (m_options.GetThreadSpec()->GetTID() == thread_id)
return;
m_options.GetThreadSpec()->SetTID(thread_id);
SendBreakpointChangedEvent (eBreakpointEventTypeThreadChanged);
}
lldb::tid_t
Breakpoint::GetThreadID ()
Breakpoint::GetThreadID () const
{
if (m_options.GetThreadSpec() == NULL)
if (m_options.GetThreadSpecNoCreate() == NULL)
return LLDB_INVALID_THREAD_ID;
else
return m_options.GetThreadSpec()->GetTID();
return m_options.GetThreadSpecNoCreate()->GetTID();
}
void
Breakpoint::SetThreadIndex (uint32_t index)
{
if (m_options.GetThreadSpec()->GetIndex() == index)
return;
m_options.GetThreadSpec()->SetIndex(index);
SendBreakpointChangedEvent (eBreakpointEventTypeThreadChanged);
}
uint32_t
Breakpoint::GetThreadIndex() const
{
if (m_options.GetThreadSpecNoCreate() == NULL)
return 0;
else
return m_options.GetThreadSpecNoCreate()->GetIndex();
}
void
Breakpoint::SetThreadName (const char *thread_name)
{
if (::strcmp (m_options.GetThreadSpec()->GetName(), thread_name) == 0)
return;
m_options.GetThreadSpec()->SetName (thread_name);
SendBreakpointChangedEvent (eBreakpointEventTypeThreadChanged);
}
const char *
Breakpoint::GetThreadName () const
{
if (m_options.GetThreadSpecNoCreate() == NULL)
return NULL;
else
return m_options.GetThreadSpecNoCreate()->GetName();
}
void
Breakpoint::SetQueueName (const char *queue_name)
{
if (::strcmp (m_options.GetThreadSpec()->GetQueueName(), queue_name) == 0)
return;
m_options.GetThreadSpec()->SetQueueName (queue_name);
SendBreakpointChangedEvent (eBreakpointEventTypeThreadChanged);
}
const char *
Breakpoint::GetQueueName () const
{
if (m_options.GetThreadSpecNoCreate() == NULL)
return NULL;
else
return m_options.GetThreadSpecNoCreate()->GetQueueName();
}
void
Breakpoint::SetCondition (const char *condition)
{
m_options.SetCondition (condition);
SendBreakpointChangedEvent (eBreakpointEventTypeConditionChanged);
}
ThreadPlan *
@ -206,6 +266,8 @@ Breakpoint::SetCallback (BreakpointHitCallback callback, void *baton, bool is_sy
// The default "Baton" class will keep a copy of "baton" and won't free
// or delete it when it goes goes out of scope.
m_options.SetCallback(callback, BatonSP (new Baton(baton)), is_synchronous);
SendBreakpointChangedEvent (eBreakpointEventTypeCommandChanged);
}
// This function is used when a baton needs to be freed and therefore is
@ -309,9 +371,31 @@ Breakpoint::ModulesChanged (ModuleList &module_list, bool load)
new_modules.AppendIfNeeded (module_sp);
}
if (new_modules.GetSize() > 0)
{
// If this is not an internal breakpoint, set up to record the new locations, then dispatch
// an event with the new locations.
if (!IsInternal())
{
BreakpointEventData *new_locations_event = new BreakpointEventData (eBreakpointEventTypeLocationsAdded,
shared_from_this());
m_locations.StartRecordingNewLocations(new_locations_event->GetBreakpointLocationCollection());
ResolveBreakpointInModules(new_modules);
m_locations.StopRecordingNewLocations();
if (new_locations_event->GetBreakpointLocationCollection().GetSize() != 0)
{
SendBreakpointChangedEvent (new_locations_event);
}
else
delete new_locations_event;
}
else
ResolveBreakpointInModules(new_modules);
}
}
else
@ -323,6 +407,13 @@ Breakpoint::ModulesChanged (ModuleList &module_list, bool load)
// the same? Or do we need to do an equality on modules that is an
// "equivalence"???
BreakpointEventData *removed_locations_event;
if (!IsInternal())
removed_locations_event = new BreakpointEventData (eBreakpointEventTypeLocationsRemoved,
shared_from_this());
else
removed_locations_event = NULL;
for (size_t i = 0; i < module_list.GetSize(); i++)
{
ModuleSP module_sp (module_list.GetModuleAtIndex (i));
@ -340,11 +431,16 @@ Breakpoint::ModulesChanged (ModuleList &module_list, bool load)
// so we always get complete hit count and breakpoint
// lifetime info
break_loc->ClearBreakpointSite();
if (removed_locations_event)
{
removed_locations_event->GetBreakpointLocationCollection().Add(break_loc);
}
}
}
}
}
SendBreakpointChangedEvent (removed_locations_event);
}
}
void
@ -429,7 +525,7 @@ Breakpoint::GetDescription (Stream *s, lldb::DescriptionLevel level, bool show_l
}
Breakpoint::BreakpointEventData::BreakpointEventData (BreakpointEventType sub_type,
BreakpointSP &new_breakpoint_sp) :
const BreakpointSP &new_breakpoint_sp) :
EventData (),
m_breakpoint_event (sub_type),
m_new_breakpoint_sp (new_breakpoint_sp)
@ -471,14 +567,14 @@ Breakpoint::BreakpointEventData::Dump (Stream *s) const
{
}
Breakpoint::BreakpointEventData *
Breakpoint::BreakpointEventData::GetEventDataFromEvent (const EventSP &event_sp)
const Breakpoint::BreakpointEventData *
Breakpoint::BreakpointEventData::GetEventDataFromEvent (const Event *event)
{
if (event_sp)
if (event)
{
EventData *event_data = event_sp->GetData();
const EventData *event_data = event->GetData();
if (event_data && event_data->GetFlavor() == BreakpointEventData::GetFlavorString())
return static_cast <BreakpointEventData *> (event_sp->GetData());
return static_cast <const BreakpointEventData *> (event->GetData());
}
return NULL;
}
@ -486,7 +582,7 @@ Breakpoint::BreakpointEventData::GetEventDataFromEvent (const EventSP &event_sp)
BreakpointEventType
Breakpoint::BreakpointEventData::GetBreakpointEventTypeFromEvent (const EventSP &event_sp)
{
BreakpointEventData *data = GetEventDataFromEvent (event_sp);
const BreakpointEventData *data = GetEventDataFromEvent (event_sp.get());
if (data == NULL)
return eBreakpointEventTypeInvalidType;
@ -499,24 +595,32 @@ Breakpoint::BreakpointEventData::GetBreakpointFromEvent (const EventSP &event_sp
{
BreakpointSP bp_sp;
BreakpointEventData *data = GetEventDataFromEvent (event_sp);
const BreakpointEventData *data = GetEventDataFromEvent (event_sp.get());
if (data)
bp_sp = data->GetBreakpoint();
bp_sp = data->m_new_breakpoint_sp;
return bp_sp;
}
uint32_t
Breakpoint::BreakpointEventData::GetNumBreakpointLocationsFromEvent (const EventSP &event_sp)
{
const BreakpointEventData *data = GetEventDataFromEvent (event_sp.get());
if (data)
return data->m_locations.GetSize();
return 0;
}
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);
const BreakpointEventData *data = GetEventDataFromEvent (event_sp.get());
if (data)
{
Breakpoint *bp = data->GetBreakpoint().get();
if (bp)
bp_loc_sp = bp->GetLocationAtIndex(bp_loc_idx);
bp_loc_sp = data->m_locations.GetByIndex(bp_loc_idx);
}
return bp_loc_sp;
@ -556,3 +660,31 @@ Breakpoint::GetFilterDescription (Stream *s)
{
m_filter_sp->GetDescription (s);
}
void
Breakpoint::SendBreakpointChangedEvent (lldb::BreakpointEventType eventKind)
{
if (!m_being_created
&& !IsInternal()
&& GetTarget().EventTypeHasListeners(Target::eBroadcastBitBreakpointChanged))
{
BreakpointEventData *data = new Breakpoint::BreakpointEventData (eventKind, shared_from_this());
GetTarget().BroadcastEvent (Target::eBroadcastBitBreakpointChanged, data);
}
}
void
Breakpoint::SendBreakpointChangedEvent (BreakpointEventData *data)
{
if (data == NULL)
return;
if (!m_being_created
&& !IsInternal()
&& GetTarget().EventTypeHasListeners(Target::eBroadcastBitBreakpointChanged))
GetTarget().BroadcastEvent (Target::eBroadcastBitBreakpointChanged, data);
else
delete data;
}

View File

@ -38,12 +38,14 @@ BreakpointLocation::BreakpointLocation
bool hardware
) :
StoppointLocation (loc_id, addr.GetOpcodeLoadAddress(&owner.GetTarget()), hardware),
m_being_created(true),
m_address (addr),
m_owner (owner),
m_options_ap (),
m_bp_site_sp ()
{
SetThreadID (tid);
m_being_created = false;
}
BreakpointLocation::~BreakpointLocation()
@ -92,6 +94,7 @@ BreakpointLocation::SetEnabled (bool enabled)
{
ClearBreakpointSite();
}
SendBreakpointLocationChangedEvent (enabled ? eBreakpointEventTypeEnabled : eBreakpointEventTypeDisabled);
}
void
@ -106,6 +109,89 @@ BreakpointLocation::SetThreadID (lldb::tid_t thread_id)
if (m_options_ap.get() != NULL)
m_options_ap->SetThreadID (thread_id);
}
SendBreakpointLocationChangedEvent (eBreakpointEventTypeThreadChanged);
}
lldb::tid_t
BreakpointLocation::GetThreadID ()
{
if (GetOptionsNoCreate()->GetThreadSpecNoCreate())
return GetOptionsNoCreate()->GetThreadSpecNoCreate()->GetTID();
else
return LLDB_INVALID_THREAD_ID;
}
void
BreakpointLocation::SetThreadIndex (uint32_t index)
{
if (index != 0)
GetLocationOptions()->GetThreadSpec()->SetIndex(index);
else
{
// If we're resetting this to an invalid thread id, then
// don't make an options pointer just to do that.
if (m_options_ap.get() != NULL)
m_options_ap->GetThreadSpec()->SetIndex(index);
}
SendBreakpointLocationChangedEvent (eBreakpointEventTypeThreadChanged);
}
uint32_t
BreakpointLocation::GetThreadIndex() const
{
if (GetOptionsNoCreate()->GetThreadSpecNoCreate())
return GetOptionsNoCreate()->GetThreadSpecNoCreate()->GetIndex();
else
return 0;
}
void
BreakpointLocation::SetThreadName (const char *thread_name)
{
if (thread_name != NULL)
GetLocationOptions()->GetThreadSpec()->SetName(thread_name);
else
{
// If we're resetting this to an invalid thread id, then
// don't make an options pointer just to do that.
if (m_options_ap.get() != NULL)
m_options_ap->GetThreadSpec()->SetName(thread_name);
}
SendBreakpointLocationChangedEvent (eBreakpointEventTypeThreadChanged);
}
const char *
BreakpointLocation::GetThreadName () const
{
if (GetOptionsNoCreate()->GetThreadSpecNoCreate())
return GetOptionsNoCreate()->GetThreadSpecNoCreate()->GetName();
else
return NULL;
}
void
BreakpointLocation::SetQueueName (const char *queue_name)
{
if (queue_name != NULL)
GetLocationOptions()->GetThreadSpec()->SetQueueName(queue_name);
else
{
// If we're resetting this to an invalid thread id, then
// don't make an options pointer just to do that.
if (m_options_ap.get() != NULL)
m_options_ap->GetThreadSpec()->SetQueueName(queue_name);
}
SendBreakpointLocationChangedEvent (eBreakpointEventTypeThreadChanged);
}
const char *
BreakpointLocation::GetQueueName () const
{
if (GetOptionsNoCreate()->GetThreadSpecNoCreate())
return GetOptionsNoCreate()->GetThreadSpecNoCreate()->GetQueueName();
else
return NULL;
}
bool
@ -124,6 +210,7 @@ BreakpointLocation::SetCallback (BreakpointHitCallback callback, void *baton,
// The default "Baton" class will keep a copy of "baton" and won't free
// or delete it when it goes goes out of scope.
GetLocationOptions()->SetCallback(callback, BatonSP (new Baton(baton)), is_synchronous);
SendBreakpointLocationChangedEvent (eBreakpointEventTypeCommandChanged);
}
void
@ -131,6 +218,7 @@ BreakpointLocation::SetCallback (BreakpointHitCallback callback, const BatonSP &
bool is_synchronous)
{
GetLocationOptions()->SetCallback (callback, baton_sp, is_synchronous);
SendBreakpointLocationChangedEvent (eBreakpointEventTypeCommandChanged);
}
@ -144,6 +232,7 @@ void
BreakpointLocation::SetCondition (const char *condition)
{
GetLocationOptions()->SetCondition (condition);
SendBreakpointLocationChangedEvent (eBreakpointEventTypeConditionChanged);
}
ThreadPlan *
@ -171,6 +260,7 @@ void
BreakpointLocation::SetIgnoreCount (uint32_t n)
{
GetLocationOptions()->SetIgnoreCount(n);
SendBreakpointLocationChangedEvent (eBreakpointEventTypeIgnoreChanged);
}
const BreakpointOptions *
@ -420,3 +510,18 @@ BreakpointLocation::Dump(Stream *s) const
GetHitCount(),
GetOptionsNoCreate()->GetIgnoreCount());
}
void
BreakpointLocation::SendBreakpointLocationChangedEvent (lldb::BreakpointEventType eventKind)
{
if (!m_being_created
&& !m_owner.IsInternal()
&& m_owner.GetTarget().EventTypeHasListeners(Target::eBroadcastBitBreakpointChanged))
{
Breakpoint::BreakpointEventData *data = new Breakpoint::BreakpointEventData (eventKind,
m_owner.shared_from_this());
data->GetBreakpointLocationCollection().Add (shared_from_this());
m_owner.GetTarget().BroadcastEvent (Target::eBroadcastBitBreakpointChanged, data);
}
}

View File

@ -16,7 +16,6 @@
#include "lldb/Core/ModuleList.h"
#include "lldb/Breakpoint/Breakpoint.h"
#include "lldb/Breakpoint/BreakpointLocation.h"
#include "lldb/Breakpoint/BreakpointLocationList.h"
#include "lldb/Target/Thread.h"
#include "lldb/Target/ThreadSpec.h"

View File

@ -20,10 +20,12 @@
using namespace lldb;
using namespace lldb_private;
BreakpointLocationList::BreakpointLocationList() :
BreakpointLocationList::BreakpointLocationList(Breakpoint &owner) :
m_locations(),
m_address_to_location (),
m_mutex (Mutex::eMutexTypeRecursive)
m_mutex (Mutex::eMutexTypeRecursive),
m_new_location_recorder (NULL),
m_owner (owner)
{
}
@ -32,12 +34,12 @@ BreakpointLocationList::~BreakpointLocationList()
}
BreakpointLocationSP
BreakpointLocationList::Create (Breakpoint &bp, const Address &addr)
BreakpointLocationList::Create (const Address &addr)
{
Mutex::Locker locker (m_mutex);
// The location ID is just the size of the location list + 1
lldb::break_id_t bp_loc_id = m_locations.size() + 1;
BreakpointLocationSP bp_loc_sp (new BreakpointLocation (bp_loc_id, bp, addr));
BreakpointLocationSP bp_loc_sp (new BreakpointLocation (bp_loc_id, m_owner, addr));
m_locations.push_back (bp_loc_sp);
m_address_to_location[addr] = bp_loc_sp;
return bp_loc_sp;
@ -217,3 +219,45 @@ BreakpointLocationList::GetDescription (Stream *s, lldb::DescriptionLevel level)
}
}
BreakpointLocationSP
BreakpointLocationList::AddLocation (const Address &addr, bool *new_location)
{
Mutex::Locker locker (m_mutex);
if (new_location)
*new_location = false;
BreakpointLocationSP bp_loc_sp (FindByAddress(addr));
if (!bp_loc_sp)
{
bp_loc_sp = Create (addr);
if (bp_loc_sp)
{
bp_loc_sp->ResolveBreakpointSite();
if (new_location)
*new_location = true;
if(m_new_location_recorder)
{
m_new_location_recorder->Add(bp_loc_sp);
}
}
}
return bp_loc_sp;
}
void
BreakpointLocationList::StartRecordingNewLocations (BreakpointLocationCollection &new_locations)
{
Mutex::Locker locker (m_mutex);
assert (m_new_location_recorder == NULL);
m_new_location_recorder = &new_locations;
}
void
BreakpointLocationList::StopRecordingNewLocations ()
{
Mutex::Locker locker (m_mutex);
m_new_location_recorder = NULL;
}

View File

@ -1516,16 +1516,16 @@ CommandObjectBreakpointModify::Execute
location->SetThreadID (m_options.m_thread_id);
if (m_options.m_thread_index_passed)
location->GetLocationOptions()->GetThreadSpec()->SetIndex(m_options.m_thread_index);
location->SetThreadIndex(m_options.m_thread_index);
if (m_options.m_name_passed)
location->GetLocationOptions()->GetThreadSpec()->SetName(m_options.m_thread_name.c_str());
location->SetThreadName(m_options.m_thread_name.c_str());
if (m_options.m_queue_passed)
location->GetLocationOptions()->GetThreadSpec()->SetQueueName(m_options.m_queue_name.c_str());
location->SetQueueName(m_options.m_queue_name.c_str());
if (m_options.m_ignore_count != 0)
location->GetLocationOptions()->SetIgnoreCount(m_options.m_ignore_count);
location->SetIgnoreCount(m_options.m_ignore_count);
if (m_options.m_enable_passed)
location->SetEnabled (m_options.m_enable_value);
@ -1540,16 +1540,16 @@ CommandObjectBreakpointModify::Execute
bp->SetThreadID (m_options.m_thread_id);
if (m_options.m_thread_index_passed)
bp->GetOptions()->GetThreadSpec()->SetIndex(m_options.m_thread_index);
bp->SetThreadIndex(m_options.m_thread_index);
if (m_options.m_name_passed)
bp->GetOptions()->GetThreadSpec()->SetName(m_options.m_thread_name.c_str());
bp->SetThreadName(m_options.m_thread_name.c_str());
if (m_options.m_queue_passed)
bp->GetOptions()->GetThreadSpec()->SetQueueName(m_options.m_queue_name.c_str());
bp->SetQueueName(m_options.m_queue_name.c_str());
if (m_options.m_ignore_count != 0)
bp->GetOptions()->SetIgnoreCount(m_options.m_ignore_count);
bp->SetIgnoreCount(m_options.m_ignore_count);
if (m_options.m_enable_passed)
bp->SetEnabled (m_options.m_enable_value);

View File

@ -161,6 +161,9 @@ TargetList::CreateTarget
Mutex::Locker locker(m_target_list_mutex);
m_selected_target_idx = m_target_list.size();
m_target_list.push_back(target_sp);
// Now sign the Debugger up to listen to target events for this target:
debugger.GetListener().StartListeningForEvents(target_sp.get(), Target::eBroadcastBitBreakpointChanged);
}
return error;

View File

@ -22,6 +22,7 @@
#include <string>
#include "IOChannel.h"
#include "lldb/API/SBBreakpoint.h"
#include "lldb/API/SBCommandInterpreter.h"
#include "lldb/API/SBCommandReturnObject.h"
#include "lldb/API/SBCommunication.h"
@ -824,6 +825,46 @@ Driver::UpdateSelectedThread ()
}
}
// This function handles events that were broadcast by the process.
void
Driver::HandleBreakpointEvent (const SBEvent &event)
{
using namespace lldb;
const uint32_t event_type = SBBreakpoint::GetBreakpointEventTypeFromEvent (event);
if (event_type & eBreakpointEventTypeAdded
|| event_type & eBreakpointEventTypeRemoved
|| event_type & eBreakpointEventTypeEnabled
|| event_type & eBreakpointEventTypeDisabled
|| event_type & eBreakpointEventTypeCommandChanged
|| event_type & eBreakpointEventTypeConditionChanged
|| event_type & eBreakpointEventTypeIgnoreChanged
|| event_type & eBreakpointEventTypeLocationsResolved)
{
// Don't do anything about these events, since the breakpoint commands already echo these actions.
}
else if (event_type & eBreakpointEventTypeLocationsAdded)
{
char message[256];
uint32_t num_new_locations = SBBreakpoint::GetNumBreakpointLocationsFromEvent(event);
if (num_new_locations > 0)
{
SBBreakpoint breakpoint = SBBreakpoint::GetBreakpointFromEvent(event);
int message_len = ::snprintf (message, sizeof(message), "%d locations added to breakpoint %d\n",
num_new_locations,
breakpoint.GetID());
m_io_channel_ap->OutWrite(message, message_len, ASYNC);
}
}
else if (event_type & eBreakpointEventTypeLocationsRemoved)
{
// These locations just get disabled, not sure it is worth spamming folks about this on the command line.
}
else if (event_type & eBreakpointEventTypeLocationsResolved)
{
// This might be an interesting thing to note, but I'm going to leave it quiet for now, it just looked noisy.
}
}
// This function handles events that were broadcast by the process.
void
@ -1348,10 +1389,14 @@ Driver::MainLoop ()
else
done = HandleIOEvent (event);
}
else if (event.BroadcasterMatchesRef (m_debugger.GetSelectedTarget().GetProcess().GetBroadcaster()))
else if (SBProcess::EventIsProcessEvent (event))
{
HandleProcessEvent (event);
}
else if (SBBreakpoint::EventIsBreakpointEvent (event))
{
HandleBreakpointEvent (event);
}
else if (event.BroadcasterMatchesRef (sb_interpreter.GetBroadcaster()))
{
if (event_type & SBCommandInterpreter::eBroadcastBitQuitCommandReceived)

View File

@ -62,6 +62,9 @@ public:
void
HandleProcessEvent (const lldb::SBEvent &event);
void
HandleBreakpointEvent (const lldb::SBEvent &event);
lldb::SBError
ParseArgs (int argc, const char *argv[], FILE *out_fh, bool &do_exit);