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