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