summaryrefslogtreecommitdiffstats
path: root/lldb/source/Breakpoint
diff options
context:
space:
mode:
authorJim Ingham <jingham@apple.com>2017-08-03 18:13:24 +0000
committerJim Ingham <jingham@apple.com>2017-08-03 18:13:24 +0000
commitf08f5c99262ff9eaa08956334accbb2614b0f7a2 (patch)
tree7627308ccb3fc7ce52a6ea0ea45c0d948fcd66af /lldb/source/Breakpoint
parentf0cadcd9f385d36dc751cdb32476b32ec43306b5 (diff)
downloadbcm5719-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.cpp8
-rw-r--r--lldb/source/Breakpoint/BreakpointLocation.cpp13
-rw-r--r--lldb/source/Breakpoint/BreakpointOptions.cpp38
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);
OpenPOWER on IntegriCloud