diff options
author | Jim Ingham <jingham@apple.com> | 2012-02-08 05:23:15 +0000 |
---|---|---|
committer | Jim Ingham <jingham@apple.com> | 2012-02-08 05:23:15 +0000 |
commit | e6bc6cb96fbcbd77a80c8cb831a2bba2b4073cac (patch) | |
tree | 486e94a3918ba4ec21b6205d6dc1f7ae3d01cf81 /lldb | |
parent | fec9f8edb788aaca0d7b86f5b6d4163e5a6faa41 (diff) | |
download | bcm5719-llvm-e6bc6cb96fbcbd77a80c8cb831a2bba2b4073cac.tar.gz bcm5719-llvm-e6bc6cb96fbcbd77a80c8cb831a2bba2b4073cac.zip |
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
Diffstat (limited to 'lldb')
-rw-r--r-- | lldb/include/lldb/API/SBBreakpoint.h | 7 | ||||
-rw-r--r-- | lldb/include/lldb/API/SBProcess.h | 3 | ||||
-rw-r--r-- | lldb/include/lldb/Breakpoint/Breakpoint.h | 43 | ||||
-rw-r--r-- | lldb/include/lldb/Breakpoint/BreakpointLocation.h | 25 | ||||
-rw-r--r-- | lldb/include/lldb/Breakpoint/BreakpointLocationList.h | 17 | ||||
-rw-r--r-- | lldb/include/lldb/lldb-enumerations.h | 10 | ||||
-rw-r--r-- | lldb/scripts/Python/interface/SBBreakpoint.i | 6 | ||||
-rw-r--r-- | lldb/scripts/Python/interface/SBProcess.i | 3 | ||||
-rw-r--r-- | lldb/source/API/SBBreakpoint.cpp | 16 | ||||
-rw-r--r-- | lldb/source/API/SBBreakpointLocation.cpp | 22 | ||||
-rw-r--r-- | lldb/source/API/SBProcess.cpp | 5 | ||||
-rw-r--r-- | lldb/source/Breakpoint/Breakpoint.cpp | 198 | ||||
-rw-r--r-- | lldb/source/Breakpoint/BreakpointLocation.cpp | 105 | ||||
-rw-r--r-- | lldb/source/Breakpoint/BreakpointLocationCollection.cpp | 1 | ||||
-rw-r--r-- | lldb/source/Breakpoint/BreakpointLocationList.cpp | 52 | ||||
-rw-r--r-- | lldb/source/Commands/CommandObjectBreakpoint.cpp | 16 | ||||
-rw-r--r-- | lldb/source/Target/TargetList.cpp | 3 | ||||
-rw-r--r-- | lldb/tools/driver/Driver.cpp | 47 | ||||
-rw-r--r-- | lldb/tools/driver/Driver.h | 3 |
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); |