Book a Demo!
CoCalc Logo Icon
StoreFeaturesDocsShareSupportNewsAboutPoliciesSign UpSign In
freebsd
GitHub Repository: freebsd/freebsd-src
Path: blob/main/contrib/llvm-project/lldb/source/API/SBBreakpointName.cpp
39587 views
1
//===-- SBBreakpointName.cpp ----------------------------------------------===//
2
//
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
6
//
7
//===----------------------------------------------------------------------===//
8
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"
17
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"
27
28
#include "SBBreakpointOptionCommon.h"
29
30
using namespace lldb;
31
using namespace lldb_private;
32
33
namespace lldb
34
{
35
class SBBreakpointNameImpl {
36
public:
37
SBBreakpointNameImpl(TargetSP target_sp, const char *name) {
38
if (!name || name[0] == '\0')
39
return;
40
m_name.assign(name);
41
42
if (!target_sp)
43
return;
44
45
m_target_wp = target_sp;
46
}
47
48
SBBreakpointNameImpl(SBTarget &sb_target, const char *name);
49
bool operator==(const SBBreakpointNameImpl &rhs);
50
bool operator!=(const SBBreakpointNameImpl &rhs);
51
52
// For now we take a simple approach and only keep the name, and relook up
53
// the location when we need it.
54
55
TargetSP GetTarget() const {
56
return m_target_wp.lock();
57
}
58
59
const char *GetName() const {
60
return m_name.c_str();
61
}
62
63
bool IsValid() const {
64
return !m_name.empty() && m_target_wp.lock();
65
}
66
67
lldb_private::BreakpointName *GetBreakpointName() const;
68
69
private:
70
TargetWP m_target_wp;
71
std::string m_name;
72
};
73
74
SBBreakpointNameImpl::SBBreakpointNameImpl(SBTarget &sb_target,
75
const char *name) {
76
if (!name || name[0] == '\0')
77
return;
78
m_name.assign(name);
79
80
if (!sb_target.IsValid())
81
return;
82
83
TargetSP target_sp = sb_target.GetSP();
84
if (!target_sp)
85
return;
86
87
m_target_wp = target_sp;
88
}
89
90
bool SBBreakpointNameImpl::operator==(const SBBreakpointNameImpl &rhs) {
91
return m_name == rhs.m_name && m_target_wp.lock() == rhs.m_target_wp.lock();
92
}
93
94
bool SBBreakpointNameImpl::operator!=(const SBBreakpointNameImpl &rhs) {
95
return m_name != rhs.m_name || m_target_wp.lock() != rhs.m_target_wp.lock();
96
}
97
98
lldb_private::BreakpointName *SBBreakpointNameImpl::GetBreakpointName() const {
99
if (!IsValid())
100
return nullptr;
101
TargetSP target_sp = GetTarget();
102
if (!target_sp)
103
return nullptr;
104
Status error;
105
return target_sp->FindBreakpointName(ConstString(m_name), true, error);
106
}
107
108
} // namespace lldb
109
110
SBBreakpointName::SBBreakpointName() { LLDB_INSTRUMENT_VA(this); }
111
112
SBBreakpointName::SBBreakpointName(SBTarget &sb_target, const char *name) {
113
LLDB_INSTRUMENT_VA(this, sb_target, name);
114
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();
118
if (!bp_name)
119
m_impl_up.reset();
120
}
121
122
SBBreakpointName::SBBreakpointName(SBBreakpoint &sb_bkpt, const char *name) {
123
LLDB_INSTRUMENT_VA(this, sb_bkpt, name);
124
125
if (!sb_bkpt.IsValid()) {
126
m_impl_up.reset();
127
return;
128
}
129
BreakpointSP bkpt_sp = sb_bkpt.GetSP();
130
Target &target = bkpt_sp->GetTarget();
131
132
m_impl_up =
133
std::make_unique<SBBreakpointNameImpl>(target.shared_from_this(), name);
134
135
// Call FindBreakpointName here to make sure the name is valid, reset if not:
136
BreakpointName *bp_name = GetBreakpointName();
137
if (!bp_name) {
138
m_impl_up.reset();
139
return;
140
}
141
142
// Now copy over the breakpoint's options:
143
target.ConfigureBreakpointName(*bp_name, bkpt_sp->GetOptions(),
144
BreakpointName::Permissions());
145
}
146
147
SBBreakpointName::SBBreakpointName(const SBBreakpointName &rhs) {
148
LLDB_INSTRUMENT_VA(this, rhs);
149
150
if (!rhs.m_impl_up)
151
return;
152
else
153
m_impl_up = std::make_unique<SBBreakpointNameImpl>(
154
rhs.m_impl_up->GetTarget(), rhs.m_impl_up->GetName());
155
}
156
157
SBBreakpointName::~SBBreakpointName() = default;
158
159
const SBBreakpointName &SBBreakpointName::
160
operator=(const SBBreakpointName &rhs) {
161
LLDB_INSTRUMENT_VA(this, rhs);
162
163
if (!rhs.m_impl_up) {
164
m_impl_up.reset();
165
return *this;
166
}
167
168
m_impl_up = std::make_unique<SBBreakpointNameImpl>(rhs.m_impl_up->GetTarget(),
169
rhs.m_impl_up->GetName());
170
return *this;
171
}
172
173
bool SBBreakpointName::operator==(const lldb::SBBreakpointName &rhs) {
174
LLDB_INSTRUMENT_VA(this, rhs);
175
176
return *m_impl_up == *rhs.m_impl_up;
177
}
178
179
bool SBBreakpointName::operator!=(const lldb::SBBreakpointName &rhs) {
180
LLDB_INSTRUMENT_VA(this, rhs);
181
182
return *m_impl_up != *rhs.m_impl_up;
183
}
184
185
bool SBBreakpointName::IsValid() const {
186
LLDB_INSTRUMENT_VA(this);
187
return this->operator bool();
188
}
189
SBBreakpointName::operator bool() const {
190
LLDB_INSTRUMENT_VA(this);
191
192
if (!m_impl_up)
193
return false;
194
return m_impl_up->IsValid();
195
}
196
197
const char *SBBreakpointName::GetName() const {
198
LLDB_INSTRUMENT_VA(this);
199
200
if (!m_impl_up)
201
return "<Invalid Breakpoint Name Object>";
202
return ConstString(m_impl_up->GetName()).GetCString();
203
}
204
205
void SBBreakpointName::SetEnabled(bool enable) {
206
LLDB_INSTRUMENT_VA(this, enable);
207
208
BreakpointName *bp_name = GetBreakpointName();
209
if (!bp_name)
210
return;
211
212
std::lock_guard<std::recursive_mutex> guard(
213
m_impl_up->GetTarget()->GetAPIMutex());
214
215
bp_name->GetOptions().SetEnabled(enable);
216
}
217
218
void SBBreakpointName::UpdateName(BreakpointName &bp_name) {
219
if (!IsValid())
220
return;
221
222
TargetSP target_sp = m_impl_up->GetTarget();
223
if (!target_sp)
224
return;
225
target_sp->ApplyNameToBreakpoints(bp_name);
226
227
}
228
229
bool SBBreakpointName::IsEnabled() {
230
LLDB_INSTRUMENT_VA(this);
231
232
BreakpointName *bp_name = GetBreakpointName();
233
if (!bp_name)
234
return false;
235
236
std::lock_guard<std::recursive_mutex> guard(
237
m_impl_up->GetTarget()->GetAPIMutex());
238
239
return bp_name->GetOptions().IsEnabled();
240
}
241
242
void SBBreakpointName::SetOneShot(bool one_shot) {
243
LLDB_INSTRUMENT_VA(this, one_shot);
244
245
BreakpointName *bp_name = GetBreakpointName();
246
if (!bp_name)
247
return;
248
249
std::lock_guard<std::recursive_mutex> guard(
250
m_impl_up->GetTarget()->GetAPIMutex());
251
252
bp_name->GetOptions().SetOneShot(one_shot);
253
UpdateName(*bp_name);
254
}
255
256
bool SBBreakpointName::IsOneShot() const {
257
LLDB_INSTRUMENT_VA(this);
258
259
const BreakpointName *bp_name = GetBreakpointName();
260
if (!bp_name)
261
return false;
262
263
std::lock_guard<std::recursive_mutex> guard(
264
m_impl_up->GetTarget()->GetAPIMutex());
265
266
return bp_name->GetOptions().IsOneShot();
267
}
268
269
void SBBreakpointName::SetIgnoreCount(uint32_t count) {
270
LLDB_INSTRUMENT_VA(this, count);
271
272
BreakpointName *bp_name = GetBreakpointName();
273
if (!bp_name)
274
return;
275
276
std::lock_guard<std::recursive_mutex> guard(
277
m_impl_up->GetTarget()->GetAPIMutex());
278
279
bp_name->GetOptions().SetIgnoreCount(count);
280
UpdateName(*bp_name);
281
}
282
283
uint32_t SBBreakpointName::GetIgnoreCount() const {
284
LLDB_INSTRUMENT_VA(this);
285
286
BreakpointName *bp_name = GetBreakpointName();
287
if (!bp_name)
288
return false;
289
290
std::lock_guard<std::recursive_mutex> guard(
291
m_impl_up->GetTarget()->GetAPIMutex());
292
293
return bp_name->GetOptions().GetIgnoreCount();
294
}
295
296
void SBBreakpointName::SetCondition(const char *condition) {
297
LLDB_INSTRUMENT_VA(this, condition);
298
299
BreakpointName *bp_name = GetBreakpointName();
300
if (!bp_name)
301
return;
302
303
std::lock_guard<std::recursive_mutex> guard(
304
m_impl_up->GetTarget()->GetAPIMutex());
305
306
bp_name->GetOptions().SetCondition(condition);
307
UpdateName(*bp_name);
308
}
309
310
const char *SBBreakpointName::GetCondition() {
311
LLDB_INSTRUMENT_VA(this);
312
313
BreakpointName *bp_name = GetBreakpointName();
314
if (!bp_name)
315
return nullptr;
316
317
std::lock_guard<std::recursive_mutex> guard(
318
m_impl_up->GetTarget()->GetAPIMutex());
319
320
return ConstString(bp_name->GetOptions().GetConditionText()).GetCString();
321
}
322
323
void SBBreakpointName::SetAutoContinue(bool auto_continue) {
324
LLDB_INSTRUMENT_VA(this, auto_continue);
325
326
BreakpointName *bp_name = GetBreakpointName();
327
if (!bp_name)
328
return;
329
330
std::lock_guard<std::recursive_mutex> guard(
331
m_impl_up->GetTarget()->GetAPIMutex());
332
333
bp_name->GetOptions().SetAutoContinue(auto_continue);
334
UpdateName(*bp_name);
335
}
336
337
bool SBBreakpointName::GetAutoContinue() {
338
LLDB_INSTRUMENT_VA(this);
339
340
BreakpointName *bp_name = GetBreakpointName();
341
if (!bp_name)
342
return false;
343
344
std::lock_guard<std::recursive_mutex> guard(
345
m_impl_up->GetTarget()->GetAPIMutex());
346
347
return bp_name->GetOptions().IsAutoContinue();
348
}
349
350
void SBBreakpointName::SetThreadID(tid_t tid) {
351
LLDB_INSTRUMENT_VA(this, tid);
352
353
BreakpointName *bp_name = GetBreakpointName();
354
if (!bp_name)
355
return;
356
357
std::lock_guard<std::recursive_mutex> guard(
358
m_impl_up->GetTarget()->GetAPIMutex());
359
360
bp_name->GetOptions().SetThreadID(tid);
361
UpdateName(*bp_name);
362
}
363
364
tid_t SBBreakpointName::GetThreadID() {
365
LLDB_INSTRUMENT_VA(this);
366
367
BreakpointName *bp_name = GetBreakpointName();
368
if (!bp_name)
369
return LLDB_INVALID_THREAD_ID;
370
371
std::lock_guard<std::recursive_mutex> guard(
372
m_impl_up->GetTarget()->GetAPIMutex());
373
374
return bp_name->GetOptions().GetThreadSpec()->GetTID();
375
}
376
377
void SBBreakpointName::SetThreadIndex(uint32_t index) {
378
LLDB_INSTRUMENT_VA(this, index);
379
380
BreakpointName *bp_name = GetBreakpointName();
381
if (!bp_name)
382
return;
383
384
std::lock_guard<std::recursive_mutex> guard(
385
m_impl_up->GetTarget()->GetAPIMutex());
386
387
bp_name->GetOptions().GetThreadSpec()->SetIndex(index);
388
UpdateName(*bp_name);
389
}
390
391
uint32_t SBBreakpointName::GetThreadIndex() const {
392
LLDB_INSTRUMENT_VA(this);
393
394
BreakpointName *bp_name = GetBreakpointName();
395
if (!bp_name)
396
return LLDB_INVALID_THREAD_ID;
397
398
std::lock_guard<std::recursive_mutex> guard(
399
m_impl_up->GetTarget()->GetAPIMutex());
400
401
return bp_name->GetOptions().GetThreadSpec()->GetIndex();
402
}
403
404
void SBBreakpointName::SetThreadName(const char *thread_name) {
405
LLDB_INSTRUMENT_VA(this, thread_name);
406
407
BreakpointName *bp_name = GetBreakpointName();
408
if (!bp_name)
409
return;
410
411
std::lock_guard<std::recursive_mutex> guard(
412
m_impl_up->GetTarget()->GetAPIMutex());
413
414
bp_name->GetOptions().GetThreadSpec()->SetName(thread_name);
415
UpdateName(*bp_name);
416
}
417
418
const char *SBBreakpointName::GetThreadName() const {
419
LLDB_INSTRUMENT_VA(this);
420
421
BreakpointName *bp_name = GetBreakpointName();
422
if (!bp_name)
423
return nullptr;
424
425
std::lock_guard<std::recursive_mutex> guard(
426
m_impl_up->GetTarget()->GetAPIMutex());
427
428
return ConstString(bp_name->GetOptions().GetThreadSpec()->GetName())
429
.GetCString();
430
}
431
432
void SBBreakpointName::SetQueueName(const char *queue_name) {
433
LLDB_INSTRUMENT_VA(this, queue_name);
434
435
BreakpointName *bp_name = GetBreakpointName();
436
if (!bp_name)
437
return;
438
439
std::lock_guard<std::recursive_mutex> guard(
440
m_impl_up->GetTarget()->GetAPIMutex());
441
442
bp_name->GetOptions().GetThreadSpec()->SetQueueName(queue_name);
443
UpdateName(*bp_name);
444
}
445
446
const char *SBBreakpointName::GetQueueName() const {
447
LLDB_INSTRUMENT_VA(this);
448
449
BreakpointName *bp_name = GetBreakpointName();
450
if (!bp_name)
451
return nullptr;
452
453
std::lock_guard<std::recursive_mutex> guard(
454
m_impl_up->GetTarget()->GetAPIMutex());
455
456
return ConstString(bp_name->GetOptions().GetThreadSpec()->GetQueueName())
457
.GetCString();
458
}
459
460
void SBBreakpointName::SetCommandLineCommands(SBStringList &commands) {
461
LLDB_INSTRUMENT_VA(this, commands);
462
463
BreakpointName *bp_name = GetBreakpointName();
464
if (!bp_name)
465
return;
466
if (commands.GetSize() == 0)
467
return;
468
469
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));
474
475
bp_name->GetOptions().SetCommandDataCallback(cmd_data_up);
476
UpdateName(*bp_name);
477
}
478
479
bool SBBreakpointName::GetCommandLineCommands(SBStringList &commands) {
480
LLDB_INSTRUMENT_VA(this, commands);
481
482
BreakpointName *bp_name = GetBreakpointName();
483
if (!bp_name)
484
return false;
485
486
StringList command_list;
487
bool has_commands =
488
bp_name->GetOptions().GetCommandLineCallbacks(command_list);
489
if (has_commands)
490
commands.AppendList(command_list);
491
return has_commands;
492
}
493
494
const char *SBBreakpointName::GetHelpString() const {
495
LLDB_INSTRUMENT_VA(this);
496
497
BreakpointName *bp_name = GetBreakpointName();
498
if (!bp_name)
499
return "";
500
501
return ConstString(bp_name->GetHelp()).GetCString();
502
}
503
504
void SBBreakpointName::SetHelpString(const char *help_string) {
505
LLDB_INSTRUMENT_VA(this, help_string);
506
507
BreakpointName *bp_name = GetBreakpointName();
508
if (!bp_name)
509
return;
510
511
512
std::lock_guard<std::recursive_mutex> guard(
513
m_impl_up->GetTarget()->GetAPIMutex());
514
bp_name->SetHelp(help_string);
515
}
516
517
bool SBBreakpointName::GetDescription(SBStream &s) {
518
LLDB_INSTRUMENT_VA(this, s);
519
520
BreakpointName *bp_name = GetBreakpointName();
521
if (!bp_name)
522
{
523
s.Printf("No value");
524
return false;
525
}
526
527
std::lock_guard<std::recursive_mutex> guard(
528
m_impl_up->GetTarget()->GetAPIMutex());
529
bp_name->GetDescription(s.get(), eDescriptionLevelFull);
530
return true;
531
}
532
533
void SBBreakpointName::SetCallback(SBBreakpointHitCallback callback,
534
void *baton) {
535
LLDB_INSTRUMENT_VA(this, callback, baton);
536
537
BreakpointName *bp_name = GetBreakpointName();
538
if (!bp_name)
539
return;
540
std::lock_guard<std::recursive_mutex> guard(
541
m_impl_up->GetTarget()->GetAPIMutex());
542
543
BatonSP baton_sp(new SBBreakpointCallbackBaton(callback, baton));
544
bp_name->GetOptions().SetCallback(SBBreakpointCallbackBaton
545
::PrivateBreakpointHitCallback,
546
baton_sp,
547
false);
548
UpdateName(*bp_name);
549
}
550
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);
556
}
557
558
SBError SBBreakpointName::SetScriptCallbackFunction(
559
const char *callback_function_name,
560
SBStructuredData &extra_args) {
561
LLDB_INSTRUMENT_VA(this, callback_function_name, extra_args);
562
SBError sb_error;
563
BreakpointName *bp_name = GetBreakpointName();
564
if (!bp_name) {
565
sb_error.SetErrorString("unrecognized breakpoint name");
566
return sb_error;
567
}
568
569
std::lock_guard<std::recursive_mutex> guard(
570
m_impl_up->GetTarget()->GetAPIMutex());
571
572
BreakpointOptions &bp_options = bp_name->GetOptions();
573
Status error;
574
error = m_impl_up->GetTarget()
575
->GetDebugger()
576
.GetScriptInterpreter()
577
->SetBreakpointCommandCallbackFunction(
578
bp_options, callback_function_name,
579
extra_args.m_impl_up->GetObjectSP());
580
sb_error.SetError(error);
581
UpdateName(*bp_name);
582
return sb_error;
583
}
584
585
SBError
586
SBBreakpointName::SetScriptCallbackBody(const char *callback_body_text) {
587
LLDB_INSTRUMENT_VA(this, callback_body_text);
588
589
SBError sb_error;
590
BreakpointName *bp_name = GetBreakpointName();
591
if (!bp_name)
592
return sb_error;
593
594
std::lock_guard<std::recursive_mutex> guard(
595
m_impl_up->GetTarget()->GetAPIMutex());
596
597
BreakpointOptions &bp_options = bp_name->GetOptions();
598
Status error = m_impl_up->GetTarget()
599
->GetDebugger()
600
.GetScriptInterpreter()
601
->SetBreakpointCommandCallback(
602
bp_options, callback_body_text, /*is_callback=*/false);
603
sb_error.SetError(error);
604
if (!sb_error.Fail())
605
UpdateName(*bp_name);
606
607
return sb_error;
608
}
609
610
bool SBBreakpointName::GetAllowList() const {
611
LLDB_INSTRUMENT_VA(this);
612
613
BreakpointName *bp_name = GetBreakpointName();
614
if (!bp_name)
615
return false;
616
return bp_name->GetPermissions().GetAllowList();
617
}
618
619
void SBBreakpointName::SetAllowList(bool value) {
620
LLDB_INSTRUMENT_VA(this, value);
621
622
BreakpointName *bp_name = GetBreakpointName();
623
if (!bp_name)
624
return;
625
bp_name->GetPermissions().SetAllowList(value);
626
}
627
628
bool SBBreakpointName::GetAllowDelete() {
629
LLDB_INSTRUMENT_VA(this);
630
631
BreakpointName *bp_name = GetBreakpointName();
632
if (!bp_name)
633
return false;
634
return bp_name->GetPermissions().GetAllowDelete();
635
}
636
637
void SBBreakpointName::SetAllowDelete(bool value) {
638
LLDB_INSTRUMENT_VA(this, value);
639
640
BreakpointName *bp_name = GetBreakpointName();
641
if (!bp_name)
642
return;
643
bp_name->GetPermissions().SetAllowDelete(value);
644
}
645
646
bool SBBreakpointName::GetAllowDisable() {
647
LLDB_INSTRUMENT_VA(this);
648
649
BreakpointName *bp_name = GetBreakpointName();
650
if (!bp_name)
651
return false;
652
return bp_name->GetPermissions().GetAllowDisable();
653
}
654
655
void SBBreakpointName::SetAllowDisable(bool value) {
656
LLDB_INSTRUMENT_VA(this, value);
657
658
BreakpointName *bp_name = GetBreakpointName();
659
if (!bp_name)
660
return;
661
bp_name->GetPermissions().SetAllowDisable(value);
662
}
663
664
lldb_private::BreakpointName *SBBreakpointName::GetBreakpointName() const
665
{
666
if (!IsValid())
667
return nullptr;
668
return m_impl_up->GetBreakpointName();
669
}
670
671