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 //===----------------------------------------------------------------------===//
10 #include "lldb/API/SBBreakpoint.h"
11 #include "lldb/API/SBBreakpointLocation.h"
12 #include "lldb/API/SBDebugger.h"
13 #include "lldb/API/SBEvent.h"
14 #include "lldb/API/SBProcess.h"
15 #include "lldb/API/SBStream.h"
16 #include "lldb/API/SBStringList.h"
17 #include "lldb/API/SBThread.h"
19 #include "lldb/Breakpoint/Breakpoint.h"
20 #include "lldb/Breakpoint/BreakpointIDList.h"
21 #include "lldb/Breakpoint/BreakpointLocation.h"
22 #include "lldb/Breakpoint/BreakpointResolver.h"
23 #include "lldb/Breakpoint/BreakpointResolverScripted.h"
24 #include "lldb/Breakpoint/StoppointCallbackContext.h"
25 #include "lldb/Core/Address.h"
26 #include "lldb/Core/Debugger.h"
27 #include "lldb/Core/StreamFile.h"
28 #include "lldb/Interpreter/CommandInterpreter.h"
29 #include "lldb/Interpreter/ScriptInterpreter.h"
30 #include "lldb/Target/Process.h"
31 #include "lldb/Target/SectionLoadList.h"
32 #include "lldb/Target/Target.h"
33 #include "lldb/Target/Thread.h"
34 #include "lldb/Target/ThreadSpec.h"
35 #include "lldb/Utility/Log.h"
36 #include "lldb/Utility/Stream.h"
38 #include "SBBreakpointOptionCommon.h"
40 #include "lldb/lldb-enumerations.h"
42 #include "llvm/ADT/STLExtras.h"
45 using namespace lldb_private;
47 SBBreakpoint::SBBreakpoint() {}
49 SBBreakpoint::SBBreakpoint(const SBBreakpoint &rhs)
50 : m_opaque_wp(rhs.m_opaque_wp) {}
52 SBBreakpoint::SBBreakpoint(const lldb::BreakpointSP &bp_sp)
53 : m_opaque_wp(bp_sp) {}
55 SBBreakpoint::~SBBreakpoint() = default;
57 const SBBreakpoint &SBBreakpoint::operator=(const SBBreakpoint &rhs) {
58 m_opaque_wp = rhs.m_opaque_wp;
62 bool SBBreakpoint::operator==(const lldb::SBBreakpoint &rhs) {
63 return m_opaque_wp.lock() == rhs.m_opaque_wp.lock();
66 bool SBBreakpoint::operator!=(const lldb::SBBreakpoint &rhs) {
67 return m_opaque_wp.lock() != rhs.m_opaque_wp.lock();
70 break_id_t SBBreakpoint::GetID() const {
71 Log *log(lldb_private::GetLogIfAllCategoriesSet(LIBLLDB_LOG_API));
73 break_id_t break_id = LLDB_INVALID_BREAK_ID;
74 BreakpointSP bkpt_sp = GetSP();
76 break_id = bkpt_sp->GetID();
78 LLDB_LOG(log, "breakpoint = {0}, id = {1}", bkpt_sp.get(), break_id);
82 bool SBBreakpoint::IsValid() const {
83 BreakpointSP bkpt_sp = GetSP();
86 else if (bkpt_sp->GetTarget().GetBreakpointByID(bkpt_sp->GetID()))
92 void SBBreakpoint::ClearAllBreakpointSites() {
93 BreakpointSP bkpt_sp = GetSP();
95 std::lock_guard<std::recursive_mutex> guard(
96 bkpt_sp->GetTarget().GetAPIMutex());
97 bkpt_sp->ClearAllBreakpointSites();
101 SBBreakpointLocation SBBreakpoint::FindLocationByAddress(addr_t vm_addr) {
102 SBBreakpointLocation sb_bp_location;
104 BreakpointSP bkpt_sp = GetSP();
106 if (vm_addr != LLDB_INVALID_ADDRESS) {
107 std::lock_guard<std::recursive_mutex> guard(
108 bkpt_sp->GetTarget().GetAPIMutex());
110 Target &target = bkpt_sp->GetTarget();
111 if (!target.GetSectionLoadList().ResolveLoadAddress(vm_addr, address)) {
112 address.SetRawAddress(vm_addr);
114 sb_bp_location.SetLocation(bkpt_sp->FindLocationByAddress(address));
117 return sb_bp_location;
120 break_id_t SBBreakpoint::FindLocationIDByAddress(addr_t vm_addr) {
121 break_id_t break_id = LLDB_INVALID_BREAK_ID;
122 BreakpointSP bkpt_sp = GetSP();
124 if (bkpt_sp && vm_addr != LLDB_INVALID_ADDRESS) {
125 std::lock_guard<std::recursive_mutex> guard(
126 bkpt_sp->GetTarget().GetAPIMutex());
128 Target &target = bkpt_sp->GetTarget();
129 if (!target.GetSectionLoadList().ResolveLoadAddress(vm_addr, address)) {
130 address.SetRawAddress(vm_addr);
132 break_id = bkpt_sp->FindLocationIDByAddress(address);
138 SBBreakpointLocation SBBreakpoint::FindLocationByID(break_id_t bp_loc_id) {
139 SBBreakpointLocation sb_bp_location;
140 BreakpointSP bkpt_sp = GetSP();
143 std::lock_guard<std::recursive_mutex> guard(
144 bkpt_sp->GetTarget().GetAPIMutex());
145 sb_bp_location.SetLocation(bkpt_sp->FindLocationByID(bp_loc_id));
148 return sb_bp_location;
151 SBBreakpointLocation SBBreakpoint::GetLocationAtIndex(uint32_t index) {
152 SBBreakpointLocation sb_bp_location;
153 BreakpointSP bkpt_sp = GetSP();
156 std::lock_guard<std::recursive_mutex> guard(
157 bkpt_sp->GetTarget().GetAPIMutex());
158 sb_bp_location.SetLocation(bkpt_sp->GetLocationAtIndex(index));
161 return sb_bp_location;
164 void SBBreakpoint::SetEnabled(bool enable) {
165 Log *log(lldb_private::GetLogIfAllCategoriesSet(LIBLLDB_LOG_API));
166 BreakpointSP bkpt_sp = GetSP();
168 LLDB_LOG(log, "breakpoint = {0}, enable = {1}", bkpt_sp.get(), enable);
171 std::lock_guard<std::recursive_mutex> guard(
172 bkpt_sp->GetTarget().GetAPIMutex());
173 bkpt_sp->SetEnabled(enable);
177 bool SBBreakpoint::IsEnabled() {
178 BreakpointSP bkpt_sp = GetSP();
180 std::lock_guard<std::recursive_mutex> guard(
181 bkpt_sp->GetTarget().GetAPIMutex());
182 return bkpt_sp->IsEnabled();
187 void SBBreakpoint::SetOneShot(bool one_shot) {
188 Log *log(lldb_private::GetLogIfAllCategoriesSet(LIBLLDB_LOG_API));
189 BreakpointSP bkpt_sp = GetSP();
191 LLDB_LOG(log, "breakpoint = {0}, one_shot = {1}", bkpt_sp.get(), one_shot);
194 std::lock_guard<std::recursive_mutex> guard(
195 bkpt_sp->GetTarget().GetAPIMutex());
196 bkpt_sp->SetOneShot(one_shot);
200 bool SBBreakpoint::IsOneShot() const {
201 BreakpointSP bkpt_sp = GetSP();
203 std::lock_guard<std::recursive_mutex> guard(
204 bkpt_sp->GetTarget().GetAPIMutex());
205 return bkpt_sp->IsOneShot();
210 bool SBBreakpoint::IsInternal() {
211 BreakpointSP bkpt_sp = GetSP();
213 std::lock_guard<std::recursive_mutex> guard(
214 bkpt_sp->GetTarget().GetAPIMutex());
215 return bkpt_sp->IsInternal();
220 void SBBreakpoint::SetIgnoreCount(uint32_t count) {
221 Log *log(lldb_private::GetLogIfAllCategoriesSet(LIBLLDB_LOG_API));
222 BreakpointSP bkpt_sp = GetSP();
224 LLDB_LOG(log, "breakpoint = {0}, count = {1}", bkpt_sp.get(), count);
227 std::lock_guard<std::recursive_mutex> guard(
228 bkpt_sp->GetTarget().GetAPIMutex());
229 bkpt_sp->SetIgnoreCount(count);
233 void SBBreakpoint::SetCondition(const char *condition) {
234 BreakpointSP bkpt_sp = GetSP();
236 std::lock_guard<std::recursive_mutex> guard(
237 bkpt_sp->GetTarget().GetAPIMutex());
238 bkpt_sp->SetCondition(condition);
242 const char *SBBreakpoint::GetCondition() {
243 BreakpointSP bkpt_sp = GetSP();
245 std::lock_guard<std::recursive_mutex> guard(
246 bkpt_sp->GetTarget().GetAPIMutex());
247 return bkpt_sp->GetConditionText();
252 void SBBreakpoint::SetAutoContinue(bool auto_continue) {
253 BreakpointSP bkpt_sp = GetSP();
255 std::lock_guard<std::recursive_mutex> guard(
256 bkpt_sp->GetTarget().GetAPIMutex());
257 bkpt_sp->SetAutoContinue(auto_continue);
261 bool SBBreakpoint::GetAutoContinue() {
262 BreakpointSP bkpt_sp = GetSP();
264 std::lock_guard<std::recursive_mutex> guard(
265 bkpt_sp->GetTarget().GetAPIMutex());
266 return bkpt_sp->IsAutoContinue();
271 uint32_t SBBreakpoint::GetHitCount() const {
273 BreakpointSP bkpt_sp = GetSP();
275 std::lock_guard<std::recursive_mutex> guard(
276 bkpt_sp->GetTarget().GetAPIMutex());
277 count = bkpt_sp->GetHitCount();
280 Log *log(lldb_private::GetLogIfAllCategoriesSet(LIBLLDB_LOG_API));
281 LLDB_LOG(log, "breakpoint = {0}, count = {1}", bkpt_sp.get(), count);
286 uint32_t SBBreakpoint::GetIgnoreCount() const {
288 BreakpointSP bkpt_sp = GetSP();
290 std::lock_guard<std::recursive_mutex> guard(
291 bkpt_sp->GetTarget().GetAPIMutex());
292 count = bkpt_sp->GetIgnoreCount();
295 Log *log(lldb_private::GetLogIfAllCategoriesSet(LIBLLDB_LOG_API));
296 LLDB_LOG(log, "breakpoint = {0}, count = {1}", bkpt_sp.get(), count);
301 void SBBreakpoint::SetThreadID(tid_t tid) {
302 BreakpointSP bkpt_sp = GetSP();
304 std::lock_guard<std::recursive_mutex> guard(
305 bkpt_sp->GetTarget().GetAPIMutex());
306 bkpt_sp->SetThreadID(tid);
308 Log *log(lldb_private::GetLogIfAllCategoriesSet(LIBLLDB_LOG_API));
309 LLDB_LOG(log, "breakpoint = {0}, tid = {1:x}", bkpt_sp.get(), tid);
312 tid_t SBBreakpoint::GetThreadID() {
313 tid_t tid = LLDB_INVALID_THREAD_ID;
314 BreakpointSP bkpt_sp = GetSP();
316 std::lock_guard<std::recursive_mutex> guard(
317 bkpt_sp->GetTarget().GetAPIMutex());
318 tid = bkpt_sp->GetThreadID();
321 Log *log(lldb_private::GetLogIfAllCategoriesSet(LIBLLDB_LOG_API));
322 LLDB_LOG(log, "breakpoint = {0}, tid = {1:x}", bkpt_sp.get(), tid);
326 void SBBreakpoint::SetThreadIndex(uint32_t index) {
327 Log *log(lldb_private::GetLogIfAllCategoriesSet(LIBLLDB_LOG_API));
328 BreakpointSP bkpt_sp = GetSP();
329 LLDB_LOG(log, "breakpoint = {0}, index = {1}", bkpt_sp.get(), index);
331 std::lock_guard<std::recursive_mutex> guard(
332 bkpt_sp->GetTarget().GetAPIMutex());
333 bkpt_sp->GetOptions()->GetThreadSpec()->SetIndex(index);
337 uint32_t SBBreakpoint::GetThreadIndex() const {
338 uint32_t thread_idx = UINT32_MAX;
339 BreakpointSP bkpt_sp = GetSP();
341 std::lock_guard<std::recursive_mutex> guard(
342 bkpt_sp->GetTarget().GetAPIMutex());
343 const ThreadSpec *thread_spec =
344 bkpt_sp->GetOptions()->GetThreadSpecNoCreate();
345 if (thread_spec != nullptr)
346 thread_idx = thread_spec->GetIndex();
348 Log *log(lldb_private::GetLogIfAllCategoriesSet(LIBLLDB_LOG_API));
349 LLDB_LOG(log, "breakpoint = {0}, index = {1}", bkpt_sp.get(), thread_idx);
354 void SBBreakpoint::SetThreadName(const char *thread_name) {
355 Log *log(lldb_private::GetLogIfAllCategoriesSet(LIBLLDB_LOG_API));
356 BreakpointSP bkpt_sp = GetSP();
357 LLDB_LOG(log, "breakpoint = {0}, name = {1}", bkpt_sp.get(), thread_name);
360 std::lock_guard<std::recursive_mutex> guard(
361 bkpt_sp->GetTarget().GetAPIMutex());
362 bkpt_sp->GetOptions()->GetThreadSpec()->SetName(thread_name);
366 const char *SBBreakpoint::GetThreadName() const {
367 const char *name = nullptr;
368 BreakpointSP bkpt_sp = GetSP();
370 std::lock_guard<std::recursive_mutex> guard(
371 bkpt_sp->GetTarget().GetAPIMutex());
372 const ThreadSpec *thread_spec =
373 bkpt_sp->GetOptions()->GetThreadSpecNoCreate();
374 if (thread_spec != nullptr)
375 name = thread_spec->GetName();
377 Log *log(lldb_private::GetLogIfAllCategoriesSet(LIBLLDB_LOG_API));
378 LLDB_LOG(log, "breakpoint = {0}, name = {1}", bkpt_sp.get(), name);
383 void SBBreakpoint::SetQueueName(const char *queue_name) {
384 Log *log(lldb_private::GetLogIfAllCategoriesSet(LIBLLDB_LOG_API));
385 BreakpointSP bkpt_sp = GetSP();
386 LLDB_LOG(log, "breakpoint = {0}, queue_name = {1}", bkpt_sp.get(),
389 std::lock_guard<std::recursive_mutex> guard(
390 bkpt_sp->GetTarget().GetAPIMutex());
391 bkpt_sp->GetOptions()->GetThreadSpec()->SetQueueName(queue_name);
395 const char *SBBreakpoint::GetQueueName() const {
396 const char *name = nullptr;
397 BreakpointSP bkpt_sp = GetSP();
399 std::lock_guard<std::recursive_mutex> guard(
400 bkpt_sp->GetTarget().GetAPIMutex());
401 const ThreadSpec *thread_spec =
402 bkpt_sp->GetOptions()->GetThreadSpecNoCreate();
404 name = thread_spec->GetQueueName();
406 Log *log(lldb_private::GetLogIfAllCategoriesSet(LIBLLDB_LOG_API));
407 LLDB_LOG(log, "breakpoint = {0}, name = {1}", bkpt_sp.get(), name);
412 size_t SBBreakpoint::GetNumResolvedLocations() const {
413 size_t num_resolved = 0;
414 BreakpointSP bkpt_sp = GetSP();
416 std::lock_guard<std::recursive_mutex> guard(
417 bkpt_sp->GetTarget().GetAPIMutex());
418 num_resolved = bkpt_sp->GetNumResolvedLocations();
420 Log *log(lldb_private::GetLogIfAllCategoriesSet(LIBLLDB_LOG_API));
421 LLDB_LOG(log, "breakpoint = {0}, num_resolved = {1}", bkpt_sp.get(),
426 size_t SBBreakpoint::GetNumLocations() const {
427 BreakpointSP bkpt_sp = GetSP();
430 std::lock_guard<std::recursive_mutex> guard(
431 bkpt_sp->GetTarget().GetAPIMutex());
432 num_locs = bkpt_sp->GetNumLocations();
434 Log *log(lldb_private::GetLogIfAllCategoriesSet(LIBLLDB_LOG_API));
435 LLDB_LOG(log, "breakpoint = {0}, num_locs = {1}", bkpt_sp.get(), num_locs);
439 void SBBreakpoint::SetCommandLineCommands(SBStringList &commands) {
440 BreakpointSP bkpt_sp = GetSP();
443 if (commands.GetSize() == 0)
446 std::lock_guard<std::recursive_mutex> guard(
447 bkpt_sp->GetTarget().GetAPIMutex());
448 std::unique_ptr<BreakpointOptions::CommandData> cmd_data_up(
449 new BreakpointOptions::CommandData(*commands, eScriptLanguageNone));
451 bkpt_sp->GetOptions()->SetCommandDataCallback(cmd_data_up);
454 bool SBBreakpoint::GetCommandLineCommands(SBStringList &commands) {
455 BreakpointSP bkpt_sp = GetSP();
458 StringList command_list;
460 bkpt_sp->GetOptions()->GetCommandLineCallbacks(command_list);
462 commands.AppendList(command_list);
466 bool SBBreakpoint::GetDescription(SBStream &s) {
467 return GetDescription(s, true);
470 bool SBBreakpoint::GetDescription(SBStream &s, bool include_locations) {
471 BreakpointSP bkpt_sp = GetSP();
473 std::lock_guard<std::recursive_mutex> guard(
474 bkpt_sp->GetTarget().GetAPIMutex());
475 s.Printf("SBBreakpoint: id = %i, ", bkpt_sp->GetID());
476 bkpt_sp->GetResolverDescription(s.get());
477 bkpt_sp->GetFilterDescription(s.get());
478 if (include_locations) {
479 const size_t num_locations = bkpt_sp->GetNumLocations();
480 s.Printf(", locations = %" PRIu64, (uint64_t)num_locations);
484 s.Printf("No value");
489 SBBreakpoint::AddLocation(SBAddress &address) {
490 BreakpointSP bkpt_sp = GetSP();
493 if (!address.IsValid()) {
494 error.SetErrorString("Can't add an invalid address.");
499 error.SetErrorString("No breakpoint to add a location to.");
503 if (!llvm::isa<BreakpointResolverScripted>(bkpt_sp->GetResolver().get())) {
504 error.SetErrorString("Only a scripted resolver can add locations.");
508 if (bkpt_sp->GetSearchFilter()->AddressPasses(address.ref()))
509 bkpt_sp->AddLocation(address.ref());
513 address.get()->Dump(&s, &bkpt_sp->GetTarget(),
514 Address::DumpStyleModuleWithFileAddress);
515 error.SetErrorStringWithFormat("Address: %s didn't pass the filter.",
523 ::SetCallback(SBBreakpointHitCallback callback,
525 Log *log(lldb_private::GetLogIfAllCategoriesSet(LIBLLDB_LOG_API));
526 BreakpointSP bkpt_sp = GetSP();
527 LLDB_LOG(log, "breakpoint = {0}, callback = {1}, baton = {2}", bkpt_sp.get(),
531 std::lock_guard<std::recursive_mutex> guard(
532 bkpt_sp->GetTarget().GetAPIMutex());
533 BatonSP baton_sp(new SBBreakpointCallbackBaton(callback, baton));
534 bkpt_sp->SetCallback(SBBreakpointCallbackBaton
535 ::PrivateBreakpointHitCallback, baton_sp,
540 void SBBreakpoint::SetScriptCallbackFunction(
541 const char *callback_function_name) {
542 Log *log(lldb_private::GetLogIfAllCategoriesSet(LIBLLDB_LOG_API));
543 BreakpointSP bkpt_sp = GetSP();
544 LLDB_LOG(log, "breakpoint = {0}, callback = {1}", bkpt_sp.get(),
545 callback_function_name);
548 std::lock_guard<std::recursive_mutex> guard(
549 bkpt_sp->GetTarget().GetAPIMutex());
550 BreakpointOptions *bp_options = bkpt_sp->GetOptions();
553 .GetCommandInterpreter()
554 .GetScriptInterpreter()
555 ->SetBreakpointCommandCallbackFunction(bp_options,
556 callback_function_name);
560 SBError SBBreakpoint::SetScriptCallbackBody(const char *callback_body_text) {
561 Log *log(lldb_private::GetLogIfAllCategoriesSet(LIBLLDB_LOG_API));
562 BreakpointSP bkpt_sp = GetSP();
563 LLDB_LOG(log, "breakpoint = {0}, callback body:\n{1}", bkpt_sp.get(),
568 std::lock_guard<std::recursive_mutex> guard(
569 bkpt_sp->GetTarget().GetAPIMutex());
570 BreakpointOptions *bp_options = bkpt_sp->GetOptions();
574 .GetCommandInterpreter()
575 .GetScriptInterpreter()
576 ->SetBreakpointCommandCallback(bp_options, callback_body_text);
577 sb_error.SetError(error);
579 sb_error.SetErrorString("invalid breakpoint");
584 bool SBBreakpoint::AddName(const char *new_name) {
585 Log *log(lldb_private::GetLogIfAllCategoriesSet(LIBLLDB_LOG_API));
586 BreakpointSP bkpt_sp = GetSP();
587 LLDB_LOG(log, "breakpoint = {0}, name = {1}", bkpt_sp.get(), new_name);
590 std::lock_guard<std::recursive_mutex> guard(
591 bkpt_sp->GetTarget().GetAPIMutex());
592 Status error; // Think I'm just going to swallow the error here, it's
593 // probably more annoying to have to provide it.
594 bkpt_sp->GetTarget().AddNameToBreakpoint(bkpt_sp, new_name, error);
598 log->Printf("Failed to add name: '%s' to breakpoint: %s",
599 new_name, error.AsCString());
607 void SBBreakpoint::RemoveName(const char *name_to_remove) {
608 Log *log(lldb_private::GetLogIfAllCategoriesSet(LIBLLDB_LOG_API));
609 BreakpointSP bkpt_sp = GetSP();
610 LLDB_LOG(log, "breakpoint = {0}, name = {1}", bkpt_sp.get(), name_to_remove);
613 std::lock_guard<std::recursive_mutex> guard(
614 bkpt_sp->GetTarget().GetAPIMutex());
615 bkpt_sp->GetTarget().RemoveNameFromBreakpoint(bkpt_sp,
616 ConstString(name_to_remove));
620 bool SBBreakpoint::MatchesName(const char *name) {
621 Log *log(lldb_private::GetLogIfAllCategoriesSet(LIBLLDB_LOG_API));
622 BreakpointSP bkpt_sp = GetSP();
623 LLDB_LOG(log, "breakpoint = {0}, name = {1}", bkpt_sp.get(), name);
626 std::lock_guard<std::recursive_mutex> guard(
627 bkpt_sp->GetTarget().GetAPIMutex());
628 return bkpt_sp->MatchesName(name);
634 void SBBreakpoint::GetNames(SBStringList &names) {
635 Log *log(lldb_private::GetLogIfAllCategoriesSet(LIBLLDB_LOG_API));
636 BreakpointSP bkpt_sp = GetSP();
637 LLDB_LOG(log, "breakpoint = {0}", bkpt_sp.get());
640 std::lock_guard<std::recursive_mutex> guard(
641 bkpt_sp->GetTarget().GetAPIMutex());
642 std::vector<std::string> names_vec;
643 bkpt_sp->GetNames(names_vec);
644 for (std::string name : names_vec) {
645 names.AppendString(name.c_str());
650 bool SBBreakpoint::EventIsBreakpointEvent(const lldb::SBEvent &event) {
651 return Breakpoint::BreakpointEventData::GetEventDataFromEvent(event.get()) !=
656 SBBreakpoint::GetBreakpointEventTypeFromEvent(const SBEvent &event) {
658 return Breakpoint::BreakpointEventData::GetBreakpointEventTypeFromEvent(
660 return eBreakpointEventTypeInvalidType;
663 SBBreakpoint SBBreakpoint::GetBreakpointFromEvent(const lldb::SBEvent &event) {
666 Breakpoint::BreakpointEventData::GetBreakpointFromEvent(event.GetSP()));
667 return SBBreakpoint();
671 SBBreakpoint::GetBreakpointLocationAtIndexFromEvent(const lldb::SBEvent &event,
673 SBBreakpointLocation sb_breakpoint_loc;
675 sb_breakpoint_loc.SetLocation(
676 Breakpoint::BreakpointEventData::GetBreakpointLocationAtIndexFromEvent(
677 event.GetSP(), loc_idx));
678 return sb_breakpoint_loc;
682 SBBreakpoint::GetNumBreakpointLocationsFromEvent(const lldb::SBEvent &event) {
683 uint32_t num_locations = 0;
686 (Breakpoint::BreakpointEventData::GetNumBreakpointLocationsFromEvent(
688 return num_locations;
691 bool SBBreakpoint::IsHardware() const {
692 BreakpointSP bkpt_sp = GetSP();
694 return bkpt_sp->IsHardware();
698 BreakpointSP SBBreakpoint::GetSP() const { return m_opaque_wp.lock(); }
700 // This is simple collection of breakpoint id's and their target.
701 class SBBreakpointListImpl {
703 SBBreakpointListImpl(lldb::TargetSP target_sp) : m_target_wp() {
704 if (target_sp && target_sp->IsValid())
705 m_target_wp = target_sp;
708 ~SBBreakpointListImpl() = default;
710 size_t GetSize() { return m_break_ids.size(); }
712 BreakpointSP GetBreakpointAtIndex(size_t idx) {
713 if (idx >= m_break_ids.size())
714 return BreakpointSP();
715 TargetSP target_sp = m_target_wp.lock();
717 return BreakpointSP();
718 lldb::break_id_t bp_id = m_break_ids[idx];
719 return target_sp->GetBreakpointList().FindBreakpointByID(bp_id);
722 BreakpointSP FindBreakpointByID(lldb::break_id_t desired_id) {
723 TargetSP target_sp = m_target_wp.lock();
725 return BreakpointSP();
727 for (lldb::break_id_t &break_id : m_break_ids) {
728 if (break_id == desired_id)
729 return target_sp->GetBreakpointList().FindBreakpointByID(break_id);
731 return BreakpointSP();
734 bool Append(BreakpointSP bkpt) {
735 TargetSP target_sp = m_target_wp.lock();
736 if (!target_sp || !bkpt)
738 if (bkpt->GetTargetSP() != target_sp)
740 m_break_ids.push_back(bkpt->GetID());
744 bool AppendIfUnique(BreakpointSP bkpt) {
745 TargetSP target_sp = m_target_wp.lock();
746 if (!target_sp || !bkpt)
748 if (bkpt->GetTargetSP() != target_sp)
750 lldb::break_id_t bp_id = bkpt->GetID();
751 if (find(m_break_ids.begin(), m_break_ids.end(), bp_id) ==
755 m_break_ids.push_back(bkpt->GetID());
759 bool AppendByID(lldb::break_id_t id) {
760 TargetSP target_sp = m_target_wp.lock();
763 if (id == LLDB_INVALID_BREAK_ID)
765 m_break_ids.push_back(id);
769 void Clear() { m_break_ids.clear(); }
771 void CopyToBreakpointIDList(lldb_private::BreakpointIDList &bp_list) {
772 for (lldb::break_id_t id : m_break_ids) {
773 bp_list.AddBreakpointID(BreakpointID(id));
777 TargetSP GetTarget() { return m_target_wp.lock(); }
780 std::vector<lldb::break_id_t> m_break_ids;
781 TargetWP m_target_wp;
784 SBBreakpointList::SBBreakpointList(SBTarget &target)
785 : m_opaque_sp(new SBBreakpointListImpl(target.GetSP())) {}
787 SBBreakpointList::~SBBreakpointList() {}
789 size_t SBBreakpointList::GetSize() const {
793 return m_opaque_sp->GetSize();
796 SBBreakpoint SBBreakpointList::GetBreakpointAtIndex(size_t idx) {
798 return SBBreakpoint();
800 BreakpointSP bkpt_sp = m_opaque_sp->GetBreakpointAtIndex(idx);
801 return SBBreakpoint(bkpt_sp);
804 SBBreakpoint SBBreakpointList::FindBreakpointByID(lldb::break_id_t id) {
806 return SBBreakpoint();
807 BreakpointSP bkpt_sp = m_opaque_sp->FindBreakpointByID(id);
808 return SBBreakpoint(bkpt_sp);
811 void SBBreakpointList::Append(const SBBreakpoint &sb_bkpt) {
812 if (!sb_bkpt.IsValid())
816 m_opaque_sp->Append(sb_bkpt.m_opaque_wp.lock());
819 void SBBreakpointList::AppendByID(lldb::break_id_t id) {
822 m_opaque_sp->AppendByID(id);
825 bool SBBreakpointList::AppendIfUnique(const SBBreakpoint &sb_bkpt) {
826 if (!sb_bkpt.IsValid())
830 return m_opaque_sp->AppendIfUnique(sb_bkpt.GetSP());
833 void SBBreakpointList::Clear() {
835 m_opaque_sp->Clear();
838 void SBBreakpointList::CopyToBreakpointIDList(
839 lldb_private::BreakpointIDList &bp_id_list) {
841 m_opaque_sp->CopyToBreakpointIDList(bp_id_list);