summaryrefslogtreecommitdiffstats
path: root/lldb/source
diff options
context:
space:
mode:
Diffstat (limited to 'lldb/source')
-rw-r--r--lldb/source/API/SBBreakpoint.cpp68
-rw-r--r--lldb/source/API/SBBreakpointName.cpp662
-rw-r--r--lldb/source/API/SBBreakpointOptionCommon.cpp84
-rw-r--r--lldb/source/API/SBBreakpointOptionCommon.h35
-rw-r--r--lldb/source/API/SBDebugger.cpp14
-rw-r--r--lldb/source/API/SBTarget.cpp33
-rw-r--r--lldb/source/Breakpoint/Breakpoint.cpp20
-rw-r--r--lldb/source/Breakpoint/BreakpointID.cpp11
-rw-r--r--lldb/source/Breakpoint/BreakpointIDList.cpp34
-rw-r--r--lldb/source/Breakpoint/BreakpointList.cpp33
-rw-r--r--lldb/source/Breakpoint/BreakpointName.cpp88
-rw-r--r--lldb/source/Breakpoint/BreakpointOptions.cpp91
-rw-r--r--lldb/source/Commands/CommandObjectBreakpoint.cpp1017
-rw-r--r--lldb/source/Commands/CommandObjectBreakpoint.h19
-rw-r--r--lldb/source/Commands/CommandObjectBreakpointCommand.cpp9
-rw-r--r--lldb/source/Interpreter/CommandObject.cpp3
-rw-r--r--lldb/source/Plugins/LanguageRuntime/RenderScript/RenderScriptRuntime/RenderScriptRuntime.cpp24
-rw-r--r--lldb/source/Target/Target.cpp140
18 files changed, 1827 insertions, 558 deletions
diff --git a/lldb/source/API/SBBreakpoint.cpp b/lldb/source/API/SBBreakpoint.cpp
index 9abdce0c928..6a0ff9536c2 100644
--- a/lldb/source/API/SBBreakpoint.cpp
+++ b/lldb/source/API/SBBreakpoint.cpp
@@ -37,6 +37,8 @@
#include "lldb/Utility/Log.h"
#include "lldb/Utility/Stream.h"
+#include "SBBreakpointOptionCommon.h"
+
#include "lldb/lldb-enumerations.h"
#include "llvm/ADT/STLExtras.h"
@@ -44,21 +46,6 @@
using namespace lldb;
using namespace lldb_private;
-struct CallbackData {
- SBBreakpoint::BreakpointHitCallback callback;
- void *callback_baton;
-};
-
-class SBBreakpointCallbackBaton : public TypedBaton<CallbackData> {
-public:
- SBBreakpointCallbackBaton(SBBreakpoint::BreakpointHitCallback callback,
- void *baton)
- : TypedBaton(llvm::make_unique<CallbackData>()) {
- getItem()->callback = callback;
- getItem()->callback_baton = baton;
- }
-};
-
SBBreakpoint::SBBreakpoint() {}
SBBreakpoint::SBBreakpoint(const SBBreakpoint &rhs)
@@ -500,37 +487,9 @@ bool SBBreakpoint::GetDescription(SBStream &s, bool include_locations) {
return false;
}
-bool SBBreakpoint::PrivateBreakpointHitCallback(void *baton,
- StoppointCallbackContext *ctx,
- lldb::user_id_t break_id,
- lldb::user_id_t break_loc_id) {
- ExecutionContext exe_ctx(ctx->exe_ctx_ref);
- BreakpointSP bp_sp(
- exe_ctx.GetTargetRef().GetBreakpointList().FindBreakpointByID(break_id));
- if (baton && bp_sp) {
- CallbackData *data = (CallbackData *)baton;
- lldb_private::Breakpoint *bp = bp_sp.get();
- if (bp && data->callback) {
- Process *process = exe_ctx.GetProcessPtr();
- if (process) {
- SBProcess sb_process(process->shared_from_this());
- SBThread sb_thread;
- SBBreakpointLocation sb_location;
- assert(bp_sp);
- sb_location.SetLocation(bp_sp->FindLocationByID(break_loc_id));
- Thread *thread = exe_ctx.GetThreadPtr();
- if (thread)
- sb_thread.SetThread(thread->shared_from_this());
-
- return data->callback(data->callback_baton, sb_process, sb_thread,
- sb_location);
- }
- }
- }
- return true; // Return true if we should stop at this breakpoint
-}
-
-void SBBreakpoint::SetCallback(BreakpointHitCallback callback, void *baton) {
+void SBBreakpoint
+ ::SetCallback(SBBreakpointHitCallback callback,
+ void *baton) {
Log *log(lldb_private::GetLogIfAllCategoriesSet(LIBLLDB_LOG_API));
BreakpointSP bkpt_sp = GetSP();
LLDB_LOG(log, "breakpoint = {0}, callback = {1}, baton = {2}", bkpt_sp.get(),
@@ -540,7 +499,8 @@ void SBBreakpoint::SetCallback(BreakpointHitCallback callback, void *baton) {
std::lock_guard<std::recursive_mutex> guard(
bkpt_sp->GetTarget().GetAPIMutex());
BatonSP baton_sp(new SBBreakpointCallbackBaton(callback, baton));
- bkpt_sp->SetCallback(SBBreakpoint::PrivateBreakpointHitCallback, baton_sp,
+ bkpt_sp->SetCallback(SBBreakpointCallbackBaton
+ ::PrivateBreakpointHitCallback, baton_sp,
false);
}
}
@@ -599,10 +559,17 @@ bool SBBreakpoint::AddName(const char *new_name) {
bkpt_sp->GetTarget().GetAPIMutex());
Status error; // Think I'm just going to swallow the error here, it's
// probably more annoying to have to provide it.
- return bkpt_sp->AddName(new_name, error);
+ bkpt_sp->GetTarget().AddNameToBreakpoint(bkpt_sp, new_name, error);
+ if (error.Fail())
+ {
+ if (log)
+ log->Printf("Failed to add name: '%s' to breakpoint: %s",
+ new_name, error.AsCString());
+ return false;
+ }
}
- return false;
+ return true;
}
void SBBreakpoint::RemoveName(const char *name_to_remove) {
@@ -613,7 +580,8 @@ void SBBreakpoint::RemoveName(const char *name_to_remove) {
if (bkpt_sp) {
std::lock_guard<std::recursive_mutex> guard(
bkpt_sp->GetTarget().GetAPIMutex());
- bkpt_sp->RemoveName(name_to_remove);
+ bkpt_sp->GetTarget().RemoveNameFromBreakpoint(bkpt_sp,
+ ConstString(name_to_remove));
}
}
diff --git a/lldb/source/API/SBBreakpointName.cpp b/lldb/source/API/SBBreakpointName.cpp
new file mode 100644
index 00000000000..b2ed5e71699
--- /dev/null
+++ b/lldb/source/API/SBBreakpointName.cpp
@@ -0,0 +1,662 @@
+//===-- SBBreakpointName.cpp ----------------------------------------*- C++ -*-===//
+//
+// The LLVM Compiler Infrastructure
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+
+// C Includes
+// C++ Includes
+// Other libraries and framework includes
+// Project includes
+#include "lldb/API/SBBreakpointName.h"
+#include "lldb/API/SBDebugger.h"
+#include "lldb/API/SBError.h"
+#include "lldb/API/SBStream.h"
+#include "lldb/API/SBStringList.h"
+#include "lldb/API/SBTarget.h"
+
+#include "lldb/Breakpoint/BreakpointName.h"
+#include "lldb/Breakpoint/StoppointCallbackContext.h"
+#include "lldb/Core/Debugger.h"
+#include "lldb/Interpreter/CommandInterpreter.h"
+#include "lldb/Interpreter/ScriptInterpreter.h"
+#include "lldb/Target/Target.h"
+#include "lldb/Target/ThreadSpec.h"
+#include "lldb/Utility/Log.h"
+#include "lldb/Utility/Stream.h"
+
+#include "SBBreakpointOptionCommon.h"
+
+using namespace lldb;
+using namespace lldb_private;
+
+namespace lldb
+{
+class SBBreakpointNameImpl {
+public:
+ SBBreakpointNameImpl(SBTarget &sb_target, const char *name)
+ {
+ if (!name || name[0] == '\0')
+ return;
+ m_name.assign(name);
+
+ if (!sb_target.IsValid())
+ return;
+
+ TargetSP target_sp = sb_target.GetSP();
+ if (!target_sp)
+ return;
+
+ m_target_wp = target_sp;
+ }
+
+ SBBreakpointNameImpl(TargetSP target_sp, const char *name)
+ {
+ if (!name || name[0] == '\0')
+ return;
+ m_name.assign(name);
+
+ if (!target_sp)
+ return;
+
+ m_target_wp = target_sp;
+ }
+
+ bool operator==(const SBBreakpointNameImpl &rhs) {
+ return m_name == rhs.m_name
+ && m_target_wp.lock() == rhs.m_target_wp.lock();
+ }
+
+ bool operator!=(const SBBreakpointNameImpl &rhs) {
+ return m_name != rhs.m_name
+ || m_target_wp.lock() != rhs.m_target_wp.lock();
+ }
+ // For now we take a simple approach and only keep the name, and relook
+ // up the location when we need it.
+
+ TargetSP GetTarget() {
+ return m_target_wp.lock();
+ }
+
+ const char *GetName() {
+ return m_name.c_str();
+ }
+
+ bool IsValid() {
+ return !m_name.empty() && m_target_wp.lock();
+ }
+
+ lldb_private::BreakpointName *GetBreakpointName()
+ {
+ if (!IsValid())
+ return nullptr;
+ TargetSP target_sp = GetTarget();
+ if (!target_sp)
+ return nullptr;
+ Status error;
+ return target_sp->FindBreakpointName(ConstString(m_name), true, error);
+ }
+
+ const lldb_private::BreakpointName *GetBreakpointName() const
+ {
+ return GetBreakpointName();
+ }
+
+private:
+ TargetWP m_target_wp;
+ std::string m_name;
+};
+} // namespace lldb
+
+SBBreakpointName::SBBreakpointName() {}
+
+SBBreakpointName::SBBreakpointName(SBTarget &sb_target, const char *name)
+{
+ m_impl_up.reset(new SBBreakpointNameImpl(sb_target, name));
+ // Call FindBreakpointName here to make sure the name is valid, reset if
+ // not:
+ BreakpointName *bp_name = GetBreakpointName();
+ if (!bp_name)
+ m_impl_up.reset();
+}
+
+SBBreakpointName::SBBreakpointName(SBBreakpoint &sb_bkpt, const char *name)
+{
+ if (!sb_bkpt.IsValid()) {
+ m_impl_up.reset();
+ return;
+ }
+ BreakpointSP bkpt_sp = sb_bkpt.GetSP();
+ Target &target = bkpt_sp->GetTarget();
+
+ m_impl_up.reset(new SBBreakpointNameImpl(target.shared_from_this(), name));
+
+ // Call FindBreakpointName here to make sure the name is valid, reset if
+ // not:
+ BreakpointName *bp_name = GetBreakpointName();
+ if (!bp_name) {
+ m_impl_up.reset();
+ return;
+ }
+
+ // Now copy over the breakpoint's options:
+ target.ConfigureBreakpointName(*bp_name, *bkpt_sp->GetOptions(),
+ BreakpointName::Permissions());
+}
+
+SBBreakpointName::SBBreakpointName(const SBBreakpointName &rhs)
+{
+ if (!rhs.m_impl_up)
+ return;
+ else
+ m_impl_up.reset(new SBBreakpointNameImpl(rhs.m_impl_up->GetTarget(),
+ rhs.m_impl_up->GetName()));
+}
+
+SBBreakpointName::~SBBreakpointName() = default;
+
+const SBBreakpointName &SBBreakpointName::operator=(const SBBreakpointName &rhs)
+{
+ if (!rhs.m_impl_up) {
+ m_impl_up.reset();
+ return *this;
+ }
+
+ m_impl_up.reset(new SBBreakpointNameImpl(rhs.m_impl_up->GetTarget(),
+ rhs.m_impl_up->GetName()));
+ return *this;
+}
+
+bool SBBreakpointName::operator==(const lldb::SBBreakpointName &rhs) {
+ return *m_impl_up.get() == *rhs.m_impl_up.get();
+}
+
+bool SBBreakpointName::operator!=(const lldb::SBBreakpointName &rhs) {
+ return *m_impl_up.get() != *rhs.m_impl_up.get();
+}
+
+bool SBBreakpointName::IsValid() const {
+ if (!m_impl_up)
+ return false;
+ return m_impl_up->IsValid();
+}
+
+const char *SBBreakpointName::GetName() const {
+ if (!m_impl_up)
+ return "<Invalid Breakpoint Name Object>";
+ return m_impl_up->GetName();
+}
+
+void SBBreakpointName::SetEnabled(bool enable) {
+ Log *log(lldb_private::GetLogIfAllCategoriesSet(LIBLLDB_LOG_API));
+
+ BreakpointName *bp_name = GetBreakpointName();
+ if (!bp_name)
+ return;
+
+ LLDB_LOG(log, "Name: {0} enabled: {1}\n", bp_name->GetName(), enable);
+ std::lock_guard<std::recursive_mutex> guard(
+ m_impl_up->GetTarget()->GetAPIMutex());
+
+ bp_name->GetOptions().SetEnabled(enable);
+}
+
+void SBBreakpointName::UpdateName(BreakpointName &bp_name) {
+ if (!IsValid())
+ return;
+
+ TargetSP target_sp = m_impl_up->GetTarget();
+ if (!target_sp)
+ return;
+ target_sp->ApplyNameToBreakpoints(bp_name);
+
+}
+
+bool SBBreakpointName::IsEnabled() {
+ Log *log(lldb_private::GetLogIfAllCategoriesSet(LIBLLDB_LOG_API));
+
+ BreakpointName *bp_name = GetBreakpointName();
+ if (!bp_name)
+ return false;
+
+ LLDB_LOG(log, "Name: {0}\n", bp_name->GetName());
+ std::lock_guard<std::recursive_mutex> guard(
+ m_impl_up->GetTarget()->GetAPIMutex());
+
+ return bp_name->GetOptions().IsEnabled();
+}
+
+void SBBreakpointName::SetOneShot(bool one_shot) {
+ Log *log(lldb_private::GetLogIfAllCategoriesSet(LIBLLDB_LOG_API));
+
+ BreakpointName *bp_name = GetBreakpointName();
+ if (!bp_name)
+ return;
+
+ LLDB_LOG(log, "Name: {0} one_shot: {1}\n", bp_name->GetName(), one_shot);
+ std::lock_guard<std::recursive_mutex> guard(
+ m_impl_up->GetTarget()->GetAPIMutex());
+
+ bp_name->GetOptions().SetOneShot(one_shot);
+ UpdateName(*bp_name);
+}
+
+bool SBBreakpointName::IsOneShot() const {
+ Log *log(lldb_private::GetLogIfAllCategoriesSet(LIBLLDB_LOG_API));
+
+ const BreakpointName *bp_name = GetBreakpointName();
+ if (!bp_name)
+ return false;
+
+ LLDB_LOG(log, "Name: {0}\n", bp_name->GetName());
+ std::lock_guard<std::recursive_mutex> guard(
+ m_impl_up->GetTarget()->GetAPIMutex());
+
+ return bp_name->GetOptions().IsOneShot();
+}
+
+void SBBreakpointName::SetIgnoreCount(uint32_t count) {
+ Log *log(lldb_private::GetLogIfAllCategoriesSet(LIBLLDB_LOG_API));
+
+ BreakpointName *bp_name = GetBreakpointName();
+ if (!bp_name)
+ return;
+
+ LLDB_LOG(log, "Name: {0} one_shot: {1}\n", bp_name->GetName(), count);
+ std::lock_guard<std::recursive_mutex> guard(
+ m_impl_up->GetTarget()->GetAPIMutex());
+
+ bp_name->GetOptions().SetIgnoreCount(count);
+ UpdateName(*bp_name);
+}
+
+uint32_t SBBreakpointName::GetIgnoreCount() const {
+ Log *log(lldb_private::GetLogIfAllCategoriesSet(LIBLLDB_LOG_API));
+
+ BreakpointName *bp_name = GetBreakpointName();
+ if (!bp_name)
+ return false;
+
+ LLDB_LOG(log, "Name: {0}\n", bp_name->GetName());
+ std::lock_guard<std::recursive_mutex> guard(
+ m_impl_up->GetTarget()->GetAPIMutex());
+
+ return bp_name->GetOptions().GetIgnoreCount();
+}
+
+void SBBreakpointName::SetCondition(const char *condition) {
+ Log *log(lldb_private::GetLogIfAllCategoriesSet(LIBLLDB_LOG_API));
+
+ BreakpointName *bp_name = GetBreakpointName();
+ if (!bp_name)
+ return;
+
+ LLDB_LOG(log, "Name: {0} one_shot: {1}\n", bp_name->GetName(),
+ condition ? condition : "<NULL>");
+
+ std::lock_guard<std::recursive_mutex> guard(
+ m_impl_up->GetTarget()->GetAPIMutex());
+
+ bp_name->GetOptions().SetCondition(condition);
+ UpdateName(*bp_name);
+}
+
+const char *SBBreakpointName::GetCondition() {
+ Log *log(lldb_private::GetLogIfAllCategoriesSet(LIBLLDB_LOG_API));
+
+ BreakpointName *bp_name = GetBreakpointName();
+ if (!bp_name)
+ return nullptr;
+
+ LLDB_LOG(log, "Name: {0}\n", bp_name->GetName());
+ std::lock_guard<std::recursive_mutex> guard(
+ m_impl_up->GetTarget()->GetAPIMutex());
+
+ return bp_name->GetOptions().GetConditionText();
+}
+
+void SBBreakpointName::SetAutoContinue(bool auto_continue) {
+ Log *log(lldb_private::GetLogIfAllCategoriesSet(LIBLLDB_LOG_API));
+
+ BreakpointName *bp_name = GetBreakpointName();
+ if (!bp_name)
+ return;
+
+ LLDB_LOG(log, "Name: {0} auto-continue: {1}\n", bp_name->GetName(), auto_continue);
+
+ std::lock_guard<std::recursive_mutex> guard(
+ m_impl_up->GetTarget()->GetAPIMutex());
+
+ bp_name->GetOptions().SetAutoContinue(auto_continue);
+ UpdateName(*bp_name);
+}
+
+bool SBBreakpointName::GetAutoContinue() {
+ Log *log(lldb_private::GetLogIfAllCategoriesSet(LIBLLDB_LOG_API));
+
+ BreakpointName *bp_name = GetBreakpointName();
+ if (!bp_name)
+ return nullptr;
+
+ LLDB_LOG(log, "Name: {0}\n", bp_name->GetName());
+ std::lock_guard<std::recursive_mutex> guard(
+ m_impl_up->GetTarget()->GetAPIMutex());
+
+ return bp_name->GetOptions().IsAutoContinue();
+}
+
+void SBBreakpointName::SetThreadID(tid_t tid) {
+ Log *log(lldb_private::GetLogIfAllCategoriesSet(LIBLLDB_LOG_API));
+
+ BreakpointName *bp_name = GetBreakpointName();
+ if (!bp_name)
+ return;
+
+ LLDB_LOG(log, "Name: {0} tid: {1:x}\n", bp_name->GetName(), tid);
+
+ std::lock_guard<std::recursive_mutex> guard(
+ m_impl_up->GetTarget()->GetAPIMutex());
+
+ bp_name->GetOptions().SetThreadID(tid);
+ UpdateName(*bp_name);
+}
+
+tid_t SBBreakpointName::GetThreadID() {
+ Log *log(lldb_private::GetLogIfAllCategoriesSet(LIBLLDB_LOG_API));
+
+ BreakpointName *bp_name = GetBreakpointName();
+ if (!bp_name)
+ return LLDB_INVALID_THREAD_ID;
+
+ LLDB_LOG(log, "Name: {0}\n", bp_name->GetName());
+ std::lock_guard<std::recursive_mutex> guard(
+ m_impl_up->GetTarget()->GetAPIMutex());
+
+ return bp_name->GetOptions().GetThreadSpec()->GetTID();
+}
+
+void SBBreakpointName::SetThreadIndex(uint32_t index) {
+ Log *log(lldb_private::GetLogIfAllCategoriesSet(LIBLLDB_LOG_API));
+
+ BreakpointName *bp_name = GetBreakpointName();
+ if (!bp_name)
+ return;
+
+ LLDB_LOG(log, "Name: {0} thread index: {1}\n", bp_name->GetName(), index);
+
+ std::lock_guard<std::recursive_mutex> guard(
+ m_impl_up->GetTarget()->GetAPIMutex());
+
+ bp_name->GetOptions().GetThreadSpec()->SetIndex(index);
+ UpdateName(*bp_name);
+}
+
+uint32_t SBBreakpointName::GetThreadIndex() const {
+ Log *log(lldb_private::GetLogIfAllCategoriesSet(LIBLLDB_LOG_API));
+
+ BreakpointName *bp_name = GetBreakpointName();
+ if (!bp_name)
+ return LLDB_INVALID_THREAD_ID;
+
+ LLDB_LOG(log, "Name: {0}\n", bp_name->GetName());
+ std::lock_guard<std::recursive_mutex> guard(
+ m_impl_up->GetTarget()->GetAPIMutex());
+
+ return bp_name->GetOptions().GetThreadSpec()->GetIndex();
+}
+
+void SBBreakpointName::SetThreadName(const char *thread_name) {
+ Log *log(lldb_private::GetLogIfAllCategoriesSet(LIBLLDB_LOG_API));
+
+ BreakpointName *bp_name = GetBreakpointName();
+ if (!bp_name)
+ return;
+
+ LLDB_LOG(log, "Name: {0} thread name: {1}\n", bp_name->GetName(), thread_name);
+
+ std::lock_guard<std::recursive_mutex> guard(
+ m_impl_up->GetTarget()->GetAPIMutex());
+
+ bp_name->GetOptions().GetThreadSpec()->SetName(thread_name);
+ UpdateName(*bp_name);
+}
+
+const char *SBBreakpointName::GetThreadName() const {
+ Log *log(lldb_private::GetLogIfAllCategoriesSet(LIBLLDB_LOG_API));
+
+ BreakpointName *bp_name = GetBreakpointName();
+ if (!bp_name)
+ return nullptr;
+
+ LLDB_LOG(log, "Name: {0}\n", bp_name->GetName());
+ std::lock_guard<std::recursive_mutex> guard(
+ m_impl_up->GetTarget()->GetAPIMutex());
+
+ return bp_name->GetOptions().GetThreadSpec()->GetName();
+}
+
+void SBBreakpointName::SetQueueName(const char *queue_name) {
+ Log *log(lldb_private::GetLogIfAllCategoriesSet(LIBLLDB_LOG_API));
+
+ BreakpointName *bp_name = GetBreakpointName();
+ if (!bp_name)
+ return;
+
+ LLDB_LOG(log, "Name: {0} queue name: {1}\n", bp_name->GetName(), queue_name);
+
+ std::lock_guard<std::recursive_mutex> guard(
+ m_impl_up->GetTarget()->GetAPIMutex());
+
+ bp_name->GetOptions().GetThreadSpec()->SetQueueName(queue_name);
+ UpdateName(*bp_name);
+}
+
+const char *SBBreakpointName::GetQueueName() const {
+ Log *log(lldb_private::GetLogIfAllCategoriesSet(LIBLLDB_LOG_API));
+
+ BreakpointName *bp_name = GetBreakpointName();
+ if (!bp_name)
+ return nullptr;
+
+ LLDB_LOG(log, "Name: {0}\n", bp_name->GetName());
+ std::lock_guard<std::recursive_mutex> guard(
+ m_impl_up->GetTarget()->GetAPIMutex());
+
+ return bp_name->GetOptions().GetThreadSpec()->GetQueueName();
+}
+
+void SBBreakpointName::SetCommandLineCommands(SBStringList &commands) {
+ Log *log(lldb_private::GetLogIfAllCategoriesSet(LIBLLDB_LOG_API));
+ BreakpointName *bp_name = GetBreakpointName();
+ if (!bp_name)
+ return;
+ if (commands.GetSize() == 0)
+ return;
+
+ LLDB_LOG(log, "Name: {0} commands\n", bp_name->GetName());
+
+ std::lock_guard<std::recursive_mutex> guard(
+ m_impl_up->GetTarget()->GetAPIMutex());
+ std::unique_ptr<BreakpointOptions::CommandData> cmd_data_up(
+ new BreakpointOptions::CommandData(*commands, eScriptLanguageNone));
+
+ bp_name->GetOptions().SetCommandDataCallback(cmd_data_up);
+ UpdateName(*bp_name);
+}
+
+bool SBBreakpointName::GetCommandLineCommands(SBStringList &commands) {
+ Log *log(lldb_private::GetLogIfAllCategoriesSet(LIBLLDB_LOG_API));
+
+ BreakpointName *bp_name = GetBreakpointName();
+ if (!bp_name)
+ return false;
+
+ LLDB_LOG(log, "Name: {0}\n", bp_name->GetName());
+ StringList command_list;
+ bool has_commands =
+ bp_name->GetOptions().GetCommandLineCallbacks(command_list);
+ if (has_commands)
+ commands.AppendList(command_list);
+ return has_commands;
+}
+
+bool SBBreakpointName::GetDescription(SBStream &s) {
+ Log *log(lldb_private::GetLogIfAllCategoriesSet(LIBLLDB_LOG_API));
+
+ BreakpointName *bp_name = GetBreakpointName();
+ if (!bp_name)
+ {
+ s.Printf("No value");
+ return false;
+ }
+
+ LLDB_LOG(log, "Name: {0}\n", bp_name->GetName());
+ std::lock_guard<std::recursive_mutex> guard(
+ m_impl_up->GetTarget()->GetAPIMutex());
+ bp_name->GetDescription(s.get(), eDescriptionLevelFull);
+ return true;
+}
+
+void SBBreakpointName::SetCallback(SBBreakpointHitCallback callback,
+ void *baton) {
+ Log *log(lldb_private::GetLogIfAllCategoriesSet(LIBLLDB_LOG_API));
+ BreakpointName *bp_name = GetBreakpointName();
+ if (!bp_name)
+ return;
+ LLDB_LOG(log, "callback = {1}, baton = {2}", callback, baton);
+ std::lock_guard<std::recursive_mutex> guard(
+ m_impl_up->GetTarget()->GetAPIMutex());
+
+ BatonSP baton_sp(new SBBreakpointCallbackBaton(callback, baton));
+ bp_name->GetOptions().SetCallback(SBBreakpointCallbackBaton
+ ::PrivateBreakpointHitCallback,
+ baton_sp,
+ false);
+ UpdateName(*bp_name);
+}
+
+void SBBreakpointName::SetScriptCallbackFunction(
+ const char *callback_function_name) {
+ Log *log(lldb_private::GetLogIfAllCategoriesSet(LIBLLDB_LOG_API));
+
+ BreakpointName *bp_name = GetBreakpointName();
+ if (!bp_name)
+ return;
+
+ LLDB_LOG(log, "Name: {0} callback: {1}\n", bp_name->GetName(),
+ callback_function_name);
+
+ std::lock_guard<std::recursive_mutex> guard(
+ m_impl_up->GetTarget()->GetAPIMutex());
+
+ BreakpointOptions &bp_options = bp_name->GetOptions();
+ m_impl_up->GetTarget()
+ ->GetDebugger()
+ .GetCommandInterpreter()
+ .GetScriptInterpreter()
+ ->SetBreakpointCommandCallbackFunction(&bp_options,
+ callback_function_name);
+ UpdateName(*bp_name);
+}
+
+SBError SBBreakpointName::SetScriptCallbackBody(const char *callback_body_text)
+{
+ Log *log(lldb_private::GetLogIfAllCategoriesSet(LIBLLDB_LOG_API));
+ SBError sb_error;
+ BreakpointName *bp_name = GetBreakpointName();
+ if (!bp_name)
+ return sb_error;
+
+ LLDB_LOG(log, "Name: {0} callback: {1}\n", bp_name->GetName(),
+ callback_body_text);
+
+ std::lock_guard<std::recursive_mutex> guard(
+ m_impl_up->GetTarget()->GetAPIMutex());
+
+ BreakpointOptions &bp_options = bp_name->GetOptions();
+ Status error =
+ m_impl_up->GetTarget()
+ ->GetDebugger()
+ .GetCommandInterpreter()
+ .GetScriptInterpreter()
+ ->SetBreakpointCommandCallback(&bp_options, callback_body_text);
+ sb_error.SetError(error);
+ if (!sb_error.Fail())
+ UpdateName(*bp_name);
+
+ return sb_error;
+}
+
+bool SBBreakpointName::GetAllowList() const
+{
+ BreakpointName *bp_name = GetBreakpointName();
+ if (!bp_name)
+ return false;
+ return bp_name->GetPermissions().GetAllowList();
+}
+
+void SBBreakpointName::SetAllowList(bool value)
+{
+ Log *log(lldb_private::GetLogIfAllCategoriesSet(LIBLLDB_LOG_API));
+
+ BreakpointName *bp_name = GetBreakpointName();
+ if (!bp_name)
+ return;
+ if (log)
+ log->Printf("Setting allow list to %u for %s.", value,
+ bp_name->GetName().AsCString());
+ bp_name->GetPermissions().SetAllowList(value);
+}
+
+bool SBBreakpointName::GetAllowDelete()
+{
+ BreakpointName *bp_name = GetBreakpointName();
+ if (!bp_name)
+ return false;
+ return bp_name->GetPermissions().GetAllowDelete();
+}
+
+void SBBreakpointName::SetAllowDelete(bool value)
+{
+ Log *log(lldb_private::GetLogIfAllCategoriesSet(LIBLLDB_LOG_API));
+
+ BreakpointName *bp_name = GetBreakpointName();
+ if (!bp_name)
+ return;
+ if (log)
+ log->Printf("Setting allow delete to %u for %s.", value,
+ bp_name->GetName().AsCString());
+ bp_name->GetPermissions().SetAllowDelete(value);
+}
+
+bool SBBreakpointName::GetAllowDisable()
+{
+ BreakpointName *bp_name = GetBreakpointName();
+ if (!bp_name)
+ return false;
+ return bp_name->GetPermissions().GetAllowDisable();
+}
+
+void SBBreakpointName::SetAllowDisable(bool value)
+{
+ Log *log(lldb_private::GetLogIfAllCategoriesSet(LIBLLDB_LOG_API));
+
+ BreakpointName *bp_name = GetBreakpointName();
+ if (!bp_name)
+ return;
+ if (log)
+ log->Printf("Setting allow disable to %u for %s.", value,
+ bp_name->GetName().AsCString());
+ bp_name->GetPermissions().SetAllowDisable(value);
+}
+
+lldb_private::BreakpointName *SBBreakpointName::GetBreakpointName() const
+{
+ if (!IsValid())
+ return nullptr;
+ return m_impl_up->GetBreakpointName();
+}
+
diff --git a/lldb/source/API/SBBreakpointOptionCommon.cpp b/lldb/source/API/SBBreakpointOptionCommon.cpp
new file mode 100644
index 00000000000..2a12491d6ec
--- /dev/null
+++ b/lldb/source/API/SBBreakpointOptionCommon.cpp
@@ -0,0 +1,84 @@
+//===-- SBBreakpointName.cpp ----------------------------------------*- C++ -*-===//
+//
+// The LLVM Compiler Infrastructure
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+
+// C Includes
+// C++ Includes
+// Other libraries and framework includes
+// Project includes
+#include "lldb/API/SBBreakpointName.h"
+#include "lldb/API/SBBreakpointLocation.h"
+#include "lldb/API/SBDebugger.h"
+#include "lldb/API/SBEvent.h"
+#include "lldb/API/SBProcess.h"
+#include "lldb/API/SBStream.h"
+#include "lldb/API/SBStringList.h"
+#include "lldb/API/SBThread.h"
+
+#include "lldb/Breakpoint/BreakpointName.h"
+#include "lldb/Breakpoint/StoppointCallbackContext.h"
+#include "lldb/Core/Address.h"
+#include "lldb/Core/Debugger.h"
+#include "lldb/Core/StreamFile.h"
+#include "lldb/Interpreter/CommandInterpreter.h"
+#include "lldb/Interpreter/ScriptInterpreter.h"
+#include "lldb/Target/Process.h"
+#include "lldb/Target/Target.h"
+#include "lldb/Target/Thread.h"
+#include "lldb/Target/ThreadSpec.h"
+#include "lldb/Utility/Log.h"
+#include "lldb/Utility/Stream.h"
+
+#include "lldb/lldb-enumerations.h"
+
+#include "SBBreakpointOptionCommon.h"
+
+#include "llvm/ADT/STLExtras.h"
+
+using namespace lldb;
+using namespace lldb_private;
+
+SBBreakpointCallbackBaton::SBBreakpointCallbackBaton(SBBreakpointHitCallback
+ callback,
+ void *baton)
+ : TypedBaton(llvm::make_unique<CallbackData>()) {
+ getItem()->callback = callback;
+ getItem()->callback_baton = baton;
+ }
+
+ bool SBBreakpointCallbackBaton::PrivateBreakpointHitCallback(void *baton,
+ StoppointCallbackContext *ctx,
+ lldb::user_id_t break_id,
+ lldb::user_id_t break_loc_id)
+{
+ ExecutionContext exe_ctx(ctx->exe_ctx_ref);
+ BreakpointSP bp_sp(
+ exe_ctx.GetTargetRef().GetBreakpointList().FindBreakpointByID(break_id));
+ if (baton && bp_sp) {
+ CallbackData *data = (CallbackData *)baton;
+ lldb_private::Breakpoint *bp = bp_sp.get();
+ if (bp && data->callback) {
+ Process *process = exe_ctx.GetProcessPtr();
+ if (process) {
+ SBProcess sb_process(process->shared_from_this());
+ SBThread sb_thread;
+ SBBreakpointLocation sb_location;
+ assert(bp_sp);
+ sb_location.SetLocation(bp_sp->FindLocationByID(break_loc_id));
+ Thread *thread = exe_ctx.GetThreadPtr();
+ if (thread)
+ sb_thread.SetThread(thread->shared_from_this());
+
+ return data->callback(data->callback_baton, sb_process, sb_thread,
+ sb_location);
+ }
+ }
+ }
+ return true; // Return true if we should stop at this breakpoint
+}
+
diff --git a/lldb/source/API/SBBreakpointOptionCommon.h b/lldb/source/API/SBBreakpointOptionCommon.h
new file mode 100644
index 00000000000..212fe398dd7
--- /dev/null
+++ b/lldb/source/API/SBBreakpointOptionCommon.h
@@ -0,0 +1,35 @@
+//===-- SBBreakpointOptionCommon.h ------------------------------------------*- C++ -*-===//
+//
+// The LLVM Compiler Infrastructure
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+
+#ifndef LLDB_SBBreakpointOptionCommons_h_
+#define LLDB_SBBreakpointOptionCommons_h_
+
+#include "lldb/API/SBDefines.h"
+#include "lldb/Utility/Baton.h"
+
+namespace lldb
+{
+struct CallbackData {
+ SBBreakpointHitCallback callback;
+ void *callback_baton;
+};
+
+class SBBreakpointCallbackBaton : public lldb_private::TypedBaton<CallbackData> {
+public:
+ SBBreakpointCallbackBaton(SBBreakpointHitCallback callback,
+ void *baton);
+
+ static bool PrivateBreakpointHitCallback(void *baton,
+ lldb_private::StoppointCallbackContext *ctx,
+ lldb::user_id_t break_id,
+ lldb::user_id_t break_loc_id);
+};
+
+} // namespace lldb
+#endif // LLDB_SBBreakpointOptionCommons_h_
diff --git a/lldb/source/API/SBDebugger.cpp b/lldb/source/API/SBDebugger.cpp
index cf6a27a049b..0185f1e9ec4 100644
--- a/lldb/source/API/SBDebugger.cpp
+++ b/lldb/source/API/SBDebugger.cpp
@@ -622,6 +622,20 @@ SBTarget SBDebugger::CreateTarget(const char *filename) {
return sb_target;
}
+SBTarget SBDebugger::GetDummyTarget() {
+ SBTarget sb_target;
+ if (m_opaque_sp) {
+ sb_target.SetSP(m_opaque_sp->GetDummyTarget()->shared_from_this());
+ }
+ Log *log(GetLogIfAllCategoriesSet(LIBLLDB_LOG_API));
+ if (log)
+ log->Printf(
+ "SBDebugger(%p)::GetDummyTarget() => SBTarget(%p)",
+ static_cast<void *>(m_opaque_sp.get()),
+ static_cast<void *>(sb_target.GetSP().get()));
+ return sb_target;
+}
+
bool SBDebugger::DeleteTarget(lldb::SBTarget &target) {
bool result = false;
if (m_opaque_sp) {
diff --git a/lldb/source/API/SBTarget.cpp b/lldb/source/API/SBTarget.cpp
index 417a15074c7..93869d71c62 100644
--- a/lldb/source/API/SBTarget.cpp
+++ b/lldb/source/API/SBTarget.cpp
@@ -1087,11 +1087,38 @@ bool SBTarget::FindBreakpointsByName(const char *name,
return true;
}
+void SBTarget::GetBreakpointNames(SBStringList &names)
+{
+ names.Clear();
+
+ TargetSP target_sp(GetSP());
+ if (target_sp) {
+ std::lock_guard<std::recursive_mutex> guard(target_sp->GetAPIMutex());
+
+ std::vector<std::string> name_vec;
+ target_sp->GetBreakpointNames(name_vec);
+ for (auto name : name_vec)
+ names.AppendString(name.c_str());
+ }
+}
+
+void SBTarget::DeleteBreakpointName(const char *name)
+{
+ TargetSP target_sp(GetSP());
+ if (target_sp) {
+ std::lock_guard<std::recursive_mutex> guard(target_sp->GetAPIMutex());
+
+ std::vector<std::string> name_vec;
+ target_sp->DeleteBreakpointName(ConstString(name));
+
+ }
+}
+
bool SBTarget::EnableAllBreakpoints() {
TargetSP target_sp(GetSP());
if (target_sp) {
std::lock_guard<std::recursive_mutex> guard(target_sp->GetAPIMutex());
- target_sp->EnableAllBreakpoints();
+ target_sp->EnableAllowedBreakpoints();
return true;
}
return false;
@@ -1101,7 +1128,7 @@ bool SBTarget::DisableAllBreakpoints() {
TargetSP target_sp(GetSP());
if (target_sp) {
std::lock_guard<std::recursive_mutex> guard(target_sp->GetAPIMutex());
- target_sp->DisableAllBreakpoints();
+ target_sp->DisableAllowedBreakpoints();
return true;
}
return false;
@@ -1111,7 +1138,7 @@ bool SBTarget::DeleteAllBreakpoints() {
TargetSP target_sp(GetSP());
if (target_sp) {
std::lock_guard<std::recursive_mutex> guard(target_sp->GetAPIMutex());
- target_sp->RemoveAllBreakpoints();
+ target_sp->RemoveAllowedBreakpoints();
return true;
}
return false;
diff --git a/lldb/source/Breakpoint/Breakpoint.cpp b/lldb/source/Breakpoint/Breakpoint.cpp
index fd606aa83d6..3f6c63e1e5b 100644
--- a/lldb/source/Breakpoint/Breakpoint.cpp
+++ b/lldb/source/Breakpoint/Breakpoint.cpp
@@ -210,7 +210,7 @@ lldb::BreakpointSP Breakpoint::CreateFromStructuredData(
llvm::StringRef name;
Status error;
success = names_array->GetItemAtIndexAsString(i, name);
- result_sp->AddName(name, error);
+ target.AddNameToBreakpoint(result_sp, name.str().c_str(), error);
}
}
@@ -455,6 +455,10 @@ bool Breakpoint::InvokeCallback(StoppointCallbackContext *context,
BreakpointOptions *Breakpoint::GetOptions() { return m_options_up.get(); }
+const BreakpointOptions *Breakpoint::GetOptions() const {
+ return m_options_up.get();
+}
+
void Breakpoint::ResolveBreakpoint() {
if (m_resolver_sp)
m_resolver_sp->ResolveBreakpoint(*m_filter_sp);
@@ -841,18 +845,8 @@ size_t Breakpoint::GetNumResolvedLocations() const {
size_t Breakpoint::GetNumLocations() const { return m_locations.GetSize(); }
-bool Breakpoint::AddName(llvm::StringRef new_name, Status &error) {
- if (new_name.empty())
- return false;
- if (!BreakpointID::StringIsBreakpointName(new_name, error)) {
- error.SetErrorStringWithFormatv("input name \"{0}\" not a breakpoint name.",
- new_name);
- return false;
- }
- if (!error.Success())
- return false;
-
- m_name_list.insert(new_name);
+bool Breakpoint::AddName(llvm::StringRef new_name) {
+ m_name_list.insert(new_name.str().c_str());
return true;
}
diff --git a/lldb/source/Breakpoint/BreakpointID.cpp b/lldb/source/Breakpoint/BreakpointID.cpp
index 112f7c0b519..b8010654682 100644
--- a/lldb/source/Breakpoint/BreakpointID.cpp
+++ b/lldb/source/Breakpoint/BreakpointID.cpp
@@ -101,15 +101,24 @@ BreakpointID::ParseCanonicalReference(llvm::StringRef input) {
bool BreakpointID::StringIsBreakpointName(llvm::StringRef str, Status &error) {
error.Clear();
if (str.empty())
+ {
+ error.SetErrorStringWithFormat("Empty breakpoint names are not allowed");
return false;
+ }
// First character must be a letter or _
if (!isalpha(str[0]) && str[0] != '_')
+ {
+ error.SetErrorStringWithFormat("Breakpoint names must start with a "
+ "character or underscore: %s",
+ str.str().c_str());
return false;
+ }
// Cannot contain ., -, or space.
if (str.find_first_of(".- ") != llvm::StringRef::npos) {
- error.SetErrorStringWithFormat("invalid breakpoint name: \"%s\"",
+ error.SetErrorStringWithFormat("Breakpoint names cannot contain "
+ "'.' or '-': \"%s\"",
str.str().c_str());
return false;
}
diff --git a/lldb/source/Breakpoint/BreakpointIDList.cpp b/lldb/source/Breakpoint/BreakpointIDList.cpp
index 7b461147a4e..0a704fdc918 100644
--- a/lldb/source/Breakpoint/BreakpointIDList.cpp
+++ b/lldb/source/Breakpoint/BreakpointIDList.cpp
@@ -11,6 +11,7 @@
// C++ Includes
// Other libraries and framework includes
// Project includes
+#include "lldb/lldb-enumerations.h"
#include "lldb/Breakpoint/BreakpointIDList.h"
#include "lldb/Breakpoint/Breakpoint.h"
@@ -117,6 +118,8 @@ void BreakpointIDList::InsertStringArray(const char **string_array,
void BreakpointIDList::FindAndReplaceIDRanges(Args &old_args, Target *target,
bool allow_locations,
+ BreakpointName::Permissions
+ ::PermissionKinds purpose,
CommandReturnObject &result,
Args &new_args) {
llvm::StringRef range_from;
@@ -302,14 +305,29 @@ void BreakpointIDList::FindAndReplaceIDRanges(Args &old_args, Target *target,
}
// Okay, now see if we found any names, and if we did, add them:
- if (target && names_found.size()) {
- for (BreakpointSP bkpt_sp : target->GetBreakpointList().Breakpoints()) {
- for (std::string name : names_found) {
- if (bkpt_sp->MatchesName(name.c_str())) {
- StreamString canonical_id_str;
- BreakpointID::GetCanonicalReference(
- &canonical_id_str, bkpt_sp->GetID(), LLDB_INVALID_BREAK_ID);
- new_args.AppendArgument(canonical_id_str.GetString());
+ if (target && !names_found.empty()) {
+ Status error;
+ // Remove any names that aren't visible for this purpose:
+ auto iter = names_found.begin();
+ while (iter != names_found.end()) {
+ BreakpointName *bp_name = target->FindBreakpointName(ConstString(*iter),
+ true,
+ error);
+ if (bp_name && !bp_name->GetPermission(purpose))
+ iter = names_found.erase(iter);
+ else
+ iter++;
+ }
+
+ if (!names_found.empty()) {
+ for (BreakpointSP bkpt_sp : target->GetBreakpointList().Breakpoints()) {
+ for (std::string name : names_found) {
+ if (bkpt_sp->MatchesName(name.c_str())) {
+ StreamString canonical_id_str;
+ BreakpointID::GetCanonicalReference(
+ &canonical_id_str, bkpt_sp->GetID(), LLDB_INVALID_BREAK_ID);
+ new_args.AppendArgument(canonical_id_str.GetString());
+ }
}
}
}
diff --git a/lldb/source/Breakpoint/BreakpointList.cpp b/lldb/source/Breakpoint/BreakpointList.cpp
index 15bcb34a3d8..01ac59f0a90 100644
--- a/lldb/source/Breakpoint/BreakpointList.cpp
+++ b/lldb/source/Breakpoint/BreakpointList.cpp
@@ -71,6 +71,13 @@ void BreakpointList::SetEnabledAll(bool enabled) {
bp_sp->SetEnabled(enabled);
}
+void BreakpointList::SetEnabledAllowed(bool enabled) {
+ std::lock_guard<std::recursive_mutex> guard(m_mutex);
+ for (const auto &bp_sp : m_breakpoints)
+ if (bp_sp->AllowDisable())
+ bp_sp->SetEnabled(enabled);
+}
+
void BreakpointList::RemoveAll(bool notify) {
std::lock_guard<std::recursive_mutex> guard(m_mutex);
ClearAllBreakpointSites();
@@ -90,6 +97,32 @@ void BreakpointList::RemoveAll(bool notify) {
m_breakpoints.erase(m_breakpoints.begin(), m_breakpoints.end());
}
+void BreakpointList::RemoveAllowed(bool notify) {
+ std::lock_guard<std::recursive_mutex> guard(m_mutex);
+
+ bp_collection::iterator pos, end = m_breakpoints.end();
+ if (notify) {
+ for (pos = m_breakpoints.begin(); pos != end; ++pos) {
+ if(!(*pos)->AllowDelete())
+ continue;
+ if ((*pos)->GetTarget().EventTypeHasListeners(
+ Target::eBroadcastBitBreakpointChanged)) {
+ (*pos)->GetTarget().BroadcastEvent(
+ Target::eBroadcastBitBreakpointChanged,
+ new Breakpoint::BreakpointEventData(eBreakpointEventTypeRemoved,
+ *pos));
+ }
+ }
+ }
+ pos = m_breakpoints.begin();
+ while ( pos != end) {
+ if((*pos)->AllowDelete())
+ pos = m_breakpoints.erase(pos);
+ else
+ pos++;
+ }
+}
+
class BreakpointIDMatches {
public:
BreakpointIDMatches(break_id_t break_id) : m_break_id(break_id) {}
diff --git a/lldb/source/Breakpoint/BreakpointName.cpp b/lldb/source/Breakpoint/BreakpointName.cpp
new file mode 100644
index 00000000000..7b9a2acfbc4
--- /dev/null
+++ b/lldb/source/Breakpoint/BreakpointName.cpp
@@ -0,0 +1,88 @@
+//===-- Breakpoint.cpp ------------------------------------------*- C++ -*-===//
+//
+// The LLVM Compiler Infrastructure
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details->
+//
+//===----------------------------------------------------------------------===//
+
+// C Includes
+// C++ Includes
+// Other libraries and framework includes
+#include "llvm/Support/Casting.h"
+
+// Project includes
+#include "lldb/Breakpoint/Breakpoint.h"
+#include "lldb/Breakpoint/BreakpointOptions.h"
+#include "lldb/Breakpoint/BreakpointLocationCollection.h"
+#include "lldb/Breakpoint/BreakpointResolver.h"
+#include "lldb/Breakpoint/BreakpointResolverFileLine.h"
+#include "lldb/Utility/Log.h"
+#include "lldb/Utility/Stream.h"
+#include "lldb/Utility/StreamString.h"
+
+using namespace lldb;
+using namespace lldb_private;
+
+const Flags::ValueType BreakpointName::Permissions::permissions_mask
+ [BreakpointName::Permissions::PermissionKinds::allPerms + 1] = {
+ (1u << 0),
+ (1u << 1),
+ (1u << 2),
+ (0x5u)
+};
+
+BreakpointName::BreakpointName(const ConstString &name, const Breakpoint &bkpt,
+ const char *help) :
+ m_name(name), m_options(bkpt.GetOptions())
+{
+ SetHelp(help);
+}
+
+bool BreakpointName::Permissions::GetDescription(Stream *s,
+ lldb::DescriptionLevel level) {
+ if (!AnySet())
+ return false;
+ s->IndentMore();
+ s->Indent();
+ if (IsSet(listPerm))
+ s->Printf("list: %s", GetAllowList() ? "allowed" : "disallowed");
+
+ if (IsSet(disablePerm))
+ s->Printf("disable: %s", GetAllowDisable() ? "allowed" : "disallowed");
+
+ if (IsSet(deletePerm))
+ s->Printf("delete: %s", GetAllowDelete() ? "allowed" : "disallowed");
+ s->IndentLess();
+ return true;
+}
+
+bool BreakpointName::GetDescription(Stream *s, lldb::DescriptionLevel level) {
+ bool printed_any = false;
+ if (GetOptions().AnySet())
+ {
+ s->PutCString("Options: \n");
+ s->IndentMore();
+ s->Indent();
+ GetOptions().GetDescription(s, level);
+ printed_any = true;
+ s->IndentLess();
+ }
+ if (GetPermissions().AnySet())
+ {
+ s->PutCString("Permissions: \n");
+ s->IndentMore();
+ s->Indent();
+ GetPermissions().GetDescription(s, level);
+ printed_any = true;
+ s->IndentLess();
+ }
+ return printed_any;
+}
+
+void BreakpointName::ConfigureBreakpoint(lldb::BreakpointSP bp_sp)
+{
+ bp_sp->GetOptions()->CopyOverSetOptions(GetOptions());
+ bp_sp->GetPermissions().MergeInto(GetPermissions());
+}
diff --git a/lldb/source/Breakpoint/BreakpointOptions.cpp b/lldb/source/Breakpoint/BreakpointOptions.cpp
index 7159688102d..662b288794d 100644
--- a/lldb/source/Breakpoint/BreakpointOptions.cpp
+++ b/lldb/source/Breakpoint/BreakpointOptions.cpp
@@ -132,7 +132,7 @@ BreakpointOptions::BreakpointOptions(bool all_flags_set)
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_auto_continue(false),
- m_set_flags() {
+ m_set_flags(0) {
if (all_flags_set)
m_set_flags.Set(~((Flags::ValueType) 0));
}
@@ -142,11 +142,14 @@ BreakpointOptions::BreakpointOptions(const char *condition, bool enabled,
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_one_shot(one_shot), m_ignore_count(ignore),
m_condition_text_hash(0), m_auto_continue(auto_continue)
{
m_set_flags.Set(eEnabled | eIgnoreCount | eOneShot
- | eCondition | eAutoContinue);
+ | eAutoContinue);
+ if (condition && *condition != '\0') {
+ SetCondition(condition);
+ }
}
//----------------------------------------------------------------------
@@ -187,6 +190,59 @@ operator=(const BreakpointOptions &rhs) {
return *this;
}
+void BreakpointOptions::CopyOverSetOptions(const BreakpointOptions &incoming)
+{
+ if (incoming.m_set_flags.Test(eEnabled))
+ {
+ m_enabled = incoming.m_enabled;
+ m_set_flags.Set(eEnabled);
+ }
+ if (incoming.m_set_flags.Test(eOneShot))
+ {
+ m_one_shot = incoming.m_one_shot;
+ m_set_flags.Set(eOneShot);
+ }
+ if (incoming.m_set_flags.Test(eCallback))
+ {
+ m_callback = incoming.m_callback;
+ m_callback_baton_sp = incoming.m_callback_baton_sp;
+ m_callback_is_synchronous = incoming.m_callback_is_synchronous;
+ m_baton_is_command_baton = incoming.m_baton_is_command_baton;
+ m_set_flags.Set(eCallback);
+ }
+ if (incoming.m_set_flags.Test(eIgnoreCount))
+ {
+ m_ignore_count = incoming.m_ignore_count;
+ m_set_flags.Set(eIgnoreCount);
+ }
+ if (incoming.m_set_flags.Test(eCondition))
+ {
+ // If we're copying over an empty condition, mark it as unset.
+ if (incoming.m_condition_text.empty()) {
+ m_condition_text.clear();
+ m_condition_text_hash = 0;
+ m_set_flags.Clear(eCondition);
+ } else {
+ m_condition_text = incoming.m_condition_text;
+ m_condition_text_hash = incoming.m_condition_text_hash;
+ m_set_flags.Set(eCondition);
+ }
+ }
+ if (incoming.m_set_flags.Test(eAutoContinue))
+ {
+ m_auto_continue = incoming.m_auto_continue;
+ m_set_flags.Set(eAutoContinue);
+ }
+ if (incoming.m_set_flags.Test(eThreadSpec) && incoming.m_thread_spec_ap)
+ {
+ if (!m_thread_spec_ap)
+ m_thread_spec_ap.reset(new ThreadSpec(*incoming.m_thread_spec_ap.get()));
+ else
+ *m_thread_spec_ap.get() = *incoming.m_thread_spec_ap.get();
+ m_set_flags.Set(eThreadSpec);
+ }
+}
+
//----------------------------------------------------------------------
// Destructor
//----------------------------------------------------------------------
@@ -327,23 +383,23 @@ std::unique_ptr<BreakpointOptions> BreakpointOptions::CreateFromStructuredData(
StructuredData::ObjectSP BreakpointOptions::SerializeToStructuredData() {
StructuredData::DictionarySP options_dict_sp(
new StructuredData::Dictionary());
- if (m_set_flags.Set(eEnabled))
+ if (m_set_flags.Test(eEnabled))
options_dict_sp->AddBooleanItem(GetKey(OptionNames::EnabledState),
m_enabled);
- if (m_set_flags.Set(eOneShot))
+ if (m_set_flags.Test(eOneShot))
options_dict_sp->AddBooleanItem(GetKey(OptionNames::OneShotState),
m_one_shot);
- if (m_set_flags.Set(eAutoContinue))
+ if (m_set_flags.Test(eAutoContinue))
options_dict_sp->AddBooleanItem(GetKey(OptionNames::AutoContinue),
m_auto_continue);
- if (m_set_flags.Set(eIgnoreCount))
+ if (m_set_flags.Test(eIgnoreCount))
options_dict_sp->AddIntegerItem(GetKey(OptionNames::IgnoreCount),
m_ignore_count);
- if (m_set_flags.Set(eCondition))
+ if (m_set_flags.Test(eCondition))
options_dict_sp->AddStringItem(GetKey(OptionNames::ConditionText),
m_condition_text);
- if (m_set_flags.Set(eCallback) && m_baton_is_command_baton) {
+ if (m_set_flags.Test(eCallback) && m_baton_is_command_baton) {
auto cmd_baton =
std::static_pointer_cast<CommandBaton>(m_callback_baton_sp);
StructuredData::ObjectSP commands_sp =
@@ -353,7 +409,7 @@ StructuredData::ObjectSP BreakpointOptions::SerializeToStructuredData() {
BreakpointOptions::CommandData::GetSerializationKey(), commands_sp);
}
}
- if (m_set_flags.Set(eThreadSpec) && m_thread_spec_ap) {
+ if (m_set_flags.Test(eThreadSpec) && m_thread_spec_ap) {
StructuredData::ObjectSP thread_spec_sp =
m_thread_spec_ap->SerializeToStructuredData();
options_dict_sp->AddItem(ThreadSpec::GetSerializationKey(), thread_spec_sp);
@@ -618,3 +674,18 @@ bool BreakpointOptions::BreakpointOptionsCallbackFunction(
}
return ret_value;
}
+
+void BreakpointOptions::Clear()
+{
+ m_set_flags.Clear();
+ m_thread_spec_ap.release();
+ m_one_shot = false;
+ m_ignore_count = 0;
+ m_auto_continue = false;
+ m_callback = nullptr;
+ m_callback_baton_sp.reset();
+ m_baton_is_command_baton = false;
+ m_callback_is_synchronous = false;
+ m_enabled = false;
+ m_condition_text.clear();
+}
diff --git a/lldb/source/Commands/CommandObjectBreakpoint.cpp b/lldb/source/Commands/CommandObjectBreakpoint.cpp
index d53e681514d..f4276e4e979 100644
--- a/lldb/source/Commands/CommandObjectBreakpoint.cpp
+++ b/lldb/source/Commands/CommandObjectBreakpoint.cpp
@@ -45,6 +45,203 @@ static void AddBreakpointDescription(Stream *s, Breakpoint *bp,
s->EOL();
}
+//-------------------------------------------------------------------------
+// Modifiable Breakpoint Options
+//-------------------------------------------------------------------------
+#pragma mark Modify::CommandOptions
+static OptionDefinition g_breakpoint_modify_options[] = {
+ // clang-format off
+ { LLDB_OPT_SET_1, false, "ignore-count", 'i', OptionParser::eRequiredArgument, nullptr, nullptr, 0, eArgTypeCount, "Set the number of times this breakpoint is skipped before stopping." },
+ { LLDB_OPT_SET_1, false, "one-shot", 'o', OptionParser::eRequiredArgument, nullptr, nullptr, 0, eArgTypeBoolean, "The breakpoint is deleted the first time it stop causes a stop." },
+ { LLDB_OPT_SET_1, false, "thread-index", 'x', OptionParser::eRequiredArgument, nullptr, nullptr, 0, eArgTypeThreadIndex, "The breakpoint stops only for the thread whose index matches this argument." },
+ { LLDB_OPT_SET_1, false, "thread-id", 't', OptionParser::eRequiredArgument, nullptr, nullptr, 0, eArgTypeThreadID, "The breakpoint stops only for the thread whose TID matches this argument." },
+ { LLDB_OPT_SET_1, false, "thread-name", 'T', OptionParser::eRequiredArgument, nullptr, nullptr, 0, eArgTypeThreadName, "The breakpoint stops only for the thread whose thread name matches this argument." },
+ { LLDB_OPT_SET_1, false, "queue-name", 'q', OptionParser::eRequiredArgument, nullptr, nullptr, 0, eArgTypeQueueName, "The breakpoint stops only for threads in the queue whose name is given by this argument." },
+ { LLDB_OPT_SET_1, false, "condition", 'c', OptionParser::eRequiredArgument, nullptr, nullptr, 0, eArgTypeExpression, "The breakpoint stops only if this condition expression evaluates to true." },
+ { LLDB_OPT_SET_1, false, "auto-continue",'G', OptionParser::eRequiredArgument, nullptr, nullptr, 0, eArgTypeBoolean, "The breakpoint will auto-continue after running its commands." },
+ { LLDB_OPT_SET_2, false, "enable", 'e', OptionParser::eNoArgument, nullptr, nullptr, 0, eArgTypeNone, "Enable the breakpoint." },
+ { LLDB_OPT_SET_3, false, "disable", 'd', OptionParser::eNoArgument, nullptr, nullptr, 0, eArgTypeNone, "Disable the breakpoint." },
+ { LLDB_OPT_SET_4, false, "command", 'C', OptionParser::eRequiredArgument, nullptr, nullptr, 0, eArgTypeCommand, "A command to run when the breakpoint is hit, can be provided more than once, the commands will get run in order left to right." },
+ // clang-format on
+};
+class lldb_private::BreakpointOptionGroup : public OptionGroup
+{
+public:
+ BreakpointOptionGroup() :
+ OptionGroup(),
+ m_bp_opts(false) {}
+
+ ~BreakpointOptionGroup() override = default;
+
+ llvm::ArrayRef<OptionDefinition> GetDefinitions() override {
+ return llvm::makeArrayRef(g_breakpoint_modify_options);
+ }
+
+ Status SetOptionValue(uint32_t option_idx, llvm::StringRef option_arg,
+ ExecutionContext *execution_context) override {
+ Status error;
+ const int short_option = g_breakpoint_modify_options[option_idx].short_option;
+
+ switch (short_option) {
+ case 'c':
+ // Normally an empty breakpoint condition marks is as unset.
+ // But we need to say it was passed in.
+ m_bp_opts.SetCondition(option_arg.str().c_str());
+ m_bp_opts.m_set_flags.Set(BreakpointOptions::eCondition);
+ break;
+ case 'C':
+ m_commands.push_back(option_arg);
+ break;
+ case 'd':
+ m_bp_opts.SetEnabled(false);
+ break;
+ case 'e':
+ m_bp_opts.SetEnabled(true);
+ break;
+ case 'G': {
+ bool value, success;
+ value = Args::StringToBoolean(option_arg, false, &success);
+ if (success) {
+ m_bp_opts.SetAutoContinue(value);
+ } else
+ error.SetErrorStringWithFormat(
+ "invalid boolean value '%s' passed for -G option",
+ option_arg.str().c_str());
+ }
+ break;
+ case 'i':
+ {
+ uint32_t ignore_count;
+ if (option_arg.getAsInteger(0, ignore_count))
+ error.SetErrorStringWithFormat("invalid ignore count '%s'",
+ option_arg.str().c_str());
+ else
+ m_bp_opts.SetIgnoreCount(ignore_count);
+ }
+ break;
+ case 'o': {
+ bool value, success;
+ value = Args::StringToBoolean(option_arg, false, &success);
+ if (success) {
+ m_bp_opts.SetOneShot(value);
+ } else
+ error.SetErrorStringWithFormat(
+ "invalid boolean value '%s' passed for -o option",
+ option_arg.str().c_str());
+ } break;
+ case 't':
+ {
+ lldb::tid_t thread_id = LLDB_INVALID_THREAD_ID;
+ if (option_arg[0] != '\0') {
+ if (option_arg.getAsInteger(0, thread_id))
+ error.SetErrorStringWithFormat("invalid thread id string '%s'",
+ option_arg.str().c_str());
+ }
+ m_bp_opts.SetThreadID(thread_id);
+ }
+ break;
+ case 'T':
+ m_bp_opts.GetThreadSpec()->SetName(option_arg.str().c_str());
+ break;
+ case 'q':
+ m_bp_opts.GetThreadSpec()->SetQueueName(option_arg.str().c_str());
+ break;
+ case 'x':
+ {
+ uint32_t thread_index = UINT32_MAX;
+ if (option_arg[0] != '\n') {
+ if (option_arg.getAsInteger(0, thread_index))
+ error.SetErrorStringWithFormat("invalid thread index string '%s'",
+ option_arg.str().c_str());
+ }
+ m_bp_opts.GetThreadSpec()->SetIndex(thread_index);
+ }
+ break;
+ default:
+ error.SetErrorStringWithFormat("unrecognized option '%c'",
+ short_option);
+ break;
+ }
+
+ return error;
+ }
+
+ void OptionParsingStarting(ExecutionContext *execution_context) override {
+ m_bp_opts.Clear();
+ m_commands.clear();
+ }
+
+ Status OptionParsingFinished(ExecutionContext *execution_context) override {
+ if (!m_commands.empty())
+ {
+ if (!m_commands.empty())
+ {
+ auto cmd_data = llvm::make_unique<BreakpointOptions::CommandData>();
+
+ for (std::string &str : m_commands)
+ cmd_data->user_source.AppendString(str);
+
+ cmd_data->stop_on_error = true;
+ m_bp_opts.SetCommandDataCallback(cmd_data);
+ }
+ }
+ return Status();
+ }
+
+ const BreakpointOptions &GetBreakpointOptions()
+ {
+ return m_bp_opts;
+ }
+
+ std::vector<std::string> m_commands;
+ BreakpointOptions m_bp_opts;
+
+};
+static OptionDefinition g_breakpoint_dummy_options[] = {
+ // clang-format off
+ { LLDB_OPT_SET_1, false, "dummy-breakpoints", 'D', OptionParser::eNoArgument, nullptr, nullptr, 0, eArgTypeNone, "Act on Dummy breakpoints - i.e. breakpoints set before a file is provided, "
+ "which prime new targets." },
+ // clang-format on
+};
+
+class BreakpointDummyOptionGroup : public OptionGroup
+{
+public:
+ BreakpointDummyOptionGroup() :
+ OptionGroup() {}
+
+ ~BreakpointDummyOptionGroup() override = default;
+
+ llvm::ArrayRef<OptionDefinition> GetDefinitions() override {
+ return llvm::makeArrayRef(g_breakpoint_dummy_options);
+ }
+
+ Status SetOptionValue(uint32_t option_idx, llvm::StringRef option_arg,
+ ExecutionContext *execution_context) override {
+ Status error;
+ const int short_option = g_breakpoint_modify_options[option_idx].short_option;
+
+ switch (short_option) {
+ case 'D':
+ m_use_dummy = true;
+ break;
+ default:
+ error.SetErrorStringWithFormat("unrecognized option '%c'",
+ short_option);
+ break;
+ }
+
+ return error;
+ }
+
+ void OptionParsingStarting(ExecutionContext *execution_context) override {
+ m_use_dummy = false;
+ }
+
+ bool m_use_dummy;
+
+};
+
// If an additional option set beyond LLDB_OPTION_SET_10 is added, make sure to
// update the numbers passed to LLDB_OPT_SET_FROM_TO(...) appropriately.
#define LLDB_OPT_FILE (LLDB_OPT_SET_FROM_TO(1, 9) & ~LLDB_OPT_SET_2)
@@ -58,18 +255,7 @@ static OptionDefinition g_breakpoint_set_options[] = {
// clang-format off
{ LLDB_OPT_NOT_10, false, "shlib", 's', OptionParser::eRequiredArgument, nullptr, nullptr, CommandCompletions::eModuleCompletion, eArgTypeShlibName, "Set the breakpoint only in this shared library. Can repeat this option "
"multiple times to specify multiple shared libraries." },
- { LLDB_OPT_SET_ALL, false, "ignore-count", 'i', OptionParser::eRequiredArgument, nullptr, nullptr, 0, eArgTypeCount, "Set the number of times this breakpoint is skipped before stopping." },
- { LLDB_OPT_SET_ALL, false, "one-shot", 'o', OptionParser::eNoArgument, nullptr, nullptr, 0, eArgTypeNone, "The breakpoint is deleted the first time it causes a stop." },
- { LLDB_OPT_SET_ALL, false, "auto-continue", 'G', OptionParser::eRequiredArgument, nullptr, nullptr, 0, eArgTypeBoolean, "The breakpoint will auto-continue after running its commands." },
- { LLDB_OPT_SET_ALL, false, "condition", 'c', OptionParser::eRequiredArgument, nullptr, nullptr, 0, eArgTypeExpression, "The breakpoint stops only if this condition expression evaluates to true." },
- { LLDB_OPT_SET_ALL, false, "command", 'd', OptionParser::eRequiredArgument, nullptr, nullptr, 0, eArgTypeCommand, "A command to run when the breakpoint is hit, can be provided more than once, the commands will get run in order left to right." },
- { LLDB_OPT_SET_ALL, false, "thread-index", 'x', OptionParser::eRequiredArgument, nullptr, nullptr, 0, eArgTypeThreadIndex, "The breakpoint stops only for the thread whose indeX matches this argument." },
- { LLDB_OPT_SET_ALL, false, "thread-id", 't', OptionParser::eRequiredArgument, nullptr, nullptr, 0, eArgTypeThreadID, "The breakpoint stops only for the thread whose TID matches this argument." },
- { LLDB_OPT_SET_ALL, false, "thread-name", 'T', OptionParser::eRequiredArgument, nullptr, nullptr, 0, eArgTypeThreadName, "The breakpoint stops only for the thread whose thread name matches this "
- "argument." },
{ LLDB_OPT_SET_ALL, false, "hardware", 'H', OptionParser::eNoArgument, nullptr, nullptr, 0, eArgTypeNone, "Require the breakpoint to use hardware breakpoints." },
- { LLDB_OPT_SET_ALL, false, "queue-name", 'q', OptionParser::eRequiredArgument, nullptr, nullptr, 0, eArgTypeQueueName, "The breakpoint stops only for threads in the queue whose name is given by "
- "this argument." },
{ LLDB_OPT_FILE, false, "file", 'f', OptionParser::eRequiredArgument, nullptr, nullptr, CommandCompletions::eSourceFileCompletion, eArgTypeFilename, "Specifies the source file in which to set this breakpoint. Note, by default "
"lldb only looks for files that are #included if they use the standard include "
"file extensions. To set breakpoints on .c/.cpp/.m/.mm files that are "
@@ -127,8 +313,6 @@ static OptionDefinition g_breakpoint_set_options[] = {
"If not set the target.language setting is used." },
{ LLDB_OPT_SKIP_PROLOGUE, false, "skip-prologue", 'K', OptionParser::eRequiredArgument, nullptr, nullptr, 0, eArgTypeBoolean, "sKip the prologue if the breakpoint is at the beginning of a function. "
"If not set the target.skip-prologue setting is used." },
- { LLDB_OPT_SET_ALL, false, "dummy-breakpoints", 'D', OptionParser::eNoArgument, nullptr, nullptr, 0, eArgTypeNone, "Sets Dummy breakpoints - i.e. breakpoints set before a file is provided, "
- "which prime new targets." },
{ LLDB_OPT_SET_ALL, false, "breakpoint-name", 'N', OptionParser::eRequiredArgument, nullptr, nullptr, 0, eArgTypeBreakpointName, "Adds this to the list of names for this breakpoint." },
{ LLDB_OPT_OFFSET_APPLIES, false, "address-slide", 'R', OptionParser::eRequiredArgument, nullptr, nullptr, 0, eArgTypeAddress, "Add the specified offset to whatever address(es) the breakpoint resolves to. "
"At present this applies the offset directly as given, and doesn't try to align it to instruction boundaries." },
@@ -158,24 +342,30 @@ public:
interpreter, "breakpoint set",
"Sets a breakpoint or set of breakpoints in the executable.",
"breakpoint set <cmd-options>"),
- m_options() {}
+ m_bp_opts(), m_options() {
+ // We're picking up all the normal options, commands and disable.
+ m_all_options.Append(&m_bp_opts,
+ LLDB_OPT_SET_1 | LLDB_OPT_SET_3 | LLDB_OPT_SET_4,
+ LLDB_OPT_SET_ALL);
+ m_all_options.Append(&m_dummy_options, LLDB_OPT_SET_1, LLDB_OPT_SET_ALL);
+ m_all_options.Append(&m_options);
+ m_all_options.Finalize();
+ }
~CommandObjectBreakpointSet() override = default;
- Options *GetOptions() override { return &m_options; }
+ Options *GetOptions() override { return &m_all_options; }
- class CommandOptions : public Options {
+ class CommandOptions : public OptionGroup {
public:
CommandOptions()
- : Options(), m_condition(), m_filenames(), m_line_num(0), m_column(0),
+ : OptionGroup(), m_condition(), m_filenames(), m_line_num(0), m_column(0),
m_func_names(), m_func_name_type_mask(eFunctionNameTypeNone),
m_func_regexp(), m_source_text_regexp(), m_modules(), m_load_addr(),
- m_ignore_count(0), m_thread_id(LLDB_INVALID_THREAD_ID),
- m_thread_index(UINT32_MAX), m_thread_name(), m_queue_name(),
m_catch_bp(false), m_throw_bp(true), m_hardware(false),
m_exception_language(eLanguageTypeUnknown),
m_language(lldb::eLanguageTypeUnknown),
- m_skip_prologue(eLazyBoolCalculate), m_one_shot(false),
+ m_skip_prologue(eLazyBoolCalculate),
m_all_files(false), m_move_to_nearest_code(eLazyBoolCalculate) {}
~CommandOptions() override = default;
@@ -183,7 +373,7 @@ public:
Status SetOptionValue(uint32_t option_idx, llvm::StringRef option_arg,
ExecutionContext *execution_context) override {
Status error;
- const int short_option = m_getopt_table[option_idx].val;
+ const int short_option = g_breakpoint_set_options[option_idx].short_option;
switch (short_option) {
case 'a': {
@@ -206,18 +396,6 @@ public:
option_arg.str().c_str());
break;
- case 'c':
- m_condition.assign(option_arg);
- break;
-
- case 'd':
- m_commands.push_back(option_arg);
- break;
-
- case 'D':
- m_use_dummy = true;
- break;
-
case 'E': {
LanguageType language = Language::GetLanguageTypeFromString(option_arg);
@@ -262,15 +440,6 @@ public:
m_func_name_type_mask |= eFunctionNameTypeFull;
break;
- case 'G' : {
- bool success;
- m_auto_continue = Args::StringToBoolean(option_arg, true, &success);
- if (!success)
- error.SetErrorStringWithFormat(
- "Invalid boolean value for auto-continue option: '%s'",
- option_arg.str().c_str());
- } break;
-
case 'h': {
bool success;
m_catch_bp = Args::StringToBoolean(option_arg, true, &success);
@@ -284,12 +453,6 @@ public:
m_hardware = true;
break;
- case 'i':
- if (option_arg.getAsInteger(0, m_ignore_count))
- error.SetErrorStringWithFormat("invalid ignore count '%s'",
- option_arg.str().c_str());
- break;
-
case 'K': {
bool success;
bool value;
@@ -362,10 +525,6 @@ public:
m_offset_addr = tmp_offset_addr;
} break;
- case 'o':
- m_one_shot = true;
- break;
-
case 'O':
m_exception_extra_args.AppendArgument("-O");
m_exception_extra_args.AppendArgument(option_arg);
@@ -375,10 +534,6 @@ public:
m_source_text_regexp.assign(option_arg);
break;
- case 'q':
- m_queue_name.assign(option_arg);
- break;
-
case 'r':
m_func_regexp.assign(option_arg);
break;
@@ -392,16 +547,6 @@ public:
m_func_name_type_mask |= eFunctionNameTypeSelector;
break;
- case 't':
- if (option_arg.getAsInteger(0, m_thread_id))
- error.SetErrorStringWithFormat("invalid thread id string '%s'",
- option_arg.str().c_str());
- break;
-
- case 'T':
- m_thread_name.assign(option_arg);
- break;
-
case 'w': {
bool success;
m_throw_bp = Args::StringToBoolean(option_arg, true, &success);
@@ -411,12 +556,6 @@ public:
option_arg.str().c_str());
} break;
- case 'x':
- if (option_arg.getAsInteger(0, m_thread_index))
- error.SetErrorStringWithFormat("invalid thread index string '%s'",
- option_arg.str().c_str());
- break;
-
case 'X':
m_source_regex_func_names.insert(option_arg);
break;
@@ -431,7 +570,6 @@ public:
}
void OptionParsingStarting(ExecutionContext *execution_context) override {
- m_condition.clear();
m_filenames.Clear();
m_line_num = 0;
m_column = 0;
@@ -442,26 +580,17 @@ public:
m_modules.Clear();
m_load_addr = LLDB_INVALID_ADDRESS;
m_offset_addr = 0;
- m_ignore_count = 0;
- m_thread_id = LLDB_INVALID_THREAD_ID;
- m_thread_index = UINT32_MAX;
- m_thread_name.clear();
- m_queue_name.clear();
m_catch_bp = false;
m_throw_bp = true;
m_hardware = false;
m_exception_language = eLanguageTypeUnknown;
m_language = lldb::eLanguageTypeUnknown;
m_skip_prologue = eLazyBoolCalculate;
- m_one_shot = false;
- m_use_dummy = false;
m_breakpoint_names.clear();
m_all_files = false;
m_exception_extra_args.Clear();
m_move_to_nearest_code = eLazyBoolCalculate;
m_source_regex_func_names.clear();
- m_commands.clear();
- m_auto_continue = false;
}
llvm::ArrayRef<OptionDefinition> GetDefinitions() override {
@@ -482,30 +611,21 @@ public:
FileSpecList m_modules;
lldb::addr_t m_load_addr;
lldb::addr_t m_offset_addr;
- uint32_t m_ignore_count;
- lldb::tid_t m_thread_id;
- uint32_t m_thread_index;
- std::string m_thread_name;
- std::string m_queue_name;
bool m_catch_bp;
bool m_throw_bp;
bool m_hardware; // Request to use hardware breakpoints
lldb::LanguageType m_exception_language;
lldb::LanguageType m_language;
LazyBool m_skip_prologue;
- bool m_one_shot;
- bool m_use_dummy;
bool m_all_files;
Args m_exception_extra_args;
LazyBool m_move_to_nearest_code;
std::unordered_set<std::string> m_source_regex_func_names;
- std::vector<std::string> m_commands;
- bool m_auto_continue;
};
protected:
bool DoExecute(Args &command, CommandReturnObject &result) override {
- Target *target = GetSelectedOrDummyTarget(m_options.m_use_dummy);
+ Target *target = GetSelectedOrDummyTarget(m_dummy_options.m_use_dummy);
if (target == nullptr) {
result.AppendError("Invalid target. Must set target before setting "
@@ -540,7 +660,7 @@ protected:
else if (m_options.m_exception_language != eLanguageTypeUnknown)
break_type = eSetTypeException;
- Breakpoint *bp = nullptr;
+ BreakpointSP bp_sp = nullptr;
FileSpec module_spec;
const bool internal = false;
@@ -572,35 +692,32 @@ protected:
// Only check for inline functions if
LazyBool check_inlines = eLazyBoolCalculate;
- bp = target
- ->CreateBreakpoint(&(m_options.m_modules), file,
- m_options.m_line_num, m_options.m_offset_addr,
- check_inlines, m_options.m_skip_prologue,
- internal, m_options.m_hardware,
- m_options.m_move_to_nearest_code)
- .get();
+ bp_sp = target->CreateBreakpoint(&(m_options.m_modules),
+ file,
+ m_options.m_line_num,
+ m_options.m_offset_addr,
+ check_inlines,
+ m_options.m_skip_prologue,
+ internal,
+ m_options.m_hardware,
+ m_options.m_move_to_nearest_code);
} break;
case eSetTypeAddress: // Breakpoint by address
{
// If a shared library has been specified, make an lldb_private::Address
- // with the library, and
- // use that. That way the address breakpoint will track the load location
- // of the library.
+ // with the library, and use that. That way the address breakpoint
+ // will track the load location of the library.
size_t num_modules_specified = m_options.m_modules.GetSize();
if (num_modules_specified == 1) {
const FileSpec *file_spec =
m_options.m_modules.GetFileSpecPointerAtIndex(0);
- bp = target
- ->CreateAddressInModuleBreakpoint(m_options.m_load_addr,
- internal, file_spec,
- m_options.m_hardware)
- .get();
+ bp_sp = target->CreateAddressInModuleBreakpoint(m_options.m_load_addr,
+ internal, file_spec,
+ m_options.m_hardware);
} else if (num_modules_specified == 0) {
- bp = target
- ->CreateBreakpoint(m_options.m_load_addr, internal,
- m_options.m_hardware)
- .get();
+ bp_sp = target->CreateBreakpoint(m_options.m_load_addr, internal,
+ m_options.m_hardware);
} else {
result.AppendError("Only one shared library can be specified for "
"address breakpoints.");
@@ -616,13 +733,15 @@ protected:
if (name_type_mask == 0)
name_type_mask = eFunctionNameTypeAuto;
- bp = target
- ->CreateBreakpoint(
- &(m_options.m_modules), &(m_options.m_filenames),
- m_options.m_func_names, name_type_mask, m_options.m_language,
- m_options.m_offset_addr, m_options.m_skip_prologue, internal,
- m_options.m_hardware)
- .get();
+ bp_sp = target->CreateBreakpoint(&(m_options.m_modules),
+ &(m_options.m_filenames),
+ m_options.m_func_names,
+ name_type_mask,
+ m_options.m_language,
+ m_options.m_offset_addr,
+ m_options.m_skip_prologue,
+ internal,
+ m_options.m_hardware);
} break;
case eSetTypeFunctionRegexp: // Breakpoint by regular expression function
@@ -639,12 +758,13 @@ protected:
return false;
}
- bp = target
- ->CreateFuncRegexBreakpoint(
- &(m_options.m_modules), &(m_options.m_filenames), regexp,
- m_options.m_language, m_options.m_skip_prologue, internal,
- m_options.m_hardware)
- .get();
+ bp_sp = target->CreateFuncRegexBreakpoint(&(m_options.m_modules),
+ &(m_options.m_filenames),
+ regexp,
+ m_options.m_language,
+ m_options.m_skip_prologue,
+ internal,
+ m_options.m_hardware);
}
break;
case eSetTypeSourceRegexp: // Breakpoint by regexp on source text.
@@ -673,26 +793,30 @@ protected:
result.SetStatus(eReturnStatusFailed);
return false;
}
- bp = target
- ->CreateSourceRegexBreakpoint(
- &(m_options.m_modules), &(m_options.m_filenames),
- m_options.m_source_regex_func_names, regexp, internal,
- m_options.m_hardware, m_options.m_move_to_nearest_code)
- .get();
+ bp_sp =
+ target->CreateSourceRegexBreakpoint(&(m_options.m_modules),
+ &(m_options.m_filenames),
+ m_options
+ .m_source_regex_func_names,
+ regexp,
+ internal,
+ m_options.m_hardware,
+ m_options.m_move_to_nearest_code);
} break;
case eSetTypeException: {
Status precond_error;
- bp = target
- ->CreateExceptionBreakpoint(
- m_options.m_exception_language, m_options.m_catch_bp,
- m_options.m_throw_bp, internal,
- &m_options.m_exception_extra_args, &precond_error)
- .get();
+ bp_sp = target->CreateExceptionBreakpoint(m_options.m_exception_language,
+ m_options.m_catch_bp,
+ m_options.m_throw_bp,
+ internal,
+ &m_options
+ .m_exception_extra_args,
+ &precond_error);
if (precond_error.Fail()) {
result.AppendErrorWithFormat(
"Error setting extra exception arguments: %s",
precond_error.AsCString());
- target->RemoveBreakpointByID(bp->GetID());
+ target->RemoveBreakpointByID(bp_sp->GetID());
result.SetStatus(eReturnStatusFailed);
return false;
}
@@ -702,76 +826,43 @@ protected:
}
// Now set the various options that were passed in:
- if (bp) {
- if (m_options.m_thread_id != LLDB_INVALID_THREAD_ID)
- bp->SetThreadID(m_options.m_thread_id);
-
- if (m_options.m_thread_index != UINT32_MAX)
- bp->GetOptions()->GetThreadSpec()->SetIndex(m_options.m_thread_index);
-
- if (!m_options.m_thread_name.empty())
- bp->GetOptions()->GetThreadSpec()->SetName(
- m_options.m_thread_name.c_str());
-
- if (!m_options.m_queue_name.empty())
- bp->GetOptions()->GetThreadSpec()->SetQueueName(
- m_options.m_queue_name.c_str());
-
- if (m_options.m_ignore_count != 0)
- bp->GetOptions()->SetIgnoreCount(m_options.m_ignore_count);
-
- if (!m_options.m_condition.empty())
- bp->GetOptions()->SetCondition(m_options.m_condition.c_str());
+ if (bp_sp) {
+ bp_sp->GetOptions()->CopyOverSetOptions(m_bp_opts.GetBreakpointOptions());
if (!m_options.m_breakpoint_names.empty()) {
Status name_error;
for (auto name : m_options.m_breakpoint_names) {
- bp->AddName(name.c_str(), name_error);
+ target->AddNameToBreakpoint(bp_sp, name.c_str(), name_error);
if (name_error.Fail()) {
result.AppendErrorWithFormat("Invalid breakpoint name: %s",
name.c_str());
- target->RemoveBreakpointByID(bp->GetID());
+ target->RemoveBreakpointByID(bp_sp->GetID());
result.SetStatus(eReturnStatusFailed);
return false;
}
}
}
-
- bp->SetOneShot(m_options.m_one_shot);
- bp->SetAutoContinue(m_options.m_auto_continue);
-
- if (!m_options.m_commands.empty())
- {
- auto cmd_data = llvm::make_unique<BreakpointOptions::CommandData>();
-
- for (std::string &str : m_options.m_commands)
- cmd_data->user_source.AppendString(str);
-
- cmd_data->stop_on_error = true;
- bp->GetOptions()->SetCommandDataCallback(cmd_data);
- }
}
-
- if (bp) {
+
+ if (bp_sp) {
Stream &output_stream = result.GetOutputStream();
const bool show_locations = false;
- bp->GetDescription(&output_stream, lldb::eDescriptionLevelInitial,
+ bp_sp->GetDescription(&output_stream, lldb::eDescriptionLevelInitial,
show_locations);
if (target == m_interpreter.GetDebugger().GetDummyTarget())
output_stream.Printf("Breakpoint set in dummy target, will get copied "
"into future targets.\n");
else {
// Don't print out this warning for exception breakpoints. They can get
- // set before the target
- // is set, but we won't know how to actually set the breakpoint till we
- // run.
- if (bp->GetNumLocations() == 0 && break_type != eSetTypeException) {
+ // set before the target is set, but we won't know how to actually set
+ // the breakpoint till we run.
+ if (bp_sp->GetNumLocations() == 0 && break_type != eSetTypeException) {
output_stream.Printf("WARNING: Unable to resolve breakpoint to any "
"actual locations.\n");
}
}
result.SetStatus(eReturnStatusSuccessFinishResult);
- } else if (!bp) {
+ } else if (!bp_sp) {
result.AppendError("Breakpoint creation failed: No breakpoint created.");
result.SetStatus(eReturnStatusFailed);
}
@@ -813,30 +904,15 @@ private:
return true;
}
+ BreakpointOptionGroup m_bp_opts;
+ BreakpointDummyOptionGroup m_dummy_options;
CommandOptions m_options;
+ OptionGroupOptions m_all_options;
};
//-------------------------------------------------------------------------
// CommandObjectBreakpointModify
//-------------------------------------------------------------------------
-
-#pragma mark Modify::CommandOptions
-static OptionDefinition g_breakpoint_modify_options[] = {
- // clang-format off
- { LLDB_OPT_SET_ALL, false, "ignore-count", 'i', OptionParser::eRequiredArgument, nullptr, nullptr, 0, eArgTypeCount, "Set the number of times this breakpoint is skipped before stopping." },
- { LLDB_OPT_SET_ALL, false, "one-shot", 'o', OptionParser::eRequiredArgument, nullptr, nullptr, 0, eArgTypeBoolean, "The breakpoint is deleted the first time it stop causes a stop." },
- { LLDB_OPT_SET_ALL, false, "thread-index", 'x', OptionParser::eRequiredArgument, nullptr, nullptr, 0, eArgTypeThreadIndex, "The breakpoint stops only for the thread whose index matches this argument." },
- { LLDB_OPT_SET_ALL, false, "thread-id", 't', OptionParser::eRequiredArgument, nullptr, nullptr, 0, eArgTypeThreadID, "The breakpoint stops only for the thread whose TID matches this argument." },
- { LLDB_OPT_SET_ALL, false, "thread-name", 'T', OptionParser::eRequiredArgument, nullptr, nullptr, 0, eArgTypeThreadName, "The breakpoint stops only for the thread whose thread name matches this argument." },
- { LLDB_OPT_SET_ALL, false, "queue-name", 'q', OptionParser::eRequiredArgument, nullptr, nullptr, 0, eArgTypeQueueName, "The breakpoint stops only for threads in the queue whose name is given by this argument." },
- { LLDB_OPT_SET_ALL, false, "condition", 'c', OptionParser::eRequiredArgument, nullptr, nullptr, 0, eArgTypeExpression, "The breakpoint stops only if this condition expression evaluates to true." },
- { LLDB_OPT_SET_1, false, "enable", 'e', OptionParser::eNoArgument, nullptr, nullptr, 0, eArgTypeNone, "Enable the breakpoint." },
- { LLDB_OPT_SET_2, false, "disable", 'd', OptionParser::eNoArgument, nullptr, nullptr, 0, eArgTypeNone, "Disable the breakpoint." },
- { LLDB_OPT_SET_ALL, false, "dummy-breakpoints", 'D', OptionParser::eNoArgument, nullptr, nullptr, 0, eArgTypeNone, "Sets Dummy breakpoints - i.e. breakpoints set before a file is provided, which prime new targets." },
- { LLDB_OPT_SET_ALL, false, "auto-continue", 'G', OptionParser::eRequiredArgument, nullptr, nullptr, 0, eArgTypeBoolean, "The breakpoint will auto-continue after running its commands." },
- // clang-format on
-};
-
#pragma mark Modify
class CommandObjectBreakpointModify : public CommandObjectParsed {
@@ -857,163 +933,21 @@ public:
// Add the entry for the first argument for this command to the object's
// arguments vector.
m_arguments.push_back(arg);
+
+ m_options.Append(&m_bp_opts,
+ LLDB_OPT_SET_1 | LLDB_OPT_SET_2 | LLDB_OPT_SET_3,
+ LLDB_OPT_SET_ALL);
+ m_options.Append(&m_dummy_opts, LLDB_OPT_SET_1, LLDB_OPT_SET_ALL);
+ m_options.Finalize();
}
~CommandObjectBreakpointModify() override = default;
Options *GetOptions() override { return &m_options; }
- class CommandOptions : public Options {
- public:
- CommandOptions()
- : Options(), m_ignore_count(0), m_thread_id(LLDB_INVALID_THREAD_ID),
- m_thread_id_passed(false), m_thread_index(UINT32_MAX),
- m_thread_index_passed(false), m_thread_name(), m_queue_name(),
- m_condition(), m_one_shot(false), m_enable_passed(false),
- m_enable_value(false), m_name_passed(false), m_queue_passed(false),
- m_condition_passed(false), m_one_shot_passed(false),
- m_use_dummy(false) {}
-
- ~CommandOptions() override = default;
-
- Status SetOptionValue(uint32_t option_idx, llvm::StringRef option_arg,
- ExecutionContext *execution_context) override {
- Status error;
- const int short_option = m_getopt_table[option_idx].val;
-
- switch (short_option) {
- case 'c':
- m_condition = option_arg;
- m_condition_passed = true;
- break;
- case 'd':
- m_enable_passed = true;
- m_enable_value = false;
- break;
- case 'D':
- m_use_dummy = true;
- break;
- case 'e':
- m_enable_passed = true;
- m_enable_value = true;
- break;
- case 'G': {
- bool value, success;
- value = Args::StringToBoolean(option_arg, false, &success);
- if (success) {
- m_auto_continue_passed = true;
- m_auto_continue = value;
- } else
- error.SetErrorStringWithFormat(
- "invalid boolean value '%s' passed for -G option",
- option_arg.str().c_str());
- } break;
- case 'i':
- if (option_arg.getAsInteger(0, m_ignore_count))
- error.SetErrorStringWithFormat("invalid ignore count '%s'",
- option_arg.str().c_str());
- break;
- case 'o': {
- bool value, success;
- value = Args::StringToBoolean(option_arg, false, &success);
- if (success) {
- m_one_shot_passed = true;
- m_one_shot = value;
- } else
- error.SetErrorStringWithFormat(
- "invalid boolean value '%s' passed for -o option",
- option_arg.str().c_str());
- } break;
- case 't':
- if (option_arg[0] == '\0') {
- m_thread_id = LLDB_INVALID_THREAD_ID;
- m_thread_id_passed = true;
- } else {
- if (option_arg.getAsInteger(0, m_thread_id))
- error.SetErrorStringWithFormat("invalid thread id string '%s'",
- option_arg.str().c_str());
- else
- m_thread_id_passed = true;
- }
- break;
- case 'T':
- m_thread_name = option_arg;
- m_name_passed = true;
- break;
- case 'q':
- m_queue_name = option_arg;
- m_queue_passed = true;
- break;
- case 'x':
- if (option_arg[0] == '\n') {
- m_thread_index = UINT32_MAX;
- m_thread_index_passed = true;
- } else {
- if (option_arg.getAsInteger(0, m_thread_index))
- error.SetErrorStringWithFormat("invalid thread index string '%s'",
- option_arg.str().c_str());
- else
- m_thread_index_passed = true;
- }
- break;
- default:
- error.SetErrorStringWithFormat("unrecognized option '%c'",
- short_option);
- break;
- }
-
- return error;
- }
-
- void OptionParsingStarting(ExecutionContext *execution_context) override {
- m_ignore_count = 0;
- m_thread_id = LLDB_INVALID_THREAD_ID;
- m_thread_id_passed = false;
- m_thread_index = UINT32_MAX;
- m_thread_index_passed = false;
- m_thread_name.clear();
- m_queue_name.clear();
- m_condition.clear();
- m_one_shot = false;
- m_enable_passed = false;
- m_queue_passed = false;
- m_name_passed = false;
- m_condition_passed = false;
- m_one_shot_passed = false;
- m_use_dummy = false;
- m_auto_continue = false;
- m_auto_continue_passed = false;
- }
-
- llvm::ArrayRef<OptionDefinition> GetDefinitions() override {
- return llvm::makeArrayRef(g_breakpoint_modify_options);
- }
-
- // Instance variables to hold the values for command options.
-
- uint32_t m_ignore_count;
- lldb::tid_t m_thread_id;
- bool m_thread_id_passed;
- uint32_t m_thread_index;
- bool m_thread_index_passed;
- std::string m_thread_name;
- std::string m_queue_name;
- std::string m_condition;
- bool m_one_shot;
- bool m_enable_passed;
- bool m_enable_value;
- bool m_name_passed;
- bool m_queue_passed;
- bool m_condition_passed;
- bool m_one_shot_passed;
- bool m_use_dummy;
- bool m_auto_continue;
- bool m_auto_continue_passed;
- };
-
protected:
bool DoExecute(Args &command, CommandReturnObject &result) override {
- Target *target = GetSelectedOrDummyTarget(m_options.m_use_dummy);
+ Target *target = GetSelectedOrDummyTarget(m_dummy_opts.m_use_dummy);
if (target == nullptr) {
result.AppendError("Invalid target. No existing target or breakpoints.");
result.SetStatus(eReturnStatusFailed);
@@ -1026,7 +960,8 @@ protected:
BreakpointIDList valid_bp_ids;
CommandObjectMultiwordBreakpoint::VerifyBreakpointOrLocationIDs(
- command, target, result, &valid_bp_ids);
+ command, target, result, &valid_bp_ids,
+ BreakpointName::Permissions::PermissionKinds::disablePerm);
if (result.Succeeded()) {
const size_t count = valid_bp_ids.GetSize();
@@ -1039,55 +974,12 @@ protected:
if (cur_bp_id.GetLocationID() != LLDB_INVALID_BREAK_ID) {
BreakpointLocation *location =
bp->FindLocationByID(cur_bp_id.GetLocationID()).get();
- if (location) {
- if (m_options.m_thread_id_passed)
- location->SetThreadID(m_options.m_thread_id);
-
- if (m_options.m_thread_index_passed)
- location->SetThreadIndex(m_options.m_thread_index);
-
- if (m_options.m_name_passed)
- location->SetThreadName(m_options.m_thread_name.c_str());
-
- if (m_options.m_queue_passed)
- location->SetQueueName(m_options.m_queue_name.c_str());
-
- if (m_options.m_ignore_count != 0)
- location->SetIgnoreCount(m_options.m_ignore_count);
-
- if (m_options.m_enable_passed)
- location->SetEnabled(m_options.m_enable_value);
-
- if (m_options.m_condition_passed)
- location->SetCondition(m_options.m_condition.c_str());
-
- if (m_options.m_auto_continue_passed)
- location->SetAutoContinue(m_options.m_auto_continue);
- }
+ if (location)
+ location->GetLocationOptions()
+ ->CopyOverSetOptions(m_bp_opts.GetBreakpointOptions());
} else {
- if (m_options.m_thread_id_passed)
- bp->SetThreadID(m_options.m_thread_id);
-
- if (m_options.m_thread_index_passed)
- bp->SetThreadIndex(m_options.m_thread_index);
-
- if (m_options.m_name_passed)
- bp->SetThreadName(m_options.m_thread_name.c_str());
-
- if (m_options.m_queue_passed)
- bp->SetQueueName(m_options.m_queue_name.c_str());
-
- if (m_options.m_ignore_count != 0)
- bp->SetIgnoreCount(m_options.m_ignore_count);
-
- if (m_options.m_enable_passed)
- bp->SetEnabled(m_options.m_enable_value);
-
- if (m_options.m_condition_passed)
- bp->SetCondition(m_options.m_condition.c_str());
-
- if (m_options.m_auto_continue_passed)
- bp->SetAutoContinue(m_options.m_auto_continue);
+ bp->GetOptions()
+ ->CopyOverSetOptions(m_bp_opts.GetBreakpointOptions());
}
}
}
@@ -1097,7 +989,9 @@ protected:
}
private:
- CommandOptions m_options;
+ BreakpointOptionGroup m_bp_opts;
+ BreakpointDummyOptionGroup m_dummy_opts;
+ OptionGroupOptions m_options;
};
//-------------------------------------------------------------------------
@@ -1146,7 +1040,7 @@ protected:
if (command.empty()) {
// No breakpoint selected; enable all currently set breakpoints.
- target->EnableAllBreakpoints();
+ target->EnableAllowedBreakpoints();
result.AppendMessageWithFormat("All breakpoints enabled. (%" PRIu64
" breakpoints)\n",
(uint64_t)num_breakpoints);
@@ -1155,7 +1049,8 @@ protected:
// Particular breakpoint selected; enable that breakpoint.
BreakpointIDList valid_bp_ids;
CommandObjectMultiwordBreakpoint::VerifyBreakpointOrLocationIDs(
- command, target, result, &valid_bp_ids);
+ command, target, result, &valid_bp_ids,
+ BreakpointName::Permissions::PermissionKinds::disablePerm);
if (result.Succeeded()) {
int enable_count = 0;
@@ -1259,7 +1154,7 @@ protected:
if (command.empty()) {
// No breakpoint selected; disable all currently set breakpoints.
- target->DisableAllBreakpoints();
+ target->DisableAllowedBreakpoints();
result.AppendMessageWithFormat("All breakpoints disabled. (%" PRIu64
" breakpoints)\n",
(uint64_t)num_breakpoints);
@@ -1269,7 +1164,8 @@ protected:
BreakpointIDList valid_bp_ids;
CommandObjectMultiwordBreakpoint::VerifyBreakpointOrLocationIDs(
- command, target, result, &valid_bp_ids);
+ command, target, result, &valid_bp_ids,
+ BreakpointName::Permissions::PermissionKinds::disablePerm);
if (result.Succeeded()) {
int disable_count = 0;
@@ -1436,14 +1332,17 @@ protected:
result.AppendMessage("Current breakpoints:");
for (size_t i = 0; i < num_breakpoints; ++i) {
Breakpoint *breakpoint = breakpoints.GetBreakpointAtIndex(i).get();
- AddBreakpointDescription(&output_stream, breakpoint, m_options.m_level);
+ if (breakpoint->AllowList())
+ AddBreakpointDescription(&output_stream, breakpoint,
+ m_options.m_level);
}
result.SetStatus(eReturnStatusSuccessFinishNoResult);
} else {
// Particular breakpoints selected; show info about that breakpoint.
BreakpointIDList valid_bp_ids;
CommandObjectMultiwordBreakpoint::VerifyBreakpointOrLocationIDs(
- command, target, result, &valid_bp_ids);
+ command, target, result, &valid_bp_ids,
+ BreakpointName::Permissions::PermissionKinds::listPerm);
if (result.Succeeded()) {
for (size_t i = 0; i < valid_bp_ids.GetSize(); ++i) {
@@ -1731,7 +1630,7 @@ protected:
true)) {
result.AppendMessage("Operation cancelled...");
} else {
- target->RemoveAllBreakpoints();
+ target->RemoveAllowedBreakpoints();
result.AppendMessageWithFormat(
"All breakpoints removed. (%" PRIu64 " breakpoint%s)\n",
(uint64_t)num_breakpoints, num_breakpoints > 1 ? "s" : "");
@@ -1741,7 +1640,8 @@ protected:
// Particular breakpoint selected; disable that breakpoint.
BreakpointIDList valid_bp_ids;
CommandObjectMultiwordBreakpoint::VerifyBreakpointOrLocationIDs(
- command, target, result, &valid_bp_ids);
+ command, target, result, &valid_bp_ids,
+ BreakpointName::Permissions::PermissionKinds::deletePerm);
if (result.Succeeded()) {
int delete_count = 0;
@@ -1789,7 +1689,7 @@ static OptionDefinition g_breakpoint_name_options[] = {
// clang-format off
{LLDB_OPT_SET_1, false, "name", 'N', OptionParser::eRequiredArgument, nullptr, nullptr, 0, eArgTypeBreakpointName, "Specifies a breakpoint name to use."},
{LLDB_OPT_SET_2, false, "breakpoint-id", 'B', OptionParser::eRequiredArgument, nullptr, nullptr, 0, eArgTypeBreakpointID, "Specify a breakpoint ID to use."},
- {LLDB_OPT_SET_ALL, false, "dummy-breakpoints", 'D', OptionParser::eNoArgument, nullptr, nullptr, 0, eArgTypeNone, "Operate on Dummy breakpoints - i.e. breakpoints set before a file is provided, which prime new targets."},
+ {LLDB_OPT_SET_3, false, "dummy-breakpoints", 'D', OptionParser::eNoArgument, nullptr, nullptr, 0, eArgTypeNone, "Operate on Dummy breakpoints - i.e. breakpoints set before a file is provided, which prime new targets."},
// clang-format on
};
class BreakpointNameOptionGroup : public OptionGroup {
@@ -1849,6 +1749,188 @@ public:
OptionValueBoolean m_use_dummy;
};
+static OptionDefinition g_breakpoint_access_options[] = {
+ // clang-format off
+ {LLDB_OPT_SET_1, false, "allow-list", 'L', OptionParser::eRequiredArgument, nullptr, nullptr, 0, eArgTypeBoolean, "Determines whether the breakpoint will show up in break list if not referred to explicitly."},
+ {LLDB_OPT_SET_2, false, "allow-disable", 'A', OptionParser::eRequiredArgument, nullptr, nullptr, 0, eArgTypeBoolean, "Determines whether the breakpoint can be disabled by name or when all breakpoints are disabled."},
+ {LLDB_OPT_SET_3, false, "allow-delete", 'D', OptionParser::eRequiredArgument, nullptr, nullptr, 0, eArgTypeBoolean, "Determines whether the breakpoint can be deleted by name or when all breakpoints are deleted."},
+ // clang-format on
+};
+
+class BreakpointAccessOptionGroup : public OptionGroup
+{
+public:
+ BreakpointAccessOptionGroup() :
+ OptionGroup()
+ {}
+
+ ~BreakpointAccessOptionGroup() override = default;
+
+ llvm::ArrayRef<OptionDefinition> GetDefinitions() override {
+ return llvm::makeArrayRef(g_breakpoint_access_options);
+ }
+ Status SetOptionValue(uint32_t option_idx, llvm::StringRef option_arg,
+ ExecutionContext *execution_context) override {
+ Status error;
+ const int short_option
+ = g_breakpoint_access_options[option_idx].short_option;
+
+ switch (short_option) {
+ case 'L': {
+ bool value, success;
+ value = Args::StringToBoolean(option_arg, false, &success);
+ if (success) {
+ m_permissions.SetAllowList(value);
+ } else
+ error.SetErrorStringWithFormat(
+ "invalid boolean value '%s' passed for -L option",
+ option_arg.str().c_str());
+ } break;
+ case 'A': {
+ bool value, success;
+ value = Args::StringToBoolean(option_arg, false, &success);
+ if (success) {
+ m_permissions.SetAllowDisable(value);
+ } else
+ error.SetErrorStringWithFormat(
+ "invalid boolean value '%s' passed for -L option",
+ option_arg.str().c_str());
+ } break;
+ case 'D': {
+ bool value, success;
+ value = Args::StringToBoolean(option_arg, false, &success);
+ if (success) {
+ m_permissions.SetAllowDelete(value);
+ } else
+ error.SetErrorStringWithFormat(
+ "invalid boolean value '%s' passed for -L option",
+ option_arg.str().c_str());
+ } break;
+
+ }
+
+ return error;
+ }
+
+ void OptionParsingStarting(ExecutionContext *execution_context) override {
+ }
+
+ const BreakpointName::Permissions &GetPermissions() const
+ {
+ return m_permissions;
+ }
+ BreakpointName::Permissions m_permissions;
+};
+
+class CommandObjectBreakpointNameConfigure : public CommandObjectParsed {
+public:
+ CommandObjectBreakpointNameConfigure(CommandInterpreter &interpreter)
+ : CommandObjectParsed(
+ interpreter, "configure", "Configure the options for the breakpoint"
+ " name provided. "
+ "If you provide a breakpoint id, the options will be copied from "
+ "the breakpoint, otherwise only the options specified will be set "
+ "on the name.",
+ "breakpoint name configure <command-options> "
+ "<breakpoint-name-list>"),
+ m_bp_opts(), m_option_group() {
+ // Create the first variant for the first (and only) argument for this
+ // command.
+ CommandArgumentEntry arg1;
+ CommandArgumentData id_arg;
+ id_arg.arg_type = eArgTypeBreakpointName;
+ id_arg.arg_repetition = eArgRepeatOptional;
+ arg1.push_back(id_arg);
+ m_arguments.push_back(arg1);
+
+ m_option_group.Append(&m_bp_opts,
+ LLDB_OPT_SET_ALL,
+ LLDB_OPT_SET_1);
+ m_option_group.Append(&m_access_options,
+ LLDB_OPT_SET_ALL,
+ LLDB_OPT_SET_ALL);
+ m_option_group.Append(&m_bp_id, LLDB_OPT_SET_2, LLDB_OPT_SET_2);
+ m_option_group.Finalize();
+ }
+
+ ~CommandObjectBreakpointNameConfigure() override = default;
+
+ Options *GetOptions() override { return &m_option_group; }
+
+protected:
+ bool DoExecute(Args &command, CommandReturnObject &result) override {
+
+ const size_t argc = command.GetArgumentCount();
+ if (argc == 0) {
+ result.AppendError("No names provided.");
+ result.SetStatus(eReturnStatusFailed);
+ return false;
+ }
+
+ Target *target =
+ GetSelectedOrDummyTarget(false);
+
+ if (target == nullptr) {
+ result.AppendError("Invalid target. No existing target or breakpoints.");
+ result.SetStatus(eReturnStatusFailed);
+ return false;
+ }
+
+ std::unique_lock<std::recursive_mutex> lock;
+ target->GetBreakpointList().GetListMutex(lock);
+
+ // Make a pass through first to see that all the names are legal.
+ for (auto &entry : command.entries()) {
+ Status error;
+ if (!BreakpointID::StringIsBreakpointName(entry.ref, error))
+ {
+ result.AppendErrorWithFormat("Invalid breakpoint name: %s - %s",
+ entry.c_str(), error.AsCString());
+ result.SetStatus(eReturnStatusFailed);
+ return false;
+ }
+ }
+ // Now configure them, we already pre-checked the names so we don't need
+ // to check the error:
+ BreakpointSP bp_sp;
+ if (m_bp_id.m_breakpoint.OptionWasSet())
+ {
+ lldb::break_id_t bp_id = m_bp_id.m_breakpoint.GetUInt64Value();
+ bp_sp = target->GetBreakpointByID(bp_id);
+ if (!bp_sp)
+ {
+ result.AppendErrorWithFormatv("Could not find specified breakpoint {0}",
+ bp_id);
+ result.SetStatus(eReturnStatusFailed);
+ return false;
+ }
+ }
+
+ Status error;
+ for (auto &entry : command.entries()) {
+ ConstString name(entry.c_str());
+ BreakpointName *bp_name = target->FindBreakpointName(name, true, error);
+ if (!bp_name)
+ continue;
+ if (bp_sp)
+ target->ConfigureBreakpointName(*bp_name,
+ *bp_sp->GetOptions(),
+ m_access_options.GetPermissions());
+ else
+ target->ConfigureBreakpointName(*bp_name,
+ m_bp_opts.GetBreakpointOptions(),
+ m_access_options.GetPermissions());
+ }
+ return true;
+ }
+
+private:
+ BreakpointNameOptionGroup m_bp_id; // Only using the id part of this.
+ BreakpointOptionGroup m_bp_opts;
+ BreakpointAccessOptionGroup m_access_options;
+ OptionGroupOptions m_option_group;
+};
+
class CommandObjectBreakpointNameAdd : public CommandObjectParsed {
public:
CommandObjectBreakpointNameAdd(CommandInterpreter &interpreter)
@@ -1904,7 +1986,8 @@ protected:
// Particular breakpoint selected; disable that breakpoint.
BreakpointIDList valid_bp_ids;
CommandObjectMultiwordBreakpoint::VerifyBreakpointIDs(
- command, target, result, &valid_bp_ids);
+ command, target, result, &valid_bp_ids,
+ BreakpointName::Permissions::PermissionKinds::listPerm);
if (result.Succeeded()) {
if (valid_bp_ids.GetSize() == 0) {
@@ -1913,13 +1996,14 @@ protected:
return false;
}
size_t num_valid_ids = valid_bp_ids.GetSize();
+ const char *bp_name = m_name_options.m_name.GetCurrentValue();
+ Status error; // This error reports illegal names, but we've already
+ // checked that, so we don't need to check it again here.
for (size_t index = 0; index < num_valid_ids; index++) {
lldb::break_id_t bp_id =
valid_bp_ids.GetBreakpointIDAtIndex(index).GetBreakpointID();
BreakpointSP bp_sp = breakpoints.FindBreakpointByID(bp_id);
- Status error; // We don't need to check the error here, since the option
- // parser checked it...
- bp_sp->AddName(m_name_options.m_name.GetCurrentValue(), error);
+ target->AddNameToBreakpoint(bp_sp, bp_name, error);
}
}
@@ -1987,7 +2071,8 @@ protected:
// Particular breakpoint selected; disable that breakpoint.
BreakpointIDList valid_bp_ids;
CommandObjectMultiwordBreakpoint::VerifyBreakpointIDs(
- command, target, result, &valid_bp_ids);
+ command, target, result, &valid_bp_ids,
+ BreakpointName::Permissions::PermissionKinds::deletePerm);
if (result.Succeeded()) {
if (valid_bp_ids.GetSize() == 0) {
@@ -1995,12 +2080,13 @@ protected:
result.SetStatus(eReturnStatusFailed);
return false;
}
+ ConstString bp_name(m_name_options.m_name.GetCurrentValue());
size_t num_valid_ids = valid_bp_ids.GetSize();
for (size_t index = 0; index < num_valid_ids; index++) {
lldb::break_id_t bp_id =
valid_bp_ids.GetBreakpointIDAtIndex(index).GetBreakpointID();
BreakpointSP bp_sp = breakpoints.FindBreakpointByID(bp_id);
- bp_sp->RemoveName(m_name_options.m_name.GetCurrentValue());
+ target->RemoveNameFromBreakpoint(bp_sp, bp_name);
}
}
@@ -2016,11 +2102,12 @@ class CommandObjectBreakpointNameList : public CommandObjectParsed {
public:
CommandObjectBreakpointNameList(CommandInterpreter &interpreter)
: CommandObjectParsed(interpreter, "list",
- "List either the names for a breakpoint or the "
- "breakpoints for a given name.",
+ "List either the names for a breakpoint or info "
+ "about a given name. With no arguments, lists all "
+ "names",
"breakpoint name list <command-options>"),
m_name_options(), m_option_group() {
- m_option_group.Append(&m_name_options);
+ m_option_group.Append(&m_name_options, LLDB_OPT_SET_3, LLDB_OPT_SET_ALL);
m_option_group.Finalize();
}
@@ -2038,42 +2125,57 @@ protected:
result.SetStatus(eReturnStatusFailed);
return false;
}
-
- if (m_name_options.m_name.OptionWasSet()) {
- const char *name = m_name_options.m_name.GetCurrentValue();
- std::unique_lock<std::recursive_mutex> lock;
- target->GetBreakpointList().GetListMutex(lock);
-
- BreakpointList &breakpoints = target->GetBreakpointList();
- for (BreakpointSP bp_sp : breakpoints.Breakpoints()) {
- if (bp_sp->MatchesName(name)) {
+
+
+ std::vector<std::string> name_list;
+ if (command.empty()) {
+ target->GetBreakpointNames(name_list);
+ } else {
+ for (const Args::ArgEntry &arg : command)
+ {
+ name_list.push_back(arg.c_str());
+ }
+ }
+
+ if (name_list.empty()) {
+ result.AppendMessage("No breakpoint names found.");
+ } else {
+ for (const std::string &name_str : name_list) {
+ const char *name = name_str.c_str();
+ // First print out the options for the name:
+ Status error;
+ BreakpointName *bp_name = target->FindBreakpointName(ConstString(name),
+ false,
+ error);
+ if (bp_name)
+ {
StreamString s;
- bp_sp->GetDescription(&s, eDescriptionLevelBrief);
- s.EOL();
- result.AppendMessage(s.GetString());
+ result.AppendMessageWithFormat("Name: %s\n", name);
+ if (bp_name->GetDescription(&s, eDescriptionLevelFull))
+ {
+ result.AppendMessage(s.GetString());
+ }
+
+ std::unique_lock<std::recursive_mutex> lock;
+ target->GetBreakpointList().GetListMutex(lock);
+
+ BreakpointList &breakpoints = target->GetBreakpointList();
+ bool any_set = false;
+ for (BreakpointSP bp_sp : breakpoints.Breakpoints()) {
+ if (bp_sp->MatchesName(name)) {
+ StreamString s;
+ any_set = true;
+ bp_sp->GetDescription(&s, eDescriptionLevelBrief);
+ s.EOL();
+ result.AppendMessage(s.GetString());
+ }
+ }
+ if (!any_set)
+ result.AppendMessage("No breakpoints using this name.");
+ } else {
+ result.AppendMessageWithFormat("Name: %s not found.\n", name);
}
}
-
- } else if (m_name_options.m_breakpoint.OptionWasSet()) {
- BreakpointSP bp_sp = target->GetBreakpointList().FindBreakpointByID(
- m_name_options.m_breakpoint.GetCurrentValue());
- if (bp_sp) {
- std::vector<std::string> names;
- bp_sp->GetNames(names);
- result.AppendMessage("Names:");
- for (auto name : names)
- result.AppendMessageWithFormat(" %s\n", name.c_str());
- } else {
- result.AppendErrorWithFormat(
- "Could not find breakpoint %" PRId64 ".\n",
- m_name_options.m_breakpoint.GetCurrentValue());
- result.SetStatus(eReturnStatusFailed);
- return false;
- }
- } else {
- result.SetError("Must specify -N or -B option to list.");
- result.SetStatus(eReturnStatusFailed);
- return false;
}
return true;
}
@@ -2098,10 +2200,13 @@ public:
new CommandObjectBreakpointNameDelete(interpreter));
CommandObjectSP list_command_object(
new CommandObjectBreakpointNameList(interpreter));
+ CommandObjectSP configure_command_object(
+ new CommandObjectBreakpointNameConfigure(interpreter));
LoadSubCommand("add", add_command_object);
LoadSubCommand("delete", delete_command_object);
LoadSubCommand("list", list_command_object);
+ LoadSubCommand("configure", configure_command_object);
}
~CommandObjectBreakpointName() override = default;
@@ -2327,7 +2432,8 @@ protected:
BreakpointIDList valid_bp_ids;
if (!command.empty()) {
CommandObjectMultiwordBreakpoint::VerifyBreakpointIDs(
- command, target, result, &valid_bp_ids);
+ command, target, result, &valid_bp_ids,
+ BreakpointName::Permissions::PermissionKinds::listPerm);
if (!result.Succeeded()) {
result.SetStatus(eReturnStatusFailed);
@@ -2412,7 +2518,10 @@ CommandObjectMultiwordBreakpoint::~CommandObjectMultiwordBreakpoint() = default;
void CommandObjectMultiwordBreakpoint::VerifyIDs(Args &args, Target *target,
bool allow_locations,
CommandReturnObject &result,
- BreakpointIDList *valid_ids) {
+ BreakpointIDList *valid_ids,
+ BreakpointName::Permissions
+ ::PermissionKinds
+ purpose) {
// args can be strings representing 1). integers (for breakpoint ids)
// 2). the full breakpoint & location
// canonical representation
@@ -2446,8 +2555,8 @@ void CommandObjectMultiwordBreakpoint::VerifyIDs(Args &args, Target *target,
// all the breakpoint ids in the range, and shove all of those breakpoint id
// strings into TEMP_ARGS.
- BreakpointIDList::FindAndReplaceIDRanges(args, target, allow_locations,
- result, temp_args);
+ BreakpointIDList::FindAndReplaceIDRanges(args, target, allow_locations,
+ purpose, result, temp_args);
// NOW, convert the list of breakpoint id strings in TEMP_ARGS into an actual
// BreakpointIDList:
diff --git a/lldb/source/Commands/CommandObjectBreakpoint.h b/lldb/source/Commands/CommandObjectBreakpoint.h
index 6e14b8f876a..5e1026a6b7e 100644
--- a/lldb/source/Commands/CommandObjectBreakpoint.h
+++ b/lldb/source/Commands/CommandObjectBreakpoint.h
@@ -18,11 +18,14 @@
// Other libraries and framework includes
// Project includes
+#include "lldb/lldb-private.h"
+#include "lldb/Breakpoint/BreakpointName.h"
#include "lldb/Core/Address.h"
#include "lldb/Core/STLUtils.h"
#include "lldb/Interpreter/CommandObjectMultiword.h"
#include "lldb/Interpreter/Options.h"
+
namespace lldb_private {
//-------------------------------------------------------------------------
@@ -37,20 +40,26 @@ public:
static void VerifyBreakpointOrLocationIDs(Args &args, Target *target,
CommandReturnObject &result,
- BreakpointIDList *valid_ids) {
- VerifyIDs(args, target, true, result, valid_ids);
+ BreakpointIDList *valid_ids,
+ BreakpointName::Permissions
+ ::PermissionKinds purpose) {
+ VerifyIDs(args, target, true, result, valid_ids, purpose);
}
static void VerifyBreakpointIDs(Args &args, Target *target,
CommandReturnObject &result,
- BreakpointIDList *valid_ids) {
- VerifyIDs(args, target, false, result, valid_ids);
+ BreakpointIDList *valid_ids,
+ BreakpointName::Permissions::PermissionKinds
+ purpose) {
+ VerifyIDs(args, target, false, result, valid_ids, purpose);
}
private:
static void VerifyIDs(Args &args, Target *target, bool allow_locations,
CommandReturnObject &result,
- BreakpointIDList *valid_ids);
+ BreakpointIDList *valid_ids,
+ BreakpointName::Permissions::PermissionKinds
+ purpose);
};
} // namespace lldb_private
diff --git a/lldb/source/Commands/CommandObjectBreakpointCommand.cpp b/lldb/source/Commands/CommandObjectBreakpointCommand.cpp
index ecb00f9a339..170cb851311 100644
--- a/lldb/source/Commands/CommandObjectBreakpointCommand.cpp
+++ b/lldb/source/Commands/CommandObjectBreakpointCommand.cpp
@@ -390,7 +390,8 @@ protected:
BreakpointIDList valid_bp_ids;
CommandObjectMultiwordBreakpoint::VerifyBreakpointOrLocationIDs(
- command, target, result, &valid_bp_ids);
+ command, target, result, &valid_bp_ids,
+ BreakpointName::Permissions::PermissionKinds::listPerm);
m_bp_options_vec.clear();
@@ -571,7 +572,8 @@ protected:
BreakpointIDList valid_bp_ids;
CommandObjectMultiwordBreakpoint::VerifyBreakpointOrLocationIDs(
- command, target, result, &valid_bp_ids);
+ command, target, result, &valid_bp_ids,
+ BreakpointName::Permissions::PermissionKinds::listPerm);
if (result.Succeeded()) {
const size_t count = valid_bp_ids.GetSize();
@@ -662,7 +664,8 @@ protected:
BreakpointIDList valid_bp_ids;
CommandObjectMultiwordBreakpoint::VerifyBreakpointOrLocationIDs(
- command, target, result, &valid_bp_ids);
+ command, target, result, &valid_bp_ids,
+ BreakpointName::Permissions::PermissionKinds::listPerm);
if (result.Succeeded()) {
const size_t count = valid_bp_ids.GetSize();
diff --git a/lldb/source/Interpreter/CommandObject.cpp b/lldb/source/Interpreter/CommandObject.cpp
index 96c245cb8bb..b1937d8b17b 100644
--- a/lldb/source/Interpreter/CommandObject.cpp
+++ b/lldb/source/Interpreter/CommandObject.cpp
@@ -1113,7 +1113,8 @@ CommandObject::ArgumentTableEntry CommandObject::g_arguments_data[] = {
{ eArgTypeWatchpointID, "watchpt-id", CommandCompletions::eNoCompletion, { nullptr, false }, "Watchpoint IDs are positive integers." },
{ eArgTypeWatchpointIDRange, "watchpt-id-list", CommandCompletions::eNoCompletion, { nullptr, false }, "For example, '1-3' or '1 to 3'." },
{ eArgTypeWatchType, "watch-type", CommandCompletions::eNoCompletion, { nullptr, false }, "Specify the type for a watchpoint." },
- { eArgRawInput, "raw-input", CommandCompletions::eNoCompletion, { nullptr, false }, "Free-form text passed to a command without prior interpretation, allowing spaces without requiring quotes. To pass arguments and free form text put two dashes ' -- ' between the last argument and any raw input." }
+ { eArgRawInput, "raw-input", CommandCompletions::eNoCompletion, { nullptr, false }, "Free-form text passed to a command without prior interpretation, allowing spaces without requiring quotes. To pass arguments and free form text put two dashes ' -- ' between the last argument and any raw input." },
+ { eArgTypeCommand, "command", CommandCompletions::eNoCompletion, { nullptr, false }, "An LLDB Command line command." }
// clang-format on
};
diff --git a/lldb/source/Plugins/LanguageRuntime/RenderScript/RenderScriptRuntime/RenderScriptRuntime.cpp b/lldb/source/Plugins/LanguageRuntime/RenderScript/RenderScriptRuntime/RenderScriptRuntime.cpp
index 7e46afcccda..ad1083be028 100644
--- a/lldb/source/Plugins/LanguageRuntime/RenderScript/RenderScriptRuntime/RenderScriptRuntime.cpp
+++ b/lldb/source/Plugins/LanguageRuntime/RenderScript/RenderScriptRuntime/RenderScriptRuntime.cpp
@@ -3615,13 +3615,15 @@ RenderScriptRuntime::CreateKernelBreakpoint(const ConstString &name) {
}
BreakpointResolverSP resolver_sp(new RSBreakpointResolver(nullptr, name));
- BreakpointSP bp = GetProcess()->GetTarget().CreateBreakpoint(
+ Target &target = GetProcess()->GetTarget();
+ BreakpointSP bp = target.CreateBreakpoint(
m_filtersp, resolver_sp, false, false, false);
// Give RS breakpoints a specific name, so the user can manipulate them as a
// group.
Status err;
- if (!bp->AddName("RenderScriptKernel", err))
+ target.AddNameToBreakpoint(bp, "RenderScriptKernel", err);
+ if (err.Fail() && log)
if (log)
log->Printf("%s - error setting break name, '%s'.", __FUNCTION__,
err.AsCString());
@@ -3643,14 +3645,15 @@ RenderScriptRuntime::CreateReductionBreakpoint(const ConstString &name,
BreakpointResolverSP resolver_sp(new RSReduceBreakpointResolver(
nullptr, name, &m_rsmodules, kernel_types));
- BreakpointSP bp = GetProcess()->GetTarget().CreateBreakpoint(
+ Target &target = GetProcess()->GetTarget();
+ BreakpointSP bp = target.CreateBreakpoint(
m_filtersp, resolver_sp, false, false, false);
// Give RS breakpoints a specific name, so the user can manipulate them as a
// group.
Status err;
- if (!bp->AddName("RenderScriptReduction", err))
- if (log)
+ target.AddNameToBreakpoint(bp, "RenderScriptReduction", err);
+ if (err.Fail() && log)
log->Printf("%s - error setting break name, '%s'.", __FUNCTION__,
err.AsCString());
@@ -3885,15 +3888,16 @@ RenderScriptRuntime::CreateScriptGroupBreakpoint(const ConstString &name,
BreakpointResolverSP resolver_sp(new RSScriptGroupBreakpointResolver(
nullptr, name, m_scriptGroups, stop_on_all));
- BreakpointSP bp = GetProcess()->GetTarget().CreateBreakpoint(
+ Target &target = GetProcess()->GetTarget();
+ BreakpointSP bp = target.CreateBreakpoint(
m_filtersp, resolver_sp, false, false, false);
// Give RS breakpoints a specific name, so the user can manipulate them as a
// group.
Status err;
- if (!bp->AddName(name.AsCString(), err))
- if (log)
- log->Printf("%s - error setting break name, '%s'.", __FUNCTION__,
- err.AsCString());
+ target.AddNameToBreakpoint(bp, name.GetCString(), err);
+ if (err.Fail() && log)
+ log->Printf("%s - error setting break name, '%s'.", __FUNCTION__,
+ err.AsCString());
// ask the breakpoint to resolve itself
bp->ResolveBreakpoint();
return bp;
diff --git a/lldb/source/Target/Target.cpp b/lldb/source/Target/Target.cpp
index d97f651ca08..08546d57c2a 100644
--- a/lldb/source/Target/Target.cpp
+++ b/lldb/source/Target/Target.cpp
@@ -123,6 +123,13 @@ void Target::PrimeFromDummyTarget(Target *target) {
BreakpointSP new_bp(new Breakpoint(*this, *breakpoint_sp.get()));
AddBreakpoint(new_bp, false);
}
+
+ for (auto bp_name_entry : target->m_breakpoint_names)
+ {
+
+ BreakpointName *new_bp_name = new BreakpointName(*bp_name_entry.second);
+ AddBreakpointName(new_bp_name);
+ }
}
void Target::Dump(Stream *s, lldb::DescriptionLevel description_level) {
@@ -601,6 +608,112 @@ void Target::AddBreakpoint(lldb::BreakpointSP bp_sp, bool internal) {
}
}
+void Target::AddNameToBreakpoint(BreakpointID &id,
+ const char *name,
+ Status &error)
+ {
+ BreakpointSP bp_sp
+ = m_breakpoint_list.FindBreakpointByID(id.GetBreakpointID());
+ if (!bp_sp)
+ {
+ StreamString s;
+ id.GetDescription(&s, eDescriptionLevelBrief);
+ error.SetErrorStringWithFormat("Could not find breakpoint %s",
+ s.GetData());
+ return;
+ }
+ AddNameToBreakpoint(bp_sp, name, error);
+ }
+
+void Target::AddNameToBreakpoint(BreakpointSP &bp_sp,
+ const char *name,
+ Status &error)
+ {
+ if (!bp_sp)
+ return;
+
+ BreakpointName *bp_name = FindBreakpointName(ConstString(name), true, error);
+ if (!bp_name)
+ return;
+
+ bp_name->ConfigureBreakpoint(bp_sp);
+ bp_sp->AddName(name);
+ }
+
+void Target::AddBreakpointName(BreakpointName *bp_name) {
+ m_breakpoint_names.insert(std::make_pair(bp_name->GetName(), bp_name));
+}
+
+BreakpointName *Target::FindBreakpointName(const ConstString &name,
+ bool can_create,
+ Status &error)
+{
+ BreakpointID::StringIsBreakpointName(name.GetStringRef(), error);
+ if (!error.Success())
+ return nullptr;
+
+ BreakpointNameList::iterator iter = m_breakpoint_names.find(name);
+ if (iter == m_breakpoint_names.end()) {
+ if (!can_create)
+ {
+ error.SetErrorStringWithFormat("Breakpoint name \"%s\" doesn't exist and "
+ "can_create is false.", name.AsCString());
+ return nullptr;
+ }
+
+ iter = m_breakpoint_names.insert(std::make_pair(name,
+ new BreakpointName(name)))
+ .first;
+ }
+ return (iter->second);
+}
+
+void
+Target::DeleteBreakpointName(const ConstString &name)
+{
+ BreakpointNameList::iterator iter = m_breakpoint_names.find(name);
+
+ if (iter != m_breakpoint_names.end()) {
+ const char *name_cstr = name.AsCString();
+ m_breakpoint_names.erase(iter);
+ for (auto bp_sp : m_breakpoint_list.Breakpoints())
+ bp_sp->RemoveName(name_cstr);
+ }
+}
+
+void Target::RemoveNameFromBreakpoint(lldb::BreakpointSP &bp_sp,
+ const ConstString &name)
+{
+ bp_sp->RemoveName(name.AsCString());
+}
+
+void Target::ConfigureBreakpointName(BreakpointName &bp_name,
+ const BreakpointOptions &new_options,
+ const BreakpointName::Permissions &new_permissions)
+{
+ bp_name.GetOptions().CopyOverSetOptions(new_options);
+ bp_name.GetPermissions().MergeInto(new_permissions);
+ ApplyNameToBreakpoints(bp_name);
+}
+
+void Target::ApplyNameToBreakpoints(BreakpointName &bp_name) {
+ BreakpointList bkpts_with_name(false);
+ m_breakpoint_list.FindBreakpointsByName(bp_name.GetName().AsCString(),
+ bkpts_with_name);
+
+ for (auto bp_sp : bkpts_with_name.Breakpoints())
+ bp_name.ConfigureBreakpoint(bp_sp);
+}
+
+void Target::GetBreakpointNames(std::vector<std::string> &names)
+{
+ names.clear();
+ for (auto bp_name : m_breakpoint_names) {
+ names.push_back(bp_name.first.AsCString());
+ }
+ std::sort(names.begin(), names.end());
+}
+
bool Target::ProcessIsValid() {
return (m_process_sp && m_process_sp->IsAlive());
}
@@ -703,6 +816,17 @@ WatchpointSP Target::CreateWatchpoint(lldb::addr_t addr, size_t size,
return wp_sp;
}
+void Target::RemoveAllowedBreakpoints ()
+{
+ Log *log(lldb_private::GetLogIfAllCategoriesSet(LIBLLDB_LOG_BREAKPOINTS));
+ if (log)
+ log->Printf("Target::%s \n", __FUNCTION__);
+
+ m_breakpoint_list.RemoveAllowed(true);
+
+ m_last_created_breakpoint.reset();
+}
+
void Target::RemoveAllBreakpoints(bool internal_also) {
Log *log(lldb_private::GetLogIfAllCategoriesSet(LIBLLDB_LOG_BREAKPOINTS));
if (log)
@@ -727,6 +851,14 @@ void Target::DisableAllBreakpoints(bool internal_also) {
m_internal_breakpoint_list.SetEnabledAll(false);
}
+void Target::DisableAllowedBreakpoints() {
+ Log *log(lldb_private::GetLogIfAllCategoriesSet(LIBLLDB_LOG_BREAKPOINTS));
+ if (log)
+ log->Printf("Target::%s", __FUNCTION__);
+
+ m_breakpoint_list.SetEnabledAllowed(false);
+}
+
void Target::EnableAllBreakpoints(bool internal_also) {
Log *log(lldb_private::GetLogIfAllCategoriesSet(LIBLLDB_LOG_BREAKPOINTS));
if (log)
@@ -738,6 +870,14 @@ void Target::EnableAllBreakpoints(bool internal_also) {
m_internal_breakpoint_list.SetEnabledAll(true);
}
+void Target::EnableAllowedBreakpoints() {
+ Log *log(lldb_private::GetLogIfAllCategoriesSet(LIBLLDB_LOG_BREAKPOINTS));
+ if (log)
+ log->Printf("Target::%s", __FUNCTION__);
+
+ m_breakpoint_list.SetEnabledAllowed(true);
+}
+
bool Target::RemoveBreakpointByID(break_id_t break_id) {
Log *log(lldb_private::GetLogIfAllCategoriesSet(LIBLLDB_LOG_BREAKPOINTS));
if (log)
OpenPOWER on IntegriCloud