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/Core/RegularExpression.h"
22 #include "lldb/Core/StreamString.h"
23 #include "lldb/Host/StringConvert.h"
24 #include "lldb/Interpreter/CommandCompletions.h"
25 #include "lldb/Interpreter/CommandInterpreter.h"
26 #include "lldb/Interpreter/CommandReturnObject.h"
27 #include "lldb/Interpreter/OptionValueBoolean.h"
28 #include "lldb/Interpreter/OptionValueString.h"
29 #include "lldb/Interpreter/OptionValueUInt64.h"
30 #include "lldb/Interpreter/Options.h"
31 #include "lldb/Target/Language.h"
32 #include "lldb/Target/StackFrame.h"
33 #include "lldb/Target/Target.h"
34 #include "lldb/Target/Thread.h"
35 #include "lldb/Target/ThreadSpec.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 // If an additional option set beyond LLDB_OPTION_SET_10 is added, make sure to
49 // update the numbers passed to LLDB_OPT_SET_FROM_TO(...) appropriately.
50 #define LLDB_OPT_FILE (LLDB_OPT_SET_FROM_TO(1, 9) & ~LLDB_OPT_SET_2)
51 #define LLDB_OPT_NOT_10 (LLDB_OPT_SET_FROM_TO(1, 10) & ~LLDB_OPT_SET_10)
52 #define LLDB_OPT_SKIP_PROLOGUE (LLDB_OPT_SET_1 | LLDB_OPT_SET_FROM_TO(3, 8))
53 #define LLDB_OPT_OFFSET_APPLIES (LLDB_OPT_SET_1 | LLDB_OPT_SET_FROM_TO(3, 8))
54 #define LLDB_OPT_MOVE_TO_NEAREST_CODE (LLDB_OPT_SET_1 | LLDB_OPT_SET_9)
55 #define LLDB_OPT_EXPR_LANGUAGE (LLDB_OPT_SET_FROM_TO(3, 8))
57 static OptionDefinition g_breakpoint_set_options[] = {
59 { 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 "
60 "multiple times to specify multiple shared libraries." },
61 { LLDB_OPT_SET_ALL, false, "ignore-count", 'i', OptionParser::eRequiredArgument, nullptr, nullptr, 0, eArgTypeCount, "Set the number of times this breakpoint is skipped before stopping." },
62 { LLDB_OPT_SET_ALL, false, "one-shot", 'o', OptionParser::eNoArgument, nullptr, nullptr, 0, eArgTypeNone, "The breakpoint is deleted the first time it causes a stop." },
63 { LLDB_OPT_SET_ALL, false, "condition", 'c', OptionParser::eRequiredArgument, nullptr, nullptr, 0, eArgTypeExpression, "The breakpoint stops only if this condition expression evaluates to true." },
64 { LLDB_OPT_SET_ALL, false, "thread-index", 'x', OptionParser::eRequiredArgument, nullptr, nullptr, 0, eArgTypeThreadIndex, "The breakpoint stops only for the thread whose indeX matches this argument." },
65 { LLDB_OPT_SET_ALL, false, "thread-id", 't', OptionParser::eRequiredArgument, nullptr, nullptr, 0, eArgTypeThreadID, "The breakpoint stops only for the thread whose TID matches this argument." },
66 { LLDB_OPT_SET_ALL, false, "thread-name", 'T', OptionParser::eRequiredArgument, nullptr, nullptr, 0, eArgTypeThreadName, "The breakpoint stops only for the thread whose thread name matches this "
68 { LLDB_OPT_SET_ALL, false, "hardware", 'H', OptionParser::eNoArgument, nullptr, nullptr, 0, eArgTypeNone, "Require the breakpoint to use hardware breakpoints." },
69 { LLDB_OPT_SET_ALL, false, "queue-name", 'q', OptionParser::eRequiredArgument, nullptr, nullptr, 0, eArgTypeQueueName, "The breakpoint stops only for threads in the queue whose name is given by "
71 { 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 "
72 "lldb only looks for files that are #included if they use the standard include "
73 "file extensions. To set breakpoints on .c/.cpp/.m/.mm files that are "
74 "#included, set target.inline-breakpoint-strategy to \"always\"." },
75 { LLDB_OPT_SET_1, true, "line", 'l', OptionParser::eRequiredArgument, nullptr, nullptr, 0, eArgTypeLineNum, "Specifies the line number on which to set this breakpoint." },
77 // Comment out this option for the moment, as we don't actually use it, but will in the future.
78 // This way users won't see it, but the infrastructure is left in place.
79 // { 0, false, "column", 'C', OptionParser::eRequiredArgument, nullptr, "<column>",
80 // "Set the breakpoint by source location at this particular column."},
82 { 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 "
83 "a particular binary, then the address will be converted to a \"file\" "
84 "address, so that the breakpoint will track that binary+offset no matter where "
85 "the binary eventually loads. Alternately, if you also specify the module - "
86 "with the -s option - then the address will be treated as a file address in "
87 "that module, and resolved accordingly. Again, this will allow lldb to track "
88 "that offset on subsequent reloads. The module need not have been loaded at "
89 "the time you specify this breakpoint, and will get resolved when the module "
91 { 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 "
92 "one breakpoint for multiple names" },
93 { 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 "
94 "functions. Can be repeated multiple times." },
95 { 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 "
96 "namespaces and all arguments, and for Objective C this means a full function "
97 "prototype with class and selector. Can be repeated multiple times to make "
98 "one breakpoint for multiple names." },
99 { 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 "
100 "make one breakpoint for multiple Selectors." },
101 { 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 "
102 "make one breakpoint for multiple methods." },
103 { 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 "
104 "the function name(s)." },
105 { 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 "
106 "ignored). Can be repeated multiple times to make one breakpoint for multiple "
108 { 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 "
109 "against the source text in a source file or files specified with the -f "
110 "option. The -f option can be specified more than once. If no source files "
111 "are specified, uses the current \"default source file\". If you want to "
112 "match against all source files, pass the \"--all-files\" option." },
113 { LLDB_OPT_SET_9, false, "all-files", 'A', OptionParser::eNoArgument, nullptr, nullptr, 0, eArgTypeNone, "All files are searched for source pattern matches." },
114 { 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 "
115 "options, on throw but not catch.)" },
116 { LLDB_OPT_SET_10, false, "on-throw", 'w', OptionParser::eRequiredArgument, nullptr, nullptr, 0, eArgTypeBoolean, "Set the breakpoint on exception throW." },
117 { LLDB_OPT_SET_10, false, "on-catch", 'h', OptionParser::eRequiredArgument, nullptr, nullptr, 0, eArgTypeBoolean, "Set the breakpoint on exception catcH." },
119 // Don't add this option till it actually does something useful...
120 // { LLDB_OPT_SET_10, false, "exception-typename", 'O', OptionParser::eRequiredArgument, nullptr, nullptr, 0, eArgTypeTypeName,
121 // "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" },
123 { LLDB_OPT_EXPR_LANGUAGE, false, "language", 'L', OptionParser::eRequiredArgument, nullptr, nullptr, 0, eArgTypeLanguage, "Specifies the Language to use when interpreting the breakpoint's expression "
124 "(note: currently only implemented for setting breakpoints on identifiers). "
125 "If not set the target.language setting is used." },
126 { 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. "
127 "If not set the target.skip-prologue setting is used." },
128 { LLDB_OPT_SET_ALL, false, "dummy-breakpoints", 'D', OptionParser::eNoArgument, nullptr, nullptr, 0, eArgTypeNone, "Sets Dummy breakpoints - i.e. breakpoints set before a file is provided, "
129 "which prime new targets." },
130 { LLDB_OPT_SET_ALL, false, "breakpoint-name", 'N', OptionParser::eRequiredArgument, nullptr, nullptr, 0, eArgTypeBreakpointName, "Adds this to the list of names for this breakpoint." },
131 { 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. "
132 "At present this applies the offset directly as given, and doesn't try to align it to instruction boundaries." },
133 { 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 "
134 "setting is used." },
138 //-------------------------------------------------------------------------
139 // CommandObjectBreakpointSet
140 //-------------------------------------------------------------------------
142 class CommandObjectBreakpointSet : public CommandObjectParsed {
144 typedef enum BreakpointSetType {
148 eSetTypeFunctionName,
149 eSetTypeFunctionRegexp,
150 eSetTypeSourceRegexp,
154 CommandObjectBreakpointSet(CommandInterpreter &interpreter)
155 : CommandObjectParsed(
156 interpreter, "breakpoint set",
157 "Sets a breakpoint or set of breakpoints in the executable.",
158 "breakpoint set <cmd-options>"),
161 ~CommandObjectBreakpointSet() override = default;
163 Options *GetOptions() override { return &m_options; }
165 class CommandOptions : public Options {
168 : Options(), m_condition(), m_filenames(), m_line_num(0), m_column(0),
169 m_func_names(), m_func_name_type_mask(eFunctionNameTypeNone),
170 m_func_regexp(), m_source_text_regexp(), m_modules(), m_load_addr(),
171 m_ignore_count(0), m_thread_id(LLDB_INVALID_THREAD_ID),
172 m_thread_index(UINT32_MAX), m_thread_name(), m_queue_name(),
173 m_catch_bp(false), m_throw_bp(true), m_hardware(false),
174 m_exception_language(eLanguageTypeUnknown),
175 m_language(lldb::eLanguageTypeUnknown),
176 m_skip_prologue(eLazyBoolCalculate), m_one_shot(false),
177 m_all_files(false), m_move_to_nearest_code(eLazyBoolCalculate) {}
179 ~CommandOptions() override = default;
181 Error SetOptionValue(uint32_t option_idx, llvm::StringRef option_arg,
182 ExecutionContext *execution_context) override {
184 const int short_option = m_getopt_table[option_idx].val;
186 switch (short_option) {
188 m_load_addr = Args::StringToAddress(execution_context, option_arg,
189 LLDB_INVALID_ADDRESS, &error);
197 m_func_names.push_back(option_arg);
198 m_func_name_type_mask |= eFunctionNameTypeBase;
202 if (option_arg.getAsInteger(0, m_column))
203 error.SetErrorStringWithFormat("invalid column number: %s",
204 option_arg.str().c_str());
208 m_condition.assign(option_arg);
216 LanguageType language = Language::GetLanguageTypeFromString(option_arg);
219 case eLanguageTypeC89:
221 case eLanguageTypeC99:
222 case eLanguageTypeC11:
223 m_exception_language = eLanguageTypeC;
225 case eLanguageTypeC_plus_plus:
226 case eLanguageTypeC_plus_plus_03:
227 case eLanguageTypeC_plus_plus_11:
228 case eLanguageTypeC_plus_plus_14:
229 m_exception_language = eLanguageTypeC_plus_plus;
231 case eLanguageTypeObjC:
232 m_exception_language = eLanguageTypeObjC;
234 case eLanguageTypeObjC_plus_plus:
235 error.SetErrorStringWithFormat(
236 "Set exception breakpoints separately for c++ and objective-c");
238 case eLanguageTypeUnknown:
239 error.SetErrorStringWithFormat(
240 "Unknown language type: '%s' for exception breakpoint",
241 option_arg.str().c_str());
244 error.SetErrorStringWithFormat(
245 "Unsupported language type: '%s' for exception breakpoint",
246 option_arg.str().c_str());
251 m_filenames.AppendIfUnique(FileSpec(option_arg, false));
255 m_func_names.push_back(option_arg);
256 m_func_name_type_mask |= eFunctionNameTypeFull;
261 m_catch_bp = Args::StringToBoolean(option_arg, true, &success);
263 error.SetErrorStringWithFormat(
264 "Invalid boolean value for on-catch option: '%s'",
265 option_arg.str().c_str());
273 if (option_arg.getAsInteger(0, m_ignore_count))
274 error.SetErrorStringWithFormat("invalid ignore count '%s'",
275 option_arg.str().c_str());
281 value = Args::StringToBoolean(option_arg, true, &success);
283 m_skip_prologue = eLazyBoolYes;
285 m_skip_prologue = eLazyBoolNo;
288 error.SetErrorStringWithFormat(
289 "Invalid boolean value for skip prologue option: '%s'",
290 option_arg.str().c_str());
294 if (option_arg.getAsInteger(0, m_line_num))
295 error.SetErrorStringWithFormat("invalid line number: %s.",
296 option_arg.str().c_str());
300 m_language = Language::GetLanguageTypeFromString(option_arg);
301 if (m_language == eLanguageTypeUnknown)
302 error.SetErrorStringWithFormat(
303 "Unknown language type: '%s' for breakpoint",
304 option_arg.str().c_str());
310 value = Args::StringToBoolean(option_arg, true, &success);
312 m_move_to_nearest_code = eLazyBoolYes;
314 m_move_to_nearest_code = eLazyBoolNo;
317 error.SetErrorStringWithFormat(
318 "Invalid boolean value for move-to-nearest-code option: '%s'",
319 option_arg.str().c_str());
324 m_func_names.push_back(option_arg);
325 m_func_name_type_mask |= eFunctionNameTypeMethod;
329 m_func_names.push_back(option_arg);
330 m_func_name_type_mask |= eFunctionNameTypeAuto;
334 if (BreakpointID::StringIsBreakpointName(option_arg, error))
335 m_breakpoint_names.push_back(option_arg);
337 error.SetErrorStringWithFormat("Invalid breakpoint name: %s",
338 option_arg.str().c_str());
343 lldb::addr_t tmp_offset_addr;
345 Args::StringToAddress(execution_context, option_arg, 0, &error);
347 m_offset_addr = tmp_offset_addr;
355 m_exception_extra_args.AppendArgument("-O");
356 m_exception_extra_args.AppendArgument(option_arg);
360 m_source_text_regexp.assign(option_arg);
364 m_queue_name.assign(option_arg);
368 m_func_regexp.assign(option_arg);
372 m_modules.AppendIfUnique(FileSpec(option_arg, false));
376 m_func_names.push_back(option_arg);
377 m_func_name_type_mask |= eFunctionNameTypeSelector;
381 if (option_arg.getAsInteger(0, m_thread_id))
382 error.SetErrorStringWithFormat("invalid thread id string '%s'",
383 option_arg.str().c_str());
387 m_thread_name.assign(option_arg);
392 m_throw_bp = Args::StringToBoolean(option_arg, true, &success);
394 error.SetErrorStringWithFormat(
395 "Invalid boolean value for on-throw option: '%s'",
396 option_arg.str().c_str());
400 if (option_arg.getAsInteger(0, m_thread_index))
401 error.SetErrorStringWithFormat("invalid thread index string '%s'",
402 option_arg.str().c_str());
406 m_source_regex_func_names.insert(option_arg);
410 error.SetErrorStringWithFormat("unrecognized option '%c'",
418 void OptionParsingStarting(ExecutionContext *execution_context) override {
423 m_func_names.clear();
424 m_func_name_type_mask = eFunctionNameTypeNone;
425 m_func_regexp.clear();
426 m_source_text_regexp.clear();
428 m_load_addr = LLDB_INVALID_ADDRESS;
431 m_thread_id = LLDB_INVALID_THREAD_ID;
432 m_thread_index = UINT32_MAX;
433 m_thread_name.clear();
434 m_queue_name.clear();
438 m_exception_language = eLanguageTypeUnknown;
439 m_language = lldb::eLanguageTypeUnknown;
440 m_skip_prologue = eLazyBoolCalculate;
443 m_breakpoint_names.clear();
445 m_exception_extra_args.Clear();
446 m_move_to_nearest_code = eLazyBoolCalculate;
447 m_source_regex_func_names.clear();
450 llvm::ArrayRef<OptionDefinition> GetDefinitions() override {
451 return llvm::makeArrayRef(g_breakpoint_set_options);
454 // Instance variables to hold the values for command options.
456 std::string m_condition;
457 FileSpecList m_filenames;
460 std::vector<std::string> m_func_names;
461 std::vector<std::string> m_breakpoint_names;
462 uint32_t m_func_name_type_mask;
463 std::string m_func_regexp;
464 std::string m_source_text_regexp;
465 FileSpecList m_modules;
466 lldb::addr_t m_load_addr;
467 lldb::addr_t m_offset_addr;
468 uint32_t m_ignore_count;
469 lldb::tid_t m_thread_id;
470 uint32_t m_thread_index;
471 std::string m_thread_name;
472 std::string m_queue_name;
475 bool m_hardware; // Request to use hardware breakpoints
476 lldb::LanguageType m_exception_language;
477 lldb::LanguageType m_language;
478 LazyBool m_skip_prologue;
482 Args m_exception_extra_args;
483 LazyBool m_move_to_nearest_code;
484 std::unordered_set<std::string> m_source_regex_func_names;
488 bool DoExecute(Args &command, CommandReturnObject &result) override {
489 Target *target = GetSelectedOrDummyTarget(m_options.m_use_dummy);
491 if (target == nullptr) {
492 result.AppendError("Invalid target. Must set target before setting "
493 "breakpoints (see 'target create' command).");
494 result.SetStatus(eReturnStatusFailed);
498 // The following are the various types of breakpoints that could be set:
499 // 1). -f -l -p [-s -g] (setting breakpoint by source location)
500 // 2). -a [-s -g] (setting breakpoint by address)
501 // 3). -n [-s -g] (setting breakpoint by function name)
502 // 4). -r [-s -g] (setting breakpoint by function name regular
504 // 5). -p -f (setting a breakpoint by comparing a reg-exp
506 // 6). -E [-w -h] (setting a breakpoint for exceptions for a
509 BreakpointSetType break_type = eSetTypeInvalid;
511 if (m_options.m_line_num != 0)
512 break_type = eSetTypeFileAndLine;
513 else if (m_options.m_load_addr != LLDB_INVALID_ADDRESS)
514 break_type = eSetTypeAddress;
515 else if (!m_options.m_func_names.empty())
516 break_type = eSetTypeFunctionName;
517 else if (!m_options.m_func_regexp.empty())
518 break_type = eSetTypeFunctionRegexp;
519 else if (!m_options.m_source_text_regexp.empty())
520 break_type = eSetTypeSourceRegexp;
521 else if (m_options.m_exception_language != eLanguageTypeUnknown)
522 break_type = eSetTypeException;
524 Breakpoint *bp = nullptr;
525 FileSpec module_spec;
526 const bool internal = false;
528 // If the user didn't specify skip-prologue, having an offset should turn
530 if (m_options.m_offset_addr != 0 &&
531 m_options.m_skip_prologue == eLazyBoolCalculate)
532 m_options.m_skip_prologue = eLazyBoolNo;
534 switch (break_type) {
535 case eSetTypeFileAndLine: // Breakpoint by source position
538 const size_t num_files = m_options.m_filenames.GetSize();
539 if (num_files == 0) {
540 if (!GetDefaultFile(target, file, result)) {
541 result.AppendError("No file supplied and no default file available.");
542 result.SetStatus(eReturnStatusFailed);
545 } else if (num_files > 1) {
546 result.AppendError("Only one file at a time is allowed for file and "
547 "line breakpoints.");
548 result.SetStatus(eReturnStatusFailed);
551 file = m_options.m_filenames.GetFileSpecAtIndex(0);
553 // Only check for inline functions if
554 LazyBool check_inlines = eLazyBoolCalculate;
557 ->CreateBreakpoint(&(m_options.m_modules), file,
558 m_options.m_line_num, m_options.m_offset_addr,
559 check_inlines, m_options.m_skip_prologue,
560 internal, m_options.m_hardware,
561 m_options.m_move_to_nearest_code)
565 case eSetTypeAddress: // Breakpoint by address
567 // If a shared library has been specified, make an lldb_private::Address
568 // with the library, and
569 // use that. That way the address breakpoint will track the load location
571 size_t num_modules_specified = m_options.m_modules.GetSize();
572 if (num_modules_specified == 1) {
573 const FileSpec *file_spec =
574 m_options.m_modules.GetFileSpecPointerAtIndex(0);
576 ->CreateAddressInModuleBreakpoint(m_options.m_load_addr,
578 m_options.m_hardware)
580 } else if (num_modules_specified == 0) {
582 ->CreateBreakpoint(m_options.m_load_addr, internal,
583 m_options.m_hardware)
586 result.AppendError("Only one shared library can be specified for "
587 "address breakpoints.");
588 result.SetStatus(eReturnStatusFailed);
593 case eSetTypeFunctionName: // Breakpoint by function name
595 uint32_t name_type_mask = m_options.m_func_name_type_mask;
597 if (name_type_mask == 0)
598 name_type_mask = eFunctionNameTypeAuto;
602 &(m_options.m_modules), &(m_options.m_filenames),
603 m_options.m_func_names, name_type_mask, m_options.m_language,
604 m_options.m_offset_addr, m_options.m_skip_prologue, internal,
605 m_options.m_hardware)
609 case eSetTypeFunctionRegexp: // Breakpoint by regular expression function
612 RegularExpression regexp(m_options.m_func_regexp);
613 if (!regexp.IsValid()) {
615 regexp.GetErrorAsCString(err_str, sizeof(err_str));
616 result.AppendErrorWithFormat(
617 "Function name regular expression could not be compiled: \"%s\"",
619 result.SetStatus(eReturnStatusFailed);
624 ->CreateFuncRegexBreakpoint(
625 &(m_options.m_modules), &(m_options.m_filenames), regexp,
626 m_options.m_language, m_options.m_skip_prologue, internal,
627 m_options.m_hardware)
631 case eSetTypeSourceRegexp: // Breakpoint by regexp on source text.
633 const size_t num_files = m_options.m_filenames.GetSize();
635 if (num_files == 0 && !m_options.m_all_files) {
637 if (!GetDefaultFile(target, file, result)) {
639 "No files provided and could not find default file.");
640 result.SetStatus(eReturnStatusFailed);
643 m_options.m_filenames.Append(file);
647 RegularExpression regexp(m_options.m_source_text_regexp);
648 if (!regexp.IsValid()) {
650 regexp.GetErrorAsCString(err_str, sizeof(err_str));
651 result.AppendErrorWithFormat(
652 "Source text regular expression could not be compiled: \"%s\"",
654 result.SetStatus(eReturnStatusFailed);
658 ->CreateSourceRegexBreakpoint(
659 &(m_options.m_modules), &(m_options.m_filenames),
660 m_options.m_source_regex_func_names, regexp, internal,
661 m_options.m_hardware, m_options.m_move_to_nearest_code)
664 case eSetTypeException: {
667 ->CreateExceptionBreakpoint(
668 m_options.m_exception_language, m_options.m_catch_bp,
669 m_options.m_throw_bp, internal,
670 &m_options.m_exception_extra_args, &precond_error)
672 if (precond_error.Fail()) {
673 result.AppendErrorWithFormat(
674 "Error setting extra exception arguments: %s",
675 precond_error.AsCString());
676 target->RemoveBreakpointByID(bp->GetID());
677 result.SetStatus(eReturnStatusFailed);
685 // Now set the various options that were passed in:
687 if (m_options.m_thread_id != LLDB_INVALID_THREAD_ID)
688 bp->SetThreadID(m_options.m_thread_id);
690 if (m_options.m_thread_index != UINT32_MAX)
691 bp->GetOptions()->GetThreadSpec()->SetIndex(m_options.m_thread_index);
693 if (!m_options.m_thread_name.empty())
694 bp->GetOptions()->GetThreadSpec()->SetName(
695 m_options.m_thread_name.c_str());
697 if (!m_options.m_queue_name.empty())
698 bp->GetOptions()->GetThreadSpec()->SetQueueName(
699 m_options.m_queue_name.c_str());
701 if (m_options.m_ignore_count != 0)
702 bp->GetOptions()->SetIgnoreCount(m_options.m_ignore_count);
704 if (!m_options.m_condition.empty())
705 bp->GetOptions()->SetCondition(m_options.m_condition.c_str());
707 if (!m_options.m_breakpoint_names.empty()) {
709 for (auto name : m_options.m_breakpoint_names) {
710 bp->AddName(name.c_str(), name_error);
711 if (name_error.Fail()) {
712 result.AppendErrorWithFormat("Invalid breakpoint name: %s",
714 target->RemoveBreakpointByID(bp->GetID());
715 result.SetStatus(eReturnStatusFailed);
721 bp->SetOneShot(m_options.m_one_shot);
725 Stream &output_stream = result.GetOutputStream();
726 const bool show_locations = false;
727 bp->GetDescription(&output_stream, lldb::eDescriptionLevelInitial,
729 if (target == m_interpreter.GetDebugger().GetDummyTarget())
730 output_stream.Printf("Breakpoint set in dummy target, will get copied "
731 "into future targets.\n");
733 // Don't print out this warning for exception breakpoints. They can get
734 // set before the target
735 // is set, but we won't know how to actually set the breakpoint till we
737 if (bp->GetNumLocations() == 0 && break_type != eSetTypeException) {
738 output_stream.Printf("WARNING: Unable to resolve breakpoint to any "
739 "actual locations.\n");
742 result.SetStatus(eReturnStatusSuccessFinishResult);
744 result.AppendError("Breakpoint creation failed: No breakpoint created.");
745 result.SetStatus(eReturnStatusFailed);
748 return result.Succeeded();
752 bool GetDefaultFile(Target *target, FileSpec &file,
753 CommandReturnObject &result) {
754 uint32_t default_line;
755 // First use the Source Manager's default file.
756 // Then use the current stack frame's file.
757 if (!target->GetSourceManager().GetDefaultFileAndLine(file, default_line)) {
758 StackFrame *cur_frame = m_exe_ctx.GetFramePtr();
759 if (cur_frame == nullptr) {
761 "No selected frame to use to find the default file.");
762 result.SetStatus(eReturnStatusFailed);
764 } else if (!cur_frame->HasDebugInformation()) {
765 result.AppendError("Cannot use the selected frame to find the default "
766 "file, it has no debug info.");
767 result.SetStatus(eReturnStatusFailed);
770 const SymbolContext &sc =
771 cur_frame->GetSymbolContext(eSymbolContextLineEntry);
772 if (sc.line_entry.file) {
773 file = sc.line_entry.file;
775 result.AppendError("Can't find the file for the selected frame to "
776 "use as the default file.");
777 result.SetStatus(eReturnStatusFailed);
785 CommandOptions m_options;
788 //-------------------------------------------------------------------------
789 // CommandObjectBreakpointModify
790 //-------------------------------------------------------------------------
792 #pragma mark Modify::CommandOptions
793 static OptionDefinition g_breakpoint_modify_options[] = {
795 { LLDB_OPT_SET_ALL, false, "ignore-count", 'i', OptionParser::eRequiredArgument, nullptr, nullptr, 0, eArgTypeCount, "Set the number of times this breakpoint is skipped before stopping." },
796 { LLDB_OPT_SET_ALL, false, "one-shot", 'o', OptionParser::eRequiredArgument, nullptr, nullptr, 0, eArgTypeBoolean, "The breakpoint is deleted the first time it stop causes a stop." },
797 { LLDB_OPT_SET_ALL, false, "thread-index", 'x', OptionParser::eRequiredArgument, nullptr, nullptr, 0, eArgTypeThreadIndex, "The breakpoint stops only for the thread whose index matches this argument." },
798 { LLDB_OPT_SET_ALL, false, "thread-id", 't', OptionParser::eRequiredArgument, nullptr, nullptr, 0, eArgTypeThreadID, "The breakpoint stops only for the thread whose TID matches this argument." },
799 { LLDB_OPT_SET_ALL, false, "thread-name", 'T', OptionParser::eRequiredArgument, nullptr, nullptr, 0, eArgTypeThreadName, "The breakpoint stops only for the thread whose thread name matches this argument." },
800 { LLDB_OPT_SET_ALL, 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." },
801 { LLDB_OPT_SET_ALL, false, "condition", 'c', OptionParser::eRequiredArgument, nullptr, nullptr, 0, eArgTypeExpression, "The breakpoint stops only if this condition expression evaluates to true." },
802 { LLDB_OPT_SET_1, false, "enable", 'e', OptionParser::eNoArgument, nullptr, nullptr, 0, eArgTypeNone, "Enable the breakpoint." },
803 { LLDB_OPT_SET_2, false, "disable", 'd', OptionParser::eNoArgument, nullptr, nullptr, 0, eArgTypeNone, "Disable the breakpoint." },
804 { LLDB_OPT_SET_ALL, false, "dummy-breakpoints", 'D', OptionParser::eNoArgument, nullptr, nullptr, 0, eArgTypeNone, "Sets Dummy breakpoints - i.e. breakpoints set before a file is provided, which prime new targets." },
810 class CommandObjectBreakpointModify : public CommandObjectParsed {
812 CommandObjectBreakpointModify(CommandInterpreter &interpreter)
813 : CommandObjectParsed(interpreter, "breakpoint modify",
814 "Modify the options on a breakpoint or set of "
815 "breakpoints in the executable. "
816 "If no breakpoint is specified, acts on the last "
817 "created breakpoint. "
818 "With the exception of -e, -d and -i, passing an "
819 "empty argument clears the modification.",
822 CommandArgumentEntry arg;
823 CommandObject::AddIDsArgumentData(arg, eArgTypeBreakpointID,
824 eArgTypeBreakpointIDRange);
825 // Add the entry for the first argument for this command to the object's
827 m_arguments.push_back(arg);
830 ~CommandObjectBreakpointModify() override = default;
832 Options *GetOptions() override { return &m_options; }
834 class CommandOptions : public Options {
837 : Options(), m_ignore_count(0), m_thread_id(LLDB_INVALID_THREAD_ID),
838 m_thread_id_passed(false), m_thread_index(UINT32_MAX),
839 m_thread_index_passed(false), m_thread_name(), m_queue_name(),
840 m_condition(), m_one_shot(false), m_enable_passed(false),
841 m_enable_value(false), m_name_passed(false), m_queue_passed(false),
842 m_condition_passed(false), m_one_shot_passed(false),
843 m_use_dummy(false) {}
845 ~CommandOptions() override = default;
847 Error SetOptionValue(uint32_t option_idx, llvm::StringRef option_arg,
848 ExecutionContext *execution_context) override {
850 const int short_option = m_getopt_table[option_idx].val;
852 switch (short_option) {
854 m_condition = option_arg;
855 m_condition_passed = true;
858 m_enable_passed = true;
859 m_enable_value = false;
865 m_enable_passed = true;
866 m_enable_value = true;
869 if (option_arg.getAsInteger(0, m_ignore_count))
870 error.SetErrorStringWithFormat("invalid ignore count '%s'",
871 option_arg.str().c_str());
875 value = Args::StringToBoolean(option_arg, false, &success);
877 m_one_shot_passed = true;
880 error.SetErrorStringWithFormat(
881 "invalid boolean value '%s' passed for -o option",
882 option_arg.str().c_str());
885 if (option_arg[0] == '\0') {
886 m_thread_id = LLDB_INVALID_THREAD_ID;
887 m_thread_id_passed = true;
889 if (option_arg.getAsInteger(0, m_thread_id))
890 error.SetErrorStringWithFormat("invalid thread id string '%s'",
891 option_arg.str().c_str());
893 m_thread_id_passed = true;
897 m_thread_name = option_arg;
898 m_name_passed = true;
901 m_queue_name = option_arg;
902 m_queue_passed = true;
905 if (option_arg[0] == '\n') {
906 m_thread_index = UINT32_MAX;
907 m_thread_index_passed = true;
909 if (option_arg.getAsInteger(0, m_thread_index))
910 error.SetErrorStringWithFormat("invalid thread index string '%s'",
911 option_arg.str().c_str());
913 m_thread_index_passed = true;
917 error.SetErrorStringWithFormat("unrecognized option '%c'",
925 void OptionParsingStarting(ExecutionContext *execution_context) override {
927 m_thread_id = LLDB_INVALID_THREAD_ID;
928 m_thread_id_passed = false;
929 m_thread_index = UINT32_MAX;
930 m_thread_index_passed = false;
931 m_thread_name.clear();
932 m_queue_name.clear();
935 m_enable_passed = false;
936 m_queue_passed = false;
937 m_name_passed = false;
938 m_condition_passed = false;
939 m_one_shot_passed = false;
943 llvm::ArrayRef<OptionDefinition> GetDefinitions() override {
944 return llvm::makeArrayRef(g_breakpoint_modify_options);
947 // Instance variables to hold the values for command options.
949 uint32_t m_ignore_count;
950 lldb::tid_t m_thread_id;
951 bool m_thread_id_passed;
952 uint32_t m_thread_index;
953 bool m_thread_index_passed;
954 std::string m_thread_name;
955 std::string m_queue_name;
956 std::string m_condition;
958 bool m_enable_passed;
962 bool m_condition_passed;
963 bool m_one_shot_passed;
968 bool DoExecute(Args &command, CommandReturnObject &result) override {
969 Target *target = GetSelectedOrDummyTarget(m_options.m_use_dummy);
970 if (target == nullptr) {
971 result.AppendError("Invalid target. No existing target or breakpoints.");
972 result.SetStatus(eReturnStatusFailed);
976 std::unique_lock<std::recursive_mutex> lock;
977 target->GetBreakpointList().GetListMutex(lock);
979 BreakpointIDList valid_bp_ids;
981 CommandObjectMultiwordBreakpoint::VerifyBreakpointOrLocationIDs(
982 command, target, result, &valid_bp_ids);
984 if (result.Succeeded()) {
985 const size_t count = valid_bp_ids.GetSize();
986 for (size_t i = 0; i < count; ++i) {
987 BreakpointID cur_bp_id = valid_bp_ids.GetBreakpointIDAtIndex(i);
989 if (cur_bp_id.GetBreakpointID() != LLDB_INVALID_BREAK_ID) {
991 target->GetBreakpointByID(cur_bp_id.GetBreakpointID()).get();
992 if (cur_bp_id.GetLocationID() != LLDB_INVALID_BREAK_ID) {
993 BreakpointLocation *location =
994 bp->FindLocationByID(cur_bp_id.GetLocationID()).get();
996 if (m_options.m_thread_id_passed)
997 location->SetThreadID(m_options.m_thread_id);
999 if (m_options.m_thread_index_passed)
1000 location->SetThreadIndex(m_options.m_thread_index);
1002 if (m_options.m_name_passed)
1003 location->SetThreadName(m_options.m_thread_name.c_str());
1005 if (m_options.m_queue_passed)
1006 location->SetQueueName(m_options.m_queue_name.c_str());
1008 if (m_options.m_ignore_count != 0)
1009 location->SetIgnoreCount(m_options.m_ignore_count);
1011 if (m_options.m_enable_passed)
1012 location->SetEnabled(m_options.m_enable_value);
1014 if (m_options.m_condition_passed)
1015 location->SetCondition(m_options.m_condition.c_str());
1018 if (m_options.m_thread_id_passed)
1019 bp->SetThreadID(m_options.m_thread_id);
1021 if (m_options.m_thread_index_passed)
1022 bp->SetThreadIndex(m_options.m_thread_index);
1024 if (m_options.m_name_passed)
1025 bp->SetThreadName(m_options.m_thread_name.c_str());
1027 if (m_options.m_queue_passed)
1028 bp->SetQueueName(m_options.m_queue_name.c_str());
1030 if (m_options.m_ignore_count != 0)
1031 bp->SetIgnoreCount(m_options.m_ignore_count);
1033 if (m_options.m_enable_passed)
1034 bp->SetEnabled(m_options.m_enable_value);
1036 if (m_options.m_condition_passed)
1037 bp->SetCondition(m_options.m_condition.c_str());
1043 return result.Succeeded();
1047 CommandOptions m_options;
1050 //-------------------------------------------------------------------------
1051 // CommandObjectBreakpointEnable
1052 //-------------------------------------------------------------------------
1055 class CommandObjectBreakpointEnable : public CommandObjectParsed {
1057 CommandObjectBreakpointEnable(CommandInterpreter &interpreter)
1058 : CommandObjectParsed(interpreter, "enable",
1059 "Enable the specified disabled breakpoint(s). If "
1060 "no breakpoints are specified, enable all of them.",
1062 CommandArgumentEntry arg;
1063 CommandObject::AddIDsArgumentData(arg, eArgTypeBreakpointID,
1064 eArgTypeBreakpointIDRange);
1065 // Add the entry for the first argument for this command to the object's
1066 // arguments vector.
1067 m_arguments.push_back(arg);
1070 ~CommandObjectBreakpointEnable() override = default;
1073 bool DoExecute(Args &command, CommandReturnObject &result) override {
1074 Target *target = GetSelectedOrDummyTarget();
1075 if (target == nullptr) {
1076 result.AppendError("Invalid target. No existing target or breakpoints.");
1077 result.SetStatus(eReturnStatusFailed);
1081 std::unique_lock<std::recursive_mutex> lock;
1082 target->GetBreakpointList().GetListMutex(lock);
1084 const BreakpointList &breakpoints = target->GetBreakpointList();
1086 size_t num_breakpoints = breakpoints.GetSize();
1088 if (num_breakpoints == 0) {
1089 result.AppendError("No breakpoints exist to be enabled.");
1090 result.SetStatus(eReturnStatusFailed);
1094 if (command.empty()) {
1095 // No breakpoint selected; enable all currently set breakpoints.
1096 target->EnableAllBreakpoints();
1097 result.AppendMessageWithFormat("All breakpoints enabled. (%" PRIu64
1099 (uint64_t)num_breakpoints);
1100 result.SetStatus(eReturnStatusSuccessFinishNoResult);
1102 // Particular breakpoint selected; enable that breakpoint.
1103 BreakpointIDList valid_bp_ids;
1104 CommandObjectMultiwordBreakpoint::VerifyBreakpointOrLocationIDs(
1105 command, target, result, &valid_bp_ids);
1107 if (result.Succeeded()) {
1108 int enable_count = 0;
1110 const size_t count = valid_bp_ids.GetSize();
1111 for (size_t i = 0; i < count; ++i) {
1112 BreakpointID cur_bp_id = valid_bp_ids.GetBreakpointIDAtIndex(i);
1114 if (cur_bp_id.GetBreakpointID() != LLDB_INVALID_BREAK_ID) {
1115 Breakpoint *breakpoint =
1116 target->GetBreakpointByID(cur_bp_id.GetBreakpointID()).get();
1117 if (cur_bp_id.GetLocationID() != LLDB_INVALID_BREAK_ID) {
1118 BreakpointLocation *location =
1119 breakpoint->FindLocationByID(cur_bp_id.GetLocationID()).get();
1121 location->SetEnabled(true);
1125 breakpoint->SetEnabled(true);
1130 result.AppendMessageWithFormat("%d breakpoints enabled.\n",
1131 enable_count + loc_count);
1132 result.SetStatus(eReturnStatusSuccessFinishNoResult);
1136 return result.Succeeded();
1140 //-------------------------------------------------------------------------
1141 // CommandObjectBreakpointDisable
1142 //-------------------------------------------------------------------------
1143 #pragma mark Disable
1145 class CommandObjectBreakpointDisable : public CommandObjectParsed {
1147 CommandObjectBreakpointDisable(CommandInterpreter &interpreter)
1148 : CommandObjectParsed(
1149 interpreter, "breakpoint disable",
1150 "Disable the specified breakpoint(s) without deleting "
1151 "them. If none are specified, disable all "
1155 "Disable the specified breakpoint(s) without deleting them. \
1156 If none are specified, disable all breakpoints."
1160 "Note: disabling a breakpoint will cause none of its locations to be hit \
1161 regardless of whether individual locations are enabled or disabled. After the sequence:"
1164 (lldb) break disable 1
1165 (lldb) break enable 1.1
1167 execution will NOT stop at location 1.1. To achieve that, type:
1169 (lldb) break disable 1.*
1170 (lldb) break enable 1.1
1173 "The first command disables all locations for breakpoint 1, \
1174 the second re-enables the first location.");
1176 CommandArgumentEntry arg;
1177 CommandObject::AddIDsArgumentData(arg, eArgTypeBreakpointID,
1178 eArgTypeBreakpointIDRange);
1179 // Add the entry for the first argument for this command to the object's
1180 // arguments vector.
1181 m_arguments.push_back(arg);
1184 ~CommandObjectBreakpointDisable() override = default;
1187 bool DoExecute(Args &command, CommandReturnObject &result) override {
1188 Target *target = GetSelectedOrDummyTarget();
1189 if (target == nullptr) {
1190 result.AppendError("Invalid target. No existing target or breakpoints.");
1191 result.SetStatus(eReturnStatusFailed);
1195 std::unique_lock<std::recursive_mutex> lock;
1196 target->GetBreakpointList().GetListMutex(lock);
1198 const BreakpointList &breakpoints = target->GetBreakpointList();
1199 size_t num_breakpoints = breakpoints.GetSize();
1201 if (num_breakpoints == 0) {
1202 result.AppendError("No breakpoints exist to be disabled.");
1203 result.SetStatus(eReturnStatusFailed);
1207 if (command.empty()) {
1208 // No breakpoint selected; disable all currently set breakpoints.
1209 target->DisableAllBreakpoints();
1210 result.AppendMessageWithFormat("All breakpoints disabled. (%" PRIu64
1212 (uint64_t)num_breakpoints);
1213 result.SetStatus(eReturnStatusSuccessFinishNoResult);
1215 // Particular breakpoint selected; disable that breakpoint.
1216 BreakpointIDList valid_bp_ids;
1218 CommandObjectMultiwordBreakpoint::VerifyBreakpointOrLocationIDs(
1219 command, target, result, &valid_bp_ids);
1221 if (result.Succeeded()) {
1222 int disable_count = 0;
1224 const size_t count = valid_bp_ids.GetSize();
1225 for (size_t i = 0; i < count; ++i) {
1226 BreakpointID cur_bp_id = valid_bp_ids.GetBreakpointIDAtIndex(i);
1228 if (cur_bp_id.GetBreakpointID() != LLDB_INVALID_BREAK_ID) {
1229 Breakpoint *breakpoint =
1230 target->GetBreakpointByID(cur_bp_id.GetBreakpointID()).get();
1231 if (cur_bp_id.GetLocationID() != LLDB_INVALID_BREAK_ID) {
1232 BreakpointLocation *location =
1233 breakpoint->FindLocationByID(cur_bp_id.GetLocationID()).get();
1235 location->SetEnabled(false);
1239 breakpoint->SetEnabled(false);
1244 result.AppendMessageWithFormat("%d breakpoints disabled.\n",
1245 disable_count + loc_count);
1246 result.SetStatus(eReturnStatusSuccessFinishNoResult);
1250 return result.Succeeded();
1254 //-------------------------------------------------------------------------
1255 // CommandObjectBreakpointList
1256 //-------------------------------------------------------------------------
1258 #pragma mark List::CommandOptions
1259 static OptionDefinition g_breakpoint_list_options[] = {
1261 { LLDB_OPT_SET_ALL, false, "internal", 'i', OptionParser::eNoArgument, nullptr, nullptr, 0, eArgTypeNone, "Show debugger internal breakpoints" },
1262 { LLDB_OPT_SET_1, false, "brief", 'b', OptionParser::eNoArgument, nullptr, nullptr, 0, eArgTypeNone, "Give a brief description of the breakpoint (no location info)." },
1263 // FIXME: We need to add an "internal" command, and then add this sort of thing to it.
1264 // But I need to see it for now, and don't want to wait.
1265 { LLDB_OPT_SET_2, false, "full", 'f', OptionParser::eNoArgument, nullptr, nullptr, 0, eArgTypeNone, "Give a full description of the breakpoint and its locations." },
1266 { LLDB_OPT_SET_3, false, "verbose", 'v', OptionParser::eNoArgument, nullptr, nullptr, 0, eArgTypeNone, "Explain everything we know about the breakpoint (for debugging debugger bugs)." },
1267 { 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." },
1273 class CommandObjectBreakpointList : public CommandObjectParsed {
1275 CommandObjectBreakpointList(CommandInterpreter &interpreter)
1276 : CommandObjectParsed(
1277 interpreter, "breakpoint list",
1278 "List some or all breakpoints at configurable levels of detail.",
1281 CommandArgumentEntry arg;
1282 CommandArgumentData bp_id_arg;
1284 // Define the first (and only) variant of this arg.
1285 bp_id_arg.arg_type = eArgTypeBreakpointID;
1286 bp_id_arg.arg_repetition = eArgRepeatOptional;
1288 // There is only one variant this argument could be; put it into the
1290 arg.push_back(bp_id_arg);
1292 // Push the data for the first argument into the m_arguments vector.
1293 m_arguments.push_back(arg);
1296 ~CommandObjectBreakpointList() override = default;
1298 Options *GetOptions() override { return &m_options; }
1300 class CommandOptions : public Options {
1303 : Options(), m_level(lldb::eDescriptionLevelBrief), m_use_dummy(false) {
1306 ~CommandOptions() override = default;
1308 Error SetOptionValue(uint32_t option_idx, llvm::StringRef option_arg,
1309 ExecutionContext *execution_context) override {
1311 const int short_option = m_getopt_table[option_idx].val;
1313 switch (short_option) {
1315 m_level = lldb::eDescriptionLevelBrief;
1321 m_level = lldb::eDescriptionLevelFull;
1324 m_level = lldb::eDescriptionLevelVerbose;
1330 error.SetErrorStringWithFormat("unrecognized option '%c'",
1338 void OptionParsingStarting(ExecutionContext *execution_context) override {
1339 m_level = lldb::eDescriptionLevelFull;
1341 m_use_dummy = false;
1344 llvm::ArrayRef<OptionDefinition> GetDefinitions() override {
1345 return llvm::makeArrayRef(g_breakpoint_list_options);
1348 // Instance variables to hold the values for command options.
1350 lldb::DescriptionLevel m_level;
1357 bool DoExecute(Args &command, CommandReturnObject &result) override {
1358 Target *target = GetSelectedOrDummyTarget(m_options.m_use_dummy);
1360 if (target == nullptr) {
1361 result.AppendError("Invalid target. No current target or breakpoints.");
1362 result.SetStatus(eReturnStatusSuccessFinishNoResult);
1366 const BreakpointList &breakpoints =
1367 target->GetBreakpointList(m_options.m_internal);
1368 std::unique_lock<std::recursive_mutex> lock;
1369 target->GetBreakpointList(m_options.m_internal).GetListMutex(lock);
1371 size_t num_breakpoints = breakpoints.GetSize();
1373 if (num_breakpoints == 0) {
1374 result.AppendMessage("No breakpoints currently set.");
1375 result.SetStatus(eReturnStatusSuccessFinishNoResult);
1379 Stream &output_stream = result.GetOutputStream();
1381 if (command.empty()) {
1382 // No breakpoint selected; show info about all currently set breakpoints.
1383 result.AppendMessage("Current breakpoints:");
1384 for (size_t i = 0; i < num_breakpoints; ++i) {
1385 Breakpoint *breakpoint = breakpoints.GetBreakpointAtIndex(i).get();
1386 AddBreakpointDescription(&output_stream, breakpoint, m_options.m_level);
1388 result.SetStatus(eReturnStatusSuccessFinishNoResult);
1390 // Particular breakpoints selected; show info about that breakpoint.
1391 BreakpointIDList valid_bp_ids;
1392 CommandObjectMultiwordBreakpoint::VerifyBreakpointOrLocationIDs(
1393 command, target, result, &valid_bp_ids);
1395 if (result.Succeeded()) {
1396 for (size_t i = 0; i < valid_bp_ids.GetSize(); ++i) {
1397 BreakpointID cur_bp_id = valid_bp_ids.GetBreakpointIDAtIndex(i);
1398 Breakpoint *breakpoint =
1399 target->GetBreakpointByID(cur_bp_id.GetBreakpointID()).get();
1400 AddBreakpointDescription(&output_stream, breakpoint,
1403 result.SetStatus(eReturnStatusSuccessFinishNoResult);
1405 result.AppendError("Invalid breakpoint ID.");
1406 result.SetStatus(eReturnStatusFailed);
1410 return result.Succeeded();
1414 CommandOptions m_options;
1417 //-------------------------------------------------------------------------
1418 // CommandObjectBreakpointClear
1419 //-------------------------------------------------------------------------
1420 #pragma mark Clear::CommandOptions
1422 static OptionDefinition g_breakpoint_clear_options[] = {
1424 { LLDB_OPT_SET_1, false, "file", 'f', OptionParser::eRequiredArgument, nullptr, nullptr, CommandCompletions::eSourceFileCompletion, eArgTypeFilename, "Specify the breakpoint by source location in this particular file." },
1425 { LLDB_OPT_SET_1, true, "line", 'l', OptionParser::eRequiredArgument, nullptr, nullptr, 0, eArgTypeLineNum, "Specify the breakpoint by source location at this particular line." }
1431 class CommandObjectBreakpointClear : public CommandObjectParsed {
1433 typedef enum BreakpointClearType {
1435 eClearTypeFileAndLine
1436 } BreakpointClearType;
1438 CommandObjectBreakpointClear(CommandInterpreter &interpreter)
1439 : CommandObjectParsed(interpreter, "breakpoint clear",
1440 "Delete or disable breakpoints matching the "
1441 "specified source file and line.",
1442 "breakpoint clear <cmd-options>"),
1445 ~CommandObjectBreakpointClear() override = default;
1447 Options *GetOptions() override { return &m_options; }
1449 class CommandOptions : public Options {
1451 CommandOptions() : Options(), m_filename(), m_line_num(0) {}
1453 ~CommandOptions() override = default;
1455 Error SetOptionValue(uint32_t option_idx, llvm::StringRef option_arg,
1456 ExecutionContext *execution_context) override {
1458 const int short_option = m_getopt_table[option_idx].val;
1460 switch (short_option) {
1462 m_filename.assign(option_arg);
1466 option_arg.getAsInteger(0, m_line_num);
1470 error.SetErrorStringWithFormat("unrecognized option '%c'",
1478 void OptionParsingStarting(ExecutionContext *execution_context) override {
1483 llvm::ArrayRef<OptionDefinition> GetDefinitions() override {
1484 return llvm::makeArrayRef(g_breakpoint_clear_options);
1487 // Instance variables to hold the values for command options.
1489 std::string m_filename;
1490 uint32_t m_line_num;
1494 bool DoExecute(Args &command, CommandReturnObject &result) override {
1495 Target *target = GetSelectedOrDummyTarget();
1496 if (target == nullptr) {
1497 result.AppendError("Invalid target. No existing target or breakpoints.");
1498 result.SetStatus(eReturnStatusFailed);
1502 // The following are the various types of breakpoints that could be cleared:
1503 // 1). -f -l (clearing breakpoint by source location)
1505 BreakpointClearType break_type = eClearTypeInvalid;
1507 if (m_options.m_line_num != 0)
1508 break_type = eClearTypeFileAndLine;
1510 std::unique_lock<std::recursive_mutex> lock;
1511 target->GetBreakpointList().GetListMutex(lock);
1513 BreakpointList &breakpoints = target->GetBreakpointList();
1514 size_t num_breakpoints = breakpoints.GetSize();
1516 // Early return if there's no breakpoint at all.
1517 if (num_breakpoints == 0) {
1518 result.AppendError("Breakpoint clear: No breakpoint cleared.");
1519 result.SetStatus(eReturnStatusFailed);
1520 return result.Succeeded();
1523 // Find matching breakpoints and delete them.
1525 // First create a copy of all the IDs.
1526 std::vector<break_id_t> BreakIDs;
1527 for (size_t i = 0; i < num_breakpoints; ++i)
1528 BreakIDs.push_back(breakpoints.GetBreakpointAtIndex(i)->GetID());
1530 int num_cleared = 0;
1532 switch (break_type) {
1533 case eClearTypeFileAndLine: // Breakpoint by source position
1535 const ConstString filename(m_options.m_filename.c_str());
1536 BreakpointLocationCollection loc_coll;
1538 for (size_t i = 0; i < num_breakpoints; ++i) {
1539 Breakpoint *bp = breakpoints.FindBreakpointByID(BreakIDs[i]).get();
1541 if (bp->GetMatchingFileLine(filename, m_options.m_line_num, loc_coll)) {
1542 // If the collection size is 0, it's a full match and we can just
1543 // remove the breakpoint.
1544 if (loc_coll.GetSize() == 0) {
1545 bp->GetDescription(&ss, lldb::eDescriptionLevelBrief);
1547 target->RemoveBreakpointByID(bp->GetID());
1558 if (num_cleared > 0) {
1559 Stream &output_stream = result.GetOutputStream();
1560 output_stream.Printf("%d breakpoints cleared:\n", num_cleared);
1561 output_stream << ss.GetString();
1562 output_stream.EOL();
1563 result.SetStatus(eReturnStatusSuccessFinishNoResult);
1565 result.AppendError("Breakpoint clear: No breakpoint cleared.");
1566 result.SetStatus(eReturnStatusFailed);
1569 return result.Succeeded();
1573 CommandOptions m_options;
1576 //-------------------------------------------------------------------------
1577 // CommandObjectBreakpointDelete
1578 //-------------------------------------------------------------------------
1579 static OptionDefinition g_breakpoint_delete_options[] = {
1581 { LLDB_OPT_SET_1, false, "force", 'f', OptionParser::eNoArgument, nullptr, nullptr, 0, eArgTypeNone, "Delete all breakpoints without querying for confirmation." },
1582 { 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." },
1588 class CommandObjectBreakpointDelete : public CommandObjectParsed {
1590 CommandObjectBreakpointDelete(CommandInterpreter &interpreter)
1591 : CommandObjectParsed(interpreter, "breakpoint delete",
1592 "Delete the specified breakpoint(s). If no "
1593 "breakpoints are specified, delete them all.",
1596 CommandArgumentEntry arg;
1597 CommandObject::AddIDsArgumentData(arg, eArgTypeBreakpointID,
1598 eArgTypeBreakpointIDRange);
1599 // Add the entry for the first argument for this command to the object's
1600 // arguments vector.
1601 m_arguments.push_back(arg);
1604 ~CommandObjectBreakpointDelete() override = default;
1606 Options *GetOptions() override { return &m_options; }
1608 class CommandOptions : public Options {
1610 CommandOptions() : Options(), m_use_dummy(false), m_force(false) {}
1612 ~CommandOptions() override = default;
1614 Error SetOptionValue(uint32_t option_idx, llvm::StringRef option_arg,
1615 ExecutionContext *execution_context) override {
1617 const int short_option = m_getopt_table[option_idx].val;
1619 switch (short_option) {
1629 error.SetErrorStringWithFormat("unrecognized option '%c'",
1637 void OptionParsingStarting(ExecutionContext *execution_context) override {
1638 m_use_dummy = false;
1642 llvm::ArrayRef<OptionDefinition> GetDefinitions() override {
1643 return llvm::makeArrayRef(g_breakpoint_delete_options);
1646 // Instance variables to hold the values for command options.
1652 bool DoExecute(Args &command, CommandReturnObject &result) override {
1653 Target *target = GetSelectedOrDummyTarget(m_options.m_use_dummy);
1655 if (target == nullptr) {
1656 result.AppendError("Invalid target. No existing target or breakpoints.");
1657 result.SetStatus(eReturnStatusFailed);
1661 std::unique_lock<std::recursive_mutex> lock;
1662 target->GetBreakpointList().GetListMutex(lock);
1664 const BreakpointList &breakpoints = target->GetBreakpointList();
1666 size_t num_breakpoints = breakpoints.GetSize();
1668 if (num_breakpoints == 0) {
1669 result.AppendError("No breakpoints exist to be deleted.");
1670 result.SetStatus(eReturnStatusFailed);
1674 if (command.empty()) {
1675 if (!m_options.m_force &&
1676 !m_interpreter.Confirm(
1677 "About to delete all breakpoints, do you want to do that?",
1679 result.AppendMessage("Operation cancelled...");
1681 target->RemoveAllBreakpoints();
1682 result.AppendMessageWithFormat(
1683 "All breakpoints removed. (%" PRIu64 " breakpoint%s)\n",
1684 (uint64_t)num_breakpoints, num_breakpoints > 1 ? "s" : "");
1686 result.SetStatus(eReturnStatusSuccessFinishNoResult);
1688 // Particular breakpoint selected; disable that breakpoint.
1689 BreakpointIDList valid_bp_ids;
1690 CommandObjectMultiwordBreakpoint::VerifyBreakpointOrLocationIDs(
1691 command, target, result, &valid_bp_ids);
1693 if (result.Succeeded()) {
1694 int delete_count = 0;
1695 int disable_count = 0;
1696 const size_t count = valid_bp_ids.GetSize();
1697 for (size_t i = 0; i < count; ++i) {
1698 BreakpointID cur_bp_id = valid_bp_ids.GetBreakpointIDAtIndex(i);
1700 if (cur_bp_id.GetBreakpointID() != LLDB_INVALID_BREAK_ID) {
1701 if (cur_bp_id.GetLocationID() != LLDB_INVALID_BREAK_ID) {
1702 Breakpoint *breakpoint =
1703 target->GetBreakpointByID(cur_bp_id.GetBreakpointID()).get();
1704 BreakpointLocation *location =
1705 breakpoint->FindLocationByID(cur_bp_id.GetLocationID()).get();
1706 // It makes no sense to try to delete individual locations, so we
1707 // disable them instead.
1709 location->SetEnabled(false);
1713 target->RemoveBreakpointByID(cur_bp_id.GetBreakpointID());
1718 result.AppendMessageWithFormat(
1719 "%d breakpoints deleted; %d breakpoint locations disabled.\n",
1720 delete_count, disable_count);
1721 result.SetStatus(eReturnStatusSuccessFinishNoResult);
1724 return result.Succeeded();
1728 CommandOptions m_options;
1731 //-------------------------------------------------------------------------
1732 // CommandObjectBreakpointName
1733 //-------------------------------------------------------------------------
1735 static OptionDefinition g_breakpoint_name_options[] = {
1737 {LLDB_OPT_SET_1, false, "name", 'N', OptionParser::eRequiredArgument, nullptr, nullptr, 0, eArgTypeBreakpointName, "Specifies a breakpoint name to use."},
1738 {LLDB_OPT_SET_2, false, "breakpoint-id", 'B', OptionParser::eRequiredArgument, nullptr, nullptr, 0, eArgTypeBreakpointID, "Specify a breakpoint ID to use."},
1739 {LLDB_OPT_SET_ALL, 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."},
1742 class BreakpointNameOptionGroup : public OptionGroup {
1744 BreakpointNameOptionGroup()
1745 : OptionGroup(), m_breakpoint(LLDB_INVALID_BREAK_ID), m_use_dummy(false) {
1748 ~BreakpointNameOptionGroup() override = default;
1750 llvm::ArrayRef<OptionDefinition> GetDefinitions() override {
1751 return llvm::makeArrayRef(g_breakpoint_name_options);
1754 Error SetOptionValue(uint32_t option_idx, llvm::StringRef option_arg,
1755 ExecutionContext *execution_context) override {
1757 const int short_option = g_breakpoint_name_options[option_idx].short_option;
1759 switch (short_option) {
1761 if (BreakpointID::StringIsBreakpointName(option_arg, error) &&
1763 m_name.SetValueFromString(option_arg);
1767 if (m_breakpoint.SetValueFromString(option_arg).Fail())
1768 error.SetErrorStringWithFormat(
1769 "unrecognized value \"%s\" for breakpoint",
1770 option_arg.str().c_str());
1773 if (m_use_dummy.SetValueFromString(option_arg).Fail())
1774 error.SetErrorStringWithFormat(
1775 "unrecognized value \"%s\" for use-dummy",
1776 option_arg.str().c_str());
1780 error.SetErrorStringWithFormat("unrecognized short option '%c'",
1787 void OptionParsingStarting(ExecutionContext *execution_context) override {
1789 m_breakpoint.Clear();
1790 m_use_dummy.Clear();
1791 m_use_dummy.SetDefaultValue(false);
1794 OptionValueString m_name;
1795 OptionValueUInt64 m_breakpoint;
1796 OptionValueBoolean m_use_dummy;
1799 class CommandObjectBreakpointNameAdd : public CommandObjectParsed {
1801 CommandObjectBreakpointNameAdd(CommandInterpreter &interpreter)
1802 : CommandObjectParsed(
1803 interpreter, "add", "Add a name to the breakpoints provided.",
1804 "breakpoint name add <command-options> <breakpoint-id-list>"),
1805 m_name_options(), m_option_group() {
1806 // Create the first variant for the first (and only) argument for this
1808 CommandArgumentEntry arg1;
1809 CommandArgumentData id_arg;
1810 id_arg.arg_type = eArgTypeBreakpointID;
1811 id_arg.arg_repetition = eArgRepeatOptional;
1812 arg1.push_back(id_arg);
1813 m_arguments.push_back(arg1);
1815 m_option_group.Append(&m_name_options, LLDB_OPT_SET_1, LLDB_OPT_SET_ALL);
1816 m_option_group.Finalize();
1819 ~CommandObjectBreakpointNameAdd() override = default;
1821 Options *GetOptions() override { return &m_option_group; }
1824 bool DoExecute(Args &command, CommandReturnObject &result) override {
1825 if (!m_name_options.m_name.OptionWasSet()) {
1826 result.SetError("No name option provided.");
1831 GetSelectedOrDummyTarget(m_name_options.m_use_dummy.GetCurrentValue());
1833 if (target == nullptr) {
1834 result.AppendError("Invalid target. No existing target or breakpoints.");
1835 result.SetStatus(eReturnStatusFailed);
1839 std::unique_lock<std::recursive_mutex> lock;
1840 target->GetBreakpointList().GetListMutex(lock);
1842 const BreakpointList &breakpoints = target->GetBreakpointList();
1844 size_t num_breakpoints = breakpoints.GetSize();
1845 if (num_breakpoints == 0) {
1846 result.SetError("No breakpoints, cannot add names.");
1847 result.SetStatus(eReturnStatusFailed);
1851 // Particular breakpoint selected; disable that breakpoint.
1852 BreakpointIDList valid_bp_ids;
1853 CommandObjectMultiwordBreakpoint::VerifyBreakpointIDs(
1854 command, target, result, &valid_bp_ids);
1856 if (result.Succeeded()) {
1857 if (valid_bp_ids.GetSize() == 0) {
1858 result.SetError("No breakpoints specified, cannot add names.");
1859 result.SetStatus(eReturnStatusFailed);
1862 size_t num_valid_ids = valid_bp_ids.GetSize();
1863 for (size_t index = 0; index < num_valid_ids; index++) {
1864 lldb::break_id_t bp_id =
1865 valid_bp_ids.GetBreakpointIDAtIndex(index).GetBreakpointID();
1866 BreakpointSP bp_sp = breakpoints.FindBreakpointByID(bp_id);
1867 Error error; // We don't need to check the error here, since the option
1868 // parser checked it...
1869 bp_sp->AddName(m_name_options.m_name.GetCurrentValue(), error);
1877 BreakpointNameOptionGroup m_name_options;
1878 OptionGroupOptions m_option_group;
1881 class CommandObjectBreakpointNameDelete : public CommandObjectParsed {
1883 CommandObjectBreakpointNameDelete(CommandInterpreter &interpreter)
1884 : CommandObjectParsed(
1885 interpreter, "delete",
1886 "Delete a name from the breakpoints provided.",
1887 "breakpoint name delete <command-options> <breakpoint-id-list>"),
1888 m_name_options(), m_option_group() {
1889 // Create the first variant for the first (and only) argument for this
1891 CommandArgumentEntry arg1;
1892 CommandArgumentData id_arg;
1893 id_arg.arg_type = eArgTypeBreakpointID;
1894 id_arg.arg_repetition = eArgRepeatOptional;
1895 arg1.push_back(id_arg);
1896 m_arguments.push_back(arg1);
1898 m_option_group.Append(&m_name_options, LLDB_OPT_SET_1, LLDB_OPT_SET_ALL);
1899 m_option_group.Finalize();
1902 ~CommandObjectBreakpointNameDelete() override = default;
1904 Options *GetOptions() override { return &m_option_group; }
1907 bool DoExecute(Args &command, CommandReturnObject &result) override {
1908 if (!m_name_options.m_name.OptionWasSet()) {
1909 result.SetError("No name option provided.");
1914 GetSelectedOrDummyTarget(m_name_options.m_use_dummy.GetCurrentValue());
1916 if (target == nullptr) {
1917 result.AppendError("Invalid target. No existing target or breakpoints.");
1918 result.SetStatus(eReturnStatusFailed);
1922 std::unique_lock<std::recursive_mutex> lock;
1923 target->GetBreakpointList().GetListMutex(lock);
1925 const BreakpointList &breakpoints = target->GetBreakpointList();
1927 size_t num_breakpoints = breakpoints.GetSize();
1928 if (num_breakpoints == 0) {
1929 result.SetError("No breakpoints, cannot delete names.");
1930 result.SetStatus(eReturnStatusFailed);
1934 // Particular breakpoint selected; disable that breakpoint.
1935 BreakpointIDList valid_bp_ids;
1936 CommandObjectMultiwordBreakpoint::VerifyBreakpointIDs(
1937 command, target, result, &valid_bp_ids);
1939 if (result.Succeeded()) {
1940 if (valid_bp_ids.GetSize() == 0) {
1941 result.SetError("No breakpoints specified, cannot delete names.");
1942 result.SetStatus(eReturnStatusFailed);
1945 size_t num_valid_ids = valid_bp_ids.GetSize();
1946 for (size_t index = 0; index < num_valid_ids; index++) {
1947 lldb::break_id_t bp_id =
1948 valid_bp_ids.GetBreakpointIDAtIndex(index).GetBreakpointID();
1949 BreakpointSP bp_sp = breakpoints.FindBreakpointByID(bp_id);
1950 bp_sp->RemoveName(m_name_options.m_name.GetCurrentValue());
1958 BreakpointNameOptionGroup m_name_options;
1959 OptionGroupOptions m_option_group;
1962 class CommandObjectBreakpointNameList : public CommandObjectParsed {
1964 CommandObjectBreakpointNameList(CommandInterpreter &interpreter)
1965 : CommandObjectParsed(interpreter, "list",
1966 "List either the names for a breakpoint or the "
1967 "breakpoints for a given name.",
1968 "breakpoint name list <command-options>"),
1969 m_name_options(), m_option_group() {
1970 m_option_group.Append(&m_name_options);
1971 m_option_group.Finalize();
1974 ~CommandObjectBreakpointNameList() override = default;
1976 Options *GetOptions() override { return &m_option_group; }
1979 bool DoExecute(Args &command, CommandReturnObject &result) override {
1981 GetSelectedOrDummyTarget(m_name_options.m_use_dummy.GetCurrentValue());
1983 if (target == nullptr) {
1984 result.AppendError("Invalid target. No existing target or breakpoints.");
1985 result.SetStatus(eReturnStatusFailed);
1989 if (m_name_options.m_name.OptionWasSet()) {
1990 const char *name = m_name_options.m_name.GetCurrentValue();
1991 std::unique_lock<std::recursive_mutex> lock;
1992 target->GetBreakpointList().GetListMutex(lock);
1994 BreakpointList &breakpoints = target->GetBreakpointList();
1995 for (BreakpointSP bp_sp : breakpoints.Breakpoints()) {
1996 if (bp_sp->MatchesName(name)) {
1998 bp_sp->GetDescription(&s, eDescriptionLevelBrief);
2000 result.AppendMessage(s.GetString());
2004 } else if (m_name_options.m_breakpoint.OptionWasSet()) {
2005 BreakpointSP bp_sp = target->GetBreakpointList().FindBreakpointByID(
2006 m_name_options.m_breakpoint.GetCurrentValue());
2008 std::vector<std::string> names;
2009 bp_sp->GetNames(names);
2010 result.AppendMessage("Names:");
2011 for (auto name : names)
2012 result.AppendMessageWithFormat(" %s\n", name.c_str());
2014 result.AppendErrorWithFormat(
2015 "Could not find breakpoint %" PRId64 ".\n",
2016 m_name_options.m_breakpoint.GetCurrentValue());
2017 result.SetStatus(eReturnStatusFailed);
2021 result.SetError("Must specify -N or -B option to list.");
2022 result.SetStatus(eReturnStatusFailed);
2029 BreakpointNameOptionGroup m_name_options;
2030 OptionGroupOptions m_option_group;
2033 //-------------------------------------------------------------------------
2034 // CommandObjectBreakpointName
2035 //-------------------------------------------------------------------------
2036 class CommandObjectBreakpointName : public CommandObjectMultiword {
2038 CommandObjectBreakpointName(CommandInterpreter &interpreter)
2039 : CommandObjectMultiword(
2040 interpreter, "name", "Commands to manage name tags for breakpoints",
2041 "breakpoint name <subcommand> [<command-options>]") {
2042 CommandObjectSP add_command_object(
2043 new CommandObjectBreakpointNameAdd(interpreter));
2044 CommandObjectSP delete_command_object(
2045 new CommandObjectBreakpointNameDelete(interpreter));
2046 CommandObjectSP list_command_object(
2047 new CommandObjectBreakpointNameList(interpreter));
2049 LoadSubCommand("add", add_command_object);
2050 LoadSubCommand("delete", delete_command_object);
2051 LoadSubCommand("list", list_command_object);
2054 ~CommandObjectBreakpointName() override = default;
2057 //-------------------------------------------------------------------------
2058 // CommandObjectBreakpointRead
2059 //-------------------------------------------------------------------------
2060 #pragma mark Read::CommandOptions
2061 static OptionDefinition g_breakpoint_read_options[] = {
2063 { LLDB_OPT_SET_ALL, true, "file", 'f', OptionParser::eRequiredArgument, nullptr, nullptr, CommandCompletions::eDiskFileCompletion, eArgTypeFilename, "The file from which to read the breakpoints." },
2064 {LLDB_OPT_SET_ALL, false, "breakpoint-name", 'N', OptionParser::eRequiredArgument, nullptr, nullptr, 0, eArgTypeBreakpointName, "Only read in breakpoints with this name."},
2070 class CommandObjectBreakpointRead : public CommandObjectParsed {
2072 CommandObjectBreakpointRead(CommandInterpreter &interpreter)
2073 : CommandObjectParsed(interpreter, "breakpoint read",
2074 "Read and set the breakpoints previously saved to "
2075 "a file with \"breakpoint write\". ",
2078 CommandArgumentEntry arg;
2079 CommandObject::AddIDsArgumentData(arg, eArgTypeBreakpointID,
2080 eArgTypeBreakpointIDRange);
2081 // Add the entry for the first argument for this command to the object's
2082 // arguments vector.
2083 m_arguments.push_back(arg);
2086 ~CommandObjectBreakpointRead() override = default;
2088 Options *GetOptions() override { return &m_options; }
2090 class CommandOptions : public Options {
2092 CommandOptions() : Options() {}
2094 ~CommandOptions() override = default;
2096 Error SetOptionValue(uint32_t option_idx, llvm::StringRef option_arg,
2097 ExecutionContext *execution_context) override {
2099 const int short_option = m_getopt_table[option_idx].val;
2101 switch (short_option) {
2103 m_filename.assign(option_arg);
2107 if (!BreakpointID::StringIsBreakpointName(llvm::StringRef(option_arg),
2109 error.SetErrorStringWithFormat("Invalid breakpoint name: %s",
2110 name_error.AsCString());
2112 m_names.push_back(option_arg);
2116 error.SetErrorStringWithFormat("unrecognized option '%c'",
2124 void OptionParsingStarting(ExecutionContext *execution_context) override {
2129 llvm::ArrayRef<OptionDefinition> GetDefinitions() override {
2130 return llvm::makeArrayRef(g_breakpoint_read_options);
2133 // Instance variables to hold the values for command options.
2135 std::string m_filename;
2136 std::vector<std::string> m_names;
2140 bool DoExecute(Args &command, CommandReturnObject &result) override {
2141 Target *target = GetSelectedOrDummyTarget();
2142 if (target == nullptr) {
2143 result.AppendError("Invalid target. No existing target or breakpoints.");
2144 result.SetStatus(eReturnStatusFailed);
2148 std::unique_lock<std::recursive_mutex> lock;
2149 target->GetBreakpointList().GetListMutex(lock);
2151 FileSpec input_spec(m_options.m_filename, true);
2152 BreakpointIDList new_bps;
2153 Error error = target->CreateBreakpointsFromFile(input_spec,
2154 m_options.m_names, new_bps);
2156 if (!error.Success()) {
2157 result.AppendError(error.AsCString());
2158 result.SetStatus(eReturnStatusFailed);
2162 Stream &output_stream = result.GetOutputStream();
2164 size_t num_breakpoints = new_bps.GetSize();
2165 if (num_breakpoints == 0) {
2166 result.AppendMessage("No breakpoints added.");
2168 // No breakpoint selected; show info about all currently set breakpoints.
2169 result.AppendMessage("New breakpoints:");
2170 for (size_t i = 0; i < num_breakpoints; ++i) {
2171 BreakpointID bp_id = new_bps.GetBreakpointIDAtIndex(i);
2172 Breakpoint *bp = target->GetBreakpointList()
2173 .FindBreakpointByID(bp_id.GetBreakpointID())
2176 bp->GetDescription(&output_stream, lldb::eDescriptionLevelInitial,
2180 return result.Succeeded();
2184 CommandOptions m_options;
2187 //-------------------------------------------------------------------------
2188 // CommandObjectBreakpointWrite
2189 //-------------------------------------------------------------------------
2190 #pragma mark Write::CommandOptions
2191 static OptionDefinition g_breakpoint_write_options[] = {
2193 { LLDB_OPT_SET_ALL, true, "file", 'f', OptionParser::eRequiredArgument, nullptr, nullptr, CommandCompletions::eDiskFileCompletion, eArgTypeFilename, "The file into which to write the breakpoints." },
2194 { LLDB_OPT_SET_ALL, false, "append",'a', OptionParser::eNoArgument, nullptr, nullptr, 0, eArgTypeNone, "Append to saved breakpoints file if it exists."},
2199 class CommandObjectBreakpointWrite : public CommandObjectParsed {
2201 CommandObjectBreakpointWrite(CommandInterpreter &interpreter)
2202 : CommandObjectParsed(interpreter, "breakpoint write",
2203 "Write the breakpoints listed to a file that can "
2204 "be read in with \"breakpoint read\". "
2205 "If given no arguments, writes all breakpoints.",
2208 CommandArgumentEntry arg;
2209 CommandObject::AddIDsArgumentData(arg, eArgTypeBreakpointID,
2210 eArgTypeBreakpointIDRange);
2211 // Add the entry for the first argument for this command to the object's
2212 // arguments vector.
2213 m_arguments.push_back(arg);
2216 ~CommandObjectBreakpointWrite() override = default;
2218 Options *GetOptions() override { return &m_options; }
2220 class CommandOptions : public Options {
2222 CommandOptions() : Options() {}
2224 ~CommandOptions() override = default;
2226 Error SetOptionValue(uint32_t option_idx, llvm::StringRef option_arg,
2227 ExecutionContext *execution_context) override {
2229 const int short_option = m_getopt_table[option_idx].val;
2231 switch (short_option) {
2233 m_filename.assign(option_arg);
2239 error.SetErrorStringWithFormat("unrecognized option '%c'",
2247 void OptionParsingStarting(ExecutionContext *execution_context) override {
2252 llvm::ArrayRef<OptionDefinition> GetDefinitions() override {
2253 return llvm::makeArrayRef(g_breakpoint_write_options);
2256 // Instance variables to hold the values for command options.
2258 std::string m_filename;
2259 bool m_append = false;
2263 bool DoExecute(Args &command, CommandReturnObject &result) override {
2264 Target *target = GetSelectedOrDummyTarget();
2265 if (target == nullptr) {
2266 result.AppendError("Invalid target. No existing target or breakpoints.");
2267 result.SetStatus(eReturnStatusFailed);
2271 std::unique_lock<std::recursive_mutex> lock;
2272 target->GetBreakpointList().GetListMutex(lock);
2274 BreakpointIDList valid_bp_ids;
2275 if (!command.empty()) {
2276 CommandObjectMultiwordBreakpoint::VerifyBreakpointIDs(
2277 command, target, result, &valid_bp_ids);
2279 if (!result.Succeeded()) {
2280 result.SetStatus(eReturnStatusFailed);
2284 Error error = target->SerializeBreakpointsToFile(
2285 FileSpec(m_options.m_filename, true), valid_bp_ids, m_options.m_append);
2286 if (!error.Success()) {
2287 result.AppendErrorWithFormat("error serializing breakpoints: %s.",
2289 result.SetStatus(eReturnStatusFailed);
2291 return result.Succeeded();
2295 CommandOptions m_options;
2298 //-------------------------------------------------------------------------
2299 // CommandObjectMultiwordBreakpoint
2300 //-------------------------------------------------------------------------
2301 #pragma mark MultiwordBreakpoint
2303 CommandObjectMultiwordBreakpoint::CommandObjectMultiwordBreakpoint(
2304 CommandInterpreter &interpreter)
2305 : CommandObjectMultiword(
2306 interpreter, "breakpoint",
2307 "Commands for operating on breakpoints (see 'help b' for shorthand.)",
2308 "breakpoint <subcommand> [<command-options>]") {
2309 CommandObjectSP list_command_object(
2310 new CommandObjectBreakpointList(interpreter));
2311 CommandObjectSP enable_command_object(
2312 new CommandObjectBreakpointEnable(interpreter));
2313 CommandObjectSP disable_command_object(
2314 new CommandObjectBreakpointDisable(interpreter));
2315 CommandObjectSP clear_command_object(
2316 new CommandObjectBreakpointClear(interpreter));
2317 CommandObjectSP delete_command_object(
2318 new CommandObjectBreakpointDelete(interpreter));
2319 CommandObjectSP set_command_object(
2320 new CommandObjectBreakpointSet(interpreter));
2321 CommandObjectSP command_command_object(
2322 new CommandObjectBreakpointCommand(interpreter));
2323 CommandObjectSP modify_command_object(
2324 new CommandObjectBreakpointModify(interpreter));
2325 CommandObjectSP name_command_object(
2326 new CommandObjectBreakpointName(interpreter));
2327 CommandObjectSP write_command_object(
2328 new CommandObjectBreakpointWrite(interpreter));
2329 CommandObjectSP read_command_object(
2330 new CommandObjectBreakpointRead(interpreter));
2332 list_command_object->SetCommandName("breakpoint list");
2333 enable_command_object->SetCommandName("breakpoint enable");
2334 disable_command_object->SetCommandName("breakpoint disable");
2335 clear_command_object->SetCommandName("breakpoint clear");
2336 delete_command_object->SetCommandName("breakpoint delete");
2337 set_command_object->SetCommandName("breakpoint set");
2338 command_command_object->SetCommandName("breakpoint command");
2339 modify_command_object->SetCommandName("breakpoint modify");
2340 name_command_object->SetCommandName("breakpoint name");
2341 write_command_object->SetCommandName("breakpoint write");
2342 read_command_object->SetCommandName("breakpoint read");
2344 LoadSubCommand("list", list_command_object);
2345 LoadSubCommand("enable", enable_command_object);
2346 LoadSubCommand("disable", disable_command_object);
2347 LoadSubCommand("clear", clear_command_object);
2348 LoadSubCommand("delete", delete_command_object);
2349 LoadSubCommand("set", set_command_object);
2350 LoadSubCommand("command", command_command_object);
2351 LoadSubCommand("modify", modify_command_object);
2352 LoadSubCommand("name", name_command_object);
2353 LoadSubCommand("write", write_command_object);
2354 LoadSubCommand("read", read_command_object);
2357 CommandObjectMultiwordBreakpoint::~CommandObjectMultiwordBreakpoint() = default;
2359 void CommandObjectMultiwordBreakpoint::VerifyIDs(Args &args, Target *target,
2360 bool allow_locations,
2361 CommandReturnObject &result,
2362 BreakpointIDList *valid_ids) {
2363 // args can be strings representing 1). integers (for breakpoint ids)
2364 // 2). the full breakpoint & location
2365 // canonical representation
2366 // 3). the word "to" or a hyphen,
2367 // representing a range (in which case there
2368 // had *better* be an entry both before &
2369 // after of one of the first two types.
2370 // 4). A breakpoint name
2371 // If args is empty, we will use the last created breakpoint (if there is
2377 if (target->GetLastCreatedBreakpoint()) {
2378 valid_ids->AddBreakpointID(BreakpointID(
2379 target->GetLastCreatedBreakpoint()->GetID(), LLDB_INVALID_BREAK_ID));
2380 result.SetStatus(eReturnStatusSuccessFinishNoResult);
2383 "No breakpoint specified and no last created breakpoint.");
2384 result.SetStatus(eReturnStatusFailed);
2389 // Create a new Args variable to use; copy any non-breakpoint-id-ranges stuff
2390 // directly from the old ARGS to
2391 // the new TEMP_ARGS. Do not copy breakpoint id range strings over; instead
2392 // generate a list of strings for
2393 // all the breakpoint ids in the range, and shove all of those breakpoint id
2394 // strings into TEMP_ARGS.
2396 BreakpointIDList::FindAndReplaceIDRanges(args, target, allow_locations,
2399 // NOW, convert the list of breakpoint id strings in TEMP_ARGS into an actual
2400 // BreakpointIDList:
2402 valid_ids->InsertStringArray(temp_args.GetConstArgumentVector(),
2403 temp_args.GetArgumentCount(), result);
2405 // At this point, all of the breakpoint ids that the user passed in have been
2406 // converted to breakpoint IDs
2407 // and put into valid_ids.
2409 if (result.Succeeded()) {
2410 // Now that we've converted everything from args into a list of breakpoint
2411 // ids, go through our tentative list
2412 // of breakpoint id's and verify that they correspond to valid/currently set
2415 const size_t count = valid_ids->GetSize();
2416 for (size_t i = 0; i < count; ++i) {
2417 BreakpointID cur_bp_id = valid_ids->GetBreakpointIDAtIndex(i);
2418 Breakpoint *breakpoint =
2419 target->GetBreakpointByID(cur_bp_id.GetBreakpointID()).get();
2420 if (breakpoint != nullptr) {
2421 const size_t num_locations = breakpoint->GetNumLocations();
2422 if (static_cast<size_t>(cur_bp_id.GetLocationID()) > num_locations) {
2423 StreamString id_str;
2424 BreakpointID::GetCanonicalReference(
2425 &id_str, cur_bp_id.GetBreakpointID(), cur_bp_id.GetLocationID());
2426 i = valid_ids->GetSize() + 1;
2427 result.AppendErrorWithFormat(
2428 "'%s' is not a currently valid breakpoint/location id.\n",
2430 result.SetStatus(eReturnStatusFailed);
2433 i = valid_ids->GetSize() + 1;
2434 result.AppendErrorWithFormat(
2435 "'%d' is not a currently valid breakpoint ID.\n",
2436 cur_bp_id.GetBreakpointID());
2437 result.SetStatus(eReturnStatusFailed);