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