1 //===-- CommandObjectBreakpoint.cpp ---------------------------------------===//
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/CommandOptionArgumentTable.h"
17 #include "lldb/Interpreter/CommandReturnObject.h"
18 #include "lldb/Interpreter/OptionArgParser.h"
19 #include "lldb/Interpreter/OptionGroupPythonClassWithDict.h"
20 #include "lldb/Interpreter/OptionValueBoolean.h"
21 #include "lldb/Interpreter/OptionValueFileColonLine.h"
22 #include "lldb/Interpreter/OptionValueString.h"
23 #include "lldb/Interpreter/OptionValueUInt64.h"
24 #include "lldb/Interpreter/Options.h"
25 #include "lldb/Target/Language.h"
26 #include "lldb/Target/StackFrame.h"
27 #include "lldb/Target/Target.h"
28 #include "lldb/Target/ThreadSpec.h"
29 #include "lldb/Utility/RegularExpression.h"
30 #include "lldb/Utility/StreamString.h"
37 using namespace lldb_private
;
39 static void AddBreakpointDescription(Stream
*s
, Breakpoint
*bp
,
40 lldb::DescriptionLevel level
) {
42 bp
->GetDescription(s
, level
, true);
47 // Modifiable Breakpoint Options
48 #pragma mark Modify::CommandOptions
49 #define LLDB_OPTIONS_breakpoint_modify
50 #include "CommandOptions.inc"
52 class lldb_private::BreakpointOptionGroup
: public OptionGroup
{
54 BreakpointOptionGroup() : m_bp_opts(false) {}
56 ~BreakpointOptionGroup() override
= default;
58 llvm::ArrayRef
<OptionDefinition
> GetDefinitions() override
{
59 return llvm::ArrayRef(g_breakpoint_modify_options
);
62 Status
SetOptionValue(uint32_t option_idx
, llvm::StringRef option_arg
,
63 ExecutionContext
*execution_context
) override
{
65 const int short_option
=
66 g_breakpoint_modify_options
[option_idx
].short_option
;
67 const char *long_option
=
68 g_breakpoint_modify_options
[option_idx
].long_option
;
70 switch (short_option
) {
72 // Normally an empty breakpoint condition marks is as unset. But we need
73 // to say it was passed in.
74 m_bp_opts
.SetCondition(option_arg
.str().c_str());
75 m_bp_opts
.m_set_flags
.Set(BreakpointOptions::eCondition
);
78 m_commands
.push_back(std::string(option_arg
));
81 m_bp_opts
.SetEnabled(false);
84 m_bp_opts
.SetEnabled(true);
88 value
= OptionArgParser::ToBoolean(option_arg
, false, &success
);
90 m_bp_opts
.SetAutoContinue(value
);
92 error
= Status::FromError(
93 CreateOptionParsingError(option_arg
, short_option
, long_option
,
94 g_bool_parsing_error_message
));
97 uint32_t ignore_count
;
98 if (option_arg
.getAsInteger(0, ignore_count
))
99 error
= Status::FromError(
100 CreateOptionParsingError(option_arg
, short_option
, long_option
,
101 g_int_parsing_error_message
));
103 m_bp_opts
.SetIgnoreCount(ignore_count
);
107 value
= OptionArgParser::ToBoolean(option_arg
, false, &success
);
109 m_bp_opts
.SetOneShot(value
);
111 error
= Status::FromError(
112 CreateOptionParsingError(option_arg
, short_option
, long_option
,
113 g_bool_parsing_error_message
));
116 lldb::tid_t thread_id
= LLDB_INVALID_THREAD_ID
;
117 if (option_arg
== "current") {
118 if (!execution_context
) {
119 error
= Status::FromError(CreateOptionParsingError(
120 option_arg
, short_option
, long_option
,
121 "No context to determine current thread"));
123 ThreadSP ctx_thread_sp
= execution_context
->GetThreadSP();
124 if (!ctx_thread_sp
|| !ctx_thread_sp
->IsValid()) {
125 error
= Status::FromError(
126 CreateOptionParsingError(option_arg
, short_option
, long_option
,
127 "No currently selected thread"));
129 thread_id
= ctx_thread_sp
->GetID();
132 } else if (option_arg
.getAsInteger(0, thread_id
)) {
133 error
= Status::FromError(
134 CreateOptionParsingError(option_arg
, short_option
, long_option
,
135 g_int_parsing_error_message
));
137 if (thread_id
!= LLDB_INVALID_THREAD_ID
)
138 m_bp_opts
.SetThreadID(thread_id
);
141 m_bp_opts
.GetThreadSpec()->SetName(option_arg
.str().c_str());
144 m_bp_opts
.GetThreadSpec()->SetQueueName(option_arg
.str().c_str());
147 uint32_t thread_index
= UINT32_MAX
;
148 if (option_arg
.getAsInteger(0, thread_index
)) {
149 error
= Status::FromError(
150 CreateOptionParsingError(option_arg
, short_option
, long_option
,
151 g_int_parsing_error_message
));
153 m_bp_opts
.GetThreadSpec()->SetIndex(thread_index
);
157 llvm_unreachable("Unimplemented option");
163 void OptionParsingStarting(ExecutionContext
*execution_context
) override
{
168 Status
OptionParsingFinished(ExecutionContext
*execution_context
) override
{
169 if (!m_commands
.empty()) {
170 auto cmd_data
= std::make_unique
<BreakpointOptions::CommandData
>();
172 for (std::string
&str
: m_commands
)
173 cmd_data
->user_source
.AppendString(str
);
175 cmd_data
->stop_on_error
= true;
176 m_bp_opts
.SetCommandDataCallback(cmd_data
);
181 const BreakpointOptions
&GetBreakpointOptions() { return m_bp_opts
; }
183 std::vector
<std::string
> m_commands
;
184 BreakpointOptions m_bp_opts
;
187 #define LLDB_OPTIONS_breakpoint_dummy
188 #include "CommandOptions.inc"
190 class BreakpointDummyOptionGroup
: public OptionGroup
{
192 BreakpointDummyOptionGroup() = default;
194 ~BreakpointDummyOptionGroup() override
= default;
196 llvm::ArrayRef
<OptionDefinition
> GetDefinitions() override
{
197 return llvm::ArrayRef(g_breakpoint_dummy_options
);
200 Status
SetOptionValue(uint32_t option_idx
, llvm::StringRef option_arg
,
201 ExecutionContext
*execution_context
) override
{
203 const int short_option
=
204 g_breakpoint_dummy_options
[option_idx
].short_option
;
206 switch (short_option
) {
211 llvm_unreachable("Unimplemented option");
217 void OptionParsingStarting(ExecutionContext
*execution_context
) override
{
224 #define LLDB_OPTIONS_breakpoint_set
225 #include "CommandOptions.inc"
227 // CommandObjectBreakpointSet
229 class CommandObjectBreakpointSet
: public CommandObjectParsed
{
231 enum BreakpointSetType
{
235 eSetTypeFunctionName
,
236 eSetTypeFunctionRegexp
,
237 eSetTypeSourceRegexp
,
242 CommandObjectBreakpointSet(CommandInterpreter
&interpreter
)
243 : CommandObjectParsed(
244 interpreter
, "breakpoint set",
245 "Sets a breakpoint or set of breakpoints in the executable.",
246 "breakpoint set <cmd-options>"),
247 m_python_class_options("scripted breakpoint", true, 'P') {
248 // We're picking up all the normal options, commands and disable.
249 m_all_options
.Append(&m_python_class_options
,
250 LLDB_OPT_SET_1
| LLDB_OPT_SET_2
, LLDB_OPT_SET_11
);
251 m_all_options
.Append(&m_bp_opts
,
252 LLDB_OPT_SET_1
| LLDB_OPT_SET_3
| LLDB_OPT_SET_4
,
254 m_all_options
.Append(&m_dummy_options
, LLDB_OPT_SET_1
, LLDB_OPT_SET_ALL
);
255 m_all_options
.Append(&m_options
);
256 m_all_options
.Finalize();
259 ~CommandObjectBreakpointSet() override
= default;
261 Options
*GetOptions() override
{ return &m_all_options
; }
263 class CommandOptions
: public OptionGroup
{
265 CommandOptions() = default;
267 ~CommandOptions() override
= default;
269 Status
SetOptionValue(uint32_t option_idx
, llvm::StringRef option_arg
,
270 ExecutionContext
*execution_context
) override
{
272 const int short_option
=
273 g_breakpoint_set_options
[option_idx
].short_option
;
274 const char *long_option
=
275 g_breakpoint_set_options
[option_idx
].long_option
;
277 switch (short_option
) {
279 m_load_addr
= OptionArgParser::ToAddress(execution_context
, option_arg
,
280 LLDB_INVALID_ADDRESS
, &error
);
288 m_func_names
.push_back(std::string(option_arg
));
289 m_func_name_type_mask
|= eFunctionNameTypeBase
;
293 if (option_arg
.getAsInteger(0, m_column
))
294 error
= Status::FromError(
295 CreateOptionParsingError(option_arg
, short_option
, long_option
,
296 g_int_parsing_error_message
));
300 LanguageType language
= Language::GetLanguageTypeFromString(option_arg
);
302 llvm::StringRef error_context
;
304 case eLanguageTypeC89
:
306 case eLanguageTypeC99
:
307 case eLanguageTypeC11
:
308 m_exception_language
= eLanguageTypeC
;
310 case eLanguageTypeC_plus_plus
:
311 case eLanguageTypeC_plus_plus_03
:
312 case eLanguageTypeC_plus_plus_11
:
313 case eLanguageTypeC_plus_plus_14
:
314 m_exception_language
= eLanguageTypeC_plus_plus
;
316 case eLanguageTypeObjC_plus_plus
:
318 "Set exception breakpoints separately for c++ and objective-c";
320 case eLanguageTypeUnknown
:
321 error_context
= "Unknown language type for exception breakpoint";
324 if (Language
*languagePlugin
= Language::FindPlugin(language
)) {
325 if (languagePlugin
->SupportsExceptionBreakpointsOnThrow() ||
326 languagePlugin
->SupportsExceptionBreakpointsOnCatch()) {
327 m_exception_language
= language
;
331 error_context
= "Unsupported language type for exception breakpoint";
333 if (!error_context
.empty())
334 error
= Status::FromError(CreateOptionParsingError(
335 option_arg
, short_option
, long_option
, error_context
));
339 m_filenames
.AppendIfUnique(FileSpec(option_arg
));
343 m_func_names
.push_back(std::string(option_arg
));
344 m_func_name_type_mask
|= eFunctionNameTypeFull
;
349 m_catch_bp
= OptionArgParser::ToBoolean(option_arg
, true, &success
);
351 error
= Status::FromError(
352 CreateOptionParsingError(option_arg
, short_option
, long_option
,
353 g_bool_parsing_error_message
));
363 value
= OptionArgParser::ToBoolean(option_arg
, true, &success
);
365 m_skip_prologue
= eLazyBoolYes
;
367 m_skip_prologue
= eLazyBoolNo
;
370 error
= Status::FromError(
371 CreateOptionParsingError(option_arg
, short_option
, long_option
,
372 g_bool_parsing_error_message
));
376 if (option_arg
.getAsInteger(0, m_line_num
))
377 error
= Status::FromError(
378 CreateOptionParsingError(option_arg
, short_option
, long_option
,
379 g_int_parsing_error_message
));
383 m_language
= Language::GetLanguageTypeFromString(option_arg
);
384 if (m_language
== eLanguageTypeUnknown
)
385 error
= Status::FromError(
386 CreateOptionParsingError(option_arg
, short_option
, long_option
,
387 g_language_parsing_error_message
));
393 value
= OptionArgParser::ToBoolean(option_arg
, true, &success
);
395 m_move_to_nearest_code
= eLazyBoolYes
;
397 m_move_to_nearest_code
= eLazyBoolNo
;
400 error
= Status::FromError(
401 CreateOptionParsingError(option_arg
, short_option
, long_option
,
402 g_bool_parsing_error_message
));
407 m_func_names
.push_back(std::string(option_arg
));
408 m_func_name_type_mask
|= eFunctionNameTypeMethod
;
412 m_func_names
.push_back(std::string(option_arg
));
413 m_func_name_type_mask
|= eFunctionNameTypeAuto
;
417 if (BreakpointID::StringIsBreakpointName(option_arg
, error
))
418 m_breakpoint_names
.push_back(std::string(option_arg
));
420 error
= Status::FromError(
421 CreateOptionParsingError(option_arg
, short_option
, long_option
,
422 "Invalid breakpoint name"));
427 lldb::addr_t tmp_offset_addr
;
428 tmp_offset_addr
= OptionArgParser::ToAddress(execution_context
,
429 option_arg
, 0, &error
);
431 m_offset_addr
= tmp_offset_addr
;
435 m_exception_extra_args
.AppendArgument("-O");
436 m_exception_extra_args
.AppendArgument(option_arg
);
440 m_source_text_regexp
.assign(std::string(option_arg
));
444 m_func_regexp
.assign(std::string(option_arg
));
448 m_modules
.AppendIfUnique(FileSpec(option_arg
));
452 m_func_names
.push_back(std::string(option_arg
));
453 m_func_name_type_mask
|= eFunctionNameTypeSelector
;
458 m_throw_bp
= OptionArgParser::ToBoolean(option_arg
, true, &success
);
460 error
= Status::FromError(
461 CreateOptionParsingError(option_arg
, short_option
, long_option
,
462 g_bool_parsing_error_message
));
466 m_source_regex_func_names
.insert(std::string(option_arg
));
471 OptionValueFileColonLine value
;
472 Status fcl_err
= value
.SetValueFromString(option_arg
);
473 if (!fcl_err
.Success()) {
474 error
= Status::FromError(CreateOptionParsingError(
475 option_arg
, short_option
, long_option
, fcl_err
.AsCString()));
477 m_filenames
.AppendIfUnique(value
.GetFileSpec());
478 m_line_num
= value
.GetLineNumber();
479 m_column
= value
.GetColumnNumber();
484 llvm_unreachable("Unimplemented option");
490 void OptionParsingStarting(ExecutionContext
*execution_context
) override
{
494 m_func_names
.clear();
495 m_func_name_type_mask
= eFunctionNameTypeNone
;
496 m_func_regexp
.clear();
497 m_source_text_regexp
.clear();
499 m_load_addr
= LLDB_INVALID_ADDRESS
;
504 m_exception_language
= eLanguageTypeUnknown
;
505 m_language
= lldb::eLanguageTypeUnknown
;
506 m_skip_prologue
= eLazyBoolCalculate
;
507 m_breakpoint_names
.clear();
509 m_exception_extra_args
.Clear();
510 m_move_to_nearest_code
= eLazyBoolCalculate
;
511 m_source_regex_func_names
.clear();
512 m_current_key
.clear();
515 llvm::ArrayRef
<OptionDefinition
> GetDefinitions() override
{
516 return llvm::ArrayRef(g_breakpoint_set_options
);
519 // Instance variables to hold the values for command options.
521 std::string m_condition
;
522 FileSpecList m_filenames
;
523 uint32_t m_line_num
= 0;
524 uint32_t m_column
= 0;
525 std::vector
<std::string
> m_func_names
;
526 std::vector
<std::string
> m_breakpoint_names
;
527 lldb::FunctionNameType m_func_name_type_mask
= eFunctionNameTypeNone
;
528 std::string m_func_regexp
;
529 std::string m_source_text_regexp
;
530 FileSpecList m_modules
;
531 lldb::addr_t m_load_addr
= 0;
532 lldb::addr_t m_offset_addr
;
533 bool m_catch_bp
= false;
534 bool m_throw_bp
= true;
535 bool m_hardware
= false; // Request to use hardware breakpoints
536 lldb::LanguageType m_exception_language
= eLanguageTypeUnknown
;
537 lldb::LanguageType m_language
= lldb::eLanguageTypeUnknown
;
538 LazyBool m_skip_prologue
= eLazyBoolCalculate
;
539 bool m_all_files
= false;
540 Args m_exception_extra_args
;
541 LazyBool m_move_to_nearest_code
= eLazyBoolCalculate
;
542 std::unordered_set
<std::string
> m_source_regex_func_names
;
543 std::string m_current_key
;
547 void DoExecute(Args
&command
, CommandReturnObject
&result
) override
{
549 m_dummy_options
.m_use_dummy
? GetDummyTarget() : GetTarget();
551 // The following are the various types of breakpoints that could be set:
552 // 1). -f -l -p [-s -g] (setting breakpoint by source location)
553 // 2). -a [-s -g] (setting breakpoint by address)
554 // 3). -n [-s -g] (setting breakpoint by function name)
555 // 4). -r [-s -g] (setting breakpoint by function name regular
557 // 5). -p -f (setting a breakpoint by comparing a reg-exp
559 // 6). -E [-w -h] (setting a breakpoint for exceptions for a
562 BreakpointSetType break_type
= eSetTypeInvalid
;
564 if (!m_python_class_options
.GetName().empty())
565 break_type
= eSetTypeScripted
;
566 else if (m_options
.m_line_num
!= 0)
567 break_type
= eSetTypeFileAndLine
;
568 else if (m_options
.m_load_addr
!= LLDB_INVALID_ADDRESS
)
569 break_type
= eSetTypeAddress
;
570 else if (!m_options
.m_func_names
.empty())
571 break_type
= eSetTypeFunctionName
;
572 else if (!m_options
.m_func_regexp
.empty())
573 break_type
= eSetTypeFunctionRegexp
;
574 else if (!m_options
.m_source_text_regexp
.empty())
575 break_type
= eSetTypeSourceRegexp
;
576 else if (m_options
.m_exception_language
!= eLanguageTypeUnknown
)
577 break_type
= eSetTypeException
;
579 BreakpointSP bp_sp
= nullptr;
580 FileSpec module_spec
;
581 const bool internal
= false;
583 // If the user didn't specify skip-prologue, having an offset should turn
585 if (m_options
.m_offset_addr
!= 0 &&
586 m_options
.m_skip_prologue
== eLazyBoolCalculate
)
587 m_options
.m_skip_prologue
= eLazyBoolNo
;
589 switch (break_type
) {
590 case eSetTypeFileAndLine
: // Breakpoint by source position
593 const size_t num_files
= m_options
.m_filenames
.GetSize();
594 if (num_files
== 0) {
595 if (!GetDefaultFile(target
, file
, result
)) {
596 result
.AppendError("No file supplied and no default file available.");
599 } else if (num_files
> 1) {
600 result
.AppendError("Only one file at a time is allowed for file and "
601 "line breakpoints.");
604 file
= m_options
.m_filenames
.GetFileSpecAtIndex(0);
606 // Only check for inline functions if
607 LazyBool check_inlines
= eLazyBoolCalculate
;
609 bp_sp
= target
.CreateBreakpoint(
610 &(m_options
.m_modules
), file
, m_options
.m_line_num
,
611 m_options
.m_column
, m_options
.m_offset_addr
, check_inlines
,
612 m_options
.m_skip_prologue
, internal
, m_options
.m_hardware
,
613 m_options
.m_move_to_nearest_code
);
616 case eSetTypeAddress
: // Breakpoint by address
618 // If a shared library has been specified, make an lldb_private::Address
619 // with the library, and use that. That way the address breakpoint
620 // will track the load location of the library.
621 size_t num_modules_specified
= m_options
.m_modules
.GetSize();
622 if (num_modules_specified
== 1) {
623 const FileSpec
&file_spec
=
624 m_options
.m_modules
.GetFileSpecAtIndex(0);
625 bp_sp
= target
.CreateAddressInModuleBreakpoint(
626 m_options
.m_load_addr
, internal
, file_spec
, m_options
.m_hardware
);
627 } else if (num_modules_specified
== 0) {
628 bp_sp
= target
.CreateBreakpoint(m_options
.m_load_addr
, internal
,
629 m_options
.m_hardware
);
631 result
.AppendError("Only one shared library can be specified for "
632 "address breakpoints.");
637 case eSetTypeFunctionName
: // Breakpoint by function name
639 FunctionNameType name_type_mask
= m_options
.m_func_name_type_mask
;
641 if (name_type_mask
== 0)
642 name_type_mask
= eFunctionNameTypeAuto
;
644 bp_sp
= target
.CreateBreakpoint(
645 &(m_options
.m_modules
), &(m_options
.m_filenames
),
646 m_options
.m_func_names
, name_type_mask
, m_options
.m_language
,
647 m_options
.m_offset_addr
, m_options
.m_skip_prologue
, internal
,
648 m_options
.m_hardware
);
651 case eSetTypeFunctionRegexp
: // Breakpoint by regular expression function
654 RegularExpression
regexp(m_options
.m_func_regexp
);
655 if (llvm::Error err
= regexp
.GetError()) {
656 result
.AppendErrorWithFormat(
657 "Function name regular expression could not be compiled: %s",
658 llvm::toString(std::move(err
)).c_str());
659 // Check if the incorrect regex looks like a globbing expression and
660 // warn the user about it.
661 if (!m_options
.m_func_regexp
.empty()) {
662 if (m_options
.m_func_regexp
[0] == '*' ||
663 m_options
.m_func_regexp
[0] == '?')
664 result
.AppendWarning(
665 "Function name regex does not accept glob patterns.");
670 bp_sp
= target
.CreateFuncRegexBreakpoint(
671 &(m_options
.m_modules
), &(m_options
.m_filenames
), std::move(regexp
),
672 m_options
.m_language
, m_options
.m_skip_prologue
, internal
,
673 m_options
.m_hardware
);
675 case eSetTypeSourceRegexp
: // Breakpoint by regexp on source text.
677 const size_t num_files
= m_options
.m_filenames
.GetSize();
679 if (num_files
== 0 && !m_options
.m_all_files
) {
681 if (!GetDefaultFile(target
, file
, result
)) {
683 "No files provided and could not find default file.");
686 m_options
.m_filenames
.Append(file
);
690 RegularExpression
regexp(m_options
.m_source_text_regexp
);
691 if (llvm::Error err
= regexp
.GetError()) {
692 result
.AppendErrorWithFormat(
693 "Source text regular expression could not be compiled: \"%s\"",
694 llvm::toString(std::move(err
)).c_str());
697 bp_sp
= target
.CreateSourceRegexBreakpoint(
698 &(m_options
.m_modules
), &(m_options
.m_filenames
),
699 m_options
.m_source_regex_func_names
, std::move(regexp
), internal
,
700 m_options
.m_hardware
, m_options
.m_move_to_nearest_code
);
702 case eSetTypeException
: {
703 Status precond_error
;
704 bp_sp
= target
.CreateExceptionBreakpoint(
705 m_options
.m_exception_language
, m_options
.m_catch_bp
,
706 m_options
.m_throw_bp
, internal
, &m_options
.m_exception_extra_args
,
708 if (precond_error
.Fail()) {
709 result
.AppendErrorWithFormat(
710 "Error setting extra exception arguments: %s",
711 precond_error
.AsCString());
712 target
.RemoveBreakpointByID(bp_sp
->GetID());
716 case eSetTypeScripted
: {
719 bp_sp
= target
.CreateScriptedBreakpoint(
720 m_python_class_options
.GetName().c_str(), &(m_options
.m_modules
),
721 &(m_options
.m_filenames
), false, m_options
.m_hardware
,
722 m_python_class_options
.GetStructuredData(), &error
);
724 result
.AppendErrorWithFormat(
725 "Error setting extra exception arguments: %s", error
.AsCString());
726 target
.RemoveBreakpointByID(bp_sp
->GetID());
734 // Now set the various options that were passed in:
736 bp_sp
->GetOptions().CopyOverSetOptions(m_bp_opts
.GetBreakpointOptions());
738 if (!m_options
.m_breakpoint_names
.empty()) {
740 for (auto name
: m_options
.m_breakpoint_names
) {
741 target
.AddNameToBreakpoint(bp_sp
, name
.c_str(), name_error
);
742 if (name_error
.Fail()) {
743 result
.AppendErrorWithFormat("Invalid breakpoint name: %s",
745 target
.RemoveBreakpointByID(bp_sp
->GetID());
753 Stream
&output_stream
= result
.GetOutputStream();
754 const bool show_locations
= false;
755 bp_sp
->GetDescription(&output_stream
, lldb::eDescriptionLevelInitial
,
757 if (&target
== &GetDummyTarget())
758 output_stream
.Printf("Breakpoint set in dummy target, will get copied "
759 "into future targets.\n");
761 // Don't print out this warning for exception breakpoints. They can
762 // get set before the target is set, but we won't know how to actually
763 // set the breakpoint till we run.
764 if (bp_sp
->GetNumLocations() == 0 && break_type
!= eSetTypeException
) {
765 output_stream
.Printf("WARNING: Unable to resolve breakpoint to any "
766 "actual locations.\n");
769 result
.SetStatus(eReturnStatusSuccessFinishResult
);
771 result
.AppendError("Breakpoint creation failed: No breakpoint created.");
776 bool GetDefaultFile(Target
&target
, FileSpec
&file
,
777 CommandReturnObject
&result
) {
778 // First use the Source Manager's default file. Then use the current stack
780 if (auto maybe_file_and_line
=
781 target
.GetSourceManager().GetDefaultFileAndLine()) {
782 file
= maybe_file_and_line
->support_file_sp
->GetSpecOnly();
786 StackFrame
*cur_frame
= m_exe_ctx
.GetFramePtr();
787 if (cur_frame
== nullptr) {
789 "No selected frame to use to find the default file.");
792 if (!cur_frame
->HasDebugInformation()) {
793 result
.AppendError("Cannot use the selected frame to find the default "
794 "file, it has no debug info.");
798 const SymbolContext
&sc
=
799 cur_frame
->GetSymbolContext(eSymbolContextLineEntry
);
800 if (sc
.line_entry
.GetFile()) {
801 file
= sc
.line_entry
.GetFile();
803 result
.AppendError("Can't find the file for the selected frame to "
804 "use as the default file.");
810 BreakpointOptionGroup m_bp_opts
;
811 BreakpointDummyOptionGroup m_dummy_options
;
812 OptionGroupPythonClassWithDict m_python_class_options
;
813 CommandOptions m_options
;
814 OptionGroupOptions m_all_options
;
817 // CommandObjectBreakpointModify
820 class CommandObjectBreakpointModify
: public CommandObjectParsed
{
822 CommandObjectBreakpointModify(CommandInterpreter
&interpreter
)
823 : CommandObjectParsed(interpreter
, "breakpoint modify",
824 "Modify the options on a breakpoint or set of "
825 "breakpoints in the executable. "
826 "If no breakpoint is specified, acts on the last "
827 "created breakpoint. "
828 "With the exception of -e, -d and -i, passing an "
829 "empty argument clears the modification.",
831 CommandObject::AddIDsArgumentData(eBreakpointArgs
);
833 m_options
.Append(&m_bp_opts
,
834 LLDB_OPT_SET_1
| LLDB_OPT_SET_2
| LLDB_OPT_SET_3
,
836 m_options
.Append(&m_dummy_opts
, LLDB_OPT_SET_1
, LLDB_OPT_SET_ALL
);
837 m_options
.Finalize();
840 ~CommandObjectBreakpointModify() override
= default;
843 HandleArgumentCompletion(CompletionRequest
&request
,
844 OptionElementVector
&opt_element_vector
) override
{
845 lldb_private::CommandCompletions::InvokeCommonCompletionCallbacks(
846 GetCommandInterpreter(), lldb::eBreakpointCompletion
, request
, nullptr);
849 Options
*GetOptions() override
{ return &m_options
; }
852 void DoExecute(Args
&command
, CommandReturnObject
&result
) override
{
853 Target
&target
= m_dummy_opts
.m_use_dummy
? GetDummyTarget() : GetTarget();
855 std::unique_lock
<std::recursive_mutex
> lock
;
856 target
.GetBreakpointList().GetListMutex(lock
);
858 BreakpointIDList valid_bp_ids
;
860 CommandObjectMultiwordBreakpoint::VerifyBreakpointOrLocationIDs(
861 command
, target
, result
, &valid_bp_ids
,
862 BreakpointName::Permissions::PermissionKinds::disablePerm
);
864 if (result
.Succeeded()) {
865 const size_t count
= valid_bp_ids
.GetSize();
866 for (size_t i
= 0; i
< count
; ++i
) {
867 BreakpointID cur_bp_id
= valid_bp_ids
.GetBreakpointIDAtIndex(i
);
869 if (cur_bp_id
.GetBreakpointID() != LLDB_INVALID_BREAK_ID
) {
871 target
.GetBreakpointByID(cur_bp_id
.GetBreakpointID()).get();
872 if (cur_bp_id
.GetLocationID() != LLDB_INVALID_BREAK_ID
) {
873 BreakpointLocation
*location
=
874 bp
->FindLocationByID(cur_bp_id
.GetLocationID()).get();
876 location
->GetLocationOptions().CopyOverSetOptions(
877 m_bp_opts
.GetBreakpointOptions());
879 bp
->GetOptions().CopyOverSetOptions(
880 m_bp_opts
.GetBreakpointOptions());
888 BreakpointOptionGroup m_bp_opts
;
889 BreakpointDummyOptionGroup m_dummy_opts
;
890 OptionGroupOptions m_options
;
893 // CommandObjectBreakpointEnable
896 class CommandObjectBreakpointEnable
: public CommandObjectParsed
{
898 CommandObjectBreakpointEnable(CommandInterpreter
&interpreter
)
899 : CommandObjectParsed(interpreter
, "enable",
900 "Enable the specified disabled breakpoint(s). If "
901 "no breakpoints are specified, enable all of them.",
903 CommandObject::AddIDsArgumentData(eBreakpointArgs
);
906 ~CommandObjectBreakpointEnable() override
= default;
909 HandleArgumentCompletion(CompletionRequest
&request
,
910 OptionElementVector
&opt_element_vector
) override
{
911 lldb_private::CommandCompletions::InvokeCommonCompletionCallbacks(
912 GetCommandInterpreter(), lldb::eBreakpointCompletion
, request
, nullptr);
916 void DoExecute(Args
&command
, CommandReturnObject
&result
) override
{
917 Target
&target
= GetTarget();
919 std::unique_lock
<std::recursive_mutex
> lock
;
920 target
.GetBreakpointList().GetListMutex(lock
);
922 const BreakpointList
&breakpoints
= target
.GetBreakpointList();
924 size_t num_breakpoints
= breakpoints
.GetSize();
926 if (num_breakpoints
== 0) {
927 result
.AppendError("No breakpoints exist to be enabled.");
931 if (command
.empty()) {
932 // No breakpoint selected; enable all currently set breakpoints.
933 target
.EnableAllowedBreakpoints();
934 result
.AppendMessageWithFormat("All breakpoints enabled. (%" PRIu64
936 (uint64_t)num_breakpoints
);
937 result
.SetStatus(eReturnStatusSuccessFinishNoResult
);
939 // Particular breakpoint selected; enable that breakpoint.
940 BreakpointIDList valid_bp_ids
;
941 CommandObjectMultiwordBreakpoint::VerifyBreakpointOrLocationIDs(
942 command
, target
, result
, &valid_bp_ids
,
943 BreakpointName::Permissions::PermissionKinds::disablePerm
);
945 if (result
.Succeeded()) {
946 int enable_count
= 0;
948 const size_t count
= valid_bp_ids
.GetSize();
949 for (size_t i
= 0; i
< count
; ++i
) {
950 BreakpointID cur_bp_id
= valid_bp_ids
.GetBreakpointIDAtIndex(i
);
952 if (cur_bp_id
.GetBreakpointID() != LLDB_INVALID_BREAK_ID
) {
953 Breakpoint
*breakpoint
=
954 target
.GetBreakpointByID(cur_bp_id
.GetBreakpointID()).get();
955 if (cur_bp_id
.GetLocationID() != LLDB_INVALID_BREAK_ID
) {
956 BreakpointLocation
*location
=
957 breakpoint
->FindLocationByID(cur_bp_id
.GetLocationID()).get();
959 location
->SetEnabled(true);
963 breakpoint
->SetEnabled(true);
968 result
.AppendMessageWithFormat("%d breakpoints enabled.\n",
969 enable_count
+ loc_count
);
970 result
.SetStatus(eReturnStatusSuccessFinishNoResult
);
976 // CommandObjectBreakpointDisable
979 class CommandObjectBreakpointDisable
: public CommandObjectParsed
{
981 CommandObjectBreakpointDisable(CommandInterpreter
&interpreter
)
982 : CommandObjectParsed(
983 interpreter
, "breakpoint disable",
984 "Disable the specified breakpoint(s) without deleting "
985 "them. If none are specified, disable all "
989 "Disable the specified breakpoint(s) without deleting them. \
990 If none are specified, disable all breakpoints."
994 "Note: disabling a breakpoint will cause none of its locations to be hit \
995 regardless of whether individual locations are enabled or disabled. After the sequence:"
998 (lldb) break disable 1
999 (lldb) break enable 1.1
1001 execution will NOT stop at location 1.1. To achieve that, type:
1003 (lldb) break disable 1.*
1004 (lldb) break enable 1.1
1007 "The first command disables all locations for breakpoint 1, \
1008 the second re-enables the first location.");
1010 CommandObject::AddIDsArgumentData(eBreakpointArgs
);
1013 ~CommandObjectBreakpointDisable() override
= default;
1016 HandleArgumentCompletion(CompletionRequest
&request
,
1017 OptionElementVector
&opt_element_vector
) override
{
1018 lldb_private::CommandCompletions::InvokeCommonCompletionCallbacks(
1019 GetCommandInterpreter(), lldb::eBreakpointCompletion
, request
, nullptr);
1023 void DoExecute(Args
&command
, CommandReturnObject
&result
) override
{
1024 Target
&target
= GetTarget();
1025 std::unique_lock
<std::recursive_mutex
> lock
;
1026 target
.GetBreakpointList().GetListMutex(lock
);
1028 const BreakpointList
&breakpoints
= target
.GetBreakpointList();
1029 size_t num_breakpoints
= breakpoints
.GetSize();
1031 if (num_breakpoints
== 0) {
1032 result
.AppendError("No breakpoints exist to be disabled.");
1036 if (command
.empty()) {
1037 // No breakpoint selected; disable all currently set breakpoints.
1038 target
.DisableAllowedBreakpoints();
1039 result
.AppendMessageWithFormat("All breakpoints disabled. (%" PRIu64
1041 (uint64_t)num_breakpoints
);
1042 result
.SetStatus(eReturnStatusSuccessFinishNoResult
);
1044 // Particular breakpoint selected; disable that breakpoint.
1045 BreakpointIDList valid_bp_ids
;
1047 CommandObjectMultiwordBreakpoint::VerifyBreakpointOrLocationIDs(
1048 command
, target
, result
, &valid_bp_ids
,
1049 BreakpointName::Permissions::PermissionKinds::disablePerm
);
1051 if (result
.Succeeded()) {
1052 int disable_count
= 0;
1054 const size_t count
= valid_bp_ids
.GetSize();
1055 for (size_t i
= 0; i
< count
; ++i
) {
1056 BreakpointID cur_bp_id
= valid_bp_ids
.GetBreakpointIDAtIndex(i
);
1058 if (cur_bp_id
.GetBreakpointID() != LLDB_INVALID_BREAK_ID
) {
1059 Breakpoint
*breakpoint
=
1060 target
.GetBreakpointByID(cur_bp_id
.GetBreakpointID()).get();
1061 if (cur_bp_id
.GetLocationID() != LLDB_INVALID_BREAK_ID
) {
1062 BreakpointLocation
*location
=
1063 breakpoint
->FindLocationByID(cur_bp_id
.GetLocationID()).get();
1065 location
->SetEnabled(false);
1069 breakpoint
->SetEnabled(false);
1074 result
.AppendMessageWithFormat("%d breakpoints disabled.\n",
1075 disable_count
+ loc_count
);
1076 result
.SetStatus(eReturnStatusSuccessFinishNoResult
);
1082 // CommandObjectBreakpointList
1084 #pragma mark List::CommandOptions
1085 #define LLDB_OPTIONS_breakpoint_list
1086 #include "CommandOptions.inc"
1090 class CommandObjectBreakpointList
: public CommandObjectParsed
{
1092 CommandObjectBreakpointList(CommandInterpreter
&interpreter
)
1093 : CommandObjectParsed(
1094 interpreter
, "breakpoint list",
1095 "List some or all breakpoints at configurable levels of detail.",
1097 CommandArgumentEntry arg
;
1098 CommandArgumentData bp_id_arg
;
1100 // Define the first (and only) variant of this arg.
1101 AddSimpleArgumentList(eArgTypeBreakpointID
, eArgRepeatOptional
);
1104 ~CommandObjectBreakpointList() override
= default;
1106 Options
*GetOptions() override
{ return &m_options
; }
1108 class CommandOptions
: public Options
{
1110 CommandOptions() = default;
1112 ~CommandOptions() override
= default;
1114 Status
SetOptionValue(uint32_t option_idx
, llvm::StringRef option_arg
,
1115 ExecutionContext
*execution_context
) override
{
1117 const int short_option
= m_getopt_table
[option_idx
].val
;
1119 switch (short_option
) {
1121 m_level
= lldb::eDescriptionLevelBrief
;
1127 m_level
= lldb::eDescriptionLevelFull
;
1130 m_level
= lldb::eDescriptionLevelVerbose
;
1136 llvm_unreachable("Unimplemented option");
1142 void OptionParsingStarting(ExecutionContext
*execution_context
) override
{
1143 m_level
= lldb::eDescriptionLevelFull
;
1145 m_use_dummy
= false;
1148 llvm::ArrayRef
<OptionDefinition
> GetDefinitions() override
{
1149 return llvm::ArrayRef(g_breakpoint_list_options
);
1152 // Instance variables to hold the values for command options.
1154 lldb::DescriptionLevel m_level
= lldb::eDescriptionLevelBrief
;
1157 bool m_use_dummy
= false;
1161 void DoExecute(Args
&command
, CommandReturnObject
&result
) override
{
1162 Target
&target
= m_options
.m_use_dummy
? GetDummyTarget() : GetTarget();
1164 const BreakpointList
&breakpoints
=
1165 target
.GetBreakpointList(m_options
.m_internal
);
1166 std::unique_lock
<std::recursive_mutex
> lock
;
1167 target
.GetBreakpointList(m_options
.m_internal
).GetListMutex(lock
);
1169 size_t num_breakpoints
= breakpoints
.GetSize();
1171 if (num_breakpoints
== 0) {
1172 result
.AppendMessage("No breakpoints currently set.");
1173 result
.SetStatus(eReturnStatusSuccessFinishNoResult
);
1177 Stream
&output_stream
= result
.GetOutputStream();
1179 if (command
.empty()) {
1180 // No breakpoint selected; show info about all currently set breakpoints.
1181 result
.AppendMessage("Current breakpoints:");
1182 for (size_t i
= 0; i
< num_breakpoints
; ++i
) {
1183 Breakpoint
*breakpoint
= breakpoints
.GetBreakpointAtIndex(i
).get();
1184 if (breakpoint
->AllowList())
1185 AddBreakpointDescription(&output_stream
, breakpoint
,
1188 result
.SetStatus(eReturnStatusSuccessFinishNoResult
);
1190 // Particular breakpoints selected; show info about that breakpoint.
1191 BreakpointIDList valid_bp_ids
;
1192 CommandObjectMultiwordBreakpoint::VerifyBreakpointOrLocationIDs(
1193 command
, target
, result
, &valid_bp_ids
,
1194 BreakpointName::Permissions::PermissionKinds::listPerm
);
1196 if (result
.Succeeded()) {
1197 for (size_t i
= 0; i
< valid_bp_ids
.GetSize(); ++i
) {
1198 BreakpointID cur_bp_id
= valid_bp_ids
.GetBreakpointIDAtIndex(i
);
1199 Breakpoint
*breakpoint
=
1200 target
.GetBreakpointByID(cur_bp_id
.GetBreakpointID()).get();
1201 AddBreakpointDescription(&output_stream
, breakpoint
,
1204 result
.SetStatus(eReturnStatusSuccessFinishNoResult
);
1206 result
.AppendError("Invalid breakpoint ID.");
1212 CommandOptions m_options
;
1215 // CommandObjectBreakpointClear
1216 #pragma mark Clear::CommandOptions
1218 #define LLDB_OPTIONS_breakpoint_clear
1219 #include "CommandOptions.inc"
1223 class CommandObjectBreakpointClear
: public CommandObjectParsed
{
1225 enum BreakpointClearType
{ eClearTypeInvalid
, eClearTypeFileAndLine
};
1227 CommandObjectBreakpointClear(CommandInterpreter
&interpreter
)
1228 : CommandObjectParsed(interpreter
, "breakpoint clear",
1229 "Delete or disable breakpoints matching the "
1230 "specified source file and line.",
1231 "breakpoint clear <cmd-options>") {}
1233 ~CommandObjectBreakpointClear() override
= default;
1235 Options
*GetOptions() override
{ return &m_options
; }
1237 class CommandOptions
: public Options
{
1239 CommandOptions() = default;
1241 ~CommandOptions() override
= default;
1243 Status
SetOptionValue(uint32_t option_idx
, llvm::StringRef option_arg
,
1244 ExecutionContext
*execution_context
) override
{
1246 const int short_option
= m_getopt_table
[option_idx
].val
;
1248 switch (short_option
) {
1250 m_filename
.assign(std::string(option_arg
));
1254 option_arg
.getAsInteger(0, m_line_num
);
1258 llvm_unreachable("Unimplemented option");
1264 void OptionParsingStarting(ExecutionContext
*execution_context
) override
{
1269 llvm::ArrayRef
<OptionDefinition
> GetDefinitions() override
{
1270 return llvm::ArrayRef(g_breakpoint_clear_options
);
1273 // Instance variables to hold the values for command options.
1275 std::string m_filename
;
1276 uint32_t m_line_num
= 0;
1280 void DoExecute(Args
&command
, CommandReturnObject
&result
) override
{
1281 Target
&target
= GetTarget();
1283 // The following are the various types of breakpoints that could be
1285 // 1). -f -l (clearing breakpoint by source location)
1287 BreakpointClearType break_type
= eClearTypeInvalid
;
1289 if (m_options
.m_line_num
!= 0)
1290 break_type
= eClearTypeFileAndLine
;
1292 std::unique_lock
<std::recursive_mutex
> lock
;
1293 target
.GetBreakpointList().GetListMutex(lock
);
1295 BreakpointList
&breakpoints
= target
.GetBreakpointList();
1296 size_t num_breakpoints
= breakpoints
.GetSize();
1298 // Early return if there's no breakpoint at all.
1299 if (num_breakpoints
== 0) {
1300 result
.AppendError("Breakpoint clear: No breakpoint cleared.");
1304 // Find matching breakpoints and delete them.
1306 // First create a copy of all the IDs.
1307 std::vector
<break_id_t
> BreakIDs
;
1308 for (size_t i
= 0; i
< num_breakpoints
; ++i
)
1309 BreakIDs
.push_back(breakpoints
.GetBreakpointAtIndex(i
)->GetID());
1311 int num_cleared
= 0;
1313 switch (break_type
) {
1314 case eClearTypeFileAndLine
: // Breakpoint by source position
1316 const ConstString
filename(m_options
.m_filename
.c_str());
1317 BreakpointLocationCollection loc_coll
;
1319 for (size_t i
= 0; i
< num_breakpoints
; ++i
) {
1320 Breakpoint
*bp
= breakpoints
.FindBreakpointByID(BreakIDs
[i
]).get();
1322 if (bp
->GetMatchingFileLine(filename
, m_options
.m_line_num
, loc_coll
)) {
1323 // If the collection size is 0, it's a full match and we can just
1324 // remove the breakpoint.
1325 if (loc_coll
.GetSize() == 0) {
1326 bp
->GetDescription(&ss
, lldb::eDescriptionLevelBrief
);
1328 target
.RemoveBreakpointByID(bp
->GetID());
1339 if (num_cleared
> 0) {
1340 Stream
&output_stream
= result
.GetOutputStream();
1341 output_stream
.Printf("%d breakpoints cleared:\n", num_cleared
);
1342 output_stream
<< ss
.GetString();
1343 output_stream
.EOL();
1344 result
.SetStatus(eReturnStatusSuccessFinishNoResult
);
1346 result
.AppendError("Breakpoint clear: No breakpoint cleared.");
1351 CommandOptions m_options
;
1354 // CommandObjectBreakpointDelete
1355 #define LLDB_OPTIONS_breakpoint_delete
1356 #include "CommandOptions.inc"
1360 class CommandObjectBreakpointDelete
: public CommandObjectParsed
{
1362 CommandObjectBreakpointDelete(CommandInterpreter
&interpreter
)
1363 : CommandObjectParsed(interpreter
, "breakpoint delete",
1364 "Delete the specified breakpoint(s). If no "
1365 "breakpoints are specified, delete them all.",
1367 CommandObject::AddIDsArgumentData(eBreakpointArgs
);
1370 ~CommandObjectBreakpointDelete() override
= default;
1373 HandleArgumentCompletion(CompletionRequest
&request
,
1374 OptionElementVector
&opt_element_vector
) override
{
1375 lldb_private::CommandCompletions::InvokeCommonCompletionCallbacks(
1376 GetCommandInterpreter(), lldb::eBreakpointCompletion
, request
, nullptr);
1379 Options
*GetOptions() override
{ return &m_options
; }
1381 class CommandOptions
: public Options
{
1383 CommandOptions() = default;
1385 ~CommandOptions() override
= default;
1387 Status
SetOptionValue(uint32_t option_idx
, llvm::StringRef option_arg
,
1388 ExecutionContext
*execution_context
) override
{
1390 const int short_option
= m_getopt_table
[option_idx
].val
;
1392 switch (short_option
) {
1402 m_delete_disabled
= true;
1406 llvm_unreachable("Unimplemented option");
1412 void OptionParsingStarting(ExecutionContext
*execution_context
) override
{
1413 m_use_dummy
= false;
1415 m_delete_disabled
= false;
1418 llvm::ArrayRef
<OptionDefinition
> GetDefinitions() override
{
1419 return llvm::ArrayRef(g_breakpoint_delete_options
);
1422 // Instance variables to hold the values for command options.
1423 bool m_use_dummy
= false;
1424 bool m_force
= false;
1425 bool m_delete_disabled
= false;
1429 void DoExecute(Args
&command
, CommandReturnObject
&result
) override
{
1430 Target
&target
= m_options
.m_use_dummy
? GetDummyTarget() : GetTarget();
1433 std::unique_lock
<std::recursive_mutex
> lock
;
1434 target
.GetBreakpointList().GetListMutex(lock
);
1436 BreakpointList
&breakpoints
= target
.GetBreakpointList();
1438 size_t num_breakpoints
= breakpoints
.GetSize();
1440 if (num_breakpoints
== 0) {
1441 result
.AppendError("No breakpoints exist to be deleted.");
1445 // Handle the delete all breakpoints case:
1446 if (command
.empty() && !m_options
.m_delete_disabled
) {
1447 if (!m_options
.m_force
&&
1448 !m_interpreter
.Confirm(
1449 "About to delete all breakpoints, do you want to do that?",
1451 result
.AppendMessage("Operation cancelled...");
1453 target
.RemoveAllowedBreakpoints();
1454 result
.AppendMessageWithFormat(
1455 "All breakpoints removed. (%" PRIu64
" breakpoint%s)\n",
1456 (uint64_t)num_breakpoints
, num_breakpoints
> 1 ? "s" : "");
1458 result
.SetStatus(eReturnStatusSuccessFinishNoResult
);
1462 // Either we have some kind of breakpoint specification(s),
1463 // or we are handling "break disable --deleted". Gather the list
1464 // of breakpoints to delete here, the we'll delete them below.
1465 BreakpointIDList valid_bp_ids
;
1467 if (m_options
.m_delete_disabled
) {
1468 BreakpointIDList excluded_bp_ids
;
1470 if (!command
.empty()) {
1471 CommandObjectMultiwordBreakpoint::VerifyBreakpointOrLocationIDs(
1472 command
, target
, result
, &excluded_bp_ids
,
1473 BreakpointName::Permissions::PermissionKinds::deletePerm
);
1474 if (!result
.Succeeded())
1478 for (auto breakpoint_sp
: breakpoints
.Breakpoints()) {
1479 if (!breakpoint_sp
->IsEnabled() && breakpoint_sp
->AllowDelete()) {
1480 BreakpointID
bp_id(breakpoint_sp
->GetID());
1481 if (!excluded_bp_ids
.Contains(bp_id
))
1482 valid_bp_ids
.AddBreakpointID(bp_id
);
1485 if (valid_bp_ids
.GetSize() == 0) {
1486 result
.AppendError("No disabled breakpoints.");
1490 CommandObjectMultiwordBreakpoint::VerifyBreakpointOrLocationIDs(
1491 command
, target
, result
, &valid_bp_ids
,
1492 BreakpointName::Permissions::PermissionKinds::deletePerm
);
1493 if (!result
.Succeeded())
1497 int delete_count
= 0;
1498 int disable_count
= 0;
1499 const size_t count
= valid_bp_ids
.GetSize();
1500 for (size_t i
= 0; i
< count
; ++i
) {
1501 BreakpointID cur_bp_id
= valid_bp_ids
.GetBreakpointIDAtIndex(i
);
1503 if (cur_bp_id
.GetBreakpointID() != LLDB_INVALID_BREAK_ID
) {
1504 if (cur_bp_id
.GetLocationID() != LLDB_INVALID_BREAK_ID
) {
1505 Breakpoint
*breakpoint
=
1506 target
.GetBreakpointByID(cur_bp_id
.GetBreakpointID()).get();
1507 BreakpointLocation
*location
=
1508 breakpoint
->FindLocationByID(cur_bp_id
.GetLocationID()).get();
1509 // It makes no sense to try to delete individual locations, so we
1510 // disable them instead.
1512 location
->SetEnabled(false);
1516 target
.RemoveBreakpointByID(cur_bp_id
.GetBreakpointID());
1521 result
.AppendMessageWithFormat(
1522 "%d breakpoints deleted; %d breakpoint locations disabled.\n",
1523 delete_count
, disable_count
);
1524 result
.SetStatus(eReturnStatusSuccessFinishNoResult
);
1528 CommandOptions m_options
;
1531 // CommandObjectBreakpointName
1532 #define LLDB_OPTIONS_breakpoint_name
1533 #include "CommandOptions.inc"
1535 class BreakpointNameOptionGroup
: public OptionGroup
{
1537 BreakpointNameOptionGroup()
1538 : m_breakpoint(LLDB_INVALID_BREAK_ID
), m_use_dummy(false) {}
1540 ~BreakpointNameOptionGroup() override
= default;
1542 llvm::ArrayRef
<OptionDefinition
> GetDefinitions() override
{
1543 return llvm::ArrayRef(g_breakpoint_name_options
);
1546 Status
SetOptionValue(uint32_t option_idx
, llvm::StringRef option_arg
,
1547 ExecutionContext
*execution_context
) override
{
1549 const int short_option
= g_breakpoint_name_options
[option_idx
].short_option
;
1550 const char *long_option
= g_breakpoint_name_options
[option_idx
].long_option
;
1552 switch (short_option
) {
1554 if (BreakpointID::StringIsBreakpointName(option_arg
, error
) &&
1556 m_name
.SetValueFromString(option_arg
);
1559 if (m_breakpoint
.SetValueFromString(option_arg
).Fail())
1560 error
= Status::FromError(
1561 CreateOptionParsingError(option_arg
, short_option
, long_option
,
1562 g_int_parsing_error_message
));
1565 if (m_use_dummy
.SetValueFromString(option_arg
).Fail())
1566 error
= Status::FromError(
1567 CreateOptionParsingError(option_arg
, short_option
, long_option
,
1568 g_bool_parsing_error_message
));
1571 m_help_string
.SetValueFromString(option_arg
);
1575 llvm_unreachable("Unimplemented option");
1580 void OptionParsingStarting(ExecutionContext
*execution_context
) override
{
1582 m_breakpoint
.Clear();
1583 m_use_dummy
.Clear();
1584 m_use_dummy
.SetDefaultValue(false);
1585 m_help_string
.Clear();
1588 OptionValueString m_name
;
1589 OptionValueUInt64 m_breakpoint
;
1590 OptionValueBoolean m_use_dummy
;
1591 OptionValueString m_help_string
;
1594 #define LLDB_OPTIONS_breakpoint_access
1595 #include "CommandOptions.inc"
1597 class BreakpointAccessOptionGroup
: public OptionGroup
{
1599 BreakpointAccessOptionGroup() = default;
1601 ~BreakpointAccessOptionGroup() override
= default;
1603 llvm::ArrayRef
<OptionDefinition
> GetDefinitions() override
{
1604 return llvm::ArrayRef(g_breakpoint_access_options
);
1606 Status
SetOptionValue(uint32_t option_idx
, llvm::StringRef option_arg
,
1607 ExecutionContext
*execution_context
) override
{
1609 const int short_option
=
1610 g_breakpoint_access_options
[option_idx
].short_option
;
1611 const char *long_option
=
1612 g_breakpoint_access_options
[option_idx
].long_option
;
1614 switch (short_option
) {
1616 bool value
, success
;
1617 value
= OptionArgParser::ToBoolean(option_arg
, false, &success
);
1619 m_permissions
.SetAllowList(value
);
1621 error
= Status::FromError(
1622 CreateOptionParsingError(option_arg
, short_option
, long_option
,
1623 g_bool_parsing_error_message
));
1626 bool value
, success
;
1627 value
= OptionArgParser::ToBoolean(option_arg
, false, &success
);
1629 m_permissions
.SetAllowDisable(value
);
1631 error
= Status::FromError(
1632 CreateOptionParsingError(option_arg
, short_option
, long_option
,
1633 g_bool_parsing_error_message
));
1636 bool value
, success
;
1637 value
= OptionArgParser::ToBoolean(option_arg
, false, &success
);
1639 m_permissions
.SetAllowDelete(value
);
1641 error
= Status::FromError(
1642 CreateOptionParsingError(option_arg
, short_option
, long_option
,
1643 g_bool_parsing_error_message
));
1646 llvm_unreachable("Unimplemented option");
1652 void OptionParsingStarting(ExecutionContext
*execution_context
) override
{}
1654 const BreakpointName::Permissions
&GetPermissions() const {
1655 return m_permissions
;
1657 BreakpointName::Permissions m_permissions
;
1660 class CommandObjectBreakpointNameConfigure
: public CommandObjectParsed
{
1662 CommandObjectBreakpointNameConfigure(CommandInterpreter
&interpreter
)
1663 : CommandObjectParsed(
1664 interpreter
, "configure",
1665 "Configure the options for the breakpoint"
1667 "If you provide a breakpoint id, the options will be copied from "
1668 "the breakpoint, otherwise only the options specified will be set "
1670 "breakpoint name configure <command-options> "
1671 "<breakpoint-name-list>") {
1672 AddSimpleArgumentList(eArgTypeBreakpointName
, eArgRepeatOptional
);
1674 m_option_group
.Append(&m_bp_opts
, LLDB_OPT_SET_ALL
, LLDB_OPT_SET_1
);
1675 m_option_group
.Append(&m_access_options
, LLDB_OPT_SET_ALL
,
1677 m_option_group
.Append(&m_bp_id
, LLDB_OPT_SET_2
| LLDB_OPT_SET_4
,
1679 m_option_group
.Finalize();
1682 ~CommandObjectBreakpointNameConfigure() override
= default;
1684 Options
*GetOptions() override
{ return &m_option_group
; }
1687 void DoExecute(Args
&command
, CommandReturnObject
&result
) override
{
1689 const size_t argc
= command
.GetArgumentCount();
1691 result
.AppendError("No names provided.");
1695 Target
&target
= GetTarget();
1697 std::unique_lock
<std::recursive_mutex
> lock
;
1698 target
.GetBreakpointList().GetListMutex(lock
);
1700 // Make a pass through first to see that all the names are legal.
1701 for (auto &entry
: command
.entries()) {
1703 if (!BreakpointID::StringIsBreakpointName(entry
.ref(), error
)) {
1704 result
.AppendErrorWithFormat("Invalid breakpoint name: %s - %s",
1705 entry
.c_str(), error
.AsCString());
1709 // Now configure them, we already pre-checked the names so we don't need to
1712 if (m_bp_id
.m_breakpoint
.OptionWasSet()) {
1713 lldb::break_id_t bp_id
=
1714 m_bp_id
.m_breakpoint
.GetValueAs
<uint64_t>().value_or(0);
1715 bp_sp
= target
.GetBreakpointByID(bp_id
);
1717 result
.AppendErrorWithFormatv("Could not find specified breakpoint {0}",
1724 for (auto &entry
: command
.entries()) {
1725 ConstString
name(entry
.c_str());
1726 BreakpointName
*bp_name
= target
.FindBreakpointName(name
, true, error
);
1729 if (m_bp_id
.m_help_string
.OptionWasSet())
1730 bp_name
->SetHelp(m_bp_id
.m_help_string
.GetValueAs
<llvm::StringRef
>()
1736 target
.ConfigureBreakpointName(*bp_name
, bp_sp
->GetOptions(),
1737 m_access_options
.GetPermissions());
1739 target
.ConfigureBreakpointName(*bp_name
,
1740 m_bp_opts
.GetBreakpointOptions(),
1741 m_access_options
.GetPermissions());
1746 BreakpointNameOptionGroup m_bp_id
; // Only using the id part of this.
1747 BreakpointOptionGroup m_bp_opts
;
1748 BreakpointAccessOptionGroup m_access_options
;
1749 OptionGroupOptions m_option_group
;
1752 class CommandObjectBreakpointNameAdd
: public CommandObjectParsed
{
1754 CommandObjectBreakpointNameAdd(CommandInterpreter
&interpreter
)
1755 : CommandObjectParsed(
1756 interpreter
, "add", "Add a name to the breakpoints provided.",
1757 "breakpoint name add <command-options> <breakpoint-id-list>") {
1758 AddSimpleArgumentList(eArgTypeBreakpointID
, eArgRepeatOptional
);
1760 m_option_group
.Append(&m_name_options
, LLDB_OPT_SET_1
, LLDB_OPT_SET_ALL
);
1761 m_option_group
.Finalize();
1764 ~CommandObjectBreakpointNameAdd() override
= default;
1767 HandleArgumentCompletion(CompletionRequest
&request
,
1768 OptionElementVector
&opt_element_vector
) override
{
1769 lldb_private::CommandCompletions::InvokeCommonCompletionCallbacks(
1770 GetCommandInterpreter(), lldb::eBreakpointCompletion
, request
, nullptr);
1773 Options
*GetOptions() override
{ return &m_option_group
; }
1776 void DoExecute(Args
&command
, CommandReturnObject
&result
) override
{
1777 if (!m_name_options
.m_name
.OptionWasSet()) {
1778 result
.AppendError("No name option provided.");
1783 m_name_options
.m_use_dummy
? GetDummyTarget() : GetTarget();
1785 std::unique_lock
<std::recursive_mutex
> lock
;
1786 target
.GetBreakpointList().GetListMutex(lock
);
1788 const BreakpointList
&breakpoints
= target
.GetBreakpointList();
1790 size_t num_breakpoints
= breakpoints
.GetSize();
1791 if (num_breakpoints
== 0) {
1792 result
.AppendError("No breakpoints, cannot add names.");
1796 // Particular breakpoint selected; disable that breakpoint.
1797 BreakpointIDList valid_bp_ids
;
1798 CommandObjectMultiwordBreakpoint::VerifyBreakpointIDs(
1799 command
, target
, result
, &valid_bp_ids
,
1800 BreakpointName::Permissions::PermissionKinds::listPerm
);
1802 if (result
.Succeeded()) {
1803 if (valid_bp_ids
.GetSize() == 0) {
1804 result
.AppendError("No breakpoints specified, cannot add names.");
1807 size_t num_valid_ids
= valid_bp_ids
.GetSize();
1808 const char *bp_name
= m_name_options
.m_name
.GetCurrentValue();
1809 Status error
; // This error reports illegal names, but we've already
1810 // checked that, so we don't need to check it again here.
1811 for (size_t index
= 0; index
< num_valid_ids
; index
++) {
1812 lldb::break_id_t bp_id
=
1813 valid_bp_ids
.GetBreakpointIDAtIndex(index
).GetBreakpointID();
1814 BreakpointSP bp_sp
= breakpoints
.FindBreakpointByID(bp_id
);
1815 target
.AddNameToBreakpoint(bp_sp
, bp_name
, error
);
1821 BreakpointNameOptionGroup m_name_options
;
1822 OptionGroupOptions m_option_group
;
1825 class CommandObjectBreakpointNameDelete
: public CommandObjectParsed
{
1827 CommandObjectBreakpointNameDelete(CommandInterpreter
&interpreter
)
1828 : CommandObjectParsed(
1829 interpreter
, "delete",
1830 "Delete a name from the breakpoints provided.",
1831 "breakpoint name delete <command-options> <breakpoint-id-list>") {
1832 AddSimpleArgumentList(eArgTypeBreakpointID
, eArgRepeatOptional
);
1834 m_option_group
.Append(&m_name_options
, LLDB_OPT_SET_1
, LLDB_OPT_SET_ALL
);
1835 m_option_group
.Finalize();
1838 ~CommandObjectBreakpointNameDelete() override
= default;
1841 HandleArgumentCompletion(CompletionRequest
&request
,
1842 OptionElementVector
&opt_element_vector
) override
{
1843 lldb_private::CommandCompletions::InvokeCommonCompletionCallbacks(
1844 GetCommandInterpreter(), lldb::eBreakpointCompletion
, request
, nullptr);
1847 Options
*GetOptions() override
{ return &m_option_group
; }
1850 void DoExecute(Args
&command
, CommandReturnObject
&result
) override
{
1851 if (!m_name_options
.m_name
.OptionWasSet()) {
1852 result
.AppendError("No name option provided.");
1857 m_name_options
.m_use_dummy
? GetDummyTarget() : GetTarget();
1859 std::unique_lock
<std::recursive_mutex
> lock
;
1860 target
.GetBreakpointList().GetListMutex(lock
);
1862 const BreakpointList
&breakpoints
= target
.GetBreakpointList();
1864 size_t num_breakpoints
= breakpoints
.GetSize();
1865 if (num_breakpoints
== 0) {
1866 result
.AppendError("No breakpoints, cannot delete names.");
1870 // Particular breakpoint selected; disable that breakpoint.
1871 BreakpointIDList valid_bp_ids
;
1872 CommandObjectMultiwordBreakpoint::VerifyBreakpointIDs(
1873 command
, target
, result
, &valid_bp_ids
,
1874 BreakpointName::Permissions::PermissionKinds::deletePerm
);
1876 if (result
.Succeeded()) {
1877 if (valid_bp_ids
.GetSize() == 0) {
1878 result
.AppendError("No breakpoints specified, cannot delete names.");
1881 ConstString
bp_name(m_name_options
.m_name
.GetCurrentValue());
1882 size_t num_valid_ids
= valid_bp_ids
.GetSize();
1883 for (size_t index
= 0; index
< num_valid_ids
; index
++) {
1884 lldb::break_id_t bp_id
=
1885 valid_bp_ids
.GetBreakpointIDAtIndex(index
).GetBreakpointID();
1886 BreakpointSP bp_sp
= breakpoints
.FindBreakpointByID(bp_id
);
1887 target
.RemoveNameFromBreakpoint(bp_sp
, bp_name
);
1893 BreakpointNameOptionGroup m_name_options
;
1894 OptionGroupOptions m_option_group
;
1897 class CommandObjectBreakpointNameList
: public CommandObjectParsed
{
1899 CommandObjectBreakpointNameList(CommandInterpreter
&interpreter
)
1900 : CommandObjectParsed(interpreter
, "list",
1901 "List either the names for a breakpoint or info "
1902 "about a given name. With no arguments, lists all "
1904 "breakpoint name list <command-options>") {
1905 m_option_group
.Append(&m_name_options
, LLDB_OPT_SET_3
, LLDB_OPT_SET_ALL
);
1906 m_option_group
.Finalize();
1909 ~CommandObjectBreakpointNameList() override
= default;
1911 Options
*GetOptions() override
{ return &m_option_group
; }
1914 void DoExecute(Args
&command
, CommandReturnObject
&result
) override
{
1916 m_name_options
.m_use_dummy
? GetDummyTarget() : GetTarget();
1918 std::vector
<std::string
> name_list
;
1919 if (command
.empty()) {
1920 target
.GetBreakpointNames(name_list
);
1922 for (const Args::ArgEntry
&arg
: command
) {
1923 name_list
.push_back(arg
.c_str());
1927 if (name_list
.empty()) {
1928 result
.AppendMessage("No breakpoint names found.");
1930 for (const std::string
&name_str
: name_list
) {
1931 const char *name
= name_str
.c_str();
1932 // First print out the options for the name:
1934 BreakpointName
*bp_name
=
1935 target
.FindBreakpointName(ConstString(name
), false, error
);
1938 result
.AppendMessageWithFormat("Name: %s\n", name
);
1939 if (bp_name
->GetDescription(&s
, eDescriptionLevelFull
)) {
1940 result
.AppendMessage(s
.GetString());
1943 std::unique_lock
<std::recursive_mutex
> lock
;
1944 target
.GetBreakpointList().GetListMutex(lock
);
1946 BreakpointList
&breakpoints
= target
.GetBreakpointList();
1947 bool any_set
= false;
1948 for (BreakpointSP bp_sp
: breakpoints
.Breakpoints()) {
1949 if (bp_sp
->MatchesName(name
)) {
1952 bp_sp
->GetDescription(&s
, eDescriptionLevelBrief
);
1954 result
.AppendMessage(s
.GetString());
1958 result
.AppendMessage("No breakpoints using this name.");
1960 result
.AppendMessageWithFormat("Name: %s not found.\n", name
);
1967 BreakpointNameOptionGroup m_name_options
;
1968 OptionGroupOptions m_option_group
;
1971 // CommandObjectBreakpointName
1972 class CommandObjectBreakpointName
: public CommandObjectMultiword
{
1974 CommandObjectBreakpointName(CommandInterpreter
&interpreter
)
1975 : CommandObjectMultiword(
1976 interpreter
, "name", "Commands to manage breakpoint names") {
1981 Breakpoint names provide a general tagging mechanism for breakpoints. Each
1982 breakpoint name can be added to any number of breakpoints, and each breakpoint
1983 can have any number of breakpoint names attached to it. For instance:
1985 (lldb) break name add -N MyName 1-10
1987 adds the name MyName to breakpoints 1-10, and:
1989 (lldb) break set -n myFunc -N Name1 -N Name2
1991 adds two names to the breakpoint set at myFunc.
1993 They have a number of interrelated uses:
1995 1) They provide a stable way to refer to a breakpoint (e.g. in another
1996 breakpoint's action). Using the breakpoint ID for this purpose is fragile, since
1997 it depends on the order of breakpoint creation. Giving a name to the breakpoint
1998 you want to act on, and then referring to it by name, is more robust:
2000 (lldb) break set -n myFunc -N BKPT1
2001 (lldb) break set -n myOtherFunc -C "break disable BKPT1
"
2003 2) This is actually just a specific use of a more general feature of breakpoint
2004 names. The <breakpt-id-list> argument type used to specify one or more
2005 breakpoints in most of the commands that deal with breakpoints also accepts
2006 breakpoint names. That allows you to refer to one breakpoint in a stable
2007 manner, but also makes them a convenient grouping mechanism, allowing you to
2008 easily act on a group of breakpoints by using their name, for instance disabling
2009 them all in one action:
2011 (lldb) break set -n myFunc -N Group1
2012 (lldb) break set -n myOtherFunc -N Group1
2013 (lldb) break disable Group1
2015 3) But breakpoint names are also entities in their own right, and can be
2016 configured with all the modifiable attributes of a breakpoint. Then when you
2017 add a breakpoint name to a breakpoint, the breakpoint will be configured to
2018 match the state of the breakpoint name. The link between the name and the
2019 breakpoints sharing it remains live, so if you change the configuration on the
2020 name, it will also change the configurations on the breakpoints:
2022 (lldb) break name configure -i 10 IgnoreSome
2023 (lldb) break set -n myFunc -N IgnoreSome
2024 (lldb) break list IgnoreSome
2025 2: name = 'myFunc', locations = 0 (pending) Options: ignore: 10 enabled
2028 (lldb) break name configure -i 5 IgnoreSome
2029 (lldb) break list IgnoreSome
2030 2: name = 'myFunc', locations = 0 (pending) Options: ignore: 5 enabled
2034 Options that are not configured on a breakpoint name don't affect the value of
2035 those options on the breakpoints they are added to. So for instance, if Name1
2036 has the -i option configured and Name2 the -c option, adding both names to a
2037 breakpoint will set the -i option from Name1 and the -c option from Name2, and
2038 the other options will be unaltered.
2040 If you add multiple names to a breakpoint which have configured values for
2041 the same option, the last name added's value wins.
2043 The "liveness
" of these settings is one way, from name to breakpoint.
2044 If you use "break modify
" to change an option that is also configured on a name
2045 which that breakpoint has, the "break modify
" command will override the setting
2046 for that breakpoint, but won't change the value configured in the name or on the
2047 other breakpoints sharing that name.
2049 4) Breakpoint names are also a convenient way to copy option sets from one
2050 breakpoint to another. Using the -B option to "breakpoint name configure
" makes
2051 a name configured with all the options of the original breakpoint. Then
2052 adding that name to another breakpoint copies over all the values from the
2053 original breakpoint to the new one.
2055 5) You can also use breakpoint names to hide breakpoints from the breakpoint
2056 operations that act on all breakpoints: "break delete", "break disable
" and
2057 "break list
". You do that by specifying a "false" value for the
2058 --allow-{list,delete,disable} options to "breakpoint name configure
" and then
2059 adding that name to a breakpoint.
2061 This won't keep the breakpoint from being deleted or disabled if you refer to it
2062 specifically by ID. The point of the feature is to make sure users don't
2063 inadvertently delete or disable useful breakpoints (e.g. ones an IDE is using
2064 for its own purposes) as part of a "delete all
" or "disable all
" operation. The
2065 list hiding is because it's confusing for people to see breakpoints they
2069 CommandObjectSP
add_command_object(
2070 new CommandObjectBreakpointNameAdd(interpreter
));
2071 CommandObjectSP
delete_command_object(
2072 new CommandObjectBreakpointNameDelete(interpreter
));
2073 CommandObjectSP
list_command_object(
2074 new CommandObjectBreakpointNameList(interpreter
));
2075 CommandObjectSP
configure_command_object(
2076 new CommandObjectBreakpointNameConfigure(interpreter
));
2078 LoadSubCommand("add", add_command_object
);
2079 LoadSubCommand("delete", delete_command_object
);
2080 LoadSubCommand("list", list_command_object
);
2081 LoadSubCommand("configure", configure_command_object
);
2084 ~CommandObjectBreakpointName() override
= default;
2087 // CommandObjectBreakpointRead
2088 #pragma mark Read::CommandOptions
2089 #define LLDB_OPTIONS_breakpoint_read
2090 #include "CommandOptions.inc"
2094 class CommandObjectBreakpointRead
: public CommandObjectParsed
{
2096 CommandObjectBreakpointRead(CommandInterpreter
&interpreter
)
2097 : CommandObjectParsed(interpreter
, "breakpoint read",
2098 "Read and set the breakpoints previously saved to "
2099 "a file with \"breakpoint write\". ",
2102 ~CommandObjectBreakpointRead() override
= default;
2104 Options
*GetOptions() override
{ return &m_options
; }
2106 class CommandOptions
: public Options
{
2108 CommandOptions() = default;
2110 ~CommandOptions() override
= default;
2112 Status
SetOptionValue(uint32_t option_idx
, llvm::StringRef option_arg
,
2113 ExecutionContext
*execution_context
) override
{
2115 const int short_option
= m_getopt_table
[option_idx
].val
;
2116 const char *long_option
=
2117 m_getopt_table
[option_idx
].definition
->long_option
;
2119 switch (short_option
) {
2121 m_filename
.assign(std::string(option_arg
));
2125 if (!BreakpointID::StringIsBreakpointName(llvm::StringRef(option_arg
),
2127 error
= Status::FromError(CreateOptionParsingError(
2128 option_arg
, short_option
, long_option
, name_error
.AsCString()));
2130 m_names
.push_back(std::string(option_arg
));
2134 llvm_unreachable("Unimplemented option");
2140 void OptionParsingStarting(ExecutionContext
*execution_context
) override
{
2145 llvm::ArrayRef
<OptionDefinition
> GetDefinitions() override
{
2146 return llvm::ArrayRef(g_breakpoint_read_options
);
2149 void HandleOptionArgumentCompletion(
2150 CompletionRequest
&request
, OptionElementVector
&opt_element_vector
,
2151 int opt_element_index
, CommandInterpreter
&interpreter
) override
{
2152 int opt_arg_pos
= opt_element_vector
[opt_element_index
].opt_arg_pos
;
2153 int opt_defs_index
= opt_element_vector
[opt_element_index
].opt_defs_index
;
2155 switch (GetDefinitions()[opt_defs_index
].short_option
) {
2157 lldb_private::CommandCompletions::InvokeCommonCompletionCallbacks(
2158 interpreter
, lldb::eDiskFileCompletion
, request
, nullptr);
2162 std::optional
<FileSpec
> file_spec
;
2163 const llvm::StringRef
dash_f("-f");
2164 for (int arg_idx
= 0; arg_idx
< opt_arg_pos
; arg_idx
++) {
2165 if (dash_f
== request
.GetParsedLine().GetArgumentAtIndex(arg_idx
)) {
2167 request
.GetParsedLine().GetArgumentAtIndex(arg_idx
+ 1));
2174 FileSystem::Instance().Resolve(*file_spec
);
2176 StructuredData::ObjectSP input_data_sp
=
2177 StructuredData::ParseJSONFromFile(*file_spec
, error
);
2178 if (!error
.Success())
2181 StructuredData::Array
*bkpt_array
= input_data_sp
->GetAsArray();
2185 const size_t num_bkpts
= bkpt_array
->GetSize();
2186 for (size_t i
= 0; i
< num_bkpts
; i
++) {
2187 StructuredData::ObjectSP bkpt_object_sp
=
2188 bkpt_array
->GetItemAtIndex(i
);
2189 if (!bkpt_object_sp
)
2192 StructuredData::Dictionary
*bkpt_dict
=
2193 bkpt_object_sp
->GetAsDictionary();
2197 StructuredData::ObjectSP bkpt_data_sp
=
2198 bkpt_dict
->GetValueForKey(Breakpoint::GetSerializationKey());
2202 bkpt_dict
= bkpt_data_sp
->GetAsDictionary();
2206 StructuredData::Array
*names_array
;
2208 if (!bkpt_dict
->GetValueForKeyAsArray("Names", names_array
))
2211 size_t num_names
= names_array
->GetSize();
2213 for (size_t i
= 0; i
< num_names
; i
++) {
2214 if (std::optional
<llvm::StringRef
> maybe_name
=
2215 names_array
->GetItemAtIndexAsString(i
))
2216 request
.TryCompleteCurrentArg(*maybe_name
);
2222 std::string m_filename
;
2223 std::vector
<std::string
> m_names
;
2227 void DoExecute(Args
&command
, CommandReturnObject
&result
) override
{
2228 Target
&target
= GetTarget();
2230 std::unique_lock
<std::recursive_mutex
> lock
;
2231 target
.GetBreakpointList().GetListMutex(lock
);
2233 FileSpec
input_spec(m_options
.m_filename
);
2234 FileSystem::Instance().Resolve(input_spec
);
2235 BreakpointIDList new_bps
;
2236 Status error
= target
.CreateBreakpointsFromFile(input_spec
,
2237 m_options
.m_names
, new_bps
);
2239 if (!error
.Success()) {
2240 result
.AppendError(error
.AsCString());
2244 Stream
&output_stream
= result
.GetOutputStream();
2246 size_t num_breakpoints
= new_bps
.GetSize();
2247 if (num_breakpoints
== 0) {
2248 result
.AppendMessage("No breakpoints added.");
2250 // No breakpoint selected; show info about all currently set breakpoints.
2251 result
.AppendMessage("New breakpoints:");
2252 for (size_t i
= 0; i
< num_breakpoints
; ++i
) {
2253 BreakpointID bp_id
= new_bps
.GetBreakpointIDAtIndex(i
);
2254 Breakpoint
*bp
= target
.GetBreakpointList()
2255 .FindBreakpointByID(bp_id
.GetBreakpointID())
2258 bp
->GetDescription(&output_stream
, lldb::eDescriptionLevelInitial
,
2265 CommandOptions m_options
;
2268 // CommandObjectBreakpointWrite
2269 #pragma mark Write::CommandOptions
2270 #define LLDB_OPTIONS_breakpoint_write
2271 #include "CommandOptions.inc"
2274 class CommandObjectBreakpointWrite
: public CommandObjectParsed
{
2276 CommandObjectBreakpointWrite(CommandInterpreter
&interpreter
)
2277 : CommandObjectParsed(interpreter
, "breakpoint write",
2278 "Write the breakpoints listed to a file that can "
2279 "be read in with \"breakpoint read\". "
2280 "If given no arguments, writes all breakpoints.",
2282 CommandObject::AddIDsArgumentData(eBreakpointArgs
);
2285 ~CommandObjectBreakpointWrite() override
= default;
2288 HandleArgumentCompletion(CompletionRequest
&request
,
2289 OptionElementVector
&opt_element_vector
) override
{
2290 lldb_private::CommandCompletions::InvokeCommonCompletionCallbacks(
2291 GetCommandInterpreter(), lldb::eBreakpointCompletion
, request
, nullptr);
2294 Options
*GetOptions() override
{ return &m_options
; }
2296 class CommandOptions
: public Options
{
2298 CommandOptions() = default;
2300 ~CommandOptions() override
= default;
2302 Status
SetOptionValue(uint32_t option_idx
, llvm::StringRef option_arg
,
2303 ExecutionContext
*execution_context
) override
{
2305 const int short_option
= m_getopt_table
[option_idx
].val
;
2307 switch (short_option
) {
2309 m_filename
.assign(std::string(option_arg
));
2315 llvm_unreachable("Unimplemented option");
2321 void OptionParsingStarting(ExecutionContext
*execution_context
) override
{
2326 llvm::ArrayRef
<OptionDefinition
> GetDefinitions() override
{
2327 return llvm::ArrayRef(g_breakpoint_write_options
);
2330 // Instance variables to hold the values for command options.
2332 std::string m_filename
;
2333 bool m_append
= false;
2337 void DoExecute(Args
&command
, CommandReturnObject
&result
) override
{
2338 Target
&target
= GetTarget();
2340 std::unique_lock
<std::recursive_mutex
> lock
;
2341 target
.GetBreakpointList().GetListMutex(lock
);
2343 BreakpointIDList valid_bp_ids
;
2344 if (!command
.empty()) {
2345 CommandObjectMultiwordBreakpoint::VerifyBreakpointIDs(
2346 command
, target
, result
, &valid_bp_ids
,
2347 BreakpointName::Permissions::PermissionKinds::listPerm
);
2349 if (!result
.Succeeded()) {
2350 result
.SetStatus(eReturnStatusFailed
);
2354 FileSpec
file_spec(m_options
.m_filename
);
2355 FileSystem::Instance().Resolve(file_spec
);
2356 Status error
= target
.SerializeBreakpointsToFile(file_spec
, valid_bp_ids
,
2357 m_options
.m_append
);
2358 if (!error
.Success()) {
2359 result
.AppendErrorWithFormat("error serializing breakpoints: %s.",
2365 CommandOptions m_options
;
2368 // CommandObjectMultiwordBreakpoint
2369 #pragma mark MultiwordBreakpoint
2371 CommandObjectMultiwordBreakpoint::CommandObjectMultiwordBreakpoint(
2372 CommandInterpreter
&interpreter
)
2373 : CommandObjectMultiword(
2374 interpreter
, "breakpoint",
2375 "Commands for operating on breakpoints (see 'help b' for shorthand.)",
2376 "breakpoint <subcommand> [<command-options>]") {
2377 CommandObjectSP
list_command_object(
2378 new CommandObjectBreakpointList(interpreter
));
2379 CommandObjectSP
enable_command_object(
2380 new CommandObjectBreakpointEnable(interpreter
));
2381 CommandObjectSP
disable_command_object(
2382 new CommandObjectBreakpointDisable(interpreter
));
2383 CommandObjectSP
clear_command_object(
2384 new CommandObjectBreakpointClear(interpreter
));
2385 CommandObjectSP
delete_command_object(
2386 new CommandObjectBreakpointDelete(interpreter
));
2387 CommandObjectSP
set_command_object(
2388 new CommandObjectBreakpointSet(interpreter
));
2389 CommandObjectSP
command_command_object(
2390 new CommandObjectBreakpointCommand(interpreter
));
2391 CommandObjectSP
modify_command_object(
2392 new CommandObjectBreakpointModify(interpreter
));
2393 CommandObjectSP
name_command_object(
2394 new CommandObjectBreakpointName(interpreter
));
2395 CommandObjectSP
write_command_object(
2396 new CommandObjectBreakpointWrite(interpreter
));
2397 CommandObjectSP
read_command_object(
2398 new CommandObjectBreakpointRead(interpreter
));
2400 list_command_object
->SetCommandName("breakpoint list");
2401 enable_command_object
->SetCommandName("breakpoint enable");
2402 disable_command_object
->SetCommandName("breakpoint disable");
2403 clear_command_object
->SetCommandName("breakpoint clear");
2404 delete_command_object
->SetCommandName("breakpoint delete");
2405 set_command_object
->SetCommandName("breakpoint set");
2406 command_command_object
->SetCommandName("breakpoint command");
2407 modify_command_object
->SetCommandName("breakpoint modify");
2408 name_command_object
->SetCommandName("breakpoint name");
2409 write_command_object
->SetCommandName("breakpoint write");
2410 read_command_object
->SetCommandName("breakpoint read");
2412 LoadSubCommand("list", list_command_object
);
2413 LoadSubCommand("enable", enable_command_object
);
2414 LoadSubCommand("disable", disable_command_object
);
2415 LoadSubCommand("clear", clear_command_object
);
2416 LoadSubCommand("delete", delete_command_object
);
2417 LoadSubCommand("set", set_command_object
);
2418 LoadSubCommand("command", command_command_object
);
2419 LoadSubCommand("modify", modify_command_object
);
2420 LoadSubCommand("name", name_command_object
);
2421 LoadSubCommand("write", write_command_object
);
2422 LoadSubCommand("read", read_command_object
);
2425 CommandObjectMultiwordBreakpoint::~CommandObjectMultiwordBreakpoint() = default;
2427 void CommandObjectMultiwordBreakpoint::VerifyIDs(
2428 Args
&args
, Target
&target
, bool allow_locations
,
2429 CommandReturnObject
&result
, BreakpointIDList
*valid_ids
,
2430 BreakpointName::Permissions ::PermissionKinds purpose
) {
2431 // args can be strings representing 1). integers (for breakpoint ids)
2432 // 2). the full breakpoint & location
2433 // canonical representation
2434 // 3). the word "to" or a hyphen,
2435 // representing a range (in which case there
2436 // had *better* be an entry both before &
2437 // after of one of the first two types.
2438 // 4). A breakpoint name
2439 // If args is empty, we will use the last created breakpoint (if there is
2445 if (target
.GetLastCreatedBreakpoint()) {
2446 valid_ids
->AddBreakpointID(BreakpointID(
2447 target
.GetLastCreatedBreakpoint()->GetID(), LLDB_INVALID_BREAK_ID
));
2448 result
.SetStatus(eReturnStatusSuccessFinishNoResult
);
2451 "No breakpoint specified and no last created breakpoint.");
2456 // Create a new Args variable to use; copy any non-breakpoint-id-ranges stuff
2457 // directly from the old ARGS to the new TEMP_ARGS. Do not copy breakpoint
2458 // id range strings over; instead generate a list of strings for all the
2459 // breakpoint ids in the range, and shove all of those breakpoint id strings
2462 if (llvm::Error err
= BreakpointIDList::FindAndReplaceIDRanges(
2463 args
, &target
, allow_locations
, purpose
, temp_args
)) {
2464 result
.SetError(std::move(err
));
2467 result
.SetStatus(eReturnStatusSuccessFinishNoResult
);
2469 // NOW, convert the list of breakpoint id strings in TEMP_ARGS into an actual
2470 // BreakpointIDList:
2472 for (llvm::StringRef temp_arg
: temp_args
.GetArgumentArrayRef())
2473 if (auto bp_id
= BreakpointID::ParseCanonicalReference(temp_arg
))
2474 valid_ids
->AddBreakpointID(*bp_id
);
2476 // At this point, all of the breakpoint ids that the user passed in have
2477 // been converted to breakpoint IDs and put into valid_ids.
2479 // Now that we've converted everything from args into a list of breakpoint
2480 // ids, go through our tentative list of breakpoint id's and verify that
2481 // they correspond to valid/currently set breakpoints.
2483 const size_t count
= valid_ids
->GetSize();
2484 for (size_t i
= 0; i
< count
; ++i
) {
2485 BreakpointID cur_bp_id
= valid_ids
->GetBreakpointIDAtIndex(i
);
2486 Breakpoint
*breakpoint
=
2487 target
.GetBreakpointByID(cur_bp_id
.GetBreakpointID()).get();
2488 if (breakpoint
!= nullptr) {
2489 const size_t num_locations
= breakpoint
->GetNumLocations();
2490 if (static_cast<size_t>(cur_bp_id
.GetLocationID()) > num_locations
) {
2491 StreamString id_str
;
2492 BreakpointID::GetCanonicalReference(
2493 &id_str
, cur_bp_id
.GetBreakpointID(), cur_bp_id
.GetLocationID());
2494 i
= valid_ids
->GetSize() + 1;
2495 result
.AppendErrorWithFormat(
2496 "'%s' is not a currently valid breakpoint/location id.\n",
2500 i
= valid_ids
->GetSize() + 1;
2501 result
.AppendErrorWithFormat(
2502 "'%d' is not a currently valid breakpoint ID.\n",
2503 cur_bp_id
.GetBreakpointID());