1 //===-- SBBreakpoint.cpp ----------------------------------------*- C++ -*-===//
3 // The LLVM Compiler Infrastructure
5 // This file is distributed under the University of Illinois Open Source
6 // License. See LICENSE.TXT for details.
8 //===----------------------------------------------------------------------===//
12 // Other libraries and framework includes
14 #include "lldb/API/SBBreakpoint.h"
15 #include "lldb/API/SBBreakpointLocation.h"
16 #include "lldb/API/SBDebugger.h"
17 #include "lldb/API/SBEvent.h"
18 #include "lldb/API/SBProcess.h"
19 #include "lldb/API/SBStream.h"
20 #include "lldb/API/SBStringList.h"
21 #include "lldb/API/SBThread.h"
23 #include "lldb/Breakpoint/Breakpoint.h"
24 #include "lldb/Breakpoint/BreakpointIDList.h"
25 #include "lldb/Breakpoint/BreakpointLocation.h"
26 #include "lldb/Breakpoint/StoppointCallbackContext.h"
27 #include "lldb/Core/Address.h"
28 #include "lldb/Core/Debugger.h"
29 #include "lldb/Core/StreamFile.h"
30 #include "lldb/Interpreter/CommandInterpreter.h"
31 #include "lldb/Interpreter/ScriptInterpreter.h"
32 #include "lldb/Target/Process.h"
33 #include "lldb/Target/SectionLoadList.h"
34 #include "lldb/Target/Target.h"
35 #include "lldb/Target/Thread.h"
36 #include "lldb/Target/ThreadSpec.h"
37 #include "lldb/Utility/Log.h"
38 #include "lldb/Utility/Stream.h"
40 #include "lldb/lldb-enumerations.h"
42 #include "llvm/ADT/STLExtras.h"
45 using namespace lldb_private;
48 SBBreakpoint::BreakpointHitCallback callback;
52 class SBBreakpointCallbackBaton : public TypedBaton<CallbackData> {
54 SBBreakpointCallbackBaton(SBBreakpoint::BreakpointHitCallback callback,
56 : TypedBaton(llvm::make_unique<CallbackData>()) {
57 getItem()->callback = callback;
58 getItem()->callback_baton = baton;
62 SBBreakpoint::SBBreakpoint() {}
64 SBBreakpoint::SBBreakpoint(const SBBreakpoint &rhs)
65 : m_opaque_wp(rhs.m_opaque_wp) {}
67 SBBreakpoint::SBBreakpoint(const lldb::BreakpointSP &bp_sp)
68 : m_opaque_wp(bp_sp) {}
70 SBBreakpoint::~SBBreakpoint() = default;
72 const SBBreakpoint &SBBreakpoint::operator=(const SBBreakpoint &rhs) {
73 m_opaque_wp = rhs.m_opaque_wp;
77 bool SBBreakpoint::operator==(const lldb::SBBreakpoint &rhs) {
78 return m_opaque_wp.lock() == rhs.m_opaque_wp.lock();
81 bool SBBreakpoint::operator!=(const lldb::SBBreakpoint &rhs) {
82 return m_opaque_wp.lock() != rhs.m_opaque_wp.lock();
85 break_id_t SBBreakpoint::GetID() const {
86 Log *log(lldb_private::GetLogIfAllCategoriesSet(LIBLLDB_LOG_API));
88 break_id_t break_id = LLDB_INVALID_BREAK_ID;
89 BreakpointSP bkpt_sp = GetSP();
91 break_id = bkpt_sp->GetID();
93 LLDB_LOG(log, "breakpoint = {0}, id = {1}", bkpt_sp.get(), break_id);
97 bool SBBreakpoint::IsValid() const {
98 BreakpointSP bkpt_sp = GetSP();
101 else if (bkpt_sp->GetTarget().GetBreakpointByID(bkpt_sp->GetID()))
107 void SBBreakpoint::ClearAllBreakpointSites() {
108 BreakpointSP bkpt_sp = GetSP();
110 std::lock_guard<std::recursive_mutex> guard(
111 bkpt_sp->GetTarget().GetAPIMutex());
112 bkpt_sp->ClearAllBreakpointSites();
116 SBBreakpointLocation SBBreakpoint::FindLocationByAddress(addr_t vm_addr) {
117 SBBreakpointLocation sb_bp_location;
119 BreakpointSP bkpt_sp = GetSP();
121 if (vm_addr != LLDB_INVALID_ADDRESS) {
122 std::lock_guard<std::recursive_mutex> guard(
123 bkpt_sp->GetTarget().GetAPIMutex());
125 Target &target = bkpt_sp->GetTarget();
126 if (!target.GetSectionLoadList().ResolveLoadAddress(vm_addr, address)) {
127 address.SetRawAddress(vm_addr);
129 sb_bp_location.SetLocation(bkpt_sp->FindLocationByAddress(address));
132 return sb_bp_location;
135 break_id_t SBBreakpoint::FindLocationIDByAddress(addr_t vm_addr) {
136 break_id_t break_id = LLDB_INVALID_BREAK_ID;
137 BreakpointSP bkpt_sp = GetSP();
139 if (bkpt_sp && vm_addr != LLDB_INVALID_ADDRESS) {
140 std::lock_guard<std::recursive_mutex> guard(
141 bkpt_sp->GetTarget().GetAPIMutex());
143 Target &target = bkpt_sp->GetTarget();
144 if (!target.GetSectionLoadList().ResolveLoadAddress(vm_addr, address)) {
145 address.SetRawAddress(vm_addr);
147 break_id = bkpt_sp->FindLocationIDByAddress(address);
153 SBBreakpointLocation SBBreakpoint::FindLocationByID(break_id_t bp_loc_id) {
154 SBBreakpointLocation sb_bp_location;
155 BreakpointSP bkpt_sp = GetSP();
158 std::lock_guard<std::recursive_mutex> guard(
159 bkpt_sp->GetTarget().GetAPIMutex());
160 sb_bp_location.SetLocation(bkpt_sp->FindLocationByID(bp_loc_id));
163 return sb_bp_location;
166 SBBreakpointLocation SBBreakpoint::GetLocationAtIndex(uint32_t index) {
167 SBBreakpointLocation sb_bp_location;
168 BreakpointSP bkpt_sp = GetSP();
171 std::lock_guard<std::recursive_mutex> guard(
172 bkpt_sp->GetTarget().GetAPIMutex());
173 sb_bp_location.SetLocation(bkpt_sp->GetLocationAtIndex(index));
176 return sb_bp_location;
179 void SBBreakpoint::SetEnabled(bool enable) {
180 Log *log(lldb_private::GetLogIfAllCategoriesSet(LIBLLDB_LOG_API));
181 BreakpointSP bkpt_sp = GetSP();
183 LLDB_LOG(log, "breakpoint = {0}, enable = {1}", bkpt_sp.get(), enable);
186 std::lock_guard<std::recursive_mutex> guard(
187 bkpt_sp->GetTarget().GetAPIMutex());
188 bkpt_sp->SetEnabled(enable);
192 bool SBBreakpoint::IsEnabled() {
193 BreakpointSP bkpt_sp = GetSP();
195 std::lock_guard<std::recursive_mutex> guard(
196 bkpt_sp->GetTarget().GetAPIMutex());
197 return bkpt_sp->IsEnabled();
202 void SBBreakpoint::SetOneShot(bool one_shot) {
203 Log *log(lldb_private::GetLogIfAllCategoriesSet(LIBLLDB_LOG_API));
204 BreakpointSP bkpt_sp = GetSP();
206 LLDB_LOG(log, "breakpoint = {0}, one_shot = {1}", bkpt_sp.get(), one_shot);
209 std::lock_guard<std::recursive_mutex> guard(
210 bkpt_sp->GetTarget().GetAPIMutex());
211 bkpt_sp->SetOneShot(one_shot);
215 bool SBBreakpoint::IsOneShot() const {
216 BreakpointSP bkpt_sp = GetSP();
218 std::lock_guard<std::recursive_mutex> guard(
219 bkpt_sp->GetTarget().GetAPIMutex());
220 return bkpt_sp->IsOneShot();
225 bool SBBreakpoint::IsInternal() {
226 BreakpointSP bkpt_sp = GetSP();
228 std::lock_guard<std::recursive_mutex> guard(
229 bkpt_sp->GetTarget().GetAPIMutex());
230 return bkpt_sp->IsInternal();
235 void SBBreakpoint::SetIgnoreCount(uint32_t count) {
236 Log *log(lldb_private::GetLogIfAllCategoriesSet(LIBLLDB_LOG_API));
237 BreakpointSP bkpt_sp = GetSP();
239 LLDB_LOG(log, "breakpoint = {0}, count = {1}", bkpt_sp.get(), count);
242 std::lock_guard<std::recursive_mutex> guard(
243 bkpt_sp->GetTarget().GetAPIMutex());
244 bkpt_sp->SetIgnoreCount(count);
248 void SBBreakpoint::SetCondition(const char *condition) {
249 BreakpointSP bkpt_sp = GetSP();
251 std::lock_guard<std::recursive_mutex> guard(
252 bkpt_sp->GetTarget().GetAPIMutex());
253 bkpt_sp->SetCondition(condition);
257 const char *SBBreakpoint::GetCondition() {
258 BreakpointSP bkpt_sp = GetSP();
260 std::lock_guard<std::recursive_mutex> guard(
261 bkpt_sp->GetTarget().GetAPIMutex());
262 return bkpt_sp->GetConditionText();
267 uint32_t SBBreakpoint::GetHitCount() const {
269 BreakpointSP bkpt_sp = GetSP();
271 std::lock_guard<std::recursive_mutex> guard(
272 bkpt_sp->GetTarget().GetAPIMutex());
273 count = bkpt_sp->GetHitCount();
276 Log *log(lldb_private::GetLogIfAllCategoriesSet(LIBLLDB_LOG_API));
277 LLDB_LOG(log, "breakpoint = {0}, count = {1}", bkpt_sp.get(), count);
282 uint32_t SBBreakpoint::GetIgnoreCount() const {
284 BreakpointSP bkpt_sp = GetSP();
286 std::lock_guard<std::recursive_mutex> guard(
287 bkpt_sp->GetTarget().GetAPIMutex());
288 count = bkpt_sp->GetIgnoreCount();
291 Log *log(lldb_private::GetLogIfAllCategoriesSet(LIBLLDB_LOG_API));
292 LLDB_LOG(log, "breakpoint = {0}, count = {1}", bkpt_sp.get(), count);
297 void SBBreakpoint::SetThreadID(tid_t tid) {
298 BreakpointSP bkpt_sp = GetSP();
300 std::lock_guard<std::recursive_mutex> guard(
301 bkpt_sp->GetTarget().GetAPIMutex());
302 bkpt_sp->SetThreadID(tid);
304 Log *log(lldb_private::GetLogIfAllCategoriesSet(LIBLLDB_LOG_API));
305 LLDB_LOG(log, "breakpoint = {0}, tid = {1:x}", bkpt_sp.get(), tid);
308 tid_t SBBreakpoint::GetThreadID() {
309 tid_t tid = LLDB_INVALID_THREAD_ID;
310 BreakpointSP bkpt_sp = GetSP();
312 std::lock_guard<std::recursive_mutex> guard(
313 bkpt_sp->GetTarget().GetAPIMutex());
314 tid = bkpt_sp->GetThreadID();
317 Log *log(lldb_private::GetLogIfAllCategoriesSet(LIBLLDB_LOG_API));
318 LLDB_LOG(log, "breakpoint = {0}, tid = {1:x}", bkpt_sp.get(), tid);
322 void SBBreakpoint::SetThreadIndex(uint32_t index) {
323 Log *log(lldb_private::GetLogIfAllCategoriesSet(LIBLLDB_LOG_API));
324 BreakpointSP bkpt_sp = GetSP();
325 LLDB_LOG(log, "breakpoint = {0}, index = {1}", bkpt_sp.get(), index);
327 std::lock_guard<std::recursive_mutex> guard(
328 bkpt_sp->GetTarget().GetAPIMutex());
329 bkpt_sp->GetOptions()->GetThreadSpec()->SetIndex(index);
333 uint32_t SBBreakpoint::GetThreadIndex() const {
334 uint32_t thread_idx = UINT32_MAX;
335 BreakpointSP bkpt_sp = GetSP();
337 std::lock_guard<std::recursive_mutex> guard(
338 bkpt_sp->GetTarget().GetAPIMutex());
339 const ThreadSpec *thread_spec =
340 bkpt_sp->GetOptions()->GetThreadSpecNoCreate();
341 if (thread_spec != nullptr)
342 thread_idx = thread_spec->GetIndex();
344 Log *log(lldb_private::GetLogIfAllCategoriesSet(LIBLLDB_LOG_API));
345 LLDB_LOG(log, "breakpoint = {0}, index = {1}", bkpt_sp.get(), thread_idx);
350 void SBBreakpoint::SetThreadName(const char *thread_name) {
351 Log *log(lldb_private::GetLogIfAllCategoriesSet(LIBLLDB_LOG_API));
352 BreakpointSP bkpt_sp = GetSP();
353 LLDB_LOG(log, "breakpoint = {0}, name = {1}", bkpt_sp.get(), thread_name);
356 std::lock_guard<std::recursive_mutex> guard(
357 bkpt_sp->GetTarget().GetAPIMutex());
358 bkpt_sp->GetOptions()->GetThreadSpec()->SetName(thread_name);
362 const char *SBBreakpoint::GetThreadName() const {
363 const char *name = nullptr;
364 BreakpointSP bkpt_sp = GetSP();
366 std::lock_guard<std::recursive_mutex> guard(
367 bkpt_sp->GetTarget().GetAPIMutex());
368 const ThreadSpec *thread_spec =
369 bkpt_sp->GetOptions()->GetThreadSpecNoCreate();
370 if (thread_spec != nullptr)
371 name = thread_spec->GetName();
373 Log *log(lldb_private::GetLogIfAllCategoriesSet(LIBLLDB_LOG_API));
374 LLDB_LOG(log, "breakpoint = {0}, name = {1}", bkpt_sp.get(), name);
379 void SBBreakpoint::SetQueueName(const char *queue_name) {
380 Log *log(lldb_private::GetLogIfAllCategoriesSet(LIBLLDB_LOG_API));
381 BreakpointSP bkpt_sp = GetSP();
382 LLDB_LOG(log, "breakpoint = {0}, queue_name = {1}", bkpt_sp.get(),
385 std::lock_guard<std::recursive_mutex> guard(
386 bkpt_sp->GetTarget().GetAPIMutex());
387 bkpt_sp->GetOptions()->GetThreadSpec()->SetQueueName(queue_name);
391 const char *SBBreakpoint::GetQueueName() const {
392 const char *name = nullptr;
393 BreakpointSP bkpt_sp = GetSP();
395 std::lock_guard<std::recursive_mutex> guard(
396 bkpt_sp->GetTarget().GetAPIMutex());
397 const ThreadSpec *thread_spec =
398 bkpt_sp->GetOptions()->GetThreadSpecNoCreate();
400 name = thread_spec->GetQueueName();
402 Log *log(lldb_private::GetLogIfAllCategoriesSet(LIBLLDB_LOG_API));
403 LLDB_LOG(log, "breakpoint = {0}, name = {1}", bkpt_sp.get(), name);
408 size_t SBBreakpoint::GetNumResolvedLocations() const {
409 size_t num_resolved = 0;
410 BreakpointSP bkpt_sp = GetSP();
412 std::lock_guard<std::recursive_mutex> guard(
413 bkpt_sp->GetTarget().GetAPIMutex());
414 num_resolved = bkpt_sp->GetNumResolvedLocations();
416 Log *log(lldb_private::GetLogIfAllCategoriesSet(LIBLLDB_LOG_API));
417 LLDB_LOG(log, "breakpoint = {0}, num_resolved = {1}", bkpt_sp.get(),
422 size_t SBBreakpoint::GetNumLocations() const {
423 BreakpointSP bkpt_sp = GetSP();
426 std::lock_guard<std::recursive_mutex> guard(
427 bkpt_sp->GetTarget().GetAPIMutex());
428 num_locs = bkpt_sp->GetNumLocations();
430 Log *log(lldb_private::GetLogIfAllCategoriesSet(LIBLLDB_LOG_API));
431 LLDB_LOG(log, "breakpoint = {0}, num_locs = {1}", bkpt_sp.get(), num_locs);
435 void SBBreakpoint::SetCommandLineCommands(SBStringList &commands) {
436 BreakpointSP bkpt_sp = GetSP();
439 if (commands.GetSize() == 0)
442 std::lock_guard<std::recursive_mutex> guard(
443 bkpt_sp->GetTarget().GetAPIMutex());
444 std::unique_ptr<BreakpointOptions::CommandData> cmd_data_up(
445 new BreakpointOptions::CommandData(*commands, eScriptLanguageNone));
447 bkpt_sp->GetOptions()->SetCommandDataCallback(cmd_data_up);
450 bool SBBreakpoint::GetCommandLineCommands(SBStringList &commands) {
451 BreakpointSP bkpt_sp = GetSP();
454 StringList command_list;
456 bkpt_sp->GetOptions()->GetCommandLineCallbacks(command_list);
458 commands.AppendList(command_list);
462 bool SBBreakpoint::GetDescription(SBStream &s) {
463 return GetDescription(s, true);
466 bool SBBreakpoint::GetDescription(SBStream &s, bool include_locations) {
467 BreakpointSP bkpt_sp = GetSP();
469 std::lock_guard<std::recursive_mutex> guard(
470 bkpt_sp->GetTarget().GetAPIMutex());
471 s.Printf("SBBreakpoint: id = %i, ", bkpt_sp->GetID());
472 bkpt_sp->GetResolverDescription(s.get());
473 bkpt_sp->GetFilterDescription(s.get());
474 if (include_locations) {
475 const size_t num_locations = bkpt_sp->GetNumLocations();
476 s.Printf(", locations = %" PRIu64, (uint64_t)num_locations);
480 s.Printf("No value");
484 bool SBBreakpoint::PrivateBreakpointHitCallback(void *baton,
485 StoppointCallbackContext *ctx,
486 lldb::user_id_t break_id,
487 lldb::user_id_t break_loc_id) {
488 ExecutionContext exe_ctx(ctx->exe_ctx_ref);
490 exe_ctx.GetTargetRef().GetBreakpointList().FindBreakpointByID(break_id));
491 if (baton && bp_sp) {
492 CallbackData *data = (CallbackData *)baton;
493 lldb_private::Breakpoint *bp = bp_sp.get();
494 if (bp && data->callback) {
495 Process *process = exe_ctx.GetProcessPtr();
497 SBProcess sb_process(process->shared_from_this());
499 SBBreakpointLocation sb_location;
501 sb_location.SetLocation(bp_sp->FindLocationByID(break_loc_id));
502 Thread *thread = exe_ctx.GetThreadPtr();
504 sb_thread.SetThread(thread->shared_from_this());
506 return data->callback(data->callback_baton, sb_process, sb_thread,
511 return true; // Return true if we should stop at this breakpoint
514 void SBBreakpoint::SetCallback(BreakpointHitCallback callback, void *baton) {
515 Log *log(lldb_private::GetLogIfAllCategoriesSet(LIBLLDB_LOG_API));
516 BreakpointSP bkpt_sp = GetSP();
517 LLDB_LOG(log, "breakpoint = {0}, callback = {1}, baton = {2}", bkpt_sp.get(),
521 std::lock_guard<std::recursive_mutex> guard(
522 bkpt_sp->GetTarget().GetAPIMutex());
523 BatonSP baton_sp(new SBBreakpointCallbackBaton(callback, baton));
524 bkpt_sp->SetCallback(SBBreakpoint::PrivateBreakpointHitCallback, baton_sp,
529 void SBBreakpoint::SetScriptCallbackFunction(
530 const char *callback_function_name) {
531 Log *log(lldb_private::GetLogIfAllCategoriesSet(LIBLLDB_LOG_API));
532 BreakpointSP bkpt_sp = GetSP();
533 LLDB_LOG(log, "breakpoint = {0}, callback = {1}", bkpt_sp.get(),
534 callback_function_name);
537 std::lock_guard<std::recursive_mutex> guard(
538 bkpt_sp->GetTarget().GetAPIMutex());
539 BreakpointOptions *bp_options = bkpt_sp->GetOptions();
542 .GetCommandInterpreter()
543 .GetScriptInterpreter()
544 ->SetBreakpointCommandCallbackFunction(bp_options,
545 callback_function_name);
549 SBError SBBreakpoint::SetScriptCallbackBody(const char *callback_body_text) {
550 Log *log(lldb_private::GetLogIfAllCategoriesSet(LIBLLDB_LOG_API));
551 BreakpointSP bkpt_sp = GetSP();
552 LLDB_LOG(log, "breakpoint = {0}, callback body:\n{1}", bkpt_sp.get(),
557 std::lock_guard<std::recursive_mutex> guard(
558 bkpt_sp->GetTarget().GetAPIMutex());
559 BreakpointOptions *bp_options = bkpt_sp->GetOptions();
563 .GetCommandInterpreter()
564 .GetScriptInterpreter()
565 ->SetBreakpointCommandCallback(bp_options, callback_body_text);
566 sb_error.SetError(error);
568 sb_error.SetErrorString("invalid breakpoint");
573 bool SBBreakpoint::AddName(const char *new_name) {
574 Log *log(lldb_private::GetLogIfAllCategoriesSet(LIBLLDB_LOG_API));
575 BreakpointSP bkpt_sp = GetSP();
576 LLDB_LOG(log, "breakpoint = {0}, name = {1}", bkpt_sp.get(), new_name);
579 std::lock_guard<std::recursive_mutex> guard(
580 bkpt_sp->GetTarget().GetAPIMutex());
581 Status error; // Think I'm just going to swallow the error here, it's
582 // probably more annoying to have to provide it.
583 return bkpt_sp->AddName(new_name, error);
589 void SBBreakpoint::RemoveName(const char *name_to_remove) {
590 Log *log(lldb_private::GetLogIfAllCategoriesSet(LIBLLDB_LOG_API));
591 BreakpointSP bkpt_sp = GetSP();
592 LLDB_LOG(log, "breakpoint = {0}, name = {1}", bkpt_sp.get(), name_to_remove);
595 std::lock_guard<std::recursive_mutex> guard(
596 bkpt_sp->GetTarget().GetAPIMutex());
597 bkpt_sp->RemoveName(name_to_remove);
601 bool SBBreakpoint::MatchesName(const char *name) {
602 Log *log(lldb_private::GetLogIfAllCategoriesSet(LIBLLDB_LOG_API));
603 BreakpointSP bkpt_sp = GetSP();
604 LLDB_LOG(log, "breakpoint = {0}, name = {1}", bkpt_sp.get(), name);
607 std::lock_guard<std::recursive_mutex> guard(
608 bkpt_sp->GetTarget().GetAPIMutex());
609 return bkpt_sp->MatchesName(name);
615 void SBBreakpoint::GetNames(SBStringList &names) {
616 Log *log(lldb_private::GetLogIfAllCategoriesSet(LIBLLDB_LOG_API));
617 BreakpointSP bkpt_sp = GetSP();
618 LLDB_LOG(log, "breakpoint = {0}", bkpt_sp.get());
621 std::lock_guard<std::recursive_mutex> guard(
622 bkpt_sp->GetTarget().GetAPIMutex());
623 std::vector<std::string> names_vec;
624 bkpt_sp->GetNames(names_vec);
625 for (std::string name : names_vec) {
626 names.AppendString(name.c_str());
631 bool SBBreakpoint::EventIsBreakpointEvent(const lldb::SBEvent &event) {
632 return Breakpoint::BreakpointEventData::GetEventDataFromEvent(event.get()) !=
637 SBBreakpoint::GetBreakpointEventTypeFromEvent(const SBEvent &event) {
639 return Breakpoint::BreakpointEventData::GetBreakpointEventTypeFromEvent(
641 return eBreakpointEventTypeInvalidType;
644 SBBreakpoint SBBreakpoint::GetBreakpointFromEvent(const lldb::SBEvent &event) {
647 Breakpoint::BreakpointEventData::GetBreakpointFromEvent(event.GetSP()));
648 return SBBreakpoint();
652 SBBreakpoint::GetBreakpointLocationAtIndexFromEvent(const lldb::SBEvent &event,
654 SBBreakpointLocation sb_breakpoint_loc;
656 sb_breakpoint_loc.SetLocation(
657 Breakpoint::BreakpointEventData::GetBreakpointLocationAtIndexFromEvent(
658 event.GetSP(), loc_idx));
659 return sb_breakpoint_loc;
663 SBBreakpoint::GetNumBreakpointLocationsFromEvent(const lldb::SBEvent &event) {
664 uint32_t num_locations = 0;
667 (Breakpoint::BreakpointEventData::GetNumBreakpointLocationsFromEvent(
669 return num_locations;
672 BreakpointSP SBBreakpoint::GetSP() const { return m_opaque_wp.lock(); }
674 // This is simple collection of breakpoint id's and their target.
675 class SBBreakpointListImpl {
677 SBBreakpointListImpl(lldb::TargetSP target_sp) : m_target_wp() {
678 if (target_sp && target_sp->IsValid())
679 m_target_wp = target_sp;
682 ~SBBreakpointListImpl() = default;
684 size_t GetSize() { return m_break_ids.size(); }
686 BreakpointSP GetBreakpointAtIndex(size_t idx) {
687 if (idx >= m_break_ids.size())
688 return BreakpointSP();
689 TargetSP target_sp = m_target_wp.lock();
691 return BreakpointSP();
692 lldb::break_id_t bp_id = m_break_ids[idx];
693 return target_sp->GetBreakpointList().FindBreakpointByID(bp_id);
696 BreakpointSP FindBreakpointByID(lldb::break_id_t desired_id) {
697 TargetSP target_sp = m_target_wp.lock();
699 return BreakpointSP();
701 for (lldb::break_id_t &break_id : m_break_ids) {
702 if (break_id == desired_id)
703 return target_sp->GetBreakpointList().FindBreakpointByID(break_id);
705 return BreakpointSP();
708 bool Append(BreakpointSP bkpt) {
709 TargetSP target_sp = m_target_wp.lock();
710 if (!target_sp || !bkpt)
712 if (bkpt->GetTargetSP() != target_sp)
714 m_break_ids.push_back(bkpt->GetID());
718 bool AppendIfUnique(BreakpointSP bkpt) {
719 TargetSP target_sp = m_target_wp.lock();
720 if (!target_sp || !bkpt)
722 if (bkpt->GetTargetSP() != target_sp)
724 lldb::break_id_t bp_id = bkpt->GetID();
725 if (find(m_break_ids.begin(), m_break_ids.end(), bp_id) ==
729 m_break_ids.push_back(bkpt->GetID());
733 bool AppendByID(lldb::break_id_t id) {
734 TargetSP target_sp = m_target_wp.lock();
737 if (id == LLDB_INVALID_BREAK_ID)
739 m_break_ids.push_back(id);
743 void Clear() { m_break_ids.clear(); }
745 void CopyToBreakpointIDList(lldb_private::BreakpointIDList &bp_list) {
746 for (lldb::break_id_t id : m_break_ids) {
747 bp_list.AddBreakpointID(BreakpointID(id));
751 TargetSP GetTarget() { return m_target_wp.lock(); }
754 std::vector<lldb::break_id_t> m_break_ids;
755 TargetWP m_target_wp;
758 SBBreakpointList::SBBreakpointList(SBTarget &target)
759 : m_opaque_sp(new SBBreakpointListImpl(target.GetSP())) {}
761 SBBreakpointList::~SBBreakpointList() {}
763 size_t SBBreakpointList::GetSize() const {
767 return m_opaque_sp->GetSize();
770 SBBreakpoint SBBreakpointList::GetBreakpointAtIndex(size_t idx) {
772 return SBBreakpoint();
774 BreakpointSP bkpt_sp = m_opaque_sp->GetBreakpointAtIndex(idx);
775 return SBBreakpoint(bkpt_sp);
778 SBBreakpoint SBBreakpointList::FindBreakpointByID(lldb::break_id_t id) {
780 return SBBreakpoint();
781 BreakpointSP bkpt_sp = m_opaque_sp->FindBreakpointByID(id);
782 return SBBreakpoint(bkpt_sp);
785 void SBBreakpointList::Append(const SBBreakpoint &sb_bkpt) {
786 if (!sb_bkpt.IsValid())
790 m_opaque_sp->Append(sb_bkpt.m_opaque_wp.lock());
793 void SBBreakpointList::AppendByID(lldb::break_id_t id) {
796 m_opaque_sp->AppendByID(id);
799 bool SBBreakpointList::AppendIfUnique(const SBBreakpoint &sb_bkpt) {
800 if (!sb_bkpt.IsValid())
804 return m_opaque_sp->AppendIfUnique(sb_bkpt.GetSP());
807 void SBBreakpointList::Clear() {
809 m_opaque_sp->Clear();
812 void SBBreakpointList::CopyToBreakpointIDList(
813 lldb_private::BreakpointIDList &bp_id_list) {
815 m_opaque_sp->CopyToBreakpointIDList(bp_id_list);