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