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