blob: 772793327ee005b48a78b0dfb2a96514a13124d2 [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),
Dawn Perchik23b1dec2015-07-21 22:05:07 +0000114 m_language (lldb::eLanguageTypeUnknown),
Jim Inghamca36cd12012-10-05 19:16:31 +0000115 m_skip_prologue (eLazyBoolCalculate),
Jim Inghame7320522015-02-12 17:37:46 +0000116 m_one_shot (false),
Ilia K055ad9b2015-05-18 13:41:01 +0000117 m_all_files (false),
118 m_move_to_nearest_code (eLazyBoolCalculate)
Jim Ingham5a988412012-06-08 21:56:10 +0000119 {
120 }
121
122
123 virtual
124 ~CommandOptions () {}
125
126 virtual Error
127 SetOptionValue (uint32_t option_idx, const char *option_arg)
128 {
129 Error error;
Greg Clayton3bcdfc02012-12-04 00:32:51 +0000130 const int short_option = m_getopt_table[option_idx].val;
Jim Ingham5a988412012-06-08 21:56:10 +0000131
132 switch (short_option)
133 {
134 case 'a':
Greg Claytonb9d5df52012-12-06 22:49:16 +0000135 {
136 ExecutionContext exe_ctx (m_interpreter.GetExecutionContext());
137 m_load_addr = Args::StringToAddress(&exe_ctx, option_arg, LLDB_INVALID_ADDRESS, &error);
138 }
Jim Ingham5a988412012-06-08 21:56:10 +0000139 break;
140
Jim Inghame7320522015-02-12 17:37:46 +0000141 case 'A':
142 m_all_files = true;
143 break;
144
Jim Inghamca36cd12012-10-05 19:16:31 +0000145 case 'b':
146 m_func_names.push_back (option_arg);
147 m_func_name_type_mask |= eFunctionNameTypeBase;
148 break;
149
Jim Ingham5a988412012-06-08 21:56:10 +0000150 case 'C':
Jim Ingham63129912015-03-16 22:47:38 +0000151 {
152 bool success;
153 m_column = StringConvert::ToUInt32 (option_arg, 0, 0, &success);
154 if (!success)
155 error.SetErrorStringWithFormat("invalid column number: %s", option_arg);
Jim Ingham5a988412012-06-08 21:56:10 +0000156 break;
Jim Ingham63129912015-03-16 22:47:38 +0000157 }
Jim Ingham5a988412012-06-08 21:56:10 +0000158 case 'c':
159 m_condition.assign(option_arg);
160 break;
161
Jim Ingham33df7cd2014-12-06 01:28:03 +0000162 case 'D':
163 m_use_dummy = true;
164 break;
165
Jim Ingham5a988412012-06-08 21:56:10 +0000166 case 'E':
167 {
168 LanguageType language = LanguageRuntime::GetLanguageTypeFromString (option_arg);
169
170 switch (language)
171 {
172 case eLanguageTypeC89:
173 case eLanguageTypeC:
174 case eLanguageTypeC99:
Bruce Mitchener1d0089f2014-07-03 00:49:08 +0000175 case eLanguageTypeC11:
Jim Inghama72b31c2015-04-22 19:42:18 +0000176 m_exception_language = eLanguageTypeC;
Jim Ingham5a988412012-06-08 21:56:10 +0000177 break;
178 case eLanguageTypeC_plus_plus:
Bruce Mitchener1d0089f2014-07-03 00:49:08 +0000179 case eLanguageTypeC_plus_plus_03:
180 case eLanguageTypeC_plus_plus_11:
Bruce Mitchener2ba84a62015-02-06 06:46:52 +0000181 case eLanguageTypeC_plus_plus_14:
Jim Inghama72b31c2015-04-22 19:42:18 +0000182 m_exception_language = eLanguageTypeC_plus_plus;
Jim Ingham5a988412012-06-08 21:56:10 +0000183 break;
184 case eLanguageTypeObjC:
Jim Inghama72b31c2015-04-22 19:42:18 +0000185 m_exception_language = eLanguageTypeObjC;
Jim Ingham5a988412012-06-08 21:56:10 +0000186 break;
187 case eLanguageTypeObjC_plus_plus:
188 error.SetErrorStringWithFormat ("Set exception breakpoints separately for c++ and objective-c");
189 break;
190 case eLanguageTypeUnknown:
191 error.SetErrorStringWithFormat ("Unknown language type: '%s' for exception breakpoint", option_arg);
192 break;
193 default:
194 error.SetErrorStringWithFormat ("Unsupported language type: '%s' for exception breakpoint", option_arg);
195 }
196 }
197 break;
Jim Inghamca36cd12012-10-05 19:16:31 +0000198
199 case 'f':
200 m_filenames.AppendIfUnique (FileSpec(option_arg, false));
201 break;
202
203 case 'F':
204 m_func_names.push_back (option_arg);
205 m_func_name_type_mask |= eFunctionNameTypeFull;
206 break;
207
Jim Ingham5a988412012-06-08 21:56:10 +0000208 case 'h':
Greg Claytoneb023e72013-10-11 19:48:25 +0000209 {
210 bool success;
211 m_catch_bp = Args::StringToBoolean (option_arg, true, &success);
212 if (!success)
213 error.SetErrorStringWithFormat ("Invalid boolean value for on-catch option: '%s'", option_arg);
214 }
215 break;
216
217 case 'H':
218 m_hardware = true;
219 break;
220
Jim Inghamca36cd12012-10-05 19:16:31 +0000221 case 'i':
222 {
Vince Harron5275aaa2015-01-15 20:08:35 +0000223 m_ignore_count = StringConvert::ToUInt32(option_arg, UINT32_MAX, 0);
Jim Inghamca36cd12012-10-05 19:16:31 +0000224 if (m_ignore_count == UINT32_MAX)
225 error.SetErrorStringWithFormat ("invalid ignore count '%s'", option_arg);
226 break;
227 }
228
Jim Ingham5a988412012-06-08 21:56:10 +0000229 case 'K':
230 {
231 bool success;
232 bool value;
233 value = Args::StringToBoolean (option_arg, true, &success);
234 if (value)
235 m_skip_prologue = eLazyBoolYes;
236 else
237 m_skip_prologue = eLazyBoolNo;
238
239 if (!success)
240 error.SetErrorStringWithFormat ("Invalid boolean value for skip prologue option: '%s'", option_arg);
241 }
242 break;
Jim Inghamca36cd12012-10-05 19:16:31 +0000243
244 case 'l':
Jim Ingham63129912015-03-16 22:47:38 +0000245 {
246 bool success;
247 m_line_num = StringConvert::ToUInt32 (option_arg, 0, 0, &success);
248 if (!success)
249 error.SetErrorStringWithFormat ("invalid line number: %s.", option_arg);
Jim Inghamca36cd12012-10-05 19:16:31 +0000250 break;
Jim Ingham63129912015-03-16 22:47:38 +0000251 }
Ilia K055ad9b2015-05-18 13:41:01 +0000252
Dawn Perchik23b1dec2015-07-21 22:05:07 +0000253 case 'L':
254 m_language = LanguageRuntime::GetLanguageTypeFromString (option_arg);
255 if (m_language == eLanguageTypeUnknown)
256 error.SetErrorStringWithFormat ("Unknown language type: '%s' for breakpoint", option_arg);
257 break;
258
Ilia K055ad9b2015-05-18 13:41:01 +0000259 case 'm':
260 {
261 bool success;
262 bool value;
263 value = Args::StringToBoolean (option_arg, true, &success);
264 if (value)
265 m_move_to_nearest_code = eLazyBoolYes;
266 else
267 m_move_to_nearest_code = eLazyBoolNo;
268
269 if (!success)
270 error.SetErrorStringWithFormat ("Invalid boolean value for move-to-nearest-code option: '%s'", option_arg);
271 break;
272 }
273
Jim Inghamca36cd12012-10-05 19:16:31 +0000274 case 'M':
275 m_func_names.push_back (option_arg);
276 m_func_name_type_mask |= eFunctionNameTypeMethod;
277 break;
278
279 case 'n':
280 m_func_names.push_back (option_arg);
281 m_func_name_type_mask |= eFunctionNameTypeAuto;
282 break;
283
Jim Ingham5e09c8c2014-12-16 23:40:14 +0000284 case 'N':
285 if (BreakpointID::StringIsBreakpointName(option_arg, error))
286 m_breakpoint_names.push_back (option_arg);
Jim Ingham5e09c8c2014-12-16 23:40:14 +0000287 break;
288
Jim Inghamca36cd12012-10-05 19:16:31 +0000289 case 'o':
290 m_one_shot = true;
291 break;
292
Jim Inghama72b31c2015-04-22 19:42:18 +0000293 case 'O':
294 m_exception_extra_args.AppendArgument ("-O");
295 m_exception_extra_args.AppendArgument (option_arg);
296 break;
297
Jim Inghamca36cd12012-10-05 19:16:31 +0000298 case 'p':
299 m_source_text_regexp.assign (option_arg);
300 break;
301
302 case 'q':
303 m_queue_name.assign (option_arg);
304 break;
305
306 case 'r':
307 m_func_regexp.assign (option_arg);
308 break;
309
310 case 's':
311 {
312 m_modules.AppendIfUnique (FileSpec (option_arg, false));
313 break;
314 }
315
316 case 'S':
317 m_func_names.push_back (option_arg);
318 m_func_name_type_mask |= eFunctionNameTypeSelector;
319 break;
320
321 case 't' :
322 {
Vince Harron5275aaa2015-01-15 20:08:35 +0000323 m_thread_id = StringConvert::ToUInt64(option_arg, LLDB_INVALID_THREAD_ID, 0);
Jim Inghamca36cd12012-10-05 19:16:31 +0000324 if (m_thread_id == LLDB_INVALID_THREAD_ID)
325 error.SetErrorStringWithFormat ("invalid thread id string '%s'", option_arg);
326 }
327 break;
328
329 case 'T':
330 m_thread_name.assign (option_arg);
331 break;
332
333 case 'w':
334 {
335 bool success;
336 m_throw_bp = Args::StringToBoolean (option_arg, true, &success);
337 if (!success)
338 error.SetErrorStringWithFormat ("Invalid boolean value for on-throw option: '%s'", option_arg);
339 }
340 break;
341
342 case 'x':
343 {
Vince Harron5275aaa2015-01-15 20:08:35 +0000344 m_thread_index = StringConvert::ToUInt32(option_arg, UINT32_MAX, 0);
Jim Inghamca36cd12012-10-05 19:16:31 +0000345 if (m_thread_id == UINT32_MAX)
346 error.SetErrorStringWithFormat ("invalid thread index string '%s'", option_arg);
347
348 }
349 break;
350
Jim Ingham5a988412012-06-08 21:56:10 +0000351 default:
352 error.SetErrorStringWithFormat ("unrecognized option '%c'", short_option);
353 break;
354 }
355
356 return error;
357 }
358 void
359 OptionParsingStarting ()
360 {
361 m_condition.clear();
362 m_filenames.Clear();
363 m_line_num = 0;
364 m_column = 0;
365 m_func_names.clear();
Greg Clayton1f746072012-08-29 21:13:06 +0000366 m_func_name_type_mask = eFunctionNameTypeNone;
Jim Ingham5a988412012-06-08 21:56:10 +0000367 m_func_regexp.clear();
Greg Clayton1f746072012-08-29 21:13:06 +0000368 m_source_text_regexp.clear();
Jim Ingham5a988412012-06-08 21:56:10 +0000369 m_modules.Clear();
Greg Clayton1f746072012-08-29 21:13:06 +0000370 m_load_addr = LLDB_INVALID_ADDRESS;
Jim Ingham5a988412012-06-08 21:56:10 +0000371 m_ignore_count = 0;
372 m_thread_id = LLDB_INVALID_THREAD_ID;
373 m_thread_index = UINT32_MAX;
374 m_thread_name.clear();
375 m_queue_name.clear();
Jim Ingham5a988412012-06-08 21:56:10 +0000376 m_catch_bp = false;
377 m_throw_bp = true;
Greg Claytoneb023e72013-10-11 19:48:25 +0000378 m_hardware = false;
Jim Inghama72b31c2015-04-22 19:42:18 +0000379 m_exception_language = eLanguageTypeUnknown;
Dawn Perchik23b1dec2015-07-21 22:05:07 +0000380 m_language = lldb::eLanguageTypeUnknown;
Jim Ingham5a988412012-06-08 21:56:10 +0000381 m_skip_prologue = eLazyBoolCalculate;
Jim Inghamca36cd12012-10-05 19:16:31 +0000382 m_one_shot = false;
Jim Ingham33df7cd2014-12-06 01:28:03 +0000383 m_use_dummy = false;
Jim Ingham5e09c8c2014-12-16 23:40:14 +0000384 m_breakpoint_names.clear();
Jim Inghame7320522015-02-12 17:37:46 +0000385 m_all_files = false;
Jim Inghama72b31c2015-04-22 19:42:18 +0000386 m_exception_extra_args.Clear();
Ilia K055ad9b2015-05-18 13:41:01 +0000387 m_move_to_nearest_code = eLazyBoolCalculate;
Jim Ingham5a988412012-06-08 21:56:10 +0000388 }
389
390 const OptionDefinition*
391 GetDefinitions ()
392 {
393 return g_option_table;
394 }
395
396 // Options table: Required for subclasses of Options.
397
398 static OptionDefinition g_option_table[];
399
400 // Instance variables to hold the values for command options.
401
402 std::string m_condition;
403 FileSpecList m_filenames;
404 uint32_t m_line_num;
405 uint32_t m_column;
Jim Ingham5a988412012-06-08 21:56:10 +0000406 std::vector<std::string> m_func_names;
Jim Ingham5e09c8c2014-12-16 23:40:14 +0000407 std::vector<std::string> m_breakpoint_names;
Jim Ingham5a988412012-06-08 21:56:10 +0000408 uint32_t m_func_name_type_mask;
409 std::string m_func_regexp;
410 std::string m_source_text_regexp;
411 FileSpecList m_modules;
412 lldb::addr_t m_load_addr;
413 uint32_t m_ignore_count;
414 lldb::tid_t m_thread_id;
415 uint32_t m_thread_index;
416 std::string m_thread_name;
417 std::string m_queue_name;
418 bool m_catch_bp;
419 bool m_throw_bp;
Greg Claytoneb023e72013-10-11 19:48:25 +0000420 bool m_hardware; // Request to use hardware breakpoints
Jim Inghama72b31c2015-04-22 19:42:18 +0000421 lldb::LanguageType m_exception_language;
Dawn Perchik23b1dec2015-07-21 22:05:07 +0000422 lldb::LanguageType m_language;
Jim Ingham5a988412012-06-08 21:56:10 +0000423 LazyBool m_skip_prologue;
Jim Inghamca36cd12012-10-05 19:16:31 +0000424 bool m_one_shot;
Jim Ingham33df7cd2014-12-06 01:28:03 +0000425 bool m_use_dummy;
Jim Inghame7320522015-02-12 17:37:46 +0000426 bool m_all_files;
Jim Inghama72b31c2015-04-22 19:42:18 +0000427 Args m_exception_extra_args;
Ilia K055ad9b2015-05-18 13:41:01 +0000428 LazyBool m_move_to_nearest_code;
Jim Ingham5a988412012-06-08 21:56:10 +0000429
430 };
431
432protected:
433 virtual bool
434 DoExecute (Args& command,
Jim Ingham33df7cd2014-12-06 01:28:03 +0000435 CommandReturnObject &result)
Jim Ingham5a988412012-06-08 21:56:10 +0000436 {
Jim Ingham33df7cd2014-12-06 01:28:03 +0000437 Target *target = GetSelectedOrDummyTarget(m_options.m_use_dummy);
438
Jim Ingham893c9322014-11-22 01:42:44 +0000439 if (target == nullptr)
Jim Ingham5a988412012-06-08 21:56:10 +0000440 {
441 result.AppendError ("Invalid target. Must set target before setting breakpoints (see 'target create' command).");
442 result.SetStatus (eReturnStatusFailed);
443 return false;
444 }
445
446 // The following are the various types of breakpoints that could be set:
447 // 1). -f -l -p [-s -g] (setting breakpoint by source location)
448 // 2). -a [-s -g] (setting breakpoint by address)
449 // 3). -n [-s -g] (setting breakpoint by function name)
450 // 4). -r [-s -g] (setting breakpoint by function name regular expression)
451 // 5). -p -f (setting a breakpoint by comparing a reg-exp to source text)
452 // 6). -E [-w -h] (setting a breakpoint for exceptions for a given language.)
453
454 BreakpointSetType break_type = eSetTypeInvalid;
455
456 if (m_options.m_line_num != 0)
457 break_type = eSetTypeFileAndLine;
458 else if (m_options.m_load_addr != LLDB_INVALID_ADDRESS)
459 break_type = eSetTypeAddress;
460 else if (!m_options.m_func_names.empty())
461 break_type = eSetTypeFunctionName;
462 else if (!m_options.m_func_regexp.empty())
463 break_type = eSetTypeFunctionRegexp;
464 else if (!m_options.m_source_text_regexp.empty())
465 break_type = eSetTypeSourceRegexp;
Jim Inghama72b31c2015-04-22 19:42:18 +0000466 else if (m_options.m_exception_language != eLanguageTypeUnknown)
Jim Ingham5a988412012-06-08 21:56:10 +0000467 break_type = eSetTypeException;
468
469 Breakpoint *bp = NULL;
470 FileSpec module_spec;
Jim Ingham5a988412012-06-08 21:56:10 +0000471 const bool internal = false;
472
Jim Ingham5a988412012-06-08 21:56:10 +0000473 switch (break_type)
474 {
475 case eSetTypeFileAndLine: // Breakpoint by source position
476 {
477 FileSpec file;
Greg Claytonc7bece562013-01-25 18:06:21 +0000478 const size_t num_files = m_options.m_filenames.GetSize();
Jim Ingham5a988412012-06-08 21:56:10 +0000479 if (num_files == 0)
480 {
481 if (!GetDefaultFile (target, file, result))
482 {
483 result.AppendError("No file supplied and no default file available.");
484 result.SetStatus (eReturnStatusFailed);
485 return false;
486 }
487 }
488 else if (num_files > 1)
489 {
490 result.AppendError("Only one file at a time is allowed for file and line breakpoints.");
491 result.SetStatus (eReturnStatusFailed);
492 return false;
493 }
494 else
495 file = m_options.m_filenames.GetFileSpecAtIndex(0);
Greg Clayton1f746072012-08-29 21:13:06 +0000496
497 // Only check for inline functions if
498 LazyBool check_inlines = eLazyBoolCalculate;
499
Jim Ingham5a988412012-06-08 21:56:10 +0000500 bp = target->CreateBreakpoint (&(m_options.m_modules),
501 file,
502 m_options.m_line_num,
Greg Clayton1f746072012-08-29 21:13:06 +0000503 check_inlines,
Jim Ingham5a988412012-06-08 21:56:10 +0000504 m_options.m_skip_prologue,
Greg Claytoneb023e72013-10-11 19:48:25 +0000505 internal,
Ilia K055ad9b2015-05-18 13:41:01 +0000506 m_options.m_hardware,
507 m_options.m_move_to_nearest_code).get();
Jim Ingham5a988412012-06-08 21:56:10 +0000508 }
509 break;
510
511 case eSetTypeAddress: // Breakpoint by address
Greg Claytoneb023e72013-10-11 19:48:25 +0000512 bp = target->CreateBreakpoint (m_options.m_load_addr,
513 internal,
514 m_options.m_hardware).get();
Jim Ingham5a988412012-06-08 21:56:10 +0000515 break;
516
517 case eSetTypeFunctionName: // Breakpoint by function name
518 {
519 uint32_t name_type_mask = m_options.m_func_name_type_mask;
520
521 if (name_type_mask == 0)
522 name_type_mask = eFunctionNameTypeAuto;
523
524 bp = target->CreateBreakpoint (&(m_options.m_modules),
525 &(m_options.m_filenames),
526 m_options.m_func_names,
527 name_type_mask,
Dawn Perchik23b1dec2015-07-21 22:05:07 +0000528 m_options.m_language,
Jim Ingham5a988412012-06-08 21:56:10 +0000529 m_options.m_skip_prologue,
Greg Claytoneb023e72013-10-11 19:48:25 +0000530 internal,
531 m_options.m_hardware).get();
Jim Ingham5a988412012-06-08 21:56:10 +0000532 }
533 break;
534
535 case eSetTypeFunctionRegexp: // Breakpoint by regular expression function name
536 {
537 RegularExpression regexp(m_options.m_func_regexp.c_str());
538 if (!regexp.IsValid())
539 {
540 char err_str[1024];
541 regexp.GetErrorAsCString(err_str, sizeof(err_str));
542 result.AppendErrorWithFormat("Function name regular expression could not be compiled: \"%s\"",
543 err_str);
544 result.SetStatus (eReturnStatusFailed);
545 return false;
546 }
547
548 bp = target->CreateFuncRegexBreakpoint (&(m_options.m_modules),
549 &(m_options.m_filenames),
550 regexp,
551 m_options.m_skip_prologue,
Greg Claytoneb023e72013-10-11 19:48:25 +0000552 internal,
553 m_options.m_hardware).get();
Jim Ingham5a988412012-06-08 21:56:10 +0000554 }
555 break;
556 case eSetTypeSourceRegexp: // Breakpoint by regexp on source text.
557 {
Greg Claytonc7bece562013-01-25 18:06:21 +0000558 const size_t num_files = m_options.m_filenames.GetSize();
Jim Ingham5a988412012-06-08 21:56:10 +0000559
Jim Inghame7320522015-02-12 17:37:46 +0000560 if (num_files == 0 && !m_options.m_all_files)
Jim Ingham5a988412012-06-08 21:56:10 +0000561 {
562 FileSpec file;
563 if (!GetDefaultFile (target, file, result))
564 {
565 result.AppendError ("No files provided and could not find default file.");
566 result.SetStatus (eReturnStatusFailed);
567 return false;
568 }
569 else
570 {
571 m_options.m_filenames.Append (file);
572 }
573 }
574
575 RegularExpression regexp(m_options.m_source_text_regexp.c_str());
576 if (!regexp.IsValid())
577 {
578 char err_str[1024];
579 regexp.GetErrorAsCString(err_str, sizeof(err_str));
580 result.AppendErrorWithFormat("Source text regular expression could not be compiled: \"%s\"",
581 err_str);
582 result.SetStatus (eReturnStatusFailed);
583 return false;
584 }
Greg Claytoneb023e72013-10-11 19:48:25 +0000585 bp = target->CreateSourceRegexBreakpoint (&(m_options.m_modules),
586 &(m_options.m_filenames),
587 regexp,
588 internal,
Ilia K055ad9b2015-05-18 13:41:01 +0000589 m_options.m_hardware,
590 m_options.m_move_to_nearest_code).get();
Jim Ingham5a988412012-06-08 21:56:10 +0000591 }
592 break;
593 case eSetTypeException:
594 {
Jim Inghama72b31c2015-04-22 19:42:18 +0000595 Error precond_error;
596 bp = target->CreateExceptionBreakpoint (m_options.m_exception_language,
Greg Claytoneb023e72013-10-11 19:48:25 +0000597 m_options.m_catch_bp,
598 m_options.m_throw_bp,
Jim Inghama72b31c2015-04-22 19:42:18 +0000599 internal,
600 &m_options.m_exception_extra_args,
601 &precond_error).get();
602 if (precond_error.Fail())
603 {
604 result.AppendErrorWithFormat("Error setting extra exception arguments: %s",
605 precond_error.AsCString());
606 target->RemoveBreakpointByID(bp->GetID());
607 result.SetStatus(eReturnStatusFailed);
608 return false;
609 }
Jim Ingham5a988412012-06-08 21:56:10 +0000610 }
611 break;
612 default:
613 break;
614 }
615
616 // Now set the various options that were passed in:
617 if (bp)
618 {
619 if (m_options.m_thread_id != LLDB_INVALID_THREAD_ID)
620 bp->SetThreadID (m_options.m_thread_id);
621
622 if (m_options.m_thread_index != UINT32_MAX)
623 bp->GetOptions()->GetThreadSpec()->SetIndex(m_options.m_thread_index);
624
625 if (!m_options.m_thread_name.empty())
626 bp->GetOptions()->GetThreadSpec()->SetName(m_options.m_thread_name.c_str());
627
628 if (!m_options.m_queue_name.empty())
629 bp->GetOptions()->GetThreadSpec()->SetQueueName(m_options.m_queue_name.c_str());
630
631 if (m_options.m_ignore_count != 0)
632 bp->GetOptions()->SetIgnoreCount(m_options.m_ignore_count);
633
634 if (!m_options.m_condition.empty())
635 bp->GetOptions()->SetCondition(m_options.m_condition.c_str());
Jim Ingham5e09c8c2014-12-16 23:40:14 +0000636
637 if (!m_options.m_breakpoint_names.empty())
638 {
639 Error error; // We don't need to check the error here, since the option parser checked it...
640 for (auto name : m_options.m_breakpoint_names)
641 bp->AddName(name.c_str(), error);
642 }
Jim Inghamca36cd12012-10-05 19:16:31 +0000643
644 bp->SetOneShot (m_options.m_one_shot);
Jim Ingham5a988412012-06-08 21:56:10 +0000645 }
646
647 if (bp)
648 {
649 Stream &output_stream = result.GetOutputStream();
Jim Ingham1391cc72012-09-22 00:04:04 +0000650 const bool show_locations = false;
651 bp->GetDescription(&output_stream, lldb::eDescriptionLevelInitial, show_locations);
Jim Ingham4aeb1982014-12-19 19:45:31 +0000652 if (target == m_interpreter.GetDebugger().GetDummyTarget())
653 output_stream.Printf ("Breakpoint set in dummy target, will get copied into future targets.\n");
654 else
655 {
656 // Don't print out this warning for exception breakpoints. They can get set before the target
657 // is set, but we won't know how to actually set the breakpoint till we run.
658 if (bp->GetNumLocations() == 0 && break_type != eSetTypeException)
659 {
660 output_stream.Printf ("WARNING: Unable to resolve breakpoint to any actual locations.\n");
661 }
662 }
Jim Ingham5a988412012-06-08 21:56:10 +0000663 result.SetStatus (eReturnStatusSuccessFinishResult);
664 }
665 else if (!bp)
666 {
667 result.AppendError ("Breakpoint creation failed: No breakpoint created.");
668 result.SetStatus (eReturnStatusFailed);
669 }
670
671 return result.Succeeded();
672 }
673
674private:
675 bool
676 GetDefaultFile (Target *target, FileSpec &file, CommandReturnObject &result)
677 {
678 uint32_t default_line;
679 // First use the Source Manager's default file.
680 // Then use the current stack frame's file.
681 if (!target->GetSourceManager().GetDefaultFileAndLine(file, default_line))
682 {
Jason Molendab57e4a12013-11-04 09:33:30 +0000683 StackFrame *cur_frame = m_exe_ctx.GetFramePtr();
Jim Ingham5a988412012-06-08 21:56:10 +0000684 if (cur_frame == NULL)
685 {
686 result.AppendError ("No selected frame to use to find the default file.");
687 result.SetStatus (eReturnStatusFailed);
688 return false;
689 }
690 else if (!cur_frame->HasDebugInformation())
691 {
692 result.AppendError ("Cannot use the selected frame to find the default file, it has no debug info.");
693 result.SetStatus (eReturnStatusFailed);
694 return false;
695 }
696 else
697 {
698 const SymbolContext &sc = cur_frame->GetSymbolContext (eSymbolContextLineEntry);
699 if (sc.line_entry.file)
700 {
701 file = sc.line_entry.file;
702 }
703 else
704 {
705 result.AppendError ("Can't find the file for the selected frame to use as the default file.");
706 result.SetStatus (eReturnStatusFailed);
707 return false;
708 }
709 }
710 }
711 return true;
712 }
713
714 CommandOptions m_options;
715};
Johnny Chen6943e7c2012-05-08 00:43:20 +0000716// If an additional option set beyond LLDB_OPTION_SET_10 is added, make sure to
717// update the numbers passed to LLDB_OPT_SET_FROM_TO(...) appropriately.
Johnny Chen4ab2e6b2012-05-07 23:23:41 +0000718#define LLDB_OPT_FILE ( LLDB_OPT_SET_FROM_TO(1, 9) & ~LLDB_OPT_SET_2 )
719#define LLDB_OPT_NOT_10 ( LLDB_OPT_SET_FROM_TO(1, 10) & ~LLDB_OPT_SET_10 )
Jim Inghama8558b62012-05-22 00:12:20 +0000720#define LLDB_OPT_SKIP_PROLOGUE ( LLDB_OPT_SET_1 | LLDB_OPT_SET_FROM_TO(3,8) )
Ilia K055ad9b2015-05-18 13:41:01 +0000721#define LLDB_OPT_MOVE_TO_NEAREST_CODE ( LLDB_OPT_SET_1 | LLDB_OPT_SET_9 )
Dawn Perchik23b1dec2015-07-21 22:05:07 +0000722#define LLDB_OPT_EXPR_LANGUAGE ( LLDB_OPT_SET_FROM_TO(3, 8) & ~LLDB_OPT_SET_7 )
Jim Ingham87df91b2011-09-23 00:54:11 +0000723
Greg Claytone0d378b2011-03-24 21:19:54 +0000724OptionDefinition
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000725CommandObjectBreakpointSet::CommandOptions::g_option_table[] =
726{
Zachary Turnerd37221d2014-07-09 16:31:49 +0000727 { LLDB_OPT_NOT_10, false, "shlib", 's', OptionParser::eRequiredArgument, NULL, NULL, CommandCompletions::eModuleCompletion, eArgTypeShlibName,
Jim Ingham64cc29c2012-05-03 20:30:08 +0000728 "Set the breakpoint only in this shared library. "
729 "Can repeat this option multiple times to specify multiple shared libraries."},
Jim Ingham86511212010-06-15 18:47:14 +0000730
Zachary Turnerd37221d2014-07-09 16:31:49 +0000731 { LLDB_OPT_SET_ALL, false, "ignore-count", 'i', OptionParser::eRequiredArgument, NULL, NULL, 0, eArgTypeCount,
Caroline Ticedeaab222010-10-01 19:59:14 +0000732 "Set the number of times this breakpoint is skipped before stopping." },
Jim Ingham1b54c882010-06-16 02:00:15 +0000733
Zachary Turnerd37221d2014-07-09 16:31:49 +0000734 { LLDB_OPT_SET_ALL, false, "one-shot", 'o', OptionParser::eNoArgument, NULL, NULL, 0, eArgTypeNone,
Jim Inghamb2b256a2013-04-09 18:05:22 +0000735 "The breakpoint is deleted the first time it causes a stop." },
Jim Inghamca36cd12012-10-05 19:16:31 +0000736
Zachary Turnerd37221d2014-07-09 16:31:49 +0000737 { LLDB_OPT_SET_ALL, false, "condition", 'c', OptionParser::eRequiredArgument, NULL, NULL, 0, eArgTypeExpression,
Johnny Chen7d49c9c2012-05-25 21:10:46 +0000738 "The breakpoint stops only if this condition expression evaluates to true."},
739
Zachary Turnerd37221d2014-07-09 16:31:49 +0000740 { LLDB_OPT_SET_ALL, false, "thread-index", 'x', OptionParser::eRequiredArgument, NULL, NULL, 0, eArgTypeThreadIndex,
Jim Inghama89be912013-03-26 18:29:03 +0000741 "The breakpoint stops only for the thread whose indeX matches this argument."},
Jim Ingham1b54c882010-06-16 02:00:15 +0000742
Zachary Turnerd37221d2014-07-09 16:31:49 +0000743 { LLDB_OPT_SET_ALL, false, "thread-id", 't', OptionParser::eRequiredArgument, NULL, NULL, 0, eArgTypeThreadID,
Jim Ingham1b54c882010-06-16 02:00:15 +0000744 "The breakpoint stops only for the thread whose TID matches this argument."},
745
Zachary Turnerd37221d2014-07-09 16:31:49 +0000746 { LLDB_OPT_SET_ALL, false, "thread-name", 'T', OptionParser::eRequiredArgument, NULL, NULL, 0, eArgTypeThreadName,
Jim Ingham1b54c882010-06-16 02:00:15 +0000747 "The breakpoint stops only for the thread whose thread name matches this argument."},
748
Zachary Turnerd37221d2014-07-09 16:31:49 +0000749 { LLDB_OPT_SET_ALL, false, "hardware", 'H', OptionParser::eNoArgument, NULL, NULL, 0, eArgTypeNone,
Greg Claytoneb023e72013-10-11 19:48:25 +0000750 "Require the breakpoint to use hardware breakpoints."},
751
Zachary Turnerd37221d2014-07-09 16:31:49 +0000752 { LLDB_OPT_SET_ALL, false, "queue-name", 'q', OptionParser::eRequiredArgument, NULL, NULL, 0, eArgTypeQueueName,
Jim Ingham1b54c882010-06-16 02:00:15 +0000753 "The breakpoint stops only for threads in the queue whose name is given by this argument."},
754
Zachary Turnerd37221d2014-07-09 16:31:49 +0000755 { LLDB_OPT_FILE, false, "file", 'f', OptionParser::eRequiredArgument, NULL, NULL, CommandCompletions::eSourceFileCompletion, eArgTypeFilename,
Jim Ingham289aca62013-02-14 19:10:36 +0000756 "Specifies the source file in which to set this breakpoint. "
757 "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 +0000758 "To set breakpoints on .c/.cpp/.m/.mm files that are #included, set target.inline-breakpoint-strategy"
Jim Ingham289aca62013-02-14 19:10:36 +0000759 " to \"always\"."},
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000760
Zachary Turnerd37221d2014-07-09 16:31:49 +0000761 { LLDB_OPT_SET_1, true, "line", 'l', OptionParser::eRequiredArgument, NULL, NULL, 0, eArgTypeLineNum,
Jim Ingham87df91b2011-09-23 00:54:11 +0000762 "Specifies the line number on which to set this breakpoint."},
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000763
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000764 // Comment out this option for the moment, as we don't actually use it, but will in the future.
765 // This way users won't see it, but the infrastructure is left in place.
Virgile Belloe2607b52013-09-05 16:42:23 +0000766 // { 0, false, "column", 'C', OptionParser::eRequiredArgument, NULL, "<column>",
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000767 // "Set the breakpoint by source location at this particular column."},
768
Zachary Turnerd37221d2014-07-09 16:31:49 +0000769 { LLDB_OPT_SET_2, true, "address", 'a', OptionParser::eRequiredArgument, NULL, NULL, 0, eArgTypeAddressOrExpression,
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000770 "Set the breakpoint by address, at the specified address."},
771
Zachary Turnerd37221d2014-07-09 16:31:49 +0000772 { LLDB_OPT_SET_3, true, "name", 'n', OptionParser::eRequiredArgument, NULL, NULL, CommandCompletions::eSymbolCompletion, eArgTypeFunctionName,
Jim Ingham551262d2013-03-27 17:36:54 +0000773 "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 +0000774
Zachary Turnerd37221d2014-07-09 16:31:49 +0000775 { LLDB_OPT_SET_4, true, "fullname", 'F', OptionParser::eRequiredArgument, NULL, NULL, CommandCompletions::eSymbolCompletion, eArgTypeFullName,
Jim Ingham64cc29c2012-05-03 20:30:08 +0000776 "Set the breakpoint by fully qualified function names. For C++ this means namespaces and all arguments, and "
777 "for Objective C this means a full function prototype with class and selector. "
778 "Can be repeated multiple times to make one breakpoint for multiple names." },
Greg Clayton0c5cd902010-06-28 21:30:43 +0000779
Zachary Turnerd37221d2014-07-09 16:31:49 +0000780 { LLDB_OPT_SET_5, true, "selector", 'S', OptionParser::eRequiredArgument, NULL, NULL, 0, eArgTypeSelector,
Jim Ingham64cc29c2012-05-03 20:30:08 +0000781 "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 +0000782
Zachary Turnerd37221d2014-07-09 16:31:49 +0000783 { LLDB_OPT_SET_6, true, "method", 'M', OptionParser::eRequiredArgument, NULL, NULL, 0, eArgTypeMethod,
Jim Ingham64cc29c2012-05-03 20:30:08 +0000784 "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 +0000785
Zachary Turnerd37221d2014-07-09 16:31:49 +0000786 { LLDB_OPT_SET_7, true, "func-regex", 'r', OptionParser::eRequiredArgument, NULL, NULL, 0, eArgTypeRegularExpression,
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000787 "Set the breakpoint by function name, evaluating a regular-expression to find the function name(s)." },
788
Zachary Turnerd37221d2014-07-09 16:31:49 +0000789 { LLDB_OPT_SET_8, true, "basename", 'b', OptionParser::eRequiredArgument, NULL, NULL, CommandCompletions::eSymbolCompletion, eArgTypeFunctionName,
Jim Ingham64cc29c2012-05-03 20:30:08 +0000790 "Set the breakpoint by function basename (C++ namespaces and arguments will be ignored). "
791 "Can be repeated multiple times to make one breakpoint for multiple symbols." },
Greg Claytone02b8502010-10-12 04:29:14 +0000792
Zachary Turnerd37221d2014-07-09 16:31:49 +0000793 { LLDB_OPT_SET_9, true, "source-pattern-regexp", 'p', OptionParser::eRequiredArgument, NULL, NULL, 0, eArgTypeRegularExpression,
Jim Inghame96ade82013-06-07 01:13:00 +0000794 "Set the breakpoint by specifying a regular expression which is matched against the source text in a source file or files "
795 "specified with the -f option. The -f option can be specified more than once. "
796 "If no source files are specified, uses the current \"default source file\"" },
Jim Ingham969795f2011-09-21 01:17:13 +0000797
Jim Inghame7320522015-02-12 17:37:46 +0000798 { LLDB_OPT_SET_9, false, "all-files", 'A', OptionParser::eNoArgument, NULL, NULL, 0, eArgTypeNone,
799 "All files are searched for source pattern matches." },
800
Zachary Turnerd37221d2014-07-09 16:31:49 +0000801 { LLDB_OPT_SET_10, true, "language-exception", 'E', OptionParser::eRequiredArgument, NULL, NULL, 0, eArgTypeLanguage,
Jim Inghamfab10e82012-03-06 00:37:27 +0000802 "Set the breakpoint on exceptions thrown by the specified language (without options, on throw but not catch.)" },
803
Zachary Turnerd37221d2014-07-09 16:31:49 +0000804 { LLDB_OPT_SET_10, false, "on-throw", 'w', OptionParser::eRequiredArgument, NULL, NULL, 0, eArgTypeBoolean,
Jim Inghamfab10e82012-03-06 00:37:27 +0000805 "Set the breakpoint on exception throW." },
806
Zachary Turnerd37221d2014-07-09 16:31:49 +0000807 { LLDB_OPT_SET_10, false, "on-catch", 'h', OptionParser::eRequiredArgument, NULL, NULL, 0, eArgTypeBoolean,
Jim Inghamfab10e82012-03-06 00:37:27 +0000808 "Set the breakpoint on exception catcH." },
Jim Ingham969795f2011-09-21 01:17:13 +0000809
Jim Inghama72b31c2015-04-22 19:42:18 +0000810// Don't add this option till it actually does something useful...
811// { LLDB_OPT_SET_10, false, "exception-typename", 'O', OptionParser::eRequiredArgument, NULL, NULL, 0, eArgTypeTypeName,
812// "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" },
813
Dawn Perchik23b1dec2015-07-21 22:05:07 +0000814 { LLDB_OPT_EXPR_LANGUAGE, false, "language", 'L', OptionParser::eRequiredArgument, NULL, NULL, 0, eArgTypeLanguage,
Dawn Perchik4112ab92015-07-22 02:01:32 +0000815 "Specifies the Language to use when interpreting the breakpoint's expression (note: currently only implemented for setting breakpoints on identifiers). If not set the target.language setting is used." },
Dawn Perchik23b1dec2015-07-21 22:05:07 +0000816
Zachary Turnerd37221d2014-07-09 16:31:49 +0000817 { LLDB_OPT_SKIP_PROLOGUE, false, "skip-prologue", 'K', OptionParser::eRequiredArgument, NULL, NULL, 0, eArgTypeBoolean,
Jim Inghama8558b62012-05-22 00:12:20 +0000818 "sKip the prologue if the breakpoint is at the beginning of a function. If not set the target.skip-prologue setting is used." },
819
Jim Ingham33df7cd2014-12-06 01:28:03 +0000820 { LLDB_OPT_SET_ALL, false, "dummy-breakpoints", 'D', OptionParser::eNoArgument, NULL, NULL, 0, eArgTypeNone,
821 "Sets Dummy breakpoints - i.e. breakpoints set before a file is provided, which prime new targets."},
822
Jim Ingham5e09c8c2014-12-16 23:40:14 +0000823 { LLDB_OPT_SET_ALL, false, "breakpoint-name", 'N', OptionParser::eRequiredArgument, NULL, NULL, 0, eArgTypeBreakpointName,
824 "Adds this to the list of names for this breakopint."},
825
Ilia K055ad9b2015-05-18 13:41:01 +0000826 { LLDB_OPT_MOVE_TO_NEAREST_CODE, false, "move-to-nearest-code", 'm', OptionParser::eRequiredArgument, NULL, NULL, 0, eArgTypeBoolean,
827 "Move breakpoints to nearest code. If not set the target.move-to-nearest-code setting is used." },
828
Zachary Turnerd37221d2014-07-09 16:31:49 +0000829 { 0, false, NULL, 0, 0, NULL, NULL, 0, eArgTypeNone, NULL }
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000830};
831
Jim Ingham5a988412012-06-08 21:56:10 +0000832//-------------------------------------------------------------------------
833// CommandObjectBreakpointModify
834//-------------------------------------------------------------------------
835#pragma mark Modify
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000836
Jim Ingham5a988412012-06-08 21:56:10 +0000837class CommandObjectBreakpointModify : public CommandObjectParsed
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000838{
Jim Ingham5a988412012-06-08 21:56:10 +0000839public:
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000840
Jim Ingham5a988412012-06-08 21:56:10 +0000841 CommandObjectBreakpointModify (CommandInterpreter &interpreter) :
842 CommandObjectParsed (interpreter,
843 "breakpoint modify",
844 "Modify the options on a breakpoint or set of breakpoints in the executable. "
845 "If no breakpoint is specified, acts on the last created breakpoint. "
846 "With the exception of -e, -d and -i, passing an empty argument clears the modification.",
847 NULL),
848 m_options (interpreter)
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000849 {
Jim Ingham5a988412012-06-08 21:56:10 +0000850 CommandArgumentEntry arg;
851 CommandObject::AddIDsArgumentData(arg, eArgTypeBreakpointID, eArgTypeBreakpointIDRange);
852 // Add the entry for the first argument for this command to the object's arguments vector.
853 m_arguments.push_back (arg);
854 }
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000855
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000856
Jim Ingham5a988412012-06-08 21:56:10 +0000857 virtual
858 ~CommandObjectBreakpointModify () {}
Greg Clayton0c5cd902010-06-28 21:30:43 +0000859
Jim Ingham5a988412012-06-08 21:56:10 +0000860 virtual Options *
861 GetOptions ()
862 {
863 return &m_options;
864 }
Johnny Chen7d49c9c2012-05-25 21:10:46 +0000865
Jim Ingham5a988412012-06-08 21:56:10 +0000866 class CommandOptions : public Options
867 {
868 public:
Greg Clayton0c5cd902010-06-28 21:30:43 +0000869
Jim Ingham5a988412012-06-08 21:56:10 +0000870 CommandOptions (CommandInterpreter &interpreter) :
871 Options (interpreter),
872 m_ignore_count (0),
873 m_thread_id(LLDB_INVALID_THREAD_ID),
874 m_thread_id_passed(false),
875 m_thread_index (UINT32_MAX),
876 m_thread_index_passed(false),
877 m_thread_name(),
878 m_queue_name(),
879 m_condition (),
Jim Inghamca36cd12012-10-05 19:16:31 +0000880 m_one_shot (false),
Jim Ingham5a988412012-06-08 21:56:10 +0000881 m_enable_passed (false),
882 m_enable_value (false),
883 m_name_passed (false),
884 m_queue_passed (false),
Jim Inghamca36cd12012-10-05 19:16:31 +0000885 m_condition_passed (false),
Jim Ingham33df7cd2014-12-06 01:28:03 +0000886 m_one_shot_passed (false),
887 m_use_dummy (false)
Jim Ingham5a988412012-06-08 21:56:10 +0000888 {
889 }
Greg Clayton0c5cd902010-06-28 21:30:43 +0000890
Jim Ingham5a988412012-06-08 21:56:10 +0000891 virtual
892 ~CommandOptions () {}
Greg Clayton0c5cd902010-06-28 21:30:43 +0000893
Jim Ingham5a988412012-06-08 21:56:10 +0000894 virtual Error
895 SetOptionValue (uint32_t option_idx, const char *option_arg)
896 {
897 Error error;
Greg Clayton3bcdfc02012-12-04 00:32:51 +0000898 const int short_option = m_getopt_table[option_idx].val;
Greg Claytone02b8502010-10-12 04:29:14 +0000899
Jim Ingham5a988412012-06-08 21:56:10 +0000900 switch (short_option)
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000901 {
Jim Ingham5a988412012-06-08 21:56:10 +0000902 case 'c':
903 if (option_arg != NULL)
904 m_condition.assign (option_arg);
905 else
906 m_condition.clear();
907 m_condition_passed = true;
908 break;
909 case 'd':
910 m_enable_passed = true;
911 m_enable_value = false;
912 break;
Jim Ingham33df7cd2014-12-06 01:28:03 +0000913 case 'D':
914 m_use_dummy = true;
915 break;
Jim Ingham5a988412012-06-08 21:56:10 +0000916 case 'e':
917 m_enable_passed = true;
918 m_enable_value = true;
919 break;
920 case 'i':
921 {
Vince Harron5275aaa2015-01-15 20:08:35 +0000922 m_ignore_count = StringConvert::ToUInt32(option_arg, UINT32_MAX, 0);
Jim Ingham5a988412012-06-08 21:56:10 +0000923 if (m_ignore_count == UINT32_MAX)
924 error.SetErrorStringWithFormat ("invalid ignore count '%s'", option_arg);
925 }
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000926 break;
Jim Inghamca36cd12012-10-05 19:16:31 +0000927 case 'o':
928 {
929 bool value, success;
930 value = Args::StringToBoolean(option_arg, false, &success);
931 if (success)
932 {
933 m_one_shot_passed = true;
934 m_one_shot = value;
935 }
936 else
937 error.SetErrorStringWithFormat("invalid boolean value '%s' passed for -o option", option_arg);
938 }
939 break;
Jim Ingham5a988412012-06-08 21:56:10 +0000940 case 't' :
Jim Ingham87df91b2011-09-23 00:54:11 +0000941 {
Jim Ingham5a988412012-06-08 21:56:10 +0000942 if (option_arg[0] == '\0')
Jim Ingham87df91b2011-09-23 00:54:11 +0000943 {
Jim Ingham5a988412012-06-08 21:56:10 +0000944 m_thread_id = LLDB_INVALID_THREAD_ID;
945 m_thread_id_passed = true;
Jim Ingham87df91b2011-09-23 00:54:11 +0000946 }
947 else
948 {
Vince Harron5275aaa2015-01-15 20:08:35 +0000949 m_thread_id = StringConvert::ToUInt64(option_arg, LLDB_INVALID_THREAD_ID, 0);
Jim Ingham5a988412012-06-08 21:56:10 +0000950 if (m_thread_id == LLDB_INVALID_THREAD_ID)
951 error.SetErrorStringWithFormat ("invalid thread id string '%s'", option_arg);
952 else
953 m_thread_id_passed = true;
Jim Ingham87df91b2011-09-23 00:54:11 +0000954 }
955 }
Jim Ingham5a988412012-06-08 21:56:10 +0000956 break;
957 case 'T':
958 if (option_arg != NULL)
959 m_thread_name.assign (option_arg);
960 else
961 m_thread_name.clear();
962 m_name_passed = true;
963 break;
964 case 'q':
965 if (option_arg != NULL)
966 m_queue_name.assign (option_arg);
967 else
968 m_queue_name.clear();
969 m_queue_passed = true;
970 break;
971 case 'x':
Jim Ingham969795f2011-09-21 01:17:13 +0000972 {
Jim Ingham5a988412012-06-08 21:56:10 +0000973 if (option_arg[0] == '\n')
974 {
975 m_thread_index = UINT32_MAX;
976 m_thread_index_passed = true;
977 }
978 else
979 {
Vince Harron5275aaa2015-01-15 20:08:35 +0000980 m_thread_index = StringConvert::ToUInt32 (option_arg, UINT32_MAX, 0);
Jim Ingham5a988412012-06-08 21:56:10 +0000981 if (m_thread_id == UINT32_MAX)
982 error.SetErrorStringWithFormat ("invalid thread index string '%s'", option_arg);
983 else
984 m_thread_index_passed = true;
985 }
Jim Ingham969795f2011-09-21 01:17:13 +0000986 }
Jim Ingham5a988412012-06-08 21:56:10 +0000987 break;
988 default:
989 error.SetErrorStringWithFormat ("unrecognized option '%c'", short_option);
990 break;
Jim Ingham969795f2011-09-21 01:17:13 +0000991 }
Jim Ingham5a988412012-06-08 21:56:10 +0000992
993 return error;
994 }
995 void
996 OptionParsingStarting ()
997 {
998 m_ignore_count = 0;
999 m_thread_id = LLDB_INVALID_THREAD_ID;
1000 m_thread_id_passed = false;
1001 m_thread_index = UINT32_MAX;
1002 m_thread_index_passed = false;
1003 m_thread_name.clear();
1004 m_queue_name.clear();
1005 m_condition.clear();
Jim Inghamca36cd12012-10-05 19:16:31 +00001006 m_one_shot = false;
Jim Ingham5a988412012-06-08 21:56:10 +00001007 m_enable_passed = false;
1008 m_queue_passed = false;
1009 m_name_passed = false;
1010 m_condition_passed = false;
Jim Inghamca36cd12012-10-05 19:16:31 +00001011 m_one_shot_passed = false;
Jim Ingham33df7cd2014-12-06 01:28:03 +00001012 m_use_dummy = false;
Jim Ingham5a988412012-06-08 21:56:10 +00001013 }
1014
1015 const OptionDefinition*
1016 GetDefinitions ()
1017 {
1018 return g_option_table;
1019 }
1020
1021
1022 // Options table: Required for subclasses of Options.
1023
1024 static OptionDefinition g_option_table[];
1025
1026 // Instance variables to hold the values for command options.
1027
1028 uint32_t m_ignore_count;
1029 lldb::tid_t m_thread_id;
1030 bool m_thread_id_passed;
1031 uint32_t m_thread_index;
1032 bool m_thread_index_passed;
1033 std::string m_thread_name;
1034 std::string m_queue_name;
1035 std::string m_condition;
Jim Inghamca36cd12012-10-05 19:16:31 +00001036 bool m_one_shot;
Jim Ingham5a988412012-06-08 21:56:10 +00001037 bool m_enable_passed;
1038 bool m_enable_value;
1039 bool m_name_passed;
1040 bool m_queue_passed;
1041 bool m_condition_passed;
Jim Inghamca36cd12012-10-05 19:16:31 +00001042 bool m_one_shot_passed;
Jim Ingham33df7cd2014-12-06 01:28:03 +00001043 bool m_use_dummy;
Jim Ingham5a988412012-06-08 21:56:10 +00001044
1045 };
1046
1047protected:
1048 virtual bool
1049 DoExecute (Args& command, CommandReturnObject &result)
1050 {
Jim Ingham33df7cd2014-12-06 01:28:03 +00001051 Target *target = GetSelectedOrDummyTarget(m_options.m_use_dummy);
Jim Ingham5a988412012-06-08 21:56:10 +00001052 if (target == NULL)
1053 {
1054 result.AppendError ("Invalid target. No existing target or breakpoints.");
1055 result.SetStatus (eReturnStatusFailed);
1056 return false;
1057 }
1058
1059 Mutex::Locker locker;
1060 target->GetBreakpointList().GetListMutex(locker);
1061
1062 BreakpointIDList valid_bp_ids;
1063
Jim Ingham5e09c8c2014-12-16 23:40:14 +00001064 CommandObjectMultiwordBreakpoint::VerifyBreakpointOrLocationIDs (command, target, result, &valid_bp_ids);
Jim Ingham5a988412012-06-08 21:56:10 +00001065
1066 if (result.Succeeded())
1067 {
1068 const size_t count = valid_bp_ids.GetSize();
1069 for (size_t i = 0; i < count; ++i)
Jim Inghamfab10e82012-03-06 00:37:27 +00001070 {
Jim Ingham5a988412012-06-08 21:56:10 +00001071 BreakpointID cur_bp_id = valid_bp_ids.GetBreakpointIDAtIndex (i);
1072
1073 if (cur_bp_id.GetBreakpointID() != LLDB_INVALID_BREAK_ID)
1074 {
1075 Breakpoint *bp = target->GetBreakpointByID (cur_bp_id.GetBreakpointID()).get();
1076 if (cur_bp_id.GetLocationID() != LLDB_INVALID_BREAK_ID)
1077 {
1078 BreakpointLocation *location = bp->FindLocationByID (cur_bp_id.GetLocationID()).get();
1079 if (location)
1080 {
1081 if (m_options.m_thread_id_passed)
1082 location->SetThreadID (m_options.m_thread_id);
1083
1084 if (m_options.m_thread_index_passed)
1085 location->SetThreadIndex(m_options.m_thread_index);
1086
1087 if (m_options.m_name_passed)
1088 location->SetThreadName(m_options.m_thread_name.c_str());
1089
1090 if (m_options.m_queue_passed)
1091 location->SetQueueName(m_options.m_queue_name.c_str());
1092
1093 if (m_options.m_ignore_count != 0)
1094 location->SetIgnoreCount(m_options.m_ignore_count);
1095
1096 if (m_options.m_enable_passed)
1097 location->SetEnabled (m_options.m_enable_value);
1098
1099 if (m_options.m_condition_passed)
1100 location->SetCondition (m_options.m_condition.c_str());
1101 }
1102 }
1103 else
1104 {
1105 if (m_options.m_thread_id_passed)
1106 bp->SetThreadID (m_options.m_thread_id);
1107
1108 if (m_options.m_thread_index_passed)
1109 bp->SetThreadIndex(m_options.m_thread_index);
1110
1111 if (m_options.m_name_passed)
1112 bp->SetThreadName(m_options.m_thread_name.c_str());
1113
1114 if (m_options.m_queue_passed)
1115 bp->SetQueueName(m_options.m_queue_name.c_str());
1116
1117 if (m_options.m_ignore_count != 0)
1118 bp->SetIgnoreCount(m_options.m_ignore_count);
1119
1120 if (m_options.m_enable_passed)
1121 bp->SetEnabled (m_options.m_enable_value);
1122
1123 if (m_options.m_condition_passed)
1124 bp->SetCondition (m_options.m_condition.c_str());
1125 }
1126 }
Jim Inghamfab10e82012-03-06 00:37:27 +00001127 }
Jim Ingham5a988412012-06-08 21:56:10 +00001128 }
1129
1130 return result.Succeeded();
Chris Lattner30fdc8d2010-06-08 16:52:24 +00001131 }
1132
Jim Ingham5a988412012-06-08 21:56:10 +00001133private:
1134 CommandOptions m_options;
1135};
Johnny Chen7d49c9c2012-05-25 21:10:46 +00001136
Jim Ingham5a988412012-06-08 21:56:10 +00001137#pragma mark Modify::CommandOptions
1138OptionDefinition
1139CommandObjectBreakpointModify::CommandOptions::g_option_table[] =
1140{
Zachary Turnerd37221d2014-07-09 16:31:49 +00001141{ 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." },
1142{ 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." },
1143{ 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."},
1144{ 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."},
1145{ 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."},
1146{ 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."},
1147{ LLDB_OPT_SET_ALL, false, "condition", 'c', OptionParser::eRequiredArgument, NULL, NULL, 0, eArgTypeExpression, "The breakpoint stops only if this condition expression evaluates to true."},
1148{ LLDB_OPT_SET_1, false, "enable", 'e', OptionParser::eNoArgument, NULL, NULL, 0, eArgTypeNone, "Enable the breakpoint."},
1149{ LLDB_OPT_SET_2, false, "disable", 'd', OptionParser::eNoArgument, NULL, NULL, 0, eArgTypeNone, "Disable the breakpoint."},
Jim Ingham33df7cd2014-12-06 01:28:03 +00001150{ 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."},
1151
Zachary Turnerd37221d2014-07-09 16:31:49 +00001152{ 0, false, NULL, 0 , 0, NULL, NULL, 0, eArgTypeNone, NULL }
Jim Ingham5a988412012-06-08 21:56:10 +00001153};
1154
1155//-------------------------------------------------------------------------
1156// CommandObjectBreakpointEnable
1157//-------------------------------------------------------------------------
1158#pragma mark Enable
1159
1160class CommandObjectBreakpointEnable : public CommandObjectParsed
1161{
1162public:
1163 CommandObjectBreakpointEnable (CommandInterpreter &interpreter) :
1164 CommandObjectParsed (interpreter,
1165 "enable",
1166 "Enable the specified disabled breakpoint(s). If no breakpoints are specified, enable all of them.",
1167 NULL)
1168 {
1169 CommandArgumentEntry arg;
1170 CommandObject::AddIDsArgumentData(arg, eArgTypeBreakpointID, eArgTypeBreakpointIDRange);
1171 // Add the entry for the first argument for this command to the object's arguments vector.
1172 m_arguments.push_back (arg);
1173 }
1174
1175
1176 virtual
1177 ~CommandObjectBreakpointEnable () {}
1178
1179protected:
1180 virtual bool
1181 DoExecute (Args& command, CommandReturnObject &result)
1182 {
Jim Ingham893c9322014-11-22 01:42:44 +00001183 Target *target = GetSelectedOrDummyTarget();
Jim Ingham5a988412012-06-08 21:56:10 +00001184 if (target == NULL)
1185 {
1186 result.AppendError ("Invalid target. No existing target or breakpoints.");
1187 result.SetStatus (eReturnStatusFailed);
1188 return false;
1189 }
1190
1191 Mutex::Locker locker;
1192 target->GetBreakpointList().GetListMutex(locker);
1193
1194 const BreakpointList &breakpoints = target->GetBreakpointList();
1195
1196 size_t num_breakpoints = breakpoints.GetSize();
1197
1198 if (num_breakpoints == 0)
1199 {
1200 result.AppendError ("No breakpoints exist to be enabled.");
1201 result.SetStatus (eReturnStatusFailed);
1202 return false;
1203 }
1204
1205 if (command.GetArgumentCount() == 0)
1206 {
1207 // No breakpoint selected; enable all currently set breakpoints.
1208 target->EnableAllBreakpoints ();
Greg Clayton6fea17e2014-03-03 19:15:20 +00001209 result.AppendMessageWithFormat ("All breakpoints enabled. (%" PRIu64 " breakpoints)\n", (uint64_t)num_breakpoints);
Jim Ingham5a988412012-06-08 21:56:10 +00001210 result.SetStatus (eReturnStatusSuccessFinishNoResult);
1211 }
1212 else
1213 {
1214 // Particular breakpoint selected; enable that breakpoint.
1215 BreakpointIDList valid_bp_ids;
Jim Ingham5e09c8c2014-12-16 23:40:14 +00001216 CommandObjectMultiwordBreakpoint::VerifyBreakpointOrLocationIDs (command, target, result, &valid_bp_ids);
Jim Ingham5a988412012-06-08 21:56:10 +00001217
1218 if (result.Succeeded())
1219 {
1220 int enable_count = 0;
1221 int loc_count = 0;
1222 const size_t count = valid_bp_ids.GetSize();
1223 for (size_t i = 0; i < count; ++i)
1224 {
1225 BreakpointID cur_bp_id = valid_bp_ids.GetBreakpointIDAtIndex (i);
1226
1227 if (cur_bp_id.GetBreakpointID() != LLDB_INVALID_BREAK_ID)
1228 {
1229 Breakpoint *breakpoint = target->GetBreakpointByID (cur_bp_id.GetBreakpointID()).get();
1230 if (cur_bp_id.GetLocationID() != LLDB_INVALID_BREAK_ID)
1231 {
1232 BreakpointLocation *location = breakpoint->FindLocationByID (cur_bp_id.GetLocationID()).get();
1233 if (location)
1234 {
1235 location->SetEnabled (true);
1236 ++loc_count;
1237 }
1238 }
1239 else
1240 {
1241 breakpoint->SetEnabled (true);
1242 ++enable_count;
1243 }
1244 }
1245 }
1246 result.AppendMessageWithFormat ("%d breakpoints enabled.\n", enable_count + loc_count);
1247 result.SetStatus (eReturnStatusSuccessFinishNoResult);
1248 }
1249 }
1250
1251 return result.Succeeded();
1252 }
1253};
1254
1255//-------------------------------------------------------------------------
1256// CommandObjectBreakpointDisable
1257//-------------------------------------------------------------------------
1258#pragma mark Disable
1259
1260class CommandObjectBreakpointDisable : public CommandObjectParsed
1261{
1262public:
1263 CommandObjectBreakpointDisable (CommandInterpreter &interpreter) :
1264 CommandObjectParsed (interpreter,
1265 "breakpoint disable",
Kate Stoneea671fb2015-07-14 05:48:36 +00001266 "Disable the specified breakpoint(s) without removing them. If none are specified, disable all breakpoints.",
Jim Ingham5a988412012-06-08 21:56:10 +00001267 NULL)
1268 {
Jim Inghamb0fac502013-03-08 00:31:40 +00001269 SetHelpLong(
Kate Stoneea671fb2015-07-14 05:48:36 +00001270"Disable the specified breakpoint(s) without removing them. \
1271If none are specified, disable all breakpoints." R"(
1272
1273)" "Note: disabling a breakpoint will cause none of its locations to be hit \
1274regardless of whether they are enabled or disabled. After the sequence:" R"(
1275
1276 (lldb) break disable 1
1277 (lldb) break enable 1.1
1278
1279execution will NOT stop at location 1.1. To achieve that, type:
1280
1281 (lldb) break disable 1.*
1282 (lldb) break enable 1.1
1283
1284)" "The first command disables all the locations of breakpoint 1, \
Jim Inghamb0fac502013-03-08 00:31:40 +00001285the second re-enables the first location."
Kate Stoneea671fb2015-07-14 05:48:36 +00001286 );
Jim Inghamb0fac502013-03-08 00:31:40 +00001287
Jim Ingham5a988412012-06-08 21:56:10 +00001288 CommandArgumentEntry arg;
1289 CommandObject::AddIDsArgumentData(arg, eArgTypeBreakpointID, eArgTypeBreakpointIDRange);
1290 // Add the entry for the first argument for this command to the object's arguments vector.
Jim Inghamb0fac502013-03-08 00:31:40 +00001291 m_arguments.push_back (arg);
1292
Jim Ingham5a988412012-06-08 21:56:10 +00001293 }
1294
1295
1296 virtual
1297 ~CommandObjectBreakpointDisable () {}
1298
1299protected:
1300 virtual bool
1301 DoExecute (Args& command, CommandReturnObject &result)
1302 {
Jim Ingham893c9322014-11-22 01:42:44 +00001303 Target *target = GetSelectedOrDummyTarget();
Jim Ingham5a988412012-06-08 21:56:10 +00001304 if (target == NULL)
1305 {
1306 result.AppendError ("Invalid target. No existing target or breakpoints.");
1307 result.SetStatus (eReturnStatusFailed);
1308 return false;
1309 }
1310
1311 Mutex::Locker locker;
1312 target->GetBreakpointList().GetListMutex(locker);
1313
1314 const BreakpointList &breakpoints = target->GetBreakpointList();
1315 size_t num_breakpoints = breakpoints.GetSize();
1316
1317 if (num_breakpoints == 0)
1318 {
1319 result.AppendError ("No breakpoints exist to be disabled.");
1320 result.SetStatus (eReturnStatusFailed);
1321 return false;
1322 }
1323
1324 if (command.GetArgumentCount() == 0)
1325 {
1326 // No breakpoint selected; disable all currently set breakpoints.
1327 target->DisableAllBreakpoints ();
Greg Clayton6fea17e2014-03-03 19:15:20 +00001328 result.AppendMessageWithFormat ("All breakpoints disabled. (%" PRIu64 " breakpoints)\n", (uint64_t)num_breakpoints);
Jim Ingham5a988412012-06-08 21:56:10 +00001329 result.SetStatus (eReturnStatusSuccessFinishNoResult);
1330 }
1331 else
1332 {
1333 // Particular breakpoint selected; disable that breakpoint.
1334 BreakpointIDList valid_bp_ids;
1335
Jim Ingham5e09c8c2014-12-16 23:40:14 +00001336 CommandObjectMultiwordBreakpoint::VerifyBreakpointOrLocationIDs (command, target, result, &valid_bp_ids);
Jim Ingham5a988412012-06-08 21:56:10 +00001337
1338 if (result.Succeeded())
1339 {
1340 int disable_count = 0;
1341 int loc_count = 0;
1342 const size_t count = valid_bp_ids.GetSize();
1343 for (size_t i = 0; i < count; ++i)
1344 {
1345 BreakpointID cur_bp_id = valid_bp_ids.GetBreakpointIDAtIndex (i);
1346
1347 if (cur_bp_id.GetBreakpointID() != LLDB_INVALID_BREAK_ID)
1348 {
1349 Breakpoint *breakpoint = target->GetBreakpointByID (cur_bp_id.GetBreakpointID()).get();
1350 if (cur_bp_id.GetLocationID() != LLDB_INVALID_BREAK_ID)
1351 {
1352 BreakpointLocation *location = breakpoint->FindLocationByID (cur_bp_id.GetLocationID()).get();
1353 if (location)
1354 {
1355 location->SetEnabled (false);
1356 ++loc_count;
1357 }
1358 }
1359 else
1360 {
1361 breakpoint->SetEnabled (false);
1362 ++disable_count;
1363 }
1364 }
1365 }
1366 result.AppendMessageWithFormat ("%d breakpoints disabled.\n", disable_count + loc_count);
1367 result.SetStatus (eReturnStatusSuccessFinishNoResult);
1368 }
1369 }
1370
1371 return result.Succeeded();
1372 }
1373
1374};
1375
1376//-------------------------------------------------------------------------
1377// CommandObjectBreakpointList
1378//-------------------------------------------------------------------------
1379#pragma mark List
1380
1381class CommandObjectBreakpointList : public CommandObjectParsed
1382{
1383public:
1384 CommandObjectBreakpointList (CommandInterpreter &interpreter) :
1385 CommandObjectParsed (interpreter,
1386 "breakpoint list",
1387 "List some or all breakpoints at configurable levels of detail.",
1388 NULL),
1389 m_options (interpreter)
1390 {
1391 CommandArgumentEntry arg;
1392 CommandArgumentData bp_id_arg;
1393
1394 // Define the first (and only) variant of this arg.
1395 bp_id_arg.arg_type = eArgTypeBreakpointID;
1396 bp_id_arg.arg_repetition = eArgRepeatOptional;
1397
1398 // There is only one variant this argument could be; put it into the argument entry.
1399 arg.push_back (bp_id_arg);
1400
1401 // Push the data for the first argument into the m_arguments vector.
1402 m_arguments.push_back (arg);
1403 }
1404
1405
1406 virtual
1407 ~CommandObjectBreakpointList () {}
1408
1409 virtual Options *
1410 GetOptions ()
1411 {
1412 return &m_options;
Jim Ingham1b54c882010-06-16 02:00:15 +00001413 }
1414
Jim Ingham5a988412012-06-08 21:56:10 +00001415 class CommandOptions : public Options
Chris Lattner30fdc8d2010-06-08 16:52:24 +00001416 {
Jim Ingham5a988412012-06-08 21:56:10 +00001417 public:
1418
1419 CommandOptions (CommandInterpreter &interpreter) :
1420 Options (interpreter),
Jim Ingham33df7cd2014-12-06 01:28:03 +00001421 m_level (lldb::eDescriptionLevelBrief),
1422 m_use_dummy(false)
Jim Ingham5a988412012-06-08 21:56:10 +00001423 {
1424 }
1425
1426 virtual
1427 ~CommandOptions () {}
1428
1429 virtual Error
1430 SetOptionValue (uint32_t option_idx, const char *option_arg)
1431 {
1432 Error error;
Greg Clayton3bcdfc02012-12-04 00:32:51 +00001433 const int short_option = m_getopt_table[option_idx].val;
Jim Ingham5a988412012-06-08 21:56:10 +00001434
1435 switch (short_option)
1436 {
1437 case 'b':
1438 m_level = lldb::eDescriptionLevelBrief;
1439 break;
Jim Ingham33df7cd2014-12-06 01:28:03 +00001440 case 'D':
1441 m_use_dummy = true;
1442 break;
Jim Ingham5a988412012-06-08 21:56:10 +00001443 case 'f':
1444 m_level = lldb::eDescriptionLevelFull;
1445 break;
1446 case 'v':
1447 m_level = lldb::eDescriptionLevelVerbose;
1448 break;
1449 case 'i':
1450 m_internal = true;
1451 break;
1452 default:
1453 error.SetErrorStringWithFormat ("unrecognized option '%c'", short_option);
1454 break;
1455 }
1456
1457 return error;
1458 }
1459
1460 void
1461 OptionParsingStarting ()
1462 {
1463 m_level = lldb::eDescriptionLevelFull;
1464 m_internal = false;
Jim Ingham33df7cd2014-12-06 01:28:03 +00001465 m_use_dummy = false;
Jim Ingham5a988412012-06-08 21:56:10 +00001466 }
1467
1468 const OptionDefinition *
1469 GetDefinitions ()
1470 {
1471 return g_option_table;
1472 }
1473
1474 // Options table: Required for subclasses of Options.
1475
1476 static OptionDefinition g_option_table[];
1477
1478 // Instance variables to hold the values for command options.
1479
1480 lldb::DescriptionLevel m_level;
1481
1482 bool m_internal;
Jim Ingham33df7cd2014-12-06 01:28:03 +00001483 bool m_use_dummy;
Jim Ingham5a988412012-06-08 21:56:10 +00001484 };
1485
1486protected:
1487 virtual bool
1488 DoExecute (Args& command, CommandReturnObject &result)
1489 {
Jim Ingham33df7cd2014-12-06 01:28:03 +00001490 Target *target = GetSelectedOrDummyTarget(m_options.m_use_dummy);
1491
Jim Ingham5a988412012-06-08 21:56:10 +00001492 if (target == NULL)
1493 {
1494 result.AppendError ("Invalid target. No current target or breakpoints.");
1495 result.SetStatus (eReturnStatusSuccessFinishNoResult);
1496 return true;
1497 }
1498
1499 const BreakpointList &breakpoints = target->GetBreakpointList(m_options.m_internal);
1500 Mutex::Locker locker;
1501 target->GetBreakpointList(m_options.m_internal).GetListMutex(locker);
1502
1503 size_t num_breakpoints = breakpoints.GetSize();
1504
1505 if (num_breakpoints == 0)
1506 {
1507 result.AppendMessage ("No breakpoints currently set.");
1508 result.SetStatus (eReturnStatusSuccessFinishNoResult);
1509 return true;
1510 }
1511
Jim Ingham85e8b812011-02-19 02:53:09 +00001512 Stream &output_stream = result.GetOutputStream();
Jim Ingham5a988412012-06-08 21:56:10 +00001513
1514 if (command.GetArgumentCount() == 0)
1515 {
1516 // No breakpoint selected; show info about all currently set breakpoints.
1517 result.AppendMessage ("Current breakpoints:");
1518 for (size_t i = 0; i < num_breakpoints; ++i)
1519 {
1520 Breakpoint *breakpoint = breakpoints.GetBreakpointAtIndex (i).get();
1521 AddBreakpointDescription (&output_stream, breakpoint, m_options.m_level);
1522 }
1523 result.SetStatus (eReturnStatusSuccessFinishNoResult);
1524 }
1525 else
1526 {
1527 // Particular breakpoints selected; show info about that breakpoint.
1528 BreakpointIDList valid_bp_ids;
Jim Ingham5e09c8c2014-12-16 23:40:14 +00001529 CommandObjectMultiwordBreakpoint::VerifyBreakpointOrLocationIDs (command, target, result, &valid_bp_ids);
Jim Ingham5a988412012-06-08 21:56:10 +00001530
1531 if (result.Succeeded())
1532 {
1533 for (size_t i = 0; i < valid_bp_ids.GetSize(); ++i)
1534 {
1535 BreakpointID cur_bp_id = valid_bp_ids.GetBreakpointIDAtIndex (i);
1536 Breakpoint *breakpoint = target->GetBreakpointByID (cur_bp_id.GetBreakpointID()).get();
1537 AddBreakpointDescription (&output_stream, breakpoint, m_options.m_level);
1538 }
1539 result.SetStatus (eReturnStatusSuccessFinishNoResult);
1540 }
1541 else
1542 {
1543 result.AppendError ("Invalid breakpoint id.");
1544 result.SetStatus (eReturnStatusFailed);
1545 }
1546 }
1547
1548 return result.Succeeded();
Chris Lattner30fdc8d2010-06-08 16:52:24 +00001549 }
1550
Jim Ingham5a988412012-06-08 21:56:10 +00001551private:
1552 CommandOptions m_options;
1553};
1554
1555#pragma mark List::CommandOptions
1556OptionDefinition
1557CommandObjectBreakpointList::CommandOptions::g_option_table[] =
1558{
Zachary Turnerd37221d2014-07-09 16:31:49 +00001559 { LLDB_OPT_SET_ALL, false, "internal", 'i', OptionParser::eNoArgument, NULL, NULL, 0, eArgTypeNone,
Jim Ingham5a988412012-06-08 21:56:10 +00001560 "Show debugger internal breakpoints" },
1561
Zachary Turnerd37221d2014-07-09 16:31:49 +00001562 { LLDB_OPT_SET_1, false, "brief", 'b', OptionParser::eNoArgument, NULL, NULL, 0, eArgTypeNone,
Jim Ingham5a988412012-06-08 21:56:10 +00001563 "Give a brief description of the breakpoint (no location info)."},
1564
1565 // FIXME: We need to add an "internal" command, and then add this sort of thing to it.
1566 // But I need to see it for now, and don't want to wait.
Zachary Turnerd37221d2014-07-09 16:31:49 +00001567 { LLDB_OPT_SET_2, false, "full", 'f', OptionParser::eNoArgument, NULL, NULL, 0, eArgTypeNone,
Jim Ingham5a988412012-06-08 21:56:10 +00001568 "Give a full description of the breakpoint and its locations."},
1569
Zachary Turnerd37221d2014-07-09 16:31:49 +00001570 { LLDB_OPT_SET_3, false, "verbose", 'v', OptionParser::eNoArgument, NULL, NULL, 0, eArgTypeNone,
Jim Ingham5a988412012-06-08 21:56:10 +00001571 "Explain everything we know about the breakpoint (for debugging debugger bugs)." },
1572
Jim Ingham33df7cd2014-12-06 01:28:03 +00001573 { LLDB_OPT_SET_ALL, false, "dummy-breakpoints", 'D', OptionParser::eNoArgument, NULL, NULL, 0, eArgTypeNone,
1574 "List Dummy breakpoints - i.e. breakpoints set before a file is provided, which prime new targets."},
1575
Zachary Turnerd37221d2014-07-09 16:31:49 +00001576 { 0, false, NULL, 0, 0, NULL, NULL, 0, eArgTypeNone, NULL }
Jim Ingham5a988412012-06-08 21:56:10 +00001577};
1578
1579//-------------------------------------------------------------------------
1580// CommandObjectBreakpointClear
1581//-------------------------------------------------------------------------
1582#pragma mark Clear
1583
1584class CommandObjectBreakpointClear : public CommandObjectParsed
1585{
1586public:
1587
1588 typedef enum BreakpointClearType
1589 {
1590 eClearTypeInvalid,
1591 eClearTypeFileAndLine
1592 } BreakpointClearType;
1593
1594 CommandObjectBreakpointClear (CommandInterpreter &interpreter) :
1595 CommandObjectParsed (interpreter,
1596 "breakpoint clear",
1597 "Clears a breakpoint or set of breakpoints in the executable.",
1598 "breakpoint clear <cmd-options>"),
1599 m_options (interpreter)
1600 {
1601 }
1602
1603 virtual
1604 ~CommandObjectBreakpointClear () {}
1605
1606 virtual Options *
1607 GetOptions ()
1608 {
1609 return &m_options;
1610 }
1611
1612 class CommandOptions : public Options
1613 {
1614 public:
1615
1616 CommandOptions (CommandInterpreter &interpreter) :
1617 Options (interpreter),
1618 m_filename (),
1619 m_line_num (0)
1620 {
1621 }
1622
1623 virtual
1624 ~CommandOptions () {}
1625
1626 virtual Error
1627 SetOptionValue (uint32_t option_idx, const char *option_arg)
1628 {
1629 Error error;
Greg Clayton3bcdfc02012-12-04 00:32:51 +00001630 const int short_option = m_getopt_table[option_idx].val;
Jim Ingham5a988412012-06-08 21:56:10 +00001631
1632 switch (short_option)
1633 {
1634 case 'f':
1635 m_filename.assign (option_arg);
1636 break;
1637
1638 case 'l':
Vince Harron5275aaa2015-01-15 20:08:35 +00001639 m_line_num = StringConvert::ToUInt32 (option_arg, 0);
Jim Ingham5a988412012-06-08 21:56:10 +00001640 break;
1641
1642 default:
1643 error.SetErrorStringWithFormat ("unrecognized option '%c'", short_option);
1644 break;
1645 }
1646
1647 return error;
1648 }
1649
1650 void
1651 OptionParsingStarting ()
1652 {
1653 m_filename.clear();
1654 m_line_num = 0;
1655 }
1656
1657 const OptionDefinition*
1658 GetDefinitions ()
1659 {
1660 return g_option_table;
1661 }
1662
1663 // Options table: Required for subclasses of Options.
1664
1665 static OptionDefinition g_option_table[];
1666
1667 // Instance variables to hold the values for command options.
1668
1669 std::string m_filename;
1670 uint32_t m_line_num;
1671
1672 };
1673
1674protected:
1675 virtual bool
1676 DoExecute (Args& command, CommandReturnObject &result)
1677 {
Jim Ingham893c9322014-11-22 01:42:44 +00001678 Target *target = GetSelectedOrDummyTarget();
Jim Ingham5a988412012-06-08 21:56:10 +00001679 if (target == NULL)
1680 {
1681 result.AppendError ("Invalid target. No existing target or breakpoints.");
1682 result.SetStatus (eReturnStatusFailed);
1683 return false;
1684 }
1685
1686 // The following are the various types of breakpoints that could be cleared:
1687 // 1). -f -l (clearing breakpoint by source location)
1688
1689 BreakpointClearType break_type = eClearTypeInvalid;
1690
1691 if (m_options.m_line_num != 0)
1692 break_type = eClearTypeFileAndLine;
1693
1694 Mutex::Locker locker;
1695 target->GetBreakpointList().GetListMutex(locker);
1696
1697 BreakpointList &breakpoints = target->GetBreakpointList();
1698 size_t num_breakpoints = breakpoints.GetSize();
1699
1700 // Early return if there's no breakpoint at all.
1701 if (num_breakpoints == 0)
1702 {
1703 result.AppendError ("Breakpoint clear: No breakpoint cleared.");
1704 result.SetStatus (eReturnStatusFailed);
1705 return result.Succeeded();
1706 }
1707
1708 // Find matching breakpoints and delete them.
1709
1710 // First create a copy of all the IDs.
1711 std::vector<break_id_t> BreakIDs;
1712 for (size_t i = 0; i < num_breakpoints; ++i)
1713 BreakIDs.push_back(breakpoints.GetBreakpointAtIndex(i).get()->GetID());
1714
1715 int num_cleared = 0;
1716 StreamString ss;
1717 switch (break_type)
1718 {
1719 case eClearTypeFileAndLine: // Breakpoint by source position
1720 {
1721 const ConstString filename(m_options.m_filename.c_str());
1722 BreakpointLocationCollection loc_coll;
1723
1724 for (size_t i = 0; i < num_breakpoints; ++i)
1725 {
1726 Breakpoint *bp = breakpoints.FindBreakpointByID(BreakIDs[i]).get();
1727
1728 if (bp->GetMatchingFileLine(filename, m_options.m_line_num, loc_coll))
1729 {
1730 // If the collection size is 0, it's a full match and we can just remove the breakpoint.
1731 if (loc_coll.GetSize() == 0)
1732 {
1733 bp->GetDescription(&ss, lldb::eDescriptionLevelBrief);
1734 ss.EOL();
1735 target->RemoveBreakpointByID (bp->GetID());
1736 ++num_cleared;
1737 }
1738 }
1739 }
1740 }
1741 break;
1742
1743 default:
1744 break;
1745 }
1746
1747 if (num_cleared > 0)
1748 {
1749 Stream &output_stream = result.GetOutputStream();
1750 output_stream.Printf ("%d breakpoints cleared:\n", num_cleared);
1751 output_stream << ss.GetData();
1752 output_stream.EOL();
1753 result.SetStatus (eReturnStatusSuccessFinishNoResult);
1754 }
1755 else
1756 {
1757 result.AppendError ("Breakpoint clear: No breakpoint cleared.");
1758 result.SetStatus (eReturnStatusFailed);
1759 }
1760
1761 return result.Succeeded();
1762 }
1763
1764private:
1765 CommandOptions m_options;
1766};
1767
1768#pragma mark Clear::CommandOptions
1769
1770OptionDefinition
1771CommandObjectBreakpointClear::CommandOptions::g_option_table[] =
1772{
Zachary Turnerd37221d2014-07-09 16:31:49 +00001773 { LLDB_OPT_SET_1, false, "file", 'f', OptionParser::eRequiredArgument, NULL, NULL, CommandCompletions::eSourceFileCompletion, eArgTypeFilename,
Jim Ingham5a988412012-06-08 21:56:10 +00001774 "Specify the breakpoint by source location in this particular file."},
1775
Zachary Turnerd37221d2014-07-09 16:31:49 +00001776 { LLDB_OPT_SET_1, true, "line", 'l', OptionParser::eRequiredArgument, NULL, NULL, 0, eArgTypeLineNum,
Jim Ingham5a988412012-06-08 21:56:10 +00001777 "Specify the breakpoint by source location at this particular line."},
1778
Zachary Turnerd37221d2014-07-09 16:31:49 +00001779 { 0, false, NULL, 0, 0, NULL, NULL, 0, eArgTypeNone, NULL }
Jim Ingham5a988412012-06-08 21:56:10 +00001780};
1781
1782//-------------------------------------------------------------------------
1783// CommandObjectBreakpointDelete
1784//-------------------------------------------------------------------------
1785#pragma mark Delete
1786
1787class CommandObjectBreakpointDelete : public CommandObjectParsed
1788{
1789public:
1790 CommandObjectBreakpointDelete (CommandInterpreter &interpreter) :
1791 CommandObjectParsed (interpreter,
1792 "breakpoint delete",
1793 "Delete the specified breakpoint(s). If no breakpoints are specified, delete them all.",
Jim Ingham33df7cd2014-12-06 01:28:03 +00001794 NULL),
1795 m_options (interpreter)
Jim Ingham5a988412012-06-08 21:56:10 +00001796 {
1797 CommandArgumentEntry arg;
1798 CommandObject::AddIDsArgumentData(arg, eArgTypeBreakpointID, eArgTypeBreakpointIDRange);
1799 // Add the entry for the first argument for this command to the object's arguments vector.
1800 m_arguments.push_back (arg);
1801 }
1802
1803 virtual
1804 ~CommandObjectBreakpointDelete () {}
1805
Jim Ingham33df7cd2014-12-06 01:28:03 +00001806 virtual Options *
1807 GetOptions ()
1808 {
1809 return &m_options;
1810 }
1811
1812 class CommandOptions : public Options
1813 {
1814 public:
1815
1816 CommandOptions (CommandInterpreter &interpreter) :
1817 Options (interpreter),
1818 m_use_dummy (false),
1819 m_force (false)
1820 {
1821 }
1822
1823 virtual
1824 ~CommandOptions () {}
1825
1826 virtual Error
1827 SetOptionValue (uint32_t option_idx, const char *option_arg)
1828 {
1829 Error error;
1830 const int short_option = m_getopt_table[option_idx].val;
1831
1832 switch (short_option)
1833 {
1834 case 'f':
1835 m_force = true;
1836 break;
1837
1838 case 'D':
1839 m_use_dummy = true;
1840 break;
1841
1842 default:
1843 error.SetErrorStringWithFormat ("unrecognized option '%c'", short_option);
1844 break;
1845 }
1846
1847 return error;
1848 }
1849
1850 void
1851 OptionParsingStarting ()
1852 {
1853 m_use_dummy = false;
1854 m_force = false;
1855 }
1856
1857 const OptionDefinition*
1858 GetDefinitions ()
1859 {
1860 return g_option_table;
1861 }
1862
1863 // Options table: Required for subclasses of Options.
1864
1865 static OptionDefinition g_option_table[];
1866
1867 // Instance variables to hold the values for command options.
1868 bool m_use_dummy;
1869 bool m_force;
1870 };
1871
Jim Ingham5a988412012-06-08 21:56:10 +00001872protected:
1873 virtual bool
1874 DoExecute (Args& command, CommandReturnObject &result)
1875 {
Jim Ingham33df7cd2014-12-06 01:28:03 +00001876 Target *target = GetSelectedOrDummyTarget(m_options.m_use_dummy);
1877
Jim Ingham5a988412012-06-08 21:56:10 +00001878 if (target == NULL)
1879 {
1880 result.AppendError ("Invalid target. No existing target or breakpoints.");
1881 result.SetStatus (eReturnStatusFailed);
1882 return false;
1883 }
1884
1885 Mutex::Locker locker;
1886 target->GetBreakpointList().GetListMutex(locker);
1887
1888 const BreakpointList &breakpoints = target->GetBreakpointList();
1889
1890 size_t num_breakpoints = breakpoints.GetSize();
1891
1892 if (num_breakpoints == 0)
1893 {
1894 result.AppendError ("No breakpoints exist to be deleted.");
1895 result.SetStatus (eReturnStatusFailed);
1896 return false;
1897 }
1898
1899 if (command.GetArgumentCount() == 0)
1900 {
Jim Ingham33df7cd2014-12-06 01:28:03 +00001901 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 +00001902 {
1903 result.AppendMessage("Operation cancelled...");
1904 }
1905 else
1906 {
1907 target->RemoveAllBreakpoints ();
Greg Clayton6fea17e2014-03-03 19:15:20 +00001908 result.AppendMessageWithFormat ("All breakpoints removed. (%" PRIu64 " breakpoint%s)\n", (uint64_t)num_breakpoints, num_breakpoints > 1 ? "s" : "");
Jim Ingham5a988412012-06-08 21:56:10 +00001909 }
1910 result.SetStatus (eReturnStatusSuccessFinishNoResult);
1911 }
1912 else
1913 {
1914 // Particular breakpoint selected; disable that breakpoint.
1915 BreakpointIDList valid_bp_ids;
Jim Ingham5e09c8c2014-12-16 23:40:14 +00001916 CommandObjectMultiwordBreakpoint::VerifyBreakpointOrLocationIDs (command, target, result, &valid_bp_ids);
Jim Ingham5a988412012-06-08 21:56:10 +00001917
1918 if (result.Succeeded())
1919 {
1920 int delete_count = 0;
1921 int disable_count = 0;
1922 const size_t count = valid_bp_ids.GetSize();
1923 for (size_t i = 0; i < count; ++i)
1924 {
1925 BreakpointID cur_bp_id = valid_bp_ids.GetBreakpointIDAtIndex (i);
1926
1927 if (cur_bp_id.GetBreakpointID() != LLDB_INVALID_BREAK_ID)
1928 {
1929 if (cur_bp_id.GetLocationID() != LLDB_INVALID_BREAK_ID)
1930 {
1931 Breakpoint *breakpoint = target->GetBreakpointByID (cur_bp_id.GetBreakpointID()).get();
1932 BreakpointLocation *location = breakpoint->FindLocationByID (cur_bp_id.GetLocationID()).get();
1933 // It makes no sense to try to delete individual locations, so we disable them instead.
1934 if (location)
1935 {
1936 location->SetEnabled (false);
1937 ++disable_count;
1938 }
1939 }
1940 else
1941 {
1942 target->RemoveBreakpointByID (cur_bp_id.GetBreakpointID());
1943 ++delete_count;
1944 }
1945 }
1946 }
1947 result.AppendMessageWithFormat ("%d breakpoints deleted; %d breakpoint locations disabled.\n",
1948 delete_count, disable_count);
1949 result.SetStatus (eReturnStatusSuccessFinishNoResult);
1950 }
1951 }
1952 return result.Succeeded();
1953 }
Jim Ingham33df7cd2014-12-06 01:28:03 +00001954private:
1955 CommandOptions m_options;
1956};
1957
1958OptionDefinition
1959CommandObjectBreakpointDelete::CommandOptions::g_option_table[] =
1960{
1961 { LLDB_OPT_SET_1, false, "force", 'f', OptionParser::eNoArgument, NULL, NULL, 0, eArgTypeNone,
1962 "Delete all breakpoints without querying for confirmation."},
1963
1964 { LLDB_OPT_SET_1, false, "dummy-breakpoints", 'D', OptionParser::eNoArgument, NULL, NULL, 0, eArgTypeNone,
1965 "Delete Dummy breakpoints - i.e. breakpoints set before a file is provided, which prime new targets."},
1966
1967 { 0, false, NULL, 0, 0, NULL, NULL, 0, eArgTypeNone, NULL }
Jim Ingham5a988412012-06-08 21:56:10 +00001968};
Chris Lattner30fdc8d2010-06-08 16:52:24 +00001969
Chris Lattner30fdc8d2010-06-08 16:52:24 +00001970//-------------------------------------------------------------------------
Jim Ingham5e09c8c2014-12-16 23:40:14 +00001971// CommandObjectBreakpointName
1972//-------------------------------------------------------------------------
1973
1974static OptionDefinition
1975g_breakpoint_name_options[] =
1976{
1977 { LLDB_OPT_SET_1, false, "name", 'N', OptionParser::eRequiredArgument, NULL, NULL, 0, eArgTypeBreakpointName, "Specifies a breakpoint name to use."},
1978 { LLDB_OPT_SET_2, false, "breakpoint-id", 'B', OptionParser::eRequiredArgument, NULL, NULL, 0, eArgTypeBreakpointID, "Specify a breakpoint id to use."},
1979 { LLDB_OPT_SET_ALL, false, "dummy-breakpoints", 'D', OptionParser::eNoArgument, NULL, NULL, 0, eArgTypeNone,
1980 "Operate on Dummy breakpoints - i.e. breakpoints set before a file is provided, which prime new targets."},
1981};
1982class BreakpointNameOptionGroup : public OptionGroup
1983{
1984public:
1985 BreakpointNameOptionGroup() :
1986 OptionGroup(),
1987 m_breakpoint(LLDB_INVALID_BREAK_ID),
1988 m_use_dummy (false)
1989 {
1990
1991 }
1992
1993 virtual
1994 ~BreakpointNameOptionGroup ()
1995 {
1996 }
1997
1998 virtual uint32_t
1999 GetNumDefinitions ()
2000 {
2001 return sizeof (g_breakpoint_name_options) / sizeof (OptionDefinition);
2002 }
2003
2004 virtual const OptionDefinition*
2005 GetDefinitions ()
2006 {
2007 return g_breakpoint_name_options;
2008 }
2009
2010 virtual Error
2011 SetOptionValue (CommandInterpreter &interpreter,
2012 uint32_t option_idx,
2013 const char *option_value)
2014 {
2015 Error error;
2016 const int short_option = g_breakpoint_name_options[option_idx].short_option;
2017
2018 switch (short_option)
2019 {
2020 case 'N':
2021 if (BreakpointID::StringIsBreakpointName(option_value, error) && error.Success())
Pavel Labathc95f7e22015-02-20 11:14:59 +00002022 m_name.SetValueFromString(option_value);
Jim Ingham5e09c8c2014-12-16 23:40:14 +00002023 break;
2024
2025 case 'B':
Pavel Labathc95f7e22015-02-20 11:14:59 +00002026 if (m_breakpoint.SetValueFromString(option_value).Fail())
Jim Ingham5e09c8c2014-12-16 23:40:14 +00002027 error.SetErrorStringWithFormat ("unrecognized value \"%s\" for breakpoint", option_value);
2028 break;
2029 case 'D':
Pavel Labathc95f7e22015-02-20 11:14:59 +00002030 if (m_use_dummy.SetValueFromString(option_value).Fail())
Jim Ingham5e09c8c2014-12-16 23:40:14 +00002031 error.SetErrorStringWithFormat ("unrecognized value \"%s\" for use-dummy", option_value);
2032 break;
2033
2034 default:
2035 error.SetErrorStringWithFormat("unrecognized short option '%c'", short_option);
2036 break;
2037 }
2038 return error;
2039 }
2040
2041 virtual void
2042 OptionParsingStarting (CommandInterpreter &interpreter)
2043 {
2044 m_name.Clear();
2045 m_breakpoint.Clear();
2046 m_use_dummy.Clear();
2047 m_use_dummy.SetDefaultValue(false);
2048 }
2049
2050 OptionValueString m_name;
2051 OptionValueUInt64 m_breakpoint;
2052 OptionValueBoolean m_use_dummy;
2053};
2054
2055
2056class CommandObjectBreakpointNameAdd : public CommandObjectParsed
2057{
2058public:
2059 CommandObjectBreakpointNameAdd (CommandInterpreter &interpreter) :
2060 CommandObjectParsed (interpreter,
2061 "add",
2062 "Add a name to the breakpoints provided.",
2063 "breakpoint name add <command-options> <breakpoint-id-list>"),
2064 m_name_options(),
2065 m_option_group(interpreter)
2066 {
2067 // Create the first variant for the first (and only) argument for this command.
2068 CommandArgumentEntry arg1;
2069 CommandArgumentData id_arg;
2070 id_arg.arg_type = eArgTypeBreakpointID;
2071 id_arg.arg_repetition = eArgRepeatOptional;
2072 arg1.push_back(id_arg);
2073 m_arguments.push_back (arg1);
2074
2075 m_option_group.Append (&m_name_options, LLDB_OPT_SET_1, LLDB_OPT_SET_ALL);
2076 m_option_group.Finalize();
2077 }
2078
2079 virtual
2080 ~CommandObjectBreakpointNameAdd () {}
2081
2082 Options *
2083 GetOptions ()
2084 {
2085 return &m_option_group;
2086 }
2087
2088protected:
2089 virtual bool
2090 DoExecute (Args& command, CommandReturnObject &result)
2091 {
2092 if (!m_name_options.m_name.OptionWasSet())
2093 {
2094 result.SetError("No name option provided.");
2095 return false;
2096 }
2097
2098 Target *target = GetSelectedOrDummyTarget(m_name_options.m_use_dummy.GetCurrentValue());
2099
2100 if (target == NULL)
2101 {
2102 result.AppendError ("Invalid target. No existing target or breakpoints.");
2103 result.SetStatus (eReturnStatusFailed);
2104 return false;
2105 }
2106
2107 Mutex::Locker locker;
2108 target->GetBreakpointList().GetListMutex(locker);
2109
2110 const BreakpointList &breakpoints = target->GetBreakpointList();
2111
2112 size_t num_breakpoints = breakpoints.GetSize();
2113 if (num_breakpoints == 0)
2114 {
2115 result.SetError("No breakpoints, cannot add names.");
2116 result.SetStatus (eReturnStatusFailed);
2117 return false;
2118 }
2119
2120 // Particular breakpoint selected; disable that breakpoint.
2121 BreakpointIDList valid_bp_ids;
2122 CommandObjectMultiwordBreakpoint::VerifyBreakpointIDs (command, target, result, &valid_bp_ids);
2123
2124 if (result.Succeeded())
2125 {
2126 if (valid_bp_ids.GetSize() == 0)
2127 {
2128 result.SetError("No breakpoints specified, cannot add names.");
2129 result.SetStatus (eReturnStatusFailed);
2130 return false;
2131 }
2132 size_t num_valid_ids = valid_bp_ids.GetSize();
2133 for (size_t index = 0; index < num_valid_ids; index++)
2134 {
2135 lldb::break_id_t bp_id = valid_bp_ids.GetBreakpointIDAtIndex(index).GetBreakpointID();
2136 BreakpointSP bp_sp = breakpoints.FindBreakpointByID(bp_id);
2137 Error error; // We don't need to check the error here, since the option parser checked it...
2138 bp_sp->AddName(m_name_options.m_name.GetCurrentValue(), error);
2139 }
2140 }
2141
2142 return true;
2143 }
2144
2145private:
2146 BreakpointNameOptionGroup m_name_options;
2147 OptionGroupOptions m_option_group;
2148};
2149
2150
2151
2152class CommandObjectBreakpointNameDelete : public CommandObjectParsed
2153{
2154public:
2155 CommandObjectBreakpointNameDelete (CommandInterpreter &interpreter) :
2156 CommandObjectParsed (interpreter,
2157 "delete",
2158 "Delete a name from the breakpoints provided.",
2159 "breakpoint name delete <command-options> <breakpoint-id-list>"),
2160 m_name_options(),
2161 m_option_group(interpreter)
2162 {
2163 // Create the first variant for the first (and only) argument for this command.
2164 CommandArgumentEntry arg1;
2165 CommandArgumentData id_arg;
2166 id_arg.arg_type = eArgTypeBreakpointID;
2167 id_arg.arg_repetition = eArgRepeatOptional;
2168 arg1.push_back(id_arg);
2169 m_arguments.push_back (arg1);
2170
2171 m_option_group.Append (&m_name_options, LLDB_OPT_SET_1, LLDB_OPT_SET_ALL);
2172 m_option_group.Finalize();
2173 }
2174
2175 virtual
2176 ~CommandObjectBreakpointNameDelete () {}
2177
2178 Options *
2179 GetOptions ()
2180 {
2181 return &m_option_group;
2182 }
2183
2184protected:
2185 virtual bool
2186 DoExecute (Args& command, CommandReturnObject &result)
2187 {
2188 if (!m_name_options.m_name.OptionWasSet())
2189 {
2190 result.SetError("No name option provided.");
2191 return false;
2192 }
2193
2194 Target *target = GetSelectedOrDummyTarget(m_name_options.m_use_dummy.GetCurrentValue());
2195
2196 if (target == NULL)
2197 {
2198 result.AppendError ("Invalid target. No existing target or breakpoints.");
2199 result.SetStatus (eReturnStatusFailed);
2200 return false;
2201 }
2202
2203 Mutex::Locker locker;
2204 target->GetBreakpointList().GetListMutex(locker);
2205
2206 const BreakpointList &breakpoints = target->GetBreakpointList();
2207
2208 size_t num_breakpoints = breakpoints.GetSize();
2209 if (num_breakpoints == 0)
2210 {
2211 result.SetError("No breakpoints, cannot delete names.");
2212 result.SetStatus (eReturnStatusFailed);
2213 return false;
2214 }
2215
2216 // Particular breakpoint selected; disable that breakpoint.
2217 BreakpointIDList valid_bp_ids;
2218 CommandObjectMultiwordBreakpoint::VerifyBreakpointIDs (command, target, result, &valid_bp_ids);
2219
2220 if (result.Succeeded())
2221 {
2222 if (valid_bp_ids.GetSize() == 0)
2223 {
2224 result.SetError("No breakpoints specified, cannot delete names.");
2225 result.SetStatus (eReturnStatusFailed);
2226 return false;
2227 }
2228 size_t num_valid_ids = valid_bp_ids.GetSize();
2229 for (size_t index = 0; index < num_valid_ids; index++)
2230 {
2231 lldb::break_id_t bp_id = valid_bp_ids.GetBreakpointIDAtIndex(index).GetBreakpointID();
2232 BreakpointSP bp_sp = breakpoints.FindBreakpointByID(bp_id);
2233 bp_sp->RemoveName(m_name_options.m_name.GetCurrentValue());
2234 }
2235 }
2236
2237 return true;
2238 }
2239
2240private:
2241 BreakpointNameOptionGroup m_name_options;
2242 OptionGroupOptions m_option_group;
2243};
2244
2245class CommandObjectBreakpointNameList : public CommandObjectParsed
2246{
2247public:
2248 CommandObjectBreakpointNameList (CommandInterpreter &interpreter) :
2249 CommandObjectParsed (interpreter,
2250 "list",
2251 "List either the names for a breakpoint or the breakpoints for a given name.",
2252 "breakpoint name list <command-options>"),
2253 m_name_options(),
2254 m_option_group(interpreter)
2255 {
2256 m_option_group.Append (&m_name_options);
2257 m_option_group.Finalize();
2258 }
2259
2260 virtual
2261 ~CommandObjectBreakpointNameList () {}
2262
2263 Options *
2264 GetOptions ()
2265 {
2266 return &m_option_group;
2267 }
2268
2269protected:
Jim Ingham5e09c8c2014-12-16 23:40:14 +00002270 virtual bool
2271 DoExecute (Args& command, CommandReturnObject &result)
2272 {
2273 Target *target = GetSelectedOrDummyTarget(m_name_options.m_use_dummy.GetCurrentValue());
2274
2275 if (target == NULL)
2276 {
2277 result.AppendError ("Invalid target. No existing target or breakpoints.");
2278 result.SetStatus (eReturnStatusFailed);
2279 return false;
2280 }
2281
2282 if (m_name_options.m_name.OptionWasSet())
2283 {
2284 const char *name = m_name_options.m_name.GetCurrentValue();
2285 Mutex::Locker locker;
2286 target->GetBreakpointList().GetListMutex(locker);
2287
2288 BreakpointList &breakpoints = target->GetBreakpointList();
2289 for (BreakpointSP bp_sp : breakpoints.Breakpoints())
2290 {
2291 if (bp_sp->MatchesName(name))
2292 {
2293 StreamString s;
2294 bp_sp->GetDescription(&s, eDescriptionLevelBrief);
2295 s.EOL();
2296 result.AppendMessage(s.GetData());
2297 }
2298 }
2299
2300 }
2301 else if (m_name_options.m_breakpoint.OptionWasSet())
2302 {
2303 BreakpointSP bp_sp = target->GetBreakpointList().FindBreakpointByID(m_name_options.m_breakpoint.GetCurrentValue());
2304 if (bp_sp)
2305 {
2306 std::vector<std::string> names;
2307 bp_sp->GetNames (names);
2308 result.AppendMessage ("Names:");
2309 for (auto name : names)
2310 result.AppendMessageWithFormat (" %s\n", name.c_str());
2311 }
2312 else
2313 {
2314 result.AppendErrorWithFormat ("Could not find breakpoint %" PRId64 ".\n",
2315 m_name_options.m_breakpoint.GetCurrentValue());
2316 result.SetStatus (eReturnStatusFailed);
2317 return false;
2318 }
2319 }
2320 else
2321 {
2322 result.SetError ("Must specify -N or -B option to list.");
2323 result.SetStatus (eReturnStatusFailed);
2324 return false;
2325 }
2326 return true;
2327 }
2328
2329private:
2330 BreakpointNameOptionGroup m_name_options;
2331 OptionGroupOptions m_option_group;
2332};
2333
2334//-------------------------------------------------------------------------
2335// CommandObjectMultiwordBreakpoint
2336//-------------------------------------------------------------------------
2337class CommandObjectBreakpointName : public CommandObjectMultiword
2338{
2339public:
2340 CommandObjectBreakpointName (CommandInterpreter &interpreter) :
2341 CommandObjectMultiword(interpreter,
2342 "name",
2343 "A set of commands to manage name tags for breakpoints",
2344 "breakpoint name <command> [<command-options>]")
2345 {
2346 CommandObjectSP add_command_object (new CommandObjectBreakpointNameAdd (interpreter));
2347 CommandObjectSP delete_command_object (new CommandObjectBreakpointNameDelete (interpreter));
2348 CommandObjectSP list_command_object (new CommandObjectBreakpointNameList (interpreter));
2349
2350 LoadSubCommand ("add", add_command_object);
2351 LoadSubCommand ("delete", delete_command_object);
2352 LoadSubCommand ("list", list_command_object);
2353
2354 }
2355
2356 virtual
2357 ~CommandObjectBreakpointName ()
2358 {
2359 }
2360
2361};
2362
2363
2364//-------------------------------------------------------------------------
Chris Lattner30fdc8d2010-06-08 16:52:24 +00002365// CommandObjectMultiwordBreakpoint
2366//-------------------------------------------------------------------------
Jim Inghamae1c4cf2010-06-18 00:58:52 +00002367#pragma mark MultiwordBreakpoint
Chris Lattner30fdc8d2010-06-08 16:52:24 +00002368
Greg Clayton66111032010-06-23 01:19:29 +00002369CommandObjectMultiwordBreakpoint::CommandObjectMultiwordBreakpoint (CommandInterpreter &interpreter) :
Greg Claytona7015092010-09-18 01:14:36 +00002370 CommandObjectMultiword (interpreter,
2371 "breakpoint",
Jim Ingham46fbc602011-05-26 20:39:01 +00002372 "A set of commands for operating on breakpoints. Also see _regexp-break.",
Greg Claytona7015092010-09-18 01:14:36 +00002373 "breakpoint <command> [<command-options>]")
Chris Lattner30fdc8d2010-06-08 16:52:24 +00002374{
Greg Claytona7015092010-09-18 01:14:36 +00002375 CommandObjectSP list_command_object (new CommandObjectBreakpointList (interpreter));
Greg Claytona7015092010-09-18 01:14:36 +00002376 CommandObjectSP enable_command_object (new CommandObjectBreakpointEnable (interpreter));
2377 CommandObjectSP disable_command_object (new CommandObjectBreakpointDisable (interpreter));
Johnny Chenb7234e42010-10-28 17:27:46 +00002378 CommandObjectSP clear_command_object (new CommandObjectBreakpointClear (interpreter));
2379 CommandObjectSP delete_command_object (new CommandObjectBreakpointDelete (interpreter));
Greg Claytona7015092010-09-18 01:14:36 +00002380 CommandObjectSP set_command_object (new CommandObjectBreakpointSet (interpreter));
Chris Lattner30fdc8d2010-06-08 16:52:24 +00002381 CommandObjectSP command_command_object (new CommandObjectBreakpointCommand (interpreter));
Greg Claytona7015092010-09-18 01:14:36 +00002382 CommandObjectSP modify_command_object (new CommandObjectBreakpointModify(interpreter));
Jim Ingham5e09c8c2014-12-16 23:40:14 +00002383 CommandObjectSP name_command_object (new CommandObjectBreakpointName(interpreter));
Chris Lattner30fdc8d2010-06-08 16:52:24 +00002384
Johnny Chenb7234e42010-10-28 17:27:46 +00002385 list_command_object->SetCommandName ("breakpoint list");
Chris Lattner30fdc8d2010-06-08 16:52:24 +00002386 enable_command_object->SetCommandName("breakpoint enable");
2387 disable_command_object->SetCommandName("breakpoint disable");
Johnny Chenb7234e42010-10-28 17:27:46 +00002388 clear_command_object->SetCommandName("breakpoint clear");
2389 delete_command_object->SetCommandName("breakpoint delete");
Jim Inghamae1c4cf2010-06-18 00:58:52 +00002390 set_command_object->SetCommandName("breakpoint set");
Johnny Chenb7234e42010-10-28 17:27:46 +00002391 command_command_object->SetCommandName ("breakpoint command");
2392 modify_command_object->SetCommandName ("breakpoint modify");
Jim Ingham5e09c8c2014-12-16 23:40:14 +00002393 name_command_object->SetCommandName ("breakpoint name");
Chris Lattner30fdc8d2010-06-08 16:52:24 +00002394
Greg Clayton23f59502012-07-17 03:23:13 +00002395 LoadSubCommand ("list", list_command_object);
2396 LoadSubCommand ("enable", enable_command_object);
2397 LoadSubCommand ("disable", disable_command_object);
2398 LoadSubCommand ("clear", clear_command_object);
2399 LoadSubCommand ("delete", delete_command_object);
2400 LoadSubCommand ("set", set_command_object);
2401 LoadSubCommand ("command", command_command_object);
2402 LoadSubCommand ("modify", modify_command_object);
Jim Ingham5e09c8c2014-12-16 23:40:14 +00002403 LoadSubCommand ("name", name_command_object);
Chris Lattner30fdc8d2010-06-08 16:52:24 +00002404}
2405
2406CommandObjectMultiwordBreakpoint::~CommandObjectMultiwordBreakpoint ()
2407{
2408}
2409
2410void
Jim Ingham5e09c8c2014-12-16 23:40:14 +00002411CommandObjectMultiwordBreakpoint::VerifyIDs (Args &args,
2412 Target *target,
2413 bool allow_locations,
2414 CommandReturnObject &result,
2415 BreakpointIDList *valid_ids)
Chris Lattner30fdc8d2010-06-08 16:52:24 +00002416{
2417 // args can be strings representing 1). integers (for breakpoint ids)
2418 // 2). the full breakpoint & location canonical representation
2419 // 3). the word "to" or a hyphen, representing a range (in which case there
2420 // had *better* be an entry both before & after of one of the first two types.
Jim Ingham5e09c8c2014-12-16 23:40:14 +00002421 // 4). A breakpoint name
Jim Ingham36f3b362010-10-14 23:45:03 +00002422 // If args is empty, we will use the last created breakpoint (if there is one.)
Chris Lattner30fdc8d2010-06-08 16:52:24 +00002423
2424 Args temp_args;
2425
Jim Ingham36f3b362010-10-14 23:45:03 +00002426 if (args.GetArgumentCount() == 0)
2427 {
Greg Clayton4d122c42011-09-17 08:33:22 +00002428 if (target->GetLastCreatedBreakpoint())
Jim Ingham36f3b362010-10-14 23:45:03 +00002429 {
2430 valid_ids->AddBreakpointID (BreakpointID(target->GetLastCreatedBreakpoint()->GetID(), LLDB_INVALID_BREAK_ID));
2431 result.SetStatus (eReturnStatusSuccessFinishNoResult);
2432 }
2433 else
2434 {
2435 result.AppendError("No breakpoint specified and no last created breakpoint.");
2436 result.SetStatus (eReturnStatusFailed);
2437 }
2438 return;
2439 }
2440
Chris Lattner30fdc8d2010-06-08 16:52:24 +00002441 // Create a new Args variable to use; copy any non-breakpoint-id-ranges stuff directly from the old ARGS to
2442 // the new TEMP_ARGS. Do not copy breakpoint id range strings over; instead generate a list of strings for
2443 // all the breakpoint ids in the range, and shove all of those breakpoint id strings into TEMP_ARGS.
2444
Jim Ingham5e09c8c2014-12-16 23:40:14 +00002445 BreakpointIDList::FindAndReplaceIDRanges (args, target, allow_locations, result, temp_args);
Chris Lattner30fdc8d2010-06-08 16:52:24 +00002446
2447 // NOW, convert the list of breakpoint id strings in TEMP_ARGS into an actual BreakpointIDList:
2448
Greg Claytonc982c762010-07-09 20:39:50 +00002449 valid_ids->InsertStringArray (temp_args.GetConstArgumentVector(), temp_args.GetArgumentCount(), result);
Chris Lattner30fdc8d2010-06-08 16:52:24 +00002450
2451 // At this point, all of the breakpoint ids that the user passed in have been converted to breakpoint IDs
2452 // and put into valid_ids.
2453
2454 if (result.Succeeded())
2455 {
2456 // Now that we've converted everything from args into a list of breakpoint ids, go through our tentative list
2457 // of breakpoint id's and verify that they correspond to valid/currently set breakpoints.
2458
Greg Claytonc982c762010-07-09 20:39:50 +00002459 const size_t count = valid_ids->GetSize();
2460 for (size_t i = 0; i < count; ++i)
Chris Lattner30fdc8d2010-06-08 16:52:24 +00002461 {
2462 BreakpointID cur_bp_id = valid_ids->GetBreakpointIDAtIndex (i);
2463 Breakpoint *breakpoint = target->GetBreakpointByID (cur_bp_id.GetBreakpointID()).get();
2464 if (breakpoint != NULL)
2465 {
Greg Claytonc7bece562013-01-25 18:06:21 +00002466 const size_t num_locations = breakpoint->GetNumLocations();
Saleem Abdulrasool3985c8c2014-04-02 03:51:35 +00002467 if (static_cast<size_t>(cur_bp_id.GetLocationID()) > num_locations)
Chris Lattner30fdc8d2010-06-08 16:52:24 +00002468 {
2469 StreamString id_str;
Greg Claytonc982c762010-07-09 20:39:50 +00002470 BreakpointID::GetCanonicalReference (&id_str,
2471 cur_bp_id.GetBreakpointID(),
2472 cur_bp_id.GetLocationID());
2473 i = valid_ids->GetSize() + 1;
Chris Lattner30fdc8d2010-06-08 16:52:24 +00002474 result.AppendErrorWithFormat ("'%s' is not a currently valid breakpoint/location id.\n",
2475 id_str.GetData());
2476 result.SetStatus (eReturnStatusFailed);
2477 }
2478 }
2479 else
2480 {
Greg Claytonc982c762010-07-09 20:39:50 +00002481 i = valid_ids->GetSize() + 1;
Chris Lattner30fdc8d2010-06-08 16:52:24 +00002482 result.AppendErrorWithFormat ("'%d' is not a currently valid breakpoint id.\n", cur_bp_id.GetBreakpointID());
2483 result.SetStatus (eReturnStatusFailed);
2484 }
2485 }
2486 }
2487}