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