Book a Demo!
CoCalc Logo Icon
StoreFeaturesDocsShareSupportNewsAboutPoliciesSign UpSign In
freebsd
GitHub Repository: freebsd/freebsd-src
Path: blob/main/contrib/llvm-project/lldb/source/API/SBBreakpoint.cpp
39587 views
1
//===-- SBBreakpoint.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/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"
19
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"
37
38
#include "SBBreakpointOptionCommon.h"
39
40
#include "lldb/lldb-enumerations.h"
41
42
#include "llvm/ADT/STLExtras.h"
43
44
using namespace lldb;
45
using namespace lldb_private;
46
47
SBBreakpoint::SBBreakpoint() { LLDB_INSTRUMENT_VA(this); }
48
49
SBBreakpoint::SBBreakpoint(const SBBreakpoint &rhs)
50
: m_opaque_wp(rhs.m_opaque_wp) {
51
LLDB_INSTRUMENT_VA(this, rhs);
52
}
53
54
SBBreakpoint::SBBreakpoint(const lldb::BreakpointSP &bp_sp)
55
: m_opaque_wp(bp_sp) {
56
LLDB_INSTRUMENT_VA(this, bp_sp);
57
}
58
59
SBBreakpoint::~SBBreakpoint() = default;
60
61
const SBBreakpoint &SBBreakpoint::operator=(const SBBreakpoint &rhs) {
62
LLDB_INSTRUMENT_VA(this, rhs);
63
64
m_opaque_wp = rhs.m_opaque_wp;
65
return *this;
66
}
67
68
bool SBBreakpoint::operator==(const lldb::SBBreakpoint &rhs) {
69
LLDB_INSTRUMENT_VA(this, rhs);
70
71
return m_opaque_wp.lock() == rhs.m_opaque_wp.lock();
72
}
73
74
bool SBBreakpoint::operator!=(const lldb::SBBreakpoint &rhs) {
75
LLDB_INSTRUMENT_VA(this, rhs);
76
77
return m_opaque_wp.lock() != rhs.m_opaque_wp.lock();
78
}
79
80
SBTarget SBBreakpoint::GetTarget() const {
81
LLDB_INSTRUMENT_VA(this);
82
83
BreakpointSP bkpt_sp = GetSP();
84
if (bkpt_sp)
85
return SBTarget(bkpt_sp->GetTargetSP());
86
87
return SBTarget();
88
}
89
90
break_id_t SBBreakpoint::GetID() const {
91
LLDB_INSTRUMENT_VA(this);
92
93
break_id_t break_id = LLDB_INVALID_BREAK_ID;
94
BreakpointSP bkpt_sp = GetSP();
95
if (bkpt_sp)
96
break_id = bkpt_sp->GetID();
97
98
return break_id;
99
}
100
101
bool SBBreakpoint::IsValid() const {
102
LLDB_INSTRUMENT_VA(this);
103
return this->operator bool();
104
}
105
SBBreakpoint::operator bool() const {
106
LLDB_INSTRUMENT_VA(this);
107
108
BreakpointSP bkpt_sp = GetSP();
109
if (!bkpt_sp)
110
return false;
111
else if (bkpt_sp->GetTarget().GetBreakpointByID(bkpt_sp->GetID()))
112
return true;
113
else
114
return false;
115
}
116
117
void SBBreakpoint::ClearAllBreakpointSites() {
118
LLDB_INSTRUMENT_VA(this);
119
120
BreakpointSP bkpt_sp = GetSP();
121
if (bkpt_sp) {
122
std::lock_guard<std::recursive_mutex> guard(
123
bkpt_sp->GetTarget().GetAPIMutex());
124
bkpt_sp->ClearAllBreakpointSites();
125
}
126
}
127
128
SBBreakpointLocation SBBreakpoint::FindLocationByAddress(addr_t vm_addr) {
129
LLDB_INSTRUMENT_VA(this, vm_addr);
130
131
SBBreakpointLocation sb_bp_location;
132
133
BreakpointSP bkpt_sp = GetSP();
134
if (bkpt_sp) {
135
if (vm_addr != LLDB_INVALID_ADDRESS) {
136
std::lock_guard<std::recursive_mutex> guard(
137
bkpt_sp->GetTarget().GetAPIMutex());
138
Address address;
139
Target &target = bkpt_sp->GetTarget();
140
if (!target.GetSectionLoadList().ResolveLoadAddress(vm_addr, address)) {
141
address.SetRawAddress(vm_addr);
142
}
143
sb_bp_location.SetLocation(bkpt_sp->FindLocationByAddress(address));
144
}
145
}
146
return sb_bp_location;
147
}
148
149
break_id_t SBBreakpoint::FindLocationIDByAddress(addr_t vm_addr) {
150
LLDB_INSTRUMENT_VA(this, vm_addr);
151
152
break_id_t break_id = LLDB_INVALID_BREAK_ID;
153
BreakpointSP bkpt_sp = GetSP();
154
155
if (bkpt_sp && vm_addr != LLDB_INVALID_ADDRESS) {
156
std::lock_guard<std::recursive_mutex> guard(
157
bkpt_sp->GetTarget().GetAPIMutex());
158
Address address;
159
Target &target = bkpt_sp->GetTarget();
160
if (!target.GetSectionLoadList().ResolveLoadAddress(vm_addr, address)) {
161
address.SetRawAddress(vm_addr);
162
}
163
break_id = bkpt_sp->FindLocationIDByAddress(address);
164
}
165
166
return break_id;
167
}
168
169
SBBreakpointLocation SBBreakpoint::FindLocationByID(break_id_t bp_loc_id) {
170
LLDB_INSTRUMENT_VA(this, bp_loc_id);
171
172
SBBreakpointLocation sb_bp_location;
173
BreakpointSP bkpt_sp = GetSP();
174
175
if (bkpt_sp) {
176
std::lock_guard<std::recursive_mutex> guard(
177
bkpt_sp->GetTarget().GetAPIMutex());
178
sb_bp_location.SetLocation(bkpt_sp->FindLocationByID(bp_loc_id));
179
}
180
181
return sb_bp_location;
182
}
183
184
SBBreakpointLocation SBBreakpoint::GetLocationAtIndex(uint32_t index) {
185
LLDB_INSTRUMENT_VA(this, index);
186
187
SBBreakpointLocation sb_bp_location;
188
BreakpointSP bkpt_sp = GetSP();
189
190
if (bkpt_sp) {
191
std::lock_guard<std::recursive_mutex> guard(
192
bkpt_sp->GetTarget().GetAPIMutex());
193
sb_bp_location.SetLocation(bkpt_sp->GetLocationAtIndex(index));
194
}
195
196
return sb_bp_location;
197
}
198
199
void SBBreakpoint::SetEnabled(bool enable) {
200
LLDB_INSTRUMENT_VA(this, enable);
201
202
BreakpointSP bkpt_sp = GetSP();
203
204
if (bkpt_sp) {
205
std::lock_guard<std::recursive_mutex> guard(
206
bkpt_sp->GetTarget().GetAPIMutex());
207
bkpt_sp->SetEnabled(enable);
208
}
209
}
210
211
bool SBBreakpoint::IsEnabled() {
212
LLDB_INSTRUMENT_VA(this);
213
214
BreakpointSP bkpt_sp = GetSP();
215
if (bkpt_sp) {
216
std::lock_guard<std::recursive_mutex> guard(
217
bkpt_sp->GetTarget().GetAPIMutex());
218
return bkpt_sp->IsEnabled();
219
} else
220
return false;
221
}
222
223
void SBBreakpoint::SetOneShot(bool one_shot) {
224
LLDB_INSTRUMENT_VA(this, one_shot);
225
226
BreakpointSP bkpt_sp = GetSP();
227
228
if (bkpt_sp) {
229
std::lock_guard<std::recursive_mutex> guard(
230
bkpt_sp->GetTarget().GetAPIMutex());
231
bkpt_sp->SetOneShot(one_shot);
232
}
233
}
234
235
bool SBBreakpoint::IsOneShot() const {
236
LLDB_INSTRUMENT_VA(this);
237
238
BreakpointSP bkpt_sp = GetSP();
239
if (bkpt_sp) {
240
std::lock_guard<std::recursive_mutex> guard(
241
bkpt_sp->GetTarget().GetAPIMutex());
242
return bkpt_sp->IsOneShot();
243
} else
244
return false;
245
}
246
247
bool SBBreakpoint::IsInternal() {
248
LLDB_INSTRUMENT_VA(this);
249
250
BreakpointSP bkpt_sp = GetSP();
251
if (bkpt_sp) {
252
std::lock_guard<std::recursive_mutex> guard(
253
bkpt_sp->GetTarget().GetAPIMutex());
254
return bkpt_sp->IsInternal();
255
} else
256
return false;
257
}
258
259
void SBBreakpoint::SetIgnoreCount(uint32_t count) {
260
LLDB_INSTRUMENT_VA(this, count);
261
262
BreakpointSP bkpt_sp = GetSP();
263
264
if (bkpt_sp) {
265
std::lock_guard<std::recursive_mutex> guard(
266
bkpt_sp->GetTarget().GetAPIMutex());
267
bkpt_sp->SetIgnoreCount(count);
268
}
269
}
270
271
void SBBreakpoint::SetCondition(const char *condition) {
272
LLDB_INSTRUMENT_VA(this, condition);
273
274
BreakpointSP bkpt_sp = GetSP();
275
if (bkpt_sp) {
276
std::lock_guard<std::recursive_mutex> guard(
277
bkpt_sp->GetTarget().GetAPIMutex());
278
bkpt_sp->SetCondition(condition);
279
}
280
}
281
282
const char *SBBreakpoint::GetCondition() {
283
LLDB_INSTRUMENT_VA(this);
284
285
BreakpointSP bkpt_sp = GetSP();
286
if (!bkpt_sp)
287
return nullptr;
288
289
std::lock_guard<std::recursive_mutex> guard(
290
bkpt_sp->GetTarget().GetAPIMutex());
291
return ConstString(bkpt_sp->GetConditionText()).GetCString();
292
}
293
294
void SBBreakpoint::SetAutoContinue(bool auto_continue) {
295
LLDB_INSTRUMENT_VA(this, auto_continue);
296
297
BreakpointSP bkpt_sp = GetSP();
298
if (bkpt_sp) {
299
std::lock_guard<std::recursive_mutex> guard(
300
bkpt_sp->GetTarget().GetAPIMutex());
301
bkpt_sp->SetAutoContinue(auto_continue);
302
}
303
}
304
305
bool SBBreakpoint::GetAutoContinue() {
306
LLDB_INSTRUMENT_VA(this);
307
308
BreakpointSP bkpt_sp = GetSP();
309
if (bkpt_sp) {
310
std::lock_guard<std::recursive_mutex> guard(
311
bkpt_sp->GetTarget().GetAPIMutex());
312
return bkpt_sp->IsAutoContinue();
313
}
314
return false;
315
}
316
317
uint32_t SBBreakpoint::GetHitCount() const {
318
LLDB_INSTRUMENT_VA(this);
319
320
uint32_t count = 0;
321
BreakpointSP bkpt_sp = GetSP();
322
if (bkpt_sp) {
323
std::lock_guard<std::recursive_mutex> guard(
324
bkpt_sp->GetTarget().GetAPIMutex());
325
count = bkpt_sp->GetHitCount();
326
}
327
328
return count;
329
}
330
331
uint32_t SBBreakpoint::GetIgnoreCount() const {
332
LLDB_INSTRUMENT_VA(this);
333
334
uint32_t count = 0;
335
BreakpointSP bkpt_sp = GetSP();
336
if (bkpt_sp) {
337
std::lock_guard<std::recursive_mutex> guard(
338
bkpt_sp->GetTarget().GetAPIMutex());
339
count = bkpt_sp->GetIgnoreCount();
340
}
341
342
return count;
343
}
344
345
void SBBreakpoint::SetThreadID(tid_t tid) {
346
LLDB_INSTRUMENT_VA(this, tid);
347
348
BreakpointSP bkpt_sp = GetSP();
349
if (bkpt_sp) {
350
std::lock_guard<std::recursive_mutex> guard(
351
bkpt_sp->GetTarget().GetAPIMutex());
352
bkpt_sp->SetThreadID(tid);
353
}
354
}
355
356
tid_t SBBreakpoint::GetThreadID() {
357
LLDB_INSTRUMENT_VA(this);
358
359
tid_t tid = LLDB_INVALID_THREAD_ID;
360
BreakpointSP bkpt_sp = GetSP();
361
if (bkpt_sp) {
362
std::lock_guard<std::recursive_mutex> guard(
363
bkpt_sp->GetTarget().GetAPIMutex());
364
tid = bkpt_sp->GetThreadID();
365
}
366
367
return tid;
368
}
369
370
void SBBreakpoint::SetThreadIndex(uint32_t index) {
371
LLDB_INSTRUMENT_VA(this, index);
372
373
BreakpointSP bkpt_sp = GetSP();
374
if (bkpt_sp) {
375
std::lock_guard<std::recursive_mutex> guard(
376
bkpt_sp->GetTarget().GetAPIMutex());
377
bkpt_sp->GetOptions().GetThreadSpec()->SetIndex(index);
378
}
379
}
380
381
uint32_t SBBreakpoint::GetThreadIndex() const {
382
LLDB_INSTRUMENT_VA(this);
383
384
uint32_t thread_idx = UINT32_MAX;
385
BreakpointSP bkpt_sp = GetSP();
386
if (bkpt_sp) {
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();
393
}
394
395
return thread_idx;
396
}
397
398
void SBBreakpoint::SetThreadName(const char *thread_name) {
399
LLDB_INSTRUMENT_VA(this, thread_name);
400
401
BreakpointSP bkpt_sp = GetSP();
402
403
if (bkpt_sp) {
404
std::lock_guard<std::recursive_mutex> guard(
405
bkpt_sp->GetTarget().GetAPIMutex());
406
bkpt_sp->GetOptions().GetThreadSpec()->SetName(thread_name);
407
}
408
}
409
410
const char *SBBreakpoint::GetThreadName() const {
411
LLDB_INSTRUMENT_VA(this);
412
413
BreakpointSP bkpt_sp = GetSP();
414
if (!bkpt_sp)
415
return nullptr;
416
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();
422
423
return nullptr;
424
}
425
426
void SBBreakpoint::SetQueueName(const char *queue_name) {
427
LLDB_INSTRUMENT_VA(this, queue_name);
428
429
BreakpointSP bkpt_sp = GetSP();
430
if (bkpt_sp) {
431
std::lock_guard<std::recursive_mutex> guard(
432
bkpt_sp->GetTarget().GetAPIMutex());
433
bkpt_sp->GetOptions().GetThreadSpec()->SetQueueName(queue_name);
434
}
435
}
436
437
const char *SBBreakpoint::GetQueueName() const {
438
LLDB_INSTRUMENT_VA(this);
439
440
BreakpointSP bkpt_sp = GetSP();
441
if (!bkpt_sp)
442
return nullptr;
443
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();
449
450
return nullptr;
451
}
452
453
size_t SBBreakpoint::GetNumResolvedLocations() const {
454
LLDB_INSTRUMENT_VA(this);
455
456
size_t num_resolved = 0;
457
BreakpointSP bkpt_sp = GetSP();
458
if (bkpt_sp) {
459
std::lock_guard<std::recursive_mutex> guard(
460
bkpt_sp->GetTarget().GetAPIMutex());
461
num_resolved = bkpt_sp->GetNumResolvedLocations();
462
}
463
return num_resolved;
464
}
465
466
size_t SBBreakpoint::GetNumLocations() const {
467
LLDB_INSTRUMENT_VA(this);
468
469
BreakpointSP bkpt_sp = GetSP();
470
size_t num_locs = 0;
471
if (bkpt_sp) {
472
std::lock_guard<std::recursive_mutex> guard(
473
bkpt_sp->GetTarget().GetAPIMutex());
474
num_locs = bkpt_sp->GetNumLocations();
475
}
476
return num_locs;
477
}
478
479
void SBBreakpoint::SetCommandLineCommands(SBStringList &commands) {
480
LLDB_INSTRUMENT_VA(this, commands);
481
482
BreakpointSP bkpt_sp = GetSP();
483
if (!bkpt_sp)
484
return;
485
if (commands.GetSize() == 0)
486
return;
487
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));
492
493
bkpt_sp->GetOptions().SetCommandDataCallback(cmd_data_up);
494
}
495
496
bool SBBreakpoint::GetCommandLineCommands(SBStringList &commands) {
497
LLDB_INSTRUMENT_VA(this, commands);
498
499
BreakpointSP bkpt_sp = GetSP();
500
if (!bkpt_sp)
501
return false;
502
StringList command_list;
503
bool has_commands =
504
bkpt_sp->GetOptions().GetCommandLineCallbacks(command_list);
505
if (has_commands)
506
commands.AppendList(command_list);
507
return has_commands;
508
}
509
510
bool SBBreakpoint::GetDescription(SBStream &s) {
511
LLDB_INSTRUMENT_VA(this, s);
512
513
return GetDescription(s, true);
514
}
515
516
bool SBBreakpoint::GetDescription(SBStream &s, bool include_locations) {
517
LLDB_INSTRUMENT_VA(this, s, include_locations);
518
519
BreakpointSP bkpt_sp = GetSP();
520
if (bkpt_sp) {
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);
529
}
530
return true;
531
}
532
s.Printf("No value");
533
return false;
534
}
535
536
SBError SBBreakpoint::AddLocation(SBAddress &address) {
537
LLDB_INSTRUMENT_VA(this, address);
538
539
BreakpointSP bkpt_sp = GetSP();
540
SBError error;
541
542
if (!address.IsValid()) {
543
error.SetErrorString("Can't add an invalid address.");
544
return error;
545
}
546
547
if (!bkpt_sp) {
548
error.SetErrorString("No breakpoint to add a location to.");
549
return error;
550
}
551
552
if (!llvm::isa<BreakpointResolverScripted>(bkpt_sp->GetResolver().get())) {
553
error.SetErrorString("Only a scripted resolver can add locations.");
554
return error;
555
}
556
557
if (bkpt_sp->GetSearchFilter()->AddressPasses(address.ref()))
558
bkpt_sp->AddLocation(address.ref());
559
else {
560
StreamString s;
561
address.get()->Dump(&s, &bkpt_sp->GetTarget(),
562
Address::DumpStyleModuleWithFileAddress);
563
error.SetErrorStringWithFormat("Address: %s didn't pass the filter.",
564
s.GetData());
565
}
566
return error;
567
}
568
569
SBStructuredData SBBreakpoint::SerializeToStructuredData() {
570
LLDB_INSTRUMENT_VA(this);
571
572
SBStructuredData data;
573
BreakpointSP bkpt_sp = GetSP();
574
575
if (!bkpt_sp)
576
return data;
577
578
StructuredData::ObjectSP bkpt_dict = bkpt_sp->SerializeToStructuredData();
579
data.m_impl_up->SetObjectSP(bkpt_dict);
580
return data;
581
}
582
583
void SBBreakpoint::SetCallback(SBBreakpointHitCallback callback, void *baton) {
584
LLDB_INSTRUMENT_VA(this, callback, baton);
585
586
BreakpointSP bkpt_sp = GetSP();
587
588
if (bkpt_sp) {
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,
594
false);
595
}
596
}
597
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);
603
}
604
605
SBError SBBreakpoint::SetScriptCallbackFunction(
606
const char *callback_function_name,
607
SBStructuredData &extra_args) {
608
LLDB_INSTRUMENT_VA(this, callback_function_name, extra_args);
609
SBError sb_error;
610
BreakpointSP bkpt_sp = GetSP();
611
612
if (bkpt_sp) {
613
Status error;
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()
618
.GetDebugger()
619
.GetScriptInterpreter()
620
->SetBreakpointCommandCallbackFunction(bp_options,
621
callback_function_name,
622
extra_args.m_impl_up
623
->GetObjectSP());
624
sb_error.SetError(error);
625
} else
626
sb_error.SetErrorString("invalid breakpoint");
627
628
return sb_error;
629
}
630
631
SBError SBBreakpoint::SetScriptCallbackBody(const char *callback_body_text) {
632
LLDB_INSTRUMENT_VA(this, callback_body_text);
633
634
BreakpointSP bkpt_sp = GetSP();
635
636
SBError sb_error;
637
if (bkpt_sp) {
638
std::lock_guard<std::recursive_mutex> guard(
639
bkpt_sp->GetTarget().GetAPIMutex());
640
BreakpointOptions &bp_options = bkpt_sp->GetOptions();
641
Status error =
642
bkpt_sp->GetTarget()
643
.GetDebugger()
644
.GetScriptInterpreter()
645
->SetBreakpointCommandCallback(bp_options, callback_body_text,
646
/*is_callback=*/false);
647
sb_error.SetError(error);
648
} else
649
sb_error.SetErrorString("invalid breakpoint");
650
651
return sb_error;
652
}
653
654
bool SBBreakpoint::AddName(const char *new_name) {
655
LLDB_INSTRUMENT_VA(this, new_name);
656
657
SBError status = AddNameWithErrorHandling(new_name);
658
return status.Success();
659
}
660
661
SBError SBBreakpoint::AddNameWithErrorHandling(const char *new_name) {
662
LLDB_INSTRUMENT_VA(this, new_name);
663
664
BreakpointSP bkpt_sp = GetSP();
665
666
SBError status;
667
if (bkpt_sp) {
668
std::lock_guard<std::recursive_mutex> guard(
669
bkpt_sp->GetTarget().GetAPIMutex());
670
Status error;
671
bkpt_sp->GetTarget().AddNameToBreakpoint(bkpt_sp, new_name, error);
672
status.SetError(error);
673
} else {
674
status.SetErrorString("invalid breakpoint");
675
}
676
677
return status;
678
}
679
680
void SBBreakpoint::RemoveName(const char *name_to_remove) {
681
LLDB_INSTRUMENT_VA(this, name_to_remove);
682
683
BreakpointSP bkpt_sp = GetSP();
684
685
if (bkpt_sp) {
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));
690
}
691
}
692
693
bool SBBreakpoint::MatchesName(const char *name) {
694
LLDB_INSTRUMENT_VA(this, name);
695
696
BreakpointSP bkpt_sp = GetSP();
697
698
if (bkpt_sp) {
699
std::lock_guard<std::recursive_mutex> guard(
700
bkpt_sp->GetTarget().GetAPIMutex());
701
return bkpt_sp->MatchesName(name);
702
}
703
704
return false;
705
}
706
707
void SBBreakpoint::GetNames(SBStringList &names) {
708
LLDB_INSTRUMENT_VA(this, names);
709
710
BreakpointSP bkpt_sp = GetSP();
711
712
if (bkpt_sp) {
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 (const std::string &name : names_vec) {
718
names.AppendString(name.c_str());
719
}
720
}
721
}
722
723
bool SBBreakpoint::EventIsBreakpointEvent(const lldb::SBEvent &event) {
724
LLDB_INSTRUMENT_VA(event);
725
726
return Breakpoint::BreakpointEventData::GetEventDataFromEvent(event.get()) !=
727
nullptr;
728
}
729
730
BreakpointEventType
731
SBBreakpoint::GetBreakpointEventTypeFromEvent(const SBEvent &event) {
732
LLDB_INSTRUMENT_VA(event);
733
734
if (event.IsValid())
735
return Breakpoint::BreakpointEventData::GetBreakpointEventTypeFromEvent(
736
event.GetSP());
737
return eBreakpointEventTypeInvalidType;
738
}
739
740
SBBreakpoint SBBreakpoint::GetBreakpointFromEvent(const lldb::SBEvent &event) {
741
LLDB_INSTRUMENT_VA(event);
742
743
if (event.IsValid())
744
return SBBreakpoint(
745
Breakpoint::BreakpointEventData::GetBreakpointFromEvent(event.GetSP()));
746
return SBBreakpoint();
747
}
748
749
SBBreakpointLocation
750
SBBreakpoint::GetBreakpointLocationAtIndexFromEvent(const lldb::SBEvent &event,
751
uint32_t loc_idx) {
752
LLDB_INSTRUMENT_VA(event, loc_idx);
753
754
SBBreakpointLocation sb_breakpoint_loc;
755
if (event.IsValid())
756
sb_breakpoint_loc.SetLocation(
757
Breakpoint::BreakpointEventData::GetBreakpointLocationAtIndexFromEvent(
758
event.GetSP(), loc_idx));
759
return sb_breakpoint_loc;
760
}
761
762
uint32_t
763
SBBreakpoint::GetNumBreakpointLocationsFromEvent(const lldb::SBEvent &event) {
764
LLDB_INSTRUMENT_VA(event);
765
766
uint32_t num_locations = 0;
767
if (event.IsValid())
768
num_locations =
769
(Breakpoint::BreakpointEventData::GetNumBreakpointLocationsFromEvent(
770
event.GetSP()));
771
return num_locations;
772
}
773
774
bool SBBreakpoint::IsHardware() const {
775
LLDB_INSTRUMENT_VA(this);
776
777
BreakpointSP bkpt_sp = GetSP();
778
if (bkpt_sp)
779
return bkpt_sp->IsHardware();
780
return false;
781
}
782
783
BreakpointSP SBBreakpoint::GetSP() const { return m_opaque_wp.lock(); }
784
785
// This is simple collection of breakpoint id's and their target.
786
class SBBreakpointListImpl {
787
public:
788
SBBreakpointListImpl(lldb::TargetSP target_sp) {
789
if (target_sp && target_sp->IsValid())
790
m_target_wp = target_sp;
791
}
792
793
~SBBreakpointListImpl() = default;
794
795
size_t GetSize() { return m_break_ids.size(); }
796
797
BreakpointSP GetBreakpointAtIndex(size_t idx) {
798
if (idx >= m_break_ids.size())
799
return BreakpointSP();
800
TargetSP target_sp = m_target_wp.lock();
801
if (!target_sp)
802
return BreakpointSP();
803
lldb::break_id_t bp_id = m_break_ids[idx];
804
return target_sp->GetBreakpointList().FindBreakpointByID(bp_id);
805
}
806
807
BreakpointSP FindBreakpointByID(lldb::break_id_t desired_id) {
808
TargetSP target_sp = m_target_wp.lock();
809
if (!target_sp)
810
return BreakpointSP();
811
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);
815
}
816
return BreakpointSP();
817
}
818
819
bool Append(BreakpointSP bkpt) {
820
TargetSP target_sp = m_target_wp.lock();
821
if (!target_sp || !bkpt)
822
return false;
823
if (bkpt->GetTargetSP() != target_sp)
824
return false;
825
m_break_ids.push_back(bkpt->GetID());
826
return true;
827
}
828
829
bool AppendIfUnique(BreakpointSP bkpt) {
830
TargetSP target_sp = m_target_wp.lock();
831
if (!target_sp || !bkpt)
832
return false;
833
if (bkpt->GetTargetSP() != target_sp)
834
return false;
835
lldb::break_id_t bp_id = bkpt->GetID();
836
if (!llvm::is_contained(m_break_ids, bp_id))
837
return false;
838
839
m_break_ids.push_back(bkpt->GetID());
840
return true;
841
}
842
843
bool AppendByID(lldb::break_id_t id) {
844
TargetSP target_sp = m_target_wp.lock();
845
if (!target_sp)
846
return false;
847
if (id == LLDB_INVALID_BREAK_ID)
848
return false;
849
m_break_ids.push_back(id);
850
return true;
851
}
852
853
void Clear() { m_break_ids.clear(); }
854
855
void CopyToBreakpointIDList(lldb_private::BreakpointIDList &bp_list) {
856
for (lldb::break_id_t id : m_break_ids) {
857
bp_list.AddBreakpointID(BreakpointID(id));
858
}
859
}
860
861
TargetSP GetTarget() { return m_target_wp.lock(); }
862
863
private:
864
std::vector<lldb::break_id_t> m_break_ids;
865
TargetWP m_target_wp;
866
};
867
868
SBBreakpointList::SBBreakpointList(SBTarget &target)
869
: m_opaque_sp(new SBBreakpointListImpl(target.GetSP())) {
870
LLDB_INSTRUMENT_VA(this, target);
871
}
872
873
SBBreakpointList::~SBBreakpointList() = default;
874
875
size_t SBBreakpointList::GetSize() const {
876
LLDB_INSTRUMENT_VA(this);
877
878
if (!m_opaque_sp)
879
return 0;
880
else
881
return m_opaque_sp->GetSize();
882
}
883
884
SBBreakpoint SBBreakpointList::GetBreakpointAtIndex(size_t idx) {
885
LLDB_INSTRUMENT_VA(this, idx);
886
887
if (!m_opaque_sp)
888
return SBBreakpoint();
889
890
BreakpointSP bkpt_sp = m_opaque_sp->GetBreakpointAtIndex(idx);
891
return SBBreakpoint(bkpt_sp);
892
}
893
894
SBBreakpoint SBBreakpointList::FindBreakpointByID(lldb::break_id_t id) {
895
LLDB_INSTRUMENT_VA(this, id);
896
897
if (!m_opaque_sp)
898
return SBBreakpoint();
899
BreakpointSP bkpt_sp = m_opaque_sp->FindBreakpointByID(id);
900
return SBBreakpoint(bkpt_sp);
901
}
902
903
void SBBreakpointList::Append(const SBBreakpoint &sb_bkpt) {
904
LLDB_INSTRUMENT_VA(this, sb_bkpt);
905
906
if (!sb_bkpt.IsValid())
907
return;
908
if (!m_opaque_sp)
909
return;
910
m_opaque_sp->Append(sb_bkpt.m_opaque_wp.lock());
911
}
912
913
void SBBreakpointList::AppendByID(lldb::break_id_t id) {
914
LLDB_INSTRUMENT_VA(this, id);
915
916
if (!m_opaque_sp)
917
return;
918
m_opaque_sp->AppendByID(id);
919
}
920
921
bool SBBreakpointList::AppendIfUnique(const SBBreakpoint &sb_bkpt) {
922
LLDB_INSTRUMENT_VA(this, sb_bkpt);
923
924
if (!sb_bkpt.IsValid())
925
return false;
926
if (!m_opaque_sp)
927
return false;
928
return m_opaque_sp->AppendIfUnique(sb_bkpt.GetSP());
929
}
930
931
void SBBreakpointList::Clear() {
932
LLDB_INSTRUMENT_VA(this);
933
934
if (m_opaque_sp)
935
m_opaque_sp->Clear();
936
}
937
938
void SBBreakpointList::CopyToBreakpointIDList(
939
lldb_private::BreakpointIDList &bp_id_list) {
940
if (m_opaque_sp)
941
m_opaque_sp->CopyToBreakpointIDList(bp_id_list);
942
}
943
944