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/Log.h"
30 #include "lldb/Core/Stream.h"
31 #include "lldb/Core/StreamFile.h"
32 #include "lldb/Interpreter/CommandInterpreter.h"
33 #include "lldb/Interpreter/ScriptInterpreter.h"
34 #include "lldb/Target/Process.h"
35 #include "lldb/Target/SectionLoadList.h"
36 #include "lldb/Target/Target.h"
37 #include "lldb/Target/Thread.h"
38 #include "lldb/Target/ThreadSpec.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() : m_opaque_sp() {}
64 SBBreakpoint::SBBreakpoint(const SBBreakpoint &rhs)
65 : m_opaque_sp(rhs.m_opaque_sp) {}
67 SBBreakpoint::SBBreakpoint(const lldb::BreakpointSP &bp_sp)
68 : m_opaque_sp(bp_sp) {}
70 SBBreakpoint::~SBBreakpoint() = default;
72 const SBBreakpoint &SBBreakpoint::operator=(const SBBreakpoint &rhs) {
74 m_opaque_sp = rhs.m_opaque_sp;
78 bool SBBreakpoint::operator==(const lldb::SBBreakpoint &rhs) {
79 if (m_opaque_sp && rhs.m_opaque_sp)
80 return m_opaque_sp.get() == rhs.m_opaque_sp.get();
84 bool SBBreakpoint::operator!=(const lldb::SBBreakpoint &rhs) {
85 if (m_opaque_sp && rhs.m_opaque_sp)
86 return m_opaque_sp.get() != rhs.m_opaque_sp.get();
87 return (m_opaque_sp && !rhs.m_opaque_sp) || (rhs.m_opaque_sp && !m_opaque_sp);
90 break_id_t SBBreakpoint::GetID() const {
91 Log *log(lldb_private::GetLogIfAllCategoriesSet(LIBLLDB_LOG_API));
93 break_id_t break_id = LLDB_INVALID_BREAK_ID;
95 break_id = m_opaque_sp->GetID();
98 if (break_id == LLDB_INVALID_BREAK_ID)
99 log->Printf("SBBreakpoint(%p)::GetID () => LLDB_INVALID_BREAK_ID",
100 static_cast<void *>(m_opaque_sp.get()));
102 log->Printf("SBBreakpoint(%p)::GetID () => %u",
103 static_cast<void *>(m_opaque_sp.get()), break_id);
109 bool SBBreakpoint::IsValid() const {
112 else if (m_opaque_sp->GetTarget().GetBreakpointByID(m_opaque_sp->GetID()))
118 void SBBreakpoint::ClearAllBreakpointSites() {
120 std::lock_guard<std::recursive_mutex> guard(
121 m_opaque_sp->GetTarget().GetAPIMutex());
122 m_opaque_sp->ClearAllBreakpointSites();
126 SBBreakpointLocation SBBreakpoint::FindLocationByAddress(addr_t vm_addr) {
127 SBBreakpointLocation sb_bp_location;
130 if (vm_addr != LLDB_INVALID_ADDRESS) {
131 std::lock_guard<std::recursive_mutex> guard(
132 m_opaque_sp->GetTarget().GetAPIMutex());
134 Target &target = m_opaque_sp->GetTarget();
135 if (!target.GetSectionLoadList().ResolveLoadAddress(vm_addr, address)) {
136 address.SetRawAddress(vm_addr);
138 sb_bp_location.SetLocation(m_opaque_sp->FindLocationByAddress(address));
141 return sb_bp_location;
144 break_id_t SBBreakpoint::FindLocationIDByAddress(addr_t vm_addr) {
145 break_id_t break_id = LLDB_INVALID_BREAK_ID;
147 if (m_opaque_sp && vm_addr != LLDB_INVALID_ADDRESS) {
148 std::lock_guard<std::recursive_mutex> guard(
149 m_opaque_sp->GetTarget().GetAPIMutex());
151 Target &target = m_opaque_sp->GetTarget();
152 if (!target.GetSectionLoadList().ResolveLoadAddress(vm_addr, address)) {
153 address.SetRawAddress(vm_addr);
155 break_id = m_opaque_sp->FindLocationIDByAddress(address);
161 SBBreakpointLocation SBBreakpoint::FindLocationByID(break_id_t bp_loc_id) {
162 SBBreakpointLocation sb_bp_location;
165 std::lock_guard<std::recursive_mutex> guard(
166 m_opaque_sp->GetTarget().GetAPIMutex());
167 sb_bp_location.SetLocation(m_opaque_sp->FindLocationByID(bp_loc_id));
170 return sb_bp_location;
173 SBBreakpointLocation SBBreakpoint::GetLocationAtIndex(uint32_t index) {
174 SBBreakpointLocation sb_bp_location;
177 std::lock_guard<std::recursive_mutex> guard(
178 m_opaque_sp->GetTarget().GetAPIMutex());
179 sb_bp_location.SetLocation(m_opaque_sp->GetLocationAtIndex(index));
182 return sb_bp_location;
185 void SBBreakpoint::SetEnabled(bool enable) {
186 Log *log(lldb_private::GetLogIfAllCategoriesSet(LIBLLDB_LOG_API));
189 log->Printf("SBBreakpoint(%p)::SetEnabled (enabled=%i)",
190 static_cast<void *>(m_opaque_sp.get()), enable);
193 std::lock_guard<std::recursive_mutex> guard(
194 m_opaque_sp->GetTarget().GetAPIMutex());
195 m_opaque_sp->SetEnabled(enable);
199 bool SBBreakpoint::IsEnabled() {
201 std::lock_guard<std::recursive_mutex> guard(
202 m_opaque_sp->GetTarget().GetAPIMutex());
203 return m_opaque_sp->IsEnabled();
208 void SBBreakpoint::SetOneShot(bool one_shot) {
209 Log *log(lldb_private::GetLogIfAllCategoriesSet(LIBLLDB_LOG_API));
212 log->Printf("SBBreakpoint(%p)::SetOneShot (one_shot=%i)",
213 static_cast<void *>(m_opaque_sp.get()), one_shot);
216 std::lock_guard<std::recursive_mutex> guard(
217 m_opaque_sp->GetTarget().GetAPIMutex());
218 m_opaque_sp->SetOneShot(one_shot);
222 bool SBBreakpoint::IsOneShot() const {
224 std::lock_guard<std::recursive_mutex> guard(
225 m_opaque_sp->GetTarget().GetAPIMutex());
226 return m_opaque_sp->IsOneShot();
231 bool SBBreakpoint::IsInternal() {
233 std::lock_guard<std::recursive_mutex> guard(
234 m_opaque_sp->GetTarget().GetAPIMutex());
235 return m_opaque_sp->IsInternal();
240 void SBBreakpoint::SetIgnoreCount(uint32_t count) {
241 Log *log(lldb_private::GetLogIfAllCategoriesSet(LIBLLDB_LOG_API));
244 log->Printf("SBBreakpoint(%p)::SetIgnoreCount (count=%u)",
245 static_cast<void *>(m_opaque_sp.get()), count);
248 std::lock_guard<std::recursive_mutex> guard(
249 m_opaque_sp->GetTarget().GetAPIMutex());
250 m_opaque_sp->SetIgnoreCount(count);
254 void SBBreakpoint::SetCondition(const char *condition) {
256 std::lock_guard<std::recursive_mutex> guard(
257 m_opaque_sp->GetTarget().GetAPIMutex());
258 m_opaque_sp->SetCondition(condition);
262 const char *SBBreakpoint::GetCondition() {
264 std::lock_guard<std::recursive_mutex> guard(
265 m_opaque_sp->GetTarget().GetAPIMutex());
266 return m_opaque_sp->GetConditionText();
271 uint32_t SBBreakpoint::GetHitCount() const {
274 std::lock_guard<std::recursive_mutex> guard(
275 m_opaque_sp->GetTarget().GetAPIMutex());
276 count = m_opaque_sp->GetHitCount();
279 Log *log(lldb_private::GetLogIfAllCategoriesSet(LIBLLDB_LOG_API));
281 log->Printf("SBBreakpoint(%p)::GetHitCount () => %u",
282 static_cast<void *>(m_opaque_sp.get()), count);
287 uint32_t SBBreakpoint::GetIgnoreCount() const {
290 std::lock_guard<std::recursive_mutex> guard(
291 m_opaque_sp->GetTarget().GetAPIMutex());
292 count = m_opaque_sp->GetIgnoreCount();
295 Log *log(lldb_private::GetLogIfAllCategoriesSet(LIBLLDB_LOG_API));
297 log->Printf("SBBreakpoint(%p)::GetIgnoreCount () => %u",
298 static_cast<void *>(m_opaque_sp.get()), count);
303 void SBBreakpoint::SetThreadID(tid_t tid) {
305 std::lock_guard<std::recursive_mutex> guard(
306 m_opaque_sp->GetTarget().GetAPIMutex());
307 m_opaque_sp->SetThreadID(tid);
309 Log *log(lldb_private::GetLogIfAllCategoriesSet(LIBLLDB_LOG_API));
311 log->Printf("SBBreakpoint(%p)::SetThreadID (tid=0x%4.4" PRIx64 ")",
312 static_cast<void *>(m_opaque_sp.get()), tid);
315 tid_t SBBreakpoint::GetThreadID() {
316 tid_t tid = LLDB_INVALID_THREAD_ID;
318 std::lock_guard<std::recursive_mutex> guard(
319 m_opaque_sp->GetTarget().GetAPIMutex());
320 tid = m_opaque_sp->GetThreadID();
323 Log *log(lldb_private::GetLogIfAllCategoriesSet(LIBLLDB_LOG_API));
325 log->Printf("SBBreakpoint(%p)::GetThreadID () => 0x%4.4" PRIx64,
326 static_cast<void *>(m_opaque_sp.get()), tid);
330 void SBBreakpoint::SetThreadIndex(uint32_t index) {
331 Log *log(lldb_private::GetLogIfAllCategoriesSet(LIBLLDB_LOG_API));
333 log->Printf("SBBreakpoint(%p)::SetThreadIndex (%u)",
334 static_cast<void *>(m_opaque_sp.get()), index);
336 std::lock_guard<std::recursive_mutex> guard(
337 m_opaque_sp->GetTarget().GetAPIMutex());
338 m_opaque_sp->GetOptions()->GetThreadSpec()->SetIndex(index);
342 uint32_t SBBreakpoint::GetThreadIndex() const {
343 uint32_t thread_idx = UINT32_MAX;
345 std::lock_guard<std::recursive_mutex> guard(
346 m_opaque_sp->GetTarget().GetAPIMutex());
347 const ThreadSpec *thread_spec =
348 m_opaque_sp->GetOptions()->GetThreadSpecNoCreate();
349 if (thread_spec != nullptr)
350 thread_idx = thread_spec->GetIndex();
352 Log *log(lldb_private::GetLogIfAllCategoriesSet(LIBLLDB_LOG_API));
354 log->Printf("SBBreakpoint(%p)::GetThreadIndex () => %u",
355 static_cast<void *>(m_opaque_sp.get()), thread_idx);
360 void SBBreakpoint::SetThreadName(const char *thread_name) {
361 Log *log(lldb_private::GetLogIfAllCategoriesSet(LIBLLDB_LOG_API));
363 log->Printf("SBBreakpoint(%p)::SetThreadName (%s)",
364 static_cast<void *>(m_opaque_sp.get()), thread_name);
367 std::lock_guard<std::recursive_mutex> guard(
368 m_opaque_sp->GetTarget().GetAPIMutex());
369 m_opaque_sp->GetOptions()->GetThreadSpec()->SetName(thread_name);
373 const char *SBBreakpoint::GetThreadName() const {
374 const char *name = nullptr;
376 std::lock_guard<std::recursive_mutex> guard(
377 m_opaque_sp->GetTarget().GetAPIMutex());
378 const ThreadSpec *thread_spec =
379 m_opaque_sp->GetOptions()->GetThreadSpecNoCreate();
380 if (thread_spec != nullptr)
381 name = thread_spec->GetName();
383 Log *log(lldb_private::GetLogIfAllCategoriesSet(LIBLLDB_LOG_API));
385 log->Printf("SBBreakpoint(%p)::GetThreadName () => %s",
386 static_cast<void *>(m_opaque_sp.get()), name);
391 void SBBreakpoint::SetQueueName(const char *queue_name) {
392 Log *log(lldb_private::GetLogIfAllCategoriesSet(LIBLLDB_LOG_API));
394 log->Printf("SBBreakpoint(%p)::SetQueueName (%s)",
395 static_cast<void *>(m_opaque_sp.get()), queue_name);
397 std::lock_guard<std::recursive_mutex> guard(
398 m_opaque_sp->GetTarget().GetAPIMutex());
399 m_opaque_sp->GetOptions()->GetThreadSpec()->SetQueueName(queue_name);
403 const char *SBBreakpoint::GetQueueName() const {
404 const char *name = nullptr;
406 std::lock_guard<std::recursive_mutex> guard(
407 m_opaque_sp->GetTarget().GetAPIMutex());
408 const ThreadSpec *thread_spec =
409 m_opaque_sp->GetOptions()->GetThreadSpecNoCreate();
411 name = thread_spec->GetQueueName();
413 Log *log(lldb_private::GetLogIfAllCategoriesSet(LIBLLDB_LOG_API));
415 log->Printf("SBBreakpoint(%p)::GetQueueName () => %s",
416 static_cast<void *>(m_opaque_sp.get()), name);
421 size_t SBBreakpoint::GetNumResolvedLocations() const {
422 size_t num_resolved = 0;
424 std::lock_guard<std::recursive_mutex> guard(
425 m_opaque_sp->GetTarget().GetAPIMutex());
426 num_resolved = m_opaque_sp->GetNumResolvedLocations();
428 Log *log(lldb_private::GetLogIfAllCategoriesSet(LIBLLDB_LOG_API));
430 log->Printf("SBBreakpoint(%p)::GetNumResolvedLocations () => %" PRIu64,
431 static_cast<void *>(m_opaque_sp.get()),
432 static_cast<uint64_t>(num_resolved));
436 size_t SBBreakpoint::GetNumLocations() const {
439 std::lock_guard<std::recursive_mutex> guard(
440 m_opaque_sp->GetTarget().GetAPIMutex());
441 num_locs = m_opaque_sp->GetNumLocations();
443 Log *log(lldb_private::GetLogIfAllCategoriesSet(LIBLLDB_LOG_API));
445 log->Printf("SBBreakpoint(%p)::GetNumLocations () => %" PRIu64,
446 static_cast<void *>(m_opaque_sp.get()),
447 static_cast<uint64_t>(num_locs));
451 void SBBreakpoint::SetCommandLineCommands(SBStringList &commands) {
454 if (commands.GetSize() == 0)
457 std::lock_guard<std::recursive_mutex> guard(
458 m_opaque_sp->GetTarget().GetAPIMutex());
459 std::unique_ptr<BreakpointOptions::CommandData> cmd_data_up(
460 new BreakpointOptions::CommandData(*commands, eScriptLanguageNone));
462 m_opaque_sp->GetOptions()->SetCommandDataCallback(cmd_data_up);
465 bool SBBreakpoint::GetCommandLineCommands(SBStringList &commands) {
468 StringList command_list;
470 m_opaque_sp->GetOptions()->GetCommandLineCallbacks(command_list);
472 commands.AppendList(command_list);
476 bool SBBreakpoint::GetDescription(SBStream &s) {
477 return GetDescription(s, true);
480 bool SBBreakpoint::GetDescription(SBStream &s, bool include_locations) {
482 std::lock_guard<std::recursive_mutex> guard(
483 m_opaque_sp->GetTarget().GetAPIMutex());
484 s.Printf("SBBreakpoint: id = %i, ", m_opaque_sp->GetID());
485 m_opaque_sp->GetResolverDescription(s.get());
486 m_opaque_sp->GetFilterDescription(s.get());
487 if (include_locations) {
488 const size_t num_locations = m_opaque_sp->GetNumLocations();
489 s.Printf(", locations = %" PRIu64, (uint64_t)num_locations);
493 s.Printf("No value");
497 bool SBBreakpoint::PrivateBreakpointHitCallback(void *baton,
498 StoppointCallbackContext *ctx,
499 lldb::user_id_t break_id,
500 lldb::user_id_t break_loc_id) {
501 ExecutionContext exe_ctx(ctx->exe_ctx_ref);
503 exe_ctx.GetTargetRef().GetBreakpointList().FindBreakpointByID(break_id));
504 if (baton && bp_sp) {
505 CallbackData *data = (CallbackData *)baton;
506 lldb_private::Breakpoint *bp = bp_sp.get();
507 if (bp && data->callback) {
508 Process *process = exe_ctx.GetProcessPtr();
510 SBProcess sb_process(process->shared_from_this());
512 SBBreakpointLocation sb_location;
514 sb_location.SetLocation(bp_sp->FindLocationByID(break_loc_id));
515 Thread *thread = exe_ctx.GetThreadPtr();
517 sb_thread.SetThread(thread->shared_from_this());
519 return data->callback(data->callback_baton, sb_process, sb_thread,
524 return true; // Return true if we should stop at this breakpoint
527 void SBBreakpoint::SetCallback(BreakpointHitCallback callback, void *baton) {
528 Log *log(lldb_private::GetLogIfAllCategoriesSet(LIBLLDB_LOG_API));
531 void *pointer = &callback;
532 log->Printf("SBBreakpoint(%p)::SetCallback (callback=%p, baton=%p)",
533 static_cast<void *>(m_opaque_sp.get()),
534 *static_cast<void **>(&pointer), static_cast<void *>(baton));
538 std::lock_guard<std::recursive_mutex> guard(
539 m_opaque_sp->GetTarget().GetAPIMutex());
540 BatonSP baton_sp(new SBBreakpointCallbackBaton(callback, baton));
541 m_opaque_sp->SetCallback(SBBreakpoint::PrivateBreakpointHitCallback,
546 void SBBreakpoint::SetScriptCallbackFunction(
547 const char *callback_function_name) {
548 Log *log(lldb_private::GetLogIfAllCategoriesSet(LIBLLDB_LOG_API));
551 log->Printf("SBBreakpoint(%p)::SetScriptCallbackFunction (callback=%s)",
552 static_cast<void *>(m_opaque_sp.get()), callback_function_name);
555 std::lock_guard<std::recursive_mutex> guard(
556 m_opaque_sp->GetTarget().GetAPIMutex());
557 BreakpointOptions *bp_options = m_opaque_sp->GetOptions();
558 m_opaque_sp->GetTarget()
560 .GetCommandInterpreter()
561 .GetScriptInterpreter()
562 ->SetBreakpointCommandCallbackFunction(bp_options,
563 callback_function_name);
567 SBError SBBreakpoint::SetScriptCallbackBody(const char *callback_body_text) {
568 Log *log(lldb_private::GetLogIfAllCategoriesSet(LIBLLDB_LOG_API));
571 log->Printf("SBBreakpoint(%p)::SetScriptCallbackBody: callback body:\n%s)",
572 static_cast<void *>(m_opaque_sp.get()), callback_body_text);
576 std::lock_guard<std::recursive_mutex> guard(
577 m_opaque_sp->GetTarget().GetAPIMutex());
578 BreakpointOptions *bp_options = m_opaque_sp->GetOptions();
580 m_opaque_sp->GetTarget()
582 .GetCommandInterpreter()
583 .GetScriptInterpreter()
584 ->SetBreakpointCommandCallback(bp_options, callback_body_text);
585 sb_error.SetError(error);
587 sb_error.SetErrorString("invalid breakpoint");
592 bool SBBreakpoint::AddName(const char *new_name) {
593 Log *log(lldb_private::GetLogIfAllCategoriesSet(LIBLLDB_LOG_API));
596 log->Printf("SBBreakpoint(%p)::AddName (name=%s)",
597 static_cast<void *>(m_opaque_sp.get()), new_name);
600 std::lock_guard<std::recursive_mutex> guard(
601 m_opaque_sp->GetTarget().GetAPIMutex());
602 Error error; // Think I'm just going to swallow the error here, it's
603 // probably more annoying to have to provide it.
604 return m_opaque_sp->AddName(new_name, error);
610 void SBBreakpoint::RemoveName(const char *name_to_remove) {
611 Log *log(lldb_private::GetLogIfAllCategoriesSet(LIBLLDB_LOG_API));
614 log->Printf("SBBreakpoint(%p)::RemoveName (name=%s)",
615 static_cast<void *>(m_opaque_sp.get()), name_to_remove);
618 std::lock_guard<std::recursive_mutex> guard(
619 m_opaque_sp->GetTarget().GetAPIMutex());
620 m_opaque_sp->RemoveName(name_to_remove);
624 bool SBBreakpoint::MatchesName(const char *name) {
625 Log *log(lldb_private::GetLogIfAllCategoriesSet(LIBLLDB_LOG_API));
628 log->Printf("SBBreakpoint(%p)::MatchesName (name=%s)",
629 static_cast<void *>(m_opaque_sp.get()), name);
632 std::lock_guard<std::recursive_mutex> guard(
633 m_opaque_sp->GetTarget().GetAPIMutex());
634 return m_opaque_sp->MatchesName(name);
640 void SBBreakpoint::GetNames(SBStringList &names) {
641 Log *log(lldb_private::GetLogIfAllCategoriesSet(LIBLLDB_LOG_API));
644 log->Printf("SBBreakpoint(%p)::GetNames ()",
645 static_cast<void *>(m_opaque_sp.get()));
648 std::lock_guard<std::recursive_mutex> guard(
649 m_opaque_sp->GetTarget().GetAPIMutex());
650 std::vector<std::string> names_vec;
651 m_opaque_sp->GetNames(names_vec);
652 for (std::string name : names_vec) {
653 names.AppendString(name.c_str());
658 lldb_private::Breakpoint *SBBreakpoint::operator->() const {
659 return m_opaque_sp.get();
662 lldb_private::Breakpoint *SBBreakpoint::get() const {
663 return m_opaque_sp.get();
666 lldb::BreakpointSP &SBBreakpoint::operator*() { return m_opaque_sp; }
668 const lldb::BreakpointSP &SBBreakpoint::operator*() const {
672 bool SBBreakpoint::EventIsBreakpointEvent(const lldb::SBEvent &event) {
673 return Breakpoint::BreakpointEventData::GetEventDataFromEvent(event.get()) !=
678 SBBreakpoint::GetBreakpointEventTypeFromEvent(const SBEvent &event) {
680 return Breakpoint::BreakpointEventData::GetBreakpointEventTypeFromEvent(
682 return eBreakpointEventTypeInvalidType;
685 SBBreakpoint SBBreakpoint::GetBreakpointFromEvent(const lldb::SBEvent &event) {
686 SBBreakpoint sb_breakpoint;
688 sb_breakpoint.m_opaque_sp =
689 Breakpoint::BreakpointEventData::GetBreakpointFromEvent(event.GetSP());
690 return sb_breakpoint;
694 SBBreakpoint::GetBreakpointLocationAtIndexFromEvent(const lldb::SBEvent &event,
696 SBBreakpointLocation sb_breakpoint_loc;
698 sb_breakpoint_loc.SetLocation(
699 Breakpoint::BreakpointEventData::GetBreakpointLocationAtIndexFromEvent(
700 event.GetSP(), loc_idx));
701 return sb_breakpoint_loc;
705 SBBreakpoint::GetNumBreakpointLocationsFromEvent(const lldb::SBEvent &event) {
706 uint32_t num_locations = 0;
709 (Breakpoint::BreakpointEventData::GetNumBreakpointLocationsFromEvent(
711 return num_locations;
714 // This is simple collection of breakpoint id's and their target.
715 class SBBreakpointListImpl {
717 SBBreakpointListImpl(lldb::TargetSP target_sp) : m_target_wp() {
718 if (target_sp && target_sp->IsValid())
719 m_target_wp = target_sp;
722 ~SBBreakpointListImpl() = default;
724 size_t GetSize() { return m_break_ids.size(); }
726 BreakpointSP GetBreakpointAtIndex(size_t idx) {
727 if (idx >= m_break_ids.size())
728 return BreakpointSP();
729 TargetSP target_sp = m_target_wp.lock();
731 return BreakpointSP();
732 lldb::break_id_t bp_id = m_break_ids[idx];
733 return target_sp->GetBreakpointList().FindBreakpointByID(bp_id);
736 BreakpointSP FindBreakpointByID(lldb::break_id_t desired_id) {
737 TargetSP target_sp = m_target_wp.lock();
739 return BreakpointSP();
741 for (lldb::break_id_t &break_id : m_break_ids) {
742 if (break_id == desired_id)
743 return target_sp->GetBreakpointList().FindBreakpointByID(break_id);
745 return BreakpointSP();
748 bool Append(Breakpoint &bkpt) {
749 TargetSP target_sp = m_target_wp.lock();
752 if (bkpt.GetTargetSP() != target_sp)
754 m_break_ids.push_back(bkpt.GetID());
758 bool AppendIfUnique(Breakpoint &bkpt) {
759 TargetSP target_sp = m_target_wp.lock();
762 if (bkpt.GetTargetSP() != target_sp)
764 lldb::break_id_t bp_id = bkpt.GetID();
765 if (find(m_break_ids.begin(), m_break_ids.end(), bp_id) ==
769 m_break_ids.push_back(bkpt.GetID());
773 bool AppendByID(lldb::break_id_t id) {
774 TargetSP target_sp = m_target_wp.lock();
777 if (id == LLDB_INVALID_BREAK_ID)
779 m_break_ids.push_back(id);
783 void Clear() { m_break_ids.clear(); }
785 void CopyToBreakpointIDList(lldb_private::BreakpointIDList &bp_list) {
786 for (lldb::break_id_t id : m_break_ids) {
787 bp_list.AddBreakpointID(BreakpointID(id));
791 TargetSP GetTarget() { return m_target_wp.lock(); }
794 std::vector<lldb::break_id_t> m_break_ids;
795 TargetWP m_target_wp;
798 SBBreakpointList::SBBreakpointList(SBTarget &target)
799 : m_opaque_sp(new SBBreakpointListImpl(target.GetSP())) {}
801 SBBreakpointList::~SBBreakpointList() {}
803 size_t SBBreakpointList::GetSize() const {
807 return m_opaque_sp->GetSize();
810 SBBreakpoint SBBreakpointList::GetBreakpointAtIndex(size_t idx) {
812 return SBBreakpoint();
814 BreakpointSP bkpt_sp = m_opaque_sp->GetBreakpointAtIndex(idx);
815 return SBBreakpoint(bkpt_sp);
818 SBBreakpoint SBBreakpointList::FindBreakpointByID(lldb::break_id_t id) {
820 return SBBreakpoint();
821 BreakpointSP bkpt_sp = m_opaque_sp->FindBreakpointByID(id);
822 return SBBreakpoint(bkpt_sp);
825 void SBBreakpointList::Append(const SBBreakpoint &sb_bkpt) {
826 if (!sb_bkpt.IsValid())
830 m_opaque_sp->Append(*sb_bkpt.get());
833 void SBBreakpointList::AppendByID(lldb::break_id_t id) {
836 m_opaque_sp->AppendByID(id);
839 bool SBBreakpointList::AppendIfUnique(const SBBreakpoint &sb_bkpt) {
840 if (!sb_bkpt.IsValid())
844 return m_opaque_sp->AppendIfUnique(*sb_bkpt.get());
847 void SBBreakpointList::Clear() {
849 m_opaque_sp->Clear();
852 void SBBreakpointList::CopyToBreakpointIDList(
853 lldb_private::BreakpointIDList &bp_id_list) {
855 m_opaque_sp->CopyToBreakpointIDList(bp_id_list);