blob: b2ed5e71699d0b0e457e90d7489f55ffac3cdf5f [file] [log] [blame]
Jim Inghamb842f2e2017-09-14 20:22:49 +00001//===-- SBBreakpointName.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/SBBreakpointName.h"
15#include "lldb/API/SBDebugger.h"
16#include "lldb/API/SBError.h"
17#include "lldb/API/SBStream.h"
18#include "lldb/API/SBStringList.h"
19#include "lldb/API/SBTarget.h"
20
21#include "lldb/Breakpoint/BreakpointName.h"
22#include "lldb/Breakpoint/StoppointCallbackContext.h"
23#include "lldb/Core/Debugger.h"
24#include "lldb/Interpreter/CommandInterpreter.h"
25#include "lldb/Interpreter/ScriptInterpreter.h"
26#include "lldb/Target/Target.h"
27#include "lldb/Target/ThreadSpec.h"
28#include "lldb/Utility/Log.h"
29#include "lldb/Utility/Stream.h"
30
31#include "SBBreakpointOptionCommon.h"
32
33using namespace lldb;
34using namespace lldb_private;
35
36namespace lldb
37{
38class SBBreakpointNameImpl {
39public:
40 SBBreakpointNameImpl(SBTarget &sb_target, const char *name)
41 {
42 if (!name || name[0] == '\0')
43 return;
44 m_name.assign(name);
45
46 if (!sb_target.IsValid())
47 return;
48
49 TargetSP target_sp = sb_target.GetSP();
50 if (!target_sp)
51 return;
52
53 m_target_wp = target_sp;
54 }
55
56 SBBreakpointNameImpl(TargetSP target_sp, const char *name)
57 {
58 if (!name || name[0] == '\0')
59 return;
60 m_name.assign(name);
61
62 if (!target_sp)
63 return;
64
65 m_target_wp = target_sp;
66 }
67
68 bool operator==(const SBBreakpointNameImpl &rhs) {
69 return m_name == rhs.m_name
70 && m_target_wp.lock() == rhs.m_target_wp.lock();
71 }
72
73 bool operator!=(const SBBreakpointNameImpl &rhs) {
74 return m_name != rhs.m_name
75 || m_target_wp.lock() != rhs.m_target_wp.lock();
76 }
77 // For now we take a simple approach and only keep the name, and relook
78 // up the location when we need it.
79
80 TargetSP GetTarget() {
81 return m_target_wp.lock();
82 }
83
84 const char *GetName() {
85 return m_name.c_str();
86 }
87
88 bool IsValid() {
89 return !m_name.empty() && m_target_wp.lock();
90 }
91
92 lldb_private::BreakpointName *GetBreakpointName()
93 {
94 if (!IsValid())
95 return nullptr;
96 TargetSP target_sp = GetTarget();
97 if (!target_sp)
98 return nullptr;
99 Status error;
100 return target_sp->FindBreakpointName(ConstString(m_name), true, error);
101 }
102
103 const lldb_private::BreakpointName *GetBreakpointName() const
104 {
105 return GetBreakpointName();
106 }
107
108private:
109 TargetWP m_target_wp;
110 std::string m_name;
111};
112} // namespace lldb
113
114SBBreakpointName::SBBreakpointName() {}
115
116SBBreakpointName::SBBreakpointName(SBTarget &sb_target, const char *name)
117{
118 m_impl_up.reset(new SBBreakpointNameImpl(sb_target, name));
119 // Call FindBreakpointName here to make sure the name is valid, reset if
120 // not:
121 BreakpointName *bp_name = GetBreakpointName();
122 if (!bp_name)
123 m_impl_up.reset();
124}
125
126SBBreakpointName::SBBreakpointName(SBBreakpoint &sb_bkpt, const char *name)
127{
128 if (!sb_bkpt.IsValid()) {
129 m_impl_up.reset();
130 return;
131 }
132 BreakpointSP bkpt_sp = sb_bkpt.GetSP();
133 Target &target = bkpt_sp->GetTarget();
134
135 m_impl_up.reset(new SBBreakpointNameImpl(target.shared_from_this(), name));
136
137 // Call FindBreakpointName here to make sure the name is valid, reset if
138 // not:
139 BreakpointName *bp_name = GetBreakpointName();
140 if (!bp_name) {
141 m_impl_up.reset();
142 return;
143 }
144
145 // Now copy over the breakpoint's options:
146 target.ConfigureBreakpointName(*bp_name, *bkpt_sp->GetOptions(),
147 BreakpointName::Permissions());
148}
149
150SBBreakpointName::SBBreakpointName(const SBBreakpointName &rhs)
151{
152 if (!rhs.m_impl_up)
153 return;
154 else
155 m_impl_up.reset(new SBBreakpointNameImpl(rhs.m_impl_up->GetTarget(),
156 rhs.m_impl_up->GetName()));
157}
158
159SBBreakpointName::~SBBreakpointName() = default;
160
161const SBBreakpointName &SBBreakpointName::operator=(const SBBreakpointName &rhs)
162{
163 if (!rhs.m_impl_up) {
164 m_impl_up.reset();
165 return *this;
166 }
167
168 m_impl_up.reset(new SBBreakpointNameImpl(rhs.m_impl_up->GetTarget(),
169 rhs.m_impl_up->GetName()));
170 return *this;
171}
172
173bool SBBreakpointName::operator==(const lldb::SBBreakpointName &rhs) {
174 return *m_impl_up.get() == *rhs.m_impl_up.get();
175}
176
177bool SBBreakpointName::operator!=(const lldb::SBBreakpointName &rhs) {
178 return *m_impl_up.get() != *rhs.m_impl_up.get();
179}
180
181bool SBBreakpointName::IsValid() const {
182 if (!m_impl_up)
183 return false;
184 return m_impl_up->IsValid();
185}
186
187const char *SBBreakpointName::GetName() const {
188 if (!m_impl_up)
189 return "<Invalid Breakpoint Name Object>";
190 return m_impl_up->GetName();
191}
192
193void SBBreakpointName::SetEnabled(bool enable) {
194 Log *log(lldb_private::GetLogIfAllCategoriesSet(LIBLLDB_LOG_API));
195
196 BreakpointName *bp_name = GetBreakpointName();
197 if (!bp_name)
198 return;
199
200 LLDB_LOG(log, "Name: {0} enabled: {1}\n", bp_name->GetName(), enable);
201 std::lock_guard<std::recursive_mutex> guard(
202 m_impl_up->GetTarget()->GetAPIMutex());
203
204 bp_name->GetOptions().SetEnabled(enable);
205}
206
207void SBBreakpointName::UpdateName(BreakpointName &bp_name) {
208 if (!IsValid())
209 return;
210
211 TargetSP target_sp = m_impl_up->GetTarget();
212 if (!target_sp)
213 return;
214 target_sp->ApplyNameToBreakpoints(bp_name);
215
216}
217
218bool SBBreakpointName::IsEnabled() {
219 Log *log(lldb_private::GetLogIfAllCategoriesSet(LIBLLDB_LOG_API));
220
221 BreakpointName *bp_name = GetBreakpointName();
222 if (!bp_name)
223 return false;
224
225 LLDB_LOG(log, "Name: {0}\n", bp_name->GetName());
226 std::lock_guard<std::recursive_mutex> guard(
227 m_impl_up->GetTarget()->GetAPIMutex());
228
229 return bp_name->GetOptions().IsEnabled();
230}
231
232void SBBreakpointName::SetOneShot(bool one_shot) {
233 Log *log(lldb_private::GetLogIfAllCategoriesSet(LIBLLDB_LOG_API));
234
235 BreakpointName *bp_name = GetBreakpointName();
236 if (!bp_name)
237 return;
238
239 LLDB_LOG(log, "Name: {0} one_shot: {1}\n", bp_name->GetName(), one_shot);
240 std::lock_guard<std::recursive_mutex> guard(
241 m_impl_up->GetTarget()->GetAPIMutex());
242
243 bp_name->GetOptions().SetOneShot(one_shot);
244 UpdateName(*bp_name);
245}
246
247bool SBBreakpointName::IsOneShot() const {
248 Log *log(lldb_private::GetLogIfAllCategoriesSet(LIBLLDB_LOG_API));
249
250 const BreakpointName *bp_name = GetBreakpointName();
251 if (!bp_name)
252 return false;
253
254 LLDB_LOG(log, "Name: {0}\n", bp_name->GetName());
255 std::lock_guard<std::recursive_mutex> guard(
256 m_impl_up->GetTarget()->GetAPIMutex());
257
258 return bp_name->GetOptions().IsOneShot();
259}
260
261void SBBreakpointName::SetIgnoreCount(uint32_t count) {
262 Log *log(lldb_private::GetLogIfAllCategoriesSet(LIBLLDB_LOG_API));
263
264 BreakpointName *bp_name = GetBreakpointName();
265 if (!bp_name)
266 return;
267
268 LLDB_LOG(log, "Name: {0} one_shot: {1}\n", bp_name->GetName(), count);
269 std::lock_guard<std::recursive_mutex> guard(
270 m_impl_up->GetTarget()->GetAPIMutex());
271
272 bp_name->GetOptions().SetIgnoreCount(count);
273 UpdateName(*bp_name);
274}
275
276uint32_t SBBreakpointName::GetIgnoreCount() const {
277 Log *log(lldb_private::GetLogIfAllCategoriesSet(LIBLLDB_LOG_API));
278
279 BreakpointName *bp_name = GetBreakpointName();
280 if (!bp_name)
281 return false;
282
283 LLDB_LOG(log, "Name: {0}\n", bp_name->GetName());
284 std::lock_guard<std::recursive_mutex> guard(
285 m_impl_up->GetTarget()->GetAPIMutex());
286
287 return bp_name->GetOptions().GetIgnoreCount();
288}
289
290void SBBreakpointName::SetCondition(const char *condition) {
291 Log *log(lldb_private::GetLogIfAllCategoriesSet(LIBLLDB_LOG_API));
292
293 BreakpointName *bp_name = GetBreakpointName();
294 if (!bp_name)
295 return;
296
297 LLDB_LOG(log, "Name: {0} one_shot: {1}\n", bp_name->GetName(),
298 condition ? condition : "<NULL>");
299
300 std::lock_guard<std::recursive_mutex> guard(
301 m_impl_up->GetTarget()->GetAPIMutex());
302
303 bp_name->GetOptions().SetCondition(condition);
304 UpdateName(*bp_name);
305}
306
307const char *SBBreakpointName::GetCondition() {
308 Log *log(lldb_private::GetLogIfAllCategoriesSet(LIBLLDB_LOG_API));
309
310 BreakpointName *bp_name = GetBreakpointName();
311 if (!bp_name)
312 return nullptr;
313
314 LLDB_LOG(log, "Name: {0}\n", bp_name->GetName());
315 std::lock_guard<std::recursive_mutex> guard(
316 m_impl_up->GetTarget()->GetAPIMutex());
317
318 return bp_name->GetOptions().GetConditionText();
319}
320
321void SBBreakpointName::SetAutoContinue(bool auto_continue) {
322 Log *log(lldb_private::GetLogIfAllCategoriesSet(LIBLLDB_LOG_API));
323
324 BreakpointName *bp_name = GetBreakpointName();
325 if (!bp_name)
326 return;
327
328 LLDB_LOG(log, "Name: {0} auto-continue: {1}\n", bp_name->GetName(), auto_continue);
329
330 std::lock_guard<std::recursive_mutex> guard(
331 m_impl_up->GetTarget()->GetAPIMutex());
332
333 bp_name->GetOptions().SetAutoContinue(auto_continue);
334 UpdateName(*bp_name);
335}
336
337bool SBBreakpointName::GetAutoContinue() {
338 Log *log(lldb_private::GetLogIfAllCategoriesSet(LIBLLDB_LOG_API));
339
340 BreakpointName *bp_name = GetBreakpointName();
341 if (!bp_name)
342 return nullptr;
343
344 LLDB_LOG(log, "Name: {0}\n", bp_name->GetName());
345 std::lock_guard<std::recursive_mutex> guard(
346 m_impl_up->GetTarget()->GetAPIMutex());
347
348 return bp_name->GetOptions().IsAutoContinue();
349}
350
351void SBBreakpointName::SetThreadID(tid_t tid) {
352 Log *log(lldb_private::GetLogIfAllCategoriesSet(LIBLLDB_LOG_API));
353
354 BreakpointName *bp_name = GetBreakpointName();
355 if (!bp_name)
356 return;
357
358 LLDB_LOG(log, "Name: {0} tid: {1:x}\n", bp_name->GetName(), tid);
359
360 std::lock_guard<std::recursive_mutex> guard(
361 m_impl_up->GetTarget()->GetAPIMutex());
362
363 bp_name->GetOptions().SetThreadID(tid);
364 UpdateName(*bp_name);
365}
366
367tid_t SBBreakpointName::GetThreadID() {
368 Log *log(lldb_private::GetLogIfAllCategoriesSet(LIBLLDB_LOG_API));
369
370 BreakpointName *bp_name = GetBreakpointName();
371 if (!bp_name)
372 return LLDB_INVALID_THREAD_ID;
373
374 LLDB_LOG(log, "Name: {0}\n", bp_name->GetName());
375 std::lock_guard<std::recursive_mutex> guard(
376 m_impl_up->GetTarget()->GetAPIMutex());
377
378 return bp_name->GetOptions().GetThreadSpec()->GetTID();
379}
380
381void SBBreakpointName::SetThreadIndex(uint32_t index) {
382 Log *log(lldb_private::GetLogIfAllCategoriesSet(LIBLLDB_LOG_API));
383
384 BreakpointName *bp_name = GetBreakpointName();
385 if (!bp_name)
386 return;
387
388 LLDB_LOG(log, "Name: {0} thread index: {1}\n", bp_name->GetName(), index);
389
390 std::lock_guard<std::recursive_mutex> guard(
391 m_impl_up->GetTarget()->GetAPIMutex());
392
393 bp_name->GetOptions().GetThreadSpec()->SetIndex(index);
394 UpdateName(*bp_name);
395}
396
397uint32_t SBBreakpointName::GetThreadIndex() const {
398 Log *log(lldb_private::GetLogIfAllCategoriesSet(LIBLLDB_LOG_API));
399
400 BreakpointName *bp_name = GetBreakpointName();
401 if (!bp_name)
402 return LLDB_INVALID_THREAD_ID;
403
404 LLDB_LOG(log, "Name: {0}\n", bp_name->GetName());
405 std::lock_guard<std::recursive_mutex> guard(
406 m_impl_up->GetTarget()->GetAPIMutex());
407
408 return bp_name->GetOptions().GetThreadSpec()->GetIndex();
409}
410
411void SBBreakpointName::SetThreadName(const char *thread_name) {
412 Log *log(lldb_private::GetLogIfAllCategoriesSet(LIBLLDB_LOG_API));
413
414 BreakpointName *bp_name = GetBreakpointName();
415 if (!bp_name)
416 return;
417
418 LLDB_LOG(log, "Name: {0} thread name: {1}\n", bp_name->GetName(), thread_name);
419
420 std::lock_guard<std::recursive_mutex> guard(
421 m_impl_up->GetTarget()->GetAPIMutex());
422
423 bp_name->GetOptions().GetThreadSpec()->SetName(thread_name);
424 UpdateName(*bp_name);
425}
426
427const char *SBBreakpointName::GetThreadName() const {
428 Log *log(lldb_private::GetLogIfAllCategoriesSet(LIBLLDB_LOG_API));
429
430 BreakpointName *bp_name = GetBreakpointName();
431 if (!bp_name)
432 return nullptr;
433
434 LLDB_LOG(log, "Name: {0}\n", bp_name->GetName());
435 std::lock_guard<std::recursive_mutex> guard(
436 m_impl_up->GetTarget()->GetAPIMutex());
437
438 return bp_name->GetOptions().GetThreadSpec()->GetName();
439}
440
441void SBBreakpointName::SetQueueName(const char *queue_name) {
442 Log *log(lldb_private::GetLogIfAllCategoriesSet(LIBLLDB_LOG_API));
443
444 BreakpointName *bp_name = GetBreakpointName();
445 if (!bp_name)
446 return;
447
448 LLDB_LOG(log, "Name: {0} queue name: {1}\n", bp_name->GetName(), queue_name);
449
450 std::lock_guard<std::recursive_mutex> guard(
451 m_impl_up->GetTarget()->GetAPIMutex());
452
453 bp_name->GetOptions().GetThreadSpec()->SetQueueName(queue_name);
454 UpdateName(*bp_name);
455}
456
457const char *SBBreakpointName::GetQueueName() const {
458 Log *log(lldb_private::GetLogIfAllCategoriesSet(LIBLLDB_LOG_API));
459
460 BreakpointName *bp_name = GetBreakpointName();
461 if (!bp_name)
462 return nullptr;
463
464 LLDB_LOG(log, "Name: {0}\n", bp_name->GetName());
465 std::lock_guard<std::recursive_mutex> guard(
466 m_impl_up->GetTarget()->GetAPIMutex());
467
468 return bp_name->GetOptions().GetThreadSpec()->GetQueueName();
469}
470
471void SBBreakpointName::SetCommandLineCommands(SBStringList &commands) {
472 Log *log(lldb_private::GetLogIfAllCategoriesSet(LIBLLDB_LOG_API));
473 BreakpointName *bp_name = GetBreakpointName();
474 if (!bp_name)
475 return;
476 if (commands.GetSize() == 0)
477 return;
478
479 LLDB_LOG(log, "Name: {0} commands\n", bp_name->GetName());
480
481 std::lock_guard<std::recursive_mutex> guard(
482 m_impl_up->GetTarget()->GetAPIMutex());
483 std::unique_ptr<BreakpointOptions::CommandData> cmd_data_up(
484 new BreakpointOptions::CommandData(*commands, eScriptLanguageNone));
485
486 bp_name->GetOptions().SetCommandDataCallback(cmd_data_up);
487 UpdateName(*bp_name);
488}
489
490bool SBBreakpointName::GetCommandLineCommands(SBStringList &commands) {
491 Log *log(lldb_private::GetLogIfAllCategoriesSet(LIBLLDB_LOG_API));
492
493 BreakpointName *bp_name = GetBreakpointName();
494 if (!bp_name)
495 return false;
496
497 LLDB_LOG(log, "Name: {0}\n", bp_name->GetName());
498 StringList command_list;
499 bool has_commands =
500 bp_name->GetOptions().GetCommandLineCallbacks(command_list);
501 if (has_commands)
502 commands.AppendList(command_list);
503 return has_commands;
504}
505
506bool SBBreakpointName::GetDescription(SBStream &s) {
507 Log *log(lldb_private::GetLogIfAllCategoriesSet(LIBLLDB_LOG_API));
508
509 BreakpointName *bp_name = GetBreakpointName();
510 if (!bp_name)
511 {
512 s.Printf("No value");
513 return false;
514 }
515
516 LLDB_LOG(log, "Name: {0}\n", bp_name->GetName());
517 std::lock_guard<std::recursive_mutex> guard(
518 m_impl_up->GetTarget()->GetAPIMutex());
519 bp_name->GetDescription(s.get(), eDescriptionLevelFull);
520 return true;
521}
522
523void SBBreakpointName::SetCallback(SBBreakpointHitCallback callback,
524 void *baton) {
525 Log *log(lldb_private::GetLogIfAllCategoriesSet(LIBLLDB_LOG_API));
526 BreakpointName *bp_name = GetBreakpointName();
527 if (!bp_name)
528 return;
529 LLDB_LOG(log, "callback = {1}, baton = {2}", callback, baton);
530 std::lock_guard<std::recursive_mutex> guard(
531 m_impl_up->GetTarget()->GetAPIMutex());
532
533 BatonSP baton_sp(new SBBreakpointCallbackBaton(callback, baton));
534 bp_name->GetOptions().SetCallback(SBBreakpointCallbackBaton
535 ::PrivateBreakpointHitCallback,
536 baton_sp,
537 false);
538 UpdateName(*bp_name);
539}
540
541void SBBreakpointName::SetScriptCallbackFunction(
542 const char *callback_function_name) {
543 Log *log(lldb_private::GetLogIfAllCategoriesSet(LIBLLDB_LOG_API));
544
545 BreakpointName *bp_name = GetBreakpointName();
546 if (!bp_name)
547 return;
548
549 LLDB_LOG(log, "Name: {0} callback: {1}\n", bp_name->GetName(),
550 callback_function_name);
551
552 std::lock_guard<std::recursive_mutex> guard(
553 m_impl_up->GetTarget()->GetAPIMutex());
554
555 BreakpointOptions &bp_options = bp_name->GetOptions();
556 m_impl_up->GetTarget()
557 ->GetDebugger()
558 .GetCommandInterpreter()
559 .GetScriptInterpreter()
560 ->SetBreakpointCommandCallbackFunction(&bp_options,
561 callback_function_name);
562 UpdateName(*bp_name);
563}
564
565SBError SBBreakpointName::SetScriptCallbackBody(const char *callback_body_text)
566{
567 Log *log(lldb_private::GetLogIfAllCategoriesSet(LIBLLDB_LOG_API));
568 SBError sb_error;
569 BreakpointName *bp_name = GetBreakpointName();
570 if (!bp_name)
571 return sb_error;
572
573 LLDB_LOG(log, "Name: {0} callback: {1}\n", bp_name->GetName(),
574 callback_body_text);
575
576 std::lock_guard<std::recursive_mutex> guard(
577 m_impl_up->GetTarget()->GetAPIMutex());
578
579 BreakpointOptions &bp_options = bp_name->GetOptions();
580 Status error =
581 m_impl_up->GetTarget()
582 ->GetDebugger()
583 .GetCommandInterpreter()
584 .GetScriptInterpreter()
585 ->SetBreakpointCommandCallback(&bp_options, callback_body_text);
586 sb_error.SetError(error);
587 if (!sb_error.Fail())
588 UpdateName(*bp_name);
589
590 return sb_error;
591}
592
593bool SBBreakpointName::GetAllowList() const
594{
595 BreakpointName *bp_name = GetBreakpointName();
596 if (!bp_name)
597 return false;
598 return bp_name->GetPermissions().GetAllowList();
599}
600
601void SBBreakpointName::SetAllowList(bool value)
602{
603 Log *log(lldb_private::GetLogIfAllCategoriesSet(LIBLLDB_LOG_API));
604
605 BreakpointName *bp_name = GetBreakpointName();
606 if (!bp_name)
607 return;
608 if (log)
609 log->Printf("Setting allow list to %u for %s.", value,
610 bp_name->GetName().AsCString());
611 bp_name->GetPermissions().SetAllowList(value);
612}
613
614bool SBBreakpointName::GetAllowDelete()
615{
616 BreakpointName *bp_name = GetBreakpointName();
617 if (!bp_name)
618 return false;
619 return bp_name->GetPermissions().GetAllowDelete();
620}
621
622void SBBreakpointName::SetAllowDelete(bool value)
623{
624 Log *log(lldb_private::GetLogIfAllCategoriesSet(LIBLLDB_LOG_API));
625
626 BreakpointName *bp_name = GetBreakpointName();
627 if (!bp_name)
628 return;
629 if (log)
630 log->Printf("Setting allow delete to %u for %s.", value,
631 bp_name->GetName().AsCString());
632 bp_name->GetPermissions().SetAllowDelete(value);
633}
634
635bool SBBreakpointName::GetAllowDisable()
636{
637 BreakpointName *bp_name = GetBreakpointName();
638 if (!bp_name)
639 return false;
640 return bp_name->GetPermissions().GetAllowDisable();
641}
642
643void SBBreakpointName::SetAllowDisable(bool value)
644{
645 Log *log(lldb_private::GetLogIfAllCategoriesSet(LIBLLDB_LOG_API));
646
647 BreakpointName *bp_name = GetBreakpointName();
648 if (!bp_name)
649 return;
650 if (log)
651 log->Printf("Setting allow disable to %u for %s.", value,
652 bp_name->GetName().AsCString());
653 bp_name->GetPermissions().SetAllowDisable(value);
654}
655
656lldb_private::BreakpointName *SBBreakpointName::GetBreakpointName() const
657{
658 if (!IsValid())
659 return nullptr;
660 return m_impl_up->GetBreakpointName();
661}
662