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