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