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"
2240af72e1SJim Ingham #include "lldb/Interpreter/Options.h"
235e09c8c3SJim Ingham #include "lldb/Interpreter/OptionValueString.h"
245e09c8c3SJim Ingham #include "lldb/Interpreter/OptionValueUInt64.h"
2530fdc8d8SChris Lattner #include "lldb/Core/RegularExpression.h"
2630fdc8d8SChris Lattner #include "lldb/Core/StreamString.h"
2730fdc8d8SChris Lattner #include "lldb/Interpreter/CommandInterpreter.h"
2830fdc8d8SChris Lattner #include "lldb/Interpreter/CommandReturnObject.h"
2930fdc8d8SChris Lattner #include "lldb/Target/Target.h"
3030fdc8d8SChris Lattner #include "lldb/Interpreter/CommandCompletions.h"
31b57e4a1bSJason Molenda #include "lldb/Target/StackFrame.h"
321b54c88cSJim Ingham #include "lldb/Target/Thread.h"
331b54c88cSJim Ingham #include "lldb/Target/ThreadSpec.h"
3430fdc8d8SChris Lattner 
35b7234e40SJohnny Chen #include <vector>
36b7234e40SJohnny Chen 
3730fdc8d8SChris Lattner using namespace lldb;
3830fdc8d8SChris Lattner using namespace lldb_private;
3930fdc8d8SChris Lattner 
4030fdc8d8SChris Lattner static void
4185e8b814SJim Ingham AddBreakpointDescription (Stream *s, Breakpoint *bp, lldb::DescriptionLevel level)
4230fdc8d8SChris Lattner {
4330fdc8d8SChris Lattner     s->IndentMore();
4430fdc8d8SChris Lattner     bp->GetDescription (s, level, true);
4530fdc8d8SChris Lattner     s->IndentLess();
4630fdc8d8SChris Lattner     s->EOL();
4730fdc8d8SChris Lattner }
4830fdc8d8SChris Lattner 
4930fdc8d8SChris Lattner //-------------------------------------------------------------------------
505a988416SJim Ingham // CommandObjectBreakpointSet
5130fdc8d8SChris Lattner //-------------------------------------------------------------------------
5230fdc8d8SChris Lattner 
535a988416SJim Ingham 
545a988416SJim Ingham class CommandObjectBreakpointSet : public CommandObjectParsed
555a988416SJim Ingham {
565a988416SJim Ingham public:
575a988416SJim Ingham 
585a988416SJim Ingham     typedef enum BreakpointSetType
595a988416SJim Ingham     {
605a988416SJim Ingham         eSetTypeInvalid,
615a988416SJim Ingham         eSetTypeFileAndLine,
625a988416SJim Ingham         eSetTypeAddress,
635a988416SJim Ingham         eSetTypeFunctionName,
645a988416SJim Ingham         eSetTypeFunctionRegexp,
655a988416SJim Ingham         eSetTypeSourceRegexp,
665a988416SJim Ingham         eSetTypeException
675a988416SJim Ingham     } BreakpointSetType;
685a988416SJim Ingham 
695a988416SJim Ingham     CommandObjectBreakpointSet (CommandInterpreter &interpreter) :
705a988416SJim Ingham         CommandObjectParsed (interpreter,
715a988416SJim Ingham                              "breakpoint set",
725a988416SJim Ingham                              "Sets a breakpoint or set of breakpoints in the executable.",
735a988416SJim Ingham                              "breakpoint set <cmd-options>"),
745a988416SJim Ingham         m_options (interpreter)
755a988416SJim Ingham     {
765a988416SJim Ingham     }
775a988416SJim Ingham 
785a988416SJim Ingham 
795a988416SJim Ingham     virtual
805a988416SJim Ingham     ~CommandObjectBreakpointSet () {}
815a988416SJim Ingham 
825a988416SJim Ingham     virtual Options *
835a988416SJim Ingham     GetOptions ()
845a988416SJim Ingham     {
855a988416SJim Ingham         return &m_options;
865a988416SJim Ingham     }
875a988416SJim Ingham 
885a988416SJim Ingham     class CommandOptions : public Options
895a988416SJim Ingham     {
905a988416SJim Ingham     public:
915a988416SJim Ingham 
925a988416SJim Ingham         CommandOptions (CommandInterpreter &interpreter) :
93eb0103f2SGreg Clayton             Options (interpreter),
947d49c9c8SJohnny Chen             m_condition (),
9587df91b8SJim Ingham             m_filenames (),
9630fdc8d8SChris Lattner             m_line_num (0),
9730fdc8d8SChris Lattner             m_column (0),
98fab10e89SJim Ingham             m_func_names (),
99fab10e89SJim Ingham             m_func_name_type_mask (eFunctionNameTypeNone),
10030fdc8d8SChris Lattner             m_func_regexp (),
101969795f1SJim Ingham             m_source_text_regexp(),
10230fdc8d8SChris Lattner             m_modules (),
1031b54c88cSJim Ingham             m_load_addr(),
104c982c768SGreg Clayton             m_ignore_count (0),
1051b54c88cSJim Ingham             m_thread_id(LLDB_INVALID_THREAD_ID),
106c982c768SGreg Clayton             m_thread_index (UINT32_MAX),
1071b54c88cSJim Ingham             m_thread_name(),
108fab10e89SJim Ingham             m_queue_name(),
109fab10e89SJim Ingham             m_catch_bp (false),
1101f746071SGreg Clayton             m_throw_bp (true),
111eb023e75SGreg Clayton             m_hardware (false),
112a8558b62SJim Ingham             m_language (eLanguageTypeUnknown),
113ca36cd16SJim Ingham             m_skip_prologue (eLazyBoolCalculate),
114ca36cd16SJim Ingham             m_one_shot (false)
11530fdc8d8SChris Lattner         {
11630fdc8d8SChris Lattner         }
11730fdc8d8SChris Lattner 
11830fdc8d8SChris Lattner 
1195a988416SJim Ingham         virtual
1205a988416SJim Ingham         ~CommandOptions () {}
12187df91b8SJim Ingham 
1225a988416SJim Ingham         virtual Error
1235a988416SJim Ingham         SetOptionValue (uint32_t option_idx, const char *option_arg)
12430fdc8d8SChris Lattner         {
12530fdc8d8SChris Lattner             Error error;
1263bcdfc0eSGreg Clayton             const int short_option = m_getopt_table[option_idx].val;
12730fdc8d8SChris Lattner 
12830fdc8d8SChris Lattner             switch (short_option)
12930fdc8d8SChris Lattner             {
13030fdc8d8SChris Lattner                 case 'a':
131b9d5df58SGreg Clayton                     {
132b9d5df58SGreg Clayton                         ExecutionContext exe_ctx (m_interpreter.GetExecutionContext());
133b9d5df58SGreg Clayton                         m_load_addr = Args::StringToAddress(&exe_ctx, option_arg, LLDB_INVALID_ADDRESS, &error);
134b9d5df58SGreg Clayton                     }
13530fdc8d8SChris Lattner                     break;
13630fdc8d8SChris Lattner 
137ca36cd16SJim Ingham                 case 'b':
138ca36cd16SJim Ingham                     m_func_names.push_back (option_arg);
139ca36cd16SJim Ingham                     m_func_name_type_mask |= eFunctionNameTypeBase;
140ca36cd16SJim Ingham                     break;
141ca36cd16SJim Ingham 
1427d49c9c8SJohnny Chen                 case 'C':
14330fdc8d8SChris Lattner                     m_column = Args::StringToUInt32 (option_arg, 0);
14430fdc8d8SChris Lattner                     break;
1450c5cd90dSGreg Clayton 
1467d49c9c8SJohnny Chen                 case 'c':
1477d49c9c8SJohnny Chen                     m_condition.assign(option_arg);
1487d49c9c8SJohnny Chen                     break;
1497d49c9c8SJohnny Chen 
15033df7cd3SJim Ingham                 case 'D':
15133df7cd3SJim Ingham                     m_use_dummy = true;
15233df7cd3SJim Ingham                     break;
15333df7cd3SJim Ingham 
154fab10e89SJim Ingham                 case 'E':
155fab10e89SJim Ingham                 {
156fab10e89SJim Ingham                     LanguageType language = LanguageRuntime::GetLanguageTypeFromString (option_arg);
157fab10e89SJim Ingham 
158fab10e89SJim Ingham                     switch (language)
159fab10e89SJim Ingham                     {
160fab10e89SJim Ingham                         case eLanguageTypeC89:
161fab10e89SJim Ingham                         case eLanguageTypeC:
162fab10e89SJim Ingham                         case eLanguageTypeC99:
1631d0089faSBruce Mitchener                         case eLanguageTypeC11:
164fab10e89SJim Ingham                             m_language = eLanguageTypeC;
165fab10e89SJim Ingham                             break;
166fab10e89SJim Ingham                         case eLanguageTypeC_plus_plus:
1671d0089faSBruce Mitchener                         case eLanguageTypeC_plus_plus_03:
1681d0089faSBruce Mitchener                         case eLanguageTypeC_plus_plus_11:
169fab10e89SJim Ingham                             m_language = eLanguageTypeC_plus_plus;
170fab10e89SJim Ingham                             break;
171fab10e89SJim Ingham                         case eLanguageTypeObjC:
172fab10e89SJim Ingham                             m_language = eLanguageTypeObjC;
173fab10e89SJim Ingham                             break;
174fab10e89SJim Ingham                         case eLanguageTypeObjC_plus_plus:
175fab10e89SJim Ingham                             error.SetErrorStringWithFormat ("Set exception breakpoints separately for c++ and objective-c");
176fab10e89SJim Ingham                             break;
177fab10e89SJim Ingham                         case eLanguageTypeUnknown:
178fab10e89SJim Ingham                             error.SetErrorStringWithFormat ("Unknown language type: '%s' for exception breakpoint", option_arg);
179fab10e89SJim Ingham                             break;
180fab10e89SJim Ingham                         default:
181fab10e89SJim Ingham                             error.SetErrorStringWithFormat ("Unsupported language type: '%s' for exception breakpoint", option_arg);
182fab10e89SJim Ingham                     }
183fab10e89SJim Ingham                 }
184fab10e89SJim Ingham                 break;
185ca36cd16SJim Ingham 
186ca36cd16SJim Ingham                 case 'f':
187ca36cd16SJim Ingham                     m_filenames.AppendIfUnique (FileSpec(option_arg, false));
188fab10e89SJim Ingham                     break;
189ca36cd16SJim Ingham 
190ca36cd16SJim Ingham                 case 'F':
191ca36cd16SJim Ingham                     m_func_names.push_back (option_arg);
192ca36cd16SJim Ingham                     m_func_name_type_mask |= eFunctionNameTypeFull;
193ca36cd16SJim Ingham                     break;
194ca36cd16SJim Ingham 
195fab10e89SJim Ingham                 case 'h':
196fab10e89SJim Ingham                     {
197fab10e89SJim Ingham                         bool success;
198fab10e89SJim Ingham                         m_catch_bp = Args::StringToBoolean (option_arg, true, &success);
199fab10e89SJim Ingham                         if (!success)
200fab10e89SJim Ingham                             error.SetErrorStringWithFormat ("Invalid boolean value for on-catch option: '%s'", option_arg);
201fab10e89SJim Ingham                     }
202168d469aSJim Ingham                     break;
203eb023e75SGreg Clayton 
204eb023e75SGreg Clayton                 case 'H':
205eb023e75SGreg Clayton                     m_hardware = true;
206eb023e75SGreg Clayton                     break;
207eb023e75SGreg Clayton 
208ca36cd16SJim Ingham                 case 'i':
209ca36cd16SJim Ingham                 {
210ca36cd16SJim Ingham                     m_ignore_count = Args::StringToUInt32(option_arg, UINT32_MAX, 0);
211ca36cd16SJim Ingham                     if (m_ignore_count == UINT32_MAX)
212ca36cd16SJim Ingham                        error.SetErrorStringWithFormat ("invalid ignore count '%s'", option_arg);
213ca36cd16SJim Ingham                     break;
214ca36cd16SJim Ingham                 }
215ca36cd16SJim Ingham 
216a8558b62SJim Ingham                 case 'K':
217a8558b62SJim Ingham                 {
218a8558b62SJim Ingham                     bool success;
219a8558b62SJim Ingham                     bool value;
220a8558b62SJim Ingham                     value = Args::StringToBoolean (option_arg, true, &success);
221a8558b62SJim Ingham                     if (value)
222a8558b62SJim Ingham                         m_skip_prologue = eLazyBoolYes;
223a8558b62SJim Ingham                     else
224a8558b62SJim Ingham                         m_skip_prologue = eLazyBoolNo;
225a8558b62SJim Ingham 
226a8558b62SJim Ingham                     if (!success)
227a8558b62SJim Ingham                         error.SetErrorStringWithFormat ("Invalid boolean value for skip prologue option: '%s'", option_arg);
228a8558b62SJim Ingham                 }
229fab10e89SJim Ingham                 break;
230ca36cd16SJim Ingham 
231ca36cd16SJim Ingham                 case 'l':
232ca36cd16SJim Ingham                     m_line_num = Args::StringToUInt32 (option_arg, 0);
233ca36cd16SJim Ingham                     break;
234ca36cd16SJim Ingham 
235ca36cd16SJim Ingham                 case 'M':
236ca36cd16SJim Ingham                     m_func_names.push_back (option_arg);
237ca36cd16SJim Ingham                     m_func_name_type_mask |= eFunctionNameTypeMethod;
238ca36cd16SJim Ingham                     break;
239ca36cd16SJim Ingham 
240ca36cd16SJim Ingham                 case 'n':
241ca36cd16SJim Ingham                     m_func_names.push_back (option_arg);
242ca36cd16SJim Ingham                     m_func_name_type_mask |= eFunctionNameTypeAuto;
243ca36cd16SJim Ingham                     break;
244ca36cd16SJim Ingham 
2455e09c8c3SJim Ingham                 case 'N':
2465e09c8c3SJim Ingham                     if (BreakpointID::StringIsBreakpointName(option_arg, error))
2475e09c8c3SJim Ingham                         m_breakpoint_names.push_back (option_arg);
2485e09c8c3SJim Ingham                     break;
2495e09c8c3SJim Ingham 
250ca36cd16SJim Ingham                 case 'o':
251ca36cd16SJim Ingham                     m_one_shot = true;
252ca36cd16SJim Ingham                     break;
253ca36cd16SJim Ingham 
254ca36cd16SJim Ingham                 case 'p':
255ca36cd16SJim Ingham                     m_source_text_regexp.assign (option_arg);
256ca36cd16SJim Ingham                     break;
257ca36cd16SJim Ingham 
258ca36cd16SJim Ingham                 case 'q':
259ca36cd16SJim Ingham                     m_queue_name.assign (option_arg);
260ca36cd16SJim Ingham                     break;
261ca36cd16SJim Ingham 
262ca36cd16SJim Ingham                 case 'r':
263ca36cd16SJim Ingham                     m_func_regexp.assign (option_arg);
264ca36cd16SJim Ingham                     break;
265ca36cd16SJim Ingham 
266ca36cd16SJim Ingham                 case 's':
267ca36cd16SJim Ingham                 {
268ca36cd16SJim Ingham                     m_modules.AppendIfUnique (FileSpec (option_arg, false));
269ca36cd16SJim Ingham                     break;
270ca36cd16SJim Ingham                 }
271ca36cd16SJim Ingham 
272ca36cd16SJim Ingham                 case 'S':
273ca36cd16SJim Ingham                     m_func_names.push_back (option_arg);
274ca36cd16SJim Ingham                     m_func_name_type_mask |= eFunctionNameTypeSelector;
275ca36cd16SJim Ingham                     break;
276ca36cd16SJim Ingham 
277ca36cd16SJim Ingham                 case 't' :
278ca36cd16SJim Ingham                 {
279ca36cd16SJim Ingham                     m_thread_id = Args::StringToUInt64(option_arg, LLDB_INVALID_THREAD_ID, 0);
280ca36cd16SJim Ingham                     if (m_thread_id == LLDB_INVALID_THREAD_ID)
281ca36cd16SJim Ingham                        error.SetErrorStringWithFormat ("invalid thread id string '%s'", option_arg);
282ca36cd16SJim Ingham                 }
283ca36cd16SJim Ingham                 break;
284ca36cd16SJim Ingham 
285ca36cd16SJim Ingham                 case 'T':
286ca36cd16SJim Ingham                     m_thread_name.assign (option_arg);
287ca36cd16SJim Ingham                     break;
288ca36cd16SJim Ingham 
289ca36cd16SJim Ingham                 case 'w':
290ca36cd16SJim Ingham                 {
291ca36cd16SJim Ingham                     bool success;
292ca36cd16SJim Ingham                     m_throw_bp = Args::StringToBoolean (option_arg, true, &success);
293ca36cd16SJim Ingham                     if (!success)
294ca36cd16SJim Ingham                         error.SetErrorStringWithFormat ("Invalid boolean value for on-throw option: '%s'", option_arg);
295ca36cd16SJim Ingham                 }
296ca36cd16SJim Ingham                 break;
297ca36cd16SJim Ingham 
298ca36cd16SJim Ingham                 case 'x':
299ca36cd16SJim Ingham                 {
300ca36cd16SJim Ingham                     m_thread_index = Args::StringToUInt32(option_arg, UINT32_MAX, 0);
301ca36cd16SJim Ingham                     if (m_thread_id == UINT32_MAX)
302ca36cd16SJim Ingham                        error.SetErrorStringWithFormat ("invalid thread index string '%s'", option_arg);
303ca36cd16SJim Ingham 
304ca36cd16SJim Ingham                 }
305ca36cd16SJim Ingham                 break;
306ca36cd16SJim Ingham 
30730fdc8d8SChris Lattner                 default:
30886edbf41SGreg Clayton                     error.SetErrorStringWithFormat ("unrecognized option '%c'", short_option);
30930fdc8d8SChris Lattner                     break;
31030fdc8d8SChris Lattner             }
31130fdc8d8SChris Lattner 
31230fdc8d8SChris Lattner             return error;
31330fdc8d8SChris Lattner         }
31430fdc8d8SChris Lattner         void
3155a988416SJim Ingham         OptionParsingStarting ()
31630fdc8d8SChris Lattner         {
3177d49c9c8SJohnny Chen             m_condition.clear();
31887df91b8SJim Ingham             m_filenames.Clear();
31930fdc8d8SChris Lattner             m_line_num = 0;
32030fdc8d8SChris Lattner             m_column = 0;
321fab10e89SJim Ingham             m_func_names.clear();
3221f746071SGreg Clayton             m_func_name_type_mask = eFunctionNameTypeNone;
32330fdc8d8SChris Lattner             m_func_regexp.clear();
3241f746071SGreg Clayton             m_source_text_regexp.clear();
32587df91b8SJim Ingham             m_modules.Clear();
3261f746071SGreg Clayton             m_load_addr = LLDB_INVALID_ADDRESS;
327c982c768SGreg Clayton             m_ignore_count = 0;
3281b54c88cSJim Ingham             m_thread_id = LLDB_INVALID_THREAD_ID;
329c982c768SGreg Clayton             m_thread_index = UINT32_MAX;
3301b54c88cSJim Ingham             m_thread_name.clear();
3311b54c88cSJim Ingham             m_queue_name.clear();
332fab10e89SJim Ingham             m_catch_bp = false;
333fab10e89SJim Ingham             m_throw_bp = true;
334eb023e75SGreg Clayton             m_hardware = false;
3351f746071SGreg Clayton             m_language = eLanguageTypeUnknown;
336a8558b62SJim Ingham             m_skip_prologue = eLazyBoolCalculate;
337ca36cd16SJim Ingham             m_one_shot = false;
33833df7cd3SJim Ingham             m_use_dummy = false;
3395e09c8c3SJim Ingham             m_breakpoint_names.clear();
34030fdc8d8SChris Lattner         }
34130fdc8d8SChris Lattner 
3425a988416SJim Ingham         const OptionDefinition*
3435a988416SJim Ingham         GetDefinitions ()
34430fdc8d8SChris Lattner         {
3455a988416SJim Ingham             return g_option_table;
34630fdc8d8SChris Lattner         }
34730fdc8d8SChris Lattner 
3485a988416SJim Ingham         // Options table: Required for subclasses of Options.
34930fdc8d8SChris Lattner 
3505a988416SJim Ingham         static OptionDefinition g_option_table[];
35130fdc8d8SChris Lattner 
3525a988416SJim Ingham         // Instance variables to hold the values for command options.
353969795f1SJim Ingham 
3545a988416SJim Ingham         std::string m_condition;
3555a988416SJim Ingham         FileSpecList m_filenames;
3565a988416SJim Ingham         uint32_t m_line_num;
3575a988416SJim Ingham         uint32_t m_column;
3585a988416SJim Ingham         std::vector<std::string> m_func_names;
3595e09c8c3SJim Ingham         std::vector<std::string> m_breakpoint_names;
3605a988416SJim Ingham         uint32_t m_func_name_type_mask;
3615a988416SJim Ingham         std::string m_func_regexp;
3625a988416SJim Ingham         std::string m_source_text_regexp;
3635a988416SJim Ingham         FileSpecList m_modules;
3645a988416SJim Ingham         lldb::addr_t m_load_addr;
3655a988416SJim Ingham         uint32_t m_ignore_count;
3665a988416SJim Ingham         lldb::tid_t m_thread_id;
3675a988416SJim Ingham         uint32_t m_thread_index;
3685a988416SJim Ingham         std::string m_thread_name;
3695a988416SJim Ingham         std::string m_queue_name;
3705a988416SJim Ingham         bool m_catch_bp;
3715a988416SJim Ingham         bool m_throw_bp;
372eb023e75SGreg Clayton         bool m_hardware; // Request to use hardware breakpoints
3735a988416SJim Ingham         lldb::LanguageType m_language;
3745a988416SJim Ingham         LazyBool m_skip_prologue;
375ca36cd16SJim Ingham         bool m_one_shot;
37633df7cd3SJim Ingham         bool m_use_dummy;
3775a988416SJim Ingham 
3785a988416SJim Ingham     };
3795a988416SJim Ingham 
3805a988416SJim Ingham protected:
3815a988416SJim Ingham     virtual bool
3825a988416SJim Ingham     DoExecute (Args& command,
3835a988416SJim Ingham               CommandReturnObject &result)
38430fdc8d8SChris Lattner     {
38533df7cd3SJim Ingham         Target *target = GetSelectedOrDummyTarget(m_options.m_use_dummy);
38633df7cd3SJim Ingham 
387893c932aSJim Ingham         if (target == nullptr)
38830fdc8d8SChris Lattner         {
389effe5c95SGreg Clayton             result.AppendError ("Invalid target.  Must set target before setting breakpoints (see 'target create' command).");
39030fdc8d8SChris Lattner             result.SetStatus (eReturnStatusFailed);
39130fdc8d8SChris Lattner             return false;
39230fdc8d8SChris Lattner         }
39330fdc8d8SChris Lattner 
39430fdc8d8SChris Lattner         // The following are the various types of breakpoints that could be set:
39530fdc8d8SChris Lattner         //   1).  -f -l -p  [-s -g]   (setting breakpoint by source location)
39630fdc8d8SChris Lattner         //   2).  -a  [-s -g]         (setting breakpoint by address)
39730fdc8d8SChris Lattner         //   3).  -n  [-s -g]         (setting breakpoint by function name)
39830fdc8d8SChris Lattner         //   4).  -r  [-s -g]         (setting breakpoint by function name regular expression)
399969795f1SJim Ingham         //   5).  -p -f               (setting a breakpoint by comparing a reg-exp to source text)
400fab10e89SJim Ingham         //   6).  -E [-w -h]          (setting a breakpoint for exceptions for a given language.)
40130fdc8d8SChris Lattner 
40230fdc8d8SChris Lattner         BreakpointSetType break_type = eSetTypeInvalid;
40330fdc8d8SChris Lattner 
40430fdc8d8SChris Lattner         if (m_options.m_line_num != 0)
40530fdc8d8SChris Lattner             break_type = eSetTypeFileAndLine;
40630fdc8d8SChris Lattner         else if (m_options.m_load_addr != LLDB_INVALID_ADDRESS)
40730fdc8d8SChris Lattner             break_type = eSetTypeAddress;
408fab10e89SJim Ingham         else if (!m_options.m_func_names.empty())
40930fdc8d8SChris Lattner             break_type = eSetTypeFunctionName;
41030fdc8d8SChris Lattner         else if  (!m_options.m_func_regexp.empty())
41130fdc8d8SChris Lattner             break_type = eSetTypeFunctionRegexp;
412969795f1SJim Ingham         else if (!m_options.m_source_text_regexp.empty())
413969795f1SJim Ingham             break_type = eSetTypeSourceRegexp;
414fab10e89SJim Ingham         else if (m_options.m_language != eLanguageTypeUnknown)
415fab10e89SJim Ingham             break_type = eSetTypeException;
41630fdc8d8SChris Lattner 
41730fdc8d8SChris Lattner         Breakpoint *bp = NULL;
418274060b6SGreg Clayton         FileSpec module_spec;
419a8558b62SJim Ingham         const bool internal = false;
420a8558b62SJim Ingham 
42130fdc8d8SChris Lattner         switch (break_type)
42230fdc8d8SChris Lattner         {
42330fdc8d8SChris Lattner             case eSetTypeFileAndLine: // Breakpoint by source position
42430fdc8d8SChris Lattner                 {
42530fdc8d8SChris Lattner                     FileSpec file;
426c7bece56SGreg Clayton                     const size_t num_files = m_options.m_filenames.GetSize();
42787df91b8SJim Ingham                     if (num_files == 0)
42887df91b8SJim Ingham                     {
42987df91b8SJim Ingham                         if (!GetDefaultFile (target, file, result))
43087df91b8SJim Ingham                         {
43187df91b8SJim Ingham                             result.AppendError("No file supplied and no default file available.");
43287df91b8SJim Ingham                             result.SetStatus (eReturnStatusFailed);
43387df91b8SJim Ingham                             return false;
43487df91b8SJim Ingham                         }
43587df91b8SJim Ingham                     }
43687df91b8SJim Ingham                     else if (num_files > 1)
43787df91b8SJim Ingham                     {
43887df91b8SJim Ingham                         result.AppendError("Only one file at a time is allowed for file and line breakpoints.");
43987df91b8SJim Ingham                         result.SetStatus (eReturnStatusFailed);
44087df91b8SJim Ingham                         return false;
44187df91b8SJim Ingham                     }
44287df91b8SJim Ingham                     else
44387df91b8SJim Ingham                         file = m_options.m_filenames.GetFileSpecAtIndex(0);
44430fdc8d8SChris Lattner 
4451f746071SGreg Clayton                     // Only check for inline functions if
4461f746071SGreg Clayton                     LazyBool check_inlines = eLazyBoolCalculate;
4471f746071SGreg Clayton 
44887df91b8SJim Ingham                     bp = target->CreateBreakpoint (&(m_options.m_modules),
44930fdc8d8SChris Lattner                                                    file,
45030fdc8d8SChris Lattner                                                    m_options.m_line_num,
4511f746071SGreg Clayton                                                    check_inlines,
452a8558b62SJim Ingham                                                    m_options.m_skip_prologue,
453eb023e75SGreg Clayton                                                    internal,
454eb023e75SGreg Clayton                                                    m_options.m_hardware).get();
45530fdc8d8SChris Lattner                 }
45630fdc8d8SChris Lattner                 break;
4576eee5aa0SGreg Clayton 
45830fdc8d8SChris Lattner             case eSetTypeAddress: // Breakpoint by address
459eb023e75SGreg Clayton                 bp = target->CreateBreakpoint (m_options.m_load_addr,
460eb023e75SGreg Clayton                                                internal,
461eb023e75SGreg Clayton                                                m_options.m_hardware).get();
46230fdc8d8SChris Lattner                 break;
4630c5cd90dSGreg Clayton 
46430fdc8d8SChris Lattner             case eSetTypeFunctionName: // Breakpoint by function name
4650c5cd90dSGreg Clayton                 {
4660c5cd90dSGreg Clayton                     uint32_t name_type_mask = m_options.m_func_name_type_mask;
4670c5cd90dSGreg Clayton 
4680c5cd90dSGreg Clayton                     if (name_type_mask == 0)
469e02b8504SGreg Clayton                         name_type_mask = eFunctionNameTypeAuto;
4700c5cd90dSGreg Clayton 
47187df91b8SJim Ingham                     bp = target->CreateBreakpoint (&(m_options.m_modules),
47287df91b8SJim Ingham                                                    &(m_options.m_filenames),
473fab10e89SJim Ingham                                                    m_options.m_func_names,
474274060b6SGreg Clayton                                                    name_type_mask,
475a8558b62SJim Ingham                                                    m_options.m_skip_prologue,
476eb023e75SGreg Clayton                                                    internal,
477eb023e75SGreg Clayton                                                    m_options.m_hardware).get();
4780c5cd90dSGreg Clayton                 }
47930fdc8d8SChris Lattner                 break;
4800c5cd90dSGreg Clayton 
48130fdc8d8SChris Lattner             case eSetTypeFunctionRegexp: // Breakpoint by regular expression function name
48230fdc8d8SChris Lattner                 {
48330fdc8d8SChris Lattner                     RegularExpression regexp(m_options.m_func_regexp.c_str());
484969795f1SJim Ingham                     if (!regexp.IsValid())
48530fdc8d8SChris Lattner                     {
486969795f1SJim Ingham                         char err_str[1024];
487969795f1SJim Ingham                         regexp.GetErrorAsCString(err_str, sizeof(err_str));
488969795f1SJim Ingham                         result.AppendErrorWithFormat("Function name regular expression could not be compiled: \"%s\"",
489969795f1SJim Ingham                                                      err_str);
49030fdc8d8SChris Lattner                         result.SetStatus (eReturnStatusFailed);
491969795f1SJim Ingham                         return false;
49230fdc8d8SChris Lattner                     }
49387df91b8SJim Ingham 
494a8558b62SJim Ingham                     bp = target->CreateFuncRegexBreakpoint (&(m_options.m_modules),
495a8558b62SJim Ingham                                                             &(m_options.m_filenames),
496a8558b62SJim Ingham                                                             regexp,
497a8558b62SJim Ingham                                                             m_options.m_skip_prologue,
498eb023e75SGreg Clayton                                                             internal,
499eb023e75SGreg Clayton                                                             m_options.m_hardware).get();
50030fdc8d8SChris Lattner                 }
50130fdc8d8SChris Lattner                 break;
502969795f1SJim Ingham             case eSetTypeSourceRegexp: // Breakpoint by regexp on source text.
503969795f1SJim Ingham                 {
504c7bece56SGreg Clayton                     const size_t num_files = m_options.m_filenames.GetSize();
50587df91b8SJim Ingham 
50687df91b8SJim Ingham                     if (num_files == 0)
50787df91b8SJim Ingham                     {
508969795f1SJim Ingham                         FileSpec file;
50987df91b8SJim Ingham                         if (!GetDefaultFile (target, file, result))
51087df91b8SJim Ingham                         {
51187df91b8SJim Ingham                             result.AppendError ("No files provided and could not find default file.");
51287df91b8SJim Ingham                             result.SetStatus (eReturnStatusFailed);
51387df91b8SJim Ingham                             return false;
51487df91b8SJim Ingham                         }
51587df91b8SJim Ingham                         else
51687df91b8SJim Ingham                         {
51787df91b8SJim Ingham                             m_options.m_filenames.Append (file);
51887df91b8SJim Ingham                         }
51987df91b8SJim Ingham                     }
5200c5cd90dSGreg Clayton 
521969795f1SJim Ingham                     RegularExpression regexp(m_options.m_source_text_regexp.c_str());
522969795f1SJim Ingham                     if (!regexp.IsValid())
523969795f1SJim Ingham                     {
524969795f1SJim Ingham                         char err_str[1024];
525969795f1SJim Ingham                         regexp.GetErrorAsCString(err_str, sizeof(err_str));
526969795f1SJim Ingham                         result.AppendErrorWithFormat("Source text regular expression could not be compiled: \"%s\"",
527969795f1SJim Ingham                                                      err_str);
528969795f1SJim Ingham                         result.SetStatus (eReturnStatusFailed);
529969795f1SJim Ingham                         return false;
530969795f1SJim Ingham                     }
531eb023e75SGreg Clayton                     bp = target->CreateSourceRegexBreakpoint (&(m_options.m_modules),
532eb023e75SGreg Clayton                                                               &(m_options.m_filenames),
533eb023e75SGreg Clayton                                                               regexp,
534eb023e75SGreg Clayton                                                               internal,
535eb023e75SGreg Clayton                                                               m_options.m_hardware).get();
536969795f1SJim Ingham                 }
537969795f1SJim Ingham                 break;
538fab10e89SJim Ingham             case eSetTypeException:
539fab10e89SJim Ingham                 {
540eb023e75SGreg Clayton                     bp = target->CreateExceptionBreakpoint (m_options.m_language,
541eb023e75SGreg Clayton                                                             m_options.m_catch_bp,
542eb023e75SGreg Clayton                                                             m_options.m_throw_bp,
543eb023e75SGreg Clayton                                                             m_options.m_hardware).get();
544fab10e89SJim Ingham                 }
545fab10e89SJim Ingham                 break;
54630fdc8d8SChris Lattner             default:
54730fdc8d8SChris Lattner                 break;
54830fdc8d8SChris Lattner         }
54930fdc8d8SChris Lattner 
5501b54c88cSJim Ingham         // Now set the various options that were passed in:
5511b54c88cSJim Ingham         if (bp)
5521b54c88cSJim Ingham         {
5531b54c88cSJim Ingham             if (m_options.m_thread_id != LLDB_INVALID_THREAD_ID)
5541b54c88cSJim Ingham                 bp->SetThreadID (m_options.m_thread_id);
5551b54c88cSJim Ingham 
556c982c768SGreg Clayton             if (m_options.m_thread_index != UINT32_MAX)
5571b54c88cSJim Ingham                 bp->GetOptions()->GetThreadSpec()->SetIndex(m_options.m_thread_index);
5581b54c88cSJim Ingham 
5591b54c88cSJim Ingham             if (!m_options.m_thread_name.empty())
5601b54c88cSJim Ingham                 bp->GetOptions()->GetThreadSpec()->SetName(m_options.m_thread_name.c_str());
5611b54c88cSJim Ingham 
5621b54c88cSJim Ingham             if (!m_options.m_queue_name.empty())
5631b54c88cSJim Ingham                 bp->GetOptions()->GetThreadSpec()->SetQueueName(m_options.m_queue_name.c_str());
5641b54c88cSJim Ingham 
565c982c768SGreg Clayton             if (m_options.m_ignore_count != 0)
5661b54c88cSJim Ingham                 bp->GetOptions()->SetIgnoreCount(m_options.m_ignore_count);
5677d49c9c8SJohnny Chen 
5687d49c9c8SJohnny Chen             if (!m_options.m_condition.empty())
5697d49c9c8SJohnny Chen                 bp->GetOptions()->SetCondition(m_options.m_condition.c_str());
570ca36cd16SJim Ingham 
5715e09c8c3SJim Ingham             if (!m_options.m_breakpoint_names.empty())
5725e09c8c3SJim Ingham             {
5735e09c8c3SJim Ingham                 Error error;  // We don't need to check the error here, since the option parser checked it...
5745e09c8c3SJim Ingham                 for (auto name : m_options.m_breakpoint_names)
5755e09c8c3SJim Ingham                     bp->AddName(name.c_str(), error);
5765e09c8c3SJim Ingham             }
5775e09c8c3SJim Ingham 
578ca36cd16SJim Ingham             bp->SetOneShot (m_options.m_one_shot);
5791b54c88cSJim Ingham         }
5801b54c88cSJim Ingham 
581969795f1SJim Ingham         if (bp)
58230fdc8d8SChris Lattner         {
58385e8b814SJim Ingham             Stream &output_stream = result.GetOutputStream();
5841391cc7dSJim Ingham             const bool show_locations = false;
5851391cc7dSJim Ingham             bp->GetDescription(&output_stream, lldb::eDescriptionLevelInitial, show_locations);
586*4aeb1989SJim Ingham             if (target == m_interpreter.GetDebugger().GetDummyTarget())
587*4aeb1989SJim Ingham                     output_stream.Printf ("Breakpoint set in dummy target, will get copied into future targets.\n");
588*4aeb1989SJim Ingham             else
589*4aeb1989SJim Ingham             {
590fab10e89SJim Ingham                 // Don't print out this warning for exception breakpoints.  They can get set before the target
591fab10e89SJim Ingham                 // is set, but we won't know how to actually set the breakpoint till we run.
592fab10e89SJim Ingham                 if (bp->GetNumLocations() == 0 && break_type != eSetTypeException)
593*4aeb1989SJim Ingham                 {
594be484f41SCaroline Tice                     output_stream.Printf ("WARNING:  Unable to resolve breakpoint to any actual locations.\n");
595*4aeb1989SJim Ingham                 }
596*4aeb1989SJim Ingham             }
59730fdc8d8SChris Lattner             result.SetStatus (eReturnStatusSuccessFinishResult);
59830fdc8d8SChris Lattner         }
59930fdc8d8SChris Lattner         else if (!bp)
60030fdc8d8SChris Lattner         {
60130fdc8d8SChris Lattner             result.AppendError ("Breakpoint creation failed: No breakpoint created.");
60230fdc8d8SChris Lattner             result.SetStatus (eReturnStatusFailed);
60330fdc8d8SChris Lattner         }
60430fdc8d8SChris Lattner 
60530fdc8d8SChris Lattner         return result.Succeeded();
60630fdc8d8SChris Lattner     }
60730fdc8d8SChris Lattner 
6085a988416SJim Ingham private:
6095a988416SJim Ingham     bool
6105a988416SJim Ingham     GetDefaultFile (Target *target, FileSpec &file, CommandReturnObject &result)
6115a988416SJim Ingham     {
6125a988416SJim Ingham         uint32_t default_line;
6135a988416SJim Ingham         // First use the Source Manager's default file.
6145a988416SJim Ingham         // Then use the current stack frame's file.
6155a988416SJim Ingham         if (!target->GetSourceManager().GetDefaultFileAndLine(file, default_line))
6165a988416SJim Ingham         {
617b57e4a1bSJason Molenda             StackFrame *cur_frame = m_exe_ctx.GetFramePtr();
6185a988416SJim Ingham             if (cur_frame == NULL)
6195a988416SJim Ingham             {
6205a988416SJim Ingham                 result.AppendError ("No selected frame to use to find the default file.");
6215a988416SJim Ingham                 result.SetStatus (eReturnStatusFailed);
6225a988416SJim Ingham                 return false;
6235a988416SJim Ingham             }
6245a988416SJim Ingham             else if (!cur_frame->HasDebugInformation())
6255a988416SJim Ingham             {
6265a988416SJim Ingham                 result.AppendError ("Cannot use the selected frame to find the default file, it has no debug info.");
6275a988416SJim Ingham                 result.SetStatus (eReturnStatusFailed);
6285a988416SJim Ingham                 return false;
6295a988416SJim Ingham             }
6305a988416SJim Ingham             else
6315a988416SJim Ingham             {
6325a988416SJim Ingham                 const SymbolContext &sc = cur_frame->GetSymbolContext (eSymbolContextLineEntry);
6335a988416SJim Ingham                 if (sc.line_entry.file)
6345a988416SJim Ingham                 {
6355a988416SJim Ingham                     file = sc.line_entry.file;
6365a988416SJim Ingham                 }
6375a988416SJim Ingham                 else
6385a988416SJim Ingham                 {
6395a988416SJim Ingham                     result.AppendError ("Can't find the file for the selected frame to use as the default file.");
6405a988416SJim Ingham                     result.SetStatus (eReturnStatusFailed);
6415a988416SJim Ingham                     return false;
6425a988416SJim Ingham                 }
6435a988416SJim Ingham             }
6445a988416SJim Ingham         }
6455a988416SJim Ingham         return true;
6465a988416SJim Ingham     }
6475a988416SJim Ingham 
6485a988416SJim Ingham     CommandOptions m_options;
6495a988416SJim Ingham };
6505a988416SJim Ingham // If an additional option set beyond LLDB_OPTION_SET_10 is added, make sure to
6515a988416SJim Ingham // update the numbers passed to LLDB_OPT_SET_FROM_TO(...) appropriately.
6525a988416SJim Ingham #define LLDB_OPT_FILE ( LLDB_OPT_SET_FROM_TO(1, 9) & ~LLDB_OPT_SET_2 )
6535a988416SJim Ingham #define LLDB_OPT_NOT_10 ( LLDB_OPT_SET_FROM_TO(1, 10) & ~LLDB_OPT_SET_10 )
6545a988416SJim Ingham #define LLDB_OPT_SKIP_PROLOGUE ( LLDB_OPT_SET_1 | LLDB_OPT_SET_FROM_TO(3,8) )
6555a988416SJim Ingham 
6565a988416SJim Ingham OptionDefinition
6575a988416SJim Ingham CommandObjectBreakpointSet::CommandOptions::g_option_table[] =
6585a988416SJim Ingham {
659d37221dcSZachary Turner     { LLDB_OPT_NOT_10, false, "shlib", 's', OptionParser::eRequiredArgument, NULL, NULL, CommandCompletions::eModuleCompletion, eArgTypeShlibName,
6605a988416SJim Ingham         "Set the breakpoint only in this shared library.  "
6615a988416SJim Ingham         "Can repeat this option multiple times to specify multiple shared libraries."},
6625a988416SJim Ingham 
663d37221dcSZachary Turner     { LLDB_OPT_SET_ALL, false, "ignore-count", 'i', OptionParser::eRequiredArgument,   NULL, NULL, 0, eArgTypeCount,
6645a988416SJim Ingham         "Set the number of times this breakpoint is skipped before stopping." },
6655a988416SJim Ingham 
666d37221dcSZachary Turner     { LLDB_OPT_SET_ALL, false, "one-shot", 'o', OptionParser::eNoArgument,   NULL, NULL, 0, eArgTypeNone,
667b2b256afSJim Ingham         "The breakpoint is deleted the first time it causes a stop." },
668ca36cd16SJim Ingham 
669d37221dcSZachary Turner     { LLDB_OPT_SET_ALL, false, "condition",    'c', OptionParser::eRequiredArgument, NULL, NULL, 0, eArgTypeExpression,
6705a988416SJim Ingham         "The breakpoint stops only if this condition expression evaluates to true."},
6715a988416SJim Ingham 
672d37221dcSZachary Turner     { LLDB_OPT_SET_ALL, false, "thread-index", 'x', OptionParser::eRequiredArgument, NULL, NULL, 0, eArgTypeThreadIndex,
673a89be91fSJim Ingham         "The breakpoint stops only for the thread whose indeX matches this argument."},
6745a988416SJim Ingham 
675d37221dcSZachary Turner     { LLDB_OPT_SET_ALL, false, "thread-id", 't', OptionParser::eRequiredArgument, NULL, NULL, 0, eArgTypeThreadID,
6765a988416SJim Ingham         "The breakpoint stops only for the thread whose TID matches this argument."},
6775a988416SJim Ingham 
678d37221dcSZachary Turner     { LLDB_OPT_SET_ALL, false, "thread-name", 'T', OptionParser::eRequiredArgument, NULL, NULL, 0, eArgTypeThreadName,
6795a988416SJim Ingham         "The breakpoint stops only for the thread whose thread name matches this argument."},
6805a988416SJim Ingham 
681d37221dcSZachary Turner     { LLDB_OPT_SET_ALL, false, "hardware", 'H', OptionParser::eNoArgument, NULL, NULL, 0, eArgTypeNone,
682eb023e75SGreg Clayton         "Require the breakpoint to use hardware breakpoints."},
683eb023e75SGreg Clayton 
684d37221dcSZachary Turner     { LLDB_OPT_SET_ALL, false, "queue-name", 'q', OptionParser::eRequiredArgument, NULL, NULL, 0, eArgTypeQueueName,
6855a988416SJim Ingham         "The breakpoint stops only for threads in the queue whose name is given by this argument."},
6865a988416SJim Ingham 
687d37221dcSZachary Turner     { LLDB_OPT_FILE, false, "file", 'f', OptionParser::eRequiredArgument, NULL, NULL, CommandCompletions::eSourceFileCompletion, eArgTypeFilename,
688289aca64SJim Ingham         "Specifies the source file in which to set this breakpoint.  "
689289aca64SJim Ingham         "Note, by default lldb only looks for files that are #included if they use the standard include file extensions.  "
6906394479eSJim Ingham         "To set breakpoints on .c/.cpp/.m/.mm files that are #included, set target.inline-breakpoint-strategy"
691289aca64SJim Ingham         " to \"always\"."},
6925a988416SJim Ingham 
693d37221dcSZachary Turner     { LLDB_OPT_SET_1, true, "line", 'l', OptionParser::eRequiredArgument, NULL, NULL, 0, eArgTypeLineNum,
6945a988416SJim Ingham         "Specifies the line number on which to set this breakpoint."},
6955a988416SJim Ingham 
6965a988416SJim Ingham     // Comment out this option for the moment, as we don't actually use it, but will in the future.
6975a988416SJim Ingham     // This way users won't see it, but the infrastructure is left in place.
698e2607b50SVirgile Bello     //    { 0, false, "column",     'C', OptionParser::eRequiredArgument, NULL, "<column>",
6995a988416SJim Ingham     //    "Set the breakpoint by source location at this particular column."},
7005a988416SJim Ingham 
701d37221dcSZachary Turner     { LLDB_OPT_SET_2, true, "address", 'a', OptionParser::eRequiredArgument, NULL, NULL, 0, eArgTypeAddressOrExpression,
7025a988416SJim Ingham         "Set the breakpoint by address, at the specified address."},
7035a988416SJim Ingham 
704d37221dcSZachary Turner     { LLDB_OPT_SET_3, true, "name", 'n', OptionParser::eRequiredArgument, NULL, NULL, CommandCompletions::eSymbolCompletion, eArgTypeFunctionName,
705551262d7SJim Ingham         "Set the breakpoint by function name.  Can be repeated multiple times to make one breakpoint for multiple names" },
7065a988416SJim Ingham 
707d37221dcSZachary Turner     { LLDB_OPT_SET_4, true, "fullname", 'F', OptionParser::eRequiredArgument, NULL, NULL, CommandCompletions::eSymbolCompletion, eArgTypeFullName,
7085a988416SJim Ingham         "Set the breakpoint by fully qualified function names. For C++ this means namespaces and all arguments, and "
7095a988416SJim Ingham         "for Objective C this means a full function prototype with class and selector.   "
7105a988416SJim Ingham         "Can be repeated multiple times to make one breakpoint for multiple names." },
7115a988416SJim Ingham 
712d37221dcSZachary Turner     { LLDB_OPT_SET_5, true, "selector", 'S', OptionParser::eRequiredArgument, NULL, NULL, 0, eArgTypeSelector,
7135a988416SJim Ingham         "Set the breakpoint by ObjC selector name. Can be repeated multiple times to make one breakpoint for multiple Selectors." },
7145a988416SJim Ingham 
715d37221dcSZachary Turner     { LLDB_OPT_SET_6, true, "method", 'M', OptionParser::eRequiredArgument, NULL, NULL, 0, eArgTypeMethod,
7165a988416SJim Ingham         "Set the breakpoint by C++ method names.  Can be repeated multiple times to make one breakpoint for multiple methods." },
7175a988416SJim Ingham 
718d37221dcSZachary Turner     { LLDB_OPT_SET_7, true, "func-regex", 'r', OptionParser::eRequiredArgument, NULL, NULL, 0, eArgTypeRegularExpression,
7195a988416SJim Ingham         "Set the breakpoint by function name, evaluating a regular-expression to find the function name(s)." },
7205a988416SJim Ingham 
721d37221dcSZachary Turner     { LLDB_OPT_SET_8, true, "basename", 'b', OptionParser::eRequiredArgument, NULL, NULL, CommandCompletions::eSymbolCompletion, eArgTypeFunctionName,
7225a988416SJim Ingham         "Set the breakpoint by function basename (C++ namespaces and arguments will be ignored). "
7235a988416SJim Ingham         "Can be repeated multiple times to make one breakpoint for multiple symbols." },
7245a988416SJim Ingham 
725d37221dcSZachary Turner     { LLDB_OPT_SET_9, true, "source-pattern-regexp", 'p', OptionParser::eRequiredArgument, NULL, NULL, 0, eArgTypeRegularExpression,
726e96ade8bSJim Ingham         "Set the breakpoint by specifying a regular expression which is matched against the source text in a source file or files "
727e96ade8bSJim Ingham         "specified with the -f option.  The -f option can be specified more than once.  "
728e96ade8bSJim Ingham         "If no source files are specified, uses the current \"default source file\"" },
7295a988416SJim Ingham 
730d37221dcSZachary Turner     { LLDB_OPT_SET_10, true, "language-exception", 'E', OptionParser::eRequiredArgument, NULL, NULL, 0, eArgTypeLanguage,
7315a988416SJim Ingham         "Set the breakpoint on exceptions thrown by the specified language (without options, on throw but not catch.)" },
7325a988416SJim Ingham 
733d37221dcSZachary Turner     { LLDB_OPT_SET_10, false, "on-throw", 'w', OptionParser::eRequiredArgument, NULL, NULL, 0, eArgTypeBoolean,
7345a988416SJim Ingham         "Set the breakpoint on exception throW." },
7355a988416SJim Ingham 
736d37221dcSZachary Turner     { LLDB_OPT_SET_10, false, "on-catch", 'h', OptionParser::eRequiredArgument, NULL, NULL, 0, eArgTypeBoolean,
7375a988416SJim Ingham         "Set the breakpoint on exception catcH." },
7385a988416SJim Ingham 
739d37221dcSZachary Turner     { LLDB_OPT_SKIP_PROLOGUE, false, "skip-prologue", 'K', OptionParser::eRequiredArgument, NULL, NULL, 0, eArgTypeBoolean,
7405a988416SJim Ingham         "sKip the prologue if the breakpoint is at the beginning of a function.  If not set the target.skip-prologue setting is used." },
7415a988416SJim Ingham 
74233df7cd3SJim Ingham     { LLDB_OPT_SET_ALL, false, "dummy-breakpoints", 'D', OptionParser::eNoArgument, NULL, NULL, 0, eArgTypeNone,
74333df7cd3SJim Ingham         "Sets Dummy breakpoints - i.e. breakpoints set before a file is provided, which prime new targets."},
74433df7cd3SJim Ingham 
7455e09c8c3SJim Ingham     { LLDB_OPT_SET_ALL, false, "breakpoint-name", 'N', OptionParser::eRequiredArgument, NULL, NULL, 0, eArgTypeBreakpointName,
7465e09c8c3SJim Ingham         "Adds this to the list of names for this breakopint."},
7475e09c8c3SJim Ingham 
748d37221dcSZachary Turner     { 0, false, NULL, 0, 0, NULL, NULL, 0, eArgTypeNone, NULL }
7495a988416SJim Ingham };
7505a988416SJim Ingham 
7515a988416SJim Ingham //-------------------------------------------------------------------------
7525a988416SJim Ingham // CommandObjectBreakpointModify
7535a988416SJim Ingham //-------------------------------------------------------------------------
7545a988416SJim Ingham #pragma mark Modify
7555a988416SJim Ingham 
7565a988416SJim Ingham class CommandObjectBreakpointModify : public CommandObjectParsed
7575a988416SJim Ingham {
7585a988416SJim Ingham public:
7595a988416SJim Ingham 
7605a988416SJim Ingham     CommandObjectBreakpointModify (CommandInterpreter &interpreter) :
7615a988416SJim Ingham         CommandObjectParsed (interpreter,
7625a988416SJim Ingham                              "breakpoint modify",
7635a988416SJim Ingham                              "Modify the options on a breakpoint or set of breakpoints in the executable.  "
7645a988416SJim Ingham                              "If no breakpoint is specified, acts on the last created breakpoint.  "
7655a988416SJim Ingham                              "With the exception of -e, -d and -i, passing an empty argument clears the modification.",
7665a988416SJim Ingham                              NULL),
7675a988416SJim Ingham         m_options (interpreter)
7685a988416SJim Ingham     {
7695a988416SJim Ingham         CommandArgumentEntry arg;
7705a988416SJim Ingham         CommandObject::AddIDsArgumentData(arg, eArgTypeBreakpointID, eArgTypeBreakpointIDRange);
7715a988416SJim Ingham         // Add the entry for the first argument for this command to the object's arguments vector.
7725a988416SJim Ingham         m_arguments.push_back (arg);
7735a988416SJim Ingham     }
7745a988416SJim Ingham 
7755a988416SJim Ingham 
7765a988416SJim Ingham     virtual
7775a988416SJim Ingham     ~CommandObjectBreakpointModify () {}
7785a988416SJim Ingham 
7795a988416SJim Ingham     virtual Options *
7805a988416SJim Ingham     GetOptions ()
7815a988416SJim Ingham     {
7825a988416SJim Ingham         return &m_options;
7835a988416SJim Ingham     }
7845a988416SJim Ingham 
7855a988416SJim Ingham     class CommandOptions : public Options
7865a988416SJim Ingham     {
7875a988416SJim Ingham     public:
7885a988416SJim Ingham 
7895a988416SJim Ingham         CommandOptions (CommandInterpreter &interpreter) :
7905a988416SJim Ingham             Options (interpreter),
7915a988416SJim Ingham             m_ignore_count (0),
7925a988416SJim Ingham             m_thread_id(LLDB_INVALID_THREAD_ID),
7935a988416SJim Ingham             m_thread_id_passed(false),
7945a988416SJim Ingham             m_thread_index (UINT32_MAX),
7955a988416SJim Ingham             m_thread_index_passed(false),
7965a988416SJim Ingham             m_thread_name(),
7975a988416SJim Ingham             m_queue_name(),
7985a988416SJim Ingham             m_condition (),
799ca36cd16SJim Ingham             m_one_shot (false),
8005a988416SJim Ingham             m_enable_passed (false),
8015a988416SJim Ingham             m_enable_value (false),
8025a988416SJim Ingham             m_name_passed (false),
8035a988416SJim Ingham             m_queue_passed (false),
804ca36cd16SJim Ingham             m_condition_passed (false),
80533df7cd3SJim Ingham             m_one_shot_passed (false),
80633df7cd3SJim Ingham             m_use_dummy (false)
8075a988416SJim Ingham         {
8085a988416SJim Ingham         }
8095a988416SJim Ingham 
8105a988416SJim Ingham         virtual
8115a988416SJim Ingham         ~CommandOptions () {}
8125a988416SJim Ingham 
8135a988416SJim Ingham         virtual Error
8145a988416SJim Ingham         SetOptionValue (uint32_t option_idx, const char *option_arg)
8155a988416SJim Ingham         {
8165a988416SJim Ingham             Error error;
8173bcdfc0eSGreg Clayton             const int short_option = m_getopt_table[option_idx].val;
8185a988416SJim Ingham 
8195a988416SJim Ingham             switch (short_option)
8205a988416SJim Ingham             {
8215a988416SJim Ingham                 case 'c':
8225a988416SJim Ingham                     if (option_arg != NULL)
8235a988416SJim Ingham                         m_condition.assign (option_arg);
8245a988416SJim Ingham                     else
8255a988416SJim Ingham                         m_condition.clear();
8265a988416SJim Ingham                     m_condition_passed = true;
8275a988416SJim Ingham                     break;
8285a988416SJim Ingham                 case 'd':
8295a988416SJim Ingham                     m_enable_passed = true;
8305a988416SJim Ingham                     m_enable_value = false;
8315a988416SJim Ingham                     break;
83233df7cd3SJim Ingham                 case 'D':
83333df7cd3SJim Ingham                     m_use_dummy = true;
83433df7cd3SJim Ingham                     break;
8355a988416SJim Ingham                 case 'e':
8365a988416SJim Ingham                     m_enable_passed = true;
8375a988416SJim Ingham                     m_enable_value = true;
8385a988416SJim Ingham                     break;
8395a988416SJim Ingham                 case 'i':
8405a988416SJim Ingham                 {
8415a988416SJim Ingham                     m_ignore_count = Args::StringToUInt32(option_arg, UINT32_MAX, 0);
8425a988416SJim Ingham                     if (m_ignore_count == UINT32_MAX)
8435a988416SJim Ingham                        error.SetErrorStringWithFormat ("invalid ignore count '%s'", option_arg);
8445a988416SJim Ingham                 }
8455a988416SJim Ingham                 break;
846ca36cd16SJim Ingham                 case 'o':
847ca36cd16SJim Ingham                 {
848ca36cd16SJim Ingham                     bool value, success;
849ca36cd16SJim Ingham                     value = Args::StringToBoolean(option_arg, false, &success);
850ca36cd16SJim Ingham                     if (success)
851ca36cd16SJim Ingham                     {
852ca36cd16SJim Ingham                         m_one_shot_passed = true;
853ca36cd16SJim Ingham                         m_one_shot = value;
854ca36cd16SJim Ingham                     }
855ca36cd16SJim Ingham                     else
856ca36cd16SJim Ingham                         error.SetErrorStringWithFormat("invalid boolean value '%s' passed for -o option", option_arg);
857ca36cd16SJim Ingham                 }
858ca36cd16SJim Ingham                 break;
8595a988416SJim Ingham                 case 't' :
8605a988416SJim Ingham                 {
8615a988416SJim Ingham                     if (option_arg[0] == '\0')
8625a988416SJim Ingham                     {
8635a988416SJim Ingham                         m_thread_id = LLDB_INVALID_THREAD_ID;
8645a988416SJim Ingham                         m_thread_id_passed = true;
8655a988416SJim Ingham                     }
8665a988416SJim Ingham                     else
8675a988416SJim Ingham                     {
8685a988416SJim Ingham                         m_thread_id = Args::StringToUInt64(option_arg, LLDB_INVALID_THREAD_ID, 0);
8695a988416SJim Ingham                         if (m_thread_id == LLDB_INVALID_THREAD_ID)
8705a988416SJim Ingham                            error.SetErrorStringWithFormat ("invalid thread id string '%s'", option_arg);
8715a988416SJim Ingham                         else
8725a988416SJim Ingham                             m_thread_id_passed = true;
8735a988416SJim Ingham                     }
8745a988416SJim Ingham                 }
8755a988416SJim Ingham                 break;
8765a988416SJim Ingham                 case 'T':
8775a988416SJim Ingham                     if (option_arg != NULL)
8785a988416SJim Ingham                         m_thread_name.assign (option_arg);
8795a988416SJim Ingham                     else
8805a988416SJim Ingham                         m_thread_name.clear();
8815a988416SJim Ingham                     m_name_passed = true;
8825a988416SJim Ingham                     break;
8835a988416SJim Ingham                 case 'q':
8845a988416SJim Ingham                     if (option_arg != NULL)
8855a988416SJim Ingham                         m_queue_name.assign (option_arg);
8865a988416SJim Ingham                     else
8875a988416SJim Ingham                         m_queue_name.clear();
8885a988416SJim Ingham                     m_queue_passed = true;
8895a988416SJim Ingham                     break;
8905a988416SJim Ingham                 case 'x':
8915a988416SJim Ingham                 {
8925a988416SJim Ingham                     if (option_arg[0] == '\n')
8935a988416SJim Ingham                     {
8945a988416SJim Ingham                         m_thread_index = UINT32_MAX;
8955a988416SJim Ingham                         m_thread_index_passed = true;
8965a988416SJim Ingham                     }
8975a988416SJim Ingham                     else
8985a988416SJim Ingham                     {
8995a988416SJim Ingham                         m_thread_index = Args::StringToUInt32 (option_arg, UINT32_MAX, 0);
9005a988416SJim Ingham                         if (m_thread_id == UINT32_MAX)
9015a988416SJim Ingham                            error.SetErrorStringWithFormat ("invalid thread index string '%s'", option_arg);
9025a988416SJim Ingham                         else
9035a988416SJim Ingham                             m_thread_index_passed = true;
9045a988416SJim Ingham                     }
9055a988416SJim Ingham                 }
9065a988416SJim Ingham                 break;
9075a988416SJim Ingham                 default:
9085a988416SJim Ingham                     error.SetErrorStringWithFormat ("unrecognized option '%c'", short_option);
9095a988416SJim Ingham                     break;
9105a988416SJim Ingham             }
9115a988416SJim Ingham 
9125a988416SJim Ingham             return error;
9135a988416SJim Ingham         }
9145a988416SJim Ingham         void
9155a988416SJim Ingham         OptionParsingStarting ()
9165a988416SJim Ingham         {
9175a988416SJim Ingham             m_ignore_count = 0;
9185a988416SJim Ingham             m_thread_id = LLDB_INVALID_THREAD_ID;
9195a988416SJim Ingham             m_thread_id_passed = false;
9205a988416SJim Ingham             m_thread_index = UINT32_MAX;
9215a988416SJim Ingham             m_thread_index_passed = false;
9225a988416SJim Ingham             m_thread_name.clear();
9235a988416SJim Ingham             m_queue_name.clear();
9245a988416SJim Ingham             m_condition.clear();
925ca36cd16SJim Ingham             m_one_shot = false;
9265a988416SJim Ingham             m_enable_passed = false;
9275a988416SJim Ingham             m_queue_passed = false;
9285a988416SJim Ingham             m_name_passed = false;
9295a988416SJim Ingham             m_condition_passed = false;
930ca36cd16SJim Ingham             m_one_shot_passed = false;
93133df7cd3SJim Ingham             m_use_dummy = false;
9325a988416SJim Ingham         }
9335a988416SJim Ingham 
9345a988416SJim Ingham         const OptionDefinition*
9355a988416SJim Ingham         GetDefinitions ()
9365a988416SJim Ingham         {
9375a988416SJim Ingham             return g_option_table;
9385a988416SJim Ingham         }
9395a988416SJim Ingham 
9405a988416SJim Ingham 
9415a988416SJim Ingham         // Options table: Required for subclasses of Options.
9425a988416SJim Ingham 
9435a988416SJim Ingham         static OptionDefinition g_option_table[];
9445a988416SJim Ingham 
9455a988416SJim Ingham         // Instance variables to hold the values for command options.
9465a988416SJim Ingham 
9475a988416SJim Ingham         uint32_t m_ignore_count;
9485a988416SJim Ingham         lldb::tid_t m_thread_id;
9495a988416SJim Ingham         bool m_thread_id_passed;
9505a988416SJim Ingham         uint32_t m_thread_index;
9515a988416SJim Ingham         bool m_thread_index_passed;
9525a988416SJim Ingham         std::string m_thread_name;
9535a988416SJim Ingham         std::string m_queue_name;
9545a988416SJim Ingham         std::string m_condition;
955ca36cd16SJim Ingham         bool m_one_shot;
9565a988416SJim Ingham         bool m_enable_passed;
9575a988416SJim Ingham         bool m_enable_value;
9585a988416SJim Ingham         bool m_name_passed;
9595a988416SJim Ingham         bool m_queue_passed;
9605a988416SJim Ingham         bool m_condition_passed;
961ca36cd16SJim Ingham         bool m_one_shot_passed;
96233df7cd3SJim Ingham         bool m_use_dummy;
9635a988416SJim Ingham 
9645a988416SJim Ingham     };
9655a988416SJim Ingham 
9665a988416SJim Ingham protected:
9675a988416SJim Ingham     virtual bool
9685a988416SJim Ingham     DoExecute (Args& command, CommandReturnObject &result)
9695a988416SJim Ingham     {
97033df7cd3SJim Ingham         Target *target = GetSelectedOrDummyTarget(m_options.m_use_dummy);
9715a988416SJim Ingham         if (target == NULL)
9725a988416SJim Ingham         {
9735a988416SJim Ingham             result.AppendError ("Invalid target.  No existing target or breakpoints.");
9745a988416SJim Ingham             result.SetStatus (eReturnStatusFailed);
9755a988416SJim Ingham             return false;
9765a988416SJim Ingham         }
9775a988416SJim Ingham 
9785a988416SJim Ingham         Mutex::Locker locker;
9795a988416SJim Ingham         target->GetBreakpointList().GetListMutex(locker);
9805a988416SJim Ingham 
9815a988416SJim Ingham         BreakpointIDList valid_bp_ids;
9825a988416SJim Ingham 
9835e09c8c3SJim Ingham         CommandObjectMultiwordBreakpoint::VerifyBreakpointOrLocationIDs (command, target, result, &valid_bp_ids);
9845a988416SJim Ingham 
9855a988416SJim Ingham         if (result.Succeeded())
9865a988416SJim Ingham         {
9875a988416SJim Ingham             const size_t count = valid_bp_ids.GetSize();
9885a988416SJim Ingham             for (size_t i = 0; i < count; ++i)
9895a988416SJim Ingham             {
9905a988416SJim Ingham                 BreakpointID cur_bp_id = valid_bp_ids.GetBreakpointIDAtIndex (i);
9915a988416SJim Ingham 
9925a988416SJim Ingham                 if (cur_bp_id.GetBreakpointID() != LLDB_INVALID_BREAK_ID)
9935a988416SJim Ingham                 {
9945a988416SJim Ingham                     Breakpoint *bp = target->GetBreakpointByID (cur_bp_id.GetBreakpointID()).get();
9955a988416SJim Ingham                     if (cur_bp_id.GetLocationID() != LLDB_INVALID_BREAK_ID)
9965a988416SJim Ingham                     {
9975a988416SJim Ingham                         BreakpointLocation *location = bp->FindLocationByID (cur_bp_id.GetLocationID()).get();
9985a988416SJim Ingham                         if (location)
9995a988416SJim Ingham                         {
10005a988416SJim Ingham                             if (m_options.m_thread_id_passed)
10015a988416SJim Ingham                                 location->SetThreadID (m_options.m_thread_id);
10025a988416SJim Ingham 
10035a988416SJim Ingham                             if (m_options.m_thread_index_passed)
10045a988416SJim Ingham                                 location->SetThreadIndex(m_options.m_thread_index);
10055a988416SJim Ingham 
10065a988416SJim Ingham                             if (m_options.m_name_passed)
10075a988416SJim Ingham                                 location->SetThreadName(m_options.m_thread_name.c_str());
10085a988416SJim Ingham 
10095a988416SJim Ingham                             if (m_options.m_queue_passed)
10105a988416SJim Ingham                                 location->SetQueueName(m_options.m_queue_name.c_str());
10115a988416SJim Ingham 
10125a988416SJim Ingham                             if (m_options.m_ignore_count != 0)
10135a988416SJim Ingham                                 location->SetIgnoreCount(m_options.m_ignore_count);
10145a988416SJim Ingham 
10155a988416SJim Ingham                             if (m_options.m_enable_passed)
10165a988416SJim Ingham                                 location->SetEnabled (m_options.m_enable_value);
10175a988416SJim Ingham 
10185a988416SJim Ingham                             if (m_options.m_condition_passed)
10195a988416SJim Ingham                                 location->SetCondition (m_options.m_condition.c_str());
10205a988416SJim Ingham                         }
10215a988416SJim Ingham                     }
10225a988416SJim Ingham                     else
10235a988416SJim Ingham                     {
10245a988416SJim Ingham                         if (m_options.m_thread_id_passed)
10255a988416SJim Ingham                             bp->SetThreadID (m_options.m_thread_id);
10265a988416SJim Ingham 
10275a988416SJim Ingham                         if (m_options.m_thread_index_passed)
10285a988416SJim Ingham                             bp->SetThreadIndex(m_options.m_thread_index);
10295a988416SJim Ingham 
10305a988416SJim Ingham                         if (m_options.m_name_passed)
10315a988416SJim Ingham                             bp->SetThreadName(m_options.m_thread_name.c_str());
10325a988416SJim Ingham 
10335a988416SJim Ingham                         if (m_options.m_queue_passed)
10345a988416SJim Ingham                             bp->SetQueueName(m_options.m_queue_name.c_str());
10355a988416SJim Ingham 
10365a988416SJim Ingham                         if (m_options.m_ignore_count != 0)
10375a988416SJim Ingham                             bp->SetIgnoreCount(m_options.m_ignore_count);
10385a988416SJim Ingham 
10395a988416SJim Ingham                         if (m_options.m_enable_passed)
10405a988416SJim Ingham                             bp->SetEnabled (m_options.m_enable_value);
10415a988416SJim Ingham 
10425a988416SJim Ingham                         if (m_options.m_condition_passed)
10435a988416SJim Ingham                             bp->SetCondition (m_options.m_condition.c_str());
10445a988416SJim Ingham                     }
10455a988416SJim Ingham                 }
10465a988416SJim Ingham             }
10475a988416SJim Ingham         }
10485a988416SJim Ingham 
10495a988416SJim Ingham         return result.Succeeded();
10505a988416SJim Ingham     }
10515a988416SJim Ingham 
10525a988416SJim Ingham private:
10535a988416SJim Ingham     CommandOptions m_options;
10545a988416SJim Ingham };
10555a988416SJim Ingham 
10565a988416SJim Ingham #pragma mark Modify::CommandOptions
10575a988416SJim Ingham OptionDefinition
10585a988416SJim Ingham CommandObjectBreakpointModify::CommandOptions::g_option_table[] =
10595a988416SJim Ingham {
1060d37221dcSZachary 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." },
1061d37221dcSZachary 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." },
1062d37221dcSZachary 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."},
1063d37221dcSZachary 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."},
1064d37221dcSZachary 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."},
1065d37221dcSZachary 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."},
1066d37221dcSZachary 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."},
1067d37221dcSZachary Turner { LLDB_OPT_SET_1,   false, "enable",       'e', OptionParser::eNoArgument,       NULL, NULL, 0, eArgTypeNone, "Enable the breakpoint."},
1068d37221dcSZachary Turner { LLDB_OPT_SET_2,   false, "disable",      'd', OptionParser::eNoArgument,       NULL, NULL, 0, eArgTypeNone, "Disable the breakpoint."},
106933df7cd3SJim 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."},
107033df7cd3SJim Ingham 
1071d37221dcSZachary Turner { 0,                false, NULL,            0 , 0,                 NULL, NULL, 0, eArgTypeNone, NULL }
10725a988416SJim Ingham };
10735a988416SJim Ingham 
10745a988416SJim Ingham //-------------------------------------------------------------------------
10755a988416SJim Ingham // CommandObjectBreakpointEnable
10765a988416SJim Ingham //-------------------------------------------------------------------------
10775a988416SJim Ingham #pragma mark Enable
10785a988416SJim Ingham 
10795a988416SJim Ingham class CommandObjectBreakpointEnable : public CommandObjectParsed
10805a988416SJim Ingham {
10815a988416SJim Ingham public:
10825a988416SJim Ingham     CommandObjectBreakpointEnable (CommandInterpreter &interpreter) :
10835a988416SJim Ingham         CommandObjectParsed (interpreter,
10845a988416SJim Ingham                              "enable",
10855a988416SJim Ingham                              "Enable the specified disabled breakpoint(s). If no breakpoints are specified, enable all of them.",
10865a988416SJim Ingham                              NULL)
10875a988416SJim Ingham     {
10885a988416SJim Ingham         CommandArgumentEntry arg;
10895a988416SJim Ingham         CommandObject::AddIDsArgumentData(arg, eArgTypeBreakpointID, eArgTypeBreakpointIDRange);
10905a988416SJim Ingham         // Add the entry for the first argument for this command to the object's arguments vector.
10915a988416SJim Ingham         m_arguments.push_back (arg);
10925a988416SJim Ingham     }
10935a988416SJim Ingham 
10945a988416SJim Ingham 
10955a988416SJim Ingham     virtual
10965a988416SJim Ingham     ~CommandObjectBreakpointEnable () {}
10975a988416SJim Ingham 
10985a988416SJim Ingham protected:
10995a988416SJim Ingham     virtual bool
11005a988416SJim Ingham     DoExecute (Args& command, CommandReturnObject &result)
11015a988416SJim Ingham     {
1102893c932aSJim Ingham         Target *target = GetSelectedOrDummyTarget();
11035a988416SJim Ingham         if (target == NULL)
11045a988416SJim Ingham         {
11055a988416SJim Ingham             result.AppendError ("Invalid target.  No existing target or breakpoints.");
11065a988416SJim Ingham             result.SetStatus (eReturnStatusFailed);
11075a988416SJim Ingham             return false;
11085a988416SJim Ingham         }
11095a988416SJim Ingham 
11105a988416SJim Ingham         Mutex::Locker locker;
11115a988416SJim Ingham         target->GetBreakpointList().GetListMutex(locker);
11125a988416SJim Ingham 
11135a988416SJim Ingham         const BreakpointList &breakpoints = target->GetBreakpointList();
11145a988416SJim Ingham 
11155a988416SJim Ingham         size_t num_breakpoints = breakpoints.GetSize();
11165a988416SJim Ingham 
11175a988416SJim Ingham         if (num_breakpoints == 0)
11185a988416SJim Ingham         {
11195a988416SJim Ingham             result.AppendError ("No breakpoints exist to be enabled.");
11205a988416SJim Ingham             result.SetStatus (eReturnStatusFailed);
11215a988416SJim Ingham             return false;
11225a988416SJim Ingham         }
11235a988416SJim Ingham 
11245a988416SJim Ingham         if (command.GetArgumentCount() == 0)
11255a988416SJim Ingham         {
11265a988416SJim Ingham             // No breakpoint selected; enable all currently set breakpoints.
11275a988416SJim Ingham             target->EnableAllBreakpoints ();
11286fea17e8SGreg Clayton             result.AppendMessageWithFormat ("All breakpoints enabled. (%" PRIu64 " breakpoints)\n", (uint64_t)num_breakpoints);
11295a988416SJim Ingham             result.SetStatus (eReturnStatusSuccessFinishNoResult);
11305a988416SJim Ingham         }
11315a988416SJim Ingham         else
11325a988416SJim Ingham         {
11335a988416SJim Ingham             // Particular breakpoint selected; enable that breakpoint.
11345a988416SJim Ingham             BreakpointIDList valid_bp_ids;
11355e09c8c3SJim Ingham             CommandObjectMultiwordBreakpoint::VerifyBreakpointOrLocationIDs (command, target, result, &valid_bp_ids);
11365a988416SJim Ingham 
11375a988416SJim Ingham             if (result.Succeeded())
11385a988416SJim Ingham             {
11395a988416SJim Ingham                 int enable_count = 0;
11405a988416SJim Ingham                 int loc_count = 0;
11415a988416SJim Ingham                 const size_t count = valid_bp_ids.GetSize();
11425a988416SJim Ingham                 for (size_t i = 0; i < count; ++i)
11435a988416SJim Ingham                 {
11445a988416SJim Ingham                     BreakpointID cur_bp_id = valid_bp_ids.GetBreakpointIDAtIndex (i);
11455a988416SJim Ingham 
11465a988416SJim Ingham                     if (cur_bp_id.GetBreakpointID() != LLDB_INVALID_BREAK_ID)
11475a988416SJim Ingham                     {
11485a988416SJim Ingham                         Breakpoint *breakpoint = target->GetBreakpointByID (cur_bp_id.GetBreakpointID()).get();
11495a988416SJim Ingham                         if (cur_bp_id.GetLocationID() != LLDB_INVALID_BREAK_ID)
11505a988416SJim Ingham                         {
11515a988416SJim Ingham                             BreakpointLocation *location = breakpoint->FindLocationByID (cur_bp_id.GetLocationID()).get();
11525a988416SJim Ingham                             if (location)
11535a988416SJim Ingham                             {
11545a988416SJim Ingham                                 location->SetEnabled (true);
11555a988416SJim Ingham                                 ++loc_count;
11565a988416SJim Ingham                             }
11575a988416SJim Ingham                         }
11585a988416SJim Ingham                         else
11595a988416SJim Ingham                         {
11605a988416SJim Ingham                             breakpoint->SetEnabled (true);
11615a988416SJim Ingham                             ++enable_count;
11625a988416SJim Ingham                         }
11635a988416SJim Ingham                     }
11645a988416SJim Ingham                 }
11655a988416SJim Ingham                 result.AppendMessageWithFormat ("%d breakpoints enabled.\n", enable_count + loc_count);
11665a988416SJim Ingham                 result.SetStatus (eReturnStatusSuccessFinishNoResult);
11675a988416SJim Ingham             }
11685a988416SJim Ingham         }
11695a988416SJim Ingham 
11705a988416SJim Ingham         return result.Succeeded();
11715a988416SJim Ingham     }
11725a988416SJim Ingham };
11735a988416SJim Ingham 
11745a988416SJim Ingham //-------------------------------------------------------------------------
11755a988416SJim Ingham // CommandObjectBreakpointDisable
11765a988416SJim Ingham //-------------------------------------------------------------------------
11775a988416SJim Ingham #pragma mark Disable
11785a988416SJim Ingham 
11795a988416SJim Ingham class CommandObjectBreakpointDisable : public CommandObjectParsed
11805a988416SJim Ingham {
11815a988416SJim Ingham public:
11825a988416SJim Ingham     CommandObjectBreakpointDisable (CommandInterpreter &interpreter) :
11835a988416SJim Ingham         CommandObjectParsed (interpreter,
11845a988416SJim Ingham                              "breakpoint disable",
11855a988416SJim Ingham                              "Disable the specified breakpoint(s) without removing it/them.  If no breakpoints are specified, disable them all.",
11865a988416SJim Ingham                              NULL)
11875a988416SJim Ingham     {
1188b0fac509SJim Ingham         SetHelpLong(
1189b0fac509SJim Ingham "Disable the specified breakpoint(s) without removing it/them.  \n\
1190b0fac509SJim Ingham If no breakpoints are specified, disable them all.\n\
1191b0fac509SJim Ingham \n\
1192b0fac509SJim Ingham Note: disabling a breakpoint will cause none of its locations to be hit\n\
1193b0fac509SJim Ingham regardless of whether they are enabled or disabled.  So the sequence: \n\
1194b0fac509SJim Ingham \n\
1195b0fac509SJim Ingham     (lldb) break disable 1\n\
1196b0fac509SJim Ingham     (lldb) break enable 1.1\n\
1197b0fac509SJim Ingham \n\
1198b0fac509SJim Ingham will NOT cause location 1.1 to get hit.  To achieve that, do:\n\
1199b0fac509SJim Ingham \n\
1200b0fac509SJim Ingham     (lldb) break disable 1.*\n\
1201b0fac509SJim Ingham     (lldb) break enable 1.1\n\
1202b0fac509SJim Ingham \n\
1203b0fac509SJim Ingham The first command disables all the locations of breakpoint 1, \n\
1204b0fac509SJim Ingham the second re-enables the first location."
1205b0fac509SJim Ingham                     );
1206b0fac509SJim Ingham 
12075a988416SJim Ingham         CommandArgumentEntry arg;
12085a988416SJim Ingham         CommandObject::AddIDsArgumentData(arg, eArgTypeBreakpointID, eArgTypeBreakpointIDRange);
12095a988416SJim Ingham         // Add the entry for the first argument for this command to the object's arguments vector.
12105a988416SJim Ingham         m_arguments.push_back (arg);
1211b0fac509SJim Ingham 
12125a988416SJim Ingham     }
12135a988416SJim Ingham 
12145a988416SJim Ingham 
12155a988416SJim Ingham     virtual
12165a988416SJim Ingham     ~CommandObjectBreakpointDisable () {}
12175a988416SJim Ingham 
12185a988416SJim Ingham protected:
12195a988416SJim Ingham     virtual bool
12205a988416SJim Ingham     DoExecute (Args& command, CommandReturnObject &result)
12215a988416SJim Ingham     {
1222893c932aSJim Ingham         Target *target = GetSelectedOrDummyTarget();
12235a988416SJim Ingham         if (target == NULL)
12245a988416SJim Ingham         {
12255a988416SJim Ingham             result.AppendError ("Invalid target.  No existing target or breakpoints.");
12265a988416SJim Ingham             result.SetStatus (eReturnStatusFailed);
12275a988416SJim Ingham             return false;
12285a988416SJim Ingham         }
12295a988416SJim Ingham 
12305a988416SJim Ingham         Mutex::Locker locker;
12315a988416SJim Ingham         target->GetBreakpointList().GetListMutex(locker);
12325a988416SJim Ingham 
12335a988416SJim Ingham         const BreakpointList &breakpoints = target->GetBreakpointList();
12345a988416SJim Ingham         size_t num_breakpoints = breakpoints.GetSize();
12355a988416SJim Ingham 
12365a988416SJim Ingham         if (num_breakpoints == 0)
12375a988416SJim Ingham         {
12385a988416SJim Ingham             result.AppendError ("No breakpoints exist to be disabled.");
12395a988416SJim Ingham             result.SetStatus (eReturnStatusFailed);
12405a988416SJim Ingham             return false;
12415a988416SJim Ingham         }
12425a988416SJim Ingham 
12435a988416SJim Ingham         if (command.GetArgumentCount() == 0)
12445a988416SJim Ingham         {
12455a988416SJim Ingham             // No breakpoint selected; disable all currently set breakpoints.
12465a988416SJim Ingham             target->DisableAllBreakpoints ();
12476fea17e8SGreg Clayton             result.AppendMessageWithFormat ("All breakpoints disabled. (%" PRIu64 " breakpoints)\n", (uint64_t)num_breakpoints);
12485a988416SJim Ingham             result.SetStatus (eReturnStatusSuccessFinishNoResult);
12495a988416SJim Ingham         }
12505a988416SJim Ingham         else
12515a988416SJim Ingham         {
12525a988416SJim Ingham             // Particular breakpoint selected; disable that breakpoint.
12535a988416SJim Ingham             BreakpointIDList valid_bp_ids;
12545a988416SJim Ingham 
12555e09c8c3SJim Ingham             CommandObjectMultiwordBreakpoint::VerifyBreakpointOrLocationIDs (command, target, result, &valid_bp_ids);
12565a988416SJim Ingham 
12575a988416SJim Ingham             if (result.Succeeded())
12585a988416SJim Ingham             {
12595a988416SJim Ingham                 int disable_count = 0;
12605a988416SJim Ingham                 int loc_count = 0;
12615a988416SJim Ingham                 const size_t count = valid_bp_ids.GetSize();
12625a988416SJim Ingham                 for (size_t i = 0; i < count; ++i)
12635a988416SJim Ingham                 {
12645a988416SJim Ingham                     BreakpointID cur_bp_id = valid_bp_ids.GetBreakpointIDAtIndex (i);
12655a988416SJim Ingham 
12665a988416SJim Ingham                     if (cur_bp_id.GetBreakpointID() != LLDB_INVALID_BREAK_ID)
12675a988416SJim Ingham                     {
12685a988416SJim Ingham                         Breakpoint *breakpoint = target->GetBreakpointByID (cur_bp_id.GetBreakpointID()).get();
12695a988416SJim Ingham                         if (cur_bp_id.GetLocationID() != LLDB_INVALID_BREAK_ID)
12705a988416SJim Ingham                         {
12715a988416SJim Ingham                             BreakpointLocation *location = breakpoint->FindLocationByID (cur_bp_id.GetLocationID()).get();
12725a988416SJim Ingham                             if (location)
12735a988416SJim Ingham                             {
12745a988416SJim Ingham                                 location->SetEnabled (false);
12755a988416SJim Ingham                                 ++loc_count;
12765a988416SJim Ingham                             }
12775a988416SJim Ingham                         }
12785a988416SJim Ingham                         else
12795a988416SJim Ingham                         {
12805a988416SJim Ingham                             breakpoint->SetEnabled (false);
12815a988416SJim Ingham                             ++disable_count;
12825a988416SJim Ingham                         }
12835a988416SJim Ingham                     }
12845a988416SJim Ingham                 }
12855a988416SJim Ingham                 result.AppendMessageWithFormat ("%d breakpoints disabled.\n", disable_count + loc_count);
12865a988416SJim Ingham                 result.SetStatus (eReturnStatusSuccessFinishNoResult);
12875a988416SJim Ingham             }
12885a988416SJim Ingham         }
12895a988416SJim Ingham 
12905a988416SJim Ingham         return result.Succeeded();
12915a988416SJim Ingham     }
12925a988416SJim Ingham 
12935a988416SJim Ingham };
12945a988416SJim Ingham 
12955a988416SJim Ingham //-------------------------------------------------------------------------
12965a988416SJim Ingham // CommandObjectBreakpointList
12975a988416SJim Ingham //-------------------------------------------------------------------------
12985a988416SJim Ingham #pragma mark List
12995a988416SJim Ingham 
13005a988416SJim Ingham class CommandObjectBreakpointList : public CommandObjectParsed
13015a988416SJim Ingham {
13025a988416SJim Ingham public:
13035a988416SJim Ingham     CommandObjectBreakpointList (CommandInterpreter &interpreter) :
13045a988416SJim Ingham         CommandObjectParsed (interpreter,
13055a988416SJim Ingham                              "breakpoint list",
13065a988416SJim Ingham                              "List some or all breakpoints at configurable levels of detail.",
13075a988416SJim Ingham                              NULL),
13085a988416SJim Ingham         m_options (interpreter)
13095a988416SJim Ingham     {
13105a988416SJim Ingham         CommandArgumentEntry arg;
13115a988416SJim Ingham         CommandArgumentData bp_id_arg;
13125a988416SJim Ingham 
13135a988416SJim Ingham         // Define the first (and only) variant of this arg.
13145a988416SJim Ingham         bp_id_arg.arg_type = eArgTypeBreakpointID;
13155a988416SJim Ingham         bp_id_arg.arg_repetition = eArgRepeatOptional;
13165a988416SJim Ingham 
13175a988416SJim Ingham         // There is only one variant this argument could be; put it into the argument entry.
13185a988416SJim Ingham         arg.push_back (bp_id_arg);
13195a988416SJim Ingham 
13205a988416SJim Ingham         // Push the data for the first argument into the m_arguments vector.
13215a988416SJim Ingham         m_arguments.push_back (arg);
13225a988416SJim Ingham     }
13235a988416SJim Ingham 
13245a988416SJim Ingham 
13255a988416SJim Ingham     virtual
13265a988416SJim Ingham     ~CommandObjectBreakpointList () {}
13275a988416SJim Ingham 
13285a988416SJim Ingham     virtual Options *
13295a988416SJim Ingham     GetOptions ()
13305a988416SJim Ingham     {
13315a988416SJim Ingham         return &m_options;
13325a988416SJim Ingham     }
13335a988416SJim Ingham 
13345a988416SJim Ingham     class CommandOptions : public Options
13355a988416SJim Ingham     {
13365a988416SJim Ingham     public:
13375a988416SJim Ingham 
13385a988416SJim Ingham         CommandOptions (CommandInterpreter &interpreter) :
13395a988416SJim Ingham             Options (interpreter),
134033df7cd3SJim Ingham             m_level (lldb::eDescriptionLevelBrief),
134133df7cd3SJim Ingham             m_use_dummy(false)
13425a988416SJim Ingham         {
13435a988416SJim Ingham         }
13445a988416SJim Ingham 
13455a988416SJim Ingham         virtual
13465a988416SJim Ingham         ~CommandOptions () {}
13475a988416SJim Ingham 
13485a988416SJim Ingham         virtual Error
13495a988416SJim Ingham         SetOptionValue (uint32_t option_idx, const char *option_arg)
13505a988416SJim Ingham         {
13515a988416SJim Ingham             Error error;
13523bcdfc0eSGreg Clayton             const int short_option = m_getopt_table[option_idx].val;
13535a988416SJim Ingham 
13545a988416SJim Ingham             switch (short_option)
13555a988416SJim Ingham             {
13565a988416SJim Ingham                 case 'b':
13575a988416SJim Ingham                     m_level = lldb::eDescriptionLevelBrief;
13585a988416SJim Ingham                     break;
135933df7cd3SJim Ingham                 case 'D':
136033df7cd3SJim Ingham                     m_use_dummy = true;
136133df7cd3SJim Ingham                     break;
13625a988416SJim Ingham                 case 'f':
13635a988416SJim Ingham                     m_level = lldb::eDescriptionLevelFull;
13645a988416SJim Ingham                     break;
13655a988416SJim Ingham                 case 'v':
13665a988416SJim Ingham                     m_level = lldb::eDescriptionLevelVerbose;
13675a988416SJim Ingham                     break;
13685a988416SJim Ingham                 case 'i':
13695a988416SJim Ingham                     m_internal = true;
13705a988416SJim Ingham                     break;
13715a988416SJim Ingham                 default:
13725a988416SJim Ingham                     error.SetErrorStringWithFormat ("unrecognized option '%c'", short_option);
13735a988416SJim Ingham                     break;
13745a988416SJim Ingham             }
13755a988416SJim Ingham 
13765a988416SJim Ingham             return error;
13775a988416SJim Ingham         }
13785a988416SJim Ingham 
13795a988416SJim Ingham         void
13805a988416SJim Ingham         OptionParsingStarting ()
13815a988416SJim Ingham         {
13825a988416SJim Ingham             m_level = lldb::eDescriptionLevelFull;
13835a988416SJim Ingham             m_internal = false;
138433df7cd3SJim Ingham             m_use_dummy = false;
13855a988416SJim Ingham         }
13865a988416SJim Ingham 
13875a988416SJim Ingham         const OptionDefinition *
13885a988416SJim Ingham         GetDefinitions ()
13895a988416SJim Ingham         {
13905a988416SJim Ingham             return g_option_table;
13915a988416SJim Ingham         }
13925a988416SJim Ingham 
13935a988416SJim Ingham         // Options table: Required for subclasses of Options.
13945a988416SJim Ingham 
13955a988416SJim Ingham         static OptionDefinition g_option_table[];
13965a988416SJim Ingham 
13975a988416SJim Ingham         // Instance variables to hold the values for command options.
13985a988416SJim Ingham 
13995a988416SJim Ingham         lldb::DescriptionLevel m_level;
14005a988416SJim Ingham 
14015a988416SJim Ingham         bool m_internal;
140233df7cd3SJim Ingham         bool m_use_dummy;
14035a988416SJim Ingham     };
14045a988416SJim Ingham 
14055a988416SJim Ingham protected:
14065a988416SJim Ingham     virtual bool
14075a988416SJim Ingham     DoExecute (Args& command, CommandReturnObject &result)
14085a988416SJim Ingham     {
140933df7cd3SJim Ingham         Target *target = GetSelectedOrDummyTarget(m_options.m_use_dummy);
141033df7cd3SJim Ingham 
14115a988416SJim Ingham         if (target == NULL)
14125a988416SJim Ingham         {
14135a988416SJim Ingham             result.AppendError ("Invalid target. No current target or breakpoints.");
14145a988416SJim Ingham             result.SetStatus (eReturnStatusSuccessFinishNoResult);
14155a988416SJim Ingham             return true;
14165a988416SJim Ingham         }
14175a988416SJim Ingham 
14185a988416SJim Ingham         const BreakpointList &breakpoints = target->GetBreakpointList(m_options.m_internal);
14195a988416SJim Ingham         Mutex::Locker locker;
14205a988416SJim Ingham         target->GetBreakpointList(m_options.m_internal).GetListMutex(locker);
14215a988416SJim Ingham 
14225a988416SJim Ingham         size_t num_breakpoints = breakpoints.GetSize();
14235a988416SJim Ingham 
14245a988416SJim Ingham         if (num_breakpoints == 0)
14255a988416SJim Ingham         {
14265a988416SJim Ingham             result.AppendMessage ("No breakpoints currently set.");
14275a988416SJim Ingham             result.SetStatus (eReturnStatusSuccessFinishNoResult);
14285a988416SJim Ingham             return true;
14295a988416SJim Ingham         }
14305a988416SJim Ingham 
14315a988416SJim Ingham         Stream &output_stream = result.GetOutputStream();
14325a988416SJim Ingham 
14335a988416SJim Ingham         if (command.GetArgumentCount() == 0)
14345a988416SJim Ingham         {
14355a988416SJim Ingham             // No breakpoint selected; show info about all currently set breakpoints.
14365a988416SJim Ingham             result.AppendMessage ("Current breakpoints:");
14375a988416SJim Ingham             for (size_t i = 0; i < num_breakpoints; ++i)
14385a988416SJim Ingham             {
14395a988416SJim Ingham                 Breakpoint *breakpoint = breakpoints.GetBreakpointAtIndex (i).get();
14405a988416SJim Ingham                 AddBreakpointDescription (&output_stream, breakpoint, m_options.m_level);
14415a988416SJim Ingham             }
14425a988416SJim Ingham             result.SetStatus (eReturnStatusSuccessFinishNoResult);
14435a988416SJim Ingham         }
14445a988416SJim Ingham         else
14455a988416SJim Ingham         {
14465a988416SJim Ingham             // Particular breakpoints selected; show info about that breakpoint.
14475a988416SJim Ingham             BreakpointIDList valid_bp_ids;
14485e09c8c3SJim Ingham             CommandObjectMultiwordBreakpoint::VerifyBreakpointOrLocationIDs (command, target, result, &valid_bp_ids);
14495a988416SJim Ingham 
14505a988416SJim Ingham             if (result.Succeeded())
14515a988416SJim Ingham             {
14525a988416SJim Ingham                 for (size_t i = 0; i < valid_bp_ids.GetSize(); ++i)
14535a988416SJim Ingham                 {
14545a988416SJim Ingham                     BreakpointID cur_bp_id = valid_bp_ids.GetBreakpointIDAtIndex (i);
14555a988416SJim Ingham                     Breakpoint *breakpoint = target->GetBreakpointByID (cur_bp_id.GetBreakpointID()).get();
14565a988416SJim Ingham                     AddBreakpointDescription (&output_stream, breakpoint, m_options.m_level);
14575a988416SJim Ingham                 }
14585a988416SJim Ingham                 result.SetStatus (eReturnStatusSuccessFinishNoResult);
14595a988416SJim Ingham             }
14605a988416SJim Ingham             else
14615a988416SJim Ingham             {
14625a988416SJim Ingham                 result.AppendError ("Invalid breakpoint id.");
14635a988416SJim Ingham                 result.SetStatus (eReturnStatusFailed);
14645a988416SJim Ingham             }
14655a988416SJim Ingham         }
14665a988416SJim Ingham 
14675a988416SJim Ingham         return result.Succeeded();
14685a988416SJim Ingham     }
14695a988416SJim Ingham 
14705a988416SJim Ingham private:
14715a988416SJim Ingham     CommandOptions m_options;
14725a988416SJim Ingham };
14735a988416SJim Ingham 
14745a988416SJim Ingham #pragma mark List::CommandOptions
14755a988416SJim Ingham OptionDefinition
14765a988416SJim Ingham CommandObjectBreakpointList::CommandOptions::g_option_table[] =
14775a988416SJim Ingham {
1478d37221dcSZachary Turner     { LLDB_OPT_SET_ALL, false, "internal", 'i', OptionParser::eNoArgument, NULL, NULL, 0, eArgTypeNone,
14795a988416SJim Ingham         "Show debugger internal breakpoints" },
14805a988416SJim Ingham 
1481d37221dcSZachary Turner     { LLDB_OPT_SET_1, false, "brief",    'b', OptionParser::eNoArgument, NULL, NULL, 0, eArgTypeNone,
14825a988416SJim Ingham         "Give a brief description of the breakpoint (no location info)."},
14835a988416SJim Ingham 
14845a988416SJim Ingham     // FIXME: We need to add an "internal" command, and then add this sort of thing to it.
14855a988416SJim Ingham     // But I need to see it for now, and don't want to wait.
1486d37221dcSZachary Turner     { LLDB_OPT_SET_2, false, "full",    'f', OptionParser::eNoArgument, NULL, NULL, 0, eArgTypeNone,
14875a988416SJim Ingham         "Give a full description of the breakpoint and its locations."},
14885a988416SJim Ingham 
1489d37221dcSZachary Turner     { LLDB_OPT_SET_3, false, "verbose", 'v', OptionParser::eNoArgument, NULL, NULL, 0, eArgTypeNone,
14905a988416SJim Ingham         "Explain everything we know about the breakpoint (for debugging debugger bugs)." },
14915a988416SJim Ingham 
149233df7cd3SJim Ingham     { LLDB_OPT_SET_ALL, false, "dummy-breakpoints", 'D', OptionParser::eNoArgument, NULL, NULL, 0, eArgTypeNone,
149333df7cd3SJim Ingham         "List Dummy breakpoints - i.e. breakpoints set before a file is provided, which prime new targets."},
149433df7cd3SJim Ingham 
1495d37221dcSZachary Turner     { 0, false, NULL, 0, 0, NULL, NULL, 0, eArgTypeNone, NULL }
14965a988416SJim Ingham };
14975a988416SJim Ingham 
14985a988416SJim Ingham //-------------------------------------------------------------------------
14995a988416SJim Ingham // CommandObjectBreakpointClear
15005a988416SJim Ingham //-------------------------------------------------------------------------
15015a988416SJim Ingham #pragma mark Clear
15025a988416SJim Ingham 
15035a988416SJim Ingham class CommandObjectBreakpointClear : public CommandObjectParsed
15045a988416SJim Ingham {
15055a988416SJim Ingham public:
15065a988416SJim Ingham 
15075a988416SJim Ingham     typedef enum BreakpointClearType
15085a988416SJim Ingham     {
15095a988416SJim Ingham         eClearTypeInvalid,
15105a988416SJim Ingham         eClearTypeFileAndLine
15115a988416SJim Ingham     } BreakpointClearType;
15125a988416SJim Ingham 
15135a988416SJim Ingham     CommandObjectBreakpointClear (CommandInterpreter &interpreter) :
15145a988416SJim Ingham         CommandObjectParsed (interpreter,
15155a988416SJim Ingham                              "breakpoint clear",
15165a988416SJim Ingham                              "Clears a breakpoint or set of breakpoints in the executable.",
15175a988416SJim Ingham                              "breakpoint clear <cmd-options>"),
15185a988416SJim Ingham         m_options (interpreter)
15195a988416SJim Ingham     {
15205a988416SJim Ingham     }
15215a988416SJim Ingham 
15225a988416SJim Ingham     virtual
15235a988416SJim Ingham     ~CommandObjectBreakpointClear () {}
15245a988416SJim Ingham 
15255a988416SJim Ingham     virtual Options *
15265a988416SJim Ingham     GetOptions ()
15275a988416SJim Ingham     {
15285a988416SJim Ingham         return &m_options;
15295a988416SJim Ingham     }
15305a988416SJim Ingham 
15315a988416SJim Ingham     class CommandOptions : public Options
15325a988416SJim Ingham     {
15335a988416SJim Ingham     public:
15345a988416SJim Ingham 
15355a988416SJim Ingham         CommandOptions (CommandInterpreter &interpreter) :
15365a988416SJim Ingham             Options (interpreter),
15375a988416SJim Ingham             m_filename (),
15385a988416SJim Ingham             m_line_num (0)
15395a988416SJim Ingham         {
15405a988416SJim Ingham         }
15415a988416SJim Ingham 
15425a988416SJim Ingham         virtual
15435a988416SJim Ingham         ~CommandOptions () {}
15445a988416SJim Ingham 
15455a988416SJim Ingham         virtual Error
15465a988416SJim Ingham         SetOptionValue (uint32_t option_idx, const char *option_arg)
15475a988416SJim Ingham         {
15485a988416SJim Ingham             Error error;
15493bcdfc0eSGreg Clayton             const int short_option = m_getopt_table[option_idx].val;
15505a988416SJim Ingham 
15515a988416SJim Ingham             switch (short_option)
15525a988416SJim Ingham             {
15535a988416SJim Ingham                 case 'f':
15545a988416SJim Ingham                     m_filename.assign (option_arg);
15555a988416SJim Ingham                     break;
15565a988416SJim Ingham 
15575a988416SJim Ingham                 case 'l':
15585a988416SJim Ingham                     m_line_num = Args::StringToUInt32 (option_arg, 0);
15595a988416SJim Ingham                     break;
15605a988416SJim Ingham 
15615a988416SJim Ingham                 default:
15625a988416SJim Ingham                     error.SetErrorStringWithFormat ("unrecognized option '%c'", short_option);
15635a988416SJim Ingham                     break;
15645a988416SJim Ingham             }
15655a988416SJim Ingham 
15665a988416SJim Ingham             return error;
15675a988416SJim Ingham         }
15685a988416SJim Ingham 
15695a988416SJim Ingham         void
15705a988416SJim Ingham         OptionParsingStarting ()
15715a988416SJim Ingham         {
15725a988416SJim Ingham             m_filename.clear();
15735a988416SJim Ingham             m_line_num = 0;
15745a988416SJim Ingham         }
15755a988416SJim Ingham 
15765a988416SJim Ingham         const OptionDefinition*
15775a988416SJim Ingham         GetDefinitions ()
15785a988416SJim Ingham         {
15795a988416SJim Ingham             return g_option_table;
15805a988416SJim Ingham         }
15815a988416SJim Ingham 
15825a988416SJim Ingham         // Options table: Required for subclasses of Options.
15835a988416SJim Ingham 
15845a988416SJim Ingham         static OptionDefinition g_option_table[];
15855a988416SJim Ingham 
15865a988416SJim Ingham         // Instance variables to hold the values for command options.
15875a988416SJim Ingham 
15885a988416SJim Ingham         std::string m_filename;
15895a988416SJim Ingham         uint32_t m_line_num;
15905a988416SJim Ingham 
15915a988416SJim Ingham     };
15925a988416SJim Ingham 
15935a988416SJim Ingham protected:
15945a988416SJim Ingham     virtual bool
15955a988416SJim Ingham     DoExecute (Args& command, CommandReturnObject &result)
15965a988416SJim Ingham     {
1597893c932aSJim Ingham         Target *target = GetSelectedOrDummyTarget();
15985a988416SJim Ingham         if (target == NULL)
15995a988416SJim Ingham         {
16005a988416SJim Ingham             result.AppendError ("Invalid target. No existing target or breakpoints.");
16015a988416SJim Ingham             result.SetStatus (eReturnStatusFailed);
16025a988416SJim Ingham             return false;
16035a988416SJim Ingham         }
16045a988416SJim Ingham 
16055a988416SJim Ingham         // The following are the various types of breakpoints that could be cleared:
16065a988416SJim Ingham         //   1). -f -l (clearing breakpoint by source location)
16075a988416SJim Ingham 
16085a988416SJim Ingham         BreakpointClearType break_type = eClearTypeInvalid;
16095a988416SJim Ingham 
16105a988416SJim Ingham         if (m_options.m_line_num != 0)
16115a988416SJim Ingham             break_type = eClearTypeFileAndLine;
16125a988416SJim Ingham 
16135a988416SJim Ingham         Mutex::Locker locker;
16145a988416SJim Ingham         target->GetBreakpointList().GetListMutex(locker);
16155a988416SJim Ingham 
16165a988416SJim Ingham         BreakpointList &breakpoints = target->GetBreakpointList();
16175a988416SJim Ingham         size_t num_breakpoints = breakpoints.GetSize();
16185a988416SJim Ingham 
16195a988416SJim Ingham         // Early return if there's no breakpoint at all.
16205a988416SJim Ingham         if (num_breakpoints == 0)
16215a988416SJim Ingham         {
16225a988416SJim Ingham             result.AppendError ("Breakpoint clear: No breakpoint cleared.");
16235a988416SJim Ingham             result.SetStatus (eReturnStatusFailed);
16245a988416SJim Ingham             return result.Succeeded();
16255a988416SJim Ingham         }
16265a988416SJim Ingham 
16275a988416SJim Ingham         // Find matching breakpoints and delete them.
16285a988416SJim Ingham 
16295a988416SJim Ingham         // First create a copy of all the IDs.
16305a988416SJim Ingham         std::vector<break_id_t> BreakIDs;
16315a988416SJim Ingham         for (size_t i = 0; i < num_breakpoints; ++i)
16325a988416SJim Ingham             BreakIDs.push_back(breakpoints.GetBreakpointAtIndex(i).get()->GetID());
16335a988416SJim Ingham 
16345a988416SJim Ingham         int num_cleared = 0;
16355a988416SJim Ingham         StreamString ss;
16365a988416SJim Ingham         switch (break_type)
16375a988416SJim Ingham         {
16385a988416SJim Ingham             case eClearTypeFileAndLine: // Breakpoint by source position
16395a988416SJim Ingham                 {
16405a988416SJim Ingham                     const ConstString filename(m_options.m_filename.c_str());
16415a988416SJim Ingham                     BreakpointLocationCollection loc_coll;
16425a988416SJim Ingham 
16435a988416SJim Ingham                     for (size_t i = 0; i < num_breakpoints; ++i)
16445a988416SJim Ingham                     {
16455a988416SJim Ingham                         Breakpoint *bp = breakpoints.FindBreakpointByID(BreakIDs[i]).get();
16465a988416SJim Ingham 
16475a988416SJim Ingham                         if (bp->GetMatchingFileLine(filename, m_options.m_line_num, loc_coll))
16485a988416SJim Ingham                         {
16495a988416SJim Ingham                             // If the collection size is 0, it's a full match and we can just remove the breakpoint.
16505a988416SJim Ingham                             if (loc_coll.GetSize() == 0)
16515a988416SJim Ingham                             {
16525a988416SJim Ingham                                 bp->GetDescription(&ss, lldb::eDescriptionLevelBrief);
16535a988416SJim Ingham                                 ss.EOL();
16545a988416SJim Ingham                                 target->RemoveBreakpointByID (bp->GetID());
16555a988416SJim Ingham                                 ++num_cleared;
16565a988416SJim Ingham                             }
16575a988416SJim Ingham                         }
16585a988416SJim Ingham                     }
16595a988416SJim Ingham                 }
16605a988416SJim Ingham                 break;
16615a988416SJim Ingham 
16625a988416SJim Ingham             default:
16635a988416SJim Ingham                 break;
16645a988416SJim Ingham         }
16655a988416SJim Ingham 
16665a988416SJim Ingham         if (num_cleared > 0)
16675a988416SJim Ingham         {
16685a988416SJim Ingham             Stream &output_stream = result.GetOutputStream();
16695a988416SJim Ingham             output_stream.Printf ("%d breakpoints cleared:\n", num_cleared);
16705a988416SJim Ingham             output_stream << ss.GetData();
16715a988416SJim Ingham             output_stream.EOL();
16725a988416SJim Ingham             result.SetStatus (eReturnStatusSuccessFinishNoResult);
16735a988416SJim Ingham         }
16745a988416SJim Ingham         else
16755a988416SJim Ingham         {
16765a988416SJim Ingham             result.AppendError ("Breakpoint clear: No breakpoint cleared.");
16775a988416SJim Ingham             result.SetStatus (eReturnStatusFailed);
16785a988416SJim Ingham         }
16795a988416SJim Ingham 
16805a988416SJim Ingham         return result.Succeeded();
16815a988416SJim Ingham     }
16825a988416SJim Ingham 
16835a988416SJim Ingham private:
16845a988416SJim Ingham     CommandOptions m_options;
16855a988416SJim Ingham };
16865a988416SJim Ingham 
16875a988416SJim Ingham #pragma mark Clear::CommandOptions
16885a988416SJim Ingham 
16895a988416SJim Ingham OptionDefinition
16905a988416SJim Ingham CommandObjectBreakpointClear::CommandOptions::g_option_table[] =
16915a988416SJim Ingham {
1692d37221dcSZachary Turner     { LLDB_OPT_SET_1, false, "file", 'f', OptionParser::eRequiredArgument, NULL, NULL, CommandCompletions::eSourceFileCompletion, eArgTypeFilename,
16935a988416SJim Ingham         "Specify the breakpoint by source location in this particular file."},
16945a988416SJim Ingham 
1695d37221dcSZachary Turner     { LLDB_OPT_SET_1, true, "line", 'l', OptionParser::eRequiredArgument, NULL, NULL, 0, eArgTypeLineNum,
16965a988416SJim Ingham         "Specify the breakpoint by source location at this particular line."},
16975a988416SJim Ingham 
1698d37221dcSZachary Turner     { 0, false, NULL, 0, 0, NULL, NULL, 0, eArgTypeNone, NULL }
16995a988416SJim Ingham };
17005a988416SJim Ingham 
17015a988416SJim Ingham //-------------------------------------------------------------------------
17025a988416SJim Ingham // CommandObjectBreakpointDelete
17035a988416SJim Ingham //-------------------------------------------------------------------------
17045a988416SJim Ingham #pragma mark Delete
17055a988416SJim Ingham 
17065a988416SJim Ingham class CommandObjectBreakpointDelete : public CommandObjectParsed
17075a988416SJim Ingham {
17085a988416SJim Ingham public:
17095a988416SJim Ingham     CommandObjectBreakpointDelete (CommandInterpreter &interpreter) :
17105a988416SJim Ingham         CommandObjectParsed (interpreter,
17115a988416SJim Ingham                              "breakpoint delete",
17125a988416SJim Ingham                              "Delete the specified breakpoint(s).  If no breakpoints are specified, delete them all.",
171333df7cd3SJim Ingham                              NULL),
171433df7cd3SJim Ingham         m_options (interpreter)
17155a988416SJim Ingham     {
17165a988416SJim Ingham         CommandArgumentEntry arg;
17175a988416SJim Ingham         CommandObject::AddIDsArgumentData(arg, eArgTypeBreakpointID, eArgTypeBreakpointIDRange);
17185a988416SJim Ingham         // Add the entry for the first argument for this command to the object's arguments vector.
17195a988416SJim Ingham         m_arguments.push_back (arg);
17205a988416SJim Ingham     }
17215a988416SJim Ingham 
17225a988416SJim Ingham     virtual
17235a988416SJim Ingham     ~CommandObjectBreakpointDelete () {}
17245a988416SJim Ingham 
172533df7cd3SJim Ingham     virtual Options *
172633df7cd3SJim Ingham     GetOptions ()
172733df7cd3SJim Ingham     {
172833df7cd3SJim Ingham         return &m_options;
172933df7cd3SJim Ingham     }
173033df7cd3SJim Ingham 
173133df7cd3SJim Ingham     class CommandOptions : public Options
173233df7cd3SJim Ingham     {
173333df7cd3SJim Ingham     public:
173433df7cd3SJim Ingham 
173533df7cd3SJim Ingham         CommandOptions (CommandInterpreter &interpreter) :
173633df7cd3SJim Ingham             Options (interpreter),
173733df7cd3SJim Ingham             m_use_dummy (false),
173833df7cd3SJim Ingham             m_force (false)
173933df7cd3SJim Ingham         {
174033df7cd3SJim Ingham         }
174133df7cd3SJim Ingham 
174233df7cd3SJim Ingham         virtual
174333df7cd3SJim Ingham         ~CommandOptions () {}
174433df7cd3SJim Ingham 
174533df7cd3SJim Ingham         virtual Error
174633df7cd3SJim Ingham         SetOptionValue (uint32_t option_idx, const char *option_arg)
174733df7cd3SJim Ingham         {
174833df7cd3SJim Ingham             Error error;
174933df7cd3SJim Ingham             const int short_option = m_getopt_table[option_idx].val;
175033df7cd3SJim Ingham 
175133df7cd3SJim Ingham             switch (short_option)
175233df7cd3SJim Ingham             {
175333df7cd3SJim Ingham                 case 'f':
175433df7cd3SJim Ingham                     m_force = true;
175533df7cd3SJim Ingham                     break;
175633df7cd3SJim Ingham 
175733df7cd3SJim Ingham                 case 'D':
175833df7cd3SJim Ingham                     m_use_dummy = true;
175933df7cd3SJim Ingham                     break;
176033df7cd3SJim Ingham 
176133df7cd3SJim Ingham                 default:
176233df7cd3SJim Ingham                     error.SetErrorStringWithFormat ("unrecognized option '%c'", short_option);
176333df7cd3SJim Ingham                     break;
176433df7cd3SJim Ingham             }
176533df7cd3SJim Ingham 
176633df7cd3SJim Ingham             return error;
176733df7cd3SJim Ingham         }
176833df7cd3SJim Ingham 
176933df7cd3SJim Ingham         void
177033df7cd3SJim Ingham         OptionParsingStarting ()
177133df7cd3SJim Ingham         {
177233df7cd3SJim Ingham             m_use_dummy = false;
177333df7cd3SJim Ingham             m_force = false;
177433df7cd3SJim Ingham         }
177533df7cd3SJim Ingham 
177633df7cd3SJim Ingham         const OptionDefinition*
177733df7cd3SJim Ingham         GetDefinitions ()
177833df7cd3SJim Ingham         {
177933df7cd3SJim Ingham             return g_option_table;
178033df7cd3SJim Ingham         }
178133df7cd3SJim Ingham 
178233df7cd3SJim Ingham         // Options table: Required for subclasses of Options.
178333df7cd3SJim Ingham 
178433df7cd3SJim Ingham         static OptionDefinition g_option_table[];
178533df7cd3SJim Ingham 
178633df7cd3SJim Ingham         // Instance variables to hold the values for command options.
178733df7cd3SJim Ingham         bool m_use_dummy;
178833df7cd3SJim Ingham         bool m_force;
178933df7cd3SJim Ingham     };
179033df7cd3SJim Ingham 
17915a988416SJim Ingham protected:
17925a988416SJim Ingham     virtual bool
17935a988416SJim Ingham     DoExecute (Args& command, CommandReturnObject &result)
17945a988416SJim Ingham     {
179533df7cd3SJim Ingham         Target *target = GetSelectedOrDummyTarget(m_options.m_use_dummy);
179633df7cd3SJim Ingham 
17975a988416SJim Ingham         if (target == NULL)
17985a988416SJim Ingham         {
17995a988416SJim Ingham             result.AppendError ("Invalid target. No existing target or breakpoints.");
18005a988416SJim Ingham             result.SetStatus (eReturnStatusFailed);
18015a988416SJim Ingham             return false;
18025a988416SJim Ingham         }
18035a988416SJim Ingham 
18045a988416SJim Ingham         Mutex::Locker locker;
18055a988416SJim Ingham         target->GetBreakpointList().GetListMutex(locker);
18065a988416SJim Ingham 
18075a988416SJim Ingham         const BreakpointList &breakpoints = target->GetBreakpointList();
18085a988416SJim Ingham 
18095a988416SJim Ingham         size_t num_breakpoints = breakpoints.GetSize();
18105a988416SJim Ingham 
18115a988416SJim Ingham         if (num_breakpoints == 0)
18125a988416SJim Ingham         {
18135a988416SJim Ingham             result.AppendError ("No breakpoints exist to be deleted.");
18145a988416SJim Ingham             result.SetStatus (eReturnStatusFailed);
18155a988416SJim Ingham             return false;
18165a988416SJim Ingham         }
18175a988416SJim Ingham 
18185a988416SJim Ingham         if (command.GetArgumentCount() == 0)
18195a988416SJim Ingham         {
182033df7cd3SJim Ingham             if (!m_options.m_force && !m_interpreter.Confirm ("About to delete all breakpoints, do you want to do that?", true))
18215a988416SJim Ingham             {
18225a988416SJim Ingham                 result.AppendMessage("Operation cancelled...");
18235a988416SJim Ingham             }
18245a988416SJim Ingham             else
18255a988416SJim Ingham             {
18265a988416SJim Ingham                 target->RemoveAllBreakpoints ();
18276fea17e8SGreg Clayton                 result.AppendMessageWithFormat ("All breakpoints removed. (%" PRIu64 " breakpoint%s)\n", (uint64_t)num_breakpoints, num_breakpoints > 1 ? "s" : "");
18285a988416SJim Ingham             }
18295a988416SJim Ingham             result.SetStatus (eReturnStatusSuccessFinishNoResult);
18305a988416SJim Ingham         }
18315a988416SJim Ingham         else
18325a988416SJim Ingham         {
18335a988416SJim Ingham             // Particular breakpoint selected; disable that breakpoint.
18345a988416SJim Ingham             BreakpointIDList valid_bp_ids;
18355e09c8c3SJim Ingham             CommandObjectMultiwordBreakpoint::VerifyBreakpointOrLocationIDs (command, target, result, &valid_bp_ids);
18365a988416SJim Ingham 
18375a988416SJim Ingham             if (result.Succeeded())
18385a988416SJim Ingham             {
18395a988416SJim Ingham                 int delete_count = 0;
18405a988416SJim Ingham                 int disable_count = 0;
18415a988416SJim Ingham                 const size_t count = valid_bp_ids.GetSize();
18425a988416SJim Ingham                 for (size_t i = 0; i < count; ++i)
18435a988416SJim Ingham                 {
18445a988416SJim Ingham                     BreakpointID cur_bp_id = valid_bp_ids.GetBreakpointIDAtIndex (i);
18455a988416SJim Ingham 
18465a988416SJim Ingham                     if (cur_bp_id.GetBreakpointID() != LLDB_INVALID_BREAK_ID)
18475a988416SJim Ingham                     {
18485a988416SJim Ingham                         if (cur_bp_id.GetLocationID() != LLDB_INVALID_BREAK_ID)
18495a988416SJim Ingham                         {
18505a988416SJim Ingham                             Breakpoint *breakpoint = target->GetBreakpointByID (cur_bp_id.GetBreakpointID()).get();
18515a988416SJim Ingham                             BreakpointLocation *location = breakpoint->FindLocationByID (cur_bp_id.GetLocationID()).get();
18525a988416SJim Ingham                             // It makes no sense to try to delete individual locations, so we disable them instead.
18535a988416SJim Ingham                             if (location)
18545a988416SJim Ingham                             {
18555a988416SJim Ingham                                 location->SetEnabled (false);
18565a988416SJim Ingham                                 ++disable_count;
18575a988416SJim Ingham                             }
18585a988416SJim Ingham                         }
18595a988416SJim Ingham                         else
18605a988416SJim Ingham                         {
18615a988416SJim Ingham                             target->RemoveBreakpointByID (cur_bp_id.GetBreakpointID());
18625a988416SJim Ingham                             ++delete_count;
18635a988416SJim Ingham                         }
18645a988416SJim Ingham                     }
18655a988416SJim Ingham                 }
18665a988416SJim Ingham                 result.AppendMessageWithFormat ("%d breakpoints deleted; %d breakpoint locations disabled.\n",
18675a988416SJim Ingham                                                delete_count, disable_count);
18685a988416SJim Ingham                 result.SetStatus (eReturnStatusSuccessFinishNoResult);
18695a988416SJim Ingham             }
18705a988416SJim Ingham         }
18715a988416SJim Ingham         return result.Succeeded();
18725a988416SJim Ingham     }
187333df7cd3SJim Ingham private:
187433df7cd3SJim Ingham     CommandOptions m_options;
187533df7cd3SJim Ingham };
187633df7cd3SJim Ingham 
187733df7cd3SJim Ingham OptionDefinition
187833df7cd3SJim Ingham CommandObjectBreakpointDelete::CommandOptions::g_option_table[] =
187933df7cd3SJim Ingham {
188033df7cd3SJim Ingham     { LLDB_OPT_SET_1, false, "force", 'f', OptionParser::eNoArgument, NULL, NULL, 0, eArgTypeNone,
188133df7cd3SJim Ingham         "Delete all breakpoints without querying for confirmation."},
188233df7cd3SJim Ingham 
188333df7cd3SJim Ingham     { LLDB_OPT_SET_1, false, "dummy-breakpoints", 'D', OptionParser::eNoArgument, NULL, NULL, 0, eArgTypeNone,
188433df7cd3SJim Ingham         "Delete Dummy breakpoints - i.e. breakpoints set before a file is provided, which prime new targets."},
188533df7cd3SJim Ingham 
188633df7cd3SJim Ingham     { 0, false, NULL, 0, 0, NULL, NULL, 0, eArgTypeNone, NULL }
18875a988416SJim Ingham };
18885a988416SJim Ingham 
188930fdc8d8SChris Lattner //-------------------------------------------------------------------------
18905e09c8c3SJim Ingham // CommandObjectBreakpointName
18915e09c8c3SJim Ingham //-------------------------------------------------------------------------
18925e09c8c3SJim Ingham 
18935e09c8c3SJim Ingham static OptionDefinition
18945e09c8c3SJim Ingham g_breakpoint_name_options[] =
18955e09c8c3SJim Ingham {
18965e09c8c3SJim Ingham     { LLDB_OPT_SET_1,   false, "name", 'N', OptionParser::eRequiredArgument, NULL, NULL, 0, eArgTypeBreakpointName, "Specifies a breakpoint name to use."},
18975e09c8c3SJim Ingham     { LLDB_OPT_SET_2,   false, "breakpoint-id", 'B', OptionParser::eRequiredArgument, NULL, NULL, 0, eArgTypeBreakpointID,   "Specify a breakpoint id to use."},
18985e09c8c3SJim Ingham     { LLDB_OPT_SET_ALL, false, "dummy-breakpoints", 'D', OptionParser::eNoArgument, NULL, NULL, 0, eArgTypeNone,
18995e09c8c3SJim Ingham         "Operate on Dummy breakpoints - i.e. breakpoints set before a file is provided, which prime new targets."},
19005e09c8c3SJim Ingham };
19015e09c8c3SJim Ingham class BreakpointNameOptionGroup : public OptionGroup
19025e09c8c3SJim Ingham {
19035e09c8c3SJim Ingham public:
19045e09c8c3SJim Ingham     BreakpointNameOptionGroup() :
19055e09c8c3SJim Ingham         OptionGroup(),
19065e09c8c3SJim Ingham         m_breakpoint(LLDB_INVALID_BREAK_ID),
19075e09c8c3SJim Ingham         m_use_dummy (false)
19085e09c8c3SJim Ingham     {
19095e09c8c3SJim Ingham 
19105e09c8c3SJim Ingham     }
19115e09c8c3SJim Ingham 
19125e09c8c3SJim Ingham     virtual
19135e09c8c3SJim Ingham     ~BreakpointNameOptionGroup ()
19145e09c8c3SJim Ingham     {
19155e09c8c3SJim Ingham     }
19165e09c8c3SJim Ingham 
19175e09c8c3SJim Ingham     virtual uint32_t
19185e09c8c3SJim Ingham     GetNumDefinitions ()
19195e09c8c3SJim Ingham     {
19205e09c8c3SJim Ingham       return sizeof (g_breakpoint_name_options) / sizeof (OptionDefinition);
19215e09c8c3SJim Ingham     }
19225e09c8c3SJim Ingham 
19235e09c8c3SJim Ingham     virtual const OptionDefinition*
19245e09c8c3SJim Ingham     GetDefinitions ()
19255e09c8c3SJim Ingham     {
19265e09c8c3SJim Ingham         return g_breakpoint_name_options;
19275e09c8c3SJim Ingham     }
19285e09c8c3SJim Ingham 
19295e09c8c3SJim Ingham     virtual Error
19305e09c8c3SJim Ingham     SetOptionValue (CommandInterpreter &interpreter,
19315e09c8c3SJim Ingham                     uint32_t option_idx,
19325e09c8c3SJim Ingham                     const char *option_value)
19335e09c8c3SJim Ingham     {
19345e09c8c3SJim Ingham         Error error;
19355e09c8c3SJim Ingham         const int short_option = g_breakpoint_name_options[option_idx].short_option;
19365e09c8c3SJim Ingham 
19375e09c8c3SJim Ingham         switch (short_option)
19385e09c8c3SJim Ingham         {
19395e09c8c3SJim Ingham         case 'N':
19405e09c8c3SJim Ingham             if (BreakpointID::StringIsBreakpointName(option_value, error) && error.Success())
19415e09c8c3SJim Ingham                 m_name.SetValueFromCString(option_value);
19425e09c8c3SJim Ingham             break;
19435e09c8c3SJim Ingham 
19445e09c8c3SJim Ingham         case 'B':
19455e09c8c3SJim Ingham             if (m_breakpoint.SetValueFromCString(option_value).Fail())
19465e09c8c3SJim Ingham                 error.SetErrorStringWithFormat ("unrecognized value \"%s\" for breakpoint", option_value);
19475e09c8c3SJim Ingham             break;
19485e09c8c3SJim Ingham         case 'D':
19495e09c8c3SJim Ingham             if (m_use_dummy.SetValueFromCString(option_value).Fail())
19505e09c8c3SJim Ingham                 error.SetErrorStringWithFormat ("unrecognized value \"%s\" for use-dummy", option_value);
19515e09c8c3SJim Ingham             break;
19525e09c8c3SJim Ingham 
19535e09c8c3SJim Ingham         default:
19545e09c8c3SJim Ingham               error.SetErrorStringWithFormat("unrecognized short option '%c'", short_option);
19555e09c8c3SJim Ingham               break;
19565e09c8c3SJim Ingham         }
19575e09c8c3SJim Ingham         return error;
19585e09c8c3SJim Ingham     }
19595e09c8c3SJim Ingham 
19605e09c8c3SJim Ingham     virtual void
19615e09c8c3SJim Ingham     OptionParsingStarting (CommandInterpreter &interpreter)
19625e09c8c3SJim Ingham     {
19635e09c8c3SJim Ingham         m_name.Clear();
19645e09c8c3SJim Ingham         m_breakpoint.Clear();
19655e09c8c3SJim Ingham         m_use_dummy.Clear();
19665e09c8c3SJim Ingham         m_use_dummy.SetDefaultValue(false);
19675e09c8c3SJim Ingham     }
19685e09c8c3SJim Ingham 
19695e09c8c3SJim Ingham     OptionValueString m_name;
19705e09c8c3SJim Ingham     OptionValueUInt64 m_breakpoint;
19715e09c8c3SJim Ingham     OptionValueBoolean m_use_dummy;
19725e09c8c3SJim Ingham };
19735e09c8c3SJim Ingham 
19745e09c8c3SJim Ingham 
19755e09c8c3SJim Ingham class CommandObjectBreakpointNameAdd : public CommandObjectParsed
19765e09c8c3SJim Ingham {
19775e09c8c3SJim Ingham public:
19785e09c8c3SJim Ingham     CommandObjectBreakpointNameAdd (CommandInterpreter &interpreter) :
19795e09c8c3SJim Ingham         CommandObjectParsed (interpreter,
19805e09c8c3SJim Ingham                              "add",
19815e09c8c3SJim Ingham                              "Add a name to the breakpoints provided.",
19825e09c8c3SJim Ingham                              "breakpoint name add <command-options> <breakpoint-id-list>"),
19835e09c8c3SJim Ingham         m_name_options(),
19845e09c8c3SJim Ingham         m_option_group(interpreter)
19855e09c8c3SJim Ingham         {
19865e09c8c3SJim Ingham             // Create the first variant for the first (and only) argument for this command.
19875e09c8c3SJim Ingham             CommandArgumentEntry arg1;
19885e09c8c3SJim Ingham             CommandArgumentData id_arg;
19895e09c8c3SJim Ingham             id_arg.arg_type = eArgTypeBreakpointID;
19905e09c8c3SJim Ingham             id_arg.arg_repetition = eArgRepeatOptional;
19915e09c8c3SJim Ingham             arg1.push_back(id_arg);
19925e09c8c3SJim Ingham             m_arguments.push_back (arg1);
19935e09c8c3SJim Ingham 
19945e09c8c3SJim Ingham             m_option_group.Append (&m_name_options, LLDB_OPT_SET_1, LLDB_OPT_SET_ALL);
19955e09c8c3SJim Ingham             m_option_group.Finalize();
19965e09c8c3SJim Ingham         }
19975e09c8c3SJim Ingham 
19985e09c8c3SJim Ingham     virtual
19995e09c8c3SJim Ingham     ~CommandObjectBreakpointNameAdd () {}
20005e09c8c3SJim Ingham 
20015e09c8c3SJim Ingham   Options *
20025e09c8c3SJim Ingham   GetOptions ()
20035e09c8c3SJim Ingham   {
20045e09c8c3SJim Ingham     return &m_option_group;
20055e09c8c3SJim Ingham   }
20065e09c8c3SJim Ingham 
20075e09c8c3SJim Ingham protected:
20085e09c8c3SJim Ingham     virtual bool
20095e09c8c3SJim Ingham     DoExecute (Args& command, CommandReturnObject &result)
20105e09c8c3SJim Ingham     {
20115e09c8c3SJim Ingham         if (!m_name_options.m_name.OptionWasSet())
20125e09c8c3SJim Ingham         {
20135e09c8c3SJim Ingham             result.SetError("No name option provided.");
20145e09c8c3SJim Ingham             return false;
20155e09c8c3SJim Ingham         }
20165e09c8c3SJim Ingham 
20175e09c8c3SJim Ingham         Target *target = GetSelectedOrDummyTarget(m_name_options.m_use_dummy.GetCurrentValue());
20185e09c8c3SJim Ingham 
20195e09c8c3SJim Ingham         if (target == NULL)
20205e09c8c3SJim Ingham         {
20215e09c8c3SJim Ingham             result.AppendError ("Invalid target. No existing target or breakpoints.");
20225e09c8c3SJim Ingham             result.SetStatus (eReturnStatusFailed);
20235e09c8c3SJim Ingham             return false;
20245e09c8c3SJim Ingham         }
20255e09c8c3SJim Ingham 
20265e09c8c3SJim Ingham         Mutex::Locker locker;
20275e09c8c3SJim Ingham         target->GetBreakpointList().GetListMutex(locker);
20285e09c8c3SJim Ingham 
20295e09c8c3SJim Ingham         const BreakpointList &breakpoints = target->GetBreakpointList();
20305e09c8c3SJim Ingham 
20315e09c8c3SJim Ingham         size_t num_breakpoints = breakpoints.GetSize();
20325e09c8c3SJim Ingham         if (num_breakpoints == 0)
20335e09c8c3SJim Ingham         {
20345e09c8c3SJim Ingham             result.SetError("No breakpoints, cannot add names.");
20355e09c8c3SJim Ingham             result.SetStatus (eReturnStatusFailed);
20365e09c8c3SJim Ingham             return false;
20375e09c8c3SJim Ingham         }
20385e09c8c3SJim Ingham 
20395e09c8c3SJim Ingham         // Particular breakpoint selected; disable that breakpoint.
20405e09c8c3SJim Ingham         BreakpointIDList valid_bp_ids;
20415e09c8c3SJim Ingham         CommandObjectMultiwordBreakpoint::VerifyBreakpointIDs (command, target, result, &valid_bp_ids);
20425e09c8c3SJim Ingham 
20435e09c8c3SJim Ingham         if (result.Succeeded())
20445e09c8c3SJim Ingham         {
20455e09c8c3SJim Ingham             if (valid_bp_ids.GetSize() == 0)
20465e09c8c3SJim Ingham             {
20475e09c8c3SJim Ingham                 result.SetError("No breakpoints specified, cannot add names.");
20485e09c8c3SJim Ingham                 result.SetStatus (eReturnStatusFailed);
20495e09c8c3SJim Ingham                 return false;
20505e09c8c3SJim Ingham             }
20515e09c8c3SJim Ingham             size_t num_valid_ids = valid_bp_ids.GetSize();
20525e09c8c3SJim Ingham             for (size_t index = 0; index < num_valid_ids; index++)
20535e09c8c3SJim Ingham             {
20545e09c8c3SJim Ingham                 lldb::break_id_t bp_id = valid_bp_ids.GetBreakpointIDAtIndex(index).GetBreakpointID();
20555e09c8c3SJim Ingham                 BreakpointSP bp_sp = breakpoints.FindBreakpointByID(bp_id);
20565e09c8c3SJim Ingham                 Error error;  // We don't need to check the error here, since the option parser checked it...
20575e09c8c3SJim Ingham                 bp_sp->AddName(m_name_options.m_name.GetCurrentValue(), error);
20585e09c8c3SJim Ingham             }
20595e09c8c3SJim Ingham         }
20605e09c8c3SJim Ingham 
20615e09c8c3SJim Ingham         return true;
20625e09c8c3SJim Ingham     }
20635e09c8c3SJim Ingham 
20645e09c8c3SJim Ingham private:
20655e09c8c3SJim Ingham     BreakpointNameOptionGroup m_name_options;
20665e09c8c3SJim Ingham     OptionGroupOptions m_option_group;
20675e09c8c3SJim Ingham };
20685e09c8c3SJim Ingham 
20695e09c8c3SJim Ingham 
20705e09c8c3SJim Ingham 
20715e09c8c3SJim Ingham class CommandObjectBreakpointNameDelete : public CommandObjectParsed
20725e09c8c3SJim Ingham {
20735e09c8c3SJim Ingham public:
20745e09c8c3SJim Ingham     CommandObjectBreakpointNameDelete (CommandInterpreter &interpreter) :
20755e09c8c3SJim Ingham         CommandObjectParsed (interpreter,
20765e09c8c3SJim Ingham                              "delete",
20775e09c8c3SJim Ingham                              "Delete a name from the breakpoints provided.",
20785e09c8c3SJim Ingham                              "breakpoint name delete <command-options> <breakpoint-id-list>"),
20795e09c8c3SJim Ingham         m_name_options(),
20805e09c8c3SJim Ingham         m_option_group(interpreter)
20815e09c8c3SJim Ingham     {
20825e09c8c3SJim Ingham         // Create the first variant for the first (and only) argument for this command.
20835e09c8c3SJim Ingham         CommandArgumentEntry arg1;
20845e09c8c3SJim Ingham         CommandArgumentData id_arg;
20855e09c8c3SJim Ingham         id_arg.arg_type = eArgTypeBreakpointID;
20865e09c8c3SJim Ingham         id_arg.arg_repetition = eArgRepeatOptional;
20875e09c8c3SJim Ingham         arg1.push_back(id_arg);
20885e09c8c3SJim Ingham         m_arguments.push_back (arg1);
20895e09c8c3SJim Ingham 
20905e09c8c3SJim Ingham         m_option_group.Append (&m_name_options, LLDB_OPT_SET_1, LLDB_OPT_SET_ALL);
20915e09c8c3SJim Ingham         m_option_group.Finalize();
20925e09c8c3SJim Ingham     }
20935e09c8c3SJim Ingham 
20945e09c8c3SJim Ingham     virtual
20955e09c8c3SJim Ingham     ~CommandObjectBreakpointNameDelete () {}
20965e09c8c3SJim Ingham 
20975e09c8c3SJim Ingham   Options *
20985e09c8c3SJim Ingham   GetOptions ()
20995e09c8c3SJim Ingham   {
21005e09c8c3SJim Ingham     return &m_option_group;
21015e09c8c3SJim Ingham   }
21025e09c8c3SJim Ingham 
21035e09c8c3SJim Ingham protected:
21045e09c8c3SJim Ingham     virtual bool
21055e09c8c3SJim Ingham     DoExecute (Args& command, CommandReturnObject &result)
21065e09c8c3SJim Ingham     {
21075e09c8c3SJim Ingham         if (!m_name_options.m_name.OptionWasSet())
21085e09c8c3SJim Ingham         {
21095e09c8c3SJim Ingham             result.SetError("No name option provided.");
21105e09c8c3SJim Ingham             return false;
21115e09c8c3SJim Ingham         }
21125e09c8c3SJim Ingham 
21135e09c8c3SJim Ingham         Target *target = GetSelectedOrDummyTarget(m_name_options.m_use_dummy.GetCurrentValue());
21145e09c8c3SJim Ingham 
21155e09c8c3SJim Ingham         if (target == NULL)
21165e09c8c3SJim Ingham         {
21175e09c8c3SJim Ingham             result.AppendError ("Invalid target. No existing target or breakpoints.");
21185e09c8c3SJim Ingham             result.SetStatus (eReturnStatusFailed);
21195e09c8c3SJim Ingham             return false;
21205e09c8c3SJim Ingham         }
21215e09c8c3SJim Ingham 
21225e09c8c3SJim Ingham         Mutex::Locker locker;
21235e09c8c3SJim Ingham         target->GetBreakpointList().GetListMutex(locker);
21245e09c8c3SJim Ingham 
21255e09c8c3SJim Ingham         const BreakpointList &breakpoints = target->GetBreakpointList();
21265e09c8c3SJim Ingham 
21275e09c8c3SJim Ingham         size_t num_breakpoints = breakpoints.GetSize();
21285e09c8c3SJim Ingham         if (num_breakpoints == 0)
21295e09c8c3SJim Ingham         {
21305e09c8c3SJim Ingham             result.SetError("No breakpoints, cannot delete names.");
21315e09c8c3SJim Ingham             result.SetStatus (eReturnStatusFailed);
21325e09c8c3SJim Ingham             return false;
21335e09c8c3SJim Ingham         }
21345e09c8c3SJim Ingham 
21355e09c8c3SJim Ingham         // Particular breakpoint selected; disable that breakpoint.
21365e09c8c3SJim Ingham         BreakpointIDList valid_bp_ids;
21375e09c8c3SJim Ingham         CommandObjectMultiwordBreakpoint::VerifyBreakpointIDs (command, target, result, &valid_bp_ids);
21385e09c8c3SJim Ingham 
21395e09c8c3SJim Ingham         if (result.Succeeded())
21405e09c8c3SJim Ingham         {
21415e09c8c3SJim Ingham             if (valid_bp_ids.GetSize() == 0)
21425e09c8c3SJim Ingham             {
21435e09c8c3SJim Ingham                 result.SetError("No breakpoints specified, cannot delete names.");
21445e09c8c3SJim Ingham                 result.SetStatus (eReturnStatusFailed);
21455e09c8c3SJim Ingham                 return false;
21465e09c8c3SJim Ingham             }
21475e09c8c3SJim Ingham             size_t num_valid_ids = valid_bp_ids.GetSize();
21485e09c8c3SJim Ingham             for (size_t index = 0; index < num_valid_ids; index++)
21495e09c8c3SJim Ingham             {
21505e09c8c3SJim Ingham                 lldb::break_id_t bp_id = valid_bp_ids.GetBreakpointIDAtIndex(index).GetBreakpointID();
21515e09c8c3SJim Ingham                 BreakpointSP bp_sp = breakpoints.FindBreakpointByID(bp_id);
21525e09c8c3SJim Ingham                 bp_sp->RemoveName(m_name_options.m_name.GetCurrentValue());
21535e09c8c3SJim Ingham             }
21545e09c8c3SJim Ingham         }
21555e09c8c3SJim Ingham 
21565e09c8c3SJim Ingham         return true;
21575e09c8c3SJim Ingham     }
21585e09c8c3SJim Ingham 
21595e09c8c3SJim Ingham private:
21605e09c8c3SJim Ingham     BreakpointNameOptionGroup m_name_options;
21615e09c8c3SJim Ingham     OptionGroupOptions m_option_group;
21625e09c8c3SJim Ingham };
21635e09c8c3SJim Ingham 
21645e09c8c3SJim Ingham class CommandObjectBreakpointNameList : public CommandObjectParsed
21655e09c8c3SJim Ingham {
21665e09c8c3SJim Ingham public:
21675e09c8c3SJim Ingham     CommandObjectBreakpointNameList (CommandInterpreter &interpreter) :
21685e09c8c3SJim Ingham         CommandObjectParsed (interpreter,
21695e09c8c3SJim Ingham                              "list",
21705e09c8c3SJim Ingham                              "List either the names for a breakpoint or the breakpoints for a given name.",
21715e09c8c3SJim Ingham                              "breakpoint name list <command-options>"),
21725e09c8c3SJim Ingham         m_name_options(),
21735e09c8c3SJim Ingham         m_option_group(interpreter)
21745e09c8c3SJim Ingham     {
21755e09c8c3SJim Ingham         m_option_group.Append (&m_name_options);
21765e09c8c3SJim Ingham         m_option_group.Finalize();
21775e09c8c3SJim Ingham     }
21785e09c8c3SJim Ingham 
21795e09c8c3SJim Ingham     virtual
21805e09c8c3SJim Ingham     ~CommandObjectBreakpointNameList () {}
21815e09c8c3SJim Ingham 
21825e09c8c3SJim Ingham   Options *
21835e09c8c3SJim Ingham   GetOptions ()
21845e09c8c3SJim Ingham   {
21855e09c8c3SJim Ingham     return &m_option_group;
21865e09c8c3SJim Ingham   }
21875e09c8c3SJim Ingham 
21885e09c8c3SJim Ingham protected:
21895e09c8c3SJim Ingham protected:
21905e09c8c3SJim Ingham     virtual bool
21915e09c8c3SJim Ingham     DoExecute (Args& command, CommandReturnObject &result)
21925e09c8c3SJim Ingham     {
21935e09c8c3SJim Ingham         Target *target = GetSelectedOrDummyTarget(m_name_options.m_use_dummy.GetCurrentValue());
21945e09c8c3SJim Ingham 
21955e09c8c3SJim Ingham         if (target == NULL)
21965e09c8c3SJim Ingham         {
21975e09c8c3SJim Ingham             result.AppendError ("Invalid target. No existing target or breakpoints.");
21985e09c8c3SJim Ingham             result.SetStatus (eReturnStatusFailed);
21995e09c8c3SJim Ingham             return false;
22005e09c8c3SJim Ingham         }
22015e09c8c3SJim Ingham 
22025e09c8c3SJim Ingham         if (m_name_options.m_name.OptionWasSet())
22035e09c8c3SJim Ingham         {
22045e09c8c3SJim Ingham             const char *name = m_name_options.m_name.GetCurrentValue();
22055e09c8c3SJim Ingham             Mutex::Locker locker;
22065e09c8c3SJim Ingham             target->GetBreakpointList().GetListMutex(locker);
22075e09c8c3SJim Ingham 
22085e09c8c3SJim Ingham             BreakpointList &breakpoints = target->GetBreakpointList();
22095e09c8c3SJim Ingham             for (BreakpointSP bp_sp : breakpoints.Breakpoints())
22105e09c8c3SJim Ingham             {
22115e09c8c3SJim Ingham                 if (bp_sp->MatchesName(name))
22125e09c8c3SJim Ingham                 {
22135e09c8c3SJim Ingham                     StreamString s;
22145e09c8c3SJim Ingham                     bp_sp->GetDescription(&s, eDescriptionLevelBrief);
22155e09c8c3SJim Ingham                     s.EOL();
22165e09c8c3SJim Ingham                     result.AppendMessage(s.GetData());
22175e09c8c3SJim Ingham                 }
22185e09c8c3SJim Ingham             }
22195e09c8c3SJim Ingham 
22205e09c8c3SJim Ingham         }
22215e09c8c3SJim Ingham         else if (m_name_options.m_breakpoint.OptionWasSet())
22225e09c8c3SJim Ingham         {
22235e09c8c3SJim Ingham             BreakpointSP bp_sp = target->GetBreakpointList().FindBreakpointByID(m_name_options.m_breakpoint.GetCurrentValue());
22245e09c8c3SJim Ingham             if (bp_sp)
22255e09c8c3SJim Ingham             {
22265e09c8c3SJim Ingham                 std::vector<std::string> names;
22275e09c8c3SJim Ingham                 bp_sp->GetNames (names);
22285e09c8c3SJim Ingham                 result.AppendMessage ("Names:");
22295e09c8c3SJim Ingham                 for (auto name : names)
22305e09c8c3SJim Ingham                     result.AppendMessageWithFormat ("    %s\n", name.c_str());
22315e09c8c3SJim Ingham             }
22325e09c8c3SJim Ingham             else
22335e09c8c3SJim Ingham             {
22345e09c8c3SJim Ingham                 result.AppendErrorWithFormat ("Could not find breakpoint %" PRId64 ".\n",
22355e09c8c3SJim Ingham                                            m_name_options.m_breakpoint.GetCurrentValue());
22365e09c8c3SJim Ingham                 result.SetStatus (eReturnStatusFailed);
22375e09c8c3SJim Ingham                 return false;
22385e09c8c3SJim Ingham             }
22395e09c8c3SJim Ingham         }
22405e09c8c3SJim Ingham         else
22415e09c8c3SJim Ingham         {
22425e09c8c3SJim Ingham             result.SetError ("Must specify -N or -B option to list.");
22435e09c8c3SJim Ingham             result.SetStatus (eReturnStatusFailed);
22445e09c8c3SJim Ingham             return false;
22455e09c8c3SJim Ingham         }
22465e09c8c3SJim Ingham         return true;
22475e09c8c3SJim Ingham     }
22485e09c8c3SJim Ingham 
22495e09c8c3SJim Ingham private:
22505e09c8c3SJim Ingham     BreakpointNameOptionGroup m_name_options;
22515e09c8c3SJim Ingham     OptionGroupOptions m_option_group;
22525e09c8c3SJim Ingham };
22535e09c8c3SJim Ingham 
22545e09c8c3SJim Ingham //-------------------------------------------------------------------------
22555e09c8c3SJim Ingham // CommandObjectMultiwordBreakpoint
22565e09c8c3SJim Ingham //-------------------------------------------------------------------------
22575e09c8c3SJim Ingham class CommandObjectBreakpointName : public CommandObjectMultiword
22585e09c8c3SJim Ingham {
22595e09c8c3SJim Ingham public:
22605e09c8c3SJim Ingham     CommandObjectBreakpointName (CommandInterpreter &interpreter) :
22615e09c8c3SJim Ingham         CommandObjectMultiword(interpreter,
22625e09c8c3SJim Ingham                                 "name",
22635e09c8c3SJim Ingham                                 "A set of commands to manage name tags for breakpoints",
22645e09c8c3SJim Ingham                                 "breakpoint name <command> [<command-options>]")
22655e09c8c3SJim Ingham     {
22665e09c8c3SJim Ingham         CommandObjectSP add_command_object (new CommandObjectBreakpointNameAdd (interpreter));
22675e09c8c3SJim Ingham         CommandObjectSP delete_command_object (new CommandObjectBreakpointNameDelete (interpreter));
22685e09c8c3SJim Ingham         CommandObjectSP list_command_object (new CommandObjectBreakpointNameList (interpreter));
22695e09c8c3SJim Ingham 
22705e09c8c3SJim Ingham         LoadSubCommand ("add", add_command_object);
22715e09c8c3SJim Ingham         LoadSubCommand ("delete", delete_command_object);
22725e09c8c3SJim Ingham         LoadSubCommand ("list", list_command_object);
22735e09c8c3SJim Ingham 
22745e09c8c3SJim Ingham     }
22755e09c8c3SJim Ingham 
22765e09c8c3SJim Ingham     virtual
22775e09c8c3SJim Ingham     ~CommandObjectBreakpointName ()
22785e09c8c3SJim Ingham     {
22795e09c8c3SJim Ingham     }
22805e09c8c3SJim Ingham 
22815e09c8c3SJim Ingham };
22825e09c8c3SJim Ingham 
22835e09c8c3SJim Ingham 
22845e09c8c3SJim Ingham //-------------------------------------------------------------------------
228530fdc8d8SChris Lattner // CommandObjectMultiwordBreakpoint
228630fdc8d8SChris Lattner //-------------------------------------------------------------------------
2287ae1c4cf5SJim Ingham #pragma mark MultiwordBreakpoint
228830fdc8d8SChris Lattner 
22896611103cSGreg Clayton CommandObjectMultiwordBreakpoint::CommandObjectMultiwordBreakpoint (CommandInterpreter &interpreter) :
2290a7015092SGreg Clayton     CommandObjectMultiword (interpreter,
2291a7015092SGreg Clayton                             "breakpoint",
229246fbc60fSJim Ingham                             "A set of commands for operating on breakpoints. Also see _regexp-break.",
229330fdc8d8SChris Lattner                             "breakpoint <command> [<command-options>]")
229430fdc8d8SChris Lattner {
2295a7015092SGreg Clayton     CommandObjectSP list_command_object (new CommandObjectBreakpointList (interpreter));
2296a7015092SGreg Clayton     CommandObjectSP enable_command_object (new CommandObjectBreakpointEnable (interpreter));
2297a7015092SGreg Clayton     CommandObjectSP disable_command_object (new CommandObjectBreakpointDisable (interpreter));
2298b7234e40SJohnny Chen     CommandObjectSP clear_command_object (new CommandObjectBreakpointClear (interpreter));
2299b7234e40SJohnny Chen     CommandObjectSP delete_command_object (new CommandObjectBreakpointDelete (interpreter));
2300a7015092SGreg Clayton     CommandObjectSP set_command_object (new CommandObjectBreakpointSet (interpreter));
230130fdc8d8SChris Lattner     CommandObjectSP command_command_object (new CommandObjectBreakpointCommand (interpreter));
2302a7015092SGreg Clayton     CommandObjectSP modify_command_object (new CommandObjectBreakpointModify(interpreter));
23035e09c8c3SJim Ingham     CommandObjectSP name_command_object (new CommandObjectBreakpointName(interpreter));
230430fdc8d8SChris Lattner 
2305b7234e40SJohnny Chen     list_command_object->SetCommandName ("breakpoint list");
230630fdc8d8SChris Lattner     enable_command_object->SetCommandName("breakpoint enable");
230730fdc8d8SChris Lattner     disable_command_object->SetCommandName("breakpoint disable");
2308b7234e40SJohnny Chen     clear_command_object->SetCommandName("breakpoint clear");
2309b7234e40SJohnny Chen     delete_command_object->SetCommandName("breakpoint delete");
2310ae1c4cf5SJim Ingham     set_command_object->SetCommandName("breakpoint set");
2311b7234e40SJohnny Chen     command_command_object->SetCommandName ("breakpoint command");
2312b7234e40SJohnny Chen     modify_command_object->SetCommandName ("breakpoint modify");
23135e09c8c3SJim Ingham     name_command_object->SetCommandName ("breakpoint name");
231430fdc8d8SChris Lattner 
231523f59509SGreg Clayton     LoadSubCommand ("list",       list_command_object);
231623f59509SGreg Clayton     LoadSubCommand ("enable",     enable_command_object);
231723f59509SGreg Clayton     LoadSubCommand ("disable",    disable_command_object);
231823f59509SGreg Clayton     LoadSubCommand ("clear",      clear_command_object);
231923f59509SGreg Clayton     LoadSubCommand ("delete",     delete_command_object);
232023f59509SGreg Clayton     LoadSubCommand ("set",        set_command_object);
232123f59509SGreg Clayton     LoadSubCommand ("command",    command_command_object);
232223f59509SGreg Clayton     LoadSubCommand ("modify",     modify_command_object);
23235e09c8c3SJim Ingham     LoadSubCommand ("name",       name_command_object);
232430fdc8d8SChris Lattner }
232530fdc8d8SChris Lattner 
232630fdc8d8SChris Lattner CommandObjectMultiwordBreakpoint::~CommandObjectMultiwordBreakpoint ()
232730fdc8d8SChris Lattner {
232830fdc8d8SChris Lattner }
232930fdc8d8SChris Lattner 
233030fdc8d8SChris Lattner void
23315e09c8c3SJim Ingham CommandObjectMultiwordBreakpoint::VerifyIDs (Args &args,
23325e09c8c3SJim Ingham                                              Target *target,
23335e09c8c3SJim Ingham                                              bool allow_locations,
23345e09c8c3SJim Ingham                                              CommandReturnObject &result,
233530fdc8d8SChris Lattner                                              BreakpointIDList *valid_ids)
233630fdc8d8SChris Lattner {
233730fdc8d8SChris Lattner     // args can be strings representing 1). integers (for breakpoint ids)
233830fdc8d8SChris Lattner     //                                  2). the full breakpoint & location canonical representation
233930fdc8d8SChris Lattner     //                                  3). the word "to" or a hyphen, representing a range (in which case there
234030fdc8d8SChris Lattner     //                                      had *better* be an entry both before & after of one of the first two types.
23415e09c8c3SJim Ingham     //                                  4). A breakpoint name
234236f3b369SJim Ingham     // If args is empty, we will use the last created breakpoint (if there is one.)
234330fdc8d8SChris Lattner 
234430fdc8d8SChris Lattner     Args temp_args;
234530fdc8d8SChris Lattner 
234636f3b369SJim Ingham     if (args.GetArgumentCount() == 0)
234736f3b369SJim Ingham     {
23484d122c40SGreg Clayton         if (target->GetLastCreatedBreakpoint())
234936f3b369SJim Ingham         {
235036f3b369SJim Ingham             valid_ids->AddBreakpointID (BreakpointID(target->GetLastCreatedBreakpoint()->GetID(), LLDB_INVALID_BREAK_ID));
235136f3b369SJim Ingham             result.SetStatus (eReturnStatusSuccessFinishNoResult);
235236f3b369SJim Ingham         }
235336f3b369SJim Ingham         else
235436f3b369SJim Ingham         {
235536f3b369SJim Ingham             result.AppendError("No breakpoint specified and no last created breakpoint.");
235636f3b369SJim Ingham             result.SetStatus (eReturnStatusFailed);
235736f3b369SJim Ingham         }
235836f3b369SJim Ingham         return;
235936f3b369SJim Ingham     }
236036f3b369SJim Ingham 
236130fdc8d8SChris Lattner     // Create a new Args variable to use; copy any non-breakpoint-id-ranges stuff directly from the old ARGS to
236230fdc8d8SChris Lattner     // the new TEMP_ARGS.  Do not copy breakpoint id range strings over; instead generate a list of strings for
236330fdc8d8SChris Lattner     // all the breakpoint ids in the range, and shove all of those breakpoint id strings into TEMP_ARGS.
236430fdc8d8SChris Lattner 
23655e09c8c3SJim Ingham     BreakpointIDList::FindAndReplaceIDRanges (args, target, allow_locations, result, temp_args);
236630fdc8d8SChris Lattner 
236730fdc8d8SChris Lattner     // NOW, convert the list of breakpoint id strings in TEMP_ARGS into an actual BreakpointIDList:
236830fdc8d8SChris Lattner 
2369c982c768SGreg Clayton     valid_ids->InsertStringArray (temp_args.GetConstArgumentVector(), temp_args.GetArgumentCount(), result);
237030fdc8d8SChris Lattner 
237130fdc8d8SChris Lattner     // At this point,  all of the breakpoint ids that the user passed in have been converted to breakpoint IDs
237230fdc8d8SChris Lattner     // and put into valid_ids.
237330fdc8d8SChris Lattner 
237430fdc8d8SChris Lattner     if (result.Succeeded())
237530fdc8d8SChris Lattner     {
237630fdc8d8SChris Lattner         // Now that we've converted everything from args into a list of breakpoint ids, go through our tentative list
237730fdc8d8SChris Lattner         // of breakpoint id's and verify that they correspond to valid/currently set breakpoints.
237830fdc8d8SChris Lattner 
2379c982c768SGreg Clayton         const size_t count = valid_ids->GetSize();
2380c982c768SGreg Clayton         for (size_t i = 0; i < count; ++i)
238130fdc8d8SChris Lattner         {
238230fdc8d8SChris Lattner             BreakpointID cur_bp_id = valid_ids->GetBreakpointIDAtIndex (i);
238330fdc8d8SChris Lattner             Breakpoint *breakpoint = target->GetBreakpointByID (cur_bp_id.GetBreakpointID()).get();
238430fdc8d8SChris Lattner             if (breakpoint != NULL)
238530fdc8d8SChris Lattner             {
2386c7bece56SGreg Clayton                 const size_t num_locations = breakpoint->GetNumLocations();
23873985c8c6SSaleem Abdulrasool                 if (static_cast<size_t>(cur_bp_id.GetLocationID()) > num_locations)
238830fdc8d8SChris Lattner                 {
238930fdc8d8SChris Lattner                     StreamString id_str;
2390c982c768SGreg Clayton                     BreakpointID::GetCanonicalReference (&id_str,
2391c982c768SGreg Clayton                                                          cur_bp_id.GetBreakpointID(),
239230fdc8d8SChris Lattner                                                          cur_bp_id.GetLocationID());
2393c982c768SGreg Clayton                     i = valid_ids->GetSize() + 1;
239430fdc8d8SChris Lattner                     result.AppendErrorWithFormat ("'%s' is not a currently valid breakpoint/location id.\n",
239530fdc8d8SChris Lattner                                                  id_str.GetData());
239630fdc8d8SChris Lattner                     result.SetStatus (eReturnStatusFailed);
239730fdc8d8SChris Lattner                 }
239830fdc8d8SChris Lattner             }
239930fdc8d8SChris Lattner             else
240030fdc8d8SChris Lattner             {
2401c982c768SGreg Clayton                 i = valid_ids->GetSize() + 1;
240230fdc8d8SChris Lattner                 result.AppendErrorWithFormat ("'%d' is not a currently valid breakpoint id.\n", cur_bp_id.GetBreakpointID());
240330fdc8d8SChris Lattner                 result.SetStatus (eReturnStatusFailed);
240430fdc8d8SChris Lattner             }
240530fdc8d8SChris Lattner         }
240630fdc8d8SChris Lattner     }
240730fdc8d8SChris Lattner }
2408