1 //===-- CommandObjectBreakpoint.cpp -----------------------------*- C++ -*-===//
3 // The LLVM Compiler Infrastructure
5 // This file is distributed under the University of Illinois Open Source
6 // License. See LICENSE.TXT for details.
8 //===----------------------------------------------------------------------===//
14 // Other libraries and framework includes
16 #include "CommandObjectBreakpoint.h"
17 #include "CommandObjectBreakpointCommand.h"
18 #include "lldb/Breakpoint/Breakpoint.h"
19 #include "lldb/Breakpoint/BreakpointIDList.h"
20 #include "lldb/Breakpoint/BreakpointLocation.h"
21 #include "lldb/Host/OptionParser.h"
22 #include "lldb/Interpreter/CommandCompletions.h"
23 #include "lldb/Interpreter/CommandInterpreter.h"
24 #include "lldb/Interpreter/CommandReturnObject.h"
25 #include "lldb/Interpreter/OptionValueBoolean.h"
26 #include "lldb/Interpreter/OptionValueString.h"
27 #include "lldb/Interpreter/OptionValueUInt64.h"
28 #include "lldb/Interpreter/Options.h"
29 #include "lldb/Target/Language.h"
30 #include "lldb/Target/StackFrame.h"
31 #include "lldb/Target/Target.h"
32 #include "lldb/Target/Thread.h"
33 #include "lldb/Target/ThreadSpec.h"
34 #include "lldb/Utility/RegularExpression.h"
35 #include "lldb/Utility/StreamString.h"
38 using namespace lldb_private;
40 static void AddBreakpointDescription(Stream *s, Breakpoint *bp,
41 lldb::DescriptionLevel level) {
43 bp->GetDescription(s, level, true);
48 //-------------------------------------------------------------------------
49 // Modifiable Breakpoint Options
50 //-------------------------------------------------------------------------
51 #pragma mark Modify::CommandOptions
52 static OptionDefinition g_breakpoint_modify_options[] = {
54 { LLDB_OPT_SET_1, false, "ignore-count", 'i', OptionParser::eRequiredArgument, nullptr, nullptr, 0, eArgTypeCount, "Set the number of times this breakpoint is skipped before stopping." },
55 { LLDB_OPT_SET_1, false, "one-shot", 'o', OptionParser::eRequiredArgument, nullptr, nullptr, 0, eArgTypeBoolean, "The breakpoint is deleted the first time it stop causes a stop." },
56 { LLDB_OPT_SET_1, false, "thread-index", 'x', OptionParser::eRequiredArgument, nullptr, nullptr, 0, eArgTypeThreadIndex, "The breakpoint stops only for the thread whose index matches this argument." },
57 { LLDB_OPT_SET_1, false, "thread-id", 't', OptionParser::eRequiredArgument, nullptr, nullptr, 0, eArgTypeThreadID, "The breakpoint stops only for the thread whose TID matches this argument." },
58 { LLDB_OPT_SET_1, false, "thread-name", 'T', OptionParser::eRequiredArgument, nullptr, nullptr, 0, eArgTypeThreadName, "The breakpoint stops only for the thread whose thread name matches this argument." },
59 { LLDB_OPT_SET_1, false, "queue-name", 'q', OptionParser::eRequiredArgument, nullptr, nullptr, 0, eArgTypeQueueName, "The breakpoint stops only for threads in the queue whose name is given by this argument." },
60 { LLDB_OPT_SET_1, false, "condition", 'c', OptionParser::eRequiredArgument, nullptr, nullptr, 0, eArgTypeExpression, "The breakpoint stops only if this condition expression evaluates to true." },
61 { LLDB_OPT_SET_1, false, "auto-continue",'G', OptionParser::eRequiredArgument, nullptr, nullptr, 0, eArgTypeBoolean, "The breakpoint will auto-continue after running its commands." },
62 { LLDB_OPT_SET_2, false, "enable", 'e', OptionParser::eNoArgument, nullptr, nullptr, 0, eArgTypeNone, "Enable the breakpoint." },
63 { LLDB_OPT_SET_3, false, "disable", 'd', OptionParser::eNoArgument, nullptr, nullptr, 0, eArgTypeNone, "Disable the breakpoint." },
64 { LLDB_OPT_SET_4, false, "command", 'C', OptionParser::eRequiredArgument, nullptr, nullptr, 0, eArgTypeCommand, "A command to run when the breakpoint is hit, can be provided more than once, the commands will get run in order left to right." },
67 class lldb_private::BreakpointOptionGroup : public OptionGroup
70 BreakpointOptionGroup() :
74 ~BreakpointOptionGroup() override = default;
76 llvm::ArrayRef<OptionDefinition> GetDefinitions() override {
77 return llvm::makeArrayRef(g_breakpoint_modify_options);
80 Status SetOptionValue(uint32_t option_idx, llvm::StringRef option_arg,
81 ExecutionContext *execution_context) override {
83 const int short_option = g_breakpoint_modify_options[option_idx].short_option;
85 switch (short_option) {
87 // Normally an empty breakpoint condition marks is as unset.
88 // But we need to say it was passed in.
89 m_bp_opts.SetCondition(option_arg.str().c_str());
90 m_bp_opts.m_set_flags.Set(BreakpointOptions::eCondition);
93 m_commands.push_back(option_arg);
96 m_bp_opts.SetEnabled(false);
99 m_bp_opts.SetEnabled(true);
103 value = Args::StringToBoolean(option_arg, false, &success);
105 m_bp_opts.SetAutoContinue(value);
107 error.SetErrorStringWithFormat(
108 "invalid boolean value '%s' passed for -G option",
109 option_arg.str().c_str());
114 uint32_t ignore_count;
115 if (option_arg.getAsInteger(0, ignore_count))
116 error.SetErrorStringWithFormat("invalid ignore count '%s'",
117 option_arg.str().c_str());
119 m_bp_opts.SetIgnoreCount(ignore_count);
124 value = Args::StringToBoolean(option_arg, false, &success);
126 m_bp_opts.SetOneShot(value);
128 error.SetErrorStringWithFormat(
129 "invalid boolean value '%s' passed for -o option",
130 option_arg.str().c_str());
134 lldb::tid_t thread_id = LLDB_INVALID_THREAD_ID;
135 if (option_arg[0] != '\0') {
136 if (option_arg.getAsInteger(0, thread_id))
137 error.SetErrorStringWithFormat("invalid thread id string '%s'",
138 option_arg.str().c_str());
140 m_bp_opts.SetThreadID(thread_id);
144 m_bp_opts.GetThreadSpec()->SetName(option_arg.str().c_str());
147 m_bp_opts.GetThreadSpec()->SetQueueName(option_arg.str().c_str());
151 uint32_t thread_index = UINT32_MAX;
152 if (option_arg[0] != '\n') {
153 if (option_arg.getAsInteger(0, thread_index))
154 error.SetErrorStringWithFormat("invalid thread index string '%s'",
155 option_arg.str().c_str());
157 m_bp_opts.GetThreadSpec()->SetIndex(thread_index);
161 error.SetErrorStringWithFormat("unrecognized option '%c'",
169 void OptionParsingStarting(ExecutionContext *execution_context) override {
174 Status OptionParsingFinished(ExecutionContext *execution_context) override {
175 if (!m_commands.empty())
177 if (!m_commands.empty())
179 auto cmd_data = llvm::make_unique<BreakpointOptions::CommandData>();
181 for (std::string &str : m_commands)
182 cmd_data->user_source.AppendString(str);
184 cmd_data->stop_on_error = true;
185 m_bp_opts.SetCommandDataCallback(cmd_data);
191 const BreakpointOptions &GetBreakpointOptions()
196 std::vector<std::string> m_commands;
197 BreakpointOptions m_bp_opts;
200 static OptionDefinition g_breakpoint_dummy_options[] = {
202 { LLDB_OPT_SET_1, false, "dummy-breakpoints", 'D', OptionParser::eNoArgument, nullptr, nullptr, 0, eArgTypeNone, "Act on Dummy breakpoints - i.e. breakpoints set before a file is provided, "
203 "which prime new targets." },
207 class BreakpointDummyOptionGroup : public OptionGroup
210 BreakpointDummyOptionGroup() :
213 ~BreakpointDummyOptionGroup() override = default;
215 llvm::ArrayRef<OptionDefinition> GetDefinitions() override {
216 return llvm::makeArrayRef(g_breakpoint_dummy_options);
219 Status SetOptionValue(uint32_t option_idx, llvm::StringRef option_arg,
220 ExecutionContext *execution_context) override {
222 const int short_option = g_breakpoint_modify_options[option_idx].short_option;
224 switch (short_option) {
229 error.SetErrorStringWithFormat("unrecognized option '%c'",
237 void OptionParsingStarting(ExecutionContext *execution_context) override {
245 // If an additional option set beyond LLDB_OPTION_SET_10 is added, make sure to
246 // update the numbers passed to LLDB_OPT_SET_FROM_TO(...) appropriately.
247 #define LLDB_OPT_FILE (LLDB_OPT_SET_FROM_TO(1, 9) & ~LLDB_OPT_SET_2)
248 #define LLDB_OPT_NOT_10 (LLDB_OPT_SET_FROM_TO(1, 10) & ~LLDB_OPT_SET_10)
249 #define LLDB_OPT_SKIP_PROLOGUE (LLDB_OPT_SET_1 | LLDB_OPT_SET_FROM_TO(3, 8))
250 #define LLDB_OPT_OFFSET_APPLIES (LLDB_OPT_SET_1 | LLDB_OPT_SET_FROM_TO(3, 8))
251 #define LLDB_OPT_MOVE_TO_NEAREST_CODE (LLDB_OPT_SET_1 | LLDB_OPT_SET_9)
252 #define LLDB_OPT_EXPR_LANGUAGE (LLDB_OPT_SET_FROM_TO(3, 8))
254 static OptionDefinition g_breakpoint_set_options[] = {
256 { LLDB_OPT_NOT_10, false, "shlib", 's', OptionParser::eRequiredArgument, nullptr, nullptr, CommandCompletions::eModuleCompletion, eArgTypeShlibName, "Set the breakpoint only in this shared library. Can repeat this option "
257 "multiple times to specify multiple shared libraries." },
258 { LLDB_OPT_SET_ALL, false, "hardware", 'H', OptionParser::eNoArgument, nullptr, nullptr, 0, eArgTypeNone, "Require the breakpoint to use hardware breakpoints." },
259 { LLDB_OPT_FILE, false, "file", 'f', OptionParser::eRequiredArgument, nullptr, nullptr, CommandCompletions::eSourceFileCompletion, eArgTypeFilename, "Specifies the source file in which to set this breakpoint. Note, by default "
260 "lldb only looks for files that are #included if they use the standard include "
261 "file extensions. To set breakpoints on .c/.cpp/.m/.mm files that are "
262 "#included, set target.inline-breakpoint-strategy to \"always\"." },
263 { LLDB_OPT_SET_1, true, "line", 'l', OptionParser::eRequiredArgument, nullptr, nullptr, 0, eArgTypeLineNum, "Specifies the line number on which to set this breakpoint." },
265 // Comment out this option for the moment, as we don't actually use it, but will in the future.
266 // This way users won't see it, but the infrastructure is left in place.
267 // { 0, false, "column", 'C', OptionParser::eRequiredArgument, nullptr, "<column>",
268 // "Set the breakpoint by source location at this particular column."},
270 { LLDB_OPT_SET_2, true, "address", 'a', OptionParser::eRequiredArgument, nullptr, nullptr, 0, eArgTypeAddressOrExpression, "Set the breakpoint at the specified address. If the address maps uniquely to "
271 "a particular binary, then the address will be converted to a \"file\" "
272 "address, so that the breakpoint will track that binary+offset no matter where "
273 "the binary eventually loads. Alternately, if you also specify the module - "
274 "with the -s option - then the address will be treated as a file address in "
275 "that module, and resolved accordingly. Again, this will allow lldb to track "
276 "that offset on subsequent reloads. The module need not have been loaded at "
277 "the time you specify this breakpoint, and will get resolved when the module "
279 { LLDB_OPT_SET_3, true, "name", 'n', OptionParser::eRequiredArgument, nullptr, nullptr, CommandCompletions::eSymbolCompletion, eArgTypeFunctionName, "Set the breakpoint by function name. Can be repeated multiple times to make "
280 "one breakpoint for multiple names" },
281 { LLDB_OPT_SET_9, false, "source-regexp-function", 'X', OptionParser::eRequiredArgument, nullptr, nullptr, CommandCompletions::eSymbolCompletion, eArgTypeFunctionName, "When used with '-p' limits the source regex to source contained in the named "
282 "functions. Can be repeated multiple times." },
283 { LLDB_OPT_SET_4, true, "fullname", 'F', OptionParser::eRequiredArgument, nullptr, nullptr, CommandCompletions::eSymbolCompletion, eArgTypeFullName, "Set the breakpoint by fully qualified function names. For C++ this means "
284 "namespaces and all arguments, and for Objective C this means a full function "
285 "prototype with class and selector. Can be repeated multiple times to make "
286 "one breakpoint for multiple names." },
287 { LLDB_OPT_SET_5, true, "selector", 'S', OptionParser::eRequiredArgument, nullptr, nullptr, 0, eArgTypeSelector, "Set the breakpoint by ObjC selector name. Can be repeated multiple times to "
288 "make one breakpoint for multiple Selectors." },
289 { LLDB_OPT_SET_6, true, "method", 'M', OptionParser::eRequiredArgument, nullptr, nullptr, 0, eArgTypeMethod, "Set the breakpoint by C++ method names. Can be repeated multiple times to "
290 "make one breakpoint for multiple methods." },
291 { LLDB_OPT_SET_7, true, "func-regex", 'r', OptionParser::eRequiredArgument, nullptr, nullptr, 0, eArgTypeRegularExpression, "Set the breakpoint by function name, evaluating a regular-expression to find "
292 "the function name(s)." },
293 { LLDB_OPT_SET_8, true, "basename", 'b', OptionParser::eRequiredArgument, nullptr, nullptr, CommandCompletions::eSymbolCompletion, eArgTypeFunctionName, "Set the breakpoint by function basename (C++ namespaces and arguments will be "
294 "ignored). Can be repeated multiple times to make one breakpoint for multiple "
296 { LLDB_OPT_SET_9, true, "source-pattern-regexp", 'p', OptionParser::eRequiredArgument, nullptr, nullptr, 0, eArgTypeRegularExpression, "Set the breakpoint by specifying a regular expression which is matched "
297 "against the source text in a source file or files specified with the -f "
298 "option. The -f option can be specified more than once. If no source files "
299 "are specified, uses the current \"default source file\". If you want to "
300 "match against all source files, pass the \"--all-files\" option." },
301 { LLDB_OPT_SET_9, false, "all-files", 'A', OptionParser::eNoArgument, nullptr, nullptr, 0, eArgTypeNone, "All files are searched for source pattern matches." },
302 { LLDB_OPT_SET_10, true, "language-exception", 'E', OptionParser::eRequiredArgument, nullptr, nullptr, 0, eArgTypeLanguage, "Set the breakpoint on exceptions thrown by the specified language (without "
303 "options, on throw but not catch.)" },
304 { LLDB_OPT_SET_10, false, "on-throw", 'w', OptionParser::eRequiredArgument, nullptr, nullptr, 0, eArgTypeBoolean, "Set the breakpoint on exception throW." },
305 { LLDB_OPT_SET_10, false, "on-catch", 'h', OptionParser::eRequiredArgument, nullptr, nullptr, 0, eArgTypeBoolean, "Set the breakpoint on exception catcH." },
307 // Don't add this option till it actually does something useful...
308 // { LLDB_OPT_SET_10, false, "exception-typename", 'O', OptionParser::eRequiredArgument, nullptr, nullptr, 0, eArgTypeTypeName,
309 // "The breakpoint will only stop if an exception Object of this type is thrown. Can be repeated multiple times to stop for multiple object types" },
311 { LLDB_OPT_EXPR_LANGUAGE, false, "language", 'L', OptionParser::eRequiredArgument, nullptr, nullptr, 0, eArgTypeLanguage, "Specifies the Language to use when interpreting the breakpoint's expression "
312 "(note: currently only implemented for setting breakpoints on identifiers). "
313 "If not set the target.language setting is used." },
314 { LLDB_OPT_SKIP_PROLOGUE, false, "skip-prologue", 'K', OptionParser::eRequiredArgument, nullptr, nullptr, 0, eArgTypeBoolean, "sKip the prologue if the breakpoint is at the beginning of a function. "
315 "If not set the target.skip-prologue setting is used." },
316 { LLDB_OPT_SET_ALL, false, "breakpoint-name", 'N', OptionParser::eRequiredArgument, nullptr, nullptr, 0, eArgTypeBreakpointName, "Adds this to the list of names for this breakpoint." },
317 { LLDB_OPT_OFFSET_APPLIES, false, "address-slide", 'R', OptionParser::eRequiredArgument, nullptr, nullptr, 0, eArgTypeAddress, "Add the specified offset to whatever address(es) the breakpoint resolves to. "
318 "At present this applies the offset directly as given, and doesn't try to align it to instruction boundaries." },
319 { LLDB_OPT_MOVE_TO_NEAREST_CODE, false, "move-to-nearest-code", 'm', OptionParser::eRequiredArgument, nullptr, nullptr, 0, eArgTypeBoolean, "Move breakpoints to nearest code. If not set the target.move-to-nearest-code "
320 "setting is used." },
324 //-------------------------------------------------------------------------
325 // CommandObjectBreakpointSet
326 //-------------------------------------------------------------------------
328 class CommandObjectBreakpointSet : public CommandObjectParsed {
330 typedef enum BreakpointSetType {
334 eSetTypeFunctionName,
335 eSetTypeFunctionRegexp,
336 eSetTypeSourceRegexp,
340 CommandObjectBreakpointSet(CommandInterpreter &interpreter)
341 : CommandObjectParsed(
342 interpreter, "breakpoint set",
343 "Sets a breakpoint or set of breakpoints in the executable.",
344 "breakpoint set <cmd-options>"),
345 m_bp_opts(), m_options() {
346 // We're picking up all the normal options, commands and disable.
347 m_all_options.Append(&m_bp_opts,
348 LLDB_OPT_SET_1 | LLDB_OPT_SET_3 | LLDB_OPT_SET_4,
350 m_all_options.Append(&m_dummy_options, LLDB_OPT_SET_1, LLDB_OPT_SET_ALL);
351 m_all_options.Append(&m_options);
352 m_all_options.Finalize();
355 ~CommandObjectBreakpointSet() override = default;
357 Options *GetOptions() override { return &m_all_options; }
359 class CommandOptions : public OptionGroup {
362 : OptionGroup(), m_condition(), m_filenames(), m_line_num(0), m_column(0),
363 m_func_names(), m_func_name_type_mask(eFunctionNameTypeNone),
364 m_func_regexp(), m_source_text_regexp(), m_modules(), m_load_addr(),
365 m_catch_bp(false), m_throw_bp(true), m_hardware(false),
366 m_exception_language(eLanguageTypeUnknown),
367 m_language(lldb::eLanguageTypeUnknown),
368 m_skip_prologue(eLazyBoolCalculate),
369 m_all_files(false), m_move_to_nearest_code(eLazyBoolCalculate) {}
371 ~CommandOptions() override = default;
373 Status SetOptionValue(uint32_t option_idx, llvm::StringRef option_arg,
374 ExecutionContext *execution_context) override {
376 const int short_option = g_breakpoint_set_options[option_idx].short_option;
378 switch (short_option) {
380 m_load_addr = Args::StringToAddress(execution_context, option_arg,
381 LLDB_INVALID_ADDRESS, &error);
389 m_func_names.push_back(option_arg);
390 m_func_name_type_mask |= eFunctionNameTypeBase;
394 if (option_arg.getAsInteger(0, m_column))
395 error.SetErrorStringWithFormat("invalid column number: %s",
396 option_arg.str().c_str());
400 LanguageType language = Language::GetLanguageTypeFromString(option_arg);
403 case eLanguageTypeC89:
405 case eLanguageTypeC99:
406 case eLanguageTypeC11:
407 m_exception_language = eLanguageTypeC;
409 case eLanguageTypeC_plus_plus:
410 case eLanguageTypeC_plus_plus_03:
411 case eLanguageTypeC_plus_plus_11:
412 case eLanguageTypeC_plus_plus_14:
413 m_exception_language = eLanguageTypeC_plus_plus;
415 case eLanguageTypeObjC:
416 m_exception_language = eLanguageTypeObjC;
418 case eLanguageTypeObjC_plus_plus:
419 error.SetErrorStringWithFormat(
420 "Set exception breakpoints separately for c++ and objective-c");
422 case eLanguageTypeUnknown:
423 error.SetErrorStringWithFormat(
424 "Unknown language type: '%s' for exception breakpoint",
425 option_arg.str().c_str());
428 error.SetErrorStringWithFormat(
429 "Unsupported language type: '%s' for exception breakpoint",
430 option_arg.str().c_str());
435 m_filenames.AppendIfUnique(FileSpec(option_arg, false));
439 m_func_names.push_back(option_arg);
440 m_func_name_type_mask |= eFunctionNameTypeFull;
445 m_catch_bp = Args::StringToBoolean(option_arg, true, &success);
447 error.SetErrorStringWithFormat(
448 "Invalid boolean value for on-catch option: '%s'",
449 option_arg.str().c_str());
459 value = Args::StringToBoolean(option_arg, true, &success);
461 m_skip_prologue = eLazyBoolYes;
463 m_skip_prologue = eLazyBoolNo;
466 error.SetErrorStringWithFormat(
467 "Invalid boolean value for skip prologue option: '%s'",
468 option_arg.str().c_str());
472 if (option_arg.getAsInteger(0, m_line_num))
473 error.SetErrorStringWithFormat("invalid line number: %s.",
474 option_arg.str().c_str());
478 m_language = Language::GetLanguageTypeFromString(option_arg);
479 if (m_language == eLanguageTypeUnknown)
480 error.SetErrorStringWithFormat(
481 "Unknown language type: '%s' for breakpoint",
482 option_arg.str().c_str());
488 value = Args::StringToBoolean(option_arg, true, &success);
490 m_move_to_nearest_code = eLazyBoolYes;
492 m_move_to_nearest_code = eLazyBoolNo;
495 error.SetErrorStringWithFormat(
496 "Invalid boolean value for move-to-nearest-code option: '%s'",
497 option_arg.str().c_str());
502 m_func_names.push_back(option_arg);
503 m_func_name_type_mask |= eFunctionNameTypeMethod;
507 m_func_names.push_back(option_arg);
508 m_func_name_type_mask |= eFunctionNameTypeAuto;
512 if (BreakpointID::StringIsBreakpointName(option_arg, error))
513 m_breakpoint_names.push_back(option_arg);
515 error.SetErrorStringWithFormat("Invalid breakpoint name: %s",
516 option_arg.str().c_str());
521 lldb::addr_t tmp_offset_addr;
523 Args::StringToAddress(execution_context, option_arg, 0, &error);
525 m_offset_addr = tmp_offset_addr;
529 m_exception_extra_args.AppendArgument("-O");
530 m_exception_extra_args.AppendArgument(option_arg);
534 m_source_text_regexp.assign(option_arg);
538 m_func_regexp.assign(option_arg);
542 m_modules.AppendIfUnique(FileSpec(option_arg, false));
546 m_func_names.push_back(option_arg);
547 m_func_name_type_mask |= eFunctionNameTypeSelector;
552 m_throw_bp = Args::StringToBoolean(option_arg, true, &success);
554 error.SetErrorStringWithFormat(
555 "Invalid boolean value for on-throw option: '%s'",
556 option_arg.str().c_str());
560 m_source_regex_func_names.insert(option_arg);
564 error.SetErrorStringWithFormat("unrecognized option '%c'",
572 void OptionParsingStarting(ExecutionContext *execution_context) override {
576 m_func_names.clear();
577 m_func_name_type_mask = eFunctionNameTypeNone;
578 m_func_regexp.clear();
579 m_source_text_regexp.clear();
581 m_load_addr = LLDB_INVALID_ADDRESS;
586 m_exception_language = eLanguageTypeUnknown;
587 m_language = lldb::eLanguageTypeUnknown;
588 m_skip_prologue = eLazyBoolCalculate;
589 m_breakpoint_names.clear();
591 m_exception_extra_args.Clear();
592 m_move_to_nearest_code = eLazyBoolCalculate;
593 m_source_regex_func_names.clear();
596 llvm::ArrayRef<OptionDefinition> GetDefinitions() override {
597 return llvm::makeArrayRef(g_breakpoint_set_options);
600 // Instance variables to hold the values for command options.
602 std::string m_condition;
603 FileSpecList m_filenames;
606 std::vector<std::string> m_func_names;
607 std::vector<std::string> m_breakpoint_names;
608 uint32_t m_func_name_type_mask;
609 std::string m_func_regexp;
610 std::string m_source_text_regexp;
611 FileSpecList m_modules;
612 lldb::addr_t m_load_addr;
613 lldb::addr_t m_offset_addr;
616 bool m_hardware; // Request to use hardware breakpoints
617 lldb::LanguageType m_exception_language;
618 lldb::LanguageType m_language;
619 LazyBool m_skip_prologue;
621 Args m_exception_extra_args;
622 LazyBool m_move_to_nearest_code;
623 std::unordered_set<std::string> m_source_regex_func_names;
627 bool DoExecute(Args &command, CommandReturnObject &result) override {
628 Target *target = GetSelectedOrDummyTarget(m_dummy_options.m_use_dummy);
630 if (target == nullptr) {
631 result.AppendError("Invalid target. Must set target before setting "
632 "breakpoints (see 'target create' command).");
633 result.SetStatus(eReturnStatusFailed);
637 // The following are the various types of breakpoints that could be set:
638 // 1). -f -l -p [-s -g] (setting breakpoint by source location)
639 // 2). -a [-s -g] (setting breakpoint by address)
640 // 3). -n [-s -g] (setting breakpoint by function name)
641 // 4). -r [-s -g] (setting breakpoint by function name regular
643 // 5). -p -f (setting a breakpoint by comparing a reg-exp
645 // 6). -E [-w -h] (setting a breakpoint for exceptions for a
648 BreakpointSetType break_type = eSetTypeInvalid;
650 if (m_options.m_line_num != 0)
651 break_type = eSetTypeFileAndLine;
652 else if (m_options.m_load_addr != LLDB_INVALID_ADDRESS)
653 break_type = eSetTypeAddress;
654 else if (!m_options.m_func_names.empty())
655 break_type = eSetTypeFunctionName;
656 else if (!m_options.m_func_regexp.empty())
657 break_type = eSetTypeFunctionRegexp;
658 else if (!m_options.m_source_text_regexp.empty())
659 break_type = eSetTypeSourceRegexp;
660 else if (m_options.m_exception_language != eLanguageTypeUnknown)
661 break_type = eSetTypeException;
663 BreakpointSP bp_sp = nullptr;
664 FileSpec module_spec;
665 const bool internal = false;
667 // If the user didn't specify skip-prologue, having an offset should turn
669 if (m_options.m_offset_addr != 0 &&
670 m_options.m_skip_prologue == eLazyBoolCalculate)
671 m_options.m_skip_prologue = eLazyBoolNo;
673 switch (break_type) {
674 case eSetTypeFileAndLine: // Breakpoint by source position
677 const size_t num_files = m_options.m_filenames.GetSize();
678 if (num_files == 0) {
679 if (!GetDefaultFile(target, file, result)) {
680 result.AppendError("No file supplied and no default file available.");
681 result.SetStatus(eReturnStatusFailed);
684 } else if (num_files > 1) {
685 result.AppendError("Only one file at a time is allowed for file and "
686 "line breakpoints.");
687 result.SetStatus(eReturnStatusFailed);
690 file = m_options.m_filenames.GetFileSpecAtIndex(0);
692 // Only check for inline functions if
693 LazyBool check_inlines = eLazyBoolCalculate;
695 bp_sp = target->CreateBreakpoint(&(m_options.m_modules),
697 m_options.m_line_num,
698 m_options.m_offset_addr,
700 m_options.m_skip_prologue,
702 m_options.m_hardware,
703 m_options.m_move_to_nearest_code);
706 case eSetTypeAddress: // Breakpoint by address
708 // If a shared library has been specified, make an lldb_private::Address
709 // with the library, and use that. That way the address breakpoint
710 // will track the load location of the library.
711 size_t num_modules_specified = m_options.m_modules.GetSize();
712 if (num_modules_specified == 1) {
713 const FileSpec *file_spec =
714 m_options.m_modules.GetFileSpecPointerAtIndex(0);
715 bp_sp = target->CreateAddressInModuleBreakpoint(m_options.m_load_addr,
717 m_options.m_hardware);
718 } else if (num_modules_specified == 0) {
719 bp_sp = target->CreateBreakpoint(m_options.m_load_addr, internal,
720 m_options.m_hardware);
722 result.AppendError("Only one shared library can be specified for "
723 "address breakpoints.");
724 result.SetStatus(eReturnStatusFailed);
729 case eSetTypeFunctionName: // Breakpoint by function name
731 uint32_t name_type_mask = m_options.m_func_name_type_mask;
733 if (name_type_mask == 0)
734 name_type_mask = eFunctionNameTypeAuto;
736 bp_sp = target->CreateBreakpoint(&(m_options.m_modules),
737 &(m_options.m_filenames),
738 m_options.m_func_names,
740 m_options.m_language,
741 m_options.m_offset_addr,
742 m_options.m_skip_prologue,
744 m_options.m_hardware);
747 case eSetTypeFunctionRegexp: // Breakpoint by regular expression function
750 RegularExpression regexp(m_options.m_func_regexp);
751 if (!regexp.IsValid()) {
753 regexp.GetErrorAsCString(err_str, sizeof(err_str));
754 result.AppendErrorWithFormat(
755 "Function name regular expression could not be compiled: \"%s\"",
757 result.SetStatus(eReturnStatusFailed);
761 bp_sp = target->CreateFuncRegexBreakpoint(&(m_options.m_modules),
762 &(m_options.m_filenames),
764 m_options.m_language,
765 m_options.m_skip_prologue,
767 m_options.m_hardware);
770 case eSetTypeSourceRegexp: // Breakpoint by regexp on source text.
772 const size_t num_files = m_options.m_filenames.GetSize();
774 if (num_files == 0 && !m_options.m_all_files) {
776 if (!GetDefaultFile(target, file, result)) {
778 "No files provided and could not find default file.");
779 result.SetStatus(eReturnStatusFailed);
782 m_options.m_filenames.Append(file);
786 RegularExpression regexp(m_options.m_source_text_regexp);
787 if (!regexp.IsValid()) {
789 regexp.GetErrorAsCString(err_str, sizeof(err_str));
790 result.AppendErrorWithFormat(
791 "Source text regular expression could not be compiled: \"%s\"",
793 result.SetStatus(eReturnStatusFailed);
797 target->CreateSourceRegexBreakpoint(&(m_options.m_modules),
798 &(m_options.m_filenames),
800 .m_source_regex_func_names,
803 m_options.m_hardware,
804 m_options.m_move_to_nearest_code);
806 case eSetTypeException: {
807 Status precond_error;
808 bp_sp = target->CreateExceptionBreakpoint(m_options.m_exception_language,
809 m_options.m_catch_bp,
810 m_options.m_throw_bp,
813 .m_exception_extra_args,
815 if (precond_error.Fail()) {
816 result.AppendErrorWithFormat(
817 "Error setting extra exception arguments: %s",
818 precond_error.AsCString());
819 target->RemoveBreakpointByID(bp_sp->GetID());
820 result.SetStatus(eReturnStatusFailed);
828 // Now set the various options that were passed in:
830 bp_sp->GetOptions()->CopyOverSetOptions(m_bp_opts.GetBreakpointOptions());
832 if (!m_options.m_breakpoint_names.empty()) {
834 for (auto name : m_options.m_breakpoint_names) {
835 target->AddNameToBreakpoint(bp_sp, name.c_str(), name_error);
836 if (name_error.Fail()) {
837 result.AppendErrorWithFormat("Invalid breakpoint name: %s",
839 target->RemoveBreakpointByID(bp_sp->GetID());
840 result.SetStatus(eReturnStatusFailed);
848 Stream &output_stream = result.GetOutputStream();
849 const bool show_locations = false;
850 bp_sp->GetDescription(&output_stream, lldb::eDescriptionLevelInitial,
852 if (target == m_interpreter.GetDebugger().GetDummyTarget())
853 output_stream.Printf("Breakpoint set in dummy target, will get copied "
854 "into future targets.\n");
856 // Don't print out this warning for exception breakpoints. They can get
857 // set before the target is set, but we won't know how to actually set
858 // the breakpoint till we run.
859 if (bp_sp->GetNumLocations() == 0 && break_type != eSetTypeException) {
860 output_stream.Printf("WARNING: Unable to resolve breakpoint to any "
861 "actual locations.\n");
864 result.SetStatus(eReturnStatusSuccessFinishResult);
866 result.AppendError("Breakpoint creation failed: No breakpoint created.");
867 result.SetStatus(eReturnStatusFailed);
870 return result.Succeeded();
874 bool GetDefaultFile(Target *target, FileSpec &file,
875 CommandReturnObject &result) {
876 uint32_t default_line;
877 // First use the Source Manager's default file.
878 // Then use the current stack frame's file.
879 if (!target->GetSourceManager().GetDefaultFileAndLine(file, default_line)) {
880 StackFrame *cur_frame = m_exe_ctx.GetFramePtr();
881 if (cur_frame == nullptr) {
883 "No selected frame to use to find the default file.");
884 result.SetStatus(eReturnStatusFailed);
886 } else if (!cur_frame->HasDebugInformation()) {
887 result.AppendError("Cannot use the selected frame to find the default "
888 "file, it has no debug info.");
889 result.SetStatus(eReturnStatusFailed);
892 const SymbolContext &sc =
893 cur_frame->GetSymbolContext(eSymbolContextLineEntry);
894 if (sc.line_entry.file) {
895 file = sc.line_entry.file;
897 result.AppendError("Can't find the file for the selected frame to "
898 "use as the default file.");
899 result.SetStatus(eReturnStatusFailed);
907 BreakpointOptionGroup m_bp_opts;
908 BreakpointDummyOptionGroup m_dummy_options;
909 CommandOptions m_options;
910 OptionGroupOptions m_all_options;
913 //-------------------------------------------------------------------------
914 // CommandObjectBreakpointModify
915 //-------------------------------------------------------------------------
918 class CommandObjectBreakpointModify : public CommandObjectParsed {
920 CommandObjectBreakpointModify(CommandInterpreter &interpreter)
921 : CommandObjectParsed(interpreter, "breakpoint modify",
922 "Modify the options on a breakpoint or set of "
923 "breakpoints in the executable. "
924 "If no breakpoint is specified, acts on the last "
925 "created breakpoint. "
926 "With the exception of -e, -d and -i, passing an "
927 "empty argument clears the modification.",
930 CommandArgumentEntry arg;
931 CommandObject::AddIDsArgumentData(arg, eArgTypeBreakpointID,
932 eArgTypeBreakpointIDRange);
933 // Add the entry for the first argument for this command to the object's
935 m_arguments.push_back(arg);
937 m_options.Append(&m_bp_opts,
938 LLDB_OPT_SET_1 | LLDB_OPT_SET_2 | LLDB_OPT_SET_3,
940 m_options.Append(&m_dummy_opts, LLDB_OPT_SET_1, LLDB_OPT_SET_ALL);
941 m_options.Finalize();
944 ~CommandObjectBreakpointModify() override = default;
946 Options *GetOptions() override { return &m_options; }
949 bool DoExecute(Args &command, CommandReturnObject &result) override {
950 Target *target = GetSelectedOrDummyTarget(m_dummy_opts.m_use_dummy);
951 if (target == nullptr) {
952 result.AppendError("Invalid target. No existing target or breakpoints.");
953 result.SetStatus(eReturnStatusFailed);
957 std::unique_lock<std::recursive_mutex> lock;
958 target->GetBreakpointList().GetListMutex(lock);
960 BreakpointIDList valid_bp_ids;
962 CommandObjectMultiwordBreakpoint::VerifyBreakpointOrLocationIDs(
963 command, target, result, &valid_bp_ids,
964 BreakpointName::Permissions::PermissionKinds::disablePerm);
966 if (result.Succeeded()) {
967 const size_t count = valid_bp_ids.GetSize();
968 for (size_t i = 0; i < count; ++i) {
969 BreakpointID cur_bp_id = valid_bp_ids.GetBreakpointIDAtIndex(i);
971 if (cur_bp_id.GetBreakpointID() != LLDB_INVALID_BREAK_ID) {
973 target->GetBreakpointByID(cur_bp_id.GetBreakpointID()).get();
974 if (cur_bp_id.GetLocationID() != LLDB_INVALID_BREAK_ID) {
975 BreakpointLocation *location =
976 bp->FindLocationByID(cur_bp_id.GetLocationID()).get();
978 location->GetLocationOptions()
979 ->CopyOverSetOptions(m_bp_opts.GetBreakpointOptions());
982 ->CopyOverSetOptions(m_bp_opts.GetBreakpointOptions());
988 return result.Succeeded();
992 BreakpointOptionGroup m_bp_opts;
993 BreakpointDummyOptionGroup m_dummy_opts;
994 OptionGroupOptions m_options;
997 //-------------------------------------------------------------------------
998 // CommandObjectBreakpointEnable
999 //-------------------------------------------------------------------------
1002 class CommandObjectBreakpointEnable : public CommandObjectParsed {
1004 CommandObjectBreakpointEnable(CommandInterpreter &interpreter)
1005 : CommandObjectParsed(interpreter, "enable",
1006 "Enable the specified disabled breakpoint(s). If "
1007 "no breakpoints are specified, enable all of them.",
1009 CommandArgumentEntry arg;
1010 CommandObject::AddIDsArgumentData(arg, eArgTypeBreakpointID,
1011 eArgTypeBreakpointIDRange);
1012 // Add the entry for the first argument for this command to the object's
1013 // arguments vector.
1014 m_arguments.push_back(arg);
1017 ~CommandObjectBreakpointEnable() override = default;
1020 bool DoExecute(Args &command, CommandReturnObject &result) override {
1021 Target *target = GetSelectedOrDummyTarget();
1022 if (target == nullptr) {
1023 result.AppendError("Invalid target. No existing target or breakpoints.");
1024 result.SetStatus(eReturnStatusFailed);
1028 std::unique_lock<std::recursive_mutex> lock;
1029 target->GetBreakpointList().GetListMutex(lock);
1031 const BreakpointList &breakpoints = target->GetBreakpointList();
1033 size_t num_breakpoints = breakpoints.GetSize();
1035 if (num_breakpoints == 0) {
1036 result.AppendError("No breakpoints exist to be enabled.");
1037 result.SetStatus(eReturnStatusFailed);
1041 if (command.empty()) {
1042 // No breakpoint selected; enable all currently set breakpoints.
1043 target->EnableAllowedBreakpoints();
1044 result.AppendMessageWithFormat("All breakpoints enabled. (%" PRIu64
1046 (uint64_t)num_breakpoints);
1047 result.SetStatus(eReturnStatusSuccessFinishNoResult);
1049 // Particular breakpoint selected; enable that breakpoint.
1050 BreakpointIDList valid_bp_ids;
1051 CommandObjectMultiwordBreakpoint::VerifyBreakpointOrLocationIDs(
1052 command, target, result, &valid_bp_ids,
1053 BreakpointName::Permissions::PermissionKinds::disablePerm);
1055 if (result.Succeeded()) {
1056 int enable_count = 0;
1058 const size_t count = valid_bp_ids.GetSize();
1059 for (size_t i = 0; i < count; ++i) {
1060 BreakpointID cur_bp_id = valid_bp_ids.GetBreakpointIDAtIndex(i);
1062 if (cur_bp_id.GetBreakpointID() != LLDB_INVALID_BREAK_ID) {
1063 Breakpoint *breakpoint =
1064 target->GetBreakpointByID(cur_bp_id.GetBreakpointID()).get();
1065 if (cur_bp_id.GetLocationID() != LLDB_INVALID_BREAK_ID) {
1066 BreakpointLocation *location =
1067 breakpoint->FindLocationByID(cur_bp_id.GetLocationID()).get();
1069 location->SetEnabled(true);
1073 breakpoint->SetEnabled(true);
1078 result.AppendMessageWithFormat("%d breakpoints enabled.\n",
1079 enable_count + loc_count);
1080 result.SetStatus(eReturnStatusSuccessFinishNoResult);
1084 return result.Succeeded();
1088 //-------------------------------------------------------------------------
1089 // CommandObjectBreakpointDisable
1090 //-------------------------------------------------------------------------
1091 #pragma mark Disable
1093 class CommandObjectBreakpointDisable : public CommandObjectParsed {
1095 CommandObjectBreakpointDisable(CommandInterpreter &interpreter)
1096 : CommandObjectParsed(
1097 interpreter, "breakpoint disable",
1098 "Disable the specified breakpoint(s) without deleting "
1099 "them. If none are specified, disable all "
1103 "Disable the specified breakpoint(s) without deleting them. \
1104 If none are specified, disable all breakpoints."
1108 "Note: disabling a breakpoint will cause none of its locations to be hit \
1109 regardless of whether individual locations are enabled or disabled. After the sequence:"
1112 (lldb) break disable 1
1113 (lldb) break enable 1.1
1115 execution will NOT stop at location 1.1. To achieve that, type:
1117 (lldb) break disable 1.*
1118 (lldb) break enable 1.1
1121 "The first command disables all locations for breakpoint 1, \
1122 the second re-enables the first location.");
1124 CommandArgumentEntry arg;
1125 CommandObject::AddIDsArgumentData(arg, eArgTypeBreakpointID,
1126 eArgTypeBreakpointIDRange);
1127 // Add the entry for the first argument for this command to the object's
1128 // arguments vector.
1129 m_arguments.push_back(arg);
1132 ~CommandObjectBreakpointDisable() override = default;
1135 bool DoExecute(Args &command, CommandReturnObject &result) override {
1136 Target *target = GetSelectedOrDummyTarget();
1137 if (target == nullptr) {
1138 result.AppendError("Invalid target. No existing target or breakpoints.");
1139 result.SetStatus(eReturnStatusFailed);
1143 std::unique_lock<std::recursive_mutex> lock;
1144 target->GetBreakpointList().GetListMutex(lock);
1146 const BreakpointList &breakpoints = target->GetBreakpointList();
1147 size_t num_breakpoints = breakpoints.GetSize();
1149 if (num_breakpoints == 0) {
1150 result.AppendError("No breakpoints exist to be disabled.");
1151 result.SetStatus(eReturnStatusFailed);
1155 if (command.empty()) {
1156 // No breakpoint selected; disable all currently set breakpoints.
1157 target->DisableAllowedBreakpoints();
1158 result.AppendMessageWithFormat("All breakpoints disabled. (%" PRIu64
1160 (uint64_t)num_breakpoints);
1161 result.SetStatus(eReturnStatusSuccessFinishNoResult);
1163 // Particular breakpoint selected; disable that breakpoint.
1164 BreakpointIDList valid_bp_ids;
1166 CommandObjectMultiwordBreakpoint::VerifyBreakpointOrLocationIDs(
1167 command, target, result, &valid_bp_ids,
1168 BreakpointName::Permissions::PermissionKinds::disablePerm);
1170 if (result.Succeeded()) {
1171 int disable_count = 0;
1173 const size_t count = valid_bp_ids.GetSize();
1174 for (size_t i = 0; i < count; ++i) {
1175 BreakpointID cur_bp_id = valid_bp_ids.GetBreakpointIDAtIndex(i);
1177 if (cur_bp_id.GetBreakpointID() != LLDB_INVALID_BREAK_ID) {
1178 Breakpoint *breakpoint =
1179 target->GetBreakpointByID(cur_bp_id.GetBreakpointID()).get();
1180 if (cur_bp_id.GetLocationID() != LLDB_INVALID_BREAK_ID) {
1181 BreakpointLocation *location =
1182 breakpoint->FindLocationByID(cur_bp_id.GetLocationID()).get();
1184 location->SetEnabled(false);
1188 breakpoint->SetEnabled(false);
1193 result.AppendMessageWithFormat("%d breakpoints disabled.\n",
1194 disable_count + loc_count);
1195 result.SetStatus(eReturnStatusSuccessFinishNoResult);
1199 return result.Succeeded();
1203 //-------------------------------------------------------------------------
1204 // CommandObjectBreakpointList
1205 //-------------------------------------------------------------------------
1207 #pragma mark List::CommandOptions
1208 static OptionDefinition g_breakpoint_list_options[] = {
1210 { LLDB_OPT_SET_ALL, false, "internal", 'i', OptionParser::eNoArgument, nullptr, nullptr, 0, eArgTypeNone, "Show debugger internal breakpoints" },
1211 { LLDB_OPT_SET_1, false, "brief", 'b', OptionParser::eNoArgument, nullptr, nullptr, 0, eArgTypeNone, "Give a brief description of the breakpoint (no location info)." },
1212 // FIXME: We need to add an "internal" command, and then add this sort of thing to it.
1213 // But I need to see it for now, and don't want to wait.
1214 { LLDB_OPT_SET_2, false, "full", 'f', OptionParser::eNoArgument, nullptr, nullptr, 0, eArgTypeNone, "Give a full description of the breakpoint and its locations." },
1215 { LLDB_OPT_SET_3, false, "verbose", 'v', OptionParser::eNoArgument, nullptr, nullptr, 0, eArgTypeNone, "Explain everything we know about the breakpoint (for debugging debugger bugs)." },
1216 { LLDB_OPT_SET_ALL, false, "dummy-breakpoints", 'D', OptionParser::eNoArgument, nullptr, nullptr, 0, eArgTypeNone, "List Dummy breakpoints - i.e. breakpoints set before a file is provided, which prime new targets." },
1222 class CommandObjectBreakpointList : public CommandObjectParsed {
1224 CommandObjectBreakpointList(CommandInterpreter &interpreter)
1225 : CommandObjectParsed(
1226 interpreter, "breakpoint list",
1227 "List some or all breakpoints at configurable levels of detail.",
1230 CommandArgumentEntry arg;
1231 CommandArgumentData bp_id_arg;
1233 // Define the first (and only) variant of this arg.
1234 bp_id_arg.arg_type = eArgTypeBreakpointID;
1235 bp_id_arg.arg_repetition = eArgRepeatOptional;
1237 // There is only one variant this argument could be; put it into the
1239 arg.push_back(bp_id_arg);
1241 // Push the data for the first argument into the m_arguments vector.
1242 m_arguments.push_back(arg);
1245 ~CommandObjectBreakpointList() override = default;
1247 Options *GetOptions() override { return &m_options; }
1249 class CommandOptions : public Options {
1252 : Options(), m_level(lldb::eDescriptionLevelBrief), m_use_dummy(false) {
1255 ~CommandOptions() override = default;
1257 Status SetOptionValue(uint32_t option_idx, llvm::StringRef option_arg,
1258 ExecutionContext *execution_context) override {
1260 const int short_option = m_getopt_table[option_idx].val;
1262 switch (short_option) {
1264 m_level = lldb::eDescriptionLevelBrief;
1270 m_level = lldb::eDescriptionLevelFull;
1273 m_level = lldb::eDescriptionLevelVerbose;
1279 error.SetErrorStringWithFormat("unrecognized option '%c'",
1287 void OptionParsingStarting(ExecutionContext *execution_context) override {
1288 m_level = lldb::eDescriptionLevelFull;
1290 m_use_dummy = false;
1293 llvm::ArrayRef<OptionDefinition> GetDefinitions() override {
1294 return llvm::makeArrayRef(g_breakpoint_list_options);
1297 // Instance variables to hold the values for command options.
1299 lldb::DescriptionLevel m_level;
1306 bool DoExecute(Args &command, CommandReturnObject &result) override {
1307 Target *target = GetSelectedOrDummyTarget(m_options.m_use_dummy);
1309 if (target == nullptr) {
1310 result.AppendError("Invalid target. No current target or breakpoints.");
1311 result.SetStatus(eReturnStatusSuccessFinishNoResult);
1315 const BreakpointList &breakpoints =
1316 target->GetBreakpointList(m_options.m_internal);
1317 std::unique_lock<std::recursive_mutex> lock;
1318 target->GetBreakpointList(m_options.m_internal).GetListMutex(lock);
1320 size_t num_breakpoints = breakpoints.GetSize();
1322 if (num_breakpoints == 0) {
1323 result.AppendMessage("No breakpoints currently set.");
1324 result.SetStatus(eReturnStatusSuccessFinishNoResult);
1328 Stream &output_stream = result.GetOutputStream();
1330 if (command.empty()) {
1331 // No breakpoint selected; show info about all currently set breakpoints.
1332 result.AppendMessage("Current breakpoints:");
1333 for (size_t i = 0; i < num_breakpoints; ++i) {
1334 Breakpoint *breakpoint = breakpoints.GetBreakpointAtIndex(i).get();
1335 if (breakpoint->AllowList())
1336 AddBreakpointDescription(&output_stream, breakpoint,
1339 result.SetStatus(eReturnStatusSuccessFinishNoResult);
1341 // Particular breakpoints selected; show info about that breakpoint.
1342 BreakpointIDList valid_bp_ids;
1343 CommandObjectMultiwordBreakpoint::VerifyBreakpointOrLocationIDs(
1344 command, target, result, &valid_bp_ids,
1345 BreakpointName::Permissions::PermissionKinds::listPerm);
1347 if (result.Succeeded()) {
1348 for (size_t i = 0; i < valid_bp_ids.GetSize(); ++i) {
1349 BreakpointID cur_bp_id = valid_bp_ids.GetBreakpointIDAtIndex(i);
1350 Breakpoint *breakpoint =
1351 target->GetBreakpointByID(cur_bp_id.GetBreakpointID()).get();
1352 AddBreakpointDescription(&output_stream, breakpoint,
1355 result.SetStatus(eReturnStatusSuccessFinishNoResult);
1357 result.AppendError("Invalid breakpoint ID.");
1358 result.SetStatus(eReturnStatusFailed);
1362 return result.Succeeded();
1366 CommandOptions m_options;
1369 //-------------------------------------------------------------------------
1370 // CommandObjectBreakpointClear
1371 //-------------------------------------------------------------------------
1372 #pragma mark Clear::CommandOptions
1374 static OptionDefinition g_breakpoint_clear_options[] = {
1376 { LLDB_OPT_SET_1, false, "file", 'f', OptionParser::eRequiredArgument, nullptr, nullptr, CommandCompletions::eSourceFileCompletion, eArgTypeFilename, "Specify the breakpoint by source location in this particular file." },
1377 { LLDB_OPT_SET_1, true, "line", 'l', OptionParser::eRequiredArgument, nullptr, nullptr, 0, eArgTypeLineNum, "Specify the breakpoint by source location at this particular line." }
1383 class CommandObjectBreakpointClear : public CommandObjectParsed {
1385 typedef enum BreakpointClearType {
1387 eClearTypeFileAndLine
1388 } BreakpointClearType;
1390 CommandObjectBreakpointClear(CommandInterpreter &interpreter)
1391 : CommandObjectParsed(interpreter, "breakpoint clear",
1392 "Delete or disable breakpoints matching the "
1393 "specified source file and line.",
1394 "breakpoint clear <cmd-options>"),
1397 ~CommandObjectBreakpointClear() override = default;
1399 Options *GetOptions() override { return &m_options; }
1401 class CommandOptions : public Options {
1403 CommandOptions() : Options(), m_filename(), m_line_num(0) {}
1405 ~CommandOptions() override = default;
1407 Status SetOptionValue(uint32_t option_idx, llvm::StringRef option_arg,
1408 ExecutionContext *execution_context) override {
1410 const int short_option = m_getopt_table[option_idx].val;
1412 switch (short_option) {
1414 m_filename.assign(option_arg);
1418 option_arg.getAsInteger(0, m_line_num);
1422 error.SetErrorStringWithFormat("unrecognized option '%c'",
1430 void OptionParsingStarting(ExecutionContext *execution_context) override {
1435 llvm::ArrayRef<OptionDefinition> GetDefinitions() override {
1436 return llvm::makeArrayRef(g_breakpoint_clear_options);
1439 // Instance variables to hold the values for command options.
1441 std::string m_filename;
1442 uint32_t m_line_num;
1446 bool DoExecute(Args &command, CommandReturnObject &result) override {
1447 Target *target = GetSelectedOrDummyTarget();
1448 if (target == nullptr) {
1449 result.AppendError("Invalid target. No existing target or breakpoints.");
1450 result.SetStatus(eReturnStatusFailed);
1454 // The following are the various types of breakpoints that could be cleared:
1455 // 1). -f -l (clearing breakpoint by source location)
1457 BreakpointClearType break_type = eClearTypeInvalid;
1459 if (m_options.m_line_num != 0)
1460 break_type = eClearTypeFileAndLine;
1462 std::unique_lock<std::recursive_mutex> lock;
1463 target->GetBreakpointList().GetListMutex(lock);
1465 BreakpointList &breakpoints = target->GetBreakpointList();
1466 size_t num_breakpoints = breakpoints.GetSize();
1468 // Early return if there's no breakpoint at all.
1469 if (num_breakpoints == 0) {
1470 result.AppendError("Breakpoint clear: No breakpoint cleared.");
1471 result.SetStatus(eReturnStatusFailed);
1472 return result.Succeeded();
1475 // Find matching breakpoints and delete them.
1477 // First create a copy of all the IDs.
1478 std::vector<break_id_t> BreakIDs;
1479 for (size_t i = 0; i < num_breakpoints; ++i)
1480 BreakIDs.push_back(breakpoints.GetBreakpointAtIndex(i)->GetID());
1482 int num_cleared = 0;
1484 switch (break_type) {
1485 case eClearTypeFileAndLine: // Breakpoint by source position
1487 const ConstString filename(m_options.m_filename.c_str());
1488 BreakpointLocationCollection loc_coll;
1490 for (size_t i = 0; i < num_breakpoints; ++i) {
1491 Breakpoint *bp = breakpoints.FindBreakpointByID(BreakIDs[i]).get();
1493 if (bp->GetMatchingFileLine(filename, m_options.m_line_num, loc_coll)) {
1494 // If the collection size is 0, it's a full match and we can just
1495 // remove the breakpoint.
1496 if (loc_coll.GetSize() == 0) {
1497 bp->GetDescription(&ss, lldb::eDescriptionLevelBrief);
1499 target->RemoveBreakpointByID(bp->GetID());
1510 if (num_cleared > 0) {
1511 Stream &output_stream = result.GetOutputStream();
1512 output_stream.Printf("%d breakpoints cleared:\n", num_cleared);
1513 output_stream << ss.GetString();
1514 output_stream.EOL();
1515 result.SetStatus(eReturnStatusSuccessFinishNoResult);
1517 result.AppendError("Breakpoint clear: No breakpoint cleared.");
1518 result.SetStatus(eReturnStatusFailed);
1521 return result.Succeeded();
1525 CommandOptions m_options;
1528 //-------------------------------------------------------------------------
1529 // CommandObjectBreakpointDelete
1530 //-------------------------------------------------------------------------
1531 static OptionDefinition g_breakpoint_delete_options[] = {
1533 { LLDB_OPT_SET_1, false, "force", 'f', OptionParser::eNoArgument, nullptr, nullptr, 0, eArgTypeNone, "Delete all breakpoints without querying for confirmation." },
1534 { LLDB_OPT_SET_1, false, "dummy-breakpoints", 'D', OptionParser::eNoArgument, nullptr, nullptr, 0, eArgTypeNone, "Delete Dummy breakpoints - i.e. breakpoints set before a file is provided, which prime new targets." },
1540 class CommandObjectBreakpointDelete : public CommandObjectParsed {
1542 CommandObjectBreakpointDelete(CommandInterpreter &interpreter)
1543 : CommandObjectParsed(interpreter, "breakpoint delete",
1544 "Delete the specified breakpoint(s). If no "
1545 "breakpoints are specified, delete them all.",
1548 CommandArgumentEntry arg;
1549 CommandObject::AddIDsArgumentData(arg, eArgTypeBreakpointID,
1550 eArgTypeBreakpointIDRange);
1551 // Add the entry for the first argument for this command to the object's
1552 // arguments vector.
1553 m_arguments.push_back(arg);
1556 ~CommandObjectBreakpointDelete() override = default;
1558 Options *GetOptions() override { return &m_options; }
1560 class CommandOptions : public Options {
1562 CommandOptions() : Options(), m_use_dummy(false), m_force(false) {}
1564 ~CommandOptions() override = default;
1566 Status SetOptionValue(uint32_t option_idx, llvm::StringRef option_arg,
1567 ExecutionContext *execution_context) override {
1569 const int short_option = m_getopt_table[option_idx].val;
1571 switch (short_option) {
1581 error.SetErrorStringWithFormat("unrecognized option '%c'",
1589 void OptionParsingStarting(ExecutionContext *execution_context) override {
1590 m_use_dummy = false;
1594 llvm::ArrayRef<OptionDefinition> GetDefinitions() override {
1595 return llvm::makeArrayRef(g_breakpoint_delete_options);
1598 // Instance variables to hold the values for command options.
1604 bool DoExecute(Args &command, CommandReturnObject &result) override {
1605 Target *target = GetSelectedOrDummyTarget(m_options.m_use_dummy);
1607 if (target == nullptr) {
1608 result.AppendError("Invalid target. No existing target or breakpoints.");
1609 result.SetStatus(eReturnStatusFailed);
1613 std::unique_lock<std::recursive_mutex> lock;
1614 target->GetBreakpointList().GetListMutex(lock);
1616 const BreakpointList &breakpoints = target->GetBreakpointList();
1618 size_t num_breakpoints = breakpoints.GetSize();
1620 if (num_breakpoints == 0) {
1621 result.AppendError("No breakpoints exist to be deleted.");
1622 result.SetStatus(eReturnStatusFailed);
1626 if (command.empty()) {
1627 if (!m_options.m_force &&
1628 !m_interpreter.Confirm(
1629 "About to delete all breakpoints, do you want to do that?",
1631 result.AppendMessage("Operation cancelled...");
1633 target->RemoveAllowedBreakpoints();
1634 result.AppendMessageWithFormat(
1635 "All breakpoints removed. (%" PRIu64 " breakpoint%s)\n",
1636 (uint64_t)num_breakpoints, num_breakpoints > 1 ? "s" : "");
1638 result.SetStatus(eReturnStatusSuccessFinishNoResult);
1640 // Particular breakpoint selected; disable that breakpoint.
1641 BreakpointIDList valid_bp_ids;
1642 CommandObjectMultiwordBreakpoint::VerifyBreakpointOrLocationIDs(
1643 command, target, result, &valid_bp_ids,
1644 BreakpointName::Permissions::PermissionKinds::deletePerm);
1646 if (result.Succeeded()) {
1647 int delete_count = 0;
1648 int disable_count = 0;
1649 const size_t count = valid_bp_ids.GetSize();
1650 for (size_t i = 0; i < count; ++i) {
1651 BreakpointID cur_bp_id = valid_bp_ids.GetBreakpointIDAtIndex(i);
1653 if (cur_bp_id.GetBreakpointID() != LLDB_INVALID_BREAK_ID) {
1654 if (cur_bp_id.GetLocationID() != LLDB_INVALID_BREAK_ID) {
1655 Breakpoint *breakpoint =
1656 target->GetBreakpointByID(cur_bp_id.GetBreakpointID()).get();
1657 BreakpointLocation *location =
1658 breakpoint->FindLocationByID(cur_bp_id.GetLocationID()).get();
1659 // It makes no sense to try to delete individual locations, so we
1660 // disable them instead.
1662 location->SetEnabled(false);
1666 target->RemoveBreakpointByID(cur_bp_id.GetBreakpointID());
1671 result.AppendMessageWithFormat(
1672 "%d breakpoints deleted; %d breakpoint locations disabled.\n",
1673 delete_count, disable_count);
1674 result.SetStatus(eReturnStatusSuccessFinishNoResult);
1677 return result.Succeeded();
1681 CommandOptions m_options;
1684 //-------------------------------------------------------------------------
1685 // CommandObjectBreakpointName
1686 //-------------------------------------------------------------------------
1688 static OptionDefinition g_breakpoint_name_options[] = {
1690 {LLDB_OPT_SET_1, false, "name", 'N', OptionParser::eRequiredArgument, nullptr, nullptr, 0, eArgTypeBreakpointName, "Specifies a breakpoint name to use."},
1691 {LLDB_OPT_SET_2, false, "breakpoint-id", 'B', OptionParser::eRequiredArgument, nullptr, nullptr, 0, eArgTypeBreakpointID, "Specify a breakpoint ID to use."},
1692 {LLDB_OPT_SET_3, false, "dummy-breakpoints", 'D', OptionParser::eNoArgument, nullptr, nullptr, 0, eArgTypeNone, "Operate on Dummy breakpoints - i.e. breakpoints set before a file is provided, which prime new targets."},
1693 {LLDB_OPT_SET_4, false, "help-string", 'H', OptionParser::eRequiredArgument, nullptr, nullptr, 0, eArgTypeNone, "A help string describing the purpose of this name."},
1696 class BreakpointNameOptionGroup : public OptionGroup {
1698 BreakpointNameOptionGroup()
1699 : OptionGroup(), m_breakpoint(LLDB_INVALID_BREAK_ID), m_use_dummy(false) {
1702 ~BreakpointNameOptionGroup() override = default;
1704 llvm::ArrayRef<OptionDefinition> GetDefinitions() override {
1705 return llvm::makeArrayRef(g_breakpoint_name_options);
1708 Status SetOptionValue(uint32_t option_idx, llvm::StringRef option_arg,
1709 ExecutionContext *execution_context) override {
1711 const int short_option = g_breakpoint_name_options[option_idx].short_option;
1713 switch (short_option) {
1715 if (BreakpointID::StringIsBreakpointName(option_arg, error) &&
1717 m_name.SetValueFromString(option_arg);
1720 if (m_breakpoint.SetValueFromString(option_arg).Fail())
1721 error.SetErrorStringWithFormat(
1722 "unrecognized value \"%s\" for breakpoint",
1723 option_arg.str().c_str());
1726 if (m_use_dummy.SetValueFromString(option_arg).Fail())
1727 error.SetErrorStringWithFormat(
1728 "unrecognized value \"%s\" for use-dummy",
1729 option_arg.str().c_str());
1732 m_help_string.SetValueFromString(option_arg);
1736 error.SetErrorStringWithFormat("unrecognized short option '%c'",
1743 void OptionParsingStarting(ExecutionContext *execution_context) override {
1745 m_breakpoint.Clear();
1746 m_use_dummy.Clear();
1747 m_use_dummy.SetDefaultValue(false);
1748 m_help_string.Clear();
1751 OptionValueString m_name;
1752 OptionValueUInt64 m_breakpoint;
1753 OptionValueBoolean m_use_dummy;
1754 OptionValueString m_help_string;
1757 static OptionDefinition g_breakpoint_access_options[] = {
1759 {LLDB_OPT_SET_1, false, "allow-list", 'L', OptionParser::eRequiredArgument, nullptr, nullptr, 0, eArgTypeBoolean, "Determines whether the breakpoint will show up in break list if not referred to explicitly."},
1760 {LLDB_OPT_SET_2, false, "allow-disable", 'A', OptionParser::eRequiredArgument, nullptr, nullptr, 0, eArgTypeBoolean, "Determines whether the breakpoint can be disabled by name or when all breakpoints are disabled."},
1761 {LLDB_OPT_SET_3, false, "allow-delete", 'D', OptionParser::eRequiredArgument, nullptr, nullptr, 0, eArgTypeBoolean, "Determines whether the breakpoint can be deleted by name or when all breakpoints are deleted."},
1765 class BreakpointAccessOptionGroup : public OptionGroup
1768 BreakpointAccessOptionGroup() :
1772 ~BreakpointAccessOptionGroup() override = default;
1774 llvm::ArrayRef<OptionDefinition> GetDefinitions() override {
1775 return llvm::makeArrayRef(g_breakpoint_access_options);
1777 Status SetOptionValue(uint32_t option_idx, llvm::StringRef option_arg,
1778 ExecutionContext *execution_context) override {
1780 const int short_option
1781 = g_breakpoint_access_options[option_idx].short_option;
1783 switch (short_option) {
1785 bool value, success;
1786 value = Args::StringToBoolean(option_arg, false, &success);
1788 m_permissions.SetAllowList(value);
1790 error.SetErrorStringWithFormat(
1791 "invalid boolean value '%s' passed for -L option",
1792 option_arg.str().c_str());
1795 bool value, success;
1796 value = Args::StringToBoolean(option_arg, false, &success);
1798 m_permissions.SetAllowDisable(value);
1800 error.SetErrorStringWithFormat(
1801 "invalid boolean value '%s' passed for -L option",
1802 option_arg.str().c_str());
1805 bool value, success;
1806 value = Args::StringToBoolean(option_arg, false, &success);
1808 m_permissions.SetAllowDelete(value);
1810 error.SetErrorStringWithFormat(
1811 "invalid boolean value '%s' passed for -L option",
1812 option_arg.str().c_str());
1820 void OptionParsingStarting(ExecutionContext *execution_context) override {
1823 const BreakpointName::Permissions &GetPermissions() const
1825 return m_permissions;
1827 BreakpointName::Permissions m_permissions;
1830 class CommandObjectBreakpointNameConfigure : public CommandObjectParsed {
1832 CommandObjectBreakpointNameConfigure(CommandInterpreter &interpreter)
1833 : CommandObjectParsed(
1834 interpreter, "configure", "Configure the options for the breakpoint"
1836 "If you provide a breakpoint id, the options will be copied from "
1837 "the breakpoint, otherwise only the options specified will be set "
1839 "breakpoint name configure <command-options> "
1840 "<breakpoint-name-list>"),
1841 m_bp_opts(), m_option_group() {
1842 // Create the first variant for the first (and only) argument for this
1844 CommandArgumentEntry arg1;
1845 CommandArgumentData id_arg;
1846 id_arg.arg_type = eArgTypeBreakpointName;
1847 id_arg.arg_repetition = eArgRepeatOptional;
1848 arg1.push_back(id_arg);
1849 m_arguments.push_back(arg1);
1851 m_option_group.Append(&m_bp_opts,
1854 m_option_group.Append(&m_access_options,
1857 m_option_group.Append(&m_bp_id,
1858 LLDB_OPT_SET_2|LLDB_OPT_SET_4,
1860 m_option_group.Finalize();
1863 ~CommandObjectBreakpointNameConfigure() override = default;
1865 Options *GetOptions() override { return &m_option_group; }
1868 bool DoExecute(Args &command, CommandReturnObject &result) override {
1870 const size_t argc = command.GetArgumentCount();
1872 result.AppendError("No names provided.");
1873 result.SetStatus(eReturnStatusFailed);
1878 GetSelectedOrDummyTarget(false);
1880 if (target == nullptr) {
1881 result.AppendError("Invalid target. No existing target or breakpoints.");
1882 result.SetStatus(eReturnStatusFailed);
1886 std::unique_lock<std::recursive_mutex> lock;
1887 target->GetBreakpointList().GetListMutex(lock);
1889 // Make a pass through first to see that all the names are legal.
1890 for (auto &entry : command.entries()) {
1892 if (!BreakpointID::StringIsBreakpointName(entry.ref, error))
1894 result.AppendErrorWithFormat("Invalid breakpoint name: %s - %s",
1895 entry.c_str(), error.AsCString());
1896 result.SetStatus(eReturnStatusFailed);
1900 // Now configure them, we already pre-checked the names so we don't need
1901 // to check the error:
1903 if (m_bp_id.m_breakpoint.OptionWasSet())
1905 lldb::break_id_t bp_id = m_bp_id.m_breakpoint.GetUInt64Value();
1906 bp_sp = target->GetBreakpointByID(bp_id);
1909 result.AppendErrorWithFormatv("Could not find specified breakpoint {0}",
1911 result.SetStatus(eReturnStatusFailed);
1917 for (auto &entry : command.entries()) {
1918 ConstString name(entry.c_str());
1919 BreakpointName *bp_name = target->FindBreakpointName(name, true, error);
1922 if (m_bp_id.m_help_string.OptionWasSet())
1923 bp_name->SetHelp(m_bp_id.m_help_string.GetStringValue().str().c_str());
1926 target->ConfigureBreakpointName(*bp_name,
1927 *bp_sp->GetOptions(),
1928 m_access_options.GetPermissions());
1930 target->ConfigureBreakpointName(*bp_name,
1931 m_bp_opts.GetBreakpointOptions(),
1932 m_access_options.GetPermissions());
1938 BreakpointNameOptionGroup m_bp_id; // Only using the id part of this.
1939 BreakpointOptionGroup m_bp_opts;
1940 BreakpointAccessOptionGroup m_access_options;
1941 OptionGroupOptions m_option_group;
1944 class CommandObjectBreakpointNameAdd : public CommandObjectParsed {
1946 CommandObjectBreakpointNameAdd(CommandInterpreter &interpreter)
1947 : CommandObjectParsed(
1948 interpreter, "add", "Add a name to the breakpoints provided.",
1949 "breakpoint name add <command-options> <breakpoint-id-list>"),
1950 m_name_options(), m_option_group() {
1951 // Create the first variant for the first (and only) argument for this
1953 CommandArgumentEntry arg1;
1954 CommandArgumentData id_arg;
1955 id_arg.arg_type = eArgTypeBreakpointID;
1956 id_arg.arg_repetition = eArgRepeatOptional;
1957 arg1.push_back(id_arg);
1958 m_arguments.push_back(arg1);
1960 m_option_group.Append(&m_name_options, LLDB_OPT_SET_1, LLDB_OPT_SET_ALL);
1961 m_option_group.Finalize();
1964 ~CommandObjectBreakpointNameAdd() override = default;
1966 Options *GetOptions() override { return &m_option_group; }
1969 bool DoExecute(Args &command, CommandReturnObject &result) override {
1970 if (!m_name_options.m_name.OptionWasSet()) {
1971 result.SetError("No name option provided.");
1976 GetSelectedOrDummyTarget(m_name_options.m_use_dummy.GetCurrentValue());
1978 if (target == nullptr) {
1979 result.AppendError("Invalid target. No existing target or breakpoints.");
1980 result.SetStatus(eReturnStatusFailed);
1984 std::unique_lock<std::recursive_mutex> lock;
1985 target->GetBreakpointList().GetListMutex(lock);
1987 const BreakpointList &breakpoints = target->GetBreakpointList();
1989 size_t num_breakpoints = breakpoints.GetSize();
1990 if (num_breakpoints == 0) {
1991 result.SetError("No breakpoints, cannot add names.");
1992 result.SetStatus(eReturnStatusFailed);
1996 // Particular breakpoint selected; disable that breakpoint.
1997 BreakpointIDList valid_bp_ids;
1998 CommandObjectMultiwordBreakpoint::VerifyBreakpointIDs(
1999 command, target, result, &valid_bp_ids,
2000 BreakpointName::Permissions::PermissionKinds::listPerm);
2002 if (result.Succeeded()) {
2003 if (valid_bp_ids.GetSize() == 0) {
2004 result.SetError("No breakpoints specified, cannot add names.");
2005 result.SetStatus(eReturnStatusFailed);
2008 size_t num_valid_ids = valid_bp_ids.GetSize();
2009 const char *bp_name = m_name_options.m_name.GetCurrentValue();
2010 Status error; // This error reports illegal names, but we've already
2011 // checked that, so we don't need to check it again here.
2012 for (size_t index = 0; index < num_valid_ids; index++) {
2013 lldb::break_id_t bp_id =
2014 valid_bp_ids.GetBreakpointIDAtIndex(index).GetBreakpointID();
2015 BreakpointSP bp_sp = breakpoints.FindBreakpointByID(bp_id);
2016 target->AddNameToBreakpoint(bp_sp, bp_name, error);
2024 BreakpointNameOptionGroup m_name_options;
2025 OptionGroupOptions m_option_group;
2028 class CommandObjectBreakpointNameDelete : public CommandObjectParsed {
2030 CommandObjectBreakpointNameDelete(CommandInterpreter &interpreter)
2031 : CommandObjectParsed(
2032 interpreter, "delete",
2033 "Delete a name from the breakpoints provided.",
2034 "breakpoint name delete <command-options> <breakpoint-id-list>"),
2035 m_name_options(), m_option_group() {
2036 // Create the first variant for the first (and only) argument for this
2038 CommandArgumentEntry arg1;
2039 CommandArgumentData id_arg;
2040 id_arg.arg_type = eArgTypeBreakpointID;
2041 id_arg.arg_repetition = eArgRepeatOptional;
2042 arg1.push_back(id_arg);
2043 m_arguments.push_back(arg1);
2045 m_option_group.Append(&m_name_options, LLDB_OPT_SET_1, LLDB_OPT_SET_ALL);
2046 m_option_group.Finalize();
2049 ~CommandObjectBreakpointNameDelete() override = default;
2051 Options *GetOptions() override { return &m_option_group; }
2054 bool DoExecute(Args &command, CommandReturnObject &result) override {
2055 if (!m_name_options.m_name.OptionWasSet()) {
2056 result.SetError("No name option provided.");
2061 GetSelectedOrDummyTarget(m_name_options.m_use_dummy.GetCurrentValue());
2063 if (target == nullptr) {
2064 result.AppendError("Invalid target. No existing target or breakpoints.");
2065 result.SetStatus(eReturnStatusFailed);
2069 std::unique_lock<std::recursive_mutex> lock;
2070 target->GetBreakpointList().GetListMutex(lock);
2072 const BreakpointList &breakpoints = target->GetBreakpointList();
2074 size_t num_breakpoints = breakpoints.GetSize();
2075 if (num_breakpoints == 0) {
2076 result.SetError("No breakpoints, cannot delete names.");
2077 result.SetStatus(eReturnStatusFailed);
2081 // Particular breakpoint selected; disable that breakpoint.
2082 BreakpointIDList valid_bp_ids;
2083 CommandObjectMultiwordBreakpoint::VerifyBreakpointIDs(
2084 command, target, result, &valid_bp_ids,
2085 BreakpointName::Permissions::PermissionKinds::deletePerm);
2087 if (result.Succeeded()) {
2088 if (valid_bp_ids.GetSize() == 0) {
2089 result.SetError("No breakpoints specified, cannot delete names.");
2090 result.SetStatus(eReturnStatusFailed);
2093 ConstString bp_name(m_name_options.m_name.GetCurrentValue());
2094 size_t num_valid_ids = valid_bp_ids.GetSize();
2095 for (size_t index = 0; index < num_valid_ids; index++) {
2096 lldb::break_id_t bp_id =
2097 valid_bp_ids.GetBreakpointIDAtIndex(index).GetBreakpointID();
2098 BreakpointSP bp_sp = breakpoints.FindBreakpointByID(bp_id);
2099 target->RemoveNameFromBreakpoint(bp_sp, bp_name);
2107 BreakpointNameOptionGroup m_name_options;
2108 OptionGroupOptions m_option_group;
2111 class CommandObjectBreakpointNameList : public CommandObjectParsed {
2113 CommandObjectBreakpointNameList(CommandInterpreter &interpreter)
2114 : CommandObjectParsed(interpreter, "list",
2115 "List either the names for a breakpoint or info "
2116 "about a given name. With no arguments, lists all "
2118 "breakpoint name list <command-options>"),
2119 m_name_options(), m_option_group() {
2120 m_option_group.Append(&m_name_options, LLDB_OPT_SET_3, LLDB_OPT_SET_ALL);
2121 m_option_group.Finalize();
2124 ~CommandObjectBreakpointNameList() override = default;
2126 Options *GetOptions() override { return &m_option_group; }
2129 bool DoExecute(Args &command, CommandReturnObject &result) override {
2131 GetSelectedOrDummyTarget(m_name_options.m_use_dummy.GetCurrentValue());
2133 if (target == nullptr) {
2134 result.AppendError("Invalid target. No existing target or breakpoints.");
2135 result.SetStatus(eReturnStatusFailed);
2140 std::vector<std::string> name_list;
2141 if (command.empty()) {
2142 target->GetBreakpointNames(name_list);
2144 for (const Args::ArgEntry &arg : command)
2146 name_list.push_back(arg.c_str());
2150 if (name_list.empty()) {
2151 result.AppendMessage("No breakpoint names found.");
2153 for (const std::string &name_str : name_list) {
2154 const char *name = name_str.c_str();
2155 // First print out the options for the name:
2157 BreakpointName *bp_name = target->FindBreakpointName(ConstString(name),
2163 result.AppendMessageWithFormat("Name: %s\n", name);
2164 if (bp_name->GetDescription(&s, eDescriptionLevelFull))
2166 result.AppendMessage(s.GetString());
2169 std::unique_lock<std::recursive_mutex> lock;
2170 target->GetBreakpointList().GetListMutex(lock);
2172 BreakpointList &breakpoints = target->GetBreakpointList();
2173 bool any_set = false;
2174 for (BreakpointSP bp_sp : breakpoints.Breakpoints()) {
2175 if (bp_sp->MatchesName(name)) {
2178 bp_sp->GetDescription(&s, eDescriptionLevelBrief);
2180 result.AppendMessage(s.GetString());
2184 result.AppendMessage("No breakpoints using this name.");
2186 result.AppendMessageWithFormat("Name: %s not found.\n", name);
2194 BreakpointNameOptionGroup m_name_options;
2195 OptionGroupOptions m_option_group;
2198 //-------------------------------------------------------------------------
2199 // CommandObjectBreakpointName
2200 //-------------------------------------------------------------------------
2201 class CommandObjectBreakpointName : public CommandObjectMultiword {
2203 CommandObjectBreakpointName(CommandInterpreter &interpreter)
2204 : CommandObjectMultiword(
2205 interpreter, "name", "Commands to manage name tags for breakpoints",
2206 "breakpoint name <subcommand> [<command-options>]") {
2207 CommandObjectSP add_command_object(
2208 new CommandObjectBreakpointNameAdd(interpreter));
2209 CommandObjectSP delete_command_object(
2210 new CommandObjectBreakpointNameDelete(interpreter));
2211 CommandObjectSP list_command_object(
2212 new CommandObjectBreakpointNameList(interpreter));
2213 CommandObjectSP configure_command_object(
2214 new CommandObjectBreakpointNameConfigure(interpreter));
2216 LoadSubCommand("add", add_command_object);
2217 LoadSubCommand("delete", delete_command_object);
2218 LoadSubCommand("list", list_command_object);
2219 LoadSubCommand("configure", configure_command_object);
2222 ~CommandObjectBreakpointName() override = default;
2225 //-------------------------------------------------------------------------
2226 // CommandObjectBreakpointRead
2227 //-------------------------------------------------------------------------
2228 #pragma mark Read::CommandOptions
2229 static OptionDefinition g_breakpoint_read_options[] = {
2231 { LLDB_OPT_SET_ALL, true, "file", 'f', OptionParser::eRequiredArgument, nullptr, nullptr, CommandCompletions::eDiskFileCompletion, eArgTypeFilename, "The file from which to read the breakpoints." },
2232 {LLDB_OPT_SET_ALL, false, "breakpoint-name", 'N', OptionParser::eRequiredArgument, nullptr, nullptr, 0, eArgTypeBreakpointName, "Only read in breakpoints with this name."},
2238 class CommandObjectBreakpointRead : public CommandObjectParsed {
2240 CommandObjectBreakpointRead(CommandInterpreter &interpreter)
2241 : CommandObjectParsed(interpreter, "breakpoint read",
2242 "Read and set the breakpoints previously saved to "
2243 "a file with \"breakpoint write\". ",
2246 CommandArgumentEntry arg;
2247 CommandObject::AddIDsArgumentData(arg, eArgTypeBreakpointID,
2248 eArgTypeBreakpointIDRange);
2249 // Add the entry for the first argument for this command to the object's
2250 // arguments vector.
2251 m_arguments.push_back(arg);
2254 ~CommandObjectBreakpointRead() override = default;
2256 Options *GetOptions() override { return &m_options; }
2258 class CommandOptions : public Options {
2260 CommandOptions() : Options() {}
2262 ~CommandOptions() override = default;
2264 Status SetOptionValue(uint32_t option_idx, llvm::StringRef option_arg,
2265 ExecutionContext *execution_context) override {
2267 const int short_option = m_getopt_table[option_idx].val;
2269 switch (short_option) {
2271 m_filename.assign(option_arg);
2275 if (!BreakpointID::StringIsBreakpointName(llvm::StringRef(option_arg),
2277 error.SetErrorStringWithFormat("Invalid breakpoint name: %s",
2278 name_error.AsCString());
2280 m_names.push_back(option_arg);
2284 error.SetErrorStringWithFormat("unrecognized option '%c'",
2292 void OptionParsingStarting(ExecutionContext *execution_context) override {
2297 llvm::ArrayRef<OptionDefinition> GetDefinitions() override {
2298 return llvm::makeArrayRef(g_breakpoint_read_options);
2301 // Instance variables to hold the values for command options.
2303 std::string m_filename;
2304 std::vector<std::string> m_names;
2308 bool DoExecute(Args &command, CommandReturnObject &result) override {
2309 Target *target = GetSelectedOrDummyTarget();
2310 if (target == nullptr) {
2311 result.AppendError("Invalid target. No existing target or breakpoints.");
2312 result.SetStatus(eReturnStatusFailed);
2316 std::unique_lock<std::recursive_mutex> lock;
2317 target->GetBreakpointList().GetListMutex(lock);
2319 FileSpec input_spec(m_options.m_filename, true);
2320 BreakpointIDList new_bps;
2321 Status error = target->CreateBreakpointsFromFile(
2322 input_spec, m_options.m_names, new_bps);
2324 if (!error.Success()) {
2325 result.AppendError(error.AsCString());
2326 result.SetStatus(eReturnStatusFailed);
2330 Stream &output_stream = result.GetOutputStream();
2332 size_t num_breakpoints = new_bps.GetSize();
2333 if (num_breakpoints == 0) {
2334 result.AppendMessage("No breakpoints added.");
2336 // No breakpoint selected; show info about all currently set breakpoints.
2337 result.AppendMessage("New breakpoints:");
2338 for (size_t i = 0; i < num_breakpoints; ++i) {
2339 BreakpointID bp_id = new_bps.GetBreakpointIDAtIndex(i);
2340 Breakpoint *bp = target->GetBreakpointList()
2341 .FindBreakpointByID(bp_id.GetBreakpointID())
2344 bp->GetDescription(&output_stream, lldb::eDescriptionLevelInitial,
2348 return result.Succeeded();
2352 CommandOptions m_options;
2355 //-------------------------------------------------------------------------
2356 // CommandObjectBreakpointWrite
2357 //-------------------------------------------------------------------------
2358 #pragma mark Write::CommandOptions
2359 static OptionDefinition g_breakpoint_write_options[] = {
2361 { LLDB_OPT_SET_ALL, true, "file", 'f', OptionParser::eRequiredArgument, nullptr, nullptr, CommandCompletions::eDiskFileCompletion, eArgTypeFilename, "The file into which to write the breakpoints." },
2362 { LLDB_OPT_SET_ALL, false, "append",'a', OptionParser::eNoArgument, nullptr, nullptr, 0, eArgTypeNone, "Append to saved breakpoints file if it exists."},
2367 class CommandObjectBreakpointWrite : public CommandObjectParsed {
2369 CommandObjectBreakpointWrite(CommandInterpreter &interpreter)
2370 : CommandObjectParsed(interpreter, "breakpoint write",
2371 "Write the breakpoints listed to a file that can "
2372 "be read in with \"breakpoint read\". "
2373 "If given no arguments, writes all breakpoints.",
2376 CommandArgumentEntry arg;
2377 CommandObject::AddIDsArgumentData(arg, eArgTypeBreakpointID,
2378 eArgTypeBreakpointIDRange);
2379 // Add the entry for the first argument for this command to the object's
2380 // arguments vector.
2381 m_arguments.push_back(arg);
2384 ~CommandObjectBreakpointWrite() override = default;
2386 Options *GetOptions() override { return &m_options; }
2388 class CommandOptions : public Options {
2390 CommandOptions() : Options() {}
2392 ~CommandOptions() override = default;
2394 Status SetOptionValue(uint32_t option_idx, llvm::StringRef option_arg,
2395 ExecutionContext *execution_context) override {
2397 const int short_option = m_getopt_table[option_idx].val;
2399 switch (short_option) {
2401 m_filename.assign(option_arg);
2407 error.SetErrorStringWithFormat("unrecognized option '%c'",
2415 void OptionParsingStarting(ExecutionContext *execution_context) override {
2420 llvm::ArrayRef<OptionDefinition> GetDefinitions() override {
2421 return llvm::makeArrayRef(g_breakpoint_write_options);
2424 // Instance variables to hold the values for command options.
2426 std::string m_filename;
2427 bool m_append = false;
2431 bool DoExecute(Args &command, CommandReturnObject &result) override {
2432 Target *target = GetSelectedOrDummyTarget();
2433 if (target == nullptr) {
2434 result.AppendError("Invalid target. No existing target or breakpoints.");
2435 result.SetStatus(eReturnStatusFailed);
2439 std::unique_lock<std::recursive_mutex> lock;
2440 target->GetBreakpointList().GetListMutex(lock);
2442 BreakpointIDList valid_bp_ids;
2443 if (!command.empty()) {
2444 CommandObjectMultiwordBreakpoint::VerifyBreakpointIDs(
2445 command, target, result, &valid_bp_ids,
2446 BreakpointName::Permissions::PermissionKinds::listPerm);
2448 if (!result.Succeeded()) {
2449 result.SetStatus(eReturnStatusFailed);
2453 Status error = target->SerializeBreakpointsToFile(
2454 FileSpec(m_options.m_filename, true), valid_bp_ids, m_options.m_append);
2455 if (!error.Success()) {
2456 result.AppendErrorWithFormat("error serializing breakpoints: %s.",
2458 result.SetStatus(eReturnStatusFailed);
2460 return result.Succeeded();
2464 CommandOptions m_options;
2467 //-------------------------------------------------------------------------
2468 // CommandObjectMultiwordBreakpoint
2469 //-------------------------------------------------------------------------
2470 #pragma mark MultiwordBreakpoint
2472 CommandObjectMultiwordBreakpoint::CommandObjectMultiwordBreakpoint(
2473 CommandInterpreter &interpreter)
2474 : CommandObjectMultiword(
2475 interpreter, "breakpoint",
2476 "Commands for operating on breakpoints (see 'help b' for shorthand.)",
2477 "breakpoint <subcommand> [<command-options>]") {
2478 CommandObjectSP list_command_object(
2479 new CommandObjectBreakpointList(interpreter));
2480 CommandObjectSP enable_command_object(
2481 new CommandObjectBreakpointEnable(interpreter));
2482 CommandObjectSP disable_command_object(
2483 new CommandObjectBreakpointDisable(interpreter));
2484 CommandObjectSP clear_command_object(
2485 new CommandObjectBreakpointClear(interpreter));
2486 CommandObjectSP delete_command_object(
2487 new CommandObjectBreakpointDelete(interpreter));
2488 CommandObjectSP set_command_object(
2489 new CommandObjectBreakpointSet(interpreter));
2490 CommandObjectSP command_command_object(
2491 new CommandObjectBreakpointCommand(interpreter));
2492 CommandObjectSP modify_command_object(
2493 new CommandObjectBreakpointModify(interpreter));
2494 CommandObjectSP name_command_object(
2495 new CommandObjectBreakpointName(interpreter));
2496 CommandObjectSP write_command_object(
2497 new CommandObjectBreakpointWrite(interpreter));
2498 CommandObjectSP read_command_object(
2499 new CommandObjectBreakpointRead(interpreter));
2501 list_command_object->SetCommandName("breakpoint list");
2502 enable_command_object->SetCommandName("breakpoint enable");
2503 disable_command_object->SetCommandName("breakpoint disable");
2504 clear_command_object->SetCommandName("breakpoint clear");
2505 delete_command_object->SetCommandName("breakpoint delete");
2506 set_command_object->SetCommandName("breakpoint set");
2507 command_command_object->SetCommandName("breakpoint command");
2508 modify_command_object->SetCommandName("breakpoint modify");
2509 name_command_object->SetCommandName("breakpoint name");
2510 write_command_object->SetCommandName("breakpoint write");
2511 read_command_object->SetCommandName("breakpoint read");
2513 LoadSubCommand("list", list_command_object);
2514 LoadSubCommand("enable", enable_command_object);
2515 LoadSubCommand("disable", disable_command_object);
2516 LoadSubCommand("clear", clear_command_object);
2517 LoadSubCommand("delete", delete_command_object);
2518 LoadSubCommand("set", set_command_object);
2519 LoadSubCommand("command", command_command_object);
2520 LoadSubCommand("modify", modify_command_object);
2521 LoadSubCommand("name", name_command_object);
2522 LoadSubCommand("write", write_command_object);
2523 LoadSubCommand("read", read_command_object);
2526 CommandObjectMultiwordBreakpoint::~CommandObjectMultiwordBreakpoint() = default;
2528 void CommandObjectMultiwordBreakpoint::VerifyIDs(Args &args, Target *target,
2529 bool allow_locations,
2530 CommandReturnObject &result,
2531 BreakpointIDList *valid_ids,
2532 BreakpointName::Permissions
2535 // args can be strings representing 1). integers (for breakpoint ids)
2536 // 2). the full breakpoint & location
2537 // canonical representation
2538 // 3). the word "to" or a hyphen,
2539 // representing a range (in which case there
2540 // had *better* be an entry both before &
2541 // after of one of the first two types.
2542 // 4). A breakpoint name
2543 // If args is empty, we will use the last created breakpoint (if there is
2549 if (target->GetLastCreatedBreakpoint()) {
2550 valid_ids->AddBreakpointID(BreakpointID(
2551 target->GetLastCreatedBreakpoint()->GetID(), LLDB_INVALID_BREAK_ID));
2552 result.SetStatus(eReturnStatusSuccessFinishNoResult);
2555 "No breakpoint specified and no last created breakpoint.");
2556 result.SetStatus(eReturnStatusFailed);
2561 // Create a new Args variable to use; copy any non-breakpoint-id-ranges stuff
2562 // directly from the old ARGS to
2563 // the new TEMP_ARGS. Do not copy breakpoint id range strings over; instead
2564 // generate a list of strings for
2565 // all the breakpoint ids in the range, and shove all of those breakpoint id
2566 // strings into TEMP_ARGS.
2568 BreakpointIDList::FindAndReplaceIDRanges(args, target, allow_locations,
2569 purpose, result, temp_args);
2571 // NOW, convert the list of breakpoint id strings in TEMP_ARGS into an actual
2572 // BreakpointIDList:
2574 valid_ids->InsertStringArray(temp_args.GetConstArgumentVector(),
2575 temp_args.GetArgumentCount(), result);
2577 // At this point, all of the breakpoint ids that the user passed in have been
2578 // converted to breakpoint IDs
2579 // and put into valid_ids.
2581 if (result.Succeeded()) {
2582 // Now that we've converted everything from args into a list of breakpoint
2583 // ids, go through our tentative list
2584 // of breakpoint id's and verify that they correspond to valid/currently set
2587 const size_t count = valid_ids->GetSize();
2588 for (size_t i = 0; i < count; ++i) {
2589 BreakpointID cur_bp_id = valid_ids->GetBreakpointIDAtIndex(i);
2590 Breakpoint *breakpoint =
2591 target->GetBreakpointByID(cur_bp_id.GetBreakpointID()).get();
2592 if (breakpoint != nullptr) {
2593 const size_t num_locations = breakpoint->GetNumLocations();
2594 if (static_cast<size_t>(cur_bp_id.GetLocationID()) > num_locations) {
2595 StreamString id_str;
2596 BreakpointID::GetCanonicalReference(
2597 &id_str, cur_bp_id.GetBreakpointID(), cur_bp_id.GetLocationID());
2598 i = valid_ids->GetSize() + 1;
2599 result.AppendErrorWithFormat(
2600 "'%s' is not a currently valid breakpoint/location id.\n",
2602 result.SetStatus(eReturnStatusFailed);
2605 i = valid_ids->GetSize() + 1;
2606 result.AppendErrorWithFormat(
2607 "'%d' is not a currently valid breakpoint ID.\n",
2608 cur_bp_id.GetBreakpointID());
2609 result.SetStatus(eReturnStatusFailed);