diff options
-rw-r--r-- | lldb/include/lldb/Breakpoint/BreakpointOptions.h | 12 | ||||
-rw-r--r-- | lldb/include/lldb/Target/Thread.h | 5 | ||||
-rw-r--r-- | lldb/include/lldb/Target/ThreadSpec.h | 9 | ||||
-rw-r--r-- | lldb/source/Breakpoint/Breakpoint.cpp | 24 | ||||
-rw-r--r-- | lldb/source/Breakpoint/BreakpointLocation.cpp | 44 | ||||
-rw-r--r-- | lldb/source/Breakpoint/BreakpointOptions.cpp | 82 | ||||
-rw-r--r-- | lldb/source/Target/Thread.cpp | 14 | ||||
-rw-r--r-- | lldb/source/Target/ThreadSpec.cpp | 64 |
8 files changed, 200 insertions, 54 deletions
diff --git a/lldb/include/lldb/Breakpoint/BreakpointOptions.h b/lldb/include/lldb/Breakpoint/BreakpointOptions.h index c0c3eeb5778..9dbfd80371e 100644 --- a/lldb/include/lldb/Breakpoint/BreakpointOptions.h +++ b/lldb/include/lldb/Breakpoint/BreakpointOptions.h @@ -39,7 +39,8 @@ public: BreakpointOptions(); BreakpointOptions(const BreakpointOptions& rhs); - + static BreakpointOptions * + CopyOptionsNoCallback (BreakpointOptions &rhs); //------------------------------------------------------------------ /// This constructor allows you to specify all the breakpoint options. /// @@ -142,6 +143,15 @@ public: void SetThreadID(lldb::tid_t thread_id); + + void + GetDescription (Stream *s, lldb::DescriptionLevel level) const; + + //------------------------------------------------------------------ + /// Returns true if the breakpoint option has a callback set. + //------------------------------------------------------------------ + bool + HasCallback(); //------------------------------------------------------------------ /// This is the default empty callback. diff --git a/lldb/include/lldb/Target/Thread.h b/lldb/include/lldb/Target/Thread.h index bd8bdf069ba..01e17773b08 100644 --- a/lldb/include/lldb/Target/Thread.h +++ b/lldb/include/lldb/Target/Thread.h @@ -263,6 +263,11 @@ public: lldb::Vote ShouldReportRun (Event *event_ptr); + // Return whether this thread matches the specification in ThreadSpec. This is a virtual + // method because at some point we may extend the thread spec with a platform specific + // dictionary of attributes, which then only the platform specific Thread implementation + // would know how to match. For now, this just calls through to the ThreadSpec's + // ThreadPassesBasicTests method. virtual bool MatchesSpec (const ThreadSpec *spec); diff --git a/lldb/include/lldb/Target/ThreadSpec.h b/lldb/include/lldb/Target/ThreadSpec.h index 2ee28a28b46..94401ce6eae 100644 --- a/lldb/include/lldb/Target/ThreadSpec.h +++ b/lldb/include/lldb/Target/ThreadSpec.h @@ -121,6 +121,15 @@ public: return m_queue_name == queue_name; } + bool + ThreadPassesBasicTests (Thread *thread) const; + + bool + HasSpecification () const; + + void + GetDescription (Stream *s, lldb::DescriptionLevel level) const; + protected: private: uint32_t m_index; diff --git a/lldb/source/Breakpoint/Breakpoint.cpp b/lldb/source/Breakpoint/Breakpoint.cpp index b3576b6a5da..fb277b223ba 100644 --- a/lldb/source/Breakpoint/Breakpoint.cpp +++ b/lldb/source/Breakpoint/Breakpoint.cpp @@ -380,28 +380,21 @@ Breakpoint::GetDescription (Stream *s, lldb::DescriptionLevel level, bool show_l s->Printf(" with 0 locations (Pending Breakpoint)."); } + GetOptions()->GetDescription(s, level); + if (level == lldb::eDescriptionLevelFull) { - Baton *baton = GetOptions()->GetBaton(); - if (baton) - { - s->EOL (); - s->Indent(); - baton->GetDescription(s, level); - } + s->IndentLess(); + s->EOL(); } break; case lldb::eDescriptionLevelVerbose: // Verbose mode does a debug dump of the breakpoint Dump (s); - Baton *baton = GetOptions()->GetBaton(); - if (baton) - { - s->EOL (); - s->Indent(); - baton->GetDescription(s, level); - } + s->EOL (); + s->Indent(); + GetOptions()->GetDescription(s, level); break; } @@ -420,7 +413,8 @@ Breakpoint::GetDescription (Stream *s, lldb::DescriptionLevel level, bool show_l } } -Breakpoint::BreakpointEventData::BreakpointEventData (Breakpoint::BreakpointEventData::EventSubType sub_type, BreakpointSP &new_breakpoint_sp) : +Breakpoint::BreakpointEventData::BreakpointEventData (Breakpoint::BreakpointEventData::EventSubType sub_type, + BreakpointSP &new_breakpoint_sp) : EventData (), m_sub_type (sub_type), m_new_breakpoint_sp (new_breakpoint_sp) diff --git a/lldb/source/Breakpoint/BreakpointLocation.cpp b/lldb/source/Breakpoint/BreakpointLocation.cpp index e00afcad750..ef9c43152b4 100644 --- a/lldb/source/Breakpoint/BreakpointLocation.cpp +++ b/lldb/source/Breakpoint/BreakpointLocation.cpp @@ -109,15 +109,10 @@ BreakpointLocation::SetThreadID (lldb::tid_t thread_id) bool BreakpointLocation::InvokeCallback (StoppointCallbackContext *context) { - bool owner_result; - - owner_result = m_owner.InvokeCallback (context, GetID()); - if (owner_result == false) - return false; - else if (m_options_ap.get() != NULL) + if (m_options_ap.get() != NULL && m_options_ap->HasCallback()) return m_options_ap->InvokeCallback (context, m_owner.GetID(), GetID()); - else - return true; + else + return m_owner.InvokeCallback (context, GetID()); } void @@ -166,9 +161,12 @@ BreakpointLocation::GetOptionsNoCopy () const BreakpointOptions * BreakpointLocation::GetLocationOptions () { + // If we make the copy we don't copy the callbacks because that is potentially + // expensive and we don't want to do that for the simple case where someone is + // just disabling the location. if (m_options_ap.get() == NULL) - m_options_ap.reset(new BreakpointOptions (*m_owner.GetOptions ())); - + m_options_ap.reset(BreakpointOptions::CopyOptionsNoCallback(*m_owner.GetOptions ())); + return m_options_ap.get(); } @@ -257,7 +255,8 @@ BreakpointLocation::ClearBreakpointSite () { if (m_bp_site_sp.get()) { - m_owner.GetTarget().GetProcessSP()->RemoveOwnerFromBreakpointSite (GetBreakpoint().GetID(), GetID(), m_bp_site_sp); + m_owner.GetTarget().GetProcessSP()->RemoveOwnerFromBreakpointSite (GetBreakpoint().GetID(), + GetID(), m_bp_site_sp); m_bp_site_sp.reset(); return true; } @@ -353,29 +352,25 @@ BreakpointLocation::GetDescription (Stream *s, lldb::DescriptionLevel level) s->Printf("resolved = %s\n", IsResolved() ? "true" : "false"); s->Indent(); - s->Printf("enabled = %s\n", IsEnabled() ? "true" : "false"); - - s->Indent(); s->Printf ("hit count = %-4u\n", GetHitCount()); if (m_options_ap.get()) { - Baton *baton = m_options_ap->GetBaton(); - if (baton) - { - s->Indent(); - baton->GetDescription (s, level); - s->EOL(); - } + s->Indent(); + m_options_ap->GetDescription (s, level); + s->EOL(); } s->IndentLess(); } else { - s->Printf(", %sresolved, %s, hit count = %u", + s->Printf(", %sresolved, hit count = %u ", (IsResolved() ? "" : "un"), - (IsEnabled() ? "enabled" : "disabled"), GetHitCount()); + if (m_options_ap.get()) + { + m_options_ap->GetDescription (s, level); + } } } @@ -385,7 +380,8 @@ BreakpointLocation::Dump(Stream *s) const if (s == NULL) return; - s->Printf("BreakpointLocation %u: tid = %4.4x load addr = 0x%8.8llx state = %s type = %s breakpoint hw_index = %i hit_count = %-4u ignore_count = %-4u", + s->Printf("BreakpointLocation %u: tid = %4.4x load addr = 0x%8.8llx state = %s type = %s breakpoint " + "hw_index = %i hit_count = %-4u ignore_count = %-4u", GetID(), GetOptionsNoCopy()->GetThreadSpec()->GetTID(), (uint64_t) m_address.GetLoadAddress(m_owner.GetTarget().GetProcessSP().get()), diff --git a/lldb/source/Breakpoint/BreakpointOptions.cpp b/lldb/source/Breakpoint/BreakpointOptions.cpp index 695f4ee5ccd..c3625140d76 100644 --- a/lldb/source/Breakpoint/BreakpointOptions.cpp +++ b/lldb/source/Breakpoint/BreakpointOptions.cpp @@ -71,6 +71,21 @@ BreakpointOptions::operator=(const BreakpointOptions& rhs) return *this; } +BreakpointOptions * +BreakpointOptions::CopyOptionsNoCallback (BreakpointOptions &orig) +{ + BreakpointHitCallback orig_callback = orig.m_callback; + lldb::BatonSP orig_callback_baton_sp = orig.m_callback_baton_sp; + bool orig_is_sync = orig.m_callback_is_synchronous; + + orig.ClearCallback(); + BreakpointOptions *ret_val = new BreakpointOptions(orig); + + orig.SetCallback (orig_callback, orig_callback_baton_sp, orig_is_sync); + + return ret_val; +} + //---------------------------------------------------------------------- // Destructor //---------------------------------------------------------------------- @@ -124,6 +139,12 @@ BreakpointOptions::InvokeCallback (StoppointCallbackContext *context, return true; } +bool +BreakpointOptions::HasCallback () +{ + return m_callback != BreakpointOptions::NullCallback; +} + //------------------------------------------------------------------ // Enabled/Ignore Count //------------------------------------------------------------------ @@ -173,10 +194,68 @@ BreakpointOptions::SetThreadID (lldb::tid_t thread_id) } void +BreakpointOptions::GetDescription (Stream *s, lldb::DescriptionLevel level) const +{ + + // Figure out if there are any options not at their default value, and only print + // anything if there are: + + if (m_ignore_count != 0 || !m_enabled || (GetThreadSpec() != NULL && GetThreadSpec()->HasSpecification ())) + { + if (level == lldb::eDescriptionLevelVerbose) + { + s->EOL (); + s->IndentMore(); + s->Indent(); + s->PutCString("Breakpoint Options:\n"); + s->IndentMore(); + s->Indent(); + } + else + s->PutCString(" Options: "); + + if (m_ignore_count > 0) + s->Printf("ignore: %d ", m_ignore_count); + s->Printf("%sabled ", m_enabled ? "en" : "dis"); + + if (m_thread_spec_ap.get()) + m_thread_spec_ap->GetDescription (s, level); + else if (level == eDescriptionLevelBrief) + s->PutCString ("thread spec: no "); + if (level == lldb::eDescriptionLevelFull) + { + s->IndentLess(); + s->IndentMore(); + } + } + + if (m_callback_baton_sp.get()) + { + if (level != eDescriptionLevelBrief) + s->EOL(); + m_callback_baton_sp->GetDescription (s, level); + } + else if (level == eDescriptionLevelBrief) + s->PutCString ("commands: no "); + +} + +void BreakpointOptions::CommandBaton::GetDescription (Stream *s, lldb::DescriptionLevel level) const { - s->Indent("Breakpoint commands:\n"); CommandData *data = (CommandData *)m_data; + + if (level == eDescriptionLevelBrief) + { + if (data && data->user_source.GetSize() > 0) + s->PutCString("commands: yes "); + else + s->PutCString("commands: no "); + return; + } + + s->IndentMore (); + s->Indent("Breakpoint commands:\n"); s->IndentMore (); if (data && data->user_source.GetSize() > 0) @@ -193,5 +272,6 @@ BreakpointOptions::CommandBaton::GetDescription (Stream *s, lldb::DescriptionLev s->PutCString ("No commands.\n"); } s->IndentLess (); + s->IndentLess (); } diff --git a/lldb/source/Target/Thread.cpp b/lldb/source/Target/Thread.cpp index 510988a1591..97a55fb7434 100644 --- a/lldb/source/Target/Thread.cpp +++ b/lldb/source/Target/Thread.cpp @@ -617,20 +617,8 @@ Thread::MatchesSpec (const ThreadSpec *spec) { if (spec == NULL) return true; - - if (!spec->TIDMatches(GetID())) - return false; - if (!spec->IndexMatches(GetIndexID())) - return false; - - if (!spec->NameMatches (GetName())) - return false; - - if (!spec->QueueNameMatches (GetQueueName())) - return false; - - return true; + return spec->ThreadPassesBasicTests(this); } void diff --git a/lldb/source/Target/ThreadSpec.cpp b/lldb/source/Target/ThreadSpec.cpp index 5d1089188fe..e2965582688 100644 --- a/lldb/source/Target/ThreadSpec.cpp +++ b/lldb/source/Target/ThreadSpec.cpp @@ -56,3 +56,67 @@ ThreadSpec::GetQueueName () const else return m_queue_name.c_str(); } + +bool +ThreadSpec::ThreadPassesBasicTests (Thread *thread) const +{ + + if (!HasSpecification()) + return true; + + if (!TIDMatches(thread->GetID())) + return false; + + if (!IndexMatches(thread->GetIndexID())) + return false; + + if (!NameMatches (thread->GetName())) + return false; + + if (!QueueNameMatches (thread->GetQueueName())) + return false; + + return true; + +} + +bool +ThreadSpec::HasSpecification() const +{ + return (m_index != -1 || m_tid != LLDB_INVALID_THREAD_ID || !m_name.empty() || !m_queue_name.empty()); +} +void +ThreadSpec::GetDescription (Stream *s, lldb::DescriptionLevel level) const +{ + if (!HasSpecification()) + { + if (level == eDescriptionLevelBrief) + { + s->PutCString("thread spec: no "); + } + } + else + { + if (level == eDescriptionLevelBrief) + { + s->PutCString("thread spec: yes "); + } + else + { + if (GetTID() != LLDB_INVALID_THREAD_ID) + s->Printf("tid: 0x%llx ", GetTID()); + + if (GetIndex() != -1) + s->Printf("index: %d ", GetIndex()); + + const char *name = GetName(); + if (name) + s->Printf ("thread name: \"%s\" ", name); + + const char *queue_name = GetQueueName(); + if (queue_name) + s->Printf ("queue name: \"%s\" ", queue_name); + } + + } +} |