1 //===-- SBBreakpoint.cpp ----------------------------------------*- C++ -*-===//
2 //
3 //                     The LLVM Compiler Infrastructure
4 //
5 // This file is distributed under the University of Illinois Open Source
6 // License. See LICENSE.TXT for details.
7 //
8 //===----------------------------------------------------------------------===//
9 
10 // C Includes
11 // C++ Includes
12 // Other libraries and framework includes
13 // Project includes
14 #include "lldb/API/SBBreakpoint.h"
15 #include "lldb/API/SBBreakpointLocation.h"
16 #include "lldb/API/SBDebugger.h"
17 #include "lldb/API/SBEvent.h"
18 #include "lldb/API/SBProcess.h"
19 #include "lldb/API/SBStream.h"
20 #include "lldb/API/SBStringList.h"
21 #include "lldb/API/SBThread.h"
22 
23 #include "lldb/Breakpoint/Breakpoint.h"
24 #include "lldb/Breakpoint/BreakpointLocation.h"
25 #include "lldb/Breakpoint/StoppointCallbackContext.h"
26 #include "lldb/Core/Address.h"
27 #include "lldb/Core/Debugger.h"
28 #include "lldb/Core/Log.h"
29 #include "lldb/Core/Stream.h"
30 #include "lldb/Core/StreamFile.h"
31 #include "lldb/Interpreter/CommandInterpreter.h"
32 #include "lldb/Interpreter/ScriptInterpreter.h"
33 #include "lldb/Target/Process.h"
34 #include "lldb/Target/SectionLoadList.h"
35 #include "lldb/Target/Target.h"
36 #include "lldb/Target/Thread.h"
37 #include "lldb/Target/ThreadSpec.h"
38 
39 #include "lldb/lldb-enumerations.h"
40 
41 using namespace lldb;
42 using namespace lldb_private;
43 
44 struct CallbackData {
45   SBBreakpoint::BreakpointHitCallback callback;
46   void *callback_baton;
47 };
48 
49 class SBBreakpointCallbackBaton : public Baton {
50 public:
51   SBBreakpointCallbackBaton(SBBreakpoint::BreakpointHitCallback callback,
52                             void *baton)
53       : Baton(new CallbackData) {
54     CallbackData *data = (CallbackData *)m_data;
55     data->callback = callback;
56     data->callback_baton = baton;
57   }
58 
59   ~SBBreakpointCallbackBaton() override {
60     CallbackData *data = (CallbackData *)m_data;
61 
62     if (data) {
63       delete data;
64       m_data = nullptr;
65     }
66   }
67 };
68 
69 SBBreakpoint::SBBreakpoint() : m_opaque_sp() {}
70 
71 SBBreakpoint::SBBreakpoint(const SBBreakpoint &rhs)
72     : m_opaque_sp(rhs.m_opaque_sp) {}
73 
74 SBBreakpoint::SBBreakpoint(const lldb::BreakpointSP &bp_sp)
75     : m_opaque_sp(bp_sp) {}
76 
77 SBBreakpoint::~SBBreakpoint() = default;
78 
79 const SBBreakpoint &SBBreakpoint::operator=(const SBBreakpoint &rhs) {
80   if (this != &rhs)
81     m_opaque_sp = rhs.m_opaque_sp;
82   return *this;
83 }
84 
85 bool SBBreakpoint::operator==(const lldb::SBBreakpoint &rhs) {
86   if (m_opaque_sp && rhs.m_opaque_sp)
87     return m_opaque_sp.get() == rhs.m_opaque_sp.get();
88   return false;
89 }
90 
91 bool SBBreakpoint::operator!=(const lldb::SBBreakpoint &rhs) {
92   if (m_opaque_sp && rhs.m_opaque_sp)
93     return m_opaque_sp.get() != rhs.m_opaque_sp.get();
94   return (m_opaque_sp && !rhs.m_opaque_sp) || (rhs.m_opaque_sp && !m_opaque_sp);
95 }
96 
97 break_id_t SBBreakpoint::GetID() const {
98   Log *log(lldb_private::GetLogIfAllCategoriesSet(LIBLLDB_LOG_API));
99 
100   break_id_t break_id = LLDB_INVALID_BREAK_ID;
101   if (m_opaque_sp)
102     break_id = m_opaque_sp->GetID();
103 
104   if (log) {
105     if (break_id == LLDB_INVALID_BREAK_ID)
106       log->Printf("SBBreakpoint(%p)::GetID () => LLDB_INVALID_BREAK_ID",
107                   static_cast<void *>(m_opaque_sp.get()));
108     else
109       log->Printf("SBBreakpoint(%p)::GetID () => %u",
110                   static_cast<void *>(m_opaque_sp.get()), break_id);
111   }
112 
113   return break_id;
114 }
115 
116 bool SBBreakpoint::IsValid() const {
117   if (!m_opaque_sp)
118     return false;
119   else if (m_opaque_sp->GetTarget().GetBreakpointByID(m_opaque_sp->GetID()))
120     return true;
121   else
122     return false;
123 }
124 
125 void SBBreakpoint::ClearAllBreakpointSites() {
126   if (m_opaque_sp) {
127     std::lock_guard<std::recursive_mutex> guard(
128         m_opaque_sp->GetTarget().GetAPIMutex());
129     m_opaque_sp->ClearAllBreakpointSites();
130   }
131 }
132 
133 SBBreakpointLocation SBBreakpoint::FindLocationByAddress(addr_t vm_addr) {
134   SBBreakpointLocation sb_bp_location;
135 
136   if (m_opaque_sp) {
137     if (vm_addr != LLDB_INVALID_ADDRESS) {
138       std::lock_guard<std::recursive_mutex> guard(
139           m_opaque_sp->GetTarget().GetAPIMutex());
140       Address address;
141       Target &target = m_opaque_sp->GetTarget();
142       if (!target.GetSectionLoadList().ResolveLoadAddress(vm_addr, address)) {
143         address.SetRawAddress(vm_addr);
144       }
145       sb_bp_location.SetLocation(m_opaque_sp->FindLocationByAddress(address));
146     }
147   }
148   return sb_bp_location;
149 }
150 
151 break_id_t SBBreakpoint::FindLocationIDByAddress(addr_t vm_addr) {
152   break_id_t break_id = LLDB_INVALID_BREAK_ID;
153 
154   if (m_opaque_sp && vm_addr != LLDB_INVALID_ADDRESS) {
155     std::lock_guard<std::recursive_mutex> guard(
156         m_opaque_sp->GetTarget().GetAPIMutex());
157     Address address;
158     Target &target = m_opaque_sp->GetTarget();
159     if (!target.GetSectionLoadList().ResolveLoadAddress(vm_addr, address)) {
160       address.SetRawAddress(vm_addr);
161     }
162     break_id = m_opaque_sp->FindLocationIDByAddress(address);
163   }
164 
165   return break_id;
166 }
167 
168 SBBreakpointLocation SBBreakpoint::FindLocationByID(break_id_t bp_loc_id) {
169   SBBreakpointLocation sb_bp_location;
170 
171   if (m_opaque_sp) {
172     std::lock_guard<std::recursive_mutex> guard(
173         m_opaque_sp->GetTarget().GetAPIMutex());
174     sb_bp_location.SetLocation(m_opaque_sp->FindLocationByID(bp_loc_id));
175   }
176 
177   return sb_bp_location;
178 }
179 
180 SBBreakpointLocation SBBreakpoint::GetLocationAtIndex(uint32_t index) {
181   SBBreakpointLocation sb_bp_location;
182 
183   if (m_opaque_sp) {
184     std::lock_guard<std::recursive_mutex> guard(
185         m_opaque_sp->GetTarget().GetAPIMutex());
186     sb_bp_location.SetLocation(m_opaque_sp->GetLocationAtIndex(index));
187   }
188 
189   return sb_bp_location;
190 }
191 
192 void SBBreakpoint::SetEnabled(bool enable) {
193   Log *log(lldb_private::GetLogIfAllCategoriesSet(LIBLLDB_LOG_API));
194 
195   if (log)
196     log->Printf("SBBreakpoint(%p)::SetEnabled (enabled=%i)",
197                 static_cast<void *>(m_opaque_sp.get()), enable);
198 
199   if (m_opaque_sp) {
200     std::lock_guard<std::recursive_mutex> guard(
201         m_opaque_sp->GetTarget().GetAPIMutex());
202     m_opaque_sp->SetEnabled(enable);
203   }
204 }
205 
206 bool SBBreakpoint::IsEnabled() {
207   if (m_opaque_sp) {
208     std::lock_guard<std::recursive_mutex> guard(
209         m_opaque_sp->GetTarget().GetAPIMutex());
210     return m_opaque_sp->IsEnabled();
211   } else
212     return false;
213 }
214 
215 void SBBreakpoint::SetOneShot(bool one_shot) {
216   Log *log(lldb_private::GetLogIfAllCategoriesSet(LIBLLDB_LOG_API));
217 
218   if (log)
219     log->Printf("SBBreakpoint(%p)::SetOneShot (one_shot=%i)",
220                 static_cast<void *>(m_opaque_sp.get()), one_shot);
221 
222   if (m_opaque_sp) {
223     std::lock_guard<std::recursive_mutex> guard(
224         m_opaque_sp->GetTarget().GetAPIMutex());
225     m_opaque_sp->SetOneShot(one_shot);
226   }
227 }
228 
229 bool SBBreakpoint::IsOneShot() const {
230   if (m_opaque_sp) {
231     std::lock_guard<std::recursive_mutex> guard(
232         m_opaque_sp->GetTarget().GetAPIMutex());
233     return m_opaque_sp->IsOneShot();
234   } else
235     return false;
236 }
237 
238 bool SBBreakpoint::IsInternal() {
239   if (m_opaque_sp) {
240     std::lock_guard<std::recursive_mutex> guard(
241         m_opaque_sp->GetTarget().GetAPIMutex());
242     return m_opaque_sp->IsInternal();
243   } else
244     return false;
245 }
246 
247 void SBBreakpoint::SetIgnoreCount(uint32_t count) {
248   Log *log(lldb_private::GetLogIfAllCategoriesSet(LIBLLDB_LOG_API));
249 
250   if (log)
251     log->Printf("SBBreakpoint(%p)::SetIgnoreCount (count=%u)",
252                 static_cast<void *>(m_opaque_sp.get()), count);
253 
254   if (m_opaque_sp) {
255     std::lock_guard<std::recursive_mutex> guard(
256         m_opaque_sp->GetTarget().GetAPIMutex());
257     m_opaque_sp->SetIgnoreCount(count);
258   }
259 }
260 
261 void SBBreakpoint::SetCondition(const char *condition) {
262   if (m_opaque_sp) {
263     std::lock_guard<std::recursive_mutex> guard(
264         m_opaque_sp->GetTarget().GetAPIMutex());
265     m_opaque_sp->SetCondition(condition);
266   }
267 }
268 
269 const char *SBBreakpoint::GetCondition() {
270   if (m_opaque_sp) {
271     std::lock_guard<std::recursive_mutex> guard(
272         m_opaque_sp->GetTarget().GetAPIMutex());
273     return m_opaque_sp->GetConditionText();
274   }
275   return nullptr;
276 }
277 
278 uint32_t SBBreakpoint::GetHitCount() const {
279   uint32_t count = 0;
280   if (m_opaque_sp) {
281     std::lock_guard<std::recursive_mutex> guard(
282         m_opaque_sp->GetTarget().GetAPIMutex());
283     count = m_opaque_sp->GetHitCount();
284   }
285 
286   Log *log(lldb_private::GetLogIfAllCategoriesSet(LIBLLDB_LOG_API));
287   if (log)
288     log->Printf("SBBreakpoint(%p)::GetHitCount () => %u",
289                 static_cast<void *>(m_opaque_sp.get()), count);
290 
291   return count;
292 }
293 
294 uint32_t SBBreakpoint::GetIgnoreCount() const {
295   uint32_t count = 0;
296   if (m_opaque_sp) {
297     std::lock_guard<std::recursive_mutex> guard(
298         m_opaque_sp->GetTarget().GetAPIMutex());
299     count = m_opaque_sp->GetIgnoreCount();
300   }
301 
302   Log *log(lldb_private::GetLogIfAllCategoriesSet(LIBLLDB_LOG_API));
303   if (log)
304     log->Printf("SBBreakpoint(%p)::GetIgnoreCount () => %u",
305                 static_cast<void *>(m_opaque_sp.get()), count);
306 
307   return count;
308 }
309 
310 void SBBreakpoint::SetThreadID(tid_t tid) {
311   if (m_opaque_sp) {
312     std::lock_guard<std::recursive_mutex> guard(
313         m_opaque_sp->GetTarget().GetAPIMutex());
314     m_opaque_sp->SetThreadID(tid);
315   }
316   Log *log(lldb_private::GetLogIfAllCategoriesSet(LIBLLDB_LOG_API));
317   if (log)
318     log->Printf("SBBreakpoint(%p)::SetThreadID (tid=0x%4.4" PRIx64 ")",
319                 static_cast<void *>(m_opaque_sp.get()), tid);
320 }
321 
322 tid_t SBBreakpoint::GetThreadID() {
323   tid_t tid = LLDB_INVALID_THREAD_ID;
324   if (m_opaque_sp) {
325     std::lock_guard<std::recursive_mutex> guard(
326         m_opaque_sp->GetTarget().GetAPIMutex());
327     tid = m_opaque_sp->GetThreadID();
328   }
329 
330   Log *log(lldb_private::GetLogIfAllCategoriesSet(LIBLLDB_LOG_API));
331   if (log)
332     log->Printf("SBBreakpoint(%p)::GetThreadID () => 0x%4.4" PRIx64,
333                 static_cast<void *>(m_opaque_sp.get()), tid);
334   return tid;
335 }
336 
337 void SBBreakpoint::SetThreadIndex(uint32_t index) {
338   Log *log(lldb_private::GetLogIfAllCategoriesSet(LIBLLDB_LOG_API));
339   if (log)
340     log->Printf("SBBreakpoint(%p)::SetThreadIndex (%u)",
341                 static_cast<void *>(m_opaque_sp.get()), index);
342   if (m_opaque_sp) {
343     std::lock_guard<std::recursive_mutex> guard(
344         m_opaque_sp->GetTarget().GetAPIMutex());
345     m_opaque_sp->GetOptions()->GetThreadSpec()->SetIndex(index);
346   }
347 }
348 
349 uint32_t SBBreakpoint::GetThreadIndex() const {
350   uint32_t thread_idx = UINT32_MAX;
351   if (m_opaque_sp) {
352     std::lock_guard<std::recursive_mutex> guard(
353         m_opaque_sp->GetTarget().GetAPIMutex());
354     const ThreadSpec *thread_spec =
355         m_opaque_sp->GetOptions()->GetThreadSpecNoCreate();
356     if (thread_spec != nullptr)
357       thread_idx = thread_spec->GetIndex();
358   }
359   Log *log(lldb_private::GetLogIfAllCategoriesSet(LIBLLDB_LOG_API));
360   if (log)
361     log->Printf("SBBreakpoint(%p)::GetThreadIndex () => %u",
362                 static_cast<void *>(m_opaque_sp.get()), thread_idx);
363 
364   return thread_idx;
365 }
366 
367 void SBBreakpoint::SetThreadName(const char *thread_name) {
368   Log *log(lldb_private::GetLogIfAllCategoriesSet(LIBLLDB_LOG_API));
369   if (log)
370     log->Printf("SBBreakpoint(%p)::SetThreadName (%s)",
371                 static_cast<void *>(m_opaque_sp.get()), thread_name);
372 
373   if (m_opaque_sp) {
374     std::lock_guard<std::recursive_mutex> guard(
375         m_opaque_sp->GetTarget().GetAPIMutex());
376     m_opaque_sp->GetOptions()->GetThreadSpec()->SetName(thread_name);
377   }
378 }
379 
380 const char *SBBreakpoint::GetThreadName() const {
381   const char *name = nullptr;
382   if (m_opaque_sp) {
383     std::lock_guard<std::recursive_mutex> guard(
384         m_opaque_sp->GetTarget().GetAPIMutex());
385     const ThreadSpec *thread_spec =
386         m_opaque_sp->GetOptions()->GetThreadSpecNoCreate();
387     if (thread_spec != nullptr)
388       name = thread_spec->GetName();
389   }
390   Log *log(lldb_private::GetLogIfAllCategoriesSet(LIBLLDB_LOG_API));
391   if (log)
392     log->Printf("SBBreakpoint(%p)::GetThreadName () => %s",
393                 static_cast<void *>(m_opaque_sp.get()), name);
394 
395   return name;
396 }
397 
398 void SBBreakpoint::SetQueueName(const char *queue_name) {
399   Log *log(lldb_private::GetLogIfAllCategoriesSet(LIBLLDB_LOG_API));
400   if (log)
401     log->Printf("SBBreakpoint(%p)::SetQueueName (%s)",
402                 static_cast<void *>(m_opaque_sp.get()), queue_name);
403   if (m_opaque_sp) {
404     std::lock_guard<std::recursive_mutex> guard(
405         m_opaque_sp->GetTarget().GetAPIMutex());
406     m_opaque_sp->GetOptions()->GetThreadSpec()->SetQueueName(queue_name);
407   }
408 }
409 
410 const char *SBBreakpoint::GetQueueName() const {
411   const char *name = nullptr;
412   if (m_opaque_sp) {
413     std::lock_guard<std::recursive_mutex> guard(
414         m_opaque_sp->GetTarget().GetAPIMutex());
415     const ThreadSpec *thread_spec =
416         m_opaque_sp->GetOptions()->GetThreadSpecNoCreate();
417     if (thread_spec)
418       name = thread_spec->GetQueueName();
419   }
420   Log *log(lldb_private::GetLogIfAllCategoriesSet(LIBLLDB_LOG_API));
421   if (log)
422     log->Printf("SBBreakpoint(%p)::GetQueueName () => %s",
423                 static_cast<void *>(m_opaque_sp.get()), name);
424 
425   return name;
426 }
427 
428 size_t SBBreakpoint::GetNumResolvedLocations() const {
429   size_t num_resolved = 0;
430   if (m_opaque_sp) {
431     std::lock_guard<std::recursive_mutex> guard(
432         m_opaque_sp->GetTarget().GetAPIMutex());
433     num_resolved = m_opaque_sp->GetNumResolvedLocations();
434   }
435   Log *log(lldb_private::GetLogIfAllCategoriesSet(LIBLLDB_LOG_API));
436   if (log)
437     log->Printf("SBBreakpoint(%p)::GetNumResolvedLocations () => %" PRIu64,
438                 static_cast<void *>(m_opaque_sp.get()),
439                 static_cast<uint64_t>(num_resolved));
440   return num_resolved;
441 }
442 
443 size_t SBBreakpoint::GetNumLocations() const {
444   size_t num_locs = 0;
445   if (m_opaque_sp) {
446     std::lock_guard<std::recursive_mutex> guard(
447         m_opaque_sp->GetTarget().GetAPIMutex());
448     num_locs = m_opaque_sp->GetNumLocations();
449   }
450   Log *log(lldb_private::GetLogIfAllCategoriesSet(LIBLLDB_LOG_API));
451   if (log)
452     log->Printf("SBBreakpoint(%p)::GetNumLocations () => %" PRIu64,
453                 static_cast<void *>(m_opaque_sp.get()),
454                 static_cast<uint64_t>(num_locs));
455   return num_locs;
456 }
457 
458 bool SBBreakpoint::GetDescription(SBStream &s) {
459   if (m_opaque_sp) {
460     std::lock_guard<std::recursive_mutex> guard(
461         m_opaque_sp->GetTarget().GetAPIMutex());
462     s.Printf("SBBreakpoint: id = %i, ", m_opaque_sp->GetID());
463     m_opaque_sp->GetResolverDescription(s.get());
464     m_opaque_sp->GetFilterDescription(s.get());
465     const size_t num_locations = m_opaque_sp->GetNumLocations();
466     s.Printf(", locations = %" PRIu64, (uint64_t)num_locations);
467     return true;
468   }
469   s.Printf("No value");
470   return false;
471 }
472 
473 bool SBBreakpoint::PrivateBreakpointHitCallback(void *baton,
474                                                 StoppointCallbackContext *ctx,
475                                                 lldb::user_id_t break_id,
476                                                 lldb::user_id_t break_loc_id) {
477   ExecutionContext exe_ctx(ctx->exe_ctx_ref);
478   BreakpointSP bp_sp(
479       exe_ctx.GetTargetRef().GetBreakpointList().FindBreakpointByID(break_id));
480   if (baton && bp_sp) {
481     CallbackData *data = (CallbackData *)baton;
482     lldb_private::Breakpoint *bp = bp_sp.get();
483     if (bp && data->callback) {
484       Process *process = exe_ctx.GetProcessPtr();
485       if (process) {
486         SBProcess sb_process(process->shared_from_this());
487         SBThread sb_thread;
488         SBBreakpointLocation sb_location;
489         assert(bp_sp);
490         sb_location.SetLocation(bp_sp->FindLocationByID(break_loc_id));
491         Thread *thread = exe_ctx.GetThreadPtr();
492         if (thread)
493           sb_thread.SetThread(thread->shared_from_this());
494 
495         return data->callback(data->callback_baton, sb_process, sb_thread,
496                               sb_location);
497       }
498     }
499   }
500   return true; // Return true if we should stop at this breakpoint
501 }
502 
503 void SBBreakpoint::SetCallback(BreakpointHitCallback callback, void *baton) {
504   Log *log(lldb_private::GetLogIfAllCategoriesSet(LIBLLDB_LOG_API));
505 
506   if (log) {
507     void *pointer = &callback;
508     log->Printf("SBBreakpoint(%p)::SetCallback (callback=%p, baton=%p)",
509                 static_cast<void *>(m_opaque_sp.get()),
510                 *static_cast<void **>(&pointer), static_cast<void *>(baton));
511   }
512 
513   if (m_opaque_sp) {
514     std::lock_guard<std::recursive_mutex> guard(
515         m_opaque_sp->GetTarget().GetAPIMutex());
516     BatonSP baton_sp(new SBBreakpointCallbackBaton(callback, baton));
517     m_opaque_sp->SetCallback(SBBreakpoint::PrivateBreakpointHitCallback,
518                              baton_sp, false);
519   }
520 }
521 
522 void SBBreakpoint::SetScriptCallbackFunction(
523     const char *callback_function_name) {
524   Log *log(lldb_private::GetLogIfAllCategoriesSet(LIBLLDB_LOG_API));
525 
526   if (log)
527     log->Printf("SBBreakpoint(%p)::SetScriptCallbackFunction (callback=%s)",
528                 static_cast<void *>(m_opaque_sp.get()), callback_function_name);
529 
530   if (m_opaque_sp) {
531     std::lock_guard<std::recursive_mutex> guard(
532         m_opaque_sp->GetTarget().GetAPIMutex());
533     BreakpointOptions *bp_options = m_opaque_sp->GetOptions();
534     m_opaque_sp->GetTarget()
535         .GetDebugger()
536         .GetCommandInterpreter()
537         .GetScriptInterpreter()
538         ->SetBreakpointCommandCallbackFunction(bp_options,
539                                                callback_function_name);
540   }
541 }
542 
543 SBError SBBreakpoint::SetScriptCallbackBody(const char *callback_body_text) {
544   Log *log(lldb_private::GetLogIfAllCategoriesSet(LIBLLDB_LOG_API));
545 
546   if (log)
547     log->Printf("SBBreakpoint(%p)::SetScriptCallbackBody: callback body:\n%s)",
548                 static_cast<void *>(m_opaque_sp.get()), callback_body_text);
549 
550   SBError sb_error;
551   if (m_opaque_sp) {
552     std::lock_guard<std::recursive_mutex> guard(
553         m_opaque_sp->GetTarget().GetAPIMutex());
554     BreakpointOptions *bp_options = m_opaque_sp->GetOptions();
555     Error error =
556         m_opaque_sp->GetTarget()
557             .GetDebugger()
558             .GetCommandInterpreter()
559             .GetScriptInterpreter()
560             ->SetBreakpointCommandCallback(bp_options, callback_body_text);
561     sb_error.SetError(error);
562   } else
563     sb_error.SetErrorString("invalid breakpoint");
564 
565   return sb_error;
566 }
567 
568 bool SBBreakpoint::AddName(const char *new_name) {
569   Log *log(lldb_private::GetLogIfAllCategoriesSet(LIBLLDB_LOG_API));
570 
571   if (log)
572     log->Printf("SBBreakpoint(%p)::AddName (name=%s)",
573                 static_cast<void *>(m_opaque_sp.get()), new_name);
574 
575   if (m_opaque_sp) {
576     std::lock_guard<std::recursive_mutex> guard(
577         m_opaque_sp->GetTarget().GetAPIMutex());
578     Error error; // Think I'm just going to swallow the error here, it's
579                  // probably more annoying to have to provide it.
580     return m_opaque_sp->AddName(new_name, error);
581   }
582 
583   return false;
584 }
585 
586 void SBBreakpoint::RemoveName(const char *name_to_remove) {
587   Log *log(lldb_private::GetLogIfAllCategoriesSet(LIBLLDB_LOG_API));
588 
589   if (log)
590     log->Printf("SBBreakpoint(%p)::RemoveName (name=%s)",
591                 static_cast<void *>(m_opaque_sp.get()), name_to_remove);
592 
593   if (m_opaque_sp) {
594     std::lock_guard<std::recursive_mutex> guard(
595         m_opaque_sp->GetTarget().GetAPIMutex());
596     m_opaque_sp->RemoveName(name_to_remove);
597   }
598 }
599 
600 bool SBBreakpoint::MatchesName(const char *name) {
601   Log *log(lldb_private::GetLogIfAllCategoriesSet(LIBLLDB_LOG_API));
602 
603   if (log)
604     log->Printf("SBBreakpoint(%p)::MatchesName (name=%s)",
605                 static_cast<void *>(m_opaque_sp.get()), name);
606 
607   if (m_opaque_sp) {
608     std::lock_guard<std::recursive_mutex> guard(
609         m_opaque_sp->GetTarget().GetAPIMutex());
610     return m_opaque_sp->MatchesName(name);
611   }
612 
613   return false;
614 }
615 
616 void SBBreakpoint::GetNames(SBStringList &names) {
617   Log *log(lldb_private::GetLogIfAllCategoriesSet(LIBLLDB_LOG_API));
618 
619   if (log)
620     log->Printf("SBBreakpoint(%p)::GetNames ()",
621                 static_cast<void *>(m_opaque_sp.get()));
622 
623   if (m_opaque_sp) {
624     std::lock_guard<std::recursive_mutex> guard(
625         m_opaque_sp->GetTarget().GetAPIMutex());
626     std::vector<std::string> names_vec;
627     m_opaque_sp->GetNames(names_vec);
628     for (std::string name : names_vec) {
629       names.AppendString(name.c_str());
630     }
631   }
632 }
633 
634 lldb_private::Breakpoint *SBBreakpoint::operator->() const {
635   return m_opaque_sp.get();
636 }
637 
638 lldb_private::Breakpoint *SBBreakpoint::get() const {
639   return m_opaque_sp.get();
640 }
641 
642 lldb::BreakpointSP &SBBreakpoint::operator*() { return m_opaque_sp; }
643 
644 const lldb::BreakpointSP &SBBreakpoint::operator*() const {
645   return m_opaque_sp;
646 }
647 
648 bool SBBreakpoint::EventIsBreakpointEvent(const lldb::SBEvent &event) {
649   return Breakpoint::BreakpointEventData::GetEventDataFromEvent(event.get()) !=
650          nullptr;
651 }
652 
653 BreakpointEventType
654 SBBreakpoint::GetBreakpointEventTypeFromEvent(const SBEvent &event) {
655   if (event.IsValid())
656     return Breakpoint::BreakpointEventData::GetBreakpointEventTypeFromEvent(
657         event.GetSP());
658   return eBreakpointEventTypeInvalidType;
659 }
660 
661 SBBreakpoint SBBreakpoint::GetBreakpointFromEvent(const lldb::SBEvent &event) {
662   SBBreakpoint sb_breakpoint;
663   if (event.IsValid())
664     sb_breakpoint.m_opaque_sp =
665         Breakpoint::BreakpointEventData::GetBreakpointFromEvent(event.GetSP());
666   return sb_breakpoint;
667 }
668 
669 SBBreakpointLocation
670 SBBreakpoint::GetBreakpointLocationAtIndexFromEvent(const lldb::SBEvent &event,
671                                                     uint32_t loc_idx) {
672   SBBreakpointLocation sb_breakpoint_loc;
673   if (event.IsValid())
674     sb_breakpoint_loc.SetLocation(
675         Breakpoint::BreakpointEventData::GetBreakpointLocationAtIndexFromEvent(
676             event.GetSP(), loc_idx));
677   return sb_breakpoint_loc;
678 }
679 
680 uint32_t
681 SBBreakpoint::GetNumBreakpointLocationsFromEvent(const lldb::SBEvent &event) {
682   uint32_t num_locations = 0;
683   if (event.IsValid())
684     num_locations =
685         (Breakpoint::BreakpointEventData::GetNumBreakpointLocationsFromEvent(
686             event.GetSP()));
687   return num_locations;
688 }
689