1 //===-- SBBreakpoint.cpp --------------------------------------------------===//
3 // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
4 // See https://llvm.org/LICENSE.txt for license information.
5 // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
7 //===----------------------------------------------------------------------===//
9 #include "lldb/API/SBBreakpoint.h"
10 #include "lldb/API/SBBreakpointLocation.h"
11 #include "lldb/API/SBDebugger.h"
12 #include "lldb/API/SBEvent.h"
13 #include "lldb/API/SBProcess.h"
14 #include "lldb/API/SBStream.h"
15 #include "lldb/API/SBStringList.h"
16 #include "lldb/API/SBStructuredData.h"
17 #include "lldb/API/SBThread.h"
18 #include "lldb/Utility/Instrumentation.h"
20 #include "lldb/Breakpoint/Breakpoint.h"
21 #include "lldb/Breakpoint/BreakpointIDList.h"
22 #include "lldb/Breakpoint/BreakpointLocation.h"
23 #include "lldb/Breakpoint/BreakpointResolver.h"
24 #include "lldb/Breakpoint/BreakpointResolverScripted.h"
25 #include "lldb/Breakpoint/StoppointCallbackContext.h"
26 #include "lldb/Core/Address.h"
27 #include "lldb/Core/Debugger.h"
28 #include "lldb/Core/StructuredDataImpl.h"
29 #include "lldb/Interpreter/CommandInterpreter.h"
30 #include "lldb/Interpreter/ScriptInterpreter.h"
31 #include "lldb/Target/Process.h"
32 #include "lldb/Target/SectionLoadList.h"
33 #include "lldb/Target/Target.h"
34 #include "lldb/Target/Thread.h"
35 #include "lldb/Target/ThreadSpec.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() { LLDB_INSTRUMENT_VA(this); }
49 SBBreakpoint::SBBreakpoint(const SBBreakpoint
&rhs
)
50 : m_opaque_wp(rhs
.m_opaque_wp
) {
51 LLDB_INSTRUMENT_VA(this, rhs
);
54 SBBreakpoint::SBBreakpoint(const lldb::BreakpointSP
&bp_sp
)
55 : m_opaque_wp(bp_sp
) {
56 LLDB_INSTRUMENT_VA(this, bp_sp
);
59 SBBreakpoint::~SBBreakpoint() = default;
61 const SBBreakpoint
&SBBreakpoint::operator=(const SBBreakpoint
&rhs
) {
62 LLDB_INSTRUMENT_VA(this, rhs
);
64 m_opaque_wp
= rhs
.m_opaque_wp
;
68 bool SBBreakpoint::operator==(const lldb::SBBreakpoint
&rhs
) {
69 LLDB_INSTRUMENT_VA(this, rhs
);
71 return m_opaque_wp
.lock() == rhs
.m_opaque_wp
.lock();
74 bool SBBreakpoint::operator!=(const lldb::SBBreakpoint
&rhs
) {
75 LLDB_INSTRUMENT_VA(this, rhs
);
77 return m_opaque_wp
.lock() != rhs
.m_opaque_wp
.lock();
80 SBTarget
SBBreakpoint::GetTarget() const {
81 LLDB_INSTRUMENT_VA(this);
83 BreakpointSP bkpt_sp
= GetSP();
85 return SBTarget(bkpt_sp
->GetTargetSP());
90 break_id_t
SBBreakpoint::GetID() const {
91 LLDB_INSTRUMENT_VA(this);
93 break_id_t break_id
= LLDB_INVALID_BREAK_ID
;
94 BreakpointSP bkpt_sp
= GetSP();
96 break_id
= bkpt_sp
->GetID();
101 bool SBBreakpoint::IsValid() const {
102 LLDB_INSTRUMENT_VA(this);
103 return this->operator bool();
105 SBBreakpoint::operator bool() const {
106 LLDB_INSTRUMENT_VA(this);
108 BreakpointSP bkpt_sp
= GetSP();
111 else if (bkpt_sp
->GetTarget().GetBreakpointByID(bkpt_sp
->GetID()))
117 void SBBreakpoint::ClearAllBreakpointSites() {
118 LLDB_INSTRUMENT_VA(this);
120 BreakpointSP bkpt_sp
= GetSP();
122 std::lock_guard
<std::recursive_mutex
> guard(
123 bkpt_sp
->GetTarget().GetAPIMutex());
124 bkpt_sp
->ClearAllBreakpointSites();
128 SBBreakpointLocation
SBBreakpoint::FindLocationByAddress(addr_t vm_addr
) {
129 LLDB_INSTRUMENT_VA(this, vm_addr
);
131 SBBreakpointLocation sb_bp_location
;
133 BreakpointSP bkpt_sp
= GetSP();
135 if (vm_addr
!= LLDB_INVALID_ADDRESS
) {
136 std::lock_guard
<std::recursive_mutex
> guard(
137 bkpt_sp
->GetTarget().GetAPIMutex());
139 Target
&target
= bkpt_sp
->GetTarget();
140 if (!target
.GetSectionLoadList().ResolveLoadAddress(vm_addr
, address
)) {
141 address
.SetRawAddress(vm_addr
);
143 sb_bp_location
.SetLocation(bkpt_sp
->FindLocationByAddress(address
));
146 return sb_bp_location
;
149 break_id_t
SBBreakpoint::FindLocationIDByAddress(addr_t vm_addr
) {
150 LLDB_INSTRUMENT_VA(this, vm_addr
);
152 break_id_t break_id
= LLDB_INVALID_BREAK_ID
;
153 BreakpointSP bkpt_sp
= GetSP();
155 if (bkpt_sp
&& vm_addr
!= LLDB_INVALID_ADDRESS
) {
156 std::lock_guard
<std::recursive_mutex
> guard(
157 bkpt_sp
->GetTarget().GetAPIMutex());
159 Target
&target
= bkpt_sp
->GetTarget();
160 if (!target
.GetSectionLoadList().ResolveLoadAddress(vm_addr
, address
)) {
161 address
.SetRawAddress(vm_addr
);
163 break_id
= bkpt_sp
->FindLocationIDByAddress(address
);
169 SBBreakpointLocation
SBBreakpoint::FindLocationByID(break_id_t bp_loc_id
) {
170 LLDB_INSTRUMENT_VA(this, bp_loc_id
);
172 SBBreakpointLocation sb_bp_location
;
173 BreakpointSP bkpt_sp
= GetSP();
176 std::lock_guard
<std::recursive_mutex
> guard(
177 bkpt_sp
->GetTarget().GetAPIMutex());
178 sb_bp_location
.SetLocation(bkpt_sp
->FindLocationByID(bp_loc_id
));
181 return sb_bp_location
;
184 SBBreakpointLocation
SBBreakpoint::GetLocationAtIndex(uint32_t index
) {
185 LLDB_INSTRUMENT_VA(this, index
);
187 SBBreakpointLocation sb_bp_location
;
188 BreakpointSP bkpt_sp
= GetSP();
191 std::lock_guard
<std::recursive_mutex
> guard(
192 bkpt_sp
->GetTarget().GetAPIMutex());
193 sb_bp_location
.SetLocation(bkpt_sp
->GetLocationAtIndex(index
));
196 return sb_bp_location
;
199 void SBBreakpoint::SetEnabled(bool enable
) {
200 LLDB_INSTRUMENT_VA(this, enable
);
202 BreakpointSP bkpt_sp
= GetSP();
205 std::lock_guard
<std::recursive_mutex
> guard(
206 bkpt_sp
->GetTarget().GetAPIMutex());
207 bkpt_sp
->SetEnabled(enable
);
211 bool SBBreakpoint::IsEnabled() {
212 LLDB_INSTRUMENT_VA(this);
214 BreakpointSP bkpt_sp
= GetSP();
216 std::lock_guard
<std::recursive_mutex
> guard(
217 bkpt_sp
->GetTarget().GetAPIMutex());
218 return bkpt_sp
->IsEnabled();
223 void SBBreakpoint::SetOneShot(bool one_shot
) {
224 LLDB_INSTRUMENT_VA(this, one_shot
);
226 BreakpointSP bkpt_sp
= GetSP();
229 std::lock_guard
<std::recursive_mutex
> guard(
230 bkpt_sp
->GetTarget().GetAPIMutex());
231 bkpt_sp
->SetOneShot(one_shot
);
235 bool SBBreakpoint::IsOneShot() const {
236 LLDB_INSTRUMENT_VA(this);
238 BreakpointSP bkpt_sp
= GetSP();
240 std::lock_guard
<std::recursive_mutex
> guard(
241 bkpt_sp
->GetTarget().GetAPIMutex());
242 return bkpt_sp
->IsOneShot();
247 bool SBBreakpoint::IsInternal() {
248 LLDB_INSTRUMENT_VA(this);
250 BreakpointSP bkpt_sp
= GetSP();
252 std::lock_guard
<std::recursive_mutex
> guard(
253 bkpt_sp
->GetTarget().GetAPIMutex());
254 return bkpt_sp
->IsInternal();
259 void SBBreakpoint::SetIgnoreCount(uint32_t count
) {
260 LLDB_INSTRUMENT_VA(this, count
);
262 BreakpointSP bkpt_sp
= GetSP();
265 std::lock_guard
<std::recursive_mutex
> guard(
266 bkpt_sp
->GetTarget().GetAPIMutex());
267 bkpt_sp
->SetIgnoreCount(count
);
271 void SBBreakpoint::SetCondition(const char *condition
) {
272 LLDB_INSTRUMENT_VA(this, condition
);
274 BreakpointSP bkpt_sp
= GetSP();
276 std::lock_guard
<std::recursive_mutex
> guard(
277 bkpt_sp
->GetTarget().GetAPIMutex());
278 bkpt_sp
->SetCondition(condition
);
282 const char *SBBreakpoint::GetCondition() {
283 LLDB_INSTRUMENT_VA(this);
285 BreakpointSP bkpt_sp
= GetSP();
289 std::lock_guard
<std::recursive_mutex
> guard(
290 bkpt_sp
->GetTarget().GetAPIMutex());
291 return ConstString(bkpt_sp
->GetConditionText()).GetCString();
294 void SBBreakpoint::SetAutoContinue(bool auto_continue
) {
295 LLDB_INSTRUMENT_VA(this, auto_continue
);
297 BreakpointSP bkpt_sp
= GetSP();
299 std::lock_guard
<std::recursive_mutex
> guard(
300 bkpt_sp
->GetTarget().GetAPIMutex());
301 bkpt_sp
->SetAutoContinue(auto_continue
);
305 bool SBBreakpoint::GetAutoContinue() {
306 LLDB_INSTRUMENT_VA(this);
308 BreakpointSP bkpt_sp
= GetSP();
310 std::lock_guard
<std::recursive_mutex
> guard(
311 bkpt_sp
->GetTarget().GetAPIMutex());
312 return bkpt_sp
->IsAutoContinue();
317 uint32_t SBBreakpoint::GetHitCount() const {
318 LLDB_INSTRUMENT_VA(this);
321 BreakpointSP bkpt_sp
= GetSP();
323 std::lock_guard
<std::recursive_mutex
> guard(
324 bkpt_sp
->GetTarget().GetAPIMutex());
325 count
= bkpt_sp
->GetHitCount();
331 uint32_t SBBreakpoint::GetIgnoreCount() const {
332 LLDB_INSTRUMENT_VA(this);
335 BreakpointSP bkpt_sp
= GetSP();
337 std::lock_guard
<std::recursive_mutex
> guard(
338 bkpt_sp
->GetTarget().GetAPIMutex());
339 count
= bkpt_sp
->GetIgnoreCount();
345 void SBBreakpoint::SetThreadID(tid_t tid
) {
346 LLDB_INSTRUMENT_VA(this, tid
);
348 BreakpointSP bkpt_sp
= GetSP();
350 std::lock_guard
<std::recursive_mutex
> guard(
351 bkpt_sp
->GetTarget().GetAPIMutex());
352 bkpt_sp
->SetThreadID(tid
);
356 tid_t
SBBreakpoint::GetThreadID() {
357 LLDB_INSTRUMENT_VA(this);
359 tid_t tid
= LLDB_INVALID_THREAD_ID
;
360 BreakpointSP bkpt_sp
= GetSP();
362 std::lock_guard
<std::recursive_mutex
> guard(
363 bkpt_sp
->GetTarget().GetAPIMutex());
364 tid
= bkpt_sp
->GetThreadID();
370 void SBBreakpoint::SetThreadIndex(uint32_t index
) {
371 LLDB_INSTRUMENT_VA(this, index
);
373 BreakpointSP bkpt_sp
= GetSP();
375 std::lock_guard
<std::recursive_mutex
> guard(
376 bkpt_sp
->GetTarget().GetAPIMutex());
377 bkpt_sp
->GetOptions().GetThreadSpec()->SetIndex(index
);
381 uint32_t SBBreakpoint::GetThreadIndex() const {
382 LLDB_INSTRUMENT_VA(this);
384 uint32_t thread_idx
= UINT32_MAX
;
385 BreakpointSP bkpt_sp
= GetSP();
387 std::lock_guard
<std::recursive_mutex
> guard(
388 bkpt_sp
->GetTarget().GetAPIMutex());
389 const ThreadSpec
*thread_spec
=
390 bkpt_sp
->GetOptions().GetThreadSpecNoCreate();
391 if (thread_spec
!= nullptr)
392 thread_idx
= thread_spec
->GetIndex();
398 void SBBreakpoint::SetThreadName(const char *thread_name
) {
399 LLDB_INSTRUMENT_VA(this, thread_name
);
401 BreakpointSP bkpt_sp
= GetSP();
404 std::lock_guard
<std::recursive_mutex
> guard(
405 bkpt_sp
->GetTarget().GetAPIMutex());
406 bkpt_sp
->GetOptions().GetThreadSpec()->SetName(thread_name
);
410 const char *SBBreakpoint::GetThreadName() const {
411 LLDB_INSTRUMENT_VA(this);
413 BreakpointSP bkpt_sp
= GetSP();
417 std::lock_guard
<std::recursive_mutex
> guard(
418 bkpt_sp
->GetTarget().GetAPIMutex());
419 if (const ThreadSpec
*thread_spec
=
420 bkpt_sp
->GetOptions().GetThreadSpecNoCreate())
421 return ConstString(thread_spec
->GetName()).GetCString();
426 void SBBreakpoint::SetQueueName(const char *queue_name
) {
427 LLDB_INSTRUMENT_VA(this, queue_name
);
429 BreakpointSP bkpt_sp
= GetSP();
431 std::lock_guard
<std::recursive_mutex
> guard(
432 bkpt_sp
->GetTarget().GetAPIMutex());
433 bkpt_sp
->GetOptions().GetThreadSpec()->SetQueueName(queue_name
);
437 const char *SBBreakpoint::GetQueueName() const {
438 LLDB_INSTRUMENT_VA(this);
440 BreakpointSP bkpt_sp
= GetSP();
444 std::lock_guard
<std::recursive_mutex
> guard(
445 bkpt_sp
->GetTarget().GetAPIMutex());
446 if (const ThreadSpec
*thread_spec
=
447 bkpt_sp
->GetOptions().GetThreadSpecNoCreate())
448 return ConstString(thread_spec
->GetQueueName()).GetCString();
453 size_t SBBreakpoint::GetNumResolvedLocations() const {
454 LLDB_INSTRUMENT_VA(this);
456 size_t num_resolved
= 0;
457 BreakpointSP bkpt_sp
= GetSP();
459 std::lock_guard
<std::recursive_mutex
> guard(
460 bkpt_sp
->GetTarget().GetAPIMutex());
461 num_resolved
= bkpt_sp
->GetNumResolvedLocations();
466 size_t SBBreakpoint::GetNumLocations() const {
467 LLDB_INSTRUMENT_VA(this);
469 BreakpointSP bkpt_sp
= GetSP();
472 std::lock_guard
<std::recursive_mutex
> guard(
473 bkpt_sp
->GetTarget().GetAPIMutex());
474 num_locs
= bkpt_sp
->GetNumLocations();
479 void SBBreakpoint::SetCommandLineCommands(SBStringList
&commands
) {
480 LLDB_INSTRUMENT_VA(this, commands
);
482 BreakpointSP bkpt_sp
= GetSP();
485 if (commands
.GetSize() == 0)
488 std::lock_guard
<std::recursive_mutex
> guard(
489 bkpt_sp
->GetTarget().GetAPIMutex());
490 std::unique_ptr
<BreakpointOptions::CommandData
> cmd_data_up(
491 new BreakpointOptions::CommandData(*commands
, eScriptLanguageNone
));
493 bkpt_sp
->GetOptions().SetCommandDataCallback(cmd_data_up
);
496 bool SBBreakpoint::GetCommandLineCommands(SBStringList
&commands
) {
497 LLDB_INSTRUMENT_VA(this, commands
);
499 BreakpointSP bkpt_sp
= GetSP();
502 StringList command_list
;
504 bkpt_sp
->GetOptions().GetCommandLineCallbacks(command_list
);
506 commands
.AppendList(command_list
);
510 bool SBBreakpoint::GetDescription(SBStream
&s
) {
511 LLDB_INSTRUMENT_VA(this, s
);
513 return GetDescription(s
, true);
516 bool SBBreakpoint::GetDescription(SBStream
&s
, bool include_locations
) {
517 LLDB_INSTRUMENT_VA(this, s
, include_locations
);
519 BreakpointSP bkpt_sp
= GetSP();
521 std::lock_guard
<std::recursive_mutex
> guard(
522 bkpt_sp
->GetTarget().GetAPIMutex());
523 s
.Printf("SBBreakpoint: id = %i, ", bkpt_sp
->GetID());
524 bkpt_sp
->GetResolverDescription(s
.get());
525 bkpt_sp
->GetFilterDescription(s
.get());
526 if (include_locations
) {
527 const size_t num_locations
= bkpt_sp
->GetNumLocations();
528 s
.Printf(", locations = %" PRIu64
, (uint64_t)num_locations
);
532 s
.Printf("No value");
536 SBError
SBBreakpoint::AddLocation(SBAddress
&address
) {
537 LLDB_INSTRUMENT_VA(this, address
);
539 BreakpointSP bkpt_sp
= GetSP();
542 if (!address
.IsValid()) {
543 error
.SetErrorString("Can't add an invalid address.");
548 error
.SetErrorString("No breakpoint to add a location to.");
552 if (!llvm::isa
<BreakpointResolverScripted
>(bkpt_sp
->GetResolver().get())) {
553 error
.SetErrorString("Only a scripted resolver can add locations.");
557 if (bkpt_sp
->GetSearchFilter()->AddressPasses(address
.ref()))
558 bkpt_sp
->AddLocation(address
.ref());
561 address
.get()->Dump(&s
, &bkpt_sp
->GetTarget(),
562 Address::DumpStyleModuleWithFileAddress
);
563 error
.SetErrorStringWithFormat("Address: %s didn't pass the filter.",
569 SBStructuredData
SBBreakpoint::SerializeToStructuredData() {
570 LLDB_INSTRUMENT_VA(this);
572 SBStructuredData data
;
573 BreakpointSP bkpt_sp
= GetSP();
578 StructuredData::ObjectSP bkpt_dict
= bkpt_sp
->SerializeToStructuredData();
579 data
.m_impl_up
->SetObjectSP(bkpt_dict
);
583 void SBBreakpoint::SetCallback(SBBreakpointHitCallback callback
, void *baton
) {
584 LLDB_INSTRUMENT_VA(this, callback
, baton
);
586 BreakpointSP bkpt_sp
= GetSP();
589 std::lock_guard
<std::recursive_mutex
> guard(
590 bkpt_sp
->GetTarget().GetAPIMutex());
591 BatonSP
baton_sp(new SBBreakpointCallbackBaton(callback
, baton
));
592 bkpt_sp
->SetCallback(SBBreakpointCallbackBaton
593 ::PrivateBreakpointHitCallback
, baton_sp
,
598 void SBBreakpoint::SetScriptCallbackFunction(
599 const char *callback_function_name
) {
600 LLDB_INSTRUMENT_VA(this, callback_function_name
);
601 SBStructuredData empty_args
;
602 SetScriptCallbackFunction(callback_function_name
, empty_args
);
605 SBError
SBBreakpoint::SetScriptCallbackFunction(
606 const char *callback_function_name
,
607 SBStructuredData
&extra_args
) {
608 LLDB_INSTRUMENT_VA(this, callback_function_name
, extra_args
);
610 BreakpointSP bkpt_sp
= GetSP();
614 std::lock_guard
<std::recursive_mutex
> guard(
615 bkpt_sp
->GetTarget().GetAPIMutex());
616 BreakpointOptions
&bp_options
= bkpt_sp
->GetOptions();
617 error
= bkpt_sp
->GetTarget()
619 .GetScriptInterpreter()
620 ->SetBreakpointCommandCallbackFunction(bp_options
,
621 callback_function_name
,
624 sb_error
.SetError(error
);
626 sb_error
.SetErrorString("invalid breakpoint");
631 SBError
SBBreakpoint::SetScriptCallbackBody(const char *callback_body_text
) {
632 LLDB_INSTRUMENT_VA(this, callback_body_text
);
634 BreakpointSP bkpt_sp
= GetSP();
638 std::lock_guard
<std::recursive_mutex
> guard(
639 bkpt_sp
->GetTarget().GetAPIMutex());
640 BreakpointOptions
&bp_options
= bkpt_sp
->GetOptions();
644 .GetScriptInterpreter()
645 ->SetBreakpointCommandCallback(bp_options
, callback_body_text
,
646 /*is_callback=*/false);
647 sb_error
.SetError(error
);
649 sb_error
.SetErrorString("invalid breakpoint");
654 bool SBBreakpoint::AddName(const char *new_name
) {
655 LLDB_INSTRUMENT_VA(this, new_name
);
657 SBError status
= AddNameWithErrorHandling(new_name
);
658 return status
.Success();
661 SBError
SBBreakpoint::AddNameWithErrorHandling(const char *new_name
) {
662 LLDB_INSTRUMENT_VA(this, new_name
);
664 BreakpointSP bkpt_sp
= GetSP();
668 std::lock_guard
<std::recursive_mutex
> guard(
669 bkpt_sp
->GetTarget().GetAPIMutex());
671 bkpt_sp
->GetTarget().AddNameToBreakpoint(bkpt_sp
, new_name
, error
);
672 status
.SetError(error
);
674 status
.SetErrorString("invalid breakpoint");
680 void SBBreakpoint::RemoveName(const char *name_to_remove
) {
681 LLDB_INSTRUMENT_VA(this, name_to_remove
);
683 BreakpointSP bkpt_sp
= GetSP();
686 std::lock_guard
<std::recursive_mutex
> guard(
687 bkpt_sp
->GetTarget().GetAPIMutex());
688 bkpt_sp
->GetTarget().RemoveNameFromBreakpoint(bkpt_sp
,
689 ConstString(name_to_remove
));
693 bool SBBreakpoint::MatchesName(const char *name
) {
694 LLDB_INSTRUMENT_VA(this, name
);
696 BreakpointSP bkpt_sp
= GetSP();
699 std::lock_guard
<std::recursive_mutex
> guard(
700 bkpt_sp
->GetTarget().GetAPIMutex());
701 return bkpt_sp
->MatchesName(name
);
707 void SBBreakpoint::GetNames(SBStringList
&names
) {
708 LLDB_INSTRUMENT_VA(this, names
);
710 BreakpointSP bkpt_sp
= GetSP();
713 std::lock_guard
<std::recursive_mutex
> guard(
714 bkpt_sp
->GetTarget().GetAPIMutex());
715 std::vector
<std::string
> names_vec
;
716 bkpt_sp
->GetNames(names_vec
);
717 for (std::string name
: names_vec
) {
718 names
.AppendString(name
.c_str());
723 bool SBBreakpoint::EventIsBreakpointEvent(const lldb::SBEvent
&event
) {
724 LLDB_INSTRUMENT_VA(event
);
726 return Breakpoint::BreakpointEventData::GetEventDataFromEvent(event
.get()) !=
731 SBBreakpoint::GetBreakpointEventTypeFromEvent(const SBEvent
&event
) {
732 LLDB_INSTRUMENT_VA(event
);
735 return Breakpoint::BreakpointEventData::GetBreakpointEventTypeFromEvent(
737 return eBreakpointEventTypeInvalidType
;
740 SBBreakpoint
SBBreakpoint::GetBreakpointFromEvent(const lldb::SBEvent
&event
) {
741 LLDB_INSTRUMENT_VA(event
);
745 Breakpoint::BreakpointEventData::GetBreakpointFromEvent(event
.GetSP()));
746 return SBBreakpoint();
750 SBBreakpoint::GetBreakpointLocationAtIndexFromEvent(const lldb::SBEvent
&event
,
752 LLDB_INSTRUMENT_VA(event
, loc_idx
);
754 SBBreakpointLocation sb_breakpoint_loc
;
756 sb_breakpoint_loc
.SetLocation(
757 Breakpoint::BreakpointEventData::GetBreakpointLocationAtIndexFromEvent(
758 event
.GetSP(), loc_idx
));
759 return sb_breakpoint_loc
;
763 SBBreakpoint::GetNumBreakpointLocationsFromEvent(const lldb::SBEvent
&event
) {
764 LLDB_INSTRUMENT_VA(event
);
766 uint32_t num_locations
= 0;
769 (Breakpoint::BreakpointEventData::GetNumBreakpointLocationsFromEvent(
771 return num_locations
;
774 bool SBBreakpoint::IsHardware() const {
775 LLDB_INSTRUMENT_VA(this);
777 BreakpointSP bkpt_sp
= GetSP();
779 return bkpt_sp
->IsHardware();
783 BreakpointSP
SBBreakpoint::GetSP() const { return m_opaque_wp
.lock(); }
785 // This is simple collection of breakpoint id's and their target.
786 class SBBreakpointListImpl
{
788 SBBreakpointListImpl(lldb::TargetSP target_sp
) {
789 if (target_sp
&& target_sp
->IsValid())
790 m_target_wp
= target_sp
;
793 ~SBBreakpointListImpl() = default;
795 size_t GetSize() { return m_break_ids
.size(); }
797 BreakpointSP
GetBreakpointAtIndex(size_t idx
) {
798 if (idx
>= m_break_ids
.size())
799 return BreakpointSP();
800 TargetSP target_sp
= m_target_wp
.lock();
802 return BreakpointSP();
803 lldb::break_id_t bp_id
= m_break_ids
[idx
];
804 return target_sp
->GetBreakpointList().FindBreakpointByID(bp_id
);
807 BreakpointSP
FindBreakpointByID(lldb::break_id_t desired_id
) {
808 TargetSP target_sp
= m_target_wp
.lock();
810 return BreakpointSP();
812 for (lldb::break_id_t
&break_id
: m_break_ids
) {
813 if (break_id
== desired_id
)
814 return target_sp
->GetBreakpointList().FindBreakpointByID(break_id
);
816 return BreakpointSP();
819 bool Append(BreakpointSP bkpt
) {
820 TargetSP target_sp
= m_target_wp
.lock();
821 if (!target_sp
|| !bkpt
)
823 if (bkpt
->GetTargetSP() != target_sp
)
825 m_break_ids
.push_back(bkpt
->GetID());
829 bool AppendIfUnique(BreakpointSP bkpt
) {
830 TargetSP target_sp
= m_target_wp
.lock();
831 if (!target_sp
|| !bkpt
)
833 if (bkpt
->GetTargetSP() != target_sp
)
835 lldb::break_id_t bp_id
= bkpt
->GetID();
836 if (!llvm::is_contained(m_break_ids
, bp_id
))
839 m_break_ids
.push_back(bkpt
->GetID());
843 bool AppendByID(lldb::break_id_t id
) {
844 TargetSP target_sp
= m_target_wp
.lock();
847 if (id
== LLDB_INVALID_BREAK_ID
)
849 m_break_ids
.push_back(id
);
853 void Clear() { m_break_ids
.clear(); }
855 void CopyToBreakpointIDList(lldb_private::BreakpointIDList
&bp_list
) {
856 for (lldb::break_id_t id
: m_break_ids
) {
857 bp_list
.AddBreakpointID(BreakpointID(id
));
861 TargetSP
GetTarget() { return m_target_wp
.lock(); }
864 std::vector
<lldb::break_id_t
> m_break_ids
;
865 TargetWP m_target_wp
;
868 SBBreakpointList::SBBreakpointList(SBTarget
&target
)
869 : m_opaque_sp(new SBBreakpointListImpl(target
.GetSP())) {
870 LLDB_INSTRUMENT_VA(this, target
);
873 SBBreakpointList::~SBBreakpointList() = default;
875 size_t SBBreakpointList::GetSize() const {
876 LLDB_INSTRUMENT_VA(this);
881 return m_opaque_sp
->GetSize();
884 SBBreakpoint
SBBreakpointList::GetBreakpointAtIndex(size_t idx
) {
885 LLDB_INSTRUMENT_VA(this, idx
);
888 return SBBreakpoint();
890 BreakpointSP bkpt_sp
= m_opaque_sp
->GetBreakpointAtIndex(idx
);
891 return SBBreakpoint(bkpt_sp
);
894 SBBreakpoint
SBBreakpointList::FindBreakpointByID(lldb::break_id_t id
) {
895 LLDB_INSTRUMENT_VA(this, id
);
898 return SBBreakpoint();
899 BreakpointSP bkpt_sp
= m_opaque_sp
->FindBreakpointByID(id
);
900 return SBBreakpoint(bkpt_sp
);
903 void SBBreakpointList::Append(const SBBreakpoint
&sb_bkpt
) {
904 LLDB_INSTRUMENT_VA(this, sb_bkpt
);
906 if (!sb_bkpt
.IsValid())
910 m_opaque_sp
->Append(sb_bkpt
.m_opaque_wp
.lock());
913 void SBBreakpointList::AppendByID(lldb::break_id_t id
) {
914 LLDB_INSTRUMENT_VA(this, id
);
918 m_opaque_sp
->AppendByID(id
);
921 bool SBBreakpointList::AppendIfUnique(const SBBreakpoint
&sb_bkpt
) {
922 LLDB_INSTRUMENT_VA(this, sb_bkpt
);
924 if (!sb_bkpt
.IsValid())
928 return m_opaque_sp
->AppendIfUnique(sb_bkpt
.GetSP());
931 void SBBreakpointList::Clear() {
932 LLDB_INSTRUMENT_VA(this);
935 m_opaque_sp
->Clear();
938 void SBBreakpointList::CopyToBreakpointIDList(
939 lldb_private::BreakpointIDList
&bp_id_list
) {
941 m_opaque_sp
->CopyToBreakpointIDList(bp_id_list
);