1 //===-- CommandObjectBreakpoint.cpp -----------------------------*- C++ -*-===//
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
7 //===----------------------------------------------------------------------===//
9 #include "CommandObjectBreakpoint.h"
10 #include "CommandObjectBreakpointCommand.h"
11 #include "lldb/Breakpoint/Breakpoint.h"
12 #include "lldb/Breakpoint/BreakpointIDList.h"
13 #include "lldb/Breakpoint/BreakpointLocation.h"
14 #include "lldb/Host/OptionParser.h"
15 #include "lldb/Interpreter/CommandInterpreter.h"
16 #include "lldb/Interpreter/CommandReturnObject.h"
17 #include "lldb/Interpreter/OptionArgParser.h"
18 #include "lldb/Interpreter/OptionGroupPythonClassWithDict.h"
19 #include "lldb/Interpreter/OptionValueBoolean.h"
20 #include "lldb/Interpreter/OptionValueString.h"
21 #include "lldb/Interpreter/OptionValueUInt64.h"
22 #include "lldb/Interpreter/Options.h"
23 #include "lldb/Target/Language.h"
24 #include "lldb/Target/StackFrame.h"
25 #include "lldb/Target/Target.h"
26 #include "lldb/Target/ThreadSpec.h"
27 #include "lldb/Utility/RegularExpression.h"
28 #include "lldb/Utility/StreamString.h"
34 using namespace lldb_private
;
36 static void AddBreakpointDescription(Stream
*s
, Breakpoint
*bp
,
37 lldb::DescriptionLevel level
) {
39 bp
->GetDescription(s
, level
, true);
44 // Modifiable Breakpoint Options
45 #pragma mark Modify::CommandOptions
46 #define LLDB_OPTIONS_breakpoint_modify
47 #include "CommandOptions.inc"
49 class lldb_private::BreakpointOptionGroup
: public OptionGroup
{
51 BreakpointOptionGroup() : OptionGroup(), m_bp_opts(false) {}
53 ~BreakpointOptionGroup() override
= default;
55 llvm::ArrayRef
<OptionDefinition
> GetDefinitions() override
{
56 return llvm::makeArrayRef(g_breakpoint_modify_options
);
59 Status
SetOptionValue(uint32_t option_idx
, llvm::StringRef option_arg
,
60 ExecutionContext
*execution_context
) override
{
62 const int short_option
=
63 g_breakpoint_modify_options
[option_idx
].short_option
;
65 switch (short_option
) {
67 // Normally an empty breakpoint condition marks is as unset. But we need
68 // to say it was passed in.
69 m_bp_opts
.SetCondition(option_arg
.str().c_str());
70 m_bp_opts
.m_set_flags
.Set(BreakpointOptions::eCondition
);
73 m_commands
.push_back(option_arg
);
76 m_bp_opts
.SetEnabled(false);
79 m_bp_opts
.SetEnabled(true);
83 value
= OptionArgParser::ToBoolean(option_arg
, false, &success
);
85 m_bp_opts
.SetAutoContinue(value
);
87 error
.SetErrorStringWithFormat(
88 "invalid boolean value '%s' passed for -G option",
89 option_arg
.str().c_str());
92 uint32_t ignore_count
;
93 if (option_arg
.getAsInteger(0, ignore_count
))
94 error
.SetErrorStringWithFormat("invalid ignore count '%s'",
95 option_arg
.str().c_str());
97 m_bp_opts
.SetIgnoreCount(ignore_count
);
101 value
= OptionArgParser::ToBoolean(option_arg
, false, &success
);
103 m_bp_opts
.SetOneShot(value
);
105 error
.SetErrorStringWithFormat(
106 "invalid boolean value '%s' passed for -o option",
107 option_arg
.str().c_str());
110 lldb::tid_t thread_id
= LLDB_INVALID_THREAD_ID
;
111 if (option_arg
[0] != '\0') {
112 if (option_arg
.getAsInteger(0, thread_id
))
113 error
.SetErrorStringWithFormat("invalid thread id string '%s'",
114 option_arg
.str().c_str());
116 m_bp_opts
.SetThreadID(thread_id
);
119 m_bp_opts
.GetThreadSpec()->SetName(option_arg
.str().c_str());
122 m_bp_opts
.GetThreadSpec()->SetQueueName(option_arg
.str().c_str());
125 uint32_t thread_index
= UINT32_MAX
;
126 if (option_arg
[0] != '\n') {
127 if (option_arg
.getAsInteger(0, thread_index
))
128 error
.SetErrorStringWithFormat("invalid thread index string '%s'",
129 option_arg
.str().c_str());
131 m_bp_opts
.GetThreadSpec()->SetIndex(thread_index
);
134 llvm_unreachable("Unimplemented option");
140 void OptionParsingStarting(ExecutionContext
*execution_context
) override
{
145 Status
OptionParsingFinished(ExecutionContext
*execution_context
) override
{
146 if (!m_commands
.empty()) {
147 auto cmd_data
= std::make_unique
<BreakpointOptions::CommandData
>();
149 for (std::string
&str
: m_commands
)
150 cmd_data
->user_source
.AppendString(str
);
152 cmd_data
->stop_on_error
= true;
153 m_bp_opts
.SetCommandDataCallback(cmd_data
);
158 const BreakpointOptions
&GetBreakpointOptions() { return m_bp_opts
; }
160 std::vector
<std::string
> m_commands
;
161 BreakpointOptions m_bp_opts
;
164 #define LLDB_OPTIONS_breakpoint_dummy
165 #include "CommandOptions.inc"
167 class BreakpointDummyOptionGroup
: public OptionGroup
{
169 BreakpointDummyOptionGroup() : OptionGroup() {}
171 ~BreakpointDummyOptionGroup() override
= default;
173 llvm::ArrayRef
<OptionDefinition
> GetDefinitions() override
{
174 return llvm::makeArrayRef(g_breakpoint_dummy_options
);
177 Status
SetOptionValue(uint32_t option_idx
, llvm::StringRef option_arg
,
178 ExecutionContext
*execution_context
) override
{
180 const int short_option
=
181 g_breakpoint_dummy_options
[option_idx
].short_option
;
183 switch (short_option
) {
188 llvm_unreachable("Unimplemented option");
194 void OptionParsingStarting(ExecutionContext
*execution_context
) override
{
201 #define LLDB_OPTIONS_breakpoint_set
202 #include "CommandOptions.inc"
204 // CommandObjectBreakpointSet
206 class CommandObjectBreakpointSet
: public CommandObjectParsed
{
208 enum BreakpointSetType
{
212 eSetTypeFunctionName
,
213 eSetTypeFunctionRegexp
,
214 eSetTypeSourceRegexp
,
219 CommandObjectBreakpointSet(CommandInterpreter
&interpreter
)
220 : CommandObjectParsed(
221 interpreter
, "breakpoint set",
222 "Sets a breakpoint or set of breakpoints in the executable.",
223 "breakpoint set <cmd-options>"),
224 m_bp_opts(), m_python_class_options("scripted breakpoint", true, 'P'),
226 // We're picking up all the normal options, commands and disable.
227 m_all_options
.Append(&m_python_class_options
,
228 LLDB_OPT_SET_1
| LLDB_OPT_SET_2
, LLDB_OPT_SET_11
);
229 m_all_options
.Append(&m_bp_opts
,
230 LLDB_OPT_SET_1
| LLDB_OPT_SET_3
| LLDB_OPT_SET_4
,
232 m_all_options
.Append(&m_dummy_options
, LLDB_OPT_SET_1
, LLDB_OPT_SET_ALL
);
233 m_all_options
.Append(&m_options
);
234 m_all_options
.Finalize();
237 ~CommandObjectBreakpointSet() override
= default;
239 Options
*GetOptions() override
{ return &m_all_options
; }
241 class CommandOptions
: public OptionGroup
{
244 : OptionGroup(), m_condition(), m_filenames(), m_line_num(0),
245 m_column(0), m_func_names(),
246 m_func_name_type_mask(eFunctionNameTypeNone
), m_func_regexp(),
247 m_source_text_regexp(), m_modules(), m_load_addr(), m_catch_bp(false),
248 m_throw_bp(true), m_hardware(false),
249 m_exception_language(eLanguageTypeUnknown
),
250 m_language(lldb::eLanguageTypeUnknown
),
251 m_skip_prologue(eLazyBoolCalculate
), m_all_files(false),
252 m_move_to_nearest_code(eLazyBoolCalculate
) {}
254 ~CommandOptions() override
= default;
256 Status
SetOptionValue(uint32_t option_idx
, llvm::StringRef option_arg
,
257 ExecutionContext
*execution_context
) override
{
259 const int short_option
=
260 g_breakpoint_set_options
[option_idx
].short_option
;
262 switch (short_option
) {
264 m_load_addr
= OptionArgParser::ToAddress(execution_context
, option_arg
,
265 LLDB_INVALID_ADDRESS
, &error
);
273 m_func_names
.push_back(option_arg
);
274 m_func_name_type_mask
|= eFunctionNameTypeBase
;
278 if (option_arg
.getAsInteger(0, m_column
))
279 error
.SetErrorStringWithFormat("invalid column number: %s",
280 option_arg
.str().c_str());
284 LanguageType language
= Language::GetLanguageTypeFromString(option_arg
);
287 case eLanguageTypeC89
:
289 case eLanguageTypeC99
:
290 case eLanguageTypeC11
:
291 m_exception_language
= eLanguageTypeC
;
293 case eLanguageTypeC_plus_plus
:
294 case eLanguageTypeC_plus_plus_03
:
295 case eLanguageTypeC_plus_plus_11
:
296 case eLanguageTypeC_plus_plus_14
:
297 m_exception_language
= eLanguageTypeC_plus_plus
;
299 case eLanguageTypeObjC
:
300 m_exception_language
= eLanguageTypeObjC
;
302 case eLanguageTypeObjC_plus_plus
:
303 error
.SetErrorStringWithFormat(
304 "Set exception breakpoints separately for c++ and objective-c");
306 case eLanguageTypeUnknown
:
307 error
.SetErrorStringWithFormat(
308 "Unknown language type: '%s' for exception breakpoint",
309 option_arg
.str().c_str());
312 error
.SetErrorStringWithFormat(
313 "Unsupported language type: '%s' for exception breakpoint",
314 option_arg
.str().c_str());
319 m_filenames
.AppendIfUnique(FileSpec(option_arg
));
323 m_func_names
.push_back(option_arg
);
324 m_func_name_type_mask
|= eFunctionNameTypeFull
;
329 m_catch_bp
= OptionArgParser::ToBoolean(option_arg
, true, &success
);
331 error
.SetErrorStringWithFormat(
332 "Invalid boolean value for on-catch option: '%s'",
333 option_arg
.str().c_str());
343 value
= OptionArgParser::ToBoolean(option_arg
, true, &success
);
345 m_skip_prologue
= eLazyBoolYes
;
347 m_skip_prologue
= eLazyBoolNo
;
350 error
.SetErrorStringWithFormat(
351 "Invalid boolean value for skip prologue option: '%s'",
352 option_arg
.str().c_str());
356 if (option_arg
.getAsInteger(0, m_line_num
))
357 error
.SetErrorStringWithFormat("invalid line number: %s.",
358 option_arg
.str().c_str());
362 m_language
= Language::GetLanguageTypeFromString(option_arg
);
363 if (m_language
== eLanguageTypeUnknown
)
364 error
.SetErrorStringWithFormat(
365 "Unknown language type: '%s' for breakpoint",
366 option_arg
.str().c_str());
372 value
= OptionArgParser::ToBoolean(option_arg
, true, &success
);
374 m_move_to_nearest_code
= eLazyBoolYes
;
376 m_move_to_nearest_code
= eLazyBoolNo
;
379 error
.SetErrorStringWithFormat(
380 "Invalid boolean value for move-to-nearest-code option: '%s'",
381 option_arg
.str().c_str());
386 m_func_names
.push_back(option_arg
);
387 m_func_name_type_mask
|= eFunctionNameTypeMethod
;
391 m_func_names
.push_back(option_arg
);
392 m_func_name_type_mask
|= eFunctionNameTypeAuto
;
396 if (BreakpointID::StringIsBreakpointName(option_arg
, error
))
397 m_breakpoint_names
.push_back(option_arg
);
399 error
.SetErrorStringWithFormat("Invalid breakpoint name: %s",
400 option_arg
.str().c_str());
405 lldb::addr_t tmp_offset_addr
;
406 tmp_offset_addr
= OptionArgParser::ToAddress(execution_context
,
407 option_arg
, 0, &error
);
409 m_offset_addr
= tmp_offset_addr
;
413 m_exception_extra_args
.AppendArgument("-O");
414 m_exception_extra_args
.AppendArgument(option_arg
);
418 m_source_text_regexp
.assign(option_arg
);
422 m_func_regexp
.assign(option_arg
);
426 m_modules
.AppendIfUnique(FileSpec(option_arg
));
430 m_func_names
.push_back(option_arg
);
431 m_func_name_type_mask
|= eFunctionNameTypeSelector
;
436 m_throw_bp
= OptionArgParser::ToBoolean(option_arg
, true, &success
);
438 error
.SetErrorStringWithFormat(
439 "Invalid boolean value for on-throw option: '%s'",
440 option_arg
.str().c_str());
444 m_source_regex_func_names
.insert(option_arg
);
448 llvm_unreachable("Unimplemented option");
454 void OptionParsingStarting(ExecutionContext
*execution_context
) override
{
458 m_func_names
.clear();
459 m_func_name_type_mask
= eFunctionNameTypeNone
;
460 m_func_regexp
.clear();
461 m_source_text_regexp
.clear();
463 m_load_addr
= LLDB_INVALID_ADDRESS
;
468 m_exception_language
= eLanguageTypeUnknown
;
469 m_language
= lldb::eLanguageTypeUnknown
;
470 m_skip_prologue
= eLazyBoolCalculate
;
471 m_breakpoint_names
.clear();
473 m_exception_extra_args
.Clear();
474 m_move_to_nearest_code
= eLazyBoolCalculate
;
475 m_source_regex_func_names
.clear();
476 m_current_key
.clear();
479 llvm::ArrayRef
<OptionDefinition
> GetDefinitions() override
{
480 return llvm::makeArrayRef(g_breakpoint_set_options
);
483 // Instance variables to hold the values for command options.
485 std::string m_condition
;
486 FileSpecList m_filenames
;
489 std::vector
<std::string
> m_func_names
;
490 std::vector
<std::string
> m_breakpoint_names
;
491 lldb::FunctionNameType m_func_name_type_mask
;
492 std::string m_func_regexp
;
493 std::string m_source_text_regexp
;
494 FileSpecList m_modules
;
495 lldb::addr_t m_load_addr
;
496 lldb::addr_t m_offset_addr
;
499 bool m_hardware
; // Request to use hardware breakpoints
500 lldb::LanguageType m_exception_language
;
501 lldb::LanguageType m_language
;
502 LazyBool m_skip_prologue
;
504 Args m_exception_extra_args
;
505 LazyBool m_move_to_nearest_code
;
506 std::unordered_set
<std::string
> m_source_regex_func_names
;
507 std::string m_current_key
;
511 bool DoExecute(Args
&command
, CommandReturnObject
&result
) override
{
512 Target
&target
= GetSelectedOrDummyTarget(m_dummy_options
.m_use_dummy
);
514 // The following are the various types of breakpoints that could be set:
515 // 1). -f -l -p [-s -g] (setting breakpoint by source location)
516 // 2). -a [-s -g] (setting breakpoint by address)
517 // 3). -n [-s -g] (setting breakpoint by function name)
518 // 4). -r [-s -g] (setting breakpoint by function name regular
520 // 5). -p -f (setting a breakpoint by comparing a reg-exp
522 // 6). -E [-w -h] (setting a breakpoint for exceptions for a
525 BreakpointSetType break_type
= eSetTypeInvalid
;
527 if (!m_python_class_options
.GetName().empty())
528 break_type
= eSetTypeScripted
;
529 else if (m_options
.m_line_num
!= 0)
530 break_type
= eSetTypeFileAndLine
;
531 else if (m_options
.m_load_addr
!= LLDB_INVALID_ADDRESS
)
532 break_type
= eSetTypeAddress
;
533 else if (!m_options
.m_func_names
.empty())
534 break_type
= eSetTypeFunctionName
;
535 else if (!m_options
.m_func_regexp
.empty())
536 break_type
= eSetTypeFunctionRegexp
;
537 else if (!m_options
.m_source_text_regexp
.empty())
538 break_type
= eSetTypeSourceRegexp
;
539 else if (m_options
.m_exception_language
!= eLanguageTypeUnknown
)
540 break_type
= eSetTypeException
;
542 BreakpointSP bp_sp
= nullptr;
543 FileSpec module_spec
;
544 const bool internal
= false;
546 // If the user didn't specify skip-prologue, having an offset should turn
548 if (m_options
.m_offset_addr
!= 0 &&
549 m_options
.m_skip_prologue
== eLazyBoolCalculate
)
550 m_options
.m_skip_prologue
= eLazyBoolNo
;
552 switch (break_type
) {
553 case eSetTypeFileAndLine
: // Breakpoint by source position
556 const size_t num_files
= m_options
.m_filenames
.GetSize();
557 if (num_files
== 0) {
558 if (!GetDefaultFile(target
, file
, result
)) {
559 result
.AppendError("No file supplied and no default file available.");
560 result
.SetStatus(eReturnStatusFailed
);
563 } else if (num_files
> 1) {
564 result
.AppendError("Only one file at a time is allowed for file and "
565 "line breakpoints.");
566 result
.SetStatus(eReturnStatusFailed
);
569 file
= m_options
.m_filenames
.GetFileSpecAtIndex(0);
571 // Only check for inline functions if
572 LazyBool check_inlines
= eLazyBoolCalculate
;
574 bp_sp
= target
.CreateBreakpoint(
575 &(m_options
.m_modules
), file
, m_options
.m_line_num
,
576 m_options
.m_column
, m_options
.m_offset_addr
, check_inlines
,
577 m_options
.m_skip_prologue
, internal
, m_options
.m_hardware
,
578 m_options
.m_move_to_nearest_code
);
581 case eSetTypeAddress
: // Breakpoint by address
583 // If a shared library has been specified, make an lldb_private::Address
584 // with the library, and use that. That way the address breakpoint
585 // will track the load location of the library.
586 size_t num_modules_specified
= m_options
.m_modules
.GetSize();
587 if (num_modules_specified
== 1) {
588 const FileSpec
*file_spec
=
589 m_options
.m_modules
.GetFileSpecPointerAtIndex(0);
590 bp_sp
= target
.CreateAddressInModuleBreakpoint(
591 m_options
.m_load_addr
, internal
, file_spec
, m_options
.m_hardware
);
592 } else if (num_modules_specified
== 0) {
593 bp_sp
= target
.CreateBreakpoint(m_options
.m_load_addr
, internal
,
594 m_options
.m_hardware
);
596 result
.AppendError("Only one shared library can be specified for "
597 "address breakpoints.");
598 result
.SetStatus(eReturnStatusFailed
);
603 case eSetTypeFunctionName
: // Breakpoint by function name
605 FunctionNameType name_type_mask
= m_options
.m_func_name_type_mask
;
607 if (name_type_mask
== 0)
608 name_type_mask
= eFunctionNameTypeAuto
;
610 bp_sp
= target
.CreateBreakpoint(
611 &(m_options
.m_modules
), &(m_options
.m_filenames
),
612 m_options
.m_func_names
, name_type_mask
, m_options
.m_language
,
613 m_options
.m_offset_addr
, m_options
.m_skip_prologue
, internal
,
614 m_options
.m_hardware
);
617 case eSetTypeFunctionRegexp
: // Breakpoint by regular expression function
620 RegularExpression
regexp(m_options
.m_func_regexp
);
621 if (llvm::Error err
= regexp
.GetError()) {
622 result
.AppendErrorWithFormat(
623 "Function name regular expression could not be compiled: \"%s\"",
624 llvm::toString(std::move(err
)).c_str());
625 result
.SetStatus(eReturnStatusFailed
);
629 bp_sp
= target
.CreateFuncRegexBreakpoint(
630 &(m_options
.m_modules
), &(m_options
.m_filenames
), std::move(regexp
),
631 m_options
.m_language
, m_options
.m_skip_prologue
, internal
,
632 m_options
.m_hardware
);
634 case eSetTypeSourceRegexp
: // Breakpoint by regexp on source text.
636 const size_t num_files
= m_options
.m_filenames
.GetSize();
638 if (num_files
== 0 && !m_options
.m_all_files
) {
640 if (!GetDefaultFile(target
, file
, result
)) {
642 "No files provided and could not find default file.");
643 result
.SetStatus(eReturnStatusFailed
);
646 m_options
.m_filenames
.Append(file
);
650 RegularExpression
regexp(m_options
.m_source_text_regexp
);
651 if (llvm::Error err
= regexp
.GetError()) {
652 result
.AppendErrorWithFormat(
653 "Source text regular expression could not be compiled: \"%s\"",
654 llvm::toString(std::move(err
)).c_str());
655 result
.SetStatus(eReturnStatusFailed
);
658 bp_sp
= target
.CreateSourceRegexBreakpoint(
659 &(m_options
.m_modules
), &(m_options
.m_filenames
),
660 m_options
.m_source_regex_func_names
, std::move(regexp
), internal
,
661 m_options
.m_hardware
, m_options
.m_move_to_nearest_code
);
663 case eSetTypeException
: {
664 Status precond_error
;
665 bp_sp
= target
.CreateExceptionBreakpoint(
666 m_options
.m_exception_language
, m_options
.m_catch_bp
,
667 m_options
.m_throw_bp
, internal
, &m_options
.m_exception_extra_args
,
669 if (precond_error
.Fail()) {
670 result
.AppendErrorWithFormat(
671 "Error setting extra exception arguments: %s",
672 precond_error
.AsCString());
673 target
.RemoveBreakpointByID(bp_sp
->GetID());
674 result
.SetStatus(eReturnStatusFailed
);
678 case eSetTypeScripted
: {
681 bp_sp
= target
.CreateScriptedBreakpoint(
682 m_python_class_options
.GetName().c_str(), &(m_options
.m_modules
),
683 &(m_options
.m_filenames
), false, m_options
.m_hardware
,
684 m_python_class_options
.GetStructuredData(), &error
);
686 result
.AppendErrorWithFormat(
687 "Error setting extra exception arguments: %s", error
.AsCString());
688 target
.RemoveBreakpointByID(bp_sp
->GetID());
689 result
.SetStatus(eReturnStatusFailed
);
697 // Now set the various options that were passed in:
699 bp_sp
->GetOptions()->CopyOverSetOptions(m_bp_opts
.GetBreakpointOptions());
701 if (!m_options
.m_breakpoint_names
.empty()) {
703 for (auto name
: m_options
.m_breakpoint_names
) {
704 target
.AddNameToBreakpoint(bp_sp
, name
.c_str(), name_error
);
705 if (name_error
.Fail()) {
706 result
.AppendErrorWithFormat("Invalid breakpoint name: %s",
708 target
.RemoveBreakpointByID(bp_sp
->GetID());
709 result
.SetStatus(eReturnStatusFailed
);
717 Stream
&output_stream
= result
.GetOutputStream();
718 const bool show_locations
= false;
719 bp_sp
->GetDescription(&output_stream
, lldb::eDescriptionLevelInitial
,
721 if (&target
== &GetDummyTarget())
722 output_stream
.Printf("Breakpoint set in dummy target, will get copied "
723 "into future targets.\n");
725 // Don't print out this warning for exception breakpoints. They can
726 // get set before the target is set, but we won't know how to actually
727 // set the breakpoint till we run.
728 if (bp_sp
->GetNumLocations() == 0 && break_type
!= eSetTypeException
) {
729 output_stream
.Printf("WARNING: Unable to resolve breakpoint to any "
730 "actual locations.\n");
733 result
.SetStatus(eReturnStatusSuccessFinishResult
);
735 result
.AppendError("Breakpoint creation failed: No breakpoint created.");
736 result
.SetStatus(eReturnStatusFailed
);
739 return result
.Succeeded();
743 bool GetDefaultFile(Target
&target
, FileSpec
&file
,
744 CommandReturnObject
&result
) {
745 uint32_t default_line
;
746 // First use the Source Manager's default file. Then use the current stack
748 if (!target
.GetSourceManager().GetDefaultFileAndLine(file
, default_line
)) {
749 StackFrame
*cur_frame
= m_exe_ctx
.GetFramePtr();
750 if (cur_frame
== nullptr) {
752 "No selected frame to use to find the default file.");
753 result
.SetStatus(eReturnStatusFailed
);
755 } else if (!cur_frame
->HasDebugInformation()) {
756 result
.AppendError("Cannot use the selected frame to find the default "
757 "file, it has no debug info.");
758 result
.SetStatus(eReturnStatusFailed
);
761 const SymbolContext
&sc
=
762 cur_frame
->GetSymbolContext(eSymbolContextLineEntry
);
763 if (sc
.line_entry
.file
) {
764 file
= sc
.line_entry
.file
;
766 result
.AppendError("Can't find the file for the selected frame to "
767 "use as the default file.");
768 result
.SetStatus(eReturnStatusFailed
);
776 BreakpointOptionGroup m_bp_opts
;
777 BreakpointDummyOptionGroup m_dummy_options
;
778 OptionGroupPythonClassWithDict m_python_class_options
;
779 CommandOptions m_options
;
780 OptionGroupOptions m_all_options
;
783 // CommandObjectBreakpointModify
786 class CommandObjectBreakpointModify
: public CommandObjectParsed
{
788 CommandObjectBreakpointModify(CommandInterpreter
&interpreter
)
789 : CommandObjectParsed(interpreter
, "breakpoint modify",
790 "Modify the options on a breakpoint or set of "
791 "breakpoints in the executable. "
792 "If no breakpoint is specified, acts on the last "
793 "created breakpoint. "
794 "With the exception of -e, -d and -i, passing an "
795 "empty argument clears the modification.",
798 CommandArgumentEntry arg
;
799 CommandObject::AddIDsArgumentData(arg
, eArgTypeBreakpointID
,
800 eArgTypeBreakpointIDRange
);
801 // Add the entry for the first argument for this command to the object's
803 m_arguments
.push_back(arg
);
805 m_options
.Append(&m_bp_opts
,
806 LLDB_OPT_SET_1
| LLDB_OPT_SET_2
| LLDB_OPT_SET_3
,
808 m_options
.Append(&m_dummy_opts
, LLDB_OPT_SET_1
, LLDB_OPT_SET_ALL
);
809 m_options
.Finalize();
812 ~CommandObjectBreakpointModify() override
= default;
814 Options
*GetOptions() override
{ return &m_options
; }
817 bool DoExecute(Args
&command
, CommandReturnObject
&result
) override
{
818 Target
&target
= GetSelectedOrDummyTarget(m_dummy_opts
.m_use_dummy
);
820 std::unique_lock
<std::recursive_mutex
> lock
;
821 target
.GetBreakpointList().GetListMutex(lock
);
823 BreakpointIDList valid_bp_ids
;
825 CommandObjectMultiwordBreakpoint::VerifyBreakpointOrLocationIDs(
826 command
, &target
, result
, &valid_bp_ids
,
827 BreakpointName::Permissions::PermissionKinds::disablePerm
);
829 if (result
.Succeeded()) {
830 const size_t count
= valid_bp_ids
.GetSize();
831 for (size_t i
= 0; i
< count
; ++i
) {
832 BreakpointID cur_bp_id
= valid_bp_ids
.GetBreakpointIDAtIndex(i
);
834 if (cur_bp_id
.GetBreakpointID() != LLDB_INVALID_BREAK_ID
) {
836 target
.GetBreakpointByID(cur_bp_id
.GetBreakpointID()).get();
837 if (cur_bp_id
.GetLocationID() != LLDB_INVALID_BREAK_ID
) {
838 BreakpointLocation
*location
=
839 bp
->FindLocationByID(cur_bp_id
.GetLocationID()).get();
841 location
->GetLocationOptions()->CopyOverSetOptions(
842 m_bp_opts
.GetBreakpointOptions());
844 bp
->GetOptions()->CopyOverSetOptions(
845 m_bp_opts
.GetBreakpointOptions());
851 return result
.Succeeded();
855 BreakpointOptionGroup m_bp_opts
;
856 BreakpointDummyOptionGroup m_dummy_opts
;
857 OptionGroupOptions m_options
;
860 // CommandObjectBreakpointEnable
863 class CommandObjectBreakpointEnable
: public CommandObjectParsed
{
865 CommandObjectBreakpointEnable(CommandInterpreter
&interpreter
)
866 : CommandObjectParsed(interpreter
, "enable",
867 "Enable the specified disabled breakpoint(s). If "
868 "no breakpoints are specified, enable all of them.",
870 CommandArgumentEntry arg
;
871 CommandObject::AddIDsArgumentData(arg
, eArgTypeBreakpointID
,
872 eArgTypeBreakpointIDRange
);
873 // Add the entry for the first argument for this command to the object's
875 m_arguments
.push_back(arg
);
878 ~CommandObjectBreakpointEnable() override
= default;
881 bool DoExecute(Args
&command
, CommandReturnObject
&result
) override
{
882 Target
&target
= GetSelectedOrDummyTarget();
884 std::unique_lock
<std::recursive_mutex
> lock
;
885 target
.GetBreakpointList().GetListMutex(lock
);
887 const BreakpointList
&breakpoints
= target
.GetBreakpointList();
889 size_t num_breakpoints
= breakpoints
.GetSize();
891 if (num_breakpoints
== 0) {
892 result
.AppendError("No breakpoints exist to be enabled.");
893 result
.SetStatus(eReturnStatusFailed
);
897 if (command
.empty()) {
898 // No breakpoint selected; enable all currently set breakpoints.
899 target
.EnableAllowedBreakpoints();
900 result
.AppendMessageWithFormat("All breakpoints enabled. (%" PRIu64
902 (uint64_t)num_breakpoints
);
903 result
.SetStatus(eReturnStatusSuccessFinishNoResult
);
905 // Particular breakpoint selected; enable that breakpoint.
906 BreakpointIDList valid_bp_ids
;
907 CommandObjectMultiwordBreakpoint::VerifyBreakpointOrLocationIDs(
908 command
, &target
, result
, &valid_bp_ids
,
909 BreakpointName::Permissions::PermissionKinds::disablePerm
);
911 if (result
.Succeeded()) {
912 int enable_count
= 0;
914 const size_t count
= valid_bp_ids
.GetSize();
915 for (size_t i
= 0; i
< count
; ++i
) {
916 BreakpointID cur_bp_id
= valid_bp_ids
.GetBreakpointIDAtIndex(i
);
918 if (cur_bp_id
.GetBreakpointID() != LLDB_INVALID_BREAK_ID
) {
919 Breakpoint
*breakpoint
=
920 target
.GetBreakpointByID(cur_bp_id
.GetBreakpointID()).get();
921 if (cur_bp_id
.GetLocationID() != LLDB_INVALID_BREAK_ID
) {
922 BreakpointLocation
*location
=
923 breakpoint
->FindLocationByID(cur_bp_id
.GetLocationID()).get();
925 location
->SetEnabled(true);
929 breakpoint
->SetEnabled(true);
934 result
.AppendMessageWithFormat("%d breakpoints enabled.\n",
935 enable_count
+ loc_count
);
936 result
.SetStatus(eReturnStatusSuccessFinishNoResult
);
940 return result
.Succeeded();
944 // CommandObjectBreakpointDisable
947 class CommandObjectBreakpointDisable
: public CommandObjectParsed
{
949 CommandObjectBreakpointDisable(CommandInterpreter
&interpreter
)
950 : CommandObjectParsed(
951 interpreter
, "breakpoint disable",
952 "Disable the specified breakpoint(s) without deleting "
953 "them. If none are specified, disable all "
957 "Disable the specified breakpoint(s) without deleting them. \
958 If none are specified, disable all breakpoints."
962 "Note: disabling a breakpoint will cause none of its locations to be hit \
963 regardless of whether individual locations are enabled or disabled. After the sequence:"
966 (lldb) break disable 1
967 (lldb) break enable 1.1
969 execution will NOT stop at location 1.1. To achieve that, type:
971 (lldb) break disable 1.*
972 (lldb) break enable 1.1
975 "The first command disables all locations for breakpoint 1, \
976 the second re-enables the first location.");
978 CommandArgumentEntry arg
;
979 CommandObject::AddIDsArgumentData(arg
, eArgTypeBreakpointID
,
980 eArgTypeBreakpointIDRange
);
981 // Add the entry for the first argument for this command to the object's
983 m_arguments
.push_back(arg
);
986 ~CommandObjectBreakpointDisable() override
= default;
989 bool DoExecute(Args
&command
, CommandReturnObject
&result
) override
{
990 Target
&target
= GetSelectedOrDummyTarget();
991 std::unique_lock
<std::recursive_mutex
> lock
;
992 target
.GetBreakpointList().GetListMutex(lock
);
994 const BreakpointList
&breakpoints
= target
.GetBreakpointList();
995 size_t num_breakpoints
= breakpoints
.GetSize();
997 if (num_breakpoints
== 0) {
998 result
.AppendError("No breakpoints exist to be disabled.");
999 result
.SetStatus(eReturnStatusFailed
);
1003 if (command
.empty()) {
1004 // No breakpoint selected; disable all currently set breakpoints.
1005 target
.DisableAllowedBreakpoints();
1006 result
.AppendMessageWithFormat("All breakpoints disabled. (%" PRIu64
1008 (uint64_t)num_breakpoints
);
1009 result
.SetStatus(eReturnStatusSuccessFinishNoResult
);
1011 // Particular breakpoint selected; disable that breakpoint.
1012 BreakpointIDList valid_bp_ids
;
1014 CommandObjectMultiwordBreakpoint::VerifyBreakpointOrLocationIDs(
1015 command
, &target
, result
, &valid_bp_ids
,
1016 BreakpointName::Permissions::PermissionKinds::disablePerm
);
1018 if (result
.Succeeded()) {
1019 int disable_count
= 0;
1021 const size_t count
= valid_bp_ids
.GetSize();
1022 for (size_t i
= 0; i
< count
; ++i
) {
1023 BreakpointID cur_bp_id
= valid_bp_ids
.GetBreakpointIDAtIndex(i
);
1025 if (cur_bp_id
.GetBreakpointID() != LLDB_INVALID_BREAK_ID
) {
1026 Breakpoint
*breakpoint
=
1027 target
.GetBreakpointByID(cur_bp_id
.GetBreakpointID()).get();
1028 if (cur_bp_id
.GetLocationID() != LLDB_INVALID_BREAK_ID
) {
1029 BreakpointLocation
*location
=
1030 breakpoint
->FindLocationByID(cur_bp_id
.GetLocationID()).get();
1032 location
->SetEnabled(false);
1036 breakpoint
->SetEnabled(false);
1041 result
.AppendMessageWithFormat("%d breakpoints disabled.\n",
1042 disable_count
+ loc_count
);
1043 result
.SetStatus(eReturnStatusSuccessFinishNoResult
);
1047 return result
.Succeeded();
1051 // CommandObjectBreakpointList
1053 #pragma mark List::CommandOptions
1054 #define LLDB_OPTIONS_breakpoint_list
1055 #include "CommandOptions.inc"
1059 class CommandObjectBreakpointList
: public CommandObjectParsed
{
1061 CommandObjectBreakpointList(CommandInterpreter
&interpreter
)
1062 : CommandObjectParsed(
1063 interpreter
, "breakpoint list",
1064 "List some or all breakpoints at configurable levels of detail.",
1067 CommandArgumentEntry arg
;
1068 CommandArgumentData bp_id_arg
;
1070 // Define the first (and only) variant of this arg.
1071 bp_id_arg
.arg_type
= eArgTypeBreakpointID
;
1072 bp_id_arg
.arg_repetition
= eArgRepeatOptional
;
1074 // There is only one variant this argument could be; put it into the
1076 arg
.push_back(bp_id_arg
);
1078 // Push the data for the first argument into the m_arguments vector.
1079 m_arguments
.push_back(arg
);
1082 ~CommandObjectBreakpointList() override
= default;
1084 Options
*GetOptions() override
{ return &m_options
; }
1086 class CommandOptions
: public Options
{
1089 : Options(), m_level(lldb::eDescriptionLevelBrief
), m_use_dummy(false) {
1092 ~CommandOptions() override
= default;
1094 Status
SetOptionValue(uint32_t option_idx
, llvm::StringRef option_arg
,
1095 ExecutionContext
*execution_context
) override
{
1097 const int short_option
= m_getopt_table
[option_idx
].val
;
1099 switch (short_option
) {
1101 m_level
= lldb::eDescriptionLevelBrief
;
1107 m_level
= lldb::eDescriptionLevelFull
;
1110 m_level
= lldb::eDescriptionLevelVerbose
;
1116 llvm_unreachable("Unimplemented option");
1122 void OptionParsingStarting(ExecutionContext
*execution_context
) override
{
1123 m_level
= lldb::eDescriptionLevelFull
;
1125 m_use_dummy
= false;
1128 llvm::ArrayRef
<OptionDefinition
> GetDefinitions() override
{
1129 return llvm::makeArrayRef(g_breakpoint_list_options
);
1132 // Instance variables to hold the values for command options.
1134 lldb::DescriptionLevel m_level
;
1141 bool DoExecute(Args
&command
, CommandReturnObject
&result
) override
{
1142 Target
&target
= GetSelectedOrDummyTarget(m_options
.m_use_dummy
);
1144 const BreakpointList
&breakpoints
=
1145 target
.GetBreakpointList(m_options
.m_internal
);
1146 std::unique_lock
<std::recursive_mutex
> lock
;
1147 target
.GetBreakpointList(m_options
.m_internal
).GetListMutex(lock
);
1149 size_t num_breakpoints
= breakpoints
.GetSize();
1151 if (num_breakpoints
== 0) {
1152 result
.AppendMessage("No breakpoints currently set.");
1153 result
.SetStatus(eReturnStatusSuccessFinishNoResult
);
1157 Stream
&output_stream
= result
.GetOutputStream();
1159 if (command
.empty()) {
1160 // No breakpoint selected; show info about all currently set breakpoints.
1161 result
.AppendMessage("Current breakpoints:");
1162 for (size_t i
= 0; i
< num_breakpoints
; ++i
) {
1163 Breakpoint
*breakpoint
= breakpoints
.GetBreakpointAtIndex(i
).get();
1164 if (breakpoint
->AllowList())
1165 AddBreakpointDescription(&output_stream
, breakpoint
,
1168 result
.SetStatus(eReturnStatusSuccessFinishNoResult
);
1170 // Particular breakpoints selected; show info about that breakpoint.
1171 BreakpointIDList valid_bp_ids
;
1172 CommandObjectMultiwordBreakpoint::VerifyBreakpointOrLocationIDs(
1173 command
, &target
, result
, &valid_bp_ids
,
1174 BreakpointName::Permissions::PermissionKinds::listPerm
);
1176 if (result
.Succeeded()) {
1177 for (size_t i
= 0; i
< valid_bp_ids
.GetSize(); ++i
) {
1178 BreakpointID cur_bp_id
= valid_bp_ids
.GetBreakpointIDAtIndex(i
);
1179 Breakpoint
*breakpoint
=
1180 target
.GetBreakpointByID(cur_bp_id
.GetBreakpointID()).get();
1181 AddBreakpointDescription(&output_stream
, breakpoint
,
1184 result
.SetStatus(eReturnStatusSuccessFinishNoResult
);
1186 result
.AppendError("Invalid breakpoint ID.");
1187 result
.SetStatus(eReturnStatusFailed
);
1191 return result
.Succeeded();
1195 CommandOptions m_options
;
1198 // CommandObjectBreakpointClear
1199 #pragma mark Clear::CommandOptions
1201 #define LLDB_OPTIONS_breakpoint_clear
1202 #include "CommandOptions.inc"
1206 class CommandObjectBreakpointClear
: public CommandObjectParsed
{
1208 enum BreakpointClearType
{ eClearTypeInvalid
, eClearTypeFileAndLine
};
1210 CommandObjectBreakpointClear(CommandInterpreter
&interpreter
)
1211 : CommandObjectParsed(interpreter
, "breakpoint clear",
1212 "Delete or disable breakpoints matching the "
1213 "specified source file and line.",
1214 "breakpoint clear <cmd-options>"),
1217 ~CommandObjectBreakpointClear() override
= default;
1219 Options
*GetOptions() override
{ return &m_options
; }
1221 class CommandOptions
: public Options
{
1223 CommandOptions() : Options(), m_filename(), m_line_num(0) {}
1225 ~CommandOptions() override
= default;
1227 Status
SetOptionValue(uint32_t option_idx
, llvm::StringRef option_arg
,
1228 ExecutionContext
*execution_context
) override
{
1230 const int short_option
= m_getopt_table
[option_idx
].val
;
1232 switch (short_option
) {
1234 m_filename
.assign(option_arg
);
1238 option_arg
.getAsInteger(0, m_line_num
);
1242 llvm_unreachable("Unimplemented option");
1248 void OptionParsingStarting(ExecutionContext
*execution_context
) override
{
1253 llvm::ArrayRef
<OptionDefinition
> GetDefinitions() override
{
1254 return llvm::makeArrayRef(g_breakpoint_clear_options
);
1257 // Instance variables to hold the values for command options.
1259 std::string m_filename
;
1260 uint32_t m_line_num
;
1264 bool DoExecute(Args
&command
, CommandReturnObject
&result
) override
{
1265 Target
&target
= GetSelectedOrDummyTarget();
1267 // The following are the various types of breakpoints that could be
1269 // 1). -f -l (clearing breakpoint by source location)
1271 BreakpointClearType break_type
= eClearTypeInvalid
;
1273 if (m_options
.m_line_num
!= 0)
1274 break_type
= eClearTypeFileAndLine
;
1276 std::unique_lock
<std::recursive_mutex
> lock
;
1277 target
.GetBreakpointList().GetListMutex(lock
);
1279 BreakpointList
&breakpoints
= target
.GetBreakpointList();
1280 size_t num_breakpoints
= breakpoints
.GetSize();
1282 // Early return if there's no breakpoint at all.
1283 if (num_breakpoints
== 0) {
1284 result
.AppendError("Breakpoint clear: No breakpoint cleared.");
1285 result
.SetStatus(eReturnStatusFailed
);
1286 return result
.Succeeded();
1289 // Find matching breakpoints and delete them.
1291 // First create a copy of all the IDs.
1292 std::vector
<break_id_t
> BreakIDs
;
1293 for (size_t i
= 0; i
< num_breakpoints
; ++i
)
1294 BreakIDs
.push_back(breakpoints
.GetBreakpointAtIndex(i
)->GetID());
1296 int num_cleared
= 0;
1298 switch (break_type
) {
1299 case eClearTypeFileAndLine
: // Breakpoint by source position
1301 const ConstString
filename(m_options
.m_filename
.c_str());
1302 BreakpointLocationCollection loc_coll
;
1304 for (size_t i
= 0; i
< num_breakpoints
; ++i
) {
1305 Breakpoint
*bp
= breakpoints
.FindBreakpointByID(BreakIDs
[i
]).get();
1307 if (bp
->GetMatchingFileLine(filename
, m_options
.m_line_num
, loc_coll
)) {
1308 // If the collection size is 0, it's a full match and we can just
1309 // remove the breakpoint.
1310 if (loc_coll
.GetSize() == 0) {
1311 bp
->GetDescription(&ss
, lldb::eDescriptionLevelBrief
);
1313 target
.RemoveBreakpointByID(bp
->GetID());
1324 if (num_cleared
> 0) {
1325 Stream
&output_stream
= result
.GetOutputStream();
1326 output_stream
.Printf("%d breakpoints cleared:\n", num_cleared
);
1327 output_stream
<< ss
.GetString();
1328 output_stream
.EOL();
1329 result
.SetStatus(eReturnStatusSuccessFinishNoResult
);
1331 result
.AppendError("Breakpoint clear: No breakpoint cleared.");
1332 result
.SetStatus(eReturnStatusFailed
);
1335 return result
.Succeeded();
1339 CommandOptions m_options
;
1342 // CommandObjectBreakpointDelete
1343 #define LLDB_OPTIONS_breakpoint_delete
1344 #include "CommandOptions.inc"
1348 class CommandObjectBreakpointDelete
: public CommandObjectParsed
{
1350 CommandObjectBreakpointDelete(CommandInterpreter
&interpreter
)
1351 : CommandObjectParsed(interpreter
, "breakpoint delete",
1352 "Delete the specified breakpoint(s). If no "
1353 "breakpoints are specified, delete them all.",
1356 CommandArgumentEntry arg
;
1357 CommandObject::AddIDsArgumentData(arg
, eArgTypeBreakpointID
,
1358 eArgTypeBreakpointIDRange
);
1359 // Add the entry for the first argument for this command to the object's
1360 // arguments vector.
1361 m_arguments
.push_back(arg
);
1364 ~CommandObjectBreakpointDelete() override
= default;
1366 Options
*GetOptions() override
{ return &m_options
; }
1368 class CommandOptions
: public Options
{
1370 CommandOptions() : Options(), m_use_dummy(false), m_force(false) {}
1372 ~CommandOptions() override
= default;
1374 Status
SetOptionValue(uint32_t option_idx
, llvm::StringRef option_arg
,
1375 ExecutionContext
*execution_context
) override
{
1377 const int short_option
= m_getopt_table
[option_idx
].val
;
1379 switch (short_option
) {
1389 llvm_unreachable("Unimplemented option");
1395 void OptionParsingStarting(ExecutionContext
*execution_context
) override
{
1396 m_use_dummy
= false;
1400 llvm::ArrayRef
<OptionDefinition
> GetDefinitions() override
{
1401 return llvm::makeArrayRef(g_breakpoint_delete_options
);
1404 // Instance variables to hold the values for command options.
1410 bool DoExecute(Args
&command
, CommandReturnObject
&result
) override
{
1411 Target
&target
= GetSelectedOrDummyTarget(m_options
.m_use_dummy
);
1413 std::unique_lock
<std::recursive_mutex
> lock
;
1414 target
.GetBreakpointList().GetListMutex(lock
);
1416 const BreakpointList
&breakpoints
= target
.GetBreakpointList();
1418 size_t num_breakpoints
= breakpoints
.GetSize();
1420 if (num_breakpoints
== 0) {
1421 result
.AppendError("No breakpoints exist to be deleted.");
1422 result
.SetStatus(eReturnStatusFailed
);
1426 if (command
.empty()) {
1427 if (!m_options
.m_force
&&
1428 !m_interpreter
.Confirm(
1429 "About to delete all breakpoints, do you want to do that?",
1431 result
.AppendMessage("Operation cancelled...");
1433 target
.RemoveAllowedBreakpoints();
1434 result
.AppendMessageWithFormat(
1435 "All breakpoints removed. (%" PRIu64
" breakpoint%s)\n",
1436 (uint64_t)num_breakpoints
, num_breakpoints
> 1 ? "s" : "");
1438 result
.SetStatus(eReturnStatusSuccessFinishNoResult
);
1440 // Particular breakpoint selected; disable that breakpoint.
1441 BreakpointIDList valid_bp_ids
;
1442 CommandObjectMultiwordBreakpoint::VerifyBreakpointOrLocationIDs(
1443 command
, &target
, result
, &valid_bp_ids
,
1444 BreakpointName::Permissions::PermissionKinds::deletePerm
);
1446 if (result
.Succeeded()) {
1447 int delete_count
= 0;
1448 int disable_count
= 0;
1449 const size_t count
= valid_bp_ids
.GetSize();
1450 for (size_t i
= 0; i
< count
; ++i
) {
1451 BreakpointID cur_bp_id
= valid_bp_ids
.GetBreakpointIDAtIndex(i
);
1453 if (cur_bp_id
.GetBreakpointID() != LLDB_INVALID_BREAK_ID
) {
1454 if (cur_bp_id
.GetLocationID() != LLDB_INVALID_BREAK_ID
) {
1455 Breakpoint
*breakpoint
=
1456 target
.GetBreakpointByID(cur_bp_id
.GetBreakpointID()).get();
1457 BreakpointLocation
*location
=
1458 breakpoint
->FindLocationByID(cur_bp_id
.GetLocationID()).get();
1459 // It makes no sense to try to delete individual locations, so we
1460 // disable them instead.
1462 location
->SetEnabled(false);
1466 target
.RemoveBreakpointByID(cur_bp_id
.GetBreakpointID());
1471 result
.AppendMessageWithFormat(
1472 "%d breakpoints deleted; %d breakpoint locations disabled.\n",
1473 delete_count
, disable_count
);
1474 result
.SetStatus(eReturnStatusSuccessFinishNoResult
);
1477 return result
.Succeeded();
1481 CommandOptions m_options
;
1484 // CommandObjectBreakpointName
1485 #define LLDB_OPTIONS_breakpoint_name
1486 #include "CommandOptions.inc"
1488 class BreakpointNameOptionGroup
: public OptionGroup
{
1490 BreakpointNameOptionGroup()
1491 : OptionGroup(), m_breakpoint(LLDB_INVALID_BREAK_ID
), m_use_dummy(false) {
1494 ~BreakpointNameOptionGroup() override
= default;
1496 llvm::ArrayRef
<OptionDefinition
> GetDefinitions() override
{
1497 return llvm::makeArrayRef(g_breakpoint_name_options
);
1500 Status
SetOptionValue(uint32_t option_idx
, llvm::StringRef option_arg
,
1501 ExecutionContext
*execution_context
) override
{
1503 const int short_option
= g_breakpoint_name_options
[option_idx
].short_option
;
1505 switch (short_option
) {
1507 if (BreakpointID::StringIsBreakpointName(option_arg
, error
) &&
1509 m_name
.SetValueFromString(option_arg
);
1512 if (m_breakpoint
.SetValueFromString(option_arg
).Fail())
1513 error
.SetErrorStringWithFormat(
1514 "unrecognized value \"%s\" for breakpoint",
1515 option_arg
.str().c_str());
1518 if (m_use_dummy
.SetValueFromString(option_arg
).Fail())
1519 error
.SetErrorStringWithFormat(
1520 "unrecognized value \"%s\" for use-dummy",
1521 option_arg
.str().c_str());
1524 m_help_string
.SetValueFromString(option_arg
);
1528 llvm_unreachable("Unimplemented option");
1533 void OptionParsingStarting(ExecutionContext
*execution_context
) override
{
1535 m_breakpoint
.Clear();
1536 m_use_dummy
.Clear();
1537 m_use_dummy
.SetDefaultValue(false);
1538 m_help_string
.Clear();
1541 OptionValueString m_name
;
1542 OptionValueUInt64 m_breakpoint
;
1543 OptionValueBoolean m_use_dummy
;
1544 OptionValueString m_help_string
;
1547 #define LLDB_OPTIONS_breakpoint_access
1548 #include "CommandOptions.inc"
1550 class BreakpointAccessOptionGroup
: public OptionGroup
{
1552 BreakpointAccessOptionGroup() : OptionGroup() {}
1554 ~BreakpointAccessOptionGroup() override
= default;
1556 llvm::ArrayRef
<OptionDefinition
> GetDefinitions() override
{
1557 return llvm::makeArrayRef(g_breakpoint_access_options
);
1559 Status
SetOptionValue(uint32_t option_idx
, llvm::StringRef option_arg
,
1560 ExecutionContext
*execution_context
) override
{
1562 const int short_option
=
1563 g_breakpoint_access_options
[option_idx
].short_option
;
1565 switch (short_option
) {
1567 bool value
, success
;
1568 value
= OptionArgParser::ToBoolean(option_arg
, false, &success
);
1570 m_permissions
.SetAllowList(value
);
1572 error
.SetErrorStringWithFormat(
1573 "invalid boolean value '%s' passed for -L option",
1574 option_arg
.str().c_str());
1577 bool value
, success
;
1578 value
= OptionArgParser::ToBoolean(option_arg
, false, &success
);
1580 m_permissions
.SetAllowDisable(value
);
1582 error
.SetErrorStringWithFormat(
1583 "invalid boolean value '%s' passed for -L option",
1584 option_arg
.str().c_str());
1587 bool value
, success
;
1588 value
= OptionArgParser::ToBoolean(option_arg
, false, &success
);
1590 m_permissions
.SetAllowDelete(value
);
1592 error
.SetErrorStringWithFormat(
1593 "invalid boolean value '%s' passed for -L option",
1594 option_arg
.str().c_str());
1597 llvm_unreachable("Unimplemented option");
1603 void OptionParsingStarting(ExecutionContext
*execution_context
) override
{}
1605 const BreakpointName::Permissions
&GetPermissions() const {
1606 return m_permissions
;
1608 BreakpointName::Permissions m_permissions
;
1611 class CommandObjectBreakpointNameConfigure
: public CommandObjectParsed
{
1613 CommandObjectBreakpointNameConfigure(CommandInterpreter
&interpreter
)
1614 : CommandObjectParsed(
1615 interpreter
, "configure",
1616 "Configure the options for the breakpoint"
1618 "If you provide a breakpoint id, the options will be copied from "
1619 "the breakpoint, otherwise only the options specified will be set "
1621 "breakpoint name configure <command-options> "
1622 "<breakpoint-name-list>"),
1623 m_bp_opts(), m_option_group() {
1624 // Create the first variant for the first (and only) argument for this
1626 CommandArgumentEntry arg1
;
1627 CommandArgumentData id_arg
;
1628 id_arg
.arg_type
= eArgTypeBreakpointName
;
1629 id_arg
.arg_repetition
= eArgRepeatOptional
;
1630 arg1
.push_back(id_arg
);
1631 m_arguments
.push_back(arg1
);
1633 m_option_group
.Append(&m_bp_opts
, LLDB_OPT_SET_ALL
, LLDB_OPT_SET_1
);
1634 m_option_group
.Append(&m_access_options
, LLDB_OPT_SET_ALL
,
1636 m_option_group
.Append(&m_bp_id
, LLDB_OPT_SET_2
| LLDB_OPT_SET_4
,
1638 m_option_group
.Finalize();
1641 ~CommandObjectBreakpointNameConfigure() override
= default;
1643 Options
*GetOptions() override
{ return &m_option_group
; }
1646 bool DoExecute(Args
&command
, CommandReturnObject
&result
) override
{
1648 const size_t argc
= command
.GetArgumentCount();
1650 result
.AppendError("No names provided.");
1651 result
.SetStatus(eReturnStatusFailed
);
1655 Target
&target
= GetSelectedOrDummyTarget(false);
1657 std::unique_lock
<std::recursive_mutex
> lock
;
1658 target
.GetBreakpointList().GetListMutex(lock
);
1660 // Make a pass through first to see that all the names are legal.
1661 for (auto &entry
: command
.entries()) {
1663 if (!BreakpointID::StringIsBreakpointName(entry
.ref(), error
)) {
1664 result
.AppendErrorWithFormat("Invalid breakpoint name: %s - %s",
1665 entry
.c_str(), error
.AsCString());
1666 result
.SetStatus(eReturnStatusFailed
);
1670 // Now configure them, we already pre-checked the names so we don't need to
1673 if (m_bp_id
.m_breakpoint
.OptionWasSet()) {
1674 lldb::break_id_t bp_id
= m_bp_id
.m_breakpoint
.GetUInt64Value();
1675 bp_sp
= target
.GetBreakpointByID(bp_id
);
1677 result
.AppendErrorWithFormatv("Could not find specified breakpoint {0}",
1679 result
.SetStatus(eReturnStatusFailed
);
1685 for (auto &entry
: command
.entries()) {
1686 ConstString
name(entry
.c_str());
1687 BreakpointName
*bp_name
= target
.FindBreakpointName(name
, true, error
);
1690 if (m_bp_id
.m_help_string
.OptionWasSet())
1691 bp_name
->SetHelp(m_bp_id
.m_help_string
.GetStringValue().str().c_str());
1694 target
.ConfigureBreakpointName(*bp_name
, *bp_sp
->GetOptions(),
1695 m_access_options
.GetPermissions());
1697 target
.ConfigureBreakpointName(*bp_name
,
1698 m_bp_opts
.GetBreakpointOptions(),
1699 m_access_options
.GetPermissions());
1705 BreakpointNameOptionGroup m_bp_id
; // Only using the id part of this.
1706 BreakpointOptionGroup m_bp_opts
;
1707 BreakpointAccessOptionGroup m_access_options
;
1708 OptionGroupOptions m_option_group
;
1711 class CommandObjectBreakpointNameAdd
: public CommandObjectParsed
{
1713 CommandObjectBreakpointNameAdd(CommandInterpreter
&interpreter
)
1714 : CommandObjectParsed(
1715 interpreter
, "add", "Add a name to the breakpoints provided.",
1716 "breakpoint name add <command-options> <breakpoint-id-list>"),
1717 m_name_options(), m_option_group() {
1718 // Create the first variant for the first (and only) argument for this
1720 CommandArgumentEntry arg1
;
1721 CommandArgumentData id_arg
;
1722 id_arg
.arg_type
= eArgTypeBreakpointID
;
1723 id_arg
.arg_repetition
= eArgRepeatOptional
;
1724 arg1
.push_back(id_arg
);
1725 m_arguments
.push_back(arg1
);
1727 m_option_group
.Append(&m_name_options
, LLDB_OPT_SET_1
, LLDB_OPT_SET_ALL
);
1728 m_option_group
.Finalize();
1731 ~CommandObjectBreakpointNameAdd() override
= default;
1733 Options
*GetOptions() override
{ return &m_option_group
; }
1736 bool DoExecute(Args
&command
, CommandReturnObject
&result
) override
{
1737 if (!m_name_options
.m_name
.OptionWasSet()) {
1738 result
.SetError("No name option provided.");
1743 GetSelectedOrDummyTarget(m_name_options
.m_use_dummy
.GetCurrentValue());
1745 std::unique_lock
<std::recursive_mutex
> lock
;
1746 target
.GetBreakpointList().GetListMutex(lock
);
1748 const BreakpointList
&breakpoints
= target
.GetBreakpointList();
1750 size_t num_breakpoints
= breakpoints
.GetSize();
1751 if (num_breakpoints
== 0) {
1752 result
.SetError("No breakpoints, cannot add names.");
1753 result
.SetStatus(eReturnStatusFailed
);
1757 // Particular breakpoint selected; disable that breakpoint.
1758 BreakpointIDList valid_bp_ids
;
1759 CommandObjectMultiwordBreakpoint::VerifyBreakpointIDs(
1760 command
, &target
, result
, &valid_bp_ids
,
1761 BreakpointName::Permissions::PermissionKinds::listPerm
);
1763 if (result
.Succeeded()) {
1764 if (valid_bp_ids
.GetSize() == 0) {
1765 result
.SetError("No breakpoints specified, cannot add names.");
1766 result
.SetStatus(eReturnStatusFailed
);
1769 size_t num_valid_ids
= valid_bp_ids
.GetSize();
1770 const char *bp_name
= m_name_options
.m_name
.GetCurrentValue();
1771 Status error
; // This error reports illegal names, but we've already
1772 // checked that, so we don't need to check it again here.
1773 for (size_t index
= 0; index
< num_valid_ids
; index
++) {
1774 lldb::break_id_t bp_id
=
1775 valid_bp_ids
.GetBreakpointIDAtIndex(index
).GetBreakpointID();
1776 BreakpointSP bp_sp
= breakpoints
.FindBreakpointByID(bp_id
);
1777 target
.AddNameToBreakpoint(bp_sp
, bp_name
, error
);
1785 BreakpointNameOptionGroup m_name_options
;
1786 OptionGroupOptions m_option_group
;
1789 class CommandObjectBreakpointNameDelete
: public CommandObjectParsed
{
1791 CommandObjectBreakpointNameDelete(CommandInterpreter
&interpreter
)
1792 : CommandObjectParsed(
1793 interpreter
, "delete",
1794 "Delete a name from the breakpoints provided.",
1795 "breakpoint name delete <command-options> <breakpoint-id-list>"),
1796 m_name_options(), m_option_group() {
1797 // Create the first variant for the first (and only) argument for this
1799 CommandArgumentEntry arg1
;
1800 CommandArgumentData id_arg
;
1801 id_arg
.arg_type
= eArgTypeBreakpointID
;
1802 id_arg
.arg_repetition
= eArgRepeatOptional
;
1803 arg1
.push_back(id_arg
);
1804 m_arguments
.push_back(arg1
);
1806 m_option_group
.Append(&m_name_options
, LLDB_OPT_SET_1
, LLDB_OPT_SET_ALL
);
1807 m_option_group
.Finalize();
1810 ~CommandObjectBreakpointNameDelete() override
= default;
1812 Options
*GetOptions() override
{ return &m_option_group
; }
1815 bool DoExecute(Args
&command
, CommandReturnObject
&result
) override
{
1816 if (!m_name_options
.m_name
.OptionWasSet()) {
1817 result
.SetError("No name option provided.");
1822 GetSelectedOrDummyTarget(m_name_options
.m_use_dummy
.GetCurrentValue());
1824 std::unique_lock
<std::recursive_mutex
> lock
;
1825 target
.GetBreakpointList().GetListMutex(lock
);
1827 const BreakpointList
&breakpoints
= target
.GetBreakpointList();
1829 size_t num_breakpoints
= breakpoints
.GetSize();
1830 if (num_breakpoints
== 0) {
1831 result
.SetError("No breakpoints, cannot delete names.");
1832 result
.SetStatus(eReturnStatusFailed
);
1836 // Particular breakpoint selected; disable that breakpoint.
1837 BreakpointIDList valid_bp_ids
;
1838 CommandObjectMultiwordBreakpoint::VerifyBreakpointIDs(
1839 command
, &target
, result
, &valid_bp_ids
,
1840 BreakpointName::Permissions::PermissionKinds::deletePerm
);
1842 if (result
.Succeeded()) {
1843 if (valid_bp_ids
.GetSize() == 0) {
1844 result
.SetError("No breakpoints specified, cannot delete names.");
1845 result
.SetStatus(eReturnStatusFailed
);
1848 ConstString
bp_name(m_name_options
.m_name
.GetCurrentValue());
1849 size_t num_valid_ids
= valid_bp_ids
.GetSize();
1850 for (size_t index
= 0; index
< num_valid_ids
; index
++) {
1851 lldb::break_id_t bp_id
=
1852 valid_bp_ids
.GetBreakpointIDAtIndex(index
).GetBreakpointID();
1853 BreakpointSP bp_sp
= breakpoints
.FindBreakpointByID(bp_id
);
1854 target
.RemoveNameFromBreakpoint(bp_sp
, bp_name
);
1862 BreakpointNameOptionGroup m_name_options
;
1863 OptionGroupOptions m_option_group
;
1866 class CommandObjectBreakpointNameList
: public CommandObjectParsed
{
1868 CommandObjectBreakpointNameList(CommandInterpreter
&interpreter
)
1869 : CommandObjectParsed(interpreter
, "list",
1870 "List either the names for a breakpoint or info "
1871 "about a given name. With no arguments, lists all "
1873 "breakpoint name list <command-options>"),
1874 m_name_options(), m_option_group() {
1875 m_option_group
.Append(&m_name_options
, LLDB_OPT_SET_3
, LLDB_OPT_SET_ALL
);
1876 m_option_group
.Finalize();
1879 ~CommandObjectBreakpointNameList() override
= default;
1881 Options
*GetOptions() override
{ return &m_option_group
; }
1884 bool DoExecute(Args
&command
, CommandReturnObject
&result
) override
{
1886 GetSelectedOrDummyTarget(m_name_options
.m_use_dummy
.GetCurrentValue());
1888 std::vector
<std::string
> name_list
;
1889 if (command
.empty()) {
1890 target
.GetBreakpointNames(name_list
);
1892 for (const Args::ArgEntry
&arg
: command
) {
1893 name_list
.push_back(arg
.c_str());
1897 if (name_list
.empty()) {
1898 result
.AppendMessage("No breakpoint names found.");
1900 for (const std::string
&name_str
: name_list
) {
1901 const char *name
= name_str
.c_str();
1902 // First print out the options for the name:
1904 BreakpointName
*bp_name
=
1905 target
.FindBreakpointName(ConstString(name
), false, error
);
1908 result
.AppendMessageWithFormat("Name: %s\n", name
);
1909 if (bp_name
->GetDescription(&s
, eDescriptionLevelFull
)) {
1910 result
.AppendMessage(s
.GetString());
1913 std::unique_lock
<std::recursive_mutex
> lock
;
1914 target
.GetBreakpointList().GetListMutex(lock
);
1916 BreakpointList
&breakpoints
= target
.GetBreakpointList();
1917 bool any_set
= false;
1918 for (BreakpointSP bp_sp
: breakpoints
.Breakpoints()) {
1919 if (bp_sp
->MatchesName(name
)) {
1922 bp_sp
->GetDescription(&s
, eDescriptionLevelBrief
);
1924 result
.AppendMessage(s
.GetString());
1928 result
.AppendMessage("No breakpoints using this name.");
1930 result
.AppendMessageWithFormat("Name: %s not found.\n", name
);
1938 BreakpointNameOptionGroup m_name_options
;
1939 OptionGroupOptions m_option_group
;
1942 // CommandObjectBreakpointName
1943 class CommandObjectBreakpointName
: public CommandObjectMultiword
{
1945 CommandObjectBreakpointName(CommandInterpreter
&interpreter
)
1946 : CommandObjectMultiword(
1947 interpreter
, "name", "Commands to manage name tags for breakpoints",
1948 "breakpoint name <subcommand> [<command-options>]") {
1949 CommandObjectSP
add_command_object(
1950 new CommandObjectBreakpointNameAdd(interpreter
));
1951 CommandObjectSP
delete_command_object(
1952 new CommandObjectBreakpointNameDelete(interpreter
));
1953 CommandObjectSP
list_command_object(
1954 new CommandObjectBreakpointNameList(interpreter
));
1955 CommandObjectSP
configure_command_object(
1956 new CommandObjectBreakpointNameConfigure(interpreter
));
1958 LoadSubCommand("add", add_command_object
);
1959 LoadSubCommand("delete", delete_command_object
);
1960 LoadSubCommand("list", list_command_object
);
1961 LoadSubCommand("configure", configure_command_object
);
1964 ~CommandObjectBreakpointName() override
= default;
1967 // CommandObjectBreakpointRead
1968 #pragma mark Read::CommandOptions
1969 #define LLDB_OPTIONS_breakpoint_read
1970 #include "CommandOptions.inc"
1974 class CommandObjectBreakpointRead
: public CommandObjectParsed
{
1976 CommandObjectBreakpointRead(CommandInterpreter
&interpreter
)
1977 : CommandObjectParsed(interpreter
, "breakpoint read",
1978 "Read and set the breakpoints previously saved to "
1979 "a file with \"breakpoint write\". ",
1982 CommandArgumentEntry arg
;
1983 CommandObject::AddIDsArgumentData(arg
, eArgTypeBreakpointID
,
1984 eArgTypeBreakpointIDRange
);
1985 // Add the entry for the first argument for this command to the object's
1986 // arguments vector.
1987 m_arguments
.push_back(arg
);
1990 ~CommandObjectBreakpointRead() override
= default;
1992 Options
*GetOptions() override
{ return &m_options
; }
1994 class CommandOptions
: public Options
{
1996 CommandOptions() : Options() {}
1998 ~CommandOptions() override
= default;
2000 Status
SetOptionValue(uint32_t option_idx
, llvm::StringRef option_arg
,
2001 ExecutionContext
*execution_context
) override
{
2003 const int short_option
= m_getopt_table
[option_idx
].val
;
2005 switch (short_option
) {
2007 m_filename
.assign(option_arg
);
2011 if (!BreakpointID::StringIsBreakpointName(llvm::StringRef(option_arg
),
2013 error
.SetErrorStringWithFormat("Invalid breakpoint name: %s",
2014 name_error
.AsCString());
2016 m_names
.push_back(option_arg
);
2020 llvm_unreachable("Unimplemented option");
2026 void OptionParsingStarting(ExecutionContext
*execution_context
) override
{
2031 llvm::ArrayRef
<OptionDefinition
> GetDefinitions() override
{
2032 return llvm::makeArrayRef(g_breakpoint_read_options
);
2035 // Instance variables to hold the values for command options.
2037 std::string m_filename
;
2038 std::vector
<std::string
> m_names
;
2042 bool DoExecute(Args
&command
, CommandReturnObject
&result
) override
{
2043 Target
&target
= GetSelectedOrDummyTarget();
2045 std::unique_lock
<std::recursive_mutex
> lock
;
2046 target
.GetBreakpointList().GetListMutex(lock
);
2048 FileSpec
input_spec(m_options
.m_filename
);
2049 FileSystem::Instance().Resolve(input_spec
);
2050 BreakpointIDList new_bps
;
2051 Status error
= target
.CreateBreakpointsFromFile(input_spec
,
2052 m_options
.m_names
, new_bps
);
2054 if (!error
.Success()) {
2055 result
.AppendError(error
.AsCString());
2056 result
.SetStatus(eReturnStatusFailed
);
2060 Stream
&output_stream
= result
.GetOutputStream();
2062 size_t num_breakpoints
= new_bps
.GetSize();
2063 if (num_breakpoints
== 0) {
2064 result
.AppendMessage("No breakpoints added.");
2066 // No breakpoint selected; show info about all currently set breakpoints.
2067 result
.AppendMessage("New breakpoints:");
2068 for (size_t i
= 0; i
< num_breakpoints
; ++i
) {
2069 BreakpointID bp_id
= new_bps
.GetBreakpointIDAtIndex(i
);
2070 Breakpoint
*bp
= target
.GetBreakpointList()
2071 .FindBreakpointByID(bp_id
.GetBreakpointID())
2074 bp
->GetDescription(&output_stream
, lldb::eDescriptionLevelInitial
,
2078 return result
.Succeeded();
2082 CommandOptions m_options
;
2085 // CommandObjectBreakpointWrite
2086 #pragma mark Write::CommandOptions
2087 #define LLDB_OPTIONS_breakpoint_write
2088 #include "CommandOptions.inc"
2091 class CommandObjectBreakpointWrite
: public CommandObjectParsed
{
2093 CommandObjectBreakpointWrite(CommandInterpreter
&interpreter
)
2094 : CommandObjectParsed(interpreter
, "breakpoint write",
2095 "Write the breakpoints listed to a file that can "
2096 "be read in with \"breakpoint read\". "
2097 "If given no arguments, writes all breakpoints.",
2100 CommandArgumentEntry arg
;
2101 CommandObject::AddIDsArgumentData(arg
, eArgTypeBreakpointID
,
2102 eArgTypeBreakpointIDRange
);
2103 // Add the entry for the first argument for this command to the object's
2104 // arguments vector.
2105 m_arguments
.push_back(arg
);
2108 ~CommandObjectBreakpointWrite() override
= default;
2110 Options
*GetOptions() override
{ return &m_options
; }
2112 class CommandOptions
: public Options
{
2114 CommandOptions() : Options() {}
2116 ~CommandOptions() override
= default;
2118 Status
SetOptionValue(uint32_t option_idx
, llvm::StringRef option_arg
,
2119 ExecutionContext
*execution_context
) override
{
2121 const int short_option
= m_getopt_table
[option_idx
].val
;
2123 switch (short_option
) {
2125 m_filename
.assign(option_arg
);
2131 llvm_unreachable("Unimplemented option");
2137 void OptionParsingStarting(ExecutionContext
*execution_context
) override
{
2142 llvm::ArrayRef
<OptionDefinition
> GetDefinitions() override
{
2143 return llvm::makeArrayRef(g_breakpoint_write_options
);
2146 // Instance variables to hold the values for command options.
2148 std::string m_filename
;
2149 bool m_append
= false;
2153 bool DoExecute(Args
&command
, CommandReturnObject
&result
) override
{
2154 Target
&target
= GetSelectedOrDummyTarget();
2156 std::unique_lock
<std::recursive_mutex
> lock
;
2157 target
.GetBreakpointList().GetListMutex(lock
);
2159 BreakpointIDList valid_bp_ids
;
2160 if (!command
.empty()) {
2161 CommandObjectMultiwordBreakpoint::VerifyBreakpointIDs(
2162 command
, &target
, result
, &valid_bp_ids
,
2163 BreakpointName::Permissions::PermissionKinds::listPerm
);
2165 if (!result
.Succeeded()) {
2166 result
.SetStatus(eReturnStatusFailed
);
2170 FileSpec
file_spec(m_options
.m_filename
);
2171 FileSystem::Instance().Resolve(file_spec
);
2172 Status error
= target
.SerializeBreakpointsToFile(file_spec
, valid_bp_ids
,
2173 m_options
.m_append
);
2174 if (!error
.Success()) {
2175 result
.AppendErrorWithFormat("error serializing breakpoints: %s.",
2177 result
.SetStatus(eReturnStatusFailed
);
2179 return result
.Succeeded();
2183 CommandOptions m_options
;
2186 // CommandObjectMultiwordBreakpoint
2187 #pragma mark MultiwordBreakpoint
2189 CommandObjectMultiwordBreakpoint::CommandObjectMultiwordBreakpoint(
2190 CommandInterpreter
&interpreter
)
2191 : CommandObjectMultiword(
2192 interpreter
, "breakpoint",
2193 "Commands for operating on breakpoints (see 'help b' for shorthand.)",
2194 "breakpoint <subcommand> [<command-options>]") {
2195 CommandObjectSP
list_command_object(
2196 new CommandObjectBreakpointList(interpreter
));
2197 CommandObjectSP
enable_command_object(
2198 new CommandObjectBreakpointEnable(interpreter
));
2199 CommandObjectSP
disable_command_object(
2200 new CommandObjectBreakpointDisable(interpreter
));
2201 CommandObjectSP
clear_command_object(
2202 new CommandObjectBreakpointClear(interpreter
));
2203 CommandObjectSP
delete_command_object(
2204 new CommandObjectBreakpointDelete(interpreter
));
2205 CommandObjectSP
set_command_object(
2206 new CommandObjectBreakpointSet(interpreter
));
2207 CommandObjectSP
command_command_object(
2208 new CommandObjectBreakpointCommand(interpreter
));
2209 CommandObjectSP
modify_command_object(
2210 new CommandObjectBreakpointModify(interpreter
));
2211 CommandObjectSP
name_command_object(
2212 new CommandObjectBreakpointName(interpreter
));
2213 CommandObjectSP
write_command_object(
2214 new CommandObjectBreakpointWrite(interpreter
));
2215 CommandObjectSP
read_command_object(
2216 new CommandObjectBreakpointRead(interpreter
));
2218 list_command_object
->SetCommandName("breakpoint list");
2219 enable_command_object
->SetCommandName("breakpoint enable");
2220 disable_command_object
->SetCommandName("breakpoint disable");
2221 clear_command_object
->SetCommandName("breakpoint clear");
2222 delete_command_object
->SetCommandName("breakpoint delete");
2223 set_command_object
->SetCommandName("breakpoint set");
2224 command_command_object
->SetCommandName("breakpoint command");
2225 modify_command_object
->SetCommandName("breakpoint modify");
2226 name_command_object
->SetCommandName("breakpoint name");
2227 write_command_object
->SetCommandName("breakpoint write");
2228 read_command_object
->SetCommandName("breakpoint read");
2230 LoadSubCommand("list", list_command_object
);
2231 LoadSubCommand("enable", enable_command_object
);
2232 LoadSubCommand("disable", disable_command_object
);
2233 LoadSubCommand("clear", clear_command_object
);
2234 LoadSubCommand("delete", delete_command_object
);
2235 LoadSubCommand("set", set_command_object
);
2236 LoadSubCommand("command", command_command_object
);
2237 LoadSubCommand("modify", modify_command_object
);
2238 LoadSubCommand("name", name_command_object
);
2239 LoadSubCommand("write", write_command_object
);
2240 LoadSubCommand("read", read_command_object
);
2243 CommandObjectMultiwordBreakpoint::~CommandObjectMultiwordBreakpoint() = default;
2245 void CommandObjectMultiwordBreakpoint::VerifyIDs(
2246 Args
&args
, Target
*target
, bool allow_locations
,
2247 CommandReturnObject
&result
, BreakpointIDList
*valid_ids
,
2248 BreakpointName::Permissions ::PermissionKinds purpose
) {
2249 // args can be strings representing 1). integers (for breakpoint ids)
2250 // 2). the full breakpoint & location
2251 // canonical representation
2252 // 3). the word "to" or a hyphen,
2253 // representing a range (in which case there
2254 // had *better* be an entry both before &
2255 // after of one of the first two types.
2256 // 4). A breakpoint name
2257 // If args is empty, we will use the last created breakpoint (if there is
2263 if (target
->GetLastCreatedBreakpoint()) {
2264 valid_ids
->AddBreakpointID(BreakpointID(
2265 target
->GetLastCreatedBreakpoint()->GetID(), LLDB_INVALID_BREAK_ID
));
2266 result
.SetStatus(eReturnStatusSuccessFinishNoResult
);
2269 "No breakpoint specified and no last created breakpoint.");
2270 result
.SetStatus(eReturnStatusFailed
);
2275 // Create a new Args variable to use; copy any non-breakpoint-id-ranges stuff
2276 // directly from the old ARGS to the new TEMP_ARGS. Do not copy breakpoint
2277 // id range strings over; instead generate a list of strings for all the
2278 // breakpoint ids in the range, and shove all of those breakpoint id strings
2281 BreakpointIDList::FindAndReplaceIDRanges(args
, target
, allow_locations
,
2282 purpose
, result
, temp_args
);
2284 // NOW, convert the list of breakpoint id strings in TEMP_ARGS into an actual
2285 // BreakpointIDList:
2287 valid_ids
->InsertStringArray(temp_args
.GetArgumentArrayRef(), result
);
2289 // At this point, all of the breakpoint ids that the user passed in have
2290 // been converted to breakpoint IDs and put into valid_ids.
2292 if (result
.Succeeded()) {
2293 // Now that we've converted everything from args into a list of breakpoint
2294 // ids, go through our tentative list of breakpoint id's and verify that
2295 // they correspond to valid/currently set breakpoints.
2297 const size_t count
= valid_ids
->GetSize();
2298 for (size_t i
= 0; i
< count
; ++i
) {
2299 BreakpointID cur_bp_id
= valid_ids
->GetBreakpointIDAtIndex(i
);
2300 Breakpoint
*breakpoint
=
2301 target
->GetBreakpointByID(cur_bp_id
.GetBreakpointID()).get();
2302 if (breakpoint
!= nullptr) {
2303 const size_t num_locations
= breakpoint
->GetNumLocations();
2304 if (static_cast<size_t>(cur_bp_id
.GetLocationID()) > num_locations
) {
2305 StreamString id_str
;
2306 BreakpointID::GetCanonicalReference(
2307 &id_str
, cur_bp_id
.GetBreakpointID(), cur_bp_id
.GetLocationID());
2308 i
= valid_ids
->GetSize() + 1;
2309 result
.AppendErrorWithFormat(
2310 "'%s' is not a currently valid breakpoint/location id.\n",
2312 result
.SetStatus(eReturnStatusFailed
);
2315 i
= valid_ids
->GetSize() + 1;
2316 result
.AppendErrorWithFormat(
2317 "'%d' is not a currently valid breakpoint ID.\n",
2318 cur_bp_id
.GetBreakpointID());
2319 result
.SetStatus(eReturnStatusFailed
);