1 //===-- SBBreakpointName.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/SBBreakpointName.h"
10 #include "lldb/API/SBDebugger.h"
11 #include "lldb/API/SBError.h"
12 #include "lldb/API/SBStream.h"
13 #include "lldb/API/SBStringList.h"
14 #include "lldb/API/SBStructuredData.h"
15 #include "lldb/API/SBTarget.h"
16 #include "lldb/Utility/Instrumentation.h"
18 #include "lldb/Breakpoint/BreakpointName.h"
19 #include "lldb/Breakpoint/StoppointCallbackContext.h"
20 #include "lldb/Core/Debugger.h"
21 #include "lldb/Core/StructuredDataImpl.h"
22 #include "lldb/Interpreter/CommandInterpreter.h"
23 #include "lldb/Interpreter/ScriptInterpreter.h"
24 #include "lldb/Target/Target.h"
25 #include "lldb/Target/ThreadSpec.h"
26 #include "lldb/Utility/Stream.h"
28 #include "SBBreakpointOptionCommon.h"
31 using namespace lldb_private
;
35 class SBBreakpointNameImpl
{
37 SBBreakpointNameImpl(TargetSP target_sp
, const char *name
) {
38 if (!name
|| name
[0] == '\0')
45 m_target_wp
= target_sp
;
48 SBBreakpointNameImpl(SBTarget
&sb_target
, const char *name
);
49 bool operator==(const SBBreakpointNameImpl
&rhs
);
50 bool operator!=(const SBBreakpointNameImpl
&rhs
);
52 // For now we take a simple approach and only keep the name, and relook up
53 // the location when we need it.
55 TargetSP
GetTarget() const {
56 return m_target_wp
.lock();
59 const char *GetName() const {
60 return m_name
.c_str();
63 bool IsValid() const {
64 return !m_name
.empty() && m_target_wp
.lock();
67 lldb_private::BreakpointName
*GetBreakpointName() const;
74 SBBreakpointNameImpl::SBBreakpointNameImpl(SBTarget
&sb_target
,
76 if (!name
|| name
[0] == '\0')
80 if (!sb_target
.IsValid())
83 TargetSP target_sp
= sb_target
.GetSP();
87 m_target_wp
= target_sp
;
90 bool SBBreakpointNameImpl::operator==(const SBBreakpointNameImpl
&rhs
) {
91 return m_name
== rhs
.m_name
&& m_target_wp
.lock() == rhs
.m_target_wp
.lock();
94 bool SBBreakpointNameImpl::operator!=(const SBBreakpointNameImpl
&rhs
) {
95 return m_name
!= rhs
.m_name
|| m_target_wp
.lock() != rhs
.m_target_wp
.lock();
98 lldb_private::BreakpointName
*SBBreakpointNameImpl::GetBreakpointName() const {
101 TargetSP target_sp
= GetTarget();
105 return target_sp
->FindBreakpointName(ConstString(m_name
), true, error
);
110 SBBreakpointName::SBBreakpointName() { LLDB_INSTRUMENT_VA(this); }
112 SBBreakpointName::SBBreakpointName(SBTarget
&sb_target
, const char *name
) {
113 LLDB_INSTRUMENT_VA(this, sb_target
, name
);
115 m_impl_up
= std::make_unique
<SBBreakpointNameImpl
>(sb_target
, name
);
116 // Call FindBreakpointName here to make sure the name is valid, reset if not:
117 BreakpointName
*bp_name
= GetBreakpointName();
122 SBBreakpointName::SBBreakpointName(SBBreakpoint
&sb_bkpt
, const char *name
) {
123 LLDB_INSTRUMENT_VA(this, sb_bkpt
, name
);
125 if (!sb_bkpt
.IsValid()) {
129 BreakpointSP bkpt_sp
= sb_bkpt
.GetSP();
130 Target
&target
= bkpt_sp
->GetTarget();
133 std::make_unique
<SBBreakpointNameImpl
>(target
.shared_from_this(), name
);
135 // Call FindBreakpointName here to make sure the name is valid, reset if not:
136 BreakpointName
*bp_name
= GetBreakpointName();
142 // Now copy over the breakpoint's options:
143 target
.ConfigureBreakpointName(*bp_name
, bkpt_sp
->GetOptions(),
144 BreakpointName::Permissions());
147 SBBreakpointName::SBBreakpointName(const SBBreakpointName
&rhs
) {
148 LLDB_INSTRUMENT_VA(this, rhs
);
153 m_impl_up
= std::make_unique
<SBBreakpointNameImpl
>(
154 rhs
.m_impl_up
->GetTarget(), rhs
.m_impl_up
->GetName());
157 SBBreakpointName::~SBBreakpointName() = default;
159 const SBBreakpointName
&SBBreakpointName::
160 operator=(const SBBreakpointName
&rhs
) {
161 LLDB_INSTRUMENT_VA(this, rhs
);
163 if (!rhs
.m_impl_up
) {
168 m_impl_up
= std::make_unique
<SBBreakpointNameImpl
>(rhs
.m_impl_up
->GetTarget(),
169 rhs
.m_impl_up
->GetName());
173 bool SBBreakpointName::operator==(const lldb::SBBreakpointName
&rhs
) {
174 LLDB_INSTRUMENT_VA(this, rhs
);
176 return *m_impl_up
== *rhs
.m_impl_up
;
179 bool SBBreakpointName::operator!=(const lldb::SBBreakpointName
&rhs
) {
180 LLDB_INSTRUMENT_VA(this, rhs
);
182 return *m_impl_up
!= *rhs
.m_impl_up
;
185 bool SBBreakpointName::IsValid() const {
186 LLDB_INSTRUMENT_VA(this);
187 return this->operator bool();
189 SBBreakpointName::operator bool() const {
190 LLDB_INSTRUMENT_VA(this);
194 return m_impl_up
->IsValid();
197 const char *SBBreakpointName::GetName() const {
198 LLDB_INSTRUMENT_VA(this);
201 return "<Invalid Breakpoint Name Object>";
202 return ConstString(m_impl_up
->GetName()).GetCString();
205 void SBBreakpointName::SetEnabled(bool enable
) {
206 LLDB_INSTRUMENT_VA(this, enable
);
208 BreakpointName
*bp_name
= GetBreakpointName();
212 std::lock_guard
<std::recursive_mutex
> guard(
213 m_impl_up
->GetTarget()->GetAPIMutex());
215 bp_name
->GetOptions().SetEnabled(enable
);
218 void SBBreakpointName::UpdateName(BreakpointName
&bp_name
) {
222 TargetSP target_sp
= m_impl_up
->GetTarget();
225 target_sp
->ApplyNameToBreakpoints(bp_name
);
229 bool SBBreakpointName::IsEnabled() {
230 LLDB_INSTRUMENT_VA(this);
232 BreakpointName
*bp_name
= GetBreakpointName();
236 std::lock_guard
<std::recursive_mutex
> guard(
237 m_impl_up
->GetTarget()->GetAPIMutex());
239 return bp_name
->GetOptions().IsEnabled();
242 void SBBreakpointName::SetOneShot(bool one_shot
) {
243 LLDB_INSTRUMENT_VA(this, one_shot
);
245 BreakpointName
*bp_name
= GetBreakpointName();
249 std::lock_guard
<std::recursive_mutex
> guard(
250 m_impl_up
->GetTarget()->GetAPIMutex());
252 bp_name
->GetOptions().SetOneShot(one_shot
);
253 UpdateName(*bp_name
);
256 bool SBBreakpointName::IsOneShot() const {
257 LLDB_INSTRUMENT_VA(this);
259 const BreakpointName
*bp_name
= GetBreakpointName();
263 std::lock_guard
<std::recursive_mutex
> guard(
264 m_impl_up
->GetTarget()->GetAPIMutex());
266 return bp_name
->GetOptions().IsOneShot();
269 void SBBreakpointName::SetIgnoreCount(uint32_t count
) {
270 LLDB_INSTRUMENT_VA(this, count
);
272 BreakpointName
*bp_name
= GetBreakpointName();
276 std::lock_guard
<std::recursive_mutex
> guard(
277 m_impl_up
->GetTarget()->GetAPIMutex());
279 bp_name
->GetOptions().SetIgnoreCount(count
);
280 UpdateName(*bp_name
);
283 uint32_t SBBreakpointName::GetIgnoreCount() const {
284 LLDB_INSTRUMENT_VA(this);
286 BreakpointName
*bp_name
= GetBreakpointName();
290 std::lock_guard
<std::recursive_mutex
> guard(
291 m_impl_up
->GetTarget()->GetAPIMutex());
293 return bp_name
->GetOptions().GetIgnoreCount();
296 void SBBreakpointName::SetCondition(const char *condition
) {
297 LLDB_INSTRUMENT_VA(this, condition
);
299 BreakpointName
*bp_name
= GetBreakpointName();
303 std::lock_guard
<std::recursive_mutex
> guard(
304 m_impl_up
->GetTarget()->GetAPIMutex());
306 bp_name
->GetOptions().SetCondition(condition
);
307 UpdateName(*bp_name
);
310 const char *SBBreakpointName::GetCondition() {
311 LLDB_INSTRUMENT_VA(this);
313 BreakpointName
*bp_name
= GetBreakpointName();
317 std::lock_guard
<std::recursive_mutex
> guard(
318 m_impl_up
->GetTarget()->GetAPIMutex());
320 return ConstString(bp_name
->GetOptions().GetConditionText()).GetCString();
323 void SBBreakpointName::SetAutoContinue(bool auto_continue
) {
324 LLDB_INSTRUMENT_VA(this, auto_continue
);
326 BreakpointName
*bp_name
= GetBreakpointName();
330 std::lock_guard
<std::recursive_mutex
> guard(
331 m_impl_up
->GetTarget()->GetAPIMutex());
333 bp_name
->GetOptions().SetAutoContinue(auto_continue
);
334 UpdateName(*bp_name
);
337 bool SBBreakpointName::GetAutoContinue() {
338 LLDB_INSTRUMENT_VA(this);
340 BreakpointName
*bp_name
= GetBreakpointName();
344 std::lock_guard
<std::recursive_mutex
> guard(
345 m_impl_up
->GetTarget()->GetAPIMutex());
347 return bp_name
->GetOptions().IsAutoContinue();
350 void SBBreakpointName::SetThreadID(lldb::tid_t tid
) {
351 LLDB_INSTRUMENT_VA(this, tid
);
353 BreakpointName
*bp_name
= GetBreakpointName();
357 std::lock_guard
<std::recursive_mutex
> guard(
358 m_impl_up
->GetTarget()->GetAPIMutex());
360 bp_name
->GetOptions().SetThreadID(tid
);
361 UpdateName(*bp_name
);
364 lldb::tid_t
SBBreakpointName::GetThreadID() {
365 LLDB_INSTRUMENT_VA(this);
367 BreakpointName
*bp_name
= GetBreakpointName();
369 return LLDB_INVALID_THREAD_ID
;
371 std::lock_guard
<std::recursive_mutex
> guard(
372 m_impl_up
->GetTarget()->GetAPIMutex());
374 return bp_name
->GetOptions().GetThreadSpec()->GetTID();
377 void SBBreakpointName::SetThreadIndex(uint32_t index
) {
378 LLDB_INSTRUMENT_VA(this, index
);
380 BreakpointName
*bp_name
= GetBreakpointName();
384 std::lock_guard
<std::recursive_mutex
> guard(
385 m_impl_up
->GetTarget()->GetAPIMutex());
387 bp_name
->GetOptions().GetThreadSpec()->SetIndex(index
);
388 UpdateName(*bp_name
);
391 uint32_t SBBreakpointName::GetThreadIndex() const {
392 LLDB_INSTRUMENT_VA(this);
394 BreakpointName
*bp_name
= GetBreakpointName();
396 return LLDB_INVALID_THREAD_ID
;
398 std::lock_guard
<std::recursive_mutex
> guard(
399 m_impl_up
->GetTarget()->GetAPIMutex());
401 return bp_name
->GetOptions().GetThreadSpec()->GetIndex();
404 void SBBreakpointName::SetThreadName(const char *thread_name
) {
405 LLDB_INSTRUMENT_VA(this, thread_name
);
407 BreakpointName
*bp_name
= GetBreakpointName();
411 std::lock_guard
<std::recursive_mutex
> guard(
412 m_impl_up
->GetTarget()->GetAPIMutex());
414 bp_name
->GetOptions().GetThreadSpec()->SetName(thread_name
);
415 UpdateName(*bp_name
);
418 const char *SBBreakpointName::GetThreadName() const {
419 LLDB_INSTRUMENT_VA(this);
421 BreakpointName
*bp_name
= GetBreakpointName();
425 std::lock_guard
<std::recursive_mutex
> guard(
426 m_impl_up
->GetTarget()->GetAPIMutex());
428 return ConstString(bp_name
->GetOptions().GetThreadSpec()->GetName())
432 void SBBreakpointName::SetQueueName(const char *queue_name
) {
433 LLDB_INSTRUMENT_VA(this, queue_name
);
435 BreakpointName
*bp_name
= GetBreakpointName();
439 std::lock_guard
<std::recursive_mutex
> guard(
440 m_impl_up
->GetTarget()->GetAPIMutex());
442 bp_name
->GetOptions().GetThreadSpec()->SetQueueName(queue_name
);
443 UpdateName(*bp_name
);
446 const char *SBBreakpointName::GetQueueName() const {
447 LLDB_INSTRUMENT_VA(this);
449 BreakpointName
*bp_name
= GetBreakpointName();
453 std::lock_guard
<std::recursive_mutex
> guard(
454 m_impl_up
->GetTarget()->GetAPIMutex());
456 return ConstString(bp_name
->GetOptions().GetThreadSpec()->GetQueueName())
460 void SBBreakpointName::SetCommandLineCommands(SBStringList
&commands
) {
461 LLDB_INSTRUMENT_VA(this, commands
);
463 BreakpointName
*bp_name
= GetBreakpointName();
466 if (commands
.GetSize() == 0)
470 std::lock_guard
<std::recursive_mutex
> guard(
471 m_impl_up
->GetTarget()->GetAPIMutex());
472 std::unique_ptr
<BreakpointOptions::CommandData
> cmd_data_up(
473 new BreakpointOptions::CommandData(*commands
, eScriptLanguageNone
));
475 bp_name
->GetOptions().SetCommandDataCallback(cmd_data_up
);
476 UpdateName(*bp_name
);
479 bool SBBreakpointName::GetCommandLineCommands(SBStringList
&commands
) {
480 LLDB_INSTRUMENT_VA(this, commands
);
482 BreakpointName
*bp_name
= GetBreakpointName();
486 StringList command_list
;
488 bp_name
->GetOptions().GetCommandLineCallbacks(command_list
);
490 commands
.AppendList(command_list
);
494 const char *SBBreakpointName::GetHelpString() const {
495 LLDB_INSTRUMENT_VA(this);
497 BreakpointName
*bp_name
= GetBreakpointName();
501 return ConstString(bp_name
->GetHelp()).GetCString();
504 void SBBreakpointName::SetHelpString(const char *help_string
) {
505 LLDB_INSTRUMENT_VA(this, help_string
);
507 BreakpointName
*bp_name
= GetBreakpointName();
512 std::lock_guard
<std::recursive_mutex
> guard(
513 m_impl_up
->GetTarget()->GetAPIMutex());
514 bp_name
->SetHelp(help_string
);
517 bool SBBreakpointName::GetDescription(SBStream
&s
) {
518 LLDB_INSTRUMENT_VA(this, s
);
520 BreakpointName
*bp_name
= GetBreakpointName();
523 s
.Printf("No value");
527 std::lock_guard
<std::recursive_mutex
> guard(
528 m_impl_up
->GetTarget()->GetAPIMutex());
529 bp_name
->GetDescription(s
.get(), eDescriptionLevelFull
);
533 void SBBreakpointName::SetCallback(SBBreakpointHitCallback callback
,
535 LLDB_INSTRUMENT_VA(this, callback
, baton
);
537 BreakpointName
*bp_name
= GetBreakpointName();
540 std::lock_guard
<std::recursive_mutex
> guard(
541 m_impl_up
->GetTarget()->GetAPIMutex());
543 BatonSP
baton_sp(new SBBreakpointCallbackBaton(callback
, baton
));
544 bp_name
->GetOptions().SetCallback(SBBreakpointCallbackBaton
545 ::PrivateBreakpointHitCallback
,
548 UpdateName(*bp_name
);
551 void SBBreakpointName::SetScriptCallbackFunction(
552 const char *callback_function_name
) {
553 LLDB_INSTRUMENT_VA(this, callback_function_name
);
554 SBStructuredData empty_args
;
555 SetScriptCallbackFunction(callback_function_name
, empty_args
);
558 SBError
SBBreakpointName::SetScriptCallbackFunction(
559 const char *callback_function_name
,
560 SBStructuredData
&extra_args
) {
561 LLDB_INSTRUMENT_VA(this, callback_function_name
, extra_args
);
563 BreakpointName
*bp_name
= GetBreakpointName();
565 sb_error
= Status::FromErrorString("unrecognized breakpoint name");
569 std::lock_guard
<std::recursive_mutex
> guard(
570 m_impl_up
->GetTarget()->GetAPIMutex());
572 BreakpointOptions
&bp_options
= bp_name
->GetOptions();
573 Status error
= m_impl_up
->GetTarget()
575 .GetScriptInterpreter()
576 ->SetBreakpointCommandCallbackFunction(
577 bp_options
, callback_function_name
,
578 extra_args
.m_impl_up
->GetObjectSP());
579 sb_error
.SetError(std::move(error
));
580 UpdateName(*bp_name
);
585 SBBreakpointName::SetScriptCallbackBody(const char *callback_body_text
) {
586 LLDB_INSTRUMENT_VA(this, callback_body_text
);
589 BreakpointName
*bp_name
= GetBreakpointName();
593 std::lock_guard
<std::recursive_mutex
> guard(
594 m_impl_up
->GetTarget()->GetAPIMutex());
596 BreakpointOptions
&bp_options
= bp_name
->GetOptions();
597 Status error
= m_impl_up
->GetTarget()
599 .GetScriptInterpreter()
600 ->SetBreakpointCommandCallback(
601 bp_options
, callback_body_text
, /*is_callback=*/false);
602 sb_error
.SetError(std::move(error
));
603 if (!sb_error
.Fail())
604 UpdateName(*bp_name
);
609 bool SBBreakpointName::GetAllowList() const {
610 LLDB_INSTRUMENT_VA(this);
612 BreakpointName
*bp_name
= GetBreakpointName();
615 return bp_name
->GetPermissions().GetAllowList();
618 void SBBreakpointName::SetAllowList(bool value
) {
619 LLDB_INSTRUMENT_VA(this, value
);
621 BreakpointName
*bp_name
= GetBreakpointName();
624 bp_name
->GetPermissions().SetAllowList(value
);
627 bool SBBreakpointName::GetAllowDelete() {
628 LLDB_INSTRUMENT_VA(this);
630 BreakpointName
*bp_name
= GetBreakpointName();
633 return bp_name
->GetPermissions().GetAllowDelete();
636 void SBBreakpointName::SetAllowDelete(bool value
) {
637 LLDB_INSTRUMENT_VA(this, value
);
639 BreakpointName
*bp_name
= GetBreakpointName();
642 bp_name
->GetPermissions().SetAllowDelete(value
);
645 bool SBBreakpointName::GetAllowDisable() {
646 LLDB_INSTRUMENT_VA(this);
648 BreakpointName
*bp_name
= GetBreakpointName();
651 return bp_name
->GetPermissions().GetAllowDisable();
654 void SBBreakpointName::SetAllowDisable(bool value
) {
655 LLDB_INSTRUMENT_VA(this, value
);
657 BreakpointName
*bp_name
= GetBreakpointName();
660 bp_name
->GetPermissions().SetAllowDisable(value
);
663 lldb_private::BreakpointName
*SBBreakpointName::GetBreakpointName() const
667 return m_impl_up
->GetBreakpointName();