summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--lldb/include/lldb/API/SBBreakpoint.h7
-rw-r--r--lldb/include/lldb/API/SBProcess.h3
-rw-r--r--lldb/include/lldb/Breakpoint/Breakpoint.h43
-rw-r--r--lldb/include/lldb/Breakpoint/BreakpointLocation.h25
-rw-r--r--lldb/include/lldb/Breakpoint/BreakpointLocationList.h17
-rw-r--r--lldb/include/lldb/lldb-enumerations.h10
-rw-r--r--lldb/scripts/Python/interface/SBBreakpoint.i6
-rw-r--r--lldb/scripts/Python/interface/SBProcess.i3
-rw-r--r--lldb/source/API/SBBreakpoint.cpp16
-rw-r--r--lldb/source/API/SBBreakpointLocation.cpp22
-rw-r--r--lldb/source/API/SBProcess.cpp5
-rw-r--r--lldb/source/Breakpoint/Breakpoint.cpp198
-rw-r--r--lldb/source/Breakpoint/BreakpointLocation.cpp105
-rw-r--r--lldb/source/Breakpoint/BreakpointLocationCollection.cpp1
-rw-r--r--lldb/source/Breakpoint/BreakpointLocationList.cpp52
-rw-r--r--lldb/source/Commands/CommandObjectBreakpoint.cpp16
-rw-r--r--lldb/source/Target/TargetList.cpp3
-rw-r--r--lldb/tools/driver/Driver.cpp47
-rw-r--r--lldb/tools/driver/Driver.h3
19 files changed, 511 insertions, 71 deletions
diff --git a/lldb/include/lldb/API/SBBreakpoint.h b/lldb/include/lldb/API/SBBreakpoint.h
index 8c49126a131..5338b0a79c8 100644
--- a/lldb/include/lldb/API/SBBreakpoint.h
+++ b/lldb/include/lldb/API/SBBreakpoint.h
@@ -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);
@@ -123,6 +126,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;
diff --git a/lldb/include/lldb/API/SBProcess.h b/lldb/include/lldb/API/SBProcess.h
index be169f0ba09..84e9192945b 100644
--- a/lldb/include/lldb/API/SBProcess.h
+++ b/lldb/include/lldb/API/SBProcess.h
@@ -171,6 +171,9 @@ public:
static lldb::SBProcess
GetProcessFromEvent (const lldb::SBEvent &event);
+
+ static bool
+ EventIsProcessEvent (const lldb::SBEvent &event);
lldb::SBBroadcaster
GetBroadcaster () const;
diff --git a/lldb/include/lldb/Breakpoint/Breakpoint.h b/lldb/include/lldb/Breakpoint/Breakpoint.h
index 2c2174f9ba3..d6427df544e 100644
--- a/lldb/include/lldb/Breakpoint/Breakpoint.h
+++ b/lldb/include/lldb/Breakpoint/Breakpoint.h
@@ -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();
@@ -116,6 +116,12 @@ public:
lldb::BreakpointSP &
GetBreakpoint ();
+
+ BreakpointLocationCollection &
+ GetBreakpointLocationCollection()
+ {
+ return m_locations;
+ }
virtual void
@@ -129,10 +135,14 @@ 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,11 +559,18 @@ 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);
};
diff --git a/lldb/include/lldb/Breakpoint/BreakpointLocation.h b/lldb/include/lldb/Breakpoint/BreakpointLocation.h
index 98941cb438b..492e029dd54 100644
--- a/lldb/include/lldb/Breakpoint/BreakpointLocation.h
+++ b/lldb/include/lldb/Breakpoint/BreakpointLocation.h
@@ -203,6 +203,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);
};
diff --git a/lldb/include/lldb/Breakpoint/BreakpointLocationList.h b/lldb/include/lldb/Breakpoint/BreakpointLocationList.h
index 3a96710b2c1..93a965b1824 100644
--- a/lldb/include/lldb/Breakpoint/BreakpointLocationList.h
+++ b/lldb/include/lldb/Breakpoint/BreakpointLocationList.h
@@ -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
diff --git a/lldb/include/lldb/lldb-enumerations.h b/lldb/include/lldb/lldb-enumerations.h
index 8b901b144c4..798479ee775 100644
--- a/lldb/include/lldb/lldb-enumerations.h
+++ b/lldb/include/lldb/lldb-enumerations.h
@@ -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;
diff --git a/lldb/scripts/Python/interface/SBBreakpoint.i b/lldb/scripts/Python/interface/SBBreakpoint.i
index 9e333c37287..0e9a80c2e9b 100644
--- a/lldb/scripts/Python/interface/SBBreakpoint.i
+++ b/lldb/scripts/Python/interface/SBBreakpoint.i
@@ -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
diff --git a/lldb/scripts/Python/interface/SBProcess.i b/lldb/scripts/Python/interface/SBProcess.i
index df58f169aa9..20d782ad5c4 100644
--- a/lldb/scripts/Python/interface/SBProcess.i
+++ b/lldb/scripts/Python/interface/SBProcess.i
@@ -269,6 +269,9 @@ public:
static lldb::SBProcess
GetProcessFromEvent (const lldb::SBEvent &event);
+ static bool
+ EventIsProcessEvent (const lldb::SBEvent &event);
+
lldb::SBBroadcaster
GetBroadcaster () const;
diff --git a/lldb/source/API/SBBreakpoint.cpp b/lldb/source/API/SBBreakpoint.cpp
index 33bdbe0b472..6b8ac6ede0a 100644
--- a/lldb/source/API/SBBreakpoint.cpp
+++ b/lldb/source/API/SBBreakpoint.cpp
@@ -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;
+}
+
diff --git a/lldb/source/API/SBBreakpointLocation.cpp b/lldb/source/API/SBBreakpointLocation.cpp
index 57cf5a1a5c7..d7fc1dc577d 100644
--- a/lldb/source/API/SBBreakpointLocation.cpp
+++ b/lldb/source/API/SBBreakpointLocation.cpp
@@ -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;
}
diff --git a/lldb/source/API/SBProcess.cpp b/lldb/source/API/SBProcess.cpp
index 4b4e840e63d..5fc71966078 100644
--- a/lldb/source/API/SBProcess.cpp
+++ b/lldb/source/API/SBProcess.cpp
@@ -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
diff --git a/lldb/source/Breakpoint/Breakpoint.cpp b/lldb/source/Breakpoint/Breakpoint.cpp
index aa9fab25618..c680acee985 100644
--- a/lldb/source/Breakpoint/Breakpoint.cpp
+++ b/lldb/source/Breakpoint/Breakpoint.cpp
@@ -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)
{
- ResolveBreakpointInModules(new_modules);
+ // 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,10 +431,15 @@ 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);
}
}
@@ -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;
+}
diff --git a/lldb/source/Breakpoint/BreakpointLocation.cpp b/lldb/source/Breakpoint/BreakpointLocation.cpp
index 358d378cf36..c99eb466378 100644
--- a/lldb/source/Breakpoint/BreakpointLocation.cpp
+++ b/lldb/source/Breakpoint/BreakpointLocation.cpp
@@ -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);
+ }
+}
+
diff --git a/lldb/source/Breakpoint/BreakpointLocationCollection.cpp b/lldb/source/Breakpoint/BreakpointLocationCollection.cpp
index e0ada3adde1..bc493b22543 100644
--- a/lldb/source/Breakpoint/BreakpointLocationCollection.cpp
+++ b/lldb/source/Breakpoint/BreakpointLocationCollection.cpp
@@ -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"
diff --git a/lldb/source/Breakpoint/BreakpointLocationList.cpp b/lldb/source/Breakpoint/BreakpointLocationList.cpp
index 54824dd4f4e..ac98b9a8f78 100644
--- a/lldb/source/Breakpoint/BreakpointLocationList.cpp
+++ b/lldb/source/Breakpoint/BreakpointLocationList.cpp
@@ -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;
+}
+
diff --git a/lldb/source/Commands/CommandObjectBreakpoint.cpp b/lldb/source/Commands/CommandObjectBreakpoint.cpp
index 34cfc782699..d3a110ca654 100644
--- a/lldb/source/Commands/CommandObjectBreakpoint.cpp
+++ b/lldb/source/Commands/CommandObjectBreakpoint.cpp
@@ -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);
diff --git a/lldb/source/Target/TargetList.cpp b/lldb/source/Target/TargetList.cpp
index b6e5d29d8ac..6ca58b86ef5 100644
--- a/lldb/source/Target/TargetList.cpp
+++ b/lldb/source/Target/TargetList.cpp
@@ -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;
diff --git a/lldb/tools/driver/Driver.cpp b/lldb/tools/driver/Driver.cpp
index aaf582687df..5808f5f9c53 100644
--- a/lldb/tools/driver/Driver.cpp
+++ b/lldb/tools/driver/Driver.cpp
@@ -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)
diff --git a/lldb/tools/driver/Driver.h b/lldb/tools/driver/Driver.h
index eb43513b1fa..29fadfc9d66 100644
--- a/lldb/tools/driver/Driver.h
+++ b/lldb/tools/driver/Driver.h
@@ -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);
OpenPOWER on IntegriCloud