diff options
| author | Jim Ingham <jingham@apple.com> | 2017-08-03 18:13:24 +0000 |
|---|---|---|
| committer | Jim Ingham <jingham@apple.com> | 2017-08-03 18:13:24 +0000 |
| commit | f08f5c99262ff9eaa08956334accbb2614b0f7a2 (patch) | |
| tree | 7627308ccb3fc7ce52a6ea0ea45c0d948fcd66af /lldb/source/Breakpoint | |
| parent | f0cadcd9f385d36dc751cdb32476b32ec43306b5 (diff) | |
| download | bcm5719-llvm-f08f5c99262ff9eaa08956334accbb2614b0f7a2.tar.gz bcm5719-llvm-f08f5c99262ff9eaa08956334accbb2614b0f7a2.zip | |
Add an auto-continue flag to breakpoints & locations.
You can get a breakpoint to auto-continue by adding "continue"
as a command, but that has the disadvantage that if you hit two
breakpoints simultaneously, the continue will force the process
to continue, and maybe even forstalling the commands on the other.
The auto-continue flag means the breakpoints can negotiate about
whether to stop.
Writing tests, I wanted to supply some commands when I made the
breakpoints, so I also added that ability.
llvm-svn: 309969
Diffstat (limited to 'lldb/source/Breakpoint')
| -rw-r--r-- | lldb/source/Breakpoint/Breakpoint.cpp | 8 | ||||
| -rw-r--r-- | lldb/source/Breakpoint/BreakpointLocation.cpp | 13 | ||||
| -rw-r--r-- | lldb/source/Breakpoint/BreakpointOptions.cpp | 38 |
3 files changed, 52 insertions, 7 deletions
diff --git a/lldb/source/Breakpoint/Breakpoint.cpp b/lldb/source/Breakpoint/Breakpoint.cpp index 043e5e8f591..fd606aa83d6 100644 --- a/lldb/source/Breakpoint/Breakpoint.cpp +++ b/lldb/source/Breakpoint/Breakpoint.cpp @@ -348,6 +348,14 @@ void Breakpoint::SetOneShot(bool one_shot) { m_options_up->SetOneShot(one_shot); } +bool Breakpoint::IsAutoContinue() const { + return m_options_up->IsAutoContinue(); +} + +void Breakpoint::SetAutoContinue(bool auto_continue) { + m_options_up->SetAutoContinue(auto_continue); +} + void Breakpoint::SetThreadID(lldb::tid_t thread_id) { if (m_options_up->GetThreadSpec()->GetTID() == thread_id) return; diff --git a/lldb/source/Breakpoint/BreakpointLocation.cpp b/lldb/source/Breakpoint/BreakpointLocation.cpp index 15865be3f9a..f59c334fe5c 100644 --- a/lldb/source/Breakpoint/BreakpointLocation.cpp +++ b/lldb/source/Breakpoint/BreakpointLocation.cpp @@ -93,6 +93,19 @@ void BreakpointLocation::SetEnabled(bool enabled) { : eBreakpointEventTypeDisabled); } +bool BreakpointLocation::IsAutoContinue() const { + if (m_options_ap + && m_options_ap->IsOptionSet(BreakpointOptions::eAutoContinue)) + return m_options_ap->IsAutoContinue(); + else + return m_owner.IsAutoContinue(); +} + +void BreakpointLocation::SetAutoContinue(bool auto_continue) { + GetLocationOptions()->SetAutoContinue(auto_continue); + SendBreakpointLocationChangedEvent(eBreakpointEventTypeAutoContinueChanged); +} + void BreakpointLocation::SetThreadID(lldb::tid_t thread_id) { if (thread_id != LLDB_INVALID_THREAD_ID) GetLocationOptions()->SetThreadID(thread_id); diff --git a/lldb/source/Breakpoint/BreakpointOptions.cpp b/lldb/source/Breakpoint/BreakpointOptions.cpp index 3e8d3dd41f3..7159688102d 100644 --- a/lldb/source/Breakpoint/BreakpointOptions.cpp +++ b/lldb/source/Breakpoint/BreakpointOptions.cpp @@ -114,7 +114,8 @@ BreakpointOptions::CommandData::CreateFromStructuredData( const char *BreakpointOptions::g_option_names[( size_t)BreakpointOptions::OptionNames::LastOptionName]{ - "ConditionText", "IgnoreCount", "EnabledState", "OneShotState"}; + "ConditionText", "IgnoreCount", + "EnabledState", "OneShotState", "AutoContinue"}; bool BreakpointOptions::NullCallback(void *baton, StoppointCallbackContext *context, @@ -130,20 +131,22 @@ BreakpointOptions::BreakpointOptions(bool all_flags_set) : m_callback(BreakpointOptions::NullCallback), m_callback_baton_sp(), m_baton_is_command_baton(false), m_callback_is_synchronous(false), m_enabled(true), m_one_shot(false), m_ignore_count(0), m_thread_spec_ap(), - m_condition_text(), m_condition_text_hash(0), + m_condition_text(), m_condition_text_hash(0), m_auto_continue(false), m_set_flags() { if (all_flags_set) m_set_flags.Set(~((Flags::ValueType) 0)); } BreakpointOptions::BreakpointOptions(const char *condition, bool enabled, - int32_t ignore, bool one_shot) + int32_t ignore, bool one_shot, + bool auto_continue) : m_callback(nullptr), m_baton_is_command_baton(false), m_callback_is_synchronous(false), m_enabled(enabled), m_one_shot(one_shot), m_ignore_count(ignore), m_condition_text(condition), - m_condition_text_hash(0) + m_condition_text_hash(0), m_auto_continue(auto_continue) { - m_set_flags.Set(eEnabled | eIgnoreCount | eOneShot | eCondition); + m_set_flags.Set(eEnabled | eIgnoreCount | eOneShot + | eCondition | eAutoContinue); } //---------------------------------------------------------------------- @@ -155,6 +158,7 @@ BreakpointOptions::BreakpointOptions(const BreakpointOptions &rhs) m_callback_is_synchronous(rhs.m_callback_is_synchronous), m_enabled(rhs.m_enabled), m_one_shot(rhs.m_one_shot), m_ignore_count(rhs.m_ignore_count), m_thread_spec_ap(), + m_auto_continue(rhs.m_auto_continue), m_set_flags(rhs.m_set_flags) { if (rhs.m_thread_spec_ap.get() != nullptr) m_thread_spec_ap.reset(new ThreadSpec(*rhs.m_thread_spec_ap.get())); @@ -178,6 +182,7 @@ operator=(const BreakpointOptions &rhs) { m_thread_spec_ap.reset(new ThreadSpec(*rhs.m_thread_spec_ap.get())); m_condition_text = rhs.m_condition_text; m_condition_text_hash = rhs.m_condition_text_hash; + m_auto_continue = rhs.m_auto_continue; m_set_flags = rhs.m_set_flags; return *this; } @@ -192,6 +197,7 @@ std::unique_ptr<BreakpointOptions> BreakpointOptions::CreateFromStructuredData( Status &error) { bool enabled = true; bool one_shot = false; + bool auto_continue = false; int32_t ignore_count = 0; llvm::StringRef condition_ref(""); Flags set_options; @@ -219,6 +225,17 @@ std::unique_ptr<BreakpointOptions> BreakpointOptions::CreateFromStructuredData( set_options.Set(eOneShot); } + key = GetKey(OptionNames::AutoContinue); + if (key) { + success = options_dict.GetValueForKeyAsBoolean(key, auto_continue); + if (!success) { + error.SetErrorStringWithFormat("%s key is not a boolean.", + GetKey(OptionNames::AutoContinue)); + return nullptr; + } + set_options.Set(eAutoContinue); + } + key = GetKey(OptionNames::IgnoreCount); if (key) { success = options_dict.GetValueForKeyAsInteger(key, ignore_count); @@ -257,7 +274,8 @@ std::unique_ptr<BreakpointOptions> BreakpointOptions::CreateFromStructuredData( } auto bp_options = llvm::make_unique<BreakpointOptions>( - condition_ref.str().c_str(), enabled, ignore_count, one_shot); + condition_ref.str().c_str(), enabled, + ignore_count, one_shot, auto_continue); if (cmd_data_up.get()) { if (cmd_data_up->interpreter == eScriptLanguageNone) bp_options->SetCommandDataCallback(cmd_data_up); @@ -315,6 +333,9 @@ StructuredData::ObjectSP BreakpointOptions::SerializeToStructuredData() { if (m_set_flags.Set(eOneShot)) options_dict_sp->AddBooleanItem(GetKey(OptionNames::OneShotState), m_one_shot); + if (m_set_flags.Set(eAutoContinue)) + options_dict_sp->AddBooleanItem(GetKey(OptionNames::AutoContinue), + m_auto_continue); if (m_set_flags.Set(eIgnoreCount)) options_dict_sp->AddIntegerItem(GetKey(OptionNames::IgnoreCount), m_ignore_count); @@ -471,7 +492,7 @@ void BreakpointOptions::GetDescription(Stream *s, // print // anything if there are: - if (m_ignore_count != 0 || !m_enabled || m_one_shot || + if (m_ignore_count != 0 || !m_enabled || m_one_shot || m_auto_continue || (GetThreadSpecNoCreate() != nullptr && GetThreadSpecNoCreate()->HasSpecification())) { if (level == lldb::eDescriptionLevelVerbose) { @@ -491,6 +512,9 @@ void BreakpointOptions::GetDescription(Stream *s, if (m_one_shot) s->Printf("one-shot "); + if (m_auto_continue) + s->Printf("auto-continue "); + if (m_thread_spec_ap.get()) m_thread_spec_ap->GetDescription(s, level); |

