130fdc8d8SChris Lattner //===-- CommandObjectBreakpoint.cpp -----------------------------*- C++ -*-===//
230fdc8d8SChris Lattner //
330fdc8d8SChris Lattner //                     The LLVM Compiler Infrastructure
430fdc8d8SChris Lattner //
530fdc8d8SChris Lattner // This file is distributed under the University of Illinois Open Source
630fdc8d8SChris Lattner // License. See LICENSE.TXT for details.
730fdc8d8SChris Lattner //
830fdc8d8SChris Lattner //===----------------------------------------------------------------------===//
930fdc8d8SChris Lattner 
1093a64300SDaniel Malea #include "lldb/lldb-python.h"
1193a64300SDaniel Malea 
1230fdc8d8SChris Lattner #include "CommandObjectBreakpoint.h"
1330fdc8d8SChris Lattner #include "CommandObjectBreakpointCommand.h"
1430fdc8d8SChris Lattner 
1530fdc8d8SChris Lattner // C Includes
1630fdc8d8SChris Lattner // C++ Includes
1730fdc8d8SChris Lattner // Other libraries and framework includes
1830fdc8d8SChris Lattner // Project includes
1930fdc8d8SChris Lattner #include "lldb/Breakpoint/Breakpoint.h"
2030fdc8d8SChris Lattner #include "lldb/Breakpoint/BreakpointIDList.h"
2130fdc8d8SChris Lattner #include "lldb/Breakpoint/BreakpointLocation.h"
225275aaa0SVince Harron #include "lldb/Host/StringConvert.h"
2340af72e1SJim Ingham #include "lldb/Interpreter/Options.h"
2432abc6edSZachary Turner #include "lldb/Interpreter/OptionValueBoolean.h"
255e09c8c3SJim Ingham #include "lldb/Interpreter/OptionValueString.h"
265e09c8c3SJim Ingham #include "lldb/Interpreter/OptionValueUInt64.h"
2730fdc8d8SChris Lattner #include "lldb/Core/RegularExpression.h"
2830fdc8d8SChris Lattner #include "lldb/Core/StreamString.h"
2930fdc8d8SChris Lattner #include "lldb/Interpreter/CommandInterpreter.h"
3030fdc8d8SChris Lattner #include "lldb/Interpreter/CommandReturnObject.h"
31a78bd7ffSZachary Turner #include "lldb/Target/LanguageRuntime.h"
3230fdc8d8SChris Lattner #include "lldb/Target/Target.h"
3330fdc8d8SChris Lattner #include "lldb/Interpreter/CommandCompletions.h"
34b57e4a1bSJason Molenda #include "lldb/Target/StackFrame.h"
351b54c88cSJim Ingham #include "lldb/Target/Thread.h"
361b54c88cSJim Ingham #include "lldb/Target/ThreadSpec.h"
3730fdc8d8SChris Lattner 
38b7234e40SJohnny Chen #include <vector>
39b7234e40SJohnny Chen 
4030fdc8d8SChris Lattner using namespace lldb;
4130fdc8d8SChris Lattner using namespace lldb_private;
4230fdc8d8SChris Lattner 
4330fdc8d8SChris Lattner static void
4485e8b814SJim Ingham AddBreakpointDescription (Stream *s, Breakpoint *bp, lldb::DescriptionLevel level)
4530fdc8d8SChris Lattner {
4630fdc8d8SChris Lattner     s->IndentMore();
4730fdc8d8SChris Lattner     bp->GetDescription (s, level, true);
4830fdc8d8SChris Lattner     s->IndentLess();
4930fdc8d8SChris Lattner     s->EOL();
5030fdc8d8SChris Lattner }
5130fdc8d8SChris Lattner 
5230fdc8d8SChris Lattner //-------------------------------------------------------------------------
535a988416SJim Ingham // CommandObjectBreakpointSet
5430fdc8d8SChris Lattner //-------------------------------------------------------------------------
5530fdc8d8SChris Lattner 
565a988416SJim Ingham 
575a988416SJim Ingham class CommandObjectBreakpointSet : public CommandObjectParsed
585a988416SJim Ingham {
595a988416SJim Ingham public:
605a988416SJim Ingham 
615a988416SJim Ingham     typedef enum BreakpointSetType
625a988416SJim Ingham     {
635a988416SJim Ingham         eSetTypeInvalid,
645a988416SJim Ingham         eSetTypeFileAndLine,
655a988416SJim Ingham         eSetTypeAddress,
665a988416SJim Ingham         eSetTypeFunctionName,
675a988416SJim Ingham         eSetTypeFunctionRegexp,
685a988416SJim Ingham         eSetTypeSourceRegexp,
695a988416SJim Ingham         eSetTypeException
705a988416SJim Ingham     } BreakpointSetType;
715a988416SJim Ingham 
725a988416SJim Ingham     CommandObjectBreakpointSet (CommandInterpreter &interpreter) :
735a988416SJim Ingham         CommandObjectParsed (interpreter,
745a988416SJim Ingham                              "breakpoint set",
755a988416SJim Ingham                              "Sets a breakpoint or set of breakpoints in the executable.",
765a988416SJim Ingham                              "breakpoint set <cmd-options>"),
775a988416SJim Ingham         m_options (interpreter)
785a988416SJim Ingham     {
795a988416SJim Ingham     }
805a988416SJim Ingham 
815a988416SJim Ingham 
825a988416SJim Ingham     virtual
835a988416SJim Ingham     ~CommandObjectBreakpointSet () {}
845a988416SJim Ingham 
855a988416SJim Ingham     virtual Options *
865a988416SJim Ingham     GetOptions ()
875a988416SJim Ingham     {
885a988416SJim Ingham         return &m_options;
895a988416SJim Ingham     }
905a988416SJim Ingham 
915a988416SJim Ingham     class CommandOptions : public Options
925a988416SJim Ingham     {
935a988416SJim Ingham     public:
945a988416SJim Ingham 
955a988416SJim Ingham         CommandOptions (CommandInterpreter &interpreter) :
96eb0103f2SGreg Clayton             Options (interpreter),
977d49c9c8SJohnny Chen             m_condition (),
9887df91b8SJim Ingham             m_filenames (),
9930fdc8d8SChris Lattner             m_line_num (0),
10030fdc8d8SChris Lattner             m_column (0),
101fab10e89SJim Ingham             m_func_names (),
102fab10e89SJim Ingham             m_func_name_type_mask (eFunctionNameTypeNone),
10330fdc8d8SChris Lattner             m_func_regexp (),
104969795f1SJim Ingham             m_source_text_regexp(),
10530fdc8d8SChris Lattner             m_modules (),
1061b54c88cSJim Ingham             m_load_addr(),
107c982c768SGreg Clayton             m_ignore_count (0),
1081b54c88cSJim Ingham             m_thread_id(LLDB_INVALID_THREAD_ID),
109c982c768SGreg Clayton             m_thread_index (UINT32_MAX),
1101b54c88cSJim Ingham             m_thread_name(),
111fab10e89SJim Ingham             m_queue_name(),
112fab10e89SJim Ingham             m_catch_bp (false),
1131f746071SGreg Clayton             m_throw_bp (true),
114eb023e75SGreg Clayton             m_hardware (false),
115*a72b31c7SJim Ingham             m_exception_language (eLanguageTypeUnknown),
116ca36cd16SJim Ingham             m_skip_prologue (eLazyBoolCalculate),
117e732052fSJim Ingham             m_one_shot (false),
118e732052fSJim Ingham             m_all_files (false)
11930fdc8d8SChris Lattner         {
12030fdc8d8SChris Lattner         }
12130fdc8d8SChris Lattner 
12230fdc8d8SChris Lattner 
1235a988416SJim Ingham         virtual
1245a988416SJim Ingham         ~CommandOptions () {}
12587df91b8SJim Ingham 
1265a988416SJim Ingham         virtual Error
1275a988416SJim Ingham         SetOptionValue (uint32_t option_idx, const char *option_arg)
12830fdc8d8SChris Lattner         {
12930fdc8d8SChris Lattner             Error error;
1303bcdfc0eSGreg Clayton             const int short_option = m_getopt_table[option_idx].val;
13130fdc8d8SChris Lattner 
13230fdc8d8SChris Lattner             switch (short_option)
13330fdc8d8SChris Lattner             {
13430fdc8d8SChris Lattner                 case 'a':
135b9d5df58SGreg Clayton                     {
136b9d5df58SGreg Clayton                         ExecutionContext exe_ctx (m_interpreter.GetExecutionContext());
137b9d5df58SGreg Clayton                         m_load_addr = Args::StringToAddress(&exe_ctx, option_arg, LLDB_INVALID_ADDRESS, &error);
138b9d5df58SGreg Clayton                     }
13930fdc8d8SChris Lattner                     break;
14030fdc8d8SChris Lattner 
141e732052fSJim Ingham                 case 'A':
142e732052fSJim Ingham                     m_all_files = true;
143e732052fSJim Ingham                     break;
144e732052fSJim Ingham 
145ca36cd16SJim Ingham                 case 'b':
146ca36cd16SJim Ingham                     m_func_names.push_back (option_arg);
147ca36cd16SJim Ingham                     m_func_name_type_mask |= eFunctionNameTypeBase;
148ca36cd16SJim Ingham                     break;
149ca36cd16SJim Ingham 
1507d49c9c8SJohnny Chen                 case 'C':
1516312991cSJim Ingham                 {
1526312991cSJim Ingham                     bool success;
1536312991cSJim Ingham                     m_column = StringConvert::ToUInt32 (option_arg, 0, 0, &success);
1546312991cSJim Ingham                     if (!success)
1556312991cSJim Ingham                         error.SetErrorStringWithFormat("invalid column number: %s", option_arg);
15630fdc8d8SChris Lattner                     break;
1576312991cSJim Ingham                 }
1587d49c9c8SJohnny Chen                 case 'c':
1597d49c9c8SJohnny Chen                     m_condition.assign(option_arg);
1607d49c9c8SJohnny Chen                     break;
1617d49c9c8SJohnny Chen 
16233df7cd3SJim Ingham                 case 'D':
16333df7cd3SJim Ingham                     m_use_dummy = true;
16433df7cd3SJim Ingham                     break;
16533df7cd3SJim Ingham 
166fab10e89SJim Ingham                 case 'E':
167fab10e89SJim Ingham                 {
168fab10e89SJim Ingham                     LanguageType language = LanguageRuntime::GetLanguageTypeFromString (option_arg);
169fab10e89SJim Ingham 
170fab10e89SJim Ingham                     switch (language)
171fab10e89SJim Ingham                     {
172fab10e89SJim Ingham                         case eLanguageTypeC89:
173fab10e89SJim Ingham                         case eLanguageTypeC:
174fab10e89SJim Ingham                         case eLanguageTypeC99:
1751d0089faSBruce Mitchener                         case eLanguageTypeC11:
176*a72b31c7SJim Ingham                             m_exception_language = eLanguageTypeC;
177fab10e89SJim Ingham                             break;
178fab10e89SJim Ingham                         case eLanguageTypeC_plus_plus:
1791d0089faSBruce Mitchener                         case eLanguageTypeC_plus_plus_03:
1801d0089faSBruce Mitchener                         case eLanguageTypeC_plus_plus_11:
1812ba84a6aSBruce Mitchener                         case eLanguageTypeC_plus_plus_14:
182*a72b31c7SJim Ingham                             m_exception_language = eLanguageTypeC_plus_plus;
183fab10e89SJim Ingham                             break;
184fab10e89SJim Ingham                         case eLanguageTypeObjC:
185*a72b31c7SJim Ingham                             m_exception_language = eLanguageTypeObjC;
186fab10e89SJim Ingham                             break;
187fab10e89SJim Ingham                         case eLanguageTypeObjC_plus_plus:
188fab10e89SJim Ingham                             error.SetErrorStringWithFormat ("Set exception breakpoints separately for c++ and objective-c");
189fab10e89SJim Ingham                             break;
190fab10e89SJim Ingham                         case eLanguageTypeUnknown:
191fab10e89SJim Ingham                             error.SetErrorStringWithFormat ("Unknown language type: '%s' for exception breakpoint", option_arg);
192fab10e89SJim Ingham                             break;
193fab10e89SJim Ingham                         default:
194fab10e89SJim Ingham                             error.SetErrorStringWithFormat ("Unsupported language type: '%s' for exception breakpoint", option_arg);
195fab10e89SJim Ingham                     }
196fab10e89SJim Ingham                 }
197fab10e89SJim Ingham                 break;
198ca36cd16SJim Ingham 
199ca36cd16SJim Ingham                 case 'f':
200ca36cd16SJim Ingham                     m_filenames.AppendIfUnique (FileSpec(option_arg, false));
201fab10e89SJim Ingham                     break;
202ca36cd16SJim Ingham 
203ca36cd16SJim Ingham                 case 'F':
204ca36cd16SJim Ingham                     m_func_names.push_back (option_arg);
205ca36cd16SJim Ingham                     m_func_name_type_mask |= eFunctionNameTypeFull;
206ca36cd16SJim Ingham                     break;
207ca36cd16SJim Ingham 
208fab10e89SJim Ingham                 case 'h':
209fab10e89SJim Ingham                     {
210fab10e89SJim Ingham                         bool success;
211fab10e89SJim Ingham                         m_catch_bp = Args::StringToBoolean (option_arg, true, &success);
212fab10e89SJim Ingham                         if (!success)
213fab10e89SJim Ingham                             error.SetErrorStringWithFormat ("Invalid boolean value for on-catch option: '%s'", option_arg);
214fab10e89SJim Ingham                     }
215168d469aSJim Ingham                     break;
216eb023e75SGreg Clayton 
217eb023e75SGreg Clayton                 case 'H':
218eb023e75SGreg Clayton                     m_hardware = true;
219eb023e75SGreg Clayton                     break;
220eb023e75SGreg Clayton 
221ca36cd16SJim Ingham                 case 'i':
222ca36cd16SJim Ingham                 {
2235275aaa0SVince Harron                     m_ignore_count = StringConvert::ToUInt32(option_arg, UINT32_MAX, 0);
224ca36cd16SJim Ingham                     if (m_ignore_count == UINT32_MAX)
225ca36cd16SJim Ingham                        error.SetErrorStringWithFormat ("invalid ignore count '%s'", option_arg);
226ca36cd16SJim Ingham                     break;
227ca36cd16SJim Ingham                 }
228ca36cd16SJim Ingham 
229a8558b62SJim Ingham                 case 'K':
230a8558b62SJim Ingham                 {
231a8558b62SJim Ingham                     bool success;
232a8558b62SJim Ingham                     bool value;
233a8558b62SJim Ingham                     value = Args::StringToBoolean (option_arg, true, &success);
234a8558b62SJim Ingham                     if (value)
235a8558b62SJim Ingham                         m_skip_prologue = eLazyBoolYes;
236a8558b62SJim Ingham                     else
237a8558b62SJim Ingham                         m_skip_prologue = eLazyBoolNo;
238a8558b62SJim Ingham 
239a8558b62SJim Ingham                     if (!success)
240a8558b62SJim Ingham                         error.SetErrorStringWithFormat ("Invalid boolean value for skip prologue option: '%s'", option_arg);
241a8558b62SJim Ingham                 }
242fab10e89SJim Ingham                 break;
243ca36cd16SJim Ingham 
244ca36cd16SJim Ingham                 case 'l':
2456312991cSJim Ingham                 {
2466312991cSJim Ingham                     bool success;
2476312991cSJim Ingham                     m_line_num = StringConvert::ToUInt32 (option_arg, 0, 0, &success);
2486312991cSJim Ingham                     if (!success)
2496312991cSJim Ingham                         error.SetErrorStringWithFormat ("invalid line number: %s.", option_arg);
250ca36cd16SJim Ingham                     break;
2516312991cSJim Ingham                 }
252ca36cd16SJim Ingham                 case 'M':
253ca36cd16SJim Ingham                     m_func_names.push_back (option_arg);
254ca36cd16SJim Ingham                     m_func_name_type_mask |= eFunctionNameTypeMethod;
255ca36cd16SJim Ingham                     break;
256ca36cd16SJim Ingham 
257ca36cd16SJim Ingham                 case 'n':
258ca36cd16SJim Ingham                     m_func_names.push_back (option_arg);
259ca36cd16SJim Ingham                     m_func_name_type_mask |= eFunctionNameTypeAuto;
260ca36cd16SJim Ingham                     break;
261ca36cd16SJim Ingham 
2625e09c8c3SJim Ingham                 case 'N':
2635e09c8c3SJim Ingham                     if (BreakpointID::StringIsBreakpointName(option_arg, error))
2645e09c8c3SJim Ingham                         m_breakpoint_names.push_back (option_arg);
2655e09c8c3SJim Ingham                     break;
2665e09c8c3SJim Ingham 
267ca36cd16SJim Ingham                 case 'o':
268ca36cd16SJim Ingham                     m_one_shot = true;
269ca36cd16SJim Ingham                     break;
270ca36cd16SJim Ingham 
271*a72b31c7SJim Ingham                 case 'O':
272*a72b31c7SJim Ingham                     m_exception_extra_args.AppendArgument ("-O");
273*a72b31c7SJim Ingham                     m_exception_extra_args.AppendArgument (option_arg);
274*a72b31c7SJim Ingham                     break;
275*a72b31c7SJim Ingham 
276ca36cd16SJim Ingham                 case 'p':
277ca36cd16SJim Ingham                     m_source_text_regexp.assign (option_arg);
278ca36cd16SJim Ingham                     break;
279ca36cd16SJim Ingham 
280ca36cd16SJim Ingham                 case 'q':
281ca36cd16SJim Ingham                     m_queue_name.assign (option_arg);
282ca36cd16SJim Ingham                     break;
283ca36cd16SJim Ingham 
284ca36cd16SJim Ingham                 case 'r':
285ca36cd16SJim Ingham                     m_func_regexp.assign (option_arg);
286ca36cd16SJim Ingham                     break;
287ca36cd16SJim Ingham 
288ca36cd16SJim Ingham                 case 's':
289ca36cd16SJim Ingham                 {
290ca36cd16SJim Ingham                     m_modules.AppendIfUnique (FileSpec (option_arg, false));
291ca36cd16SJim Ingham                     break;
292ca36cd16SJim Ingham                 }
293ca36cd16SJim Ingham 
294ca36cd16SJim Ingham                 case 'S':
295ca36cd16SJim Ingham                     m_func_names.push_back (option_arg);
296ca36cd16SJim Ingham                     m_func_name_type_mask |= eFunctionNameTypeSelector;
297ca36cd16SJim Ingham                     break;
298ca36cd16SJim Ingham 
299ca36cd16SJim Ingham                 case 't' :
300ca36cd16SJim Ingham                 {
3015275aaa0SVince Harron                     m_thread_id = StringConvert::ToUInt64(option_arg, LLDB_INVALID_THREAD_ID, 0);
302ca36cd16SJim Ingham                     if (m_thread_id == LLDB_INVALID_THREAD_ID)
303ca36cd16SJim Ingham                        error.SetErrorStringWithFormat ("invalid thread id string '%s'", option_arg);
304ca36cd16SJim Ingham                 }
305ca36cd16SJim Ingham                 break;
306ca36cd16SJim Ingham 
307ca36cd16SJim Ingham                 case 'T':
308ca36cd16SJim Ingham                     m_thread_name.assign (option_arg);
309ca36cd16SJim Ingham                     break;
310ca36cd16SJim Ingham 
311ca36cd16SJim Ingham                 case 'w':
312ca36cd16SJim Ingham                 {
313ca36cd16SJim Ingham                     bool success;
314ca36cd16SJim Ingham                     m_throw_bp = Args::StringToBoolean (option_arg, true, &success);
315ca36cd16SJim Ingham                     if (!success)
316ca36cd16SJim Ingham                         error.SetErrorStringWithFormat ("Invalid boolean value for on-throw option: '%s'", option_arg);
317ca36cd16SJim Ingham                 }
318ca36cd16SJim Ingham                 break;
319ca36cd16SJim Ingham 
320ca36cd16SJim Ingham                 case 'x':
321ca36cd16SJim Ingham                 {
3225275aaa0SVince Harron                     m_thread_index = StringConvert::ToUInt32(option_arg, UINT32_MAX, 0);
323ca36cd16SJim Ingham                     if (m_thread_id == UINT32_MAX)
324ca36cd16SJim Ingham                        error.SetErrorStringWithFormat ("invalid thread index string '%s'", option_arg);
325ca36cd16SJim Ingham 
326ca36cd16SJim Ingham                 }
327ca36cd16SJim Ingham                 break;
328ca36cd16SJim Ingham 
32930fdc8d8SChris Lattner                 default:
33086edbf41SGreg Clayton                     error.SetErrorStringWithFormat ("unrecognized option '%c'", short_option);
33130fdc8d8SChris Lattner                     break;
33230fdc8d8SChris Lattner             }
33330fdc8d8SChris Lattner 
33430fdc8d8SChris Lattner             return error;
33530fdc8d8SChris Lattner         }
33630fdc8d8SChris Lattner         void
3375a988416SJim Ingham         OptionParsingStarting ()
33830fdc8d8SChris Lattner         {
3397d49c9c8SJohnny Chen             m_condition.clear();
34087df91b8SJim Ingham             m_filenames.Clear();
34130fdc8d8SChris Lattner             m_line_num = 0;
34230fdc8d8SChris Lattner             m_column = 0;
343fab10e89SJim Ingham             m_func_names.clear();
3441f746071SGreg Clayton             m_func_name_type_mask = eFunctionNameTypeNone;
34530fdc8d8SChris Lattner             m_func_regexp.clear();
3461f746071SGreg Clayton             m_source_text_regexp.clear();
34787df91b8SJim Ingham             m_modules.Clear();
3481f746071SGreg Clayton             m_load_addr = LLDB_INVALID_ADDRESS;
349c982c768SGreg Clayton             m_ignore_count = 0;
3501b54c88cSJim Ingham             m_thread_id = LLDB_INVALID_THREAD_ID;
351c982c768SGreg Clayton             m_thread_index = UINT32_MAX;
3521b54c88cSJim Ingham             m_thread_name.clear();
3531b54c88cSJim Ingham             m_queue_name.clear();
354fab10e89SJim Ingham             m_catch_bp = false;
355fab10e89SJim Ingham             m_throw_bp = true;
356eb023e75SGreg Clayton             m_hardware = false;
357*a72b31c7SJim Ingham             m_exception_language = eLanguageTypeUnknown;
358a8558b62SJim Ingham             m_skip_prologue = eLazyBoolCalculate;
359ca36cd16SJim Ingham             m_one_shot = false;
36033df7cd3SJim Ingham             m_use_dummy = false;
3615e09c8c3SJim Ingham             m_breakpoint_names.clear();
362e732052fSJim Ingham             m_all_files = false;
363*a72b31c7SJim Ingham             m_exception_extra_args.Clear();
36430fdc8d8SChris Lattner         }
36530fdc8d8SChris Lattner 
3665a988416SJim Ingham         const OptionDefinition*
3675a988416SJim Ingham         GetDefinitions ()
36830fdc8d8SChris Lattner         {
3695a988416SJim Ingham             return g_option_table;
37030fdc8d8SChris Lattner         }
37130fdc8d8SChris Lattner 
3725a988416SJim Ingham         // Options table: Required for subclasses of Options.
37330fdc8d8SChris Lattner 
3745a988416SJim Ingham         static OptionDefinition g_option_table[];
37530fdc8d8SChris Lattner 
3765a988416SJim Ingham         // Instance variables to hold the values for command options.
377969795f1SJim Ingham 
3785a988416SJim Ingham         std::string m_condition;
3795a988416SJim Ingham         FileSpecList m_filenames;
3805a988416SJim Ingham         uint32_t m_line_num;
3815a988416SJim Ingham         uint32_t m_column;
3825a988416SJim Ingham         std::vector<std::string> m_func_names;
3835e09c8c3SJim Ingham         std::vector<std::string> m_breakpoint_names;
3845a988416SJim Ingham         uint32_t m_func_name_type_mask;
3855a988416SJim Ingham         std::string m_func_regexp;
3865a988416SJim Ingham         std::string m_source_text_regexp;
3875a988416SJim Ingham         FileSpecList m_modules;
3885a988416SJim Ingham         lldb::addr_t m_load_addr;
3895a988416SJim Ingham         uint32_t m_ignore_count;
3905a988416SJim Ingham         lldb::tid_t m_thread_id;
3915a988416SJim Ingham         uint32_t m_thread_index;
3925a988416SJim Ingham         std::string m_thread_name;
3935a988416SJim Ingham         std::string m_queue_name;
3945a988416SJim Ingham         bool m_catch_bp;
3955a988416SJim Ingham         bool m_throw_bp;
396eb023e75SGreg Clayton         bool m_hardware; // Request to use hardware breakpoints
397*a72b31c7SJim Ingham         lldb::LanguageType m_exception_language;
3985a988416SJim Ingham         LazyBool m_skip_prologue;
399ca36cd16SJim Ingham         bool m_one_shot;
40033df7cd3SJim Ingham         bool m_use_dummy;
401e732052fSJim Ingham         bool m_all_files;
402*a72b31c7SJim Ingham         Args m_exception_extra_args;
4035a988416SJim Ingham 
4045a988416SJim Ingham     };
4055a988416SJim Ingham 
4065a988416SJim Ingham protected:
4075a988416SJim Ingham     virtual bool
4085a988416SJim Ingham     DoExecute (Args& command,
4095a988416SJim Ingham               CommandReturnObject &result)
41030fdc8d8SChris Lattner     {
41133df7cd3SJim Ingham         Target *target = GetSelectedOrDummyTarget(m_options.m_use_dummy);
41233df7cd3SJim Ingham 
413893c932aSJim Ingham         if (target == nullptr)
41430fdc8d8SChris Lattner         {
415effe5c95SGreg Clayton             result.AppendError ("Invalid target.  Must set target before setting breakpoints (see 'target create' command).");
41630fdc8d8SChris Lattner             result.SetStatus (eReturnStatusFailed);
41730fdc8d8SChris Lattner             return false;
41830fdc8d8SChris Lattner         }
41930fdc8d8SChris Lattner 
42030fdc8d8SChris Lattner         // The following are the various types of breakpoints that could be set:
42130fdc8d8SChris Lattner         //   1).  -f -l -p  [-s -g]   (setting breakpoint by source location)
42230fdc8d8SChris Lattner         //   2).  -a  [-s -g]         (setting breakpoint by address)
42330fdc8d8SChris Lattner         //   3).  -n  [-s -g]         (setting breakpoint by function name)
42430fdc8d8SChris Lattner         //   4).  -r  [-s -g]         (setting breakpoint by function name regular expression)
425969795f1SJim Ingham         //   5).  -p -f               (setting a breakpoint by comparing a reg-exp to source text)
426fab10e89SJim Ingham         //   6).  -E [-w -h]          (setting a breakpoint for exceptions for a given language.)
42730fdc8d8SChris Lattner 
42830fdc8d8SChris Lattner         BreakpointSetType break_type = eSetTypeInvalid;
42930fdc8d8SChris Lattner 
43030fdc8d8SChris Lattner         if (m_options.m_line_num != 0)
43130fdc8d8SChris Lattner             break_type = eSetTypeFileAndLine;
43230fdc8d8SChris Lattner         else if (m_options.m_load_addr != LLDB_INVALID_ADDRESS)
43330fdc8d8SChris Lattner             break_type = eSetTypeAddress;
434fab10e89SJim Ingham         else if (!m_options.m_func_names.empty())
43530fdc8d8SChris Lattner             break_type = eSetTypeFunctionName;
43630fdc8d8SChris Lattner         else if  (!m_options.m_func_regexp.empty())
43730fdc8d8SChris Lattner             break_type = eSetTypeFunctionRegexp;
438969795f1SJim Ingham         else if (!m_options.m_source_text_regexp.empty())
439969795f1SJim Ingham             break_type = eSetTypeSourceRegexp;
440*a72b31c7SJim Ingham         else if (m_options.m_exception_language != eLanguageTypeUnknown)
441fab10e89SJim Ingham             break_type = eSetTypeException;
44230fdc8d8SChris Lattner 
44330fdc8d8SChris Lattner         Breakpoint *bp = NULL;
444274060b6SGreg Clayton         FileSpec module_spec;
445a8558b62SJim Ingham         const bool internal = false;
446a8558b62SJim Ingham 
44730fdc8d8SChris Lattner         switch (break_type)
44830fdc8d8SChris Lattner         {
44930fdc8d8SChris Lattner             case eSetTypeFileAndLine: // Breakpoint by source position
45030fdc8d8SChris Lattner                 {
45130fdc8d8SChris Lattner                     FileSpec file;
452c7bece56SGreg Clayton                     const size_t num_files = m_options.m_filenames.GetSize();
45387df91b8SJim Ingham                     if (num_files == 0)
45487df91b8SJim Ingham                     {
45587df91b8SJim Ingham                         if (!GetDefaultFile (target, file, result))
45687df91b8SJim Ingham                         {
45787df91b8SJim Ingham                             result.AppendError("No file supplied and no default file available.");
45887df91b8SJim Ingham                             result.SetStatus (eReturnStatusFailed);
45987df91b8SJim Ingham                             return false;
46087df91b8SJim Ingham                         }
46187df91b8SJim Ingham                     }
46287df91b8SJim Ingham                     else if (num_files > 1)
46387df91b8SJim Ingham                     {
46487df91b8SJim Ingham                         result.AppendError("Only one file at a time is allowed for file and line breakpoints.");
46587df91b8SJim Ingham                         result.SetStatus (eReturnStatusFailed);
46687df91b8SJim Ingham                         return false;
46787df91b8SJim Ingham                     }
46887df91b8SJim Ingham                     else
46987df91b8SJim Ingham                         file = m_options.m_filenames.GetFileSpecAtIndex(0);
47030fdc8d8SChris Lattner 
4711f746071SGreg Clayton                     // Only check for inline functions if
4721f746071SGreg Clayton                     LazyBool check_inlines = eLazyBoolCalculate;
4731f746071SGreg Clayton 
47487df91b8SJim Ingham                     bp = target->CreateBreakpoint (&(m_options.m_modules),
47530fdc8d8SChris Lattner                                                    file,
47630fdc8d8SChris Lattner                                                    m_options.m_line_num,
4771f746071SGreg Clayton                                                    check_inlines,
478a8558b62SJim Ingham                                                    m_options.m_skip_prologue,
479eb023e75SGreg Clayton                                                    internal,
480eb023e75SGreg Clayton                                                    m_options.m_hardware).get();
48130fdc8d8SChris Lattner                 }
48230fdc8d8SChris Lattner                 break;
4836eee5aa0SGreg Clayton 
48430fdc8d8SChris Lattner             case eSetTypeAddress: // Breakpoint by address
485eb023e75SGreg Clayton                 bp = target->CreateBreakpoint (m_options.m_load_addr,
486eb023e75SGreg Clayton                                                internal,
487eb023e75SGreg Clayton                                                m_options.m_hardware).get();
48830fdc8d8SChris Lattner                 break;
4890c5cd90dSGreg Clayton 
49030fdc8d8SChris Lattner             case eSetTypeFunctionName: // Breakpoint by function name
4910c5cd90dSGreg Clayton                 {
4920c5cd90dSGreg Clayton                     uint32_t name_type_mask = m_options.m_func_name_type_mask;
4930c5cd90dSGreg Clayton 
4940c5cd90dSGreg Clayton                     if (name_type_mask == 0)
495e02b8504SGreg Clayton                         name_type_mask = eFunctionNameTypeAuto;
4960c5cd90dSGreg Clayton 
49787df91b8SJim Ingham                     bp = target->CreateBreakpoint (&(m_options.m_modules),
49887df91b8SJim Ingham                                                    &(m_options.m_filenames),
499fab10e89SJim Ingham                                                    m_options.m_func_names,
500274060b6SGreg Clayton                                                    name_type_mask,
501a8558b62SJim Ingham                                                    m_options.m_skip_prologue,
502eb023e75SGreg Clayton                                                    internal,
503eb023e75SGreg Clayton                                                    m_options.m_hardware).get();
5040c5cd90dSGreg Clayton                 }
50530fdc8d8SChris Lattner                 break;
5060c5cd90dSGreg Clayton 
50730fdc8d8SChris Lattner             case eSetTypeFunctionRegexp: // Breakpoint by regular expression function name
50830fdc8d8SChris Lattner                 {
50930fdc8d8SChris Lattner                     RegularExpression regexp(m_options.m_func_regexp.c_str());
510969795f1SJim Ingham                     if (!regexp.IsValid())
51130fdc8d8SChris Lattner                     {
512969795f1SJim Ingham                         char err_str[1024];
513969795f1SJim Ingham                         regexp.GetErrorAsCString(err_str, sizeof(err_str));
514969795f1SJim Ingham                         result.AppendErrorWithFormat("Function name regular expression could not be compiled: \"%s\"",
515969795f1SJim Ingham                                                      err_str);
51630fdc8d8SChris Lattner                         result.SetStatus (eReturnStatusFailed);
517969795f1SJim Ingham                         return false;
51830fdc8d8SChris Lattner                     }
51987df91b8SJim Ingham 
520a8558b62SJim Ingham                     bp = target->CreateFuncRegexBreakpoint (&(m_options.m_modules),
521a8558b62SJim Ingham                                                             &(m_options.m_filenames),
522a8558b62SJim Ingham                                                             regexp,
523a8558b62SJim Ingham                                                             m_options.m_skip_prologue,
524eb023e75SGreg Clayton                                                             internal,
525eb023e75SGreg Clayton                                                             m_options.m_hardware).get();
52630fdc8d8SChris Lattner                 }
52730fdc8d8SChris Lattner                 break;
528969795f1SJim Ingham             case eSetTypeSourceRegexp: // Breakpoint by regexp on source text.
529969795f1SJim Ingham                 {
530c7bece56SGreg Clayton                     const size_t num_files = m_options.m_filenames.GetSize();
53187df91b8SJim Ingham 
532e732052fSJim Ingham                     if (num_files == 0 && !m_options.m_all_files)
53387df91b8SJim Ingham                     {
534969795f1SJim Ingham                         FileSpec file;
53587df91b8SJim Ingham                         if (!GetDefaultFile (target, file, result))
53687df91b8SJim Ingham                         {
53787df91b8SJim Ingham                             result.AppendError ("No files provided and could not find default file.");
53887df91b8SJim Ingham                             result.SetStatus (eReturnStatusFailed);
53987df91b8SJim Ingham                             return false;
54087df91b8SJim Ingham                         }
54187df91b8SJim Ingham                         else
54287df91b8SJim Ingham                         {
54387df91b8SJim Ingham                             m_options.m_filenames.Append (file);
54487df91b8SJim Ingham                         }
54587df91b8SJim Ingham                     }
5460c5cd90dSGreg Clayton 
547969795f1SJim Ingham                     RegularExpression regexp(m_options.m_source_text_regexp.c_str());
548969795f1SJim Ingham                     if (!regexp.IsValid())
549969795f1SJim Ingham                     {
550969795f1SJim Ingham                         char err_str[1024];
551969795f1SJim Ingham                         regexp.GetErrorAsCString(err_str, sizeof(err_str));
552969795f1SJim Ingham                         result.AppendErrorWithFormat("Source text regular expression could not be compiled: \"%s\"",
553969795f1SJim Ingham                                                      err_str);
554969795f1SJim Ingham                         result.SetStatus (eReturnStatusFailed);
555969795f1SJim Ingham                         return false;
556969795f1SJim Ingham                     }
557eb023e75SGreg Clayton                     bp = target->CreateSourceRegexBreakpoint (&(m_options.m_modules),
558eb023e75SGreg Clayton                                                               &(m_options.m_filenames),
559eb023e75SGreg Clayton                                                               regexp,
560eb023e75SGreg Clayton                                                               internal,
561eb023e75SGreg Clayton                                                               m_options.m_hardware).get();
562969795f1SJim Ingham                 }
563969795f1SJim Ingham                 break;
564fab10e89SJim Ingham             case eSetTypeException:
565fab10e89SJim Ingham                 {
566*a72b31c7SJim Ingham                     Error precond_error;
567*a72b31c7SJim Ingham                     bp = target->CreateExceptionBreakpoint (m_options.m_exception_language,
568eb023e75SGreg Clayton                                                             m_options.m_catch_bp,
569eb023e75SGreg Clayton                                                             m_options.m_throw_bp,
570*a72b31c7SJim Ingham                                                             internal,
571*a72b31c7SJim Ingham                                                             &m_options.m_exception_extra_args,
572*a72b31c7SJim Ingham                                                             &precond_error).get();
573*a72b31c7SJim Ingham                     if (precond_error.Fail())
574*a72b31c7SJim Ingham                     {
575*a72b31c7SJim Ingham                         result.AppendErrorWithFormat("Error setting extra exception arguments: %s",
576*a72b31c7SJim Ingham                                                      precond_error.AsCString());
577*a72b31c7SJim Ingham                         target->RemoveBreakpointByID(bp->GetID());
578*a72b31c7SJim Ingham                         result.SetStatus(eReturnStatusFailed);
579*a72b31c7SJim Ingham                         return false;
580*a72b31c7SJim Ingham                     }
581fab10e89SJim Ingham                 }
582fab10e89SJim Ingham                 break;
58330fdc8d8SChris Lattner             default:
58430fdc8d8SChris Lattner                 break;
58530fdc8d8SChris Lattner         }
58630fdc8d8SChris Lattner 
5871b54c88cSJim Ingham         // Now set the various options that were passed in:
5881b54c88cSJim Ingham         if (bp)
5891b54c88cSJim Ingham         {
5901b54c88cSJim Ingham             if (m_options.m_thread_id != LLDB_INVALID_THREAD_ID)
5911b54c88cSJim Ingham                 bp->SetThreadID (m_options.m_thread_id);
5921b54c88cSJim Ingham 
593c982c768SGreg Clayton             if (m_options.m_thread_index != UINT32_MAX)
5941b54c88cSJim Ingham                 bp->GetOptions()->GetThreadSpec()->SetIndex(m_options.m_thread_index);
5951b54c88cSJim Ingham 
5961b54c88cSJim Ingham             if (!m_options.m_thread_name.empty())
5971b54c88cSJim Ingham                 bp->GetOptions()->GetThreadSpec()->SetName(m_options.m_thread_name.c_str());
5981b54c88cSJim Ingham 
5991b54c88cSJim Ingham             if (!m_options.m_queue_name.empty())
6001b54c88cSJim Ingham                 bp->GetOptions()->GetThreadSpec()->SetQueueName(m_options.m_queue_name.c_str());
6011b54c88cSJim Ingham 
602c982c768SGreg Clayton             if (m_options.m_ignore_count != 0)
6031b54c88cSJim Ingham                 bp->GetOptions()->SetIgnoreCount(m_options.m_ignore_count);
6047d49c9c8SJohnny Chen 
6057d49c9c8SJohnny Chen             if (!m_options.m_condition.empty())
6067d49c9c8SJohnny Chen                 bp->GetOptions()->SetCondition(m_options.m_condition.c_str());
607ca36cd16SJim Ingham 
6085e09c8c3SJim Ingham             if (!m_options.m_breakpoint_names.empty())
6095e09c8c3SJim Ingham             {
6105e09c8c3SJim Ingham                 Error error;  // We don't need to check the error here, since the option parser checked it...
6115e09c8c3SJim Ingham                 for (auto name : m_options.m_breakpoint_names)
6125e09c8c3SJim Ingham                     bp->AddName(name.c_str(), error);
6135e09c8c3SJim Ingham             }
6145e09c8c3SJim Ingham 
615ca36cd16SJim Ingham             bp->SetOneShot (m_options.m_one_shot);
6161b54c88cSJim Ingham         }
6171b54c88cSJim Ingham 
618969795f1SJim Ingham         if (bp)
61930fdc8d8SChris Lattner         {
62085e8b814SJim Ingham             Stream &output_stream = result.GetOutputStream();
6211391cc7dSJim Ingham             const bool show_locations = false;
6221391cc7dSJim Ingham             bp->GetDescription(&output_stream, lldb::eDescriptionLevelInitial, show_locations);
6234aeb1989SJim Ingham             if (target == m_interpreter.GetDebugger().GetDummyTarget())
6244aeb1989SJim Ingham                     output_stream.Printf ("Breakpoint set in dummy target, will get copied into future targets.\n");
6254aeb1989SJim Ingham             else
6264aeb1989SJim Ingham             {
627fab10e89SJim Ingham                 // Don't print out this warning for exception breakpoints.  They can get set before the target
628fab10e89SJim Ingham                 // is set, but we won't know how to actually set the breakpoint till we run.
629fab10e89SJim Ingham                 if (bp->GetNumLocations() == 0 && break_type != eSetTypeException)
6304aeb1989SJim Ingham                 {
631be484f41SCaroline Tice                     output_stream.Printf ("WARNING:  Unable to resolve breakpoint to any actual locations.\n");
6324aeb1989SJim Ingham                 }
6334aeb1989SJim Ingham             }
63430fdc8d8SChris Lattner             result.SetStatus (eReturnStatusSuccessFinishResult);
63530fdc8d8SChris Lattner         }
63630fdc8d8SChris Lattner         else if (!bp)
63730fdc8d8SChris Lattner         {
63830fdc8d8SChris Lattner             result.AppendError ("Breakpoint creation failed: No breakpoint created.");
63930fdc8d8SChris Lattner             result.SetStatus (eReturnStatusFailed);
64030fdc8d8SChris Lattner         }
64130fdc8d8SChris Lattner 
64230fdc8d8SChris Lattner         return result.Succeeded();
64330fdc8d8SChris Lattner     }
64430fdc8d8SChris Lattner 
6455a988416SJim Ingham private:
6465a988416SJim Ingham     bool
6475a988416SJim Ingham     GetDefaultFile (Target *target, FileSpec &file, CommandReturnObject &result)
6485a988416SJim Ingham     {
6495a988416SJim Ingham         uint32_t default_line;
6505a988416SJim Ingham         // First use the Source Manager's default file.
6515a988416SJim Ingham         // Then use the current stack frame's file.
6525a988416SJim Ingham         if (!target->GetSourceManager().GetDefaultFileAndLine(file, default_line))
6535a988416SJim Ingham         {
654b57e4a1bSJason Molenda             StackFrame *cur_frame = m_exe_ctx.GetFramePtr();
6555a988416SJim Ingham             if (cur_frame == NULL)
6565a988416SJim Ingham             {
6575a988416SJim Ingham                 result.AppendError ("No selected frame to use to find the default file.");
6585a988416SJim Ingham                 result.SetStatus (eReturnStatusFailed);
6595a988416SJim Ingham                 return false;
6605a988416SJim Ingham             }
6615a988416SJim Ingham             else if (!cur_frame->HasDebugInformation())
6625a988416SJim Ingham             {
6635a988416SJim Ingham                 result.AppendError ("Cannot use the selected frame to find the default file, it has no debug info.");
6645a988416SJim Ingham                 result.SetStatus (eReturnStatusFailed);
6655a988416SJim Ingham                 return false;
6665a988416SJim Ingham             }
6675a988416SJim Ingham             else
6685a988416SJim Ingham             {
6695a988416SJim Ingham                 const SymbolContext &sc = cur_frame->GetSymbolContext (eSymbolContextLineEntry);
6705a988416SJim Ingham                 if (sc.line_entry.file)
6715a988416SJim Ingham                 {
6725a988416SJim Ingham                     file = sc.line_entry.file;
6735a988416SJim Ingham                 }
6745a988416SJim Ingham                 else
6755a988416SJim Ingham                 {
6765a988416SJim Ingham                     result.AppendError ("Can't find the file for the selected frame to use as the default file.");
6775a988416SJim Ingham                     result.SetStatus (eReturnStatusFailed);
6785a988416SJim Ingham                     return false;
6795a988416SJim Ingham                 }
6805a988416SJim Ingham             }
6815a988416SJim Ingham         }
6825a988416SJim Ingham         return true;
6835a988416SJim Ingham     }
6845a988416SJim Ingham 
6855a988416SJim Ingham     CommandOptions m_options;
6865a988416SJim Ingham };
6875a988416SJim Ingham // If an additional option set beyond LLDB_OPTION_SET_10 is added, make sure to
6885a988416SJim Ingham // update the numbers passed to LLDB_OPT_SET_FROM_TO(...) appropriately.
6895a988416SJim Ingham #define LLDB_OPT_FILE ( LLDB_OPT_SET_FROM_TO(1, 9) & ~LLDB_OPT_SET_2 )
6905a988416SJim Ingham #define LLDB_OPT_NOT_10 ( LLDB_OPT_SET_FROM_TO(1, 10) & ~LLDB_OPT_SET_10 )
6915a988416SJim Ingham #define LLDB_OPT_SKIP_PROLOGUE ( LLDB_OPT_SET_1 | LLDB_OPT_SET_FROM_TO(3,8) )
6925a988416SJim Ingham 
6935a988416SJim Ingham OptionDefinition
6945a988416SJim Ingham CommandObjectBreakpointSet::CommandOptions::g_option_table[] =
6955a988416SJim Ingham {
696d37221dcSZachary Turner     { LLDB_OPT_NOT_10, false, "shlib", 's', OptionParser::eRequiredArgument, NULL, NULL, CommandCompletions::eModuleCompletion, eArgTypeShlibName,
6975a988416SJim Ingham         "Set the breakpoint only in this shared library.  "
6985a988416SJim Ingham         "Can repeat this option multiple times to specify multiple shared libraries."},
6995a988416SJim Ingham 
700d37221dcSZachary Turner     { LLDB_OPT_SET_ALL, false, "ignore-count", 'i', OptionParser::eRequiredArgument,   NULL, NULL, 0, eArgTypeCount,
7015a988416SJim Ingham         "Set the number of times this breakpoint is skipped before stopping." },
7025a988416SJim Ingham 
703d37221dcSZachary Turner     { LLDB_OPT_SET_ALL, false, "one-shot", 'o', OptionParser::eNoArgument,   NULL, NULL, 0, eArgTypeNone,
704b2b256afSJim Ingham         "The breakpoint is deleted the first time it causes a stop." },
705ca36cd16SJim Ingham 
706d37221dcSZachary Turner     { LLDB_OPT_SET_ALL, false, "condition",    'c', OptionParser::eRequiredArgument, NULL, NULL, 0, eArgTypeExpression,
7075a988416SJim Ingham         "The breakpoint stops only if this condition expression evaluates to true."},
7085a988416SJim Ingham 
709d37221dcSZachary Turner     { LLDB_OPT_SET_ALL, false, "thread-index", 'x', OptionParser::eRequiredArgument, NULL, NULL, 0, eArgTypeThreadIndex,
710a89be91fSJim Ingham         "The breakpoint stops only for the thread whose indeX matches this argument."},
7115a988416SJim Ingham 
712d37221dcSZachary Turner     { LLDB_OPT_SET_ALL, false, "thread-id", 't', OptionParser::eRequiredArgument, NULL, NULL, 0, eArgTypeThreadID,
7135a988416SJim Ingham         "The breakpoint stops only for the thread whose TID matches this argument."},
7145a988416SJim Ingham 
715d37221dcSZachary Turner     { LLDB_OPT_SET_ALL, false, "thread-name", 'T', OptionParser::eRequiredArgument, NULL, NULL, 0, eArgTypeThreadName,
7165a988416SJim Ingham         "The breakpoint stops only for the thread whose thread name matches this argument."},
7175a988416SJim Ingham 
718d37221dcSZachary Turner     { LLDB_OPT_SET_ALL, false, "hardware", 'H', OptionParser::eNoArgument, NULL, NULL, 0, eArgTypeNone,
719eb023e75SGreg Clayton         "Require the breakpoint to use hardware breakpoints."},
720eb023e75SGreg Clayton 
721d37221dcSZachary Turner     { LLDB_OPT_SET_ALL, false, "queue-name", 'q', OptionParser::eRequiredArgument, NULL, NULL, 0, eArgTypeQueueName,
7225a988416SJim Ingham         "The breakpoint stops only for threads in the queue whose name is given by this argument."},
7235a988416SJim Ingham 
724d37221dcSZachary Turner     { LLDB_OPT_FILE, false, "file", 'f', OptionParser::eRequiredArgument, NULL, NULL, CommandCompletions::eSourceFileCompletion, eArgTypeFilename,
725289aca64SJim Ingham         "Specifies the source file in which to set this breakpoint.  "
726289aca64SJim Ingham         "Note, by default lldb only looks for files that are #included if they use the standard include file extensions.  "
7276394479eSJim Ingham         "To set breakpoints on .c/.cpp/.m/.mm files that are #included, set target.inline-breakpoint-strategy"
728289aca64SJim Ingham         " to \"always\"."},
7295a988416SJim Ingham 
730d37221dcSZachary Turner     { LLDB_OPT_SET_1, true, "line", 'l', OptionParser::eRequiredArgument, NULL, NULL, 0, eArgTypeLineNum,
7315a988416SJim Ingham         "Specifies the line number on which to set this breakpoint."},
7325a988416SJim Ingham 
7335a988416SJim Ingham     // Comment out this option for the moment, as we don't actually use it, but will in the future.
7345a988416SJim Ingham     // This way users won't see it, but the infrastructure is left in place.
735e2607b50SVirgile Bello     //    { 0, false, "column",     'C', OptionParser::eRequiredArgument, NULL, "<column>",
7365a988416SJim Ingham     //    "Set the breakpoint by source location at this particular column."},
7375a988416SJim Ingham 
738d37221dcSZachary Turner     { LLDB_OPT_SET_2, true, "address", 'a', OptionParser::eRequiredArgument, NULL, NULL, 0, eArgTypeAddressOrExpression,
7395a988416SJim Ingham         "Set the breakpoint by address, at the specified address."},
7405a988416SJim Ingham 
741d37221dcSZachary Turner     { LLDB_OPT_SET_3, true, "name", 'n', OptionParser::eRequiredArgument, NULL, NULL, CommandCompletions::eSymbolCompletion, eArgTypeFunctionName,
742551262d7SJim Ingham         "Set the breakpoint by function name.  Can be repeated multiple times to make one breakpoint for multiple names" },
7435a988416SJim Ingham 
744d37221dcSZachary Turner     { LLDB_OPT_SET_4, true, "fullname", 'F', OptionParser::eRequiredArgument, NULL, NULL, CommandCompletions::eSymbolCompletion, eArgTypeFullName,
7455a988416SJim Ingham         "Set the breakpoint by fully qualified function names. For C++ this means namespaces and all arguments, and "
7465a988416SJim Ingham         "for Objective C this means a full function prototype with class and selector.   "
7475a988416SJim Ingham         "Can be repeated multiple times to make one breakpoint for multiple names." },
7485a988416SJim Ingham 
749d37221dcSZachary Turner     { LLDB_OPT_SET_5, true, "selector", 'S', OptionParser::eRequiredArgument, NULL, NULL, 0, eArgTypeSelector,
7505a988416SJim Ingham         "Set the breakpoint by ObjC selector name. Can be repeated multiple times to make one breakpoint for multiple Selectors." },
7515a988416SJim Ingham 
752d37221dcSZachary Turner     { LLDB_OPT_SET_6, true, "method", 'M', OptionParser::eRequiredArgument, NULL, NULL, 0, eArgTypeMethod,
7535a988416SJim Ingham         "Set the breakpoint by C++ method names.  Can be repeated multiple times to make one breakpoint for multiple methods." },
7545a988416SJim Ingham 
755d37221dcSZachary Turner     { LLDB_OPT_SET_7, true, "func-regex", 'r', OptionParser::eRequiredArgument, NULL, NULL, 0, eArgTypeRegularExpression,
7565a988416SJim Ingham         "Set the breakpoint by function name, evaluating a regular-expression to find the function name(s)." },
7575a988416SJim Ingham 
758d37221dcSZachary Turner     { LLDB_OPT_SET_8, true, "basename", 'b', OptionParser::eRequiredArgument, NULL, NULL, CommandCompletions::eSymbolCompletion, eArgTypeFunctionName,
7595a988416SJim Ingham         "Set the breakpoint by function basename (C++ namespaces and arguments will be ignored). "
7605a988416SJim Ingham         "Can be repeated multiple times to make one breakpoint for multiple symbols." },
7615a988416SJim Ingham 
762d37221dcSZachary Turner     { LLDB_OPT_SET_9, true, "source-pattern-regexp", 'p', OptionParser::eRequiredArgument, NULL, NULL, 0, eArgTypeRegularExpression,
763e96ade8bSJim Ingham         "Set the breakpoint by specifying a regular expression which is matched against the source text in a source file or files "
764e96ade8bSJim Ingham         "specified with the -f option.  The -f option can be specified more than once.  "
765e96ade8bSJim Ingham         "If no source files are specified, uses the current \"default source file\"" },
7665a988416SJim Ingham 
767e732052fSJim Ingham     { LLDB_OPT_SET_9, false, "all-files", 'A', OptionParser::eNoArgument,   NULL, NULL, 0, eArgTypeNone,
768e732052fSJim Ingham         "All files are searched for source pattern matches." },
769e732052fSJim Ingham 
770d37221dcSZachary Turner     { LLDB_OPT_SET_10, true, "language-exception", 'E', OptionParser::eRequiredArgument, NULL, NULL, 0, eArgTypeLanguage,
7715a988416SJim Ingham         "Set the breakpoint on exceptions thrown by the specified language (without options, on throw but not catch.)" },
7725a988416SJim Ingham 
773d37221dcSZachary Turner     { LLDB_OPT_SET_10, false, "on-throw", 'w', OptionParser::eRequiredArgument, NULL, NULL, 0, eArgTypeBoolean,
7745a988416SJim Ingham         "Set the breakpoint on exception throW." },
7755a988416SJim Ingham 
776d37221dcSZachary Turner     { LLDB_OPT_SET_10, false, "on-catch", 'h', OptionParser::eRequiredArgument, NULL, NULL, 0, eArgTypeBoolean,
7775a988416SJim Ingham         "Set the breakpoint on exception catcH." },
7785a988416SJim Ingham 
779*a72b31c7SJim Ingham //  Don't add this option till it actually does something useful...
780*a72b31c7SJim Ingham //    { LLDB_OPT_SET_10, false, "exception-typename", 'O', OptionParser::eRequiredArgument, NULL, NULL, 0, eArgTypeTypeName,
781*a72b31c7SJim Ingham //        "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" },
782*a72b31c7SJim Ingham 
783d37221dcSZachary Turner     { LLDB_OPT_SKIP_PROLOGUE, false, "skip-prologue", 'K', OptionParser::eRequiredArgument, NULL, NULL, 0, eArgTypeBoolean,
7845a988416SJim Ingham         "sKip the prologue if the breakpoint is at the beginning of a function.  If not set the target.skip-prologue setting is used." },
7855a988416SJim Ingham 
78633df7cd3SJim Ingham     { LLDB_OPT_SET_ALL, false, "dummy-breakpoints", 'D', OptionParser::eNoArgument, NULL, NULL, 0, eArgTypeNone,
78733df7cd3SJim Ingham         "Sets Dummy breakpoints - i.e. breakpoints set before a file is provided, which prime new targets."},
78833df7cd3SJim Ingham 
7895e09c8c3SJim Ingham     { LLDB_OPT_SET_ALL, false, "breakpoint-name", 'N', OptionParser::eRequiredArgument, NULL, NULL, 0, eArgTypeBreakpointName,
7905e09c8c3SJim Ingham         "Adds this to the list of names for this breakopint."},
7915e09c8c3SJim Ingham 
792d37221dcSZachary Turner     { 0, false, NULL, 0, 0, NULL, NULL, 0, eArgTypeNone, NULL }
7935a988416SJim Ingham };
7945a988416SJim Ingham 
7955a988416SJim Ingham //-------------------------------------------------------------------------
7965a988416SJim Ingham // CommandObjectBreakpointModify
7975a988416SJim Ingham //-------------------------------------------------------------------------
7985a988416SJim Ingham #pragma mark Modify
7995a988416SJim Ingham 
8005a988416SJim Ingham class CommandObjectBreakpointModify : public CommandObjectParsed
8015a988416SJim Ingham {
8025a988416SJim Ingham public:
8035a988416SJim Ingham 
8045a988416SJim Ingham     CommandObjectBreakpointModify (CommandInterpreter &interpreter) :
8055a988416SJim Ingham         CommandObjectParsed (interpreter,
8065a988416SJim Ingham                              "breakpoint modify",
8075a988416SJim Ingham                              "Modify the options on a breakpoint or set of breakpoints in the executable.  "
8085a988416SJim Ingham                              "If no breakpoint is specified, acts on the last created breakpoint.  "
8095a988416SJim Ingham                              "With the exception of -e, -d and -i, passing an empty argument clears the modification.",
8105a988416SJim Ingham                              NULL),
8115a988416SJim Ingham         m_options (interpreter)
8125a988416SJim Ingham     {
8135a988416SJim Ingham         CommandArgumentEntry arg;
8145a988416SJim Ingham         CommandObject::AddIDsArgumentData(arg, eArgTypeBreakpointID, eArgTypeBreakpointIDRange);
8155a988416SJim Ingham         // Add the entry for the first argument for this command to the object's arguments vector.
8165a988416SJim Ingham         m_arguments.push_back (arg);
8175a988416SJim Ingham     }
8185a988416SJim Ingham 
8195a988416SJim Ingham 
8205a988416SJim Ingham     virtual
8215a988416SJim Ingham     ~CommandObjectBreakpointModify () {}
8225a988416SJim Ingham 
8235a988416SJim Ingham     virtual Options *
8245a988416SJim Ingham     GetOptions ()
8255a988416SJim Ingham     {
8265a988416SJim Ingham         return &m_options;
8275a988416SJim Ingham     }
8285a988416SJim Ingham 
8295a988416SJim Ingham     class CommandOptions : public Options
8305a988416SJim Ingham     {
8315a988416SJim Ingham     public:
8325a988416SJim Ingham 
8335a988416SJim Ingham         CommandOptions (CommandInterpreter &interpreter) :
8345a988416SJim Ingham             Options (interpreter),
8355a988416SJim Ingham             m_ignore_count (0),
8365a988416SJim Ingham             m_thread_id(LLDB_INVALID_THREAD_ID),
8375a988416SJim Ingham             m_thread_id_passed(false),
8385a988416SJim Ingham             m_thread_index (UINT32_MAX),
8395a988416SJim Ingham             m_thread_index_passed(false),
8405a988416SJim Ingham             m_thread_name(),
8415a988416SJim Ingham             m_queue_name(),
8425a988416SJim Ingham             m_condition (),
843ca36cd16SJim Ingham             m_one_shot (false),
8445a988416SJim Ingham             m_enable_passed (false),
8455a988416SJim Ingham             m_enable_value (false),
8465a988416SJim Ingham             m_name_passed (false),
8475a988416SJim Ingham             m_queue_passed (false),
848ca36cd16SJim Ingham             m_condition_passed (false),
84933df7cd3SJim Ingham             m_one_shot_passed (false),
85033df7cd3SJim Ingham             m_use_dummy (false)
8515a988416SJim Ingham         {
8525a988416SJim Ingham         }
8535a988416SJim Ingham 
8545a988416SJim Ingham         virtual
8555a988416SJim Ingham         ~CommandOptions () {}
8565a988416SJim Ingham 
8575a988416SJim Ingham         virtual Error
8585a988416SJim Ingham         SetOptionValue (uint32_t option_idx, const char *option_arg)
8595a988416SJim Ingham         {
8605a988416SJim Ingham             Error error;
8613bcdfc0eSGreg Clayton             const int short_option = m_getopt_table[option_idx].val;
8625a988416SJim Ingham 
8635a988416SJim Ingham             switch (short_option)
8645a988416SJim Ingham             {
8655a988416SJim Ingham                 case 'c':
8665a988416SJim Ingham                     if (option_arg != NULL)
8675a988416SJim Ingham                         m_condition.assign (option_arg);
8685a988416SJim Ingham                     else
8695a988416SJim Ingham                         m_condition.clear();
8705a988416SJim Ingham                     m_condition_passed = true;
8715a988416SJim Ingham                     break;
8725a988416SJim Ingham                 case 'd':
8735a988416SJim Ingham                     m_enable_passed = true;
8745a988416SJim Ingham                     m_enable_value = false;
8755a988416SJim Ingham                     break;
87633df7cd3SJim Ingham                 case 'D':
87733df7cd3SJim Ingham                     m_use_dummy = true;
87833df7cd3SJim Ingham                     break;
8795a988416SJim Ingham                 case 'e':
8805a988416SJim Ingham                     m_enable_passed = true;
8815a988416SJim Ingham                     m_enable_value = true;
8825a988416SJim Ingham                     break;
8835a988416SJim Ingham                 case 'i':
8845a988416SJim Ingham                 {
8855275aaa0SVince Harron                     m_ignore_count = StringConvert::ToUInt32(option_arg, UINT32_MAX, 0);
8865a988416SJim Ingham                     if (m_ignore_count == UINT32_MAX)
8875a988416SJim Ingham                        error.SetErrorStringWithFormat ("invalid ignore count '%s'", option_arg);
8885a988416SJim Ingham                 }
8895a988416SJim Ingham                 break;
890ca36cd16SJim Ingham                 case 'o':
891ca36cd16SJim Ingham                 {
892ca36cd16SJim Ingham                     bool value, success;
893ca36cd16SJim Ingham                     value = Args::StringToBoolean(option_arg, false, &success);
894ca36cd16SJim Ingham                     if (success)
895ca36cd16SJim Ingham                     {
896ca36cd16SJim Ingham                         m_one_shot_passed = true;
897ca36cd16SJim Ingham                         m_one_shot = value;
898ca36cd16SJim Ingham                     }
899ca36cd16SJim Ingham                     else
900ca36cd16SJim Ingham                         error.SetErrorStringWithFormat("invalid boolean value '%s' passed for -o option", option_arg);
901ca36cd16SJim Ingham                 }
902ca36cd16SJim Ingham                 break;
9035a988416SJim Ingham                 case 't' :
9045a988416SJim Ingham                 {
9055a988416SJim Ingham                     if (option_arg[0] == '\0')
9065a988416SJim Ingham                     {
9075a988416SJim Ingham                         m_thread_id = LLDB_INVALID_THREAD_ID;
9085a988416SJim Ingham                         m_thread_id_passed = true;
9095a988416SJim Ingham                     }
9105a988416SJim Ingham                     else
9115a988416SJim Ingham                     {
9125275aaa0SVince Harron                         m_thread_id = StringConvert::ToUInt64(option_arg, LLDB_INVALID_THREAD_ID, 0);
9135a988416SJim Ingham                         if (m_thread_id == LLDB_INVALID_THREAD_ID)
9145a988416SJim Ingham                            error.SetErrorStringWithFormat ("invalid thread id string '%s'", option_arg);
9155a988416SJim Ingham                         else
9165a988416SJim Ingham                             m_thread_id_passed = true;
9175a988416SJim Ingham                     }
9185a988416SJim Ingham                 }
9195a988416SJim Ingham                 break;
9205a988416SJim Ingham                 case 'T':
9215a988416SJim Ingham                     if (option_arg != NULL)
9225a988416SJim Ingham                         m_thread_name.assign (option_arg);
9235a988416SJim Ingham                     else
9245a988416SJim Ingham                         m_thread_name.clear();
9255a988416SJim Ingham                     m_name_passed = true;
9265a988416SJim Ingham                     break;
9275a988416SJim Ingham                 case 'q':
9285a988416SJim Ingham                     if (option_arg != NULL)
9295a988416SJim Ingham                         m_queue_name.assign (option_arg);
9305a988416SJim Ingham                     else
9315a988416SJim Ingham                         m_queue_name.clear();
9325a988416SJim Ingham                     m_queue_passed = true;
9335a988416SJim Ingham                     break;
9345a988416SJim Ingham                 case 'x':
9355a988416SJim Ingham                 {
9365a988416SJim Ingham                     if (option_arg[0] == '\n')
9375a988416SJim Ingham                     {
9385a988416SJim Ingham                         m_thread_index = UINT32_MAX;
9395a988416SJim Ingham                         m_thread_index_passed = true;
9405a988416SJim Ingham                     }
9415a988416SJim Ingham                     else
9425a988416SJim Ingham                     {
9435275aaa0SVince Harron                         m_thread_index = StringConvert::ToUInt32 (option_arg, UINT32_MAX, 0);
9445a988416SJim Ingham                         if (m_thread_id == UINT32_MAX)
9455a988416SJim Ingham                            error.SetErrorStringWithFormat ("invalid thread index string '%s'", option_arg);
9465a988416SJim Ingham                         else
9475a988416SJim Ingham                             m_thread_index_passed = true;
9485a988416SJim Ingham                     }
9495a988416SJim Ingham                 }
9505a988416SJim Ingham                 break;
9515a988416SJim Ingham                 default:
9525a988416SJim Ingham                     error.SetErrorStringWithFormat ("unrecognized option '%c'", short_option);
9535a988416SJim Ingham                     break;
9545a988416SJim Ingham             }
9555a988416SJim Ingham 
9565a988416SJim Ingham             return error;
9575a988416SJim Ingham         }
9585a988416SJim Ingham         void
9595a988416SJim Ingham         OptionParsingStarting ()
9605a988416SJim Ingham         {
9615a988416SJim Ingham             m_ignore_count = 0;
9625a988416SJim Ingham             m_thread_id = LLDB_INVALID_THREAD_ID;
9635a988416SJim Ingham             m_thread_id_passed = false;
9645a988416SJim Ingham             m_thread_index = UINT32_MAX;
9655a988416SJim Ingham             m_thread_index_passed = false;
9665a988416SJim Ingham             m_thread_name.clear();
9675a988416SJim Ingham             m_queue_name.clear();
9685a988416SJim Ingham             m_condition.clear();
969ca36cd16SJim Ingham             m_one_shot = false;
9705a988416SJim Ingham             m_enable_passed = false;
9715a988416SJim Ingham             m_queue_passed = false;
9725a988416SJim Ingham             m_name_passed = false;
9735a988416SJim Ingham             m_condition_passed = false;
974ca36cd16SJim Ingham             m_one_shot_passed = false;
97533df7cd3SJim Ingham             m_use_dummy = false;
9765a988416SJim Ingham         }
9775a988416SJim Ingham 
9785a988416SJim Ingham         const OptionDefinition*
9795a988416SJim Ingham         GetDefinitions ()
9805a988416SJim Ingham         {
9815a988416SJim Ingham             return g_option_table;
9825a988416SJim Ingham         }
9835a988416SJim Ingham 
9845a988416SJim Ingham 
9855a988416SJim Ingham         // Options table: Required for subclasses of Options.
9865a988416SJim Ingham 
9875a988416SJim Ingham         static OptionDefinition g_option_table[];
9885a988416SJim Ingham 
9895a988416SJim Ingham         // Instance variables to hold the values for command options.
9905a988416SJim Ingham 
9915a988416SJim Ingham         uint32_t m_ignore_count;
9925a988416SJim Ingham         lldb::tid_t m_thread_id;
9935a988416SJim Ingham         bool m_thread_id_passed;
9945a988416SJim Ingham         uint32_t m_thread_index;
9955a988416SJim Ingham         bool m_thread_index_passed;
9965a988416SJim Ingham         std::string m_thread_name;
9975a988416SJim Ingham         std::string m_queue_name;
9985a988416SJim Ingham         std::string m_condition;
999ca36cd16SJim Ingham         bool m_one_shot;
10005a988416SJim Ingham         bool m_enable_passed;
10015a988416SJim Ingham         bool m_enable_value;
10025a988416SJim Ingham         bool m_name_passed;
10035a988416SJim Ingham         bool m_queue_passed;
10045a988416SJim Ingham         bool m_condition_passed;
1005ca36cd16SJim Ingham         bool m_one_shot_passed;
100633df7cd3SJim Ingham         bool m_use_dummy;
10075a988416SJim Ingham 
10085a988416SJim Ingham     };
10095a988416SJim Ingham 
10105a988416SJim Ingham protected:
10115a988416SJim Ingham     virtual bool
10125a988416SJim Ingham     DoExecute (Args& command, CommandReturnObject &result)
10135a988416SJim Ingham     {
101433df7cd3SJim Ingham         Target *target = GetSelectedOrDummyTarget(m_options.m_use_dummy);
10155a988416SJim Ingham         if (target == NULL)
10165a988416SJim Ingham         {
10175a988416SJim Ingham             result.AppendError ("Invalid target.  No existing target or breakpoints.");
10185a988416SJim Ingham             result.SetStatus (eReturnStatusFailed);
10195a988416SJim Ingham             return false;
10205a988416SJim Ingham         }
10215a988416SJim Ingham 
10225a988416SJim Ingham         Mutex::Locker locker;
10235a988416SJim Ingham         target->GetBreakpointList().GetListMutex(locker);
10245a988416SJim Ingham 
10255a988416SJim Ingham         BreakpointIDList valid_bp_ids;
10265a988416SJim Ingham 
10275e09c8c3SJim Ingham         CommandObjectMultiwordBreakpoint::VerifyBreakpointOrLocationIDs (command, target, result, &valid_bp_ids);
10285a988416SJim Ingham 
10295a988416SJim Ingham         if (result.Succeeded())
10305a988416SJim Ingham         {
10315a988416SJim Ingham             const size_t count = valid_bp_ids.GetSize();
10325a988416SJim Ingham             for (size_t i = 0; i < count; ++i)
10335a988416SJim Ingham             {
10345a988416SJim Ingham                 BreakpointID cur_bp_id = valid_bp_ids.GetBreakpointIDAtIndex (i);
10355a988416SJim Ingham 
10365a988416SJim Ingham                 if (cur_bp_id.GetBreakpointID() != LLDB_INVALID_BREAK_ID)
10375a988416SJim Ingham                 {
10385a988416SJim Ingham                     Breakpoint *bp = target->GetBreakpointByID (cur_bp_id.GetBreakpointID()).get();
10395a988416SJim Ingham                     if (cur_bp_id.GetLocationID() != LLDB_INVALID_BREAK_ID)
10405a988416SJim Ingham                     {
10415a988416SJim Ingham                         BreakpointLocation *location = bp->FindLocationByID (cur_bp_id.GetLocationID()).get();
10425a988416SJim Ingham                         if (location)
10435a988416SJim Ingham                         {
10445a988416SJim Ingham                             if (m_options.m_thread_id_passed)
10455a988416SJim Ingham                                 location->SetThreadID (m_options.m_thread_id);
10465a988416SJim Ingham 
10475a988416SJim Ingham                             if (m_options.m_thread_index_passed)
10485a988416SJim Ingham                                 location->SetThreadIndex(m_options.m_thread_index);
10495a988416SJim Ingham 
10505a988416SJim Ingham                             if (m_options.m_name_passed)
10515a988416SJim Ingham                                 location->SetThreadName(m_options.m_thread_name.c_str());
10525a988416SJim Ingham 
10535a988416SJim Ingham                             if (m_options.m_queue_passed)
10545a988416SJim Ingham                                 location->SetQueueName(m_options.m_queue_name.c_str());
10555a988416SJim Ingham 
10565a988416SJim Ingham                             if (m_options.m_ignore_count != 0)
10575a988416SJim Ingham                                 location->SetIgnoreCount(m_options.m_ignore_count);
10585a988416SJim Ingham 
10595a988416SJim Ingham                             if (m_options.m_enable_passed)
10605a988416SJim Ingham                                 location->SetEnabled (m_options.m_enable_value);
10615a988416SJim Ingham 
10625a988416SJim Ingham                             if (m_options.m_condition_passed)
10635a988416SJim Ingham                                 location->SetCondition (m_options.m_condition.c_str());
10645a988416SJim Ingham                         }
10655a988416SJim Ingham                     }
10665a988416SJim Ingham                     else
10675a988416SJim Ingham                     {
10685a988416SJim Ingham                         if (m_options.m_thread_id_passed)
10695a988416SJim Ingham                             bp->SetThreadID (m_options.m_thread_id);
10705a988416SJim Ingham 
10715a988416SJim Ingham                         if (m_options.m_thread_index_passed)
10725a988416SJim Ingham                             bp->SetThreadIndex(m_options.m_thread_index);
10735a988416SJim Ingham 
10745a988416SJim Ingham                         if (m_options.m_name_passed)
10755a988416SJim Ingham                             bp->SetThreadName(m_options.m_thread_name.c_str());
10765a988416SJim Ingham 
10775a988416SJim Ingham                         if (m_options.m_queue_passed)
10785a988416SJim Ingham                             bp->SetQueueName(m_options.m_queue_name.c_str());
10795a988416SJim Ingham 
10805a988416SJim Ingham                         if (m_options.m_ignore_count != 0)
10815a988416SJim Ingham                             bp->SetIgnoreCount(m_options.m_ignore_count);
10825a988416SJim Ingham 
10835a988416SJim Ingham                         if (m_options.m_enable_passed)
10845a988416SJim Ingham                             bp->SetEnabled (m_options.m_enable_value);
10855a988416SJim Ingham 
10865a988416SJim Ingham                         if (m_options.m_condition_passed)
10875a988416SJim Ingham                             bp->SetCondition (m_options.m_condition.c_str());
10885a988416SJim Ingham                     }
10895a988416SJim Ingham                 }
10905a988416SJim Ingham             }
10915a988416SJim Ingham         }
10925a988416SJim Ingham 
10935a988416SJim Ingham         return result.Succeeded();
10945a988416SJim Ingham     }
10955a988416SJim Ingham 
10965a988416SJim Ingham private:
10975a988416SJim Ingham     CommandOptions m_options;
10985a988416SJim Ingham };
10995a988416SJim Ingham 
11005a988416SJim Ingham #pragma mark Modify::CommandOptions
11015a988416SJim Ingham OptionDefinition
11025a988416SJim Ingham CommandObjectBreakpointModify::CommandOptions::g_option_table[] =
11035a988416SJim Ingham {
1104d37221dcSZachary Turner { LLDB_OPT_SET_ALL, false, "ignore-count", 'i', OptionParser::eRequiredArgument, NULL, NULL, 0, eArgTypeCount, "Set the number of times this breakpoint is skipped before stopping." },
1105d37221dcSZachary Turner { LLDB_OPT_SET_ALL, false, "one-shot",     'o', OptionParser::eRequiredArgument, NULL, NULL, 0, eArgTypeBoolean, "The breakpoint is deleted the first time it stop causes a stop." },
1106d37221dcSZachary Turner { LLDB_OPT_SET_ALL, false, "thread-index", 'x', OptionParser::eRequiredArgument, NULL, NULL, 0, eArgTypeThreadIndex, "The breakpoint stops only for the thread whose index matches this argument."},
1107d37221dcSZachary Turner { LLDB_OPT_SET_ALL, false, "thread-id",    't', OptionParser::eRequiredArgument, NULL, NULL, 0, eArgTypeThreadID, "The breakpoint stops only for the thread whose TID matches this argument."},
1108d37221dcSZachary Turner { LLDB_OPT_SET_ALL, false, "thread-name",  'T', OptionParser::eRequiredArgument, NULL, NULL, 0, eArgTypeThreadName, "The breakpoint stops only for the thread whose thread name matches this argument."},
1109d37221dcSZachary Turner { LLDB_OPT_SET_ALL, false, "queue-name",   'q', OptionParser::eRequiredArgument, NULL, NULL, 0, eArgTypeQueueName, "The breakpoint stops only for threads in the queue whose name is given by this argument."},
1110d37221dcSZachary Turner { LLDB_OPT_SET_ALL, false, "condition",    'c', OptionParser::eRequiredArgument, NULL, NULL, 0, eArgTypeExpression, "The breakpoint stops only if this condition expression evaluates to true."},
1111d37221dcSZachary Turner { LLDB_OPT_SET_1,   false, "enable",       'e', OptionParser::eNoArgument,       NULL, NULL, 0, eArgTypeNone, "Enable the breakpoint."},
1112d37221dcSZachary Turner { LLDB_OPT_SET_2,   false, "disable",      'd', OptionParser::eNoArgument,       NULL, NULL, 0, eArgTypeNone, "Disable the breakpoint."},
111333df7cd3SJim Ingham { LLDB_OPT_SET_ALL, false, "dummy-breakpoints", 'D', OptionParser::eNoArgument, NULL, NULL, 0, eArgTypeNone, "Sets Dummy breakpoints - i.e. breakpoints set before a file is provided, which prime new targets."},
111433df7cd3SJim Ingham 
1115d37221dcSZachary Turner { 0,                false, NULL,            0 , 0,                 NULL, NULL, 0, eArgTypeNone, NULL }
11165a988416SJim Ingham };
11175a988416SJim Ingham 
11185a988416SJim Ingham //-------------------------------------------------------------------------
11195a988416SJim Ingham // CommandObjectBreakpointEnable
11205a988416SJim Ingham //-------------------------------------------------------------------------
11215a988416SJim Ingham #pragma mark Enable
11225a988416SJim Ingham 
11235a988416SJim Ingham class CommandObjectBreakpointEnable : public CommandObjectParsed
11245a988416SJim Ingham {
11255a988416SJim Ingham public:
11265a988416SJim Ingham     CommandObjectBreakpointEnable (CommandInterpreter &interpreter) :
11275a988416SJim Ingham         CommandObjectParsed (interpreter,
11285a988416SJim Ingham                              "enable",
11295a988416SJim Ingham                              "Enable the specified disabled breakpoint(s). If no breakpoints are specified, enable all of them.",
11305a988416SJim Ingham                              NULL)
11315a988416SJim Ingham     {
11325a988416SJim Ingham         CommandArgumentEntry arg;
11335a988416SJim Ingham         CommandObject::AddIDsArgumentData(arg, eArgTypeBreakpointID, eArgTypeBreakpointIDRange);
11345a988416SJim Ingham         // Add the entry for the first argument for this command to the object's arguments vector.
11355a988416SJim Ingham         m_arguments.push_back (arg);
11365a988416SJim Ingham     }
11375a988416SJim Ingham 
11385a988416SJim Ingham 
11395a988416SJim Ingham     virtual
11405a988416SJim Ingham     ~CommandObjectBreakpointEnable () {}
11415a988416SJim Ingham 
11425a988416SJim Ingham protected:
11435a988416SJim Ingham     virtual bool
11445a988416SJim Ingham     DoExecute (Args& command, CommandReturnObject &result)
11455a988416SJim Ingham     {
1146893c932aSJim Ingham         Target *target = GetSelectedOrDummyTarget();
11475a988416SJim Ingham         if (target == NULL)
11485a988416SJim Ingham         {
11495a988416SJim Ingham             result.AppendError ("Invalid target.  No existing target or breakpoints.");
11505a988416SJim Ingham             result.SetStatus (eReturnStatusFailed);
11515a988416SJim Ingham             return false;
11525a988416SJim Ingham         }
11535a988416SJim Ingham 
11545a988416SJim Ingham         Mutex::Locker locker;
11555a988416SJim Ingham         target->GetBreakpointList().GetListMutex(locker);
11565a988416SJim Ingham 
11575a988416SJim Ingham         const BreakpointList &breakpoints = target->GetBreakpointList();
11585a988416SJim Ingham 
11595a988416SJim Ingham         size_t num_breakpoints = breakpoints.GetSize();
11605a988416SJim Ingham 
11615a988416SJim Ingham         if (num_breakpoints == 0)
11625a988416SJim Ingham         {
11635a988416SJim Ingham             result.AppendError ("No breakpoints exist to be enabled.");
11645a988416SJim Ingham             result.SetStatus (eReturnStatusFailed);
11655a988416SJim Ingham             return false;
11665a988416SJim Ingham         }
11675a988416SJim Ingham 
11685a988416SJim Ingham         if (command.GetArgumentCount() == 0)
11695a988416SJim Ingham         {
11705a988416SJim Ingham             // No breakpoint selected; enable all currently set breakpoints.
11715a988416SJim Ingham             target->EnableAllBreakpoints ();
11726fea17e8SGreg Clayton             result.AppendMessageWithFormat ("All breakpoints enabled. (%" PRIu64 " breakpoints)\n", (uint64_t)num_breakpoints);
11735a988416SJim Ingham             result.SetStatus (eReturnStatusSuccessFinishNoResult);
11745a988416SJim Ingham         }
11755a988416SJim Ingham         else
11765a988416SJim Ingham         {
11775a988416SJim Ingham             // Particular breakpoint selected; enable that breakpoint.
11785a988416SJim Ingham             BreakpointIDList valid_bp_ids;
11795e09c8c3SJim Ingham             CommandObjectMultiwordBreakpoint::VerifyBreakpointOrLocationIDs (command, target, result, &valid_bp_ids);
11805a988416SJim Ingham 
11815a988416SJim Ingham             if (result.Succeeded())
11825a988416SJim Ingham             {
11835a988416SJim Ingham                 int enable_count = 0;
11845a988416SJim Ingham                 int loc_count = 0;
11855a988416SJim Ingham                 const size_t count = valid_bp_ids.GetSize();
11865a988416SJim Ingham                 for (size_t i = 0; i < count; ++i)
11875a988416SJim Ingham                 {
11885a988416SJim Ingham                     BreakpointID cur_bp_id = valid_bp_ids.GetBreakpointIDAtIndex (i);
11895a988416SJim Ingham 
11905a988416SJim Ingham                     if (cur_bp_id.GetBreakpointID() != LLDB_INVALID_BREAK_ID)
11915a988416SJim Ingham                     {
11925a988416SJim Ingham                         Breakpoint *breakpoint = target->GetBreakpointByID (cur_bp_id.GetBreakpointID()).get();
11935a988416SJim Ingham                         if (cur_bp_id.GetLocationID() != LLDB_INVALID_BREAK_ID)
11945a988416SJim Ingham                         {
11955a988416SJim Ingham                             BreakpointLocation *location = breakpoint->FindLocationByID (cur_bp_id.GetLocationID()).get();
11965a988416SJim Ingham                             if (location)
11975a988416SJim Ingham                             {
11985a988416SJim Ingham                                 location->SetEnabled (true);
11995a988416SJim Ingham                                 ++loc_count;
12005a988416SJim Ingham                             }
12015a988416SJim Ingham                         }
12025a988416SJim Ingham                         else
12035a988416SJim Ingham                         {
12045a988416SJim Ingham                             breakpoint->SetEnabled (true);
12055a988416SJim Ingham                             ++enable_count;
12065a988416SJim Ingham                         }
12075a988416SJim Ingham                     }
12085a988416SJim Ingham                 }
12095a988416SJim Ingham                 result.AppendMessageWithFormat ("%d breakpoints enabled.\n", enable_count + loc_count);
12105a988416SJim Ingham                 result.SetStatus (eReturnStatusSuccessFinishNoResult);
12115a988416SJim Ingham             }
12125a988416SJim Ingham         }
12135a988416SJim Ingham 
12145a988416SJim Ingham         return result.Succeeded();
12155a988416SJim Ingham     }
12165a988416SJim Ingham };
12175a988416SJim Ingham 
12185a988416SJim Ingham //-------------------------------------------------------------------------
12195a988416SJim Ingham // CommandObjectBreakpointDisable
12205a988416SJim Ingham //-------------------------------------------------------------------------
12215a988416SJim Ingham #pragma mark Disable
12225a988416SJim Ingham 
12235a988416SJim Ingham class CommandObjectBreakpointDisable : public CommandObjectParsed
12245a988416SJim Ingham {
12255a988416SJim Ingham public:
12265a988416SJim Ingham     CommandObjectBreakpointDisable (CommandInterpreter &interpreter) :
12275a988416SJim Ingham         CommandObjectParsed (interpreter,
12285a988416SJim Ingham                              "breakpoint disable",
12295a988416SJim Ingham                              "Disable the specified breakpoint(s) without removing it/them.  If no breakpoints are specified, disable them all.",
12305a988416SJim Ingham                              NULL)
12315a988416SJim Ingham     {
1232b0fac509SJim Ingham         SetHelpLong(
1233b0fac509SJim Ingham "Disable the specified breakpoint(s) without removing it/them.  \n\
1234b0fac509SJim Ingham If no breakpoints are specified, disable them all.\n\
1235b0fac509SJim Ingham \n\
1236b0fac509SJim Ingham Note: disabling a breakpoint will cause none of its locations to be hit\n\
1237b0fac509SJim Ingham regardless of whether they are enabled or disabled.  So the sequence: \n\
1238b0fac509SJim Ingham \n\
1239b0fac509SJim Ingham     (lldb) break disable 1\n\
1240b0fac509SJim Ingham     (lldb) break enable 1.1\n\
1241b0fac509SJim Ingham \n\
1242b0fac509SJim Ingham will NOT cause location 1.1 to get hit.  To achieve that, do:\n\
1243b0fac509SJim Ingham \n\
1244b0fac509SJim Ingham     (lldb) break disable 1.*\n\
1245b0fac509SJim Ingham     (lldb) break enable 1.1\n\
1246b0fac509SJim Ingham \n\
1247b0fac509SJim Ingham The first command disables all the locations of breakpoint 1, \n\
1248b0fac509SJim Ingham the second re-enables the first location."
1249b0fac509SJim Ingham                     );
1250b0fac509SJim Ingham 
12515a988416SJim Ingham         CommandArgumentEntry arg;
12525a988416SJim Ingham         CommandObject::AddIDsArgumentData(arg, eArgTypeBreakpointID, eArgTypeBreakpointIDRange);
12535a988416SJim Ingham         // Add the entry for the first argument for this command to the object's arguments vector.
12545a988416SJim Ingham         m_arguments.push_back (arg);
1255b0fac509SJim Ingham 
12565a988416SJim Ingham     }
12575a988416SJim Ingham 
12585a988416SJim Ingham 
12595a988416SJim Ingham     virtual
12605a988416SJim Ingham     ~CommandObjectBreakpointDisable () {}
12615a988416SJim Ingham 
12625a988416SJim Ingham protected:
12635a988416SJim Ingham     virtual bool
12645a988416SJim Ingham     DoExecute (Args& command, CommandReturnObject &result)
12655a988416SJim Ingham     {
1266893c932aSJim Ingham         Target *target = GetSelectedOrDummyTarget();
12675a988416SJim Ingham         if (target == NULL)
12685a988416SJim Ingham         {
12695a988416SJim Ingham             result.AppendError ("Invalid target.  No existing target or breakpoints.");
12705a988416SJim Ingham             result.SetStatus (eReturnStatusFailed);
12715a988416SJim Ingham             return false;
12725a988416SJim Ingham         }
12735a988416SJim Ingham 
12745a988416SJim Ingham         Mutex::Locker locker;
12755a988416SJim Ingham         target->GetBreakpointList().GetListMutex(locker);
12765a988416SJim Ingham 
12775a988416SJim Ingham         const BreakpointList &breakpoints = target->GetBreakpointList();
12785a988416SJim Ingham         size_t num_breakpoints = breakpoints.GetSize();
12795a988416SJim Ingham 
12805a988416SJim Ingham         if (num_breakpoints == 0)
12815a988416SJim Ingham         {
12825a988416SJim Ingham             result.AppendError ("No breakpoints exist to be disabled.");
12835a988416SJim Ingham             result.SetStatus (eReturnStatusFailed);
12845a988416SJim Ingham             return false;
12855a988416SJim Ingham         }
12865a988416SJim Ingham 
12875a988416SJim Ingham         if (command.GetArgumentCount() == 0)
12885a988416SJim Ingham         {
12895a988416SJim Ingham             // No breakpoint selected; disable all currently set breakpoints.
12905a988416SJim Ingham             target->DisableAllBreakpoints ();
12916fea17e8SGreg Clayton             result.AppendMessageWithFormat ("All breakpoints disabled. (%" PRIu64 " breakpoints)\n", (uint64_t)num_breakpoints);
12925a988416SJim Ingham             result.SetStatus (eReturnStatusSuccessFinishNoResult);
12935a988416SJim Ingham         }
12945a988416SJim Ingham         else
12955a988416SJim Ingham         {
12965a988416SJim Ingham             // Particular breakpoint selected; disable that breakpoint.
12975a988416SJim Ingham             BreakpointIDList valid_bp_ids;
12985a988416SJim Ingham 
12995e09c8c3SJim Ingham             CommandObjectMultiwordBreakpoint::VerifyBreakpointOrLocationIDs (command, target, result, &valid_bp_ids);
13005a988416SJim Ingham 
13015a988416SJim Ingham             if (result.Succeeded())
13025a988416SJim Ingham             {
13035a988416SJim Ingham                 int disable_count = 0;
13045a988416SJim Ingham                 int loc_count = 0;
13055a988416SJim Ingham                 const size_t count = valid_bp_ids.GetSize();
13065a988416SJim Ingham                 for (size_t i = 0; i < count; ++i)
13075a988416SJim Ingham                 {
13085a988416SJim Ingham                     BreakpointID cur_bp_id = valid_bp_ids.GetBreakpointIDAtIndex (i);
13095a988416SJim Ingham 
13105a988416SJim Ingham                     if (cur_bp_id.GetBreakpointID() != LLDB_INVALID_BREAK_ID)
13115a988416SJim Ingham                     {
13125a988416SJim Ingham                         Breakpoint *breakpoint = target->GetBreakpointByID (cur_bp_id.GetBreakpointID()).get();
13135a988416SJim Ingham                         if (cur_bp_id.GetLocationID() != LLDB_INVALID_BREAK_ID)
13145a988416SJim Ingham                         {
13155a988416SJim Ingham                             BreakpointLocation *location = breakpoint->FindLocationByID (cur_bp_id.GetLocationID()).get();
13165a988416SJim Ingham                             if (location)
13175a988416SJim Ingham                             {
13185a988416SJim Ingham                                 location->SetEnabled (false);
13195a988416SJim Ingham                                 ++loc_count;
13205a988416SJim Ingham                             }
13215a988416SJim Ingham                         }
13225a988416SJim Ingham                         else
13235a988416SJim Ingham                         {
13245a988416SJim Ingham                             breakpoint->SetEnabled (false);
13255a988416SJim Ingham                             ++disable_count;
13265a988416SJim Ingham                         }
13275a988416SJim Ingham                     }
13285a988416SJim Ingham                 }
13295a988416SJim Ingham                 result.AppendMessageWithFormat ("%d breakpoints disabled.\n", disable_count + loc_count);
13305a988416SJim Ingham                 result.SetStatus (eReturnStatusSuccessFinishNoResult);
13315a988416SJim Ingham             }
13325a988416SJim Ingham         }
13335a988416SJim Ingham 
13345a988416SJim Ingham         return result.Succeeded();
13355a988416SJim Ingham     }
13365a988416SJim Ingham 
13375a988416SJim Ingham };
13385a988416SJim Ingham 
13395a988416SJim Ingham //-------------------------------------------------------------------------
13405a988416SJim Ingham // CommandObjectBreakpointList
13415a988416SJim Ingham //-------------------------------------------------------------------------
13425a988416SJim Ingham #pragma mark List
13435a988416SJim Ingham 
13445a988416SJim Ingham class CommandObjectBreakpointList : public CommandObjectParsed
13455a988416SJim Ingham {
13465a988416SJim Ingham public:
13475a988416SJim Ingham     CommandObjectBreakpointList (CommandInterpreter &interpreter) :
13485a988416SJim Ingham         CommandObjectParsed (interpreter,
13495a988416SJim Ingham                              "breakpoint list",
13505a988416SJim Ingham                              "List some or all breakpoints at configurable levels of detail.",
13515a988416SJim Ingham                              NULL),
13525a988416SJim Ingham         m_options (interpreter)
13535a988416SJim Ingham     {
13545a988416SJim Ingham         CommandArgumentEntry arg;
13555a988416SJim Ingham         CommandArgumentData bp_id_arg;
13565a988416SJim Ingham 
13575a988416SJim Ingham         // Define the first (and only) variant of this arg.
13585a988416SJim Ingham         bp_id_arg.arg_type = eArgTypeBreakpointID;
13595a988416SJim Ingham         bp_id_arg.arg_repetition = eArgRepeatOptional;
13605a988416SJim Ingham 
13615a988416SJim Ingham         // There is only one variant this argument could be; put it into the argument entry.
13625a988416SJim Ingham         arg.push_back (bp_id_arg);
13635a988416SJim Ingham 
13645a988416SJim Ingham         // Push the data for the first argument into the m_arguments vector.
13655a988416SJim Ingham         m_arguments.push_back (arg);
13665a988416SJim Ingham     }
13675a988416SJim Ingham 
13685a988416SJim Ingham 
13695a988416SJim Ingham     virtual
13705a988416SJim Ingham     ~CommandObjectBreakpointList () {}
13715a988416SJim Ingham 
13725a988416SJim Ingham     virtual Options *
13735a988416SJim Ingham     GetOptions ()
13745a988416SJim Ingham     {
13755a988416SJim Ingham         return &m_options;
13765a988416SJim Ingham     }
13775a988416SJim Ingham 
13785a988416SJim Ingham     class CommandOptions : public Options
13795a988416SJim Ingham     {
13805a988416SJim Ingham     public:
13815a988416SJim Ingham 
13825a988416SJim Ingham         CommandOptions (CommandInterpreter &interpreter) :
13835a988416SJim Ingham             Options (interpreter),
138433df7cd3SJim Ingham             m_level (lldb::eDescriptionLevelBrief),
138533df7cd3SJim Ingham             m_use_dummy(false)
13865a988416SJim Ingham         {
13875a988416SJim Ingham         }
13885a988416SJim Ingham 
13895a988416SJim Ingham         virtual
13905a988416SJim Ingham         ~CommandOptions () {}
13915a988416SJim Ingham 
13925a988416SJim Ingham         virtual Error
13935a988416SJim Ingham         SetOptionValue (uint32_t option_idx, const char *option_arg)
13945a988416SJim Ingham         {
13955a988416SJim Ingham             Error error;
13963bcdfc0eSGreg Clayton             const int short_option = m_getopt_table[option_idx].val;
13975a988416SJim Ingham 
13985a988416SJim Ingham             switch (short_option)
13995a988416SJim Ingham             {
14005a988416SJim Ingham                 case 'b':
14015a988416SJim Ingham                     m_level = lldb::eDescriptionLevelBrief;
14025a988416SJim Ingham                     break;
140333df7cd3SJim Ingham                 case 'D':
140433df7cd3SJim Ingham                     m_use_dummy = true;
140533df7cd3SJim Ingham                     break;
14065a988416SJim Ingham                 case 'f':
14075a988416SJim Ingham                     m_level = lldb::eDescriptionLevelFull;
14085a988416SJim Ingham                     break;
14095a988416SJim Ingham                 case 'v':
14105a988416SJim Ingham                     m_level = lldb::eDescriptionLevelVerbose;
14115a988416SJim Ingham                     break;
14125a988416SJim Ingham                 case 'i':
14135a988416SJim Ingham                     m_internal = true;
14145a988416SJim Ingham                     break;
14155a988416SJim Ingham                 default:
14165a988416SJim Ingham                     error.SetErrorStringWithFormat ("unrecognized option '%c'", short_option);
14175a988416SJim Ingham                     break;
14185a988416SJim Ingham             }
14195a988416SJim Ingham 
14205a988416SJim Ingham             return error;
14215a988416SJim Ingham         }
14225a988416SJim Ingham 
14235a988416SJim Ingham         void
14245a988416SJim Ingham         OptionParsingStarting ()
14255a988416SJim Ingham         {
14265a988416SJim Ingham             m_level = lldb::eDescriptionLevelFull;
14275a988416SJim Ingham             m_internal = false;
142833df7cd3SJim Ingham             m_use_dummy = false;
14295a988416SJim Ingham         }
14305a988416SJim Ingham 
14315a988416SJim Ingham         const OptionDefinition *
14325a988416SJim Ingham         GetDefinitions ()
14335a988416SJim Ingham         {
14345a988416SJim Ingham             return g_option_table;
14355a988416SJim Ingham         }
14365a988416SJim Ingham 
14375a988416SJim Ingham         // Options table: Required for subclasses of Options.
14385a988416SJim Ingham 
14395a988416SJim Ingham         static OptionDefinition g_option_table[];
14405a988416SJim Ingham 
14415a988416SJim Ingham         // Instance variables to hold the values for command options.
14425a988416SJim Ingham 
14435a988416SJim Ingham         lldb::DescriptionLevel m_level;
14445a988416SJim Ingham 
14455a988416SJim Ingham         bool m_internal;
144633df7cd3SJim Ingham         bool m_use_dummy;
14475a988416SJim Ingham     };
14485a988416SJim Ingham 
14495a988416SJim Ingham protected:
14505a988416SJim Ingham     virtual bool
14515a988416SJim Ingham     DoExecute (Args& command, CommandReturnObject &result)
14525a988416SJim Ingham     {
145333df7cd3SJim Ingham         Target *target = GetSelectedOrDummyTarget(m_options.m_use_dummy);
145433df7cd3SJim Ingham 
14555a988416SJim Ingham         if (target == NULL)
14565a988416SJim Ingham         {
14575a988416SJim Ingham             result.AppendError ("Invalid target. No current target or breakpoints.");
14585a988416SJim Ingham             result.SetStatus (eReturnStatusSuccessFinishNoResult);
14595a988416SJim Ingham             return true;
14605a988416SJim Ingham         }
14615a988416SJim Ingham 
14625a988416SJim Ingham         const BreakpointList &breakpoints = target->GetBreakpointList(m_options.m_internal);
14635a988416SJim Ingham         Mutex::Locker locker;
14645a988416SJim Ingham         target->GetBreakpointList(m_options.m_internal).GetListMutex(locker);
14655a988416SJim Ingham 
14665a988416SJim Ingham         size_t num_breakpoints = breakpoints.GetSize();
14675a988416SJim Ingham 
14685a988416SJim Ingham         if (num_breakpoints == 0)
14695a988416SJim Ingham         {
14705a988416SJim Ingham             result.AppendMessage ("No breakpoints currently set.");
14715a988416SJim Ingham             result.SetStatus (eReturnStatusSuccessFinishNoResult);
14725a988416SJim Ingham             return true;
14735a988416SJim Ingham         }
14745a988416SJim Ingham 
14755a988416SJim Ingham         Stream &output_stream = result.GetOutputStream();
14765a988416SJim Ingham 
14775a988416SJim Ingham         if (command.GetArgumentCount() == 0)
14785a988416SJim Ingham         {
14795a988416SJim Ingham             // No breakpoint selected; show info about all currently set breakpoints.
14805a988416SJim Ingham             result.AppendMessage ("Current breakpoints:");
14815a988416SJim Ingham             for (size_t i = 0; i < num_breakpoints; ++i)
14825a988416SJim Ingham             {
14835a988416SJim Ingham                 Breakpoint *breakpoint = breakpoints.GetBreakpointAtIndex (i).get();
14845a988416SJim Ingham                 AddBreakpointDescription (&output_stream, breakpoint, m_options.m_level);
14855a988416SJim Ingham             }
14865a988416SJim Ingham             result.SetStatus (eReturnStatusSuccessFinishNoResult);
14875a988416SJim Ingham         }
14885a988416SJim Ingham         else
14895a988416SJim Ingham         {
14905a988416SJim Ingham             // Particular breakpoints selected; show info about that breakpoint.
14915a988416SJim Ingham             BreakpointIDList valid_bp_ids;
14925e09c8c3SJim Ingham             CommandObjectMultiwordBreakpoint::VerifyBreakpointOrLocationIDs (command, target, result, &valid_bp_ids);
14935a988416SJim Ingham 
14945a988416SJim Ingham             if (result.Succeeded())
14955a988416SJim Ingham             {
14965a988416SJim Ingham                 for (size_t i = 0; i < valid_bp_ids.GetSize(); ++i)
14975a988416SJim Ingham                 {
14985a988416SJim Ingham                     BreakpointID cur_bp_id = valid_bp_ids.GetBreakpointIDAtIndex (i);
14995a988416SJim Ingham                     Breakpoint *breakpoint = target->GetBreakpointByID (cur_bp_id.GetBreakpointID()).get();
15005a988416SJim Ingham                     AddBreakpointDescription (&output_stream, breakpoint, m_options.m_level);
15015a988416SJim Ingham                 }
15025a988416SJim Ingham                 result.SetStatus (eReturnStatusSuccessFinishNoResult);
15035a988416SJim Ingham             }
15045a988416SJim Ingham             else
15055a988416SJim Ingham             {
15065a988416SJim Ingham                 result.AppendError ("Invalid breakpoint id.");
15075a988416SJim Ingham                 result.SetStatus (eReturnStatusFailed);
15085a988416SJim Ingham             }
15095a988416SJim Ingham         }
15105a988416SJim Ingham 
15115a988416SJim Ingham         return result.Succeeded();
15125a988416SJim Ingham     }
15135a988416SJim Ingham 
15145a988416SJim Ingham private:
15155a988416SJim Ingham     CommandOptions m_options;
15165a988416SJim Ingham };
15175a988416SJim Ingham 
15185a988416SJim Ingham #pragma mark List::CommandOptions
15195a988416SJim Ingham OptionDefinition
15205a988416SJim Ingham CommandObjectBreakpointList::CommandOptions::g_option_table[] =
15215a988416SJim Ingham {
1522d37221dcSZachary Turner     { LLDB_OPT_SET_ALL, false, "internal", 'i', OptionParser::eNoArgument, NULL, NULL, 0, eArgTypeNone,
15235a988416SJim Ingham         "Show debugger internal breakpoints" },
15245a988416SJim Ingham 
1525d37221dcSZachary Turner     { LLDB_OPT_SET_1, false, "brief",    'b', OptionParser::eNoArgument, NULL, NULL, 0, eArgTypeNone,
15265a988416SJim Ingham         "Give a brief description of the breakpoint (no location info)."},
15275a988416SJim Ingham 
15285a988416SJim Ingham     // FIXME: We need to add an "internal" command, and then add this sort of thing to it.
15295a988416SJim Ingham     // But I need to see it for now, and don't want to wait.
1530d37221dcSZachary Turner     { LLDB_OPT_SET_2, false, "full",    'f', OptionParser::eNoArgument, NULL, NULL, 0, eArgTypeNone,
15315a988416SJim Ingham         "Give a full description of the breakpoint and its locations."},
15325a988416SJim Ingham 
1533d37221dcSZachary Turner     { LLDB_OPT_SET_3, false, "verbose", 'v', OptionParser::eNoArgument, NULL, NULL, 0, eArgTypeNone,
15345a988416SJim Ingham         "Explain everything we know about the breakpoint (for debugging debugger bugs)." },
15355a988416SJim Ingham 
153633df7cd3SJim Ingham     { LLDB_OPT_SET_ALL, false, "dummy-breakpoints", 'D', OptionParser::eNoArgument, NULL, NULL, 0, eArgTypeNone,
153733df7cd3SJim Ingham         "List Dummy breakpoints - i.e. breakpoints set before a file is provided, which prime new targets."},
153833df7cd3SJim Ingham 
1539d37221dcSZachary Turner     { 0, false, NULL, 0, 0, NULL, NULL, 0, eArgTypeNone, NULL }
15405a988416SJim Ingham };
15415a988416SJim Ingham 
15425a988416SJim Ingham //-------------------------------------------------------------------------
15435a988416SJim Ingham // CommandObjectBreakpointClear
15445a988416SJim Ingham //-------------------------------------------------------------------------
15455a988416SJim Ingham #pragma mark Clear
15465a988416SJim Ingham 
15475a988416SJim Ingham class CommandObjectBreakpointClear : public CommandObjectParsed
15485a988416SJim Ingham {
15495a988416SJim Ingham public:
15505a988416SJim Ingham 
15515a988416SJim Ingham     typedef enum BreakpointClearType
15525a988416SJim Ingham     {
15535a988416SJim Ingham         eClearTypeInvalid,
15545a988416SJim Ingham         eClearTypeFileAndLine
15555a988416SJim Ingham     } BreakpointClearType;
15565a988416SJim Ingham 
15575a988416SJim Ingham     CommandObjectBreakpointClear (CommandInterpreter &interpreter) :
15585a988416SJim Ingham         CommandObjectParsed (interpreter,
15595a988416SJim Ingham                              "breakpoint clear",
15605a988416SJim Ingham                              "Clears a breakpoint or set of breakpoints in the executable.",
15615a988416SJim Ingham                              "breakpoint clear <cmd-options>"),
15625a988416SJim Ingham         m_options (interpreter)
15635a988416SJim Ingham     {
15645a988416SJim Ingham     }
15655a988416SJim Ingham 
15665a988416SJim Ingham     virtual
15675a988416SJim Ingham     ~CommandObjectBreakpointClear () {}
15685a988416SJim Ingham 
15695a988416SJim Ingham     virtual Options *
15705a988416SJim Ingham     GetOptions ()
15715a988416SJim Ingham     {
15725a988416SJim Ingham         return &m_options;
15735a988416SJim Ingham     }
15745a988416SJim Ingham 
15755a988416SJim Ingham     class CommandOptions : public Options
15765a988416SJim Ingham     {
15775a988416SJim Ingham     public:
15785a988416SJim Ingham 
15795a988416SJim Ingham         CommandOptions (CommandInterpreter &interpreter) :
15805a988416SJim Ingham             Options (interpreter),
15815a988416SJim Ingham             m_filename (),
15825a988416SJim Ingham             m_line_num (0)
15835a988416SJim Ingham         {
15845a988416SJim Ingham         }
15855a988416SJim Ingham 
15865a988416SJim Ingham         virtual
15875a988416SJim Ingham         ~CommandOptions () {}
15885a988416SJim Ingham 
15895a988416SJim Ingham         virtual Error
15905a988416SJim Ingham         SetOptionValue (uint32_t option_idx, const char *option_arg)
15915a988416SJim Ingham         {
15925a988416SJim Ingham             Error error;
15933bcdfc0eSGreg Clayton             const int short_option = m_getopt_table[option_idx].val;
15945a988416SJim Ingham 
15955a988416SJim Ingham             switch (short_option)
15965a988416SJim Ingham             {
15975a988416SJim Ingham                 case 'f':
15985a988416SJim Ingham                     m_filename.assign (option_arg);
15995a988416SJim Ingham                     break;
16005a988416SJim Ingham 
16015a988416SJim Ingham                 case 'l':
16025275aaa0SVince Harron                     m_line_num = StringConvert::ToUInt32 (option_arg, 0);
16035a988416SJim Ingham                     break;
16045a988416SJim Ingham 
16055a988416SJim Ingham                 default:
16065a988416SJim Ingham                     error.SetErrorStringWithFormat ("unrecognized option '%c'", short_option);
16075a988416SJim Ingham                     break;
16085a988416SJim Ingham             }
16095a988416SJim Ingham 
16105a988416SJim Ingham             return error;
16115a988416SJim Ingham         }
16125a988416SJim Ingham 
16135a988416SJim Ingham         void
16145a988416SJim Ingham         OptionParsingStarting ()
16155a988416SJim Ingham         {
16165a988416SJim Ingham             m_filename.clear();
16175a988416SJim Ingham             m_line_num = 0;
16185a988416SJim Ingham         }
16195a988416SJim Ingham 
16205a988416SJim Ingham         const OptionDefinition*
16215a988416SJim Ingham         GetDefinitions ()
16225a988416SJim Ingham         {
16235a988416SJim Ingham             return g_option_table;
16245a988416SJim Ingham         }
16255a988416SJim Ingham 
16265a988416SJim Ingham         // Options table: Required for subclasses of Options.
16275a988416SJim Ingham 
16285a988416SJim Ingham         static OptionDefinition g_option_table[];
16295a988416SJim Ingham 
16305a988416SJim Ingham         // Instance variables to hold the values for command options.
16315a988416SJim Ingham 
16325a988416SJim Ingham         std::string m_filename;
16335a988416SJim Ingham         uint32_t m_line_num;
16345a988416SJim Ingham 
16355a988416SJim Ingham     };
16365a988416SJim Ingham 
16375a988416SJim Ingham protected:
16385a988416SJim Ingham     virtual bool
16395a988416SJim Ingham     DoExecute (Args& command, CommandReturnObject &result)
16405a988416SJim Ingham     {
1641893c932aSJim Ingham         Target *target = GetSelectedOrDummyTarget();
16425a988416SJim Ingham         if (target == NULL)
16435a988416SJim Ingham         {
16445a988416SJim Ingham             result.AppendError ("Invalid target. No existing target or breakpoints.");
16455a988416SJim Ingham             result.SetStatus (eReturnStatusFailed);
16465a988416SJim Ingham             return false;
16475a988416SJim Ingham         }
16485a988416SJim Ingham 
16495a988416SJim Ingham         // The following are the various types of breakpoints that could be cleared:
16505a988416SJim Ingham         //   1). -f -l (clearing breakpoint by source location)
16515a988416SJim Ingham 
16525a988416SJim Ingham         BreakpointClearType break_type = eClearTypeInvalid;
16535a988416SJim Ingham 
16545a988416SJim Ingham         if (m_options.m_line_num != 0)
16555a988416SJim Ingham             break_type = eClearTypeFileAndLine;
16565a988416SJim Ingham 
16575a988416SJim Ingham         Mutex::Locker locker;
16585a988416SJim Ingham         target->GetBreakpointList().GetListMutex(locker);
16595a988416SJim Ingham 
16605a988416SJim Ingham         BreakpointList &breakpoints = target->GetBreakpointList();
16615a988416SJim Ingham         size_t num_breakpoints = breakpoints.GetSize();
16625a988416SJim Ingham 
16635a988416SJim Ingham         // Early return if there's no breakpoint at all.
16645a988416SJim Ingham         if (num_breakpoints == 0)
16655a988416SJim Ingham         {
16665a988416SJim Ingham             result.AppendError ("Breakpoint clear: No breakpoint cleared.");
16675a988416SJim Ingham             result.SetStatus (eReturnStatusFailed);
16685a988416SJim Ingham             return result.Succeeded();
16695a988416SJim Ingham         }
16705a988416SJim Ingham 
16715a988416SJim Ingham         // Find matching breakpoints and delete them.
16725a988416SJim Ingham 
16735a988416SJim Ingham         // First create a copy of all the IDs.
16745a988416SJim Ingham         std::vector<break_id_t> BreakIDs;
16755a988416SJim Ingham         for (size_t i = 0; i < num_breakpoints; ++i)
16765a988416SJim Ingham             BreakIDs.push_back(breakpoints.GetBreakpointAtIndex(i).get()->GetID());
16775a988416SJim Ingham 
16785a988416SJim Ingham         int num_cleared = 0;
16795a988416SJim Ingham         StreamString ss;
16805a988416SJim Ingham         switch (break_type)
16815a988416SJim Ingham         {
16825a988416SJim Ingham             case eClearTypeFileAndLine: // Breakpoint by source position
16835a988416SJim Ingham                 {
16845a988416SJim Ingham                     const ConstString filename(m_options.m_filename.c_str());
16855a988416SJim Ingham                     BreakpointLocationCollection loc_coll;
16865a988416SJim Ingham 
16875a988416SJim Ingham                     for (size_t i = 0; i < num_breakpoints; ++i)
16885a988416SJim Ingham                     {
16895a988416SJim Ingham                         Breakpoint *bp = breakpoints.FindBreakpointByID(BreakIDs[i]).get();
16905a988416SJim Ingham 
16915a988416SJim Ingham                         if (bp->GetMatchingFileLine(filename, m_options.m_line_num, loc_coll))
16925a988416SJim Ingham                         {
16935a988416SJim Ingham                             // If the collection size is 0, it's a full match and we can just remove the breakpoint.
16945a988416SJim Ingham                             if (loc_coll.GetSize() == 0)
16955a988416SJim Ingham                             {
16965a988416SJim Ingham                                 bp->GetDescription(&ss, lldb::eDescriptionLevelBrief);
16975a988416SJim Ingham                                 ss.EOL();
16985a988416SJim Ingham                                 target->RemoveBreakpointByID (bp->GetID());
16995a988416SJim Ingham                                 ++num_cleared;
17005a988416SJim Ingham                             }
17015a988416SJim Ingham                         }
17025a988416SJim Ingham                     }
17035a988416SJim Ingham                 }
17045a988416SJim Ingham                 break;
17055a988416SJim Ingham 
17065a988416SJim Ingham             default:
17075a988416SJim Ingham                 break;
17085a988416SJim Ingham         }
17095a988416SJim Ingham 
17105a988416SJim Ingham         if (num_cleared > 0)
17115a988416SJim Ingham         {
17125a988416SJim Ingham             Stream &output_stream = result.GetOutputStream();
17135a988416SJim Ingham             output_stream.Printf ("%d breakpoints cleared:\n", num_cleared);
17145a988416SJim Ingham             output_stream << ss.GetData();
17155a988416SJim Ingham             output_stream.EOL();
17165a988416SJim Ingham             result.SetStatus (eReturnStatusSuccessFinishNoResult);
17175a988416SJim Ingham         }
17185a988416SJim Ingham         else
17195a988416SJim Ingham         {
17205a988416SJim Ingham             result.AppendError ("Breakpoint clear: No breakpoint cleared.");
17215a988416SJim Ingham             result.SetStatus (eReturnStatusFailed);
17225a988416SJim Ingham         }
17235a988416SJim Ingham 
17245a988416SJim Ingham         return result.Succeeded();
17255a988416SJim Ingham     }
17265a988416SJim Ingham 
17275a988416SJim Ingham private:
17285a988416SJim Ingham     CommandOptions m_options;
17295a988416SJim Ingham };
17305a988416SJim Ingham 
17315a988416SJim Ingham #pragma mark Clear::CommandOptions
17325a988416SJim Ingham 
17335a988416SJim Ingham OptionDefinition
17345a988416SJim Ingham CommandObjectBreakpointClear::CommandOptions::g_option_table[] =
17355a988416SJim Ingham {
1736d37221dcSZachary Turner     { LLDB_OPT_SET_1, false, "file", 'f', OptionParser::eRequiredArgument, NULL, NULL, CommandCompletions::eSourceFileCompletion, eArgTypeFilename,
17375a988416SJim Ingham         "Specify the breakpoint by source location in this particular file."},
17385a988416SJim Ingham 
1739d37221dcSZachary Turner     { LLDB_OPT_SET_1, true, "line", 'l', OptionParser::eRequiredArgument, NULL, NULL, 0, eArgTypeLineNum,
17405a988416SJim Ingham         "Specify the breakpoint by source location at this particular line."},
17415a988416SJim Ingham 
1742d37221dcSZachary Turner     { 0, false, NULL, 0, 0, NULL, NULL, 0, eArgTypeNone, NULL }
17435a988416SJim Ingham };
17445a988416SJim Ingham 
17455a988416SJim Ingham //-------------------------------------------------------------------------
17465a988416SJim Ingham // CommandObjectBreakpointDelete
17475a988416SJim Ingham //-------------------------------------------------------------------------
17485a988416SJim Ingham #pragma mark Delete
17495a988416SJim Ingham 
17505a988416SJim Ingham class CommandObjectBreakpointDelete : public CommandObjectParsed
17515a988416SJim Ingham {
17525a988416SJim Ingham public:
17535a988416SJim Ingham     CommandObjectBreakpointDelete (CommandInterpreter &interpreter) :
17545a988416SJim Ingham         CommandObjectParsed (interpreter,
17555a988416SJim Ingham                              "breakpoint delete",
17565a988416SJim Ingham                              "Delete the specified breakpoint(s).  If no breakpoints are specified, delete them all.",
175733df7cd3SJim Ingham                              NULL),
175833df7cd3SJim Ingham         m_options (interpreter)
17595a988416SJim Ingham     {
17605a988416SJim Ingham         CommandArgumentEntry arg;
17615a988416SJim Ingham         CommandObject::AddIDsArgumentData(arg, eArgTypeBreakpointID, eArgTypeBreakpointIDRange);
17625a988416SJim Ingham         // Add the entry for the first argument for this command to the object's arguments vector.
17635a988416SJim Ingham         m_arguments.push_back (arg);
17645a988416SJim Ingham     }
17655a988416SJim Ingham 
17665a988416SJim Ingham     virtual
17675a988416SJim Ingham     ~CommandObjectBreakpointDelete () {}
17685a988416SJim Ingham 
176933df7cd3SJim Ingham     virtual Options *
177033df7cd3SJim Ingham     GetOptions ()
177133df7cd3SJim Ingham     {
177233df7cd3SJim Ingham         return &m_options;
177333df7cd3SJim Ingham     }
177433df7cd3SJim Ingham 
177533df7cd3SJim Ingham     class CommandOptions : public Options
177633df7cd3SJim Ingham     {
177733df7cd3SJim Ingham     public:
177833df7cd3SJim Ingham 
177933df7cd3SJim Ingham         CommandOptions (CommandInterpreter &interpreter) :
178033df7cd3SJim Ingham             Options (interpreter),
178133df7cd3SJim Ingham             m_use_dummy (false),
178233df7cd3SJim Ingham             m_force (false)
178333df7cd3SJim Ingham         {
178433df7cd3SJim Ingham         }
178533df7cd3SJim Ingham 
178633df7cd3SJim Ingham         virtual
178733df7cd3SJim Ingham         ~CommandOptions () {}
178833df7cd3SJim Ingham 
178933df7cd3SJim Ingham         virtual Error
179033df7cd3SJim Ingham         SetOptionValue (uint32_t option_idx, const char *option_arg)
179133df7cd3SJim Ingham         {
179233df7cd3SJim Ingham             Error error;
179333df7cd3SJim Ingham             const int short_option = m_getopt_table[option_idx].val;
179433df7cd3SJim Ingham 
179533df7cd3SJim Ingham             switch (short_option)
179633df7cd3SJim Ingham             {
179733df7cd3SJim Ingham                 case 'f':
179833df7cd3SJim Ingham                     m_force = true;
179933df7cd3SJim Ingham                     break;
180033df7cd3SJim Ingham 
180133df7cd3SJim Ingham                 case 'D':
180233df7cd3SJim Ingham                     m_use_dummy = true;
180333df7cd3SJim Ingham                     break;
180433df7cd3SJim Ingham 
180533df7cd3SJim Ingham                 default:
180633df7cd3SJim Ingham                     error.SetErrorStringWithFormat ("unrecognized option '%c'", short_option);
180733df7cd3SJim Ingham                     break;
180833df7cd3SJim Ingham             }
180933df7cd3SJim Ingham 
181033df7cd3SJim Ingham             return error;
181133df7cd3SJim Ingham         }
181233df7cd3SJim Ingham 
181333df7cd3SJim Ingham         void
181433df7cd3SJim Ingham         OptionParsingStarting ()
181533df7cd3SJim Ingham         {
181633df7cd3SJim Ingham             m_use_dummy = false;
181733df7cd3SJim Ingham             m_force = false;
181833df7cd3SJim Ingham         }
181933df7cd3SJim Ingham 
182033df7cd3SJim Ingham         const OptionDefinition*
182133df7cd3SJim Ingham         GetDefinitions ()
182233df7cd3SJim Ingham         {
182333df7cd3SJim Ingham             return g_option_table;
182433df7cd3SJim Ingham         }
182533df7cd3SJim Ingham 
182633df7cd3SJim Ingham         // Options table: Required for subclasses of Options.
182733df7cd3SJim Ingham 
182833df7cd3SJim Ingham         static OptionDefinition g_option_table[];
182933df7cd3SJim Ingham 
183033df7cd3SJim Ingham         // Instance variables to hold the values for command options.
183133df7cd3SJim Ingham         bool m_use_dummy;
183233df7cd3SJim Ingham         bool m_force;
183333df7cd3SJim Ingham     };
183433df7cd3SJim Ingham 
18355a988416SJim Ingham protected:
18365a988416SJim Ingham     virtual bool
18375a988416SJim Ingham     DoExecute (Args& command, CommandReturnObject &result)
18385a988416SJim Ingham     {
183933df7cd3SJim Ingham         Target *target = GetSelectedOrDummyTarget(m_options.m_use_dummy);
184033df7cd3SJim Ingham 
18415a988416SJim Ingham         if (target == NULL)
18425a988416SJim Ingham         {
18435a988416SJim Ingham             result.AppendError ("Invalid target. No existing target or breakpoints.");
18445a988416SJim Ingham             result.SetStatus (eReturnStatusFailed);
18455a988416SJim Ingham             return false;
18465a988416SJim Ingham         }
18475a988416SJim Ingham 
18485a988416SJim Ingham         Mutex::Locker locker;
18495a988416SJim Ingham         target->GetBreakpointList().GetListMutex(locker);
18505a988416SJim Ingham 
18515a988416SJim Ingham         const BreakpointList &breakpoints = target->GetBreakpointList();
18525a988416SJim Ingham 
18535a988416SJim Ingham         size_t num_breakpoints = breakpoints.GetSize();
18545a988416SJim Ingham 
18555a988416SJim Ingham         if (num_breakpoints == 0)
18565a988416SJim Ingham         {
18575a988416SJim Ingham             result.AppendError ("No breakpoints exist to be deleted.");
18585a988416SJim Ingham             result.SetStatus (eReturnStatusFailed);
18595a988416SJim Ingham             return false;
18605a988416SJim Ingham         }
18615a988416SJim Ingham 
18625a988416SJim Ingham         if (command.GetArgumentCount() == 0)
18635a988416SJim Ingham         {
186433df7cd3SJim Ingham             if (!m_options.m_force && !m_interpreter.Confirm ("About to delete all breakpoints, do you want to do that?", true))
18655a988416SJim Ingham             {
18665a988416SJim Ingham                 result.AppendMessage("Operation cancelled...");
18675a988416SJim Ingham             }
18685a988416SJim Ingham             else
18695a988416SJim Ingham             {
18705a988416SJim Ingham                 target->RemoveAllBreakpoints ();
18716fea17e8SGreg Clayton                 result.AppendMessageWithFormat ("All breakpoints removed. (%" PRIu64 " breakpoint%s)\n", (uint64_t)num_breakpoints, num_breakpoints > 1 ? "s" : "");
18725a988416SJim Ingham             }
18735a988416SJim Ingham             result.SetStatus (eReturnStatusSuccessFinishNoResult);
18745a988416SJim Ingham         }
18755a988416SJim Ingham         else
18765a988416SJim Ingham         {
18775a988416SJim Ingham             // Particular breakpoint selected; disable that breakpoint.
18785a988416SJim Ingham             BreakpointIDList valid_bp_ids;
18795e09c8c3SJim Ingham             CommandObjectMultiwordBreakpoint::VerifyBreakpointOrLocationIDs (command, target, result, &valid_bp_ids);
18805a988416SJim Ingham 
18815a988416SJim Ingham             if (result.Succeeded())
18825a988416SJim Ingham             {
18835a988416SJim Ingham                 int delete_count = 0;
18845a988416SJim Ingham                 int disable_count = 0;
18855a988416SJim Ingham                 const size_t count = valid_bp_ids.GetSize();
18865a988416SJim Ingham                 for (size_t i = 0; i < count; ++i)
18875a988416SJim Ingham                 {
18885a988416SJim Ingham                     BreakpointID cur_bp_id = valid_bp_ids.GetBreakpointIDAtIndex (i);
18895a988416SJim Ingham 
18905a988416SJim Ingham                     if (cur_bp_id.GetBreakpointID() != LLDB_INVALID_BREAK_ID)
18915a988416SJim Ingham                     {
18925a988416SJim Ingham                         if (cur_bp_id.GetLocationID() != LLDB_INVALID_BREAK_ID)
18935a988416SJim Ingham                         {
18945a988416SJim Ingham                             Breakpoint *breakpoint = target->GetBreakpointByID (cur_bp_id.GetBreakpointID()).get();
18955a988416SJim Ingham                             BreakpointLocation *location = breakpoint->FindLocationByID (cur_bp_id.GetLocationID()).get();
18965a988416SJim Ingham                             // It makes no sense to try to delete individual locations, so we disable them instead.
18975a988416SJim Ingham                             if (location)
18985a988416SJim Ingham                             {
18995a988416SJim Ingham                                 location->SetEnabled (false);
19005a988416SJim Ingham                                 ++disable_count;
19015a988416SJim Ingham                             }
19025a988416SJim Ingham                         }
19035a988416SJim Ingham                         else
19045a988416SJim Ingham                         {
19055a988416SJim Ingham                             target->RemoveBreakpointByID (cur_bp_id.GetBreakpointID());
19065a988416SJim Ingham                             ++delete_count;
19075a988416SJim Ingham                         }
19085a988416SJim Ingham                     }
19095a988416SJim Ingham                 }
19105a988416SJim Ingham                 result.AppendMessageWithFormat ("%d breakpoints deleted; %d breakpoint locations disabled.\n",
19115a988416SJim Ingham                                                delete_count, disable_count);
19125a988416SJim Ingham                 result.SetStatus (eReturnStatusSuccessFinishNoResult);
19135a988416SJim Ingham             }
19145a988416SJim Ingham         }
19155a988416SJim Ingham         return result.Succeeded();
19165a988416SJim Ingham     }
191733df7cd3SJim Ingham private:
191833df7cd3SJim Ingham     CommandOptions m_options;
191933df7cd3SJim Ingham };
192033df7cd3SJim Ingham 
192133df7cd3SJim Ingham OptionDefinition
192233df7cd3SJim Ingham CommandObjectBreakpointDelete::CommandOptions::g_option_table[] =
192333df7cd3SJim Ingham {
192433df7cd3SJim Ingham     { LLDB_OPT_SET_1, false, "force", 'f', OptionParser::eNoArgument, NULL, NULL, 0, eArgTypeNone,
192533df7cd3SJim Ingham         "Delete all breakpoints without querying for confirmation."},
192633df7cd3SJim Ingham 
192733df7cd3SJim Ingham     { LLDB_OPT_SET_1, false, "dummy-breakpoints", 'D', OptionParser::eNoArgument, NULL, NULL, 0, eArgTypeNone,
192833df7cd3SJim Ingham         "Delete Dummy breakpoints - i.e. breakpoints set before a file is provided, which prime new targets."},
192933df7cd3SJim Ingham 
193033df7cd3SJim Ingham     { 0, false, NULL, 0, 0, NULL, NULL, 0, eArgTypeNone, NULL }
19315a988416SJim Ingham };
19325a988416SJim Ingham 
193330fdc8d8SChris Lattner //-------------------------------------------------------------------------
19345e09c8c3SJim Ingham // CommandObjectBreakpointName
19355e09c8c3SJim Ingham //-------------------------------------------------------------------------
19365e09c8c3SJim Ingham 
19375e09c8c3SJim Ingham static OptionDefinition
19385e09c8c3SJim Ingham g_breakpoint_name_options[] =
19395e09c8c3SJim Ingham {
19405e09c8c3SJim Ingham     { LLDB_OPT_SET_1,   false, "name", 'N', OptionParser::eRequiredArgument, NULL, NULL, 0, eArgTypeBreakpointName, "Specifies a breakpoint name to use."},
19415e09c8c3SJim Ingham     { LLDB_OPT_SET_2,   false, "breakpoint-id", 'B', OptionParser::eRequiredArgument, NULL, NULL, 0, eArgTypeBreakpointID,   "Specify a breakpoint id to use."},
19425e09c8c3SJim Ingham     { LLDB_OPT_SET_ALL, false, "dummy-breakpoints", 'D', OptionParser::eNoArgument, NULL, NULL, 0, eArgTypeNone,
19435e09c8c3SJim Ingham         "Operate on Dummy breakpoints - i.e. breakpoints set before a file is provided, which prime new targets."},
19445e09c8c3SJim Ingham };
19455e09c8c3SJim Ingham class BreakpointNameOptionGroup : public OptionGroup
19465e09c8c3SJim Ingham {
19475e09c8c3SJim Ingham public:
19485e09c8c3SJim Ingham     BreakpointNameOptionGroup() :
19495e09c8c3SJim Ingham         OptionGroup(),
19505e09c8c3SJim Ingham         m_breakpoint(LLDB_INVALID_BREAK_ID),
19515e09c8c3SJim Ingham         m_use_dummy (false)
19525e09c8c3SJim Ingham     {
19535e09c8c3SJim Ingham 
19545e09c8c3SJim Ingham     }
19555e09c8c3SJim Ingham 
19565e09c8c3SJim Ingham     virtual
19575e09c8c3SJim Ingham     ~BreakpointNameOptionGroup ()
19585e09c8c3SJim Ingham     {
19595e09c8c3SJim Ingham     }
19605e09c8c3SJim Ingham 
19615e09c8c3SJim Ingham     virtual uint32_t
19625e09c8c3SJim Ingham     GetNumDefinitions ()
19635e09c8c3SJim Ingham     {
19645e09c8c3SJim Ingham       return sizeof (g_breakpoint_name_options) / sizeof (OptionDefinition);
19655e09c8c3SJim Ingham     }
19665e09c8c3SJim Ingham 
19675e09c8c3SJim Ingham     virtual const OptionDefinition*
19685e09c8c3SJim Ingham     GetDefinitions ()
19695e09c8c3SJim Ingham     {
19705e09c8c3SJim Ingham         return g_breakpoint_name_options;
19715e09c8c3SJim Ingham     }
19725e09c8c3SJim Ingham 
19735e09c8c3SJim Ingham     virtual Error
19745e09c8c3SJim Ingham     SetOptionValue (CommandInterpreter &interpreter,
19755e09c8c3SJim Ingham                     uint32_t option_idx,
19765e09c8c3SJim Ingham                     const char *option_value)
19775e09c8c3SJim Ingham     {
19785e09c8c3SJim Ingham         Error error;
19795e09c8c3SJim Ingham         const int short_option = g_breakpoint_name_options[option_idx].short_option;
19805e09c8c3SJim Ingham 
19815e09c8c3SJim Ingham         switch (short_option)
19825e09c8c3SJim Ingham         {
19835e09c8c3SJim Ingham         case 'N':
19845e09c8c3SJim Ingham             if (BreakpointID::StringIsBreakpointName(option_value, error) && error.Success())
1985c95f7e2aSPavel Labath                 m_name.SetValueFromString(option_value);
19865e09c8c3SJim Ingham             break;
19875e09c8c3SJim Ingham 
19885e09c8c3SJim Ingham         case 'B':
1989c95f7e2aSPavel Labath             if (m_breakpoint.SetValueFromString(option_value).Fail())
19905e09c8c3SJim Ingham                 error.SetErrorStringWithFormat ("unrecognized value \"%s\" for breakpoint", option_value);
19915e09c8c3SJim Ingham             break;
19925e09c8c3SJim Ingham         case 'D':
1993c95f7e2aSPavel Labath             if (m_use_dummy.SetValueFromString(option_value).Fail())
19945e09c8c3SJim Ingham                 error.SetErrorStringWithFormat ("unrecognized value \"%s\" for use-dummy", option_value);
19955e09c8c3SJim Ingham             break;
19965e09c8c3SJim Ingham 
19975e09c8c3SJim Ingham         default:
19985e09c8c3SJim Ingham               error.SetErrorStringWithFormat("unrecognized short option '%c'", short_option);
19995e09c8c3SJim Ingham               break;
20005e09c8c3SJim Ingham         }
20015e09c8c3SJim Ingham         return error;
20025e09c8c3SJim Ingham     }
20035e09c8c3SJim Ingham 
20045e09c8c3SJim Ingham     virtual void
20055e09c8c3SJim Ingham     OptionParsingStarting (CommandInterpreter &interpreter)
20065e09c8c3SJim Ingham     {
20075e09c8c3SJim Ingham         m_name.Clear();
20085e09c8c3SJim Ingham         m_breakpoint.Clear();
20095e09c8c3SJim Ingham         m_use_dummy.Clear();
20105e09c8c3SJim Ingham         m_use_dummy.SetDefaultValue(false);
20115e09c8c3SJim Ingham     }
20125e09c8c3SJim Ingham 
20135e09c8c3SJim Ingham     OptionValueString m_name;
20145e09c8c3SJim Ingham     OptionValueUInt64 m_breakpoint;
20155e09c8c3SJim Ingham     OptionValueBoolean m_use_dummy;
20165e09c8c3SJim Ingham };
20175e09c8c3SJim Ingham 
20185e09c8c3SJim Ingham 
20195e09c8c3SJim Ingham class CommandObjectBreakpointNameAdd : public CommandObjectParsed
20205e09c8c3SJim Ingham {
20215e09c8c3SJim Ingham public:
20225e09c8c3SJim Ingham     CommandObjectBreakpointNameAdd (CommandInterpreter &interpreter) :
20235e09c8c3SJim Ingham         CommandObjectParsed (interpreter,
20245e09c8c3SJim Ingham                              "add",
20255e09c8c3SJim Ingham                              "Add a name to the breakpoints provided.",
20265e09c8c3SJim Ingham                              "breakpoint name add <command-options> <breakpoint-id-list>"),
20275e09c8c3SJim Ingham         m_name_options(),
20285e09c8c3SJim Ingham         m_option_group(interpreter)
20295e09c8c3SJim Ingham         {
20305e09c8c3SJim Ingham             // Create the first variant for the first (and only) argument for this command.
20315e09c8c3SJim Ingham             CommandArgumentEntry arg1;
20325e09c8c3SJim Ingham             CommandArgumentData id_arg;
20335e09c8c3SJim Ingham             id_arg.arg_type = eArgTypeBreakpointID;
20345e09c8c3SJim Ingham             id_arg.arg_repetition = eArgRepeatOptional;
20355e09c8c3SJim Ingham             arg1.push_back(id_arg);
20365e09c8c3SJim Ingham             m_arguments.push_back (arg1);
20375e09c8c3SJim Ingham 
20385e09c8c3SJim Ingham             m_option_group.Append (&m_name_options, LLDB_OPT_SET_1, LLDB_OPT_SET_ALL);
20395e09c8c3SJim Ingham             m_option_group.Finalize();
20405e09c8c3SJim Ingham         }
20415e09c8c3SJim Ingham 
20425e09c8c3SJim Ingham     virtual
20435e09c8c3SJim Ingham     ~CommandObjectBreakpointNameAdd () {}
20445e09c8c3SJim Ingham 
20455e09c8c3SJim Ingham   Options *
20465e09c8c3SJim Ingham   GetOptions ()
20475e09c8c3SJim Ingham   {
20485e09c8c3SJim Ingham     return &m_option_group;
20495e09c8c3SJim Ingham   }
20505e09c8c3SJim Ingham 
20515e09c8c3SJim Ingham protected:
20525e09c8c3SJim Ingham     virtual bool
20535e09c8c3SJim Ingham     DoExecute (Args& command, CommandReturnObject &result)
20545e09c8c3SJim Ingham     {
20555e09c8c3SJim Ingham         if (!m_name_options.m_name.OptionWasSet())
20565e09c8c3SJim Ingham         {
20575e09c8c3SJim Ingham             result.SetError("No name option provided.");
20585e09c8c3SJim Ingham             return false;
20595e09c8c3SJim Ingham         }
20605e09c8c3SJim Ingham 
20615e09c8c3SJim Ingham         Target *target = GetSelectedOrDummyTarget(m_name_options.m_use_dummy.GetCurrentValue());
20625e09c8c3SJim Ingham 
20635e09c8c3SJim Ingham         if (target == NULL)
20645e09c8c3SJim Ingham         {
20655e09c8c3SJim Ingham             result.AppendError ("Invalid target. No existing target or breakpoints.");
20665e09c8c3SJim Ingham             result.SetStatus (eReturnStatusFailed);
20675e09c8c3SJim Ingham             return false;
20685e09c8c3SJim Ingham         }
20695e09c8c3SJim Ingham 
20705e09c8c3SJim Ingham         Mutex::Locker locker;
20715e09c8c3SJim Ingham         target->GetBreakpointList().GetListMutex(locker);
20725e09c8c3SJim Ingham 
20735e09c8c3SJim Ingham         const BreakpointList &breakpoints = target->GetBreakpointList();
20745e09c8c3SJim Ingham 
20755e09c8c3SJim Ingham         size_t num_breakpoints = breakpoints.GetSize();
20765e09c8c3SJim Ingham         if (num_breakpoints == 0)
20775e09c8c3SJim Ingham         {
20785e09c8c3SJim Ingham             result.SetError("No breakpoints, cannot add names.");
20795e09c8c3SJim Ingham             result.SetStatus (eReturnStatusFailed);
20805e09c8c3SJim Ingham             return false;
20815e09c8c3SJim Ingham         }
20825e09c8c3SJim Ingham 
20835e09c8c3SJim Ingham         // Particular breakpoint selected; disable that breakpoint.
20845e09c8c3SJim Ingham         BreakpointIDList valid_bp_ids;
20855e09c8c3SJim Ingham         CommandObjectMultiwordBreakpoint::VerifyBreakpointIDs (command, target, result, &valid_bp_ids);
20865e09c8c3SJim Ingham 
20875e09c8c3SJim Ingham         if (result.Succeeded())
20885e09c8c3SJim Ingham         {
20895e09c8c3SJim Ingham             if (valid_bp_ids.GetSize() == 0)
20905e09c8c3SJim Ingham             {
20915e09c8c3SJim Ingham                 result.SetError("No breakpoints specified, cannot add names.");
20925e09c8c3SJim Ingham                 result.SetStatus (eReturnStatusFailed);
20935e09c8c3SJim Ingham                 return false;
20945e09c8c3SJim Ingham             }
20955e09c8c3SJim Ingham             size_t num_valid_ids = valid_bp_ids.GetSize();
20965e09c8c3SJim Ingham             for (size_t index = 0; index < num_valid_ids; index++)
20975e09c8c3SJim Ingham             {
20985e09c8c3SJim Ingham                 lldb::break_id_t bp_id = valid_bp_ids.GetBreakpointIDAtIndex(index).GetBreakpointID();
20995e09c8c3SJim Ingham                 BreakpointSP bp_sp = breakpoints.FindBreakpointByID(bp_id);
21005e09c8c3SJim Ingham                 Error error;  // We don't need to check the error here, since the option parser checked it...
21015e09c8c3SJim Ingham                 bp_sp->AddName(m_name_options.m_name.GetCurrentValue(), error);
21025e09c8c3SJim Ingham             }
21035e09c8c3SJim Ingham         }
21045e09c8c3SJim Ingham 
21055e09c8c3SJim Ingham         return true;
21065e09c8c3SJim Ingham     }
21075e09c8c3SJim Ingham 
21085e09c8c3SJim Ingham private:
21095e09c8c3SJim Ingham     BreakpointNameOptionGroup m_name_options;
21105e09c8c3SJim Ingham     OptionGroupOptions m_option_group;
21115e09c8c3SJim Ingham };
21125e09c8c3SJim Ingham 
21135e09c8c3SJim Ingham 
21145e09c8c3SJim Ingham 
21155e09c8c3SJim Ingham class CommandObjectBreakpointNameDelete : public CommandObjectParsed
21165e09c8c3SJim Ingham {
21175e09c8c3SJim Ingham public:
21185e09c8c3SJim Ingham     CommandObjectBreakpointNameDelete (CommandInterpreter &interpreter) :
21195e09c8c3SJim Ingham         CommandObjectParsed (interpreter,
21205e09c8c3SJim Ingham                              "delete",
21215e09c8c3SJim Ingham                              "Delete a name from the breakpoints provided.",
21225e09c8c3SJim Ingham                              "breakpoint name delete <command-options> <breakpoint-id-list>"),
21235e09c8c3SJim Ingham         m_name_options(),
21245e09c8c3SJim Ingham         m_option_group(interpreter)
21255e09c8c3SJim Ingham     {
21265e09c8c3SJim Ingham         // Create the first variant for the first (and only) argument for this command.
21275e09c8c3SJim Ingham         CommandArgumentEntry arg1;
21285e09c8c3SJim Ingham         CommandArgumentData id_arg;
21295e09c8c3SJim Ingham         id_arg.arg_type = eArgTypeBreakpointID;
21305e09c8c3SJim Ingham         id_arg.arg_repetition = eArgRepeatOptional;
21315e09c8c3SJim Ingham         arg1.push_back(id_arg);
21325e09c8c3SJim Ingham         m_arguments.push_back (arg1);
21335e09c8c3SJim Ingham 
21345e09c8c3SJim Ingham         m_option_group.Append (&m_name_options, LLDB_OPT_SET_1, LLDB_OPT_SET_ALL);
21355e09c8c3SJim Ingham         m_option_group.Finalize();
21365e09c8c3SJim Ingham     }
21375e09c8c3SJim Ingham 
21385e09c8c3SJim Ingham     virtual
21395e09c8c3SJim Ingham     ~CommandObjectBreakpointNameDelete () {}
21405e09c8c3SJim Ingham 
21415e09c8c3SJim Ingham   Options *
21425e09c8c3SJim Ingham   GetOptions ()
21435e09c8c3SJim Ingham   {
21445e09c8c3SJim Ingham     return &m_option_group;
21455e09c8c3SJim Ingham   }
21465e09c8c3SJim Ingham 
21475e09c8c3SJim Ingham protected:
21485e09c8c3SJim Ingham     virtual bool
21495e09c8c3SJim Ingham     DoExecute (Args& command, CommandReturnObject &result)
21505e09c8c3SJim Ingham     {
21515e09c8c3SJim Ingham         if (!m_name_options.m_name.OptionWasSet())
21525e09c8c3SJim Ingham         {
21535e09c8c3SJim Ingham             result.SetError("No name option provided.");
21545e09c8c3SJim Ingham             return false;
21555e09c8c3SJim Ingham         }
21565e09c8c3SJim Ingham 
21575e09c8c3SJim Ingham         Target *target = GetSelectedOrDummyTarget(m_name_options.m_use_dummy.GetCurrentValue());
21585e09c8c3SJim Ingham 
21595e09c8c3SJim Ingham         if (target == NULL)
21605e09c8c3SJim Ingham         {
21615e09c8c3SJim Ingham             result.AppendError ("Invalid target. No existing target or breakpoints.");
21625e09c8c3SJim Ingham             result.SetStatus (eReturnStatusFailed);
21635e09c8c3SJim Ingham             return false;
21645e09c8c3SJim Ingham         }
21655e09c8c3SJim Ingham 
21665e09c8c3SJim Ingham         Mutex::Locker locker;
21675e09c8c3SJim Ingham         target->GetBreakpointList().GetListMutex(locker);
21685e09c8c3SJim Ingham 
21695e09c8c3SJim Ingham         const BreakpointList &breakpoints = target->GetBreakpointList();
21705e09c8c3SJim Ingham 
21715e09c8c3SJim Ingham         size_t num_breakpoints = breakpoints.GetSize();
21725e09c8c3SJim Ingham         if (num_breakpoints == 0)
21735e09c8c3SJim Ingham         {
21745e09c8c3SJim Ingham             result.SetError("No breakpoints, cannot delete names.");
21755e09c8c3SJim Ingham             result.SetStatus (eReturnStatusFailed);
21765e09c8c3SJim Ingham             return false;
21775e09c8c3SJim Ingham         }
21785e09c8c3SJim Ingham 
21795e09c8c3SJim Ingham         // Particular breakpoint selected; disable that breakpoint.
21805e09c8c3SJim Ingham         BreakpointIDList valid_bp_ids;
21815e09c8c3SJim Ingham         CommandObjectMultiwordBreakpoint::VerifyBreakpointIDs (command, target, result, &valid_bp_ids);
21825e09c8c3SJim Ingham 
21835e09c8c3SJim Ingham         if (result.Succeeded())
21845e09c8c3SJim Ingham         {
21855e09c8c3SJim Ingham             if (valid_bp_ids.GetSize() == 0)
21865e09c8c3SJim Ingham             {
21875e09c8c3SJim Ingham                 result.SetError("No breakpoints specified, cannot delete names.");
21885e09c8c3SJim Ingham                 result.SetStatus (eReturnStatusFailed);
21895e09c8c3SJim Ingham                 return false;
21905e09c8c3SJim Ingham             }
21915e09c8c3SJim Ingham             size_t num_valid_ids = valid_bp_ids.GetSize();
21925e09c8c3SJim Ingham             for (size_t index = 0; index < num_valid_ids; index++)
21935e09c8c3SJim Ingham             {
21945e09c8c3SJim Ingham                 lldb::break_id_t bp_id = valid_bp_ids.GetBreakpointIDAtIndex(index).GetBreakpointID();
21955e09c8c3SJim Ingham                 BreakpointSP bp_sp = breakpoints.FindBreakpointByID(bp_id);
21965e09c8c3SJim Ingham                 bp_sp->RemoveName(m_name_options.m_name.GetCurrentValue());
21975e09c8c3SJim Ingham             }
21985e09c8c3SJim Ingham         }
21995e09c8c3SJim Ingham 
22005e09c8c3SJim Ingham         return true;
22015e09c8c3SJim Ingham     }
22025e09c8c3SJim Ingham 
22035e09c8c3SJim Ingham private:
22045e09c8c3SJim Ingham     BreakpointNameOptionGroup m_name_options;
22055e09c8c3SJim Ingham     OptionGroupOptions m_option_group;
22065e09c8c3SJim Ingham };
22075e09c8c3SJim Ingham 
22085e09c8c3SJim Ingham class CommandObjectBreakpointNameList : public CommandObjectParsed
22095e09c8c3SJim Ingham {
22105e09c8c3SJim Ingham public:
22115e09c8c3SJim Ingham     CommandObjectBreakpointNameList (CommandInterpreter &interpreter) :
22125e09c8c3SJim Ingham         CommandObjectParsed (interpreter,
22135e09c8c3SJim Ingham                              "list",
22145e09c8c3SJim Ingham                              "List either the names for a breakpoint or the breakpoints for a given name.",
22155e09c8c3SJim Ingham                              "breakpoint name list <command-options>"),
22165e09c8c3SJim Ingham         m_name_options(),
22175e09c8c3SJim Ingham         m_option_group(interpreter)
22185e09c8c3SJim Ingham     {
22195e09c8c3SJim Ingham         m_option_group.Append (&m_name_options);
22205e09c8c3SJim Ingham         m_option_group.Finalize();
22215e09c8c3SJim Ingham     }
22225e09c8c3SJim Ingham 
22235e09c8c3SJim Ingham     virtual
22245e09c8c3SJim Ingham     ~CommandObjectBreakpointNameList () {}
22255e09c8c3SJim Ingham 
22265e09c8c3SJim Ingham   Options *
22275e09c8c3SJim Ingham   GetOptions ()
22285e09c8c3SJim Ingham   {
22295e09c8c3SJim Ingham     return &m_option_group;
22305e09c8c3SJim Ingham   }
22315e09c8c3SJim Ingham 
22325e09c8c3SJim Ingham protected:
22335e09c8c3SJim Ingham     virtual bool
22345e09c8c3SJim Ingham     DoExecute (Args& command, CommandReturnObject &result)
22355e09c8c3SJim Ingham     {
22365e09c8c3SJim Ingham         Target *target = GetSelectedOrDummyTarget(m_name_options.m_use_dummy.GetCurrentValue());
22375e09c8c3SJim Ingham 
22385e09c8c3SJim Ingham         if (target == NULL)
22395e09c8c3SJim Ingham         {
22405e09c8c3SJim Ingham             result.AppendError ("Invalid target. No existing target or breakpoints.");
22415e09c8c3SJim Ingham             result.SetStatus (eReturnStatusFailed);
22425e09c8c3SJim Ingham             return false;
22435e09c8c3SJim Ingham         }
22445e09c8c3SJim Ingham 
22455e09c8c3SJim Ingham         if (m_name_options.m_name.OptionWasSet())
22465e09c8c3SJim Ingham         {
22475e09c8c3SJim Ingham             const char *name = m_name_options.m_name.GetCurrentValue();
22485e09c8c3SJim Ingham             Mutex::Locker locker;
22495e09c8c3SJim Ingham             target->GetBreakpointList().GetListMutex(locker);
22505e09c8c3SJim Ingham 
22515e09c8c3SJim Ingham             BreakpointList &breakpoints = target->GetBreakpointList();
22525e09c8c3SJim Ingham             for (BreakpointSP bp_sp : breakpoints.Breakpoints())
22535e09c8c3SJim Ingham             {
22545e09c8c3SJim Ingham                 if (bp_sp->MatchesName(name))
22555e09c8c3SJim Ingham                 {
22565e09c8c3SJim Ingham                     StreamString s;
22575e09c8c3SJim Ingham                     bp_sp->GetDescription(&s, eDescriptionLevelBrief);
22585e09c8c3SJim Ingham                     s.EOL();
22595e09c8c3SJim Ingham                     result.AppendMessage(s.GetData());
22605e09c8c3SJim Ingham                 }
22615e09c8c3SJim Ingham             }
22625e09c8c3SJim Ingham 
22635e09c8c3SJim Ingham         }
22645e09c8c3SJim Ingham         else if (m_name_options.m_breakpoint.OptionWasSet())
22655e09c8c3SJim Ingham         {
22665e09c8c3SJim Ingham             BreakpointSP bp_sp = target->GetBreakpointList().FindBreakpointByID(m_name_options.m_breakpoint.GetCurrentValue());
22675e09c8c3SJim Ingham             if (bp_sp)
22685e09c8c3SJim Ingham             {
22695e09c8c3SJim Ingham                 std::vector<std::string> names;
22705e09c8c3SJim Ingham                 bp_sp->GetNames (names);
22715e09c8c3SJim Ingham                 result.AppendMessage ("Names:");
22725e09c8c3SJim Ingham                 for (auto name : names)
22735e09c8c3SJim Ingham                     result.AppendMessageWithFormat ("    %s\n", name.c_str());
22745e09c8c3SJim Ingham             }
22755e09c8c3SJim Ingham             else
22765e09c8c3SJim Ingham             {
22775e09c8c3SJim Ingham                 result.AppendErrorWithFormat ("Could not find breakpoint %" PRId64 ".\n",
22785e09c8c3SJim Ingham                                            m_name_options.m_breakpoint.GetCurrentValue());
22795e09c8c3SJim Ingham                 result.SetStatus (eReturnStatusFailed);
22805e09c8c3SJim Ingham                 return false;
22815e09c8c3SJim Ingham             }
22825e09c8c3SJim Ingham         }
22835e09c8c3SJim Ingham         else
22845e09c8c3SJim Ingham         {
22855e09c8c3SJim Ingham             result.SetError ("Must specify -N or -B option to list.");
22865e09c8c3SJim Ingham             result.SetStatus (eReturnStatusFailed);
22875e09c8c3SJim Ingham             return false;
22885e09c8c3SJim Ingham         }
22895e09c8c3SJim Ingham         return true;
22905e09c8c3SJim Ingham     }
22915e09c8c3SJim Ingham 
22925e09c8c3SJim Ingham private:
22935e09c8c3SJim Ingham     BreakpointNameOptionGroup m_name_options;
22945e09c8c3SJim Ingham     OptionGroupOptions m_option_group;
22955e09c8c3SJim Ingham };
22965e09c8c3SJim Ingham 
22975e09c8c3SJim Ingham //-------------------------------------------------------------------------
22985e09c8c3SJim Ingham // CommandObjectMultiwordBreakpoint
22995e09c8c3SJim Ingham //-------------------------------------------------------------------------
23005e09c8c3SJim Ingham class CommandObjectBreakpointName : public CommandObjectMultiword
23015e09c8c3SJim Ingham {
23025e09c8c3SJim Ingham public:
23035e09c8c3SJim Ingham     CommandObjectBreakpointName (CommandInterpreter &interpreter) :
23045e09c8c3SJim Ingham         CommandObjectMultiword(interpreter,
23055e09c8c3SJim Ingham                                 "name",
23065e09c8c3SJim Ingham                                 "A set of commands to manage name tags for breakpoints",
23075e09c8c3SJim Ingham                                 "breakpoint name <command> [<command-options>]")
23085e09c8c3SJim Ingham     {
23095e09c8c3SJim Ingham         CommandObjectSP add_command_object (new CommandObjectBreakpointNameAdd (interpreter));
23105e09c8c3SJim Ingham         CommandObjectSP delete_command_object (new CommandObjectBreakpointNameDelete (interpreter));
23115e09c8c3SJim Ingham         CommandObjectSP list_command_object (new CommandObjectBreakpointNameList (interpreter));
23125e09c8c3SJim Ingham 
23135e09c8c3SJim Ingham         LoadSubCommand ("add", add_command_object);
23145e09c8c3SJim Ingham         LoadSubCommand ("delete", delete_command_object);
23155e09c8c3SJim Ingham         LoadSubCommand ("list", list_command_object);
23165e09c8c3SJim Ingham 
23175e09c8c3SJim Ingham     }
23185e09c8c3SJim Ingham 
23195e09c8c3SJim Ingham     virtual
23205e09c8c3SJim Ingham     ~CommandObjectBreakpointName ()
23215e09c8c3SJim Ingham     {
23225e09c8c3SJim Ingham     }
23235e09c8c3SJim Ingham 
23245e09c8c3SJim Ingham };
23255e09c8c3SJim Ingham 
23265e09c8c3SJim Ingham 
23275e09c8c3SJim Ingham //-------------------------------------------------------------------------
232830fdc8d8SChris Lattner // CommandObjectMultiwordBreakpoint
232930fdc8d8SChris Lattner //-------------------------------------------------------------------------
2330ae1c4cf5SJim Ingham #pragma mark MultiwordBreakpoint
233130fdc8d8SChris Lattner 
23326611103cSGreg Clayton CommandObjectMultiwordBreakpoint::CommandObjectMultiwordBreakpoint (CommandInterpreter &interpreter) :
2333a7015092SGreg Clayton     CommandObjectMultiword (interpreter,
2334a7015092SGreg Clayton                             "breakpoint",
233546fbc60fSJim Ingham                             "A set of commands for operating on breakpoints. Also see _regexp-break.",
233630fdc8d8SChris Lattner                             "breakpoint <command> [<command-options>]")
233730fdc8d8SChris Lattner {
2338a7015092SGreg Clayton     CommandObjectSP list_command_object (new CommandObjectBreakpointList (interpreter));
2339a7015092SGreg Clayton     CommandObjectSP enable_command_object (new CommandObjectBreakpointEnable (interpreter));
2340a7015092SGreg Clayton     CommandObjectSP disable_command_object (new CommandObjectBreakpointDisable (interpreter));
2341b7234e40SJohnny Chen     CommandObjectSP clear_command_object (new CommandObjectBreakpointClear (interpreter));
2342b7234e40SJohnny Chen     CommandObjectSP delete_command_object (new CommandObjectBreakpointDelete (interpreter));
2343a7015092SGreg Clayton     CommandObjectSP set_command_object (new CommandObjectBreakpointSet (interpreter));
234430fdc8d8SChris Lattner     CommandObjectSP command_command_object (new CommandObjectBreakpointCommand (interpreter));
2345a7015092SGreg Clayton     CommandObjectSP modify_command_object (new CommandObjectBreakpointModify(interpreter));
23465e09c8c3SJim Ingham     CommandObjectSP name_command_object (new CommandObjectBreakpointName(interpreter));
234730fdc8d8SChris Lattner 
2348b7234e40SJohnny Chen     list_command_object->SetCommandName ("breakpoint list");
234930fdc8d8SChris Lattner     enable_command_object->SetCommandName("breakpoint enable");
235030fdc8d8SChris Lattner     disable_command_object->SetCommandName("breakpoint disable");
2351b7234e40SJohnny Chen     clear_command_object->SetCommandName("breakpoint clear");
2352b7234e40SJohnny Chen     delete_command_object->SetCommandName("breakpoint delete");
2353ae1c4cf5SJim Ingham     set_command_object->SetCommandName("breakpoint set");
2354b7234e40SJohnny Chen     command_command_object->SetCommandName ("breakpoint command");
2355b7234e40SJohnny Chen     modify_command_object->SetCommandName ("breakpoint modify");
23565e09c8c3SJim Ingham     name_command_object->SetCommandName ("breakpoint name");
235730fdc8d8SChris Lattner 
235823f59509SGreg Clayton     LoadSubCommand ("list",       list_command_object);
235923f59509SGreg Clayton     LoadSubCommand ("enable",     enable_command_object);
236023f59509SGreg Clayton     LoadSubCommand ("disable",    disable_command_object);
236123f59509SGreg Clayton     LoadSubCommand ("clear",      clear_command_object);
236223f59509SGreg Clayton     LoadSubCommand ("delete",     delete_command_object);
236323f59509SGreg Clayton     LoadSubCommand ("set",        set_command_object);
236423f59509SGreg Clayton     LoadSubCommand ("command",    command_command_object);
236523f59509SGreg Clayton     LoadSubCommand ("modify",     modify_command_object);
23665e09c8c3SJim Ingham     LoadSubCommand ("name",       name_command_object);
236730fdc8d8SChris Lattner }
236830fdc8d8SChris Lattner 
236930fdc8d8SChris Lattner CommandObjectMultiwordBreakpoint::~CommandObjectMultiwordBreakpoint ()
237030fdc8d8SChris Lattner {
237130fdc8d8SChris Lattner }
237230fdc8d8SChris Lattner 
237330fdc8d8SChris Lattner void
23745e09c8c3SJim Ingham CommandObjectMultiwordBreakpoint::VerifyIDs (Args &args,
23755e09c8c3SJim Ingham                                              Target *target,
23765e09c8c3SJim Ingham                                              bool allow_locations,
23775e09c8c3SJim Ingham                                              CommandReturnObject &result,
237830fdc8d8SChris Lattner                                              BreakpointIDList *valid_ids)
237930fdc8d8SChris Lattner {
238030fdc8d8SChris Lattner     // args can be strings representing 1). integers (for breakpoint ids)
238130fdc8d8SChris Lattner     //                                  2). the full breakpoint & location canonical representation
238230fdc8d8SChris Lattner     //                                  3). the word "to" or a hyphen, representing a range (in which case there
238330fdc8d8SChris Lattner     //                                      had *better* be an entry both before & after of one of the first two types.
23845e09c8c3SJim Ingham     //                                  4). A breakpoint name
238536f3b369SJim Ingham     // If args is empty, we will use the last created breakpoint (if there is one.)
238630fdc8d8SChris Lattner 
238730fdc8d8SChris Lattner     Args temp_args;
238830fdc8d8SChris Lattner 
238936f3b369SJim Ingham     if (args.GetArgumentCount() == 0)
239036f3b369SJim Ingham     {
23914d122c40SGreg Clayton         if (target->GetLastCreatedBreakpoint())
239236f3b369SJim Ingham         {
239336f3b369SJim Ingham             valid_ids->AddBreakpointID (BreakpointID(target->GetLastCreatedBreakpoint()->GetID(), LLDB_INVALID_BREAK_ID));
239436f3b369SJim Ingham             result.SetStatus (eReturnStatusSuccessFinishNoResult);
239536f3b369SJim Ingham         }
239636f3b369SJim Ingham         else
239736f3b369SJim Ingham         {
239836f3b369SJim Ingham             result.AppendError("No breakpoint specified and no last created breakpoint.");
239936f3b369SJim Ingham             result.SetStatus (eReturnStatusFailed);
240036f3b369SJim Ingham         }
240136f3b369SJim Ingham         return;
240236f3b369SJim Ingham     }
240336f3b369SJim Ingham 
240430fdc8d8SChris Lattner     // Create a new Args variable to use; copy any non-breakpoint-id-ranges stuff directly from the old ARGS to
240530fdc8d8SChris Lattner     // the new TEMP_ARGS.  Do not copy breakpoint id range strings over; instead generate a list of strings for
240630fdc8d8SChris Lattner     // all the breakpoint ids in the range, and shove all of those breakpoint id strings into TEMP_ARGS.
240730fdc8d8SChris Lattner 
24085e09c8c3SJim Ingham     BreakpointIDList::FindAndReplaceIDRanges (args, target, allow_locations, result, temp_args);
240930fdc8d8SChris Lattner 
241030fdc8d8SChris Lattner     // NOW, convert the list of breakpoint id strings in TEMP_ARGS into an actual BreakpointIDList:
241130fdc8d8SChris Lattner 
2412c982c768SGreg Clayton     valid_ids->InsertStringArray (temp_args.GetConstArgumentVector(), temp_args.GetArgumentCount(), result);
241330fdc8d8SChris Lattner 
241430fdc8d8SChris Lattner     // At this point,  all of the breakpoint ids that the user passed in have been converted to breakpoint IDs
241530fdc8d8SChris Lattner     // and put into valid_ids.
241630fdc8d8SChris Lattner 
241730fdc8d8SChris Lattner     if (result.Succeeded())
241830fdc8d8SChris Lattner     {
241930fdc8d8SChris Lattner         // Now that we've converted everything from args into a list of breakpoint ids, go through our tentative list
242030fdc8d8SChris Lattner         // of breakpoint id's and verify that they correspond to valid/currently set breakpoints.
242130fdc8d8SChris Lattner 
2422c982c768SGreg Clayton         const size_t count = valid_ids->GetSize();
2423c982c768SGreg Clayton         for (size_t i = 0; i < count; ++i)
242430fdc8d8SChris Lattner         {
242530fdc8d8SChris Lattner             BreakpointID cur_bp_id = valid_ids->GetBreakpointIDAtIndex (i);
242630fdc8d8SChris Lattner             Breakpoint *breakpoint = target->GetBreakpointByID (cur_bp_id.GetBreakpointID()).get();
242730fdc8d8SChris Lattner             if (breakpoint != NULL)
242830fdc8d8SChris Lattner             {
2429c7bece56SGreg Clayton                 const size_t num_locations = breakpoint->GetNumLocations();
24303985c8c6SSaleem Abdulrasool                 if (static_cast<size_t>(cur_bp_id.GetLocationID()) > num_locations)
243130fdc8d8SChris Lattner                 {
243230fdc8d8SChris Lattner                     StreamString id_str;
2433c982c768SGreg Clayton                     BreakpointID::GetCanonicalReference (&id_str,
2434c982c768SGreg Clayton                                                          cur_bp_id.GetBreakpointID(),
243530fdc8d8SChris Lattner                                                          cur_bp_id.GetLocationID());
2436c982c768SGreg Clayton                     i = valid_ids->GetSize() + 1;
243730fdc8d8SChris Lattner                     result.AppendErrorWithFormat ("'%s' is not a currently valid breakpoint/location id.\n",
243830fdc8d8SChris Lattner                                                  id_str.GetData());
243930fdc8d8SChris Lattner                     result.SetStatus (eReturnStatusFailed);
244030fdc8d8SChris Lattner                 }
244130fdc8d8SChris Lattner             }
244230fdc8d8SChris Lattner             else
244330fdc8d8SChris Lattner             {
2444c982c768SGreg Clayton                 i = valid_ids->GetSize() + 1;
244530fdc8d8SChris Lattner                 result.AppendErrorWithFormat ("'%d' is not a currently valid breakpoint id.\n", cur_bp_id.GetBreakpointID());
244630fdc8d8SChris Lattner                 result.SetStatus (eReturnStatusFailed);
244730fdc8d8SChris Lattner             }
244830fdc8d8SChris Lattner         }
244930fdc8d8SChris Lattner     }
245030fdc8d8SChris Lattner }
2451