diff options
-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); |