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