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