LLDB mainline
CommandObjectBreakpoint.cpp
Go to the documentation of this file.
1//===-- CommandObjectBreakpoint.cpp ---------------------------------------===//
2//
3// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
4// See https://llvm.org/LICENSE.txt for license information.
5// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
6//
7//===----------------------------------------------------------------------===//
8
27#include "lldb/Target/Target.h"
31#include "llvm/Support/FormatAdapters.h"
32
33#include <memory>
34#include <optional>
35#include <vector>
36
37using namespace lldb;
38using namespace lldb_private;
39
42 s->IndentMore();
43 bp->GetDescription(s, level, true);
44 s->IndentLess();
45 s->EOL();
46}
47
48static bool GetDefaultFile(Target &target, StackFrame *cur_frame,
49 FileSpec &file, CommandReturnObject &result) {
50 // First use the Source Manager's default file. Then use the current stack
51 // frame's file.
52 if (auto maybe_file_and_line =
54 file = maybe_file_and_line->support_file_nsp->GetSpecOnly();
55 return true;
56 }
57
58 if (cur_frame == nullptr) {
59 result.AppendError("No selected frame to use to find the default file.");
60 return false;
61 }
62 if (!cur_frame->HasDebugInformation()) {
63 result.AppendError("Cannot use the selected frame to find the default "
64 "file, it has no debug info.");
65 return false;
66 }
67
68 const SymbolContext &sc =
69 cur_frame->GetSymbolContext(eSymbolContextLineEntry);
70 if (sc.line_entry.GetFile()) {
71 file = sc.line_entry.GetFile();
72 } else {
73 result.AppendError("Can't find the file for the selected frame to "
74 "use as the default file.");
75 return false;
76 }
77 return true;
78}
79
80// Modifiable Breakpoint Options
81#pragma mark Modify::CommandOptions
82#define LLDB_OPTIONS_breakpoint_modify
83#include "CommandOptions.inc"
84
86public:
88
89 ~BreakpointOptionGroup() override = default;
90
91 llvm::ArrayRef<OptionDefinition> GetDefinitions() override {
92 return llvm::ArrayRef(g_breakpoint_modify_options);
93 }
94
95 Status SetOptionValue(uint32_t option_idx, llvm::StringRef option_arg,
96 ExecutionContext *execution_context) override {
98 const int short_option =
99 g_breakpoint_modify_options[option_idx].short_option;
100 const char *long_option =
101 g_breakpoint_modify_options[option_idx].long_option;
102
103 switch (short_option) {
104 case 'c':
105 // Normally an empty breakpoint condition marks is as unset. But we need
106 // to say it was passed in.
107 m_bp_opts.GetCondition().SetText(option_arg.str());
109 break;
110 case 'C':
111 m_commands.push_back(std::string(option_arg));
112 break;
113 case 'd':
114 m_bp_opts.SetEnabled(false);
115 break;
116 case 'e':
117 m_bp_opts.SetEnabled(true);
118 break;
119 case 'G': {
120 bool value, success;
121 value = OptionArgParser::ToBoolean(option_arg, false, &success);
122 if (success)
123 m_bp_opts.SetAutoContinue(value);
124 else
126 CreateOptionParsingError(option_arg, short_option, long_option,
128 } break;
129 case 'i': {
130 uint32_t ignore_count;
131 if (option_arg.getAsInteger(0, ignore_count))
133 CreateOptionParsingError(option_arg, short_option, long_option,
135 else
136 m_bp_opts.SetIgnoreCount(ignore_count);
137 } break;
138 case 'o': {
139 bool value, success;
140 value = OptionArgParser::ToBoolean(option_arg, false, &success);
141 if (success) {
142 m_bp_opts.SetOneShot(value);
143 } else
145 CreateOptionParsingError(option_arg, short_option, long_option,
147 } break;
148 case 't': {
150 if (option_arg == "current") {
151 if (!execution_context) {
153 option_arg, short_option, long_option,
154 "No context to determine current thread"));
155 } else {
156 ThreadSP ctx_thread_sp = execution_context->GetThreadSP();
157 if (!ctx_thread_sp || !ctx_thread_sp->IsValid()) {
159 CreateOptionParsingError(option_arg, short_option, long_option,
160 "No currently selected thread"));
161 } else {
162 thread_id = ctx_thread_sp->GetID();
163 }
164 }
165 } else if (option_arg.getAsInteger(0, thread_id)) {
167 CreateOptionParsingError(option_arg, short_option, long_option,
169 }
170 if (thread_id != LLDB_INVALID_THREAD_ID)
171 m_bp_opts.SetThreadID(thread_id);
172 } break;
173 case 'T':
174 m_bp_opts.GetThreadSpec()->SetName(option_arg.str().c_str());
175 break;
176 case 'q':
177 m_bp_opts.GetThreadSpec()->SetQueueName(option_arg.str().c_str());
178 break;
179 case 'x': {
180 uint32_t thread_index = UINT32_MAX;
181 if (option_arg.getAsInteger(0, thread_index)) {
183 CreateOptionParsingError(option_arg, short_option, long_option,
185 } else {
186 m_bp_opts.GetThreadSpec()->SetIndex(thread_index);
187 }
188 } break;
189 case 'Y': {
191
192 LanguageSet languages_for_expressions =
194 if (language == eLanguageTypeUnknown)
196 option_arg, short_option, long_option, "invalid language"));
197 else if (!languages_for_expressions[language])
199 CreateOptionParsingError(option_arg, short_option, long_option,
200 "no expression support for language"));
201 else
202 m_bp_opts.GetCondition().SetLanguage(language);
203 } break;
204 default:
205 llvm_unreachable("Unimplemented option");
206 }
207
208 return error;
209 }
210
211 void OptionParsingStarting(ExecutionContext *execution_context) override {
212 m_bp_opts.Clear();
213 m_commands.clear();
214 }
215
216 Status OptionParsingFinished(ExecutionContext *execution_context) override {
217 if (!m_commands.empty()) {
218 auto cmd_data = std::make_unique<BreakpointOptions::CommandData>();
219
220 for (std::string &str : m_commands)
221 cmd_data->user_source.AppendString(str);
222
223 cmd_data->stop_on_error = true;
224 m_bp_opts.SetCommandDataCallback(cmd_data);
225 }
226 return Status();
227 }
228
230
231 std::vector<std::string> m_commands;
233};
234
235// This is the Breakpoint Names option group - used to add Names to breakpoints
236// while making them. Not to be confused with the "Breakpoint Name" option
237// group which is the common options of various "breakpoint name" commands.
238#define LLDB_OPTIONS_breakpoint_names
239#include "CommandOptions.inc"
240
242public:
244
245 ~BreakpointNamesOptionGroup() override = default;
246
247 llvm::ArrayRef<OptionDefinition> GetDefinitions() override {
248 return g_breakpoint_names_options;
249 }
250
251 Status SetOptionValue(uint32_t option_idx, llvm::StringRef option_value,
252 ExecutionContext *execution_context) override {
254 const int short_option = GetDefinitions()[option_idx].short_option;
255 const char *long_option = GetDefinitions()[option_idx].long_option;
256
257 switch (short_option) {
258 case 'N':
260 m_breakpoint_names.push_back(std::string(option_value));
261 else
263 CreateOptionParsingError(option_value, short_option, long_option,
264 "Invalid breakpoint name"));
265 break;
266 }
267 return error;
268 }
269
270 void OptionParsingStarting(ExecutionContext *execution_context) override {
271 m_breakpoint_names.clear();
272 }
273
274 const std::vector<std::string> &GetBreakpointNames() {
275 return m_breakpoint_names;
276 }
277
278protected:
279 std::vector<std::string> m_breakpoint_names;
280};
281
282#define LLDB_OPTIONS_breakpoint_dummy
283#include "CommandOptions.inc"
284
286public:
288
289 ~BreakpointDummyOptionGroup() override = default;
290
291 llvm::ArrayRef<OptionDefinition> GetDefinitions() override {
292 return llvm::ArrayRef(g_breakpoint_dummy_options);
293 }
294
295 Status SetOptionValue(uint32_t option_idx, llvm::StringRef option_arg,
296 ExecutionContext *execution_context) override {
298 const int short_option =
299 g_breakpoint_dummy_options[option_idx].short_option;
300
301 switch (short_option) {
302 case 'D':
303 m_use_dummy = true;
304 break;
305 default:
306 llvm_unreachable("Unimplemented option");
307 }
308
309 return error;
310 }
311
312 void OptionParsingStarting(ExecutionContext *execution_context) override {
313 m_use_dummy = false;
314 }
315
317};
318
319#pragma mark AddAddress::CommandOptions
320#define LLDB_OPTIONS_breakpoint_add_address
321#include "CommandOptions.inc"
322
323#pragma mark Add Address
324
326 BreakpointOptionGroup &bp_opts,
327 const std::vector<std::string> &bp_names,
328 CommandReturnObject &result) {
329 assert(bp_sp && "CopyOverBreakpointOptions called with no breakpoint");
330
331 bp_sp->GetOptions().CopyOverSetOptions(bp_opts.GetBreakpointOptions());
332 Target &target = bp_sp->GetTarget();
333 if (!bp_names.empty()) {
334 Status name_error;
335 for (auto name : bp_names) {
336 target.AddNameToBreakpoint(bp_sp, name.c_str(), name_error);
337 if (name_error.Fail()) {
338 result.AppendErrorWithFormat("Invalid breakpoint name: %s",
339 name.c_str());
340 target.RemoveBreakpointByID(bp_sp->GetID());
341 return false;
342 }
343 }
344 }
345 return true;
346}
347
348static llvm::Expected<LanguageType>
349GetExceptionLanguageForLanguage(llvm::StringRef lang_name,
350 char short_option = '\0',
351 llvm::StringRef long_option = {}) {
352 llvm::Expected<LanguageType> exception_language =
354 if (!exception_language) {
355 std::string error_msg = llvm::toString(exception_language.takeError());
356 return CreateOptionParsingError(lang_name, short_option, long_option,
357 error_msg);
358 }
359 return exception_language;
360}
361
363 OptionValueFileColonLine &line_entry) {
365 uint32_t line_num = line_entry.GetLineNumber();
366 if (!line_entry.GetFileSpec()) {
367 FileSpec default_file_spec;
368 std::string error_msg;
369 Target *target = exe_ctx.GetTargetPtr();
370 if (!target) {
371 error.FromErrorString("Can't complete a line entry with no "
372 "target");
373 return error;
374 }
375 Debugger &dbg = target->GetDebugger();
376 CommandReturnObject result(dbg.GetUseColor());
377 if (!GetDefaultFile(*target, exe_ctx.GetFramePtr(), default_file_spec,
378 result)) {
379 error.FromErrorStringWithFormatv("{0}/nCouldn't get default file for "
380 "line {1}: {2}",
381 result.GetErrorString(), line_num,
382 error_msg);
383 return error;
384 }
385 line_entry.SetFile(default_file_spec);
386 }
387 return error;
388}
389
391public:
393 : CommandObjectParsed(interpreter, "breakpoint add address",
394 "Add breakpoints by raw address", nullptr) {
395 CommandArgumentData bp_id_arg;
396
397 // Define the first (and only) variant of this arg.
399 m_all_options.Append(&m_name_opts);
402 m_all_options.Finalize();
403
405 }
406
408
409 Options *GetOptions() override { return &m_all_options; }
410
412 public:
413 CommandOptions() = default;
414
415 ~CommandOptions() override = default;
416
417 Status SetOptionValue(uint32_t option_idx, llvm::StringRef option_arg,
418 ExecutionContext *execution_context) override {
420 const int short_option = GetDefinitions()[option_idx].short_option;
421 const char *long_option = GetDefinitions()[option_idx].long_option;
422
423 switch (short_option) {
424 case 'H':
425 m_hardware = true;
426 break;
427
428 case 's':
429 if (m_modules.GetSize() == 0)
430 m_modules.AppendIfUnique(FileSpec(option_arg));
431 else
433 CreateOptionParsingError(option_arg, short_option, long_option,
434 "Only one shared library can be "
435 "specified for address breakpoints."));
436 break;
437
438 default:
439 llvm_unreachable("Unimplemented option");
440 }
441
442 return error;
443 }
444
445 void OptionParsingStarting(ExecutionContext *execution_context) override {
446 m_hardware = false;
447 m_modules.Clear();
448 }
449
450 llvm::ArrayRef<OptionDefinition> GetDefinitions() override {
451 return llvm::ArrayRef(g_breakpoint_add_address_options);
452 }
453
454 // Instance variables to hold the values for command options.
455 bool m_hardware = false; // FIXME - this can go in the "modify" options.
457 };
458
459protected:
460 void DoExecute(Args &command, CommandReturnObject &result) override {
461 // We've already asserted that there can only be one entry in m_modules:
462 const ExecutionContext &exe_ctx = m_interpreter.GetExecutionContext();
463 // We don't set address breakpoints in the dummy target.
464 if (!exe_ctx.HasTargetScope() || exe_ctx.GetTargetPtr()->IsDummyTarget()) {
465 result.AppendError(
466 "can't set address breakpoints without a real target.");
467 return;
468 }
469 // Commands can't set internal breakpoints:
470 const bool internal = false;
471
472 Target &target = exe_ctx.GetTargetRef();
473
474 FileSpec module_spec;
475 bool has_module = false;
476 if (m_options.m_modules.GetSize() != 0) {
477 has_module = true;
478 module_spec = m_options.m_modules.GetFileSpecAtIndex(0);
479 }
480 BreakpointSP bp_sp;
481 // Let's process the arguments first so we can short-circuit if there are
482 // any errors:
483 std::vector<lldb::addr_t> bp_addrs;
484 for (const Args::ArgEntry &arg_entry : command) {
485 Address bp_address;
488 &exe_ctx, arg_entry.ref(), LLDB_INVALID_ADDRESS, &error);
489 if (error.Fail()) {
490 result.AppendErrorWithFormatv("invalid argument value '{0}': {1}",
491 arg_entry.ref(), error);
492 return;
493 }
494 bp_addrs.push_back(bp_load_addr);
495 }
496 for (auto bp_addr : bp_addrs) {
497 if (has_module)
498 bp_sp = target.CreateAddressInModuleBreakpoint(
499 bp_addr, internal, module_spec, m_options.m_hardware);
500 else
501 // ENHANCEMENT: we should see if bp_addr is in a single loaded module,
502 // and pass that module in if it is.
503 bp_sp =
504 target.CreateBreakpoint(bp_addr, internal, m_options.m_hardware);
505 }
506
507 if (bp_sp) {
509 m_name_opts.GetBreakpointNames(), result);
510 Stream &output_stream = result.GetOutputStream();
511 bp_sp->GetDescription(&output_stream, lldb::eDescriptionLevelInitial,
512 /*show_locations=*/false);
514 } else {
515 result.AppendError("Breakpoint creation failed: No breakpoint created.");
516 }
517 }
518
519private:
525};
526
527#pragma mark AddException::CommandOptions
528#define LLDB_OPTIONS_breakpoint_add_exception
529#include "CommandOptions.inc"
530
531#pragma mark Add Exception
532
534public:
537 interpreter, "breakpoint add exception",
538 "Add breakpoints on language exceptions. If no language is "
539 "specified, break on exceptions for all supported languages",
540 nullptr) {
541 // Define the first (and only) variant of this arg.
543
544 // Next add all the options.
546 m_all_options.Append(&m_name_opts);
548 m_all_options.Append(&m_options);
549 m_all_options.Finalize();
550 }
551
553
554 Options *GetOptions() override { return &m_all_options; }
555
557 public:
558 CommandOptions() = default;
559
560 ~CommandOptions() override = default;
561
562 Status SetOptionValue(uint32_t option_idx, llvm::StringRef option_arg,
563 ExecutionContext *execution_context) override {
565 const int short_option = GetDefinitions()[option_idx].short_option;
566
567 switch (short_option) {
568 case 'E': {
569 uint32_t this_val = (uint32_t)OptionArgParser::ToOptionEnum(
570 option_arg, GetDefinitions()[option_idx].enum_values,
572 if (error.Fail())
573 return error;
574 m_exception_stage |= this_val;
575 } break;
576 case 'H':
577 m_hardware = true;
578 break;
579
580 case 'O':
581 m_exception_extra_args.AppendArgument("-O");
582 m_exception_extra_args.AppendArgument(option_arg);
583 break;
584
585 default:
586 llvm_unreachable("Unimplemented option");
587 }
588
589 return error;
590 }
591
592 void OptionParsingStarting(ExecutionContext *execution_context) override {
593 m_hardware = false;
596 }
597
598 llvm::ArrayRef<OptionDefinition> GetDefinitions() override {
599 return llvm::ArrayRef(g_breakpoint_add_exception_options);
600 }
601
602 // Instance variables to hold the values for command options.
603 bool m_hardware = false; // FIXME - this can go in the "modify" options.
606 };
607
608protected:
609 void DoExecute(Args &command, CommandReturnObject &result) override {
610 Target &target =
611 m_dummy_options.m_use_dummy ? GetDummyTarget() : GetTarget();
612 BreakpointSP bp_sp;
613 LanguageType exception_language = eLanguageTypeUnknown;
614
615 if (command.size() == 0) {
616 result.AppendError("no languages specified");
617 } else if (command.size() > 1) {
618 result.AppendError(
619 "can only set exception breakpoints on one language at a time");
620 } else {
621 llvm::Expected<LanguageType> language =
622 GetExceptionLanguageForLanguage(command[0].ref());
623 if (language)
624 exception_language = *language;
625 else {
626 result.SetError(language.takeError());
627 return;
628 }
629 }
630 Status precond_error;
631 const bool internal = false;
632 bool catch_bp = (m_options.m_exception_stage & eExceptionStageCatch) != 0;
633 bool throw_bp = (m_options.m_exception_stage & eExceptionStageThrow) != 0;
634 bp_sp = target.CreateExceptionBreakpoint(
635 exception_language, catch_bp, throw_bp, internal,
636 &m_options.m_exception_extra_args, &precond_error);
637 if (precond_error.Fail()) {
639 "Error setting extra exception arguments: %s",
640 precond_error.AsCString());
641 target.RemoveBreakpointByID(bp_sp->GetID());
642 return;
643 }
644
645 if (bp_sp) {
647 m_name_opts.GetBreakpointNames(), result);
648 Stream &output_stream = result.GetOutputStream();
649 bp_sp->GetDescription(&output_stream, lldb::eDescriptionLevelInitial,
650 /*show_locations=*/false);
651 // Note, we don't print a "got no locations" warning for exception
652 // breakpoints. They can get set in the dummy target, and we won't know
653 // how to actually set the breakpoint till we know what version of the
654 // relevant LanguageRuntime gets loaded.
655 if (&target == &GetDummyTarget())
656 output_stream.Printf("Breakpoint set in dummy target, will get copied "
657 "into future targets.\n");
659 } else {
660 result.AppendError("Breakpoint creation failed: No breakpoint created.");
661 }
662 }
663
664private:
670};
671
672#pragma mark AddFile::CommandOptions
673#define LLDB_OPTIONS_breakpoint_add_file
674#include "CommandOptions.inc"
675
676#pragma mark Add File
677
679public:
682 interpreter, "breakpoint add file",
683 "Add breakpoints on lines in specified source files", nullptr) {
685 CommandArgumentData linespec_arg;
686 CommandArgumentData no_arg;
687
688 // Any number of linespecs in group 1:
689 linespec_arg.arg_type = eArgTypeFileLineColumn;
690 linespec_arg.arg_repetition = eArgRepeatPlus;
692
693 arg1.push_back(linespec_arg);
694
695 // Leave arg2 empty, there are no arguments to this variant.
697 no_arg.arg_type = eArgTypeNone;
700
701 arg2.push_back(linespec_arg);
702
703 // Push the data for the first argument into the m_arguments vector.
704 m_arguments.push_back(arg1);
705 m_arguments.push_back(arg2);
706
707 // Define the first (and only) variant of this arg.
710 m_all_options.Append(&m_name_opts);
713 m_all_options.Append(&m_options);
714 m_all_options.Finalize();
715 }
716
718
719 Options *GetOptions() override { return &m_all_options; }
720
722 public:
723 CommandOptions() = default;
724
725 ~CommandOptions() override = default;
726
727 Status SetOptionValue(uint32_t option_idx, llvm::StringRef option_arg,
728 ExecutionContext *execution_context) override {
730 const int short_option = GetDefinitions()[option_idx].short_option;
731 const char *long_option = GetDefinitions()[option_idx].long_option;
732
733 switch (short_option) {
734 case 'f':
735 m_cur_value.SetFile(FileSpec(option_arg));
736 break;
737 case 'l':
738 uint32_t line_num;
739 if (option_arg.getAsInteger(0, line_num))
741 CreateOptionParsingError(option_arg, short_option, long_option,
743 else {
744 // The line number is the only required part of the options for a
745 // specifying the location - since we will fill in the file with the
746 // default file. So when we see a new line, the old line entry we
747 // were building is done. If we haven't gotten a file, try to fill
748 // in the default file, and then finish up this linespec and start
749 // the next one.
750 if (m_cur_value.GetLineNumber() != LLDB_INVALID_LINE_NUMBER) {
751 // FIXME: It should be possible to create a breakpoint with a list
752 // of file, line, column values. But for now we can only create
753 // one, so return an error here. The commented out code is what we
754 // will do when I come back to add that capability.
755 return Status::FromErrorString("Can only specify one file and line "
756 "pair at a time.");
757#if 0 // This code will be appropriate once we have a resolver that can take
758 // more than one linespec at a time.
759 error = CompleteLineEntry(*execution_context, m_cur_value);
760 if (error.Fail())
761 return error;
762
763 m_line_specs.push_back(m_cur_value);
764 m_cur_value.Clear();
765#endif
766 }
767 m_cur_value.SetLine(line_num);
768 }
769 break;
770 case 'u':
771 uint32_t column_num;
772 if (option_arg.getAsInteger(0, column_num))
774 CreateOptionParsingError(option_arg, short_option, long_option,
776 else
777 m_cur_value.SetColumn(column_num);
778 break;
779 case 'K': {
780 bool success;
781 bool value;
782 value = OptionArgParser::ToBoolean(option_arg, true, &success);
783 if (value)
785 else
787
788 if (!success)
790 CreateOptionParsingError(option_arg, short_option, long_option,
792 } break;
793 case 'm': {
794 bool success;
795 bool value;
796 value = OptionArgParser::ToBoolean(option_arg, true, &success);
797 if (value)
799 else
801
802 if (!success)
804 CreateOptionParsingError(option_arg, short_option, long_option,
806 } break;
807 case 's':
808 m_modules.AppendIfUnique(FileSpec(option_arg));
809 break;
810 case 'H':
811 m_hardware = true;
812 break;
813 case 'S': {
814 lldb::addr_t tmp_offset_addr;
815 tmp_offset_addr = OptionArgParser::ToAddress(execution_context,
816 option_arg, 0, &error);
817 if (error.Success())
818 m_offset_addr = tmp_offset_addr;
819 } break;
820
821 default:
822 llvm_unreachable("Unimplemented option");
823 }
824
825 return error;
826 }
827
828 void OptionParsingStarting(ExecutionContext *execution_context) override {
829 m_hardware = false;
830 m_line_specs.clear();
831 m_cur_value.Clear();
833 m_modules.Clear();
835 m_offset_addr = 0;
836 }
837
838 Status OptionParsingFinished(ExecutionContext *execution_context) override {
839 // We were supplied at least a line from the options, so fill in the
840 // default file if needed.
841 if (m_cur_value.GetLineNumber() != LLDB_INVALID_LINE_NUMBER) {
842 Status error = CompleteLineEntry(*execution_context, m_cur_value);
843 if (error.Fail())
844 return error;
845 m_line_specs.push_back(m_cur_value);
846 m_cur_value.Clear();
847 }
848 return {};
849 }
850
851 llvm::ArrayRef<OptionDefinition> GetDefinitions() override {
852 return llvm::ArrayRef(g_breakpoint_add_file_options);
853 }
854
855 // Instance variables to hold the values for command options.
856 bool m_hardware = false; // FIXME - this can go in the "modify" options.
857 std::vector<OptionValueFileColonLine> m_line_specs;
863 };
864
865protected:
866 void DoExecute(Args &command, CommandReturnObject &result) override {
867 bool internal = false;
868 Target &target =
869 m_dummy_options.m_use_dummy ? GetDummyTarget() : GetTarget();
870 // FIXME: At present we can only make file & line breakpoints for one file
871 // and line pair. It wouldn't be hard to extend that, but I'm not adding
872 // features at this point so I'll leave that for a future patch. For now,
873 // flag this as an error.
874
875 // I'm leaving this as a loop since that's how it should be when we can
876 // do more than one linespec at a time.
877 FileSpec default_file;
878 for (const Args::ArgEntry &this_arg : command) {
880 uint32_t line_value = LLDB_INVALID_LINE_NUMBER;
881 if (!this_arg.ref().getAsInteger(0, line_value)) {
882 // The argument is a plain number. Treat that as a line number, and
883 // allow it if we can find a default file & line.
884 std::string error_msg;
885 if (!GetDefaultFile(target, m_exe_ctx.GetFramePtr(), default_file,
886 result)) {
887 result.AppendErrorWithFormatv("Couldn't find default file for line "
888 "input: {0} - {1}",
889 line_value, error_msg);
890 return;
891 }
892 value.SetLine(line_value);
893 value.SetFile(default_file);
894 } else {
895 Status error = value.SetValueFromString(this_arg.c_str());
896 if (error.Fail()) {
897 result.AppendErrorWithFormatv("Failed to parse linespec: {0}", error);
898 return;
899 }
900 }
901 m_options.m_line_specs.push_back(value);
902 }
903
904 if (m_options.m_line_specs.size() != 1) {
905 result.AppendError("Can only make file and line breakpoints with one "
906 "specification at a time.");
907 return;
908 }
909
910 BreakpointSP bp_sp;
911 // Only check for inline functions if
912 LazyBool check_inlines = eLazyBoolCalculate;
913
914 OptionValueFileColonLine &this_spec = m_options.m_line_specs[0];
915 bp_sp = target.CreateBreakpoint(
916 &(m_options.m_modules), this_spec.GetFileSpec(),
917 this_spec.GetLineNumber(), this_spec.GetColumnNumber(),
918 m_options.m_offset_addr, check_inlines, m_options.m_skip_prologue,
919 internal, m_options.m_hardware, m_options.m_move_to_nearest_code);
920
921 if (bp_sp) {
923 m_name_opts.GetBreakpointNames(), result);
924 Stream &output_stream = result.GetOutputStream();
925 bp_sp->GetDescription(&output_stream, lldb::eDescriptionLevelInitial,
926 /*show_locations=*/false);
927 if (&target == &GetDummyTarget())
928 output_stream.Printf("Breakpoint set in dummy target, will get copied "
929 "into future targets.\n");
930 else {
931 // Don't print out this warning for exception breakpoints. They can
932 // get set before the target is set, but we won't know how to actually
933 // set the breakpoint till we run.
934 if (bp_sp->GetNumLocations() == 0) {
935 output_stream.Printf("WARNING: Unable to resolve breakpoint to any "
936 "actual locations.\n");
937 }
938 }
940 } else {
941 result.AppendError("Breakpoint creation failed: No breakpoint created.");
942 }
943 }
944
945private:
951};
952
953#pragma mark AddName::CommandOptions
954#define LLDB_OPTIONS_breakpoint_add_name
955#include "CommandOptions.inc"
956
957#pragma mark Add Name
958
960public:
962 : CommandObjectParsed(interpreter, "breakpoint add name",
963 "Add breakpoints matching function or symbol names",
964 nullptr) {
965 // FIXME: Add a completer that's aware of the name match style.
966 // Define the first (and only) variant of this arg.
968
969 // Now add all the options groups.
971 m_all_options.Append(&m_name_opts);
973 m_all_options.Append(&m_options);
974 m_all_options.Finalize();
975 }
976
978
979 Options *GetOptions() override { return &m_all_options; }
980
982 public:
983 CommandOptions() = default;
984
985 ~CommandOptions() override = default;
986
987 Status SetOptionValue(uint32_t option_idx, llvm::StringRef option_arg,
988 ExecutionContext *execution_context) override {
990 const int short_option = GetDefinitions()[option_idx].short_option;
991 const char *long_option = GetDefinitions()[option_idx].long_option;
992
993 switch (short_option) {
994 case 'f':
995 m_files.AppendIfUnique(FileSpec(option_arg));
996 break;
997 case 'K': {
998 bool success;
999 bool value;
1000 value = OptionArgParser::ToBoolean(option_arg, true, &success);
1001 if (!success)
1003 CreateOptionParsingError(option_arg, short_option, long_option,
1005 else {
1006 if (value)
1008 else
1010 }
1011 } break;
1012 case 'L': {
1016 CreateOptionParsingError(option_arg, short_option, long_option,
1018 } break;
1019 case 'm': {
1020 uint32_t this_val = (uint32_t)OptionArgParser::ToOptionEnum(
1021 option_arg, GetDefinitions()[option_idx].enum_values,
1023 if (error.Fail())
1024 return error;
1025 m_lookup_style = (NameMatchStyle)this_val;
1026 } break;
1027 case 's':
1028 m_modules.AppendIfUnique(FileSpec(option_arg));
1029 break;
1030 case 'H':
1031 m_hardware = true;
1032 break;
1033 case 'S': {
1034 lldb::addr_t tmp_offset_addr;
1035 tmp_offset_addr = OptionArgParser::ToAddress(execution_context,
1036 option_arg, 0, &error);
1037 if (error.Success())
1038 m_offset_addr = tmp_offset_addr;
1039 } break;
1040
1041 default:
1042 llvm_unreachable("Unimplemented option");
1043 }
1044
1045 return error;
1046 }
1047
1048 void OptionParsingStarting(ExecutionContext *execution_context) override {
1049 m_hardware = false;
1051 m_files.Clear();
1053 m_modules.Clear();
1054 m_offset_addr = 0;
1056 }
1057
1058 llvm::ArrayRef<OptionDefinition> GetDefinitions() override {
1059 return llvm::ArrayRef(g_breakpoint_add_name_options);
1060 }
1061
1062 // Instance variables to hold the values for command options.
1063 bool m_hardware = false; // FIXME - this can go in the "modify" options.
1071 };
1072
1073protected:
1074 void DoExecute(Args &command, CommandReturnObject &result) override {
1075 const bool internal = false;
1076 Target &target =
1077 m_dummy_options.m_use_dummy ? GetDummyTarget() : GetTarget();
1078 // Parse the argument list - this is a simple list of names.
1079 std::vector<std::string> func_names;
1080 for (const Args::ArgEntry &this_arg : command) {
1081 func_names.push_back(this_arg.ref().str());
1082 }
1083 BreakpointSP bp_sp;
1084 if (!(m_options.m_lookup_style & eNameMatchStyleRegex))
1085 bp_sp = target.CreateBreakpoint(
1086 &m_options.m_modules, &m_options.m_files, func_names,
1087 (FunctionNameType)m_options.m_lookup_style, m_options.m_language,
1088 m_options.m_offset_addr, m_options.m_skip_prologue, internal,
1089 m_options.m_hardware);
1090 else {
1091 if (func_names.size() != 1) {
1092 result.AppendError("Can only set function regular expression "
1093 "breakpoints on one regex at a time.");
1094 return;
1095 }
1096 std::string &func_regexp = func_names[0];
1097 RegularExpression regexp(func_regexp);
1098 if (llvm::Error err = regexp.GetError()) {
1099 result.AppendErrorWithFormat(
1100 "Function name regular expression could not be compiled: %s",
1101 llvm::toString(std::move(err)).c_str());
1102 // Check if the incorrect regex looks like a globbing expression and
1103 // warn the user about it.
1104 if (!func_regexp.empty()) {
1105 if (func_regexp[0] == '*' || func_regexp[0] == '?')
1106 result.AppendWarning(
1107 "Function name regex does not accept glob patterns.");
1108 }
1109 return;
1110 }
1111
1112 bp_sp = target.CreateFuncRegexBreakpoint(
1113 &(m_options.m_modules), &(m_options.m_files), std::move(regexp),
1114 m_options.m_language, m_options.m_skip_prologue, internal,
1115 m_options.m_hardware);
1116 }
1117 if (bp_sp) {
1119 m_name_opts.GetBreakpointNames(), result);
1120 Stream &output_stream = result.GetOutputStream();
1121 bp_sp->GetDescription(&output_stream, lldb::eDescriptionLevelInitial,
1122 /*show_locations=*/false);
1123 if (&target == &GetDummyTarget())
1124 output_stream.Printf("Breakpoint set in dummy target, will get copied "
1125 "into future targets.\n");
1126 else {
1127 if (bp_sp->GetNumLocations() == 0) {
1128 output_stream.Printf("WARNING: Unable to resolve breakpoint to any "
1129 "actual locations.\n");
1130 }
1131 }
1133 } else {
1134 result.AppendError("Breakpoint creation failed: No breakpoint created.");
1135 }
1136 }
1137
1138private:
1144};
1145
1146#pragma mark AddPattern::CommandOptions
1147#define LLDB_OPTIONS_breakpoint_add_pattern
1148#include "CommandOptions.inc"
1149
1150#pragma mark Add Pattern
1151
1153public:
1155 : CommandObjectRaw(interpreter, "breakpoint add pattern",
1156 "Add breakpoints matching patterns in the source text",
1157 "breakpoint add pattern [options] -- <pattern>") {
1159 // Now add all the options groups.
1161 m_all_options.Append(&m_name_opts);
1163 m_all_options.Append(&m_options);
1164 m_all_options.Finalize();
1165 }
1166
1168
1169 Options *GetOptions() override { return &m_all_options; }
1170
1172 public:
1173 CommandOptions() = default;
1174
1175 ~CommandOptions() override = default;
1176
1177 Status SetOptionValue(uint32_t option_idx, llvm::StringRef option_arg,
1178 ExecutionContext *execution_context) override {
1179 Status error;
1180 const int short_option = GetDefinitions()[option_idx].short_option;
1181 const char *long_option = GetDefinitions()[option_idx].long_option;
1182
1183 switch (short_option) {
1184 case 'a': {
1185 bool success;
1186 bool value;
1187 value = OptionArgParser::ToBoolean(option_arg, true, &success);
1188 if (!success)
1190 CreateOptionParsingError(option_arg, short_option, long_option,
1192 else
1193 m_all_files = value;
1194 } break;
1195 case 'f':
1196 m_files.AppendIfUnique(FileSpec(option_arg));
1197 break;
1198 case 'm': {
1199 bool success;
1200 bool value;
1201 value = OptionArgParser::ToBoolean(option_arg, true, &success);
1202 if (!success)
1204 CreateOptionParsingError(option_arg, short_option, long_option,
1206 else {
1207 if (value)
1209 else
1211 }
1212 } break;
1213 case 'n':
1214 m_func_names.insert(option_arg.str());
1215 break;
1216 case 's':
1217 m_modules.AppendIfUnique(FileSpec(option_arg));
1218 break;
1219 case 'H':
1220 m_hardware = true;
1221 break;
1222 default:
1223 llvm_unreachable("Unimplemented option");
1224 }
1225
1226 return error;
1227 }
1228
1229 void OptionParsingStarting(ExecutionContext *execution_context) override {
1230 m_hardware = false;
1232 m_modules.Clear();
1233 m_files.Clear();
1234 m_func_names.clear();
1235 m_all_files = false;
1237 }
1238
1239 llvm::ArrayRef<OptionDefinition> GetDefinitions() override {
1240 return llvm::ArrayRef(g_breakpoint_add_pattern_options);
1241 }
1242
1243 // Instance variables to hold the values for command options.
1244 bool m_hardware = false; // FIXME - this can go in the "modify" options.
1248 std::unordered_set<std::string> m_func_names;
1249 bool m_all_files = false;
1251 };
1252
1253protected:
1254 void DoExecute(llvm::StringRef command,
1255 CommandReturnObject &result) override {
1256 const bool internal = false;
1258 m_all_options.NotifyOptionParsingStarting(&exe_ctx);
1259
1260 if (command.empty()) {
1261 result.AppendError("no pattern to seek.");
1262 return;
1263 }
1264
1265 OptionsWithRaw args(command);
1266
1267 if (args.HasArgs()) {
1268 if (!ParseOptionsAndNotify(args.GetArgs(), result, m_all_options,
1269 exe_ctx))
1270 return;
1271 }
1272 llvm::StringRef pattern = args.GetRawPart();
1273 if (pattern.empty()) {
1274 result.AppendError("no pattern to seek");
1275 return;
1276 }
1277
1278 Target &target =
1279 m_dummy_options.m_use_dummy ? GetDummyTarget() : GetTarget();
1280
1281 BreakpointSP bp_sp;
1282 const size_t num_files = m_options.m_files.GetSize();
1283
1284 if (num_files == 0 && !m_options.m_all_files) {
1285 FileSpec file;
1286 if (!GetDefaultFile(target, m_exe_ctx.GetFramePtr(), file, result)) {
1287 result.AppendError(
1288 "No files provided and could not find default file.");
1289 return;
1290 } else {
1291 m_options.m_files.Append(file);
1292 }
1293 }
1294
1295 RegularExpression regexp(pattern);
1296 if (llvm::Error err = regexp.GetError()) {
1297 result.AppendErrorWithFormat(
1298 "Source text regular expression could not be compiled: \"%s\"",
1299 llvm::toString(std::move(err)).c_str());
1300 return;
1301 }
1302 bp_sp = target.CreateSourceRegexBreakpoint(
1303 &(m_options.m_modules), &(m_options.m_files), m_options.m_func_names,
1304 std::move(regexp), internal, m_options.m_hardware,
1305 m_options.m_move_to_nearest_code);
1306
1307 if (bp_sp) {
1309 m_name_opts.GetBreakpointNames(), result);
1310 Stream &output_stream = result.GetOutputStream();
1311 bp_sp->GetDescription(&output_stream, lldb::eDescriptionLevelInitial,
1312 /*show_locations=*/false);
1313 if (&target == &GetDummyTarget())
1314 output_stream.Printf("Breakpoint set in dummy target, will get copied "
1315 "into future targets.\n");
1316 else {
1317 // Don't print out this warning for exception breakpoints. They can
1318 // get set before the target is set, but we won't know how to actually
1319 // set the breakpoint till we run.
1320 if (bp_sp->GetNumLocations() == 0) {
1321 output_stream.Printf("WARNING: Unable to resolve breakpoint to any "
1322 "actual locations.\n");
1323 }
1324 }
1326 } else {
1327 result.AppendError("Breakpoint creation failed: No breakpoint created.");
1328 }
1329 }
1330
1331private:
1337};
1338
1339#pragma mark AddScripted::CommandOptions
1340#define LLDB_OPTIONS_breakpoint_add_scripted
1341#include "CommandOptions.inc"
1342
1343#pragma mark Add Scripted
1344
1346public:
1349 interpreter, "breakpoint add scripted",
1350 "Add breakpoints using a scripted breakpoint resolver.", nullptr),
1351 m_python_class_options("scripted breakpoint", true, 'P') {
1352 // We're picking up all the normal options, commands and disable.
1355 // Define the first (and only) variant of this arg.
1357 m_all_options.Append(&m_name_opts);
1359 m_all_options.Append(&m_options);
1360 m_all_options.Finalize();
1361 }
1362
1364
1365 Options *GetOptions() override { return &m_all_options; }
1366
1368 public:
1369 CommandOptions() = default;
1370
1371 ~CommandOptions() override = default;
1372
1373 Status SetOptionValue(uint32_t option_idx, llvm::StringRef option_arg,
1374 ExecutionContext *execution_context) override {
1375 Status error;
1376 const int short_option = GetDefinitions()[option_idx].short_option;
1377
1378 switch (short_option) {
1379 case 'f':
1380 m_files.Append(FileSpec(option_arg));
1381 break;
1382 case 's':
1383 m_modules.AppendIfUnique(FileSpec(option_arg));
1384 break;
1385 case 'H':
1386 m_hardware = true;
1387 break;
1388
1389 default:
1390 llvm_unreachable("Unimplemented option");
1391 }
1392
1393 return error;
1394 }
1395
1396 void OptionParsingStarting(ExecutionContext *execution_context) override {
1397 m_hardware = false;
1398 m_files.Clear();
1399 m_modules.Clear();
1400 }
1401
1402 llvm::ArrayRef<OptionDefinition> GetDefinitions() override {
1403 return llvm::ArrayRef(g_breakpoint_add_scripted_options);
1404 }
1405
1406 // Instance variables to hold the values for command options.
1407 bool m_hardware = false; // FIXME - this can go in the "modify" options.
1410 };
1411
1412protected:
1413 void DoExecute(Args &command, CommandReturnObject &result) override {
1414 Target &target =
1415 m_dummy_options.m_use_dummy ? GetDummyTarget() : GetTarget();
1416
1417 BreakpointSP bp_sp;
1418 Status error;
1419 bp_sp = target.CreateScriptedBreakpoint(
1420 m_python_class_options.GetName().c_str(), &(m_options.m_modules),
1421 &(m_options.m_files), false, m_options.m_hardware,
1422 m_python_class_options.GetStructuredData(), &error);
1423 if (error.Fail()) {
1424 result.AppendErrorWithFormat(
1425 "error setting extra exception arguments: %s", error.AsCString());
1426 target.RemoveBreakpointByID(bp_sp->GetID());
1427 return;
1428 }
1429
1430 if (bp_sp) {
1432 m_name_opts.GetBreakpointNames(), result);
1433 Stream &output_stream = result.GetOutputStream();
1434 bp_sp->GetDescription(&output_stream, lldb::eDescriptionLevelInitial,
1435 /*show_locations=*/false);
1436 if (&target == &GetDummyTarget())
1437 output_stream.Printf("Breakpoint set in dummy target, will get copied "
1438 "into future targets.\n");
1439 else {
1440 // Don't print out this warning for exception breakpoints. They can
1441 // get set before the target is set, but we won't know how to actually
1442 // set the breakpoint till we run.
1443 if (bp_sp->GetNumLocations() == 0) {
1444 output_stream.Printf("WARNING: Unable to resolve breakpoint to any "
1445 "actual locations.\n");
1446 }
1447 }
1449 } else {
1450 result.AppendError("breakpoint creation failed: No breakpoint created.");
1451 }
1452 }
1453
1454private:
1461};
1462
1463#pragma mark Add::CommandOptions
1464#define LLDB_OPTIONS_breakpoint_add
1465#include "CommandOptions.inc"
1466
1467#pragma mark Add
1468
1470public:
1472 : CommandObjectMultiword(interpreter, "add",
1473 "Commands to add breakpoints of various types") {
1475 R"(
1476Access the breakpoint search kernels built into lldb. Along with specifying the
1477search kernel, each breakpoint add operation can specify a common set of
1478"reaction" options for each breakpoint. The reaction options can also be
1479modified after breakpoint creation using the "breakpoint modify" command.
1480 )");
1481 CommandObjectSP address_command_object(
1482 new CommandObjectBreakpointAddAddress(interpreter));
1483 CommandObjectSP exception_command_object(
1484 new CommandObjectBreakpointAddException(interpreter));
1485 CommandObjectSP file_command_object(
1486 new CommandObjectBreakpointAddFile(interpreter));
1487 CommandObjectSP name_command_object(
1488 new CommandObjectBreakpointAddName(interpreter));
1489 CommandObjectSP pattern_command_object(
1490 new CommandObjectBreakpointAddPattern(interpreter));
1491 CommandObjectSP scripted_command_object(
1492 new CommandObjectBreakpointAddScripted(interpreter));
1493
1494 LoadSubCommand("address", address_command_object);
1495 LoadSubCommand("exception", exception_command_object);
1496 LoadSubCommand("file", file_command_object);
1497 LoadSubCommand("name", name_command_object);
1498 LoadSubCommand("pattern", pattern_command_object);
1499 LoadSubCommand("scripted", scripted_command_object);
1500 }
1501};
1502
1503#define LLDB_OPTIONS_breakpoint_set
1504#include "CommandOptions.inc"
1505
1506// CommandObjectBreakpointSet
1507
1509public:
1520
1523 interpreter, "breakpoint set",
1524 "Sets a breakpoint or set of breakpoints in the executable.",
1525 "breakpoint set <cmd-options>"),
1526 m_python_class_options("scripted breakpoint", true, 'P') {
1527 // We're picking up all the normal options, commands and disable.
1530 m_all_options.Append(&m_bp_opts,
1534 m_all_options.Append(&m_options);
1535 m_all_options.Finalize();
1536 }
1537
1538 ~CommandObjectBreakpointSet() override = default;
1539
1540 Options *GetOptions() override { return &m_all_options; }
1541
1543 public:
1544 CommandOptions() = default;
1545
1546 ~CommandOptions() override = default;
1547
1548 Status SetOptionValue(uint32_t option_idx, llvm::StringRef option_arg,
1549 ExecutionContext *execution_context) override {
1550 Status error;
1551 const int short_option =
1552 g_breakpoint_set_options[option_idx].short_option;
1553 const char *long_option =
1554 g_breakpoint_set_options[option_idx].long_option;
1555
1556 switch (short_option) {
1557 case 'a': {
1558 m_load_addr = OptionArgParser::ToAddress(execution_context, option_arg,
1560 } break;
1561
1562 case 'A':
1563 m_all_files = true;
1564 break;
1565
1566 case 'b':
1567 m_func_names.push_back(std::string(option_arg));
1568 m_func_name_type_mask |= eFunctionNameTypeBase;
1569 break;
1570
1571 case 'u':
1572 if (option_arg.getAsInteger(0, m_column))
1574 CreateOptionParsingError(option_arg, short_option, long_option,
1576 break;
1577
1578 case 'E': {
1579 llvm::Expected<LanguageType> language = GetExceptionLanguageForLanguage(
1580 option_arg, short_option, long_option);
1581 if (language)
1582 m_exception_language = *language;
1583 else
1584 error = Status::FromError(language.takeError());
1585 } break;
1586
1587 case 'f':
1588 m_filenames.AppendIfUnique(FileSpec(option_arg));
1589 break;
1590
1591 case 'F':
1592 m_func_names.push_back(std::string(option_arg));
1593 m_func_name_type_mask |= eFunctionNameTypeFull;
1594 break;
1595
1596 case 'h': {
1597 bool success;
1598 m_catch_bp = OptionArgParser::ToBoolean(option_arg, true, &success);
1599 if (!success)
1601 CreateOptionParsingError(option_arg, short_option, long_option,
1603 } break;
1604
1605 case 'H':
1606 m_hardware = true;
1607 break;
1608
1609 case 'K': {
1610 bool success;
1611 bool value;
1612 value = OptionArgParser::ToBoolean(option_arg, true, &success);
1613 if (value)
1615 else
1617
1618 if (!success)
1620 CreateOptionParsingError(option_arg, short_option, long_option,
1622 } break;
1623
1624 case 'l':
1625 if (option_arg.getAsInteger(0, m_line_num))
1627 CreateOptionParsingError(option_arg, short_option, long_option,
1629 break;
1630
1631 case 'L':
1635 CreateOptionParsingError(option_arg, short_option, long_option,
1637 break;
1638
1639 case 'm': {
1640 bool success;
1641 bool value;
1642 value = OptionArgParser::ToBoolean(option_arg, true, &success);
1643 if (value)
1645 else
1647
1648 if (!success)
1650 CreateOptionParsingError(option_arg, short_option, long_option,
1652 break;
1653 }
1654
1655 case 'M':
1656 m_func_names.push_back(std::string(option_arg));
1657 m_func_name_type_mask |= eFunctionNameTypeMethod;
1658 break;
1659
1660 case 'n':
1661 m_func_names.push_back(std::string(option_arg));
1662 m_func_name_type_mask |= eFunctionNameTypeAuto;
1663 break;
1664
1665 case 'N': {
1667 m_breakpoint_names.push_back(std::string(option_arg));
1668 else
1670 CreateOptionParsingError(option_arg, short_option, long_option,
1671 "Invalid breakpoint name"));
1672 break;
1673 }
1674
1675 case 'R': {
1676 lldb::addr_t tmp_offset_addr;
1677 tmp_offset_addr = OptionArgParser::ToAddress(execution_context,
1678 option_arg, 0, &error);
1679 if (error.Success())
1680 m_offset_addr = tmp_offset_addr;
1681 } break;
1682
1683 case 'O':
1684 m_exception_extra_args.AppendArgument("-O");
1685 m_exception_extra_args.AppendArgument(option_arg);
1686 break;
1687
1688 case 'p':
1689 m_source_text_regexp.assign(std::string(option_arg));
1690 break;
1691
1692 case 'r':
1693 m_func_regexp.assign(std::string(option_arg));
1694 break;
1695
1696 case 's':
1697 m_modules.AppendIfUnique(FileSpec(option_arg));
1698 break;
1699
1700 case 'S':
1701 m_func_names.push_back(std::string(option_arg));
1702 m_func_name_type_mask |= eFunctionNameTypeSelector;
1703 break;
1704
1705 case 'w': {
1706 bool success;
1707 m_throw_bp = OptionArgParser::ToBoolean(option_arg, true, &success);
1708 if (!success)
1710 CreateOptionParsingError(option_arg, short_option, long_option,
1712 } break;
1713
1714 case 'X':
1715 m_source_regex_func_names.insert(std::string(option_arg));
1716 break;
1717
1718 case 'y':
1719 {
1721 Status fcl_err = value.SetValueFromString(option_arg);
1722 if (!fcl_err.Success()) {
1724 option_arg, short_option, long_option, fcl_err.AsCString()));
1725 } else {
1726 m_filenames.AppendIfUnique(value.GetFileSpec());
1727 m_line_num = value.GetLineNumber();
1728 m_column = value.GetColumnNumber();
1729 }
1730 } break;
1731
1732 default:
1733 llvm_unreachable("Unimplemented option");
1734 }
1735
1736 return error;
1737 }
1738
1739 void OptionParsingStarting(ExecutionContext *execution_context) override {
1740 m_filenames.Clear();
1741 m_line_num = 0;
1742 m_column = 0;
1743 m_func_names.clear();
1744 m_func_name_type_mask = eFunctionNameTypeNone;
1745 m_func_regexp.clear();
1746 m_source_text_regexp.clear();
1747 m_modules.Clear();
1749 m_offset_addr = 0;
1750 m_catch_bp = false;
1751 m_throw_bp = true;
1752 m_hardware = false;
1756 m_breakpoint_names.clear();
1757 m_all_files = false;
1758 m_exception_extra_args.Clear();
1761 m_current_key.clear();
1762 }
1763
1764 llvm::ArrayRef<OptionDefinition> GetDefinitions() override {
1765 return llvm::ArrayRef(g_breakpoint_set_options);
1766 }
1767
1768 // Instance variables to hold the values for command options.
1769
1770 std::string m_condition;
1772 uint32_t m_line_num = 0;
1773 uint32_t m_column = 0;
1774 std::vector<std::string> m_func_names;
1775 std::vector<std::string> m_breakpoint_names;
1776 lldb::FunctionNameType m_func_name_type_mask = eFunctionNameTypeNone;
1777 std::string m_func_regexp;
1782 bool m_catch_bp = false;
1783 bool m_throw_bp = true;
1784 bool m_hardware = false; // Request to use hardware breakpoints
1788 bool m_all_files = false;
1791 std::unordered_set<std::string> m_source_regex_func_names;
1792 std::string m_current_key;
1793 };
1794
1795protected:
1796 void DoExecute(Args &command, CommandReturnObject &result) override {
1797 Target &target =
1798 m_dummy_options.m_use_dummy ? GetDummyTarget() : GetTarget();
1799
1800 // The following are the various types of breakpoints that could be set:
1801 // 1). -f -l -p [-s -g] (setting breakpoint by source location)
1802 // 2). -a [-s -g] (setting breakpoint by address)
1803 // 3). -n [-s -g] (setting breakpoint by function name)
1804 // 4). -r [-s -g] (setting breakpoint by function name regular
1805 // expression)
1806 // 5). -p -f (setting a breakpoint by comparing a reg-exp
1807 // to source text)
1808 // 6). -E [-w -h] (setting a breakpoint for exceptions for a
1809 // given language.)
1810
1812
1813 if (!m_python_class_options.GetName().empty())
1814 break_type = eSetTypeScripted;
1815 else if (m_options.m_line_num != 0)
1816 break_type = eSetTypeFileAndLine;
1817 else if (m_options.m_load_addr != LLDB_INVALID_ADDRESS)
1818 break_type = eSetTypeAddress;
1819 else if (!m_options.m_func_names.empty())
1820 break_type = eSetTypeFunctionName;
1821 else if (!m_options.m_func_regexp.empty())
1822 break_type = eSetTypeFunctionRegexp;
1823 else if (!m_options.m_source_text_regexp.empty())
1824 break_type = eSetTypeSourceRegexp;
1825 else if (m_options.m_exception_language != eLanguageTypeUnknown)
1826 break_type = eSetTypeException;
1827
1828 BreakpointSP bp_sp = nullptr;
1829 FileSpec module_spec;
1830 const bool internal = false;
1831
1832 // If the user didn't specify skip-prologue, having an offset should turn
1833 // that off.
1834 if (m_options.m_offset_addr != 0 &&
1835 m_options.m_skip_prologue == eLazyBoolCalculate)
1836 m_options.m_skip_prologue = eLazyBoolNo;
1837
1838 switch (break_type) {
1839 case eSetTypeFileAndLine: // Breakpoint by source position
1840 {
1841 FileSpec file;
1842 const size_t num_files = m_options.m_filenames.GetSize();
1843 if (num_files == 0) {
1844 if (!GetDefaultFile(target, m_exe_ctx.GetFramePtr(), file, result)) {
1845 result.AppendError("no file supplied and no default file available.");
1846 return;
1847 }
1848 } else if (num_files > 1) {
1849 result.AppendError("only one file at a time is allowed for file and "
1850 "line breakpoints");
1851 return;
1852 } else
1853 file = m_options.m_filenames.GetFileSpecAtIndex(0);
1854
1855 // Only check for inline functions if
1856 LazyBool check_inlines = eLazyBoolCalculate;
1857
1858 bp_sp = target.CreateBreakpoint(
1859 &(m_options.m_modules), file, m_options.m_line_num,
1860 m_options.m_column, m_options.m_offset_addr, check_inlines,
1861 m_options.m_skip_prologue, internal, m_options.m_hardware,
1862 m_options.m_move_to_nearest_code);
1863 } break;
1864
1865 case eSetTypeAddress: // Breakpoint by address
1866 {
1867 // If a shared library has been specified, make an lldb_private::Address
1868 // with the library, and use that. That way the address breakpoint
1869 // will track the load location of the library.
1870 size_t num_modules_specified = m_options.m_modules.GetSize();
1871 if (num_modules_specified == 1) {
1872 const FileSpec &file_spec =
1873 m_options.m_modules.GetFileSpecAtIndex(0);
1874 bp_sp = target.CreateAddressInModuleBreakpoint(
1875 m_options.m_load_addr, internal, file_spec, m_options.m_hardware);
1876 } else if (num_modules_specified == 0) {
1877 bp_sp = target.CreateBreakpoint(m_options.m_load_addr, internal,
1878 m_options.m_hardware);
1879 } else {
1880 result.AppendError("Only one shared library can be specified for "
1881 "address breakpoints.");
1882 return;
1883 }
1884 break;
1885 }
1886 case eSetTypeFunctionName: // Breakpoint by function name
1887 {
1888 FunctionNameType name_type_mask = m_options.m_func_name_type_mask;
1889
1890 if (name_type_mask == 0)
1891 name_type_mask = eFunctionNameTypeAuto;
1892
1893 bp_sp = target.CreateBreakpoint(
1894 &(m_options.m_modules), &(m_options.m_filenames),
1895 m_options.m_func_names, name_type_mask, m_options.m_language,
1896 m_options.m_offset_addr, m_options.m_skip_prologue, internal,
1897 m_options.m_hardware);
1898 } break;
1899
1900 case eSetTypeFunctionRegexp: // Breakpoint by regular expression function
1901 // name
1902 {
1903 RegularExpression regexp(m_options.m_func_regexp);
1904 if (llvm::Error err = regexp.GetError()) {
1905 result.AppendErrorWithFormat(
1906 "Function name regular expression could not be compiled: %s",
1907 llvm::toString(std::move(err)).c_str());
1908 // Check if the incorrect regex looks like a globbing expression and
1909 // warn the user about it.
1910 if (!m_options.m_func_regexp.empty()) {
1911 if (m_options.m_func_regexp[0] == '*' ||
1912 m_options.m_func_regexp[0] == '?')
1913 result.AppendWarning(
1914 "Function name regex does not accept glob patterns.");
1915 }
1916 return;
1917 }
1918
1919 bp_sp = target.CreateFuncRegexBreakpoint(
1920 &(m_options.m_modules), &(m_options.m_filenames), std::move(regexp),
1921 m_options.m_language, m_options.m_skip_prologue, internal,
1922 m_options.m_hardware);
1923 } break;
1924 case eSetTypeSourceRegexp: // Breakpoint by regexp on source text.
1925 {
1926 const size_t num_files = m_options.m_filenames.GetSize();
1927
1928 if (num_files == 0 && !m_options.m_all_files) {
1929 FileSpec file;
1930 if (!GetDefaultFile(target, m_exe_ctx.GetFramePtr(), file, result)) {
1931 result.AppendError(
1932 "No files provided and could not find default file.");
1933 return;
1934 } else {
1935 m_options.m_filenames.Append(file);
1936 }
1937 }
1938
1939 RegularExpression regexp(m_options.m_source_text_regexp);
1940 if (llvm::Error err = regexp.GetError()) {
1941 result.AppendErrorWithFormat(
1942 "Source text regular expression could not be compiled: \"%s\"",
1943 llvm::toString(std::move(err)).c_str());
1944 return;
1945 }
1946 bp_sp = target.CreateSourceRegexBreakpoint(
1947 &(m_options.m_modules), &(m_options.m_filenames),
1948 m_options.m_source_regex_func_names, std::move(regexp), internal,
1949 m_options.m_hardware, m_options.m_move_to_nearest_code);
1950 } break;
1951 case eSetTypeException: {
1952 Status precond_error;
1953 bp_sp = target.CreateExceptionBreakpoint(
1954 m_options.m_exception_language, m_options.m_catch_bp,
1955 m_options.m_throw_bp, internal, &m_options.m_exception_extra_args,
1956 &precond_error);
1957 if (precond_error.Fail()) {
1958 result.AppendErrorWithFormat(
1959 "Error setting extra exception arguments: %s",
1960 precond_error.AsCString());
1961 target.RemoveBreakpointByID(bp_sp->GetID());
1962 return;
1963 }
1964 } break;
1965 case eSetTypeScripted: {
1966
1967 Status error;
1968 bp_sp = target.CreateScriptedBreakpoint(
1969 m_python_class_options.GetName().c_str(), &(m_options.m_modules),
1970 &(m_options.m_filenames), false, m_options.m_hardware,
1971 m_python_class_options.GetStructuredData(), &error);
1972 if (error.Fail()) {
1973 result.AppendErrorWithFormat(
1974 "Error setting extra exception arguments: %s", error.AsCString());
1975 target.RemoveBreakpointByID(bp_sp->GetID());
1976 return;
1977 }
1978 } break;
1979 default:
1980 break;
1981 }
1982
1983 // Now set the various options that were passed in:
1984 if (bp_sp) {
1985 bp_sp->GetOptions().CopyOverSetOptions(m_bp_opts.GetBreakpointOptions());
1986
1987 if (!m_options.m_breakpoint_names.empty()) {
1988 Status name_error;
1989 for (auto name : m_options.m_breakpoint_names) {
1990 target.AddNameToBreakpoint(bp_sp, name.c_str(), name_error);
1991 if (name_error.Fail()) {
1992 result.AppendErrorWithFormat("Invalid breakpoint name: %s",
1993 name.c_str());
1994 target.RemoveBreakpointByID(bp_sp->GetID());
1995 return;
1996 }
1997 }
1998 }
1999 }
2000
2001 if (bp_sp) {
2002 Stream &output_stream = result.GetOutputStream();
2003 const bool show_locations = false;
2004 bp_sp->GetDescription(&output_stream, lldb::eDescriptionLevelInitial,
2005 show_locations);
2006 if (&target == &GetDummyTarget())
2007 output_stream.Printf("Breakpoint set in dummy target, will get copied "
2008 "into future targets.\n");
2009 else {
2010 // Don't print out this warning for exception breakpoints. They can
2011 // get set before the target is set, but we won't know how to actually
2012 // set the breakpoint till we run.
2013 if (bp_sp->GetNumLocations() == 0 && break_type != eSetTypeException) {
2014 output_stream.Printf("WARNING: Unable to resolve breakpoint to any "
2015 "actual locations.\n");
2016 }
2017 }
2019 } else if (!bp_sp) {
2020 result.AppendError("breakpoint creation failed: no breakpoint created");
2021 }
2022 }
2023
2024private:
2030};
2031
2032// CommandObjectBreakpointModify
2033#pragma mark Modify
2034
2036public:
2038 : CommandObjectParsed(interpreter, "breakpoint modify",
2039 "Modify the options on a breakpoint or set of "
2040 "breakpoints in the executable. "
2041 "If no breakpoint is specified, acts on the last "
2042 "created breakpoint. "
2043 "With the exception of -e, -d and -i, passing an "
2044 "empty argument clears the modification.",
2045 nullptr) {
2047
2048 m_options.Append(&m_bp_opts,
2052 m_options.Finalize();
2053 }
2054
2056
2057 void
2063
2064 Options *GetOptions() override { return &m_options; }
2065
2066protected:
2067 void DoExecute(Args &command, CommandReturnObject &result) override {
2068 Target &target = m_dummy_opts.m_use_dummy ? GetDummyTarget() : GetTarget();
2069
2070 std::unique_lock<std::recursive_mutex> lock;
2071 target.GetBreakpointList().GetListMutex(lock);
2072
2073 BreakpointIDList valid_bp_ids;
2074
2076 command, target, result, &valid_bp_ids,
2078
2079 if (result.Succeeded()) {
2080 const size_t count = valid_bp_ids.GetSize();
2081 for (size_t i = 0; i < count; ++i) {
2082 BreakpointID cur_bp_id = valid_bp_ids.GetBreakpointIDAtIndex(i);
2083
2084 if (cur_bp_id.GetBreakpointID() != LLDB_INVALID_BREAK_ID) {
2085 Breakpoint *bp =
2086 target.GetBreakpointByID(cur_bp_id.GetBreakpointID()).get();
2087 if (cur_bp_id.GetLocationID() != LLDB_INVALID_BREAK_ID) {
2088 BreakpointLocation *location =
2089 bp->FindLocationByID(cur_bp_id.GetLocationID()).get();
2090 if (location)
2092 m_bp_opts.GetBreakpointOptions());
2093 } else {
2095 m_bp_opts.GetBreakpointOptions());
2096 }
2097 }
2098 }
2099 }
2100 }
2101
2102private:
2106};
2107
2108// CommandObjectBreakpointEnable
2109#pragma mark Enable
2110
2112public:
2114 : CommandObjectParsed(interpreter, "enable",
2115 "Enable the specified disabled breakpoint(s). If "
2116 "no breakpoints are specified, enable all of them.",
2117 nullptr) {
2119 }
2120
2122
2123 void
2129
2130protected:
2131 void DoExecute(Args &command, CommandReturnObject &result) override {
2132 Target &target = GetTarget();
2133
2134 std::unique_lock<std::recursive_mutex> lock;
2135 target.GetBreakpointList().GetListMutex(lock);
2136
2137 const BreakpointList &breakpoints = target.GetBreakpointList();
2138
2139 size_t num_breakpoints = breakpoints.GetSize();
2140
2141 if (num_breakpoints == 0) {
2142 result.AppendError("no breakpoints exist to be enabled");
2143 return;
2144 }
2145
2146 if (command.empty()) {
2147 // No breakpoint selected; enable all currently set breakpoints.
2148 target.EnableAllowedBreakpoints();
2150 "All breakpoints enabled. ({0} breakpoints)", num_breakpoints);
2152 } else {
2153 // Particular breakpoint selected; enable that breakpoint.
2154 BreakpointIDList valid_bp_ids;
2156 command, target, result, &valid_bp_ids,
2158
2159 if (result.Succeeded()) {
2160 int enable_count = 0;
2161 int loc_count = 0;
2162 const size_t count = valid_bp_ids.GetSize();
2163 for (size_t i = 0; i < count; ++i) {
2164 BreakpointID cur_bp_id = valid_bp_ids.GetBreakpointIDAtIndex(i);
2165
2166 if (cur_bp_id.GetBreakpointID() != LLDB_INVALID_BREAK_ID) {
2167 Breakpoint *breakpoint =
2168 target.GetBreakpointByID(cur_bp_id.GetBreakpointID()).get();
2169 if (cur_bp_id.GetLocationID() != LLDB_INVALID_BREAK_ID) {
2170 BreakpointLocation *location =
2171 breakpoint->FindLocationByID(cur_bp_id.GetLocationID()).get();
2172 if (location) {
2173 if (llvm::Error error = location->SetEnabled(true))
2175 "failed to enable breakpoint location: {0}",
2176 llvm::fmt_consume(std::move(error)));
2177 ++loc_count;
2178 }
2179 } else {
2180 breakpoint->SetEnabled(true);
2181 ++enable_count;
2182 }
2183 }
2184 }
2185 result.AppendMessageWithFormatv("{0} breakpoints enabled.",
2186 enable_count + loc_count);
2188 }
2189 }
2190 }
2191};
2192
2193// CommandObjectBreakpointDisable
2194#pragma mark Disable
2195
2197public:
2200 interpreter, "breakpoint disable",
2201 "Disable the specified breakpoint(s) without deleting "
2202 "them. If none are specified, disable all "
2203 "breakpoints.",
2204 nullptr) {
2206 "Disable the specified breakpoint(s) without deleting them. \
2207If none are specified, disable all breakpoints."
2208 R"(
2209
2210)"
2211 "Note: disabling a breakpoint will cause none of its locations to be hit \
2212regardless of whether individual locations are enabled or disabled. After the sequence:"
2213 R"(
2214
2215 (lldb) break disable 1
2216 (lldb) break enable 1.1
2217
2218execution will NOT stop at location 1.1. To achieve that, type:
2219
2220 (lldb) break disable 1.*
2221 (lldb) break enable 1.1
2222
2223)"
2224 "The first command disables all locations for breakpoint 1, \
2225the second re-enables the first location.");
2226
2229
2230 ~CommandObjectBreakpointDisable() override = default;
2231
2232 void
2234 OptionElementVector &opt_element_vector) override {
2237 }
2238
2239protected:
2240 void DoExecute(Args &command, CommandReturnObject &result) override {
2241 Target &target = GetTarget();
2242 std::unique_lock<std::recursive_mutex> lock;
2243 target.GetBreakpointList().GetListMutex(lock);
2244
2245 const BreakpointList &breakpoints = target.GetBreakpointList();
2246 size_t num_breakpoints = breakpoints.GetSize();
2247
2248 if (num_breakpoints == 0) {
2249 result.AppendError("no breakpoints exist to be disabled");
2250 return;
2251 }
2252
2253 if (command.empty()) {
2254 // No breakpoint selected; disable all currently set breakpoints.
2257 "All breakpoints disabled. ({0} breakpoints)\n", num_breakpoints);
2259 } else {
2260 // Particular breakpoint selected; disable that breakpoint.
2261 BreakpointIDList valid_bp_ids;
2262
2264 command, target, result, &valid_bp_ids,
2265 BreakpointName::Permissions::PermissionKinds::disablePerm);
2266
2267 if (result.Succeeded()) {
2268 int disable_count = 0;
2269 int loc_count = 0;
2270 const size_t count = valid_bp_ids.GetSize();
2271 for (size_t i = 0; i < count; ++i) {
2272 BreakpointID cur_bp_id = valid_bp_ids.GetBreakpointIDAtIndex(i);
2273
2274 if (cur_bp_id.GetBreakpointID() != LLDB_INVALID_BREAK_ID) {
2275 Breakpoint *breakpoint =
2276 target.GetBreakpointByID(cur_bp_id.GetBreakpointID()).get();
2277 if (cur_bp_id.GetLocationID() != LLDB_INVALID_BREAK_ID) {
2278 BreakpointLocation *location =
2279 breakpoint->FindLocationByID(cur_bp_id.GetLocationID()).get();
2280 if (location) {
2281 if (llvm::Error error = location->SetEnabled(false))
2283 "failed to disable breakpoint location: {0}",
2284 llvm::fmt_consume(std::move(error)));
2285 ++loc_count;
2286 }
2287 } else {
2288 breakpoint->SetEnabled(false);
2289 ++disable_count;
2290 }
2291 }
2292 }
2293 result.AppendMessageWithFormatv("{0} breakpoints disabled.",
2294 disable_count + loc_count);
2296 }
2297 }
2298 }
2299};
2300
2301// CommandObjectBreakpointList
2302
2303#pragma mark List::CommandOptions
2304#define LLDB_OPTIONS_breakpoint_list
2305#include "CommandOptions.inc"
2306
2307#pragma mark List
2308
2310public:
2313 interpreter, "breakpoint list",
2314 "List some or all breakpoints at configurable levels of detail.") {
2315
2316 // Define the first (and only) variant of this arg.
2318 }
2319
2320 ~CommandObjectBreakpointList() override = default;
2321
2322 Options *GetOptions() override { return &m_options; }
2323
2324 class CommandOptions : public Options {
2325 public:
2326 CommandOptions() = default;
2327
2328 ~CommandOptions() override = default;
2329
2330 Status SetOptionValue(uint32_t option_idx, llvm::StringRef option_arg,
2331 ExecutionContext *execution_context) override {
2332 Status error;
2333 const int short_option = m_getopt_table[option_idx].val;
2334
2335 switch (short_option) {
2336 case 'b':
2338 break;
2339 case 'D':
2340 m_use_dummy = true;
2341 break;
2342 case 'f':
2344 break;
2345 case 'v':
2347 break;
2348 case 'i':
2349 m_internal = true;
2350 break;
2351 default:
2352 llvm_unreachable("Unimplemented option");
2353 }
2354
2355 return error;
2356 }
2357
2358 void OptionParsingStarting(ExecutionContext *execution_context) override {
2360 m_internal = false;
2361 m_use_dummy = false;
2362 }
2363
2364 llvm::ArrayRef<OptionDefinition> GetDefinitions() override {
2365 return llvm::ArrayRef(g_breakpoint_list_options);
2366 }
2367
2368 // Instance variables to hold the values for command options.
2369
2371
2373 bool m_use_dummy = false;
2374 };
2375
2376protected:
2377 void DoExecute(Args &command, CommandReturnObject &result) override {
2378 Target &target = m_options.m_use_dummy ? GetDummyTarget() : GetTarget();
2379
2380 const BreakpointList &breakpoints =
2381 target.GetBreakpointList(m_options.m_internal);
2382 std::unique_lock<std::recursive_mutex> lock;
2383 target.GetBreakpointList(m_options.m_internal).GetListMutex(lock);
2384
2385 size_t num_breakpoints = breakpoints.GetSize();
2386
2387 if (num_breakpoints == 0) {
2388 result.AppendMessage("No breakpoints currently set.");
2390 return;
2391 }
2392
2393 Stream &output_stream = result.GetOutputStream();
2394
2395 if (command.empty()) {
2396 // No breakpoint selected; show info about all currently set breakpoints.
2397 result.AppendMessage("Current breakpoints:");
2398 for (size_t i = 0; i < num_breakpoints; ++i) {
2399 Breakpoint *breakpoint = breakpoints.GetBreakpointAtIndex(i).get();
2400 if (breakpoint->AllowList())
2401 AddBreakpointDescription(&output_stream, breakpoint,
2402 m_options.m_level);
2403 }
2405 } else {
2406 // Particular breakpoints selected; show info about that breakpoint.
2407 BreakpointIDList valid_bp_ids;
2409 command, target, result, &valid_bp_ids,
2411
2412 if (result.Succeeded()) {
2413 for (size_t i = 0; i < valid_bp_ids.GetSize(); ++i) {
2414 BreakpointID cur_bp_id = valid_bp_ids.GetBreakpointIDAtIndex(i);
2415 Breakpoint *breakpoint =
2416 target.GetBreakpointByID(cur_bp_id.GetBreakpointID()).get();
2417 AddBreakpointDescription(&output_stream, breakpoint,
2418 m_options.m_level);
2419 }
2421 } else {
2422 result.AppendError("invalid breakpoint ID");
2423 }
2424 }
2425 }
2426
2427private:
2429};
2430
2431// CommandObjectBreakpointClear
2432#pragma mark Clear::CommandOptions
2433
2434#define LLDB_OPTIONS_breakpoint_clear
2435#include "CommandOptions.inc"
2436
2437#pragma mark Clear
2438
2440public:
2442
2444 : CommandObjectParsed(interpreter, "breakpoint clear",
2445 "Delete or disable breakpoints matching the "
2446 "specified source file and line.",
2447 "breakpoint clear <cmd-options>") {}
2448
2449 ~CommandObjectBreakpointClear() override = default;
2450
2451 Options *GetOptions() override { return &m_options; }
2452
2453 class CommandOptions : public Options {
2454 public:
2455 CommandOptions() = default;
2456
2457 ~CommandOptions() override = default;
2458
2459 Status SetOptionValue(uint32_t option_idx, llvm::StringRef option_arg,
2460 ExecutionContext *execution_context) override {
2461 Status error;
2462 const int short_option = m_getopt_table[option_idx].val;
2463
2464 switch (short_option) {
2465 case 'f':
2466 m_filename.assign(std::string(option_arg));
2467 break;
2468
2469 case 'l':
2470 option_arg.getAsInteger(0, m_line_num);
2471 break;
2472
2473 default:
2474 llvm_unreachable("Unimplemented option");
2475 }
2476
2477 return error;
2478 }
2479
2480 void OptionParsingStarting(ExecutionContext *execution_context) override {
2481 m_filename.clear();
2482 m_line_num = 0;
2483 }
2484
2485 llvm::ArrayRef<OptionDefinition> GetDefinitions() override {
2486 return llvm::ArrayRef(g_breakpoint_clear_options);
2487 }
2488
2489 // Instance variables to hold the values for command options.
2490
2491 std::string m_filename;
2492 uint32_t m_line_num = 0;
2493 };
2494
2495protected:
2496 void DoExecute(Args &command, CommandReturnObject &result) override {
2497 Target &target = GetTarget();
2498
2499 // The following are the various types of breakpoints that could be
2500 // cleared:
2501 // 1). -f -l (clearing breakpoint by source location)
2502
2504
2505 if (m_options.m_line_num != 0)
2506 break_type = eClearTypeFileAndLine;
2507
2508 std::unique_lock<std::recursive_mutex> lock;
2509 target.GetBreakpointList().GetListMutex(lock);
2510
2511 BreakpointList &breakpoints = target.GetBreakpointList();
2512 size_t num_breakpoints = breakpoints.GetSize();
2513
2514 // Early return if there's no breakpoint at all.
2515 if (num_breakpoints == 0) {
2516 result.AppendError("breakpoint clear: no breakpoint cleared");
2517 return;
2518 }
2519
2520 // Find matching breakpoints and delete them.
2521
2522 // First create a copy of all the IDs.
2523 std::vector<break_id_t> BreakIDs;
2524 for (size_t i = 0; i < num_breakpoints; ++i)
2525 BreakIDs.push_back(breakpoints.GetBreakpointAtIndex(i)->GetID());
2526
2527 int num_cleared = 0;
2528 StreamString ss;
2529 switch (break_type) {
2530 case eClearTypeFileAndLine: // Breakpoint by source position
2531 {
2532 const ConstString filename(m_options.m_filename.c_str());
2534
2535 for (size_t i = 0; i < num_breakpoints; ++i) {
2536 Breakpoint *bp = breakpoints.FindBreakpointByID(BreakIDs[i]).get();
2537
2538 if (bp->GetMatchingFileLine(filename, m_options.m_line_num, loc_coll)) {
2539 // If the collection size is 0, it's a full match and we can just
2540 // remove the breakpoint.
2541 if (loc_coll.GetSize() == 0) {
2543 ss.EOL();
2544 target.RemoveBreakpointByID(bp->GetID());
2545 ++num_cleared;
2546 }
2547 }
2548 }
2549 } break;
2550
2551 default:
2552 break;
2553 }
2554
2555 if (num_cleared > 0) {
2556 Stream &output_stream = result.GetOutputStream();
2557 output_stream.Printf("%d breakpoints cleared:\n", num_cleared);
2558 output_stream << ss.GetString();
2559 output_stream.EOL();
2561 } else {
2562 result.AppendError("breakpoint clear: no breakpoint cleared");
2563 }
2564 }
2565
2566private:
2568};
2569
2570// CommandObjectBreakpointDelete
2571#define LLDB_OPTIONS_breakpoint_delete
2572#include "CommandOptions.inc"
2573
2574#pragma mark Delete
2575
2577public:
2579 : CommandObjectParsed(interpreter, "breakpoint delete",
2580 "Delete the specified breakpoint(s). If no "
2581 "breakpoints are specified, delete them all.",
2582 nullptr) {
2584 }
2585
2587
2588 void
2594
2595 Options *GetOptions() override { return &m_options; }
2596
2597 class CommandOptions : public Options {
2598 public:
2599 CommandOptions() = default;
2600
2601 ~CommandOptions() override = default;
2602
2603 Status SetOptionValue(uint32_t option_idx, llvm::StringRef option_arg,
2604 ExecutionContext *execution_context) override {
2605 Status error;
2606 const int short_option = m_getopt_table[option_idx].val;
2607
2608 switch (short_option) {
2609 case 'f':
2610 m_force = true;
2611 break;
2612
2613 case 'D':
2614 m_use_dummy = true;
2615 break;
2616
2617 case 'd':
2618 m_delete_disabled = true;
2619 break;
2620
2621 default:
2622 llvm_unreachable("Unimplemented option");
2623 }
2624
2625 return error;
2626 }
2627
2628 void OptionParsingStarting(ExecutionContext *execution_context) override {
2629 m_use_dummy = false;
2630 m_force = false;
2631 m_delete_disabled = false;
2632 }
2633
2634 llvm::ArrayRef<OptionDefinition> GetDefinitions() override {
2635 return llvm::ArrayRef(g_breakpoint_delete_options);
2636 }
2637
2638 // Instance variables to hold the values for command options.
2639 bool m_use_dummy = false;
2640 bool m_force = false;
2641 bool m_delete_disabled = false;
2642 };
2643
2644protected:
2645 void DoExecute(Args &command, CommandReturnObject &result) override {
2646 Target &target = m_options.m_use_dummy ? GetDummyTarget() : GetTarget();
2647 result.Clear();
2648
2649 std::unique_lock<std::recursive_mutex> lock;
2650 target.GetBreakpointList().GetListMutex(lock);
2651
2652 BreakpointList &breakpoints = target.GetBreakpointList();
2653
2654 size_t num_breakpoints = breakpoints.GetSize();
2655
2656 if (num_breakpoints == 0) {
2657 result.AppendError("no breakpoints exist to be deleted");
2658 return;
2659 }
2660
2661 // Handle the delete all breakpoints case:
2662 if (command.empty() && !m_options.m_delete_disabled) {
2663 if (!m_options.m_force &&
2664 !m_interpreter.Confirm(
2665 "About to delete all breakpoints, do you want to do that?",
2666 true)) {
2667 result.AppendMessage("Operation cancelled...");
2668 } else {
2669 target.RemoveAllowedBreakpoints();
2671 "All breakpoints removed. ({0} breakpoint{1})", num_breakpoints,
2672 num_breakpoints > 1 ? "s" : "");
2673 }
2675 return;
2676 }
2677
2678 // Either we have some kind of breakpoint specification(s),
2679 // or we are handling "break disable --deleted". Gather the list
2680 // of breakpoints to delete here, the we'll delete them below.
2681 BreakpointIDList valid_bp_ids;
2682
2683 if (m_options.m_delete_disabled) {
2684 BreakpointIDList excluded_bp_ids;
2685
2686 if (!command.empty()) {
2688 command, target, result, &excluded_bp_ids,
2690 if (!result.Succeeded())
2691 return;
2692 }
2693
2694 for (auto breakpoint_sp : breakpoints.Breakpoints()) {
2695 if (!breakpoint_sp->IsEnabled() && breakpoint_sp->AllowDelete()) {
2696 BreakpointID bp_id(breakpoint_sp->GetID());
2697 if (!excluded_bp_ids.Contains(bp_id))
2698 valid_bp_ids.AddBreakpointID(bp_id);
2699 }
2700 }
2701 if (valid_bp_ids.GetSize() == 0) {
2702 result.AppendError("no disabled breakpoints");
2703 return;
2704 }
2705 } else {
2707 command, target, result, &valid_bp_ids,
2709 if (!result.Succeeded())
2710 return;
2711 }
2712
2713 int delete_count = 0;
2714 int disable_count = 0;
2715 const size_t count = valid_bp_ids.GetSize();
2716 for (size_t i = 0; i < count; ++i) {
2717 BreakpointID cur_bp_id = valid_bp_ids.GetBreakpointIDAtIndex(i);
2718
2719 if (cur_bp_id.GetBreakpointID() != LLDB_INVALID_BREAK_ID) {
2720 if (cur_bp_id.GetLocationID() != LLDB_INVALID_BREAK_ID) {
2721 Breakpoint *breakpoint =
2722 target.GetBreakpointByID(cur_bp_id.GetBreakpointID()).get();
2723 BreakpointLocation *location =
2724 breakpoint->FindLocationByID(cur_bp_id.GetLocationID()).get();
2725 // It makes no sense to try to delete individual locations, so we
2726 // disable them instead.
2727 if (location) {
2728 if (llvm::Error error = location->SetEnabled(false))
2730 "failed to disable breakpoint location: {0}",
2731 llvm::fmt_consume(std::move(error)));
2732 ++disable_count;
2733 }
2734 } else {
2735 target.RemoveBreakpointByID(cur_bp_id.GetBreakpointID());
2736 ++delete_count;
2737 }
2738 }
2739 }
2741 "{0} breakpoints deleted; {1} breakpoint locations disabled.",
2742 delete_count, disable_count);
2744 }
2745
2746private:
2748};
2749
2750// CommandObjectBreakpointName
2751#define LLDB_OPTIONS_breakpoint_name
2752#include "CommandOptions.inc"
2753
2755public:
2758
2759 ~BreakpointNameOptionGroup() override = default;
2760
2761 llvm::ArrayRef<OptionDefinition> GetDefinitions() override {
2762 return llvm::ArrayRef(g_breakpoint_name_options);
2763 }
2764
2765 Status SetOptionValue(uint32_t option_idx, llvm::StringRef option_arg,
2766 ExecutionContext *execution_context) override {
2767 Status error;
2768 const int short_option = g_breakpoint_name_options[option_idx].short_option;
2769 const char *long_option = g_breakpoint_name_options[option_idx].long_option;
2770
2771 switch (short_option) {
2772 case 'N':
2774 error.Success())
2775 m_name.SetValueFromString(option_arg);
2776 break;
2777 case 'B':
2778 if (m_breakpoint.SetValueFromString(option_arg).Fail())
2780 CreateOptionParsingError(option_arg, short_option, long_option,
2782 break;
2783 case 'D':
2784 if (m_use_dummy.SetValueFromString(option_arg).Fail())
2786 CreateOptionParsingError(option_arg, short_option, long_option,
2788 break;
2789 case 'H':
2790 m_help_string.SetValueFromString(option_arg);
2791 break;
2792
2793 default:
2794 llvm_unreachable("Unimplemented option");
2795 }
2796 return error;
2797 }
2798
2799 void OptionParsingStarting(ExecutionContext *execution_context) override {
2800 m_name.Clear();
2801 m_breakpoint.Clear();
2802 m_use_dummy.Clear();
2803 m_use_dummy.SetDefaultValue(false);
2804 m_help_string.Clear();
2805 }
2806
2811};
2812
2813#define LLDB_OPTIONS_breakpoint_access
2814#include "CommandOptions.inc"
2815
2817public:
2819
2820 ~BreakpointAccessOptionGroup() override = default;
2821
2822 llvm::ArrayRef<OptionDefinition> GetDefinitions() override {
2823 return llvm::ArrayRef(g_breakpoint_access_options);
2824 }
2825 Status SetOptionValue(uint32_t option_idx, llvm::StringRef option_arg,
2826 ExecutionContext *execution_context) override {
2827 Status error;
2828 const int short_option =
2829 g_breakpoint_access_options[option_idx].short_option;
2830 const char *long_option =
2831 g_breakpoint_access_options[option_idx].long_option;
2832
2833 switch (short_option) {
2834 case 'L': {
2835 bool value, success;
2836 value = OptionArgParser::ToBoolean(option_arg, false, &success);
2837 if (success) {
2838 m_permissions.SetAllowList(value);
2839 } else
2841 CreateOptionParsingError(option_arg, short_option, long_option,
2843 } break;
2844 case 'A': {
2845 bool value, success;
2846 value = OptionArgParser::ToBoolean(option_arg, false, &success);
2847 if (success) {
2848 m_permissions.SetAllowDisable(value);
2849 } else
2851 CreateOptionParsingError(option_arg, short_option, long_option,
2853 } break;
2854 case 'D': {
2855 bool value, success;
2856 value = OptionArgParser::ToBoolean(option_arg, false, &success);
2857 if (success) {
2858 m_permissions.SetAllowDelete(value);
2859 } else
2861 CreateOptionParsingError(option_arg, short_option, long_option,
2863 } break;
2864 default:
2865 llvm_unreachable("Unimplemented option");
2866 }
2867
2868 return error;
2869 }
2870
2871 void OptionParsingStarting(ExecutionContext *execution_context) override {}
2872
2874 return m_permissions;
2875 }
2877};
2878
2880public:
2883 interpreter, "configure",
2884 "Configure the options for the breakpoint"
2885 " name provided. "
2886 "If you provide a breakpoint id, the options will be copied from "
2887 "the breakpoint, otherwise only the options specified will be set "
2888 "on the name.",
2889 "breakpoint name configure <command-options> "
2890 "<breakpoint-name-list>") {
2892
2898 m_option_group.Finalize();
2899 }
2900
2902
2903 Options *GetOptions() override { return &m_option_group; }
2904
2905protected:
2906 void DoExecute(Args &command, CommandReturnObject &result) override {
2907
2908 const size_t argc = command.GetArgumentCount();
2909 if (argc == 0) {
2910 result.AppendError("no names provided");
2911 return;
2912 }
2913
2914 Target &target = GetTarget();
2915
2916 std::unique_lock<std::recursive_mutex> lock;
2917 target.GetBreakpointList().GetListMutex(lock);
2918
2919 // Make a pass through first to see that all the names are legal.
2920 for (auto &entry : command.entries()) {
2921 Status error;
2922 if (!BreakpointID::StringIsBreakpointName(entry.ref(), error)) {
2923 result.AppendErrorWithFormat("Invalid breakpoint name: %s - %s",
2924 entry.c_str(), error.AsCString());
2925 return;
2926 }
2927 }
2928 // Now configure them, we already pre-checked the names so we don't need to
2929 // check the error:
2930 BreakpointSP bp_sp;
2931 if (m_bp_id.m_breakpoint.OptionWasSet()) {
2932 lldb::break_id_t bp_id =
2933 m_bp_id.m_breakpoint.GetValueAs<uint64_t>().value_or(0);
2934 bp_sp = target.GetBreakpointByID(bp_id);
2935 if (!bp_sp) {
2936 result.AppendErrorWithFormatv("Could not find specified breakpoint {0}",
2937 bp_id);
2938 return;
2939 }
2940 }
2941
2942 Status error;
2943 for (auto &entry : command.entries()) {
2944 ConstString name(entry.c_str());
2945 BreakpointName *bp_name = target.FindBreakpointName(name, true, error);
2946 if (!bp_name)
2947 continue;
2948 if (m_bp_id.m_help_string.OptionWasSet())
2949 bp_name->SetHelp(m_bp_id.m_help_string.GetValueAs<llvm::StringRef>()
2950 .value_or("")
2951 .str()
2952 .c_str());
2953
2954 if (bp_sp)
2955 target.ConfigureBreakpointName(*bp_name, bp_sp->GetOptions(),
2956 m_access_options.GetPermissions());
2957 else
2958 target.ConfigureBreakpointName(*bp_name,
2959 m_bp_opts.GetBreakpointOptions(),
2960 m_access_options.GetPermissions());
2961 }
2962 }
2963
2964private:
2965 BreakpointNameOptionGroup m_bp_id; // Only using the id part of this.
2969};
2970
2972public:
2975 interpreter, "add", "Add a name to the breakpoints provided.",
2976 "breakpoint name add <command-options> <breakpoint-id-list>") {
2978
2980 m_option_group.Finalize();
2981 }
2982
2984
2985 void
2991
2992 Options *GetOptions() override { return &m_option_group; }
2993
2994protected:
2995 void DoExecute(Args &command, CommandReturnObject &result) override {
2996 if (!m_name_options.m_name.OptionWasSet()) {
2997 result.AppendError("no name option provided");
2998 return;
2999 }
3000
3001 Target &target =
3002 m_name_options.m_use_dummy ? GetDummyTarget() : GetTarget();
3003
3004 std::unique_lock<std::recursive_mutex> lock;
3005 target.GetBreakpointList().GetListMutex(lock);
3006
3007 const BreakpointList &breakpoints = target.GetBreakpointList();
3008
3009 size_t num_breakpoints = breakpoints.GetSize();
3010 if (num_breakpoints == 0) {
3011 result.AppendError("no breakpoints, cannot add names");
3012 return;
3013 }
3014
3015 // Particular breakpoint selected; disable that breakpoint.
3016 BreakpointIDList valid_bp_ids;
3018 command, target, result, &valid_bp_ids,
3020
3021 if (result.Succeeded()) {
3022 if (valid_bp_ids.GetSize() == 0) {
3023 result.AppendError("no breakpoints specified, cannot add names");
3024 return;
3025 }
3026 size_t num_valid_ids = valid_bp_ids.GetSize();
3027 const char *bp_name = m_name_options.m_name.GetCurrentValue();
3028 Status error; // This error reports illegal names, but we've already
3029 // checked that, so we don't need to check it again here.
3030 for (size_t index = 0; index < num_valid_ids; index++) {
3031 lldb::break_id_t bp_id =
3032 valid_bp_ids.GetBreakpointIDAtIndex(index).GetBreakpointID();
3033 BreakpointSP bp_sp = breakpoints.FindBreakpointByID(bp_id);
3034 target.AddNameToBreakpoint(bp_sp, bp_name, error);
3035 }
3036 }
3037 }
3038
3039private:
3042};
3043
3045public:
3048 interpreter, "delete",
3049 "Delete a name from the breakpoints provided.",
3050 "breakpoint name delete <command-options> <breakpoint-id-list>") {
3052
3054 m_option_group.Finalize();
3055 }
3056
3058
3059 void
3065
3066 Options *GetOptions() override { return &m_option_group; }
3067
3068protected:
3069 void DoExecute(Args &command, CommandReturnObject &result) override {
3070 if (!m_name_options.m_name.OptionWasSet()) {
3071 result.AppendError("no name option provided");
3072 return;
3073 }
3074
3075 Target &target =
3076 m_name_options.m_use_dummy ? GetDummyTarget() : GetTarget();
3077
3078 std::unique_lock<std::recursive_mutex> lock;
3079 target.GetBreakpointList().GetListMutex(lock);
3080
3081 const BreakpointList &breakpoints = target.GetBreakpointList();
3082
3083 size_t num_breakpoints = breakpoints.GetSize();
3084 if (num_breakpoints == 0) {
3085 result.AppendError("no breakpoints, cannot delete names");
3086 return;
3087 }
3088
3089 // Particular breakpoint selected; disable that breakpoint.
3090 BreakpointIDList valid_bp_ids;
3092 command, target, result, &valid_bp_ids,
3094
3095 if (result.Succeeded()) {
3096 if (valid_bp_ids.GetSize() == 0) {
3097 result.AppendError("no breakpoints specified, cannot delete names");
3098 return;
3099 }
3100 ConstString bp_name(m_name_options.m_name.GetCurrentValue());
3101 size_t num_valid_ids = valid_bp_ids.GetSize();
3102 for (size_t index = 0; index < num_valid_ids; index++) {
3103 lldb::break_id_t bp_id =
3104 valid_bp_ids.GetBreakpointIDAtIndex(index).GetBreakpointID();
3105 BreakpointSP bp_sp = breakpoints.FindBreakpointByID(bp_id);
3106 target.RemoveNameFromBreakpoint(bp_sp, bp_name);
3107 }
3108 }
3109 }
3110
3111private:
3114};
3115
3117public:
3119 : CommandObjectParsed(interpreter, "list",
3120 "List either the names for a breakpoint or info "
3121 "about a given name. With no arguments, lists all "
3122 "names",
3123 "breakpoint name list <command-options>") {
3125 m_option_group.Finalize();
3126 }
3127
3129
3130 Options *GetOptions() override { return &m_option_group; }
3131
3132protected:
3133 void DoExecute(Args &command, CommandReturnObject &result) override {
3134 Target &target =
3135 m_name_options.m_use_dummy ? GetDummyTarget() : GetTarget();
3136
3137 std::vector<std::string> name_list;
3138 if (command.empty()) {
3139 target.GetBreakpointNames(name_list);
3140 } else {
3141 for (const Args::ArgEntry &arg : command) {
3142 name_list.push_back(arg.c_str());
3143 }
3144 }
3145
3146 if (name_list.empty()) {
3147 result.AppendMessage("No breakpoint names found.");
3148 } else {
3149 for (const std::string &name_str : name_list) {
3150 const char *name = name_str.c_str();
3151 // First print out the options for the name:
3152 Status error;
3153 BreakpointName *bp_name =
3154 target.FindBreakpointName(ConstString(name), false, error);
3155 if (bp_name) {
3156 StreamString s;
3157 result.AppendMessageWithFormatv("Name: {0}", name);
3158 if (bp_name->GetDescription(&s, eDescriptionLevelFull)) {
3159 result.AppendMessage(s.GetString());
3160 }
3161
3162 std::unique_lock<std::recursive_mutex> lock;
3163 target.GetBreakpointList().GetListMutex(lock);
3164
3165 BreakpointList &breakpoints = target.GetBreakpointList();
3166 bool any_set = false;
3167 for (BreakpointSP bp_sp : breakpoints.Breakpoints()) {
3168 if (bp_sp->MatchesName(name)) {
3169 StreamString s;
3170 any_set = true;
3171 bp_sp->GetDescription(&s, eDescriptionLevelBrief);
3172 s.EOL();
3173 result.AppendMessage(s.GetString());
3174 }
3175 }
3176 if (!any_set)
3177 result.AppendMessage("No breakpoints using this name.");
3178 } else {
3179 result.AppendMessageWithFormatv("Name: {0} not found.", name);
3180 }
3181 }
3182 }
3183 }
3184
3185private:
3188};
3189
3190// CommandObjectBreakpointName
3192public:
3195 interpreter, "name", "Commands to manage breakpoint names") {
3196
3197
3199 R"(
3200Breakpoint names provide a general tagging mechanism for breakpoints. Each
3201breakpoint name can be added to any number of breakpoints, and each breakpoint
3202can have any number of breakpoint names attached to it. For instance:
3203
3204 (lldb) break name add -N MyName 1-10
3205
3206adds the name MyName to breakpoints 1-10, and:
3207
3208 (lldb) break set -n myFunc -N Name1 -N Name2
3209
3210adds two names to the breakpoint set at myFunc.
3211
3212They have a number of interrelated uses:
3213
32141) They provide a stable way to refer to a breakpoint (e.g. in another
3215breakpoint's action). Using the breakpoint ID for this purpose is fragile, since
3216it depends on the order of breakpoint creation. Giving a name to the breakpoint
3217you want to act on, and then referring to it by name, is more robust:
3218
3219 (lldb) break set -n myFunc -N BKPT1
3220 (lldb) break set -n myOtherFunc -C "break disable BKPT1"
3221
32222) This is actually just a specific use of a more general feature of breakpoint
3223names. The <breakpt-id-list> argument type used to specify one or more
3224breakpoints in most of the commands that deal with breakpoints also accepts
3225breakpoint names. That allows you to refer to one breakpoint in a stable
3226manner, but also makes them a convenient grouping mechanism, allowing you to
3227easily act on a group of breakpoints by using their name, for instance disabling
3228them all in one action:
3229
3230 (lldb) break set -n myFunc -N Group1
3231 (lldb) break set -n myOtherFunc -N Group1
3232 (lldb) break disable Group1
3233
32343) But breakpoint names are also entities in their own right, and can be
3235configured with all the modifiable attributes of a breakpoint. Then when you
3236add a breakpoint name to a breakpoint, the breakpoint will be configured to
3237match the state of the breakpoint name. The link between the name and the
3238breakpoints sharing it remains live, so if you change the configuration on the
3239name, it will also change the configurations on the breakpoints:
3240
3241 (lldb) break name configure -i 10 IgnoreSome
3242 (lldb) break set -n myFunc -N IgnoreSome
3243 (lldb) break list IgnoreSome
3244 2: name = 'myFunc', locations = 0 (pending) Options: ignore: 10 enabled
3245 Names:
3246 IgnoreSome
3247 (lldb) break name configure -i 5 IgnoreSome
3248 (lldb) break list IgnoreSome
3249 2: name = 'myFunc', locations = 0 (pending) Options: ignore: 5 enabled
3250 Names:
3251 IgnoreSome
3252
3253Options that are not configured on a breakpoint name don't affect the value of
3254those options on the breakpoints they are added to. So for instance, if Name1
3255has the -i option configured and Name2 the -c option, adding both names to a
3256breakpoint will set the -i option from Name1 and the -c option from Name2, and
3257the other options will be unaltered.
3258
3259If you add multiple names to a breakpoint which have configured values for
3260the same option, the last name added's value wins.
3261
3262The "liveness" of these settings is one way, from name to breakpoint.
3263If you use "break modify" to change an option that is also configured on a name
3264which that breakpoint has, the "break modify" command will override the setting
3265for that breakpoint, but won't change the value configured in the name or on the
3266other breakpoints sharing that name.
3267
32684) Breakpoint names are also a convenient way to copy option sets from one
3269breakpoint to another. Using the -B option to "breakpoint name configure" makes
3270a name configured with all the options of the original breakpoint. Then
3271adding that name to another breakpoint copies over all the values from the
3272original breakpoint to the new one.
3273
32745) You can also use breakpoint names to hide breakpoints from the breakpoint
3275operations that act on all breakpoints: "break delete", "break disable" and
3276"break list". You do that by specifying a "false" value for the
3277--allow-{list,delete,disable} options to "breakpoint name configure" and then
3278adding that name to a breakpoint.
3279
3280This won't keep the breakpoint from being deleted or disabled if you refer to it
3281specifically by ID. The point of the feature is to make sure users don't
3282inadvertently delete or disable useful breakpoints (e.g. ones an IDE is using
3283for its own purposes) as part of a "delete all" or "disable all" operation. The
3284list hiding is because it's confusing for people to see breakpoints they
3285didn't set.
3286
3287)");
3288 CommandObjectSP add_command_object(
3289 new CommandObjectBreakpointNameAdd(interpreter));
3290 CommandObjectSP delete_command_object(
3291 new CommandObjectBreakpointNameDelete(interpreter));
3292 CommandObjectSP list_command_object(
3293 new CommandObjectBreakpointNameList(interpreter));
3294 CommandObjectSP configure_command_object(
3295 new CommandObjectBreakpointNameConfigure(interpreter));
3296
3297 LoadSubCommand("add", add_command_object);
3298 LoadSubCommand("delete", delete_command_object);
3299 LoadSubCommand("list", list_command_object);
3300 LoadSubCommand("configure", configure_command_object);
3301 }
3302
3303 ~CommandObjectBreakpointName() override = default;
3304};
3305
3306// CommandObjectBreakpointRead
3307#pragma mark Read::CommandOptions
3308#define LLDB_OPTIONS_breakpoint_read
3309#include "CommandOptions.inc"
3310
3311#pragma mark Read
3312
3314public:
3316 : CommandObjectParsed(interpreter, "breakpoint read",
3317 "Read and set the breakpoints previously saved to "
3318 "a file with \"breakpoint write\". ",
3319 nullptr) {}
3320
3321 ~CommandObjectBreakpointRead() override = default;
3322
3323 Options *GetOptions() override { return &m_options; }
3324
3325 class CommandOptions : public Options {
3326 public:
3327 CommandOptions() = default;
3328
3329 ~CommandOptions() override = default;
3330
3331 Status SetOptionValue(uint32_t option_idx, llvm::StringRef option_arg,
3332 ExecutionContext *execution_context) override {
3333 Status error;
3334 const int short_option = m_getopt_table[option_idx].val;
3335 const char *long_option =
3336 m_getopt_table[option_idx].definition->long_option;
3337
3338 switch (short_option) {
3339 case 'f':
3340 m_filename.assign(std::string(option_arg));
3341 break;
3342 case 'N': {
3343 Status name_error;
3344 if (!BreakpointID::StringIsBreakpointName(llvm::StringRef(option_arg),
3345 name_error)) {
3347 option_arg, short_option, long_option, name_error.AsCString()));
3348 }
3349 m_names.push_back(std::string(option_arg));
3350 break;
3351 }
3352 default:
3353 llvm_unreachable("Unimplemented option");
3354 }
3355
3356 return error;
3357 }
3358
3359 void OptionParsingStarting(ExecutionContext *execution_context) override {
3360 m_filename.clear();
3361 m_names.clear();
3362 }
3363
3364 llvm::ArrayRef<OptionDefinition> GetDefinitions() override {
3365 return llvm::ArrayRef(g_breakpoint_read_options);
3366 }
3367
3369 CompletionRequest &request, OptionElementVector &opt_element_vector,
3370 int opt_element_index, CommandInterpreter &interpreter) override {
3371 int opt_arg_pos = opt_element_vector[opt_element_index].opt_arg_pos;
3372 int opt_defs_index = opt_element_vector[opt_element_index].opt_defs_index;
3373
3374 switch (GetDefinitions()[opt_defs_index].short_option) {
3375 case 'f':
3377 interpreter, lldb::eDiskFileCompletion, request, nullptr);
3378 break;
3379
3380 case 'N':
3381 std::optional<FileSpec> file_spec;
3382 const llvm::StringRef dash_f("-f");
3383 for (int arg_idx = 0; arg_idx < opt_arg_pos; arg_idx++) {
3384 if (dash_f == request.GetParsedLine().GetArgumentAtIndex(arg_idx)) {
3385 file_spec.emplace(
3386 request.GetParsedLine().GetArgumentAtIndex(arg_idx + 1));
3387 break;
3388 }
3389 }
3390 if (!file_spec)
3391 return;
3392
3393 FileSystem::Instance().Resolve(*file_spec);
3394 Status error;
3395 StructuredData::ObjectSP input_data_sp =
3397 if (!error.Success())
3398 return;
3399
3400 StructuredData::Array *bkpt_array = input_data_sp->GetAsArray();
3401 if (!bkpt_array)
3402 return;
3403
3404 const size_t num_bkpts = bkpt_array->GetSize();
3405 for (size_t i = 0; i < num_bkpts; i++) {
3406 StructuredData::ObjectSP bkpt_object_sp =
3407 bkpt_array->GetItemAtIndex(i);
3408 if (!bkpt_object_sp)
3409 return;
3410
3411 StructuredData::Dictionary *bkpt_dict =
3412 bkpt_object_sp->GetAsDictionary();
3413 if (!bkpt_dict)
3414 return;
3415
3416 StructuredData::ObjectSP bkpt_data_sp =
3418 if (!bkpt_data_sp)
3419 return;
3420
3421 bkpt_dict = bkpt_data_sp->GetAsDictionary();
3422 if (!bkpt_dict)
3423 return;
3424
3425 StructuredData::Array *names_array;
3426
3427 if (!bkpt_dict->GetValueForKeyAsArray("Names", names_array))
3428 return;
3429
3430 size_t num_names = names_array->GetSize();
3431
3432 for (size_t i = 0; i < num_names; i++) {
3433 if (std::optional<llvm::StringRef> maybe_name =
3434 names_array->GetItemAtIndexAsString(i))
3435 request.TryCompleteCurrentArg(*maybe_name);
3436 }
3437 }
3438 }
3439 }
3440
3441 std::string m_filename;
3442 std::vector<std::string> m_names;
3443 };
3444
3445protected:
3446 void DoExecute(Args &command, CommandReturnObject &result) override {
3447 Target &target = GetTarget();
3448
3449 std::unique_lock<std::recursive_mutex> lock;
3450 target.GetBreakpointList().GetListMutex(lock);
3451
3452 FileSpec input_spec(m_options.m_filename);
3453 FileSystem::Instance().Resolve(input_spec);
3454 BreakpointIDList new_bps;
3455 Status error = target.CreateBreakpointsFromFile(input_spec,
3456 m_options.m_names, new_bps);
3457
3458 if (!error.Success()) {
3459 result.AppendError(error.AsCString());
3460 return;
3461 }
3462
3463 Stream &output_stream = result.GetOutputStream();
3464
3465 size_t num_breakpoints = new_bps.GetSize();
3466 if (num_breakpoints == 0) {
3467 result.AppendMessage("No breakpoints added.");
3468 } else {
3469 // No breakpoint selected; show info about all currently set breakpoints.
3470 result.AppendMessage("New breakpoints:");
3471 for (size_t i = 0; i < num_breakpoints; ++i) {
3472 BreakpointID bp_id = new_bps.GetBreakpointIDAtIndex(i);
3473 Breakpoint *bp = target.GetBreakpointList()
3475 .get();
3476 if (bp)
3478 false);
3479 }
3480 }
3481 }
3482
3483private:
3485};
3486
3487// CommandObjectBreakpointWrite
3488#pragma mark Write::CommandOptions
3489#define LLDB_OPTIONS_breakpoint_write
3490#include "CommandOptions.inc"
3491
3492#pragma mark Write
3494public:
3496 : CommandObjectParsed(interpreter, "breakpoint write",
3497 "Write the breakpoints listed to a file that can "
3498 "be read in with \"breakpoint read\". "
3499 "If given no arguments, writes all breakpoints.",
3500 nullptr) {
3502 }
3503
3504 ~CommandObjectBreakpointWrite() override = default;
3505
3506 void
3512
3513 Options *GetOptions() override { return &m_options; }
3514
3515 class CommandOptions : public Options {
3516 public:
3517 CommandOptions() = default;
3518
3519 ~CommandOptions() override = default;
3520
3521 Status SetOptionValue(uint32_t option_idx, llvm::StringRef option_arg,
3522 ExecutionContext *execution_context) override {
3523 Status error;
3524 const int short_option = m_getopt_table[option_idx].val;
3525
3526 switch (short_option) {
3527 case 'f':
3528 m_filename.assign(std::string(option_arg));
3529 break;
3530 case 'a':
3531 m_append = true;
3532 break;
3533 default:
3534 llvm_unreachable("Unimplemented option");
3535 }
3536
3537 return error;
3538 }
3539
3540 void OptionParsingStarting(ExecutionContext *execution_context) override {
3541 m_filename.clear();
3542 m_append = false;
3543 }
3544
3545 llvm::ArrayRef<OptionDefinition> GetDefinitions() override {
3546 return llvm::ArrayRef(g_breakpoint_write_options);
3547 }
3548
3549 // Instance variables to hold the values for command options.
3550
3551 std::string m_filename;
3552 bool m_append = false;
3553 };
3554
3555protected:
3556 void DoExecute(Args &command, CommandReturnObject &result) override {
3557 Target &target = GetTarget();
3558
3559 std::unique_lock<std::recursive_mutex> lock;
3560 target.GetBreakpointList().GetListMutex(lock);
3561
3562 BreakpointIDList valid_bp_ids;
3563 if (!command.empty()) {
3565 command, target, result, &valid_bp_ids,
3567
3568 if (!result.Succeeded()) {
3570 return;
3571 }
3572 }
3573 FileSpec file_spec(m_options.m_filename);
3574 FileSystem::Instance().Resolve(file_spec);
3575 Status error = target.SerializeBreakpointsToFile(file_spec, valid_bp_ids,
3576 m_options.m_append);
3577 if (!error.Success()) {
3578 result.AppendErrorWithFormat("error serializing breakpoints: %s.",
3579 error.AsCString());
3580 }
3581 }
3582
3583private:
3585};
3586
3587// CommandObjectMultiwordBreakpoint
3588#pragma mark MultiwordBreakpoint
3589
3591 CommandInterpreter &interpreter)
3593 interpreter, "breakpoint",
3594 "Commands for operating on breakpoints (see 'help b' for shorthand.)",
3595 "breakpoint <subcommand> [<command-options>]") {
3596 CommandObjectSP list_command_object(
3597 new CommandObjectBreakpointList(interpreter));
3598 CommandObjectSP enable_command_object(
3599 new CommandObjectBreakpointEnable(interpreter));
3600 CommandObjectSP disable_command_object(
3601 new CommandObjectBreakpointDisable(interpreter));
3602 CommandObjectSP clear_command_object(
3603 new CommandObjectBreakpointClear(interpreter));
3604 CommandObjectSP delete_command_object(
3605 new CommandObjectBreakpointDelete(interpreter));
3606 CommandObjectSP set_command_object(
3607 new CommandObjectBreakpointSet(interpreter));
3608 CommandObjectSP add_command_object(
3609 new CommandObjectBreakpointAdd(interpreter));
3610 CommandObjectSP command_command_object(
3611 new CommandObjectBreakpointCommand(interpreter));
3612 CommandObjectSP modify_command_object(
3613 new CommandObjectBreakpointModify(interpreter));
3614 CommandObjectSP name_command_object(
3615 new CommandObjectBreakpointName(interpreter));
3616 CommandObjectSP write_command_object(
3617 new CommandObjectBreakpointWrite(interpreter));
3618 CommandObjectSP read_command_object(
3619 new CommandObjectBreakpointRead(interpreter));
3620
3621 list_command_object->SetCommandName("breakpoint list");
3622 enable_command_object->SetCommandName("breakpoint enable");
3623 disable_command_object->SetCommandName("breakpoint disable");
3624 clear_command_object->SetCommandName("breakpoint clear");
3625 delete_command_object->SetCommandName("breakpoint delete");
3626 set_command_object->SetCommandName("breakpoint set");
3627 add_command_object->SetCommandName("breakpoint add");
3628 command_command_object->SetCommandName("breakpoint command");
3629 modify_command_object->SetCommandName("breakpoint modify");
3630 name_command_object->SetCommandName("breakpoint name");
3631 write_command_object->SetCommandName("breakpoint write");
3632 read_command_object->SetCommandName("breakpoint read");
3633
3634 LoadSubCommand("list", list_command_object);
3635 LoadSubCommand("enable", enable_command_object);
3636 LoadSubCommand("disable", disable_command_object);
3637 LoadSubCommand("clear", clear_command_object);
3638 LoadSubCommand("delete", delete_command_object);
3639 LoadSubCommand("set", set_command_object);
3640 LoadSubCommand("add", add_command_object);
3641 LoadSubCommand("command", command_command_object);
3642 LoadSubCommand("modify", modify_command_object);
3643 LoadSubCommand("name", name_command_object);
3644 LoadSubCommand("write", write_command_object);
3645 LoadSubCommand("read", read_command_object);
3646}
3647
3649
3651 Args &args, Target &target, bool allow_locations,
3652 CommandReturnObject &result, BreakpointIDList *valid_ids,
3653 BreakpointName::Permissions ::PermissionKinds purpose) {
3654 // args can be strings representing 1). integers (for breakpoint ids)
3655 // 2). the full breakpoint & location
3656 // canonical representation
3657 // 3). the word "to" or a hyphen,
3658 // representing a range (in which case there
3659 // had *better* be an entry both before &
3660 // after of one of the first two types.
3661 // 4). A breakpoint name
3662 // If args is empty, we will use the last created breakpoint (if there is
3663 // one.)
3664
3665 Args temp_args;
3666
3667 if (args.empty()) {
3668 if (target.GetLastCreatedBreakpoint()) {
3669 valid_ids->AddBreakpointID(BreakpointID(
3672 } else {
3673 result.AppendError(
3674 "No breakpoint specified and no last created breakpoint.");
3675 }
3676 return;
3677 }
3678
3679 // Create a new Args variable to use; copy any non-breakpoint-id-ranges stuff
3680 // directly from the old ARGS to the new TEMP_ARGS. Do not copy breakpoint
3681 // id range strings over; instead generate a list of strings for all the
3682 // breakpoint ids in the range, and shove all of those breakpoint id strings
3683 // into TEMP_ARGS.
3684
3685 if (llvm::Error err = BreakpointIDList::FindAndReplaceIDRanges(
3686 args, &target, allow_locations, purpose, temp_args)) {
3687 result.SetError(std::move(err));
3688 return;
3689 }
3691
3692 // NOW, convert the list of breakpoint id strings in TEMP_ARGS into an actual
3693 // BreakpointIDList:
3694
3695 for (llvm::StringRef temp_arg : temp_args.GetArgumentArrayRef())
3696 if (auto bp_id = BreakpointID::ParseCanonicalReference(temp_arg))
3697 valid_ids->AddBreakpointID(*bp_id);
3698
3699 // At this point, all of the breakpoint ids that the user passed in have
3700 // been converted to breakpoint IDs and put into valid_ids.
3701
3702 // Now that we've converted everything from args into a list of breakpoint
3703 // ids, go through our tentative list of breakpoint id's and verify that
3704 // they correspond to valid/currently set breakpoints.
3705
3706 const size_t count = valid_ids->GetSize();
3707 for (size_t i = 0; i < count; ++i) {
3708 BreakpointID cur_bp_id = valid_ids->GetBreakpointIDAtIndex(i);
3709 Breakpoint *breakpoint =
3710 target.GetBreakpointByID(cur_bp_id.GetBreakpointID()).get();
3711 if (breakpoint != nullptr) {
3712 lldb::break_id_t cur_loc_id = cur_bp_id.GetLocationID();
3713 // GetLocationID returns 0 when the location isn't specified.
3714 if (cur_loc_id != 0 && !breakpoint->FindLocationByID(cur_loc_id)) {
3715 StreamString id_str;
3717 &id_str, cur_bp_id.GetBreakpointID(), cur_bp_id.GetLocationID());
3718 i = valid_ids->GetSize() + 1;
3719 result.AppendErrorWithFormat(
3720 "'%s' is not a currently valid breakpoint/location id.\n",
3721 id_str.GetData());
3722 }
3723 } else {
3724 i = valid_ids->GetSize() + 1;
3725 result.AppendErrorWithFormat(
3726 "'%d' is not a currently valid breakpoint ID.\n",
3727 cur_bp_id.GetBreakpointID());
3728 }
3729 }
3730}
static bool GetDefaultFile(Target &target, StackFrame *cur_frame, FileSpec &file, CommandReturnObject &result)
static bool CopyOverBreakpointOptions(BreakpointSP bp_sp, BreakpointOptionGroup &bp_opts, const std::vector< std::string > &bp_names, CommandReturnObject &result)
static llvm::Expected< LanguageType > GetExceptionLanguageForLanguage(llvm::StringRef lang_name, char short_option='\0', llvm::StringRef long_option={})
static void AddBreakpointDescription(Stream *s, Breakpoint *bp, lldb::DescriptionLevel level)
static Status CompleteLineEntry(ExecutionContext &exe_ctx, OptionValueFileColonLine &line_entry)
static llvm::raw_ostream & error(Stream &strm)
llvm::ArrayRef< OptionDefinition > GetDefinitions() override
const BreakpointName::Permissions & GetPermissions() const
~BreakpointAccessOptionGroup() override=default
BreakpointName::Permissions m_permissions
Status SetOptionValue(uint32_t option_idx, llvm::StringRef option_arg, ExecutionContext *execution_context) override
void OptionParsingStarting(ExecutionContext *execution_context) override
BreakpointDummyOptionGroup()=default
llvm::ArrayRef< OptionDefinition > GetDefinitions() override
void OptionParsingStarting(ExecutionContext *execution_context) override
~BreakpointDummyOptionGroup() override=default
Status SetOptionValue(uint32_t option_idx, llvm::StringRef option_arg, ExecutionContext *execution_context) override
Status SetOptionValue(uint32_t option_idx, llvm::StringRef option_arg, ExecutionContext *execution_context) override
llvm::ArrayRef< OptionDefinition > GetDefinitions() override
~BreakpointNameOptionGroup() override=default
void OptionParsingStarting(ExecutionContext *execution_context) override
void OptionParsingStarting(ExecutionContext *execution_context) override
llvm::ArrayRef< OptionDefinition > GetDefinitions() override
const std::vector< std::string > & GetBreakpointNames()
Status SetOptionValue(uint32_t option_idx, llvm::StringRef option_value, ExecutionContext *execution_context) override
~BreakpointNamesOptionGroup() override=default
std::vector< std::string > m_breakpoint_names
BreakpointNamesOptionGroup()=default
Status SetOptionValue(uint32_t option_idx, llvm::StringRef option_arg, ExecutionContext *execution_context) override
void OptionParsingStarting(ExecutionContext *execution_context) override
llvm::ArrayRef< OptionDefinition > GetDefinitions() override
void DoExecute(Args &command, CommandReturnObject &result) override
CommandObjectBreakpointAddAddress(CommandInterpreter &interpreter)
~CommandObjectBreakpointAddAddress() override=default
llvm::ArrayRef< OptionDefinition > GetDefinitions() override
void OptionParsingStarting(ExecutionContext *execution_context) override
Status SetOptionValue(uint32_t option_idx, llvm::StringRef option_arg, ExecutionContext *execution_context) override
~CommandObjectBreakpointAddException() override=default
CommandObjectBreakpointAddException(CommandInterpreter &interpreter)
void DoExecute(Args &command, CommandReturnObject &result) override
llvm::ArrayRef< OptionDefinition > GetDefinitions() override
Status OptionParsingFinished(ExecutionContext *execution_context) override
void OptionParsingStarting(ExecutionContext *execution_context) override
Status SetOptionValue(uint32_t option_idx, llvm::StringRef option_arg, ExecutionContext *execution_context) override
std::vector< OptionValueFileColonLine > m_line_specs
CommandObjectBreakpointAddFile(CommandInterpreter &interpreter)
void DoExecute(Args &command, CommandReturnObject &result) override
~CommandObjectBreakpointAddFile() override=default
BreakpointDummyOptionGroup m_dummy_options
llvm::ArrayRef< OptionDefinition > GetDefinitions() override
void OptionParsingStarting(ExecutionContext *execution_context) override
Status SetOptionValue(uint32_t option_idx, llvm::StringRef option_arg, ExecutionContext *execution_context) override
BreakpointDummyOptionGroup m_dummy_options
~CommandObjectBreakpointAddName() override=default
CommandObjectBreakpointAddName(CommandInterpreter &interpreter)
void DoExecute(Args &command, CommandReturnObject &result) override
void OptionParsingStarting(ExecutionContext *execution_context) override
llvm::ArrayRef< OptionDefinition > GetDefinitions() override
Status SetOptionValue(uint32_t option_idx, llvm::StringRef option_arg, ExecutionContext *execution_context) override
void DoExecute(llvm::StringRef command, CommandReturnObject &result) override
~CommandObjectBreakpointAddPattern() override=default
CommandObjectBreakpointAddPattern(CommandInterpreter &interpreter)
llvm::ArrayRef< OptionDefinition > GetDefinitions() override
void OptionParsingStarting(ExecutionContext *execution_context) override
Status SetOptionValue(uint32_t option_idx, llvm::StringRef option_arg, ExecutionContext *execution_context) override
~CommandObjectBreakpointAddScripted() override=default
CommandObjectBreakpointAddScripted(CommandInterpreter &interpreter)
void DoExecute(Args &command, CommandReturnObject &result) override
OptionGroupPythonClassWithDict m_python_class_options
CommandObjectBreakpointAdd(CommandInterpreter &interpreter)
Status SetOptionValue(uint32_t option_idx, llvm::StringRef option_arg, ExecutionContext *execution_context) override
Set the value of an option.
llvm::ArrayRef< OptionDefinition > GetDefinitions() override
void OptionParsingStarting(ExecutionContext *execution_context) override
void DoExecute(Args &command, CommandReturnObject &result) override
CommandObjectBreakpointClear(CommandInterpreter &interpreter)
~CommandObjectBreakpointClear() override=default
void OptionParsingStarting(ExecutionContext *execution_context) override
llvm::ArrayRef< OptionDefinition > GetDefinitions() override
Status SetOptionValue(uint32_t option_idx, llvm::StringRef option_arg, ExecutionContext *execution_context) override
Set the value of an option.
CommandObjectBreakpointDelete(CommandInterpreter &interpreter)
~CommandObjectBreakpointDelete() override=default
void HandleArgumentCompletion(CompletionRequest &request, OptionElementVector &opt_element_vector) override
The default version handles argument definitions that have only one argument type,...
void DoExecute(Args &command, CommandReturnObject &result) override
~CommandObjectBreakpointDisable() override=default
CommandObjectBreakpointDisable(CommandInterpreter &interpreter)
void DoExecute(Args &command, CommandReturnObject &result) override
void HandleArgumentCompletion(CompletionRequest &request, OptionElementVector &opt_element_vector) override
The default version handles argument definitions that have only one argument type,...
~CommandObjectBreakpointEnable() override=default
void HandleArgumentCompletion(CompletionRequest &request, OptionElementVector &opt_element_vector) override
The default version handles argument definitions that have only one argument type,...
CommandObjectBreakpointEnable(CommandInterpreter &interpreter)
void DoExecute(Args &command, CommandReturnObject &result) override
llvm::ArrayRef< OptionDefinition > GetDefinitions() override
void OptionParsingStarting(ExecutionContext *execution_context) override
Status SetOptionValue(uint32_t option_idx, llvm::StringRef option_arg, ExecutionContext *execution_context) override
Set the value of an option.
~CommandObjectBreakpointList() override=default
void DoExecute(Args &command, CommandReturnObject &result) override
CommandObjectBreakpointList(CommandInterpreter &interpreter)
void DoExecute(Args &command, CommandReturnObject &result) override
BreakpointDummyOptionGroup m_dummy_opts
void HandleArgumentCompletion(CompletionRequest &request, OptionElementVector &opt_element_vector) override
The default version handles argument definitions that have only one argument type,...
CommandObjectBreakpointModify(CommandInterpreter &interpreter)
~CommandObjectBreakpointModify() override=default
void DoExecute(Args &command, CommandReturnObject &result) override
CommandObjectBreakpointNameAdd(CommandInterpreter &interpreter)
~CommandObjectBreakpointNameAdd() override=default
void HandleArgumentCompletion(CompletionRequest &request, OptionElementVector &opt_element_vector) override
The default version handles argument definitions that have only one argument type,...
~CommandObjectBreakpointNameConfigure() override=default
void DoExecute(Args &command, CommandReturnObject &result) override
CommandObjectBreakpointNameConfigure(CommandInterpreter &interpreter)
void HandleArgumentCompletion(CompletionRequest &request, OptionElementVector &opt_element_vector) override
The default version handles argument definitions that have only one argument type,...
CommandObjectBreakpointNameDelete(CommandInterpreter &interpreter)
void DoExecute(Args &command, CommandReturnObject &result) override
~CommandObjectBreakpointNameDelete() override=default
CommandObjectBreakpointNameList(CommandInterpreter &interpreter)
void DoExecute(Args &command, CommandReturnObject &result) override
~CommandObjectBreakpointNameList() override=default
~CommandObjectBreakpointName() override=default
CommandObjectBreakpointName(CommandInterpreter &interpreter)
void HandleOptionArgumentCompletion(CompletionRequest &request, OptionElementVector &opt_element_vector, int opt_element_index, CommandInterpreter &interpreter) override
Handles the generic bits of figuring out whether we are in an option, and if so completing it.
llvm::ArrayRef< OptionDefinition > GetDefinitions() override
Status SetOptionValue(uint32_t option_idx, llvm::StringRef option_arg, ExecutionContext *execution_context) override
Set the value of an option.
void OptionParsingStarting(ExecutionContext *execution_context) override
void DoExecute(Args &command, CommandReturnObject &result) override
CommandObjectBreakpointRead(CommandInterpreter &interpreter)
~CommandObjectBreakpointRead() override=default
void OptionParsingStarting(ExecutionContext *execution_context) override
llvm::ArrayRef< OptionDefinition > GetDefinitions() override
Status SetOptionValue(uint32_t option_idx, llvm::StringRef option_arg, ExecutionContext *execution_context) override
std::unordered_set< std::string > m_source_regex_func_names
~CommandObjectBreakpointSet() override=default
void DoExecute(Args &command, CommandReturnObject &result) override
OptionGroupPythonClassWithDict m_python_class_options
CommandObjectBreakpointSet(CommandInterpreter &interpreter)
BreakpointDummyOptionGroup m_dummy_options
llvm::ArrayRef< OptionDefinition > GetDefinitions() override
void OptionParsingStarting(ExecutionContext *execution_context) override
Status SetOptionValue(uint32_t option_idx, llvm::StringRef option_arg, ExecutionContext *execution_context) override
Set the value of an option.
void DoExecute(Args &command, CommandReturnObject &result) override
void HandleArgumentCompletion(CompletionRequest &request, OptionElementVector &opt_element_vector) override
The default version handles argument definitions that have only one argument type,...
CommandObjectBreakpointWrite(CommandInterpreter &interpreter)
~CommandObjectBreakpointWrite() override=default
A section + offset based address class.
Definition Address.h:62
A command line argument class.
Definition Args.h:33
llvm::ArrayRef< const char * > GetArgumentArrayRef() const
Gets the argument as an ArrayRef.
Definition Args.h:173
size_t GetArgumentCount() const
Gets the number of arguments left in this command object.
Definition Args.h:120
llvm::ArrayRef< ArgEntry > entries() const
Definition Args.h:132
size_t size() const
Definition Args.h:139
const char * GetArgumentAtIndex(size_t idx) const
Gets the NULL terminated C string argument pointer for the argument at index idx.
Definition Args.cpp:273
bool empty() const
Definition Args.h:122
bool Contains(BreakpointID bp_id) const
bool AddBreakpointID(BreakpointID bp_id)
BreakpointID GetBreakpointIDAtIndex(size_t index) const
static llvm::Error FindAndReplaceIDRanges(Args &old_args, Target *target, bool allow_locations, BreakpointName::Permissions ::PermissionKinds purpose, Args &new_args)
static std::optional< BreakpointID > ParseCanonicalReference(llvm::StringRef input)
Takes an input string containing the description of a breakpoint or breakpoint and location and retur...
lldb::break_id_t GetBreakpointID() const
lldb::break_id_t GetLocationID() const
static void GetCanonicalReference(Stream *s, lldb::break_id_t break_id, lldb::break_id_t break_loc_id)
Takes a breakpoint ID and the breakpoint location id and returns a string containing the canonical de...
static bool StringIsBreakpointName(llvm::StringRef str, Status &error)
Takes an input string and checks to see whether it is a breakpoint name.
General Outline: Allows adding and removing breakpoints and find by ID and index.
BreakpointIterable Breakpoints()
lldb::BreakpointSP FindBreakpointByID(lldb::break_id_t breakID) const
Returns a shared pointer to the breakpoint with id breakID.
void GetListMutex(std::unique_lock< std::recursive_mutex > &lock)
Sets the passed in Locker to hold the Breakpoint List mutex.
size_t GetSize() const
Returns the number of elements in this breakpoint list.
lldb::BreakpointSP GetBreakpointAtIndex(size_t i) const
Returns a shared pointer to the breakpoint with index i.
size_t GetSize() const
Returns the number of elements in this breakpoint location list.
General Outline: A breakpoint location is defined by the breakpoint that produces it,...
llvm::Error SetEnabled(bool enabled)
If enabled is true, enable the breakpoint, if false disable it.
BreakpointOptions & GetLocationOptions()
Use this to set location specific breakpoint options.
bool GetDescription(Stream *s, lldb::DescriptionLevel level)
void SetHelp(const char *description)
Status SetOptionValue(uint32_t option_idx, llvm::StringRef option_arg, ExecutionContext *execution_context) override
llvm::ArrayRef< OptionDefinition > GetDefinitions() override
Status OptionParsingFinished(ExecutionContext *execution_context) override
const BreakpointOptions & GetBreakpointOptions()
~BreakpointOptionGroup() override=default
void OptionParsingStarting(ExecutionContext *execution_context) override
"lldb/Breakpoint/BreakpointOptions.h" Class that manages the options on a breakpoint or breakpoint lo...
void CopyOverSetOptions(const BreakpointOptions &rhs)
Copy over only the options set in the incoming BreakpointOptions.
General Outline: A breakpoint has four main parts, a filter, a resolver, the list of breakpoint locat...
Definition Breakpoint.h:81
lldb::BreakpointLocationSP FindLocationByID(lldb::break_id_t bp_loc_id, bool use_facade=true)
Find a breakpoint location for a given breakpoint location ID.
void GetDescription(Stream *s, lldb::DescriptionLevel level, bool show_locations=false)
Put a description of this breakpoint into the stream s.
BreakpointOptions & GetOptions()
Returns the BreakpointOptions structure set at the breakpoint level.
static const char * GetSerializationKey()
Definition Breakpoint.h:160
bool GetMatchingFileLine(ConstString filename, uint32_t line_number, BreakpointLocationCollection &loc_coll)
Find breakpoint locations which match the (filename, line_number) description.
void SetEnabled(bool enable) override
If enable is true, enable the breakpoint, if false disable it.
static bool InvokeCommonCompletionCallbacks(CommandInterpreter &interpreter, uint32_t completion_mask, lldb_private::CompletionRequest &request, SearchFilter *searcher)
ExecutionContext GetExecutionContext() const
static void VerifyIDs(Args &args, Target &target, bool allow_locations, CommandReturnObject &result, BreakpointIDList *valid_ids, BreakpointName::Permissions::PermissionKinds purpose)
static void VerifyBreakpointOrLocationIDs(Args &args, Target &target, CommandReturnObject &result, BreakpointIDList *valid_ids, BreakpointName::Permissions ::PermissionKinds purpose)
CommandObjectMultiwordBreakpoint(CommandInterpreter &interpreter)
static void VerifyBreakpointIDs(Args &args, Target &target, CommandReturnObject &result, BreakpointIDList *valid_ids, BreakpointName::Permissions::PermissionKinds purpose)
bool LoadSubCommand(llvm::StringRef cmd_name, const lldb::CommandObjectSP &command_obj) override
CommandObjectMultiword(CommandInterpreter &interpreter, const char *name, const char *help=nullptr, const char *syntax=nullptr, uint32_t flags=0)
CommandObjectParsed(CommandInterpreter &interpreter, const char *name, const char *help=nullptr, const char *syntax=nullptr, uint32_t flags=0)
CommandObjectRaw(CommandInterpreter &interpreter, llvm::StringRef name, llvm::StringRef help="", llvm::StringRef syntax="", uint32_t flags=0)
std::vector< CommandArgumentData > CommandArgumentEntry
virtual void SetHelpLong(llvm::StringRef str)
void AddSimpleArgumentList(lldb::CommandArgumentType arg_type, ArgumentRepetitionType repetition_type=eArgRepeatPlain)
bool ParseOptionsAndNotify(Args &args, CommandReturnObject &result, OptionGroupOptions &group_options, ExecutionContext &exe_ctx)
std::vector< CommandArgumentEntry > m_arguments
void AddIDsArgumentData(IDType type)
CommandInterpreter & GetCommandInterpreter()
CommandInterpreter & m_interpreter
void AppendMessage(llvm::StringRef in_string)
void void AppendError(llvm::StringRef in_string)
std::string GetErrorString(bool with_diagnostics=true) const
Return the errors as a string.
void SetStatus(lldb::ReturnStatus status)
void AppendErrorWithFormat(const char *format,...) __attribute__((format(printf
void void AppendMessageWithFormatv(const char *format, Args &&...args)
void void AppendWarning(llvm::StringRef in_string)
void AppendErrorWithFormatv(const char *format, Args &&...args)
"lldb/Utility/ArgCompletionRequest.h"
void TryCompleteCurrentArg(llvm::StringRef completion, llvm::StringRef description="")
Adds a possible completion string if the completion would complete the current argument.
A uniqued constant string class.
Definition ConstString.h:40
A class to manage flag bits.
Definition Debugger.h:87
bool GetUseColor() const
Definition Debugger.cpp:484
"lldb/Target/ExecutionContext.h" A class that contains an execution context.
StackFrame * GetFramePtr() const
Returns a pointer to the frame object.
Target * GetTargetPtr() const
Returns a pointer to the target object.
const lldb::ThreadSP & GetThreadSP() const
Get accessor to get the thread shared pointer.
bool HasTargetScope() const
Returns true the ExecutionContext object contains a valid target.
Target & GetTargetRef() const
Returns a reference to the target object.
A file collection class.
A file utility class.
Definition FileSpec.h:57
static FileSystem & Instance()
void Resolve(llvm::SmallVectorImpl< char > &path, bool force_make_absolute=false)
Resolve path to make it canonical.
static llvm::Expected< lldb::LanguageType > GetExceptionLanguageForLanguage(llvm::StringRef lang_name)
Definition Language.cpp:159
static LanguageSet GetLanguagesSupportingTypeSystemsForExpressions()
Definition Language.cpp:471
static lldb::LanguageType GetLanguageTypeFromString(const char *string)=delete
Status SetValueFromString(llvm::StringRef value, VarSetOperationType op=eVarSetOperationAssign) override
A pair of an option list with a 'raw' string as a suffix.
Definition Args.h:319
bool HasArgs() const
Returns true if there are any arguments before the raw suffix.
Definition Args.h:330
Args & GetArgs()
Returns the list of arguments.
Definition Args.h:335
const std::string & GetRawPart() const
Returns the raw suffix part of the parsed string.
Definition Args.h:368
A command line option parsing protocol class.
Definition Options.h:58
std::vector< Option > m_getopt_table
Definition Options.h:198
llvm::Error GetError() const
Return an error if the regular expression failed to compile.
std::optional< SupportFileAndLine > GetDefaultFileAndLine()
This base class provides an interface to stack frames.
Definition StackFrame.h:44
virtual const SymbolContext & GetSymbolContext(lldb::SymbolContextItem resolve_scope)
Provide a SymbolContext for this StackFrame's current pc value.
virtual bool HasDebugInformation()
Determine whether this StackFrame has debug information available or not.
An error handling class.
Definition Status.h:118
static Status FromErrorString(const char *str)
Definition Status.h:141
bool Fail() const
Test for error condition.
Definition Status.cpp:293
const char * AsCString(const char *default_error_str="unknown error") const
Get the error string associated with the current error.
Definition Status.cpp:194
static Status FromError(llvm::Error error)
Avoid using this in new code. Migrate APIs to llvm::Expected instead.
Definition Status.cpp:136
bool Success() const
Test for success condition.
Definition Status.cpp:303
lldb::break_id_t GetID() const
Definition Stoppoint.cpp:22
const char * GetData() const
llvm::StringRef GetString() const
A stream class that can stream formatted output to a file.
Definition Stream.h:28
size_t Printf(const char *format,...) __attribute__((format(printf
Output printf formatted output to the stream.
Definition Stream.cpp:134
size_t EOL()
Output and End of Line character to the stream.
Definition Stream.cpp:155
void IndentLess(unsigned amount=2)
Decrement the current indentation level.
Definition Stream.cpp:198
void IndentMore(unsigned amount=2)
Increment the current indentation level.
Definition Stream.cpp:195
ObjectSP GetItemAtIndex(size_t idx) const
std::optional< llvm::StringRef > GetItemAtIndexAsString(size_t idx) const
ObjectSP GetValueForKey(llvm::StringRef key) const
bool GetValueForKeyAsArray(llvm::StringRef key, Array *&result) const
std::shared_ptr< Object > ObjectSP
static ObjectSP ParseJSONFromFile(const FileSpec &file, Status &error)
Defines a symbol context baton that can be handed other debug core functions.
LineEntry line_entry
The LineEntry for a given query.
lldb::BreakpointSP CreateScriptedBreakpoint(const llvm::StringRef class_name, const FileSpecList *containingModules, const FileSpecList *containingSourceFiles, bool internal, bool request_hardware, StructuredData::ObjectSP extra_args_sp, Status *creation_error=nullptr)
Definition Target.cpp:761
lldb::BreakpointSP CreateFuncRegexBreakpoint(const FileSpecList *containingModules, const FileSpecList *containingSourceFiles, RegularExpression func_regexp, lldb::LanguageType requested_language, LazyBool skip_prologue, bool internal, bool request_hardware)
Definition Target.cpp:727
lldb::BreakpointSP GetBreakpointByID(lldb::break_id_t break_id)
Definition Target.cpp:422
BreakpointList & GetBreakpointList(bool internal=false)
Definition Target.cpp:408
SourceManager & GetSourceManager()
Definition Target.cpp:3042
Debugger & GetDebugger() const
Definition Target.h:1224
void AddNameToBreakpoint(BreakpointID &id, llvm::StringRef name, Status &error)
Definition Target.cpp:829
void DisableAllowedBreakpoints()
Definition Target.cpp:1083
bool RemoveBreakpointByID(lldb::break_id_t break_id)
Definition Target.cpp:1107
BreakpointName * FindBreakpointName(ConstString name, bool can_create, Status &error)
Definition Target.cpp:861
void ConfigureBreakpointName(BreakpointName &bp_name, const BreakpointOptions &options, const BreakpointName::Permissions &permissions)
Definition Target.cpp:901
Status SerializeBreakpointsToFile(const FileSpec &file, const BreakpointIDList &bp_ids, bool append)
Definition Target.cpp:1168
lldb::BreakpointSP CreateExceptionBreakpoint(enum lldb::LanguageType language, bool catch_bp, bool throw_bp, bool internal, Args *additional_args=nullptr, Status *additional_args_error=nullptr)
Definition Target.cpp:744
void EnableAllowedBreakpoints()
Definition Target.cpp:1100
void RemoveAllowedBreakpoints()
Definition Target.cpp:1052
lldb::BreakpointSP CreateAddressInModuleBreakpoint(lldb::addr_t file_addr, bool internal, const FileSpec &file_spec, bool request_hardware)
Definition Target.cpp:578
lldb::BreakpointSP CreateBreakpoint(const FileSpecList *containingModules, const FileSpec &file, uint32_t line_no, uint32_t column, lldb::addr_t offset, LazyBool check_inlines, LazyBool skip_prologue, bool internal, bool request_hardware, LazyBool move_to_nearest_code)
Definition Target.cpp:489
lldb::BreakpointSP CreateSourceRegexBreakpoint(const FileSpecList *containingModules, const FileSpecList *source_file_list, const std::unordered_set< std::string > &function_names, RegularExpression source_regex, bool internal, bool request_hardware, LazyBool move_to_nearest_code)
Definition Target.cpp:472
void GetBreakpointNames(std::vector< std::string > &names)
Definition Target.cpp:923
bool IsDummyTarget() const
Definition Target.h:643
Status CreateBreakpointsFromFile(const FileSpec &file, BreakpointIDList &new_bps)
Definition Target.cpp:1260
void RemoveNameFromBreakpoint(lldb::BreakpointSP &bp_sp, ConstString name)
Definition Target.cpp:896
lldb::BreakpointSP GetLastCreatedBreakpoint()
Definition Target.h:815
#define LLDB_OPT_SET_1
#define LLDB_OPT_SET_2
#define LLDB_INVALID_BREAK_ID
#define LLDB_INVALID_LINE_NUMBER
#define LLDB_INVALID_THREAD_ID
#define LLDB_OPT_SET_ALL
#define LLDB_OPT_SET_3
#define LLDB_OPT_SET_11
#define LLDB_INVALID_ADDRESS
#define UINT32_MAX
#define LLDB_OPT_SET_4
A class that represents a running process on the host machine.
std::vector< OptionArgElement > OptionElementVector
Definition Options.h:43
static constexpr llvm::StringLiteral g_bool_parsing_error_message
Definition Options.h:367
static constexpr llvm::StringLiteral g_int_parsing_error_message
Definition Options.h:369
llvm::Error CreateOptionParsingError(llvm::StringRef option_arg, const char short_option, llvm::StringRef long_option={}, llvm::StringRef additional_context={})
Creates an error that represents the failure to parse an command line option argument.
Definition Options.cpp:1364
static constexpr llvm::StringLiteral g_language_parsing_error_message
Definition Options.h:371
@ eBreakpointCompletion
DescriptionLevel
Description levels for "void GetDescription(Stream *, DescriptionLevel)" calls.
@ eDescriptionLevelBrief
@ eDescriptionLevelInitial
@ eDescriptionLevelFull
@ eDescriptionLevelVerbose
std::shared_ptr< lldb_private::Thread > ThreadSP
std::shared_ptr< lldb_private::CommandObject > CommandObjectSP
LanguageType
Programming language type.
@ eLanguageTypeUnknown
Unknown or invalid language value.
std::shared_ptr< lldb_private::Breakpoint > BreakpointSP
int32_t break_id_t
Definition lldb-types.h:87
@ eReturnStatusFailed
@ eReturnStatusSuccessFinishResult
@ eReturnStatusSuccessFinishNoResult
@ eArgTypeBreakpointID
@ eArgTypeFileLineColumn
@ eArgTypeFunctionOrSymbol
@ eArgTypeBreakpointName
@ eArgTypeRegularExpression
uint64_t addr_t
Definition lldb-types.h:80
uint64_t tid_t
Definition lldb-types.h:84
Used to build individual command argument lists.
uint32_t arg_opt_set_association
This arg might be associated only with some particular option set(s).
A SmallBitVector that represents a set of source languages (lldb::LanguageType).
Definition Type.h:38
const FileSpec & GetFile() const
Helper to access the file.
Definition LineEntry.h:134
static int64_t ToOptionEnum(llvm::StringRef s, const OptionEnumValues &enum_values, int32_t fail_value, Status &error)
static lldb::addr_t ToAddress(const ExecutionContext *exe_ctx, llvm::StringRef s, lldb::addr_t fail_value, Status *error_ptr)
Try to parse an address.
static bool ToBoolean(llvm::StringRef s, bool fail_value, bool *success_ptr)