1 //===-- CommandObjectBreakpoint.cpp -----------------------------*- C++ -*-===//
2 //
3 //                     The LLVM Compiler Infrastructure
4 //
5 // This file is distributed under the University of Illinois Open Source
6 // License. See LICENSE.TXT for details.
7 //
8 //===----------------------------------------------------------------------===//
9 
10 // C Includes
11 // C++ Includes
12 #include <vector>
13 
14 // Other libraries and framework includes
15 // Project includes
16 #include "CommandObjectBreakpoint.h"
17 #include "CommandObjectBreakpointCommand.h"
18 #include "lldb/Breakpoint/Breakpoint.h"
19 #include "lldb/Breakpoint/BreakpointIDList.h"
20 #include "lldb/Breakpoint/BreakpointLocation.h"
21 #include "lldb/Host/StringConvert.h"
22 #include "lldb/Interpreter/Options.h"
23 #include "lldb/Interpreter/OptionValueBoolean.h"
24 #include "lldb/Interpreter/OptionValueString.h"
25 #include "lldb/Interpreter/OptionValueUInt64.h"
26 #include "lldb/Core/RegularExpression.h"
27 #include "lldb/Core/StreamString.h"
28 #include "lldb/Interpreter/CommandInterpreter.h"
29 #include "lldb/Interpreter/CommandReturnObject.h"
30 #include "lldb/Target/Language.h"
31 #include "lldb/Target/Target.h"
32 #include "lldb/Interpreter/CommandCompletions.h"
33 #include "lldb/Target/StackFrame.h"
34 #include "lldb/Target/Thread.h"
35 #include "lldb/Target/ThreadSpec.h"
36 
37 using namespace lldb;
38 using namespace lldb_private;
39 
40 static void
41 AddBreakpointDescription (Stream *s, Breakpoint *bp, lldb::DescriptionLevel level)
42 {
43     s->IndentMore();
44     bp->GetDescription (s, level, true);
45     s->IndentLess();
46     s->EOL();
47 }
48 
49 //-------------------------------------------------------------------------
50 // CommandObjectBreakpointSet
51 //-------------------------------------------------------------------------
52 
53 class CommandObjectBreakpointSet : public CommandObjectParsed
54 {
55 public:
56     typedef enum BreakpointSetType
57     {
58         eSetTypeInvalid,
59         eSetTypeFileAndLine,
60         eSetTypeAddress,
61         eSetTypeFunctionName,
62         eSetTypeFunctionRegexp,
63         eSetTypeSourceRegexp,
64         eSetTypeException
65     } BreakpointSetType;
66 
67     CommandObjectBreakpointSet (CommandInterpreter &interpreter) :
68         CommandObjectParsed (interpreter,
69                              "breakpoint set",
70                              "Sets a breakpoint or set of breakpoints in the executable.",
71                              "breakpoint set <cmd-options>"),
72         m_options (interpreter)
73     {
74     }
75 
76     ~CommandObjectBreakpointSet() override = default;
77 
78     Options *
79     GetOptions () override
80     {
81         return &m_options;
82     }
83 
84     class CommandOptions : public Options
85     {
86     public:
87         CommandOptions (CommandInterpreter &interpreter) :
88             Options (interpreter),
89             m_condition (),
90             m_filenames (),
91             m_line_num (0),
92             m_column (0),
93             m_func_names (),
94             m_func_name_type_mask (eFunctionNameTypeNone),
95             m_func_regexp (),
96             m_source_text_regexp(),
97             m_modules (),
98             m_load_addr(),
99             m_ignore_count (0),
100             m_thread_id(LLDB_INVALID_THREAD_ID),
101             m_thread_index (UINT32_MAX),
102             m_thread_name(),
103             m_queue_name(),
104             m_catch_bp (false),
105             m_throw_bp (true),
106             m_hardware (false),
107             m_exception_language (eLanguageTypeUnknown),
108             m_language (lldb::eLanguageTypeUnknown),
109             m_skip_prologue (eLazyBoolCalculate),
110             m_one_shot (false),
111             m_all_files (false),
112             m_move_to_nearest_code (eLazyBoolCalculate)
113         {
114         }
115 
116         ~CommandOptions() override = default;
117 
118         Error
119         SetOptionValue (uint32_t option_idx, const char *option_arg) override
120         {
121             Error error;
122             const int short_option = m_getopt_table[option_idx].val;
123 
124             switch (short_option)
125             {
126                 case 'a':
127                     {
128                         ExecutionContext exe_ctx (m_interpreter.GetExecutionContext());
129                         m_load_addr = Args::StringToAddress(&exe_ctx, option_arg, LLDB_INVALID_ADDRESS, &error);
130                     }
131                     break;
132 
133                 case 'A':
134                     m_all_files = true;
135                     break;
136 
137                 case 'b':
138                     m_func_names.push_back (option_arg);
139                     m_func_name_type_mask |= eFunctionNameTypeBase;
140                     break;
141 
142                 case 'C':
143                 {
144                     bool success;
145                     m_column = StringConvert::ToUInt32 (option_arg, 0, 0, &success);
146                     if (!success)
147                         error.SetErrorStringWithFormat("invalid column number: %s", option_arg);
148                     break;
149                 }
150 
151                 case 'c':
152                     m_condition.assign(option_arg);
153                     break;
154 
155                 case 'D':
156                     m_use_dummy = true;
157                     break;
158 
159                 case 'E':
160                 {
161                     LanguageType language = Language::GetLanguageTypeFromString (option_arg);
162 
163                     switch (language)
164                     {
165                         case eLanguageTypeC89:
166                         case eLanguageTypeC:
167                         case eLanguageTypeC99:
168                         case eLanguageTypeC11:
169                             m_exception_language = eLanguageTypeC;
170                             break;
171                         case eLanguageTypeC_plus_plus:
172                         case eLanguageTypeC_plus_plus_03:
173                         case eLanguageTypeC_plus_plus_11:
174                         case eLanguageTypeC_plus_plus_14:
175                             m_exception_language = eLanguageTypeC_plus_plus;
176                             break;
177                         case eLanguageTypeObjC:
178                             m_exception_language = eLanguageTypeObjC;
179                             break;
180                         case eLanguageTypeObjC_plus_plus:
181                             error.SetErrorStringWithFormat ("Set exception breakpoints separately for c++ and objective-c");
182                             break;
183                         case eLanguageTypeUnknown:
184                             error.SetErrorStringWithFormat ("Unknown language type: '%s' for exception breakpoint", option_arg);
185                             break;
186                         default:
187                             error.SetErrorStringWithFormat ("Unsupported language type: '%s' for exception breakpoint", option_arg);
188                     }
189                 }
190                 break;
191 
192                 case 'f':
193                     m_filenames.AppendIfUnique (FileSpec(option_arg, false));
194                     break;
195 
196                 case 'F':
197                     m_func_names.push_back (option_arg);
198                     m_func_name_type_mask |= eFunctionNameTypeFull;
199                     break;
200 
201                 case 'h':
202                     {
203                         bool success;
204                         m_catch_bp = Args::StringToBoolean (option_arg, true, &success);
205                         if (!success)
206                             error.SetErrorStringWithFormat ("Invalid boolean value for on-catch option: '%s'", option_arg);
207                     }
208                     break;
209 
210                 case 'H':
211                     m_hardware = true;
212                     break;
213 
214                 case 'i':
215                     m_ignore_count = StringConvert::ToUInt32(option_arg, UINT32_MAX, 0);
216                     if (m_ignore_count == UINT32_MAX)
217                        error.SetErrorStringWithFormat ("invalid ignore count '%s'", option_arg);
218                     break;
219 
220                 case 'K':
221                 {
222                     bool success;
223                     bool value;
224                     value = Args::StringToBoolean (option_arg, true, &success);
225                     if (value)
226                         m_skip_prologue = eLazyBoolYes;
227                     else
228                         m_skip_prologue = eLazyBoolNo;
229 
230                     if (!success)
231                         error.SetErrorStringWithFormat ("Invalid boolean value for skip prologue option: '%s'", option_arg);
232                 }
233                 break;
234 
235                 case 'l':
236                 {
237                     bool success;
238                     m_line_num = StringConvert::ToUInt32 (option_arg, 0, 0, &success);
239                     if (!success)
240                         error.SetErrorStringWithFormat ("invalid line number: %s.", option_arg);
241                     break;
242                 }
243 
244                 case 'L':
245                     m_language = Language::GetLanguageTypeFromString (option_arg);
246                     if (m_language == eLanguageTypeUnknown)
247                         error.SetErrorStringWithFormat ("Unknown language type: '%s' for breakpoint", option_arg);
248                     break;
249 
250                 case 'm':
251                 {
252                     bool success;
253                     bool value;
254                     value = Args::StringToBoolean (option_arg, true, &success);
255                     if (value)
256                         m_move_to_nearest_code = eLazyBoolYes;
257                     else
258                         m_move_to_nearest_code = eLazyBoolNo;
259 
260                     if (!success)
261                         error.SetErrorStringWithFormat ("Invalid boolean value for move-to-nearest-code option: '%s'", option_arg);
262                     break;
263                 }
264 
265                 case 'M':
266                     m_func_names.push_back (option_arg);
267                     m_func_name_type_mask |= eFunctionNameTypeMethod;
268                     break;
269 
270                 case 'n':
271                     m_func_names.push_back (option_arg);
272                     m_func_name_type_mask |= eFunctionNameTypeAuto;
273                     break;
274 
275                 case 'N':
276                     if (BreakpointID::StringIsBreakpointName(option_arg, error))
277                         m_breakpoint_names.push_back (option_arg);
278                     break;
279 
280                 case 'o':
281                     m_one_shot = true;
282                     break;
283 
284                 case 'O':
285                     m_exception_extra_args.AppendArgument ("-O");
286                     m_exception_extra_args.AppendArgument (option_arg);
287                     break;
288 
289                 case 'p':
290                     m_source_text_regexp.assign (option_arg);
291                     break;
292 
293                 case 'q':
294                     m_queue_name.assign (option_arg);
295                     break;
296 
297                 case 'r':
298                     m_func_regexp.assign (option_arg);
299                     break;
300 
301                 case 's':
302                     m_modules.AppendIfUnique (FileSpec (option_arg, false));
303                     break;
304 
305                 case 'S':
306                     m_func_names.push_back (option_arg);
307                     m_func_name_type_mask |= eFunctionNameTypeSelector;
308                     break;
309 
310                 case 't' :
311                     m_thread_id = StringConvert::ToUInt64(option_arg, LLDB_INVALID_THREAD_ID, 0);
312                     if (m_thread_id == LLDB_INVALID_THREAD_ID)
313                        error.SetErrorStringWithFormat ("invalid thread id string '%s'", option_arg);
314                     break;
315 
316                 case 'T':
317                     m_thread_name.assign (option_arg);
318                     break;
319 
320                 case 'w':
321                 {
322                     bool success;
323                     m_throw_bp = Args::StringToBoolean (option_arg, true, &success);
324                     if (!success)
325                         error.SetErrorStringWithFormat ("Invalid boolean value for on-throw option: '%s'", option_arg);
326                 }
327                 break;
328 
329                 case 'x':
330                     m_thread_index = StringConvert::ToUInt32(option_arg, UINT32_MAX, 0);
331                     if (m_thread_id == UINT32_MAX)
332                        error.SetErrorStringWithFormat ("invalid thread index string '%s'", option_arg);
333                     break;
334 
335                 default:
336                     error.SetErrorStringWithFormat ("unrecognized option '%c'", short_option);
337                     break;
338             }
339 
340             return error;
341         }
342 
343         void
344         OptionParsingStarting () override
345         {
346             m_condition.clear();
347             m_filenames.Clear();
348             m_line_num = 0;
349             m_column = 0;
350             m_func_names.clear();
351             m_func_name_type_mask = eFunctionNameTypeNone;
352             m_func_regexp.clear();
353             m_source_text_regexp.clear();
354             m_modules.Clear();
355             m_load_addr = LLDB_INVALID_ADDRESS;
356             m_ignore_count = 0;
357             m_thread_id = LLDB_INVALID_THREAD_ID;
358             m_thread_index = UINT32_MAX;
359             m_thread_name.clear();
360             m_queue_name.clear();
361             m_catch_bp = false;
362             m_throw_bp = true;
363             m_hardware = false;
364             m_exception_language = eLanguageTypeUnknown;
365             m_language = lldb::eLanguageTypeUnknown;
366             m_skip_prologue = eLazyBoolCalculate;
367             m_one_shot = false;
368             m_use_dummy = false;
369             m_breakpoint_names.clear();
370             m_all_files = false;
371             m_exception_extra_args.Clear();
372             m_move_to_nearest_code = eLazyBoolCalculate;
373         }
374 
375         const OptionDefinition*
376         GetDefinitions () override
377         {
378             return g_option_table;
379         }
380 
381         // Options table: Required for subclasses of Options.
382 
383         static OptionDefinition g_option_table[];
384 
385         // Instance variables to hold the values for command options.
386 
387         std::string m_condition;
388         FileSpecList m_filenames;
389         uint32_t m_line_num;
390         uint32_t m_column;
391         std::vector<std::string> m_func_names;
392         std::vector<std::string> m_breakpoint_names;
393         uint32_t m_func_name_type_mask;
394         std::string m_func_regexp;
395         std::string m_source_text_regexp;
396         FileSpecList m_modules;
397         lldb::addr_t m_load_addr;
398         uint32_t m_ignore_count;
399         lldb::tid_t m_thread_id;
400         uint32_t m_thread_index;
401         std::string m_thread_name;
402         std::string m_queue_name;
403         bool m_catch_bp;
404         bool m_throw_bp;
405         bool m_hardware; // Request to use hardware breakpoints
406         lldb::LanguageType m_exception_language;
407         lldb::LanguageType m_language;
408         LazyBool m_skip_prologue;
409         bool m_one_shot;
410         bool m_use_dummy;
411         bool m_all_files;
412         Args m_exception_extra_args;
413         LazyBool m_move_to_nearest_code;
414     };
415 
416 protected:
417     bool
418     DoExecute (Args& command,
419               CommandReturnObject &result) override
420     {
421         Target *target = GetSelectedOrDummyTarget(m_options.m_use_dummy);
422 
423         if (target == nullptr)
424         {
425             result.AppendError ("Invalid target.  Must set target before setting breakpoints (see 'target create' command).");
426             result.SetStatus (eReturnStatusFailed);
427             return false;
428         }
429 
430         // The following are the various types of breakpoints that could be set:
431         //   1).  -f -l -p  [-s -g]   (setting breakpoint by source location)
432         //   2).  -a  [-s -g]         (setting breakpoint by address)
433         //   3).  -n  [-s -g]         (setting breakpoint by function name)
434         //   4).  -r  [-s -g]         (setting breakpoint by function name regular expression)
435         //   5).  -p -f               (setting a breakpoint by comparing a reg-exp to source text)
436         //   6).  -E [-w -h]          (setting a breakpoint for exceptions for a given language.)
437 
438         BreakpointSetType break_type = eSetTypeInvalid;
439 
440         if (m_options.m_line_num != 0)
441             break_type = eSetTypeFileAndLine;
442         else if (m_options.m_load_addr != LLDB_INVALID_ADDRESS)
443             break_type = eSetTypeAddress;
444         else if (!m_options.m_func_names.empty())
445             break_type = eSetTypeFunctionName;
446         else if  (!m_options.m_func_regexp.empty())
447             break_type = eSetTypeFunctionRegexp;
448         else if (!m_options.m_source_text_regexp.empty())
449             break_type = eSetTypeSourceRegexp;
450         else if (m_options.m_exception_language != eLanguageTypeUnknown)
451             break_type = eSetTypeException;
452 
453         Breakpoint *bp = nullptr;
454         FileSpec module_spec;
455         const bool internal = false;
456 
457         switch (break_type)
458         {
459             case eSetTypeFileAndLine: // Breakpoint by source position
460                 {
461                     FileSpec file;
462                     const size_t num_files = m_options.m_filenames.GetSize();
463                     if (num_files == 0)
464                     {
465                         if (!GetDefaultFile (target, file, result))
466                         {
467                             result.AppendError("No file supplied and no default file available.");
468                             result.SetStatus (eReturnStatusFailed);
469                             return false;
470                         }
471                     }
472                     else if (num_files > 1)
473                     {
474                         result.AppendError("Only one file at a time is allowed for file and line breakpoints.");
475                         result.SetStatus (eReturnStatusFailed);
476                         return false;
477                     }
478                     else
479                         file = m_options.m_filenames.GetFileSpecAtIndex(0);
480 
481                     // Only check for inline functions if
482                     LazyBool check_inlines = eLazyBoolCalculate;
483 
484                     bp = target->CreateBreakpoint (&(m_options.m_modules),
485                                                    file,
486                                                    m_options.m_line_num,
487                                                    check_inlines,
488                                                    m_options.m_skip_prologue,
489                                                    internal,
490                                                    m_options.m_hardware,
491                                                    m_options.m_move_to_nearest_code).get();
492                 }
493                 break;
494 
495             case eSetTypeAddress: // Breakpoint by address
496                 {
497                     // If a shared library has been specified, make an lldb_private::Address with the library, and
498                     // use that.  That way the address breakpoint will track the load location of the library.
499                     size_t num_modules_specified = m_options.m_modules.GetSize();
500                     if (num_modules_specified == 1)
501                     {
502                         const FileSpec *file_spec = m_options.m_modules.GetFileSpecPointerAtIndex(0);
503                         bp = target->CreateAddressInModuleBreakpoint (m_options.m_load_addr,
504                                                                       internal,
505                                                                       file_spec,
506                                                                       m_options.m_hardware).get();
507                     }
508                     else if (num_modules_specified == 0)
509                     {
510                         bp = target->CreateBreakpoint (m_options.m_load_addr,
511                                                        internal,
512                                                        m_options.m_hardware).get();
513                     }
514                     else
515                     {
516                         result.AppendError("Only one shared library can be specified for address breakpoints.");
517                         result.SetStatus(eReturnStatusFailed);
518                         return false;
519                     }
520                 break;
521                 }
522             case eSetTypeFunctionName: // Breakpoint by function name
523                 {
524                     uint32_t name_type_mask = m_options.m_func_name_type_mask;
525 
526                     if (name_type_mask == 0)
527                         name_type_mask = eFunctionNameTypeAuto;
528 
529                     bp = target->CreateBreakpoint (&(m_options.m_modules),
530                                                    &(m_options.m_filenames),
531                                                    m_options.m_func_names,
532                                                    name_type_mask,
533                                                    m_options.m_language,
534                                                    m_options.m_skip_prologue,
535                                                    internal,
536                                                    m_options.m_hardware).get();
537                 }
538                 break;
539 
540             case eSetTypeFunctionRegexp: // Breakpoint by regular expression function name
541                 {
542                     RegularExpression regexp(m_options.m_func_regexp.c_str());
543                     if (!regexp.IsValid())
544                     {
545                         char err_str[1024];
546                         regexp.GetErrorAsCString(err_str, sizeof(err_str));
547                         result.AppendErrorWithFormat("Function name regular expression could not be compiled: \"%s\"",
548                                                      err_str);
549                         result.SetStatus (eReturnStatusFailed);
550                         return false;
551                     }
552 
553                     bp = target->CreateFuncRegexBreakpoint (&(m_options.m_modules),
554                                                             &(m_options.m_filenames),
555                                                             regexp,
556                                                             m_options.m_language,
557                                                             m_options.m_skip_prologue,
558                                                             internal,
559                                                             m_options.m_hardware).get();
560                 }
561                 break;
562             case eSetTypeSourceRegexp: // Breakpoint by regexp on source text.
563                 {
564                     const size_t num_files = m_options.m_filenames.GetSize();
565 
566                     if (num_files == 0 && !m_options.m_all_files)
567                     {
568                         FileSpec file;
569                         if (!GetDefaultFile (target, file, result))
570                         {
571                             result.AppendError ("No files provided and could not find default file.");
572                             result.SetStatus (eReturnStatusFailed);
573                             return false;
574                         }
575                         else
576                         {
577                             m_options.m_filenames.Append (file);
578                         }
579                     }
580 
581                     RegularExpression regexp(m_options.m_source_text_regexp.c_str());
582                     if (!regexp.IsValid())
583                     {
584                         char err_str[1024];
585                         regexp.GetErrorAsCString(err_str, sizeof(err_str));
586                         result.AppendErrorWithFormat("Source text regular expression could not be compiled: \"%s\"",
587                                                      err_str);
588                         result.SetStatus (eReturnStatusFailed);
589                         return false;
590                     }
591                     bp = target->CreateSourceRegexBreakpoint (&(m_options.m_modules),
592                                                               &(m_options.m_filenames),
593                                                               regexp,
594                                                               internal,
595                                                               m_options.m_hardware,
596                                                               m_options.m_move_to_nearest_code).get();
597                 }
598                 break;
599             case eSetTypeException:
600                 {
601                     Error precond_error;
602                     bp = target->CreateExceptionBreakpoint (m_options.m_exception_language,
603                                                             m_options.m_catch_bp,
604                                                             m_options.m_throw_bp,
605                                                             internal,
606                                                             &m_options.m_exception_extra_args,
607                                                             &precond_error).get();
608                     if (precond_error.Fail())
609                     {
610                         result.AppendErrorWithFormat("Error setting extra exception arguments: %s",
611                                                      precond_error.AsCString());
612                         target->RemoveBreakpointByID(bp->GetID());
613                         result.SetStatus(eReturnStatusFailed);
614                         return false;
615                     }
616                 }
617                 break;
618             default:
619                 break;
620         }
621 
622         // Now set the various options that were passed in:
623         if (bp)
624         {
625             if (m_options.m_thread_id != LLDB_INVALID_THREAD_ID)
626                 bp->SetThreadID (m_options.m_thread_id);
627 
628             if (m_options.m_thread_index != UINT32_MAX)
629                 bp->GetOptions()->GetThreadSpec()->SetIndex(m_options.m_thread_index);
630 
631             if (!m_options.m_thread_name.empty())
632                 bp->GetOptions()->GetThreadSpec()->SetName(m_options.m_thread_name.c_str());
633 
634             if (!m_options.m_queue_name.empty())
635                 bp->GetOptions()->GetThreadSpec()->SetQueueName(m_options.m_queue_name.c_str());
636 
637             if (m_options.m_ignore_count != 0)
638                 bp->GetOptions()->SetIgnoreCount(m_options.m_ignore_count);
639 
640             if (!m_options.m_condition.empty())
641                 bp->GetOptions()->SetCondition(m_options.m_condition.c_str());
642 
643             if (!m_options.m_breakpoint_names.empty())
644             {
645                 Error error;  // We don't need to check the error here, since the option parser checked it...
646                 for (auto name : m_options.m_breakpoint_names)
647                     bp->AddName(name.c_str(), error);
648             }
649 
650             bp->SetOneShot (m_options.m_one_shot);
651         }
652 
653         if (bp)
654         {
655             Stream &output_stream = result.GetOutputStream();
656             const bool show_locations = false;
657             bp->GetDescription(&output_stream, lldb::eDescriptionLevelInitial, show_locations);
658             if (target == m_interpreter.GetDebugger().GetDummyTarget())
659                     output_stream.Printf ("Breakpoint set in dummy target, will get copied into future targets.\n");
660             else
661             {
662                 // Don't print out this warning for exception breakpoints.  They can get set before the target
663                 // is set, but we won't know how to actually set the breakpoint till we run.
664                 if (bp->GetNumLocations() == 0 && break_type != eSetTypeException)
665                 {
666                     output_stream.Printf ("WARNING:  Unable to resolve breakpoint to any actual locations.\n");
667                 }
668             }
669             result.SetStatus (eReturnStatusSuccessFinishResult);
670         }
671         else if (!bp)
672         {
673             result.AppendError ("Breakpoint creation failed: No breakpoint created.");
674             result.SetStatus (eReturnStatusFailed);
675         }
676 
677         return result.Succeeded();
678     }
679 
680 private:
681     bool
682     GetDefaultFile (Target *target, FileSpec &file, CommandReturnObject &result)
683     {
684         uint32_t default_line;
685         // First use the Source Manager's default file.
686         // Then use the current stack frame's file.
687         if (!target->GetSourceManager().GetDefaultFileAndLine(file, default_line))
688         {
689             StackFrame *cur_frame = m_exe_ctx.GetFramePtr();
690             if (cur_frame == nullptr)
691             {
692                 result.AppendError ("No selected frame to use to find the default file.");
693                 result.SetStatus (eReturnStatusFailed);
694                 return false;
695             }
696             else if (!cur_frame->HasDebugInformation())
697             {
698                 result.AppendError ("Cannot use the selected frame to find the default file, it has no debug info.");
699                 result.SetStatus (eReturnStatusFailed);
700                 return false;
701             }
702             else
703             {
704                 const SymbolContext &sc = cur_frame->GetSymbolContext (eSymbolContextLineEntry);
705                 if (sc.line_entry.file)
706                 {
707                     file = sc.line_entry.file;
708                 }
709                 else
710                 {
711                     result.AppendError ("Can't find the file for the selected frame to use as the default file.");
712                     result.SetStatus (eReturnStatusFailed);
713                     return false;
714                 }
715             }
716         }
717         return true;
718     }
719 
720     CommandOptions m_options;
721 };
722 
723 // If an additional option set beyond LLDB_OPTION_SET_10 is added, make sure to
724 // update the numbers passed to LLDB_OPT_SET_FROM_TO(...) appropriately.
725 #define LLDB_OPT_FILE ( LLDB_OPT_SET_FROM_TO(1, 9) & ~LLDB_OPT_SET_2 )
726 #define LLDB_OPT_NOT_10 ( LLDB_OPT_SET_FROM_TO(1, 10) & ~LLDB_OPT_SET_10 )
727 #define LLDB_OPT_SKIP_PROLOGUE ( LLDB_OPT_SET_1 | LLDB_OPT_SET_FROM_TO(3,8) )
728 #define LLDB_OPT_MOVE_TO_NEAREST_CODE ( LLDB_OPT_SET_1 | LLDB_OPT_SET_9 )
729 #define LLDB_OPT_EXPR_LANGUAGE ( LLDB_OPT_SET_FROM_TO(3, 8) )
730 
731 OptionDefinition
732 CommandObjectBreakpointSet::CommandOptions::g_option_table[] =
733 {
734     { LLDB_OPT_NOT_10, false, "shlib", 's', OptionParser::eRequiredArgument, nullptr, nullptr, CommandCompletions::eModuleCompletion, eArgTypeShlibName,
735         "Set the breakpoint only in this shared library.  "
736         "Can repeat this option multiple times to specify multiple shared libraries."},
737 
738     { LLDB_OPT_SET_ALL, false, "ignore-count", 'i', OptionParser::eRequiredArgument, nullptr, nullptr, 0, eArgTypeCount,
739         "Set the number of times this breakpoint is skipped before stopping." },
740 
741     { LLDB_OPT_SET_ALL, false, "one-shot", 'o', OptionParser::eNoArgument, nullptr, nullptr, 0, eArgTypeNone,
742         "The breakpoint is deleted the first time it causes a stop." },
743 
744     { LLDB_OPT_SET_ALL, false, "condition",    'c', OptionParser::eRequiredArgument, nullptr, nullptr, 0, eArgTypeExpression,
745         "The breakpoint stops only if this condition expression evaluates to true."},
746 
747     { LLDB_OPT_SET_ALL, false, "thread-index", 'x', OptionParser::eRequiredArgument, nullptr, nullptr, 0, eArgTypeThreadIndex,
748         "The breakpoint stops only for the thread whose indeX matches this argument."},
749 
750     { LLDB_OPT_SET_ALL, false, "thread-id", 't', OptionParser::eRequiredArgument, nullptr, nullptr, 0, eArgTypeThreadID,
751         "The breakpoint stops only for the thread whose TID matches this argument."},
752 
753     { LLDB_OPT_SET_ALL, false, "thread-name", 'T', OptionParser::eRequiredArgument, nullptr, nullptr, 0, eArgTypeThreadName,
754         "The breakpoint stops only for the thread whose thread name matches this argument."},
755 
756     { LLDB_OPT_SET_ALL, false, "hardware", 'H', OptionParser::eNoArgument, nullptr, nullptr, 0, eArgTypeNone,
757         "Require the breakpoint to use hardware breakpoints."},
758 
759     { LLDB_OPT_SET_ALL, false, "queue-name", 'q', OptionParser::eRequiredArgument, nullptr, nullptr, 0, eArgTypeQueueName,
760         "The breakpoint stops only for threads in the queue whose name is given by this argument."},
761 
762     { LLDB_OPT_FILE, false, "file", 'f', OptionParser::eRequiredArgument, nullptr, nullptr, CommandCompletions::eSourceFileCompletion, eArgTypeFilename,
763         "Specifies the source file in which to set this breakpoint.  "
764         "Note, by default lldb only looks for files that are #included if they use the standard include file extensions.  "
765         "To set breakpoints on .c/.cpp/.m/.mm files that are #included, set target.inline-breakpoint-strategy"
766         " to \"always\"."},
767 
768     { LLDB_OPT_SET_1, true, "line", 'l', OptionParser::eRequiredArgument, nullptr, nullptr, 0, eArgTypeLineNum,
769         "Specifies the line number on which to set this breakpoint."},
770 
771     // Comment out this option for the moment, as we don't actually use it, but will in the future.
772     // This way users won't see it, but the infrastructure is left in place.
773     //    { 0, false, "column",     'C', OptionParser::eRequiredArgument, nullptr, "<column>",
774     //    "Set the breakpoint by source location at this particular column."},
775 
776     { LLDB_OPT_SET_2, true, "address", 'a', OptionParser::eRequiredArgument, nullptr, nullptr, 0, eArgTypeAddressOrExpression,
777         "Set the breakpoint at the specified address.  "
778         "If the address maps uniquely to a particular "
779         "binary, then the address will be converted to a \"file\" address, so that the breakpoint will track that binary+offset no matter where "
780         "the binary eventually loads.  "
781         "Alternately, if you also specify the module - with the -s option - then the address will be treated as "
782         "a file address in that module, and resolved accordingly.  Again, this will allow lldb to track that offset on "
783         "subsequent reloads.  The module need not have been loaded at the time you specify this breakpoint, and will "
784         "get resolved when the module is loaded."},
785 
786     { LLDB_OPT_SET_3, true, "name", 'n', OptionParser::eRequiredArgument, nullptr, nullptr, CommandCompletions::eSymbolCompletion, eArgTypeFunctionName,
787         "Set the breakpoint by function name.  Can be repeated multiple times to make one breakpoint for multiple names" },
788 
789     { LLDB_OPT_SET_4, true, "fullname", 'F', OptionParser::eRequiredArgument, nullptr, nullptr, CommandCompletions::eSymbolCompletion, eArgTypeFullName,
790         "Set the breakpoint by fully qualified function names. For C++ this means namespaces and all arguments, and "
791         "for Objective C this means a full function prototype with class and selector.  "
792         "Can be repeated multiple times to make one breakpoint for multiple names." },
793 
794     { LLDB_OPT_SET_5, true, "selector", 'S', OptionParser::eRequiredArgument, nullptr, nullptr, 0, eArgTypeSelector,
795         "Set the breakpoint by ObjC selector name. Can be repeated multiple times to make one breakpoint for multiple Selectors." },
796 
797     { LLDB_OPT_SET_6, true, "method", 'M', OptionParser::eRequiredArgument, nullptr, nullptr, 0, eArgTypeMethod,
798         "Set the breakpoint by C++ method names.  Can be repeated multiple times to make one breakpoint for multiple methods." },
799 
800     { LLDB_OPT_SET_7, true, "func-regex", 'r', OptionParser::eRequiredArgument, nullptr, nullptr, 0, eArgTypeRegularExpression,
801         "Set the breakpoint by function name, evaluating a regular-expression to find the function name(s)." },
802 
803     { LLDB_OPT_SET_8, true, "basename", 'b', OptionParser::eRequiredArgument, nullptr, nullptr, CommandCompletions::eSymbolCompletion, eArgTypeFunctionName,
804         "Set the breakpoint by function basename (C++ namespaces and arguments will be ignored). "
805         "Can be repeated multiple times to make one breakpoint for multiple symbols." },
806 
807     { LLDB_OPT_SET_9, true, "source-pattern-regexp", 'p', OptionParser::eRequiredArgument, nullptr, nullptr, 0, eArgTypeRegularExpression,
808         "Set the breakpoint by specifying a regular expression which is matched against the source text in a source file or files "
809         "specified with the -f option.  The -f option can be specified more than once.  "
810         "If no source files are specified, uses the current \"default source file\".  "
811         "If you want to match against all source files, pass the \"--all-files\" option." },
812 
813     { LLDB_OPT_SET_9, false, "all-files", 'A', OptionParser::eNoArgument, nullptr, nullptr, 0, eArgTypeNone,
814         "All files are searched for source pattern matches." },
815 
816     { LLDB_OPT_SET_10, true, "language-exception", 'E', OptionParser::eRequiredArgument, nullptr, nullptr, 0, eArgTypeLanguage,
817         "Set the breakpoint on exceptions thrown by the specified language (without options, on throw but not catch.)" },
818 
819     { LLDB_OPT_SET_10, false, "on-throw", 'w', OptionParser::eRequiredArgument, nullptr, nullptr, 0, eArgTypeBoolean,
820         "Set the breakpoint on exception throW." },
821 
822     { LLDB_OPT_SET_10, false, "on-catch", 'h', OptionParser::eRequiredArgument, nullptr, nullptr, 0, eArgTypeBoolean,
823         "Set the breakpoint on exception catcH." },
824 
825 //  Don't add this option till it actually does something useful...
826 //    { LLDB_OPT_SET_10, false, "exception-typename", 'O', OptionParser::eRequiredArgument, nullptr, nullptr, 0, eArgTypeTypeName,
827 //        "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" },
828 
829     { LLDB_OPT_EXPR_LANGUAGE, false, "language", 'L', OptionParser::eRequiredArgument, nullptr, nullptr, 0, eArgTypeLanguage,
830         "Specifies the Language to use when interpreting the breakpoint's expression (note: currently only implemented for setting breakpoints on identifiers).  If not set the target.language setting is used." },
831 
832     { LLDB_OPT_SKIP_PROLOGUE, false, "skip-prologue", 'K', OptionParser::eRequiredArgument, nullptr, nullptr, 0, eArgTypeBoolean,
833         "sKip the prologue if the breakpoint is at the beginning of a function.  If not set the target.skip-prologue setting is used." },
834 
835     { LLDB_OPT_SET_ALL, false, "dummy-breakpoints", 'D', OptionParser::eNoArgument, nullptr, nullptr, 0, eArgTypeNone,
836         "Sets Dummy breakpoints - i.e. breakpoints set before a file is provided, which prime new targets."},
837 
838     { LLDB_OPT_SET_ALL, false, "breakpoint-name", 'N', OptionParser::eRequiredArgument, nullptr, nullptr, 0, eArgTypeBreakpointName,
839         "Adds this to the list of names for this breakopint."},
840 
841     { LLDB_OPT_MOVE_TO_NEAREST_CODE, false, "move-to-nearest-code", 'm', OptionParser::eRequiredArgument, nullptr, nullptr, 0, eArgTypeBoolean,
842         "Move breakpoints to nearest code. If not set the target.move-to-nearest-code setting is used." },
843 
844     { 0, false, nullptr, 0, 0, nullptr, nullptr, 0, eArgTypeNone, nullptr }
845 };
846 
847 //-------------------------------------------------------------------------
848 // CommandObjectBreakpointModify
849 //-------------------------------------------------------------------------
850 #pragma mark Modify
851 
852 class CommandObjectBreakpointModify : public CommandObjectParsed
853 {
854 public:
855     CommandObjectBreakpointModify (CommandInterpreter &interpreter) :
856         CommandObjectParsed(interpreter,
857                             "breakpoint modify",
858                             "Modify the options on a breakpoint or set of breakpoints in the executable.  "
859                             "If no breakpoint is specified, acts on the last created breakpoint.  "
860                             "With the exception of -e, -d and -i, passing an empty argument clears the modification.",
861                             nullptr),
862         m_options (interpreter)
863     {
864         CommandArgumentEntry arg;
865         CommandObject::AddIDsArgumentData(arg, eArgTypeBreakpointID, eArgTypeBreakpointIDRange);
866         // Add the entry for the first argument for this command to the object's arguments vector.
867         m_arguments.push_back (arg);
868     }
869 
870     ~CommandObjectBreakpointModify() override = default;
871 
872     Options *
873     GetOptions () override
874     {
875         return &m_options;
876     }
877 
878     class CommandOptions : public Options
879     {
880     public:
881         CommandOptions (CommandInterpreter &interpreter) :
882             Options (interpreter),
883             m_ignore_count (0),
884             m_thread_id(LLDB_INVALID_THREAD_ID),
885             m_thread_id_passed(false),
886             m_thread_index (UINT32_MAX),
887             m_thread_index_passed(false),
888             m_thread_name(),
889             m_queue_name(),
890             m_condition (),
891             m_one_shot (false),
892             m_enable_passed (false),
893             m_enable_value (false),
894             m_name_passed (false),
895             m_queue_passed (false),
896             m_condition_passed (false),
897             m_one_shot_passed (false),
898             m_use_dummy (false)
899         {
900         }
901 
902         ~CommandOptions() override = default;
903 
904         Error
905         SetOptionValue (uint32_t option_idx, const char *option_arg) override
906         {
907             Error error;
908             const int short_option = m_getopt_table[option_idx].val;
909 
910             switch (short_option)
911             {
912                 case 'c':
913                     if (option_arg != nullptr)
914                         m_condition.assign (option_arg);
915                     else
916                         m_condition.clear();
917                     m_condition_passed = true;
918                     break;
919                 case 'd':
920                     m_enable_passed = true;
921                     m_enable_value = false;
922                     break;
923                 case 'D':
924                     m_use_dummy = true;
925                     break;
926                 case 'e':
927                     m_enable_passed = true;
928                     m_enable_value = true;
929                     break;
930                 case 'i':
931                     m_ignore_count = StringConvert::ToUInt32(option_arg, UINT32_MAX, 0);
932                     if (m_ignore_count == UINT32_MAX)
933                        error.SetErrorStringWithFormat ("invalid ignore count '%s'", option_arg);
934                     break;
935                 case 'o':
936                 {
937                     bool value, success;
938                     value = Args::StringToBoolean(option_arg, false, &success);
939                     if (success)
940                     {
941                         m_one_shot_passed = true;
942                         m_one_shot = value;
943                     }
944                     else
945                         error.SetErrorStringWithFormat("invalid boolean value '%s' passed for -o option", option_arg);
946                 }
947                 break;
948                 case 't' :
949                     if (option_arg[0] == '\0')
950                     {
951                         m_thread_id = LLDB_INVALID_THREAD_ID;
952                         m_thread_id_passed = true;
953                     }
954                     else
955                     {
956                         m_thread_id = StringConvert::ToUInt64(option_arg, LLDB_INVALID_THREAD_ID, 0);
957                         if (m_thread_id == LLDB_INVALID_THREAD_ID)
958                            error.SetErrorStringWithFormat ("invalid thread id string '%s'", option_arg);
959                         else
960                             m_thread_id_passed = true;
961                     }
962                     break;
963                 case 'T':
964                     if (option_arg != nullptr)
965                         m_thread_name.assign (option_arg);
966                     else
967                         m_thread_name.clear();
968                     m_name_passed = true;
969                     break;
970                 case 'q':
971                     if (option_arg != nullptr)
972                         m_queue_name.assign (option_arg);
973                     else
974                         m_queue_name.clear();
975                     m_queue_passed = true;
976                     break;
977                 case 'x':
978                     if (option_arg[0] == '\n')
979                     {
980                         m_thread_index = UINT32_MAX;
981                         m_thread_index_passed = true;
982                     }
983                     else
984                     {
985                         m_thread_index = StringConvert::ToUInt32 (option_arg, UINT32_MAX, 0);
986                         if (m_thread_id == UINT32_MAX)
987                            error.SetErrorStringWithFormat ("invalid thread index string '%s'", option_arg);
988                         else
989                             m_thread_index_passed = true;
990                     }
991                     break;
992                 default:
993                     error.SetErrorStringWithFormat ("unrecognized option '%c'", short_option);
994                     break;
995             }
996 
997             return error;
998         }
999 
1000         void
1001         OptionParsingStarting () override
1002         {
1003             m_ignore_count = 0;
1004             m_thread_id = LLDB_INVALID_THREAD_ID;
1005             m_thread_id_passed = false;
1006             m_thread_index = UINT32_MAX;
1007             m_thread_index_passed = false;
1008             m_thread_name.clear();
1009             m_queue_name.clear();
1010             m_condition.clear();
1011             m_one_shot = false;
1012             m_enable_passed = false;
1013             m_queue_passed = false;
1014             m_name_passed = false;
1015             m_condition_passed = false;
1016             m_one_shot_passed = false;
1017             m_use_dummy = false;
1018         }
1019 
1020         const OptionDefinition*
1021         GetDefinitions () override
1022         {
1023             return g_option_table;
1024         }
1025 
1026         // Options table: Required for subclasses of Options.
1027 
1028         static OptionDefinition g_option_table[];
1029 
1030         // Instance variables to hold the values for command options.
1031 
1032         uint32_t m_ignore_count;
1033         lldb::tid_t m_thread_id;
1034         bool m_thread_id_passed;
1035         uint32_t m_thread_index;
1036         bool m_thread_index_passed;
1037         std::string m_thread_name;
1038         std::string m_queue_name;
1039         std::string m_condition;
1040         bool m_one_shot;
1041         bool m_enable_passed;
1042         bool m_enable_value;
1043         bool m_name_passed;
1044         bool m_queue_passed;
1045         bool m_condition_passed;
1046         bool m_one_shot_passed;
1047         bool m_use_dummy;
1048     };
1049 
1050 protected:
1051     bool
1052     DoExecute (Args& command, CommandReturnObject &result) override
1053     {
1054         Target *target = GetSelectedOrDummyTarget(m_options.m_use_dummy);
1055         if (target == nullptr)
1056         {
1057             result.AppendError ("Invalid target.  No existing target or breakpoints.");
1058             result.SetStatus (eReturnStatusFailed);
1059             return false;
1060         }
1061 
1062         Mutex::Locker locker;
1063         target->GetBreakpointList().GetListMutex(locker);
1064 
1065         BreakpointIDList valid_bp_ids;
1066 
1067         CommandObjectMultiwordBreakpoint::VerifyBreakpointOrLocationIDs (command, target, result, &valid_bp_ids);
1068 
1069         if (result.Succeeded())
1070         {
1071             const size_t count = valid_bp_ids.GetSize();
1072             for (size_t i = 0; i < count; ++i)
1073             {
1074                 BreakpointID cur_bp_id = valid_bp_ids.GetBreakpointIDAtIndex (i);
1075 
1076                 if (cur_bp_id.GetBreakpointID() != LLDB_INVALID_BREAK_ID)
1077                 {
1078                     Breakpoint *bp = target->GetBreakpointByID (cur_bp_id.GetBreakpointID()).get();
1079                     if (cur_bp_id.GetLocationID() != LLDB_INVALID_BREAK_ID)
1080                     {
1081                         BreakpointLocation *location = bp->FindLocationByID (cur_bp_id.GetLocationID()).get();
1082                         if (location)
1083                         {
1084                             if (m_options.m_thread_id_passed)
1085                                 location->SetThreadID (m_options.m_thread_id);
1086 
1087                             if (m_options.m_thread_index_passed)
1088                                 location->SetThreadIndex(m_options.m_thread_index);
1089 
1090                             if (m_options.m_name_passed)
1091                                 location->SetThreadName(m_options.m_thread_name.c_str());
1092 
1093                             if (m_options.m_queue_passed)
1094                                 location->SetQueueName(m_options.m_queue_name.c_str());
1095 
1096                             if (m_options.m_ignore_count != 0)
1097                                 location->SetIgnoreCount(m_options.m_ignore_count);
1098 
1099                             if (m_options.m_enable_passed)
1100                                 location->SetEnabled (m_options.m_enable_value);
1101 
1102                             if (m_options.m_condition_passed)
1103                                 location->SetCondition (m_options.m_condition.c_str());
1104                         }
1105                     }
1106                     else
1107                     {
1108                         if (m_options.m_thread_id_passed)
1109                             bp->SetThreadID (m_options.m_thread_id);
1110 
1111                         if (m_options.m_thread_index_passed)
1112                             bp->SetThreadIndex(m_options.m_thread_index);
1113 
1114                         if (m_options.m_name_passed)
1115                             bp->SetThreadName(m_options.m_thread_name.c_str());
1116 
1117                         if (m_options.m_queue_passed)
1118                             bp->SetQueueName(m_options.m_queue_name.c_str());
1119 
1120                         if (m_options.m_ignore_count != 0)
1121                             bp->SetIgnoreCount(m_options.m_ignore_count);
1122 
1123                         if (m_options.m_enable_passed)
1124                             bp->SetEnabled (m_options.m_enable_value);
1125 
1126                         if (m_options.m_condition_passed)
1127                             bp->SetCondition (m_options.m_condition.c_str());
1128                     }
1129                 }
1130             }
1131         }
1132 
1133         return result.Succeeded();
1134     }
1135 
1136 private:
1137     CommandOptions m_options;
1138 };
1139 
1140 #pragma mark Modify::CommandOptions
1141 OptionDefinition
1142 CommandObjectBreakpointModify::CommandOptions::g_option_table[] =
1143 {
1144 { LLDB_OPT_SET_ALL, false, "ignore-count", 'i', OptionParser::eRequiredArgument, nullptr, nullptr, 0, eArgTypeCount, "Set the number of times this breakpoint is skipped before stopping." },
1145 { LLDB_OPT_SET_ALL, false, "one-shot",     'o', OptionParser::eRequiredArgument, nullptr, nullptr, 0, eArgTypeBoolean, "The breakpoint is deleted the first time it stop causes a stop." },
1146 { LLDB_OPT_SET_ALL, false, "thread-index", 'x', OptionParser::eRequiredArgument, nullptr, nullptr, 0, eArgTypeThreadIndex, "The breakpoint stops only for the thread whose index matches this argument."},
1147 { LLDB_OPT_SET_ALL, false, "thread-id",    't', OptionParser::eRequiredArgument, nullptr, nullptr, 0, eArgTypeThreadID, "The breakpoint stops only for the thread whose TID matches this argument."},
1148 { LLDB_OPT_SET_ALL, false, "thread-name",  'T', OptionParser::eRequiredArgument, nullptr, nullptr, 0, eArgTypeThreadName, "The breakpoint stops only for the thread whose thread name matches this argument."},
1149 { LLDB_OPT_SET_ALL, false, "queue-name",   'q', OptionParser::eRequiredArgument, nullptr, nullptr, 0, eArgTypeQueueName, "The breakpoint stops only for threads in the queue whose name is given by this argument."},
1150 { LLDB_OPT_SET_ALL, false, "condition",    'c', OptionParser::eRequiredArgument, nullptr, nullptr, 0, eArgTypeExpression, "The breakpoint stops only if this condition expression evaluates to true."},
1151 { LLDB_OPT_SET_1,   false, "enable",       'e', OptionParser::eNoArgument,       nullptr, nullptr, 0, eArgTypeNone, "Enable the breakpoint."},
1152 { LLDB_OPT_SET_2,   false, "disable",      'd', OptionParser::eNoArgument,       nullptr, nullptr, 0, eArgTypeNone, "Disable the breakpoint."},
1153 { LLDB_OPT_SET_ALL, false, "dummy-breakpoints", 'D', OptionParser::eNoArgument,  nullptr, nullptr, 0, eArgTypeNone, "Sets Dummy breakpoints - i.e. breakpoints set before a file is provided, which prime new targets."},
1154 
1155 { 0,                false, nullptr,            0 , 0,                 nullptr, nullptr, 0, eArgTypeNone, nullptr }
1156 };
1157 
1158 //-------------------------------------------------------------------------
1159 // CommandObjectBreakpointEnable
1160 //-------------------------------------------------------------------------
1161 #pragma mark Enable
1162 
1163 class CommandObjectBreakpointEnable : public CommandObjectParsed
1164 {
1165 public:
1166     CommandObjectBreakpointEnable (CommandInterpreter &interpreter) :
1167         CommandObjectParsed(interpreter,
1168                             "enable",
1169                             "Enable the specified disabled breakpoint(s). If no breakpoints are specified, enable all of them.",
1170                             nullptr)
1171     {
1172         CommandArgumentEntry arg;
1173         CommandObject::AddIDsArgumentData(arg, eArgTypeBreakpointID, eArgTypeBreakpointIDRange);
1174         // Add the entry for the first argument for this command to the object's arguments vector.
1175         m_arguments.push_back (arg);
1176     }
1177 
1178     ~CommandObjectBreakpointEnable() override = default;
1179 
1180 protected:
1181     bool
1182     DoExecute (Args& command, CommandReturnObject &result) override
1183     {
1184         Target *target = GetSelectedOrDummyTarget();
1185         if (target == nullptr)
1186         {
1187             result.AppendError ("Invalid target.  No existing target or breakpoints.");
1188             result.SetStatus (eReturnStatusFailed);
1189             return false;
1190         }
1191 
1192         Mutex::Locker locker;
1193         target->GetBreakpointList().GetListMutex(locker);
1194 
1195         const BreakpointList &breakpoints = target->GetBreakpointList();
1196 
1197         size_t num_breakpoints = breakpoints.GetSize();
1198 
1199         if (num_breakpoints == 0)
1200         {
1201             result.AppendError ("No breakpoints exist to be enabled.");
1202             result.SetStatus (eReturnStatusFailed);
1203             return false;
1204         }
1205 
1206         if (command.GetArgumentCount() == 0)
1207         {
1208             // No breakpoint selected; enable all currently set breakpoints.
1209             target->EnableAllBreakpoints ();
1210             result.AppendMessageWithFormat ("All breakpoints enabled. (%" PRIu64 " breakpoints)\n", (uint64_t)num_breakpoints);
1211             result.SetStatus (eReturnStatusSuccessFinishNoResult);
1212         }
1213         else
1214         {
1215             // Particular breakpoint selected; enable that breakpoint.
1216             BreakpointIDList valid_bp_ids;
1217             CommandObjectMultiwordBreakpoint::VerifyBreakpointOrLocationIDs (command, target, result, &valid_bp_ids);
1218 
1219             if (result.Succeeded())
1220             {
1221                 int enable_count = 0;
1222                 int loc_count = 0;
1223                 const size_t count = valid_bp_ids.GetSize();
1224                 for (size_t i = 0; i < count; ++i)
1225                 {
1226                     BreakpointID cur_bp_id = valid_bp_ids.GetBreakpointIDAtIndex (i);
1227 
1228                     if (cur_bp_id.GetBreakpointID() != LLDB_INVALID_BREAK_ID)
1229                     {
1230                         Breakpoint *breakpoint = target->GetBreakpointByID (cur_bp_id.GetBreakpointID()).get();
1231                         if (cur_bp_id.GetLocationID() != LLDB_INVALID_BREAK_ID)
1232                         {
1233                             BreakpointLocation *location = breakpoint->FindLocationByID (cur_bp_id.GetLocationID()).get();
1234                             if (location)
1235                             {
1236                                 location->SetEnabled (true);
1237                                 ++loc_count;
1238                             }
1239                         }
1240                         else
1241                         {
1242                             breakpoint->SetEnabled (true);
1243                             ++enable_count;
1244                         }
1245                     }
1246                 }
1247                 result.AppendMessageWithFormat ("%d breakpoints enabled.\n", enable_count + loc_count);
1248                 result.SetStatus (eReturnStatusSuccessFinishNoResult);
1249             }
1250         }
1251 
1252         return result.Succeeded();
1253     }
1254 };
1255 
1256 //-------------------------------------------------------------------------
1257 // CommandObjectBreakpointDisable
1258 //-------------------------------------------------------------------------
1259 #pragma mark Disable
1260 
1261 class CommandObjectBreakpointDisable : public CommandObjectParsed
1262 {
1263 public:
1264     CommandObjectBreakpointDisable (CommandInterpreter &interpreter) :
1265         CommandObjectParsed(interpreter,
1266                             "breakpoint disable",
1267                             "Disable the specified breakpoint(s) without removing them.  If none are specified, disable all breakpoints.",
1268                             nullptr)
1269     {
1270         SetHelpLong(
1271 "Disable the specified breakpoint(s) without removing them.  \
1272 If none are specified, disable all breakpoints." R"(
1273 
1274 )" "Note: disabling a breakpoint will cause none of its locations to be hit \
1275 regardless of whether they are enabled or disabled.  After the sequence:" R"(
1276 
1277     (lldb) break disable 1
1278     (lldb) break enable 1.1
1279 
1280 execution will NOT stop at location 1.1.  To achieve that, type:
1281 
1282     (lldb) break disable 1.*
1283     (lldb) break enable 1.1
1284 
1285 )" "The first command disables all the locations of breakpoint 1, \
1286 the second re-enables the first location."
1287         );
1288 
1289         CommandArgumentEntry arg;
1290         CommandObject::AddIDsArgumentData(arg, eArgTypeBreakpointID, eArgTypeBreakpointIDRange);
1291         // Add the entry for the first argument for this command to the object's arguments vector.
1292         m_arguments.push_back (arg);
1293     }
1294 
1295     ~CommandObjectBreakpointDisable() override = default;
1296 
1297 protected:
1298     bool
1299     DoExecute (Args& command, CommandReturnObject &result) override
1300     {
1301         Target *target = GetSelectedOrDummyTarget();
1302         if (target == nullptr)
1303         {
1304             result.AppendError ("Invalid target.  No existing target or breakpoints.");
1305             result.SetStatus (eReturnStatusFailed);
1306             return false;
1307         }
1308 
1309         Mutex::Locker locker;
1310         target->GetBreakpointList().GetListMutex(locker);
1311 
1312         const BreakpointList &breakpoints = target->GetBreakpointList();
1313         size_t num_breakpoints = breakpoints.GetSize();
1314 
1315         if (num_breakpoints == 0)
1316         {
1317             result.AppendError ("No breakpoints exist to be disabled.");
1318             result.SetStatus (eReturnStatusFailed);
1319             return false;
1320         }
1321 
1322         if (command.GetArgumentCount() == 0)
1323         {
1324             // No breakpoint selected; disable all currently set breakpoints.
1325             target->DisableAllBreakpoints ();
1326             result.AppendMessageWithFormat ("All breakpoints disabled. (%" PRIu64 " breakpoints)\n", (uint64_t)num_breakpoints);
1327             result.SetStatus (eReturnStatusSuccessFinishNoResult);
1328         }
1329         else
1330         {
1331             // Particular breakpoint selected; disable that breakpoint.
1332             BreakpointIDList valid_bp_ids;
1333 
1334             CommandObjectMultiwordBreakpoint::VerifyBreakpointOrLocationIDs (command, target, result, &valid_bp_ids);
1335 
1336             if (result.Succeeded())
1337             {
1338                 int disable_count = 0;
1339                 int loc_count = 0;
1340                 const size_t count = valid_bp_ids.GetSize();
1341                 for (size_t i = 0; i < count; ++i)
1342                 {
1343                     BreakpointID cur_bp_id = valid_bp_ids.GetBreakpointIDAtIndex (i);
1344 
1345                     if (cur_bp_id.GetBreakpointID() != LLDB_INVALID_BREAK_ID)
1346                     {
1347                         Breakpoint *breakpoint = target->GetBreakpointByID (cur_bp_id.GetBreakpointID()).get();
1348                         if (cur_bp_id.GetLocationID() != LLDB_INVALID_BREAK_ID)
1349                         {
1350                             BreakpointLocation *location = breakpoint->FindLocationByID (cur_bp_id.GetLocationID()).get();
1351                             if (location)
1352                             {
1353                                 location->SetEnabled (false);
1354                                 ++loc_count;
1355                             }
1356                         }
1357                         else
1358                         {
1359                             breakpoint->SetEnabled (false);
1360                             ++disable_count;
1361                         }
1362                     }
1363                 }
1364                 result.AppendMessageWithFormat ("%d breakpoints disabled.\n", disable_count + loc_count);
1365                 result.SetStatus (eReturnStatusSuccessFinishNoResult);
1366             }
1367         }
1368 
1369         return result.Succeeded();
1370     }
1371 };
1372 
1373 //-------------------------------------------------------------------------
1374 // CommandObjectBreakpointList
1375 //-------------------------------------------------------------------------
1376 #pragma mark List
1377 
1378 class CommandObjectBreakpointList : public CommandObjectParsed
1379 {
1380 public:
1381     CommandObjectBreakpointList (CommandInterpreter &interpreter) :
1382         CommandObjectParsed(interpreter,
1383                             "breakpoint list",
1384                             "List some or all breakpoints at configurable levels of detail.",
1385                             nullptr),
1386         m_options (interpreter)
1387     {
1388         CommandArgumentEntry arg;
1389         CommandArgumentData bp_id_arg;
1390 
1391         // Define the first (and only) variant of this arg.
1392         bp_id_arg.arg_type = eArgTypeBreakpointID;
1393         bp_id_arg.arg_repetition = eArgRepeatOptional;
1394 
1395         // There is only one variant this argument could be; put it into the argument entry.
1396         arg.push_back (bp_id_arg);
1397 
1398         // Push the data for the first argument into the m_arguments vector.
1399         m_arguments.push_back (arg);
1400     }
1401 
1402     ~CommandObjectBreakpointList() override = default;
1403 
1404     Options *
1405     GetOptions () override
1406     {
1407         return &m_options;
1408     }
1409 
1410     class CommandOptions : public Options
1411     {
1412     public:
1413         CommandOptions (CommandInterpreter &interpreter) :
1414             Options (interpreter),
1415             m_level (lldb::eDescriptionLevelBrief),
1416             m_use_dummy(false)
1417         {
1418         }
1419 
1420         ~CommandOptions() override = default;
1421 
1422         Error
1423         SetOptionValue (uint32_t option_idx, const char *option_arg) override
1424         {
1425             Error error;
1426             const int short_option = m_getopt_table[option_idx].val;
1427 
1428             switch (short_option)
1429             {
1430                 case 'b':
1431                     m_level = lldb::eDescriptionLevelBrief;
1432                     break;
1433                 case 'D':
1434                     m_use_dummy = true;
1435                     break;
1436                 case 'f':
1437                     m_level = lldb::eDescriptionLevelFull;
1438                     break;
1439                 case 'v':
1440                     m_level = lldb::eDescriptionLevelVerbose;
1441                     break;
1442                 case 'i':
1443                     m_internal = true;
1444                     break;
1445                 default:
1446                     error.SetErrorStringWithFormat ("unrecognized option '%c'", short_option);
1447                     break;
1448             }
1449 
1450             return error;
1451         }
1452 
1453         void
1454         OptionParsingStarting () override
1455         {
1456             m_level = lldb::eDescriptionLevelFull;
1457             m_internal = false;
1458             m_use_dummy = false;
1459         }
1460 
1461         const OptionDefinition *
1462         GetDefinitions () override
1463         {
1464             return g_option_table;
1465         }
1466 
1467         // Options table: Required for subclasses of Options.
1468 
1469         static OptionDefinition g_option_table[];
1470 
1471         // Instance variables to hold the values for command options.
1472 
1473         lldb::DescriptionLevel m_level;
1474 
1475         bool m_internal;
1476         bool m_use_dummy;
1477     };
1478 
1479 protected:
1480     bool
1481     DoExecute (Args& command, CommandReturnObject &result) override
1482     {
1483         Target *target = GetSelectedOrDummyTarget(m_options.m_use_dummy);
1484 
1485         if (target == nullptr)
1486         {
1487             result.AppendError ("Invalid target. No current target or breakpoints.");
1488             result.SetStatus (eReturnStatusSuccessFinishNoResult);
1489             return true;
1490         }
1491 
1492         const BreakpointList &breakpoints = target->GetBreakpointList(m_options.m_internal);
1493         Mutex::Locker locker;
1494         target->GetBreakpointList(m_options.m_internal).GetListMutex(locker);
1495 
1496         size_t num_breakpoints = breakpoints.GetSize();
1497 
1498         if (num_breakpoints == 0)
1499         {
1500             result.AppendMessage ("No breakpoints currently set.");
1501             result.SetStatus (eReturnStatusSuccessFinishNoResult);
1502             return true;
1503         }
1504 
1505         Stream &output_stream = result.GetOutputStream();
1506 
1507         if (command.GetArgumentCount() == 0)
1508         {
1509             // No breakpoint selected; show info about all currently set breakpoints.
1510             result.AppendMessage ("Current breakpoints:");
1511             for (size_t i = 0; i < num_breakpoints; ++i)
1512             {
1513                 Breakpoint *breakpoint = breakpoints.GetBreakpointAtIndex (i).get();
1514                 AddBreakpointDescription (&output_stream, breakpoint, m_options.m_level);
1515             }
1516             result.SetStatus (eReturnStatusSuccessFinishNoResult);
1517         }
1518         else
1519         {
1520             // Particular breakpoints selected; show info about that breakpoint.
1521             BreakpointIDList valid_bp_ids;
1522             CommandObjectMultiwordBreakpoint::VerifyBreakpointOrLocationIDs (command, target, result, &valid_bp_ids);
1523 
1524             if (result.Succeeded())
1525             {
1526                 for (size_t i = 0; i < valid_bp_ids.GetSize(); ++i)
1527                 {
1528                     BreakpointID cur_bp_id = valid_bp_ids.GetBreakpointIDAtIndex (i);
1529                     Breakpoint *breakpoint = target->GetBreakpointByID (cur_bp_id.GetBreakpointID()).get();
1530                     AddBreakpointDescription (&output_stream, breakpoint, m_options.m_level);
1531                 }
1532                 result.SetStatus (eReturnStatusSuccessFinishNoResult);
1533             }
1534             else
1535             {
1536                 result.AppendError ("Invalid breakpoint id.");
1537                 result.SetStatus (eReturnStatusFailed);
1538             }
1539         }
1540 
1541         return result.Succeeded();
1542     }
1543 
1544 private:
1545     CommandOptions m_options;
1546 };
1547 
1548 #pragma mark List::CommandOptions
1549 OptionDefinition
1550 CommandObjectBreakpointList::CommandOptions::g_option_table[] =
1551 {
1552     { LLDB_OPT_SET_ALL, false, "internal", 'i', OptionParser::eNoArgument, nullptr, nullptr, 0, eArgTypeNone,
1553         "Show debugger internal breakpoints" },
1554 
1555     { LLDB_OPT_SET_1, false, "brief",    'b', OptionParser::eNoArgument, nullptr, nullptr, 0, eArgTypeNone,
1556         "Give a brief description of the breakpoint (no location info)."},
1557 
1558     // FIXME: We need to add an "internal" command, and then add this sort of thing to it.
1559     // But I need to see it for now, and don't want to wait.
1560     { LLDB_OPT_SET_2, false, "full",    'f', OptionParser::eNoArgument, nullptr, nullptr, 0, eArgTypeNone,
1561         "Give a full description of the breakpoint and its locations."},
1562 
1563     { LLDB_OPT_SET_3, false, "verbose", 'v', OptionParser::eNoArgument, nullptr, nullptr, 0, eArgTypeNone,
1564         "Explain everything we know about the breakpoint (for debugging debugger bugs)." },
1565 
1566     { LLDB_OPT_SET_ALL, false, "dummy-breakpoints", 'D', OptionParser::eNoArgument, nullptr, nullptr, 0, eArgTypeNone,
1567         "List Dummy breakpoints - i.e. breakpoints set before a file is provided, which prime new targets."},
1568 
1569     { 0, false, nullptr, 0, 0, nullptr, nullptr, 0, eArgTypeNone, nullptr }
1570 };
1571 
1572 //-------------------------------------------------------------------------
1573 // CommandObjectBreakpointClear
1574 //-------------------------------------------------------------------------
1575 #pragma mark Clear
1576 
1577 class CommandObjectBreakpointClear : public CommandObjectParsed
1578 {
1579 public:
1580     typedef enum BreakpointClearType
1581     {
1582         eClearTypeInvalid,
1583         eClearTypeFileAndLine
1584     } BreakpointClearType;
1585 
1586     CommandObjectBreakpointClear (CommandInterpreter &interpreter) :
1587         CommandObjectParsed (interpreter,
1588                              "breakpoint clear",
1589                              "Clears a breakpoint or set of breakpoints in the executable.",
1590                              "breakpoint clear <cmd-options>"),
1591         m_options (interpreter)
1592     {
1593     }
1594 
1595     ~CommandObjectBreakpointClear() override = default;
1596 
1597     Options *
1598     GetOptions () override
1599     {
1600         return &m_options;
1601     }
1602 
1603     class CommandOptions : public Options
1604     {
1605     public:
1606         CommandOptions (CommandInterpreter &interpreter) :
1607             Options (interpreter),
1608             m_filename (),
1609             m_line_num (0)
1610         {
1611         }
1612 
1613         ~CommandOptions() override = default;
1614 
1615         Error
1616         SetOptionValue (uint32_t option_idx, const char *option_arg) override
1617         {
1618             Error error;
1619             const int short_option = m_getopt_table[option_idx].val;
1620 
1621             switch (short_option)
1622             {
1623                 case 'f':
1624                     m_filename.assign (option_arg);
1625                     break;
1626 
1627                 case 'l':
1628                     m_line_num = StringConvert::ToUInt32 (option_arg, 0);
1629                     break;
1630 
1631                 default:
1632                     error.SetErrorStringWithFormat ("unrecognized option '%c'", short_option);
1633                     break;
1634             }
1635 
1636             return error;
1637         }
1638 
1639         void
1640         OptionParsingStarting () override
1641         {
1642             m_filename.clear();
1643             m_line_num = 0;
1644         }
1645 
1646         const OptionDefinition*
1647         GetDefinitions () override
1648         {
1649             return g_option_table;
1650         }
1651 
1652         // Options table: Required for subclasses of Options.
1653 
1654         static OptionDefinition g_option_table[];
1655 
1656         // Instance variables to hold the values for command options.
1657 
1658         std::string m_filename;
1659         uint32_t m_line_num;
1660 
1661     };
1662 
1663 protected:
1664     bool
1665     DoExecute (Args& command, CommandReturnObject &result) override
1666     {
1667         Target *target = GetSelectedOrDummyTarget();
1668         if (target == nullptr)
1669         {
1670             result.AppendError ("Invalid target. No existing target or breakpoints.");
1671             result.SetStatus (eReturnStatusFailed);
1672             return false;
1673         }
1674 
1675         // The following are the various types of breakpoints that could be cleared:
1676         //   1). -f -l (clearing breakpoint by source location)
1677 
1678         BreakpointClearType break_type = eClearTypeInvalid;
1679 
1680         if (m_options.m_line_num != 0)
1681             break_type = eClearTypeFileAndLine;
1682 
1683         Mutex::Locker locker;
1684         target->GetBreakpointList().GetListMutex(locker);
1685 
1686         BreakpointList &breakpoints = target->GetBreakpointList();
1687         size_t num_breakpoints = breakpoints.GetSize();
1688 
1689         // Early return if there's no breakpoint at all.
1690         if (num_breakpoints == 0)
1691         {
1692             result.AppendError ("Breakpoint clear: No breakpoint cleared.");
1693             result.SetStatus (eReturnStatusFailed);
1694             return result.Succeeded();
1695         }
1696 
1697         // Find matching breakpoints and delete them.
1698 
1699         // First create a copy of all the IDs.
1700         std::vector<break_id_t> BreakIDs;
1701         for (size_t i = 0; i < num_breakpoints; ++i)
1702             BreakIDs.push_back(breakpoints.GetBreakpointAtIndex(i)->GetID());
1703 
1704         int num_cleared = 0;
1705         StreamString ss;
1706         switch (break_type)
1707         {
1708             case eClearTypeFileAndLine: // Breakpoint by source position
1709                 {
1710                     const ConstString filename(m_options.m_filename.c_str());
1711                     BreakpointLocationCollection loc_coll;
1712 
1713                     for (size_t i = 0; i < num_breakpoints; ++i)
1714                     {
1715                         Breakpoint *bp = breakpoints.FindBreakpointByID(BreakIDs[i]).get();
1716 
1717                         if (bp->GetMatchingFileLine(filename, m_options.m_line_num, loc_coll))
1718                         {
1719                             // If the collection size is 0, it's a full match and we can just remove the breakpoint.
1720                             if (loc_coll.GetSize() == 0)
1721                             {
1722                                 bp->GetDescription(&ss, lldb::eDescriptionLevelBrief);
1723                                 ss.EOL();
1724                                 target->RemoveBreakpointByID (bp->GetID());
1725                                 ++num_cleared;
1726                             }
1727                         }
1728                     }
1729                 }
1730                 break;
1731 
1732             default:
1733                 break;
1734         }
1735 
1736         if (num_cleared > 0)
1737         {
1738             Stream &output_stream = result.GetOutputStream();
1739             output_stream.Printf ("%d breakpoints cleared:\n", num_cleared);
1740             output_stream << ss.GetData();
1741             output_stream.EOL();
1742             result.SetStatus (eReturnStatusSuccessFinishNoResult);
1743         }
1744         else
1745         {
1746             result.AppendError ("Breakpoint clear: No breakpoint cleared.");
1747             result.SetStatus (eReturnStatusFailed);
1748         }
1749 
1750         return result.Succeeded();
1751     }
1752 
1753 private:
1754     CommandOptions m_options;
1755 };
1756 
1757 #pragma mark Clear::CommandOptions
1758 
1759 OptionDefinition
1760 CommandObjectBreakpointClear::CommandOptions::g_option_table[] =
1761 {
1762     { LLDB_OPT_SET_1, false, "file", 'f', OptionParser::eRequiredArgument, nullptr, nullptr, CommandCompletions::eSourceFileCompletion, eArgTypeFilename,
1763         "Specify the breakpoint by source location in this particular file."},
1764 
1765     { LLDB_OPT_SET_1, true, "line", 'l', OptionParser::eRequiredArgument, nullptr, nullptr, 0, eArgTypeLineNum,
1766         "Specify the breakpoint by source location at this particular line."},
1767 
1768     { 0, false, nullptr, 0, 0, nullptr, nullptr, 0, eArgTypeNone, nullptr }
1769 };
1770 
1771 //-------------------------------------------------------------------------
1772 // CommandObjectBreakpointDelete
1773 //-------------------------------------------------------------------------
1774 #pragma mark Delete
1775 
1776 class CommandObjectBreakpointDelete : public CommandObjectParsed
1777 {
1778 public:
1779     CommandObjectBreakpointDelete (CommandInterpreter &interpreter) :
1780         CommandObjectParsed(interpreter,
1781                             "breakpoint delete",
1782                             "Delete the specified breakpoint(s).  If no breakpoints are specified, delete them all.",
1783                             nullptr),
1784         m_options (interpreter)
1785     {
1786         CommandArgumentEntry arg;
1787         CommandObject::AddIDsArgumentData(arg, eArgTypeBreakpointID, eArgTypeBreakpointIDRange);
1788         // Add the entry for the first argument for this command to the object's arguments vector.
1789         m_arguments.push_back (arg);
1790     }
1791 
1792     ~CommandObjectBreakpointDelete() override = default;
1793 
1794     Options *
1795     GetOptions () override
1796     {
1797         return &m_options;
1798     }
1799 
1800     class CommandOptions : public Options
1801     {
1802     public:
1803         CommandOptions (CommandInterpreter &interpreter) :
1804             Options (interpreter),
1805             m_use_dummy (false),
1806             m_force (false)
1807         {
1808         }
1809 
1810         ~CommandOptions() override = default;
1811 
1812         Error
1813         SetOptionValue (uint32_t option_idx, const char *option_arg) override
1814         {
1815             Error error;
1816             const int short_option = m_getopt_table[option_idx].val;
1817 
1818             switch (short_option)
1819             {
1820                 case 'f':
1821                     m_force = true;
1822                     break;
1823 
1824                 case 'D':
1825                     m_use_dummy = true;
1826                     break;
1827 
1828                 default:
1829                     error.SetErrorStringWithFormat ("unrecognized option '%c'", short_option);
1830                     break;
1831             }
1832 
1833             return error;
1834         }
1835 
1836         void
1837         OptionParsingStarting () override
1838         {
1839             m_use_dummy = false;
1840             m_force = false;
1841         }
1842 
1843         const OptionDefinition*
1844         GetDefinitions () override
1845         {
1846             return g_option_table;
1847         }
1848 
1849         // Options table: Required for subclasses of Options.
1850 
1851         static OptionDefinition g_option_table[];
1852 
1853         // Instance variables to hold the values for command options.
1854         bool m_use_dummy;
1855         bool m_force;
1856     };
1857 
1858 protected:
1859     bool
1860     DoExecute (Args& command, CommandReturnObject &result) override
1861     {
1862         Target *target = GetSelectedOrDummyTarget(m_options.m_use_dummy);
1863 
1864         if (target == nullptr)
1865         {
1866             result.AppendError ("Invalid target. No existing target or breakpoints.");
1867             result.SetStatus (eReturnStatusFailed);
1868             return false;
1869         }
1870 
1871         Mutex::Locker locker;
1872         target->GetBreakpointList().GetListMutex(locker);
1873 
1874         const BreakpointList &breakpoints = target->GetBreakpointList();
1875 
1876         size_t num_breakpoints = breakpoints.GetSize();
1877 
1878         if (num_breakpoints == 0)
1879         {
1880             result.AppendError ("No breakpoints exist to be deleted.");
1881             result.SetStatus (eReturnStatusFailed);
1882             return false;
1883         }
1884 
1885         if (command.GetArgumentCount() == 0)
1886         {
1887             if (!m_options.m_force && !m_interpreter.Confirm ("About to delete all breakpoints, do you want to do that?", true))
1888             {
1889                 result.AppendMessage("Operation cancelled...");
1890             }
1891             else
1892             {
1893                 target->RemoveAllBreakpoints ();
1894                 result.AppendMessageWithFormat ("All breakpoints removed. (%" PRIu64 " breakpoint%s)\n", (uint64_t)num_breakpoints, num_breakpoints > 1 ? "s" : "");
1895             }
1896             result.SetStatus (eReturnStatusSuccessFinishNoResult);
1897         }
1898         else
1899         {
1900             // Particular breakpoint selected; disable that breakpoint.
1901             BreakpointIDList valid_bp_ids;
1902             CommandObjectMultiwordBreakpoint::VerifyBreakpointOrLocationIDs (command, target, result, &valid_bp_ids);
1903 
1904             if (result.Succeeded())
1905             {
1906                 int delete_count = 0;
1907                 int disable_count = 0;
1908                 const size_t count = valid_bp_ids.GetSize();
1909                 for (size_t i = 0; i < count; ++i)
1910                 {
1911                     BreakpointID cur_bp_id = valid_bp_ids.GetBreakpointIDAtIndex (i);
1912 
1913                     if (cur_bp_id.GetBreakpointID() != LLDB_INVALID_BREAK_ID)
1914                     {
1915                         if (cur_bp_id.GetLocationID() != LLDB_INVALID_BREAK_ID)
1916                         {
1917                             Breakpoint *breakpoint = target->GetBreakpointByID (cur_bp_id.GetBreakpointID()).get();
1918                             BreakpointLocation *location = breakpoint->FindLocationByID (cur_bp_id.GetLocationID()).get();
1919                             // It makes no sense to try to delete individual locations, so we disable them instead.
1920                             if (location)
1921                             {
1922                                 location->SetEnabled (false);
1923                                 ++disable_count;
1924                             }
1925                         }
1926                         else
1927                         {
1928                             target->RemoveBreakpointByID (cur_bp_id.GetBreakpointID());
1929                             ++delete_count;
1930                         }
1931                     }
1932                 }
1933                 result.AppendMessageWithFormat ("%d breakpoints deleted; %d breakpoint locations disabled.\n",
1934                                                delete_count, disable_count);
1935                 result.SetStatus (eReturnStatusSuccessFinishNoResult);
1936             }
1937         }
1938         return result.Succeeded();
1939     }
1940 
1941 private:
1942     CommandOptions m_options;
1943 };
1944 
1945 OptionDefinition
1946 CommandObjectBreakpointDelete::CommandOptions::g_option_table[] =
1947 {
1948     { LLDB_OPT_SET_1, false, "force", 'f', OptionParser::eNoArgument, nullptr, nullptr, 0, eArgTypeNone,
1949         "Delete all breakpoints without querying for confirmation."},
1950 
1951     { LLDB_OPT_SET_1, false, "dummy-breakpoints", 'D', OptionParser::eNoArgument, nullptr, nullptr, 0, eArgTypeNone,
1952         "Delete Dummy breakpoints - i.e. breakpoints set before a file is provided, which prime new targets."},
1953 
1954     { 0, false, nullptr, 0, 0, nullptr, nullptr, 0, eArgTypeNone, nullptr }
1955 };
1956 
1957 //-------------------------------------------------------------------------
1958 // CommandObjectBreakpointName
1959 //-------------------------------------------------------------------------
1960 
1961 static OptionDefinition
1962 g_breakpoint_name_options[] =
1963 {
1964     { LLDB_OPT_SET_1,   false, "name", 'N', OptionParser::eRequiredArgument, nullptr, nullptr, 0, eArgTypeBreakpointName, "Specifies a breakpoint name to use."},
1965     { LLDB_OPT_SET_2,   false, "breakpoint-id", 'B', OptionParser::eRequiredArgument, nullptr, nullptr, 0, eArgTypeBreakpointID,   "Specify a breakpoint id to use."},
1966     { LLDB_OPT_SET_ALL, false, "dummy-breakpoints", 'D', OptionParser::eNoArgument, nullptr, nullptr, 0, eArgTypeNone,
1967         "Operate on Dummy breakpoints - i.e. breakpoints set before a file is provided, which prime new targets."},
1968 };
1969 class BreakpointNameOptionGroup : public OptionGroup
1970 {
1971 public:
1972     BreakpointNameOptionGroup() :
1973         OptionGroup(),
1974         m_breakpoint(LLDB_INVALID_BREAK_ID),
1975         m_use_dummy (false)
1976     {
1977     }
1978 
1979     ~BreakpointNameOptionGroup() override = default;
1980 
1981     uint32_t
1982     GetNumDefinitions () override
1983     {
1984       return sizeof (g_breakpoint_name_options) / sizeof (OptionDefinition);
1985     }
1986 
1987     const OptionDefinition*
1988     GetDefinitions () override
1989     {
1990         return g_breakpoint_name_options;
1991     }
1992 
1993     Error
1994     SetOptionValue (CommandInterpreter &interpreter,
1995                     uint32_t option_idx,
1996                     const char *option_value) override
1997     {
1998         Error error;
1999         const int short_option = g_breakpoint_name_options[option_idx].short_option;
2000 
2001         switch (short_option)
2002         {
2003         case 'N':
2004             if (BreakpointID::StringIsBreakpointName(option_value, error) && error.Success())
2005                 m_name.SetValueFromString(option_value);
2006             break;
2007 
2008         case 'B':
2009             if (m_breakpoint.SetValueFromString(option_value).Fail())
2010                 error.SetErrorStringWithFormat ("unrecognized value \"%s\" for breakpoint", option_value);
2011             break;
2012         case 'D':
2013             if (m_use_dummy.SetValueFromString(option_value).Fail())
2014                 error.SetErrorStringWithFormat ("unrecognized value \"%s\" for use-dummy", option_value);
2015             break;
2016 
2017         default:
2018               error.SetErrorStringWithFormat("unrecognized short option '%c'", short_option);
2019               break;
2020         }
2021         return error;
2022     }
2023 
2024     void
2025     OptionParsingStarting (CommandInterpreter &interpreter) override
2026     {
2027         m_name.Clear();
2028         m_breakpoint.Clear();
2029         m_use_dummy.Clear();
2030         m_use_dummy.SetDefaultValue(false);
2031     }
2032 
2033     OptionValueString m_name;
2034     OptionValueUInt64 m_breakpoint;
2035     OptionValueBoolean m_use_dummy;
2036 };
2037 
2038 class CommandObjectBreakpointNameAdd : public CommandObjectParsed
2039 {
2040 public:
2041     CommandObjectBreakpointNameAdd (CommandInterpreter &interpreter) :
2042         CommandObjectParsed (interpreter,
2043                              "add",
2044                              "Add a name to the breakpoints provided.",
2045                              "breakpoint name add <command-options> <breakpoint-id-list>"),
2046         m_name_options(),
2047         m_option_group(interpreter)
2048         {
2049             // Create the first variant for the first (and only) argument for this command.
2050             CommandArgumentEntry arg1;
2051             CommandArgumentData id_arg;
2052             id_arg.arg_type = eArgTypeBreakpointID;
2053             id_arg.arg_repetition = eArgRepeatOptional;
2054             arg1.push_back(id_arg);
2055             m_arguments.push_back (arg1);
2056 
2057             m_option_group.Append (&m_name_options, LLDB_OPT_SET_1, LLDB_OPT_SET_ALL);
2058             m_option_group.Finalize();
2059         }
2060 
2061     ~CommandObjectBreakpointNameAdd() override = default;
2062 
2063     Options *
2064     GetOptions() override
2065     {
2066         return &m_option_group;
2067     }
2068 
2069 protected:
2070     bool
2071     DoExecute (Args& command, CommandReturnObject &result) override
2072     {
2073         if (!m_name_options.m_name.OptionWasSet())
2074         {
2075             result.SetError("No name option provided.");
2076             return false;
2077         }
2078 
2079         Target *target = GetSelectedOrDummyTarget(m_name_options.m_use_dummy.GetCurrentValue());
2080 
2081         if (target == nullptr)
2082         {
2083             result.AppendError ("Invalid target. No existing target or breakpoints.");
2084             result.SetStatus (eReturnStatusFailed);
2085             return false;
2086         }
2087 
2088         Mutex::Locker locker;
2089         target->GetBreakpointList().GetListMutex(locker);
2090 
2091         const BreakpointList &breakpoints = target->GetBreakpointList();
2092 
2093         size_t num_breakpoints = breakpoints.GetSize();
2094         if (num_breakpoints == 0)
2095         {
2096             result.SetError("No breakpoints, cannot add names.");
2097             result.SetStatus (eReturnStatusFailed);
2098             return false;
2099         }
2100 
2101         // Particular breakpoint selected; disable that breakpoint.
2102         BreakpointIDList valid_bp_ids;
2103         CommandObjectMultiwordBreakpoint::VerifyBreakpointIDs (command, target, result, &valid_bp_ids);
2104 
2105         if (result.Succeeded())
2106         {
2107             if (valid_bp_ids.GetSize() == 0)
2108             {
2109                 result.SetError("No breakpoints specified, cannot add names.");
2110                 result.SetStatus (eReturnStatusFailed);
2111                 return false;
2112             }
2113             size_t num_valid_ids = valid_bp_ids.GetSize();
2114             for (size_t index = 0; index < num_valid_ids; index++)
2115             {
2116                 lldb::break_id_t bp_id = valid_bp_ids.GetBreakpointIDAtIndex(index).GetBreakpointID();
2117                 BreakpointSP bp_sp = breakpoints.FindBreakpointByID(bp_id);
2118                 Error error;  // We don't need to check the error here, since the option parser checked it...
2119                 bp_sp->AddName(m_name_options.m_name.GetCurrentValue(), error);
2120             }
2121         }
2122 
2123         return true;
2124     }
2125 
2126 private:
2127     BreakpointNameOptionGroup m_name_options;
2128     OptionGroupOptions m_option_group;
2129 };
2130 
2131 class CommandObjectBreakpointNameDelete : public CommandObjectParsed
2132 {
2133 public:
2134     CommandObjectBreakpointNameDelete (CommandInterpreter &interpreter) :
2135         CommandObjectParsed (interpreter,
2136                              "delete",
2137                              "Delete a name from the breakpoints provided.",
2138                              "breakpoint name delete <command-options> <breakpoint-id-list>"),
2139         m_name_options(),
2140         m_option_group(interpreter)
2141     {
2142         // Create the first variant for the first (and only) argument for this command.
2143         CommandArgumentEntry arg1;
2144         CommandArgumentData id_arg;
2145         id_arg.arg_type = eArgTypeBreakpointID;
2146         id_arg.arg_repetition = eArgRepeatOptional;
2147         arg1.push_back(id_arg);
2148         m_arguments.push_back (arg1);
2149 
2150         m_option_group.Append (&m_name_options, LLDB_OPT_SET_1, LLDB_OPT_SET_ALL);
2151         m_option_group.Finalize();
2152     }
2153 
2154     ~CommandObjectBreakpointNameDelete() override = default;
2155 
2156     Options *
2157     GetOptions() override
2158     {
2159         return &m_option_group;
2160     }
2161 
2162 protected:
2163     bool
2164     DoExecute (Args& command, CommandReturnObject &result) override
2165     {
2166         if (!m_name_options.m_name.OptionWasSet())
2167         {
2168             result.SetError("No name option provided.");
2169             return false;
2170         }
2171 
2172         Target *target = GetSelectedOrDummyTarget(m_name_options.m_use_dummy.GetCurrentValue());
2173 
2174         if (target == nullptr)
2175         {
2176             result.AppendError ("Invalid target. No existing target or breakpoints.");
2177             result.SetStatus (eReturnStatusFailed);
2178             return false;
2179         }
2180 
2181         Mutex::Locker locker;
2182         target->GetBreakpointList().GetListMutex(locker);
2183 
2184         const BreakpointList &breakpoints = target->GetBreakpointList();
2185 
2186         size_t num_breakpoints = breakpoints.GetSize();
2187         if (num_breakpoints == 0)
2188         {
2189             result.SetError("No breakpoints, cannot delete names.");
2190             result.SetStatus (eReturnStatusFailed);
2191             return false;
2192         }
2193 
2194         // Particular breakpoint selected; disable that breakpoint.
2195         BreakpointIDList valid_bp_ids;
2196         CommandObjectMultiwordBreakpoint::VerifyBreakpointIDs (command, target, result, &valid_bp_ids);
2197 
2198         if (result.Succeeded())
2199         {
2200             if (valid_bp_ids.GetSize() == 0)
2201             {
2202                 result.SetError("No breakpoints specified, cannot delete names.");
2203                 result.SetStatus (eReturnStatusFailed);
2204                 return false;
2205             }
2206             size_t num_valid_ids = valid_bp_ids.GetSize();
2207             for (size_t index = 0; index < num_valid_ids; index++)
2208             {
2209                 lldb::break_id_t bp_id = valid_bp_ids.GetBreakpointIDAtIndex(index).GetBreakpointID();
2210                 BreakpointSP bp_sp = breakpoints.FindBreakpointByID(bp_id);
2211                 bp_sp->RemoveName(m_name_options.m_name.GetCurrentValue());
2212             }
2213         }
2214 
2215         return true;
2216     }
2217 
2218 private:
2219     BreakpointNameOptionGroup m_name_options;
2220     OptionGroupOptions m_option_group;
2221 };
2222 
2223 class CommandObjectBreakpointNameList : public CommandObjectParsed
2224 {
2225 public:
2226     CommandObjectBreakpointNameList (CommandInterpreter &interpreter) :
2227         CommandObjectParsed (interpreter,
2228                              "list",
2229                              "List either the names for a breakpoint or the breakpoints for a given name.",
2230                              "breakpoint name list <command-options>"),
2231         m_name_options(),
2232         m_option_group(interpreter)
2233     {
2234         m_option_group.Append (&m_name_options);
2235         m_option_group.Finalize();
2236     }
2237 
2238     ~CommandObjectBreakpointNameList() override = default;
2239 
2240     Options *
2241     GetOptions() override
2242     {
2243         return &m_option_group;
2244     }
2245 
2246 protected:
2247     bool
2248     DoExecute (Args& command, CommandReturnObject &result) override
2249     {
2250         Target *target = GetSelectedOrDummyTarget(m_name_options.m_use_dummy.GetCurrentValue());
2251 
2252         if (target == nullptr)
2253         {
2254             result.AppendError ("Invalid target. No existing target or breakpoints.");
2255             result.SetStatus (eReturnStatusFailed);
2256             return false;
2257         }
2258 
2259         if (m_name_options.m_name.OptionWasSet())
2260         {
2261             const char *name = m_name_options.m_name.GetCurrentValue();
2262             Mutex::Locker locker;
2263             target->GetBreakpointList().GetListMutex(locker);
2264 
2265             BreakpointList &breakpoints = target->GetBreakpointList();
2266             for (BreakpointSP bp_sp : breakpoints.Breakpoints())
2267             {
2268                 if (bp_sp->MatchesName(name))
2269                 {
2270                     StreamString s;
2271                     bp_sp->GetDescription(&s, eDescriptionLevelBrief);
2272                     s.EOL();
2273                     result.AppendMessage(s.GetData());
2274                 }
2275             }
2276 
2277         }
2278         else if (m_name_options.m_breakpoint.OptionWasSet())
2279         {
2280             BreakpointSP bp_sp = target->GetBreakpointList().FindBreakpointByID(m_name_options.m_breakpoint.GetCurrentValue());
2281             if (bp_sp)
2282             {
2283                 std::vector<std::string> names;
2284                 bp_sp->GetNames (names);
2285                 result.AppendMessage ("Names:");
2286                 for (auto name : names)
2287                     result.AppendMessageWithFormat ("    %s\n", name.c_str());
2288             }
2289             else
2290             {
2291                 result.AppendErrorWithFormat ("Could not find breakpoint %" PRId64 ".\n",
2292                                            m_name_options.m_breakpoint.GetCurrentValue());
2293                 result.SetStatus (eReturnStatusFailed);
2294                 return false;
2295             }
2296         }
2297         else
2298         {
2299             result.SetError ("Must specify -N or -B option to list.");
2300             result.SetStatus (eReturnStatusFailed);
2301             return false;
2302         }
2303         return true;
2304     }
2305 
2306 private:
2307     BreakpointNameOptionGroup m_name_options;
2308     OptionGroupOptions m_option_group;
2309 };
2310 
2311 //-------------------------------------------------------------------------
2312 // CommandObjectMultiwordBreakpoint
2313 //-------------------------------------------------------------------------
2314 class CommandObjectBreakpointName : public CommandObjectMultiword
2315 {
2316 public:
2317     CommandObjectBreakpointName (CommandInterpreter &interpreter) :
2318         CommandObjectMultiword(interpreter,
2319                                 "name",
2320                                 "A set of commands to manage name tags for breakpoints",
2321                                 "breakpoint name <command> [<command-options>]")
2322     {
2323         CommandObjectSP add_command_object (new CommandObjectBreakpointNameAdd (interpreter));
2324         CommandObjectSP delete_command_object (new CommandObjectBreakpointNameDelete (interpreter));
2325         CommandObjectSP list_command_object (new CommandObjectBreakpointNameList (interpreter));
2326 
2327         LoadSubCommand ("add", add_command_object);
2328         LoadSubCommand ("delete", delete_command_object);
2329         LoadSubCommand ("list", list_command_object);
2330     }
2331 
2332     ~CommandObjectBreakpointName() override = default;
2333 };
2334 
2335 //-------------------------------------------------------------------------
2336 // CommandObjectMultiwordBreakpoint
2337 //-------------------------------------------------------------------------
2338 #pragma mark MultiwordBreakpoint
2339 
2340 CommandObjectMultiwordBreakpoint::CommandObjectMultiwordBreakpoint (CommandInterpreter &interpreter) :
2341     CommandObjectMultiword (interpreter,
2342                             "breakpoint",
2343                             "A set of commands for operating on breakpoints. Also see _regexp-break.",
2344                             "breakpoint <command> [<command-options>]")
2345 {
2346     CommandObjectSP list_command_object (new CommandObjectBreakpointList (interpreter));
2347     CommandObjectSP enable_command_object (new CommandObjectBreakpointEnable (interpreter));
2348     CommandObjectSP disable_command_object (new CommandObjectBreakpointDisable (interpreter));
2349     CommandObjectSP clear_command_object (new CommandObjectBreakpointClear (interpreter));
2350     CommandObjectSP delete_command_object (new CommandObjectBreakpointDelete (interpreter));
2351     CommandObjectSP set_command_object (new CommandObjectBreakpointSet (interpreter));
2352     CommandObjectSP command_command_object (new CommandObjectBreakpointCommand (interpreter));
2353     CommandObjectSP modify_command_object (new CommandObjectBreakpointModify(interpreter));
2354     CommandObjectSP name_command_object (new CommandObjectBreakpointName(interpreter));
2355 
2356     list_command_object->SetCommandName ("breakpoint list");
2357     enable_command_object->SetCommandName("breakpoint enable");
2358     disable_command_object->SetCommandName("breakpoint disable");
2359     clear_command_object->SetCommandName("breakpoint clear");
2360     delete_command_object->SetCommandName("breakpoint delete");
2361     set_command_object->SetCommandName("breakpoint set");
2362     command_command_object->SetCommandName ("breakpoint command");
2363     modify_command_object->SetCommandName ("breakpoint modify");
2364     name_command_object->SetCommandName ("breakpoint name");
2365 
2366     LoadSubCommand ("list",       list_command_object);
2367     LoadSubCommand ("enable",     enable_command_object);
2368     LoadSubCommand ("disable",    disable_command_object);
2369     LoadSubCommand ("clear",      clear_command_object);
2370     LoadSubCommand ("delete",     delete_command_object);
2371     LoadSubCommand ("set",        set_command_object);
2372     LoadSubCommand ("command",    command_command_object);
2373     LoadSubCommand ("modify",     modify_command_object);
2374     LoadSubCommand ("name",       name_command_object);
2375 }
2376 
2377 CommandObjectMultiwordBreakpoint::~CommandObjectMultiwordBreakpoint() = default;
2378 
2379 void
2380 CommandObjectMultiwordBreakpoint::VerifyIDs (Args &args,
2381                                              Target *target,
2382                                              bool allow_locations,
2383                                              CommandReturnObject &result,
2384                                              BreakpointIDList *valid_ids)
2385 {
2386     // args can be strings representing 1). integers (for breakpoint ids)
2387     //                                  2). the full breakpoint & location canonical representation
2388     //                                  3). the word "to" or a hyphen, representing a range (in which case there
2389     //                                      had *better* be an entry both before & after of one of the first two types.
2390     //                                  4). A breakpoint name
2391     // If args is empty, we will use the last created breakpoint (if there is one.)
2392 
2393     Args temp_args;
2394 
2395     if (args.GetArgumentCount() == 0)
2396     {
2397         if (target->GetLastCreatedBreakpoint())
2398         {
2399             valid_ids->AddBreakpointID (BreakpointID(target->GetLastCreatedBreakpoint()->GetID(), LLDB_INVALID_BREAK_ID));
2400             result.SetStatus (eReturnStatusSuccessFinishNoResult);
2401         }
2402         else
2403         {
2404             result.AppendError("No breakpoint specified and no last created breakpoint.");
2405             result.SetStatus (eReturnStatusFailed);
2406         }
2407         return;
2408     }
2409 
2410     // Create a new Args variable to use; copy any non-breakpoint-id-ranges stuff directly from the old ARGS to
2411     // the new TEMP_ARGS.  Do not copy breakpoint id range strings over; instead generate a list of strings for
2412     // all the breakpoint ids in the range, and shove all of those breakpoint id strings into TEMP_ARGS.
2413 
2414     BreakpointIDList::FindAndReplaceIDRanges (args, target, allow_locations, result, temp_args);
2415 
2416     // NOW, convert the list of breakpoint id strings in TEMP_ARGS into an actual BreakpointIDList:
2417 
2418     valid_ids->InsertStringArray (temp_args.GetConstArgumentVector(), temp_args.GetArgumentCount(), result);
2419 
2420     // At this point,  all of the breakpoint ids that the user passed in have been converted to breakpoint IDs
2421     // and put into valid_ids.
2422 
2423     if (result.Succeeded())
2424     {
2425         // Now that we've converted everything from args into a list of breakpoint ids, go through our tentative list
2426         // of breakpoint id's and verify that they correspond to valid/currently set breakpoints.
2427 
2428         const size_t count = valid_ids->GetSize();
2429         for (size_t i = 0; i < count; ++i)
2430         {
2431             BreakpointID cur_bp_id = valid_ids->GetBreakpointIDAtIndex (i);
2432             Breakpoint *breakpoint = target->GetBreakpointByID (cur_bp_id.GetBreakpointID()).get();
2433             if (breakpoint != nullptr)
2434             {
2435                 const size_t num_locations = breakpoint->GetNumLocations();
2436                 if (static_cast<size_t>(cur_bp_id.GetLocationID()) > num_locations)
2437                 {
2438                     StreamString id_str;
2439                     BreakpointID::GetCanonicalReference (&id_str,
2440                                                          cur_bp_id.GetBreakpointID(),
2441                                                          cur_bp_id.GetLocationID());
2442                     i = valid_ids->GetSize() + 1;
2443                     result.AppendErrorWithFormat ("'%s' is not a currently valid breakpoint/location id.\n",
2444                                                  id_str.GetData());
2445                     result.SetStatus (eReturnStatusFailed);
2446                 }
2447             }
2448             else
2449             {
2450                 i = valid_ids->GetSize() + 1;
2451                 result.AppendErrorWithFormat ("'%d' is not a currently valid breakpoint id.\n", cur_bp_id.GetBreakpointID());
2452                 result.SetStatus (eReturnStatusFailed);
2453             }
2454         }
2455     }
2456 }
2457