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"
23*5e09c8c3SJim Ingham #include "lldb/Interpreter/OptionValueString.h"
24*5e09c8c3SJim 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 
245*5e09c8c3SJim Ingham                 case 'N':
246*5e09c8c3SJim Ingham                     if (BreakpointID::StringIsBreakpointName(option_arg, error))
247*5e09c8c3SJim Ingham                         m_breakpoint_names.push_back (option_arg);
248*5e09c8c3SJim Ingham                     else
249*5e09c8c3SJim Ingham                         error.SetErrorStringWithFormat(error.AsCString());
250*5e09c8c3SJim Ingham                     break;
251*5e09c8c3SJim Ingham 
252ca36cd16SJim Ingham                 case 'o':
253ca36cd16SJim Ingham                     m_one_shot = true;
254ca36cd16SJim Ingham                     break;
255ca36cd16SJim Ingham 
256ca36cd16SJim Ingham                 case 'p':
257ca36cd16SJim Ingham                     m_source_text_regexp.assign (option_arg);
258ca36cd16SJim Ingham                     break;
259ca36cd16SJim Ingham 
260ca36cd16SJim Ingham                 case 'q':
261ca36cd16SJim Ingham                     m_queue_name.assign (option_arg);
262ca36cd16SJim Ingham                     break;
263ca36cd16SJim Ingham 
264ca36cd16SJim Ingham                 case 'r':
265ca36cd16SJim Ingham                     m_func_regexp.assign (option_arg);
266ca36cd16SJim Ingham                     break;
267ca36cd16SJim Ingham 
268ca36cd16SJim Ingham                 case 's':
269ca36cd16SJim Ingham                 {
270ca36cd16SJim Ingham                     m_modules.AppendIfUnique (FileSpec (option_arg, false));
271ca36cd16SJim Ingham                     break;
272ca36cd16SJim Ingham                 }
273ca36cd16SJim Ingham 
274ca36cd16SJim Ingham                 case 'S':
275ca36cd16SJim Ingham                     m_func_names.push_back (option_arg);
276ca36cd16SJim Ingham                     m_func_name_type_mask |= eFunctionNameTypeSelector;
277ca36cd16SJim Ingham                     break;
278ca36cd16SJim Ingham 
279ca36cd16SJim Ingham                 case 't' :
280ca36cd16SJim Ingham                 {
281ca36cd16SJim Ingham                     m_thread_id = Args::StringToUInt64(option_arg, LLDB_INVALID_THREAD_ID, 0);
282ca36cd16SJim Ingham                     if (m_thread_id == LLDB_INVALID_THREAD_ID)
283ca36cd16SJim Ingham                        error.SetErrorStringWithFormat ("invalid thread id string '%s'", option_arg);
284ca36cd16SJim Ingham                 }
285ca36cd16SJim Ingham                 break;
286ca36cd16SJim Ingham 
287ca36cd16SJim Ingham                 case 'T':
288ca36cd16SJim Ingham                     m_thread_name.assign (option_arg);
289ca36cd16SJim Ingham                     break;
290ca36cd16SJim Ingham 
291ca36cd16SJim Ingham                 case 'w':
292ca36cd16SJim Ingham                 {
293ca36cd16SJim Ingham                     bool success;
294ca36cd16SJim Ingham                     m_throw_bp = Args::StringToBoolean (option_arg, true, &success);
295ca36cd16SJim Ingham                     if (!success)
296ca36cd16SJim Ingham                         error.SetErrorStringWithFormat ("Invalid boolean value for on-throw option: '%s'", option_arg);
297ca36cd16SJim Ingham                 }
298ca36cd16SJim Ingham                 break;
299ca36cd16SJim Ingham 
300ca36cd16SJim Ingham                 case 'x':
301ca36cd16SJim Ingham                 {
302ca36cd16SJim Ingham                     m_thread_index = Args::StringToUInt32(option_arg, UINT32_MAX, 0);
303ca36cd16SJim Ingham                     if (m_thread_id == UINT32_MAX)
304ca36cd16SJim Ingham                        error.SetErrorStringWithFormat ("invalid thread index string '%s'", option_arg);
305ca36cd16SJim Ingham 
306ca36cd16SJim Ingham                 }
307ca36cd16SJim Ingham                 break;
308ca36cd16SJim Ingham 
30930fdc8d8SChris Lattner                 default:
31086edbf41SGreg Clayton                     error.SetErrorStringWithFormat ("unrecognized option '%c'", short_option);
31130fdc8d8SChris Lattner                     break;
31230fdc8d8SChris Lattner             }
31330fdc8d8SChris Lattner 
31430fdc8d8SChris Lattner             return error;
31530fdc8d8SChris Lattner         }
31630fdc8d8SChris Lattner         void
3175a988416SJim Ingham         OptionParsingStarting ()
31830fdc8d8SChris Lattner         {
3197d49c9c8SJohnny Chen             m_condition.clear();
32087df91b8SJim Ingham             m_filenames.Clear();
32130fdc8d8SChris Lattner             m_line_num = 0;
32230fdc8d8SChris Lattner             m_column = 0;
323fab10e89SJim Ingham             m_func_names.clear();
3241f746071SGreg Clayton             m_func_name_type_mask = eFunctionNameTypeNone;
32530fdc8d8SChris Lattner             m_func_regexp.clear();
3261f746071SGreg Clayton             m_source_text_regexp.clear();
32787df91b8SJim Ingham             m_modules.Clear();
3281f746071SGreg Clayton             m_load_addr = LLDB_INVALID_ADDRESS;
329c982c768SGreg Clayton             m_ignore_count = 0;
3301b54c88cSJim Ingham             m_thread_id = LLDB_INVALID_THREAD_ID;
331c982c768SGreg Clayton             m_thread_index = UINT32_MAX;
3321b54c88cSJim Ingham             m_thread_name.clear();
3331b54c88cSJim Ingham             m_queue_name.clear();
334fab10e89SJim Ingham             m_catch_bp = false;
335fab10e89SJim Ingham             m_throw_bp = true;
336eb023e75SGreg Clayton             m_hardware = false;
3371f746071SGreg Clayton             m_language = eLanguageTypeUnknown;
338a8558b62SJim Ingham             m_skip_prologue = eLazyBoolCalculate;
339ca36cd16SJim Ingham             m_one_shot = false;
34033df7cd3SJim Ingham             m_use_dummy = false;
341*5e09c8c3SJim Ingham             m_breakpoint_names.clear();
34230fdc8d8SChris Lattner         }
34330fdc8d8SChris Lattner 
3445a988416SJim Ingham         const OptionDefinition*
3455a988416SJim Ingham         GetDefinitions ()
34630fdc8d8SChris Lattner         {
3475a988416SJim Ingham             return g_option_table;
34830fdc8d8SChris Lattner         }
34930fdc8d8SChris Lattner 
3505a988416SJim Ingham         // Options table: Required for subclasses of Options.
35130fdc8d8SChris Lattner 
3525a988416SJim Ingham         static OptionDefinition g_option_table[];
35330fdc8d8SChris Lattner 
3545a988416SJim Ingham         // Instance variables to hold the values for command options.
355969795f1SJim Ingham 
3565a988416SJim Ingham         std::string m_condition;
3575a988416SJim Ingham         FileSpecList m_filenames;
3585a988416SJim Ingham         uint32_t m_line_num;
3595a988416SJim Ingham         uint32_t m_column;
3605a988416SJim Ingham         std::vector<std::string> m_func_names;
361*5e09c8c3SJim Ingham         std::vector<std::string> m_breakpoint_names;
3625a988416SJim Ingham         uint32_t m_func_name_type_mask;
3635a988416SJim Ingham         std::string m_func_regexp;
3645a988416SJim Ingham         std::string m_source_text_regexp;
3655a988416SJim Ingham         FileSpecList m_modules;
3665a988416SJim Ingham         lldb::addr_t m_load_addr;
3675a988416SJim Ingham         uint32_t m_ignore_count;
3685a988416SJim Ingham         lldb::tid_t m_thread_id;
3695a988416SJim Ingham         uint32_t m_thread_index;
3705a988416SJim Ingham         std::string m_thread_name;
3715a988416SJim Ingham         std::string m_queue_name;
3725a988416SJim Ingham         bool m_catch_bp;
3735a988416SJim Ingham         bool m_throw_bp;
374eb023e75SGreg Clayton         bool m_hardware; // Request to use hardware breakpoints
3755a988416SJim Ingham         lldb::LanguageType m_language;
3765a988416SJim Ingham         LazyBool m_skip_prologue;
377ca36cd16SJim Ingham         bool m_one_shot;
37833df7cd3SJim Ingham         bool m_use_dummy;
3795a988416SJim Ingham 
3805a988416SJim Ingham     };
3815a988416SJim Ingham 
3825a988416SJim Ingham protected:
3835a988416SJim Ingham     virtual bool
3845a988416SJim Ingham     DoExecute (Args& command,
3855a988416SJim Ingham               CommandReturnObject &result)
38630fdc8d8SChris Lattner     {
38733df7cd3SJim Ingham         Target *target = GetSelectedOrDummyTarget(m_options.m_use_dummy);
38833df7cd3SJim Ingham 
389893c932aSJim Ingham         if (target == nullptr)
39030fdc8d8SChris Lattner         {
391effe5c95SGreg Clayton             result.AppendError ("Invalid target.  Must set target before setting breakpoints (see 'target create' command).");
39230fdc8d8SChris Lattner             result.SetStatus (eReturnStatusFailed);
39330fdc8d8SChris Lattner             return false;
39430fdc8d8SChris Lattner         }
39530fdc8d8SChris Lattner 
39630fdc8d8SChris Lattner         // The following are the various types of breakpoints that could be set:
39730fdc8d8SChris Lattner         //   1).  -f -l -p  [-s -g]   (setting breakpoint by source location)
39830fdc8d8SChris Lattner         //   2).  -a  [-s -g]         (setting breakpoint by address)
39930fdc8d8SChris Lattner         //   3).  -n  [-s -g]         (setting breakpoint by function name)
40030fdc8d8SChris Lattner         //   4).  -r  [-s -g]         (setting breakpoint by function name regular expression)
401969795f1SJim Ingham         //   5).  -p -f               (setting a breakpoint by comparing a reg-exp to source text)
402fab10e89SJim Ingham         //   6).  -E [-w -h]          (setting a breakpoint for exceptions for a given language.)
40330fdc8d8SChris Lattner 
40430fdc8d8SChris Lattner         BreakpointSetType break_type = eSetTypeInvalid;
40530fdc8d8SChris Lattner 
40630fdc8d8SChris Lattner         if (m_options.m_line_num != 0)
40730fdc8d8SChris Lattner             break_type = eSetTypeFileAndLine;
40830fdc8d8SChris Lattner         else if (m_options.m_load_addr != LLDB_INVALID_ADDRESS)
40930fdc8d8SChris Lattner             break_type = eSetTypeAddress;
410fab10e89SJim Ingham         else if (!m_options.m_func_names.empty())
41130fdc8d8SChris Lattner             break_type = eSetTypeFunctionName;
41230fdc8d8SChris Lattner         else if  (!m_options.m_func_regexp.empty())
41330fdc8d8SChris Lattner             break_type = eSetTypeFunctionRegexp;
414969795f1SJim Ingham         else if (!m_options.m_source_text_regexp.empty())
415969795f1SJim Ingham             break_type = eSetTypeSourceRegexp;
416fab10e89SJim Ingham         else if (m_options.m_language != eLanguageTypeUnknown)
417fab10e89SJim Ingham             break_type = eSetTypeException;
41830fdc8d8SChris Lattner 
41930fdc8d8SChris Lattner         Breakpoint *bp = NULL;
420274060b6SGreg Clayton         FileSpec module_spec;
421a8558b62SJim Ingham         const bool internal = false;
422a8558b62SJim Ingham 
42330fdc8d8SChris Lattner         switch (break_type)
42430fdc8d8SChris Lattner         {
42530fdc8d8SChris Lattner             case eSetTypeFileAndLine: // Breakpoint by source position
42630fdc8d8SChris Lattner                 {
42730fdc8d8SChris Lattner                     FileSpec file;
428c7bece56SGreg Clayton                     const size_t num_files = m_options.m_filenames.GetSize();
42987df91b8SJim Ingham                     if (num_files == 0)
43087df91b8SJim Ingham                     {
43187df91b8SJim Ingham                         if (!GetDefaultFile (target, file, result))
43287df91b8SJim Ingham                         {
43387df91b8SJim Ingham                             result.AppendError("No file supplied and no default file available.");
43487df91b8SJim Ingham                             result.SetStatus (eReturnStatusFailed);
43587df91b8SJim Ingham                             return false;
43687df91b8SJim Ingham                         }
43787df91b8SJim Ingham                     }
43887df91b8SJim Ingham                     else if (num_files > 1)
43987df91b8SJim Ingham                     {
44087df91b8SJim Ingham                         result.AppendError("Only one file at a time is allowed for file and line breakpoints.");
44187df91b8SJim Ingham                         result.SetStatus (eReturnStatusFailed);
44287df91b8SJim Ingham                         return false;
44387df91b8SJim Ingham                     }
44487df91b8SJim Ingham                     else
44587df91b8SJim Ingham                         file = m_options.m_filenames.GetFileSpecAtIndex(0);
44630fdc8d8SChris Lattner 
4471f746071SGreg Clayton                     // Only check for inline functions if
4481f746071SGreg Clayton                     LazyBool check_inlines = eLazyBoolCalculate;
4491f746071SGreg Clayton 
45087df91b8SJim Ingham                     bp = target->CreateBreakpoint (&(m_options.m_modules),
45130fdc8d8SChris Lattner                                                    file,
45230fdc8d8SChris Lattner                                                    m_options.m_line_num,
4531f746071SGreg Clayton                                                    check_inlines,
454a8558b62SJim Ingham                                                    m_options.m_skip_prologue,
455eb023e75SGreg Clayton                                                    internal,
456eb023e75SGreg Clayton                                                    m_options.m_hardware).get();
45730fdc8d8SChris Lattner                 }
45830fdc8d8SChris Lattner                 break;
4596eee5aa0SGreg Clayton 
46030fdc8d8SChris Lattner             case eSetTypeAddress: // Breakpoint by address
461eb023e75SGreg Clayton                 bp = target->CreateBreakpoint (m_options.m_load_addr,
462eb023e75SGreg Clayton                                                internal,
463eb023e75SGreg Clayton                                                m_options.m_hardware).get();
46430fdc8d8SChris Lattner                 break;
4650c5cd90dSGreg Clayton 
46630fdc8d8SChris Lattner             case eSetTypeFunctionName: // Breakpoint by function name
4670c5cd90dSGreg Clayton                 {
4680c5cd90dSGreg Clayton                     uint32_t name_type_mask = m_options.m_func_name_type_mask;
4690c5cd90dSGreg Clayton 
4700c5cd90dSGreg Clayton                     if (name_type_mask == 0)
471e02b8504SGreg Clayton                         name_type_mask = eFunctionNameTypeAuto;
4720c5cd90dSGreg Clayton 
47387df91b8SJim Ingham                     bp = target->CreateBreakpoint (&(m_options.m_modules),
47487df91b8SJim Ingham                                                    &(m_options.m_filenames),
475fab10e89SJim Ingham                                                    m_options.m_func_names,
476274060b6SGreg Clayton                                                    name_type_mask,
477a8558b62SJim Ingham                                                    m_options.m_skip_prologue,
478eb023e75SGreg Clayton                                                    internal,
479eb023e75SGreg Clayton                                                    m_options.m_hardware).get();
4800c5cd90dSGreg Clayton                 }
48130fdc8d8SChris Lattner                 break;
4820c5cd90dSGreg Clayton 
48330fdc8d8SChris Lattner             case eSetTypeFunctionRegexp: // Breakpoint by regular expression function name
48430fdc8d8SChris Lattner                 {
48530fdc8d8SChris Lattner                     RegularExpression regexp(m_options.m_func_regexp.c_str());
486969795f1SJim Ingham                     if (!regexp.IsValid())
48730fdc8d8SChris Lattner                     {
488969795f1SJim Ingham                         char err_str[1024];
489969795f1SJim Ingham                         regexp.GetErrorAsCString(err_str, sizeof(err_str));
490969795f1SJim Ingham                         result.AppendErrorWithFormat("Function name regular expression could not be compiled: \"%s\"",
491969795f1SJim Ingham                                                      err_str);
49230fdc8d8SChris Lattner                         result.SetStatus (eReturnStatusFailed);
493969795f1SJim Ingham                         return false;
49430fdc8d8SChris Lattner                     }
49587df91b8SJim Ingham 
496a8558b62SJim Ingham                     bp = target->CreateFuncRegexBreakpoint (&(m_options.m_modules),
497a8558b62SJim Ingham                                                             &(m_options.m_filenames),
498a8558b62SJim Ingham                                                             regexp,
499a8558b62SJim Ingham                                                             m_options.m_skip_prologue,
500eb023e75SGreg Clayton                                                             internal,
501eb023e75SGreg Clayton                                                             m_options.m_hardware).get();
50230fdc8d8SChris Lattner                 }
50330fdc8d8SChris Lattner                 break;
504969795f1SJim Ingham             case eSetTypeSourceRegexp: // Breakpoint by regexp on source text.
505969795f1SJim Ingham                 {
506c7bece56SGreg Clayton                     const size_t num_files = m_options.m_filenames.GetSize();
50787df91b8SJim Ingham 
50887df91b8SJim Ingham                     if (num_files == 0)
50987df91b8SJim Ingham                     {
510969795f1SJim Ingham                         FileSpec file;
51187df91b8SJim Ingham                         if (!GetDefaultFile (target, file, result))
51287df91b8SJim Ingham                         {
51387df91b8SJim Ingham                             result.AppendError ("No files provided and could not find default file.");
51487df91b8SJim Ingham                             result.SetStatus (eReturnStatusFailed);
51587df91b8SJim Ingham                             return false;
51687df91b8SJim Ingham                         }
51787df91b8SJim Ingham                         else
51887df91b8SJim Ingham                         {
51987df91b8SJim Ingham                             m_options.m_filenames.Append (file);
52087df91b8SJim Ingham                         }
52187df91b8SJim Ingham                     }
5220c5cd90dSGreg Clayton 
523969795f1SJim Ingham                     RegularExpression regexp(m_options.m_source_text_regexp.c_str());
524969795f1SJim Ingham                     if (!regexp.IsValid())
525969795f1SJim Ingham                     {
526969795f1SJim Ingham                         char err_str[1024];
527969795f1SJim Ingham                         regexp.GetErrorAsCString(err_str, sizeof(err_str));
528969795f1SJim Ingham                         result.AppendErrorWithFormat("Source text regular expression could not be compiled: \"%s\"",
529969795f1SJim Ingham                                                      err_str);
530969795f1SJim Ingham                         result.SetStatus (eReturnStatusFailed);
531969795f1SJim Ingham                         return false;
532969795f1SJim Ingham                     }
533eb023e75SGreg Clayton                     bp = target->CreateSourceRegexBreakpoint (&(m_options.m_modules),
534eb023e75SGreg Clayton                                                               &(m_options.m_filenames),
535eb023e75SGreg Clayton                                                               regexp,
536eb023e75SGreg Clayton                                                               internal,
537eb023e75SGreg Clayton                                                               m_options.m_hardware).get();
538969795f1SJim Ingham                 }
539969795f1SJim Ingham                 break;
540fab10e89SJim Ingham             case eSetTypeException:
541fab10e89SJim Ingham                 {
542eb023e75SGreg Clayton                     bp = target->CreateExceptionBreakpoint (m_options.m_language,
543eb023e75SGreg Clayton                                                             m_options.m_catch_bp,
544eb023e75SGreg Clayton                                                             m_options.m_throw_bp,
545eb023e75SGreg Clayton                                                             m_options.m_hardware).get();
546fab10e89SJim Ingham                 }
547fab10e89SJim Ingham                 break;
54830fdc8d8SChris Lattner             default:
54930fdc8d8SChris Lattner                 break;
55030fdc8d8SChris Lattner         }
55130fdc8d8SChris Lattner 
5521b54c88cSJim Ingham         // Now set the various options that were passed in:
5531b54c88cSJim Ingham         if (bp)
5541b54c88cSJim Ingham         {
5551b54c88cSJim Ingham             if (m_options.m_thread_id != LLDB_INVALID_THREAD_ID)
5561b54c88cSJim Ingham                 bp->SetThreadID (m_options.m_thread_id);
5571b54c88cSJim Ingham 
558c982c768SGreg Clayton             if (m_options.m_thread_index != UINT32_MAX)
5591b54c88cSJim Ingham                 bp->GetOptions()->GetThreadSpec()->SetIndex(m_options.m_thread_index);
5601b54c88cSJim Ingham 
5611b54c88cSJim Ingham             if (!m_options.m_thread_name.empty())
5621b54c88cSJim Ingham                 bp->GetOptions()->GetThreadSpec()->SetName(m_options.m_thread_name.c_str());
5631b54c88cSJim Ingham 
5641b54c88cSJim Ingham             if (!m_options.m_queue_name.empty())
5651b54c88cSJim Ingham                 bp->GetOptions()->GetThreadSpec()->SetQueueName(m_options.m_queue_name.c_str());
5661b54c88cSJim Ingham 
567c982c768SGreg Clayton             if (m_options.m_ignore_count != 0)
5681b54c88cSJim Ingham                 bp->GetOptions()->SetIgnoreCount(m_options.m_ignore_count);
5697d49c9c8SJohnny Chen 
5707d49c9c8SJohnny Chen             if (!m_options.m_condition.empty())
5717d49c9c8SJohnny Chen                 bp->GetOptions()->SetCondition(m_options.m_condition.c_str());
572ca36cd16SJim Ingham 
573*5e09c8c3SJim Ingham             if (!m_options.m_breakpoint_names.empty())
574*5e09c8c3SJim Ingham             {
575*5e09c8c3SJim Ingham                 Error error;  // We don't need to check the error here, since the option parser checked it...
576*5e09c8c3SJim Ingham                 for (auto name : m_options.m_breakpoint_names)
577*5e09c8c3SJim Ingham                     bp->AddName(name.c_str(), error);
578*5e09c8c3SJim Ingham             }
579*5e09c8c3SJim Ingham 
580ca36cd16SJim Ingham             bp->SetOneShot (m_options.m_one_shot);
5811b54c88cSJim Ingham         }
5821b54c88cSJim Ingham 
583969795f1SJim Ingham         if (bp)
58430fdc8d8SChris Lattner         {
58585e8b814SJim Ingham             Stream &output_stream = result.GetOutputStream();
5861391cc7dSJim Ingham             const bool show_locations = false;
5871391cc7dSJim Ingham             bp->GetDescription(&output_stream, lldb::eDescriptionLevelInitial, show_locations);
588fab10e89SJim Ingham             // Don't print out this warning for exception breakpoints.  They can get set before the target
589fab10e89SJim Ingham             // is set, but we won't know how to actually set the breakpoint till we run.
590fab10e89SJim Ingham             if (bp->GetNumLocations() == 0 && break_type != eSetTypeException)
591be484f41SCaroline Tice                 output_stream.Printf ("WARNING:  Unable to resolve breakpoint to any actual locations.\n");
59230fdc8d8SChris Lattner             result.SetStatus (eReturnStatusSuccessFinishResult);
59330fdc8d8SChris Lattner         }
59430fdc8d8SChris Lattner         else if (!bp)
59530fdc8d8SChris Lattner         {
59630fdc8d8SChris Lattner             result.AppendError ("Breakpoint creation failed: No breakpoint created.");
59730fdc8d8SChris Lattner             result.SetStatus (eReturnStatusFailed);
59830fdc8d8SChris Lattner         }
59930fdc8d8SChris Lattner 
60030fdc8d8SChris Lattner         return result.Succeeded();
60130fdc8d8SChris Lattner     }
60230fdc8d8SChris Lattner 
6035a988416SJim Ingham private:
6045a988416SJim Ingham     bool
6055a988416SJim Ingham     GetDefaultFile (Target *target, FileSpec &file, CommandReturnObject &result)
6065a988416SJim Ingham     {
6075a988416SJim Ingham         uint32_t default_line;
6085a988416SJim Ingham         // First use the Source Manager's default file.
6095a988416SJim Ingham         // Then use the current stack frame's file.
6105a988416SJim Ingham         if (!target->GetSourceManager().GetDefaultFileAndLine(file, default_line))
6115a988416SJim Ingham         {
612b57e4a1bSJason Molenda             StackFrame *cur_frame = m_exe_ctx.GetFramePtr();
6135a988416SJim Ingham             if (cur_frame == NULL)
6145a988416SJim Ingham             {
6155a988416SJim Ingham                 result.AppendError ("No selected frame to use to find the default file.");
6165a988416SJim Ingham                 result.SetStatus (eReturnStatusFailed);
6175a988416SJim Ingham                 return false;
6185a988416SJim Ingham             }
6195a988416SJim Ingham             else if (!cur_frame->HasDebugInformation())
6205a988416SJim Ingham             {
6215a988416SJim Ingham                 result.AppendError ("Cannot use the selected frame to find the default file, it has no debug info.");
6225a988416SJim Ingham                 result.SetStatus (eReturnStatusFailed);
6235a988416SJim Ingham                 return false;
6245a988416SJim Ingham             }
6255a988416SJim Ingham             else
6265a988416SJim Ingham             {
6275a988416SJim Ingham                 const SymbolContext &sc = cur_frame->GetSymbolContext (eSymbolContextLineEntry);
6285a988416SJim Ingham                 if (sc.line_entry.file)
6295a988416SJim Ingham                 {
6305a988416SJim Ingham                     file = sc.line_entry.file;
6315a988416SJim Ingham                 }
6325a988416SJim Ingham                 else
6335a988416SJim Ingham                 {
6345a988416SJim Ingham                     result.AppendError ("Can't find the file for the selected frame to use as the default file.");
6355a988416SJim Ingham                     result.SetStatus (eReturnStatusFailed);
6365a988416SJim Ingham                     return false;
6375a988416SJim Ingham                 }
6385a988416SJim Ingham             }
6395a988416SJim Ingham         }
6405a988416SJim Ingham         return true;
6415a988416SJim Ingham     }
6425a988416SJim Ingham 
6435a988416SJim Ingham     CommandOptions m_options;
6445a988416SJim Ingham };
6455a988416SJim Ingham // If an additional option set beyond LLDB_OPTION_SET_10 is added, make sure to
6465a988416SJim Ingham // update the numbers passed to LLDB_OPT_SET_FROM_TO(...) appropriately.
6475a988416SJim Ingham #define LLDB_OPT_FILE ( LLDB_OPT_SET_FROM_TO(1, 9) & ~LLDB_OPT_SET_2 )
6485a988416SJim Ingham #define LLDB_OPT_NOT_10 ( LLDB_OPT_SET_FROM_TO(1, 10) & ~LLDB_OPT_SET_10 )
6495a988416SJim Ingham #define LLDB_OPT_SKIP_PROLOGUE ( LLDB_OPT_SET_1 | LLDB_OPT_SET_FROM_TO(3,8) )
6505a988416SJim Ingham 
6515a988416SJim Ingham OptionDefinition
6525a988416SJim Ingham CommandObjectBreakpointSet::CommandOptions::g_option_table[] =
6535a988416SJim Ingham {
654d37221dcSZachary Turner     { LLDB_OPT_NOT_10, false, "shlib", 's', OptionParser::eRequiredArgument, NULL, NULL, CommandCompletions::eModuleCompletion, eArgTypeShlibName,
6555a988416SJim Ingham         "Set the breakpoint only in this shared library.  "
6565a988416SJim Ingham         "Can repeat this option multiple times to specify multiple shared libraries."},
6575a988416SJim Ingham 
658d37221dcSZachary Turner     { LLDB_OPT_SET_ALL, false, "ignore-count", 'i', OptionParser::eRequiredArgument,   NULL, NULL, 0, eArgTypeCount,
6595a988416SJim Ingham         "Set the number of times this breakpoint is skipped before stopping." },
6605a988416SJim Ingham 
661d37221dcSZachary Turner     { LLDB_OPT_SET_ALL, false, "one-shot", 'o', OptionParser::eNoArgument,   NULL, NULL, 0, eArgTypeNone,
662b2b256afSJim Ingham         "The breakpoint is deleted the first time it causes a stop." },
663ca36cd16SJim Ingham 
664d37221dcSZachary Turner     { LLDB_OPT_SET_ALL, false, "condition",    'c', OptionParser::eRequiredArgument, NULL, NULL, 0, eArgTypeExpression,
6655a988416SJim Ingham         "The breakpoint stops only if this condition expression evaluates to true."},
6665a988416SJim Ingham 
667d37221dcSZachary Turner     { LLDB_OPT_SET_ALL, false, "thread-index", 'x', OptionParser::eRequiredArgument, NULL, NULL, 0, eArgTypeThreadIndex,
668a89be91fSJim Ingham         "The breakpoint stops only for the thread whose indeX matches this argument."},
6695a988416SJim Ingham 
670d37221dcSZachary Turner     { LLDB_OPT_SET_ALL, false, "thread-id", 't', OptionParser::eRequiredArgument, NULL, NULL, 0, eArgTypeThreadID,
6715a988416SJim Ingham         "The breakpoint stops only for the thread whose TID matches this argument."},
6725a988416SJim Ingham 
673d37221dcSZachary Turner     { LLDB_OPT_SET_ALL, false, "thread-name", 'T', OptionParser::eRequiredArgument, NULL, NULL, 0, eArgTypeThreadName,
6745a988416SJim Ingham         "The breakpoint stops only for the thread whose thread name matches this argument."},
6755a988416SJim Ingham 
676d37221dcSZachary Turner     { LLDB_OPT_SET_ALL, false, "hardware", 'H', OptionParser::eNoArgument, NULL, NULL, 0, eArgTypeNone,
677eb023e75SGreg Clayton         "Require the breakpoint to use hardware breakpoints."},
678eb023e75SGreg Clayton 
679d37221dcSZachary Turner     { LLDB_OPT_SET_ALL, false, "queue-name", 'q', OptionParser::eRequiredArgument, NULL, NULL, 0, eArgTypeQueueName,
6805a988416SJim Ingham         "The breakpoint stops only for threads in the queue whose name is given by this argument."},
6815a988416SJim Ingham 
682d37221dcSZachary Turner     { LLDB_OPT_FILE, false, "file", 'f', OptionParser::eRequiredArgument, NULL, NULL, CommandCompletions::eSourceFileCompletion, eArgTypeFilename,
683289aca64SJim Ingham         "Specifies the source file in which to set this breakpoint.  "
684289aca64SJim Ingham         "Note, by default lldb only looks for files that are #included if they use the standard include file extensions.  "
6856394479eSJim Ingham         "To set breakpoints on .c/.cpp/.m/.mm files that are #included, set target.inline-breakpoint-strategy"
686289aca64SJim Ingham         " to \"always\"."},
6875a988416SJim Ingham 
688d37221dcSZachary Turner     { LLDB_OPT_SET_1, true, "line", 'l', OptionParser::eRequiredArgument, NULL, NULL, 0, eArgTypeLineNum,
6895a988416SJim Ingham         "Specifies the line number on which to set this breakpoint."},
6905a988416SJim Ingham 
6915a988416SJim Ingham     // Comment out this option for the moment, as we don't actually use it, but will in the future.
6925a988416SJim Ingham     // This way users won't see it, but the infrastructure is left in place.
693e2607b50SVirgile Bello     //    { 0, false, "column",     'C', OptionParser::eRequiredArgument, NULL, "<column>",
6945a988416SJim Ingham     //    "Set the breakpoint by source location at this particular column."},
6955a988416SJim Ingham 
696d37221dcSZachary Turner     { LLDB_OPT_SET_2, true, "address", 'a', OptionParser::eRequiredArgument, NULL, NULL, 0, eArgTypeAddressOrExpression,
6975a988416SJim Ingham         "Set the breakpoint by address, at the specified address."},
6985a988416SJim Ingham 
699d37221dcSZachary Turner     { LLDB_OPT_SET_3, true, "name", 'n', OptionParser::eRequiredArgument, NULL, NULL, CommandCompletions::eSymbolCompletion, eArgTypeFunctionName,
700551262d7SJim Ingham         "Set the breakpoint by function name.  Can be repeated multiple times to make one breakpoint for multiple names" },
7015a988416SJim Ingham 
702d37221dcSZachary Turner     { LLDB_OPT_SET_4, true, "fullname", 'F', OptionParser::eRequiredArgument, NULL, NULL, CommandCompletions::eSymbolCompletion, eArgTypeFullName,
7035a988416SJim Ingham         "Set the breakpoint by fully qualified function names. For C++ this means namespaces and all arguments, and "
7045a988416SJim Ingham         "for Objective C this means a full function prototype with class and selector.   "
7055a988416SJim Ingham         "Can be repeated multiple times to make one breakpoint for multiple names." },
7065a988416SJim Ingham 
707d37221dcSZachary Turner     { LLDB_OPT_SET_5, true, "selector", 'S', OptionParser::eRequiredArgument, NULL, NULL, 0, eArgTypeSelector,
7085a988416SJim Ingham         "Set the breakpoint by ObjC selector name. Can be repeated multiple times to make one breakpoint for multiple Selectors." },
7095a988416SJim Ingham 
710d37221dcSZachary Turner     { LLDB_OPT_SET_6, true, "method", 'M', OptionParser::eRequiredArgument, NULL, NULL, 0, eArgTypeMethod,
7115a988416SJim Ingham         "Set the breakpoint by C++ method names.  Can be repeated multiple times to make one breakpoint for multiple methods." },
7125a988416SJim Ingham 
713d37221dcSZachary Turner     { LLDB_OPT_SET_7, true, "func-regex", 'r', OptionParser::eRequiredArgument, NULL, NULL, 0, eArgTypeRegularExpression,
7145a988416SJim Ingham         "Set the breakpoint by function name, evaluating a regular-expression to find the function name(s)." },
7155a988416SJim Ingham 
716d37221dcSZachary Turner     { LLDB_OPT_SET_8, true, "basename", 'b', OptionParser::eRequiredArgument, NULL, NULL, CommandCompletions::eSymbolCompletion, eArgTypeFunctionName,
7175a988416SJim Ingham         "Set the breakpoint by function basename (C++ namespaces and arguments will be ignored). "
7185a988416SJim Ingham         "Can be repeated multiple times to make one breakpoint for multiple symbols." },
7195a988416SJim Ingham 
720d37221dcSZachary Turner     { LLDB_OPT_SET_9, true, "source-pattern-regexp", 'p', OptionParser::eRequiredArgument, NULL, NULL, 0, eArgTypeRegularExpression,
721e96ade8bSJim Ingham         "Set the breakpoint by specifying a regular expression which is matched against the source text in a source file or files "
722e96ade8bSJim Ingham         "specified with the -f option.  The -f option can be specified more than once.  "
723e96ade8bSJim Ingham         "If no source files are specified, uses the current \"default source file\"" },
7245a988416SJim Ingham 
725d37221dcSZachary Turner     { LLDB_OPT_SET_10, true, "language-exception", 'E', OptionParser::eRequiredArgument, NULL, NULL, 0, eArgTypeLanguage,
7265a988416SJim Ingham         "Set the breakpoint on exceptions thrown by the specified language (without options, on throw but not catch.)" },
7275a988416SJim Ingham 
728d37221dcSZachary Turner     { LLDB_OPT_SET_10, false, "on-throw", 'w', OptionParser::eRequiredArgument, NULL, NULL, 0, eArgTypeBoolean,
7295a988416SJim Ingham         "Set the breakpoint on exception throW." },
7305a988416SJim Ingham 
731d37221dcSZachary Turner     { LLDB_OPT_SET_10, false, "on-catch", 'h', OptionParser::eRequiredArgument, NULL, NULL, 0, eArgTypeBoolean,
7325a988416SJim Ingham         "Set the breakpoint on exception catcH." },
7335a988416SJim Ingham 
734d37221dcSZachary Turner     { LLDB_OPT_SKIP_PROLOGUE, false, "skip-prologue", 'K', OptionParser::eRequiredArgument, NULL, NULL, 0, eArgTypeBoolean,
7355a988416SJim Ingham         "sKip the prologue if the breakpoint is at the beginning of a function.  If not set the target.skip-prologue setting is used." },
7365a988416SJim Ingham 
73733df7cd3SJim Ingham     { LLDB_OPT_SET_ALL, false, "dummy-breakpoints", 'D', OptionParser::eNoArgument, NULL, NULL, 0, eArgTypeNone,
73833df7cd3SJim Ingham         "Sets Dummy breakpoints - i.e. breakpoints set before a file is provided, which prime new targets."},
73933df7cd3SJim Ingham 
740*5e09c8c3SJim Ingham     { LLDB_OPT_SET_ALL, false, "breakpoint-name", 'N', OptionParser::eRequiredArgument, NULL, NULL, 0, eArgTypeBreakpointName,
741*5e09c8c3SJim Ingham         "Adds this to the list of names for this breakopint."},
742*5e09c8c3SJim Ingham 
743d37221dcSZachary Turner     { 0, false, NULL, 0, 0, NULL, NULL, 0, eArgTypeNone, NULL }
7445a988416SJim Ingham };
7455a988416SJim Ingham 
7465a988416SJim Ingham //-------------------------------------------------------------------------
7475a988416SJim Ingham // CommandObjectBreakpointModify
7485a988416SJim Ingham //-------------------------------------------------------------------------
7495a988416SJim Ingham #pragma mark Modify
7505a988416SJim Ingham 
7515a988416SJim Ingham class CommandObjectBreakpointModify : public CommandObjectParsed
7525a988416SJim Ingham {
7535a988416SJim Ingham public:
7545a988416SJim Ingham 
7555a988416SJim Ingham     CommandObjectBreakpointModify (CommandInterpreter &interpreter) :
7565a988416SJim Ingham         CommandObjectParsed (interpreter,
7575a988416SJim Ingham                              "breakpoint modify",
7585a988416SJim Ingham                              "Modify the options on a breakpoint or set of breakpoints in the executable.  "
7595a988416SJim Ingham                              "If no breakpoint is specified, acts on the last created breakpoint.  "
7605a988416SJim Ingham                              "With the exception of -e, -d and -i, passing an empty argument clears the modification.",
7615a988416SJim Ingham                              NULL),
7625a988416SJim Ingham         m_options (interpreter)
7635a988416SJim Ingham     {
7645a988416SJim Ingham         CommandArgumentEntry arg;
7655a988416SJim Ingham         CommandObject::AddIDsArgumentData(arg, eArgTypeBreakpointID, eArgTypeBreakpointIDRange);
7665a988416SJim Ingham         // Add the entry for the first argument for this command to the object's arguments vector.
7675a988416SJim Ingham         m_arguments.push_back (arg);
7685a988416SJim Ingham     }
7695a988416SJim Ingham 
7705a988416SJim Ingham 
7715a988416SJim Ingham     virtual
7725a988416SJim Ingham     ~CommandObjectBreakpointModify () {}
7735a988416SJim Ingham 
7745a988416SJim Ingham     virtual Options *
7755a988416SJim Ingham     GetOptions ()
7765a988416SJim Ingham     {
7775a988416SJim Ingham         return &m_options;
7785a988416SJim Ingham     }
7795a988416SJim Ingham 
7805a988416SJim Ingham     class CommandOptions : public Options
7815a988416SJim Ingham     {
7825a988416SJim Ingham     public:
7835a988416SJim Ingham 
7845a988416SJim Ingham         CommandOptions (CommandInterpreter &interpreter) :
7855a988416SJim Ingham             Options (interpreter),
7865a988416SJim Ingham             m_ignore_count (0),
7875a988416SJim Ingham             m_thread_id(LLDB_INVALID_THREAD_ID),
7885a988416SJim Ingham             m_thread_id_passed(false),
7895a988416SJim Ingham             m_thread_index (UINT32_MAX),
7905a988416SJim Ingham             m_thread_index_passed(false),
7915a988416SJim Ingham             m_thread_name(),
7925a988416SJim Ingham             m_queue_name(),
7935a988416SJim Ingham             m_condition (),
794ca36cd16SJim Ingham             m_one_shot (false),
7955a988416SJim Ingham             m_enable_passed (false),
7965a988416SJim Ingham             m_enable_value (false),
7975a988416SJim Ingham             m_name_passed (false),
7985a988416SJim Ingham             m_queue_passed (false),
799ca36cd16SJim Ingham             m_condition_passed (false),
80033df7cd3SJim Ingham             m_one_shot_passed (false),
80133df7cd3SJim Ingham             m_use_dummy (false)
8025a988416SJim Ingham         {
8035a988416SJim Ingham         }
8045a988416SJim Ingham 
8055a988416SJim Ingham         virtual
8065a988416SJim Ingham         ~CommandOptions () {}
8075a988416SJim Ingham 
8085a988416SJim Ingham         virtual Error
8095a988416SJim Ingham         SetOptionValue (uint32_t option_idx, const char *option_arg)
8105a988416SJim Ingham         {
8115a988416SJim Ingham             Error error;
8123bcdfc0eSGreg Clayton             const int short_option = m_getopt_table[option_idx].val;
8135a988416SJim Ingham 
8145a988416SJim Ingham             switch (short_option)
8155a988416SJim Ingham             {
8165a988416SJim Ingham                 case 'c':
8175a988416SJim Ingham                     if (option_arg != NULL)
8185a988416SJim Ingham                         m_condition.assign (option_arg);
8195a988416SJim Ingham                     else
8205a988416SJim Ingham                         m_condition.clear();
8215a988416SJim Ingham                     m_condition_passed = true;
8225a988416SJim Ingham                     break;
8235a988416SJim Ingham                 case 'd':
8245a988416SJim Ingham                     m_enable_passed = true;
8255a988416SJim Ingham                     m_enable_value = false;
8265a988416SJim Ingham                     break;
82733df7cd3SJim Ingham                 case 'D':
82833df7cd3SJim Ingham                     m_use_dummy = true;
82933df7cd3SJim Ingham                     break;
8305a988416SJim Ingham                 case 'e':
8315a988416SJim Ingham                     m_enable_passed = true;
8325a988416SJim Ingham                     m_enable_value = true;
8335a988416SJim Ingham                     break;
8345a988416SJim Ingham                 case 'i':
8355a988416SJim Ingham                 {
8365a988416SJim Ingham                     m_ignore_count = Args::StringToUInt32(option_arg, UINT32_MAX, 0);
8375a988416SJim Ingham                     if (m_ignore_count == UINT32_MAX)
8385a988416SJim Ingham                        error.SetErrorStringWithFormat ("invalid ignore count '%s'", option_arg);
8395a988416SJim Ingham                 }
8405a988416SJim Ingham                 break;
841ca36cd16SJim Ingham                 case 'o':
842ca36cd16SJim Ingham                 {
843ca36cd16SJim Ingham                     bool value, success;
844ca36cd16SJim Ingham                     value = Args::StringToBoolean(option_arg, false, &success);
845ca36cd16SJim Ingham                     if (success)
846ca36cd16SJim Ingham                     {
847ca36cd16SJim Ingham                         m_one_shot_passed = true;
848ca36cd16SJim Ingham                         m_one_shot = value;
849ca36cd16SJim Ingham                     }
850ca36cd16SJim Ingham                     else
851ca36cd16SJim Ingham                         error.SetErrorStringWithFormat("invalid boolean value '%s' passed for -o option", option_arg);
852ca36cd16SJim Ingham                 }
853ca36cd16SJim Ingham                 break;
8545a988416SJim Ingham                 case 't' :
8555a988416SJim Ingham                 {
8565a988416SJim Ingham                     if (option_arg[0] == '\0')
8575a988416SJim Ingham                     {
8585a988416SJim Ingham                         m_thread_id = LLDB_INVALID_THREAD_ID;
8595a988416SJim Ingham                         m_thread_id_passed = true;
8605a988416SJim Ingham                     }
8615a988416SJim Ingham                     else
8625a988416SJim Ingham                     {
8635a988416SJim Ingham                         m_thread_id = Args::StringToUInt64(option_arg, LLDB_INVALID_THREAD_ID, 0);
8645a988416SJim Ingham                         if (m_thread_id == LLDB_INVALID_THREAD_ID)
8655a988416SJim Ingham                            error.SetErrorStringWithFormat ("invalid thread id string '%s'", option_arg);
8665a988416SJim Ingham                         else
8675a988416SJim Ingham                             m_thread_id_passed = true;
8685a988416SJim Ingham                     }
8695a988416SJim Ingham                 }
8705a988416SJim Ingham                 break;
8715a988416SJim Ingham                 case 'T':
8725a988416SJim Ingham                     if (option_arg != NULL)
8735a988416SJim Ingham                         m_thread_name.assign (option_arg);
8745a988416SJim Ingham                     else
8755a988416SJim Ingham                         m_thread_name.clear();
8765a988416SJim Ingham                     m_name_passed = true;
8775a988416SJim Ingham                     break;
8785a988416SJim Ingham                 case 'q':
8795a988416SJim Ingham                     if (option_arg != NULL)
8805a988416SJim Ingham                         m_queue_name.assign (option_arg);
8815a988416SJim Ingham                     else
8825a988416SJim Ingham                         m_queue_name.clear();
8835a988416SJim Ingham                     m_queue_passed = true;
8845a988416SJim Ingham                     break;
8855a988416SJim Ingham                 case 'x':
8865a988416SJim Ingham                 {
8875a988416SJim Ingham                     if (option_arg[0] == '\n')
8885a988416SJim Ingham                     {
8895a988416SJim Ingham                         m_thread_index = UINT32_MAX;
8905a988416SJim Ingham                         m_thread_index_passed = true;
8915a988416SJim Ingham                     }
8925a988416SJim Ingham                     else
8935a988416SJim Ingham                     {
8945a988416SJim Ingham                         m_thread_index = Args::StringToUInt32 (option_arg, UINT32_MAX, 0);
8955a988416SJim Ingham                         if (m_thread_id == UINT32_MAX)
8965a988416SJim Ingham                            error.SetErrorStringWithFormat ("invalid thread index string '%s'", option_arg);
8975a988416SJim Ingham                         else
8985a988416SJim Ingham                             m_thread_index_passed = true;
8995a988416SJim Ingham                     }
9005a988416SJim Ingham                 }
9015a988416SJim Ingham                 break;
9025a988416SJim Ingham                 default:
9035a988416SJim Ingham                     error.SetErrorStringWithFormat ("unrecognized option '%c'", short_option);
9045a988416SJim Ingham                     break;
9055a988416SJim Ingham             }
9065a988416SJim Ingham 
9075a988416SJim Ingham             return error;
9085a988416SJim Ingham         }
9095a988416SJim Ingham         void
9105a988416SJim Ingham         OptionParsingStarting ()
9115a988416SJim Ingham         {
9125a988416SJim Ingham             m_ignore_count = 0;
9135a988416SJim Ingham             m_thread_id = LLDB_INVALID_THREAD_ID;
9145a988416SJim Ingham             m_thread_id_passed = false;
9155a988416SJim Ingham             m_thread_index = UINT32_MAX;
9165a988416SJim Ingham             m_thread_index_passed = false;
9175a988416SJim Ingham             m_thread_name.clear();
9185a988416SJim Ingham             m_queue_name.clear();
9195a988416SJim Ingham             m_condition.clear();
920ca36cd16SJim Ingham             m_one_shot = false;
9215a988416SJim Ingham             m_enable_passed = false;
9225a988416SJim Ingham             m_queue_passed = false;
9235a988416SJim Ingham             m_name_passed = false;
9245a988416SJim Ingham             m_condition_passed = false;
925ca36cd16SJim Ingham             m_one_shot_passed = false;
92633df7cd3SJim Ingham             m_use_dummy = false;
9275a988416SJim Ingham         }
9285a988416SJim Ingham 
9295a988416SJim Ingham         const OptionDefinition*
9305a988416SJim Ingham         GetDefinitions ()
9315a988416SJim Ingham         {
9325a988416SJim Ingham             return g_option_table;
9335a988416SJim Ingham         }
9345a988416SJim Ingham 
9355a988416SJim Ingham 
9365a988416SJim Ingham         // Options table: Required for subclasses of Options.
9375a988416SJim Ingham 
9385a988416SJim Ingham         static OptionDefinition g_option_table[];
9395a988416SJim Ingham 
9405a988416SJim Ingham         // Instance variables to hold the values for command options.
9415a988416SJim Ingham 
9425a988416SJim Ingham         uint32_t m_ignore_count;
9435a988416SJim Ingham         lldb::tid_t m_thread_id;
9445a988416SJim Ingham         bool m_thread_id_passed;
9455a988416SJim Ingham         uint32_t m_thread_index;
9465a988416SJim Ingham         bool m_thread_index_passed;
9475a988416SJim Ingham         std::string m_thread_name;
9485a988416SJim Ingham         std::string m_queue_name;
9495a988416SJim Ingham         std::string m_condition;
950ca36cd16SJim Ingham         bool m_one_shot;
9515a988416SJim Ingham         bool m_enable_passed;
9525a988416SJim Ingham         bool m_enable_value;
9535a988416SJim Ingham         bool m_name_passed;
9545a988416SJim Ingham         bool m_queue_passed;
9555a988416SJim Ingham         bool m_condition_passed;
956ca36cd16SJim Ingham         bool m_one_shot_passed;
95733df7cd3SJim Ingham         bool m_use_dummy;
9585a988416SJim Ingham 
9595a988416SJim Ingham     };
9605a988416SJim Ingham 
9615a988416SJim Ingham protected:
9625a988416SJim Ingham     virtual bool
9635a988416SJim Ingham     DoExecute (Args& command, CommandReturnObject &result)
9645a988416SJim Ingham     {
96533df7cd3SJim Ingham         Target *target = GetSelectedOrDummyTarget(m_options.m_use_dummy);
9665a988416SJim Ingham         if (target == NULL)
9675a988416SJim Ingham         {
9685a988416SJim Ingham             result.AppendError ("Invalid target.  No existing target or breakpoints.");
9695a988416SJim Ingham             result.SetStatus (eReturnStatusFailed);
9705a988416SJim Ingham             return false;
9715a988416SJim Ingham         }
9725a988416SJim Ingham 
9735a988416SJim Ingham         Mutex::Locker locker;
9745a988416SJim Ingham         target->GetBreakpointList().GetListMutex(locker);
9755a988416SJim Ingham 
9765a988416SJim Ingham         BreakpointIDList valid_bp_ids;
9775a988416SJim Ingham 
978*5e09c8c3SJim Ingham         CommandObjectMultiwordBreakpoint::VerifyBreakpointOrLocationIDs (command, target, result, &valid_bp_ids);
9795a988416SJim Ingham 
9805a988416SJim Ingham         if (result.Succeeded())
9815a988416SJim Ingham         {
9825a988416SJim Ingham             const size_t count = valid_bp_ids.GetSize();
9835a988416SJim Ingham             for (size_t i = 0; i < count; ++i)
9845a988416SJim Ingham             {
9855a988416SJim Ingham                 BreakpointID cur_bp_id = valid_bp_ids.GetBreakpointIDAtIndex (i);
9865a988416SJim Ingham 
9875a988416SJim Ingham                 if (cur_bp_id.GetBreakpointID() != LLDB_INVALID_BREAK_ID)
9885a988416SJim Ingham                 {
9895a988416SJim Ingham                     Breakpoint *bp = target->GetBreakpointByID (cur_bp_id.GetBreakpointID()).get();
9905a988416SJim Ingham                     if (cur_bp_id.GetLocationID() != LLDB_INVALID_BREAK_ID)
9915a988416SJim Ingham                     {
9925a988416SJim Ingham                         BreakpointLocation *location = bp->FindLocationByID (cur_bp_id.GetLocationID()).get();
9935a988416SJim Ingham                         if (location)
9945a988416SJim Ingham                         {
9955a988416SJim Ingham                             if (m_options.m_thread_id_passed)
9965a988416SJim Ingham                                 location->SetThreadID (m_options.m_thread_id);
9975a988416SJim Ingham 
9985a988416SJim Ingham                             if (m_options.m_thread_index_passed)
9995a988416SJim Ingham                                 location->SetThreadIndex(m_options.m_thread_index);
10005a988416SJim Ingham 
10015a988416SJim Ingham                             if (m_options.m_name_passed)
10025a988416SJim Ingham                                 location->SetThreadName(m_options.m_thread_name.c_str());
10035a988416SJim Ingham 
10045a988416SJim Ingham                             if (m_options.m_queue_passed)
10055a988416SJim Ingham                                 location->SetQueueName(m_options.m_queue_name.c_str());
10065a988416SJim Ingham 
10075a988416SJim Ingham                             if (m_options.m_ignore_count != 0)
10085a988416SJim Ingham                                 location->SetIgnoreCount(m_options.m_ignore_count);
10095a988416SJim Ingham 
10105a988416SJim Ingham                             if (m_options.m_enable_passed)
10115a988416SJim Ingham                                 location->SetEnabled (m_options.m_enable_value);
10125a988416SJim Ingham 
10135a988416SJim Ingham                             if (m_options.m_condition_passed)
10145a988416SJim Ingham                                 location->SetCondition (m_options.m_condition.c_str());
10155a988416SJim Ingham                         }
10165a988416SJim Ingham                     }
10175a988416SJim Ingham                     else
10185a988416SJim Ingham                     {
10195a988416SJim Ingham                         if (m_options.m_thread_id_passed)
10205a988416SJim Ingham                             bp->SetThreadID (m_options.m_thread_id);
10215a988416SJim Ingham 
10225a988416SJim Ingham                         if (m_options.m_thread_index_passed)
10235a988416SJim Ingham                             bp->SetThreadIndex(m_options.m_thread_index);
10245a988416SJim Ingham 
10255a988416SJim Ingham                         if (m_options.m_name_passed)
10265a988416SJim Ingham                             bp->SetThreadName(m_options.m_thread_name.c_str());
10275a988416SJim Ingham 
10285a988416SJim Ingham                         if (m_options.m_queue_passed)
10295a988416SJim Ingham                             bp->SetQueueName(m_options.m_queue_name.c_str());
10305a988416SJim Ingham 
10315a988416SJim Ingham                         if (m_options.m_ignore_count != 0)
10325a988416SJim Ingham                             bp->SetIgnoreCount(m_options.m_ignore_count);
10335a988416SJim Ingham 
10345a988416SJim Ingham                         if (m_options.m_enable_passed)
10355a988416SJim Ingham                             bp->SetEnabled (m_options.m_enable_value);
10365a988416SJim Ingham 
10375a988416SJim Ingham                         if (m_options.m_condition_passed)
10385a988416SJim Ingham                             bp->SetCondition (m_options.m_condition.c_str());
10395a988416SJim Ingham                     }
10405a988416SJim Ingham                 }
10415a988416SJim Ingham             }
10425a988416SJim Ingham         }
10435a988416SJim Ingham 
10445a988416SJim Ingham         return result.Succeeded();
10455a988416SJim Ingham     }
10465a988416SJim Ingham 
10475a988416SJim Ingham private:
10485a988416SJim Ingham     CommandOptions m_options;
10495a988416SJim Ingham };
10505a988416SJim Ingham 
10515a988416SJim Ingham #pragma mark Modify::CommandOptions
10525a988416SJim Ingham OptionDefinition
10535a988416SJim Ingham CommandObjectBreakpointModify::CommandOptions::g_option_table[] =
10545a988416SJim Ingham {
1055d37221dcSZachary 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." },
1056d37221dcSZachary 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." },
1057d37221dcSZachary 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."},
1058d37221dcSZachary 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."},
1059d37221dcSZachary 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."},
1060d37221dcSZachary 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."},
1061d37221dcSZachary 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."},
1062d37221dcSZachary Turner { LLDB_OPT_SET_1,   false, "enable",       'e', OptionParser::eNoArgument,       NULL, NULL, 0, eArgTypeNone, "Enable the breakpoint."},
1063d37221dcSZachary Turner { LLDB_OPT_SET_2,   false, "disable",      'd', OptionParser::eNoArgument,       NULL, NULL, 0, eArgTypeNone, "Disable the breakpoint."},
106433df7cd3SJim 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."},
106533df7cd3SJim Ingham 
1066d37221dcSZachary Turner { 0,                false, NULL,            0 , 0,                 NULL, NULL, 0, eArgTypeNone, NULL }
10675a988416SJim Ingham };
10685a988416SJim Ingham 
10695a988416SJim Ingham //-------------------------------------------------------------------------
10705a988416SJim Ingham // CommandObjectBreakpointEnable
10715a988416SJim Ingham //-------------------------------------------------------------------------
10725a988416SJim Ingham #pragma mark Enable
10735a988416SJim Ingham 
10745a988416SJim Ingham class CommandObjectBreakpointEnable : public CommandObjectParsed
10755a988416SJim Ingham {
10765a988416SJim Ingham public:
10775a988416SJim Ingham     CommandObjectBreakpointEnable (CommandInterpreter &interpreter) :
10785a988416SJim Ingham         CommandObjectParsed (interpreter,
10795a988416SJim Ingham                              "enable",
10805a988416SJim Ingham                              "Enable the specified disabled breakpoint(s). If no breakpoints are specified, enable all of them.",
10815a988416SJim Ingham                              NULL)
10825a988416SJim Ingham     {
10835a988416SJim Ingham         CommandArgumentEntry arg;
10845a988416SJim Ingham         CommandObject::AddIDsArgumentData(arg, eArgTypeBreakpointID, eArgTypeBreakpointIDRange);
10855a988416SJim Ingham         // Add the entry for the first argument for this command to the object's arguments vector.
10865a988416SJim Ingham         m_arguments.push_back (arg);
10875a988416SJim Ingham     }
10885a988416SJim Ingham 
10895a988416SJim Ingham 
10905a988416SJim Ingham     virtual
10915a988416SJim Ingham     ~CommandObjectBreakpointEnable () {}
10925a988416SJim Ingham 
10935a988416SJim Ingham protected:
10945a988416SJim Ingham     virtual bool
10955a988416SJim Ingham     DoExecute (Args& command, CommandReturnObject &result)
10965a988416SJim Ingham     {
1097893c932aSJim Ingham         Target *target = GetSelectedOrDummyTarget();
10985a988416SJim Ingham         if (target == NULL)
10995a988416SJim Ingham         {
11005a988416SJim Ingham             result.AppendError ("Invalid target.  No existing target or breakpoints.");
11015a988416SJim Ingham             result.SetStatus (eReturnStatusFailed);
11025a988416SJim Ingham             return false;
11035a988416SJim Ingham         }
11045a988416SJim Ingham 
11055a988416SJim Ingham         Mutex::Locker locker;
11065a988416SJim Ingham         target->GetBreakpointList().GetListMutex(locker);
11075a988416SJim Ingham 
11085a988416SJim Ingham         const BreakpointList &breakpoints = target->GetBreakpointList();
11095a988416SJim Ingham 
11105a988416SJim Ingham         size_t num_breakpoints = breakpoints.GetSize();
11115a988416SJim Ingham 
11125a988416SJim Ingham         if (num_breakpoints == 0)
11135a988416SJim Ingham         {
11145a988416SJim Ingham             result.AppendError ("No breakpoints exist to be enabled.");
11155a988416SJim Ingham             result.SetStatus (eReturnStatusFailed);
11165a988416SJim Ingham             return false;
11175a988416SJim Ingham         }
11185a988416SJim Ingham 
11195a988416SJim Ingham         if (command.GetArgumentCount() == 0)
11205a988416SJim Ingham         {
11215a988416SJim Ingham             // No breakpoint selected; enable all currently set breakpoints.
11225a988416SJim Ingham             target->EnableAllBreakpoints ();
11236fea17e8SGreg Clayton             result.AppendMessageWithFormat ("All breakpoints enabled. (%" PRIu64 " breakpoints)\n", (uint64_t)num_breakpoints);
11245a988416SJim Ingham             result.SetStatus (eReturnStatusSuccessFinishNoResult);
11255a988416SJim Ingham         }
11265a988416SJim Ingham         else
11275a988416SJim Ingham         {
11285a988416SJim Ingham             // Particular breakpoint selected; enable that breakpoint.
11295a988416SJim Ingham             BreakpointIDList valid_bp_ids;
1130*5e09c8c3SJim Ingham             CommandObjectMultiwordBreakpoint::VerifyBreakpointOrLocationIDs (command, target, result, &valid_bp_ids);
11315a988416SJim Ingham 
11325a988416SJim Ingham             if (result.Succeeded())
11335a988416SJim Ingham             {
11345a988416SJim Ingham                 int enable_count = 0;
11355a988416SJim Ingham                 int loc_count = 0;
11365a988416SJim Ingham                 const size_t count = valid_bp_ids.GetSize();
11375a988416SJim Ingham                 for (size_t i = 0; i < count; ++i)
11385a988416SJim Ingham                 {
11395a988416SJim Ingham                     BreakpointID cur_bp_id = valid_bp_ids.GetBreakpointIDAtIndex (i);
11405a988416SJim Ingham 
11415a988416SJim Ingham                     if (cur_bp_id.GetBreakpointID() != LLDB_INVALID_BREAK_ID)
11425a988416SJim Ingham                     {
11435a988416SJim Ingham                         Breakpoint *breakpoint = target->GetBreakpointByID (cur_bp_id.GetBreakpointID()).get();
11445a988416SJim Ingham                         if (cur_bp_id.GetLocationID() != LLDB_INVALID_BREAK_ID)
11455a988416SJim Ingham                         {
11465a988416SJim Ingham                             BreakpointLocation *location = breakpoint->FindLocationByID (cur_bp_id.GetLocationID()).get();
11475a988416SJim Ingham                             if (location)
11485a988416SJim Ingham                             {
11495a988416SJim Ingham                                 location->SetEnabled (true);
11505a988416SJim Ingham                                 ++loc_count;
11515a988416SJim Ingham                             }
11525a988416SJim Ingham                         }
11535a988416SJim Ingham                         else
11545a988416SJim Ingham                         {
11555a988416SJim Ingham                             breakpoint->SetEnabled (true);
11565a988416SJim Ingham                             ++enable_count;
11575a988416SJim Ingham                         }
11585a988416SJim Ingham                     }
11595a988416SJim Ingham                 }
11605a988416SJim Ingham                 result.AppendMessageWithFormat ("%d breakpoints enabled.\n", enable_count + loc_count);
11615a988416SJim Ingham                 result.SetStatus (eReturnStatusSuccessFinishNoResult);
11625a988416SJim Ingham             }
11635a988416SJim Ingham         }
11645a988416SJim Ingham 
11655a988416SJim Ingham         return result.Succeeded();
11665a988416SJim Ingham     }
11675a988416SJim Ingham };
11685a988416SJim Ingham 
11695a988416SJim Ingham //-------------------------------------------------------------------------
11705a988416SJim Ingham // CommandObjectBreakpointDisable
11715a988416SJim Ingham //-------------------------------------------------------------------------
11725a988416SJim Ingham #pragma mark Disable
11735a988416SJim Ingham 
11745a988416SJim Ingham class CommandObjectBreakpointDisable : public CommandObjectParsed
11755a988416SJim Ingham {
11765a988416SJim Ingham public:
11775a988416SJim Ingham     CommandObjectBreakpointDisable (CommandInterpreter &interpreter) :
11785a988416SJim Ingham         CommandObjectParsed (interpreter,
11795a988416SJim Ingham                              "breakpoint disable",
11805a988416SJim Ingham                              "Disable the specified breakpoint(s) without removing it/them.  If no breakpoints are specified, disable them all.",
11815a988416SJim Ingham                              NULL)
11825a988416SJim Ingham     {
1183b0fac509SJim Ingham         SetHelpLong(
1184b0fac509SJim Ingham "Disable the specified breakpoint(s) without removing it/them.  \n\
1185b0fac509SJim Ingham If no breakpoints are specified, disable them all.\n\
1186b0fac509SJim Ingham \n\
1187b0fac509SJim Ingham Note: disabling a breakpoint will cause none of its locations to be hit\n\
1188b0fac509SJim Ingham regardless of whether they are enabled or disabled.  So the sequence: \n\
1189b0fac509SJim Ingham \n\
1190b0fac509SJim Ingham     (lldb) break disable 1\n\
1191b0fac509SJim Ingham     (lldb) break enable 1.1\n\
1192b0fac509SJim Ingham \n\
1193b0fac509SJim Ingham will NOT cause location 1.1 to get hit.  To achieve that, do:\n\
1194b0fac509SJim Ingham \n\
1195b0fac509SJim Ingham     (lldb) break disable 1.*\n\
1196b0fac509SJim Ingham     (lldb) break enable 1.1\n\
1197b0fac509SJim Ingham \n\
1198b0fac509SJim Ingham The first command disables all the locations of breakpoint 1, \n\
1199b0fac509SJim Ingham the second re-enables the first location."
1200b0fac509SJim Ingham                     );
1201b0fac509SJim Ingham 
12025a988416SJim Ingham         CommandArgumentEntry arg;
12035a988416SJim Ingham         CommandObject::AddIDsArgumentData(arg, eArgTypeBreakpointID, eArgTypeBreakpointIDRange);
12045a988416SJim Ingham         // Add the entry for the first argument for this command to the object's arguments vector.
12055a988416SJim Ingham         m_arguments.push_back (arg);
1206b0fac509SJim Ingham 
12075a988416SJim Ingham     }
12085a988416SJim Ingham 
12095a988416SJim Ingham 
12105a988416SJim Ingham     virtual
12115a988416SJim Ingham     ~CommandObjectBreakpointDisable () {}
12125a988416SJim Ingham 
12135a988416SJim Ingham protected:
12145a988416SJim Ingham     virtual bool
12155a988416SJim Ingham     DoExecute (Args& command, CommandReturnObject &result)
12165a988416SJim Ingham     {
1217893c932aSJim Ingham         Target *target = GetSelectedOrDummyTarget();
12185a988416SJim Ingham         if (target == NULL)
12195a988416SJim Ingham         {
12205a988416SJim Ingham             result.AppendError ("Invalid target.  No existing target or breakpoints.");
12215a988416SJim Ingham             result.SetStatus (eReturnStatusFailed);
12225a988416SJim Ingham             return false;
12235a988416SJim Ingham         }
12245a988416SJim Ingham 
12255a988416SJim Ingham         Mutex::Locker locker;
12265a988416SJim Ingham         target->GetBreakpointList().GetListMutex(locker);
12275a988416SJim Ingham 
12285a988416SJim Ingham         const BreakpointList &breakpoints = target->GetBreakpointList();
12295a988416SJim Ingham         size_t num_breakpoints = breakpoints.GetSize();
12305a988416SJim Ingham 
12315a988416SJim Ingham         if (num_breakpoints == 0)
12325a988416SJim Ingham         {
12335a988416SJim Ingham             result.AppendError ("No breakpoints exist to be disabled.");
12345a988416SJim Ingham             result.SetStatus (eReturnStatusFailed);
12355a988416SJim Ingham             return false;
12365a988416SJim Ingham         }
12375a988416SJim Ingham 
12385a988416SJim Ingham         if (command.GetArgumentCount() == 0)
12395a988416SJim Ingham         {
12405a988416SJim Ingham             // No breakpoint selected; disable all currently set breakpoints.
12415a988416SJim Ingham             target->DisableAllBreakpoints ();
12426fea17e8SGreg Clayton             result.AppendMessageWithFormat ("All breakpoints disabled. (%" PRIu64 " breakpoints)\n", (uint64_t)num_breakpoints);
12435a988416SJim Ingham             result.SetStatus (eReturnStatusSuccessFinishNoResult);
12445a988416SJim Ingham         }
12455a988416SJim Ingham         else
12465a988416SJim Ingham         {
12475a988416SJim Ingham             // Particular breakpoint selected; disable that breakpoint.
12485a988416SJim Ingham             BreakpointIDList valid_bp_ids;
12495a988416SJim Ingham 
1250*5e09c8c3SJim Ingham             CommandObjectMultiwordBreakpoint::VerifyBreakpointOrLocationIDs (command, target, result, &valid_bp_ids);
12515a988416SJim Ingham 
12525a988416SJim Ingham             if (result.Succeeded())
12535a988416SJim Ingham             {
12545a988416SJim Ingham                 int disable_count = 0;
12555a988416SJim Ingham                 int loc_count = 0;
12565a988416SJim Ingham                 const size_t count = valid_bp_ids.GetSize();
12575a988416SJim Ingham                 for (size_t i = 0; i < count; ++i)
12585a988416SJim Ingham                 {
12595a988416SJim Ingham                     BreakpointID cur_bp_id = valid_bp_ids.GetBreakpointIDAtIndex (i);
12605a988416SJim Ingham 
12615a988416SJim Ingham                     if (cur_bp_id.GetBreakpointID() != LLDB_INVALID_BREAK_ID)
12625a988416SJim Ingham                     {
12635a988416SJim Ingham                         Breakpoint *breakpoint = target->GetBreakpointByID (cur_bp_id.GetBreakpointID()).get();
12645a988416SJim Ingham                         if (cur_bp_id.GetLocationID() != LLDB_INVALID_BREAK_ID)
12655a988416SJim Ingham                         {
12665a988416SJim Ingham                             BreakpointLocation *location = breakpoint->FindLocationByID (cur_bp_id.GetLocationID()).get();
12675a988416SJim Ingham                             if (location)
12685a988416SJim Ingham                             {
12695a988416SJim Ingham                                 location->SetEnabled (false);
12705a988416SJim Ingham                                 ++loc_count;
12715a988416SJim Ingham                             }
12725a988416SJim Ingham                         }
12735a988416SJim Ingham                         else
12745a988416SJim Ingham                         {
12755a988416SJim Ingham                             breakpoint->SetEnabled (false);
12765a988416SJim Ingham                             ++disable_count;
12775a988416SJim Ingham                         }
12785a988416SJim Ingham                     }
12795a988416SJim Ingham                 }
12805a988416SJim Ingham                 result.AppendMessageWithFormat ("%d breakpoints disabled.\n", disable_count + loc_count);
12815a988416SJim Ingham                 result.SetStatus (eReturnStatusSuccessFinishNoResult);
12825a988416SJim Ingham             }
12835a988416SJim Ingham         }
12845a988416SJim Ingham 
12855a988416SJim Ingham         return result.Succeeded();
12865a988416SJim Ingham     }
12875a988416SJim Ingham 
12885a988416SJim Ingham };
12895a988416SJim Ingham 
12905a988416SJim Ingham //-------------------------------------------------------------------------
12915a988416SJim Ingham // CommandObjectBreakpointList
12925a988416SJim Ingham //-------------------------------------------------------------------------
12935a988416SJim Ingham #pragma mark List
12945a988416SJim Ingham 
12955a988416SJim Ingham class CommandObjectBreakpointList : public CommandObjectParsed
12965a988416SJim Ingham {
12975a988416SJim Ingham public:
12985a988416SJim Ingham     CommandObjectBreakpointList (CommandInterpreter &interpreter) :
12995a988416SJim Ingham         CommandObjectParsed (interpreter,
13005a988416SJim Ingham                              "breakpoint list",
13015a988416SJim Ingham                              "List some or all breakpoints at configurable levels of detail.",
13025a988416SJim Ingham                              NULL),
13035a988416SJim Ingham         m_options (interpreter)
13045a988416SJim Ingham     {
13055a988416SJim Ingham         CommandArgumentEntry arg;
13065a988416SJim Ingham         CommandArgumentData bp_id_arg;
13075a988416SJim Ingham 
13085a988416SJim Ingham         // Define the first (and only) variant of this arg.
13095a988416SJim Ingham         bp_id_arg.arg_type = eArgTypeBreakpointID;
13105a988416SJim Ingham         bp_id_arg.arg_repetition = eArgRepeatOptional;
13115a988416SJim Ingham 
13125a988416SJim Ingham         // There is only one variant this argument could be; put it into the argument entry.
13135a988416SJim Ingham         arg.push_back (bp_id_arg);
13145a988416SJim Ingham 
13155a988416SJim Ingham         // Push the data for the first argument into the m_arguments vector.
13165a988416SJim Ingham         m_arguments.push_back (arg);
13175a988416SJim Ingham     }
13185a988416SJim Ingham 
13195a988416SJim Ingham 
13205a988416SJim Ingham     virtual
13215a988416SJim Ingham     ~CommandObjectBreakpointList () {}
13225a988416SJim Ingham 
13235a988416SJim Ingham     virtual Options *
13245a988416SJim Ingham     GetOptions ()
13255a988416SJim Ingham     {
13265a988416SJim Ingham         return &m_options;
13275a988416SJim Ingham     }
13285a988416SJim Ingham 
13295a988416SJim Ingham     class CommandOptions : public Options
13305a988416SJim Ingham     {
13315a988416SJim Ingham     public:
13325a988416SJim Ingham 
13335a988416SJim Ingham         CommandOptions (CommandInterpreter &interpreter) :
13345a988416SJim Ingham             Options (interpreter),
133533df7cd3SJim Ingham             m_level (lldb::eDescriptionLevelBrief),
133633df7cd3SJim Ingham             m_use_dummy(false)
13375a988416SJim Ingham         {
13385a988416SJim Ingham         }
13395a988416SJim Ingham 
13405a988416SJim Ingham         virtual
13415a988416SJim Ingham         ~CommandOptions () {}
13425a988416SJim Ingham 
13435a988416SJim Ingham         virtual Error
13445a988416SJim Ingham         SetOptionValue (uint32_t option_idx, const char *option_arg)
13455a988416SJim Ingham         {
13465a988416SJim Ingham             Error error;
13473bcdfc0eSGreg Clayton             const int short_option = m_getopt_table[option_idx].val;
13485a988416SJim Ingham 
13495a988416SJim Ingham             switch (short_option)
13505a988416SJim Ingham             {
13515a988416SJim Ingham                 case 'b':
13525a988416SJim Ingham                     m_level = lldb::eDescriptionLevelBrief;
13535a988416SJim Ingham                     break;
135433df7cd3SJim Ingham                 case 'D':
135533df7cd3SJim Ingham                     m_use_dummy = true;
135633df7cd3SJim Ingham                     break;
13575a988416SJim Ingham                 case 'f':
13585a988416SJim Ingham                     m_level = lldb::eDescriptionLevelFull;
13595a988416SJim Ingham                     break;
13605a988416SJim Ingham                 case 'v':
13615a988416SJim Ingham                     m_level = lldb::eDescriptionLevelVerbose;
13625a988416SJim Ingham                     break;
13635a988416SJim Ingham                 case 'i':
13645a988416SJim Ingham                     m_internal = true;
13655a988416SJim Ingham                     break;
13665a988416SJim Ingham                 default:
13675a988416SJim Ingham                     error.SetErrorStringWithFormat ("unrecognized option '%c'", short_option);
13685a988416SJim Ingham                     break;
13695a988416SJim Ingham             }
13705a988416SJim Ingham 
13715a988416SJim Ingham             return error;
13725a988416SJim Ingham         }
13735a988416SJim Ingham 
13745a988416SJim Ingham         void
13755a988416SJim Ingham         OptionParsingStarting ()
13765a988416SJim Ingham         {
13775a988416SJim Ingham             m_level = lldb::eDescriptionLevelFull;
13785a988416SJim Ingham             m_internal = false;
137933df7cd3SJim Ingham             m_use_dummy = false;
13805a988416SJim Ingham         }
13815a988416SJim Ingham 
13825a988416SJim Ingham         const OptionDefinition *
13835a988416SJim Ingham         GetDefinitions ()
13845a988416SJim Ingham         {
13855a988416SJim Ingham             return g_option_table;
13865a988416SJim Ingham         }
13875a988416SJim Ingham 
13885a988416SJim Ingham         // Options table: Required for subclasses of Options.
13895a988416SJim Ingham 
13905a988416SJim Ingham         static OptionDefinition g_option_table[];
13915a988416SJim Ingham 
13925a988416SJim Ingham         // Instance variables to hold the values for command options.
13935a988416SJim Ingham 
13945a988416SJim Ingham         lldb::DescriptionLevel m_level;
13955a988416SJim Ingham 
13965a988416SJim Ingham         bool m_internal;
139733df7cd3SJim Ingham         bool m_use_dummy;
13985a988416SJim Ingham     };
13995a988416SJim Ingham 
14005a988416SJim Ingham protected:
14015a988416SJim Ingham     virtual bool
14025a988416SJim Ingham     DoExecute (Args& command, CommandReturnObject &result)
14035a988416SJim Ingham     {
140433df7cd3SJim Ingham         Target *target = GetSelectedOrDummyTarget(m_options.m_use_dummy);
140533df7cd3SJim Ingham 
14065a988416SJim Ingham         if (target == NULL)
14075a988416SJim Ingham         {
14085a988416SJim Ingham             result.AppendError ("Invalid target. No current target or breakpoints.");
14095a988416SJim Ingham             result.SetStatus (eReturnStatusSuccessFinishNoResult);
14105a988416SJim Ingham             return true;
14115a988416SJim Ingham         }
14125a988416SJim Ingham 
14135a988416SJim Ingham         const BreakpointList &breakpoints = target->GetBreakpointList(m_options.m_internal);
14145a988416SJim Ingham         Mutex::Locker locker;
14155a988416SJim Ingham         target->GetBreakpointList(m_options.m_internal).GetListMutex(locker);
14165a988416SJim Ingham 
14175a988416SJim Ingham         size_t num_breakpoints = breakpoints.GetSize();
14185a988416SJim Ingham 
14195a988416SJim Ingham         if (num_breakpoints == 0)
14205a988416SJim Ingham         {
14215a988416SJim Ingham             result.AppendMessage ("No breakpoints currently set.");
14225a988416SJim Ingham             result.SetStatus (eReturnStatusSuccessFinishNoResult);
14235a988416SJim Ingham             return true;
14245a988416SJim Ingham         }
14255a988416SJim Ingham 
14265a988416SJim Ingham         Stream &output_stream = result.GetOutputStream();
14275a988416SJim Ingham 
14285a988416SJim Ingham         if (command.GetArgumentCount() == 0)
14295a988416SJim Ingham         {
14305a988416SJim Ingham             // No breakpoint selected; show info about all currently set breakpoints.
14315a988416SJim Ingham             result.AppendMessage ("Current breakpoints:");
14325a988416SJim Ingham             for (size_t i = 0; i < num_breakpoints; ++i)
14335a988416SJim Ingham             {
14345a988416SJim Ingham                 Breakpoint *breakpoint = breakpoints.GetBreakpointAtIndex (i).get();
14355a988416SJim Ingham                 AddBreakpointDescription (&output_stream, breakpoint, m_options.m_level);
14365a988416SJim Ingham             }
14375a988416SJim Ingham             result.SetStatus (eReturnStatusSuccessFinishNoResult);
14385a988416SJim Ingham         }
14395a988416SJim Ingham         else
14405a988416SJim Ingham         {
14415a988416SJim Ingham             // Particular breakpoints selected; show info about that breakpoint.
14425a988416SJim Ingham             BreakpointIDList valid_bp_ids;
1443*5e09c8c3SJim Ingham             CommandObjectMultiwordBreakpoint::VerifyBreakpointOrLocationIDs (command, target, result, &valid_bp_ids);
14445a988416SJim Ingham 
14455a988416SJim Ingham             if (result.Succeeded())
14465a988416SJim Ingham             {
14475a988416SJim Ingham                 for (size_t i = 0; i < valid_bp_ids.GetSize(); ++i)
14485a988416SJim Ingham                 {
14495a988416SJim Ingham                     BreakpointID cur_bp_id = valid_bp_ids.GetBreakpointIDAtIndex (i);
14505a988416SJim Ingham                     Breakpoint *breakpoint = target->GetBreakpointByID (cur_bp_id.GetBreakpointID()).get();
14515a988416SJim Ingham                     AddBreakpointDescription (&output_stream, breakpoint, m_options.m_level);
14525a988416SJim Ingham                 }
14535a988416SJim Ingham                 result.SetStatus (eReturnStatusSuccessFinishNoResult);
14545a988416SJim Ingham             }
14555a988416SJim Ingham             else
14565a988416SJim Ingham             {
14575a988416SJim Ingham                 result.AppendError ("Invalid breakpoint id.");
14585a988416SJim Ingham                 result.SetStatus (eReturnStatusFailed);
14595a988416SJim Ingham             }
14605a988416SJim Ingham         }
14615a988416SJim Ingham 
14625a988416SJim Ingham         return result.Succeeded();
14635a988416SJim Ingham     }
14645a988416SJim Ingham 
14655a988416SJim Ingham private:
14665a988416SJim Ingham     CommandOptions m_options;
14675a988416SJim Ingham };
14685a988416SJim Ingham 
14695a988416SJim Ingham #pragma mark List::CommandOptions
14705a988416SJim Ingham OptionDefinition
14715a988416SJim Ingham CommandObjectBreakpointList::CommandOptions::g_option_table[] =
14725a988416SJim Ingham {
1473d37221dcSZachary Turner     { LLDB_OPT_SET_ALL, false, "internal", 'i', OptionParser::eNoArgument, NULL, NULL, 0, eArgTypeNone,
14745a988416SJim Ingham         "Show debugger internal breakpoints" },
14755a988416SJim Ingham 
1476d37221dcSZachary Turner     { LLDB_OPT_SET_1, false, "brief",    'b', OptionParser::eNoArgument, NULL, NULL, 0, eArgTypeNone,
14775a988416SJim Ingham         "Give a brief description of the breakpoint (no location info)."},
14785a988416SJim Ingham 
14795a988416SJim Ingham     // FIXME: We need to add an "internal" command, and then add this sort of thing to it.
14805a988416SJim Ingham     // But I need to see it for now, and don't want to wait.
1481d37221dcSZachary Turner     { LLDB_OPT_SET_2, false, "full",    'f', OptionParser::eNoArgument, NULL, NULL, 0, eArgTypeNone,
14825a988416SJim Ingham         "Give a full description of the breakpoint and its locations."},
14835a988416SJim Ingham 
1484d37221dcSZachary Turner     { LLDB_OPT_SET_3, false, "verbose", 'v', OptionParser::eNoArgument, NULL, NULL, 0, eArgTypeNone,
14855a988416SJim Ingham         "Explain everything we know about the breakpoint (for debugging debugger bugs)." },
14865a988416SJim Ingham 
148733df7cd3SJim Ingham     { LLDB_OPT_SET_ALL, false, "dummy-breakpoints", 'D', OptionParser::eNoArgument, NULL, NULL, 0, eArgTypeNone,
148833df7cd3SJim Ingham         "List Dummy breakpoints - i.e. breakpoints set before a file is provided, which prime new targets."},
148933df7cd3SJim Ingham 
1490d37221dcSZachary Turner     { 0, false, NULL, 0, 0, NULL, NULL, 0, eArgTypeNone, NULL }
14915a988416SJim Ingham };
14925a988416SJim Ingham 
14935a988416SJim Ingham //-------------------------------------------------------------------------
14945a988416SJim Ingham // CommandObjectBreakpointClear
14955a988416SJim Ingham //-------------------------------------------------------------------------
14965a988416SJim Ingham #pragma mark Clear
14975a988416SJim Ingham 
14985a988416SJim Ingham class CommandObjectBreakpointClear : public CommandObjectParsed
14995a988416SJim Ingham {
15005a988416SJim Ingham public:
15015a988416SJim Ingham 
15025a988416SJim Ingham     typedef enum BreakpointClearType
15035a988416SJim Ingham     {
15045a988416SJim Ingham         eClearTypeInvalid,
15055a988416SJim Ingham         eClearTypeFileAndLine
15065a988416SJim Ingham     } BreakpointClearType;
15075a988416SJim Ingham 
15085a988416SJim Ingham     CommandObjectBreakpointClear (CommandInterpreter &interpreter) :
15095a988416SJim Ingham         CommandObjectParsed (interpreter,
15105a988416SJim Ingham                              "breakpoint clear",
15115a988416SJim Ingham                              "Clears a breakpoint or set of breakpoints in the executable.",
15125a988416SJim Ingham                              "breakpoint clear <cmd-options>"),
15135a988416SJim Ingham         m_options (interpreter)
15145a988416SJim Ingham     {
15155a988416SJim Ingham     }
15165a988416SJim Ingham 
15175a988416SJim Ingham     virtual
15185a988416SJim Ingham     ~CommandObjectBreakpointClear () {}
15195a988416SJim Ingham 
15205a988416SJim Ingham     virtual Options *
15215a988416SJim Ingham     GetOptions ()
15225a988416SJim Ingham     {
15235a988416SJim Ingham         return &m_options;
15245a988416SJim Ingham     }
15255a988416SJim Ingham 
15265a988416SJim Ingham     class CommandOptions : public Options
15275a988416SJim Ingham     {
15285a988416SJim Ingham     public:
15295a988416SJim Ingham 
15305a988416SJim Ingham         CommandOptions (CommandInterpreter &interpreter) :
15315a988416SJim Ingham             Options (interpreter),
15325a988416SJim Ingham             m_filename (),
15335a988416SJim Ingham             m_line_num (0)
15345a988416SJim Ingham         {
15355a988416SJim Ingham         }
15365a988416SJim Ingham 
15375a988416SJim Ingham         virtual
15385a988416SJim Ingham         ~CommandOptions () {}
15395a988416SJim Ingham 
15405a988416SJim Ingham         virtual Error
15415a988416SJim Ingham         SetOptionValue (uint32_t option_idx, const char *option_arg)
15425a988416SJim Ingham         {
15435a988416SJim Ingham             Error error;
15443bcdfc0eSGreg Clayton             const int short_option = m_getopt_table[option_idx].val;
15455a988416SJim Ingham 
15465a988416SJim Ingham             switch (short_option)
15475a988416SJim Ingham             {
15485a988416SJim Ingham                 case 'f':
15495a988416SJim Ingham                     m_filename.assign (option_arg);
15505a988416SJim Ingham                     break;
15515a988416SJim Ingham 
15525a988416SJim Ingham                 case 'l':
15535a988416SJim Ingham                     m_line_num = Args::StringToUInt32 (option_arg, 0);
15545a988416SJim Ingham                     break;
15555a988416SJim Ingham 
15565a988416SJim Ingham                 default:
15575a988416SJim Ingham                     error.SetErrorStringWithFormat ("unrecognized option '%c'", short_option);
15585a988416SJim Ingham                     break;
15595a988416SJim Ingham             }
15605a988416SJim Ingham 
15615a988416SJim Ingham             return error;
15625a988416SJim Ingham         }
15635a988416SJim Ingham 
15645a988416SJim Ingham         void
15655a988416SJim Ingham         OptionParsingStarting ()
15665a988416SJim Ingham         {
15675a988416SJim Ingham             m_filename.clear();
15685a988416SJim Ingham             m_line_num = 0;
15695a988416SJim Ingham         }
15705a988416SJim Ingham 
15715a988416SJim Ingham         const OptionDefinition*
15725a988416SJim Ingham         GetDefinitions ()
15735a988416SJim Ingham         {
15745a988416SJim Ingham             return g_option_table;
15755a988416SJim Ingham         }
15765a988416SJim Ingham 
15775a988416SJim Ingham         // Options table: Required for subclasses of Options.
15785a988416SJim Ingham 
15795a988416SJim Ingham         static OptionDefinition g_option_table[];
15805a988416SJim Ingham 
15815a988416SJim Ingham         // Instance variables to hold the values for command options.
15825a988416SJim Ingham 
15835a988416SJim Ingham         std::string m_filename;
15845a988416SJim Ingham         uint32_t m_line_num;
15855a988416SJim Ingham 
15865a988416SJim Ingham     };
15875a988416SJim Ingham 
15885a988416SJim Ingham protected:
15895a988416SJim Ingham     virtual bool
15905a988416SJim Ingham     DoExecute (Args& command, CommandReturnObject &result)
15915a988416SJim Ingham     {
1592893c932aSJim Ingham         Target *target = GetSelectedOrDummyTarget();
15935a988416SJim Ingham         if (target == NULL)
15945a988416SJim Ingham         {
15955a988416SJim Ingham             result.AppendError ("Invalid target. No existing target or breakpoints.");
15965a988416SJim Ingham             result.SetStatus (eReturnStatusFailed);
15975a988416SJim Ingham             return false;
15985a988416SJim Ingham         }
15995a988416SJim Ingham 
16005a988416SJim Ingham         // The following are the various types of breakpoints that could be cleared:
16015a988416SJim Ingham         //   1). -f -l (clearing breakpoint by source location)
16025a988416SJim Ingham 
16035a988416SJim Ingham         BreakpointClearType break_type = eClearTypeInvalid;
16045a988416SJim Ingham 
16055a988416SJim Ingham         if (m_options.m_line_num != 0)
16065a988416SJim Ingham             break_type = eClearTypeFileAndLine;
16075a988416SJim Ingham 
16085a988416SJim Ingham         Mutex::Locker locker;
16095a988416SJim Ingham         target->GetBreakpointList().GetListMutex(locker);
16105a988416SJim Ingham 
16115a988416SJim Ingham         BreakpointList &breakpoints = target->GetBreakpointList();
16125a988416SJim Ingham         size_t num_breakpoints = breakpoints.GetSize();
16135a988416SJim Ingham 
16145a988416SJim Ingham         // Early return if there's no breakpoint at all.
16155a988416SJim Ingham         if (num_breakpoints == 0)
16165a988416SJim Ingham         {
16175a988416SJim Ingham             result.AppendError ("Breakpoint clear: No breakpoint cleared.");
16185a988416SJim Ingham             result.SetStatus (eReturnStatusFailed);
16195a988416SJim Ingham             return result.Succeeded();
16205a988416SJim Ingham         }
16215a988416SJim Ingham 
16225a988416SJim Ingham         // Find matching breakpoints and delete them.
16235a988416SJim Ingham 
16245a988416SJim Ingham         // First create a copy of all the IDs.
16255a988416SJim Ingham         std::vector<break_id_t> BreakIDs;
16265a988416SJim Ingham         for (size_t i = 0; i < num_breakpoints; ++i)
16275a988416SJim Ingham             BreakIDs.push_back(breakpoints.GetBreakpointAtIndex(i).get()->GetID());
16285a988416SJim Ingham 
16295a988416SJim Ingham         int num_cleared = 0;
16305a988416SJim Ingham         StreamString ss;
16315a988416SJim Ingham         switch (break_type)
16325a988416SJim Ingham         {
16335a988416SJim Ingham             case eClearTypeFileAndLine: // Breakpoint by source position
16345a988416SJim Ingham                 {
16355a988416SJim Ingham                     const ConstString filename(m_options.m_filename.c_str());
16365a988416SJim Ingham                     BreakpointLocationCollection loc_coll;
16375a988416SJim Ingham 
16385a988416SJim Ingham                     for (size_t i = 0; i < num_breakpoints; ++i)
16395a988416SJim Ingham                     {
16405a988416SJim Ingham                         Breakpoint *bp = breakpoints.FindBreakpointByID(BreakIDs[i]).get();
16415a988416SJim Ingham 
16425a988416SJim Ingham                         if (bp->GetMatchingFileLine(filename, m_options.m_line_num, loc_coll))
16435a988416SJim Ingham                         {
16445a988416SJim Ingham                             // If the collection size is 0, it's a full match and we can just remove the breakpoint.
16455a988416SJim Ingham                             if (loc_coll.GetSize() == 0)
16465a988416SJim Ingham                             {
16475a988416SJim Ingham                                 bp->GetDescription(&ss, lldb::eDescriptionLevelBrief);
16485a988416SJim Ingham                                 ss.EOL();
16495a988416SJim Ingham                                 target->RemoveBreakpointByID (bp->GetID());
16505a988416SJim Ingham                                 ++num_cleared;
16515a988416SJim Ingham                             }
16525a988416SJim Ingham                         }
16535a988416SJim Ingham                     }
16545a988416SJim Ingham                 }
16555a988416SJim Ingham                 break;
16565a988416SJim Ingham 
16575a988416SJim Ingham             default:
16585a988416SJim Ingham                 break;
16595a988416SJim Ingham         }
16605a988416SJim Ingham 
16615a988416SJim Ingham         if (num_cleared > 0)
16625a988416SJim Ingham         {
16635a988416SJim Ingham             Stream &output_stream = result.GetOutputStream();
16645a988416SJim Ingham             output_stream.Printf ("%d breakpoints cleared:\n", num_cleared);
16655a988416SJim Ingham             output_stream << ss.GetData();
16665a988416SJim Ingham             output_stream.EOL();
16675a988416SJim Ingham             result.SetStatus (eReturnStatusSuccessFinishNoResult);
16685a988416SJim Ingham         }
16695a988416SJim Ingham         else
16705a988416SJim Ingham         {
16715a988416SJim Ingham             result.AppendError ("Breakpoint clear: No breakpoint cleared.");
16725a988416SJim Ingham             result.SetStatus (eReturnStatusFailed);
16735a988416SJim Ingham         }
16745a988416SJim Ingham 
16755a988416SJim Ingham         return result.Succeeded();
16765a988416SJim Ingham     }
16775a988416SJim Ingham 
16785a988416SJim Ingham private:
16795a988416SJim Ingham     CommandOptions m_options;
16805a988416SJim Ingham };
16815a988416SJim Ingham 
16825a988416SJim Ingham #pragma mark Clear::CommandOptions
16835a988416SJim Ingham 
16845a988416SJim Ingham OptionDefinition
16855a988416SJim Ingham CommandObjectBreakpointClear::CommandOptions::g_option_table[] =
16865a988416SJim Ingham {
1687d37221dcSZachary Turner     { LLDB_OPT_SET_1, false, "file", 'f', OptionParser::eRequiredArgument, NULL, NULL, CommandCompletions::eSourceFileCompletion, eArgTypeFilename,
16885a988416SJim Ingham         "Specify the breakpoint by source location in this particular file."},
16895a988416SJim Ingham 
1690d37221dcSZachary Turner     { LLDB_OPT_SET_1, true, "line", 'l', OptionParser::eRequiredArgument, NULL, NULL, 0, eArgTypeLineNum,
16915a988416SJim Ingham         "Specify the breakpoint by source location at this particular line."},
16925a988416SJim Ingham 
1693d37221dcSZachary Turner     { 0, false, NULL, 0, 0, NULL, NULL, 0, eArgTypeNone, NULL }
16945a988416SJim Ingham };
16955a988416SJim Ingham 
16965a988416SJim Ingham //-------------------------------------------------------------------------
16975a988416SJim Ingham // CommandObjectBreakpointDelete
16985a988416SJim Ingham //-------------------------------------------------------------------------
16995a988416SJim Ingham #pragma mark Delete
17005a988416SJim Ingham 
17015a988416SJim Ingham class CommandObjectBreakpointDelete : public CommandObjectParsed
17025a988416SJim Ingham {
17035a988416SJim Ingham public:
17045a988416SJim Ingham     CommandObjectBreakpointDelete (CommandInterpreter &interpreter) :
17055a988416SJim Ingham         CommandObjectParsed (interpreter,
17065a988416SJim Ingham                              "breakpoint delete",
17075a988416SJim Ingham                              "Delete the specified breakpoint(s).  If no breakpoints are specified, delete them all.",
170833df7cd3SJim Ingham                              NULL),
170933df7cd3SJim Ingham         m_options (interpreter)
17105a988416SJim Ingham     {
17115a988416SJim Ingham         CommandArgumentEntry arg;
17125a988416SJim Ingham         CommandObject::AddIDsArgumentData(arg, eArgTypeBreakpointID, eArgTypeBreakpointIDRange);
17135a988416SJim Ingham         // Add the entry for the first argument for this command to the object's arguments vector.
17145a988416SJim Ingham         m_arguments.push_back (arg);
17155a988416SJim Ingham     }
17165a988416SJim Ingham 
17175a988416SJim Ingham     virtual
17185a988416SJim Ingham     ~CommandObjectBreakpointDelete () {}
17195a988416SJim Ingham 
172033df7cd3SJim Ingham     virtual Options *
172133df7cd3SJim Ingham     GetOptions ()
172233df7cd3SJim Ingham     {
172333df7cd3SJim Ingham         return &m_options;
172433df7cd3SJim Ingham     }
172533df7cd3SJim Ingham 
172633df7cd3SJim Ingham     class CommandOptions : public Options
172733df7cd3SJim Ingham     {
172833df7cd3SJim Ingham     public:
172933df7cd3SJim Ingham 
173033df7cd3SJim Ingham         CommandOptions (CommandInterpreter &interpreter) :
173133df7cd3SJim Ingham             Options (interpreter),
173233df7cd3SJim Ingham             m_use_dummy (false),
173333df7cd3SJim Ingham             m_force (false)
173433df7cd3SJim Ingham         {
173533df7cd3SJim Ingham         }
173633df7cd3SJim Ingham 
173733df7cd3SJim Ingham         virtual
173833df7cd3SJim Ingham         ~CommandOptions () {}
173933df7cd3SJim Ingham 
174033df7cd3SJim Ingham         virtual Error
174133df7cd3SJim Ingham         SetOptionValue (uint32_t option_idx, const char *option_arg)
174233df7cd3SJim Ingham         {
174333df7cd3SJim Ingham             Error error;
174433df7cd3SJim Ingham             const int short_option = m_getopt_table[option_idx].val;
174533df7cd3SJim Ingham 
174633df7cd3SJim Ingham             switch (short_option)
174733df7cd3SJim Ingham             {
174833df7cd3SJim Ingham                 case 'f':
174933df7cd3SJim Ingham                     m_force = true;
175033df7cd3SJim Ingham                     break;
175133df7cd3SJim Ingham 
175233df7cd3SJim Ingham                 case 'D':
175333df7cd3SJim Ingham                     m_use_dummy = true;
175433df7cd3SJim Ingham                     break;
175533df7cd3SJim Ingham 
175633df7cd3SJim Ingham                 default:
175733df7cd3SJim Ingham                     error.SetErrorStringWithFormat ("unrecognized option '%c'", short_option);
175833df7cd3SJim Ingham                     break;
175933df7cd3SJim Ingham             }
176033df7cd3SJim Ingham 
176133df7cd3SJim Ingham             return error;
176233df7cd3SJim Ingham         }
176333df7cd3SJim Ingham 
176433df7cd3SJim Ingham         void
176533df7cd3SJim Ingham         OptionParsingStarting ()
176633df7cd3SJim Ingham         {
176733df7cd3SJim Ingham             m_use_dummy = false;
176833df7cd3SJim Ingham             m_force = false;
176933df7cd3SJim Ingham         }
177033df7cd3SJim Ingham 
177133df7cd3SJim Ingham         const OptionDefinition*
177233df7cd3SJim Ingham         GetDefinitions ()
177333df7cd3SJim Ingham         {
177433df7cd3SJim Ingham             return g_option_table;
177533df7cd3SJim Ingham         }
177633df7cd3SJim Ingham 
177733df7cd3SJim Ingham         // Options table: Required for subclasses of Options.
177833df7cd3SJim Ingham 
177933df7cd3SJim Ingham         static OptionDefinition g_option_table[];
178033df7cd3SJim Ingham 
178133df7cd3SJim Ingham         // Instance variables to hold the values for command options.
178233df7cd3SJim Ingham         bool m_use_dummy;
178333df7cd3SJim Ingham         bool m_force;
178433df7cd3SJim Ingham     };
178533df7cd3SJim Ingham 
17865a988416SJim Ingham protected:
17875a988416SJim Ingham     virtual bool
17885a988416SJim Ingham     DoExecute (Args& command, CommandReturnObject &result)
17895a988416SJim Ingham     {
179033df7cd3SJim Ingham         Target *target = GetSelectedOrDummyTarget(m_options.m_use_dummy);
179133df7cd3SJim Ingham 
17925a988416SJim Ingham         if (target == NULL)
17935a988416SJim Ingham         {
17945a988416SJim Ingham             result.AppendError ("Invalid target. No existing target or breakpoints.");
17955a988416SJim Ingham             result.SetStatus (eReturnStatusFailed);
17965a988416SJim Ingham             return false;
17975a988416SJim Ingham         }
17985a988416SJim Ingham 
17995a988416SJim Ingham         Mutex::Locker locker;
18005a988416SJim Ingham         target->GetBreakpointList().GetListMutex(locker);
18015a988416SJim Ingham 
18025a988416SJim Ingham         const BreakpointList &breakpoints = target->GetBreakpointList();
18035a988416SJim Ingham 
18045a988416SJim Ingham         size_t num_breakpoints = breakpoints.GetSize();
18055a988416SJim Ingham 
18065a988416SJim Ingham         if (num_breakpoints == 0)
18075a988416SJim Ingham         {
18085a988416SJim Ingham             result.AppendError ("No breakpoints exist to be deleted.");
18095a988416SJim Ingham             result.SetStatus (eReturnStatusFailed);
18105a988416SJim Ingham             return false;
18115a988416SJim Ingham         }
18125a988416SJim Ingham 
18135a988416SJim Ingham         if (command.GetArgumentCount() == 0)
18145a988416SJim Ingham         {
181533df7cd3SJim Ingham             if (!m_options.m_force && !m_interpreter.Confirm ("About to delete all breakpoints, do you want to do that?", true))
18165a988416SJim Ingham             {
18175a988416SJim Ingham                 result.AppendMessage("Operation cancelled...");
18185a988416SJim Ingham             }
18195a988416SJim Ingham             else
18205a988416SJim Ingham             {
18215a988416SJim Ingham                 target->RemoveAllBreakpoints ();
18226fea17e8SGreg Clayton                 result.AppendMessageWithFormat ("All breakpoints removed. (%" PRIu64 " breakpoint%s)\n", (uint64_t)num_breakpoints, num_breakpoints > 1 ? "s" : "");
18235a988416SJim Ingham             }
18245a988416SJim Ingham             result.SetStatus (eReturnStatusSuccessFinishNoResult);
18255a988416SJim Ingham         }
18265a988416SJim Ingham         else
18275a988416SJim Ingham         {
18285a988416SJim Ingham             // Particular breakpoint selected; disable that breakpoint.
18295a988416SJim Ingham             BreakpointIDList valid_bp_ids;
1830*5e09c8c3SJim Ingham             CommandObjectMultiwordBreakpoint::VerifyBreakpointOrLocationIDs (command, target, result, &valid_bp_ids);
18315a988416SJim Ingham 
18325a988416SJim Ingham             if (result.Succeeded())
18335a988416SJim Ingham             {
18345a988416SJim Ingham                 int delete_count = 0;
18355a988416SJim Ingham                 int disable_count = 0;
18365a988416SJim Ingham                 const size_t count = valid_bp_ids.GetSize();
18375a988416SJim Ingham                 for (size_t i = 0; i < count; ++i)
18385a988416SJim Ingham                 {
18395a988416SJim Ingham                     BreakpointID cur_bp_id = valid_bp_ids.GetBreakpointIDAtIndex (i);
18405a988416SJim Ingham 
18415a988416SJim Ingham                     if (cur_bp_id.GetBreakpointID() != LLDB_INVALID_BREAK_ID)
18425a988416SJim Ingham                     {
18435a988416SJim Ingham                         if (cur_bp_id.GetLocationID() != LLDB_INVALID_BREAK_ID)
18445a988416SJim Ingham                         {
18455a988416SJim Ingham                             Breakpoint *breakpoint = target->GetBreakpointByID (cur_bp_id.GetBreakpointID()).get();
18465a988416SJim Ingham                             BreakpointLocation *location = breakpoint->FindLocationByID (cur_bp_id.GetLocationID()).get();
18475a988416SJim Ingham                             // It makes no sense to try to delete individual locations, so we disable them instead.
18485a988416SJim Ingham                             if (location)
18495a988416SJim Ingham                             {
18505a988416SJim Ingham                                 location->SetEnabled (false);
18515a988416SJim Ingham                                 ++disable_count;
18525a988416SJim Ingham                             }
18535a988416SJim Ingham                         }
18545a988416SJim Ingham                         else
18555a988416SJim Ingham                         {
18565a988416SJim Ingham                             target->RemoveBreakpointByID (cur_bp_id.GetBreakpointID());
18575a988416SJim Ingham                             ++delete_count;
18585a988416SJim Ingham                         }
18595a988416SJim Ingham                     }
18605a988416SJim Ingham                 }
18615a988416SJim Ingham                 result.AppendMessageWithFormat ("%d breakpoints deleted; %d breakpoint locations disabled.\n",
18625a988416SJim Ingham                                                delete_count, disable_count);
18635a988416SJim Ingham                 result.SetStatus (eReturnStatusSuccessFinishNoResult);
18645a988416SJim Ingham             }
18655a988416SJim Ingham         }
18665a988416SJim Ingham         return result.Succeeded();
18675a988416SJim Ingham     }
186833df7cd3SJim Ingham private:
186933df7cd3SJim Ingham     CommandOptions m_options;
187033df7cd3SJim Ingham };
187133df7cd3SJim Ingham 
187233df7cd3SJim Ingham OptionDefinition
187333df7cd3SJim Ingham CommandObjectBreakpointDelete::CommandOptions::g_option_table[] =
187433df7cd3SJim Ingham {
187533df7cd3SJim Ingham     { LLDB_OPT_SET_1, false, "force", 'f', OptionParser::eNoArgument, NULL, NULL, 0, eArgTypeNone,
187633df7cd3SJim Ingham         "Delete all breakpoints without querying for confirmation."},
187733df7cd3SJim Ingham 
187833df7cd3SJim Ingham     { LLDB_OPT_SET_1, false, "dummy-breakpoints", 'D', OptionParser::eNoArgument, NULL, NULL, 0, eArgTypeNone,
187933df7cd3SJim Ingham         "Delete Dummy breakpoints - i.e. breakpoints set before a file is provided, which prime new targets."},
188033df7cd3SJim Ingham 
188133df7cd3SJim Ingham     { 0, false, NULL, 0, 0, NULL, NULL, 0, eArgTypeNone, NULL }
18825a988416SJim Ingham };
18835a988416SJim Ingham 
188430fdc8d8SChris Lattner //-------------------------------------------------------------------------
1885*5e09c8c3SJim Ingham // CommandObjectBreakpointName
1886*5e09c8c3SJim Ingham //-------------------------------------------------------------------------
1887*5e09c8c3SJim Ingham 
1888*5e09c8c3SJim Ingham static OptionDefinition
1889*5e09c8c3SJim Ingham g_breakpoint_name_options[] =
1890*5e09c8c3SJim Ingham {
1891*5e09c8c3SJim Ingham     { LLDB_OPT_SET_1,   false, "name", 'N', OptionParser::eRequiredArgument, NULL, NULL, 0, eArgTypeBreakpointName, "Specifies a breakpoint name to use."},
1892*5e09c8c3SJim Ingham     { LLDB_OPT_SET_2,   false, "breakpoint-id", 'B', OptionParser::eRequiredArgument, NULL, NULL, 0, eArgTypeBreakpointID,   "Specify a breakpoint id to use."},
1893*5e09c8c3SJim Ingham     { LLDB_OPT_SET_ALL, false, "dummy-breakpoints", 'D', OptionParser::eNoArgument, NULL, NULL, 0, eArgTypeNone,
1894*5e09c8c3SJim Ingham         "Operate on Dummy breakpoints - i.e. breakpoints set before a file is provided, which prime new targets."},
1895*5e09c8c3SJim Ingham };
1896*5e09c8c3SJim Ingham class BreakpointNameOptionGroup : public OptionGroup
1897*5e09c8c3SJim Ingham {
1898*5e09c8c3SJim Ingham public:
1899*5e09c8c3SJim Ingham     BreakpointNameOptionGroup() :
1900*5e09c8c3SJim Ingham         OptionGroup(),
1901*5e09c8c3SJim Ingham         m_breakpoint(LLDB_INVALID_BREAK_ID),
1902*5e09c8c3SJim Ingham         m_use_dummy (false)
1903*5e09c8c3SJim Ingham     {
1904*5e09c8c3SJim Ingham 
1905*5e09c8c3SJim Ingham     }
1906*5e09c8c3SJim Ingham 
1907*5e09c8c3SJim Ingham     virtual
1908*5e09c8c3SJim Ingham     ~BreakpointNameOptionGroup ()
1909*5e09c8c3SJim Ingham     {
1910*5e09c8c3SJim Ingham     }
1911*5e09c8c3SJim Ingham 
1912*5e09c8c3SJim Ingham     virtual uint32_t
1913*5e09c8c3SJim Ingham     GetNumDefinitions ()
1914*5e09c8c3SJim Ingham     {
1915*5e09c8c3SJim Ingham       return sizeof (g_breakpoint_name_options) / sizeof (OptionDefinition);
1916*5e09c8c3SJim Ingham     }
1917*5e09c8c3SJim Ingham 
1918*5e09c8c3SJim Ingham     virtual const OptionDefinition*
1919*5e09c8c3SJim Ingham     GetDefinitions ()
1920*5e09c8c3SJim Ingham     {
1921*5e09c8c3SJim Ingham         return g_breakpoint_name_options;
1922*5e09c8c3SJim Ingham     }
1923*5e09c8c3SJim Ingham 
1924*5e09c8c3SJim Ingham     virtual Error
1925*5e09c8c3SJim Ingham     SetOptionValue (CommandInterpreter &interpreter,
1926*5e09c8c3SJim Ingham                     uint32_t option_idx,
1927*5e09c8c3SJim Ingham                     const char *option_value)
1928*5e09c8c3SJim Ingham     {
1929*5e09c8c3SJim Ingham         Error error;
1930*5e09c8c3SJim Ingham         const int short_option = g_breakpoint_name_options[option_idx].short_option;
1931*5e09c8c3SJim Ingham 
1932*5e09c8c3SJim Ingham         switch (short_option)
1933*5e09c8c3SJim Ingham         {
1934*5e09c8c3SJim Ingham         case 'N':
1935*5e09c8c3SJim Ingham             if (BreakpointID::StringIsBreakpointName(option_value, error) && error.Success())
1936*5e09c8c3SJim Ingham                 m_name.SetValueFromCString(option_value);
1937*5e09c8c3SJim Ingham             break;
1938*5e09c8c3SJim Ingham 
1939*5e09c8c3SJim Ingham         case 'B':
1940*5e09c8c3SJim Ingham             if (m_breakpoint.SetValueFromCString(option_value).Fail())
1941*5e09c8c3SJim Ingham                 error.SetErrorStringWithFormat ("unrecognized value \"%s\" for breakpoint", option_value);
1942*5e09c8c3SJim Ingham             break;
1943*5e09c8c3SJim Ingham         case 'D':
1944*5e09c8c3SJim Ingham             if (m_use_dummy.SetValueFromCString(option_value).Fail())
1945*5e09c8c3SJim Ingham                 error.SetErrorStringWithFormat ("unrecognized value \"%s\" for use-dummy", option_value);
1946*5e09c8c3SJim Ingham             break;
1947*5e09c8c3SJim Ingham 
1948*5e09c8c3SJim Ingham         default:
1949*5e09c8c3SJim Ingham               error.SetErrorStringWithFormat("unrecognized short option '%c'", short_option);
1950*5e09c8c3SJim Ingham               break;
1951*5e09c8c3SJim Ingham         }
1952*5e09c8c3SJim Ingham         return error;
1953*5e09c8c3SJim Ingham     }
1954*5e09c8c3SJim Ingham 
1955*5e09c8c3SJim Ingham     virtual void
1956*5e09c8c3SJim Ingham     OptionParsingStarting (CommandInterpreter &interpreter)
1957*5e09c8c3SJim Ingham     {
1958*5e09c8c3SJim Ingham         m_name.Clear();
1959*5e09c8c3SJim Ingham         m_breakpoint.Clear();
1960*5e09c8c3SJim Ingham         m_use_dummy.Clear();
1961*5e09c8c3SJim Ingham         m_use_dummy.SetDefaultValue(false);
1962*5e09c8c3SJim Ingham     }
1963*5e09c8c3SJim Ingham 
1964*5e09c8c3SJim Ingham     OptionValueString m_name;
1965*5e09c8c3SJim Ingham     OptionValueUInt64 m_breakpoint;
1966*5e09c8c3SJim Ingham     OptionValueBoolean m_use_dummy;
1967*5e09c8c3SJim Ingham };
1968*5e09c8c3SJim Ingham 
1969*5e09c8c3SJim Ingham 
1970*5e09c8c3SJim Ingham class CommandObjectBreakpointNameAdd : public CommandObjectParsed
1971*5e09c8c3SJim Ingham {
1972*5e09c8c3SJim Ingham public:
1973*5e09c8c3SJim Ingham     CommandObjectBreakpointNameAdd (CommandInterpreter &interpreter) :
1974*5e09c8c3SJim Ingham         CommandObjectParsed (interpreter,
1975*5e09c8c3SJim Ingham                              "add",
1976*5e09c8c3SJim Ingham                              "Add a name to the breakpoints provided.",
1977*5e09c8c3SJim Ingham                              "breakpoint name add <command-options> <breakpoint-id-list>"),
1978*5e09c8c3SJim Ingham         m_name_options(),
1979*5e09c8c3SJim Ingham         m_option_group(interpreter)
1980*5e09c8c3SJim Ingham         {
1981*5e09c8c3SJim Ingham             // Create the first variant for the first (and only) argument for this command.
1982*5e09c8c3SJim Ingham             CommandArgumentEntry arg1;
1983*5e09c8c3SJim Ingham             CommandArgumentData id_arg;
1984*5e09c8c3SJim Ingham             id_arg.arg_type = eArgTypeBreakpointID;
1985*5e09c8c3SJim Ingham             id_arg.arg_repetition = eArgRepeatOptional;
1986*5e09c8c3SJim Ingham             arg1.push_back(id_arg);
1987*5e09c8c3SJim Ingham             m_arguments.push_back (arg1);
1988*5e09c8c3SJim Ingham 
1989*5e09c8c3SJim Ingham             m_option_group.Append (&m_name_options, LLDB_OPT_SET_1, LLDB_OPT_SET_ALL);
1990*5e09c8c3SJim Ingham             m_option_group.Finalize();
1991*5e09c8c3SJim Ingham         }
1992*5e09c8c3SJim Ingham 
1993*5e09c8c3SJim Ingham     virtual
1994*5e09c8c3SJim Ingham     ~CommandObjectBreakpointNameAdd () {}
1995*5e09c8c3SJim Ingham 
1996*5e09c8c3SJim Ingham   Options *
1997*5e09c8c3SJim Ingham   GetOptions ()
1998*5e09c8c3SJim Ingham   {
1999*5e09c8c3SJim Ingham     return &m_option_group;
2000*5e09c8c3SJim Ingham   }
2001*5e09c8c3SJim Ingham 
2002*5e09c8c3SJim Ingham protected:
2003*5e09c8c3SJim Ingham     virtual bool
2004*5e09c8c3SJim Ingham     DoExecute (Args& command, CommandReturnObject &result)
2005*5e09c8c3SJim Ingham     {
2006*5e09c8c3SJim Ingham         if (!m_name_options.m_name.OptionWasSet())
2007*5e09c8c3SJim Ingham         {
2008*5e09c8c3SJim Ingham             result.SetError("No name option provided.");
2009*5e09c8c3SJim Ingham             return false;
2010*5e09c8c3SJim Ingham         }
2011*5e09c8c3SJim Ingham 
2012*5e09c8c3SJim Ingham         Target *target = GetSelectedOrDummyTarget(m_name_options.m_use_dummy.GetCurrentValue());
2013*5e09c8c3SJim Ingham 
2014*5e09c8c3SJim Ingham         if (target == NULL)
2015*5e09c8c3SJim Ingham         {
2016*5e09c8c3SJim Ingham             result.AppendError ("Invalid target. No existing target or breakpoints.");
2017*5e09c8c3SJim Ingham             result.SetStatus (eReturnStatusFailed);
2018*5e09c8c3SJim Ingham             return false;
2019*5e09c8c3SJim Ingham         }
2020*5e09c8c3SJim Ingham 
2021*5e09c8c3SJim Ingham         Mutex::Locker locker;
2022*5e09c8c3SJim Ingham         target->GetBreakpointList().GetListMutex(locker);
2023*5e09c8c3SJim Ingham 
2024*5e09c8c3SJim Ingham         const BreakpointList &breakpoints = target->GetBreakpointList();
2025*5e09c8c3SJim Ingham 
2026*5e09c8c3SJim Ingham         size_t num_breakpoints = breakpoints.GetSize();
2027*5e09c8c3SJim Ingham         if (num_breakpoints == 0)
2028*5e09c8c3SJim Ingham         {
2029*5e09c8c3SJim Ingham             result.SetError("No breakpoints, cannot add names.");
2030*5e09c8c3SJim Ingham             result.SetStatus (eReturnStatusFailed);
2031*5e09c8c3SJim Ingham             return false;
2032*5e09c8c3SJim Ingham         }
2033*5e09c8c3SJim Ingham 
2034*5e09c8c3SJim Ingham         // Particular breakpoint selected; disable that breakpoint.
2035*5e09c8c3SJim Ingham         BreakpointIDList valid_bp_ids;
2036*5e09c8c3SJim Ingham         CommandObjectMultiwordBreakpoint::VerifyBreakpointIDs (command, target, result, &valid_bp_ids);
2037*5e09c8c3SJim Ingham 
2038*5e09c8c3SJim Ingham         if (result.Succeeded())
2039*5e09c8c3SJim Ingham         {
2040*5e09c8c3SJim Ingham             if (valid_bp_ids.GetSize() == 0)
2041*5e09c8c3SJim Ingham             {
2042*5e09c8c3SJim Ingham                 result.SetError("No breakpoints specified, cannot add names.");
2043*5e09c8c3SJim Ingham                 result.SetStatus (eReturnStatusFailed);
2044*5e09c8c3SJim Ingham                 return false;
2045*5e09c8c3SJim Ingham             }
2046*5e09c8c3SJim Ingham             size_t num_valid_ids = valid_bp_ids.GetSize();
2047*5e09c8c3SJim Ingham             for (size_t index = 0; index < num_valid_ids; index++)
2048*5e09c8c3SJim Ingham             {
2049*5e09c8c3SJim Ingham                 lldb::break_id_t bp_id = valid_bp_ids.GetBreakpointIDAtIndex(index).GetBreakpointID();
2050*5e09c8c3SJim Ingham                 BreakpointSP bp_sp = breakpoints.FindBreakpointByID(bp_id);
2051*5e09c8c3SJim Ingham                 Error error;  // We don't need to check the error here, since the option parser checked it...
2052*5e09c8c3SJim Ingham                 bp_sp->AddName(m_name_options.m_name.GetCurrentValue(), error);
2053*5e09c8c3SJim Ingham             }
2054*5e09c8c3SJim Ingham         }
2055*5e09c8c3SJim Ingham 
2056*5e09c8c3SJim Ingham         return true;
2057*5e09c8c3SJim Ingham     }
2058*5e09c8c3SJim Ingham 
2059*5e09c8c3SJim Ingham private:
2060*5e09c8c3SJim Ingham     BreakpointNameOptionGroup m_name_options;
2061*5e09c8c3SJim Ingham     OptionGroupOptions m_option_group;
2062*5e09c8c3SJim Ingham };
2063*5e09c8c3SJim Ingham 
2064*5e09c8c3SJim Ingham 
2065*5e09c8c3SJim Ingham 
2066*5e09c8c3SJim Ingham class CommandObjectBreakpointNameDelete : public CommandObjectParsed
2067*5e09c8c3SJim Ingham {
2068*5e09c8c3SJim Ingham public:
2069*5e09c8c3SJim Ingham     CommandObjectBreakpointNameDelete (CommandInterpreter &interpreter) :
2070*5e09c8c3SJim Ingham         CommandObjectParsed (interpreter,
2071*5e09c8c3SJim Ingham                              "delete",
2072*5e09c8c3SJim Ingham                              "Delete a name from the breakpoints provided.",
2073*5e09c8c3SJim Ingham                              "breakpoint name delete <command-options> <breakpoint-id-list>"),
2074*5e09c8c3SJim Ingham         m_name_options(),
2075*5e09c8c3SJim Ingham         m_option_group(interpreter)
2076*5e09c8c3SJim Ingham     {
2077*5e09c8c3SJim Ingham         // Create the first variant for the first (and only) argument for this command.
2078*5e09c8c3SJim Ingham         CommandArgumentEntry arg1;
2079*5e09c8c3SJim Ingham         CommandArgumentData id_arg;
2080*5e09c8c3SJim Ingham         id_arg.arg_type = eArgTypeBreakpointID;
2081*5e09c8c3SJim Ingham         id_arg.arg_repetition = eArgRepeatOptional;
2082*5e09c8c3SJim Ingham         arg1.push_back(id_arg);
2083*5e09c8c3SJim Ingham         m_arguments.push_back (arg1);
2084*5e09c8c3SJim Ingham 
2085*5e09c8c3SJim Ingham         m_option_group.Append (&m_name_options, LLDB_OPT_SET_1, LLDB_OPT_SET_ALL);
2086*5e09c8c3SJim Ingham         m_option_group.Finalize();
2087*5e09c8c3SJim Ingham     }
2088*5e09c8c3SJim Ingham 
2089*5e09c8c3SJim Ingham     virtual
2090*5e09c8c3SJim Ingham     ~CommandObjectBreakpointNameDelete () {}
2091*5e09c8c3SJim Ingham 
2092*5e09c8c3SJim Ingham   Options *
2093*5e09c8c3SJim Ingham   GetOptions ()
2094*5e09c8c3SJim Ingham   {
2095*5e09c8c3SJim Ingham     return &m_option_group;
2096*5e09c8c3SJim Ingham   }
2097*5e09c8c3SJim Ingham 
2098*5e09c8c3SJim Ingham protected:
2099*5e09c8c3SJim Ingham     virtual bool
2100*5e09c8c3SJim Ingham     DoExecute (Args& command, CommandReturnObject &result)
2101*5e09c8c3SJim Ingham     {
2102*5e09c8c3SJim Ingham         if (!m_name_options.m_name.OptionWasSet())
2103*5e09c8c3SJim Ingham         {
2104*5e09c8c3SJim Ingham             result.SetError("No name option provided.");
2105*5e09c8c3SJim Ingham             return false;
2106*5e09c8c3SJim Ingham         }
2107*5e09c8c3SJim Ingham 
2108*5e09c8c3SJim Ingham         Target *target = GetSelectedOrDummyTarget(m_name_options.m_use_dummy.GetCurrentValue());
2109*5e09c8c3SJim Ingham 
2110*5e09c8c3SJim Ingham         if (target == NULL)
2111*5e09c8c3SJim Ingham         {
2112*5e09c8c3SJim Ingham             result.AppendError ("Invalid target. No existing target or breakpoints.");
2113*5e09c8c3SJim Ingham             result.SetStatus (eReturnStatusFailed);
2114*5e09c8c3SJim Ingham             return false;
2115*5e09c8c3SJim Ingham         }
2116*5e09c8c3SJim Ingham 
2117*5e09c8c3SJim Ingham         Mutex::Locker locker;
2118*5e09c8c3SJim Ingham         target->GetBreakpointList().GetListMutex(locker);
2119*5e09c8c3SJim Ingham 
2120*5e09c8c3SJim Ingham         const BreakpointList &breakpoints = target->GetBreakpointList();
2121*5e09c8c3SJim Ingham 
2122*5e09c8c3SJim Ingham         size_t num_breakpoints = breakpoints.GetSize();
2123*5e09c8c3SJim Ingham         if (num_breakpoints == 0)
2124*5e09c8c3SJim Ingham         {
2125*5e09c8c3SJim Ingham             result.SetError("No breakpoints, cannot delete names.");
2126*5e09c8c3SJim Ingham             result.SetStatus (eReturnStatusFailed);
2127*5e09c8c3SJim Ingham             return false;
2128*5e09c8c3SJim Ingham         }
2129*5e09c8c3SJim Ingham 
2130*5e09c8c3SJim Ingham         // Particular breakpoint selected; disable that breakpoint.
2131*5e09c8c3SJim Ingham         BreakpointIDList valid_bp_ids;
2132*5e09c8c3SJim Ingham         CommandObjectMultiwordBreakpoint::VerifyBreakpointIDs (command, target, result, &valid_bp_ids);
2133*5e09c8c3SJim Ingham 
2134*5e09c8c3SJim Ingham         if (result.Succeeded())
2135*5e09c8c3SJim Ingham         {
2136*5e09c8c3SJim Ingham             if (valid_bp_ids.GetSize() == 0)
2137*5e09c8c3SJim Ingham             {
2138*5e09c8c3SJim Ingham                 result.SetError("No breakpoints specified, cannot delete names.");
2139*5e09c8c3SJim Ingham                 result.SetStatus (eReturnStatusFailed);
2140*5e09c8c3SJim Ingham                 return false;
2141*5e09c8c3SJim Ingham             }
2142*5e09c8c3SJim Ingham             size_t num_valid_ids = valid_bp_ids.GetSize();
2143*5e09c8c3SJim Ingham             for (size_t index = 0; index < num_valid_ids; index++)
2144*5e09c8c3SJim Ingham             {
2145*5e09c8c3SJim Ingham                 lldb::break_id_t bp_id = valid_bp_ids.GetBreakpointIDAtIndex(index).GetBreakpointID();
2146*5e09c8c3SJim Ingham                 BreakpointSP bp_sp = breakpoints.FindBreakpointByID(bp_id);
2147*5e09c8c3SJim Ingham                 bp_sp->RemoveName(m_name_options.m_name.GetCurrentValue());
2148*5e09c8c3SJim Ingham             }
2149*5e09c8c3SJim Ingham         }
2150*5e09c8c3SJim Ingham 
2151*5e09c8c3SJim Ingham         return true;
2152*5e09c8c3SJim Ingham     }
2153*5e09c8c3SJim Ingham 
2154*5e09c8c3SJim Ingham private:
2155*5e09c8c3SJim Ingham     BreakpointNameOptionGroup m_name_options;
2156*5e09c8c3SJim Ingham     OptionGroupOptions m_option_group;
2157*5e09c8c3SJim Ingham };
2158*5e09c8c3SJim Ingham 
2159*5e09c8c3SJim Ingham class CommandObjectBreakpointNameList : public CommandObjectParsed
2160*5e09c8c3SJim Ingham {
2161*5e09c8c3SJim Ingham public:
2162*5e09c8c3SJim Ingham     CommandObjectBreakpointNameList (CommandInterpreter &interpreter) :
2163*5e09c8c3SJim Ingham         CommandObjectParsed (interpreter,
2164*5e09c8c3SJim Ingham                              "list",
2165*5e09c8c3SJim Ingham                              "List either the names for a breakpoint or the breakpoints for a given name.",
2166*5e09c8c3SJim Ingham                              "breakpoint name list <command-options>"),
2167*5e09c8c3SJim Ingham         m_name_options(),
2168*5e09c8c3SJim Ingham         m_option_group(interpreter)
2169*5e09c8c3SJim Ingham     {
2170*5e09c8c3SJim Ingham         m_option_group.Append (&m_name_options);
2171*5e09c8c3SJim Ingham         m_option_group.Finalize();
2172*5e09c8c3SJim Ingham     }
2173*5e09c8c3SJim Ingham 
2174*5e09c8c3SJim Ingham     virtual
2175*5e09c8c3SJim Ingham     ~CommandObjectBreakpointNameList () {}
2176*5e09c8c3SJim Ingham 
2177*5e09c8c3SJim Ingham   Options *
2178*5e09c8c3SJim Ingham   GetOptions ()
2179*5e09c8c3SJim Ingham   {
2180*5e09c8c3SJim Ingham     return &m_option_group;
2181*5e09c8c3SJim Ingham   }
2182*5e09c8c3SJim Ingham 
2183*5e09c8c3SJim Ingham protected:
2184*5e09c8c3SJim Ingham protected:
2185*5e09c8c3SJim Ingham     virtual bool
2186*5e09c8c3SJim Ingham     DoExecute (Args& command, CommandReturnObject &result)
2187*5e09c8c3SJim Ingham     {
2188*5e09c8c3SJim Ingham         Target *target = GetSelectedOrDummyTarget(m_name_options.m_use_dummy.GetCurrentValue());
2189*5e09c8c3SJim Ingham 
2190*5e09c8c3SJim Ingham         if (target == NULL)
2191*5e09c8c3SJim Ingham         {
2192*5e09c8c3SJim Ingham             result.AppendError ("Invalid target. No existing target or breakpoints.");
2193*5e09c8c3SJim Ingham             result.SetStatus (eReturnStatusFailed);
2194*5e09c8c3SJim Ingham             return false;
2195*5e09c8c3SJim Ingham         }
2196*5e09c8c3SJim Ingham 
2197*5e09c8c3SJim Ingham         if (m_name_options.m_name.OptionWasSet())
2198*5e09c8c3SJim Ingham         {
2199*5e09c8c3SJim Ingham             const char *name = m_name_options.m_name.GetCurrentValue();
2200*5e09c8c3SJim Ingham             Mutex::Locker locker;
2201*5e09c8c3SJim Ingham             target->GetBreakpointList().GetListMutex(locker);
2202*5e09c8c3SJim Ingham 
2203*5e09c8c3SJim Ingham             BreakpointList &breakpoints = target->GetBreakpointList();
2204*5e09c8c3SJim Ingham             for (BreakpointSP bp_sp : breakpoints.Breakpoints())
2205*5e09c8c3SJim Ingham             {
2206*5e09c8c3SJim Ingham                 if (bp_sp->MatchesName(name))
2207*5e09c8c3SJim Ingham                 {
2208*5e09c8c3SJim Ingham                     StreamString s;
2209*5e09c8c3SJim Ingham                     bp_sp->GetDescription(&s, eDescriptionLevelBrief);
2210*5e09c8c3SJim Ingham                     s.EOL();
2211*5e09c8c3SJim Ingham                     result.AppendMessage(s.GetData());
2212*5e09c8c3SJim Ingham                 }
2213*5e09c8c3SJim Ingham             }
2214*5e09c8c3SJim Ingham 
2215*5e09c8c3SJim Ingham         }
2216*5e09c8c3SJim Ingham         else if (m_name_options.m_breakpoint.OptionWasSet())
2217*5e09c8c3SJim Ingham         {
2218*5e09c8c3SJim Ingham             BreakpointSP bp_sp = target->GetBreakpointList().FindBreakpointByID(m_name_options.m_breakpoint.GetCurrentValue());
2219*5e09c8c3SJim Ingham             if (bp_sp)
2220*5e09c8c3SJim Ingham             {
2221*5e09c8c3SJim Ingham                 std::vector<std::string> names;
2222*5e09c8c3SJim Ingham                 bp_sp->GetNames (names);
2223*5e09c8c3SJim Ingham                 result.AppendMessage ("Names:");
2224*5e09c8c3SJim Ingham                 for (auto name : names)
2225*5e09c8c3SJim Ingham                     result.AppendMessageWithFormat ("    %s\n", name.c_str());
2226*5e09c8c3SJim Ingham             }
2227*5e09c8c3SJim Ingham             else
2228*5e09c8c3SJim Ingham             {
2229*5e09c8c3SJim Ingham                 result.AppendErrorWithFormat ("Could not find breakpoint %" PRId64 ".\n",
2230*5e09c8c3SJim Ingham                                            m_name_options.m_breakpoint.GetCurrentValue());
2231*5e09c8c3SJim Ingham                 result.SetStatus (eReturnStatusFailed);
2232*5e09c8c3SJim Ingham                 return false;
2233*5e09c8c3SJim Ingham             }
2234*5e09c8c3SJim Ingham         }
2235*5e09c8c3SJim Ingham         else
2236*5e09c8c3SJim Ingham         {
2237*5e09c8c3SJim Ingham             result.SetError ("Must specify -N or -B option to list.");
2238*5e09c8c3SJim Ingham             result.SetStatus (eReturnStatusFailed);
2239*5e09c8c3SJim Ingham             return false;
2240*5e09c8c3SJim Ingham         }
2241*5e09c8c3SJim Ingham         return true;
2242*5e09c8c3SJim Ingham     }
2243*5e09c8c3SJim Ingham 
2244*5e09c8c3SJim Ingham private:
2245*5e09c8c3SJim Ingham     BreakpointNameOptionGroup m_name_options;
2246*5e09c8c3SJim Ingham     OptionGroupOptions m_option_group;
2247*5e09c8c3SJim Ingham };
2248*5e09c8c3SJim Ingham 
2249*5e09c8c3SJim Ingham //-------------------------------------------------------------------------
2250*5e09c8c3SJim Ingham // CommandObjectMultiwordBreakpoint
2251*5e09c8c3SJim Ingham //-------------------------------------------------------------------------
2252*5e09c8c3SJim Ingham class CommandObjectBreakpointName : public CommandObjectMultiword
2253*5e09c8c3SJim Ingham {
2254*5e09c8c3SJim Ingham public:
2255*5e09c8c3SJim Ingham     CommandObjectBreakpointName (CommandInterpreter &interpreter) :
2256*5e09c8c3SJim Ingham         CommandObjectMultiword(interpreter,
2257*5e09c8c3SJim Ingham                                 "name",
2258*5e09c8c3SJim Ingham                                 "A set of commands to manage name tags for breakpoints",
2259*5e09c8c3SJim Ingham                                 "breakpoint name <command> [<command-options>]")
2260*5e09c8c3SJim Ingham     {
2261*5e09c8c3SJim Ingham         CommandObjectSP add_command_object (new CommandObjectBreakpointNameAdd (interpreter));
2262*5e09c8c3SJim Ingham         CommandObjectSP delete_command_object (new CommandObjectBreakpointNameDelete (interpreter));
2263*5e09c8c3SJim Ingham         CommandObjectSP list_command_object (new CommandObjectBreakpointNameList (interpreter));
2264*5e09c8c3SJim Ingham 
2265*5e09c8c3SJim Ingham         LoadSubCommand ("add", add_command_object);
2266*5e09c8c3SJim Ingham         LoadSubCommand ("delete", delete_command_object);
2267*5e09c8c3SJim Ingham         LoadSubCommand ("list", list_command_object);
2268*5e09c8c3SJim Ingham 
2269*5e09c8c3SJim Ingham     }
2270*5e09c8c3SJim Ingham 
2271*5e09c8c3SJim Ingham     virtual
2272*5e09c8c3SJim Ingham     ~CommandObjectBreakpointName ()
2273*5e09c8c3SJim Ingham     {
2274*5e09c8c3SJim Ingham     }
2275*5e09c8c3SJim Ingham 
2276*5e09c8c3SJim Ingham };
2277*5e09c8c3SJim Ingham 
2278*5e09c8c3SJim Ingham 
2279*5e09c8c3SJim Ingham //-------------------------------------------------------------------------
228030fdc8d8SChris Lattner // CommandObjectMultiwordBreakpoint
228130fdc8d8SChris Lattner //-------------------------------------------------------------------------
2282ae1c4cf5SJim Ingham #pragma mark MultiwordBreakpoint
228330fdc8d8SChris Lattner 
22846611103cSGreg Clayton CommandObjectMultiwordBreakpoint::CommandObjectMultiwordBreakpoint (CommandInterpreter &interpreter) :
2285a7015092SGreg Clayton     CommandObjectMultiword (interpreter,
2286a7015092SGreg Clayton                             "breakpoint",
228746fbc60fSJim Ingham                             "A set of commands for operating on breakpoints. Also see _regexp-break.",
228830fdc8d8SChris Lattner                             "breakpoint <command> [<command-options>]")
228930fdc8d8SChris Lattner {
2290a7015092SGreg Clayton     CommandObjectSP list_command_object (new CommandObjectBreakpointList (interpreter));
2291a7015092SGreg Clayton     CommandObjectSP enable_command_object (new CommandObjectBreakpointEnable (interpreter));
2292a7015092SGreg Clayton     CommandObjectSP disable_command_object (new CommandObjectBreakpointDisable (interpreter));
2293b7234e40SJohnny Chen     CommandObjectSP clear_command_object (new CommandObjectBreakpointClear (interpreter));
2294b7234e40SJohnny Chen     CommandObjectSP delete_command_object (new CommandObjectBreakpointDelete (interpreter));
2295a7015092SGreg Clayton     CommandObjectSP set_command_object (new CommandObjectBreakpointSet (interpreter));
229630fdc8d8SChris Lattner     CommandObjectSP command_command_object (new CommandObjectBreakpointCommand (interpreter));
2297a7015092SGreg Clayton     CommandObjectSP modify_command_object (new CommandObjectBreakpointModify(interpreter));
2298*5e09c8c3SJim Ingham     CommandObjectSP name_command_object (new CommandObjectBreakpointName(interpreter));
229930fdc8d8SChris Lattner 
2300b7234e40SJohnny Chen     list_command_object->SetCommandName ("breakpoint list");
230130fdc8d8SChris Lattner     enable_command_object->SetCommandName("breakpoint enable");
230230fdc8d8SChris Lattner     disable_command_object->SetCommandName("breakpoint disable");
2303b7234e40SJohnny Chen     clear_command_object->SetCommandName("breakpoint clear");
2304b7234e40SJohnny Chen     delete_command_object->SetCommandName("breakpoint delete");
2305ae1c4cf5SJim Ingham     set_command_object->SetCommandName("breakpoint set");
2306b7234e40SJohnny Chen     command_command_object->SetCommandName ("breakpoint command");
2307b7234e40SJohnny Chen     modify_command_object->SetCommandName ("breakpoint modify");
2308*5e09c8c3SJim Ingham     name_command_object->SetCommandName ("breakpoint name");
230930fdc8d8SChris Lattner 
231023f59509SGreg Clayton     LoadSubCommand ("list",       list_command_object);
231123f59509SGreg Clayton     LoadSubCommand ("enable",     enable_command_object);
231223f59509SGreg Clayton     LoadSubCommand ("disable",    disable_command_object);
231323f59509SGreg Clayton     LoadSubCommand ("clear",      clear_command_object);
231423f59509SGreg Clayton     LoadSubCommand ("delete",     delete_command_object);
231523f59509SGreg Clayton     LoadSubCommand ("set",        set_command_object);
231623f59509SGreg Clayton     LoadSubCommand ("command",    command_command_object);
231723f59509SGreg Clayton     LoadSubCommand ("modify",     modify_command_object);
2318*5e09c8c3SJim Ingham     LoadSubCommand ("name",       name_command_object);
231930fdc8d8SChris Lattner }
232030fdc8d8SChris Lattner 
232130fdc8d8SChris Lattner CommandObjectMultiwordBreakpoint::~CommandObjectMultiwordBreakpoint ()
232230fdc8d8SChris Lattner {
232330fdc8d8SChris Lattner }
232430fdc8d8SChris Lattner 
232530fdc8d8SChris Lattner void
2326*5e09c8c3SJim Ingham CommandObjectMultiwordBreakpoint::VerifyIDs (Args &args,
2327*5e09c8c3SJim Ingham                                              Target *target,
2328*5e09c8c3SJim Ingham                                              bool allow_locations,
2329*5e09c8c3SJim Ingham                                              CommandReturnObject &result,
233030fdc8d8SChris Lattner                                              BreakpointIDList *valid_ids)
233130fdc8d8SChris Lattner {
233230fdc8d8SChris Lattner     // args can be strings representing 1). integers (for breakpoint ids)
233330fdc8d8SChris Lattner     //                                  2). the full breakpoint & location canonical representation
233430fdc8d8SChris Lattner     //                                  3). the word "to" or a hyphen, representing a range (in which case there
233530fdc8d8SChris Lattner     //                                      had *better* be an entry both before & after of one of the first two types.
2336*5e09c8c3SJim Ingham     //                                  4). A breakpoint name
233736f3b369SJim Ingham     // If args is empty, we will use the last created breakpoint (if there is one.)
233830fdc8d8SChris Lattner 
233930fdc8d8SChris Lattner     Args temp_args;
234030fdc8d8SChris Lattner 
234136f3b369SJim Ingham     if (args.GetArgumentCount() == 0)
234236f3b369SJim Ingham     {
23434d122c40SGreg Clayton         if (target->GetLastCreatedBreakpoint())
234436f3b369SJim Ingham         {
234536f3b369SJim Ingham             valid_ids->AddBreakpointID (BreakpointID(target->GetLastCreatedBreakpoint()->GetID(), LLDB_INVALID_BREAK_ID));
234636f3b369SJim Ingham             result.SetStatus (eReturnStatusSuccessFinishNoResult);
234736f3b369SJim Ingham         }
234836f3b369SJim Ingham         else
234936f3b369SJim Ingham         {
235036f3b369SJim Ingham             result.AppendError("No breakpoint specified and no last created breakpoint.");
235136f3b369SJim Ingham             result.SetStatus (eReturnStatusFailed);
235236f3b369SJim Ingham         }
235336f3b369SJim Ingham         return;
235436f3b369SJim Ingham     }
235536f3b369SJim Ingham 
235630fdc8d8SChris Lattner     // Create a new Args variable to use; copy any non-breakpoint-id-ranges stuff directly from the old ARGS to
235730fdc8d8SChris Lattner     // the new TEMP_ARGS.  Do not copy breakpoint id range strings over; instead generate a list of strings for
235830fdc8d8SChris Lattner     // all the breakpoint ids in the range, and shove all of those breakpoint id strings into TEMP_ARGS.
235930fdc8d8SChris Lattner 
2360*5e09c8c3SJim Ingham     BreakpointIDList::FindAndReplaceIDRanges (args, target, allow_locations, result, temp_args);
236130fdc8d8SChris Lattner 
236230fdc8d8SChris Lattner     // NOW, convert the list of breakpoint id strings in TEMP_ARGS into an actual BreakpointIDList:
236330fdc8d8SChris Lattner 
2364c982c768SGreg Clayton     valid_ids->InsertStringArray (temp_args.GetConstArgumentVector(), temp_args.GetArgumentCount(), result);
236530fdc8d8SChris Lattner 
236630fdc8d8SChris Lattner     // At this point,  all of the breakpoint ids that the user passed in have been converted to breakpoint IDs
236730fdc8d8SChris Lattner     // and put into valid_ids.
236830fdc8d8SChris Lattner 
236930fdc8d8SChris Lattner     if (result.Succeeded())
237030fdc8d8SChris Lattner     {
237130fdc8d8SChris Lattner         // Now that we've converted everything from args into a list of breakpoint ids, go through our tentative list
237230fdc8d8SChris Lattner         // of breakpoint id's and verify that they correspond to valid/currently set breakpoints.
237330fdc8d8SChris Lattner 
2374c982c768SGreg Clayton         const size_t count = valid_ids->GetSize();
2375c982c768SGreg Clayton         for (size_t i = 0; i < count; ++i)
237630fdc8d8SChris Lattner         {
237730fdc8d8SChris Lattner             BreakpointID cur_bp_id = valid_ids->GetBreakpointIDAtIndex (i);
237830fdc8d8SChris Lattner             Breakpoint *breakpoint = target->GetBreakpointByID (cur_bp_id.GetBreakpointID()).get();
237930fdc8d8SChris Lattner             if (breakpoint != NULL)
238030fdc8d8SChris Lattner             {
2381c7bece56SGreg Clayton                 const size_t num_locations = breakpoint->GetNumLocations();
23823985c8c6SSaleem Abdulrasool                 if (static_cast<size_t>(cur_bp_id.GetLocationID()) > num_locations)
238330fdc8d8SChris Lattner                 {
238430fdc8d8SChris Lattner                     StreamString id_str;
2385c982c768SGreg Clayton                     BreakpointID::GetCanonicalReference (&id_str,
2386c982c768SGreg Clayton                                                          cur_bp_id.GetBreakpointID(),
238730fdc8d8SChris Lattner                                                          cur_bp_id.GetLocationID());
2388c982c768SGreg Clayton                     i = valid_ids->GetSize() + 1;
238930fdc8d8SChris Lattner                     result.AppendErrorWithFormat ("'%s' is not a currently valid breakpoint/location id.\n",
239030fdc8d8SChris Lattner                                                  id_str.GetData());
239130fdc8d8SChris Lattner                     result.SetStatus (eReturnStatusFailed);
239230fdc8d8SChris Lattner                 }
239330fdc8d8SChris Lattner             }
239430fdc8d8SChris Lattner             else
239530fdc8d8SChris Lattner             {
2396c982c768SGreg Clayton                 i = valid_ids->GetSize() + 1;
239730fdc8d8SChris Lattner                 result.AppendErrorWithFormat ("'%d' is not a currently valid breakpoint id.\n", cur_bp_id.GetBreakpointID());
239830fdc8d8SChris Lattner                 result.SetStatus (eReturnStatusFailed);
239930fdc8d8SChris Lattner             }
240030fdc8d8SChris Lattner         }
240130fdc8d8SChris Lattner     }
240230fdc8d8SChris Lattner }
2403