blob: 162bfb4b5a76ebdec34f1b4d1cf79b008eedff9e [file] [log] [blame]
Chris Lattner30fdc8d2010-06-08 16:52:24 +00001//===-- CommandObjectBreakpoint.cpp -----------------------------*- C++ -*-===//
2//
3// The LLVM Compiler Infrastructure
4//
5// This file is distributed under the University of Illinois Open Source
6// License. See LICENSE.TXT for details.
7//
8//===----------------------------------------------------------------------===//
9
10#include "CommandObjectBreakpoint.h"
11#include "CommandObjectBreakpointCommand.h"
12
13// C Includes
14// C++ Includes
15// Other libraries and framework includes
16// Project includes
17#include "lldb/Breakpoint/Breakpoint.h"
18#include "lldb/Breakpoint/BreakpointIDList.h"
19#include "lldb/Breakpoint/BreakpointLocation.h"
Vince Harron5275aaa2015-01-15 20:08:35 +000020#include "lldb/Host/StringConvert.h"
Jim Ingham40af72e2010-06-15 19:49:27 +000021#include "lldb/Interpreter/Options.h"
Zachary Turner32abc6e2015-03-03 19:23:09 +000022#include "lldb/Interpreter/OptionValueBoolean.h"
Jim Ingham5e09c8c2014-12-16 23:40:14 +000023#include "lldb/Interpreter/OptionValueString.h"
24#include "lldb/Interpreter/OptionValueUInt64.h"
Chris Lattner30fdc8d2010-06-08 16:52:24 +000025#include "lldb/Core/RegularExpression.h"
26#include "lldb/Core/StreamString.h"
27#include "lldb/Interpreter/CommandInterpreter.h"
28#include "lldb/Interpreter/CommandReturnObject.h"
Zachary Turnera78bd7f2015-03-03 23:11:11 +000029#include "lldb/Target/LanguageRuntime.h"
Chris Lattner30fdc8d2010-06-08 16:52:24 +000030#include "lldb/Target/Target.h"
31#include "lldb/Interpreter/CommandCompletions.h"
Jason Molendab57e4a12013-11-04 09:33:30 +000032#include "lldb/Target/StackFrame.h"
Jim Ingham1b54c882010-06-16 02:00:15 +000033#include "lldb/Target/Thread.h"
34#include "lldb/Target/ThreadSpec.h"
Chris Lattner30fdc8d2010-06-08 16:52:24 +000035
Johnny Chenb7234e42010-10-28 17:27:46 +000036#include <vector>
37
Chris Lattner30fdc8d2010-06-08 16:52:24 +000038using namespace lldb;
39using namespace lldb_private;
40
41static void
Jim Ingham85e8b812011-02-19 02:53:09 +000042AddBreakpointDescription (Stream *s, Breakpoint *bp, lldb::DescriptionLevel level)
Chris Lattner30fdc8d2010-06-08 16:52:24 +000043{
44 s->IndentMore();
45 bp->GetDescription (s, level, true);
46 s->IndentLess();
47 s->EOL();
48}
49
50//-------------------------------------------------------------------------
Jim Ingham5a988412012-06-08 21:56:10 +000051// CommandObjectBreakpointSet
Chris Lattner30fdc8d2010-06-08 16:52:24 +000052//-------------------------------------------------------------------------
53
Jim Ingham5a988412012-06-08 21:56:10 +000054
55class CommandObjectBreakpointSet : public CommandObjectParsed
Chris Lattner30fdc8d2010-06-08 16:52:24 +000056{
Jim Ingham5a988412012-06-08 21:56:10 +000057public:
Chris Lattner30fdc8d2010-06-08 16:52:24 +000058
Jim Ingham5a988412012-06-08 21:56:10 +000059 typedef enum BreakpointSetType
60 {
61 eSetTypeInvalid,
62 eSetTypeFileAndLine,
63 eSetTypeAddress,
64 eSetTypeFunctionName,
65 eSetTypeFunctionRegexp,
66 eSetTypeSourceRegexp,
67 eSetTypeException
68 } BreakpointSetType;
Chris Lattner30fdc8d2010-06-08 16:52:24 +000069
Jim Ingham5a988412012-06-08 21:56:10 +000070 CommandObjectBreakpointSet (CommandInterpreter &interpreter) :
71 CommandObjectParsed (interpreter,
72 "breakpoint set",
73 "Sets a breakpoint or set of breakpoints in the executable.",
74 "breakpoint set <cmd-options>"),
75 m_options (interpreter)
76 {
77 }
78
79
80 virtual
81 ~CommandObjectBreakpointSet () {}
82
83 virtual Options *
84 GetOptions ()
85 {
86 return &m_options;
87 }
88
89 class CommandOptions : public Options
90 {
91 public:
92
93 CommandOptions (CommandInterpreter &interpreter) :
94 Options (interpreter),
95 m_condition (),
96 m_filenames (),
97 m_line_num (0),
98 m_column (0),
Jim Ingham5a988412012-06-08 21:56:10 +000099 m_func_names (),
100 m_func_name_type_mask (eFunctionNameTypeNone),
101 m_func_regexp (),
102 m_source_text_regexp(),
103 m_modules (),
104 m_load_addr(),
105 m_ignore_count (0),
106 m_thread_id(LLDB_INVALID_THREAD_ID),
107 m_thread_index (UINT32_MAX),
108 m_thread_name(),
109 m_queue_name(),
110 m_catch_bp (false),
Greg Clayton1f746072012-08-29 21:13:06 +0000111 m_throw_bp (true),
Greg Claytoneb023e72013-10-11 19:48:25 +0000112 m_hardware (false),
Jim Inghama72b31c2015-04-22 19:42:18 +0000113 m_exception_language (eLanguageTypeUnknown),
Jim Inghamca36cd12012-10-05 19:16:31 +0000114 m_skip_prologue (eLazyBoolCalculate),
Jim Inghame7320522015-02-12 17:37:46 +0000115 m_one_shot (false),
Ilia K055ad9b2015-05-18 13:41:01 +0000116 m_all_files (false),
117 m_move_to_nearest_code (eLazyBoolCalculate)
Jim Ingham5a988412012-06-08 21:56:10 +0000118 {
119 }
120
121
122 virtual
123 ~CommandOptions () {}
124
125 virtual Error
126 SetOptionValue (uint32_t option_idx, const char *option_arg)
127 {
128 Error error;
Greg Clayton3bcdfc02012-12-04 00:32:51 +0000129 const int short_option = m_getopt_table[option_idx].val;
Jim Ingham5a988412012-06-08 21:56:10 +0000130
131 switch (short_option)
132 {
133 case 'a':
Greg Claytonb9d5df52012-12-06 22:49:16 +0000134 {
135 ExecutionContext exe_ctx (m_interpreter.GetExecutionContext());
136 m_load_addr = Args::StringToAddress(&exe_ctx, option_arg, LLDB_INVALID_ADDRESS, &error);
137 }
Jim Ingham5a988412012-06-08 21:56:10 +0000138 break;
139
Jim Inghame7320522015-02-12 17:37:46 +0000140 case 'A':
141 m_all_files = true;
142 break;
143
Jim Inghamca36cd12012-10-05 19:16:31 +0000144 case 'b':
145 m_func_names.push_back (option_arg);
146 m_func_name_type_mask |= eFunctionNameTypeBase;
147 break;
148
Jim Ingham5a988412012-06-08 21:56:10 +0000149 case 'C':
Jim Ingham63129912015-03-16 22:47:38 +0000150 {
151 bool success;
152 m_column = StringConvert::ToUInt32 (option_arg, 0, 0, &success);
153 if (!success)
154 error.SetErrorStringWithFormat("invalid column number: %s", option_arg);
Jim Ingham5a988412012-06-08 21:56:10 +0000155 break;
Jim Ingham63129912015-03-16 22:47:38 +0000156 }
Jim Ingham5a988412012-06-08 21:56:10 +0000157 case 'c':
158 m_condition.assign(option_arg);
159 break;
160
Jim Ingham33df7cd2014-12-06 01:28:03 +0000161 case 'D':
162 m_use_dummy = true;
163 break;
164
Jim Ingham5a988412012-06-08 21:56:10 +0000165 case 'E':
166 {
167 LanguageType language = LanguageRuntime::GetLanguageTypeFromString (option_arg);
168
169 switch (language)
170 {
171 case eLanguageTypeC89:
172 case eLanguageTypeC:
173 case eLanguageTypeC99:
Bruce Mitchener1d0089f2014-07-03 00:49:08 +0000174 case eLanguageTypeC11:
Jim Inghama72b31c2015-04-22 19:42:18 +0000175 m_exception_language = eLanguageTypeC;
Jim Ingham5a988412012-06-08 21:56:10 +0000176 break;
177 case eLanguageTypeC_plus_plus:
Bruce Mitchener1d0089f2014-07-03 00:49:08 +0000178 case eLanguageTypeC_plus_plus_03:
179 case eLanguageTypeC_plus_plus_11:
Bruce Mitchener2ba84a62015-02-06 06:46:52 +0000180 case eLanguageTypeC_plus_plus_14:
Jim Inghama72b31c2015-04-22 19:42:18 +0000181 m_exception_language = eLanguageTypeC_plus_plus;
Jim Ingham5a988412012-06-08 21:56:10 +0000182 break;
183 case eLanguageTypeObjC:
Jim Inghama72b31c2015-04-22 19:42:18 +0000184 m_exception_language = eLanguageTypeObjC;
Jim Ingham5a988412012-06-08 21:56:10 +0000185 break;
186 case eLanguageTypeObjC_plus_plus:
187 error.SetErrorStringWithFormat ("Set exception breakpoints separately for c++ and objective-c");
188 break;
189 case eLanguageTypeUnknown:
190 error.SetErrorStringWithFormat ("Unknown language type: '%s' for exception breakpoint", option_arg);
191 break;
192 default:
193 error.SetErrorStringWithFormat ("Unsupported language type: '%s' for exception breakpoint", option_arg);
194 }
195 }
196 break;
Jim Inghamca36cd12012-10-05 19:16:31 +0000197
198 case 'f':
199 m_filenames.AppendIfUnique (FileSpec(option_arg, false));
200 break;
201
202 case 'F':
203 m_func_names.push_back (option_arg);
204 m_func_name_type_mask |= eFunctionNameTypeFull;
205 break;
206
Jim Ingham5a988412012-06-08 21:56:10 +0000207 case 'h':
Greg Claytoneb023e72013-10-11 19:48:25 +0000208 {
209 bool success;
210 m_catch_bp = Args::StringToBoolean (option_arg, true, &success);
211 if (!success)
212 error.SetErrorStringWithFormat ("Invalid boolean value for on-catch option: '%s'", option_arg);
213 }
214 break;
215
216 case 'H':
217 m_hardware = true;
218 break;
219
Jim Inghamca36cd12012-10-05 19:16:31 +0000220 case 'i':
221 {
Vince Harron5275aaa2015-01-15 20:08:35 +0000222 m_ignore_count = StringConvert::ToUInt32(option_arg, UINT32_MAX, 0);
Jim Inghamca36cd12012-10-05 19:16:31 +0000223 if (m_ignore_count == UINT32_MAX)
224 error.SetErrorStringWithFormat ("invalid ignore count '%s'", option_arg);
225 break;
226 }
227
Jim Ingham5a988412012-06-08 21:56:10 +0000228 case 'K':
229 {
230 bool success;
231 bool value;
232 value = Args::StringToBoolean (option_arg, true, &success);
233 if (value)
234 m_skip_prologue = eLazyBoolYes;
235 else
236 m_skip_prologue = eLazyBoolNo;
237
238 if (!success)
239 error.SetErrorStringWithFormat ("Invalid boolean value for skip prologue option: '%s'", option_arg);
240 }
241 break;
Jim Inghamca36cd12012-10-05 19:16:31 +0000242
243 case 'l':
Jim Ingham63129912015-03-16 22:47:38 +0000244 {
245 bool success;
246 m_line_num = StringConvert::ToUInt32 (option_arg, 0, 0, &success);
247 if (!success)
248 error.SetErrorStringWithFormat ("invalid line number: %s.", option_arg);
Jim Inghamca36cd12012-10-05 19:16:31 +0000249 break;
Jim Ingham63129912015-03-16 22:47:38 +0000250 }
Ilia K055ad9b2015-05-18 13:41:01 +0000251
252 case 'm':
253 {
254 bool success;
255 bool value;
256 value = Args::StringToBoolean (option_arg, true, &success);
257 if (value)
258 m_move_to_nearest_code = eLazyBoolYes;
259 else
260 m_move_to_nearest_code = eLazyBoolNo;
261
262 if (!success)
263 error.SetErrorStringWithFormat ("Invalid boolean value for move-to-nearest-code option: '%s'", option_arg);
264 break;
265 }
266
Jim Inghamca36cd12012-10-05 19:16:31 +0000267 case 'M':
268 m_func_names.push_back (option_arg);
269 m_func_name_type_mask |= eFunctionNameTypeMethod;
270 break;
271
272 case 'n':
273 m_func_names.push_back (option_arg);
274 m_func_name_type_mask |= eFunctionNameTypeAuto;
275 break;
276
Jim Ingham5e09c8c2014-12-16 23:40:14 +0000277 case 'N':
278 if (BreakpointID::StringIsBreakpointName(option_arg, error))
279 m_breakpoint_names.push_back (option_arg);
Jim Ingham5e09c8c2014-12-16 23:40:14 +0000280 break;
281
Jim Inghamca36cd12012-10-05 19:16:31 +0000282 case 'o':
283 m_one_shot = true;
284 break;
285
Jim Inghama72b31c2015-04-22 19:42:18 +0000286 case 'O':
287 m_exception_extra_args.AppendArgument ("-O");
288 m_exception_extra_args.AppendArgument (option_arg);
289 break;
290
Jim Inghamca36cd12012-10-05 19:16:31 +0000291 case 'p':
292 m_source_text_regexp.assign (option_arg);
293 break;
294
295 case 'q':
296 m_queue_name.assign (option_arg);
297 break;
298
299 case 'r':
300 m_func_regexp.assign (option_arg);
301 break;
302
303 case 's':
304 {
305 m_modules.AppendIfUnique (FileSpec (option_arg, false));
306 break;
307 }
308
309 case 'S':
310 m_func_names.push_back (option_arg);
311 m_func_name_type_mask |= eFunctionNameTypeSelector;
312 break;
313
314 case 't' :
315 {
Vince Harron5275aaa2015-01-15 20:08:35 +0000316 m_thread_id = StringConvert::ToUInt64(option_arg, LLDB_INVALID_THREAD_ID, 0);
Jim Inghamca36cd12012-10-05 19:16:31 +0000317 if (m_thread_id == LLDB_INVALID_THREAD_ID)
318 error.SetErrorStringWithFormat ("invalid thread id string '%s'", option_arg);
319 }
320 break;
321
322 case 'T':
323 m_thread_name.assign (option_arg);
324 break;
325
326 case 'w':
327 {
328 bool success;
329 m_throw_bp = Args::StringToBoolean (option_arg, true, &success);
330 if (!success)
331 error.SetErrorStringWithFormat ("Invalid boolean value for on-throw option: '%s'", option_arg);
332 }
333 break;
334
335 case 'x':
336 {
Vince Harron5275aaa2015-01-15 20:08:35 +0000337 m_thread_index = StringConvert::ToUInt32(option_arg, UINT32_MAX, 0);
Jim Inghamca36cd12012-10-05 19:16:31 +0000338 if (m_thread_id == UINT32_MAX)
339 error.SetErrorStringWithFormat ("invalid thread index string '%s'", option_arg);
340
341 }
342 break;
343
Jim Ingham5a988412012-06-08 21:56:10 +0000344 default:
345 error.SetErrorStringWithFormat ("unrecognized option '%c'", short_option);
346 break;
347 }
348
349 return error;
350 }
351 void
352 OptionParsingStarting ()
353 {
354 m_condition.clear();
355 m_filenames.Clear();
356 m_line_num = 0;
357 m_column = 0;
358 m_func_names.clear();
Greg Clayton1f746072012-08-29 21:13:06 +0000359 m_func_name_type_mask = eFunctionNameTypeNone;
Jim Ingham5a988412012-06-08 21:56:10 +0000360 m_func_regexp.clear();
Greg Clayton1f746072012-08-29 21:13:06 +0000361 m_source_text_regexp.clear();
Jim Ingham5a988412012-06-08 21:56:10 +0000362 m_modules.Clear();
Greg Clayton1f746072012-08-29 21:13:06 +0000363 m_load_addr = LLDB_INVALID_ADDRESS;
Jim Ingham5a988412012-06-08 21:56:10 +0000364 m_ignore_count = 0;
365 m_thread_id = LLDB_INVALID_THREAD_ID;
366 m_thread_index = UINT32_MAX;
367 m_thread_name.clear();
368 m_queue_name.clear();
Jim Ingham5a988412012-06-08 21:56:10 +0000369 m_catch_bp = false;
370 m_throw_bp = true;
Greg Claytoneb023e72013-10-11 19:48:25 +0000371 m_hardware = false;
Jim Inghama72b31c2015-04-22 19:42:18 +0000372 m_exception_language = eLanguageTypeUnknown;
Jim Ingham5a988412012-06-08 21:56:10 +0000373 m_skip_prologue = eLazyBoolCalculate;
Jim Inghamca36cd12012-10-05 19:16:31 +0000374 m_one_shot = false;
Jim Ingham33df7cd2014-12-06 01:28:03 +0000375 m_use_dummy = false;
Jim Ingham5e09c8c2014-12-16 23:40:14 +0000376 m_breakpoint_names.clear();
Jim Inghame7320522015-02-12 17:37:46 +0000377 m_all_files = false;
Jim Inghama72b31c2015-04-22 19:42:18 +0000378 m_exception_extra_args.Clear();
Ilia K055ad9b2015-05-18 13:41:01 +0000379 m_move_to_nearest_code = eLazyBoolCalculate;
Jim Ingham5a988412012-06-08 21:56:10 +0000380 }
381
382 const OptionDefinition*
383 GetDefinitions ()
384 {
385 return g_option_table;
386 }
387
388 // Options table: Required for subclasses of Options.
389
390 static OptionDefinition g_option_table[];
391
392 // Instance variables to hold the values for command options.
393
394 std::string m_condition;
395 FileSpecList m_filenames;
396 uint32_t m_line_num;
397 uint32_t m_column;
Jim Ingham5a988412012-06-08 21:56:10 +0000398 std::vector<std::string> m_func_names;
Jim Ingham5e09c8c2014-12-16 23:40:14 +0000399 std::vector<std::string> m_breakpoint_names;
Jim Ingham5a988412012-06-08 21:56:10 +0000400 uint32_t m_func_name_type_mask;
401 std::string m_func_regexp;
402 std::string m_source_text_regexp;
403 FileSpecList m_modules;
404 lldb::addr_t m_load_addr;
405 uint32_t m_ignore_count;
406 lldb::tid_t m_thread_id;
407 uint32_t m_thread_index;
408 std::string m_thread_name;
409 std::string m_queue_name;
410 bool m_catch_bp;
411 bool m_throw_bp;
Greg Claytoneb023e72013-10-11 19:48:25 +0000412 bool m_hardware; // Request to use hardware breakpoints
Jim Inghama72b31c2015-04-22 19:42:18 +0000413 lldb::LanguageType m_exception_language;
Jim Ingham5a988412012-06-08 21:56:10 +0000414 LazyBool m_skip_prologue;
Jim Inghamca36cd12012-10-05 19:16:31 +0000415 bool m_one_shot;
Jim Ingham33df7cd2014-12-06 01:28:03 +0000416 bool m_use_dummy;
Jim Inghame7320522015-02-12 17:37:46 +0000417 bool m_all_files;
Jim Inghama72b31c2015-04-22 19:42:18 +0000418 Args m_exception_extra_args;
Ilia K055ad9b2015-05-18 13:41:01 +0000419 LazyBool m_move_to_nearest_code;
Jim Ingham5a988412012-06-08 21:56:10 +0000420
421 };
422
423protected:
424 virtual bool
425 DoExecute (Args& command,
Jim Ingham33df7cd2014-12-06 01:28:03 +0000426 CommandReturnObject &result)
Jim Ingham5a988412012-06-08 21:56:10 +0000427 {
Jim Ingham33df7cd2014-12-06 01:28:03 +0000428 Target *target = GetSelectedOrDummyTarget(m_options.m_use_dummy);
429
Jim Ingham893c9322014-11-22 01:42:44 +0000430 if (target == nullptr)
Jim Ingham5a988412012-06-08 21:56:10 +0000431 {
432 result.AppendError ("Invalid target. Must set target before setting breakpoints (see 'target create' command).");
433 result.SetStatus (eReturnStatusFailed);
434 return false;
435 }
436
437 // The following are the various types of breakpoints that could be set:
438 // 1). -f -l -p [-s -g] (setting breakpoint by source location)
439 // 2). -a [-s -g] (setting breakpoint by address)
440 // 3). -n [-s -g] (setting breakpoint by function name)
441 // 4). -r [-s -g] (setting breakpoint by function name regular expression)
442 // 5). -p -f (setting a breakpoint by comparing a reg-exp to source text)
443 // 6). -E [-w -h] (setting a breakpoint for exceptions for a given language.)
444
445 BreakpointSetType break_type = eSetTypeInvalid;
446
447 if (m_options.m_line_num != 0)
448 break_type = eSetTypeFileAndLine;
449 else if (m_options.m_load_addr != LLDB_INVALID_ADDRESS)
450 break_type = eSetTypeAddress;
451 else if (!m_options.m_func_names.empty())
452 break_type = eSetTypeFunctionName;
453 else if (!m_options.m_func_regexp.empty())
454 break_type = eSetTypeFunctionRegexp;
455 else if (!m_options.m_source_text_regexp.empty())
456 break_type = eSetTypeSourceRegexp;
Jim Inghama72b31c2015-04-22 19:42:18 +0000457 else if (m_options.m_exception_language != eLanguageTypeUnknown)
Jim Ingham5a988412012-06-08 21:56:10 +0000458 break_type = eSetTypeException;
459
460 Breakpoint *bp = NULL;
461 FileSpec module_spec;
Jim Ingham5a988412012-06-08 21:56:10 +0000462 const bool internal = false;
463
Jim Ingham5a988412012-06-08 21:56:10 +0000464 switch (break_type)
465 {
466 case eSetTypeFileAndLine: // Breakpoint by source position
467 {
468 FileSpec file;
Greg Claytonc7bece562013-01-25 18:06:21 +0000469 const size_t num_files = m_options.m_filenames.GetSize();
Jim Ingham5a988412012-06-08 21:56:10 +0000470 if (num_files == 0)
471 {
472 if (!GetDefaultFile (target, file, result))
473 {
474 result.AppendError("No file supplied and no default file available.");
475 result.SetStatus (eReturnStatusFailed);
476 return false;
477 }
478 }
479 else if (num_files > 1)
480 {
481 result.AppendError("Only one file at a time is allowed for file and line breakpoints.");
482 result.SetStatus (eReturnStatusFailed);
483 return false;
484 }
485 else
486 file = m_options.m_filenames.GetFileSpecAtIndex(0);
Greg Clayton1f746072012-08-29 21:13:06 +0000487
488 // Only check for inline functions if
489 LazyBool check_inlines = eLazyBoolCalculate;
490
Jim Ingham5a988412012-06-08 21:56:10 +0000491 bp = target->CreateBreakpoint (&(m_options.m_modules),
492 file,
493 m_options.m_line_num,
Greg Clayton1f746072012-08-29 21:13:06 +0000494 check_inlines,
Jim Ingham5a988412012-06-08 21:56:10 +0000495 m_options.m_skip_prologue,
Greg Claytoneb023e72013-10-11 19:48:25 +0000496 internal,
Ilia K055ad9b2015-05-18 13:41:01 +0000497 m_options.m_hardware,
498 m_options.m_move_to_nearest_code).get();
Jim Ingham5a988412012-06-08 21:56:10 +0000499 }
500 break;
501
502 case eSetTypeAddress: // Breakpoint by address
Greg Claytoneb023e72013-10-11 19:48:25 +0000503 bp = target->CreateBreakpoint (m_options.m_load_addr,
504 internal,
505 m_options.m_hardware).get();
Jim Ingham5a988412012-06-08 21:56:10 +0000506 break;
507
508 case eSetTypeFunctionName: // Breakpoint by function name
509 {
510 uint32_t name_type_mask = m_options.m_func_name_type_mask;
511
512 if (name_type_mask == 0)
513 name_type_mask = eFunctionNameTypeAuto;
514
515 bp = target->CreateBreakpoint (&(m_options.m_modules),
516 &(m_options.m_filenames),
517 m_options.m_func_names,
518 name_type_mask,
519 m_options.m_skip_prologue,
Greg Claytoneb023e72013-10-11 19:48:25 +0000520 internal,
521 m_options.m_hardware).get();
Jim Ingham5a988412012-06-08 21:56:10 +0000522 }
523 break;
524
525 case eSetTypeFunctionRegexp: // Breakpoint by regular expression function name
526 {
527 RegularExpression regexp(m_options.m_func_regexp.c_str());
528 if (!regexp.IsValid())
529 {
530 char err_str[1024];
531 regexp.GetErrorAsCString(err_str, sizeof(err_str));
532 result.AppendErrorWithFormat("Function name regular expression could not be compiled: \"%s\"",
533 err_str);
534 result.SetStatus (eReturnStatusFailed);
535 return false;
536 }
537
538 bp = target->CreateFuncRegexBreakpoint (&(m_options.m_modules),
539 &(m_options.m_filenames),
540 regexp,
541 m_options.m_skip_prologue,
Greg Claytoneb023e72013-10-11 19:48:25 +0000542 internal,
543 m_options.m_hardware).get();
Jim Ingham5a988412012-06-08 21:56:10 +0000544 }
545 break;
546 case eSetTypeSourceRegexp: // Breakpoint by regexp on source text.
547 {
Greg Claytonc7bece562013-01-25 18:06:21 +0000548 const size_t num_files = m_options.m_filenames.GetSize();
Jim Ingham5a988412012-06-08 21:56:10 +0000549
Jim Inghame7320522015-02-12 17:37:46 +0000550 if (num_files == 0 && !m_options.m_all_files)
Jim Ingham5a988412012-06-08 21:56:10 +0000551 {
552 FileSpec file;
553 if (!GetDefaultFile (target, file, result))
554 {
555 result.AppendError ("No files provided and could not find default file.");
556 result.SetStatus (eReturnStatusFailed);
557 return false;
558 }
559 else
560 {
561 m_options.m_filenames.Append (file);
562 }
563 }
564
565 RegularExpression regexp(m_options.m_source_text_regexp.c_str());
566 if (!regexp.IsValid())
567 {
568 char err_str[1024];
569 regexp.GetErrorAsCString(err_str, sizeof(err_str));
570 result.AppendErrorWithFormat("Source text regular expression could not be compiled: \"%s\"",
571 err_str);
572 result.SetStatus (eReturnStatusFailed);
573 return false;
574 }
Greg Claytoneb023e72013-10-11 19:48:25 +0000575 bp = target->CreateSourceRegexBreakpoint (&(m_options.m_modules),
576 &(m_options.m_filenames),
577 regexp,
578 internal,
Ilia K055ad9b2015-05-18 13:41:01 +0000579 m_options.m_hardware,
580 m_options.m_move_to_nearest_code).get();
Jim Ingham5a988412012-06-08 21:56:10 +0000581 }
582 break;
583 case eSetTypeException:
584 {
Jim Inghama72b31c2015-04-22 19:42:18 +0000585 Error precond_error;
586 bp = target->CreateExceptionBreakpoint (m_options.m_exception_language,
Greg Claytoneb023e72013-10-11 19:48:25 +0000587 m_options.m_catch_bp,
588 m_options.m_throw_bp,
Jim Inghama72b31c2015-04-22 19:42:18 +0000589 internal,
590 &m_options.m_exception_extra_args,
591 &precond_error).get();
592 if (precond_error.Fail())
593 {
594 result.AppendErrorWithFormat("Error setting extra exception arguments: %s",
595 precond_error.AsCString());
596 target->RemoveBreakpointByID(bp->GetID());
597 result.SetStatus(eReturnStatusFailed);
598 return false;
599 }
Jim Ingham5a988412012-06-08 21:56:10 +0000600 }
601 break;
602 default:
603 break;
604 }
605
606 // Now set the various options that were passed in:
607 if (bp)
608 {
609 if (m_options.m_thread_id != LLDB_INVALID_THREAD_ID)
610 bp->SetThreadID (m_options.m_thread_id);
611
612 if (m_options.m_thread_index != UINT32_MAX)
613 bp->GetOptions()->GetThreadSpec()->SetIndex(m_options.m_thread_index);
614
615 if (!m_options.m_thread_name.empty())
616 bp->GetOptions()->GetThreadSpec()->SetName(m_options.m_thread_name.c_str());
617
618 if (!m_options.m_queue_name.empty())
619 bp->GetOptions()->GetThreadSpec()->SetQueueName(m_options.m_queue_name.c_str());
620
621 if (m_options.m_ignore_count != 0)
622 bp->GetOptions()->SetIgnoreCount(m_options.m_ignore_count);
623
624 if (!m_options.m_condition.empty())
625 bp->GetOptions()->SetCondition(m_options.m_condition.c_str());
Jim Ingham5e09c8c2014-12-16 23:40:14 +0000626
627 if (!m_options.m_breakpoint_names.empty())
628 {
629 Error error; // We don't need to check the error here, since the option parser checked it...
630 for (auto name : m_options.m_breakpoint_names)
631 bp->AddName(name.c_str(), error);
632 }
Jim Inghamca36cd12012-10-05 19:16:31 +0000633
634 bp->SetOneShot (m_options.m_one_shot);
Jim Ingham5a988412012-06-08 21:56:10 +0000635 }
636
637 if (bp)
638 {
639 Stream &output_stream = result.GetOutputStream();
Jim Ingham1391cc72012-09-22 00:04:04 +0000640 const bool show_locations = false;
641 bp->GetDescription(&output_stream, lldb::eDescriptionLevelInitial, show_locations);
Jim Ingham4aeb1982014-12-19 19:45:31 +0000642 if (target == m_interpreter.GetDebugger().GetDummyTarget())
643 output_stream.Printf ("Breakpoint set in dummy target, will get copied into future targets.\n");
644 else
645 {
646 // Don't print out this warning for exception breakpoints. They can get set before the target
647 // is set, but we won't know how to actually set the breakpoint till we run.
648 if (bp->GetNumLocations() == 0 && break_type != eSetTypeException)
649 {
650 output_stream.Printf ("WARNING: Unable to resolve breakpoint to any actual locations.\n");
651 }
652 }
Jim Ingham5a988412012-06-08 21:56:10 +0000653 result.SetStatus (eReturnStatusSuccessFinishResult);
654 }
655 else if (!bp)
656 {
657 result.AppendError ("Breakpoint creation failed: No breakpoint created.");
658 result.SetStatus (eReturnStatusFailed);
659 }
660
661 return result.Succeeded();
662 }
663
664private:
665 bool
666 GetDefaultFile (Target *target, FileSpec &file, CommandReturnObject &result)
667 {
668 uint32_t default_line;
669 // First use the Source Manager's default file.
670 // Then use the current stack frame's file.
671 if (!target->GetSourceManager().GetDefaultFileAndLine(file, default_line))
672 {
Jason Molendab57e4a12013-11-04 09:33:30 +0000673 StackFrame *cur_frame = m_exe_ctx.GetFramePtr();
Jim Ingham5a988412012-06-08 21:56:10 +0000674 if (cur_frame == NULL)
675 {
676 result.AppendError ("No selected frame to use to find the default file.");
677 result.SetStatus (eReturnStatusFailed);
678 return false;
679 }
680 else if (!cur_frame->HasDebugInformation())
681 {
682 result.AppendError ("Cannot use the selected frame to find the default file, it has no debug info.");
683 result.SetStatus (eReturnStatusFailed);
684 return false;
685 }
686 else
687 {
688 const SymbolContext &sc = cur_frame->GetSymbolContext (eSymbolContextLineEntry);
689 if (sc.line_entry.file)
690 {
691 file = sc.line_entry.file;
692 }
693 else
694 {
695 result.AppendError ("Can't find the file for the selected frame to use as the default file.");
696 result.SetStatus (eReturnStatusFailed);
697 return false;
698 }
699 }
700 }
701 return true;
702 }
703
704 CommandOptions m_options;
705};
Johnny Chen6943e7c2012-05-08 00:43:20 +0000706// If an additional option set beyond LLDB_OPTION_SET_10 is added, make sure to
707// update the numbers passed to LLDB_OPT_SET_FROM_TO(...) appropriately.
Johnny Chen4ab2e6b2012-05-07 23:23:41 +0000708#define LLDB_OPT_FILE ( LLDB_OPT_SET_FROM_TO(1, 9) & ~LLDB_OPT_SET_2 )
709#define LLDB_OPT_NOT_10 ( LLDB_OPT_SET_FROM_TO(1, 10) & ~LLDB_OPT_SET_10 )
Jim Inghama8558b62012-05-22 00:12:20 +0000710#define LLDB_OPT_SKIP_PROLOGUE ( LLDB_OPT_SET_1 | LLDB_OPT_SET_FROM_TO(3,8) )
Ilia K055ad9b2015-05-18 13:41:01 +0000711#define LLDB_OPT_MOVE_TO_NEAREST_CODE ( LLDB_OPT_SET_1 | LLDB_OPT_SET_9 )
Jim Ingham87df91b2011-09-23 00:54:11 +0000712
Greg Claytone0d378b2011-03-24 21:19:54 +0000713OptionDefinition
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000714CommandObjectBreakpointSet::CommandOptions::g_option_table[] =
715{
Zachary Turnerd37221d2014-07-09 16:31:49 +0000716 { LLDB_OPT_NOT_10, false, "shlib", 's', OptionParser::eRequiredArgument, NULL, NULL, CommandCompletions::eModuleCompletion, eArgTypeShlibName,
Jim Ingham64cc29c2012-05-03 20:30:08 +0000717 "Set the breakpoint only in this shared library. "
718 "Can repeat this option multiple times to specify multiple shared libraries."},
Jim Ingham86511212010-06-15 18:47:14 +0000719
Zachary Turnerd37221d2014-07-09 16:31:49 +0000720 { LLDB_OPT_SET_ALL, false, "ignore-count", 'i', OptionParser::eRequiredArgument, NULL, NULL, 0, eArgTypeCount,
Caroline Ticedeaab222010-10-01 19:59:14 +0000721 "Set the number of times this breakpoint is skipped before stopping." },
Jim Ingham1b54c882010-06-16 02:00:15 +0000722
Zachary Turnerd37221d2014-07-09 16:31:49 +0000723 { LLDB_OPT_SET_ALL, false, "one-shot", 'o', OptionParser::eNoArgument, NULL, NULL, 0, eArgTypeNone,
Jim Inghamb2b256a2013-04-09 18:05:22 +0000724 "The breakpoint is deleted the first time it causes a stop." },
Jim Inghamca36cd12012-10-05 19:16:31 +0000725
Zachary Turnerd37221d2014-07-09 16:31:49 +0000726 { LLDB_OPT_SET_ALL, false, "condition", 'c', OptionParser::eRequiredArgument, NULL, NULL, 0, eArgTypeExpression,
Johnny Chen7d49c9c2012-05-25 21:10:46 +0000727 "The breakpoint stops only if this condition expression evaluates to true."},
728
Zachary Turnerd37221d2014-07-09 16:31:49 +0000729 { LLDB_OPT_SET_ALL, false, "thread-index", 'x', OptionParser::eRequiredArgument, NULL, NULL, 0, eArgTypeThreadIndex,
Jim Inghama89be912013-03-26 18:29:03 +0000730 "The breakpoint stops only for the thread whose indeX matches this argument."},
Jim Ingham1b54c882010-06-16 02:00:15 +0000731
Zachary Turnerd37221d2014-07-09 16:31:49 +0000732 { LLDB_OPT_SET_ALL, false, "thread-id", 't', OptionParser::eRequiredArgument, NULL, NULL, 0, eArgTypeThreadID,
Jim Ingham1b54c882010-06-16 02:00:15 +0000733 "The breakpoint stops only for the thread whose TID matches this argument."},
734
Zachary Turnerd37221d2014-07-09 16:31:49 +0000735 { LLDB_OPT_SET_ALL, false, "thread-name", 'T', OptionParser::eRequiredArgument, NULL, NULL, 0, eArgTypeThreadName,
Jim Ingham1b54c882010-06-16 02:00:15 +0000736 "The breakpoint stops only for the thread whose thread name matches this argument."},
737
Zachary Turnerd37221d2014-07-09 16:31:49 +0000738 { LLDB_OPT_SET_ALL, false, "hardware", 'H', OptionParser::eNoArgument, NULL, NULL, 0, eArgTypeNone,
Greg Claytoneb023e72013-10-11 19:48:25 +0000739 "Require the breakpoint to use hardware breakpoints."},
740
Zachary Turnerd37221d2014-07-09 16:31:49 +0000741 { LLDB_OPT_SET_ALL, false, "queue-name", 'q', OptionParser::eRequiredArgument, NULL, NULL, 0, eArgTypeQueueName,
Jim Ingham1b54c882010-06-16 02:00:15 +0000742 "The breakpoint stops only for threads in the queue whose name is given by this argument."},
743
Zachary Turnerd37221d2014-07-09 16:31:49 +0000744 { LLDB_OPT_FILE, false, "file", 'f', OptionParser::eRequiredArgument, NULL, NULL, CommandCompletions::eSourceFileCompletion, eArgTypeFilename,
Jim Ingham289aca62013-02-14 19:10:36 +0000745 "Specifies the source file in which to set this breakpoint. "
746 "Note, by default lldb only looks for files that are #included if they use the standard include file extensions. "
Jim Ingham63944792013-02-14 19:30:35 +0000747 "To set breakpoints on .c/.cpp/.m/.mm files that are #included, set target.inline-breakpoint-strategy"
Jim Ingham289aca62013-02-14 19:10:36 +0000748 " to \"always\"."},
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000749
Zachary Turnerd37221d2014-07-09 16:31:49 +0000750 { LLDB_OPT_SET_1, true, "line", 'l', OptionParser::eRequiredArgument, NULL, NULL, 0, eArgTypeLineNum,
Jim Ingham87df91b2011-09-23 00:54:11 +0000751 "Specifies the line number on which to set this breakpoint."},
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000752
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000753 // Comment out this option for the moment, as we don't actually use it, but will in the future.
754 // This way users won't see it, but the infrastructure is left in place.
Virgile Belloe2607b52013-09-05 16:42:23 +0000755 // { 0, false, "column", 'C', OptionParser::eRequiredArgument, NULL, "<column>",
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000756 // "Set the breakpoint by source location at this particular column."},
757
Zachary Turnerd37221d2014-07-09 16:31:49 +0000758 { LLDB_OPT_SET_2, true, "address", 'a', OptionParser::eRequiredArgument, NULL, NULL, 0, eArgTypeAddressOrExpression,
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000759 "Set the breakpoint by address, at the specified address."},
760
Zachary Turnerd37221d2014-07-09 16:31:49 +0000761 { LLDB_OPT_SET_3, true, "name", 'n', OptionParser::eRequiredArgument, NULL, NULL, CommandCompletions::eSymbolCompletion, eArgTypeFunctionName,
Jim Ingham551262d2013-03-27 17:36:54 +0000762 "Set the breakpoint by function name. Can be repeated multiple times to make one breakpoint for multiple names" },
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000763
Zachary Turnerd37221d2014-07-09 16:31:49 +0000764 { LLDB_OPT_SET_4, true, "fullname", 'F', OptionParser::eRequiredArgument, NULL, NULL, CommandCompletions::eSymbolCompletion, eArgTypeFullName,
Jim Ingham64cc29c2012-05-03 20:30:08 +0000765 "Set the breakpoint by fully qualified function names. For C++ this means namespaces and all arguments, and "
766 "for Objective C this means a full function prototype with class and selector. "
767 "Can be repeated multiple times to make one breakpoint for multiple names." },
Greg Clayton0c5cd902010-06-28 21:30:43 +0000768
Zachary Turnerd37221d2014-07-09 16:31:49 +0000769 { LLDB_OPT_SET_5, true, "selector", 'S', OptionParser::eRequiredArgument, NULL, NULL, 0, eArgTypeSelector,
Jim Ingham64cc29c2012-05-03 20:30:08 +0000770 "Set the breakpoint by ObjC selector name. Can be repeated multiple times to make one breakpoint for multiple Selectors." },
Greg Clayton0c5cd902010-06-28 21:30:43 +0000771
Zachary Turnerd37221d2014-07-09 16:31:49 +0000772 { LLDB_OPT_SET_6, true, "method", 'M', OptionParser::eRequiredArgument, NULL, NULL, 0, eArgTypeMethod,
Jim Ingham64cc29c2012-05-03 20:30:08 +0000773 "Set the breakpoint by C++ method names. Can be repeated multiple times to make one breakpoint for multiple methods." },
Greg Clayton0c5cd902010-06-28 21:30:43 +0000774
Zachary Turnerd37221d2014-07-09 16:31:49 +0000775 { LLDB_OPT_SET_7, true, "func-regex", 'r', OptionParser::eRequiredArgument, NULL, NULL, 0, eArgTypeRegularExpression,
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000776 "Set the breakpoint by function name, evaluating a regular-expression to find the function name(s)." },
777
Zachary Turnerd37221d2014-07-09 16:31:49 +0000778 { LLDB_OPT_SET_8, true, "basename", 'b', OptionParser::eRequiredArgument, NULL, NULL, CommandCompletions::eSymbolCompletion, eArgTypeFunctionName,
Jim Ingham64cc29c2012-05-03 20:30:08 +0000779 "Set the breakpoint by function basename (C++ namespaces and arguments will be ignored). "
780 "Can be repeated multiple times to make one breakpoint for multiple symbols." },
Greg Claytone02b8502010-10-12 04:29:14 +0000781
Zachary Turnerd37221d2014-07-09 16:31:49 +0000782 { LLDB_OPT_SET_9, true, "source-pattern-regexp", 'p', OptionParser::eRequiredArgument, NULL, NULL, 0, eArgTypeRegularExpression,
Jim Inghame96ade82013-06-07 01:13:00 +0000783 "Set the breakpoint by specifying a regular expression which is matched against the source text in a source file or files "
784 "specified with the -f option. The -f option can be specified more than once. "
785 "If no source files are specified, uses the current \"default source file\"" },
Jim Ingham969795f2011-09-21 01:17:13 +0000786
Jim Inghame7320522015-02-12 17:37:46 +0000787 { LLDB_OPT_SET_9, false, "all-files", 'A', OptionParser::eNoArgument, NULL, NULL, 0, eArgTypeNone,
788 "All files are searched for source pattern matches." },
789
Zachary Turnerd37221d2014-07-09 16:31:49 +0000790 { LLDB_OPT_SET_10, true, "language-exception", 'E', OptionParser::eRequiredArgument, NULL, NULL, 0, eArgTypeLanguage,
Jim Inghamfab10e82012-03-06 00:37:27 +0000791 "Set the breakpoint on exceptions thrown by the specified language (without options, on throw but not catch.)" },
792
Zachary Turnerd37221d2014-07-09 16:31:49 +0000793 { LLDB_OPT_SET_10, false, "on-throw", 'w', OptionParser::eRequiredArgument, NULL, NULL, 0, eArgTypeBoolean,
Jim Inghamfab10e82012-03-06 00:37:27 +0000794 "Set the breakpoint on exception throW." },
795
Zachary Turnerd37221d2014-07-09 16:31:49 +0000796 { LLDB_OPT_SET_10, false, "on-catch", 'h', OptionParser::eRequiredArgument, NULL, NULL, 0, eArgTypeBoolean,
Jim Inghamfab10e82012-03-06 00:37:27 +0000797 "Set the breakpoint on exception catcH." },
Jim Ingham969795f2011-09-21 01:17:13 +0000798
Jim Inghama72b31c2015-04-22 19:42:18 +0000799// Don't add this option till it actually does something useful...
800// { LLDB_OPT_SET_10, false, "exception-typename", 'O', OptionParser::eRequiredArgument, NULL, NULL, 0, eArgTypeTypeName,
801// "The breakpoint will only stop if an exception Object of this type is thrown. Can be repeated multiple times to stop for multiple object types" },
802
Zachary Turnerd37221d2014-07-09 16:31:49 +0000803 { LLDB_OPT_SKIP_PROLOGUE, false, "skip-prologue", 'K', OptionParser::eRequiredArgument, NULL, NULL, 0, eArgTypeBoolean,
Jim Inghama8558b62012-05-22 00:12:20 +0000804 "sKip the prologue if the breakpoint is at the beginning of a function. If not set the target.skip-prologue setting is used." },
805
Jim Ingham33df7cd2014-12-06 01:28:03 +0000806 { LLDB_OPT_SET_ALL, false, "dummy-breakpoints", 'D', OptionParser::eNoArgument, NULL, NULL, 0, eArgTypeNone,
807 "Sets Dummy breakpoints - i.e. breakpoints set before a file is provided, which prime new targets."},
808
Jim Ingham5e09c8c2014-12-16 23:40:14 +0000809 { LLDB_OPT_SET_ALL, false, "breakpoint-name", 'N', OptionParser::eRequiredArgument, NULL, NULL, 0, eArgTypeBreakpointName,
810 "Adds this to the list of names for this breakopint."},
811
Ilia K055ad9b2015-05-18 13:41:01 +0000812 { LLDB_OPT_MOVE_TO_NEAREST_CODE, false, "move-to-nearest-code", 'm', OptionParser::eRequiredArgument, NULL, NULL, 0, eArgTypeBoolean,
813 "Move breakpoints to nearest code. If not set the target.move-to-nearest-code setting is used." },
814
Zachary Turnerd37221d2014-07-09 16:31:49 +0000815 { 0, false, NULL, 0, 0, NULL, NULL, 0, eArgTypeNone, NULL }
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000816};
817
Jim Ingham5a988412012-06-08 21:56:10 +0000818//-------------------------------------------------------------------------
819// CommandObjectBreakpointModify
820//-------------------------------------------------------------------------
821#pragma mark Modify
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000822
Jim Ingham5a988412012-06-08 21:56:10 +0000823class CommandObjectBreakpointModify : public CommandObjectParsed
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000824{
Jim Ingham5a988412012-06-08 21:56:10 +0000825public:
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000826
Jim Ingham5a988412012-06-08 21:56:10 +0000827 CommandObjectBreakpointModify (CommandInterpreter &interpreter) :
828 CommandObjectParsed (interpreter,
829 "breakpoint modify",
830 "Modify the options on a breakpoint or set of breakpoints in the executable. "
831 "If no breakpoint is specified, acts on the last created breakpoint. "
832 "With the exception of -e, -d and -i, passing an empty argument clears the modification.",
833 NULL),
834 m_options (interpreter)
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000835 {
Jim Ingham5a988412012-06-08 21:56:10 +0000836 CommandArgumentEntry arg;
837 CommandObject::AddIDsArgumentData(arg, eArgTypeBreakpointID, eArgTypeBreakpointIDRange);
838 // Add the entry for the first argument for this command to the object's arguments vector.
839 m_arguments.push_back (arg);
840 }
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000841
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000842
Jim Ingham5a988412012-06-08 21:56:10 +0000843 virtual
844 ~CommandObjectBreakpointModify () {}
Greg Clayton0c5cd902010-06-28 21:30:43 +0000845
Jim Ingham5a988412012-06-08 21:56:10 +0000846 virtual Options *
847 GetOptions ()
848 {
849 return &m_options;
850 }
Johnny Chen7d49c9c2012-05-25 21:10:46 +0000851
Jim Ingham5a988412012-06-08 21:56:10 +0000852 class CommandOptions : public Options
853 {
854 public:
Greg Clayton0c5cd902010-06-28 21:30:43 +0000855
Jim Ingham5a988412012-06-08 21:56:10 +0000856 CommandOptions (CommandInterpreter &interpreter) :
857 Options (interpreter),
858 m_ignore_count (0),
859 m_thread_id(LLDB_INVALID_THREAD_ID),
860 m_thread_id_passed(false),
861 m_thread_index (UINT32_MAX),
862 m_thread_index_passed(false),
863 m_thread_name(),
864 m_queue_name(),
865 m_condition (),
Jim Inghamca36cd12012-10-05 19:16:31 +0000866 m_one_shot (false),
Jim Ingham5a988412012-06-08 21:56:10 +0000867 m_enable_passed (false),
868 m_enable_value (false),
869 m_name_passed (false),
870 m_queue_passed (false),
Jim Inghamca36cd12012-10-05 19:16:31 +0000871 m_condition_passed (false),
Jim Ingham33df7cd2014-12-06 01:28:03 +0000872 m_one_shot_passed (false),
873 m_use_dummy (false)
Jim Ingham5a988412012-06-08 21:56:10 +0000874 {
875 }
Greg Clayton0c5cd902010-06-28 21:30:43 +0000876
Jim Ingham5a988412012-06-08 21:56:10 +0000877 virtual
878 ~CommandOptions () {}
Greg Clayton0c5cd902010-06-28 21:30:43 +0000879
Jim Ingham5a988412012-06-08 21:56:10 +0000880 virtual Error
881 SetOptionValue (uint32_t option_idx, const char *option_arg)
882 {
883 Error error;
Greg Clayton3bcdfc02012-12-04 00:32:51 +0000884 const int short_option = m_getopt_table[option_idx].val;
Greg Claytone02b8502010-10-12 04:29:14 +0000885
Jim Ingham5a988412012-06-08 21:56:10 +0000886 switch (short_option)
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000887 {
Jim Ingham5a988412012-06-08 21:56:10 +0000888 case 'c':
889 if (option_arg != NULL)
890 m_condition.assign (option_arg);
891 else
892 m_condition.clear();
893 m_condition_passed = true;
894 break;
895 case 'd':
896 m_enable_passed = true;
897 m_enable_value = false;
898 break;
Jim Ingham33df7cd2014-12-06 01:28:03 +0000899 case 'D':
900 m_use_dummy = true;
901 break;
Jim Ingham5a988412012-06-08 21:56:10 +0000902 case 'e':
903 m_enable_passed = true;
904 m_enable_value = true;
905 break;
906 case 'i':
907 {
Vince Harron5275aaa2015-01-15 20:08:35 +0000908 m_ignore_count = StringConvert::ToUInt32(option_arg, UINT32_MAX, 0);
Jim Ingham5a988412012-06-08 21:56:10 +0000909 if (m_ignore_count == UINT32_MAX)
910 error.SetErrorStringWithFormat ("invalid ignore count '%s'", option_arg);
911 }
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000912 break;
Jim Inghamca36cd12012-10-05 19:16:31 +0000913 case 'o':
914 {
915 bool value, success;
916 value = Args::StringToBoolean(option_arg, false, &success);
917 if (success)
918 {
919 m_one_shot_passed = true;
920 m_one_shot = value;
921 }
922 else
923 error.SetErrorStringWithFormat("invalid boolean value '%s' passed for -o option", option_arg);
924 }
925 break;
Jim Ingham5a988412012-06-08 21:56:10 +0000926 case 't' :
Jim Ingham87df91b2011-09-23 00:54:11 +0000927 {
Jim Ingham5a988412012-06-08 21:56:10 +0000928 if (option_arg[0] == '\0')
Jim Ingham87df91b2011-09-23 00:54:11 +0000929 {
Jim Ingham5a988412012-06-08 21:56:10 +0000930 m_thread_id = LLDB_INVALID_THREAD_ID;
931 m_thread_id_passed = true;
Jim Ingham87df91b2011-09-23 00:54:11 +0000932 }
933 else
934 {
Vince Harron5275aaa2015-01-15 20:08:35 +0000935 m_thread_id = StringConvert::ToUInt64(option_arg, LLDB_INVALID_THREAD_ID, 0);
Jim Ingham5a988412012-06-08 21:56:10 +0000936 if (m_thread_id == LLDB_INVALID_THREAD_ID)
937 error.SetErrorStringWithFormat ("invalid thread id string '%s'", option_arg);
938 else
939 m_thread_id_passed = true;
Jim Ingham87df91b2011-09-23 00:54:11 +0000940 }
941 }
Jim Ingham5a988412012-06-08 21:56:10 +0000942 break;
943 case 'T':
944 if (option_arg != NULL)
945 m_thread_name.assign (option_arg);
946 else
947 m_thread_name.clear();
948 m_name_passed = true;
949 break;
950 case 'q':
951 if (option_arg != NULL)
952 m_queue_name.assign (option_arg);
953 else
954 m_queue_name.clear();
955 m_queue_passed = true;
956 break;
957 case 'x':
Jim Ingham969795f2011-09-21 01:17:13 +0000958 {
Jim Ingham5a988412012-06-08 21:56:10 +0000959 if (option_arg[0] == '\n')
960 {
961 m_thread_index = UINT32_MAX;
962 m_thread_index_passed = true;
963 }
964 else
965 {
Vince Harron5275aaa2015-01-15 20:08:35 +0000966 m_thread_index = StringConvert::ToUInt32 (option_arg, UINT32_MAX, 0);
Jim Ingham5a988412012-06-08 21:56:10 +0000967 if (m_thread_id == UINT32_MAX)
968 error.SetErrorStringWithFormat ("invalid thread index string '%s'", option_arg);
969 else
970 m_thread_index_passed = true;
971 }
Jim Ingham969795f2011-09-21 01:17:13 +0000972 }
Jim Ingham5a988412012-06-08 21:56:10 +0000973 break;
974 default:
975 error.SetErrorStringWithFormat ("unrecognized option '%c'", short_option);
976 break;
Jim Ingham969795f2011-09-21 01:17:13 +0000977 }
Jim Ingham5a988412012-06-08 21:56:10 +0000978
979 return error;
980 }
981 void
982 OptionParsingStarting ()
983 {
984 m_ignore_count = 0;
985 m_thread_id = LLDB_INVALID_THREAD_ID;
986 m_thread_id_passed = false;
987 m_thread_index = UINT32_MAX;
988 m_thread_index_passed = false;
989 m_thread_name.clear();
990 m_queue_name.clear();
991 m_condition.clear();
Jim Inghamca36cd12012-10-05 19:16:31 +0000992 m_one_shot = false;
Jim Ingham5a988412012-06-08 21:56:10 +0000993 m_enable_passed = false;
994 m_queue_passed = false;
995 m_name_passed = false;
996 m_condition_passed = false;
Jim Inghamca36cd12012-10-05 19:16:31 +0000997 m_one_shot_passed = false;
Jim Ingham33df7cd2014-12-06 01:28:03 +0000998 m_use_dummy = false;
Jim Ingham5a988412012-06-08 21:56:10 +0000999 }
1000
1001 const OptionDefinition*
1002 GetDefinitions ()
1003 {
1004 return g_option_table;
1005 }
1006
1007
1008 // Options table: Required for subclasses of Options.
1009
1010 static OptionDefinition g_option_table[];
1011
1012 // Instance variables to hold the values for command options.
1013
1014 uint32_t m_ignore_count;
1015 lldb::tid_t m_thread_id;
1016 bool m_thread_id_passed;
1017 uint32_t m_thread_index;
1018 bool m_thread_index_passed;
1019 std::string m_thread_name;
1020 std::string m_queue_name;
1021 std::string m_condition;
Jim Inghamca36cd12012-10-05 19:16:31 +00001022 bool m_one_shot;
Jim Ingham5a988412012-06-08 21:56:10 +00001023 bool m_enable_passed;
1024 bool m_enable_value;
1025 bool m_name_passed;
1026 bool m_queue_passed;
1027 bool m_condition_passed;
Jim Inghamca36cd12012-10-05 19:16:31 +00001028 bool m_one_shot_passed;
Jim Ingham33df7cd2014-12-06 01:28:03 +00001029 bool m_use_dummy;
Jim Ingham5a988412012-06-08 21:56:10 +00001030
1031 };
1032
1033protected:
1034 virtual bool
1035 DoExecute (Args& command, CommandReturnObject &result)
1036 {
Jim Ingham33df7cd2014-12-06 01:28:03 +00001037 Target *target = GetSelectedOrDummyTarget(m_options.m_use_dummy);
Jim Ingham5a988412012-06-08 21:56:10 +00001038 if (target == NULL)
1039 {
1040 result.AppendError ("Invalid target. No existing target or breakpoints.");
1041 result.SetStatus (eReturnStatusFailed);
1042 return false;
1043 }
1044
1045 Mutex::Locker locker;
1046 target->GetBreakpointList().GetListMutex(locker);
1047
1048 BreakpointIDList valid_bp_ids;
1049
Jim Ingham5e09c8c2014-12-16 23:40:14 +00001050 CommandObjectMultiwordBreakpoint::VerifyBreakpointOrLocationIDs (command, target, result, &valid_bp_ids);
Jim Ingham5a988412012-06-08 21:56:10 +00001051
1052 if (result.Succeeded())
1053 {
1054 const size_t count = valid_bp_ids.GetSize();
1055 for (size_t i = 0; i < count; ++i)
Jim Inghamfab10e82012-03-06 00:37:27 +00001056 {
Jim Ingham5a988412012-06-08 21:56:10 +00001057 BreakpointID cur_bp_id = valid_bp_ids.GetBreakpointIDAtIndex (i);
1058
1059 if (cur_bp_id.GetBreakpointID() != LLDB_INVALID_BREAK_ID)
1060 {
1061 Breakpoint *bp = target->GetBreakpointByID (cur_bp_id.GetBreakpointID()).get();
1062 if (cur_bp_id.GetLocationID() != LLDB_INVALID_BREAK_ID)
1063 {
1064 BreakpointLocation *location = bp->FindLocationByID (cur_bp_id.GetLocationID()).get();
1065 if (location)
1066 {
1067 if (m_options.m_thread_id_passed)
1068 location->SetThreadID (m_options.m_thread_id);
1069
1070 if (m_options.m_thread_index_passed)
1071 location->SetThreadIndex(m_options.m_thread_index);
1072
1073 if (m_options.m_name_passed)
1074 location->SetThreadName(m_options.m_thread_name.c_str());
1075
1076 if (m_options.m_queue_passed)
1077 location->SetQueueName(m_options.m_queue_name.c_str());
1078
1079 if (m_options.m_ignore_count != 0)
1080 location->SetIgnoreCount(m_options.m_ignore_count);
1081
1082 if (m_options.m_enable_passed)
1083 location->SetEnabled (m_options.m_enable_value);
1084
1085 if (m_options.m_condition_passed)
1086 location->SetCondition (m_options.m_condition.c_str());
1087 }
1088 }
1089 else
1090 {
1091 if (m_options.m_thread_id_passed)
1092 bp->SetThreadID (m_options.m_thread_id);
1093
1094 if (m_options.m_thread_index_passed)
1095 bp->SetThreadIndex(m_options.m_thread_index);
1096
1097 if (m_options.m_name_passed)
1098 bp->SetThreadName(m_options.m_thread_name.c_str());
1099
1100 if (m_options.m_queue_passed)
1101 bp->SetQueueName(m_options.m_queue_name.c_str());
1102
1103 if (m_options.m_ignore_count != 0)
1104 bp->SetIgnoreCount(m_options.m_ignore_count);
1105
1106 if (m_options.m_enable_passed)
1107 bp->SetEnabled (m_options.m_enable_value);
1108
1109 if (m_options.m_condition_passed)
1110 bp->SetCondition (m_options.m_condition.c_str());
1111 }
1112 }
Jim Inghamfab10e82012-03-06 00:37:27 +00001113 }
Jim Ingham5a988412012-06-08 21:56:10 +00001114 }
1115
1116 return result.Succeeded();
Chris Lattner30fdc8d2010-06-08 16:52:24 +00001117 }
1118
Jim Ingham5a988412012-06-08 21:56:10 +00001119private:
1120 CommandOptions m_options;
1121};
Johnny Chen7d49c9c2012-05-25 21:10:46 +00001122
Jim Ingham5a988412012-06-08 21:56:10 +00001123#pragma mark Modify::CommandOptions
1124OptionDefinition
1125CommandObjectBreakpointModify::CommandOptions::g_option_table[] =
1126{
Zachary Turnerd37221d2014-07-09 16:31:49 +00001127{ 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." },
1128{ 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." },
1129{ 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."},
1130{ 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."},
1131{ 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."},
1132{ 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."},
1133{ LLDB_OPT_SET_ALL, false, "condition", 'c', OptionParser::eRequiredArgument, NULL, NULL, 0, eArgTypeExpression, "The breakpoint stops only if this condition expression evaluates to true."},
1134{ LLDB_OPT_SET_1, false, "enable", 'e', OptionParser::eNoArgument, NULL, NULL, 0, eArgTypeNone, "Enable the breakpoint."},
1135{ LLDB_OPT_SET_2, false, "disable", 'd', OptionParser::eNoArgument, NULL, NULL, 0, eArgTypeNone, "Disable the breakpoint."},
Jim Ingham33df7cd2014-12-06 01:28:03 +00001136{ 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."},
1137
Zachary Turnerd37221d2014-07-09 16:31:49 +00001138{ 0, false, NULL, 0 , 0, NULL, NULL, 0, eArgTypeNone, NULL }
Jim Ingham5a988412012-06-08 21:56:10 +00001139};
1140
1141//-------------------------------------------------------------------------
1142// CommandObjectBreakpointEnable
1143//-------------------------------------------------------------------------
1144#pragma mark Enable
1145
1146class CommandObjectBreakpointEnable : public CommandObjectParsed
1147{
1148public:
1149 CommandObjectBreakpointEnable (CommandInterpreter &interpreter) :
1150 CommandObjectParsed (interpreter,
1151 "enable",
1152 "Enable the specified disabled breakpoint(s). If no breakpoints are specified, enable all of them.",
1153 NULL)
1154 {
1155 CommandArgumentEntry arg;
1156 CommandObject::AddIDsArgumentData(arg, eArgTypeBreakpointID, eArgTypeBreakpointIDRange);
1157 // Add the entry for the first argument for this command to the object's arguments vector.
1158 m_arguments.push_back (arg);
1159 }
1160
1161
1162 virtual
1163 ~CommandObjectBreakpointEnable () {}
1164
1165protected:
1166 virtual bool
1167 DoExecute (Args& command, CommandReturnObject &result)
1168 {
Jim Ingham893c9322014-11-22 01:42:44 +00001169 Target *target = GetSelectedOrDummyTarget();
Jim Ingham5a988412012-06-08 21:56:10 +00001170 if (target == NULL)
1171 {
1172 result.AppendError ("Invalid target. No existing target or breakpoints.");
1173 result.SetStatus (eReturnStatusFailed);
1174 return false;
1175 }
1176
1177 Mutex::Locker locker;
1178 target->GetBreakpointList().GetListMutex(locker);
1179
1180 const BreakpointList &breakpoints = target->GetBreakpointList();
1181
1182 size_t num_breakpoints = breakpoints.GetSize();
1183
1184 if (num_breakpoints == 0)
1185 {
1186 result.AppendError ("No breakpoints exist to be enabled.");
1187 result.SetStatus (eReturnStatusFailed);
1188 return false;
1189 }
1190
1191 if (command.GetArgumentCount() == 0)
1192 {
1193 // No breakpoint selected; enable all currently set breakpoints.
1194 target->EnableAllBreakpoints ();
Greg Clayton6fea17e2014-03-03 19:15:20 +00001195 result.AppendMessageWithFormat ("All breakpoints enabled. (%" PRIu64 " breakpoints)\n", (uint64_t)num_breakpoints);
Jim Ingham5a988412012-06-08 21:56:10 +00001196 result.SetStatus (eReturnStatusSuccessFinishNoResult);
1197 }
1198 else
1199 {
1200 // Particular breakpoint selected; enable that breakpoint.
1201 BreakpointIDList valid_bp_ids;
Jim Ingham5e09c8c2014-12-16 23:40:14 +00001202 CommandObjectMultiwordBreakpoint::VerifyBreakpointOrLocationIDs (command, target, result, &valid_bp_ids);
Jim Ingham5a988412012-06-08 21:56:10 +00001203
1204 if (result.Succeeded())
1205 {
1206 int enable_count = 0;
1207 int loc_count = 0;
1208 const size_t count = valid_bp_ids.GetSize();
1209 for (size_t i = 0; i < count; ++i)
1210 {
1211 BreakpointID cur_bp_id = valid_bp_ids.GetBreakpointIDAtIndex (i);
1212
1213 if (cur_bp_id.GetBreakpointID() != LLDB_INVALID_BREAK_ID)
1214 {
1215 Breakpoint *breakpoint = target->GetBreakpointByID (cur_bp_id.GetBreakpointID()).get();
1216 if (cur_bp_id.GetLocationID() != LLDB_INVALID_BREAK_ID)
1217 {
1218 BreakpointLocation *location = breakpoint->FindLocationByID (cur_bp_id.GetLocationID()).get();
1219 if (location)
1220 {
1221 location->SetEnabled (true);
1222 ++loc_count;
1223 }
1224 }
1225 else
1226 {
1227 breakpoint->SetEnabled (true);
1228 ++enable_count;
1229 }
1230 }
1231 }
1232 result.AppendMessageWithFormat ("%d breakpoints enabled.\n", enable_count + loc_count);
1233 result.SetStatus (eReturnStatusSuccessFinishNoResult);
1234 }
1235 }
1236
1237 return result.Succeeded();
1238 }
1239};
1240
1241//-------------------------------------------------------------------------
1242// CommandObjectBreakpointDisable
1243//-------------------------------------------------------------------------
1244#pragma mark Disable
1245
1246class CommandObjectBreakpointDisable : public CommandObjectParsed
1247{
1248public:
1249 CommandObjectBreakpointDisable (CommandInterpreter &interpreter) :
1250 CommandObjectParsed (interpreter,
1251 "breakpoint disable",
Kate Stoneea671fb2015-07-14 05:48:36 +00001252 "Disable the specified breakpoint(s) without removing them. If none are specified, disable all breakpoints.",
Jim Ingham5a988412012-06-08 21:56:10 +00001253 NULL)
1254 {
Jim Inghamb0fac502013-03-08 00:31:40 +00001255 SetHelpLong(
Kate Stoneea671fb2015-07-14 05:48:36 +00001256"Disable the specified breakpoint(s) without removing them. \
1257If none are specified, disable all breakpoints." R"(
1258
1259)" "Note: disabling a breakpoint will cause none of its locations to be hit \
1260regardless of whether they are enabled or disabled. After the sequence:" R"(
1261
1262 (lldb) break disable 1
1263 (lldb) break enable 1.1
1264
1265execution will NOT stop at location 1.1. To achieve that, type:
1266
1267 (lldb) break disable 1.*
1268 (lldb) break enable 1.1
1269
1270)" "The first command disables all the locations of breakpoint 1, \
Jim Inghamb0fac502013-03-08 00:31:40 +00001271the second re-enables the first location."
Kate Stoneea671fb2015-07-14 05:48:36 +00001272 );
Jim Inghamb0fac502013-03-08 00:31:40 +00001273
Jim Ingham5a988412012-06-08 21:56:10 +00001274 CommandArgumentEntry arg;
1275 CommandObject::AddIDsArgumentData(arg, eArgTypeBreakpointID, eArgTypeBreakpointIDRange);
1276 // Add the entry for the first argument for this command to the object's arguments vector.
Jim Inghamb0fac502013-03-08 00:31:40 +00001277 m_arguments.push_back (arg);
1278
Jim Ingham5a988412012-06-08 21:56:10 +00001279 }
1280
1281
1282 virtual
1283 ~CommandObjectBreakpointDisable () {}
1284
1285protected:
1286 virtual bool
1287 DoExecute (Args& command, CommandReturnObject &result)
1288 {
Jim Ingham893c9322014-11-22 01:42:44 +00001289 Target *target = GetSelectedOrDummyTarget();
Jim Ingham5a988412012-06-08 21:56:10 +00001290 if (target == NULL)
1291 {
1292 result.AppendError ("Invalid target. No existing target or breakpoints.");
1293 result.SetStatus (eReturnStatusFailed);
1294 return false;
1295 }
1296
1297 Mutex::Locker locker;
1298 target->GetBreakpointList().GetListMutex(locker);
1299
1300 const BreakpointList &breakpoints = target->GetBreakpointList();
1301 size_t num_breakpoints = breakpoints.GetSize();
1302
1303 if (num_breakpoints == 0)
1304 {
1305 result.AppendError ("No breakpoints exist to be disabled.");
1306 result.SetStatus (eReturnStatusFailed);
1307 return false;
1308 }
1309
1310 if (command.GetArgumentCount() == 0)
1311 {
1312 // No breakpoint selected; disable all currently set breakpoints.
1313 target->DisableAllBreakpoints ();
Greg Clayton6fea17e2014-03-03 19:15:20 +00001314 result.AppendMessageWithFormat ("All breakpoints disabled. (%" PRIu64 " breakpoints)\n", (uint64_t)num_breakpoints);
Jim Ingham5a988412012-06-08 21:56:10 +00001315 result.SetStatus (eReturnStatusSuccessFinishNoResult);
1316 }
1317 else
1318 {
1319 // Particular breakpoint selected; disable that breakpoint.
1320 BreakpointIDList valid_bp_ids;
1321
Jim Ingham5e09c8c2014-12-16 23:40:14 +00001322 CommandObjectMultiwordBreakpoint::VerifyBreakpointOrLocationIDs (command, target, result, &valid_bp_ids);
Jim Ingham5a988412012-06-08 21:56:10 +00001323
1324 if (result.Succeeded())
1325 {
1326 int disable_count = 0;
1327 int loc_count = 0;
1328 const size_t count = valid_bp_ids.GetSize();
1329 for (size_t i = 0; i < count; ++i)
1330 {
1331 BreakpointID cur_bp_id = valid_bp_ids.GetBreakpointIDAtIndex (i);
1332
1333 if (cur_bp_id.GetBreakpointID() != LLDB_INVALID_BREAK_ID)
1334 {
1335 Breakpoint *breakpoint = target->GetBreakpointByID (cur_bp_id.GetBreakpointID()).get();
1336 if (cur_bp_id.GetLocationID() != LLDB_INVALID_BREAK_ID)
1337 {
1338 BreakpointLocation *location = breakpoint->FindLocationByID (cur_bp_id.GetLocationID()).get();
1339 if (location)
1340 {
1341 location->SetEnabled (false);
1342 ++loc_count;
1343 }
1344 }
1345 else
1346 {
1347 breakpoint->SetEnabled (false);
1348 ++disable_count;
1349 }
1350 }
1351 }
1352 result.AppendMessageWithFormat ("%d breakpoints disabled.\n", disable_count + loc_count);
1353 result.SetStatus (eReturnStatusSuccessFinishNoResult);
1354 }
1355 }
1356
1357 return result.Succeeded();
1358 }
1359
1360};
1361
1362//-------------------------------------------------------------------------
1363// CommandObjectBreakpointList
1364//-------------------------------------------------------------------------
1365#pragma mark List
1366
1367class CommandObjectBreakpointList : public CommandObjectParsed
1368{
1369public:
1370 CommandObjectBreakpointList (CommandInterpreter &interpreter) :
1371 CommandObjectParsed (interpreter,
1372 "breakpoint list",
1373 "List some or all breakpoints at configurable levels of detail.",
1374 NULL),
1375 m_options (interpreter)
1376 {
1377 CommandArgumentEntry arg;
1378 CommandArgumentData bp_id_arg;
1379
1380 // Define the first (and only) variant of this arg.
1381 bp_id_arg.arg_type = eArgTypeBreakpointID;
1382 bp_id_arg.arg_repetition = eArgRepeatOptional;
1383
1384 // There is only one variant this argument could be; put it into the argument entry.
1385 arg.push_back (bp_id_arg);
1386
1387 // Push the data for the first argument into the m_arguments vector.
1388 m_arguments.push_back (arg);
1389 }
1390
1391
1392 virtual
1393 ~CommandObjectBreakpointList () {}
1394
1395 virtual Options *
1396 GetOptions ()
1397 {
1398 return &m_options;
Jim Ingham1b54c882010-06-16 02:00:15 +00001399 }
1400
Jim Ingham5a988412012-06-08 21:56:10 +00001401 class CommandOptions : public Options
Chris Lattner30fdc8d2010-06-08 16:52:24 +00001402 {
Jim Ingham5a988412012-06-08 21:56:10 +00001403 public:
1404
1405 CommandOptions (CommandInterpreter &interpreter) :
1406 Options (interpreter),
Jim Ingham33df7cd2014-12-06 01:28:03 +00001407 m_level (lldb::eDescriptionLevelBrief),
1408 m_use_dummy(false)
Jim Ingham5a988412012-06-08 21:56:10 +00001409 {
1410 }
1411
1412 virtual
1413 ~CommandOptions () {}
1414
1415 virtual Error
1416 SetOptionValue (uint32_t option_idx, const char *option_arg)
1417 {
1418 Error error;
Greg Clayton3bcdfc02012-12-04 00:32:51 +00001419 const int short_option = m_getopt_table[option_idx].val;
Jim Ingham5a988412012-06-08 21:56:10 +00001420
1421 switch (short_option)
1422 {
1423 case 'b':
1424 m_level = lldb::eDescriptionLevelBrief;
1425 break;
Jim Ingham33df7cd2014-12-06 01:28:03 +00001426 case 'D':
1427 m_use_dummy = true;
1428 break;
Jim Ingham5a988412012-06-08 21:56:10 +00001429 case 'f':
1430 m_level = lldb::eDescriptionLevelFull;
1431 break;
1432 case 'v':
1433 m_level = lldb::eDescriptionLevelVerbose;
1434 break;
1435 case 'i':
1436 m_internal = true;
1437 break;
1438 default:
1439 error.SetErrorStringWithFormat ("unrecognized option '%c'", short_option);
1440 break;
1441 }
1442
1443 return error;
1444 }
1445
1446 void
1447 OptionParsingStarting ()
1448 {
1449 m_level = lldb::eDescriptionLevelFull;
1450 m_internal = false;
Jim Ingham33df7cd2014-12-06 01:28:03 +00001451 m_use_dummy = false;
Jim Ingham5a988412012-06-08 21:56:10 +00001452 }
1453
1454 const OptionDefinition *
1455 GetDefinitions ()
1456 {
1457 return g_option_table;
1458 }
1459
1460 // Options table: Required for subclasses of Options.
1461
1462 static OptionDefinition g_option_table[];
1463
1464 // Instance variables to hold the values for command options.
1465
1466 lldb::DescriptionLevel m_level;
1467
1468 bool m_internal;
Jim Ingham33df7cd2014-12-06 01:28:03 +00001469 bool m_use_dummy;
Jim Ingham5a988412012-06-08 21:56:10 +00001470 };
1471
1472protected:
1473 virtual bool
1474 DoExecute (Args& command, CommandReturnObject &result)
1475 {
Jim Ingham33df7cd2014-12-06 01:28:03 +00001476 Target *target = GetSelectedOrDummyTarget(m_options.m_use_dummy);
1477
Jim Ingham5a988412012-06-08 21:56:10 +00001478 if (target == NULL)
1479 {
1480 result.AppendError ("Invalid target. No current target or breakpoints.");
1481 result.SetStatus (eReturnStatusSuccessFinishNoResult);
1482 return true;
1483 }
1484
1485 const BreakpointList &breakpoints = target->GetBreakpointList(m_options.m_internal);
1486 Mutex::Locker locker;
1487 target->GetBreakpointList(m_options.m_internal).GetListMutex(locker);
1488
1489 size_t num_breakpoints = breakpoints.GetSize();
1490
1491 if (num_breakpoints == 0)
1492 {
1493 result.AppendMessage ("No breakpoints currently set.");
1494 result.SetStatus (eReturnStatusSuccessFinishNoResult);
1495 return true;
1496 }
1497
Jim Ingham85e8b812011-02-19 02:53:09 +00001498 Stream &output_stream = result.GetOutputStream();
Jim Ingham5a988412012-06-08 21:56:10 +00001499
1500 if (command.GetArgumentCount() == 0)
1501 {
1502 // No breakpoint selected; show info about all currently set breakpoints.
1503 result.AppendMessage ("Current breakpoints:");
1504 for (size_t i = 0; i < num_breakpoints; ++i)
1505 {
1506 Breakpoint *breakpoint = breakpoints.GetBreakpointAtIndex (i).get();
1507 AddBreakpointDescription (&output_stream, breakpoint, m_options.m_level);
1508 }
1509 result.SetStatus (eReturnStatusSuccessFinishNoResult);
1510 }
1511 else
1512 {
1513 // Particular breakpoints selected; show info about that breakpoint.
1514 BreakpointIDList valid_bp_ids;
Jim Ingham5e09c8c2014-12-16 23:40:14 +00001515 CommandObjectMultiwordBreakpoint::VerifyBreakpointOrLocationIDs (command, target, result, &valid_bp_ids);
Jim Ingham5a988412012-06-08 21:56:10 +00001516
1517 if (result.Succeeded())
1518 {
1519 for (size_t i = 0; i < valid_bp_ids.GetSize(); ++i)
1520 {
1521 BreakpointID cur_bp_id = valid_bp_ids.GetBreakpointIDAtIndex (i);
1522 Breakpoint *breakpoint = target->GetBreakpointByID (cur_bp_id.GetBreakpointID()).get();
1523 AddBreakpointDescription (&output_stream, breakpoint, m_options.m_level);
1524 }
1525 result.SetStatus (eReturnStatusSuccessFinishNoResult);
1526 }
1527 else
1528 {
1529 result.AppendError ("Invalid breakpoint id.");
1530 result.SetStatus (eReturnStatusFailed);
1531 }
1532 }
1533
1534 return result.Succeeded();
Chris Lattner30fdc8d2010-06-08 16:52:24 +00001535 }
1536
Jim Ingham5a988412012-06-08 21:56:10 +00001537private:
1538 CommandOptions m_options;
1539};
1540
1541#pragma mark List::CommandOptions
1542OptionDefinition
1543CommandObjectBreakpointList::CommandOptions::g_option_table[] =
1544{
Zachary Turnerd37221d2014-07-09 16:31:49 +00001545 { LLDB_OPT_SET_ALL, false, "internal", 'i', OptionParser::eNoArgument, NULL, NULL, 0, eArgTypeNone,
Jim Ingham5a988412012-06-08 21:56:10 +00001546 "Show debugger internal breakpoints" },
1547
Zachary Turnerd37221d2014-07-09 16:31:49 +00001548 { LLDB_OPT_SET_1, false, "brief", 'b', OptionParser::eNoArgument, NULL, NULL, 0, eArgTypeNone,
Jim Ingham5a988412012-06-08 21:56:10 +00001549 "Give a brief description of the breakpoint (no location info)."},
1550
1551 // FIXME: We need to add an "internal" command, and then add this sort of thing to it.
1552 // But I need to see it for now, and don't want to wait.
Zachary Turnerd37221d2014-07-09 16:31:49 +00001553 { LLDB_OPT_SET_2, false, "full", 'f', OptionParser::eNoArgument, NULL, NULL, 0, eArgTypeNone,
Jim Ingham5a988412012-06-08 21:56:10 +00001554 "Give a full description of the breakpoint and its locations."},
1555
Zachary Turnerd37221d2014-07-09 16:31:49 +00001556 { LLDB_OPT_SET_3, false, "verbose", 'v', OptionParser::eNoArgument, NULL, NULL, 0, eArgTypeNone,
Jim Ingham5a988412012-06-08 21:56:10 +00001557 "Explain everything we know about the breakpoint (for debugging debugger bugs)." },
1558
Jim Ingham33df7cd2014-12-06 01:28:03 +00001559 { LLDB_OPT_SET_ALL, false, "dummy-breakpoints", 'D', OptionParser::eNoArgument, NULL, NULL, 0, eArgTypeNone,
1560 "List Dummy breakpoints - i.e. breakpoints set before a file is provided, which prime new targets."},
1561
Zachary Turnerd37221d2014-07-09 16:31:49 +00001562 { 0, false, NULL, 0, 0, NULL, NULL, 0, eArgTypeNone, NULL }
Jim Ingham5a988412012-06-08 21:56:10 +00001563};
1564
1565//-------------------------------------------------------------------------
1566// CommandObjectBreakpointClear
1567//-------------------------------------------------------------------------
1568#pragma mark Clear
1569
1570class CommandObjectBreakpointClear : public CommandObjectParsed
1571{
1572public:
1573
1574 typedef enum BreakpointClearType
1575 {
1576 eClearTypeInvalid,
1577 eClearTypeFileAndLine
1578 } BreakpointClearType;
1579
1580 CommandObjectBreakpointClear (CommandInterpreter &interpreter) :
1581 CommandObjectParsed (interpreter,
1582 "breakpoint clear",
1583 "Clears a breakpoint or set of breakpoints in the executable.",
1584 "breakpoint clear <cmd-options>"),
1585 m_options (interpreter)
1586 {
1587 }
1588
1589 virtual
1590 ~CommandObjectBreakpointClear () {}
1591
1592 virtual Options *
1593 GetOptions ()
1594 {
1595 return &m_options;
1596 }
1597
1598 class CommandOptions : public Options
1599 {
1600 public:
1601
1602 CommandOptions (CommandInterpreter &interpreter) :
1603 Options (interpreter),
1604 m_filename (),
1605 m_line_num (0)
1606 {
1607 }
1608
1609 virtual
1610 ~CommandOptions () {}
1611
1612 virtual Error
1613 SetOptionValue (uint32_t option_idx, const char *option_arg)
1614 {
1615 Error error;
Greg Clayton3bcdfc02012-12-04 00:32:51 +00001616 const int short_option = m_getopt_table[option_idx].val;
Jim Ingham5a988412012-06-08 21:56:10 +00001617
1618 switch (short_option)
1619 {
1620 case 'f':
1621 m_filename.assign (option_arg);
1622 break;
1623
1624 case 'l':
Vince Harron5275aaa2015-01-15 20:08:35 +00001625 m_line_num = StringConvert::ToUInt32 (option_arg, 0);
Jim Ingham5a988412012-06-08 21:56:10 +00001626 break;
1627
1628 default:
1629 error.SetErrorStringWithFormat ("unrecognized option '%c'", short_option);
1630 break;
1631 }
1632
1633 return error;
1634 }
1635
1636 void
1637 OptionParsingStarting ()
1638 {
1639 m_filename.clear();
1640 m_line_num = 0;
1641 }
1642
1643 const OptionDefinition*
1644 GetDefinitions ()
1645 {
1646 return g_option_table;
1647 }
1648
1649 // Options table: Required for subclasses of Options.
1650
1651 static OptionDefinition g_option_table[];
1652
1653 // Instance variables to hold the values for command options.
1654
1655 std::string m_filename;
1656 uint32_t m_line_num;
1657
1658 };
1659
1660protected:
1661 virtual bool
1662 DoExecute (Args& command, CommandReturnObject &result)
1663 {
Jim Ingham893c9322014-11-22 01:42:44 +00001664 Target *target = GetSelectedOrDummyTarget();
Jim Ingham5a988412012-06-08 21:56:10 +00001665 if (target == NULL)
1666 {
1667 result.AppendError ("Invalid target. No existing target or breakpoints.");
1668 result.SetStatus (eReturnStatusFailed);
1669 return false;
1670 }
1671
1672 // The following are the various types of breakpoints that could be cleared:
1673 // 1). -f -l (clearing breakpoint by source location)
1674
1675 BreakpointClearType break_type = eClearTypeInvalid;
1676
1677 if (m_options.m_line_num != 0)
1678 break_type = eClearTypeFileAndLine;
1679
1680 Mutex::Locker locker;
1681 target->GetBreakpointList().GetListMutex(locker);
1682
1683 BreakpointList &breakpoints = target->GetBreakpointList();
1684 size_t num_breakpoints = breakpoints.GetSize();
1685
1686 // Early return if there's no breakpoint at all.
1687 if (num_breakpoints == 0)
1688 {
1689 result.AppendError ("Breakpoint clear: No breakpoint cleared.");
1690 result.SetStatus (eReturnStatusFailed);
1691 return result.Succeeded();
1692 }
1693
1694 // Find matching breakpoints and delete them.
1695
1696 // First create a copy of all the IDs.
1697 std::vector<break_id_t> BreakIDs;
1698 for (size_t i = 0; i < num_breakpoints; ++i)
1699 BreakIDs.push_back(breakpoints.GetBreakpointAtIndex(i).get()->GetID());
1700
1701 int num_cleared = 0;
1702 StreamString ss;
1703 switch (break_type)
1704 {
1705 case eClearTypeFileAndLine: // Breakpoint by source position
1706 {
1707 const ConstString filename(m_options.m_filename.c_str());
1708 BreakpointLocationCollection loc_coll;
1709
1710 for (size_t i = 0; i < num_breakpoints; ++i)
1711 {
1712 Breakpoint *bp = breakpoints.FindBreakpointByID(BreakIDs[i]).get();
1713
1714 if (bp->GetMatchingFileLine(filename, m_options.m_line_num, loc_coll))
1715 {
1716 // If the collection size is 0, it's a full match and we can just remove the breakpoint.
1717 if (loc_coll.GetSize() == 0)
1718 {
1719 bp->GetDescription(&ss, lldb::eDescriptionLevelBrief);
1720 ss.EOL();
1721 target->RemoveBreakpointByID (bp->GetID());
1722 ++num_cleared;
1723 }
1724 }
1725 }
1726 }
1727 break;
1728
1729 default:
1730 break;
1731 }
1732
1733 if (num_cleared > 0)
1734 {
1735 Stream &output_stream = result.GetOutputStream();
1736 output_stream.Printf ("%d breakpoints cleared:\n", num_cleared);
1737 output_stream << ss.GetData();
1738 output_stream.EOL();
1739 result.SetStatus (eReturnStatusSuccessFinishNoResult);
1740 }
1741 else
1742 {
1743 result.AppendError ("Breakpoint clear: No breakpoint cleared.");
1744 result.SetStatus (eReturnStatusFailed);
1745 }
1746
1747 return result.Succeeded();
1748 }
1749
1750private:
1751 CommandOptions m_options;
1752};
1753
1754#pragma mark Clear::CommandOptions
1755
1756OptionDefinition
1757CommandObjectBreakpointClear::CommandOptions::g_option_table[] =
1758{
Zachary Turnerd37221d2014-07-09 16:31:49 +00001759 { LLDB_OPT_SET_1, false, "file", 'f', OptionParser::eRequiredArgument, NULL, NULL, CommandCompletions::eSourceFileCompletion, eArgTypeFilename,
Jim Ingham5a988412012-06-08 21:56:10 +00001760 "Specify the breakpoint by source location in this particular file."},
1761
Zachary Turnerd37221d2014-07-09 16:31:49 +00001762 { LLDB_OPT_SET_1, true, "line", 'l', OptionParser::eRequiredArgument, NULL, NULL, 0, eArgTypeLineNum,
Jim Ingham5a988412012-06-08 21:56:10 +00001763 "Specify the breakpoint by source location at this particular line."},
1764
Zachary Turnerd37221d2014-07-09 16:31:49 +00001765 { 0, false, NULL, 0, 0, NULL, NULL, 0, eArgTypeNone, NULL }
Jim Ingham5a988412012-06-08 21:56:10 +00001766};
1767
1768//-------------------------------------------------------------------------
1769// CommandObjectBreakpointDelete
1770//-------------------------------------------------------------------------
1771#pragma mark Delete
1772
1773class CommandObjectBreakpointDelete : public CommandObjectParsed
1774{
1775public:
1776 CommandObjectBreakpointDelete (CommandInterpreter &interpreter) :
1777 CommandObjectParsed (interpreter,
1778 "breakpoint delete",
1779 "Delete the specified breakpoint(s). If no breakpoints are specified, delete them all.",
Jim Ingham33df7cd2014-12-06 01:28:03 +00001780 NULL),
1781 m_options (interpreter)
Jim Ingham5a988412012-06-08 21:56:10 +00001782 {
1783 CommandArgumentEntry arg;
1784 CommandObject::AddIDsArgumentData(arg, eArgTypeBreakpointID, eArgTypeBreakpointIDRange);
1785 // Add the entry for the first argument for this command to the object's arguments vector.
1786 m_arguments.push_back (arg);
1787 }
1788
1789 virtual
1790 ~CommandObjectBreakpointDelete () {}
1791
Jim Ingham33df7cd2014-12-06 01:28:03 +00001792 virtual Options *
1793 GetOptions ()
1794 {
1795 return &m_options;
1796 }
1797
1798 class CommandOptions : public Options
1799 {
1800 public:
1801
1802 CommandOptions (CommandInterpreter &interpreter) :
1803 Options (interpreter),
1804 m_use_dummy (false),
1805 m_force (false)
1806 {
1807 }
1808
1809 virtual
1810 ~CommandOptions () {}
1811
1812 virtual Error
1813 SetOptionValue (uint32_t option_idx, const char *option_arg)
1814 {
1815 Error error;
1816 const int short_option = m_getopt_table[option_idx].val;
1817
1818 switch (short_option)
1819 {
1820 case 'f':
1821 m_force = true;
1822 break;
1823
1824 case 'D':
1825 m_use_dummy = true;
1826 break;
1827
1828 default:
1829 error.SetErrorStringWithFormat ("unrecognized option '%c'", short_option);
1830 break;
1831 }
1832
1833 return error;
1834 }
1835
1836 void
1837 OptionParsingStarting ()
1838 {
1839 m_use_dummy = false;
1840 m_force = false;
1841 }
1842
1843 const OptionDefinition*
1844 GetDefinitions ()
1845 {
1846 return g_option_table;
1847 }
1848
1849 // Options table: Required for subclasses of Options.
1850
1851 static OptionDefinition g_option_table[];
1852
1853 // Instance variables to hold the values for command options.
1854 bool m_use_dummy;
1855 bool m_force;
1856 };
1857
Jim Ingham5a988412012-06-08 21:56:10 +00001858protected:
1859 virtual bool
1860 DoExecute (Args& command, CommandReturnObject &result)
1861 {
Jim Ingham33df7cd2014-12-06 01:28:03 +00001862 Target *target = GetSelectedOrDummyTarget(m_options.m_use_dummy);
1863
Jim Ingham5a988412012-06-08 21:56:10 +00001864 if (target == NULL)
1865 {
1866 result.AppendError ("Invalid target. No existing target or breakpoints.");
1867 result.SetStatus (eReturnStatusFailed);
1868 return false;
1869 }
1870
1871 Mutex::Locker locker;
1872 target->GetBreakpointList().GetListMutex(locker);
1873
1874 const BreakpointList &breakpoints = target->GetBreakpointList();
1875
1876 size_t num_breakpoints = breakpoints.GetSize();
1877
1878 if (num_breakpoints == 0)
1879 {
1880 result.AppendError ("No breakpoints exist to be deleted.");
1881 result.SetStatus (eReturnStatusFailed);
1882 return false;
1883 }
1884
1885 if (command.GetArgumentCount() == 0)
1886 {
Jim Ingham33df7cd2014-12-06 01:28:03 +00001887 if (!m_options.m_force && !m_interpreter.Confirm ("About to delete all breakpoints, do you want to do that?", true))
Jim Ingham5a988412012-06-08 21:56:10 +00001888 {
1889 result.AppendMessage("Operation cancelled...");
1890 }
1891 else
1892 {
1893 target->RemoveAllBreakpoints ();
Greg Clayton6fea17e2014-03-03 19:15:20 +00001894 result.AppendMessageWithFormat ("All breakpoints removed. (%" PRIu64 " breakpoint%s)\n", (uint64_t)num_breakpoints, num_breakpoints > 1 ? "s" : "");
Jim Ingham5a988412012-06-08 21:56:10 +00001895 }
1896 result.SetStatus (eReturnStatusSuccessFinishNoResult);
1897 }
1898 else
1899 {
1900 // Particular breakpoint selected; disable that breakpoint.
1901 BreakpointIDList valid_bp_ids;
Jim Ingham5e09c8c2014-12-16 23:40:14 +00001902 CommandObjectMultiwordBreakpoint::VerifyBreakpointOrLocationIDs (command, target, result, &valid_bp_ids);
Jim Ingham5a988412012-06-08 21:56:10 +00001903
1904 if (result.Succeeded())
1905 {
1906 int delete_count = 0;
1907 int disable_count = 0;
1908 const size_t count = valid_bp_ids.GetSize();
1909 for (size_t i = 0; i < count; ++i)
1910 {
1911 BreakpointID cur_bp_id = valid_bp_ids.GetBreakpointIDAtIndex (i);
1912
1913 if (cur_bp_id.GetBreakpointID() != LLDB_INVALID_BREAK_ID)
1914 {
1915 if (cur_bp_id.GetLocationID() != LLDB_INVALID_BREAK_ID)
1916 {
1917 Breakpoint *breakpoint = target->GetBreakpointByID (cur_bp_id.GetBreakpointID()).get();
1918 BreakpointLocation *location = breakpoint->FindLocationByID (cur_bp_id.GetLocationID()).get();
1919 // It makes no sense to try to delete individual locations, so we disable them instead.
1920 if (location)
1921 {
1922 location->SetEnabled (false);
1923 ++disable_count;
1924 }
1925 }
1926 else
1927 {
1928 target->RemoveBreakpointByID (cur_bp_id.GetBreakpointID());
1929 ++delete_count;
1930 }
1931 }
1932 }
1933 result.AppendMessageWithFormat ("%d breakpoints deleted; %d breakpoint locations disabled.\n",
1934 delete_count, disable_count);
1935 result.SetStatus (eReturnStatusSuccessFinishNoResult);
1936 }
1937 }
1938 return result.Succeeded();
1939 }
Jim Ingham33df7cd2014-12-06 01:28:03 +00001940private:
1941 CommandOptions m_options;
1942};
1943
1944OptionDefinition
1945CommandObjectBreakpointDelete::CommandOptions::g_option_table[] =
1946{
1947 { LLDB_OPT_SET_1, false, "force", 'f', OptionParser::eNoArgument, NULL, NULL, 0, eArgTypeNone,
1948 "Delete all breakpoints without querying for confirmation."},
1949
1950 { LLDB_OPT_SET_1, false, "dummy-breakpoints", 'D', OptionParser::eNoArgument, NULL, NULL, 0, eArgTypeNone,
1951 "Delete Dummy breakpoints - i.e. breakpoints set before a file is provided, which prime new targets."},
1952
1953 { 0, false, NULL, 0, 0, NULL, NULL, 0, eArgTypeNone, NULL }
Jim Ingham5a988412012-06-08 21:56:10 +00001954};
Chris Lattner30fdc8d2010-06-08 16:52:24 +00001955
Chris Lattner30fdc8d2010-06-08 16:52:24 +00001956//-------------------------------------------------------------------------
Jim Ingham5e09c8c2014-12-16 23:40:14 +00001957// CommandObjectBreakpointName
1958//-------------------------------------------------------------------------
1959
1960static OptionDefinition
1961g_breakpoint_name_options[] =
1962{
1963 { LLDB_OPT_SET_1, false, "name", 'N', OptionParser::eRequiredArgument, NULL, NULL, 0, eArgTypeBreakpointName, "Specifies a breakpoint name to use."},
1964 { LLDB_OPT_SET_2, false, "breakpoint-id", 'B', OptionParser::eRequiredArgument, NULL, NULL, 0, eArgTypeBreakpointID, "Specify a breakpoint id to use."},
1965 { LLDB_OPT_SET_ALL, false, "dummy-breakpoints", 'D', OptionParser::eNoArgument, NULL, NULL, 0, eArgTypeNone,
1966 "Operate on Dummy breakpoints - i.e. breakpoints set before a file is provided, which prime new targets."},
1967};
1968class BreakpointNameOptionGroup : public OptionGroup
1969{
1970public:
1971 BreakpointNameOptionGroup() :
1972 OptionGroup(),
1973 m_breakpoint(LLDB_INVALID_BREAK_ID),
1974 m_use_dummy (false)
1975 {
1976
1977 }
1978
1979 virtual
1980 ~BreakpointNameOptionGroup ()
1981 {
1982 }
1983
1984 virtual uint32_t
1985 GetNumDefinitions ()
1986 {
1987 return sizeof (g_breakpoint_name_options) / sizeof (OptionDefinition);
1988 }
1989
1990 virtual const OptionDefinition*
1991 GetDefinitions ()
1992 {
1993 return g_breakpoint_name_options;
1994 }
1995
1996 virtual Error
1997 SetOptionValue (CommandInterpreter &interpreter,
1998 uint32_t option_idx,
1999 const char *option_value)
2000 {
2001 Error error;
2002 const int short_option = g_breakpoint_name_options[option_idx].short_option;
2003
2004 switch (short_option)
2005 {
2006 case 'N':
2007 if (BreakpointID::StringIsBreakpointName(option_value, error) && error.Success())
Pavel Labathc95f7e22015-02-20 11:14:59 +00002008 m_name.SetValueFromString(option_value);
Jim Ingham5e09c8c2014-12-16 23:40:14 +00002009 break;
2010
2011 case 'B':
Pavel Labathc95f7e22015-02-20 11:14:59 +00002012 if (m_breakpoint.SetValueFromString(option_value).Fail())
Jim Ingham5e09c8c2014-12-16 23:40:14 +00002013 error.SetErrorStringWithFormat ("unrecognized value \"%s\" for breakpoint", option_value);
2014 break;
2015 case 'D':
Pavel Labathc95f7e22015-02-20 11:14:59 +00002016 if (m_use_dummy.SetValueFromString(option_value).Fail())
Jim Ingham5e09c8c2014-12-16 23:40:14 +00002017 error.SetErrorStringWithFormat ("unrecognized value \"%s\" for use-dummy", option_value);
2018 break;
2019
2020 default:
2021 error.SetErrorStringWithFormat("unrecognized short option '%c'", short_option);
2022 break;
2023 }
2024 return error;
2025 }
2026
2027 virtual void
2028 OptionParsingStarting (CommandInterpreter &interpreter)
2029 {
2030 m_name.Clear();
2031 m_breakpoint.Clear();
2032 m_use_dummy.Clear();
2033 m_use_dummy.SetDefaultValue(false);
2034 }
2035
2036 OptionValueString m_name;
2037 OptionValueUInt64 m_breakpoint;
2038 OptionValueBoolean m_use_dummy;
2039};
2040
2041
2042class CommandObjectBreakpointNameAdd : public CommandObjectParsed
2043{
2044public:
2045 CommandObjectBreakpointNameAdd (CommandInterpreter &interpreter) :
2046 CommandObjectParsed (interpreter,
2047 "add",
2048 "Add a name to the breakpoints provided.",
2049 "breakpoint name add <command-options> <breakpoint-id-list>"),
2050 m_name_options(),
2051 m_option_group(interpreter)
2052 {
2053 // Create the first variant for the first (and only) argument for this command.
2054 CommandArgumentEntry arg1;
2055 CommandArgumentData id_arg;
2056 id_arg.arg_type = eArgTypeBreakpointID;
2057 id_arg.arg_repetition = eArgRepeatOptional;
2058 arg1.push_back(id_arg);
2059 m_arguments.push_back (arg1);
2060
2061 m_option_group.Append (&m_name_options, LLDB_OPT_SET_1, LLDB_OPT_SET_ALL);
2062 m_option_group.Finalize();
2063 }
2064
2065 virtual
2066 ~CommandObjectBreakpointNameAdd () {}
2067
2068 Options *
2069 GetOptions ()
2070 {
2071 return &m_option_group;
2072 }
2073
2074protected:
2075 virtual bool
2076 DoExecute (Args& command, CommandReturnObject &result)
2077 {
2078 if (!m_name_options.m_name.OptionWasSet())
2079 {
2080 result.SetError("No name option provided.");
2081 return false;
2082 }
2083
2084 Target *target = GetSelectedOrDummyTarget(m_name_options.m_use_dummy.GetCurrentValue());
2085
2086 if (target == NULL)
2087 {
2088 result.AppendError ("Invalid target. No existing target or breakpoints.");
2089 result.SetStatus (eReturnStatusFailed);
2090 return false;
2091 }
2092
2093 Mutex::Locker locker;
2094 target->GetBreakpointList().GetListMutex(locker);
2095
2096 const BreakpointList &breakpoints = target->GetBreakpointList();
2097
2098 size_t num_breakpoints = breakpoints.GetSize();
2099 if (num_breakpoints == 0)
2100 {
2101 result.SetError("No breakpoints, cannot add names.");
2102 result.SetStatus (eReturnStatusFailed);
2103 return false;
2104 }
2105
2106 // Particular breakpoint selected; disable that breakpoint.
2107 BreakpointIDList valid_bp_ids;
2108 CommandObjectMultiwordBreakpoint::VerifyBreakpointIDs (command, target, result, &valid_bp_ids);
2109
2110 if (result.Succeeded())
2111 {
2112 if (valid_bp_ids.GetSize() == 0)
2113 {
2114 result.SetError("No breakpoints specified, cannot add names.");
2115 result.SetStatus (eReturnStatusFailed);
2116 return false;
2117 }
2118 size_t num_valid_ids = valid_bp_ids.GetSize();
2119 for (size_t index = 0; index < num_valid_ids; index++)
2120 {
2121 lldb::break_id_t bp_id = valid_bp_ids.GetBreakpointIDAtIndex(index).GetBreakpointID();
2122 BreakpointSP bp_sp = breakpoints.FindBreakpointByID(bp_id);
2123 Error error; // We don't need to check the error here, since the option parser checked it...
2124 bp_sp->AddName(m_name_options.m_name.GetCurrentValue(), error);
2125 }
2126 }
2127
2128 return true;
2129 }
2130
2131private:
2132 BreakpointNameOptionGroup m_name_options;
2133 OptionGroupOptions m_option_group;
2134};
2135
2136
2137
2138class CommandObjectBreakpointNameDelete : public CommandObjectParsed
2139{
2140public:
2141 CommandObjectBreakpointNameDelete (CommandInterpreter &interpreter) :
2142 CommandObjectParsed (interpreter,
2143 "delete",
2144 "Delete a name from the breakpoints provided.",
2145 "breakpoint name delete <command-options> <breakpoint-id-list>"),
2146 m_name_options(),
2147 m_option_group(interpreter)
2148 {
2149 // Create the first variant for the first (and only) argument for this command.
2150 CommandArgumentEntry arg1;
2151 CommandArgumentData id_arg;
2152 id_arg.arg_type = eArgTypeBreakpointID;
2153 id_arg.arg_repetition = eArgRepeatOptional;
2154 arg1.push_back(id_arg);
2155 m_arguments.push_back (arg1);
2156
2157 m_option_group.Append (&m_name_options, LLDB_OPT_SET_1, LLDB_OPT_SET_ALL);
2158 m_option_group.Finalize();
2159 }
2160
2161 virtual
2162 ~CommandObjectBreakpointNameDelete () {}
2163
2164 Options *
2165 GetOptions ()
2166 {
2167 return &m_option_group;
2168 }
2169
2170protected:
2171 virtual bool
2172 DoExecute (Args& command, CommandReturnObject &result)
2173 {
2174 if (!m_name_options.m_name.OptionWasSet())
2175 {
2176 result.SetError("No name option provided.");
2177 return false;
2178 }
2179
2180 Target *target = GetSelectedOrDummyTarget(m_name_options.m_use_dummy.GetCurrentValue());
2181
2182 if (target == NULL)
2183 {
2184 result.AppendError ("Invalid target. No existing target or breakpoints.");
2185 result.SetStatus (eReturnStatusFailed);
2186 return false;
2187 }
2188
2189 Mutex::Locker locker;
2190 target->GetBreakpointList().GetListMutex(locker);
2191
2192 const BreakpointList &breakpoints = target->GetBreakpointList();
2193
2194 size_t num_breakpoints = breakpoints.GetSize();
2195 if (num_breakpoints == 0)
2196 {
2197 result.SetError("No breakpoints, cannot delete names.");
2198 result.SetStatus (eReturnStatusFailed);
2199 return false;
2200 }
2201
2202 // Particular breakpoint selected; disable that breakpoint.
2203 BreakpointIDList valid_bp_ids;
2204 CommandObjectMultiwordBreakpoint::VerifyBreakpointIDs (command, target, result, &valid_bp_ids);
2205
2206 if (result.Succeeded())
2207 {
2208 if (valid_bp_ids.GetSize() == 0)
2209 {
2210 result.SetError("No breakpoints specified, cannot delete names.");
2211 result.SetStatus (eReturnStatusFailed);
2212 return false;
2213 }
2214 size_t num_valid_ids = valid_bp_ids.GetSize();
2215 for (size_t index = 0; index < num_valid_ids; index++)
2216 {
2217 lldb::break_id_t bp_id = valid_bp_ids.GetBreakpointIDAtIndex(index).GetBreakpointID();
2218 BreakpointSP bp_sp = breakpoints.FindBreakpointByID(bp_id);
2219 bp_sp->RemoveName(m_name_options.m_name.GetCurrentValue());
2220 }
2221 }
2222
2223 return true;
2224 }
2225
2226private:
2227 BreakpointNameOptionGroup m_name_options;
2228 OptionGroupOptions m_option_group;
2229};
2230
2231class CommandObjectBreakpointNameList : public CommandObjectParsed
2232{
2233public:
2234 CommandObjectBreakpointNameList (CommandInterpreter &interpreter) :
2235 CommandObjectParsed (interpreter,
2236 "list",
2237 "List either the names for a breakpoint or the breakpoints for a given name.",
2238 "breakpoint name list <command-options>"),
2239 m_name_options(),
2240 m_option_group(interpreter)
2241 {
2242 m_option_group.Append (&m_name_options);
2243 m_option_group.Finalize();
2244 }
2245
2246 virtual
2247 ~CommandObjectBreakpointNameList () {}
2248
2249 Options *
2250 GetOptions ()
2251 {
2252 return &m_option_group;
2253 }
2254
2255protected:
Jim Ingham5e09c8c2014-12-16 23:40:14 +00002256 virtual bool
2257 DoExecute (Args& command, CommandReturnObject &result)
2258 {
2259 Target *target = GetSelectedOrDummyTarget(m_name_options.m_use_dummy.GetCurrentValue());
2260
2261 if (target == NULL)
2262 {
2263 result.AppendError ("Invalid target. No existing target or breakpoints.");
2264 result.SetStatus (eReturnStatusFailed);
2265 return false;
2266 }
2267
2268 if (m_name_options.m_name.OptionWasSet())
2269 {
2270 const char *name = m_name_options.m_name.GetCurrentValue();
2271 Mutex::Locker locker;
2272 target->GetBreakpointList().GetListMutex(locker);
2273
2274 BreakpointList &breakpoints = target->GetBreakpointList();
2275 for (BreakpointSP bp_sp : breakpoints.Breakpoints())
2276 {
2277 if (bp_sp->MatchesName(name))
2278 {
2279 StreamString s;
2280 bp_sp->GetDescription(&s, eDescriptionLevelBrief);
2281 s.EOL();
2282 result.AppendMessage(s.GetData());
2283 }
2284 }
2285
2286 }
2287 else if (m_name_options.m_breakpoint.OptionWasSet())
2288 {
2289 BreakpointSP bp_sp = target->GetBreakpointList().FindBreakpointByID(m_name_options.m_breakpoint.GetCurrentValue());
2290 if (bp_sp)
2291 {
2292 std::vector<std::string> names;
2293 bp_sp->GetNames (names);
2294 result.AppendMessage ("Names:");
2295 for (auto name : names)
2296 result.AppendMessageWithFormat (" %s\n", name.c_str());
2297 }
2298 else
2299 {
2300 result.AppendErrorWithFormat ("Could not find breakpoint %" PRId64 ".\n",
2301 m_name_options.m_breakpoint.GetCurrentValue());
2302 result.SetStatus (eReturnStatusFailed);
2303 return false;
2304 }
2305 }
2306 else
2307 {
2308 result.SetError ("Must specify -N or -B option to list.");
2309 result.SetStatus (eReturnStatusFailed);
2310 return false;
2311 }
2312 return true;
2313 }
2314
2315private:
2316 BreakpointNameOptionGroup m_name_options;
2317 OptionGroupOptions m_option_group;
2318};
2319
2320//-------------------------------------------------------------------------
2321// CommandObjectMultiwordBreakpoint
2322//-------------------------------------------------------------------------
2323class CommandObjectBreakpointName : public CommandObjectMultiword
2324{
2325public:
2326 CommandObjectBreakpointName (CommandInterpreter &interpreter) :
2327 CommandObjectMultiword(interpreter,
2328 "name",
2329 "A set of commands to manage name tags for breakpoints",
2330 "breakpoint name <command> [<command-options>]")
2331 {
2332 CommandObjectSP add_command_object (new CommandObjectBreakpointNameAdd (interpreter));
2333 CommandObjectSP delete_command_object (new CommandObjectBreakpointNameDelete (interpreter));
2334 CommandObjectSP list_command_object (new CommandObjectBreakpointNameList (interpreter));
2335
2336 LoadSubCommand ("add", add_command_object);
2337 LoadSubCommand ("delete", delete_command_object);
2338 LoadSubCommand ("list", list_command_object);
2339
2340 }
2341
2342 virtual
2343 ~CommandObjectBreakpointName ()
2344 {
2345 }
2346
2347};
2348
2349
2350//-------------------------------------------------------------------------
Chris Lattner30fdc8d2010-06-08 16:52:24 +00002351// CommandObjectMultiwordBreakpoint
2352//-------------------------------------------------------------------------
Jim Inghamae1c4cf2010-06-18 00:58:52 +00002353#pragma mark MultiwordBreakpoint
Chris Lattner30fdc8d2010-06-08 16:52:24 +00002354
Greg Clayton66111032010-06-23 01:19:29 +00002355CommandObjectMultiwordBreakpoint::CommandObjectMultiwordBreakpoint (CommandInterpreter &interpreter) :
Greg Claytona7015092010-09-18 01:14:36 +00002356 CommandObjectMultiword (interpreter,
2357 "breakpoint",
Jim Ingham46fbc602011-05-26 20:39:01 +00002358 "A set of commands for operating on breakpoints. Also see _regexp-break.",
Greg Claytona7015092010-09-18 01:14:36 +00002359 "breakpoint <command> [<command-options>]")
Chris Lattner30fdc8d2010-06-08 16:52:24 +00002360{
Greg Claytona7015092010-09-18 01:14:36 +00002361 CommandObjectSP list_command_object (new CommandObjectBreakpointList (interpreter));
Greg Claytona7015092010-09-18 01:14:36 +00002362 CommandObjectSP enable_command_object (new CommandObjectBreakpointEnable (interpreter));
2363 CommandObjectSP disable_command_object (new CommandObjectBreakpointDisable (interpreter));
Johnny Chenb7234e42010-10-28 17:27:46 +00002364 CommandObjectSP clear_command_object (new CommandObjectBreakpointClear (interpreter));
2365 CommandObjectSP delete_command_object (new CommandObjectBreakpointDelete (interpreter));
Greg Claytona7015092010-09-18 01:14:36 +00002366 CommandObjectSP set_command_object (new CommandObjectBreakpointSet (interpreter));
Chris Lattner30fdc8d2010-06-08 16:52:24 +00002367 CommandObjectSP command_command_object (new CommandObjectBreakpointCommand (interpreter));
Greg Claytona7015092010-09-18 01:14:36 +00002368 CommandObjectSP modify_command_object (new CommandObjectBreakpointModify(interpreter));
Jim Ingham5e09c8c2014-12-16 23:40:14 +00002369 CommandObjectSP name_command_object (new CommandObjectBreakpointName(interpreter));
Chris Lattner30fdc8d2010-06-08 16:52:24 +00002370
Johnny Chenb7234e42010-10-28 17:27:46 +00002371 list_command_object->SetCommandName ("breakpoint list");
Chris Lattner30fdc8d2010-06-08 16:52:24 +00002372 enable_command_object->SetCommandName("breakpoint enable");
2373 disable_command_object->SetCommandName("breakpoint disable");
Johnny Chenb7234e42010-10-28 17:27:46 +00002374 clear_command_object->SetCommandName("breakpoint clear");
2375 delete_command_object->SetCommandName("breakpoint delete");
Jim Inghamae1c4cf2010-06-18 00:58:52 +00002376 set_command_object->SetCommandName("breakpoint set");
Johnny Chenb7234e42010-10-28 17:27:46 +00002377 command_command_object->SetCommandName ("breakpoint command");
2378 modify_command_object->SetCommandName ("breakpoint modify");
Jim Ingham5e09c8c2014-12-16 23:40:14 +00002379 name_command_object->SetCommandName ("breakpoint name");
Chris Lattner30fdc8d2010-06-08 16:52:24 +00002380
Greg Clayton23f59502012-07-17 03:23:13 +00002381 LoadSubCommand ("list", list_command_object);
2382 LoadSubCommand ("enable", enable_command_object);
2383 LoadSubCommand ("disable", disable_command_object);
2384 LoadSubCommand ("clear", clear_command_object);
2385 LoadSubCommand ("delete", delete_command_object);
2386 LoadSubCommand ("set", set_command_object);
2387 LoadSubCommand ("command", command_command_object);
2388 LoadSubCommand ("modify", modify_command_object);
Jim Ingham5e09c8c2014-12-16 23:40:14 +00002389 LoadSubCommand ("name", name_command_object);
Chris Lattner30fdc8d2010-06-08 16:52:24 +00002390}
2391
2392CommandObjectMultiwordBreakpoint::~CommandObjectMultiwordBreakpoint ()
2393{
2394}
2395
2396void
Jim Ingham5e09c8c2014-12-16 23:40:14 +00002397CommandObjectMultiwordBreakpoint::VerifyIDs (Args &args,
2398 Target *target,
2399 bool allow_locations,
2400 CommandReturnObject &result,
2401 BreakpointIDList *valid_ids)
Chris Lattner30fdc8d2010-06-08 16:52:24 +00002402{
2403 // args can be strings representing 1). integers (for breakpoint ids)
2404 // 2). the full breakpoint & location canonical representation
2405 // 3). the word "to" or a hyphen, representing a range (in which case there
2406 // had *better* be an entry both before & after of one of the first two types.
Jim Ingham5e09c8c2014-12-16 23:40:14 +00002407 // 4). A breakpoint name
Jim Ingham36f3b362010-10-14 23:45:03 +00002408 // If args is empty, we will use the last created breakpoint (if there is one.)
Chris Lattner30fdc8d2010-06-08 16:52:24 +00002409
2410 Args temp_args;
2411
Jim Ingham36f3b362010-10-14 23:45:03 +00002412 if (args.GetArgumentCount() == 0)
2413 {
Greg Clayton4d122c42011-09-17 08:33:22 +00002414 if (target->GetLastCreatedBreakpoint())
Jim Ingham36f3b362010-10-14 23:45:03 +00002415 {
2416 valid_ids->AddBreakpointID (BreakpointID(target->GetLastCreatedBreakpoint()->GetID(), LLDB_INVALID_BREAK_ID));
2417 result.SetStatus (eReturnStatusSuccessFinishNoResult);
2418 }
2419 else
2420 {
2421 result.AppendError("No breakpoint specified and no last created breakpoint.");
2422 result.SetStatus (eReturnStatusFailed);
2423 }
2424 return;
2425 }
2426
Chris Lattner30fdc8d2010-06-08 16:52:24 +00002427 // Create a new Args variable to use; copy any non-breakpoint-id-ranges stuff directly from the old ARGS to
2428 // the new TEMP_ARGS. Do not copy breakpoint id range strings over; instead generate a list of strings for
2429 // all the breakpoint ids in the range, and shove all of those breakpoint id strings into TEMP_ARGS.
2430
Jim Ingham5e09c8c2014-12-16 23:40:14 +00002431 BreakpointIDList::FindAndReplaceIDRanges (args, target, allow_locations, result, temp_args);
Chris Lattner30fdc8d2010-06-08 16:52:24 +00002432
2433 // NOW, convert the list of breakpoint id strings in TEMP_ARGS into an actual BreakpointIDList:
2434
Greg Claytonc982c762010-07-09 20:39:50 +00002435 valid_ids->InsertStringArray (temp_args.GetConstArgumentVector(), temp_args.GetArgumentCount(), result);
Chris Lattner30fdc8d2010-06-08 16:52:24 +00002436
2437 // At this point, all of the breakpoint ids that the user passed in have been converted to breakpoint IDs
2438 // and put into valid_ids.
2439
2440 if (result.Succeeded())
2441 {
2442 // Now that we've converted everything from args into a list of breakpoint ids, go through our tentative list
2443 // of breakpoint id's and verify that they correspond to valid/currently set breakpoints.
2444
Greg Claytonc982c762010-07-09 20:39:50 +00002445 const size_t count = valid_ids->GetSize();
2446 for (size_t i = 0; i < count; ++i)
Chris Lattner30fdc8d2010-06-08 16:52:24 +00002447 {
2448 BreakpointID cur_bp_id = valid_ids->GetBreakpointIDAtIndex (i);
2449 Breakpoint *breakpoint = target->GetBreakpointByID (cur_bp_id.GetBreakpointID()).get();
2450 if (breakpoint != NULL)
2451 {
Greg Claytonc7bece562013-01-25 18:06:21 +00002452 const size_t num_locations = breakpoint->GetNumLocations();
Saleem Abdulrasool3985c8c2014-04-02 03:51:35 +00002453 if (static_cast<size_t>(cur_bp_id.GetLocationID()) > num_locations)
Chris Lattner30fdc8d2010-06-08 16:52:24 +00002454 {
2455 StreamString id_str;
Greg Claytonc982c762010-07-09 20:39:50 +00002456 BreakpointID::GetCanonicalReference (&id_str,
2457 cur_bp_id.GetBreakpointID(),
2458 cur_bp_id.GetLocationID());
2459 i = valid_ids->GetSize() + 1;
Chris Lattner30fdc8d2010-06-08 16:52:24 +00002460 result.AppendErrorWithFormat ("'%s' is not a currently valid breakpoint/location id.\n",
2461 id_str.GetData());
2462 result.SetStatus (eReturnStatusFailed);
2463 }
2464 }
2465 else
2466 {
Greg Claytonc982c762010-07-09 20:39:50 +00002467 i = valid_ids->GetSize() + 1;
Chris Lattner30fdc8d2010-06-08 16:52:24 +00002468 result.AppendErrorWithFormat ("'%d' is not a currently valid breakpoint id.\n", cur_bp_id.GetBreakpointID());
2469 result.SetStatus (eReturnStatusFailed);
2470 }
2471 }
2472 }
2473}