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             output_stream.Printf ("Breakpoint created: ");
520             bp->GetDescription(&output_stream, lldb::eDescriptionLevelBrief);
521             output_stream.EOL();
522             // Don't print out this warning for exception breakpoints.  They can get set before the target
523             // is set, but we won't know how to actually set the breakpoint till we run.
524             if (bp->GetNumLocations() == 0 && break_type != eSetTypeException)
525                 output_stream.Printf ("WARNING:  Unable to resolve breakpoint to any actual locations.\n");
526             result.SetStatus (eReturnStatusSuccessFinishResult);
527         }
528         else if (!bp)
529         {
530             result.AppendError ("Breakpoint creation failed: No breakpoint created.");
531             result.SetStatus (eReturnStatusFailed);
532         }
533 
534         return result.Succeeded();
535     }
536 
537 private:
538     bool
539     GetDefaultFile (Target *target, FileSpec &file, CommandReturnObject &result)
540     {
541         uint32_t default_line;
542         // First use the Source Manager's default file.
543         // Then use the current stack frame's file.
544         if (!target->GetSourceManager().GetDefaultFileAndLine(file, default_line))
545         {
546             StackFrame *cur_frame = m_interpreter.GetExecutionContext().GetFramePtr();
547             if (cur_frame == NULL)
548             {
549                 result.AppendError ("No selected frame to use to find the default file.");
550                 result.SetStatus (eReturnStatusFailed);
551                 return false;
552             }
553             else if (!cur_frame->HasDebugInformation())
554             {
555                 result.AppendError ("Cannot use the selected frame to find the default file, it has no debug info.");
556                 result.SetStatus (eReturnStatusFailed);
557                 return false;
558             }
559             else
560             {
561                 const SymbolContext &sc = cur_frame->GetSymbolContext (eSymbolContextLineEntry);
562                 if (sc.line_entry.file)
563                 {
564                     file = sc.line_entry.file;
565                 }
566                 else
567                 {
568                     result.AppendError ("Can't find the file for the selected frame to use as the default file.");
569                     result.SetStatus (eReturnStatusFailed);
570                     return false;
571                 }
572             }
573         }
574         return true;
575     }
576 
577     CommandOptions m_options;
578 };
579 // If an additional option set beyond LLDB_OPTION_SET_10 is added, make sure to
580 // update the numbers passed to LLDB_OPT_SET_FROM_TO(...) appropriately.
581 #define LLDB_OPT_FILE ( LLDB_OPT_SET_FROM_TO(1, 9) & ~LLDB_OPT_SET_2 )
582 #define LLDB_OPT_NOT_10 ( LLDB_OPT_SET_FROM_TO(1, 10) & ~LLDB_OPT_SET_10 )
583 #define LLDB_OPT_SKIP_PROLOGUE ( LLDB_OPT_SET_1 | LLDB_OPT_SET_FROM_TO(3,8) )
584 
585 OptionDefinition
586 CommandObjectBreakpointSet::CommandOptions::g_option_table[] =
587 {
588     { LLDB_OPT_NOT_10, false, "shlib", 's', required_argument, NULL, CommandCompletions::eModuleCompletion, eArgTypeShlibName,
589         "Set the breakpoint only in this shared library.  "
590         "Can repeat this option multiple times to specify multiple shared libraries."},
591 
592     { LLDB_OPT_SET_ALL, false, "ignore-count", 'i', required_argument,   NULL, 0, eArgTypeCount,
593         "Set the number of times this breakpoint is skipped before stopping." },
594 
595     { LLDB_OPT_SET_ALL, false, "condition",    'c', required_argument, NULL, 0, eArgTypeExpression,
596         "The breakpoint stops only if this condition expression evaluates to true."},
597 
598     { LLDB_OPT_SET_ALL, false, "thread-index", 'x', required_argument, NULL, 0, eArgTypeThreadIndex,
599         "The breakpoint stops only for the thread whose index matches this argument."},
600 
601     { LLDB_OPT_SET_ALL, false, "thread-id", 't', required_argument, NULL, 0, eArgTypeThreadID,
602         "The breakpoint stops only for the thread whose TID matches this argument."},
603 
604     { LLDB_OPT_SET_ALL, false, "thread-name", 'T', required_argument, NULL, 0, eArgTypeThreadName,
605         "The breakpoint stops only for the thread whose thread name matches this argument."},
606 
607     { LLDB_OPT_SET_ALL, false, "queue-name", 'q', required_argument, NULL, 0, eArgTypeQueueName,
608         "The breakpoint stops only for threads in the queue whose name is given by this argument."},
609 
610     { LLDB_OPT_FILE, false, "file", 'f', required_argument, NULL, CommandCompletions::eSourceFileCompletion, eArgTypeFilename,
611         "Specifies the source file in which to set this breakpoint."},
612 
613     { LLDB_OPT_SET_1, true, "line", 'l', required_argument, NULL, 0, eArgTypeLineNum,
614         "Specifies the line number on which to set this breakpoint."},
615 
616     // Comment out this option for the moment, as we don't actually use it, but will in the future.
617     // This way users won't see it, but the infrastructure is left in place.
618     //    { 0, false, "column",     'C', required_argument, NULL, "<column>",
619     //    "Set the breakpoint by source location at this particular column."},
620 
621     { LLDB_OPT_SET_2, true, "address", 'a', required_argument, NULL, 0, eArgTypeAddress,
622         "Set the breakpoint by address, at the specified address."},
623 
624     { LLDB_OPT_SET_3, true, "name", 'n', required_argument, NULL, CommandCompletions::eSymbolCompletion, eArgTypeFunctionName,
625         "Set the breakpoint by function name.  Can be repeated multiple times to make one breakpoint for multiple snames" },
626 
627     { LLDB_OPT_SET_4, true, "fullname", 'F', required_argument, NULL, CommandCompletions::eSymbolCompletion, eArgTypeFullName,
628         "Set the breakpoint by fully qualified function names. For C++ this means namespaces and all arguments, and "
629         "for Objective C this means a full function prototype with class and selector.   "
630         "Can be repeated multiple times to make one breakpoint for multiple names." },
631 
632     { LLDB_OPT_SET_5, true, "selector", 'S', required_argument, NULL, 0, eArgTypeSelector,
633         "Set the breakpoint by ObjC selector name. Can be repeated multiple times to make one breakpoint for multiple Selectors." },
634 
635     { LLDB_OPT_SET_6, true, "method", 'M', required_argument, NULL, 0, eArgTypeMethod,
636         "Set the breakpoint by C++ method names.  Can be repeated multiple times to make one breakpoint for multiple methods." },
637 
638     { LLDB_OPT_SET_7, true, "func-regex", 'r', required_argument, NULL, 0, eArgTypeRegularExpression,
639         "Set the breakpoint by function name, evaluating a regular-expression to find the function name(s)." },
640 
641     { LLDB_OPT_SET_8, true, "basename", 'b', required_argument, NULL, CommandCompletions::eSymbolCompletion, eArgTypeFunctionName,
642         "Set the breakpoint by function basename (C++ namespaces and arguments will be ignored). "
643         "Can be repeated multiple times to make one breakpoint for multiple symbols." },
644 
645     { LLDB_OPT_SET_9, true, "source-pattern-regexp", 'p', required_argument, NULL, 0, eArgTypeRegularExpression,
646         "Set the breakpoint specifying a regular expression to match a pattern in the source text in a given source file." },
647 
648     { LLDB_OPT_SET_10, true, "language-exception", 'E', required_argument, NULL, 0, eArgTypeLanguage,
649         "Set the breakpoint on exceptions thrown by the specified language (without options, on throw but not catch.)" },
650 
651     { LLDB_OPT_SET_10, false, "on-throw", 'w', required_argument, NULL, 0, eArgTypeBoolean,
652         "Set the breakpoint on exception throW." },
653 
654     { LLDB_OPT_SET_10, false, "on-catch", 'h', required_argument, NULL, 0, eArgTypeBoolean,
655         "Set the breakpoint on exception catcH." },
656 
657     { LLDB_OPT_SKIP_PROLOGUE, false, "skip-prologue", 'K', required_argument, NULL, 0, eArgTypeBoolean,
658         "sKip the prologue if the breakpoint is at the beginning of a function.  If not set the target.skip-prologue setting is used." },
659 
660     { 0, false, NULL, 0, 0, NULL, 0, eArgTypeNone, NULL }
661 };
662 
663 //-------------------------------------------------------------------------
664 // CommandObjectBreakpointModify
665 //-------------------------------------------------------------------------
666 #pragma mark Modify
667 
668 class CommandObjectBreakpointModify : public CommandObjectParsed
669 {
670 public:
671 
672     CommandObjectBreakpointModify (CommandInterpreter &interpreter) :
673         CommandObjectParsed (interpreter,
674                              "breakpoint modify",
675                              "Modify the options on a breakpoint or set of breakpoints in the executable.  "
676                              "If no breakpoint is specified, acts on the last created breakpoint.  "
677                              "With the exception of -e, -d and -i, passing an empty argument clears the modification.",
678                              NULL),
679         m_options (interpreter)
680     {
681         CommandArgumentEntry arg;
682         CommandObject::AddIDsArgumentData(arg, eArgTypeBreakpointID, eArgTypeBreakpointIDRange);
683         // Add the entry for the first argument for this command to the object's arguments vector.
684         m_arguments.push_back (arg);
685     }
686 
687 
688     virtual
689     ~CommandObjectBreakpointModify () {}
690 
691     virtual Options *
692     GetOptions ()
693     {
694         return &m_options;
695     }
696 
697     class CommandOptions : public Options
698     {
699     public:
700 
701         CommandOptions (CommandInterpreter &interpreter) :
702             Options (interpreter),
703             m_ignore_count (0),
704             m_thread_id(LLDB_INVALID_THREAD_ID),
705             m_thread_id_passed(false),
706             m_thread_index (UINT32_MAX),
707             m_thread_index_passed(false),
708             m_thread_name(),
709             m_queue_name(),
710             m_condition (),
711             m_enable_passed (false),
712             m_enable_value (false),
713             m_name_passed (false),
714             m_queue_passed (false),
715             m_condition_passed (false)
716         {
717         }
718 
719         virtual
720         ~CommandOptions () {}
721 
722         virtual Error
723         SetOptionValue (uint32_t option_idx, const char *option_arg)
724         {
725             Error error;
726             char short_option = (char) m_getopt_table[option_idx].val;
727 
728             switch (short_option)
729             {
730                 case 'c':
731                     if (option_arg != NULL)
732                         m_condition.assign (option_arg);
733                     else
734                         m_condition.clear();
735                     m_condition_passed = true;
736                     break;
737                 case 'd':
738                     m_enable_passed = true;
739                     m_enable_value = false;
740                     break;
741                 case 'e':
742                     m_enable_passed = true;
743                     m_enable_value = true;
744                     break;
745                 case 'i':
746                 {
747                     m_ignore_count = Args::StringToUInt32(option_arg, UINT32_MAX, 0);
748                     if (m_ignore_count == UINT32_MAX)
749                        error.SetErrorStringWithFormat ("invalid ignore count '%s'", option_arg);
750                 }
751                 break;
752                 case 't' :
753                 {
754                     if (option_arg[0] == '\0')
755                     {
756                         m_thread_id = LLDB_INVALID_THREAD_ID;
757                         m_thread_id_passed = true;
758                     }
759                     else
760                     {
761                         m_thread_id = Args::StringToUInt64(option_arg, LLDB_INVALID_THREAD_ID, 0);
762                         if (m_thread_id == LLDB_INVALID_THREAD_ID)
763                            error.SetErrorStringWithFormat ("invalid thread id string '%s'", option_arg);
764                         else
765                             m_thread_id_passed = true;
766                     }
767                 }
768                 break;
769                 case 'T':
770                     if (option_arg != NULL)
771                         m_thread_name.assign (option_arg);
772                     else
773                         m_thread_name.clear();
774                     m_name_passed = true;
775                     break;
776                 case 'q':
777                     if (option_arg != NULL)
778                         m_queue_name.assign (option_arg);
779                     else
780                         m_queue_name.clear();
781                     m_queue_passed = true;
782                     break;
783                 case 'x':
784                 {
785                     if (option_arg[0] == '\n')
786                     {
787                         m_thread_index = UINT32_MAX;
788                         m_thread_index_passed = true;
789                     }
790                     else
791                     {
792                         m_thread_index = Args::StringToUInt32 (option_arg, UINT32_MAX, 0);
793                         if (m_thread_id == UINT32_MAX)
794                            error.SetErrorStringWithFormat ("invalid thread index string '%s'", option_arg);
795                         else
796                             m_thread_index_passed = true;
797                     }
798                 }
799                 break;
800                 default:
801                     error.SetErrorStringWithFormat ("unrecognized option '%c'", short_option);
802                     break;
803             }
804 
805             return error;
806         }
807         void
808         OptionParsingStarting ()
809         {
810             m_ignore_count = 0;
811             m_thread_id = LLDB_INVALID_THREAD_ID;
812             m_thread_id_passed = false;
813             m_thread_index = UINT32_MAX;
814             m_thread_index_passed = false;
815             m_thread_name.clear();
816             m_queue_name.clear();
817             m_condition.clear();
818             m_enable_passed = false;
819             m_queue_passed = false;
820             m_name_passed = false;
821             m_condition_passed = false;
822         }
823 
824         const OptionDefinition*
825         GetDefinitions ()
826         {
827             return g_option_table;
828         }
829 
830 
831         // Options table: Required for subclasses of Options.
832 
833         static OptionDefinition g_option_table[];
834 
835         // Instance variables to hold the values for command options.
836 
837         uint32_t m_ignore_count;
838         lldb::tid_t m_thread_id;
839         bool m_thread_id_passed;
840         uint32_t m_thread_index;
841         bool m_thread_index_passed;
842         std::string m_thread_name;
843         std::string m_queue_name;
844         std::string m_condition;
845         bool m_enable_passed;
846         bool m_enable_value;
847         bool m_name_passed;
848         bool m_queue_passed;
849         bool m_condition_passed;
850 
851     };
852 
853 protected:
854     virtual bool
855     DoExecute (Args& command, CommandReturnObject &result)
856     {
857         Target *target = m_interpreter.GetDebugger().GetSelectedTarget().get();
858         if (target == NULL)
859         {
860             result.AppendError ("Invalid target.  No existing target or breakpoints.");
861             result.SetStatus (eReturnStatusFailed);
862             return false;
863         }
864 
865         Mutex::Locker locker;
866         target->GetBreakpointList().GetListMutex(locker);
867 
868         BreakpointIDList valid_bp_ids;
869 
870         CommandObjectMultiwordBreakpoint::VerifyBreakpointIDs (command, target, result, &valid_bp_ids);
871 
872         if (result.Succeeded())
873         {
874             const size_t count = valid_bp_ids.GetSize();
875             for (size_t i = 0; i < count; ++i)
876             {
877                 BreakpointID cur_bp_id = valid_bp_ids.GetBreakpointIDAtIndex (i);
878 
879                 if (cur_bp_id.GetBreakpointID() != LLDB_INVALID_BREAK_ID)
880                 {
881                     Breakpoint *bp = target->GetBreakpointByID (cur_bp_id.GetBreakpointID()).get();
882                     if (cur_bp_id.GetLocationID() != LLDB_INVALID_BREAK_ID)
883                     {
884                         BreakpointLocation *location = bp->FindLocationByID (cur_bp_id.GetLocationID()).get();
885                         if (location)
886                         {
887                             if (m_options.m_thread_id_passed)
888                                 location->SetThreadID (m_options.m_thread_id);
889 
890                             if (m_options.m_thread_index_passed)
891                                 location->SetThreadIndex(m_options.m_thread_index);
892 
893                             if (m_options.m_name_passed)
894                                 location->SetThreadName(m_options.m_thread_name.c_str());
895 
896                             if (m_options.m_queue_passed)
897                                 location->SetQueueName(m_options.m_queue_name.c_str());
898 
899                             if (m_options.m_ignore_count != 0)
900                                 location->SetIgnoreCount(m_options.m_ignore_count);
901 
902                             if (m_options.m_enable_passed)
903                                 location->SetEnabled (m_options.m_enable_value);
904 
905                             if (m_options.m_condition_passed)
906                                 location->SetCondition (m_options.m_condition.c_str());
907                         }
908                     }
909                     else
910                     {
911                         if (m_options.m_thread_id_passed)
912                             bp->SetThreadID (m_options.m_thread_id);
913 
914                         if (m_options.m_thread_index_passed)
915                             bp->SetThreadIndex(m_options.m_thread_index);
916 
917                         if (m_options.m_name_passed)
918                             bp->SetThreadName(m_options.m_thread_name.c_str());
919 
920                         if (m_options.m_queue_passed)
921                             bp->SetQueueName(m_options.m_queue_name.c_str());
922 
923                         if (m_options.m_ignore_count != 0)
924                             bp->SetIgnoreCount(m_options.m_ignore_count);
925 
926                         if (m_options.m_enable_passed)
927                             bp->SetEnabled (m_options.m_enable_value);
928 
929                         if (m_options.m_condition_passed)
930                             bp->SetCondition (m_options.m_condition.c_str());
931                     }
932                 }
933             }
934         }
935 
936         return result.Succeeded();
937     }
938 
939 private:
940     CommandOptions m_options;
941 };
942 
943 #pragma mark Modify::CommandOptions
944 OptionDefinition
945 CommandObjectBreakpointModify::CommandOptions::g_option_table[] =
946 {
947 { LLDB_OPT_SET_ALL, false, "ignore-count", 'i', required_argument, NULL, 0, eArgTypeCount, "Set the number of times this breakpoint is skipped before stopping." },
948 { 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."},
949 { 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."},
950 { 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."},
951 { 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."},
952 { LLDB_OPT_SET_ALL, false, "condition",    'c', required_argument, NULL, 0, eArgTypeExpression, "The breakpoint stops only if this condition expression evaluates to true."},
953 { LLDB_OPT_SET_1,   false, "enable",       'e', no_argument,       NULL, 0, eArgTypeNone, "Enable the breakpoint."},
954 { LLDB_OPT_SET_2,   false, "disable",      'd', no_argument,       NULL, 0, eArgTypeNone, "Disable the breakpoint."},
955 { 0,                false, NULL,            0 , 0,                 NULL, 0,    eArgTypeNone, NULL }
956 };
957 
958 //-------------------------------------------------------------------------
959 // CommandObjectBreakpointEnable
960 //-------------------------------------------------------------------------
961 #pragma mark Enable
962 
963 class CommandObjectBreakpointEnable : public CommandObjectParsed
964 {
965 public:
966     CommandObjectBreakpointEnable (CommandInterpreter &interpreter) :
967         CommandObjectParsed (interpreter,
968                              "enable",
969                              "Enable the specified disabled breakpoint(s). If no breakpoints are specified, enable all of them.",
970                              NULL)
971     {
972         CommandArgumentEntry arg;
973         CommandObject::AddIDsArgumentData(arg, eArgTypeBreakpointID, eArgTypeBreakpointIDRange);
974         // Add the entry for the first argument for this command to the object's arguments vector.
975         m_arguments.push_back (arg);
976     }
977 
978 
979     virtual
980     ~CommandObjectBreakpointEnable () {}
981 
982 protected:
983     virtual bool
984     DoExecute (Args& command, CommandReturnObject &result)
985     {
986         Target *target = m_interpreter.GetDebugger().GetSelectedTarget().get();
987         if (target == NULL)
988         {
989             result.AppendError ("Invalid target.  No existing target or breakpoints.");
990             result.SetStatus (eReturnStatusFailed);
991             return false;
992         }
993 
994         Mutex::Locker locker;
995         target->GetBreakpointList().GetListMutex(locker);
996 
997         const BreakpointList &breakpoints = target->GetBreakpointList();
998 
999         size_t num_breakpoints = breakpoints.GetSize();
1000 
1001         if (num_breakpoints == 0)
1002         {
1003             result.AppendError ("No breakpoints exist to be enabled.");
1004             result.SetStatus (eReturnStatusFailed);
1005             return false;
1006         }
1007 
1008         if (command.GetArgumentCount() == 0)
1009         {
1010             // No breakpoint selected; enable all currently set breakpoints.
1011             target->EnableAllBreakpoints ();
1012             result.AppendMessageWithFormat ("All breakpoints enabled. (%lu breakpoints)\n", num_breakpoints);
1013             result.SetStatus (eReturnStatusSuccessFinishNoResult);
1014         }
1015         else
1016         {
1017             // Particular breakpoint selected; enable that breakpoint.
1018             BreakpointIDList valid_bp_ids;
1019             CommandObjectMultiwordBreakpoint::VerifyBreakpointIDs (command, target, result, &valid_bp_ids);
1020 
1021             if (result.Succeeded())
1022             {
1023                 int enable_count = 0;
1024                 int loc_count = 0;
1025                 const size_t count = valid_bp_ids.GetSize();
1026                 for (size_t i = 0; i < count; ++i)
1027                 {
1028                     BreakpointID cur_bp_id = valid_bp_ids.GetBreakpointIDAtIndex (i);
1029 
1030                     if (cur_bp_id.GetBreakpointID() != LLDB_INVALID_BREAK_ID)
1031                     {
1032                         Breakpoint *breakpoint = target->GetBreakpointByID (cur_bp_id.GetBreakpointID()).get();
1033                         if (cur_bp_id.GetLocationID() != LLDB_INVALID_BREAK_ID)
1034                         {
1035                             BreakpointLocation *location = breakpoint->FindLocationByID (cur_bp_id.GetLocationID()).get();
1036                             if (location)
1037                             {
1038                                 location->SetEnabled (true);
1039                                 ++loc_count;
1040                             }
1041                         }
1042                         else
1043                         {
1044                             breakpoint->SetEnabled (true);
1045                             ++enable_count;
1046                         }
1047                     }
1048                 }
1049                 result.AppendMessageWithFormat ("%d breakpoints enabled.\n", enable_count + loc_count);
1050                 result.SetStatus (eReturnStatusSuccessFinishNoResult);
1051             }
1052         }
1053 
1054         return result.Succeeded();
1055     }
1056 };
1057 
1058 //-------------------------------------------------------------------------
1059 // CommandObjectBreakpointDisable
1060 //-------------------------------------------------------------------------
1061 #pragma mark Disable
1062 
1063 class CommandObjectBreakpointDisable : public CommandObjectParsed
1064 {
1065 public:
1066     CommandObjectBreakpointDisable (CommandInterpreter &interpreter) :
1067         CommandObjectParsed (interpreter,
1068                              "breakpoint disable",
1069                              "Disable the specified breakpoint(s) without removing it/them.  If no breakpoints are specified, disable them all.",
1070                              NULL)
1071     {
1072         CommandArgumentEntry arg;
1073         CommandObject::AddIDsArgumentData(arg, eArgTypeBreakpointID, eArgTypeBreakpointIDRange);
1074         // Add the entry for the first argument for this command to the object's arguments vector.
1075         m_arguments.push_back (arg);
1076     }
1077 
1078 
1079     virtual
1080     ~CommandObjectBreakpointDisable () {}
1081 
1082 protected:
1083     virtual bool
1084     DoExecute (Args& command, CommandReturnObject &result)
1085     {
1086         Target *target = m_interpreter.GetDebugger().GetSelectedTarget().get();
1087         if (target == NULL)
1088         {
1089             result.AppendError ("Invalid target.  No existing target or breakpoints.");
1090             result.SetStatus (eReturnStatusFailed);
1091             return false;
1092         }
1093 
1094         Mutex::Locker locker;
1095         target->GetBreakpointList().GetListMutex(locker);
1096 
1097         const BreakpointList &breakpoints = target->GetBreakpointList();
1098         size_t num_breakpoints = breakpoints.GetSize();
1099 
1100         if (num_breakpoints == 0)
1101         {
1102             result.AppendError ("No breakpoints exist to be disabled.");
1103             result.SetStatus (eReturnStatusFailed);
1104             return false;
1105         }
1106 
1107         if (command.GetArgumentCount() == 0)
1108         {
1109             // No breakpoint selected; disable all currently set breakpoints.
1110             target->DisableAllBreakpoints ();
1111             result.AppendMessageWithFormat ("All breakpoints disabled. (%lu breakpoints)\n", num_breakpoints);
1112             result.SetStatus (eReturnStatusSuccessFinishNoResult);
1113         }
1114         else
1115         {
1116             // Particular breakpoint selected; disable that breakpoint.
1117             BreakpointIDList valid_bp_ids;
1118 
1119             CommandObjectMultiwordBreakpoint::VerifyBreakpointIDs (command, target, result, &valid_bp_ids);
1120 
1121             if (result.Succeeded())
1122             {
1123                 int disable_count = 0;
1124                 int loc_count = 0;
1125                 const size_t count = valid_bp_ids.GetSize();
1126                 for (size_t i = 0; i < count; ++i)
1127                 {
1128                     BreakpointID cur_bp_id = valid_bp_ids.GetBreakpointIDAtIndex (i);
1129 
1130                     if (cur_bp_id.GetBreakpointID() != LLDB_INVALID_BREAK_ID)
1131                     {
1132                         Breakpoint *breakpoint = target->GetBreakpointByID (cur_bp_id.GetBreakpointID()).get();
1133                         if (cur_bp_id.GetLocationID() != LLDB_INVALID_BREAK_ID)
1134                         {
1135                             BreakpointLocation *location = breakpoint->FindLocationByID (cur_bp_id.GetLocationID()).get();
1136                             if (location)
1137                             {
1138                                 location->SetEnabled (false);
1139                                 ++loc_count;
1140                             }
1141                         }
1142                         else
1143                         {
1144                             breakpoint->SetEnabled (false);
1145                             ++disable_count;
1146                         }
1147                     }
1148                 }
1149                 result.AppendMessageWithFormat ("%d breakpoints disabled.\n", disable_count + loc_count);
1150                 result.SetStatus (eReturnStatusSuccessFinishNoResult);
1151             }
1152         }
1153 
1154         return result.Succeeded();
1155     }
1156 
1157 };
1158 
1159 //-------------------------------------------------------------------------
1160 // CommandObjectBreakpointList
1161 //-------------------------------------------------------------------------
1162 #pragma mark List
1163 
1164 class CommandObjectBreakpointList : public CommandObjectParsed
1165 {
1166 public:
1167     CommandObjectBreakpointList (CommandInterpreter &interpreter) :
1168         CommandObjectParsed (interpreter,
1169                              "breakpoint list",
1170                              "List some or all breakpoints at configurable levels of detail.",
1171                              NULL),
1172         m_options (interpreter)
1173     {
1174         CommandArgumentEntry arg;
1175         CommandArgumentData bp_id_arg;
1176 
1177         // Define the first (and only) variant of this arg.
1178         bp_id_arg.arg_type = eArgTypeBreakpointID;
1179         bp_id_arg.arg_repetition = eArgRepeatOptional;
1180 
1181         // There is only one variant this argument could be; put it into the argument entry.
1182         arg.push_back (bp_id_arg);
1183 
1184         // Push the data for the first argument into the m_arguments vector.
1185         m_arguments.push_back (arg);
1186     }
1187 
1188 
1189     virtual
1190     ~CommandObjectBreakpointList () {}
1191 
1192     virtual Options *
1193     GetOptions ()
1194     {
1195         return &m_options;
1196     }
1197 
1198     class CommandOptions : public Options
1199     {
1200     public:
1201 
1202         CommandOptions (CommandInterpreter &interpreter) :
1203             Options (interpreter),
1204             m_level (lldb::eDescriptionLevelBrief)  // Breakpoint List defaults to brief descriptions
1205         {
1206         }
1207 
1208         virtual
1209         ~CommandOptions () {}
1210 
1211         virtual Error
1212         SetOptionValue (uint32_t option_idx, const char *option_arg)
1213         {
1214             Error error;
1215             char short_option = (char) m_getopt_table[option_idx].val;
1216 
1217             switch (short_option)
1218             {
1219                 case 'b':
1220                     m_level = lldb::eDescriptionLevelBrief;
1221                     break;
1222                 case 'f':
1223                     m_level = lldb::eDescriptionLevelFull;
1224                     break;
1225                 case 'v':
1226                     m_level = lldb::eDescriptionLevelVerbose;
1227                     break;
1228                 case 'i':
1229                     m_internal = true;
1230                     break;
1231                 default:
1232                     error.SetErrorStringWithFormat ("unrecognized option '%c'", short_option);
1233                     break;
1234             }
1235 
1236             return error;
1237         }
1238 
1239         void
1240         OptionParsingStarting ()
1241         {
1242             m_level = lldb::eDescriptionLevelFull;
1243             m_internal = false;
1244         }
1245 
1246         const OptionDefinition *
1247         GetDefinitions ()
1248         {
1249             return g_option_table;
1250         }
1251 
1252         // Options table: Required for subclasses of Options.
1253 
1254         static OptionDefinition g_option_table[];
1255 
1256         // Instance variables to hold the values for command options.
1257 
1258         lldb::DescriptionLevel m_level;
1259 
1260         bool m_internal;
1261     };
1262 
1263 protected:
1264     virtual bool
1265     DoExecute (Args& command, CommandReturnObject &result)
1266     {
1267         Target *target = m_interpreter.GetDebugger().GetSelectedTarget().get();
1268         if (target == NULL)
1269         {
1270             result.AppendError ("Invalid target. No current target or breakpoints.");
1271             result.SetStatus (eReturnStatusSuccessFinishNoResult);
1272             return true;
1273         }
1274 
1275         const BreakpointList &breakpoints = target->GetBreakpointList(m_options.m_internal);
1276         Mutex::Locker locker;
1277         target->GetBreakpointList(m_options.m_internal).GetListMutex(locker);
1278 
1279         size_t num_breakpoints = breakpoints.GetSize();
1280 
1281         if (num_breakpoints == 0)
1282         {
1283             result.AppendMessage ("No breakpoints currently set.");
1284             result.SetStatus (eReturnStatusSuccessFinishNoResult);
1285             return true;
1286         }
1287 
1288         Stream &output_stream = result.GetOutputStream();
1289 
1290         if (command.GetArgumentCount() == 0)
1291         {
1292             // No breakpoint selected; show info about all currently set breakpoints.
1293             result.AppendMessage ("Current breakpoints:");
1294             for (size_t i = 0; i < num_breakpoints; ++i)
1295             {
1296                 Breakpoint *breakpoint = breakpoints.GetBreakpointAtIndex (i).get();
1297                 AddBreakpointDescription (&output_stream, breakpoint, m_options.m_level);
1298             }
1299             result.SetStatus (eReturnStatusSuccessFinishNoResult);
1300         }
1301         else
1302         {
1303             // Particular breakpoints selected; show info about that breakpoint.
1304             BreakpointIDList valid_bp_ids;
1305             CommandObjectMultiwordBreakpoint::VerifyBreakpointIDs (command, target, result, &valid_bp_ids);
1306 
1307             if (result.Succeeded())
1308             {
1309                 for (size_t i = 0; i < valid_bp_ids.GetSize(); ++i)
1310                 {
1311                     BreakpointID cur_bp_id = valid_bp_ids.GetBreakpointIDAtIndex (i);
1312                     Breakpoint *breakpoint = target->GetBreakpointByID (cur_bp_id.GetBreakpointID()).get();
1313                     AddBreakpointDescription (&output_stream, breakpoint, m_options.m_level);
1314                 }
1315                 result.SetStatus (eReturnStatusSuccessFinishNoResult);
1316             }
1317             else
1318             {
1319                 result.AppendError ("Invalid breakpoint id.");
1320                 result.SetStatus (eReturnStatusFailed);
1321             }
1322         }
1323 
1324         return result.Succeeded();
1325     }
1326 
1327 private:
1328     CommandOptions m_options;
1329 };
1330 
1331 #pragma mark List::CommandOptions
1332 OptionDefinition
1333 CommandObjectBreakpointList::CommandOptions::g_option_table[] =
1334 {
1335     { LLDB_OPT_SET_ALL, false, "internal", 'i', no_argument, NULL, 0, eArgTypeNone,
1336         "Show debugger internal breakpoints" },
1337 
1338     { LLDB_OPT_SET_1, false, "brief",    'b', no_argument, NULL, 0, eArgTypeNone,
1339         "Give a brief description of the breakpoint (no location info)."},
1340 
1341     // FIXME: We need to add an "internal" command, and then add this sort of thing to it.
1342     // But I need to see it for now, and don't want to wait.
1343     { LLDB_OPT_SET_2, false, "full",    'f', no_argument, NULL, 0, eArgTypeNone,
1344         "Give a full description of the breakpoint and its locations."},
1345 
1346     { LLDB_OPT_SET_3, false, "verbose", 'v', no_argument, NULL, 0, eArgTypeNone,
1347         "Explain everything we know about the breakpoint (for debugging debugger bugs)." },
1348 
1349     { 0, false, NULL, 0, 0, NULL, 0, eArgTypeNone, NULL }
1350 };
1351 
1352 //-------------------------------------------------------------------------
1353 // CommandObjectBreakpointClear
1354 //-------------------------------------------------------------------------
1355 #pragma mark Clear
1356 
1357 class CommandObjectBreakpointClear : public CommandObjectParsed
1358 {
1359 public:
1360 
1361     typedef enum BreakpointClearType
1362     {
1363         eClearTypeInvalid,
1364         eClearTypeFileAndLine
1365     } BreakpointClearType;
1366 
1367     CommandObjectBreakpointClear (CommandInterpreter &interpreter) :
1368         CommandObjectParsed (interpreter,
1369                              "breakpoint clear",
1370                              "Clears a breakpoint or set of breakpoints in the executable.",
1371                              "breakpoint clear <cmd-options>"),
1372         m_options (interpreter)
1373     {
1374     }
1375 
1376     virtual
1377     ~CommandObjectBreakpointClear () {}
1378 
1379     virtual Options *
1380     GetOptions ()
1381     {
1382         return &m_options;
1383     }
1384 
1385     class CommandOptions : public Options
1386     {
1387     public:
1388 
1389         CommandOptions (CommandInterpreter &interpreter) :
1390             Options (interpreter),
1391             m_filename (),
1392             m_line_num (0)
1393         {
1394         }
1395 
1396         virtual
1397         ~CommandOptions () {}
1398 
1399         virtual Error
1400         SetOptionValue (uint32_t option_idx, const char *option_arg)
1401         {
1402             Error error;
1403             char short_option = (char) m_getopt_table[option_idx].val;
1404 
1405             switch (short_option)
1406             {
1407                 case 'f':
1408                     m_filename.assign (option_arg);
1409                     break;
1410 
1411                 case 'l':
1412                     m_line_num = Args::StringToUInt32 (option_arg, 0);
1413                     break;
1414 
1415                 default:
1416                     error.SetErrorStringWithFormat ("unrecognized option '%c'", short_option);
1417                     break;
1418             }
1419 
1420             return error;
1421         }
1422 
1423         void
1424         OptionParsingStarting ()
1425         {
1426             m_filename.clear();
1427             m_line_num = 0;
1428         }
1429 
1430         const OptionDefinition*
1431         GetDefinitions ()
1432         {
1433             return g_option_table;
1434         }
1435 
1436         // Options table: Required for subclasses of Options.
1437 
1438         static OptionDefinition g_option_table[];
1439 
1440         // Instance variables to hold the values for command options.
1441 
1442         std::string m_filename;
1443         uint32_t m_line_num;
1444 
1445     };
1446 
1447 protected:
1448     virtual bool
1449     DoExecute (Args& command, CommandReturnObject &result)
1450     {
1451         Target *target = m_interpreter.GetDebugger().GetSelectedTarget().get();
1452         if (target == NULL)
1453         {
1454             result.AppendError ("Invalid target. No existing target or breakpoints.");
1455             result.SetStatus (eReturnStatusFailed);
1456             return false;
1457         }
1458 
1459         // The following are the various types of breakpoints that could be cleared:
1460         //   1). -f -l (clearing breakpoint by source location)
1461 
1462         BreakpointClearType break_type = eClearTypeInvalid;
1463 
1464         if (m_options.m_line_num != 0)
1465             break_type = eClearTypeFileAndLine;
1466 
1467         Mutex::Locker locker;
1468         target->GetBreakpointList().GetListMutex(locker);
1469 
1470         BreakpointList &breakpoints = target->GetBreakpointList();
1471         size_t num_breakpoints = breakpoints.GetSize();
1472 
1473         // Early return if there's no breakpoint at all.
1474         if (num_breakpoints == 0)
1475         {
1476             result.AppendError ("Breakpoint clear: No breakpoint cleared.");
1477             result.SetStatus (eReturnStatusFailed);
1478             return result.Succeeded();
1479         }
1480 
1481         // Find matching breakpoints and delete them.
1482 
1483         // First create a copy of all the IDs.
1484         std::vector<break_id_t> BreakIDs;
1485         for (size_t i = 0; i < num_breakpoints; ++i)
1486             BreakIDs.push_back(breakpoints.GetBreakpointAtIndex(i).get()->GetID());
1487 
1488         int num_cleared = 0;
1489         StreamString ss;
1490         switch (break_type)
1491         {
1492             case eClearTypeFileAndLine: // Breakpoint by source position
1493                 {
1494                     const ConstString filename(m_options.m_filename.c_str());
1495                     BreakpointLocationCollection loc_coll;
1496 
1497                     for (size_t i = 0; i < num_breakpoints; ++i)
1498                     {
1499                         Breakpoint *bp = breakpoints.FindBreakpointByID(BreakIDs[i]).get();
1500 
1501                         if (bp->GetMatchingFileLine(filename, m_options.m_line_num, loc_coll))
1502                         {
1503                             // If the collection size is 0, it's a full match and we can just remove the breakpoint.
1504                             if (loc_coll.GetSize() == 0)
1505                             {
1506                                 bp->GetDescription(&ss, lldb::eDescriptionLevelBrief);
1507                                 ss.EOL();
1508                                 target->RemoveBreakpointByID (bp->GetID());
1509                                 ++num_cleared;
1510                             }
1511                         }
1512                     }
1513                 }
1514                 break;
1515 
1516             default:
1517                 break;
1518         }
1519 
1520         if (num_cleared > 0)
1521         {
1522             Stream &output_stream = result.GetOutputStream();
1523             output_stream.Printf ("%d breakpoints cleared:\n", num_cleared);
1524             output_stream << ss.GetData();
1525             output_stream.EOL();
1526             result.SetStatus (eReturnStatusSuccessFinishNoResult);
1527         }
1528         else
1529         {
1530             result.AppendError ("Breakpoint clear: No breakpoint cleared.");
1531             result.SetStatus (eReturnStatusFailed);
1532         }
1533 
1534         return result.Succeeded();
1535     }
1536 
1537 private:
1538     CommandOptions m_options;
1539 };
1540 
1541 #pragma mark Clear::CommandOptions
1542 
1543 OptionDefinition
1544 CommandObjectBreakpointClear::CommandOptions::g_option_table[] =
1545 {
1546     { LLDB_OPT_SET_1, false, "file", 'f', required_argument, NULL, CommandCompletions::eSourceFileCompletion, eArgTypeFilename,
1547         "Specify the breakpoint by source location in this particular file."},
1548 
1549     { LLDB_OPT_SET_1, true, "line", 'l', required_argument, NULL, 0, eArgTypeLineNum,
1550         "Specify the breakpoint by source location at this particular line."},
1551 
1552     { 0, false, NULL, 0, 0, NULL, 0, eArgTypeNone, NULL }
1553 };
1554 
1555 //-------------------------------------------------------------------------
1556 // CommandObjectBreakpointDelete
1557 //-------------------------------------------------------------------------
1558 #pragma mark Delete
1559 
1560 class CommandObjectBreakpointDelete : public CommandObjectParsed
1561 {
1562 public:
1563     CommandObjectBreakpointDelete (CommandInterpreter &interpreter) :
1564         CommandObjectParsed (interpreter,
1565                              "breakpoint delete",
1566                              "Delete the specified breakpoint(s).  If no breakpoints are specified, delete them all.",
1567                              NULL)
1568     {
1569         CommandArgumentEntry arg;
1570         CommandObject::AddIDsArgumentData(arg, eArgTypeBreakpointID, eArgTypeBreakpointIDRange);
1571         // Add the entry for the first argument for this command to the object's arguments vector.
1572         m_arguments.push_back (arg);
1573     }
1574 
1575     virtual
1576     ~CommandObjectBreakpointDelete () {}
1577 
1578 protected:
1579     virtual bool
1580     DoExecute (Args& command, CommandReturnObject &result)
1581     {
1582         Target *target = m_interpreter.GetDebugger().GetSelectedTarget().get();
1583         if (target == NULL)
1584         {
1585             result.AppendError ("Invalid target. No existing target or breakpoints.");
1586             result.SetStatus (eReturnStatusFailed);
1587             return false;
1588         }
1589 
1590         Mutex::Locker locker;
1591         target->GetBreakpointList().GetListMutex(locker);
1592 
1593         const BreakpointList &breakpoints = target->GetBreakpointList();
1594 
1595         size_t num_breakpoints = breakpoints.GetSize();
1596 
1597         if (num_breakpoints == 0)
1598         {
1599             result.AppendError ("No breakpoints exist to be deleted.");
1600             result.SetStatus (eReturnStatusFailed);
1601             return false;
1602         }
1603 
1604         if (command.GetArgumentCount() == 0)
1605         {
1606             if (!m_interpreter.Confirm ("About to delete all breakpoints, do you want to do that?", true))
1607             {
1608                 result.AppendMessage("Operation cancelled...");
1609             }
1610             else
1611             {
1612                 target->RemoveAllBreakpoints ();
1613                 result.AppendMessageWithFormat ("All breakpoints removed. (%lu breakpoints)\n", num_breakpoints);
1614             }
1615             result.SetStatus (eReturnStatusSuccessFinishNoResult);
1616         }
1617         else
1618         {
1619             // Particular breakpoint selected; disable that breakpoint.
1620             BreakpointIDList valid_bp_ids;
1621             CommandObjectMultiwordBreakpoint::VerifyBreakpointIDs (command, target, result, &valid_bp_ids);
1622 
1623             if (result.Succeeded())
1624             {
1625                 int delete_count = 0;
1626                 int disable_count = 0;
1627                 const size_t count = valid_bp_ids.GetSize();
1628                 for (size_t i = 0; i < count; ++i)
1629                 {
1630                     BreakpointID cur_bp_id = valid_bp_ids.GetBreakpointIDAtIndex (i);
1631 
1632                     if (cur_bp_id.GetBreakpointID() != LLDB_INVALID_BREAK_ID)
1633                     {
1634                         if (cur_bp_id.GetLocationID() != LLDB_INVALID_BREAK_ID)
1635                         {
1636                             Breakpoint *breakpoint = target->GetBreakpointByID (cur_bp_id.GetBreakpointID()).get();
1637                             BreakpointLocation *location = breakpoint->FindLocationByID (cur_bp_id.GetLocationID()).get();
1638                             // It makes no sense to try to delete individual locations, so we disable them instead.
1639                             if (location)
1640                             {
1641                                 location->SetEnabled (false);
1642                                 ++disable_count;
1643                             }
1644                         }
1645                         else
1646                         {
1647                             target->RemoveBreakpointByID (cur_bp_id.GetBreakpointID());
1648                             ++delete_count;
1649                         }
1650                     }
1651                 }
1652                 result.AppendMessageWithFormat ("%d breakpoints deleted; %d breakpoint locations disabled.\n",
1653                                                delete_count, disable_count);
1654                 result.SetStatus (eReturnStatusSuccessFinishNoResult);
1655             }
1656         }
1657         return result.Succeeded();
1658     }
1659 };
1660 
1661 //-------------------------------------------------------------------------
1662 // CommandObjectMultiwordBreakpoint
1663 //-------------------------------------------------------------------------
1664 #pragma mark MultiwordBreakpoint
1665 
1666 CommandObjectMultiwordBreakpoint::CommandObjectMultiwordBreakpoint (CommandInterpreter &interpreter) :
1667     CommandObjectMultiword (interpreter,
1668                             "breakpoint",
1669                             "A set of commands for operating on breakpoints. Also see _regexp-break.",
1670                             "breakpoint <command> [<command-options>]")
1671 {
1672     CommandObjectSP list_command_object (new CommandObjectBreakpointList (interpreter));
1673     CommandObjectSP enable_command_object (new CommandObjectBreakpointEnable (interpreter));
1674     CommandObjectSP disable_command_object (new CommandObjectBreakpointDisable (interpreter));
1675     CommandObjectSP clear_command_object (new CommandObjectBreakpointClear (interpreter));
1676     CommandObjectSP delete_command_object (new CommandObjectBreakpointDelete (interpreter));
1677     CommandObjectSP set_command_object (new CommandObjectBreakpointSet (interpreter));
1678     CommandObjectSP command_command_object (new CommandObjectBreakpointCommand (interpreter));
1679     CommandObjectSP modify_command_object (new CommandObjectBreakpointModify(interpreter));
1680 
1681     list_command_object->SetCommandName ("breakpoint list");
1682     enable_command_object->SetCommandName("breakpoint enable");
1683     disable_command_object->SetCommandName("breakpoint disable");
1684     clear_command_object->SetCommandName("breakpoint clear");
1685     delete_command_object->SetCommandName("breakpoint delete");
1686     set_command_object->SetCommandName("breakpoint set");
1687     command_command_object->SetCommandName ("breakpoint command");
1688     modify_command_object->SetCommandName ("breakpoint modify");
1689 
1690     LoadSubCommand ("list",       list_command_object);
1691     LoadSubCommand ("enable",     enable_command_object);
1692     LoadSubCommand ("disable",    disable_command_object);
1693     LoadSubCommand ("clear",      clear_command_object);
1694     LoadSubCommand ("delete",     delete_command_object);
1695     LoadSubCommand ("set",        set_command_object);
1696     LoadSubCommand ("command",    command_command_object);
1697     LoadSubCommand ("modify",     modify_command_object);
1698 }
1699 
1700 CommandObjectMultiwordBreakpoint::~CommandObjectMultiwordBreakpoint ()
1701 {
1702 }
1703 
1704 void
1705 CommandObjectMultiwordBreakpoint::VerifyBreakpointIDs (Args &args, Target *target, CommandReturnObject &result,
1706                                                          BreakpointIDList *valid_ids)
1707 {
1708     // args can be strings representing 1). integers (for breakpoint ids)
1709     //                                  2). the full breakpoint & location canonical representation
1710     //                                  3). the word "to" or a hyphen, representing a range (in which case there
1711     //                                      had *better* be an entry both before & after of one of the first two types.
1712     // If args is empty, we will use the last created breakpoint (if there is one.)
1713 
1714     Args temp_args;
1715 
1716     if (args.GetArgumentCount() == 0)
1717     {
1718         if (target->GetLastCreatedBreakpoint())
1719         {
1720             valid_ids->AddBreakpointID (BreakpointID(target->GetLastCreatedBreakpoint()->GetID(), LLDB_INVALID_BREAK_ID));
1721             result.SetStatus (eReturnStatusSuccessFinishNoResult);
1722         }
1723         else
1724         {
1725             result.AppendError("No breakpoint specified and no last created breakpoint.");
1726             result.SetStatus (eReturnStatusFailed);
1727         }
1728         return;
1729     }
1730 
1731     // Create a new Args variable to use; copy any non-breakpoint-id-ranges stuff directly from the old ARGS to
1732     // the new TEMP_ARGS.  Do not copy breakpoint id range strings over; instead generate a list of strings for
1733     // all the breakpoint ids in the range, and shove all of those breakpoint id strings into TEMP_ARGS.
1734 
1735     BreakpointIDList::FindAndReplaceIDRanges (args, target, result, temp_args);
1736 
1737     // NOW, convert the list of breakpoint id strings in TEMP_ARGS into an actual BreakpointIDList:
1738 
1739     valid_ids->InsertStringArray (temp_args.GetConstArgumentVector(), temp_args.GetArgumentCount(), result);
1740 
1741     // At this point,  all of the breakpoint ids that the user passed in have been converted to breakpoint IDs
1742     // and put into valid_ids.
1743 
1744     if (result.Succeeded())
1745     {
1746         // Now that we've converted everything from args into a list of breakpoint ids, go through our tentative list
1747         // of breakpoint id's and verify that they correspond to valid/currently set breakpoints.
1748 
1749         const size_t count = valid_ids->GetSize();
1750         for (size_t i = 0; i < count; ++i)
1751         {
1752             BreakpointID cur_bp_id = valid_ids->GetBreakpointIDAtIndex (i);
1753             Breakpoint *breakpoint = target->GetBreakpointByID (cur_bp_id.GetBreakpointID()).get();
1754             if (breakpoint != NULL)
1755             {
1756                 int num_locations = breakpoint->GetNumLocations();
1757                 if (cur_bp_id.GetLocationID() > num_locations)
1758                 {
1759                     StreamString id_str;
1760                     BreakpointID::GetCanonicalReference (&id_str,
1761                                                          cur_bp_id.GetBreakpointID(),
1762                                                          cur_bp_id.GetLocationID());
1763                     i = valid_ids->GetSize() + 1;
1764                     result.AppendErrorWithFormat ("'%s' is not a currently valid breakpoint/location id.\n",
1765                                                  id_str.GetData());
1766                     result.SetStatus (eReturnStatusFailed);
1767                 }
1768             }
1769             else
1770             {
1771                 i = valid_ids->GetSize() + 1;
1772                 result.AppendErrorWithFormat ("'%d' is not a currently valid breakpoint id.\n", cur_bp_id.GetBreakpointID());
1773                 result.SetStatus (eReturnStatusFailed);
1774             }
1775         }
1776     }
1777 }
1778