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