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();
2149 result.AppendMessageWithFormat("All breakpoints enabled. (%" PRIu64
2150 " breakpoints)\n",
2151 (uint64_t)num_breakpoints);
2153 } else {
2154 // Particular breakpoint selected; enable that breakpoint.
2155 BreakpointIDList valid_bp_ids;
2157 command, target, result, &valid_bp_ids,
2159
2160 if (result.Succeeded()) {
2161 int enable_count = 0;
2162 int loc_count = 0;
2163 const size_t count = valid_bp_ids.GetSize();
2164 for (size_t i = 0; i < count; ++i) {
2165 BreakpointID cur_bp_id = valid_bp_ids.GetBreakpointIDAtIndex(i);
2166
2167 if (cur_bp_id.GetBreakpointID() != LLDB_INVALID_BREAK_ID) {
2168 Breakpoint *breakpoint =
2169 target.GetBreakpointByID(cur_bp_id.GetBreakpointID()).get();
2170 if (cur_bp_id.GetLocationID() != LLDB_INVALID_BREAK_ID) {
2171 BreakpointLocation *location =
2172 breakpoint->FindLocationByID(cur_bp_id.GetLocationID()).get();
2173 if (location) {
2174 if (llvm::Error error = location->SetEnabled(true))
2176 "failed to enable breakpoint location: {0}",
2177 llvm::fmt_consume(std::move(error)));
2178 ++loc_count;
2179 }
2180 } else {
2181 breakpoint->SetEnabled(true);
2182 ++enable_count;
2183 }
2184 }
2185 }
2186 result.AppendMessageWithFormat("%d breakpoints enabled.\n",
2187 enable_count + loc_count);
2189 }
2190 }
2191 }
2192};
2193
2194// CommandObjectBreakpointDisable
2195#pragma mark Disable
2196
2198public:
2201 interpreter, "breakpoint disable",
2202 "Disable the specified breakpoint(s) without deleting "
2203 "them. If none are specified, disable all "
2204 "breakpoints.",
2205 nullptr) {
2207 "Disable the specified breakpoint(s) without deleting them. \
2208If none are specified, disable all breakpoints."
2209 R"(
2210
2211)"
2212 "Note: disabling a breakpoint will cause none of its locations to be hit \
2213regardless of whether individual locations are enabled or disabled. After the sequence:"
2214 R"(
2215
2216 (lldb) break disable 1
2217 (lldb) break enable 1.1
2218
2219execution will NOT stop at location 1.1. To achieve that, type:
2220
2221 (lldb) break disable 1.*
2222 (lldb) break enable 1.1
2223
2224)"
2225 "The first command disables all locations for breakpoint 1, \
2226the second re-enables the first location.");
2227
2230
2231 ~CommandObjectBreakpointDisable() override = default;
2232
2233 void
2235 OptionElementVector &opt_element_vector) override {
2238 }
2239
2240protected:
2241 void DoExecute(Args &command, CommandReturnObject &result) override {
2242 Target &target = GetTarget();
2243 std::unique_lock<std::recursive_mutex> lock;
2244 target.GetBreakpointList().GetListMutex(lock);
2245
2246 const BreakpointList &breakpoints = target.GetBreakpointList();
2247 size_t num_breakpoints = breakpoints.GetSize();
2248
2249 if (num_breakpoints == 0) {
2250 result.AppendError("no breakpoints exist to be disabled");
2251 return;
2252 }
2253
2254 if (command.empty()) {
2255 // No breakpoint selected; disable all currently set breakpoints.
2257 result.AppendMessageWithFormat("All breakpoints disabled. (%" PRIu64
2258 " breakpoints)\n",
2259 (uint64_t)num_breakpoints);
2261 } else {
2262 // Particular breakpoint selected; disable that breakpoint.
2263 BreakpointIDList valid_bp_ids;
2264
2266 command, target, result, &valid_bp_ids,
2267 BreakpointName::Permissions::PermissionKinds::disablePerm);
2268
2269 if (result.Succeeded()) {
2270 int disable_count = 0;
2271 int loc_count = 0;
2272 const size_t count = valid_bp_ids.GetSize();
2273 for (size_t i = 0; i < count; ++i) {
2274 BreakpointID cur_bp_id = valid_bp_ids.GetBreakpointIDAtIndex(i);
2275
2276 if (cur_bp_id.GetBreakpointID() != LLDB_INVALID_BREAK_ID) {
2277 Breakpoint *breakpoint =
2278 target.GetBreakpointByID(cur_bp_id.GetBreakpointID()).get();
2279 if (cur_bp_id.GetLocationID() != LLDB_INVALID_BREAK_ID) {
2280 BreakpointLocation *location =
2281 breakpoint->FindLocationByID(cur_bp_id.GetLocationID()).get();
2282 if (location) {
2283 if (llvm::Error error = location->SetEnabled(false))
2285 "failed to disable breakpoint location: {0}",
2286 llvm::fmt_consume(std::move(error)));
2287 ++loc_count;
2288 }
2289 } else {
2290 breakpoint->SetEnabled(false);
2291 ++disable_count;
2292 }
2293 }
2294 }
2295 result.AppendMessageWithFormat("%d breakpoints disabled.\n",
2296 disable_count + loc_count);
2298 }
2299 }
2300 }
2301};
2302
2303// CommandObjectBreakpointList
2304
2305#pragma mark List::CommandOptions
2306#define LLDB_OPTIONS_breakpoint_list
2307#include "CommandOptions.inc"
2308
2309#pragma mark List
2310
2312public:
2315 interpreter, "breakpoint list",
2316 "List some or all breakpoints at configurable levels of detail.") {
2317
2318 // Define the first (and only) variant of this arg.
2320 }
2321
2322 ~CommandObjectBreakpointList() override = default;
2323
2324 Options *GetOptions() override { return &m_options; }
2325
2326 class CommandOptions : public Options {
2327 public:
2328 CommandOptions() = default;
2329
2330 ~CommandOptions() override = default;
2331
2332 Status SetOptionValue(uint32_t option_idx, llvm::StringRef option_arg,
2333 ExecutionContext *execution_context) override {
2334 Status error;
2335 const int short_option = m_getopt_table[option_idx].val;
2336
2337 switch (short_option) {
2338 case 'b':
2340 break;
2341 case 'D':
2342 m_use_dummy = true;
2343 break;
2344 case 'f':
2346 break;
2347 case 'v':
2349 break;
2350 case 'i':
2351 m_internal = true;
2352 break;
2353 default:
2354 llvm_unreachable("Unimplemented option");
2355 }
2356
2357 return error;
2358 }
2359
2360 void OptionParsingStarting(ExecutionContext *execution_context) override {
2362 m_internal = false;
2363 m_use_dummy = false;
2364 }
2365
2366 llvm::ArrayRef<OptionDefinition> GetDefinitions() override {
2367 return llvm::ArrayRef(g_breakpoint_list_options);
2368 }
2369
2370 // Instance variables to hold the values for command options.
2371
2373
2375 bool m_use_dummy = false;
2376 };
2377
2378protected:
2379 void DoExecute(Args &command, CommandReturnObject &result) override {
2380 Target &target = m_options.m_use_dummy ? GetDummyTarget() : GetTarget();
2381
2382 const BreakpointList &breakpoints =
2383 target.GetBreakpointList(m_options.m_internal);
2384 std::unique_lock<std::recursive_mutex> lock;
2385 target.GetBreakpointList(m_options.m_internal).GetListMutex(lock);
2386
2387 size_t num_breakpoints = breakpoints.GetSize();
2388
2389 if (num_breakpoints == 0) {
2390 result.AppendMessage("No breakpoints currently set.");
2392 return;
2393 }
2394
2395 Stream &output_stream = result.GetOutputStream();
2396
2397 if (command.empty()) {
2398 // No breakpoint selected; show info about all currently set breakpoints.
2399 result.AppendMessage("Current breakpoints:");
2400 for (size_t i = 0; i < num_breakpoints; ++i) {
2401 Breakpoint *breakpoint = breakpoints.GetBreakpointAtIndex(i).get();
2402 if (breakpoint->AllowList())
2403 AddBreakpointDescription(&output_stream, breakpoint,
2404 m_options.m_level);
2405 }
2407 } else {
2408 // Particular breakpoints selected; show info about that breakpoint.
2409 BreakpointIDList valid_bp_ids;
2411 command, target, result, &valid_bp_ids,
2413
2414 if (result.Succeeded()) {
2415 for (size_t i = 0; i < valid_bp_ids.GetSize(); ++i) {
2416 BreakpointID cur_bp_id = valid_bp_ids.GetBreakpointIDAtIndex(i);
2417 Breakpoint *breakpoint =
2418 target.GetBreakpointByID(cur_bp_id.GetBreakpointID()).get();
2419 AddBreakpointDescription(&output_stream, breakpoint,
2420 m_options.m_level);
2421 }
2423 } else {
2424 result.AppendError("invalid breakpoint ID");
2425 }
2426 }
2427 }
2428
2429private:
2431};
2432
2433// CommandObjectBreakpointClear
2434#pragma mark Clear::CommandOptions
2435
2436#define LLDB_OPTIONS_breakpoint_clear
2437#include "CommandOptions.inc"
2438
2439#pragma mark Clear
2440
2442public:
2444
2446 : CommandObjectParsed(interpreter, "breakpoint clear",
2447 "Delete or disable breakpoints matching the "
2448 "specified source file and line.",
2449 "breakpoint clear <cmd-options>") {}
2450
2451 ~CommandObjectBreakpointClear() override = default;
2452
2453 Options *GetOptions() override { return &m_options; }
2454
2455 class CommandOptions : public Options {
2456 public:
2457 CommandOptions() = default;
2458
2459 ~CommandOptions() override = default;
2460
2461 Status SetOptionValue(uint32_t option_idx, llvm::StringRef option_arg,
2462 ExecutionContext *execution_context) override {
2463 Status error;
2464 const int short_option = m_getopt_table[option_idx].val;
2465
2466 switch (short_option) {
2467 case 'f':
2468 m_filename.assign(std::string(option_arg));
2469 break;
2470
2471 case 'l':
2472 option_arg.getAsInteger(0, m_line_num);
2473 break;
2474
2475 default:
2476 llvm_unreachable("Unimplemented option");
2477 }
2478
2479 return error;
2480 }
2481
2482 void OptionParsingStarting(ExecutionContext *execution_context) override {
2483 m_filename.clear();
2484 m_line_num = 0;
2485 }
2486
2487 llvm::ArrayRef<OptionDefinition> GetDefinitions() override {
2488 return llvm::ArrayRef(g_breakpoint_clear_options);
2489 }
2490
2491 // Instance variables to hold the values for command options.
2492
2493 std::string m_filename;
2494 uint32_t m_line_num = 0;
2495 };
2496
2497protected:
2498 void DoExecute(Args &command, CommandReturnObject &result) override {
2499 Target &target = GetTarget();
2500
2501 // The following are the various types of breakpoints that could be
2502 // cleared:
2503 // 1). -f -l (clearing breakpoint by source location)
2504
2506
2507 if (m_options.m_line_num != 0)
2508 break_type = eClearTypeFileAndLine;
2509
2510 std::unique_lock<std::recursive_mutex> lock;
2511 target.GetBreakpointList().GetListMutex(lock);
2512
2513 BreakpointList &breakpoints = target.GetBreakpointList();
2514 size_t num_breakpoints = breakpoints.GetSize();
2515
2516 // Early return if there's no breakpoint at all.
2517 if (num_breakpoints == 0) {
2518 result.AppendError("breakpoint clear: no breakpoint cleared");
2519 return;
2520 }
2521
2522 // Find matching breakpoints and delete them.
2523
2524 // First create a copy of all the IDs.
2525 std::vector<break_id_t> BreakIDs;
2526 for (size_t i = 0; i < num_breakpoints; ++i)
2527 BreakIDs.push_back(breakpoints.GetBreakpointAtIndex(i)->GetID());
2528
2529 int num_cleared = 0;
2530 StreamString ss;
2531 switch (break_type) {
2532 case eClearTypeFileAndLine: // Breakpoint by source position
2533 {
2534 const ConstString filename(m_options.m_filename.c_str());
2536
2537 for (size_t i = 0; i < num_breakpoints; ++i) {
2538 Breakpoint *bp = breakpoints.FindBreakpointByID(BreakIDs[i]).get();
2539
2540 if (bp->GetMatchingFileLine(filename, m_options.m_line_num, loc_coll)) {
2541 // If the collection size is 0, it's a full match and we can just
2542 // remove the breakpoint.
2543 if (loc_coll.GetSize() == 0) {
2545 ss.EOL();
2546 target.RemoveBreakpointByID(bp->GetID());
2547 ++num_cleared;
2548 }
2549 }
2550 }
2551 } break;
2552
2553 default:
2554 break;
2555 }
2556
2557 if (num_cleared > 0) {
2558 Stream &output_stream = result.GetOutputStream();
2559 output_stream.Printf("%d breakpoints cleared:\n", num_cleared);
2560 output_stream << ss.GetString();
2561 output_stream.EOL();
2563 } else {
2564 result.AppendError("breakpoint clear: no breakpoint cleared");
2565 }
2566 }
2567
2568private:
2570};
2571
2572// CommandObjectBreakpointDelete
2573#define LLDB_OPTIONS_breakpoint_delete
2574#include "CommandOptions.inc"
2575
2576#pragma mark Delete
2577
2579public:
2581 : CommandObjectParsed(interpreter, "breakpoint delete",
2582 "Delete the specified breakpoint(s). If no "
2583 "breakpoints are specified, delete them all.",
2584 nullptr) {
2586 }
2587
2589
2590 void
2596
2597 Options *GetOptions() override { return &m_options; }
2598
2599 class CommandOptions : public Options {
2600 public:
2601 CommandOptions() = default;
2602
2603 ~CommandOptions() override = default;
2604
2605 Status SetOptionValue(uint32_t option_idx, llvm::StringRef option_arg,
2606 ExecutionContext *execution_context) override {
2607 Status error;
2608 const int short_option = m_getopt_table[option_idx].val;
2609
2610 switch (short_option) {
2611 case 'f':
2612 m_force = true;
2613 break;
2614
2615 case 'D':
2616 m_use_dummy = true;
2617 break;
2618
2619 case 'd':
2620 m_delete_disabled = true;
2621 break;
2622
2623 default:
2624 llvm_unreachable("Unimplemented option");
2625 }
2626
2627 return error;
2628 }
2629
2630 void OptionParsingStarting(ExecutionContext *execution_context) override {
2631 m_use_dummy = false;
2632 m_force = false;
2633 m_delete_disabled = false;
2634 }
2635
2636 llvm::ArrayRef<OptionDefinition> GetDefinitions() override {
2637 return llvm::ArrayRef(g_breakpoint_delete_options);
2638 }
2639
2640 // Instance variables to hold the values for command options.
2641 bool m_use_dummy = false;
2642 bool m_force = false;
2643 bool m_delete_disabled = false;
2644 };
2645
2646protected:
2647 void DoExecute(Args &command, CommandReturnObject &result) override {
2648 Target &target = m_options.m_use_dummy ? GetDummyTarget() : GetTarget();
2649 result.Clear();
2650
2651 std::unique_lock<std::recursive_mutex> lock;
2652 target.GetBreakpointList().GetListMutex(lock);
2653
2654 BreakpointList &breakpoints = target.GetBreakpointList();
2655
2656 size_t num_breakpoints = breakpoints.GetSize();
2657
2658 if (num_breakpoints == 0) {
2659 result.AppendError("no breakpoints exist to be deleted");
2660 return;
2661 }
2662
2663 // Handle the delete all breakpoints case:
2664 if (command.empty() && !m_options.m_delete_disabled) {
2665 if (!m_options.m_force &&
2666 !m_interpreter.Confirm(
2667 "About to delete all breakpoints, do you want to do that?",
2668 true)) {
2669 result.AppendMessage("Operation cancelled...");
2670 } else {
2671 target.RemoveAllowedBreakpoints();
2673 "All breakpoints removed. (%" PRIu64 " breakpoint%s)\n",
2674 (uint64_t)num_breakpoints, num_breakpoints > 1 ? "s" : "");
2675 }
2677 return;
2678 }
2679
2680 // Either we have some kind of breakpoint specification(s),
2681 // or we are handling "break disable --deleted". Gather the list
2682 // of breakpoints to delete here, the we'll delete them below.
2683 BreakpointIDList valid_bp_ids;
2684
2685 if (m_options.m_delete_disabled) {
2686 BreakpointIDList excluded_bp_ids;
2687
2688 if (!command.empty()) {
2690 command, target, result, &excluded_bp_ids,
2692 if (!result.Succeeded())
2693 return;
2694 }
2695
2696 for (auto breakpoint_sp : breakpoints.Breakpoints()) {
2697 if (!breakpoint_sp->IsEnabled() && breakpoint_sp->AllowDelete()) {
2698 BreakpointID bp_id(breakpoint_sp->GetID());
2699 if (!excluded_bp_ids.Contains(bp_id))
2700 valid_bp_ids.AddBreakpointID(bp_id);
2701 }
2702 }
2703 if (valid_bp_ids.GetSize() == 0) {
2704 result.AppendError("no disabled breakpoints");
2705 return;
2706 }
2707 } else {
2709 command, target, result, &valid_bp_ids,
2711 if (!result.Succeeded())
2712 return;
2713 }
2714
2715 int delete_count = 0;
2716 int disable_count = 0;
2717 const size_t count = valid_bp_ids.GetSize();
2718 for (size_t i = 0; i < count; ++i) {
2719 BreakpointID cur_bp_id = valid_bp_ids.GetBreakpointIDAtIndex(i);
2720
2721 if (cur_bp_id.GetBreakpointID() != LLDB_INVALID_BREAK_ID) {
2722 if (cur_bp_id.GetLocationID() != LLDB_INVALID_BREAK_ID) {
2723 Breakpoint *breakpoint =
2724 target.GetBreakpointByID(cur_bp_id.GetBreakpointID()).get();
2725 BreakpointLocation *location =
2726 breakpoint->FindLocationByID(cur_bp_id.GetLocationID()).get();
2727 // It makes no sense to try to delete individual locations, so we
2728 // disable them instead.
2729 if (location) {
2730 if (llvm::Error error = location->SetEnabled(false))
2732 "failed to disable breakpoint location: {0}",
2733 llvm::fmt_consume(std::move(error)));
2734 ++disable_count;
2735 }
2736 } else {
2737 target.RemoveBreakpointByID(cur_bp_id.GetBreakpointID());
2738 ++delete_count;
2739 }
2740 }
2741 }
2743 "%d breakpoints deleted; %d breakpoint locations disabled.\n",
2744 delete_count, disable_count);
2746 }
2747
2748private:
2750};
2751
2752// CommandObjectBreakpointName
2753#define LLDB_OPTIONS_breakpoint_name
2754#include "CommandOptions.inc"
2755
2757public:
2760
2761 ~BreakpointNameOptionGroup() override = default;
2762
2763 llvm::ArrayRef<OptionDefinition> GetDefinitions() override {
2764 return llvm::ArrayRef(g_breakpoint_name_options);
2765 }
2766
2767 Status SetOptionValue(uint32_t option_idx, llvm::StringRef option_arg,
2768 ExecutionContext *execution_context) override {
2769 Status error;
2770 const int short_option = g_breakpoint_name_options[option_idx].short_option;
2771 const char *long_option = g_breakpoint_name_options[option_idx].long_option;
2772
2773 switch (short_option) {
2774 case 'N':
2776 error.Success())
2777 m_name.SetValueFromString(option_arg);
2778 break;
2779 case 'B':
2780 if (m_breakpoint.SetValueFromString(option_arg).Fail())
2782 CreateOptionParsingError(option_arg, short_option, long_option,
2784 break;
2785 case 'D':
2786 if (m_use_dummy.SetValueFromString(option_arg).Fail())
2788 CreateOptionParsingError(option_arg, short_option, long_option,
2790 break;
2791 case 'H':
2792 m_help_string.SetValueFromString(option_arg);
2793 break;
2794
2795 default:
2796 llvm_unreachable("Unimplemented option");
2797 }
2798 return error;
2799 }
2800
2801 void OptionParsingStarting(ExecutionContext *execution_context) override {
2802 m_name.Clear();
2803 m_breakpoint.Clear();
2804 m_use_dummy.Clear();
2805 m_use_dummy.SetDefaultValue(false);
2806 m_help_string.Clear();
2807 }
2808
2813};
2814
2815#define LLDB_OPTIONS_breakpoint_access
2816#include "CommandOptions.inc"
2817
2819public:
2821
2822 ~BreakpointAccessOptionGroup() override = default;
2823
2824 llvm::ArrayRef<OptionDefinition> GetDefinitions() override {
2825 return llvm::ArrayRef(g_breakpoint_access_options);
2826 }
2827 Status SetOptionValue(uint32_t option_idx, llvm::StringRef option_arg,
2828 ExecutionContext *execution_context) override {
2829 Status error;
2830 const int short_option =
2831 g_breakpoint_access_options[option_idx].short_option;
2832 const char *long_option =
2833 g_breakpoint_access_options[option_idx].long_option;
2834
2835 switch (short_option) {
2836 case 'L': {
2837 bool value, success;
2838 value = OptionArgParser::ToBoolean(option_arg, false, &success);
2839 if (success) {
2840 m_permissions.SetAllowList(value);
2841 } else
2843 CreateOptionParsingError(option_arg, short_option, long_option,
2845 } break;
2846 case 'A': {
2847 bool value, success;
2848 value = OptionArgParser::ToBoolean(option_arg, false, &success);
2849 if (success) {
2850 m_permissions.SetAllowDisable(value);
2851 } else
2853 CreateOptionParsingError(option_arg, short_option, long_option,
2855 } break;
2856 case 'D': {
2857 bool value, success;
2858 value = OptionArgParser::ToBoolean(option_arg, false, &success);
2859 if (success) {
2860 m_permissions.SetAllowDelete(value);
2861 } else
2863 CreateOptionParsingError(option_arg, short_option, long_option,
2865 } break;
2866 default:
2867 llvm_unreachable("Unimplemented option");
2868 }
2869
2870 return error;
2871 }
2872
2873 void OptionParsingStarting(ExecutionContext *execution_context) override {}
2874
2876 return m_permissions;
2877 }
2879};
2880
2882public:
2885 interpreter, "configure",
2886 "Configure the options for the breakpoint"
2887 " name provided. "
2888 "If you provide a breakpoint id, the options will be copied from "
2889 "the breakpoint, otherwise only the options specified will be set "
2890 "on the name.",
2891 "breakpoint name configure <command-options> "
2892 "<breakpoint-name-list>") {
2894
2900 m_option_group.Finalize();
2901 }
2902
2904
2905 Options *GetOptions() override { return &m_option_group; }
2906
2907protected:
2908 void DoExecute(Args &command, CommandReturnObject &result) override {
2909
2910 const size_t argc = command.GetArgumentCount();
2911 if (argc == 0) {
2912 result.AppendError("no names provided");
2913 return;
2914 }
2915
2916 Target &target = GetTarget();
2917
2918 std::unique_lock<std::recursive_mutex> lock;
2919 target.GetBreakpointList().GetListMutex(lock);
2920
2921 // Make a pass through first to see that all the names are legal.
2922 for (auto &entry : command.entries()) {
2923 Status error;
2924 if (!BreakpointID::StringIsBreakpointName(entry.ref(), error)) {
2925 result.AppendErrorWithFormat("Invalid breakpoint name: %s - %s",
2926 entry.c_str(), error.AsCString());
2927 return;
2928 }
2929 }
2930 // Now configure them, we already pre-checked the names so we don't need to
2931 // check the error:
2932 BreakpointSP bp_sp;
2933 if (m_bp_id.m_breakpoint.OptionWasSet()) {
2934 lldb::break_id_t bp_id =
2935 m_bp_id.m_breakpoint.GetValueAs<uint64_t>().value_or(0);
2936 bp_sp = target.GetBreakpointByID(bp_id);
2937 if (!bp_sp) {
2938 result.AppendErrorWithFormatv("Could not find specified breakpoint {0}",
2939 bp_id);
2940 return;
2941 }
2942 }
2943
2944 Status error;
2945 for (auto &entry : command.entries()) {
2946 ConstString name(entry.c_str());
2947 BreakpointName *bp_name = target.FindBreakpointName(name, true, error);
2948 if (!bp_name)
2949 continue;
2950 if (m_bp_id.m_help_string.OptionWasSet())
2951 bp_name->SetHelp(m_bp_id.m_help_string.GetValueAs<llvm::StringRef>()
2952 .value_or("")
2953 .str()
2954 .c_str());
2955
2956 if (bp_sp)
2957 target.ConfigureBreakpointName(*bp_name, bp_sp->GetOptions(),
2958 m_access_options.GetPermissions());
2959 else
2960 target.ConfigureBreakpointName(*bp_name,
2961 m_bp_opts.GetBreakpointOptions(),
2962 m_access_options.GetPermissions());
2963 }
2964 }
2965
2966private:
2967 BreakpointNameOptionGroup m_bp_id; // Only using the id part of this.
2971};
2972
2974public:
2977 interpreter, "add", "Add a name to the breakpoints provided.",
2978 "breakpoint name add <command-options> <breakpoint-id-list>") {
2980
2982 m_option_group.Finalize();
2983 }
2984
2986
2987 void
2993
2994 Options *GetOptions() override { return &m_option_group; }
2995
2996protected:
2997 void DoExecute(Args &command, CommandReturnObject &result) override {
2998 if (!m_name_options.m_name.OptionWasSet()) {
2999 result.AppendError("no name option provided");
3000 return;
3001 }
3002
3003 Target &target =
3004 m_name_options.m_use_dummy ? GetDummyTarget() : GetTarget();
3005
3006 std::unique_lock<std::recursive_mutex> lock;
3007 target.GetBreakpointList().GetListMutex(lock);
3008
3009 const BreakpointList &breakpoints = target.GetBreakpointList();
3010
3011 size_t num_breakpoints = breakpoints.GetSize();
3012 if (num_breakpoints == 0) {
3013 result.AppendError("no breakpoints, cannot add names");
3014 return;
3015 }
3016
3017 // Particular breakpoint selected; disable that breakpoint.
3018 BreakpointIDList valid_bp_ids;
3020 command, target, result, &valid_bp_ids,
3022
3023 if (result.Succeeded()) {
3024 if (valid_bp_ids.GetSize() == 0) {
3025 result.AppendError("no breakpoints specified, cannot add names");
3026 return;
3027 }
3028 size_t num_valid_ids = valid_bp_ids.GetSize();
3029 const char *bp_name = m_name_options.m_name.GetCurrentValue();
3030 Status error; // This error reports illegal names, but we've already
3031 // checked that, so we don't need to check it again here.
3032 for (size_t index = 0; index < num_valid_ids; index++) {
3033 lldb::break_id_t bp_id =
3034 valid_bp_ids.GetBreakpointIDAtIndex(index).GetBreakpointID();
3035 BreakpointSP bp_sp = breakpoints.FindBreakpointByID(bp_id);
3036 target.AddNameToBreakpoint(bp_sp, bp_name, error);
3037 }
3038 }
3039 }
3040
3041private:
3044};
3045
3047public:
3050 interpreter, "delete",
3051 "Delete a name from the breakpoints provided.",
3052 "breakpoint name delete <command-options> <breakpoint-id-list>") {
3054
3056 m_option_group.Finalize();
3057 }
3058
3060
3061 void
3067
3068 Options *GetOptions() override { return &m_option_group; }
3069
3070protected:
3071 void DoExecute(Args &command, CommandReturnObject &result) override {
3072 if (!m_name_options.m_name.OptionWasSet()) {
3073 result.AppendError("no name option provided");
3074 return;
3075 }
3076
3077 Target &target =
3078 m_name_options.m_use_dummy ? GetDummyTarget() : GetTarget();
3079
3080 std::unique_lock<std::recursive_mutex> lock;
3081 target.GetBreakpointList().GetListMutex(lock);
3082
3083 const BreakpointList &breakpoints = target.GetBreakpointList();
3084
3085 size_t num_breakpoints = breakpoints.GetSize();
3086 if (num_breakpoints == 0) {
3087 result.AppendError("no breakpoints, cannot delete names");
3088 return;
3089 }
3090
3091 // Particular breakpoint selected; disable that breakpoint.
3092 BreakpointIDList valid_bp_ids;
3094 command, target, result, &valid_bp_ids,
3096
3097 if (result.Succeeded()) {
3098 if (valid_bp_ids.GetSize() == 0) {
3099 result.AppendError("no breakpoints specified, cannot delete names");
3100 return;
3101 }
3102 ConstString bp_name(m_name_options.m_name.GetCurrentValue());
3103 size_t num_valid_ids = valid_bp_ids.GetSize();
3104 for (size_t index = 0; index < num_valid_ids; index++) {
3105 lldb::break_id_t bp_id =
3106 valid_bp_ids.GetBreakpointIDAtIndex(index).GetBreakpointID();
3107 BreakpointSP bp_sp = breakpoints.FindBreakpointByID(bp_id);
3108 target.RemoveNameFromBreakpoint(bp_sp, bp_name);
3109 }
3110 }
3111 }
3112
3113private:
3116};
3117
3119public:
3121 : CommandObjectParsed(interpreter, "list",
3122 "List either the names for a breakpoint or info "
3123 "about a given name. With no arguments, lists all "
3124 "names",
3125 "breakpoint name list <command-options>") {
3127 m_option_group.Finalize();
3128 }
3129
3131
3132 Options *GetOptions() override { return &m_option_group; }
3133
3134protected:
3135 void DoExecute(Args &command, CommandReturnObject &result) override {
3136 Target &target =
3137 m_name_options.m_use_dummy ? GetDummyTarget() : GetTarget();
3138
3139 std::vector<std::string> name_list;
3140 if (command.empty()) {
3141 target.GetBreakpointNames(name_list);
3142 } else {
3143 for (const Args::ArgEntry &arg : command) {
3144 name_list.push_back(arg.c_str());
3145 }
3146 }
3147
3148 if (name_list.empty()) {
3149 result.AppendMessage("No breakpoint names found.");
3150 } else {
3151 for (const std::string &name_str : name_list) {
3152 const char *name = name_str.c_str();
3153 // First print out the options for the name:
3154 Status error;
3155 BreakpointName *bp_name =
3156 target.FindBreakpointName(ConstString(name), false, error);
3157 if (bp_name) {
3158 StreamString s;
3159 result.AppendMessageWithFormat("Name: %s\n", name);
3160 if (bp_name->GetDescription(&s, eDescriptionLevelFull)) {
3161 result.AppendMessage(s.GetString());
3162 }
3163
3164 std::unique_lock<std::recursive_mutex> lock;
3165 target.GetBreakpointList().GetListMutex(lock);
3166
3167 BreakpointList &breakpoints = target.GetBreakpointList();
3168 bool any_set = false;
3169 for (BreakpointSP bp_sp : breakpoints.Breakpoints()) {
3170 if (bp_sp->MatchesName(name)) {
3171 StreamString s;
3172 any_set = true;
3173 bp_sp->GetDescription(&s, eDescriptionLevelBrief);
3174 s.EOL();
3175 result.AppendMessage(s.GetString());
3176 }
3177 }
3178 if (!any_set)
3179 result.AppendMessage("No breakpoints using this name.");
3180 } else {
3181 result.AppendMessageWithFormat("Name: %s not found.\n", name);
3182 }
3183 }
3184 }
3185 }
3186
3187private:
3190};
3191
3192// CommandObjectBreakpointName
3194public:
3197 interpreter, "name", "Commands to manage breakpoint names") {
3198
3199
3201 R"(
3202Breakpoint names provide a general tagging mechanism for breakpoints. Each
3203breakpoint name can be added to any number of breakpoints, and each breakpoint
3204can have any number of breakpoint names attached to it. For instance:
3205
3206 (lldb) break name add -N MyName 1-10
3207
3208adds the name MyName to breakpoints 1-10, and:
3209
3210 (lldb) break set -n myFunc -N Name1 -N Name2
3211
3212adds two names to the breakpoint set at myFunc.
3213
3214They have a number of interrelated uses:
3215
32161) They provide a stable way to refer to a breakpoint (e.g. in another
3217breakpoint's action). Using the breakpoint ID for this purpose is fragile, since
3218it depends on the order of breakpoint creation. Giving a name to the breakpoint
3219you want to act on, and then referring to it by name, is more robust:
3220
3221 (lldb) break set -n myFunc -N BKPT1
3222 (lldb) break set -n myOtherFunc -C "break disable BKPT1"
3223
32242) This is actually just a specific use of a more general feature of breakpoint
3225names. The <breakpt-id-list> argument type used to specify one or more
3226breakpoints in most of the commands that deal with breakpoints also accepts
3227breakpoint names. That allows you to refer to one breakpoint in a stable
3228manner, but also makes them a convenient grouping mechanism, allowing you to
3229easily act on a group of breakpoints by using their name, for instance disabling
3230them all in one action:
3231
3232 (lldb) break set -n myFunc -N Group1
3233 (lldb) break set -n myOtherFunc -N Group1
3234 (lldb) break disable Group1
3235
32363) But breakpoint names are also entities in their own right, and can be
3237configured with all the modifiable attributes of a breakpoint. Then when you
3238add a breakpoint name to a breakpoint, the breakpoint will be configured to
3239match the state of the breakpoint name. The link between the name and the
3240breakpoints sharing it remains live, so if you change the configuration on the
3241name, it will also change the configurations on the breakpoints:
3242
3243 (lldb) break name configure -i 10 IgnoreSome
3244 (lldb) break set -n myFunc -N IgnoreSome
3245 (lldb) break list IgnoreSome
3246 2: name = 'myFunc', locations = 0 (pending) Options: ignore: 10 enabled
3247 Names:
3248 IgnoreSome
3249 (lldb) break name configure -i 5 IgnoreSome
3250 (lldb) break list IgnoreSome
3251 2: name = 'myFunc', locations = 0 (pending) Options: ignore: 5 enabled
3252 Names:
3253 IgnoreSome
3254
3255Options that are not configured on a breakpoint name don't affect the value of
3256those options on the breakpoints they are added to. So for instance, if Name1
3257has the -i option configured and Name2 the -c option, adding both names to a
3258breakpoint will set the -i option from Name1 and the -c option from Name2, and
3259the other options will be unaltered.
3260
3261If you add multiple names to a breakpoint which have configured values for
3262the same option, the last name added's value wins.
3263
3264The "liveness" of these settings is one way, from name to breakpoint.
3265If you use "break modify" to change an option that is also configured on a name
3266which that breakpoint has, the "break modify" command will override the setting
3267for that breakpoint, but won't change the value configured in the name or on the
3268other breakpoints sharing that name.
3269
32704) Breakpoint names are also a convenient way to copy option sets from one
3271breakpoint to another. Using the -B option to "breakpoint name configure" makes
3272a name configured with all the options of the original breakpoint. Then
3273adding that name to another breakpoint copies over all the values from the
3274original breakpoint to the new one.
3275
32765) You can also use breakpoint names to hide breakpoints from the breakpoint
3277operations that act on all breakpoints: "break delete", "break disable" and
3278"break list". You do that by specifying a "false" value for the
3279--allow-{list,delete,disable} options to "breakpoint name configure" and then
3280adding that name to a breakpoint.
3281
3282This won't keep the breakpoint from being deleted or disabled if you refer to it
3283specifically by ID. The point of the feature is to make sure users don't
3284inadvertently delete or disable useful breakpoints (e.g. ones an IDE is using
3285for its own purposes) as part of a "delete all" or "disable all" operation. The
3286list hiding is because it's confusing for people to see breakpoints they
3287didn't set.
3288
3289)");
3290 CommandObjectSP add_command_object(
3291 new CommandObjectBreakpointNameAdd(interpreter));
3292 CommandObjectSP delete_command_object(
3293 new CommandObjectBreakpointNameDelete(interpreter));
3294 CommandObjectSP list_command_object(
3295 new CommandObjectBreakpointNameList(interpreter));
3296 CommandObjectSP configure_command_object(
3297 new CommandObjectBreakpointNameConfigure(interpreter));
3298
3299 LoadSubCommand("add", add_command_object);
3300 LoadSubCommand("delete", delete_command_object);
3301 LoadSubCommand("list", list_command_object);
3302 LoadSubCommand("configure", configure_command_object);
3303 }
3304
3305 ~CommandObjectBreakpointName() override = default;
3306};
3307
3308// CommandObjectBreakpointRead
3309#pragma mark Read::CommandOptions
3310#define LLDB_OPTIONS_breakpoint_read
3311#include "CommandOptions.inc"
3312
3313#pragma mark Read
3314
3316public:
3318 : CommandObjectParsed(interpreter, "breakpoint read",
3319 "Read and set the breakpoints previously saved to "
3320 "a file with \"breakpoint write\". ",
3321 nullptr) {}
3322
3323 ~CommandObjectBreakpointRead() override = default;
3324
3325 Options *GetOptions() override { return &m_options; }
3326
3327 class CommandOptions : public Options {
3328 public:
3329 CommandOptions() = default;
3330
3331 ~CommandOptions() override = default;
3332
3333 Status SetOptionValue(uint32_t option_idx, llvm::StringRef option_arg,
3334 ExecutionContext *execution_context) override {
3335 Status error;
3336 const int short_option = m_getopt_table[option_idx].val;
3337 const char *long_option =
3338 m_getopt_table[option_idx].definition->long_option;
3339
3340 switch (short_option) {
3341 case 'f':
3342 m_filename.assign(std::string(option_arg));
3343 break;
3344 case 'N': {
3345 Status name_error;
3346 if (!BreakpointID::StringIsBreakpointName(llvm::StringRef(option_arg),
3347 name_error)) {
3349 option_arg, short_option, long_option, name_error.AsCString()));
3350 }
3351 m_names.push_back(std::string(option_arg));
3352 break;
3353 }
3354 default:
3355 llvm_unreachable("Unimplemented option");
3356 }
3357
3358 return error;
3359 }
3360
3361 void OptionParsingStarting(ExecutionContext *execution_context) override {
3362 m_filename.clear();
3363 m_names.clear();
3364 }
3365
3366 llvm::ArrayRef<OptionDefinition> GetDefinitions() override {
3367 return llvm::ArrayRef(g_breakpoint_read_options);
3368 }
3369
3371 CompletionRequest &request, OptionElementVector &opt_element_vector,
3372 int opt_element_index, CommandInterpreter &interpreter) override {
3373 int opt_arg_pos = opt_element_vector[opt_element_index].opt_arg_pos;
3374 int opt_defs_index = opt_element_vector[opt_element_index].opt_defs_index;
3375
3376 switch (GetDefinitions()[opt_defs_index].short_option) {
3377 case 'f':
3379 interpreter, lldb::eDiskFileCompletion, request, nullptr);
3380 break;
3381
3382 case 'N':
3383 std::optional<FileSpec> file_spec;
3384 const llvm::StringRef dash_f("-f");
3385 for (int arg_idx = 0; arg_idx < opt_arg_pos; arg_idx++) {
3386 if (dash_f == request.GetParsedLine().GetArgumentAtIndex(arg_idx)) {
3387 file_spec.emplace(
3388 request.GetParsedLine().GetArgumentAtIndex(arg_idx + 1));
3389 break;
3390 }
3391 }
3392 if (!file_spec)
3393 return;
3394
3395 FileSystem::Instance().Resolve(*file_spec);
3396 Status error;
3397 StructuredData::ObjectSP input_data_sp =
3399 if (!error.Success())
3400 return;
3401
3402 StructuredData::Array *bkpt_array = input_data_sp->GetAsArray();
3403 if (!bkpt_array)
3404 return;
3405
3406 const size_t num_bkpts = bkpt_array->GetSize();
3407 for (size_t i = 0; i < num_bkpts; i++) {
3408 StructuredData::ObjectSP bkpt_object_sp =
3409 bkpt_array->GetItemAtIndex(i);
3410 if (!bkpt_object_sp)
3411 return;
3412
3413 StructuredData::Dictionary *bkpt_dict =
3414 bkpt_object_sp->GetAsDictionary();
3415 if (!bkpt_dict)
3416 return;
3417
3418 StructuredData::ObjectSP bkpt_data_sp =
3420 if (!bkpt_data_sp)
3421 return;
3422
3423 bkpt_dict = bkpt_data_sp->GetAsDictionary();
3424 if (!bkpt_dict)
3425 return;
3426
3427 StructuredData::Array *names_array;
3428
3429 if (!bkpt_dict->GetValueForKeyAsArray("Names", names_array))
3430 return;
3431
3432 size_t num_names = names_array->GetSize();
3433
3434 for (size_t i = 0; i < num_names; i++) {
3435 if (std::optional<llvm::StringRef> maybe_name =
3436 names_array->GetItemAtIndexAsString(i))
3437 request.TryCompleteCurrentArg(*maybe_name);
3438 }
3439 }
3440 }
3441 }
3442
3443 std::string m_filename;
3444 std::vector<std::string> m_names;
3445 };
3446
3447protected:
3448 void DoExecute(Args &command, CommandReturnObject &result) override {
3449 Target &target = GetTarget();
3450
3451 std::unique_lock<std::recursive_mutex> lock;
3452 target.GetBreakpointList().GetListMutex(lock);
3453
3454 FileSpec input_spec(m_options.m_filename);
3455 FileSystem::Instance().Resolve(input_spec);
3456 BreakpointIDList new_bps;
3457 Status error = target.CreateBreakpointsFromFile(input_spec,
3458 m_options.m_names, new_bps);
3459
3460 if (!error.Success()) {
3461 result.AppendError(error.AsCString());
3462 return;
3463 }
3464
3465 Stream &output_stream = result.GetOutputStream();
3466
3467 size_t num_breakpoints = new_bps.GetSize();
3468 if (num_breakpoints == 0) {
3469 result.AppendMessage("No breakpoints added.");
3470 } else {
3471 // No breakpoint selected; show info about all currently set breakpoints.
3472 result.AppendMessage("New breakpoints:");
3473 for (size_t i = 0; i < num_breakpoints; ++i) {
3474 BreakpointID bp_id = new_bps.GetBreakpointIDAtIndex(i);
3475 Breakpoint *bp = target.GetBreakpointList()
3477 .get();
3478 if (bp)
3480 false);
3481 }
3482 }
3483 }
3484
3485private:
3487};
3488
3489// CommandObjectBreakpointWrite
3490#pragma mark Write::CommandOptions
3491#define LLDB_OPTIONS_breakpoint_write
3492#include "CommandOptions.inc"
3493
3494#pragma mark Write
3496public:
3498 : CommandObjectParsed(interpreter, "breakpoint write",
3499 "Write the breakpoints listed to a file that can "
3500 "be read in with \"breakpoint read\". "
3501 "If given no arguments, writes all breakpoints.",
3502 nullptr) {
3504 }
3505
3506 ~CommandObjectBreakpointWrite() override = default;
3507
3508 void
3514
3515 Options *GetOptions() override { return &m_options; }
3516
3517 class CommandOptions : public Options {
3518 public:
3519 CommandOptions() = default;
3520
3521 ~CommandOptions() override = default;
3522
3523 Status SetOptionValue(uint32_t option_idx, llvm::StringRef option_arg,
3524 ExecutionContext *execution_context) override {
3525 Status error;
3526 const int short_option = m_getopt_table[option_idx].val;
3527
3528 switch (short_option) {
3529 case 'f':
3530 m_filename.assign(std::string(option_arg));
3531 break;
3532 case 'a':
3533 m_append = true;
3534 break;
3535 default:
3536 llvm_unreachable("Unimplemented option");
3537 }
3538
3539 return error;
3540 }
3541
3542 void OptionParsingStarting(ExecutionContext *execution_context) override {
3543 m_filename.clear();
3544 m_append = false;
3545 }
3546
3547 llvm::ArrayRef<OptionDefinition> GetDefinitions() override {
3548 return llvm::ArrayRef(g_breakpoint_write_options);
3549 }
3550
3551 // Instance variables to hold the values for command options.
3552
3553 std::string m_filename;
3554 bool m_append = false;
3555 };
3556
3557protected:
3558 void DoExecute(Args &command, CommandReturnObject &result) override {
3559 Target &target = GetTarget();
3560
3561 std::unique_lock<std::recursive_mutex> lock;
3562 target.GetBreakpointList().GetListMutex(lock);
3563
3564 BreakpointIDList valid_bp_ids;
3565 if (!command.empty()) {
3567 command, target, result, &valid_bp_ids,
3569
3570 if (!result.Succeeded()) {
3572 return;
3573 }
3574 }
3575 FileSpec file_spec(m_options.m_filename);
3576 FileSystem::Instance().Resolve(file_spec);
3577 Status error = target.SerializeBreakpointsToFile(file_spec, valid_bp_ids,
3578 m_options.m_append);
3579 if (!error.Success()) {
3580 result.AppendErrorWithFormat("error serializing breakpoints: %s.",
3581 error.AsCString());
3582 }
3583 }
3584
3585private:
3587};
3588
3589// CommandObjectMultiwordBreakpoint
3590#pragma mark MultiwordBreakpoint
3591
3593 CommandInterpreter &interpreter)
3595 interpreter, "breakpoint",
3596 "Commands for operating on breakpoints (see 'help b' for shorthand.)",
3597 "breakpoint <subcommand> [<command-options>]") {
3598 CommandObjectSP list_command_object(
3599 new CommandObjectBreakpointList(interpreter));
3600 CommandObjectSP enable_command_object(
3601 new CommandObjectBreakpointEnable(interpreter));
3602 CommandObjectSP disable_command_object(
3603 new CommandObjectBreakpointDisable(interpreter));
3604 CommandObjectSP clear_command_object(
3605 new CommandObjectBreakpointClear(interpreter));
3606 CommandObjectSP delete_command_object(
3607 new CommandObjectBreakpointDelete(interpreter));
3608 CommandObjectSP set_command_object(
3609 new CommandObjectBreakpointSet(interpreter));
3610 CommandObjectSP add_command_object(
3611 new CommandObjectBreakpointAdd(interpreter));
3612 CommandObjectSP command_command_object(
3613 new CommandObjectBreakpointCommand(interpreter));
3614 CommandObjectSP modify_command_object(
3615 new CommandObjectBreakpointModify(interpreter));
3616 CommandObjectSP name_command_object(
3617 new CommandObjectBreakpointName(interpreter));
3618 CommandObjectSP write_command_object(
3619 new CommandObjectBreakpointWrite(interpreter));
3620 CommandObjectSP read_command_object(
3621 new CommandObjectBreakpointRead(interpreter));
3622
3623 list_command_object->SetCommandName("breakpoint list");
3624 enable_command_object->SetCommandName("breakpoint enable");
3625 disable_command_object->SetCommandName("breakpoint disable");
3626 clear_command_object->SetCommandName("breakpoint clear");
3627 delete_command_object->SetCommandName("breakpoint delete");
3628 set_command_object->SetCommandName("breakpoint set");
3629 add_command_object->SetCommandName("breakpoint add");
3630 command_command_object->SetCommandName("breakpoint command");
3631 modify_command_object->SetCommandName("breakpoint modify");
3632 name_command_object->SetCommandName("breakpoint name");
3633 write_command_object->SetCommandName("breakpoint write");
3634 read_command_object->SetCommandName("breakpoint read");
3635
3636 LoadSubCommand("list", list_command_object);
3637 LoadSubCommand("enable", enable_command_object);
3638 LoadSubCommand("disable", disable_command_object);
3639 LoadSubCommand("clear", clear_command_object);
3640 LoadSubCommand("delete", delete_command_object);
3641 LoadSubCommand("set", set_command_object);
3642 LoadSubCommand("add", add_command_object);
3643 LoadSubCommand("command", command_command_object);
3644 LoadSubCommand("modify", modify_command_object);
3645 LoadSubCommand("name", name_command_object);
3646 LoadSubCommand("write", write_command_object);
3647 LoadSubCommand("read", read_command_object);
3648}
3649
3651
3653 Args &args, Target &target, bool allow_locations,
3654 CommandReturnObject &result, BreakpointIDList *valid_ids,
3655 BreakpointName::Permissions ::PermissionKinds purpose) {
3656 // args can be strings representing 1). integers (for breakpoint ids)
3657 // 2). the full breakpoint & location
3658 // canonical representation
3659 // 3). the word "to" or a hyphen,
3660 // representing a range (in which case there
3661 // had *better* be an entry both before &
3662 // after of one of the first two types.
3663 // 4). A breakpoint name
3664 // If args is empty, we will use the last created breakpoint (if there is
3665 // one.)
3666
3667 Args temp_args;
3668
3669 if (args.empty()) {
3670 if (target.GetLastCreatedBreakpoint()) {
3671 valid_ids->AddBreakpointID(BreakpointID(
3674 } else {
3675 result.AppendError(
3676 "No breakpoint specified and no last created breakpoint.");
3677 }
3678 return;
3679 }
3680
3681 // Create a new Args variable to use; copy any non-breakpoint-id-ranges stuff
3682 // directly from the old ARGS to the new TEMP_ARGS. Do not copy breakpoint
3683 // id range strings over; instead generate a list of strings for all the
3684 // breakpoint ids in the range, and shove all of those breakpoint id strings
3685 // into TEMP_ARGS.
3686
3687 if (llvm::Error err = BreakpointIDList::FindAndReplaceIDRanges(
3688 args, &target, allow_locations, purpose, temp_args)) {
3689 result.SetError(std::move(err));
3690 return;
3691 }
3693
3694 // NOW, convert the list of breakpoint id strings in TEMP_ARGS into an actual
3695 // BreakpointIDList:
3696
3697 for (llvm::StringRef temp_arg : temp_args.GetArgumentArrayRef())
3698 if (auto bp_id = BreakpointID::ParseCanonicalReference(temp_arg))
3699 valid_ids->AddBreakpointID(*bp_id);
3700
3701 // At this point, all of the breakpoint ids that the user passed in have
3702 // been converted to breakpoint IDs and put into valid_ids.
3703
3704 // Now that we've converted everything from args into a list of breakpoint
3705 // ids, go through our tentative list of breakpoint id's and verify that
3706 // they correspond to valid/currently set breakpoints.
3707
3708 const size_t count = valid_ids->GetSize();
3709 for (size_t i = 0; i < count; ++i) {
3710 BreakpointID cur_bp_id = valid_ids->GetBreakpointIDAtIndex(i);
3711 Breakpoint *breakpoint =
3712 target.GetBreakpointByID(cur_bp_id.GetBreakpointID()).get();
3713 if (breakpoint != nullptr) {
3714 lldb::break_id_t cur_loc_id = cur_bp_id.GetLocationID();
3715 // GetLocationID returns 0 when the location isn't specified.
3716 if (cur_loc_id != 0 && !breakpoint->FindLocationByID(cur_loc_id)) {
3717 StreamString id_str;
3719 &id_str, cur_bp_id.GetBreakpointID(), cur_bp_id.GetLocationID());
3720 i = valid_ids->GetSize() + 1;
3721 result.AppendErrorWithFormat(
3722 "'%s' is not a currently valid breakpoint/location id.\n",
3723 id_str.GetData());
3724 }
3725 } else {
3726 i = valid_ids->GetSize() + 1;
3727 result.AppendErrorWithFormat(
3728 "'%d' is not a currently valid breakpoint ID.\n",
3729 cur_bp_id.GetBreakpointID());
3730 }
3731 }
3732}
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 AppendMessageWithFormat(const char *format,...) __attribute__((format(printf
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:80
bool GetUseColor() const
Definition Debugger.cpp:456
"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
void Resolve(llvm::SmallVectorImpl< char > &path)
Resolve path to make it canonical.
static FileSystem & Instance()
static llvm::Expected< lldb::LanguageType > GetExceptionLanguageForLanguage(llvm::StringRef lang_name)
Definition Language.cpp:163
static LanguageSet GetLanguagesSupportingTypeSystemsForExpressions()
Definition Language.cpp:475
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:294
const char * AsCString(const char *default_error_str="unknown error") const
Get the error string associated with the current error.
Definition Status.cpp:195
static Status FromError(llvm::Error error)
Avoid using this in new code. Migrate APIs to llvm::Expected instead.
Definition Status.cpp:137
bool Success() const
Test for success condition.
Definition Status.cpp:304
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:760
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:726
lldb::BreakpointSP GetBreakpointByID(lldb::break_id_t break_id)
Definition Target.cpp:421
BreakpointList & GetBreakpointList(bool internal=false)
Definition Target.cpp:407
SourceManager & GetSourceManager()
Definition Target.cpp:3043
Debugger & GetDebugger() const
Definition Target.h:1194
void AddNameToBreakpoint(BreakpointID &id, llvm::StringRef name, Status &error)
Definition Target.cpp:828
void DisableAllowedBreakpoints()
Definition Target.cpp:1082
bool RemoveBreakpointByID(lldb::break_id_t break_id)
Definition Target.cpp:1106
BreakpointName * FindBreakpointName(ConstString name, bool can_create, Status &error)
Definition Target.cpp:860
void ConfigureBreakpointName(BreakpointName &bp_name, const BreakpointOptions &options, const BreakpointName::Permissions &permissions)
Definition Target.cpp:900
Status SerializeBreakpointsToFile(const FileSpec &file, const BreakpointIDList &bp_ids, bool append)
Definition Target.cpp:1167
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:743
void EnableAllowedBreakpoints()
Definition Target.cpp:1099
void RemoveAllowedBreakpoints()
Definition Target.cpp:1051
lldb::BreakpointSP CreateAddressInModuleBreakpoint(lldb::addr_t file_addr, bool internal, const FileSpec &file_spec, bool request_hardware)
Definition Target.cpp:577
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:488
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:471
void GetBreakpointNames(std::vector< std::string > &names)
Definition Target.cpp:922
bool IsDummyTarget() const
Definition Target.h:619
Status CreateBreakpointsFromFile(const FileSpec &file, BreakpointIDList &new_bps)
Definition Target.cpp:1259
void RemoveNameFromBreakpoint(lldb::BreakpointSP &bp_sp, ConstString name)
Definition Target.cpp:895
lldb::BreakpointSP GetLastCreatedBreakpoint()
Definition Target.h:785
#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:1408
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:86
@ 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)