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