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