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