LLDB  mainline
CommandObjectBreakpoint.cpp
Go to the documentation of this file.
1 //===-- CommandObjectBreakpoint.cpp -----------------------------*- C++ -*-===//
2 //
3 // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
4 // See https://llvm.org/LICENSE.txt for license information.
5 // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
6 //
7 //===----------------------------------------------------------------------===//
8 
14 #include "lldb/Host/OptionParser.h"
23 #include "lldb/Target/Language.h"
24 #include "lldb/Target/StackFrame.h"
25 #include "lldb/Target/Target.h"
26 #include "lldb/Target/Thread.h"
27 #include "lldb/Target/ThreadSpec.h"
30 
31 #include <memory>
32 #include <vector>
33 
34 using namespace lldb;
35 using namespace lldb_private;
36 
38  lldb::DescriptionLevel level) {
39  s->IndentMore();
40  bp->GetDescription(s, level, true);
41  s->IndentLess();
42  s->EOL();
43 }
44 
45 // Modifiable Breakpoint Options
46 #pragma mark Modify::CommandOptions
47 static constexpr OptionDefinition g_breakpoint_modify_options[] = {
48  // clang-format off
49  { LLDB_OPT_SET_1, false, "ignore-count", 'i', OptionParser::eRequiredArgument, nullptr, {}, 0, eArgTypeCount, "Set the number of times this breakpoint is skipped before stopping." },
50  { LLDB_OPT_SET_1, false, "one-shot", 'o', OptionParser::eRequiredArgument, nullptr, {}, 0, eArgTypeBoolean, "The breakpoint is deleted the first time it stop causes a stop." },
51  { LLDB_OPT_SET_1, false, "thread-index", 'x', OptionParser::eRequiredArgument, nullptr, {}, 0, eArgTypeThreadIndex, "The breakpoint stops only for the thread whose index matches this argument." },
52  { LLDB_OPT_SET_1, false, "thread-id", 't', OptionParser::eRequiredArgument, nullptr, {}, 0, eArgTypeThreadID, "The breakpoint stops only for the thread whose TID matches this argument." },
53  { LLDB_OPT_SET_1, false, "thread-name", 'T', OptionParser::eRequiredArgument, nullptr, {}, 0, eArgTypeThreadName, "The breakpoint stops only for the thread whose thread name matches this argument." },
54  { LLDB_OPT_SET_1, false, "queue-name", 'q', OptionParser::eRequiredArgument, nullptr, {}, 0, eArgTypeQueueName, "The breakpoint stops only for threads in the queue whose name is given by this argument." },
55  { LLDB_OPT_SET_1, false, "condition", 'c', OptionParser::eRequiredArgument, nullptr, {}, 0, eArgTypeExpression, "The breakpoint stops only if this condition expression evaluates to true." },
56  { LLDB_OPT_SET_1, false, "auto-continue",'G', OptionParser::eRequiredArgument, nullptr, {}, 0, eArgTypeBoolean, "The breakpoint will auto-continue after running its commands." },
57  { LLDB_OPT_SET_2, false, "enable", 'e', OptionParser::eNoArgument, nullptr, {}, 0, eArgTypeNone, "Enable the breakpoint." },
58  { LLDB_OPT_SET_3, false, "disable", 'd', OptionParser::eNoArgument, nullptr, {}, 0, eArgTypeNone, "Disable the breakpoint." },
59  { LLDB_OPT_SET_4, false, "command", 'C', OptionParser::eRequiredArgument, 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." },
60  // clang-format on
61 };
63 {
64 public:
66  OptionGroup(),
67  m_bp_opts(false) {}
68 
69  ~BreakpointOptionGroup() override = default;
70 
71  llvm::ArrayRef<OptionDefinition> GetDefinitions() override {
72  return llvm::makeArrayRef(g_breakpoint_modify_options);
73  }
74 
75  Status SetOptionValue(uint32_t option_idx, llvm::StringRef option_arg,
76  ExecutionContext *execution_context) override {
77  Status error;
78  const int short_option = g_breakpoint_modify_options[option_idx].short_option;
79 
80  switch (short_option) {
81  case 'c':
82  // Normally an empty breakpoint condition marks is as unset. But we need
83  // to say it was passed in.
84  m_bp_opts.SetCondition(option_arg.str().c_str());
85  m_bp_opts.m_set_flags.Set(BreakpointOptions::eCondition);
86  break;
87  case 'C':
88  m_commands.push_back(option_arg);
89  break;
90  case 'd':
91  m_bp_opts.SetEnabled(false);
92  break;
93  case 'e':
94  m_bp_opts.SetEnabled(true);
95  break;
96  case 'G': {
97  bool value, success;
98  value = OptionArgParser::ToBoolean(option_arg, false, &success);
99  if (success) {
100  m_bp_opts.SetAutoContinue(value);
101  } else
103  "invalid boolean value '%s' passed for -G option",
104  option_arg.str().c_str());
105  }
106  break;
107  case 'i':
108  {
109  uint32_t ignore_count;
110  if (option_arg.getAsInteger(0, ignore_count))
111  error.SetErrorStringWithFormat("invalid ignore count '%s'",
112  option_arg.str().c_str());
113  else
114  m_bp_opts.SetIgnoreCount(ignore_count);
115  }
116  break;
117  case 'o': {
118  bool value, success;
119  value = OptionArgParser::ToBoolean(option_arg, false, &success);
120  if (success) {
121  m_bp_opts.SetOneShot(value);
122  } else
124  "invalid boolean value '%s' passed for -o option",
125  option_arg.str().c_str());
126  } break;
127  case 't':
128  {
130  if (option_arg[0] != '\0') {
131  if (option_arg.getAsInteger(0, thread_id))
132  error.SetErrorStringWithFormat("invalid thread id string '%s'",
133  option_arg.str().c_str());
134  }
135  m_bp_opts.SetThreadID(thread_id);
136  }
137  break;
138  case 'T':
139  m_bp_opts.GetThreadSpec()->SetName(option_arg.str().c_str());
140  break;
141  case 'q':
142  m_bp_opts.GetThreadSpec()->SetQueueName(option_arg.str().c_str());
143  break;
144  case 'x':
145  {
146  uint32_t thread_index = UINT32_MAX;
147  if (option_arg[0] != '\n') {
148  if (option_arg.getAsInteger(0, thread_index))
149  error.SetErrorStringWithFormat("invalid thread index string '%s'",
150  option_arg.str().c_str());
151  }
152  m_bp_opts.GetThreadSpec()->SetIndex(thread_index);
153  }
154  break;
155  default:
156  error.SetErrorStringWithFormat("unrecognized option '%c'",
157  short_option);
158  break;
159  }
160 
161  return error;
162  }
163 
164  void OptionParsingStarting(ExecutionContext *execution_context) override {
165  m_bp_opts.Clear();
166  m_commands.clear();
167  }
168 
169  Status OptionParsingFinished(ExecutionContext *execution_context) override {
170  if (!m_commands.empty())
171  {
172  if (!m_commands.empty())
173  {
174  auto cmd_data = llvm::make_unique<BreakpointOptions::CommandData>();
175 
176  for (std::string &str : m_commands)
177  cmd_data->user_source.AppendString(str);
178 
179  cmd_data->stop_on_error = true;
180  m_bp_opts.SetCommandDataCallback(cmd_data);
181  }
182  }
183  return Status();
184  }
185 
187  {
188  return m_bp_opts;
189  }
190 
191  std::vector<std::string> m_commands;
193 
194 };
195 static constexpr OptionDefinition g_breakpoint_dummy_options[] = {
196  // clang-format off
197  { LLDB_OPT_SET_1, false, "dummy-breakpoints", 'D', OptionParser::eNoArgument, nullptr, {}, 0, eArgTypeNone, "Act on Dummy breakpoints - i.e. breakpoints set before a file is provided, "
198  "which prime new targets." },
199  // clang-format on
200 };
201 
203 {
204 public:
206  OptionGroup() {}
207 
208  ~BreakpointDummyOptionGroup() override = default;
209 
210  llvm::ArrayRef<OptionDefinition> GetDefinitions() override {
211  return llvm::makeArrayRef(g_breakpoint_dummy_options);
212  }
213 
214  Status SetOptionValue(uint32_t option_idx, llvm::StringRef option_arg,
215  ExecutionContext *execution_context) override {
216  Status error;
217  const int short_option = g_breakpoint_modify_options[option_idx].short_option;
218 
219  switch (short_option) {
220  case 'D':
221  m_use_dummy = true;
222  break;
223  default:
224  error.SetErrorStringWithFormat("unrecognized option '%c'",
225  short_option);
226  break;
227  }
228 
229  return error;
230  }
231 
232  void OptionParsingStarting(ExecutionContext *execution_context) override {
233  m_use_dummy = false;
234  }
235 
237 
238 };
239 
240 // If an additional option set beyond LLDB_OPTION_SET_10 is added, make sure to
241 // update the numbers passed to LLDB_OPT_SET_FROM_TO(...) appropriately.
242 #define LLDB_OPT_NOT_10 (LLDB_OPT_SET_FROM_TO(1, 11) & ~LLDB_OPT_SET_10)
243 #define LLDB_OPT_SKIP_PROLOGUE (LLDB_OPT_SET_1 | LLDB_OPT_SET_FROM_TO(3, 8))
244 #define LLDB_OPT_FILE (LLDB_OPT_SET_FROM_TO(1, 11) & ~LLDB_OPT_SET_2 & ~LLDB_OPT_SET_10)
245 #define LLDB_OPT_OFFSET_APPLIES (LLDB_OPT_SET_FROM_TO(1, 8) & ~LLDB_OPT_SET_2)
246 #define LLDB_OPT_MOVE_TO_NEAREST_CODE (LLDB_OPT_SET_1 | LLDB_OPT_SET_9)
247 #define LLDB_OPT_EXPR_LANGUAGE (LLDB_OPT_SET_FROM_TO(3, 8))
248 
249 static constexpr OptionDefinition g_breakpoint_set_options[] = {
250  // clang-format off
251  { LLDB_OPT_NOT_10, false, "shlib", 's', OptionParser::eRequiredArgument, nullptr, {}, CommandCompletions::eModuleCompletion, eArgTypeShlibName, "Set the breakpoint only in this shared library. Can repeat this option "
252  "multiple times to specify multiple shared libraries." },
253  { LLDB_OPT_SET_ALL, false, "hardware", 'H', OptionParser::eNoArgument, nullptr, {}, 0, eArgTypeNone, "Require the breakpoint to use hardware breakpoints." },
254  { LLDB_OPT_FILE, false, "file", 'f', OptionParser::eRequiredArgument, nullptr, {}, CommandCompletions::eSourceFileCompletion, eArgTypeFilename, "Specifies the source file in which to set this breakpoint. Note, by default "
255  "lldb only looks for files that are #included if they use the standard include "
256  "file extensions. To set breakpoints on .c/.cpp/.m/.mm files that are "
257  "#included, set target.inline-breakpoint-strategy to \"always\"." },
258  { LLDB_OPT_SET_1, true, "line", 'l', OptionParser::eRequiredArgument, nullptr, {}, 0, eArgTypeLineNum, "Specifies the line number on which to set this breakpoint." },
259 
260  // Comment out this option for the moment, as we don't actually use it, but
261  // will in the future. This way users won't see it, but the infrastructure is
262  // left in place.
263  // { 0, false, "column", 'C', OptionParser::eRequiredArgument, nullptr, "<column>",
264  // "Set the breakpoint by source location at this particular column."},
265 
266  { LLDB_OPT_SET_2, true, "address", 'a', OptionParser::eRequiredArgument, nullptr, {}, 0, eArgTypeAddressOrExpression, "Set the breakpoint at the specified address. If the address maps uniquely to "
267  "a particular binary, then the address will be converted to a \"file\" "
268  "address, so that the breakpoint will track that binary+offset no matter where "
269  "the binary eventually loads. Alternately, if you also specify the module - "
270  "with the -s option - then the address will be treated as a file address in "
271  "that module, and resolved accordingly. Again, this will allow lldb to track "
272  "that offset on subsequent reloads. The module need not have been loaded at "
273  "the time you specify this breakpoint, and will get resolved when the module "
274  "is loaded." },
275  { LLDB_OPT_SET_3, true, "name", 'n', OptionParser::eRequiredArgument, nullptr, {}, CommandCompletions::eSymbolCompletion, eArgTypeFunctionName, "Set the breakpoint by function name. Can be repeated multiple times to make "
276  "one breakpoint for multiple names" },
277  { LLDB_OPT_SET_9, false, "source-regexp-function", 'X', OptionParser::eRequiredArgument, nullptr, {}, CommandCompletions::eSymbolCompletion, eArgTypeFunctionName, "When used with '-p' limits the source regex to source contained in the named "
278  "functions. Can be repeated multiple times." },
279  { LLDB_OPT_SET_4, true, "fullname", 'F', OptionParser::eRequiredArgument, nullptr, {}, CommandCompletions::eSymbolCompletion, eArgTypeFullName, "Set the breakpoint by fully qualified function names. For C++ this means "
280  "namespaces and all arguments, and for Objective-C this means a full function "
281  "prototype with class and selector. Can be repeated multiple times to make "
282  "one breakpoint for multiple names." },
283  { LLDB_OPT_SET_5, true, "selector", 'S', OptionParser::eRequiredArgument, nullptr, {}, 0, eArgTypeSelector, "Set the breakpoint by ObjC selector name. Can be repeated multiple times to "
284  "make one breakpoint for multiple Selectors." },
285  { LLDB_OPT_SET_6, true, "method", 'M', OptionParser::eRequiredArgument, nullptr, {}, 0, eArgTypeMethod, "Set the breakpoint by C++ method names. Can be repeated multiple times to "
286  "make one breakpoint for multiple methods." },
287  { LLDB_OPT_SET_7, true, "func-regex", 'r', OptionParser::eRequiredArgument, nullptr, {}, 0, eArgTypeRegularExpression, "Set the breakpoint by function name, evaluating a regular-expression to find "
288  "the function name(s)." },
289  { LLDB_OPT_SET_8, true, "basename", 'b', OptionParser::eRequiredArgument, nullptr, {}, CommandCompletions::eSymbolCompletion, eArgTypeFunctionName, "Set the breakpoint by function basename (C++ namespaces and arguments will be "
290  "ignored). Can be repeated multiple times to make one breakpoint for multiple "
291  "symbols." },
292  { LLDB_OPT_SET_9, true, "source-pattern-regexp", 'p', OptionParser::eRequiredArgument, nullptr, {}, 0, eArgTypeRegularExpression, "Set the breakpoint by specifying a regular expression which is matched "
293  "against the source text in a source file or files specified with the -f "
294  "option. The -f option can be specified more than once. If no source files "
295  "are specified, uses the current \"default source file\". If you want to "
296  "match against all source files, pass the \"--all-files\" option." },
297  { LLDB_OPT_SET_9, false, "all-files", 'A', OptionParser::eNoArgument, nullptr, {}, 0, eArgTypeNone, "All files are searched for source pattern matches." },
298  { LLDB_OPT_SET_11, true, "python-class", 'P', OptionParser::eRequiredArgument, nullptr, {}, 0, eArgTypePythonClass, "The name of the class that implement a scripted breakpoint." },
299  { LLDB_OPT_SET_11, false, "python-class-key", 'k', OptionParser::eRequiredArgument, nullptr, {}, 0, eArgTypeNone, "The key for a key/value pair passed to the class that implements a scripted breakpoint. Can be specified more than once." },
300  { LLDB_OPT_SET_11, false, "python-class-value", 'v', OptionParser::eRequiredArgument, nullptr, {}, 0, eArgTypeNone, "The value for the previous key in the pair passed to the class that implements a scripted breakpoint. Can be specified more than once." },
301  { LLDB_OPT_SET_10, true, "language-exception", 'E', OptionParser::eRequiredArgument, nullptr, {}, 0, eArgTypeLanguage, "Set the breakpoint on exceptions thrown by the specified language (without "
302  "options, on throw but not catch.)" },
303  { LLDB_OPT_SET_10, false, "on-throw", 'w', OptionParser::eRequiredArgument, nullptr, {}, 0, eArgTypeBoolean, "Set the breakpoint on exception throW." },
304  { LLDB_OPT_SET_10, false, "on-catch", 'h', OptionParser::eRequiredArgument, nullptr, {}, 0, eArgTypeBoolean, "Set the breakpoint on exception catcH." },
305 
306  // Don't add this option till it actually does something useful...
307  // { LLDB_OPT_SET_10, false, "exception-typename", 'O', OptionParser::eRequiredArgument, nullptr, nullptr, 0, eArgTypeTypeName,
308  // "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" },
309 
310  { LLDB_OPT_EXPR_LANGUAGE, false, "language", 'L', OptionParser::eRequiredArgument, nullptr, {}, 0, eArgTypeLanguage, "Specifies the Language to use when interpreting the breakpoint's expression "
311  "(note: currently only implemented for setting breakpoints on identifiers). "
312  "If not set the target.language setting is used." },
313  { LLDB_OPT_SKIP_PROLOGUE, false, "skip-prologue", 'K', OptionParser::eRequiredArgument, nullptr, {}, 0, eArgTypeBoolean, "sKip the prologue if the breakpoint is at the beginning of a function. "
314  "If not set the target.skip-prologue setting is used." },
315  { LLDB_OPT_SET_ALL, false, "breakpoint-name", 'N', OptionParser::eRequiredArgument, nullptr, {}, 0, eArgTypeBreakpointName, "Adds this to the list of names for this breakpoint." },
316  { LLDB_OPT_OFFSET_APPLIES, false, "address-slide", 'R', OptionParser::eRequiredArgument, nullptr, {}, 0, eArgTypeAddress, "Add the specified offset to whatever address(es) the breakpoint resolves to. "
317  "At present this applies the offset directly as given, and doesn't try to align it to instruction boundaries." },
318  { LLDB_OPT_MOVE_TO_NEAREST_CODE, false, "move-to-nearest-code", 'm', OptionParser::eRequiredArgument, nullptr, {}, 0, eArgTypeBoolean, "Move breakpoints to nearest code. If not set the target.move-to-nearest-code "
319  "setting is used." },
320  // clang-format on
321 };
322 
323 // CommandObjectBreakpointSet
324 
326 public:
327  typedef enum BreakpointSetType {
337 
340  interpreter, "breakpoint set",
341  "Sets a breakpoint or set of breakpoints in the executable.",
342  "breakpoint set <cmd-options>"),
343  m_bp_opts(), m_options() {
344  // We're picking up all the normal options, commands and disable.
345  m_all_options.Append(&m_bp_opts,
348  m_all_options.Append(&m_dummy_options, LLDB_OPT_SET_1, LLDB_OPT_SET_ALL);
349  m_all_options.Append(&m_options);
350  m_all_options.Finalize();
351  }
352 
353  ~CommandObjectBreakpointSet() override = default;
354 
355  Options *GetOptions() override { return &m_all_options; }
356 
357  class CommandOptions : public OptionGroup {
358  public:
360  : OptionGroup(), m_condition(), m_filenames(), m_line_num(0), m_column(0),
361  m_func_names(), m_func_name_type_mask(eFunctionNameTypeNone),
362  m_func_regexp(), m_source_text_regexp(), m_modules(), m_load_addr(),
363  m_catch_bp(false), m_throw_bp(true), m_hardware(false),
364  m_exception_language(eLanguageTypeUnknown),
365  m_language(lldb::eLanguageTypeUnknown),
366  m_skip_prologue(eLazyBoolCalculate),
367  m_all_files(false), m_move_to_nearest_code(eLazyBoolCalculate) {}
368 
369  ~CommandOptions() override = default;
370 
371  Status SetOptionValue(uint32_t option_idx, llvm::StringRef option_arg,
372  ExecutionContext *execution_context) override {
373  Status error;
374  const int short_option = g_breakpoint_set_options[option_idx].short_option;
375 
376  switch (short_option) {
377  case 'a': {
378  m_load_addr = OptionArgParser::ToAddress(execution_context, option_arg,
379  LLDB_INVALID_ADDRESS, &error);
380  } break;
381 
382  case 'A':
383  m_all_files = true;
384  break;
385 
386  case 'b':
387  m_func_names.push_back(option_arg);
388  m_func_name_type_mask |= eFunctionNameTypeBase;
389  break;
390 
391  case 'C':
392  if (option_arg.getAsInteger(0, m_column))
393  error.SetErrorStringWithFormat("invalid column number: %s",
394  option_arg.str().c_str());
395  break;
396 
397  case 'E': {
398  LanguageType language = Language::GetLanguageTypeFromString(option_arg);
399 
400  switch (language) {
401  case eLanguageTypeC89:
402  case eLanguageTypeC:
403  case eLanguageTypeC99:
404  case eLanguageTypeC11:
405  m_exception_language = eLanguageTypeC;
406  break;
411  m_exception_language = eLanguageTypeC_plus_plus;
412  break;
413  case eLanguageTypeObjC:
414  m_exception_language = eLanguageTypeObjC;
415  break;
418  "Set exception breakpoints separately for c++ and objective-c");
419  break;
422  "Unknown language type: '%s' for exception breakpoint",
423  option_arg.str().c_str());
424  break;
425  default:
427  "Unsupported language type: '%s' for exception breakpoint",
428  option_arg.str().c_str());
429  }
430  } break;
431 
432  case 'f':
433  m_filenames.AppendIfUnique(FileSpec(option_arg));
434  break;
435 
436  case 'F':
437  m_func_names.push_back(option_arg);
438  m_func_name_type_mask |= eFunctionNameTypeFull;
439  break;
440 
441  case 'h': {
442  bool success;
443  m_catch_bp = OptionArgParser::ToBoolean(option_arg, true, &success);
444  if (!success)
446  "Invalid boolean value for on-catch option: '%s'",
447  option_arg.str().c_str());
448  } break;
449 
450  case 'H':
451  m_hardware = true;
452  break;
453 
454  case 'k': {
455  if (m_current_key.empty())
456  m_current_key.assign(option_arg);
457  else
458  error.SetErrorStringWithFormat("Key: %s missing value.",
459  m_current_key.c_str());
460 
461  } break;
462  case 'K': {
463  bool success;
464  bool value;
465  value = OptionArgParser::ToBoolean(option_arg, true, &success);
466  if (value)
467  m_skip_prologue = eLazyBoolYes;
468  else
469  m_skip_prologue = eLazyBoolNo;
470 
471  if (!success)
473  "Invalid boolean value for skip prologue option: '%s'",
474  option_arg.str().c_str());
475  } break;
476 
477  case 'l':
478  if (option_arg.getAsInteger(0, m_line_num))
479  error.SetErrorStringWithFormat("invalid line number: %s.",
480  option_arg.str().c_str());
481  break;
482 
483  case 'L':
484  m_language = Language::GetLanguageTypeFromString(option_arg);
485  if (m_language == eLanguageTypeUnknown)
487  "Unknown language type: '%s' for breakpoint",
488  option_arg.str().c_str());
489  break;
490 
491  case 'm': {
492  bool success;
493  bool value;
494  value = OptionArgParser::ToBoolean(option_arg, true, &success);
495  if (value)
496  m_move_to_nearest_code = eLazyBoolYes;
497  else
498  m_move_to_nearest_code = eLazyBoolNo;
499 
500  if (!success)
502  "Invalid boolean value for move-to-nearest-code option: '%s'",
503  option_arg.str().c_str());
504  break;
505  }
506 
507  case 'M':
508  m_func_names.push_back(option_arg);
509  m_func_name_type_mask |= eFunctionNameTypeMethod;
510  break;
511 
512  case 'n':
513  m_func_names.push_back(option_arg);
514  m_func_name_type_mask |= eFunctionNameTypeAuto;
515  break;
516 
517  case 'N': {
518  if (BreakpointID::StringIsBreakpointName(option_arg, error))
519  m_breakpoint_names.push_back(option_arg);
520  else
521  error.SetErrorStringWithFormat("Invalid breakpoint name: %s",
522  option_arg.str().c_str());
523  break;
524  }
525 
526  case 'R': {
527  lldb::addr_t tmp_offset_addr;
528  tmp_offset_addr = OptionArgParser::ToAddress(execution_context,
529  option_arg, 0, &error);
530  if (error.Success())
531  m_offset_addr = tmp_offset_addr;
532  } break;
533 
534  case 'O':
535  m_exception_extra_args.AppendArgument("-O");
536  m_exception_extra_args.AppendArgument(option_arg);
537  break;
538 
539  case 'p':
540  m_source_text_regexp.assign(option_arg);
541  break;
542 
543  case 'P':
544  m_python_class.assign(option_arg);
545  break;
546 
547  case 'r':
548  m_func_regexp.assign(option_arg);
549  break;
550 
551  case 's':
552  m_modules.AppendIfUnique(FileSpec(option_arg));
553  break;
554 
555  case 'S':
556  m_func_names.push_back(option_arg);
557  m_func_name_type_mask |= eFunctionNameTypeSelector;
558  break;
559 
560  case 'v': {
561  if (!m_current_key.empty()) {
562  m_extra_args_sp->AddStringItem(m_current_key, option_arg);
563  m_current_key.clear();
564  }
565  else
566  error.SetErrorStringWithFormat("Value \"%s\" missing matching key.",
567  option_arg.str().c_str());
568  } break;
569 
570  case 'w': {
571  bool success;
572  m_throw_bp = OptionArgParser::ToBoolean(option_arg, true, &success);
573  if (!success)
575  "Invalid boolean value for on-throw option: '%s'",
576  option_arg.str().c_str());
577  } break;
578 
579  case 'X':
580  m_source_regex_func_names.insert(option_arg);
581  break;
582 
583  default:
584  error.SetErrorStringWithFormat("unrecognized option '%c'",
585  short_option);
586  break;
587  }
588 
589  return error;
590  }
591 
592  void OptionParsingStarting(ExecutionContext *execution_context) override {
593  m_filenames.Clear();
594  m_line_num = 0;
595  m_column = 0;
596  m_func_names.clear();
597  m_func_name_type_mask = eFunctionNameTypeNone;
598  m_func_regexp.clear();
599  m_source_text_regexp.clear();
600  m_modules.Clear();
601  m_load_addr = LLDB_INVALID_ADDRESS;
602  m_offset_addr = 0;
603  m_catch_bp = false;
604  m_throw_bp = true;
605  m_hardware = false;
606  m_exception_language = eLanguageTypeUnknown;
607  m_language = lldb::eLanguageTypeUnknown;
608  m_skip_prologue = eLazyBoolCalculate;
609  m_breakpoint_names.clear();
610  m_all_files = false;
611  m_exception_extra_args.Clear();
612  m_move_to_nearest_code = eLazyBoolCalculate;
613  m_source_regex_func_names.clear();
614  m_python_class.clear();
615  m_extra_args_sp = std::make_shared<StructuredData::Dictionary>();
616  m_current_key.clear();
617  }
618 
619  llvm::ArrayRef<OptionDefinition> GetDefinitions() override {
620  return llvm::makeArrayRef(g_breakpoint_set_options);
621  }
622 
623  // Instance variables to hold the values for command options.
624 
625  std::string m_condition;
626  FileSpecList m_filenames;
629  std::vector<std::string> m_func_names;
630  std::vector<std::string> m_breakpoint_names;
631  lldb::FunctionNameType m_func_name_type_mask;
632  std::string m_func_regexp;
633  std::string m_source_text_regexp;
634  FileSpecList m_modules;
639  bool m_hardware; // Request to use hardware breakpoints
646  std::unordered_set<std::string> m_source_regex_func_names;
647  std::string m_python_class;
649  std::string m_current_key;
650  };
651 
652 protected:
653  bool DoExecute(Args &command, CommandReturnObject &result) override {
654  Target *target = GetSelectedOrDummyTarget(m_dummy_options.m_use_dummy);
655 
656  if (target == nullptr) {
657  result.AppendError("Invalid target. Must set target before setting "
658  "breakpoints (see 'target create' command).");
660  return false;
661  }
662 
663  // The following are the various types of breakpoints that could be set:
664  // 1). -f -l -p [-s -g] (setting breakpoint by source location)
665  // 2). -a [-s -g] (setting breakpoint by address)
666  // 3). -n [-s -g] (setting breakpoint by function name)
667  // 4). -r [-s -g] (setting breakpoint by function name regular
668  // expression)
669  // 5). -p -f (setting a breakpoint by comparing a reg-exp
670  // to source text)
671  // 6). -E [-w -h] (setting a breakpoint for exceptions for a
672  // given language.)
673 
674  BreakpointSetType break_type = eSetTypeInvalid;
675 
676  if (!m_options.m_python_class.empty())
677  break_type = eSetTypeScripted;
678  else if (m_options.m_line_num != 0)
679  break_type = eSetTypeFileAndLine;
680  else if (m_options.m_load_addr != LLDB_INVALID_ADDRESS)
681  break_type = eSetTypeAddress;
682  else if (!m_options.m_func_names.empty())
683  break_type = eSetTypeFunctionName;
684  else if (!m_options.m_func_regexp.empty())
685  break_type = eSetTypeFunctionRegexp;
686  else if (!m_options.m_source_text_regexp.empty())
687  break_type = eSetTypeSourceRegexp;
688  else if (m_options.m_exception_language != eLanguageTypeUnknown)
689  break_type = eSetTypeException;
690 
691  BreakpointSP bp_sp = nullptr;
692  FileSpec module_spec;
693  const bool internal = false;
694 
695  // If the user didn't specify skip-prologue, having an offset should turn
696  // that off.
697  if (m_options.m_offset_addr != 0 &&
698  m_options.m_skip_prologue == eLazyBoolCalculate)
699  m_options.m_skip_prologue = eLazyBoolNo;
700 
701  switch (break_type) {
702  case eSetTypeFileAndLine: // Breakpoint by source position
703  {
704  FileSpec file;
705  const size_t num_files = m_options.m_filenames.GetSize();
706  if (num_files == 0) {
707  if (!GetDefaultFile(target, file, result)) {
708  result.AppendError("No file supplied and no default file available.");
710  return false;
711  }
712  } else if (num_files > 1) {
713  result.AppendError("Only one file at a time is allowed for file and "
714  "line breakpoints.");
716  return false;
717  } else
718  file = m_options.m_filenames.GetFileSpecAtIndex(0);
719 
720  // Only check for inline functions if
721  LazyBool check_inlines = eLazyBoolCalculate;
722 
723  bp_sp = target->CreateBreakpoint(&(m_options.m_modules),
724  file,
725  m_options.m_line_num,
726  m_options.m_column,
727  m_options.m_offset_addr,
728  check_inlines,
729  m_options.m_skip_prologue,
730  internal,
731  m_options.m_hardware,
732  m_options.m_move_to_nearest_code);
733  } break;
734 
735  case eSetTypeAddress: // Breakpoint by address
736  {
737  // If a shared library has been specified, make an lldb_private::Address
738  // with the library, and use that. That way the address breakpoint
739  // will track the load location of the library.
740  size_t num_modules_specified = m_options.m_modules.GetSize();
741  if (num_modules_specified == 1) {
742  const FileSpec *file_spec =
743  m_options.m_modules.GetFileSpecPointerAtIndex(0);
744  bp_sp = target->CreateAddressInModuleBreakpoint(m_options.m_load_addr,
745  internal, file_spec,
746  m_options.m_hardware);
747  } else if (num_modules_specified == 0) {
748  bp_sp = target->CreateBreakpoint(m_options.m_load_addr, internal,
749  m_options.m_hardware);
750  } else {
751  result.AppendError("Only one shared library can be specified for "
752  "address breakpoints.");
754  return false;
755  }
756  break;
757  }
758  case eSetTypeFunctionName: // Breakpoint by function name
759  {
760  FunctionNameType name_type_mask = m_options.m_func_name_type_mask;
761 
762  if (name_type_mask == 0)
763  name_type_mask = eFunctionNameTypeAuto;
764 
765  bp_sp = target->CreateBreakpoint(&(m_options.m_modules),
766  &(m_options.m_filenames),
767  m_options.m_func_names,
768  name_type_mask,
769  m_options.m_language,
770  m_options.m_offset_addr,
771  m_options.m_skip_prologue,
772  internal,
773  m_options.m_hardware);
774  } break;
775 
776  case eSetTypeFunctionRegexp: // Breakpoint by regular expression function
777  // name
778  {
779  RegularExpression regexp(m_options.m_func_regexp);
780  if (!regexp.IsValid()) {
781  char err_str[1024];
782  regexp.GetErrorAsCString(err_str, sizeof(err_str));
783  result.AppendErrorWithFormat(
784  "Function name regular expression could not be compiled: \"%s\"",
785  err_str);
787  return false;
788  }
789 
790  bp_sp = target->CreateFuncRegexBreakpoint(&(m_options.m_modules),
791  &(m_options.m_filenames),
792  regexp,
793  m_options.m_language,
794  m_options.m_skip_prologue,
795  internal,
796  m_options.m_hardware);
797  }
798  break;
799  case eSetTypeSourceRegexp: // Breakpoint by regexp on source text.
800  {
801  const size_t num_files = m_options.m_filenames.GetSize();
802 
803  if (num_files == 0 && !m_options.m_all_files) {
804  FileSpec file;
805  if (!GetDefaultFile(target, file, result)) {
806  result.AppendError(
807  "No files provided and could not find default file.");
809  return false;
810  } else {
811  m_options.m_filenames.Append(file);
812  }
813  }
814 
815  RegularExpression regexp(m_options.m_source_text_regexp);
816  if (!regexp.IsValid()) {
817  char err_str[1024];
818  regexp.GetErrorAsCString(err_str, sizeof(err_str));
819  result.AppendErrorWithFormat(
820  "Source text regular expression could not be compiled: \"%s\"",
821  err_str);
823  return false;
824  }
825  bp_sp =
826  target->CreateSourceRegexBreakpoint(&(m_options.m_modules),
827  &(m_options.m_filenames),
828  m_options
829  .m_source_regex_func_names,
830  regexp,
831  internal,
832  m_options.m_hardware,
833  m_options.m_move_to_nearest_code);
834  } break;
835  case eSetTypeException: {
836  Status precond_error;
837  bp_sp = target->CreateExceptionBreakpoint(m_options.m_exception_language,
838  m_options.m_catch_bp,
839  m_options.m_throw_bp,
840  internal,
841  &m_options
842  .m_exception_extra_args,
843  &precond_error);
844  if (precond_error.Fail()) {
845  result.AppendErrorWithFormat(
846  "Error setting extra exception arguments: %s",
847  precond_error.AsCString());
848  target->RemoveBreakpointByID(bp_sp->GetID());
850  return false;
851  }
852  } break;
853  case eSetTypeScripted: {
854 
855  Status error;
856  bp_sp = target->CreateScriptedBreakpoint(m_options.m_python_class,
857  &(m_options.m_modules),
858  &(m_options.m_filenames),
859  false,
860  m_options.m_hardware,
861  m_options.m_extra_args_sp,
862  &error);
863  if (error.Fail()) {
864  result.AppendErrorWithFormat(
865  "Error setting extra exception arguments: %s",
866  error.AsCString());
867  target->RemoveBreakpointByID(bp_sp->GetID());
869  return false;
870  }
871  } break;
872  default:
873  break;
874  }
875 
876  // Now set the various options that were passed in:
877  if (bp_sp) {
878  bp_sp->GetOptions()->CopyOverSetOptions(m_bp_opts.GetBreakpointOptions());
879 
880  if (!m_options.m_breakpoint_names.empty()) {
881  Status name_error;
882  for (auto name : m_options.m_breakpoint_names) {
883  target->AddNameToBreakpoint(bp_sp, name.c_str(), name_error);
884  if (name_error.Fail()) {
885  result.AppendErrorWithFormat("Invalid breakpoint name: %s",
886  name.c_str());
887  target->RemoveBreakpointByID(bp_sp->GetID());
889  return false;
890  }
891  }
892  }
893  }
894 
895  if (bp_sp) {
896  Stream &output_stream = result.GetOutputStream();
897  const bool show_locations = false;
898  bp_sp->GetDescription(&output_stream, lldb::eDescriptionLevelInitial,
899  show_locations);
900  if (target == GetDebugger().GetDummyTarget())
901  output_stream.Printf("Breakpoint set in dummy target, will get copied "
902  "into future targets.\n");
903  else {
904  // Don't print out this warning for exception breakpoints. They can
905  // get set before the target is set, but we won't know how to actually
906  // set the breakpoint till we run.
907  if (bp_sp->GetNumLocations() == 0 && break_type != eSetTypeException) {
908  output_stream.Printf("WARNING: Unable to resolve breakpoint to any "
909  "actual locations.\n");
910  }
911  }
913  } else if (!bp_sp) {
914  result.AppendError("Breakpoint creation failed: No breakpoint created.");
916  }
917 
918  return result.Succeeded();
919  }
920 
921 private:
922  bool GetDefaultFile(Target *target, FileSpec &file,
923  CommandReturnObject &result) {
924  uint32_t default_line;
925  // First use the Source Manager's default file. Then use the current stack
926  // frame's file.
927  if (!target->GetSourceManager().GetDefaultFileAndLine(file, default_line)) {
928  StackFrame *cur_frame = m_exe_ctx.GetFramePtr();
929  if (cur_frame == nullptr) {
930  result.AppendError(
931  "No selected frame to use to find the default file.");
933  return false;
934  } else if (!cur_frame->HasDebugInformation()) {
935  result.AppendError("Cannot use the selected frame to find the default "
936  "file, it has no debug info.");
938  return false;
939  } else {
940  const SymbolContext &sc =
941  cur_frame->GetSymbolContext(eSymbolContextLineEntry);
942  if (sc.line_entry.file) {
943  file = sc.line_entry.file;
944  } else {
945  result.AppendError("Can't find the file for the selected frame to "
946  "use as the default file.");
948  return false;
949  }
950  }
951  }
952  return true;
953  }
954 
955  BreakpointOptionGroup m_bp_opts;
956  BreakpointDummyOptionGroup m_dummy_options;
957  CommandOptions m_options;
958  OptionGroupOptions m_all_options;
959 };
960 
961 // CommandObjectBreakpointModify
962 #pragma mark Modify
963 
965 public:
967  : CommandObjectParsed(interpreter, "breakpoint modify",
968  "Modify the options on a breakpoint or set of "
969  "breakpoints in the executable. "
970  "If no breakpoint is specified, acts on the last "
971  "created breakpoint. "
972  "With the exception of -e, -d and -i, passing an "
973  "empty argument clears the modification.",
974  nullptr),
975  m_options() {
977  CommandObject::AddIDsArgumentData(arg, eArgTypeBreakpointID,
979  // Add the entry for the first argument for this command to the object's
980  // arguments vector.
981  m_arguments.push_back(arg);
982 
983  m_options.Append(&m_bp_opts,
986  m_options.Append(&m_dummy_opts, LLDB_OPT_SET_1, LLDB_OPT_SET_ALL);
987  m_options.Finalize();
988  }
989 
990  ~CommandObjectBreakpointModify() override = default;
991 
992  Options *GetOptions() override { return &m_options; }
993 
994 protected:
995  bool DoExecute(Args &command, CommandReturnObject &result) override {
996  Target *target = GetSelectedOrDummyTarget(m_dummy_opts.m_use_dummy);
997  if (target == nullptr) {
998  result.AppendError("Invalid target. No existing target or breakpoints.");
1000  return false;
1001  }
1002 
1003  std::unique_lock<std::recursive_mutex> lock;
1004  target->GetBreakpointList().GetListMutex(lock);
1005 
1006  BreakpointIDList valid_bp_ids;
1007 
1008  CommandObjectMultiwordBreakpoint::VerifyBreakpointOrLocationIDs(
1009  command, target, result, &valid_bp_ids,
1010  BreakpointName::Permissions::PermissionKinds::disablePerm);
1011 
1012  if (result.Succeeded()) {
1013  const size_t count = valid_bp_ids.GetSize();
1014  for (size_t i = 0; i < count; ++i) {
1015  BreakpointID cur_bp_id = valid_bp_ids.GetBreakpointIDAtIndex(i);
1016 
1017  if (cur_bp_id.GetBreakpointID() != LLDB_INVALID_BREAK_ID) {
1018  Breakpoint *bp =
1019  target->GetBreakpointByID(cur_bp_id.GetBreakpointID()).get();
1020  if (cur_bp_id.GetLocationID() != LLDB_INVALID_BREAK_ID) {
1021  BreakpointLocation *location =
1022  bp->FindLocationByID(cur_bp_id.GetLocationID()).get();
1023  if (location)
1024  location->GetLocationOptions()
1025  ->CopyOverSetOptions(m_bp_opts.GetBreakpointOptions());
1026  } else {
1027  bp->GetOptions()
1028  ->CopyOverSetOptions(m_bp_opts.GetBreakpointOptions());
1029  }
1030  }
1031  }
1032  }
1033 
1034  return result.Succeeded();
1035  }
1036 
1037 private:
1038  BreakpointOptionGroup m_bp_opts;
1039  BreakpointDummyOptionGroup m_dummy_opts;
1040  OptionGroupOptions m_options;
1041 };
1042 
1043 // CommandObjectBreakpointEnable
1044 #pragma mark Enable
1045 
1047 public:
1049  : CommandObjectParsed(interpreter, "enable",
1050  "Enable the specified disabled breakpoint(s). If "
1051  "no breakpoints are specified, enable all of them.",
1052  nullptr) {
1054  CommandObject::AddIDsArgumentData(arg, eArgTypeBreakpointID,
1056  // Add the entry for the first argument for this command to the object's
1057  // arguments vector.
1058  m_arguments.push_back(arg);
1059  }
1060 
1061  ~CommandObjectBreakpointEnable() override = default;
1062 
1063 protected:
1064  bool DoExecute(Args &command, CommandReturnObject &result) override {
1065  Target *target = GetSelectedOrDummyTarget();
1066  if (target == nullptr) {
1067  result.AppendError("Invalid target. No existing target or breakpoints.");
1069  return false;
1070  }
1071 
1072  std::unique_lock<std::recursive_mutex> lock;
1073  target->GetBreakpointList().GetListMutex(lock);
1074 
1075  const BreakpointList &breakpoints = target->GetBreakpointList();
1076 
1077  size_t num_breakpoints = breakpoints.GetSize();
1078 
1079  if (num_breakpoints == 0) {
1080  result.AppendError("No breakpoints exist to be enabled.");
1082  return false;
1083  }
1084 
1085  if (command.empty()) {
1086  // No breakpoint selected; enable all currently set breakpoints.
1087  target->EnableAllowedBreakpoints();
1088  result.AppendMessageWithFormat("All breakpoints enabled. (%" PRIu64
1089  " breakpoints)\n",
1090  (uint64_t)num_breakpoints);
1092  } else {
1093  // Particular breakpoint selected; enable that breakpoint.
1094  BreakpointIDList valid_bp_ids;
1095  CommandObjectMultiwordBreakpoint::VerifyBreakpointOrLocationIDs(
1096  command, target, result, &valid_bp_ids,
1097  BreakpointName::Permissions::PermissionKinds::disablePerm);
1098 
1099  if (result.Succeeded()) {
1100  int enable_count = 0;
1101  int loc_count = 0;
1102  const size_t count = valid_bp_ids.GetSize();
1103  for (size_t i = 0; i < count; ++i) {
1104  BreakpointID cur_bp_id = valid_bp_ids.GetBreakpointIDAtIndex(i);
1105 
1106  if (cur_bp_id.GetBreakpointID() != LLDB_INVALID_BREAK_ID) {
1107  Breakpoint *breakpoint =
1108  target->GetBreakpointByID(cur_bp_id.GetBreakpointID()).get();
1109  if (cur_bp_id.GetLocationID() != LLDB_INVALID_BREAK_ID) {
1110  BreakpointLocation *location =
1111  breakpoint->FindLocationByID(cur_bp_id.GetLocationID()).get();
1112  if (location) {
1113  location->SetEnabled(true);
1114  ++loc_count;
1115  }
1116  } else {
1117  breakpoint->SetEnabled(true);
1118  ++enable_count;
1119  }
1120  }
1121  }
1122  result.AppendMessageWithFormat("%d breakpoints enabled.\n",
1123  enable_count + loc_count);
1125  }
1126  }
1127 
1128  return result.Succeeded();
1129  }
1130 };
1131 
1132 // CommandObjectBreakpointDisable
1133 #pragma mark Disable
1134 
1136 public:
1139  interpreter, "breakpoint disable",
1140  "Disable the specified breakpoint(s) without deleting "
1141  "them. If none are specified, disable all "
1142  "breakpoints.",
1143  nullptr) {
1144  SetHelpLong(
1145  "Disable the specified breakpoint(s) without deleting them. \
1146 If none are specified, disable all breakpoints."
1147  R"(
1148 
1149 )"
1150  "Note: disabling a breakpoint will cause none of its locations to be hit \
1151 regardless of whether individual locations are enabled or disabled. After the sequence:"
1152  R"(
1153 
1154  (lldb) break disable 1
1155  (lldb) break enable 1.1
1156 
1157 execution will NOT stop at location 1.1. To achieve that, type:
1158 
1159  (lldb) break disable 1.*
1160  (lldb) break enable 1.1
1161 
1162 )"
1163  "The first command disables all locations for breakpoint 1, \
1164 the second re-enables the first location.");
1165 
1167  CommandObject::AddIDsArgumentData(arg, eArgTypeBreakpointID,
1169  // Add the entry for the first argument for this command to the object's
1170  // arguments vector.
1171  m_arguments.push_back(arg);
1172  }
1173 
1174  ~CommandObjectBreakpointDisable() override = default;
1175 
1176 protected:
1177  bool DoExecute(Args &command, CommandReturnObject &result) override {
1178  Target *target = GetSelectedOrDummyTarget();
1179  if (target == nullptr) {
1180  result.AppendError("Invalid target. No existing target or breakpoints.");
1182  return false;
1183  }
1184 
1185  std::unique_lock<std::recursive_mutex> lock;
1186  target->GetBreakpointList().GetListMutex(lock);
1187 
1188  const BreakpointList &breakpoints = target->GetBreakpointList();
1189  size_t num_breakpoints = breakpoints.GetSize();
1190 
1191  if (num_breakpoints == 0) {
1192  result.AppendError("No breakpoints exist to be disabled.");
1194  return false;
1195  }
1196 
1197  if (command.empty()) {
1198  // No breakpoint selected; disable all currently set breakpoints.
1199  target->DisableAllowedBreakpoints();
1200  result.AppendMessageWithFormat("All breakpoints disabled. (%" PRIu64
1201  " breakpoints)\n",
1202  (uint64_t)num_breakpoints);
1204  } else {
1205  // Particular breakpoint selected; disable that breakpoint.
1206  BreakpointIDList valid_bp_ids;
1207 
1208  CommandObjectMultiwordBreakpoint::VerifyBreakpointOrLocationIDs(
1209  command, target, result, &valid_bp_ids,
1210  BreakpointName::Permissions::PermissionKinds::disablePerm);
1211 
1212  if (result.Succeeded()) {
1213  int disable_count = 0;
1214  int loc_count = 0;
1215  const size_t count = valid_bp_ids.GetSize();
1216  for (size_t i = 0; i < count; ++i) {
1217  BreakpointID cur_bp_id = valid_bp_ids.GetBreakpointIDAtIndex(i);
1218 
1219  if (cur_bp_id.GetBreakpointID() != LLDB_INVALID_BREAK_ID) {
1220  Breakpoint *breakpoint =
1221  target->GetBreakpointByID(cur_bp_id.GetBreakpointID()).get();
1222  if (cur_bp_id.GetLocationID() != LLDB_INVALID_BREAK_ID) {
1223  BreakpointLocation *location =
1224  breakpoint->FindLocationByID(cur_bp_id.GetLocationID()).get();
1225  if (location) {
1226  location->SetEnabled(false);
1227  ++loc_count;
1228  }
1229  } else {
1230  breakpoint->SetEnabled(false);
1231  ++disable_count;
1232  }
1233  }
1234  }
1235  result.AppendMessageWithFormat("%d breakpoints disabled.\n",
1236  disable_count + loc_count);
1238  }
1239  }
1240 
1241  return result.Succeeded();
1242  }
1243 };
1244 
1245 // CommandObjectBreakpointList
1246 
1247 #pragma mark List::CommandOptions
1248 static constexpr OptionDefinition g_breakpoint_list_options[] = {
1249  // clang-format off
1250  { LLDB_OPT_SET_ALL, false, "internal", 'i', OptionParser::eNoArgument, nullptr, {}, 0, eArgTypeNone, "Show debugger internal breakpoints" },
1251  { LLDB_OPT_SET_1, false, "brief", 'b', OptionParser::eNoArgument, nullptr, {}, 0, eArgTypeNone, "Give a brief description of the breakpoint (no location info)." },
1252  // FIXME: We need to add an "internal" command, and then add this sort of thing to it.
1253  // But I need to see it for now, and don't want to wait.
1254  { LLDB_OPT_SET_2, false, "full", 'f', OptionParser::eNoArgument, nullptr, {}, 0, eArgTypeNone, "Give a full description of the breakpoint and its locations." },
1255  { LLDB_OPT_SET_3, false, "verbose", 'v', OptionParser::eNoArgument, nullptr, {}, 0, eArgTypeNone, "Explain everything we know about the breakpoint (for debugging debugger bugs)." },
1256  { LLDB_OPT_SET_ALL, false, "dummy-breakpoints", 'D', OptionParser::eNoArgument, nullptr, {}, 0, eArgTypeNone, "List Dummy breakpoints - i.e. breakpoints set before a file is provided, which prime new targets." },
1257  // clang-format on
1258 };
1259 
1260 #pragma mark List
1261 
1263 public:
1266  interpreter, "breakpoint list",
1267  "List some or all breakpoints at configurable levels of detail.",
1268  nullptr),
1269  m_options() {
1271  CommandArgumentData bp_id_arg;
1272 
1273  // Define the first (and only) variant of this arg.
1274  bp_id_arg.arg_type = eArgTypeBreakpointID;
1275  bp_id_arg.arg_repetition = eArgRepeatOptional;
1276 
1277  // There is only one variant this argument could be; put it into the
1278  // argument entry.
1279  arg.push_back(bp_id_arg);
1280 
1281  // Push the data for the first argument into the m_arguments vector.
1282  m_arguments.push_back(arg);
1283  }
1284 
1285  ~CommandObjectBreakpointList() override = default;
1286 
1287  Options *GetOptions() override { return &m_options; }
1288 
1289  class CommandOptions : public Options {
1290  public:
1292  : Options(), m_level(lldb::eDescriptionLevelBrief), m_use_dummy(false) {
1293  }
1294 
1295  ~CommandOptions() override = default;
1296 
1297  Status SetOptionValue(uint32_t option_idx, llvm::StringRef option_arg,
1298  ExecutionContext *execution_context) override {
1299  Status error;
1300  const int short_option = m_getopt_table[option_idx].val;
1301 
1302  switch (short_option) {
1303  case 'b':
1304  m_level = lldb::eDescriptionLevelBrief;
1305  break;
1306  case 'D':
1307  m_use_dummy = true;
1308  break;
1309  case 'f':
1310  m_level = lldb::eDescriptionLevelFull;
1311  break;
1312  case 'v':
1314  break;
1315  case 'i':
1316  m_internal = true;
1317  break;
1318  default:
1319  error.SetErrorStringWithFormat("unrecognized option '%c'",
1320  short_option);
1321  break;
1322  }
1323 
1324  return error;
1325  }
1326 
1327  void OptionParsingStarting(ExecutionContext *execution_context) override {
1328  m_level = lldb::eDescriptionLevelFull;
1329  m_internal = false;
1330  m_use_dummy = false;
1331  }
1332 
1333  llvm::ArrayRef<OptionDefinition> GetDefinitions() override {
1334  return llvm::makeArrayRef(g_breakpoint_list_options);
1335  }
1336 
1337  // Instance variables to hold the values for command options.
1338 
1340 
1343  };
1344 
1345 protected:
1346  bool DoExecute(Args &command, CommandReturnObject &result) override {
1347  Target *target = GetSelectedOrDummyTarget(m_options.m_use_dummy);
1348 
1349  if (target == nullptr) {
1350  result.AppendError("Invalid target. No current target or breakpoints.");
1352  return true;
1353  }
1354 
1355  const BreakpointList &breakpoints =
1356  target->GetBreakpointList(m_options.m_internal);
1357  std::unique_lock<std::recursive_mutex> lock;
1358  target->GetBreakpointList(m_options.m_internal).GetListMutex(lock);
1359 
1360  size_t num_breakpoints = breakpoints.GetSize();
1361 
1362  if (num_breakpoints == 0) {
1363  result.AppendMessage("No breakpoints currently set.");
1365  return true;
1366  }
1367 
1368  Stream &output_stream = result.GetOutputStream();
1369 
1370  if (command.empty()) {
1371  // No breakpoint selected; show info about all currently set breakpoints.
1372  result.AppendMessage("Current breakpoints:");
1373  for (size_t i = 0; i < num_breakpoints; ++i) {
1374  Breakpoint *breakpoint = breakpoints.GetBreakpointAtIndex(i).get();
1375  if (breakpoint->AllowList())
1376  AddBreakpointDescription(&output_stream, breakpoint,
1377  m_options.m_level);
1378  }
1380  } else {
1381  // Particular breakpoints selected; show info about that breakpoint.
1382  BreakpointIDList valid_bp_ids;
1383  CommandObjectMultiwordBreakpoint::VerifyBreakpointOrLocationIDs(
1384  command, target, result, &valid_bp_ids,
1385  BreakpointName::Permissions::PermissionKinds::listPerm);
1386 
1387  if (result.Succeeded()) {
1388  for (size_t i = 0; i < valid_bp_ids.GetSize(); ++i) {
1389  BreakpointID cur_bp_id = valid_bp_ids.GetBreakpointIDAtIndex(i);
1390  Breakpoint *breakpoint =
1391  target->GetBreakpointByID(cur_bp_id.GetBreakpointID()).get();
1392  AddBreakpointDescription(&output_stream, breakpoint,
1393  m_options.m_level);
1394  }
1396  } else {
1397  result.AppendError("Invalid breakpoint ID.");
1399  }
1400  }
1401 
1402  return result.Succeeded();
1403  }
1404 
1405 private:
1406  CommandOptions m_options;
1407 };
1408 
1409 // CommandObjectBreakpointClear
1410 #pragma mark Clear::CommandOptions
1411 
1412 static constexpr OptionDefinition g_breakpoint_clear_options[] = {
1413  // clang-format off
1414  { LLDB_OPT_SET_1, false, "file", 'f', OptionParser::eRequiredArgument, nullptr, {}, CommandCompletions::eSourceFileCompletion, eArgTypeFilename, "Specify the breakpoint by source location in this particular file." },
1415  { LLDB_OPT_SET_1, true, "line", 'l', OptionParser::eRequiredArgument, nullptr, {}, 0, eArgTypeLineNum, "Specify the breakpoint by source location at this particular line." }
1416  // clang-format on
1417 };
1418 
1419 #pragma mark Clear
1420 
1422 public:
1423  typedef enum BreakpointClearType {
1425  eClearTypeFileAndLine
1427 
1429  : CommandObjectParsed(interpreter, "breakpoint clear",
1430  "Delete or disable breakpoints matching the "
1431  "specified source file and line.",
1432  "breakpoint clear <cmd-options>"),
1433  m_options() {}
1434 
1435  ~CommandObjectBreakpointClear() override = default;
1436 
1437  Options *GetOptions() override { return &m_options; }
1438 
1439  class CommandOptions : public Options {
1440  public:
1441  CommandOptions() : Options(), m_filename(), m_line_num(0) {}
1442 
1443  ~CommandOptions() override = default;
1444 
1445  Status SetOptionValue(uint32_t option_idx, llvm::StringRef option_arg,
1446  ExecutionContext *execution_context) override {
1447  Status error;
1448  const int short_option = m_getopt_table[option_idx].val;
1449 
1450  switch (short_option) {
1451  case 'f':
1452  m_filename.assign(option_arg);
1453  break;
1454 
1455  case 'l':
1456  option_arg.getAsInteger(0, m_line_num);
1457  break;
1458 
1459  default:
1460  error.SetErrorStringWithFormat("unrecognized option '%c'",
1461  short_option);
1462  break;
1463  }
1464 
1465  return error;
1466  }
1467 
1468  void OptionParsingStarting(ExecutionContext *execution_context) override {
1469  m_filename.clear();
1470  m_line_num = 0;
1471  }
1472 
1473  llvm::ArrayRef<OptionDefinition> GetDefinitions() override {
1474  return llvm::makeArrayRef(g_breakpoint_clear_options);
1475  }
1476 
1477  // Instance variables to hold the values for command options.
1478 
1479  std::string m_filename;
1481  };
1482 
1483 protected:
1484  bool DoExecute(Args &command, CommandReturnObject &result) override {
1485  Target *target = GetSelectedOrDummyTarget();
1486  if (target == nullptr) {
1487  result.AppendError("Invalid target. No existing target or breakpoints.");
1489  return false;
1490  }
1491 
1492  // The following are the various types of breakpoints that could be
1493  // cleared:
1494  // 1). -f -l (clearing breakpoint by source location)
1495 
1496  BreakpointClearType break_type = eClearTypeInvalid;
1497 
1498  if (m_options.m_line_num != 0)
1499  break_type = eClearTypeFileAndLine;
1500 
1501  std::unique_lock<std::recursive_mutex> lock;
1502  target->GetBreakpointList().GetListMutex(lock);
1503 
1504  BreakpointList &breakpoints = target->GetBreakpointList();
1505  size_t num_breakpoints = breakpoints.GetSize();
1506 
1507  // Early return if there's no breakpoint at all.
1508  if (num_breakpoints == 0) {
1509  result.AppendError("Breakpoint clear: No breakpoint cleared.");
1511  return result.Succeeded();
1512  }
1513 
1514  // Find matching breakpoints and delete them.
1515 
1516  // First create a copy of all the IDs.
1517  std::vector<break_id_t> BreakIDs;
1518  for (size_t i = 0; i < num_breakpoints; ++i)
1519  BreakIDs.push_back(breakpoints.GetBreakpointAtIndex(i)->GetID());
1520 
1521  int num_cleared = 0;
1522  StreamString ss;
1523  switch (break_type) {
1524  case eClearTypeFileAndLine: // Breakpoint by source position
1525  {
1526  const ConstString filename(m_options.m_filename.c_str());
1528 
1529  for (size_t i = 0; i < num_breakpoints; ++i) {
1530  Breakpoint *bp = breakpoints.FindBreakpointByID(BreakIDs[i]).get();
1531 
1532  if (bp->GetMatchingFileLine(filename, m_options.m_line_num, loc_coll)) {
1533  // If the collection size is 0, it's a full match and we can just
1534  // remove the breakpoint.
1535  if (loc_coll.GetSize() == 0) {
1537  ss.EOL();
1538  target->RemoveBreakpointByID(bp->GetID());
1539  ++num_cleared;
1540  }
1541  }
1542  }
1543  } break;
1544 
1545  default:
1546  break;
1547  }
1548 
1549  if (num_cleared > 0) {
1550  Stream &output_stream = result.GetOutputStream();
1551  output_stream.Printf("%d breakpoints cleared:\n", num_cleared);
1552  output_stream << ss.GetString();
1553  output_stream.EOL();
1555  } else {
1556  result.AppendError("Breakpoint clear: No breakpoint cleared.");
1558  }
1559 
1560  return result.Succeeded();
1561  }
1562 
1563 private:
1564  CommandOptions m_options;
1565 };
1566 
1567 // CommandObjectBreakpointDelete
1568 static constexpr OptionDefinition g_breakpoint_delete_options[] = {
1569  // clang-format off
1570  { LLDB_OPT_SET_1, false, "force", 'f', OptionParser::eNoArgument, nullptr, {}, 0, eArgTypeNone, "Delete all breakpoints without querying for confirmation." },
1571  { LLDB_OPT_SET_1, false, "dummy-breakpoints", 'D', OptionParser::eNoArgument, nullptr, {}, 0, eArgTypeNone, "Delete Dummy breakpoints - i.e. breakpoints set before a file is provided, which prime new targets." },
1572  // clang-format on
1573 };
1574 
1575 #pragma mark Delete
1576 
1578 public:
1580  : CommandObjectParsed(interpreter, "breakpoint delete",
1581  "Delete the specified breakpoint(s). If no "
1582  "breakpoints are specified, delete them all.",
1583  nullptr),
1584  m_options() {
1586  CommandObject::AddIDsArgumentData(arg, eArgTypeBreakpointID,
1588  // Add the entry for the first argument for this command to the object's
1589  // arguments vector.
1590  m_arguments.push_back(arg);
1591  }
1592 
1593  ~CommandObjectBreakpointDelete() override = default;
1594 
1595  Options *GetOptions() override { return &m_options; }
1596 
1597  class CommandOptions : public Options {
1598  public:
1599  CommandOptions() : Options(), m_use_dummy(false), m_force(false) {}
1600 
1601  ~CommandOptions() override = default;
1602 
1603  Status SetOptionValue(uint32_t option_idx, llvm::StringRef option_arg,
1604  ExecutionContext *execution_context) override {
1605  Status error;
1606  const int short_option = m_getopt_table[option_idx].val;
1607 
1608  switch (short_option) {
1609  case 'f':
1610  m_force = true;
1611  break;
1612 
1613  case 'D':
1614  m_use_dummy = true;
1615  break;
1616 
1617  default:
1618  error.SetErrorStringWithFormat("unrecognized option '%c'",
1619  short_option);
1620  break;
1621  }
1622 
1623  return error;
1624  }
1625 
1626  void OptionParsingStarting(ExecutionContext *execution_context) override {
1627  m_use_dummy = false;
1628  m_force = false;
1629  }
1630 
1631  llvm::ArrayRef<OptionDefinition> GetDefinitions() override {
1632  return llvm::makeArrayRef(g_breakpoint_delete_options);
1633  }
1634 
1635  // Instance variables to hold the values for command options.
1637  bool m_force;
1638  };
1639 
1640 protected:
1641  bool DoExecute(Args &command, CommandReturnObject &result) override {
1642  Target *target = GetSelectedOrDummyTarget(m_options.m_use_dummy);
1643 
1644  if (target == nullptr) {
1645  result.AppendError("Invalid target. No existing target or breakpoints.");
1647  return false;
1648  }
1649 
1650  std::unique_lock<std::recursive_mutex> lock;
1651  target->GetBreakpointList().GetListMutex(lock);
1652 
1653  const BreakpointList &breakpoints = target->GetBreakpointList();
1654 
1655  size_t num_breakpoints = breakpoints.GetSize();
1656 
1657  if (num_breakpoints == 0) {
1658  result.AppendError("No breakpoints exist to be deleted.");
1660  return false;
1661  }
1662 
1663  if (command.empty()) {
1664  if (!m_options.m_force &&
1665  !m_interpreter.Confirm(
1666  "About to delete all breakpoints, do you want to do that?",
1667  true)) {
1668  result.AppendMessage("Operation cancelled...");
1669  } else {
1670  target->RemoveAllowedBreakpoints();
1671  result.AppendMessageWithFormat(
1672  "All breakpoints removed. (%" PRIu64 " breakpoint%s)\n",
1673  (uint64_t)num_breakpoints, num_breakpoints > 1 ? "s" : "");
1674  }
1676  } else {
1677  // Particular breakpoint selected; disable that breakpoint.
1678  BreakpointIDList valid_bp_ids;
1679  CommandObjectMultiwordBreakpoint::VerifyBreakpointOrLocationIDs(
1680  command, target, result, &valid_bp_ids,
1681  BreakpointName::Permissions::PermissionKinds::deletePerm);
1682 
1683  if (result.Succeeded()) {
1684  int delete_count = 0;
1685  int disable_count = 0;
1686  const size_t count = valid_bp_ids.GetSize();
1687  for (size_t i = 0; i < count; ++i) {
1688  BreakpointID cur_bp_id = valid_bp_ids.GetBreakpointIDAtIndex(i);
1689 
1690  if (cur_bp_id.GetBreakpointID() != LLDB_INVALID_BREAK_ID) {
1691  if (cur_bp_id.GetLocationID() != LLDB_INVALID_BREAK_ID) {
1692  Breakpoint *breakpoint =
1693  target->GetBreakpointByID(cur_bp_id.GetBreakpointID()).get();
1694  BreakpointLocation *location =
1695  breakpoint->FindLocationByID(cur_bp_id.GetLocationID()).get();
1696  // It makes no sense to try to delete individual locations, so we
1697  // disable them instead.
1698  if (location) {
1699  location->SetEnabled(false);
1700  ++disable_count;
1701  }
1702  } else {
1703  target->RemoveBreakpointByID(cur_bp_id.GetBreakpointID());
1704  ++delete_count;
1705  }
1706  }
1707  }
1708  result.AppendMessageWithFormat(
1709  "%d breakpoints deleted; %d breakpoint locations disabled.\n",
1710  delete_count, disable_count);
1712  }
1713  }
1714  return result.Succeeded();
1715  }
1716 
1717 private:
1718  CommandOptions m_options;
1719 };
1720 
1721 // CommandObjectBreakpointName
1722 
1723 static constexpr OptionDefinition g_breakpoint_name_options[] = {
1724  // clang-format off
1725  {LLDB_OPT_SET_1, false, "name", 'N', OptionParser::eRequiredArgument, nullptr, {}, 0, eArgTypeBreakpointName, "Specifies a breakpoint name to use."},
1726  {LLDB_OPT_SET_2, false, "breakpoint-id", 'B', OptionParser::eRequiredArgument, nullptr, {}, 0, eArgTypeBreakpointID, "Specify a breakpoint ID to use."},
1727  {LLDB_OPT_SET_3, false, "dummy-breakpoints", 'D', OptionParser::eNoArgument, nullptr, {}, 0, eArgTypeNone, "Operate on Dummy breakpoints - i.e. breakpoints set before a file is provided, which prime new targets."},
1728  {LLDB_OPT_SET_4, false, "help-string", 'H', OptionParser::eRequiredArgument, nullptr, {}, 0, eArgTypeNone, "A help string describing the purpose of this name."},
1729  // clang-format on
1730 };
1732 public:
1734  : OptionGroup(), m_breakpoint(LLDB_INVALID_BREAK_ID), m_use_dummy(false) {
1735  }
1736 
1737  ~BreakpointNameOptionGroup() override = default;
1738 
1739  llvm::ArrayRef<OptionDefinition> GetDefinitions() override {
1740  return llvm::makeArrayRef(g_breakpoint_name_options);
1741  }
1742 
1743  Status SetOptionValue(uint32_t option_idx, llvm::StringRef option_arg,
1744  ExecutionContext *execution_context) override {
1745  Status error;
1746  const int short_option = g_breakpoint_name_options[option_idx].short_option;
1747 
1748  switch (short_option) {
1749  case 'N':
1750  if (BreakpointID::StringIsBreakpointName(option_arg, error) &&
1751  error.Success())
1752  m_name.SetValueFromString(option_arg);
1753  break;
1754  case 'B':
1755  if (m_breakpoint.SetValueFromString(option_arg).Fail())
1757  "unrecognized value \"%s\" for breakpoint",
1758  option_arg.str().c_str());
1759  break;
1760  case 'D':
1761  if (m_use_dummy.SetValueFromString(option_arg).Fail())
1763  "unrecognized value \"%s\" for use-dummy",
1764  option_arg.str().c_str());
1765  break;
1766  case 'H':
1767  m_help_string.SetValueFromString(option_arg);
1768  break;
1769 
1770  default:
1771  error.SetErrorStringWithFormat("unrecognized short option '%c'",
1772  short_option);
1773  break;
1774  }
1775  return error;
1776  }
1777 
1778  void OptionParsingStarting(ExecutionContext *execution_context) override {
1779  m_name.Clear();
1780  m_breakpoint.Clear();
1781  m_use_dummy.Clear();
1782  m_use_dummy.SetDefaultValue(false);
1783  m_help_string.Clear();
1784  }
1785 
1790 };
1791 
1792 static constexpr OptionDefinition g_breakpoint_access_options[] = {
1793  // clang-format off
1794  {LLDB_OPT_SET_1, false, "allow-list", 'L', OptionParser::eRequiredArgument, nullptr, {}, 0, eArgTypeBoolean, "Determines whether the breakpoint will show up in break list if not referred to explicitly."},
1795  {LLDB_OPT_SET_2, false, "allow-disable", 'A', OptionParser::eRequiredArgument, nullptr, {}, 0, eArgTypeBoolean, "Determines whether the breakpoint can be disabled by name or when all breakpoints are disabled."},
1796  {LLDB_OPT_SET_3, false, "allow-delete", 'D', OptionParser::eRequiredArgument, nullptr, {}, 0, eArgTypeBoolean, "Determines whether the breakpoint can be deleted by name or when all breakpoints are deleted."},
1797  // clang-format on
1798 };
1799 
1801 public:
1803 
1804  ~BreakpointAccessOptionGroup() override = default;
1805 
1806  llvm::ArrayRef<OptionDefinition> GetDefinitions() override {
1807  return llvm::makeArrayRef(g_breakpoint_access_options);
1808  }
1809  Status SetOptionValue(uint32_t option_idx, llvm::StringRef option_arg,
1810  ExecutionContext *execution_context) override {
1811  Status error;
1812  const int short_option
1813  = g_breakpoint_access_options[option_idx].short_option;
1814 
1815  switch (short_option) {
1816  case 'L': {
1817  bool value, success;
1818  value = OptionArgParser::ToBoolean(option_arg, false, &success);
1819  if (success) {
1820  m_permissions.SetAllowList(value);
1821  } else
1823  "invalid boolean value '%s' passed for -L option",
1824  option_arg.str().c_str());
1825  } break;
1826  case 'A': {
1827  bool value, success;
1828  value = OptionArgParser::ToBoolean(option_arg, false, &success);
1829  if (success) {
1830  m_permissions.SetAllowDisable(value);
1831  } else
1833  "invalid boolean value '%s' passed for -L option",
1834  option_arg.str().c_str());
1835  } break;
1836  case 'D': {
1837  bool value, success;
1838  value = OptionArgParser::ToBoolean(option_arg, false, &success);
1839  if (success) {
1840  m_permissions.SetAllowDelete(value);
1841  } else
1843  "invalid boolean value '%s' passed for -L option",
1844  option_arg.str().c_str());
1845  } break;
1846 
1847  }
1848 
1849  return error;
1850  }
1851 
1852  void OptionParsingStarting(ExecutionContext *execution_context) override {
1853  }
1854 
1856  {
1857  return m_permissions;
1858  }
1860 };
1861 
1863 public:
1866  interpreter, "configure", "Configure the options for the breakpoint"
1867  " name provided. "
1868  "If you provide a breakpoint id, the options will be copied from "
1869  "the breakpoint, otherwise only the options specified will be set "
1870  "on the name.",
1871  "breakpoint name configure <command-options> "
1872  "<breakpoint-name-list>"),
1873  m_bp_opts(), m_option_group() {
1874  // Create the first variant for the first (and only) argument for this
1875  // command.
1876  CommandArgumentEntry arg1;
1877  CommandArgumentData id_arg;
1880  arg1.push_back(id_arg);
1881  m_arguments.push_back(arg1);
1882 
1883  m_option_group.Append(&m_bp_opts,
1885  LLDB_OPT_SET_1);
1886  m_option_group.Append(&m_access_options,
1889  m_option_group.Append(&m_bp_id,
1892  m_option_group.Finalize();
1893  }
1894 
1895  ~CommandObjectBreakpointNameConfigure() override = default;
1896 
1897  Options *GetOptions() override { return &m_option_group; }
1898 
1899 protected:
1900  bool DoExecute(Args &command, CommandReturnObject &result) override {
1901 
1902  const size_t argc = command.GetArgumentCount();
1903  if (argc == 0) {
1904  result.AppendError("No names provided.");
1906  return false;
1907  }
1908 
1909  Target *target =
1910  GetSelectedOrDummyTarget(false);
1911 
1912  if (target == nullptr) {
1913  result.AppendError("Invalid target. No existing target or breakpoints.");
1915  return false;
1916  }
1917 
1918  std::unique_lock<std::recursive_mutex> lock;
1919  target->GetBreakpointList().GetListMutex(lock);
1920 
1921  // Make a pass through first to see that all the names are legal.
1922  for (auto &entry : command.entries()) {
1923  Status error;
1924  if (!BreakpointID::StringIsBreakpointName(entry.ref, error))
1925  {
1926  result.AppendErrorWithFormat("Invalid breakpoint name: %s - %s",
1927  entry.c_str(), error.AsCString());
1929  return false;
1930  }
1931  }
1932  // Now configure them, we already pre-checked the names so we don't need to
1933  // check the error:
1934  BreakpointSP bp_sp;
1935  if (m_bp_id.m_breakpoint.OptionWasSet())
1936  {
1937  lldb::break_id_t bp_id = m_bp_id.m_breakpoint.GetUInt64Value();
1938  bp_sp = target->GetBreakpointByID(bp_id);
1939  if (!bp_sp)
1940  {
1941  result.AppendErrorWithFormatv("Could not find specified breakpoint {0}",
1942  bp_id);
1944  return false;
1945  }
1946  }
1947 
1948  Status error;
1949  for (auto &entry : command.entries()) {
1950  ConstString name(entry.c_str());
1951  BreakpointName *bp_name = target->FindBreakpointName(name, true, error);
1952  if (!bp_name)
1953  continue;
1954  if (m_bp_id.m_help_string.OptionWasSet())
1955  bp_name->SetHelp(m_bp_id.m_help_string.GetStringValue().str().c_str());
1956 
1957  if (bp_sp)
1958  target->ConfigureBreakpointName(*bp_name,
1959  *bp_sp->GetOptions(),
1960  m_access_options.GetPermissions());
1961  else
1962  target->ConfigureBreakpointName(*bp_name,
1963  m_bp_opts.GetBreakpointOptions(),
1964  m_access_options.GetPermissions());
1965  }
1966  return true;
1967  }
1968 
1969 private:
1970  BreakpointNameOptionGroup m_bp_id; // Only using the id part of this.
1971  BreakpointOptionGroup m_bp_opts;
1972  BreakpointAccessOptionGroup m_access_options;
1973  OptionGroupOptions m_option_group;
1974 };
1975 
1977 public:
1980  interpreter, "add", "Add a name to the breakpoints provided.",
1981  "breakpoint name add <command-options> <breakpoint-id-list>"),
1982  m_name_options(), m_option_group() {
1983  // Create the first variant for the first (and only) argument for this
1984  // command.
1985  CommandArgumentEntry arg1;
1986  CommandArgumentData id_arg;
1987  id_arg.arg_type = eArgTypeBreakpointID;
1989  arg1.push_back(id_arg);
1990  m_arguments.push_back(arg1);
1991 
1992  m_option_group.Append(&m_name_options, LLDB_OPT_SET_1, LLDB_OPT_SET_ALL);
1993  m_option_group.Finalize();
1994  }
1995 
1996  ~CommandObjectBreakpointNameAdd() override = default;
1997 
1998  Options *GetOptions() override { return &m_option_group; }
1999 
2000 protected:
2001  bool DoExecute(Args &command, CommandReturnObject &result) override {
2002  if (!m_name_options.m_name.OptionWasSet()) {
2003  result.SetError("No name option provided.");
2004  return false;
2005  }
2006 
2007  Target *target =
2008  GetSelectedOrDummyTarget(m_name_options.m_use_dummy.GetCurrentValue());
2009 
2010  if (target == nullptr) {
2011  result.AppendError("Invalid target. No existing target or breakpoints.");
2013  return false;
2014  }
2015 
2016  std::unique_lock<std::recursive_mutex> lock;
2017  target->GetBreakpointList().GetListMutex(lock);
2018 
2019  const BreakpointList &breakpoints = target->GetBreakpointList();
2020 
2021  size_t num_breakpoints = breakpoints.GetSize();
2022  if (num_breakpoints == 0) {
2023  result.SetError("No breakpoints, cannot add names.");
2025  return false;
2026  }
2027 
2028  // Particular breakpoint selected; disable that breakpoint.
2029  BreakpointIDList valid_bp_ids;
2030  CommandObjectMultiwordBreakpoint::VerifyBreakpointIDs(
2031  command, target, result, &valid_bp_ids,
2032  BreakpointName::Permissions::PermissionKinds::listPerm);
2033 
2034  if (result.Succeeded()) {
2035  if (valid_bp_ids.GetSize() == 0) {
2036  result.SetError("No breakpoints specified, cannot add names.");
2038  return false;
2039  }
2040  size_t num_valid_ids = valid_bp_ids.GetSize();
2041  const char *bp_name = m_name_options.m_name.GetCurrentValue();
2042  Status error; // This error reports illegal names, but we've already
2043  // checked that, so we don't need to check it again here.
2044  for (size_t index = 0; index < num_valid_ids; index++) {
2045  lldb::break_id_t bp_id =
2046  valid_bp_ids.GetBreakpointIDAtIndex(index).GetBreakpointID();
2047  BreakpointSP bp_sp = breakpoints.FindBreakpointByID(bp_id);
2048  target->AddNameToBreakpoint(bp_sp, bp_name, error);
2049  }
2050  }
2051 
2052  return true;
2053  }
2054 
2055 private:
2056  BreakpointNameOptionGroup m_name_options;
2057  OptionGroupOptions m_option_group;
2058 };
2059 
2061 public:
2064  interpreter, "delete",
2065  "Delete a name from the breakpoints provided.",
2066  "breakpoint name delete <command-options> <breakpoint-id-list>"),
2067  m_name_options(), m_option_group() {
2068  // Create the first variant for the first (and only) argument for this
2069  // command.
2070  CommandArgumentEntry arg1;
2071  CommandArgumentData id_arg;
2072  id_arg.arg_type = eArgTypeBreakpointID;
2074  arg1.push_back(id_arg);
2075  m_arguments.push_back(arg1);
2076 
2077  m_option_group.Append(&m_name_options, LLDB_OPT_SET_1, LLDB_OPT_SET_ALL);
2078  m_option_group.Finalize();
2079  }
2080 
2081  ~CommandObjectBreakpointNameDelete() override = default;
2082 
2083  Options *GetOptions() override { return &m_option_group; }
2084 
2085 protected:
2086  bool DoExecute(Args &command, CommandReturnObject &result) override {
2087  if (!m_name_options.m_name.OptionWasSet()) {
2088  result.SetError("No name option provided.");
2089  return false;
2090  }
2091 
2092  Target *target =
2093  GetSelectedOrDummyTarget(m_name_options.m_use_dummy.GetCurrentValue());
2094 
2095  if (target == nullptr) {
2096  result.AppendError("Invalid target. No existing target or breakpoints.");
2098  return false;
2099  }
2100 
2101  std::unique_lock<std::recursive_mutex> lock;
2102  target->GetBreakpointList().GetListMutex(lock);
2103 
2104  const BreakpointList &breakpoints = target->GetBreakpointList();
2105 
2106  size_t num_breakpoints = breakpoints.GetSize();
2107  if (num_breakpoints == 0) {
2108  result.SetError("No breakpoints, cannot delete names.");
2110  return false;
2111  }
2112 
2113  // Particular breakpoint selected; disable that breakpoint.
2114  BreakpointIDList valid_bp_ids;
2115  CommandObjectMultiwordBreakpoint::VerifyBreakpointIDs(
2116  command, target, result, &valid_bp_ids,
2117  BreakpointName::Permissions::PermissionKinds::deletePerm);
2118 
2119  if (result.Succeeded()) {
2120  if (valid_bp_ids.GetSize() == 0) {
2121  result.SetError("No breakpoints specified, cannot delete names.");
2123  return false;
2124  }
2125  ConstString bp_name(m_name_options.m_name.GetCurrentValue());
2126  size_t num_valid_ids = valid_bp_ids.GetSize();
2127  for (size_t index = 0; index < num_valid_ids; index++) {
2128  lldb::break_id_t bp_id =
2129  valid_bp_ids.GetBreakpointIDAtIndex(index).GetBreakpointID();
2130  BreakpointSP bp_sp = breakpoints.FindBreakpointByID(bp_id);
2131  target->RemoveNameFromBreakpoint(bp_sp, bp_name);
2132  }
2133  }
2134 
2135  return true;
2136  }
2137 
2138 private:
2139  BreakpointNameOptionGroup m_name_options;
2140  OptionGroupOptions m_option_group;
2141 };
2142 
2144 public:
2146  : CommandObjectParsed(interpreter, "list",
2147  "List either the names for a breakpoint or info "
2148  "about a given name. With no arguments, lists all "
2149  "names",
2150  "breakpoint name list <command-options>"),
2151  m_name_options(), m_option_group() {
2152  m_option_group.Append(&m_name_options, LLDB_OPT_SET_3, LLDB_OPT_SET_ALL);
2153  m_option_group.Finalize();
2154  }
2155 
2156  ~CommandObjectBreakpointNameList() override = default;
2157 
2158  Options *GetOptions() override { return &m_option_group; }
2159 
2160 protected:
2161  bool DoExecute(Args &command, CommandReturnObject &result) override {
2162  Target *target =
2163  GetSelectedOrDummyTarget(m_name_options.m_use_dummy.GetCurrentValue());
2164 
2165  if (target == nullptr) {
2166  result.AppendError("Invalid target. No existing target or breakpoints.");
2168  return false;
2169  }
2170 
2171 
2172  std::vector<std::string> name_list;
2173  if (command.empty()) {
2174  target->GetBreakpointNames(name_list);
2175  } else {
2176  for (const Args::ArgEntry &arg : command)
2177  {
2178  name_list.push_back(arg.c_str());
2179  }
2180  }
2181 
2182  if (name_list.empty()) {
2183  result.AppendMessage("No breakpoint names found.");
2184  } else {
2185  for (const std::string &name_str : name_list) {
2186  const char *name = name_str.c_str();
2187  // First print out the options for the name:
2188  Status error;
2189  BreakpointName *bp_name = target->FindBreakpointName(ConstString(name),
2190  false,
2191  error);
2192  if (bp_name)
2193  {
2194  StreamString s;
2195  result.AppendMessageWithFormat("Name: %s\n", name);
2196  if (bp_name->GetDescription(&s, eDescriptionLevelFull))
2197  {
2198  result.AppendMessage(s.GetString());
2199  }
2200 
2201  std::unique_lock<std::recursive_mutex> lock;
2202  target->GetBreakpointList().GetListMutex(lock);
2203 
2204  BreakpointList &breakpoints = target->GetBreakpointList();
2205  bool any_set = false;
2206  for (BreakpointSP bp_sp : breakpoints.Breakpoints()) {
2207  if (bp_sp->MatchesName(name)) {
2208  StreamString s;
2209  any_set = true;
2210  bp_sp->GetDescription(&s, eDescriptionLevelBrief);
2211  s.EOL();
2212  result.AppendMessage(s.GetString());
2213  }
2214  }
2215  if (!any_set)
2216  result.AppendMessage("No breakpoints using this name.");
2217  } else {
2218  result.AppendMessageWithFormat("Name: %s not found.\n", name);
2219  }
2220  }
2221  }
2222  return true;
2223  }
2224 
2225 private:
2226  BreakpointNameOptionGroup m_name_options;
2227  OptionGroupOptions m_option_group;
2228 };
2229 
2230 // CommandObjectBreakpointName
2232 public:
2235  interpreter, "name", "Commands to manage name tags for breakpoints",
2236  "breakpoint name <subcommand> [<command-options>]") {
2237  CommandObjectSP add_command_object(
2238  new CommandObjectBreakpointNameAdd(interpreter));
2239  CommandObjectSP delete_command_object(
2240  new CommandObjectBreakpointNameDelete(interpreter));
2241  CommandObjectSP list_command_object(
2242  new CommandObjectBreakpointNameList(interpreter));
2243  CommandObjectSP configure_command_object(
2244  new CommandObjectBreakpointNameConfigure(interpreter));
2245 
2246  LoadSubCommand("add", add_command_object);
2247  LoadSubCommand("delete", delete_command_object);
2248  LoadSubCommand("list", list_command_object);
2249  LoadSubCommand("configure", configure_command_object);
2250  }
2251 
2252  ~CommandObjectBreakpointName() override = default;
2253 };
2254 
2255 // CommandObjectBreakpointRead
2256 #pragma mark Read::CommandOptions
2257 static constexpr OptionDefinition g_breakpoint_read_options[] = {
2258  // clang-format off
2259  {LLDB_OPT_SET_ALL, true, "file", 'f', OptionParser::eRequiredArgument, nullptr, {}, CommandCompletions::eDiskFileCompletion, eArgTypeFilename, "The file from which to read the breakpoints." },
2260  {LLDB_OPT_SET_ALL, false, "breakpoint-name", 'N', OptionParser::eRequiredArgument, nullptr, {}, 0, eArgTypeBreakpointName, "Only read in breakpoints with this name."},
2261  // clang-format on
2262 };
2263 
2264 #pragma mark Read
2265 
2267 public:
2269  : CommandObjectParsed(interpreter, "breakpoint read",
2270  "Read and set the breakpoints previously saved to "
2271  "a file with \"breakpoint write\". ",
2272  nullptr),
2273  m_options() {
2275  CommandObject::AddIDsArgumentData(arg, eArgTypeBreakpointID,
2277  // Add the entry for the first argument for this command to the object's
2278  // arguments vector.
2279  m_arguments.push_back(arg);
2280  }
2281 
2282  ~CommandObjectBreakpointRead() override = default;
2283 
2284  Options *GetOptions() override { return &m_options; }
2285 
2286  class CommandOptions : public Options {
2287  public:
2289 
2290  ~CommandOptions() override = default;
2291 
2292  Status SetOptionValue(uint32_t option_idx, llvm::StringRef option_arg,
2293  ExecutionContext *execution_context) override {
2294  Status error;
2295  const int short_option = m_getopt_table[option_idx].val;
2296 
2297  switch (short_option) {
2298  case 'f':
2299  m_filename.assign(option_arg);
2300  break;
2301  case 'N': {
2302  Status name_error;
2303  if (!BreakpointID::StringIsBreakpointName(llvm::StringRef(option_arg),
2304  name_error)) {
2305  error.SetErrorStringWithFormat("Invalid breakpoint name: %s",
2306  name_error.AsCString());
2307  }
2308  m_names.push_back(option_arg);
2309  break;
2310  }
2311  default:
2312  error.SetErrorStringWithFormat("unrecognized option '%c'",
2313  short_option);
2314  break;
2315  }
2316 
2317  return error;
2318  }
2319 
2320  void OptionParsingStarting(ExecutionContext *execution_context) override {
2321  m_filename.clear();
2322  m_names.clear();
2323  }
2324 
2325  llvm::ArrayRef<OptionDefinition> GetDefinitions() override {
2326  return llvm::makeArrayRef(g_breakpoint_read_options);
2327  }
2328 
2329  // Instance variables to hold the values for command options.
2330 
2331  std::string m_filename;
2332  std::vector<std::string> m_names;
2333  };
2334 
2335 protected:
2336  bool DoExecute(Args &command, CommandReturnObject &result) override {
2337  Target *target = GetSelectedOrDummyTarget();
2338  if (target == nullptr) {
2339  result.AppendError("Invalid target. No existing target or breakpoints.");
2341  return false;
2342  }
2343 
2344  std::unique_lock<std::recursive_mutex> lock;
2345  target->GetBreakpointList().GetListMutex(lock);
2346 
2347  FileSpec input_spec(m_options.m_filename);
2348  FileSystem::Instance().Resolve(input_spec);
2349  BreakpointIDList new_bps;
2350  Status error = target->CreateBreakpointsFromFile(
2351  input_spec, m_options.m_names, new_bps);
2352 
2353  if (!error.Success()) {
2354  result.AppendError(error.AsCString());
2356  return false;
2357  }
2358 
2359  Stream &output_stream = result.GetOutputStream();
2360 
2361  size_t num_breakpoints = new_bps.GetSize();
2362  if (num_breakpoints == 0) {
2363  result.AppendMessage("No breakpoints added.");
2364  } else {
2365  // No breakpoint selected; show info about all currently set breakpoints.
2366  result.AppendMessage("New breakpoints:");
2367  for (size_t i = 0; i < num_breakpoints; ++i) {
2368  BreakpointID bp_id = new_bps.GetBreakpointIDAtIndex(i);
2369  Breakpoint *bp = target->GetBreakpointList()
2371  .get();
2372  if (bp)
2373  bp->GetDescription(&output_stream, lldb::eDescriptionLevelInitial,
2374  false);
2375  }
2376  }
2377  return result.Succeeded();
2378  }
2379 
2380 private:
2381  CommandOptions m_options;
2382 };
2383 
2384 // CommandObjectBreakpointWrite
2385 #pragma mark Write::CommandOptions
2386 static constexpr OptionDefinition g_breakpoint_write_options[] = {
2387  // clang-format off
2388  { LLDB_OPT_SET_ALL, true, "file", 'f', OptionParser::eRequiredArgument, nullptr, {}, CommandCompletions::eDiskFileCompletion, eArgTypeFilename, "The file into which to write the breakpoints." },
2389  { LLDB_OPT_SET_ALL, false, "append",'a', OptionParser::eNoArgument, nullptr, {}, 0, eArgTypeNone, "Append to saved breakpoints file if it exists."},
2390  // clang-format on
2391 };
2392 
2393 #pragma mark Write
2395 public:
2397  : CommandObjectParsed(interpreter, "breakpoint write",
2398  "Write the breakpoints listed to a file that can "
2399  "be read in with \"breakpoint read\". "
2400  "If given no arguments, writes all breakpoints.",
2401  nullptr),
2402  m_options() {
2404  CommandObject::AddIDsArgumentData(arg, eArgTypeBreakpointID,
2406  // Add the entry for the first argument for this command to the object's
2407  // arguments vector.
2408  m_arguments.push_back(arg);
2409  }
2410 
2411  ~CommandObjectBreakpointWrite() override = default;
2412 
2413  Options *GetOptions() override { return &m_options; }
2414 
2415  class CommandOptions : public Options {
2416  public:
2418 
2419  ~CommandOptions() override = default;
2420 
2421  Status SetOptionValue(uint32_t option_idx, llvm::StringRef option_arg,
2422  ExecutionContext *execution_context) override {
2423  Status error;
2424  const int short_option = m_getopt_table[option_idx].val;
2425 
2426  switch (short_option) {
2427  case 'f':
2428  m_filename.assign(option_arg);
2429  break;
2430  case 'a':
2431  m_append = true;
2432  break;
2433  default:
2434  error.SetErrorStringWithFormat("unrecognized option '%c'",
2435  short_option);
2436  break;
2437  }
2438 
2439  return error;
2440  }
2441 
2442  void OptionParsingStarting(ExecutionContext *execution_context) override {
2443  m_filename.clear();
2444  m_append = false;
2445  }
2446 
2447  llvm::ArrayRef<OptionDefinition> GetDefinitions() override {
2448  return llvm::makeArrayRef(g_breakpoint_write_options);
2449  }
2450 
2451  // Instance variables to hold the values for command options.
2452 
2453  std::string m_filename;
2454  bool m_append = false;
2455  };
2456 
2457 protected:
2458  bool DoExecute(Args &command, CommandReturnObject &result) override {
2459  Target *target = GetSelectedOrDummyTarget();
2460  if (target == nullptr) {
2461  result.AppendError("Invalid target. No existing target or breakpoints.");
2463  return false;
2464  }
2465 
2466  std::unique_lock<std::recursive_mutex> lock;
2467  target->GetBreakpointList().GetListMutex(lock);
2468 
2469  BreakpointIDList valid_bp_ids;
2470  if (!command.empty()) {
2471  CommandObjectMultiwordBreakpoint::VerifyBreakpointIDs(
2472  command, target, result, &valid_bp_ids,
2473  BreakpointName::Permissions::PermissionKinds::listPerm);
2474 
2475  if (!result.Succeeded()) {
2477  return false;
2478  }
2479  }
2480  FileSpec file_spec(m_options.m_filename);
2481  FileSystem::Instance().Resolve(file_spec);
2482  Status error = target->SerializeBreakpointsToFile(file_spec, valid_bp_ids,
2483  m_options.m_append);
2484  if (!error.Success()) {
2485  result.AppendErrorWithFormat("error serializing breakpoints: %s.",
2486  error.AsCString());
2488  }
2489  return result.Succeeded();
2490  }
2491 
2492 private:
2493  CommandOptions m_options;
2494 };
2495 
2496 // CommandObjectMultiwordBreakpoint
2497 #pragma mark MultiwordBreakpoint
2498 
2499 CommandObjectMultiwordBreakpoint::CommandObjectMultiwordBreakpoint(
2500  CommandInterpreter &interpreter)
2502  interpreter, "breakpoint",
2503  "Commands for operating on breakpoints (see 'help b' for shorthand.)",
2504  "breakpoint <subcommand> [<command-options>]") {
2505  CommandObjectSP list_command_object(
2506  new CommandObjectBreakpointList(interpreter));
2507  CommandObjectSP enable_command_object(
2508  new CommandObjectBreakpointEnable(interpreter));
2509  CommandObjectSP disable_command_object(
2510  new CommandObjectBreakpointDisable(interpreter));
2511  CommandObjectSP clear_command_object(
2512  new CommandObjectBreakpointClear(interpreter));
2513  CommandObjectSP delete_command_object(
2514  new CommandObjectBreakpointDelete(interpreter));
2515  CommandObjectSP set_command_object(
2516  new CommandObjectBreakpointSet(interpreter));
2517  CommandObjectSP command_command_object(
2518  new CommandObjectBreakpointCommand(interpreter));
2519  CommandObjectSP modify_command_object(
2520  new CommandObjectBreakpointModify(interpreter));
2521  CommandObjectSP name_command_object(
2522  new CommandObjectBreakpointName(interpreter));
2523  CommandObjectSP write_command_object(
2524  new CommandObjectBreakpointWrite(interpreter));
2525  CommandObjectSP read_command_object(
2526  new CommandObjectBreakpointRead(interpreter));
2527 
2528  list_command_object->SetCommandName("breakpoint list");
2529  enable_command_object->SetCommandName("breakpoint enable");
2530  disable_command_object->SetCommandName("breakpoint disable");
2531  clear_command_object->SetCommandName("breakpoint clear");
2532  delete_command_object->SetCommandName("breakpoint delete");
2533  set_command_object->SetCommandName("breakpoint set");
2534  command_command_object->SetCommandName("breakpoint command");
2535  modify_command_object->SetCommandName("breakpoint modify");
2536  name_command_object->SetCommandName("breakpoint name");
2537  write_command_object->SetCommandName("breakpoint write");
2538  read_command_object->SetCommandName("breakpoint read");
2539 
2540  LoadSubCommand("list", list_command_object);
2541  LoadSubCommand("enable", enable_command_object);
2542  LoadSubCommand("disable", disable_command_object);
2543  LoadSubCommand("clear", clear_command_object);
2544  LoadSubCommand("delete", delete_command_object);
2545  LoadSubCommand("set", set_command_object);
2546  LoadSubCommand("command", command_command_object);
2547  LoadSubCommand("modify", modify_command_object);
2548  LoadSubCommand("name", name_command_object);
2549  LoadSubCommand("write", write_command_object);
2550  LoadSubCommand("read", read_command_object);
2551 }
2552 
2554 
2555 void CommandObjectMultiwordBreakpoint::VerifyIDs(Args &args, Target *target,
2556  bool allow_locations,
2557  CommandReturnObject &result,
2558  BreakpointIDList *valid_ids,
2560  ::PermissionKinds
2561  purpose) {
2562  // args can be strings representing 1). integers (for breakpoint ids)
2563  // 2). the full breakpoint & location
2564  // canonical representation
2565  // 3). the word "to" or a hyphen,
2566  // representing a range (in which case there
2567  // had *better* be an entry both before &
2568  // after of one of the first two types.
2569  // 4). A breakpoint name
2570  // If args is empty, we will use the last created breakpoint (if there is
2571  // one.)
2572 
2573  Args temp_args;
2574 
2575  if (args.empty()) {
2576  if (target->GetLastCreatedBreakpoint()) {
2577  valid_ids->AddBreakpointID(BreakpointID(
2578  target->GetLastCreatedBreakpoint()->GetID(), LLDB_INVALID_BREAK_ID));
2580  } else {
2581  result.AppendError(
2582  "No breakpoint specified and no last created breakpoint.");
2584  }
2585  return;
2586  }
2587 
2588  // Create a new Args variable to use; copy any non-breakpoint-id-ranges stuff
2589  // directly from the old ARGS to the new TEMP_ARGS. Do not copy breakpoint
2590  // id range strings over; instead generate a list of strings for all the
2591  // breakpoint ids in the range, and shove all of those breakpoint id strings
2592  // into TEMP_ARGS.
2593 
2594  BreakpointIDList::FindAndReplaceIDRanges(args, target, allow_locations,
2595  purpose, result, temp_args);
2596 
2597  // NOW, convert the list of breakpoint id strings in TEMP_ARGS into an actual
2598  // BreakpointIDList:
2599 
2600  valid_ids->InsertStringArray(temp_args.GetArgumentArrayRef(), result);
2601 
2602  // At this point, all of the breakpoint ids that the user passed in have
2603  // been converted to breakpoint IDs and put into valid_ids.
2604 
2605  if (result.Succeeded()) {
2606  // Now that we've converted everything from args into a list of breakpoint
2607  // ids, go through our tentative list of breakpoint id's and verify that
2608  // they correspond to valid/currently set breakpoints.
2609 
2610  const size_t count = valid_ids->GetSize();
2611  for (size_t i = 0; i < count; ++i) {
2612  BreakpointID cur_bp_id = valid_ids->GetBreakpointIDAtIndex(i);
2613  Breakpoint *breakpoint =
2614  target->GetBreakpointByID(cur_bp_id.GetBreakpointID()).get();
2615  if (breakpoint != nullptr) {
2616  const size_t num_locations = breakpoint->GetNumLocations();
2617  if (static_cast<size_t>(cur_bp_id.GetLocationID()) > num_locations) {
2618  StreamString id_str;
2620  &id_str, cur_bp_id.GetBreakpointID(), cur_bp_id.GetLocationID());
2621  i = valid_ids->GetSize() + 1;
2622  result.AppendErrorWithFormat(
2623  "'%s' is not a currently valid breakpoint/location id.\n",
2624  id_str.GetData());
2626  }
2627  } else {
2628  i = valid_ids->GetSize() + 1;
2629  result.AppendErrorWithFormat(
2630  "'%d' is not a currently valid breakpoint ID.\n",
2631  cur_bp_id.GetBreakpointID());
2633  }
2634  }
2635  }
2636 }
BreakpointOptions * GetOptions()
Returns the BreakpointOptions structure set at the breakpoint level.
Definition: Breakpoint.cpp:446
llvm::ArrayRef< OptionDefinition > GetDefinitions() override
Status SetOptionValue(uint32_t option_idx, llvm::StringRef option_arg, ExecutionContext *execution_context) override
#define LLDB_OPT_FILE
std::vector< CommandArgumentData > CommandArgumentEntry
A command line argument class.
Definition: Args.h:32
Status SetOptionValue(uint32_t option_idx, llvm::StringRef option_arg, ExecutionContext *execution_context) override
General Outline: A breakpoint location is defined by the breakpoint that produces it...
bool DoExecute(Args &command, CommandReturnObject &result) override
static void AddBreakpointDescription(Stream *s, Breakpoint *bp, lldb::DescriptionLevel level)
#define LLDB_OPT_SET_9
Definition: lldb-defines.h:119
#define LLDB_OPT_SET_11
Definition: lldb-defines.h:121
bool empty() const
Definition: Args.h:113
void DisableAllowedBreakpoints()
Definition: Target.cpp:913
bool RemoveBreakpointByID(lldb::break_id_t break_id)
Definition: Target.cpp:940
static constexpr OptionDefinition g_breakpoint_read_options[]
static void FindAndReplaceIDRanges(Args &old_args, Target *target, bool allow_locations, BreakpointName::Permissions ::PermissionKinds purpose, CommandReturnObject &result, Args &new_args)
Enumerations for broadcasting.
Definition: SBLaunchInfo.h:14
llvm::ArrayRef< OptionDefinition > GetDefinitions() override
int32_t break_id_t
Definition: lldb-types.h:88
bool DoExecute(Args &command, CommandReturnObject &result) override
A stream class that can stream formatted output to a file.
Definition: Stream.h:28
std::unordered_set< std::string > m_source_regex_func_names
BreakpointList & GetBreakpointList(bool internal=false)
Definition: Target.cpp:283
Status SetOptionValue(uint32_t option_idx, llvm::StringRef option_arg, ExecutionContext *execution_context) override
Set the value of an option.
llvm::ArrayRef< ArgEntry > entries() const
Definition: Args.h:123
static constexpr OptionDefinition g_breakpoint_write_options[]
Defines a symbol context baton that can be handed other debug core functions.
Definition: SymbolContext.h:33
void OptionParsingStarting(ExecutionContext *execution_context) override
bool LoadSubCommand(llvm::StringRef cmd_name, const lldb::CommandObjectSP &command_obj) override
size_t GetSize() const
Returns the number of elements in this breakpoint list.
void AppendErrorWithFormat(const char *format,...) __attribute__((format(printf
General Outline: A breakpoint has four main parts, a filter, a resolver, the list of breakpoint locat...
Definition: Breakpoint.h:78
Status SetOptionValue(uint32_t option_idx, llvm::StringRef option_arg, ExecutionContext *execution_context) override
Set the value of an option.
bool DoExecute(Args &command, CommandReturnObject &result) override
lldb::break_id_t GetBreakpointID() const
Definition: BreakpointID.h:30
size_t GetArgumentCount() const
Gets the number of arguments left in this command object.
Definition: Args.cpp:254
static constexpr OptionDefinition g_breakpoint_clear_options[]
Status SerializeBreakpointsToFile(const FileSpec &file, const BreakpointIDList &bp_ids, bool append)
Definition: Target.cpp:1000
A file utility class.
Definition: FileSpec.h:55
"lldb/Utility/RegularExpression.h" A C++ wrapper class for regex.
lldb::BreakpointLocationSP FindLocationByID(lldb::break_id_t bp_loc_id)
Find a breakpoint location for a given breakpoint location ID.
Definition: Breakpoint.cpp:267
llvm::ArrayRef< const char * > GetArgumentArrayRef() const
Gets the argument as an ArrayRef.
Definition: Args.h:165
#define LLDB_OPT_EXPR_LANGUAGE
BreakpointName::Permissions m_permissions
void SetEnabled(bool enabled)
If enable is true, enable the breakpoint, if false disable it.
bool DoExecute(Args &command, CommandReturnObject &result) override
llvm::ArrayRef< OptionDefinition > GetDefinitions() override
"lldb/Target/ExecutionContext.h" A class that contains an execution context.
void OptionParsingStarting(ExecutionContext *execution_context) override
Status SetOptionValue(uint32_t option_idx, llvm::StringRef option_arg, ExecutionContext *execution_context) override
bool DoExecute(Args &command, CommandReturnObject &result) override
lldb::BreakpointSP FindBreakpointByID(lldb::break_id_t breakID) const
Returns a shared pointer to the breakpoint with id breakID.
const char * GetData() const
Definition: StreamString.h:43
CommandObjectBreakpointNameAdd(CommandInterpreter &interpreter)
CommandObjectBreakpointName(CommandInterpreter &interpreter)
#define LLDB_OPT_MOVE_TO_NEAREST_CODE
CommandObjectBreakpointRead(CommandInterpreter &interpreter)
const BreakpointID & GetBreakpointIDAtIndex(size_t index) const
CommandObjectBreakpointEnable(CommandInterpreter &interpreter)
static constexpr OptionDefinition g_breakpoint_set_options[]
llvm::ArrayRef< OptionDefinition > GetDefinitions() override
llvm::ArrayRef< OptionDefinition > GetDefinitions() override
static constexpr OptionDefinition g_breakpoint_name_options[]
BreakpointName * FindBreakpointName(ConstString name, bool can_create, Status &error)
Definition: Target.cpp:701
bool DoExecute(Args &command, CommandReturnObject &result) override
const SymbolContext & GetSymbolContext(lldb::SymbolContextItem resolve_scope)
Provide a SymbolContext for this StackFrame&#39;s current pc value.
Definition: StackFrame.cpp:267
#define LLDB_OPT_SET_3
Definition: lldb-defines.h:113
std::shared_ptr< Dictionary > DictionarySP
#define LLDB_OPT_NOT_10
Status OptionParsingFinished(ExecutionContext *execution_context) override
bool DoExecute(Args &command, CommandReturnObject &result) override
llvm::ArrayRef< OptionDefinition > GetDefinitions() override
CommandObjectBreakpointDelete(CommandInterpreter &interpreter)
#define UINT32_MAX
Definition: lldb-defines.h:31
SourceManager & GetSourceManager()
Definition: Target.cpp:2482
void SetEnabled(bool enable) override
If enable is true, enable the breakpoint, if false disable it.
Definition: Breakpoint.cpp:287
#define LLDB_INVALID_ADDRESS
Invalid value definitions.
Definition: lldb-defines.h:85
static void GetCanonicalReference(Stream *s, lldb::break_id_t break_id, lldb::break_id_t break_loc_id)
Takes a breakpoint ID and the breakpoint location id and returns a string containing the canonical de...
bool IsValid() const
Test if valid.
lldb::BreakpointSP GetBreakpointByID(lldb::break_id_t break_id)
Definition: Target.cpp:297
LanguageType
Programming language type.
bool GetMatchingFileLine(ConstString filename, uint32_t line_number, BreakpointLocationCollection &loc_coll)
Find breakpoint locations which match the (filename, line_number) description.
Definition: Breakpoint.cpp:967
llvm::ArrayRef< OptionDefinition > GetDefinitions() override
lldb::BreakpointSP CreateSourceRegexBreakpoint(const FileSpecList *containingModules, const FileSpecList *source_file_list, const std::unordered_set< std::string > &function_names, RegularExpression &source_regex, bool internal, bool request_hardware, LazyBool move_to_nearest_code)
Definition: Target.cpp:308
lldb::BreakpointSP GetLastCreatedBreakpoint()
Definition: Target.h:581
void InsertStringArray(llvm::ArrayRef< const char *> string_array, CommandReturnObject &result)
size_t EOL()
Output and End of Line character to the stream.
Definition: Stream.cpp:127
BreakpointOptions * GetLocationOptions()
Use this to set location specific breakpoint options.
void OptionParsingStarting(ExecutionContext *execution_context) override
lldb::BreakpointSP CreateAddressInModuleBreakpoint(lldb::addr_t file_addr, bool internal, const FileSpec *file_spec, bool request_hardware)
Definition: Target.cpp:406
CommandObjectBreakpointSet(CommandInterpreter &interpreter)
lldb::break_id_t GetID() const
Definition: Stoppoint.cpp:22
void AppendMessageWithFormat(const char *format,...) __attribute__((format(printf
size_t GetNumLocations() const
Return the number of breakpoint locations.
Definition: Breakpoint.cpp:853
CommandObjectBreakpointWrite(CommandInterpreter &interpreter)
uint64_t tid_t
Definition: lldb-types.h:86
void AppendMessage(llvm::StringRef in_string)
llvm::StringRef GetString() const
llvm::ArrayRef< OptionDefinition > GetDefinitions() override
static constexpr OptionDefinition g_breakpoint_modify_options[]
Status SetOptionValue(uint32_t option_idx, llvm::StringRef option_arg, ExecutionContext *execution_context) override
Set the value of an option.
void ConfigureBreakpointName(BreakpointName &bp_name, const BreakpointOptions &options, const BreakpointName::Permissions &permissions)
Definition: Target.cpp:744
void SetError(const Status &error, const char *fallback_error_cstr=nullptr)
FileSpec file
The source file, possibly mapped by the target.source-map setting.
Definition: LineEntry.h:151
void CopyOverSetOptions(const BreakpointOptions &rhs)
Copy over only the options set in the incoming BreakpointOptions.
const BreakpointOptions & GetBreakpointOptions()
bool DoExecute(Args &command, CommandReturnObject &result) override
bool DoExecute(Args &command, CommandReturnObject &result) override
#define LLDB_OPT_SET_4
Definition: lldb-defines.h:114
void IndentLess(int amount=2)
Decrement the current indentation level.
Definition: Stream.cpp:221
size_t Printf(const char *format,...) __attribute__((format(printf
Output printf formatted output to the stream.
Definition: Stream.cpp:106
bool Success() const
Test for success condition.
Definition: Status.cpp:287
void AppendErrorWithFormatv(const char *format, Args &&... args)
bool DoExecute(Args &command, CommandReturnObject &result) override
static constexpr OptionDefinition g_breakpoint_dummy_options[]
size_t GetErrorAsCString(char *err_str, size_t err_str_max_len) const
void GetBreakpointNames(std::vector< std::string > &names)
Definition: Target.cpp:762
General Outline: Allows adding and removing breakpoints and find by ID and index. ...
Status SetOptionValue(uint32_t option_idx, llvm::StringRef option_arg, ExecutionContext *execution_context) override
Set the value of an option.
Status SetOptionValue(uint32_t option_idx, llvm::StringRef option_arg, ExecutionContext *execution_context) override
Set the value of an option.
bool GetDescription(Stream *s, lldb::DescriptionLevel level)
lldb::break_id_t GetLocationID() const
Definition: BreakpointID.h:32
lldb::BreakpointSP GetBreakpointAtIndex(size_t i) const
Returns a shared pointer to the breakpoint with index i.
static constexpr OptionDefinition g_breakpoint_access_options[]
#define LLDB_OPT_SET_2
Definition: lldb-defines.h:112
#define LLDB_OPT_SET_10
Definition: lldb-defines.h:120
void RemoveAllowedBreakpoints()
Definition: Target.cpp:878
void OptionParsingStarting(ExecutionContext *execution_context) override
void OptionParsingStarting(ExecutionContext *execution_context) override
void OptionParsingStarting(ExecutionContext *execution_context) override
A command line option parsing protocol class.
Definition: Options.h:62
bool DoExecute(Args &command, CommandReturnObject &result) override
Status CreateBreakpointsFromFile(const FileSpec &file, BreakpointIDList &new_bps)
Definition: Target.cpp:1093
void OptionParsingStarting(ExecutionContext *execution_context) override
void void AppendError(llvm::StringRef in_string)
#define LLDB_INVALID_THREAD_ID
Definition: lldb-defines.h:93
uint64_t addr_t
Definition: lldb-types.h:83
lldb::BreakpointSP CreateScriptedBreakpoint(const llvm::StringRef class_name, const FileSpecList *containingModules, const FileSpecList *containingSourceFiles, bool internal, bool request_hardware, StructuredData::ObjectSP extra_args_sp, Status *creation_error=nullptr)
Definition: Target.cpp:588
void OptionParsingStarting(ExecutionContext *execution_context) override
A uniqued constant string class.
Definition: ConstString.h:38
CommandObjectBreakpointNameConfigure(CommandInterpreter &interpreter)
Unknown or invalid language value.
bool Fail() const
Test for error condition.
Definition: Status.cpp:181
#define LLDB_OPT_SET_7
Definition: lldb-defines.h:117
"lldb/Breakpoint/BreakpointOptions.h" Class that manages the options on a breakpoint or breakpoint lo...
Non-standardized C, such as K&R.
CommandObjectBreakpointNameDelete(CommandInterpreter &interpreter)
LineEntry line_entry
The LineEntry for a given query.
#define LLDB_OPT_OFFSET_APPLIES
Definition: SBAddress.h:15
bool AllowList() const
Definition: Breakpoint.h:578
CommandObjectBreakpointModify(CommandInterpreter &interpreter)
void GetListMutex(std::unique_lock< std::recursive_mutex > &lock)
Sets the passed in Locker to hold the Breakpoint List mutex.
bool DoExecute(Args &command, CommandReturnObject &result) override
void AddNameToBreakpoint(BreakpointID &id, const char *name, Status &error)
Definition: Target.cpp:665
llvm::ArrayRef< OptionDefinition > GetDefinitions() override
#define LLDB_OPT_SKIP_PROLOGUE
static constexpr OptionDefinition g_breakpoint_delete_options[]
bool GetDefaultFileAndLine(FileSpec &file_spec, uint32_t &line)
#define LLDB_OPT_SET_ALL
Definition: lldb-defines.h:110
CommandObjectBreakpointDisable(CommandInterpreter &interpreter)
CommandObjectBreakpointNameList(CommandInterpreter &interpreter)
bool DoExecute(Args &command, CommandReturnObject &result) override
#define LLDB_INVALID_BREAK_ID
Definition: lldb-defines.h:49
int SetErrorStringWithFormat(const char *format,...) __attribute__((format(printf
Set the current error string to a formatted error string.
Definition: Status.cpp:255
static constexpr OptionDefinition g_breakpoint_list_options[]
void OptionParsingStarting(ExecutionContext *execution_context) override
BreakpointIterable Breakpoints()
void IndentMore(int amount=2)
Increment the current indentation level.
Definition: Stream.cpp:218
bool HasDebugInformation()
Determine whether this StackFrame has debug information available or not.
CommandObjectBreakpointClear(CommandInterpreter &interpreter)
#define LLDB_OPT_SET_1
Definition: lldb-defines.h:111
const char * AsCString(const char *default_error_str="unknown error") const
Get the error string associated with the current error.
Definition: Status.cpp:130
Status SetOptionValue(uint32_t option_idx, llvm::StringRef option_arg, ExecutionContext *execution_context) override
void OptionParsingStarting(ExecutionContext *execution_context) override
Status SetOptionValue(uint32_t option_idx, llvm::StringRef option_arg, ExecutionContext *execution_context) override
lldb::BreakpointSP CreateExceptionBreakpoint(enum lldb::LanguageType language, bool catch_bp, bool throw_bp, bool internal, Args *additional_args=nullptr, Status *additional_args_error=nullptr)
Definition: Target.cpp:569
const BreakpointName::Permissions & GetPermissions() const
#define LLDB_OPT_SET_5
Definition: lldb-defines.h:115
lldb::BreakpointSP CreateFuncRegexBreakpoint(const FileSpecList *containingModules, const FileSpecList *containingSourceFiles, RegularExpression &func_regexp, lldb::LanguageType requested_language, LazyBool skip_prologue, bool internal, bool request_hardware)
Definition: Target.cpp:552
CommandObjectBreakpointList(CommandInterpreter &interpreter)
void EnableAllowedBreakpoints()
Definition: Target.cpp:932
#define LLDB_OPT_SET_6
Definition: lldb-defines.h:116
void SetStatus(lldb::ReturnStatus status)
llvm::ArrayRef< OptionDefinition > GetDefinitions() override
This base class provides an interface to stack frames.
Definition: StackFrame.h:40
lldb::BreakpointSP CreateBreakpoint(const FileSpecList *containingModules, const FileSpec &file, uint32_t line_no, uint32_t column, lldb::addr_t offset, LazyBool check_inlines, LazyBool skip_prologue, bool internal, bool request_hardware, LazyBool move_to_nearest_code)
Definition: Target.cpp:325
void RemoveNameFromBreakpoint(lldb::BreakpointSP &bp_sp, ConstString name)
Definition: Target.cpp:738
bool AddBreakpointID(BreakpointID bp_id)
void GetDescription(Stream *s, lldb::DescriptionLevel level, bool show_locations=false)
Put a description of this breakpoint into the stream s.
Definition: Breakpoint.cpp:860
An error handling class.
Definition: Status.h:44
#define LLDB_OPT_SET_8
Definition: lldb-defines.h:118
void SetHelp(const char *description)