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