Coverage Report

Created: 2023-11-11 10:31

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