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 "CommandObjectBreakpoint.h"
11 #include "CommandObjectBreakpointCommand.h"
12 
13 // C Includes
14 // C++ Includes
15 // Other libraries and framework includes
16 // Project includes
17 #include "lldb/Breakpoint/Breakpoint.h"
18 #include "lldb/Breakpoint/BreakpointIDList.h"
19 #include "lldb/Breakpoint/BreakpointLocation.h"
20 #include "lldb/Interpreter/Options.h"
21 #include "lldb/Core/RegularExpression.h"
22 #include "lldb/Core/StreamString.h"
23 #include "lldb/Interpreter/CommandInterpreter.h"
24 #include "lldb/Interpreter/CommandReturnObject.h"
25 #include "lldb/Target/Target.h"
26 #include "lldb/Interpreter/CommandCompletions.h"
27 #include "lldb/Target/StackFrame.h"
28 #include "lldb/Target/Thread.h"
29 #include "lldb/Target/ThreadSpec.h"
30 
31 #include <vector>
32 
33 using namespace lldb;
34 using namespace lldb_private;
35 
36 static void
37 AddBreakpointDescription (Stream *s, Breakpoint *bp, lldb::DescriptionLevel level)
38 {
39     s->IndentMore();
40     bp->GetDescription (s, level, true);
41     s->IndentLess();
42     s->EOL();
43 }
44 
45 //-------------------------------------------------------------------------
46 // CommandObjectBreakpointSet
47 //-------------------------------------------------------------------------
48 
49 
50 class CommandObjectBreakpointSet : public CommandObjectParsed
51 {
52 public:
53 
54     typedef enum BreakpointSetType
55     {
56         eSetTypeInvalid,
57         eSetTypeFileAndLine,
58         eSetTypeAddress,
59         eSetTypeFunctionName,
60         eSetTypeFunctionRegexp,
61         eSetTypeSourceRegexp,
62         eSetTypeException
63     } BreakpointSetType;
64 
65     CommandObjectBreakpointSet (CommandInterpreter &interpreter) :
66         CommandObjectParsed (interpreter,
67                              "breakpoint set",
68                              "Sets a breakpoint or set of breakpoints in the executable.",
69                              "breakpoint set <cmd-options>"),
70         m_options (interpreter)
71     {
72     }
73 
74 
75     virtual
76     ~CommandObjectBreakpointSet () {}
77 
78     virtual Options *
79     GetOptions ()
80     {
81         return &m_options;
82     }
83 
84     class CommandOptions : public Options
85     {
86     public:
87 
88         CommandOptions (CommandInterpreter &interpreter) :
89             Options (interpreter),
90             m_condition (),
91             m_filenames (),
92             m_line_num (0),
93             m_column (0),
94             m_func_names (),
95             m_func_name_type_mask (eFunctionNameTypeNone),
96             m_func_regexp (),
97             m_source_text_regexp(),
98             m_modules (),
99             m_load_addr(),
100             m_ignore_count (0),
101             m_thread_id(LLDB_INVALID_THREAD_ID),
102             m_thread_index (UINT32_MAX),
103             m_thread_name(),
104             m_queue_name(),
105             m_catch_bp (false),
106             m_throw_bp (true),
107             m_language (eLanguageTypeUnknown),
108             m_skip_prologue (eLazyBoolCalculate)
109         {
110         }
111 
112 
113         virtual
114         ~CommandOptions () {}
115 
116         virtual Error
117         SetOptionValue (uint32_t option_idx, const char *option_arg)
118         {
119             Error error;
120             char short_option = (char) m_getopt_table[option_idx].val;
121 
122             switch (short_option)
123             {
124                 case 'a':
125                     m_load_addr = Args::StringToUInt64(option_arg, LLDB_INVALID_ADDRESS, 0);
126                     if (m_load_addr == LLDB_INVALID_ADDRESS)
127                         m_load_addr = Args::StringToUInt64(option_arg, LLDB_INVALID_ADDRESS, 16);
128 
129                     if (m_load_addr == LLDB_INVALID_ADDRESS)
130                         error.SetErrorStringWithFormat ("invalid address string '%s'", option_arg);
131                     break;
132 
133                 case 'C':
134                     m_column = Args::StringToUInt32 (option_arg, 0);
135                     break;
136 
137                 case 'c':
138                     m_condition.assign(option_arg);
139                     break;
140 
141                 case 'f':
142                     m_filenames.AppendIfUnique (FileSpec(option_arg, false));
143                     break;
144 
145                 case 'l':
146                     m_line_num = Args::StringToUInt32 (option_arg, 0);
147                     break;
148 
149                 case 'b':
150                     m_func_names.push_back (option_arg);
151                     m_func_name_type_mask |= eFunctionNameTypeBase;
152                     break;
153 
154                 case 'n':
155                     m_func_names.push_back (option_arg);
156                     m_func_name_type_mask |= eFunctionNameTypeAuto;
157                     break;
158 
159                 case 'F':
160                     m_func_names.push_back (option_arg);
161                     m_func_name_type_mask |= eFunctionNameTypeFull;
162                     break;
163 
164                 case 'S':
165                     m_func_names.push_back (option_arg);
166                     m_func_name_type_mask |= eFunctionNameTypeSelector;
167                     break;
168 
169                 case 'M':
170                     m_func_names.push_back (option_arg);
171                     m_func_name_type_mask |= eFunctionNameTypeMethod;
172                     break;
173 
174                 case 'p':
175                     m_source_text_regexp.assign (option_arg);
176                     break;
177 
178                 case 'r':
179                     m_func_regexp.assign (option_arg);
180                     break;
181 
182                 case 's':
183                     {
184                         m_modules.AppendIfUnique (FileSpec (option_arg, false));
185                         break;
186                     }
187                 case 'i':
188                 {
189                     m_ignore_count = Args::StringToUInt32(option_arg, UINT32_MAX, 0);
190                     if (m_ignore_count == UINT32_MAX)
191                        error.SetErrorStringWithFormat ("invalid ignore count '%s'", option_arg);
192                 }
193                 break;
194                 case 't' :
195                 {
196                     m_thread_id = Args::StringToUInt64(option_arg, LLDB_INVALID_THREAD_ID, 0);
197                     if (m_thread_id == LLDB_INVALID_THREAD_ID)
198                        error.SetErrorStringWithFormat ("invalid thread id string '%s'", option_arg);
199                 }
200                 break;
201                 case 'T':
202                     m_thread_name.assign (option_arg);
203                     break;
204                 case 'q':
205                     m_queue_name.assign (option_arg);
206                     break;
207                 case 'x':
208                 {
209                     m_thread_index = Args::StringToUInt32(option_arg, UINT32_MAX, 0);
210                     if (m_thread_id == UINT32_MAX)
211                        error.SetErrorStringWithFormat ("invalid thread index string '%s'", option_arg);
212 
213                 }
214                 break;
215                 case 'E':
216                 {
217                     LanguageType language = LanguageRuntime::GetLanguageTypeFromString (option_arg);
218 
219                     switch (language)
220                     {
221                         case eLanguageTypeC89:
222                         case eLanguageTypeC:
223                         case eLanguageTypeC99:
224                             m_language = eLanguageTypeC;
225                             break;
226                         case eLanguageTypeC_plus_plus:
227                             m_language = eLanguageTypeC_plus_plus;
228                             break;
229                         case eLanguageTypeObjC:
230                             m_language = eLanguageTypeObjC;
231                             break;
232                         case eLanguageTypeObjC_plus_plus:
233                             error.SetErrorStringWithFormat ("Set exception breakpoints separately for c++ and objective-c");
234                             break;
235                         case eLanguageTypeUnknown:
236                             error.SetErrorStringWithFormat ("Unknown language type: '%s' for exception breakpoint", option_arg);
237                             break;
238                         default:
239                             error.SetErrorStringWithFormat ("Unsupported language type: '%s' for exception breakpoint", option_arg);
240                     }
241                 }
242                 break;
243                 case 'w':
244                 {
245                     bool success;
246                     m_throw_bp = Args::StringToBoolean (option_arg, true, &success);
247                     if (!success)
248                         error.SetErrorStringWithFormat ("Invalid boolean value for on-throw option: '%s'", option_arg);
249                 }
250                 break;
251                 case 'h':
252                 {
253                     bool success;
254                     m_catch_bp = Args::StringToBoolean (option_arg, true, &success);
255                     if (!success)
256                         error.SetErrorStringWithFormat ("Invalid boolean value for on-catch option: '%s'", option_arg);
257                 }
258                 case 'K':
259                 {
260                     bool success;
261                     bool value;
262                     value = Args::StringToBoolean (option_arg, true, &success);
263                     if (value)
264                         m_skip_prologue = eLazyBoolYes;
265                     else
266                         m_skip_prologue = eLazyBoolNo;
267 
268                     if (!success)
269                         error.SetErrorStringWithFormat ("Invalid boolean value for skip prologue option: '%s'", option_arg);
270                 }
271                 break;
272                 default:
273                     error.SetErrorStringWithFormat ("unrecognized option '%c'", short_option);
274                     break;
275             }
276 
277             return error;
278         }
279         void
280         OptionParsingStarting ()
281         {
282             m_condition.clear();
283             m_filenames.Clear();
284             m_line_num = 0;
285             m_column = 0;
286             m_func_names.clear();
287             m_func_name_type_mask = eFunctionNameTypeNone;
288             m_func_regexp.clear();
289             m_source_text_regexp.clear();
290             m_modules.Clear();
291             m_load_addr = LLDB_INVALID_ADDRESS;
292             m_ignore_count = 0;
293             m_thread_id = LLDB_INVALID_THREAD_ID;
294             m_thread_index = UINT32_MAX;
295             m_thread_name.clear();
296             m_queue_name.clear();
297             m_catch_bp = false;
298             m_throw_bp = true;
299             m_language = eLanguageTypeUnknown;
300             m_skip_prologue = eLazyBoolCalculate;
301         }
302 
303         const OptionDefinition*
304         GetDefinitions ()
305         {
306             return g_option_table;
307         }
308 
309         // Options table: Required for subclasses of Options.
310 
311         static OptionDefinition g_option_table[];
312 
313         // Instance variables to hold the values for command options.
314 
315         std::string m_condition;
316         FileSpecList m_filenames;
317         uint32_t m_line_num;
318         uint32_t m_column;
319         std::vector<std::string> m_func_names;
320         uint32_t m_func_name_type_mask;
321         std::string m_func_regexp;
322         std::string m_source_text_regexp;
323         FileSpecList m_modules;
324         lldb::addr_t m_load_addr;
325         uint32_t m_ignore_count;
326         lldb::tid_t m_thread_id;
327         uint32_t m_thread_index;
328         std::string m_thread_name;
329         std::string m_queue_name;
330         bool m_catch_bp;
331         bool m_throw_bp;
332         lldb::LanguageType m_language;
333         LazyBool m_skip_prologue;
334 
335     };
336 
337 protected:
338     virtual bool
339     DoExecute (Args& command,
340              CommandReturnObject &result)
341     {
342         Target *target = m_interpreter.GetDebugger().GetSelectedTarget().get();
343         if (target == NULL)
344         {
345             result.AppendError ("Invalid target.  Must set target before setting breakpoints (see 'target create' command).");
346             result.SetStatus (eReturnStatusFailed);
347             return false;
348         }
349 
350         // The following are the various types of breakpoints that could be set:
351         //   1).  -f -l -p  [-s -g]   (setting breakpoint by source location)
352         //   2).  -a  [-s -g]         (setting breakpoint by address)
353         //   3).  -n  [-s -g]         (setting breakpoint by function name)
354         //   4).  -r  [-s -g]         (setting breakpoint by function name regular expression)
355         //   5).  -p -f               (setting a breakpoint by comparing a reg-exp to source text)
356         //   6).  -E [-w -h]          (setting a breakpoint for exceptions for a given language.)
357 
358         BreakpointSetType break_type = eSetTypeInvalid;
359 
360         if (m_options.m_line_num != 0)
361             break_type = eSetTypeFileAndLine;
362         else if (m_options.m_load_addr != LLDB_INVALID_ADDRESS)
363             break_type = eSetTypeAddress;
364         else if (!m_options.m_func_names.empty())
365             break_type = eSetTypeFunctionName;
366         else if  (!m_options.m_func_regexp.empty())
367             break_type = eSetTypeFunctionRegexp;
368         else if (!m_options.m_source_text_regexp.empty())
369             break_type = eSetTypeSourceRegexp;
370         else if (m_options.m_language != eLanguageTypeUnknown)
371             break_type = eSetTypeException;
372 
373         Breakpoint *bp = NULL;
374         FileSpec module_spec;
375         const bool internal = false;
376 
377         switch (break_type)
378         {
379             case eSetTypeFileAndLine: // Breakpoint by source position
380                 {
381                     FileSpec file;
382                     uint32_t num_files = m_options.m_filenames.GetSize();
383                     if (num_files == 0)
384                     {
385                         if (!GetDefaultFile (target, file, result))
386                         {
387                             result.AppendError("No file supplied and no default file available.");
388                             result.SetStatus (eReturnStatusFailed);
389                             return false;
390                         }
391                     }
392                     else if (num_files > 1)
393                     {
394                         result.AppendError("Only one file at a time is allowed for file and line breakpoints.");
395                         result.SetStatus (eReturnStatusFailed);
396                         return false;
397                     }
398                     else
399                         file = m_options.m_filenames.GetFileSpecAtIndex(0);
400 
401                     // Only check for inline functions if
402                     LazyBool check_inlines = eLazyBoolCalculate;
403 
404                     bp = target->CreateBreakpoint (&(m_options.m_modules),
405                                                    file,
406                                                    m_options.m_line_num,
407                                                    check_inlines,
408                                                    m_options.m_skip_prologue,
409                                                    internal).get();
410                 }
411                 break;
412 
413             case eSetTypeAddress: // Breakpoint by address
414                 bp = target->CreateBreakpoint (m_options.m_load_addr, false).get();
415                 break;
416 
417             case eSetTypeFunctionName: // Breakpoint by function name
418                 {
419                     uint32_t name_type_mask = m_options.m_func_name_type_mask;
420 
421                     if (name_type_mask == 0)
422                         name_type_mask = eFunctionNameTypeAuto;
423 
424                     bp = target->CreateBreakpoint (&(m_options.m_modules),
425                                                    &(m_options.m_filenames),
426                                                    m_options.m_func_names,
427                                                    name_type_mask,
428                                                    m_options.m_skip_prologue,
429                                                    internal).get();
430                 }
431                 break;
432 
433             case eSetTypeFunctionRegexp: // Breakpoint by regular expression function name
434                 {
435                     RegularExpression regexp(m_options.m_func_regexp.c_str());
436                     if (!regexp.IsValid())
437                     {
438                         char err_str[1024];
439                         regexp.GetErrorAsCString(err_str, sizeof(err_str));
440                         result.AppendErrorWithFormat("Function name regular expression could not be compiled: \"%s\"",
441                                                      err_str);
442                         result.SetStatus (eReturnStatusFailed);
443                         return false;
444                     }
445 
446                     bp = target->CreateFuncRegexBreakpoint (&(m_options.m_modules),
447                                                             &(m_options.m_filenames),
448                                                             regexp,
449                                                             m_options.m_skip_prologue,
450                                                             internal).get();
451                 }
452                 break;
453             case eSetTypeSourceRegexp: // Breakpoint by regexp on source text.
454                 {
455                     int num_files = m_options.m_filenames.GetSize();
456 
457                     if (num_files == 0)
458                     {
459                         FileSpec file;
460                         if (!GetDefaultFile (target, file, result))
461                         {
462                             result.AppendError ("No files provided and could not find default file.");
463                             result.SetStatus (eReturnStatusFailed);
464                             return false;
465                         }
466                         else
467                         {
468                             m_options.m_filenames.Append (file);
469                         }
470                     }
471 
472                     RegularExpression regexp(m_options.m_source_text_regexp.c_str());
473                     if (!regexp.IsValid())
474                     {
475                         char err_str[1024];
476                         regexp.GetErrorAsCString(err_str, sizeof(err_str));
477                         result.AppendErrorWithFormat("Source text regular expression could not be compiled: \"%s\"",
478                                                      err_str);
479                         result.SetStatus (eReturnStatusFailed);
480                         return false;
481                     }
482                     bp = target->CreateSourceRegexBreakpoint (&(m_options.m_modules), &(m_options.m_filenames), regexp).get();
483                 }
484                 break;
485             case eSetTypeException:
486                 {
487                     bp = target->CreateExceptionBreakpoint (m_options.m_language, m_options.m_catch_bp, m_options.m_throw_bp).get();
488                 }
489                 break;
490             default:
491                 break;
492         }
493 
494         // Now set the various options that were passed in:
495         if (bp)
496         {
497             if (m_options.m_thread_id != LLDB_INVALID_THREAD_ID)
498                 bp->SetThreadID (m_options.m_thread_id);
499 
500             if (m_options.m_thread_index != UINT32_MAX)
501                 bp->GetOptions()->GetThreadSpec()->SetIndex(m_options.m_thread_index);
502 
503             if (!m_options.m_thread_name.empty())
504                 bp->GetOptions()->GetThreadSpec()->SetName(m_options.m_thread_name.c_str());
505 
506             if (!m_options.m_queue_name.empty())
507                 bp->GetOptions()->GetThreadSpec()->SetQueueName(m_options.m_queue_name.c_str());
508 
509             if (m_options.m_ignore_count != 0)
510                 bp->GetOptions()->SetIgnoreCount(m_options.m_ignore_count);
511 
512             if (!m_options.m_condition.empty())
513                 bp->GetOptions()->SetCondition(m_options.m_condition.c_str());
514         }
515 
516         if (bp)
517         {
518             Stream &output_stream = result.GetOutputStream();
519             const bool show_locations = false;
520             bp->GetDescription(&output_stream, lldb::eDescriptionLevelInitial, show_locations);
521             // Don't print out this warning for exception breakpoints.  They can get set before the target
522             // is set, but we won't know how to actually set the breakpoint till we run.
523             if (bp->GetNumLocations() == 0 && break_type != eSetTypeException)
524                 output_stream.Printf ("WARNING:  Unable to resolve breakpoint to any actual locations.\n");
525             result.SetStatus (eReturnStatusSuccessFinishResult);
526         }
527         else if (!bp)
528         {
529             result.AppendError ("Breakpoint creation failed: No breakpoint created.");
530             result.SetStatus (eReturnStatusFailed);
531         }
532 
533         return result.Succeeded();
534     }
535 
536 private:
537     bool
538     GetDefaultFile (Target *target, FileSpec &file, CommandReturnObject &result)
539     {
540         uint32_t default_line;
541         // First use the Source Manager's default file.
542         // Then use the current stack frame's file.
543         if (!target->GetSourceManager().GetDefaultFileAndLine(file, default_line))
544         {
545             StackFrame *cur_frame = m_interpreter.GetExecutionContext().GetFramePtr();
546             if (cur_frame == NULL)
547             {
548                 result.AppendError ("No selected frame to use to find the default file.");
549                 result.SetStatus (eReturnStatusFailed);
550                 return false;
551             }
552             else if (!cur_frame->HasDebugInformation())
553             {
554                 result.AppendError ("Cannot use the selected frame to find the default file, it has no debug info.");
555                 result.SetStatus (eReturnStatusFailed);
556                 return false;
557             }
558             else
559             {
560                 const SymbolContext &sc = cur_frame->GetSymbolContext (eSymbolContextLineEntry);
561                 if (sc.line_entry.file)
562                 {
563                     file = sc.line_entry.file;
564                 }
565                 else
566                 {
567                     result.AppendError ("Can't find the file for the selected frame to use as the default file.");
568                     result.SetStatus (eReturnStatusFailed);
569                     return false;
570                 }
571             }
572         }
573         return true;
574     }
575 
576     CommandOptions m_options;
577 };
578 // If an additional option set beyond LLDB_OPTION_SET_10 is added, make sure to
579 // update the numbers passed to LLDB_OPT_SET_FROM_TO(...) appropriately.
580 #define LLDB_OPT_FILE ( LLDB_OPT_SET_FROM_TO(1, 9) & ~LLDB_OPT_SET_2 )
581 #define LLDB_OPT_NOT_10 ( LLDB_OPT_SET_FROM_TO(1, 10) & ~LLDB_OPT_SET_10 )
582 #define LLDB_OPT_SKIP_PROLOGUE ( LLDB_OPT_SET_1 | LLDB_OPT_SET_FROM_TO(3,8) )
583 
584 OptionDefinition
585 CommandObjectBreakpointSet::CommandOptions::g_option_table[] =
586 {
587     { LLDB_OPT_NOT_10, false, "shlib", 's', required_argument, NULL, CommandCompletions::eModuleCompletion, eArgTypeShlibName,
588         "Set the breakpoint only in this shared library.  "
589         "Can repeat this option multiple times to specify multiple shared libraries."},
590 
591     { LLDB_OPT_SET_ALL, false, "ignore-count", 'i', required_argument,   NULL, 0, eArgTypeCount,
592         "Set the number of times this breakpoint is skipped before stopping." },
593 
594     { LLDB_OPT_SET_ALL, false, "condition",    'c', required_argument, NULL, 0, eArgTypeExpression,
595         "The breakpoint stops only if this condition expression evaluates to true."},
596 
597     { LLDB_OPT_SET_ALL, false, "thread-index", 'x', required_argument, NULL, 0, eArgTypeThreadIndex,
598         "The breakpoint stops only for the thread whose index matches this argument."},
599 
600     { LLDB_OPT_SET_ALL, false, "thread-id", 't', required_argument, NULL, 0, eArgTypeThreadID,
601         "The breakpoint stops only for the thread whose TID matches this argument."},
602 
603     { LLDB_OPT_SET_ALL, false, "thread-name", 'T', required_argument, NULL, 0, eArgTypeThreadName,
604         "The breakpoint stops only for the thread whose thread name matches this argument."},
605 
606     { LLDB_OPT_SET_ALL, false, "queue-name", 'q', required_argument, NULL, 0, eArgTypeQueueName,
607         "The breakpoint stops only for threads in the queue whose name is given by this argument."},
608 
609     { LLDB_OPT_FILE, false, "file", 'f', required_argument, NULL, CommandCompletions::eSourceFileCompletion, eArgTypeFilename,
610         "Specifies the source file in which to set this breakpoint."},
611 
612     { LLDB_OPT_SET_1, true, "line", 'l', required_argument, NULL, 0, eArgTypeLineNum,
613         "Specifies the line number on which to set this breakpoint."},
614 
615     // Comment out this option for the moment, as we don't actually use it, but will in the future.
616     // This way users won't see it, but the infrastructure is left in place.
617     //    { 0, false, "column",     'C', required_argument, NULL, "<column>",
618     //    "Set the breakpoint by source location at this particular column."},
619 
620     { LLDB_OPT_SET_2, true, "address", 'a', required_argument, NULL, 0, eArgTypeAddress,
621         "Set the breakpoint by address, at the specified address."},
622 
623     { LLDB_OPT_SET_3, true, "name", 'n', required_argument, NULL, CommandCompletions::eSymbolCompletion, eArgTypeFunctionName,
624         "Set the breakpoint by function name.  Can be repeated multiple times to make one breakpoint for multiple snames" },
625 
626     { LLDB_OPT_SET_4, true, "fullname", 'F', required_argument, NULL, CommandCompletions::eSymbolCompletion, eArgTypeFullName,
627         "Set the breakpoint by fully qualified function names. For C++ this means namespaces and all arguments, and "
628         "for Objective C this means a full function prototype with class and selector.   "
629         "Can be repeated multiple times to make one breakpoint for multiple names." },
630 
631     { LLDB_OPT_SET_5, true, "selector", 'S', required_argument, NULL, 0, eArgTypeSelector,
632         "Set the breakpoint by ObjC selector name. Can be repeated multiple times to make one breakpoint for multiple Selectors." },
633 
634     { LLDB_OPT_SET_6, true, "method", 'M', required_argument, NULL, 0, eArgTypeMethod,
635         "Set the breakpoint by C++ method names.  Can be repeated multiple times to make one breakpoint for multiple methods." },
636 
637     { LLDB_OPT_SET_7, true, "func-regex", 'r', required_argument, NULL, 0, eArgTypeRegularExpression,
638         "Set the breakpoint by function name, evaluating a regular-expression to find the function name(s)." },
639 
640     { LLDB_OPT_SET_8, true, "basename", 'b', required_argument, NULL, CommandCompletions::eSymbolCompletion, eArgTypeFunctionName,
641         "Set the breakpoint by function basename (C++ namespaces and arguments will be ignored). "
642         "Can be repeated multiple times to make one breakpoint for multiple symbols." },
643 
644     { LLDB_OPT_SET_9, true, "source-pattern-regexp", 'p', required_argument, NULL, 0, eArgTypeRegularExpression,
645         "Set the breakpoint specifying a regular expression to match a pattern in the source text in a given source file." },
646 
647     { LLDB_OPT_SET_10, true, "language-exception", 'E', required_argument, NULL, 0, eArgTypeLanguage,
648         "Set the breakpoint on exceptions thrown by the specified language (without options, on throw but not catch.)" },
649 
650     { LLDB_OPT_SET_10, false, "on-throw", 'w', required_argument, NULL, 0, eArgTypeBoolean,
651         "Set the breakpoint on exception throW." },
652 
653     { LLDB_OPT_SET_10, false, "on-catch", 'h', required_argument, NULL, 0, eArgTypeBoolean,
654         "Set the breakpoint on exception catcH." },
655 
656     { LLDB_OPT_SKIP_PROLOGUE, false, "skip-prologue", 'K', required_argument, NULL, 0, eArgTypeBoolean,
657         "sKip the prologue if the breakpoint is at the beginning of a function.  If not set the target.skip-prologue setting is used." },
658 
659     { 0, false, NULL, 0, 0, NULL, 0, eArgTypeNone, NULL }
660 };
661 
662 //-------------------------------------------------------------------------
663 // CommandObjectBreakpointModify
664 //-------------------------------------------------------------------------
665 #pragma mark Modify
666 
667 class CommandObjectBreakpointModify : public CommandObjectParsed
668 {
669 public:
670 
671     CommandObjectBreakpointModify (CommandInterpreter &interpreter) :
672         CommandObjectParsed (interpreter,
673                              "breakpoint modify",
674                              "Modify the options on a breakpoint or set of breakpoints in the executable.  "
675                              "If no breakpoint is specified, acts on the last created breakpoint.  "
676                              "With the exception of -e, -d and -i, passing an empty argument clears the modification.",
677                              NULL),
678         m_options (interpreter)
679     {
680         CommandArgumentEntry arg;
681         CommandObject::AddIDsArgumentData(arg, eArgTypeBreakpointID, eArgTypeBreakpointIDRange);
682         // Add the entry for the first argument for this command to the object's arguments vector.
683         m_arguments.push_back (arg);
684     }
685 
686 
687     virtual
688     ~CommandObjectBreakpointModify () {}
689 
690     virtual Options *
691     GetOptions ()
692     {
693         return &m_options;
694     }
695 
696     class CommandOptions : public Options
697     {
698     public:
699 
700         CommandOptions (CommandInterpreter &interpreter) :
701             Options (interpreter),
702             m_ignore_count (0),
703             m_thread_id(LLDB_INVALID_THREAD_ID),
704             m_thread_id_passed(false),
705             m_thread_index (UINT32_MAX),
706             m_thread_index_passed(false),
707             m_thread_name(),
708             m_queue_name(),
709             m_condition (),
710             m_enable_passed (false),
711             m_enable_value (false),
712             m_name_passed (false),
713             m_queue_passed (false),
714             m_condition_passed (false)
715         {
716         }
717 
718         virtual
719         ~CommandOptions () {}
720 
721         virtual Error
722         SetOptionValue (uint32_t option_idx, const char *option_arg)
723         {
724             Error error;
725             char short_option = (char) m_getopt_table[option_idx].val;
726 
727             switch (short_option)
728             {
729                 case 'c':
730                     if (option_arg != NULL)
731                         m_condition.assign (option_arg);
732                     else
733                         m_condition.clear();
734                     m_condition_passed = true;
735                     break;
736                 case 'd':
737                     m_enable_passed = true;
738                     m_enable_value = false;
739                     break;
740                 case 'e':
741                     m_enable_passed = true;
742                     m_enable_value = true;
743                     break;
744                 case 'i':
745                 {
746                     m_ignore_count = Args::StringToUInt32(option_arg, UINT32_MAX, 0);
747                     if (m_ignore_count == UINT32_MAX)
748                        error.SetErrorStringWithFormat ("invalid ignore count '%s'", option_arg);
749                 }
750                 break;
751                 case 't' :
752                 {
753                     if (option_arg[0] == '\0')
754                     {
755                         m_thread_id = LLDB_INVALID_THREAD_ID;
756                         m_thread_id_passed = true;
757                     }
758                     else
759                     {
760                         m_thread_id = Args::StringToUInt64(option_arg, LLDB_INVALID_THREAD_ID, 0);
761                         if (m_thread_id == LLDB_INVALID_THREAD_ID)
762                            error.SetErrorStringWithFormat ("invalid thread id string '%s'", option_arg);
763                         else
764                             m_thread_id_passed = true;
765                     }
766                 }
767                 break;
768                 case 'T':
769                     if (option_arg != NULL)
770                         m_thread_name.assign (option_arg);
771                     else
772                         m_thread_name.clear();
773                     m_name_passed = true;
774                     break;
775                 case 'q':
776                     if (option_arg != NULL)
777                         m_queue_name.assign (option_arg);
778                     else
779                         m_queue_name.clear();
780                     m_queue_passed = true;
781                     break;
782                 case 'x':
783                 {
784                     if (option_arg[0] == '\n')
785                     {
786                         m_thread_index = UINT32_MAX;
787                         m_thread_index_passed = true;
788                     }
789                     else
790                     {
791                         m_thread_index = Args::StringToUInt32 (option_arg, UINT32_MAX, 0);
792                         if (m_thread_id == UINT32_MAX)
793                            error.SetErrorStringWithFormat ("invalid thread index string '%s'", option_arg);
794                         else
795                             m_thread_index_passed = true;
796                     }
797                 }
798                 break;
799                 default:
800                     error.SetErrorStringWithFormat ("unrecognized option '%c'", short_option);
801                     break;
802             }
803 
804             return error;
805         }
806         void
807         OptionParsingStarting ()
808         {
809             m_ignore_count = 0;
810             m_thread_id = LLDB_INVALID_THREAD_ID;
811             m_thread_id_passed = false;
812             m_thread_index = UINT32_MAX;
813             m_thread_index_passed = false;
814             m_thread_name.clear();
815             m_queue_name.clear();
816             m_condition.clear();
817             m_enable_passed = false;
818             m_queue_passed = false;
819             m_name_passed = false;
820             m_condition_passed = false;
821         }
822 
823         const OptionDefinition*
824         GetDefinitions ()
825         {
826             return g_option_table;
827         }
828 
829 
830         // Options table: Required for subclasses of Options.
831 
832         static OptionDefinition g_option_table[];
833 
834         // Instance variables to hold the values for command options.
835 
836         uint32_t m_ignore_count;
837         lldb::tid_t m_thread_id;
838         bool m_thread_id_passed;
839         uint32_t m_thread_index;
840         bool m_thread_index_passed;
841         std::string m_thread_name;
842         std::string m_queue_name;
843         std::string m_condition;
844         bool m_enable_passed;
845         bool m_enable_value;
846         bool m_name_passed;
847         bool m_queue_passed;
848         bool m_condition_passed;
849 
850     };
851 
852 protected:
853     virtual bool
854     DoExecute (Args& command, CommandReturnObject &result)
855     {
856         Target *target = m_interpreter.GetDebugger().GetSelectedTarget().get();
857         if (target == NULL)
858         {
859             result.AppendError ("Invalid target.  No existing target or breakpoints.");
860             result.SetStatus (eReturnStatusFailed);
861             return false;
862         }
863 
864         Mutex::Locker locker;
865         target->GetBreakpointList().GetListMutex(locker);
866 
867         BreakpointIDList valid_bp_ids;
868 
869         CommandObjectMultiwordBreakpoint::VerifyBreakpointIDs (command, target, result, &valid_bp_ids);
870 
871         if (result.Succeeded())
872         {
873             const size_t count = valid_bp_ids.GetSize();
874             for (size_t i = 0; i < count; ++i)
875             {
876                 BreakpointID cur_bp_id = valid_bp_ids.GetBreakpointIDAtIndex (i);
877 
878                 if (cur_bp_id.GetBreakpointID() != LLDB_INVALID_BREAK_ID)
879                 {
880                     Breakpoint *bp = target->GetBreakpointByID (cur_bp_id.GetBreakpointID()).get();
881                     if (cur_bp_id.GetLocationID() != LLDB_INVALID_BREAK_ID)
882                     {
883                         BreakpointLocation *location = bp->FindLocationByID (cur_bp_id.GetLocationID()).get();
884                         if (location)
885                         {
886                             if (m_options.m_thread_id_passed)
887                                 location->SetThreadID (m_options.m_thread_id);
888 
889                             if (m_options.m_thread_index_passed)
890                                 location->SetThreadIndex(m_options.m_thread_index);
891 
892                             if (m_options.m_name_passed)
893                                 location->SetThreadName(m_options.m_thread_name.c_str());
894 
895                             if (m_options.m_queue_passed)
896                                 location->SetQueueName(m_options.m_queue_name.c_str());
897 
898                             if (m_options.m_ignore_count != 0)
899                                 location->SetIgnoreCount(m_options.m_ignore_count);
900 
901                             if (m_options.m_enable_passed)
902                                 location->SetEnabled (m_options.m_enable_value);
903 
904                             if (m_options.m_condition_passed)
905                                 location->SetCondition (m_options.m_condition.c_str());
906                         }
907                     }
908                     else
909                     {
910                         if (m_options.m_thread_id_passed)
911                             bp->SetThreadID (m_options.m_thread_id);
912 
913                         if (m_options.m_thread_index_passed)
914                             bp->SetThreadIndex(m_options.m_thread_index);
915 
916                         if (m_options.m_name_passed)
917                             bp->SetThreadName(m_options.m_thread_name.c_str());
918 
919                         if (m_options.m_queue_passed)
920                             bp->SetQueueName(m_options.m_queue_name.c_str());
921 
922                         if (m_options.m_ignore_count != 0)
923                             bp->SetIgnoreCount(m_options.m_ignore_count);
924 
925                         if (m_options.m_enable_passed)
926                             bp->SetEnabled (m_options.m_enable_value);
927 
928                         if (m_options.m_condition_passed)
929                             bp->SetCondition (m_options.m_condition.c_str());
930                     }
931                 }
932             }
933         }
934 
935         return result.Succeeded();
936     }
937 
938 private:
939     CommandOptions m_options;
940 };
941 
942 #pragma mark Modify::CommandOptions
943 OptionDefinition
944 CommandObjectBreakpointModify::CommandOptions::g_option_table[] =
945 {
946 { LLDB_OPT_SET_ALL, false, "ignore-count", 'i', required_argument, NULL, 0, eArgTypeCount, "Set the number of times this breakpoint is skipped before stopping." },
947 { LLDB_OPT_SET_ALL, false, "thread-index", 'x', required_argument, NULL, 0, eArgTypeThreadIndex, "The breakpoint stops only for the thread whose indeX matches this argument."},
948 { LLDB_OPT_SET_ALL, false, "thread-id",    't', required_argument, NULL, 0, eArgTypeThreadID, "The breakpoint stops only for the thread whose TID matches this argument."},
949 { LLDB_OPT_SET_ALL, false, "thread-name",  'T', required_argument, NULL, 0, eArgTypeThreadName, "The breakpoint stops only for the thread whose thread name matches this argument."},
950 { LLDB_OPT_SET_ALL, false, "queue-name",   'q', required_argument, NULL, 0, eArgTypeQueueName, "The breakpoint stops only for threads in the queue whose name is given by this argument."},
951 { LLDB_OPT_SET_ALL, false, "condition",    'c', required_argument, NULL, 0, eArgTypeExpression, "The breakpoint stops only if this condition expression evaluates to true."},
952 { LLDB_OPT_SET_1,   false, "enable",       'e', no_argument,       NULL, 0, eArgTypeNone, "Enable the breakpoint."},
953 { LLDB_OPT_SET_2,   false, "disable",      'd', no_argument,       NULL, 0, eArgTypeNone, "Disable the breakpoint."},
954 { 0,                false, NULL,            0 , 0,                 NULL, 0,    eArgTypeNone, NULL }
955 };
956 
957 //-------------------------------------------------------------------------
958 // CommandObjectBreakpointEnable
959 //-------------------------------------------------------------------------
960 #pragma mark Enable
961 
962 class CommandObjectBreakpointEnable : public CommandObjectParsed
963 {
964 public:
965     CommandObjectBreakpointEnable (CommandInterpreter &interpreter) :
966         CommandObjectParsed (interpreter,
967                              "enable",
968                              "Enable the specified disabled breakpoint(s). If no breakpoints are specified, enable all of them.",
969                              NULL)
970     {
971         CommandArgumentEntry arg;
972         CommandObject::AddIDsArgumentData(arg, eArgTypeBreakpointID, eArgTypeBreakpointIDRange);
973         // Add the entry for the first argument for this command to the object's arguments vector.
974         m_arguments.push_back (arg);
975     }
976 
977 
978     virtual
979     ~CommandObjectBreakpointEnable () {}
980 
981 protected:
982     virtual bool
983     DoExecute (Args& command, CommandReturnObject &result)
984     {
985         Target *target = m_interpreter.GetDebugger().GetSelectedTarget().get();
986         if (target == NULL)
987         {
988             result.AppendError ("Invalid target.  No existing target or breakpoints.");
989             result.SetStatus (eReturnStatusFailed);
990             return false;
991         }
992 
993         Mutex::Locker locker;
994         target->GetBreakpointList().GetListMutex(locker);
995 
996         const BreakpointList &breakpoints = target->GetBreakpointList();
997 
998         size_t num_breakpoints = breakpoints.GetSize();
999 
1000         if (num_breakpoints == 0)
1001         {
1002             result.AppendError ("No breakpoints exist to be enabled.");
1003             result.SetStatus (eReturnStatusFailed);
1004             return false;
1005         }
1006 
1007         if (command.GetArgumentCount() == 0)
1008         {
1009             // No breakpoint selected; enable all currently set breakpoints.
1010             target->EnableAllBreakpoints ();
1011             result.AppendMessageWithFormat ("All breakpoints enabled. (%lu breakpoints)\n", num_breakpoints);
1012             result.SetStatus (eReturnStatusSuccessFinishNoResult);
1013         }
1014         else
1015         {
1016             // Particular breakpoint selected; enable that breakpoint.
1017             BreakpointIDList valid_bp_ids;
1018             CommandObjectMultiwordBreakpoint::VerifyBreakpointIDs (command, target, result, &valid_bp_ids);
1019 
1020             if (result.Succeeded())
1021             {
1022                 int enable_count = 0;
1023                 int loc_count = 0;
1024                 const size_t count = valid_bp_ids.GetSize();
1025                 for (size_t i = 0; i < count; ++i)
1026                 {
1027                     BreakpointID cur_bp_id = valid_bp_ids.GetBreakpointIDAtIndex (i);
1028 
1029                     if (cur_bp_id.GetBreakpointID() != LLDB_INVALID_BREAK_ID)
1030                     {
1031                         Breakpoint *breakpoint = target->GetBreakpointByID (cur_bp_id.GetBreakpointID()).get();
1032                         if (cur_bp_id.GetLocationID() != LLDB_INVALID_BREAK_ID)
1033                         {
1034                             BreakpointLocation *location = breakpoint->FindLocationByID (cur_bp_id.GetLocationID()).get();
1035                             if (location)
1036                             {
1037                                 location->SetEnabled (true);
1038                                 ++loc_count;
1039                             }
1040                         }
1041                         else
1042                         {
1043                             breakpoint->SetEnabled (true);
1044                             ++enable_count;
1045                         }
1046                     }
1047                 }
1048                 result.AppendMessageWithFormat ("%d breakpoints enabled.\n", enable_count + loc_count);
1049                 result.SetStatus (eReturnStatusSuccessFinishNoResult);
1050             }
1051         }
1052 
1053         return result.Succeeded();
1054     }
1055 };
1056 
1057 //-------------------------------------------------------------------------
1058 // CommandObjectBreakpointDisable
1059 //-------------------------------------------------------------------------
1060 #pragma mark Disable
1061 
1062 class CommandObjectBreakpointDisable : public CommandObjectParsed
1063 {
1064 public:
1065     CommandObjectBreakpointDisable (CommandInterpreter &interpreter) :
1066         CommandObjectParsed (interpreter,
1067                              "breakpoint disable",
1068                              "Disable the specified breakpoint(s) without removing it/them.  If no breakpoints are specified, disable them all.",
1069                              NULL)
1070     {
1071         CommandArgumentEntry arg;
1072         CommandObject::AddIDsArgumentData(arg, eArgTypeBreakpointID, eArgTypeBreakpointIDRange);
1073         // Add the entry for the first argument for this command to the object's arguments vector.
1074         m_arguments.push_back (arg);
1075     }
1076 
1077 
1078     virtual
1079     ~CommandObjectBreakpointDisable () {}
1080 
1081 protected:
1082     virtual bool
1083     DoExecute (Args& command, CommandReturnObject &result)
1084     {
1085         Target *target = m_interpreter.GetDebugger().GetSelectedTarget().get();
1086         if (target == NULL)
1087         {
1088             result.AppendError ("Invalid target.  No existing target or breakpoints.");
1089             result.SetStatus (eReturnStatusFailed);
1090             return false;
1091         }
1092 
1093         Mutex::Locker locker;
1094         target->GetBreakpointList().GetListMutex(locker);
1095 
1096         const BreakpointList &breakpoints = target->GetBreakpointList();
1097         size_t num_breakpoints = breakpoints.GetSize();
1098 
1099         if (num_breakpoints == 0)
1100         {
1101             result.AppendError ("No breakpoints exist to be disabled.");
1102             result.SetStatus (eReturnStatusFailed);
1103             return false;
1104         }
1105 
1106         if (command.GetArgumentCount() == 0)
1107         {
1108             // No breakpoint selected; disable all currently set breakpoints.
1109             target->DisableAllBreakpoints ();
1110             result.AppendMessageWithFormat ("All breakpoints disabled. (%lu breakpoints)\n", num_breakpoints);
1111             result.SetStatus (eReturnStatusSuccessFinishNoResult);
1112         }
1113         else
1114         {
1115             // Particular breakpoint selected; disable that breakpoint.
1116             BreakpointIDList valid_bp_ids;
1117 
1118             CommandObjectMultiwordBreakpoint::VerifyBreakpointIDs (command, target, result, &valid_bp_ids);
1119 
1120             if (result.Succeeded())
1121             {
1122                 int disable_count = 0;
1123                 int loc_count = 0;
1124                 const size_t count = valid_bp_ids.GetSize();
1125                 for (size_t i = 0; i < count; ++i)
1126                 {
1127                     BreakpointID cur_bp_id = valid_bp_ids.GetBreakpointIDAtIndex (i);
1128 
1129                     if (cur_bp_id.GetBreakpointID() != LLDB_INVALID_BREAK_ID)
1130                     {
1131                         Breakpoint *breakpoint = target->GetBreakpointByID (cur_bp_id.GetBreakpointID()).get();
1132                         if (cur_bp_id.GetLocationID() != LLDB_INVALID_BREAK_ID)
1133                         {
1134                             BreakpointLocation *location = breakpoint->FindLocationByID (cur_bp_id.GetLocationID()).get();
1135                             if (location)
1136                             {
1137                                 location->SetEnabled (false);
1138                                 ++loc_count;
1139                             }
1140                         }
1141                         else
1142                         {
1143                             breakpoint->SetEnabled (false);
1144                             ++disable_count;
1145                         }
1146                     }
1147                 }
1148                 result.AppendMessageWithFormat ("%d breakpoints disabled.\n", disable_count + loc_count);
1149                 result.SetStatus (eReturnStatusSuccessFinishNoResult);
1150             }
1151         }
1152 
1153         return result.Succeeded();
1154     }
1155 
1156 };
1157 
1158 //-------------------------------------------------------------------------
1159 // CommandObjectBreakpointList
1160 //-------------------------------------------------------------------------
1161 #pragma mark List
1162 
1163 class CommandObjectBreakpointList : public CommandObjectParsed
1164 {
1165 public:
1166     CommandObjectBreakpointList (CommandInterpreter &interpreter) :
1167         CommandObjectParsed (interpreter,
1168                              "breakpoint list",
1169                              "List some or all breakpoints at configurable levels of detail.",
1170                              NULL),
1171         m_options (interpreter)
1172     {
1173         CommandArgumentEntry arg;
1174         CommandArgumentData bp_id_arg;
1175 
1176         // Define the first (and only) variant of this arg.
1177         bp_id_arg.arg_type = eArgTypeBreakpointID;
1178         bp_id_arg.arg_repetition = eArgRepeatOptional;
1179 
1180         // There is only one variant this argument could be; put it into the argument entry.
1181         arg.push_back (bp_id_arg);
1182 
1183         // Push the data for the first argument into the m_arguments vector.
1184         m_arguments.push_back (arg);
1185     }
1186 
1187 
1188     virtual
1189     ~CommandObjectBreakpointList () {}
1190 
1191     virtual Options *
1192     GetOptions ()
1193     {
1194         return &m_options;
1195     }
1196 
1197     class CommandOptions : public Options
1198     {
1199     public:
1200 
1201         CommandOptions (CommandInterpreter &interpreter) :
1202             Options (interpreter),
1203             m_level (lldb::eDescriptionLevelBrief)  // Breakpoint List defaults to brief descriptions
1204         {
1205         }
1206 
1207         virtual
1208         ~CommandOptions () {}
1209 
1210         virtual Error
1211         SetOptionValue (uint32_t option_idx, const char *option_arg)
1212         {
1213             Error error;
1214             char short_option = (char) m_getopt_table[option_idx].val;
1215 
1216             switch (short_option)
1217             {
1218                 case 'b':
1219                     m_level = lldb::eDescriptionLevelBrief;
1220                     break;
1221                 case 'f':
1222                     m_level = lldb::eDescriptionLevelFull;
1223                     break;
1224                 case 'v':
1225                     m_level = lldb::eDescriptionLevelVerbose;
1226                     break;
1227                 case 'i':
1228                     m_internal = true;
1229                     break;
1230                 default:
1231                     error.SetErrorStringWithFormat ("unrecognized option '%c'", short_option);
1232                     break;
1233             }
1234 
1235             return error;
1236         }
1237 
1238         void
1239         OptionParsingStarting ()
1240         {
1241             m_level = lldb::eDescriptionLevelFull;
1242             m_internal = false;
1243         }
1244 
1245         const OptionDefinition *
1246         GetDefinitions ()
1247         {
1248             return g_option_table;
1249         }
1250 
1251         // Options table: Required for subclasses of Options.
1252 
1253         static OptionDefinition g_option_table[];
1254 
1255         // Instance variables to hold the values for command options.
1256 
1257         lldb::DescriptionLevel m_level;
1258 
1259         bool m_internal;
1260     };
1261 
1262 protected:
1263     virtual bool
1264     DoExecute (Args& command, CommandReturnObject &result)
1265     {
1266         Target *target = m_interpreter.GetDebugger().GetSelectedTarget().get();
1267         if (target == NULL)
1268         {
1269             result.AppendError ("Invalid target. No current target or breakpoints.");
1270             result.SetStatus (eReturnStatusSuccessFinishNoResult);
1271             return true;
1272         }
1273 
1274         const BreakpointList &breakpoints = target->GetBreakpointList(m_options.m_internal);
1275         Mutex::Locker locker;
1276         target->GetBreakpointList(m_options.m_internal).GetListMutex(locker);
1277 
1278         size_t num_breakpoints = breakpoints.GetSize();
1279 
1280         if (num_breakpoints == 0)
1281         {
1282             result.AppendMessage ("No breakpoints currently set.");
1283             result.SetStatus (eReturnStatusSuccessFinishNoResult);
1284             return true;
1285         }
1286 
1287         Stream &output_stream = result.GetOutputStream();
1288 
1289         if (command.GetArgumentCount() == 0)
1290         {
1291             // No breakpoint selected; show info about all currently set breakpoints.
1292             result.AppendMessage ("Current breakpoints:");
1293             for (size_t i = 0; i < num_breakpoints; ++i)
1294             {
1295                 Breakpoint *breakpoint = breakpoints.GetBreakpointAtIndex (i).get();
1296                 AddBreakpointDescription (&output_stream, breakpoint, m_options.m_level);
1297             }
1298             result.SetStatus (eReturnStatusSuccessFinishNoResult);
1299         }
1300         else
1301         {
1302             // Particular breakpoints selected; show info about that breakpoint.
1303             BreakpointIDList valid_bp_ids;
1304             CommandObjectMultiwordBreakpoint::VerifyBreakpointIDs (command, target, result, &valid_bp_ids);
1305 
1306             if (result.Succeeded())
1307             {
1308                 for (size_t i = 0; i < valid_bp_ids.GetSize(); ++i)
1309                 {
1310                     BreakpointID cur_bp_id = valid_bp_ids.GetBreakpointIDAtIndex (i);
1311                     Breakpoint *breakpoint = target->GetBreakpointByID (cur_bp_id.GetBreakpointID()).get();
1312                     AddBreakpointDescription (&output_stream, breakpoint, m_options.m_level);
1313                 }
1314                 result.SetStatus (eReturnStatusSuccessFinishNoResult);
1315             }
1316             else
1317             {
1318                 result.AppendError ("Invalid breakpoint id.");
1319                 result.SetStatus (eReturnStatusFailed);
1320             }
1321         }
1322 
1323         return result.Succeeded();
1324     }
1325 
1326 private:
1327     CommandOptions m_options;
1328 };
1329 
1330 #pragma mark List::CommandOptions
1331 OptionDefinition
1332 CommandObjectBreakpointList::CommandOptions::g_option_table[] =
1333 {
1334     { LLDB_OPT_SET_ALL, false, "internal", 'i', no_argument, NULL, 0, eArgTypeNone,
1335         "Show debugger internal breakpoints" },
1336 
1337     { LLDB_OPT_SET_1, false, "brief",    'b', no_argument, NULL, 0, eArgTypeNone,
1338         "Give a brief description of the breakpoint (no location info)."},
1339 
1340     // FIXME: We need to add an "internal" command, and then add this sort of thing to it.
1341     // But I need to see it for now, and don't want to wait.
1342     { LLDB_OPT_SET_2, false, "full",    'f', no_argument, NULL, 0, eArgTypeNone,
1343         "Give a full description of the breakpoint and its locations."},
1344 
1345     { LLDB_OPT_SET_3, false, "verbose", 'v', no_argument, NULL, 0, eArgTypeNone,
1346         "Explain everything we know about the breakpoint (for debugging debugger bugs)." },
1347 
1348     { 0, false, NULL, 0, 0, NULL, 0, eArgTypeNone, NULL }
1349 };
1350 
1351 //-------------------------------------------------------------------------
1352 // CommandObjectBreakpointClear
1353 //-------------------------------------------------------------------------
1354 #pragma mark Clear
1355 
1356 class CommandObjectBreakpointClear : public CommandObjectParsed
1357 {
1358 public:
1359 
1360     typedef enum BreakpointClearType
1361     {
1362         eClearTypeInvalid,
1363         eClearTypeFileAndLine
1364     } BreakpointClearType;
1365 
1366     CommandObjectBreakpointClear (CommandInterpreter &interpreter) :
1367         CommandObjectParsed (interpreter,
1368                              "breakpoint clear",
1369                              "Clears a breakpoint or set of breakpoints in the executable.",
1370                              "breakpoint clear <cmd-options>"),
1371         m_options (interpreter)
1372     {
1373     }
1374 
1375     virtual
1376     ~CommandObjectBreakpointClear () {}
1377 
1378     virtual Options *
1379     GetOptions ()
1380     {
1381         return &m_options;
1382     }
1383 
1384     class CommandOptions : public Options
1385     {
1386     public:
1387 
1388         CommandOptions (CommandInterpreter &interpreter) :
1389             Options (interpreter),
1390             m_filename (),
1391             m_line_num (0)
1392         {
1393         }
1394 
1395         virtual
1396         ~CommandOptions () {}
1397 
1398         virtual Error
1399         SetOptionValue (uint32_t option_idx, const char *option_arg)
1400         {
1401             Error error;
1402             char short_option = (char) m_getopt_table[option_idx].val;
1403 
1404             switch (short_option)
1405             {
1406                 case 'f':
1407                     m_filename.assign (option_arg);
1408                     break;
1409 
1410                 case 'l':
1411                     m_line_num = Args::StringToUInt32 (option_arg, 0);
1412                     break;
1413 
1414                 default:
1415                     error.SetErrorStringWithFormat ("unrecognized option '%c'", short_option);
1416                     break;
1417             }
1418 
1419             return error;
1420         }
1421 
1422         void
1423         OptionParsingStarting ()
1424         {
1425             m_filename.clear();
1426             m_line_num = 0;
1427         }
1428 
1429         const OptionDefinition*
1430         GetDefinitions ()
1431         {
1432             return g_option_table;
1433         }
1434 
1435         // Options table: Required for subclasses of Options.
1436 
1437         static OptionDefinition g_option_table[];
1438 
1439         // Instance variables to hold the values for command options.
1440 
1441         std::string m_filename;
1442         uint32_t m_line_num;
1443 
1444     };
1445 
1446 protected:
1447     virtual bool
1448     DoExecute (Args& command, CommandReturnObject &result)
1449     {
1450         Target *target = m_interpreter.GetDebugger().GetSelectedTarget().get();
1451         if (target == NULL)
1452         {
1453             result.AppendError ("Invalid target. No existing target or breakpoints.");
1454             result.SetStatus (eReturnStatusFailed);
1455             return false;
1456         }
1457 
1458         // The following are the various types of breakpoints that could be cleared:
1459         //   1). -f -l (clearing breakpoint by source location)
1460 
1461         BreakpointClearType break_type = eClearTypeInvalid;
1462 
1463         if (m_options.m_line_num != 0)
1464             break_type = eClearTypeFileAndLine;
1465 
1466         Mutex::Locker locker;
1467         target->GetBreakpointList().GetListMutex(locker);
1468 
1469         BreakpointList &breakpoints = target->GetBreakpointList();
1470         size_t num_breakpoints = breakpoints.GetSize();
1471 
1472         // Early return if there's no breakpoint at all.
1473         if (num_breakpoints == 0)
1474         {
1475             result.AppendError ("Breakpoint clear: No breakpoint cleared.");
1476             result.SetStatus (eReturnStatusFailed);
1477             return result.Succeeded();
1478         }
1479 
1480         // Find matching breakpoints and delete them.
1481 
1482         // First create a copy of all the IDs.
1483         std::vector<break_id_t> BreakIDs;
1484         for (size_t i = 0; i < num_breakpoints; ++i)
1485             BreakIDs.push_back(breakpoints.GetBreakpointAtIndex(i).get()->GetID());
1486 
1487         int num_cleared = 0;
1488         StreamString ss;
1489         switch (break_type)
1490         {
1491             case eClearTypeFileAndLine: // Breakpoint by source position
1492                 {
1493                     const ConstString filename(m_options.m_filename.c_str());
1494                     BreakpointLocationCollection loc_coll;
1495 
1496                     for (size_t i = 0; i < num_breakpoints; ++i)
1497                     {
1498                         Breakpoint *bp = breakpoints.FindBreakpointByID(BreakIDs[i]).get();
1499 
1500                         if (bp->GetMatchingFileLine(filename, m_options.m_line_num, loc_coll))
1501                         {
1502                             // If the collection size is 0, it's a full match and we can just remove the breakpoint.
1503                             if (loc_coll.GetSize() == 0)
1504                             {
1505                                 bp->GetDescription(&ss, lldb::eDescriptionLevelBrief);
1506                                 ss.EOL();
1507                                 target->RemoveBreakpointByID (bp->GetID());
1508                                 ++num_cleared;
1509                             }
1510                         }
1511                     }
1512                 }
1513                 break;
1514 
1515             default:
1516                 break;
1517         }
1518 
1519         if (num_cleared > 0)
1520         {
1521             Stream &output_stream = result.GetOutputStream();
1522             output_stream.Printf ("%d breakpoints cleared:\n", num_cleared);
1523             output_stream << ss.GetData();
1524             output_stream.EOL();
1525             result.SetStatus (eReturnStatusSuccessFinishNoResult);
1526         }
1527         else
1528         {
1529             result.AppendError ("Breakpoint clear: No breakpoint cleared.");
1530             result.SetStatus (eReturnStatusFailed);
1531         }
1532 
1533         return result.Succeeded();
1534     }
1535 
1536 private:
1537     CommandOptions m_options;
1538 };
1539 
1540 #pragma mark Clear::CommandOptions
1541 
1542 OptionDefinition
1543 CommandObjectBreakpointClear::CommandOptions::g_option_table[] =
1544 {
1545     { LLDB_OPT_SET_1, false, "file", 'f', required_argument, NULL, CommandCompletions::eSourceFileCompletion, eArgTypeFilename,
1546         "Specify the breakpoint by source location in this particular file."},
1547 
1548     { LLDB_OPT_SET_1, true, "line", 'l', required_argument, NULL, 0, eArgTypeLineNum,
1549         "Specify the breakpoint by source location at this particular line."},
1550 
1551     { 0, false, NULL, 0, 0, NULL, 0, eArgTypeNone, NULL }
1552 };
1553 
1554 //-------------------------------------------------------------------------
1555 // CommandObjectBreakpointDelete
1556 //-------------------------------------------------------------------------
1557 #pragma mark Delete
1558 
1559 class CommandObjectBreakpointDelete : public CommandObjectParsed
1560 {
1561 public:
1562     CommandObjectBreakpointDelete (CommandInterpreter &interpreter) :
1563         CommandObjectParsed (interpreter,
1564                              "breakpoint delete",
1565                              "Delete the specified breakpoint(s).  If no breakpoints are specified, delete them all.",
1566                              NULL)
1567     {
1568         CommandArgumentEntry arg;
1569         CommandObject::AddIDsArgumentData(arg, eArgTypeBreakpointID, eArgTypeBreakpointIDRange);
1570         // Add the entry for the first argument for this command to the object's arguments vector.
1571         m_arguments.push_back (arg);
1572     }
1573 
1574     virtual
1575     ~CommandObjectBreakpointDelete () {}
1576 
1577 protected:
1578     virtual bool
1579     DoExecute (Args& command, CommandReturnObject &result)
1580     {
1581         Target *target = m_interpreter.GetDebugger().GetSelectedTarget().get();
1582         if (target == NULL)
1583         {
1584             result.AppendError ("Invalid target. No existing target or breakpoints.");
1585             result.SetStatus (eReturnStatusFailed);
1586             return false;
1587         }
1588 
1589         Mutex::Locker locker;
1590         target->GetBreakpointList().GetListMutex(locker);
1591 
1592         const BreakpointList &breakpoints = target->GetBreakpointList();
1593 
1594         size_t num_breakpoints = breakpoints.GetSize();
1595 
1596         if (num_breakpoints == 0)
1597         {
1598             result.AppendError ("No breakpoints exist to be deleted.");
1599             result.SetStatus (eReturnStatusFailed);
1600             return false;
1601         }
1602 
1603         if (command.GetArgumentCount() == 0)
1604         {
1605             if (!m_interpreter.Confirm ("About to delete all breakpoints, do you want to do that?", true))
1606             {
1607                 result.AppendMessage("Operation cancelled...");
1608             }
1609             else
1610             {
1611                 target->RemoveAllBreakpoints ();
1612                 result.AppendMessageWithFormat ("All breakpoints removed. (%lu breakpoints)\n", num_breakpoints);
1613             }
1614             result.SetStatus (eReturnStatusSuccessFinishNoResult);
1615         }
1616         else
1617         {
1618             // Particular breakpoint selected; disable that breakpoint.
1619             BreakpointIDList valid_bp_ids;
1620             CommandObjectMultiwordBreakpoint::VerifyBreakpointIDs (command, target, result, &valid_bp_ids);
1621 
1622             if (result.Succeeded())
1623             {
1624                 int delete_count = 0;
1625                 int disable_count = 0;
1626                 const size_t count = valid_bp_ids.GetSize();
1627                 for (size_t i = 0; i < count; ++i)
1628                 {
1629                     BreakpointID cur_bp_id = valid_bp_ids.GetBreakpointIDAtIndex (i);
1630 
1631                     if (cur_bp_id.GetBreakpointID() != LLDB_INVALID_BREAK_ID)
1632                     {
1633                         if (cur_bp_id.GetLocationID() != LLDB_INVALID_BREAK_ID)
1634                         {
1635                             Breakpoint *breakpoint = target->GetBreakpointByID (cur_bp_id.GetBreakpointID()).get();
1636                             BreakpointLocation *location = breakpoint->FindLocationByID (cur_bp_id.GetLocationID()).get();
1637                             // It makes no sense to try to delete individual locations, so we disable them instead.
1638                             if (location)
1639                             {
1640                                 location->SetEnabled (false);
1641                                 ++disable_count;
1642                             }
1643                         }
1644                         else
1645                         {
1646                             target->RemoveBreakpointByID (cur_bp_id.GetBreakpointID());
1647                             ++delete_count;
1648                         }
1649                     }
1650                 }
1651                 result.AppendMessageWithFormat ("%d breakpoints deleted; %d breakpoint locations disabled.\n",
1652                                                delete_count, disable_count);
1653                 result.SetStatus (eReturnStatusSuccessFinishNoResult);
1654             }
1655         }
1656         return result.Succeeded();
1657     }
1658 };
1659 
1660 //-------------------------------------------------------------------------
1661 // CommandObjectMultiwordBreakpoint
1662 //-------------------------------------------------------------------------
1663 #pragma mark MultiwordBreakpoint
1664 
1665 CommandObjectMultiwordBreakpoint::CommandObjectMultiwordBreakpoint (CommandInterpreter &interpreter) :
1666     CommandObjectMultiword (interpreter,
1667                             "breakpoint",
1668                             "A set of commands for operating on breakpoints. Also see _regexp-break.",
1669                             "breakpoint <command> [<command-options>]")
1670 {
1671     CommandObjectSP list_command_object (new CommandObjectBreakpointList (interpreter));
1672     CommandObjectSP enable_command_object (new CommandObjectBreakpointEnable (interpreter));
1673     CommandObjectSP disable_command_object (new CommandObjectBreakpointDisable (interpreter));
1674     CommandObjectSP clear_command_object (new CommandObjectBreakpointClear (interpreter));
1675     CommandObjectSP delete_command_object (new CommandObjectBreakpointDelete (interpreter));
1676     CommandObjectSP set_command_object (new CommandObjectBreakpointSet (interpreter));
1677     CommandObjectSP command_command_object (new CommandObjectBreakpointCommand (interpreter));
1678     CommandObjectSP modify_command_object (new CommandObjectBreakpointModify(interpreter));
1679 
1680     list_command_object->SetCommandName ("breakpoint list");
1681     enable_command_object->SetCommandName("breakpoint enable");
1682     disable_command_object->SetCommandName("breakpoint disable");
1683     clear_command_object->SetCommandName("breakpoint clear");
1684     delete_command_object->SetCommandName("breakpoint delete");
1685     set_command_object->SetCommandName("breakpoint set");
1686     command_command_object->SetCommandName ("breakpoint command");
1687     modify_command_object->SetCommandName ("breakpoint modify");
1688 
1689     LoadSubCommand ("list",       list_command_object);
1690     LoadSubCommand ("enable",     enable_command_object);
1691     LoadSubCommand ("disable",    disable_command_object);
1692     LoadSubCommand ("clear",      clear_command_object);
1693     LoadSubCommand ("delete",     delete_command_object);
1694     LoadSubCommand ("set",        set_command_object);
1695     LoadSubCommand ("command",    command_command_object);
1696     LoadSubCommand ("modify",     modify_command_object);
1697 }
1698 
1699 CommandObjectMultiwordBreakpoint::~CommandObjectMultiwordBreakpoint ()
1700 {
1701 }
1702 
1703 void
1704 CommandObjectMultiwordBreakpoint::VerifyBreakpointIDs (Args &args, Target *target, CommandReturnObject &result,
1705                                                          BreakpointIDList *valid_ids)
1706 {
1707     // args can be strings representing 1). integers (for breakpoint ids)
1708     //                                  2). the full breakpoint & location canonical representation
1709     //                                  3). the word "to" or a hyphen, representing a range (in which case there
1710     //                                      had *better* be an entry both before & after of one of the first two types.
1711     // If args is empty, we will use the last created breakpoint (if there is one.)
1712 
1713     Args temp_args;
1714 
1715     if (args.GetArgumentCount() == 0)
1716     {
1717         if (target->GetLastCreatedBreakpoint())
1718         {
1719             valid_ids->AddBreakpointID (BreakpointID(target->GetLastCreatedBreakpoint()->GetID(), LLDB_INVALID_BREAK_ID));
1720             result.SetStatus (eReturnStatusSuccessFinishNoResult);
1721         }
1722         else
1723         {
1724             result.AppendError("No breakpoint specified and no last created breakpoint.");
1725             result.SetStatus (eReturnStatusFailed);
1726         }
1727         return;
1728     }
1729 
1730     // Create a new Args variable to use; copy any non-breakpoint-id-ranges stuff directly from the old ARGS to
1731     // the new TEMP_ARGS.  Do not copy breakpoint id range strings over; instead generate a list of strings for
1732     // all the breakpoint ids in the range, and shove all of those breakpoint id strings into TEMP_ARGS.
1733 
1734     BreakpointIDList::FindAndReplaceIDRanges (args, target, result, temp_args);
1735 
1736     // NOW, convert the list of breakpoint id strings in TEMP_ARGS into an actual BreakpointIDList:
1737 
1738     valid_ids->InsertStringArray (temp_args.GetConstArgumentVector(), temp_args.GetArgumentCount(), result);
1739 
1740     // At this point,  all of the breakpoint ids that the user passed in have been converted to breakpoint IDs
1741     // and put into valid_ids.
1742 
1743     if (result.Succeeded())
1744     {
1745         // Now that we've converted everything from args into a list of breakpoint ids, go through our tentative list
1746         // of breakpoint id's and verify that they correspond to valid/currently set breakpoints.
1747 
1748         const size_t count = valid_ids->GetSize();
1749         for (size_t i = 0; i < count; ++i)
1750         {
1751             BreakpointID cur_bp_id = valid_ids->GetBreakpointIDAtIndex (i);
1752             Breakpoint *breakpoint = target->GetBreakpointByID (cur_bp_id.GetBreakpointID()).get();
1753             if (breakpoint != NULL)
1754             {
1755                 int num_locations = breakpoint->GetNumLocations();
1756                 if (cur_bp_id.GetLocationID() > num_locations)
1757                 {
1758                     StreamString id_str;
1759                     BreakpointID::GetCanonicalReference (&id_str,
1760                                                          cur_bp_id.GetBreakpointID(),
1761                                                          cur_bp_id.GetLocationID());
1762                     i = valid_ids->GetSize() + 1;
1763                     result.AppendErrorWithFormat ("'%s' is not a currently valid breakpoint/location id.\n",
1764                                                  id_str.GetData());
1765                     result.SetStatus (eReturnStatusFailed);
1766                 }
1767             }
1768             else
1769             {
1770                 i = valid_ids->GetSize() + 1;
1771                 result.AppendErrorWithFormat ("'%d' is not a currently valid breakpoint id.\n", cur_bp_id.GetBreakpointID());
1772                 result.SetStatus (eReturnStatusFailed);
1773             }
1774         }
1775     }
1776 }
1777