blob: e36809f485fe896dc5d3efa083c8b30e2997252c [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
Daniel Malea93a64302012-12-05 00:20:57 +000010#include "lldb/lldb-python.h"
11
Chris Lattner30fdc8d2010-06-08 16:52:24 +000012#include "CommandObjectBreakpoint.h"
13#include "CommandObjectBreakpointCommand.h"
14
15// C Includes
16// C++ Includes
17// Other libraries and framework includes
18// Project includes
19#include "lldb/Breakpoint/Breakpoint.h"
20#include "lldb/Breakpoint/BreakpointIDList.h"
21#include "lldb/Breakpoint/BreakpointLocation.h"
Vince Harron5275aaa2015-01-15 20:08:35 +000022#include "lldb/Host/StringConvert.h"
Jim Ingham40af72e2010-06-15 19:49:27 +000023#include "lldb/Interpreter/Options.h"
Jim Ingham5e09c8c2014-12-16 23:40:14 +000024#include "lldb/Interpreter/OptionValueString.h"
25#include "lldb/Interpreter/OptionValueUInt64.h"
Chris Lattner30fdc8d2010-06-08 16:52:24 +000026#include "lldb/Core/RegularExpression.h"
27#include "lldb/Core/StreamString.h"
28#include "lldb/Interpreter/CommandInterpreter.h"
29#include "lldb/Interpreter/CommandReturnObject.h"
30#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 Ingham5a988412012-06-08 21:56:10 +0000113 m_language (eLanguageTypeUnknown),
Jim Inghamca36cd12012-10-05 19:16:31 +0000114 m_skip_prologue (eLazyBoolCalculate),
Jim Inghame7320522015-02-12 17:37:46 +0000115 m_one_shot (false),
116 m_all_files (false)
Jim Ingham5a988412012-06-08 21:56:10 +0000117 {
118 }
119
120
121 virtual
122 ~CommandOptions () {}
123
124 virtual Error
125 SetOptionValue (uint32_t option_idx, const char *option_arg)
126 {
127 Error error;
Greg Clayton3bcdfc02012-12-04 00:32:51 +0000128 const int short_option = m_getopt_table[option_idx].val;
Jim Ingham5a988412012-06-08 21:56:10 +0000129
130 switch (short_option)
131 {
132 case 'a':
Greg Claytonb9d5df52012-12-06 22:49:16 +0000133 {
134 ExecutionContext exe_ctx (m_interpreter.GetExecutionContext());
135 m_load_addr = Args::StringToAddress(&exe_ctx, option_arg, LLDB_INVALID_ADDRESS, &error);
136 }
Jim Ingham5a988412012-06-08 21:56:10 +0000137 break;
138
Jim Inghame7320522015-02-12 17:37:46 +0000139 case 'A':
140 m_all_files = true;
141 break;
142
Jim Inghamca36cd12012-10-05 19:16:31 +0000143 case 'b':
144 m_func_names.push_back (option_arg);
145 m_func_name_type_mask |= eFunctionNameTypeBase;
146 break;
147
Jim Ingham5a988412012-06-08 21:56:10 +0000148 case 'C':
Vince Harron5275aaa2015-01-15 20:08:35 +0000149 m_column = StringConvert::ToUInt32 (option_arg, 0);
Jim Ingham5a988412012-06-08 21:56:10 +0000150 break;
151
152 case 'c':
153 m_condition.assign(option_arg);
154 break;
155
Jim Ingham33df7cd2014-12-06 01:28:03 +0000156 case 'D':
157 m_use_dummy = true;
158 break;
159
Jim Ingham5a988412012-06-08 21:56:10 +0000160 case 'E':
161 {
162 LanguageType language = LanguageRuntime::GetLanguageTypeFromString (option_arg);
163
164 switch (language)
165 {
166 case eLanguageTypeC89:
167 case eLanguageTypeC:
168 case eLanguageTypeC99:
Bruce Mitchener1d0089f2014-07-03 00:49:08 +0000169 case eLanguageTypeC11:
Jim Ingham5a988412012-06-08 21:56:10 +0000170 m_language = eLanguageTypeC;
171 break;
172 case eLanguageTypeC_plus_plus:
Bruce Mitchener1d0089f2014-07-03 00:49:08 +0000173 case eLanguageTypeC_plus_plus_03:
174 case eLanguageTypeC_plus_plus_11:
Bruce Mitchener2ba84a62015-02-06 06:46:52 +0000175 case eLanguageTypeC_plus_plus_14:
Jim Ingham5a988412012-06-08 21:56:10 +0000176 m_language = eLanguageTypeC_plus_plus;
177 break;
178 case eLanguageTypeObjC:
179 m_language = eLanguageTypeObjC;
180 break;
181 case eLanguageTypeObjC_plus_plus:
182 error.SetErrorStringWithFormat ("Set exception breakpoints separately for c++ and objective-c");
183 break;
184 case eLanguageTypeUnknown:
185 error.SetErrorStringWithFormat ("Unknown language type: '%s' for exception breakpoint", option_arg);
186 break;
187 default:
188 error.SetErrorStringWithFormat ("Unsupported language type: '%s' for exception breakpoint", option_arg);
189 }
190 }
191 break;
Jim Inghamca36cd12012-10-05 19:16:31 +0000192
193 case 'f':
194 m_filenames.AppendIfUnique (FileSpec(option_arg, false));
195 break;
196
197 case 'F':
198 m_func_names.push_back (option_arg);
199 m_func_name_type_mask |= eFunctionNameTypeFull;
200 break;
201
Jim Ingham5a988412012-06-08 21:56:10 +0000202 case 'h':
Greg Claytoneb023e72013-10-11 19:48:25 +0000203 {
204 bool success;
205 m_catch_bp = Args::StringToBoolean (option_arg, true, &success);
206 if (!success)
207 error.SetErrorStringWithFormat ("Invalid boolean value for on-catch option: '%s'", option_arg);
208 }
209 break;
210
211 case 'H':
212 m_hardware = true;
213 break;
214
Jim Inghamca36cd12012-10-05 19:16:31 +0000215 case 'i':
216 {
Vince Harron5275aaa2015-01-15 20:08:35 +0000217 m_ignore_count = StringConvert::ToUInt32(option_arg, UINT32_MAX, 0);
Jim Inghamca36cd12012-10-05 19:16:31 +0000218 if (m_ignore_count == UINT32_MAX)
219 error.SetErrorStringWithFormat ("invalid ignore count '%s'", option_arg);
220 break;
221 }
222
Jim Ingham5a988412012-06-08 21:56:10 +0000223 case 'K':
224 {
225 bool success;
226 bool value;
227 value = Args::StringToBoolean (option_arg, true, &success);
228 if (value)
229 m_skip_prologue = eLazyBoolYes;
230 else
231 m_skip_prologue = eLazyBoolNo;
232
233 if (!success)
234 error.SetErrorStringWithFormat ("Invalid boolean value for skip prologue option: '%s'", option_arg);
235 }
236 break;
Jim Inghamca36cd12012-10-05 19:16:31 +0000237
238 case 'l':
Vince Harron5275aaa2015-01-15 20:08:35 +0000239 m_line_num = StringConvert::ToUInt32 (option_arg, 0);
Jim Inghamca36cd12012-10-05 19:16:31 +0000240 break;
241
242 case 'M':
243 m_func_names.push_back (option_arg);
244 m_func_name_type_mask |= eFunctionNameTypeMethod;
245 break;
246
247 case 'n':
248 m_func_names.push_back (option_arg);
249 m_func_name_type_mask |= eFunctionNameTypeAuto;
250 break;
251
Jim Ingham5e09c8c2014-12-16 23:40:14 +0000252 case 'N':
253 if (BreakpointID::StringIsBreakpointName(option_arg, error))
254 m_breakpoint_names.push_back (option_arg);
Jim Ingham5e09c8c2014-12-16 23:40:14 +0000255 break;
256
Jim Inghamca36cd12012-10-05 19:16:31 +0000257 case 'o':
258 m_one_shot = true;
259 break;
260
261 case 'p':
262 m_source_text_regexp.assign (option_arg);
263 break;
264
265 case 'q':
266 m_queue_name.assign (option_arg);
267 break;
268
269 case 'r':
270 m_func_regexp.assign (option_arg);
271 break;
272
273 case 's':
274 {
275 m_modules.AppendIfUnique (FileSpec (option_arg, false));
276 break;
277 }
278
279 case 'S':
280 m_func_names.push_back (option_arg);
281 m_func_name_type_mask |= eFunctionNameTypeSelector;
282 break;
283
284 case 't' :
285 {
Vince Harron5275aaa2015-01-15 20:08:35 +0000286 m_thread_id = StringConvert::ToUInt64(option_arg, LLDB_INVALID_THREAD_ID, 0);
Jim Inghamca36cd12012-10-05 19:16:31 +0000287 if (m_thread_id == LLDB_INVALID_THREAD_ID)
288 error.SetErrorStringWithFormat ("invalid thread id string '%s'", option_arg);
289 }
290 break;
291
292 case 'T':
293 m_thread_name.assign (option_arg);
294 break;
295
296 case 'w':
297 {
298 bool success;
299 m_throw_bp = Args::StringToBoolean (option_arg, true, &success);
300 if (!success)
301 error.SetErrorStringWithFormat ("Invalid boolean value for on-throw option: '%s'", option_arg);
302 }
303 break;
304
305 case 'x':
306 {
Vince Harron5275aaa2015-01-15 20:08:35 +0000307 m_thread_index = StringConvert::ToUInt32(option_arg, UINT32_MAX, 0);
Jim Inghamca36cd12012-10-05 19:16:31 +0000308 if (m_thread_id == UINT32_MAX)
309 error.SetErrorStringWithFormat ("invalid thread index string '%s'", option_arg);
310
311 }
312 break;
313
Jim Ingham5a988412012-06-08 21:56:10 +0000314 default:
315 error.SetErrorStringWithFormat ("unrecognized option '%c'", short_option);
316 break;
317 }
318
319 return error;
320 }
321 void
322 OptionParsingStarting ()
323 {
324 m_condition.clear();
325 m_filenames.Clear();
326 m_line_num = 0;
327 m_column = 0;
328 m_func_names.clear();
Greg Clayton1f746072012-08-29 21:13:06 +0000329 m_func_name_type_mask = eFunctionNameTypeNone;
Jim Ingham5a988412012-06-08 21:56:10 +0000330 m_func_regexp.clear();
Greg Clayton1f746072012-08-29 21:13:06 +0000331 m_source_text_regexp.clear();
Jim Ingham5a988412012-06-08 21:56:10 +0000332 m_modules.Clear();
Greg Clayton1f746072012-08-29 21:13:06 +0000333 m_load_addr = LLDB_INVALID_ADDRESS;
Jim Ingham5a988412012-06-08 21:56:10 +0000334 m_ignore_count = 0;
335 m_thread_id = LLDB_INVALID_THREAD_ID;
336 m_thread_index = UINT32_MAX;
337 m_thread_name.clear();
338 m_queue_name.clear();
Jim Ingham5a988412012-06-08 21:56:10 +0000339 m_catch_bp = false;
340 m_throw_bp = true;
Greg Claytoneb023e72013-10-11 19:48:25 +0000341 m_hardware = false;
Greg Clayton1f746072012-08-29 21:13:06 +0000342 m_language = eLanguageTypeUnknown;
Jim Ingham5a988412012-06-08 21:56:10 +0000343 m_skip_prologue = eLazyBoolCalculate;
Jim Inghamca36cd12012-10-05 19:16:31 +0000344 m_one_shot = false;
Jim Ingham33df7cd2014-12-06 01:28:03 +0000345 m_use_dummy = false;
Jim Ingham5e09c8c2014-12-16 23:40:14 +0000346 m_breakpoint_names.clear();
Jim Inghame7320522015-02-12 17:37:46 +0000347 m_all_files = false;
Jim Ingham5a988412012-06-08 21:56:10 +0000348 }
349
350 const OptionDefinition*
351 GetDefinitions ()
352 {
353 return g_option_table;
354 }
355
356 // Options table: Required for subclasses of Options.
357
358 static OptionDefinition g_option_table[];
359
360 // Instance variables to hold the values for command options.
361
362 std::string m_condition;
363 FileSpecList m_filenames;
364 uint32_t m_line_num;
365 uint32_t m_column;
Jim Ingham5a988412012-06-08 21:56:10 +0000366 std::vector<std::string> m_func_names;
Jim Ingham5e09c8c2014-12-16 23:40:14 +0000367 std::vector<std::string> m_breakpoint_names;
Jim Ingham5a988412012-06-08 21:56:10 +0000368 uint32_t m_func_name_type_mask;
369 std::string m_func_regexp;
370 std::string m_source_text_regexp;
371 FileSpecList m_modules;
372 lldb::addr_t m_load_addr;
373 uint32_t m_ignore_count;
374 lldb::tid_t m_thread_id;
375 uint32_t m_thread_index;
376 std::string m_thread_name;
377 std::string m_queue_name;
378 bool m_catch_bp;
379 bool m_throw_bp;
Greg Claytoneb023e72013-10-11 19:48:25 +0000380 bool m_hardware; // Request to use hardware breakpoints
Jim Ingham5a988412012-06-08 21:56:10 +0000381 lldb::LanguageType m_language;
382 LazyBool m_skip_prologue;
Jim Inghamca36cd12012-10-05 19:16:31 +0000383 bool m_one_shot;
Jim Ingham33df7cd2014-12-06 01:28:03 +0000384 bool m_use_dummy;
Jim Inghame7320522015-02-12 17:37:46 +0000385 bool m_all_files;
Jim Ingham5a988412012-06-08 21:56:10 +0000386
387 };
388
389protected:
390 virtual bool
391 DoExecute (Args& command,
Jim Ingham33df7cd2014-12-06 01:28:03 +0000392 CommandReturnObject &result)
Jim Ingham5a988412012-06-08 21:56:10 +0000393 {
Jim Ingham33df7cd2014-12-06 01:28:03 +0000394 Target *target = GetSelectedOrDummyTarget(m_options.m_use_dummy);
395
Jim Ingham893c9322014-11-22 01:42:44 +0000396 if (target == nullptr)
Jim Ingham5a988412012-06-08 21:56:10 +0000397 {
398 result.AppendError ("Invalid target. Must set target before setting breakpoints (see 'target create' command).");
399 result.SetStatus (eReturnStatusFailed);
400 return false;
401 }
402
403 // The following are the various types of breakpoints that could be set:
404 // 1). -f -l -p [-s -g] (setting breakpoint by source location)
405 // 2). -a [-s -g] (setting breakpoint by address)
406 // 3). -n [-s -g] (setting breakpoint by function name)
407 // 4). -r [-s -g] (setting breakpoint by function name regular expression)
408 // 5). -p -f (setting a breakpoint by comparing a reg-exp to source text)
409 // 6). -E [-w -h] (setting a breakpoint for exceptions for a given language.)
410
411 BreakpointSetType break_type = eSetTypeInvalid;
412
413 if (m_options.m_line_num != 0)
414 break_type = eSetTypeFileAndLine;
415 else if (m_options.m_load_addr != LLDB_INVALID_ADDRESS)
416 break_type = eSetTypeAddress;
417 else if (!m_options.m_func_names.empty())
418 break_type = eSetTypeFunctionName;
419 else if (!m_options.m_func_regexp.empty())
420 break_type = eSetTypeFunctionRegexp;
421 else if (!m_options.m_source_text_regexp.empty())
422 break_type = eSetTypeSourceRegexp;
423 else if (m_options.m_language != eLanguageTypeUnknown)
424 break_type = eSetTypeException;
425
426 Breakpoint *bp = NULL;
427 FileSpec module_spec;
Jim Ingham5a988412012-06-08 21:56:10 +0000428 const bool internal = false;
429
Jim Ingham5a988412012-06-08 21:56:10 +0000430 switch (break_type)
431 {
432 case eSetTypeFileAndLine: // Breakpoint by source position
433 {
434 FileSpec file;
Greg Claytonc7bece562013-01-25 18:06:21 +0000435 const size_t num_files = m_options.m_filenames.GetSize();
Jim Ingham5a988412012-06-08 21:56:10 +0000436 if (num_files == 0)
437 {
438 if (!GetDefaultFile (target, file, result))
439 {
440 result.AppendError("No file supplied and no default file available.");
441 result.SetStatus (eReturnStatusFailed);
442 return false;
443 }
444 }
445 else if (num_files > 1)
446 {
447 result.AppendError("Only one file at a time is allowed for file and line breakpoints.");
448 result.SetStatus (eReturnStatusFailed);
449 return false;
450 }
451 else
452 file = m_options.m_filenames.GetFileSpecAtIndex(0);
Greg Clayton1f746072012-08-29 21:13:06 +0000453
454 // Only check for inline functions if
455 LazyBool check_inlines = eLazyBoolCalculate;
456
Jim Ingham5a988412012-06-08 21:56:10 +0000457 bp = target->CreateBreakpoint (&(m_options.m_modules),
458 file,
459 m_options.m_line_num,
Greg Clayton1f746072012-08-29 21:13:06 +0000460 check_inlines,
Jim Ingham5a988412012-06-08 21:56:10 +0000461 m_options.m_skip_prologue,
Greg Claytoneb023e72013-10-11 19:48:25 +0000462 internal,
463 m_options.m_hardware).get();
Jim Ingham5a988412012-06-08 21:56:10 +0000464 }
465 break;
466
467 case eSetTypeAddress: // Breakpoint by address
Greg Claytoneb023e72013-10-11 19:48:25 +0000468 bp = target->CreateBreakpoint (m_options.m_load_addr,
469 internal,
470 m_options.m_hardware).get();
Jim Ingham5a988412012-06-08 21:56:10 +0000471 break;
472
473 case eSetTypeFunctionName: // Breakpoint by function name
474 {
475 uint32_t name_type_mask = m_options.m_func_name_type_mask;
476
477 if (name_type_mask == 0)
478 name_type_mask = eFunctionNameTypeAuto;
479
480 bp = target->CreateBreakpoint (&(m_options.m_modules),
481 &(m_options.m_filenames),
482 m_options.m_func_names,
483 name_type_mask,
484 m_options.m_skip_prologue,
Greg Claytoneb023e72013-10-11 19:48:25 +0000485 internal,
486 m_options.m_hardware).get();
Jim Ingham5a988412012-06-08 21:56:10 +0000487 }
488 break;
489
490 case eSetTypeFunctionRegexp: // Breakpoint by regular expression function name
491 {
492 RegularExpression regexp(m_options.m_func_regexp.c_str());
493 if (!regexp.IsValid())
494 {
495 char err_str[1024];
496 regexp.GetErrorAsCString(err_str, sizeof(err_str));
497 result.AppendErrorWithFormat("Function name regular expression could not be compiled: \"%s\"",
498 err_str);
499 result.SetStatus (eReturnStatusFailed);
500 return false;
501 }
502
503 bp = target->CreateFuncRegexBreakpoint (&(m_options.m_modules),
504 &(m_options.m_filenames),
505 regexp,
506 m_options.m_skip_prologue,
Greg Claytoneb023e72013-10-11 19:48:25 +0000507 internal,
508 m_options.m_hardware).get();
Jim Ingham5a988412012-06-08 21:56:10 +0000509 }
510 break;
511 case eSetTypeSourceRegexp: // Breakpoint by regexp on source text.
512 {
Greg Claytonc7bece562013-01-25 18:06:21 +0000513 const size_t num_files = m_options.m_filenames.GetSize();
Jim Ingham5a988412012-06-08 21:56:10 +0000514
Jim Inghame7320522015-02-12 17:37:46 +0000515 if (num_files == 0 && !m_options.m_all_files)
Jim Ingham5a988412012-06-08 21:56:10 +0000516 {
517 FileSpec file;
518 if (!GetDefaultFile (target, file, result))
519 {
520 result.AppendError ("No files provided and could not find default file.");
521 result.SetStatus (eReturnStatusFailed);
522 return false;
523 }
524 else
525 {
526 m_options.m_filenames.Append (file);
527 }
528 }
529
530 RegularExpression regexp(m_options.m_source_text_regexp.c_str());
531 if (!regexp.IsValid())
532 {
533 char err_str[1024];
534 regexp.GetErrorAsCString(err_str, sizeof(err_str));
535 result.AppendErrorWithFormat("Source text regular expression could not be compiled: \"%s\"",
536 err_str);
537 result.SetStatus (eReturnStatusFailed);
538 return false;
539 }
Greg Claytoneb023e72013-10-11 19:48:25 +0000540 bp = target->CreateSourceRegexBreakpoint (&(m_options.m_modules),
541 &(m_options.m_filenames),
542 regexp,
543 internal,
544 m_options.m_hardware).get();
Jim Ingham5a988412012-06-08 21:56:10 +0000545 }
546 break;
547 case eSetTypeException:
548 {
Greg Claytoneb023e72013-10-11 19:48:25 +0000549 bp = target->CreateExceptionBreakpoint (m_options.m_language,
550 m_options.m_catch_bp,
551 m_options.m_throw_bp,
552 m_options.m_hardware).get();
Jim Ingham5a988412012-06-08 21:56:10 +0000553 }
554 break;
555 default:
556 break;
557 }
558
559 // Now set the various options that were passed in:
560 if (bp)
561 {
562 if (m_options.m_thread_id != LLDB_INVALID_THREAD_ID)
563 bp->SetThreadID (m_options.m_thread_id);
564
565 if (m_options.m_thread_index != UINT32_MAX)
566 bp->GetOptions()->GetThreadSpec()->SetIndex(m_options.m_thread_index);
567
568 if (!m_options.m_thread_name.empty())
569 bp->GetOptions()->GetThreadSpec()->SetName(m_options.m_thread_name.c_str());
570
571 if (!m_options.m_queue_name.empty())
572 bp->GetOptions()->GetThreadSpec()->SetQueueName(m_options.m_queue_name.c_str());
573
574 if (m_options.m_ignore_count != 0)
575 bp->GetOptions()->SetIgnoreCount(m_options.m_ignore_count);
576
577 if (!m_options.m_condition.empty())
578 bp->GetOptions()->SetCondition(m_options.m_condition.c_str());
Jim Ingham5e09c8c2014-12-16 23:40:14 +0000579
580 if (!m_options.m_breakpoint_names.empty())
581 {
582 Error error; // We don't need to check the error here, since the option parser checked it...
583 for (auto name : m_options.m_breakpoint_names)
584 bp->AddName(name.c_str(), error);
585 }
Jim Inghamca36cd12012-10-05 19:16:31 +0000586
587 bp->SetOneShot (m_options.m_one_shot);
Jim Ingham5a988412012-06-08 21:56:10 +0000588 }
589
590 if (bp)
591 {
592 Stream &output_stream = result.GetOutputStream();
Jim Ingham1391cc72012-09-22 00:04:04 +0000593 const bool show_locations = false;
594 bp->GetDescription(&output_stream, lldb::eDescriptionLevelInitial, show_locations);
Jim Ingham4aeb1982014-12-19 19:45:31 +0000595 if (target == m_interpreter.GetDebugger().GetDummyTarget())
596 output_stream.Printf ("Breakpoint set in dummy target, will get copied into future targets.\n");
597 else
598 {
599 // Don't print out this warning for exception breakpoints. They can get set before the target
600 // is set, but we won't know how to actually set the breakpoint till we run.
601 if (bp->GetNumLocations() == 0 && break_type != eSetTypeException)
602 {
603 output_stream.Printf ("WARNING: Unable to resolve breakpoint to any actual locations.\n");
604 }
605 }
Jim Ingham5a988412012-06-08 21:56:10 +0000606 result.SetStatus (eReturnStatusSuccessFinishResult);
607 }
608 else if (!bp)
609 {
610 result.AppendError ("Breakpoint creation failed: No breakpoint created.");
611 result.SetStatus (eReturnStatusFailed);
612 }
613
614 return result.Succeeded();
615 }
616
617private:
618 bool
619 GetDefaultFile (Target *target, FileSpec &file, CommandReturnObject &result)
620 {
621 uint32_t default_line;
622 // First use the Source Manager's default file.
623 // Then use the current stack frame's file.
624 if (!target->GetSourceManager().GetDefaultFileAndLine(file, default_line))
625 {
Jason Molendab57e4a12013-11-04 09:33:30 +0000626 StackFrame *cur_frame = m_exe_ctx.GetFramePtr();
Jim Ingham5a988412012-06-08 21:56:10 +0000627 if (cur_frame == NULL)
628 {
629 result.AppendError ("No selected frame to use to find the default file.");
630 result.SetStatus (eReturnStatusFailed);
631 return false;
632 }
633 else if (!cur_frame->HasDebugInformation())
634 {
635 result.AppendError ("Cannot use the selected frame to find the default file, it has no debug info.");
636 result.SetStatus (eReturnStatusFailed);
637 return false;
638 }
639 else
640 {
641 const SymbolContext &sc = cur_frame->GetSymbolContext (eSymbolContextLineEntry);
642 if (sc.line_entry.file)
643 {
644 file = sc.line_entry.file;
645 }
646 else
647 {
648 result.AppendError ("Can't find the file for the selected frame to use as the default file.");
649 result.SetStatus (eReturnStatusFailed);
650 return false;
651 }
652 }
653 }
654 return true;
655 }
656
657 CommandOptions m_options;
658};
Johnny Chen6943e7c2012-05-08 00:43:20 +0000659// If an additional option set beyond LLDB_OPTION_SET_10 is added, make sure to
660// update the numbers passed to LLDB_OPT_SET_FROM_TO(...) appropriately.
Johnny Chen4ab2e6b2012-05-07 23:23:41 +0000661#define LLDB_OPT_FILE ( LLDB_OPT_SET_FROM_TO(1, 9) & ~LLDB_OPT_SET_2 )
662#define LLDB_OPT_NOT_10 ( LLDB_OPT_SET_FROM_TO(1, 10) & ~LLDB_OPT_SET_10 )
Jim Inghama8558b62012-05-22 00:12:20 +0000663#define LLDB_OPT_SKIP_PROLOGUE ( LLDB_OPT_SET_1 | LLDB_OPT_SET_FROM_TO(3,8) )
Jim Ingham87df91b2011-09-23 00:54:11 +0000664
Greg Claytone0d378b2011-03-24 21:19:54 +0000665OptionDefinition
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000666CommandObjectBreakpointSet::CommandOptions::g_option_table[] =
667{
Zachary Turnerd37221d2014-07-09 16:31:49 +0000668 { LLDB_OPT_NOT_10, false, "shlib", 's', OptionParser::eRequiredArgument, NULL, NULL, CommandCompletions::eModuleCompletion, eArgTypeShlibName,
Jim Ingham64cc29c2012-05-03 20:30:08 +0000669 "Set the breakpoint only in this shared library. "
670 "Can repeat this option multiple times to specify multiple shared libraries."},
Jim Ingham86511212010-06-15 18:47:14 +0000671
Zachary Turnerd37221d2014-07-09 16:31:49 +0000672 { LLDB_OPT_SET_ALL, false, "ignore-count", 'i', OptionParser::eRequiredArgument, NULL, NULL, 0, eArgTypeCount,
Caroline Ticedeaab222010-10-01 19:59:14 +0000673 "Set the number of times this breakpoint is skipped before stopping." },
Jim Ingham1b54c882010-06-16 02:00:15 +0000674
Zachary Turnerd37221d2014-07-09 16:31:49 +0000675 { LLDB_OPT_SET_ALL, false, "one-shot", 'o', OptionParser::eNoArgument, NULL, NULL, 0, eArgTypeNone,
Jim Inghamb2b256a2013-04-09 18:05:22 +0000676 "The breakpoint is deleted the first time it causes a stop." },
Jim Inghamca36cd12012-10-05 19:16:31 +0000677
Zachary Turnerd37221d2014-07-09 16:31:49 +0000678 { LLDB_OPT_SET_ALL, false, "condition", 'c', OptionParser::eRequiredArgument, NULL, NULL, 0, eArgTypeExpression,
Johnny Chen7d49c9c2012-05-25 21:10:46 +0000679 "The breakpoint stops only if this condition expression evaluates to true."},
680
Zachary Turnerd37221d2014-07-09 16:31:49 +0000681 { LLDB_OPT_SET_ALL, false, "thread-index", 'x', OptionParser::eRequiredArgument, NULL, NULL, 0, eArgTypeThreadIndex,
Jim Inghama89be912013-03-26 18:29:03 +0000682 "The breakpoint stops only for the thread whose indeX matches this argument."},
Jim Ingham1b54c882010-06-16 02:00:15 +0000683
Zachary Turnerd37221d2014-07-09 16:31:49 +0000684 { LLDB_OPT_SET_ALL, false, "thread-id", 't', OptionParser::eRequiredArgument, NULL, NULL, 0, eArgTypeThreadID,
Jim Ingham1b54c882010-06-16 02:00:15 +0000685 "The breakpoint stops only for the thread whose TID matches this argument."},
686
Zachary Turnerd37221d2014-07-09 16:31:49 +0000687 { LLDB_OPT_SET_ALL, false, "thread-name", 'T', OptionParser::eRequiredArgument, NULL, NULL, 0, eArgTypeThreadName,
Jim Ingham1b54c882010-06-16 02:00:15 +0000688 "The breakpoint stops only for the thread whose thread name matches this argument."},
689
Zachary Turnerd37221d2014-07-09 16:31:49 +0000690 { LLDB_OPT_SET_ALL, false, "hardware", 'H', OptionParser::eNoArgument, NULL, NULL, 0, eArgTypeNone,
Greg Claytoneb023e72013-10-11 19:48:25 +0000691 "Require the breakpoint to use hardware breakpoints."},
692
Zachary Turnerd37221d2014-07-09 16:31:49 +0000693 { LLDB_OPT_SET_ALL, false, "queue-name", 'q', OptionParser::eRequiredArgument, NULL, NULL, 0, eArgTypeQueueName,
Jim Ingham1b54c882010-06-16 02:00:15 +0000694 "The breakpoint stops only for threads in the queue whose name is given by this argument."},
695
Zachary Turnerd37221d2014-07-09 16:31:49 +0000696 { LLDB_OPT_FILE, false, "file", 'f', OptionParser::eRequiredArgument, NULL, NULL, CommandCompletions::eSourceFileCompletion, eArgTypeFilename,
Jim Ingham289aca62013-02-14 19:10:36 +0000697 "Specifies the source file in which to set this breakpoint. "
698 "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 +0000699 "To set breakpoints on .c/.cpp/.m/.mm files that are #included, set target.inline-breakpoint-strategy"
Jim Ingham289aca62013-02-14 19:10:36 +0000700 " to \"always\"."},
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000701
Zachary Turnerd37221d2014-07-09 16:31:49 +0000702 { LLDB_OPT_SET_1, true, "line", 'l', OptionParser::eRequiredArgument, NULL, NULL, 0, eArgTypeLineNum,
Jim Ingham87df91b2011-09-23 00:54:11 +0000703 "Specifies the line number on which to set this breakpoint."},
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000704
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000705 // Comment out this option for the moment, as we don't actually use it, but will in the future.
706 // This way users won't see it, but the infrastructure is left in place.
Virgile Belloe2607b52013-09-05 16:42:23 +0000707 // { 0, false, "column", 'C', OptionParser::eRequiredArgument, NULL, "<column>",
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000708 // "Set the breakpoint by source location at this particular column."},
709
Zachary Turnerd37221d2014-07-09 16:31:49 +0000710 { LLDB_OPT_SET_2, true, "address", 'a', OptionParser::eRequiredArgument, NULL, NULL, 0, eArgTypeAddressOrExpression,
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000711 "Set the breakpoint by address, at the specified address."},
712
Zachary Turnerd37221d2014-07-09 16:31:49 +0000713 { LLDB_OPT_SET_3, true, "name", 'n', OptionParser::eRequiredArgument, NULL, NULL, CommandCompletions::eSymbolCompletion, eArgTypeFunctionName,
Jim Ingham551262d2013-03-27 17:36:54 +0000714 "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 +0000715
Zachary Turnerd37221d2014-07-09 16:31:49 +0000716 { LLDB_OPT_SET_4, true, "fullname", 'F', OptionParser::eRequiredArgument, NULL, NULL, CommandCompletions::eSymbolCompletion, eArgTypeFullName,
Jim Ingham64cc29c2012-05-03 20:30:08 +0000717 "Set the breakpoint by fully qualified function names. For C++ this means namespaces and all arguments, and "
718 "for Objective C this means a full function prototype with class and selector. "
719 "Can be repeated multiple times to make one breakpoint for multiple names." },
Greg Clayton0c5cd902010-06-28 21:30:43 +0000720
Zachary Turnerd37221d2014-07-09 16:31:49 +0000721 { LLDB_OPT_SET_5, true, "selector", 'S', OptionParser::eRequiredArgument, NULL, NULL, 0, eArgTypeSelector,
Jim Ingham64cc29c2012-05-03 20:30:08 +0000722 "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 +0000723
Zachary Turnerd37221d2014-07-09 16:31:49 +0000724 { LLDB_OPT_SET_6, true, "method", 'M', OptionParser::eRequiredArgument, NULL, NULL, 0, eArgTypeMethod,
Jim Ingham64cc29c2012-05-03 20:30:08 +0000725 "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 +0000726
Zachary Turnerd37221d2014-07-09 16:31:49 +0000727 { LLDB_OPT_SET_7, true, "func-regex", 'r', OptionParser::eRequiredArgument, NULL, NULL, 0, eArgTypeRegularExpression,
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000728 "Set the breakpoint by function name, evaluating a regular-expression to find the function name(s)." },
729
Zachary Turnerd37221d2014-07-09 16:31:49 +0000730 { LLDB_OPT_SET_8, true, "basename", 'b', OptionParser::eRequiredArgument, NULL, NULL, CommandCompletions::eSymbolCompletion, eArgTypeFunctionName,
Jim Ingham64cc29c2012-05-03 20:30:08 +0000731 "Set the breakpoint by function basename (C++ namespaces and arguments will be ignored). "
732 "Can be repeated multiple times to make one breakpoint for multiple symbols." },
Greg Claytone02b8502010-10-12 04:29:14 +0000733
Zachary Turnerd37221d2014-07-09 16:31:49 +0000734 { LLDB_OPT_SET_9, true, "source-pattern-regexp", 'p', OptionParser::eRequiredArgument, NULL, NULL, 0, eArgTypeRegularExpression,
Jim Inghame96ade82013-06-07 01:13:00 +0000735 "Set the breakpoint by specifying a regular expression which is matched against the source text in a source file or files "
736 "specified with the -f option. The -f option can be specified more than once. "
737 "If no source files are specified, uses the current \"default source file\"" },
Jim Ingham969795f2011-09-21 01:17:13 +0000738
Jim Inghame7320522015-02-12 17:37:46 +0000739 { LLDB_OPT_SET_9, false, "all-files", 'A', OptionParser::eNoArgument, NULL, NULL, 0, eArgTypeNone,
740 "All files are searched for source pattern matches." },
741
Zachary Turnerd37221d2014-07-09 16:31:49 +0000742 { LLDB_OPT_SET_10, true, "language-exception", 'E', OptionParser::eRequiredArgument, NULL, NULL, 0, eArgTypeLanguage,
Jim Inghamfab10e82012-03-06 00:37:27 +0000743 "Set the breakpoint on exceptions thrown by the specified language (without options, on throw but not catch.)" },
744
Zachary Turnerd37221d2014-07-09 16:31:49 +0000745 { LLDB_OPT_SET_10, false, "on-throw", 'w', OptionParser::eRequiredArgument, NULL, NULL, 0, eArgTypeBoolean,
Jim Inghamfab10e82012-03-06 00:37:27 +0000746 "Set the breakpoint on exception throW." },
747
Zachary Turnerd37221d2014-07-09 16:31:49 +0000748 { LLDB_OPT_SET_10, false, "on-catch", 'h', OptionParser::eRequiredArgument, NULL, NULL, 0, eArgTypeBoolean,
Jim Inghamfab10e82012-03-06 00:37:27 +0000749 "Set the breakpoint on exception catcH." },
Jim Ingham969795f2011-09-21 01:17:13 +0000750
Zachary Turnerd37221d2014-07-09 16:31:49 +0000751 { LLDB_OPT_SKIP_PROLOGUE, false, "skip-prologue", 'K', OptionParser::eRequiredArgument, NULL, NULL, 0, eArgTypeBoolean,
Jim Inghama8558b62012-05-22 00:12:20 +0000752 "sKip the prologue if the breakpoint is at the beginning of a function. If not set the target.skip-prologue setting is used." },
753
Jim Ingham33df7cd2014-12-06 01:28:03 +0000754 { LLDB_OPT_SET_ALL, false, "dummy-breakpoints", 'D', OptionParser::eNoArgument, NULL, NULL, 0, eArgTypeNone,
755 "Sets Dummy breakpoints - i.e. breakpoints set before a file is provided, which prime new targets."},
756
Jim Ingham5e09c8c2014-12-16 23:40:14 +0000757 { LLDB_OPT_SET_ALL, false, "breakpoint-name", 'N', OptionParser::eRequiredArgument, NULL, NULL, 0, eArgTypeBreakpointName,
758 "Adds this to the list of names for this breakopint."},
759
Zachary Turnerd37221d2014-07-09 16:31:49 +0000760 { 0, false, NULL, 0, 0, NULL, NULL, 0, eArgTypeNone, NULL }
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000761};
762
Jim Ingham5a988412012-06-08 21:56:10 +0000763//-------------------------------------------------------------------------
764// CommandObjectBreakpointModify
765//-------------------------------------------------------------------------
766#pragma mark Modify
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000767
Jim Ingham5a988412012-06-08 21:56:10 +0000768class CommandObjectBreakpointModify : public CommandObjectParsed
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000769{
Jim Ingham5a988412012-06-08 21:56:10 +0000770public:
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000771
Jim Ingham5a988412012-06-08 21:56:10 +0000772 CommandObjectBreakpointModify (CommandInterpreter &interpreter) :
773 CommandObjectParsed (interpreter,
774 "breakpoint modify",
775 "Modify the options on a breakpoint or set of breakpoints in the executable. "
776 "If no breakpoint is specified, acts on the last created breakpoint. "
777 "With the exception of -e, -d and -i, passing an empty argument clears the modification.",
778 NULL),
779 m_options (interpreter)
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000780 {
Jim Ingham5a988412012-06-08 21:56:10 +0000781 CommandArgumentEntry arg;
782 CommandObject::AddIDsArgumentData(arg, eArgTypeBreakpointID, eArgTypeBreakpointIDRange);
783 // Add the entry for the first argument for this command to the object's arguments vector.
784 m_arguments.push_back (arg);
785 }
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000786
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000787
Jim Ingham5a988412012-06-08 21:56:10 +0000788 virtual
789 ~CommandObjectBreakpointModify () {}
Greg Clayton0c5cd902010-06-28 21:30:43 +0000790
Jim Ingham5a988412012-06-08 21:56:10 +0000791 virtual Options *
792 GetOptions ()
793 {
794 return &m_options;
795 }
Johnny Chen7d49c9c2012-05-25 21:10:46 +0000796
Jim Ingham5a988412012-06-08 21:56:10 +0000797 class CommandOptions : public Options
798 {
799 public:
Greg Clayton0c5cd902010-06-28 21:30:43 +0000800
Jim Ingham5a988412012-06-08 21:56:10 +0000801 CommandOptions (CommandInterpreter &interpreter) :
802 Options (interpreter),
803 m_ignore_count (0),
804 m_thread_id(LLDB_INVALID_THREAD_ID),
805 m_thread_id_passed(false),
806 m_thread_index (UINT32_MAX),
807 m_thread_index_passed(false),
808 m_thread_name(),
809 m_queue_name(),
810 m_condition (),
Jim Inghamca36cd12012-10-05 19:16:31 +0000811 m_one_shot (false),
Jim Ingham5a988412012-06-08 21:56:10 +0000812 m_enable_passed (false),
813 m_enable_value (false),
814 m_name_passed (false),
815 m_queue_passed (false),
Jim Inghamca36cd12012-10-05 19:16:31 +0000816 m_condition_passed (false),
Jim Ingham33df7cd2014-12-06 01:28:03 +0000817 m_one_shot_passed (false),
818 m_use_dummy (false)
Jim Ingham5a988412012-06-08 21:56:10 +0000819 {
820 }
Greg Clayton0c5cd902010-06-28 21:30:43 +0000821
Jim Ingham5a988412012-06-08 21:56:10 +0000822 virtual
823 ~CommandOptions () {}
Greg Clayton0c5cd902010-06-28 21:30:43 +0000824
Jim Ingham5a988412012-06-08 21:56:10 +0000825 virtual Error
826 SetOptionValue (uint32_t option_idx, const char *option_arg)
827 {
828 Error error;
Greg Clayton3bcdfc02012-12-04 00:32:51 +0000829 const int short_option = m_getopt_table[option_idx].val;
Greg Claytone02b8502010-10-12 04:29:14 +0000830
Jim Ingham5a988412012-06-08 21:56:10 +0000831 switch (short_option)
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000832 {
Jim Ingham5a988412012-06-08 21:56:10 +0000833 case 'c':
834 if (option_arg != NULL)
835 m_condition.assign (option_arg);
836 else
837 m_condition.clear();
838 m_condition_passed = true;
839 break;
840 case 'd':
841 m_enable_passed = true;
842 m_enable_value = false;
843 break;
Jim Ingham33df7cd2014-12-06 01:28:03 +0000844 case 'D':
845 m_use_dummy = true;
846 break;
Jim Ingham5a988412012-06-08 21:56:10 +0000847 case 'e':
848 m_enable_passed = true;
849 m_enable_value = true;
850 break;
851 case 'i':
852 {
Vince Harron5275aaa2015-01-15 20:08:35 +0000853 m_ignore_count = StringConvert::ToUInt32(option_arg, UINT32_MAX, 0);
Jim Ingham5a988412012-06-08 21:56:10 +0000854 if (m_ignore_count == UINT32_MAX)
855 error.SetErrorStringWithFormat ("invalid ignore count '%s'", option_arg);
856 }
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000857 break;
Jim Inghamca36cd12012-10-05 19:16:31 +0000858 case 'o':
859 {
860 bool value, success;
861 value = Args::StringToBoolean(option_arg, false, &success);
862 if (success)
863 {
864 m_one_shot_passed = true;
865 m_one_shot = value;
866 }
867 else
868 error.SetErrorStringWithFormat("invalid boolean value '%s' passed for -o option", option_arg);
869 }
870 break;
Jim Ingham5a988412012-06-08 21:56:10 +0000871 case 't' :
Jim Ingham87df91b2011-09-23 00:54:11 +0000872 {
Jim Ingham5a988412012-06-08 21:56:10 +0000873 if (option_arg[0] == '\0')
Jim Ingham87df91b2011-09-23 00:54:11 +0000874 {
Jim Ingham5a988412012-06-08 21:56:10 +0000875 m_thread_id = LLDB_INVALID_THREAD_ID;
876 m_thread_id_passed = true;
Jim Ingham87df91b2011-09-23 00:54:11 +0000877 }
878 else
879 {
Vince Harron5275aaa2015-01-15 20:08:35 +0000880 m_thread_id = StringConvert::ToUInt64(option_arg, LLDB_INVALID_THREAD_ID, 0);
Jim Ingham5a988412012-06-08 21:56:10 +0000881 if (m_thread_id == LLDB_INVALID_THREAD_ID)
882 error.SetErrorStringWithFormat ("invalid thread id string '%s'", option_arg);
883 else
884 m_thread_id_passed = true;
Jim Ingham87df91b2011-09-23 00:54:11 +0000885 }
886 }
Jim Ingham5a988412012-06-08 21:56:10 +0000887 break;
888 case 'T':
889 if (option_arg != NULL)
890 m_thread_name.assign (option_arg);
891 else
892 m_thread_name.clear();
893 m_name_passed = true;
894 break;
895 case 'q':
896 if (option_arg != NULL)
897 m_queue_name.assign (option_arg);
898 else
899 m_queue_name.clear();
900 m_queue_passed = true;
901 break;
902 case 'x':
Jim Ingham969795f2011-09-21 01:17:13 +0000903 {
Jim Ingham5a988412012-06-08 21:56:10 +0000904 if (option_arg[0] == '\n')
905 {
906 m_thread_index = UINT32_MAX;
907 m_thread_index_passed = true;
908 }
909 else
910 {
Vince Harron5275aaa2015-01-15 20:08:35 +0000911 m_thread_index = StringConvert::ToUInt32 (option_arg, UINT32_MAX, 0);
Jim Ingham5a988412012-06-08 21:56:10 +0000912 if (m_thread_id == UINT32_MAX)
913 error.SetErrorStringWithFormat ("invalid thread index string '%s'", option_arg);
914 else
915 m_thread_index_passed = true;
916 }
Jim Ingham969795f2011-09-21 01:17:13 +0000917 }
Jim Ingham5a988412012-06-08 21:56:10 +0000918 break;
919 default:
920 error.SetErrorStringWithFormat ("unrecognized option '%c'", short_option);
921 break;
Jim Ingham969795f2011-09-21 01:17:13 +0000922 }
Jim Ingham5a988412012-06-08 21:56:10 +0000923
924 return error;
925 }
926 void
927 OptionParsingStarting ()
928 {
929 m_ignore_count = 0;
930 m_thread_id = LLDB_INVALID_THREAD_ID;
931 m_thread_id_passed = false;
932 m_thread_index = UINT32_MAX;
933 m_thread_index_passed = false;
934 m_thread_name.clear();
935 m_queue_name.clear();
936 m_condition.clear();
Jim Inghamca36cd12012-10-05 19:16:31 +0000937 m_one_shot = false;
Jim Ingham5a988412012-06-08 21:56:10 +0000938 m_enable_passed = false;
939 m_queue_passed = false;
940 m_name_passed = false;
941 m_condition_passed = false;
Jim Inghamca36cd12012-10-05 19:16:31 +0000942 m_one_shot_passed = false;
Jim Ingham33df7cd2014-12-06 01:28:03 +0000943 m_use_dummy = false;
Jim Ingham5a988412012-06-08 21:56:10 +0000944 }
945
946 const OptionDefinition*
947 GetDefinitions ()
948 {
949 return g_option_table;
950 }
951
952
953 // Options table: Required for subclasses of Options.
954
955 static OptionDefinition g_option_table[];
956
957 // Instance variables to hold the values for command options.
958
959 uint32_t m_ignore_count;
960 lldb::tid_t m_thread_id;
961 bool m_thread_id_passed;
962 uint32_t m_thread_index;
963 bool m_thread_index_passed;
964 std::string m_thread_name;
965 std::string m_queue_name;
966 std::string m_condition;
Jim Inghamca36cd12012-10-05 19:16:31 +0000967 bool m_one_shot;
Jim Ingham5a988412012-06-08 21:56:10 +0000968 bool m_enable_passed;
969 bool m_enable_value;
970 bool m_name_passed;
971 bool m_queue_passed;
972 bool m_condition_passed;
Jim Inghamca36cd12012-10-05 19:16:31 +0000973 bool m_one_shot_passed;
Jim Ingham33df7cd2014-12-06 01:28:03 +0000974 bool m_use_dummy;
Jim Ingham5a988412012-06-08 21:56:10 +0000975
976 };
977
978protected:
979 virtual bool
980 DoExecute (Args& command, CommandReturnObject &result)
981 {
Jim Ingham33df7cd2014-12-06 01:28:03 +0000982 Target *target = GetSelectedOrDummyTarget(m_options.m_use_dummy);
Jim Ingham5a988412012-06-08 21:56:10 +0000983 if (target == NULL)
984 {
985 result.AppendError ("Invalid target. No existing target or breakpoints.");
986 result.SetStatus (eReturnStatusFailed);
987 return false;
988 }
989
990 Mutex::Locker locker;
991 target->GetBreakpointList().GetListMutex(locker);
992
993 BreakpointIDList valid_bp_ids;
994
Jim Ingham5e09c8c2014-12-16 23:40:14 +0000995 CommandObjectMultiwordBreakpoint::VerifyBreakpointOrLocationIDs (command, target, result, &valid_bp_ids);
Jim Ingham5a988412012-06-08 21:56:10 +0000996
997 if (result.Succeeded())
998 {
999 const size_t count = valid_bp_ids.GetSize();
1000 for (size_t i = 0; i < count; ++i)
Jim Inghamfab10e82012-03-06 00:37:27 +00001001 {
Jim Ingham5a988412012-06-08 21:56:10 +00001002 BreakpointID cur_bp_id = valid_bp_ids.GetBreakpointIDAtIndex (i);
1003
1004 if (cur_bp_id.GetBreakpointID() != LLDB_INVALID_BREAK_ID)
1005 {
1006 Breakpoint *bp = target->GetBreakpointByID (cur_bp_id.GetBreakpointID()).get();
1007 if (cur_bp_id.GetLocationID() != LLDB_INVALID_BREAK_ID)
1008 {
1009 BreakpointLocation *location = bp->FindLocationByID (cur_bp_id.GetLocationID()).get();
1010 if (location)
1011 {
1012 if (m_options.m_thread_id_passed)
1013 location->SetThreadID (m_options.m_thread_id);
1014
1015 if (m_options.m_thread_index_passed)
1016 location->SetThreadIndex(m_options.m_thread_index);
1017
1018 if (m_options.m_name_passed)
1019 location->SetThreadName(m_options.m_thread_name.c_str());
1020
1021 if (m_options.m_queue_passed)
1022 location->SetQueueName(m_options.m_queue_name.c_str());
1023
1024 if (m_options.m_ignore_count != 0)
1025 location->SetIgnoreCount(m_options.m_ignore_count);
1026
1027 if (m_options.m_enable_passed)
1028 location->SetEnabled (m_options.m_enable_value);
1029
1030 if (m_options.m_condition_passed)
1031 location->SetCondition (m_options.m_condition.c_str());
1032 }
1033 }
1034 else
1035 {
1036 if (m_options.m_thread_id_passed)
1037 bp->SetThreadID (m_options.m_thread_id);
1038
1039 if (m_options.m_thread_index_passed)
1040 bp->SetThreadIndex(m_options.m_thread_index);
1041
1042 if (m_options.m_name_passed)
1043 bp->SetThreadName(m_options.m_thread_name.c_str());
1044
1045 if (m_options.m_queue_passed)
1046 bp->SetQueueName(m_options.m_queue_name.c_str());
1047
1048 if (m_options.m_ignore_count != 0)
1049 bp->SetIgnoreCount(m_options.m_ignore_count);
1050
1051 if (m_options.m_enable_passed)
1052 bp->SetEnabled (m_options.m_enable_value);
1053
1054 if (m_options.m_condition_passed)
1055 bp->SetCondition (m_options.m_condition.c_str());
1056 }
1057 }
Jim Inghamfab10e82012-03-06 00:37:27 +00001058 }
Jim Ingham5a988412012-06-08 21:56:10 +00001059 }
1060
1061 return result.Succeeded();
Chris Lattner30fdc8d2010-06-08 16:52:24 +00001062 }
1063
Jim Ingham5a988412012-06-08 21:56:10 +00001064private:
1065 CommandOptions m_options;
1066};
Johnny Chen7d49c9c2012-05-25 21:10:46 +00001067
Jim Ingham5a988412012-06-08 21:56:10 +00001068#pragma mark Modify::CommandOptions
1069OptionDefinition
1070CommandObjectBreakpointModify::CommandOptions::g_option_table[] =
1071{
Zachary Turnerd37221d2014-07-09 16:31:49 +00001072{ 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." },
1073{ 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." },
1074{ 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."},
1075{ 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."},
1076{ 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."},
1077{ 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."},
1078{ LLDB_OPT_SET_ALL, false, "condition", 'c', OptionParser::eRequiredArgument, NULL, NULL, 0, eArgTypeExpression, "The breakpoint stops only if this condition expression evaluates to true."},
1079{ LLDB_OPT_SET_1, false, "enable", 'e', OptionParser::eNoArgument, NULL, NULL, 0, eArgTypeNone, "Enable the breakpoint."},
1080{ LLDB_OPT_SET_2, false, "disable", 'd', OptionParser::eNoArgument, NULL, NULL, 0, eArgTypeNone, "Disable the breakpoint."},
Jim Ingham33df7cd2014-12-06 01:28:03 +00001081{ 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."},
1082
Zachary Turnerd37221d2014-07-09 16:31:49 +00001083{ 0, false, NULL, 0 , 0, NULL, NULL, 0, eArgTypeNone, NULL }
Jim Ingham5a988412012-06-08 21:56:10 +00001084};
1085
1086//-------------------------------------------------------------------------
1087// CommandObjectBreakpointEnable
1088//-------------------------------------------------------------------------
1089#pragma mark Enable
1090
1091class CommandObjectBreakpointEnable : public CommandObjectParsed
1092{
1093public:
1094 CommandObjectBreakpointEnable (CommandInterpreter &interpreter) :
1095 CommandObjectParsed (interpreter,
1096 "enable",
1097 "Enable the specified disabled breakpoint(s). If no breakpoints are specified, enable all of them.",
1098 NULL)
1099 {
1100 CommandArgumentEntry arg;
1101 CommandObject::AddIDsArgumentData(arg, eArgTypeBreakpointID, eArgTypeBreakpointIDRange);
1102 // Add the entry for the first argument for this command to the object's arguments vector.
1103 m_arguments.push_back (arg);
1104 }
1105
1106
1107 virtual
1108 ~CommandObjectBreakpointEnable () {}
1109
1110protected:
1111 virtual bool
1112 DoExecute (Args& command, CommandReturnObject &result)
1113 {
Jim Ingham893c9322014-11-22 01:42:44 +00001114 Target *target = GetSelectedOrDummyTarget();
Jim Ingham5a988412012-06-08 21:56:10 +00001115 if (target == NULL)
1116 {
1117 result.AppendError ("Invalid target. No existing target or breakpoints.");
1118 result.SetStatus (eReturnStatusFailed);
1119 return false;
1120 }
1121
1122 Mutex::Locker locker;
1123 target->GetBreakpointList().GetListMutex(locker);
1124
1125 const BreakpointList &breakpoints = target->GetBreakpointList();
1126
1127 size_t num_breakpoints = breakpoints.GetSize();
1128
1129 if (num_breakpoints == 0)
1130 {
1131 result.AppendError ("No breakpoints exist to be enabled.");
1132 result.SetStatus (eReturnStatusFailed);
1133 return false;
1134 }
1135
1136 if (command.GetArgumentCount() == 0)
1137 {
1138 // No breakpoint selected; enable all currently set breakpoints.
1139 target->EnableAllBreakpoints ();
Greg Clayton6fea17e2014-03-03 19:15:20 +00001140 result.AppendMessageWithFormat ("All breakpoints enabled. (%" PRIu64 " breakpoints)\n", (uint64_t)num_breakpoints);
Jim Ingham5a988412012-06-08 21:56:10 +00001141 result.SetStatus (eReturnStatusSuccessFinishNoResult);
1142 }
1143 else
1144 {
1145 // Particular breakpoint selected; enable that breakpoint.
1146 BreakpointIDList valid_bp_ids;
Jim Ingham5e09c8c2014-12-16 23:40:14 +00001147 CommandObjectMultiwordBreakpoint::VerifyBreakpointOrLocationIDs (command, target, result, &valid_bp_ids);
Jim Ingham5a988412012-06-08 21:56:10 +00001148
1149 if (result.Succeeded())
1150 {
1151 int enable_count = 0;
1152 int loc_count = 0;
1153 const size_t count = valid_bp_ids.GetSize();
1154 for (size_t i = 0; i < count; ++i)
1155 {
1156 BreakpointID cur_bp_id = valid_bp_ids.GetBreakpointIDAtIndex (i);
1157
1158 if (cur_bp_id.GetBreakpointID() != LLDB_INVALID_BREAK_ID)
1159 {
1160 Breakpoint *breakpoint = target->GetBreakpointByID (cur_bp_id.GetBreakpointID()).get();
1161 if (cur_bp_id.GetLocationID() != LLDB_INVALID_BREAK_ID)
1162 {
1163 BreakpointLocation *location = breakpoint->FindLocationByID (cur_bp_id.GetLocationID()).get();
1164 if (location)
1165 {
1166 location->SetEnabled (true);
1167 ++loc_count;
1168 }
1169 }
1170 else
1171 {
1172 breakpoint->SetEnabled (true);
1173 ++enable_count;
1174 }
1175 }
1176 }
1177 result.AppendMessageWithFormat ("%d breakpoints enabled.\n", enable_count + loc_count);
1178 result.SetStatus (eReturnStatusSuccessFinishNoResult);
1179 }
1180 }
1181
1182 return result.Succeeded();
1183 }
1184};
1185
1186//-------------------------------------------------------------------------
1187// CommandObjectBreakpointDisable
1188//-------------------------------------------------------------------------
1189#pragma mark Disable
1190
1191class CommandObjectBreakpointDisable : public CommandObjectParsed
1192{
1193public:
1194 CommandObjectBreakpointDisable (CommandInterpreter &interpreter) :
1195 CommandObjectParsed (interpreter,
1196 "breakpoint disable",
1197 "Disable the specified breakpoint(s) without removing it/them. If no breakpoints are specified, disable them all.",
1198 NULL)
1199 {
Jim Inghamb0fac502013-03-08 00:31:40 +00001200 SetHelpLong(
1201"Disable the specified breakpoint(s) without removing it/them. \n\
1202If no breakpoints are specified, disable them all.\n\
1203\n\
1204Note: disabling a breakpoint will cause none of its locations to be hit\n\
1205regardless of whether they are enabled or disabled. So the sequence: \n\
1206\n\
1207 (lldb) break disable 1\n\
1208 (lldb) break enable 1.1\n\
1209\n\
1210will NOT cause location 1.1 to get hit. To achieve that, do:\n\
1211\n\
1212 (lldb) break disable 1.*\n\
1213 (lldb) break enable 1.1\n\
1214\n\
1215The first command disables all the locations of breakpoint 1, \n\
1216the second re-enables the first location."
1217 );
1218
Jim Ingham5a988412012-06-08 21:56:10 +00001219 CommandArgumentEntry arg;
1220 CommandObject::AddIDsArgumentData(arg, eArgTypeBreakpointID, eArgTypeBreakpointIDRange);
1221 // Add the entry for the first argument for this command to the object's arguments vector.
Jim Inghamb0fac502013-03-08 00:31:40 +00001222 m_arguments.push_back (arg);
1223
Jim Ingham5a988412012-06-08 21:56:10 +00001224 }
1225
1226
1227 virtual
1228 ~CommandObjectBreakpointDisable () {}
1229
1230protected:
1231 virtual bool
1232 DoExecute (Args& command, CommandReturnObject &result)
1233 {
Jim Ingham893c9322014-11-22 01:42:44 +00001234 Target *target = GetSelectedOrDummyTarget();
Jim Ingham5a988412012-06-08 21:56:10 +00001235 if (target == NULL)
1236 {
1237 result.AppendError ("Invalid target. No existing target or breakpoints.");
1238 result.SetStatus (eReturnStatusFailed);
1239 return false;
1240 }
1241
1242 Mutex::Locker locker;
1243 target->GetBreakpointList().GetListMutex(locker);
1244
1245 const BreakpointList &breakpoints = target->GetBreakpointList();
1246 size_t num_breakpoints = breakpoints.GetSize();
1247
1248 if (num_breakpoints == 0)
1249 {
1250 result.AppendError ("No breakpoints exist to be disabled.");
1251 result.SetStatus (eReturnStatusFailed);
1252 return false;
1253 }
1254
1255 if (command.GetArgumentCount() == 0)
1256 {
1257 // No breakpoint selected; disable all currently set breakpoints.
1258 target->DisableAllBreakpoints ();
Greg Clayton6fea17e2014-03-03 19:15:20 +00001259 result.AppendMessageWithFormat ("All breakpoints disabled. (%" PRIu64 " breakpoints)\n", (uint64_t)num_breakpoints);
Jim Ingham5a988412012-06-08 21:56:10 +00001260 result.SetStatus (eReturnStatusSuccessFinishNoResult);
1261 }
1262 else
1263 {
1264 // Particular breakpoint selected; disable that breakpoint.
1265 BreakpointIDList valid_bp_ids;
1266
Jim Ingham5e09c8c2014-12-16 23:40:14 +00001267 CommandObjectMultiwordBreakpoint::VerifyBreakpointOrLocationIDs (command, target, result, &valid_bp_ids);
Jim Ingham5a988412012-06-08 21:56:10 +00001268
1269 if (result.Succeeded())
1270 {
1271 int disable_count = 0;
1272 int loc_count = 0;
1273 const size_t count = valid_bp_ids.GetSize();
1274 for (size_t i = 0; i < count; ++i)
1275 {
1276 BreakpointID cur_bp_id = valid_bp_ids.GetBreakpointIDAtIndex (i);
1277
1278 if (cur_bp_id.GetBreakpointID() != LLDB_INVALID_BREAK_ID)
1279 {
1280 Breakpoint *breakpoint = target->GetBreakpointByID (cur_bp_id.GetBreakpointID()).get();
1281 if (cur_bp_id.GetLocationID() != LLDB_INVALID_BREAK_ID)
1282 {
1283 BreakpointLocation *location = breakpoint->FindLocationByID (cur_bp_id.GetLocationID()).get();
1284 if (location)
1285 {
1286 location->SetEnabled (false);
1287 ++loc_count;
1288 }
1289 }
1290 else
1291 {
1292 breakpoint->SetEnabled (false);
1293 ++disable_count;
1294 }
1295 }
1296 }
1297 result.AppendMessageWithFormat ("%d breakpoints disabled.\n", disable_count + loc_count);
1298 result.SetStatus (eReturnStatusSuccessFinishNoResult);
1299 }
1300 }
1301
1302 return result.Succeeded();
1303 }
1304
1305};
1306
1307//-------------------------------------------------------------------------
1308// CommandObjectBreakpointList
1309//-------------------------------------------------------------------------
1310#pragma mark List
1311
1312class CommandObjectBreakpointList : public CommandObjectParsed
1313{
1314public:
1315 CommandObjectBreakpointList (CommandInterpreter &interpreter) :
1316 CommandObjectParsed (interpreter,
1317 "breakpoint list",
1318 "List some or all breakpoints at configurable levels of detail.",
1319 NULL),
1320 m_options (interpreter)
1321 {
1322 CommandArgumentEntry arg;
1323 CommandArgumentData bp_id_arg;
1324
1325 // Define the first (and only) variant of this arg.
1326 bp_id_arg.arg_type = eArgTypeBreakpointID;
1327 bp_id_arg.arg_repetition = eArgRepeatOptional;
1328
1329 // There is only one variant this argument could be; put it into the argument entry.
1330 arg.push_back (bp_id_arg);
1331
1332 // Push the data for the first argument into the m_arguments vector.
1333 m_arguments.push_back (arg);
1334 }
1335
1336
1337 virtual
1338 ~CommandObjectBreakpointList () {}
1339
1340 virtual Options *
1341 GetOptions ()
1342 {
1343 return &m_options;
Jim Ingham1b54c882010-06-16 02:00:15 +00001344 }
1345
Jim Ingham5a988412012-06-08 21:56:10 +00001346 class CommandOptions : public Options
Chris Lattner30fdc8d2010-06-08 16:52:24 +00001347 {
Jim Ingham5a988412012-06-08 21:56:10 +00001348 public:
1349
1350 CommandOptions (CommandInterpreter &interpreter) :
1351 Options (interpreter),
Jim Ingham33df7cd2014-12-06 01:28:03 +00001352 m_level (lldb::eDescriptionLevelBrief),
1353 m_use_dummy(false)
Jim Ingham5a988412012-06-08 21:56:10 +00001354 {
1355 }
1356
1357 virtual
1358 ~CommandOptions () {}
1359
1360 virtual Error
1361 SetOptionValue (uint32_t option_idx, const char *option_arg)
1362 {
1363 Error error;
Greg Clayton3bcdfc02012-12-04 00:32:51 +00001364 const int short_option = m_getopt_table[option_idx].val;
Jim Ingham5a988412012-06-08 21:56:10 +00001365
1366 switch (short_option)
1367 {
1368 case 'b':
1369 m_level = lldb::eDescriptionLevelBrief;
1370 break;
Jim Ingham33df7cd2014-12-06 01:28:03 +00001371 case 'D':
1372 m_use_dummy = true;
1373 break;
Jim Ingham5a988412012-06-08 21:56:10 +00001374 case 'f':
1375 m_level = lldb::eDescriptionLevelFull;
1376 break;
1377 case 'v':
1378 m_level = lldb::eDescriptionLevelVerbose;
1379 break;
1380 case 'i':
1381 m_internal = true;
1382 break;
1383 default:
1384 error.SetErrorStringWithFormat ("unrecognized option '%c'", short_option);
1385 break;
1386 }
1387
1388 return error;
1389 }
1390
1391 void
1392 OptionParsingStarting ()
1393 {
1394 m_level = lldb::eDescriptionLevelFull;
1395 m_internal = false;
Jim Ingham33df7cd2014-12-06 01:28:03 +00001396 m_use_dummy = false;
Jim Ingham5a988412012-06-08 21:56:10 +00001397 }
1398
1399 const OptionDefinition *
1400 GetDefinitions ()
1401 {
1402 return g_option_table;
1403 }
1404
1405 // Options table: Required for subclasses of Options.
1406
1407 static OptionDefinition g_option_table[];
1408
1409 // Instance variables to hold the values for command options.
1410
1411 lldb::DescriptionLevel m_level;
1412
1413 bool m_internal;
Jim Ingham33df7cd2014-12-06 01:28:03 +00001414 bool m_use_dummy;
Jim Ingham5a988412012-06-08 21:56:10 +00001415 };
1416
1417protected:
1418 virtual bool
1419 DoExecute (Args& command, CommandReturnObject &result)
1420 {
Jim Ingham33df7cd2014-12-06 01:28:03 +00001421 Target *target = GetSelectedOrDummyTarget(m_options.m_use_dummy);
1422
Jim Ingham5a988412012-06-08 21:56:10 +00001423 if (target == NULL)
1424 {
1425 result.AppendError ("Invalid target. No current target or breakpoints.");
1426 result.SetStatus (eReturnStatusSuccessFinishNoResult);
1427 return true;
1428 }
1429
1430 const BreakpointList &breakpoints = target->GetBreakpointList(m_options.m_internal);
1431 Mutex::Locker locker;
1432 target->GetBreakpointList(m_options.m_internal).GetListMutex(locker);
1433
1434 size_t num_breakpoints = breakpoints.GetSize();
1435
1436 if (num_breakpoints == 0)
1437 {
1438 result.AppendMessage ("No breakpoints currently set.");
1439 result.SetStatus (eReturnStatusSuccessFinishNoResult);
1440 return true;
1441 }
1442
Jim Ingham85e8b812011-02-19 02:53:09 +00001443 Stream &output_stream = result.GetOutputStream();
Jim Ingham5a988412012-06-08 21:56:10 +00001444
1445 if (command.GetArgumentCount() == 0)
1446 {
1447 // No breakpoint selected; show info about all currently set breakpoints.
1448 result.AppendMessage ("Current breakpoints:");
1449 for (size_t i = 0; i < num_breakpoints; ++i)
1450 {
1451 Breakpoint *breakpoint = breakpoints.GetBreakpointAtIndex (i).get();
1452 AddBreakpointDescription (&output_stream, breakpoint, m_options.m_level);
1453 }
1454 result.SetStatus (eReturnStatusSuccessFinishNoResult);
1455 }
1456 else
1457 {
1458 // Particular breakpoints selected; show info about that breakpoint.
1459 BreakpointIDList valid_bp_ids;
Jim Ingham5e09c8c2014-12-16 23:40:14 +00001460 CommandObjectMultiwordBreakpoint::VerifyBreakpointOrLocationIDs (command, target, result, &valid_bp_ids);
Jim Ingham5a988412012-06-08 21:56:10 +00001461
1462 if (result.Succeeded())
1463 {
1464 for (size_t i = 0; i < valid_bp_ids.GetSize(); ++i)
1465 {
1466 BreakpointID cur_bp_id = valid_bp_ids.GetBreakpointIDAtIndex (i);
1467 Breakpoint *breakpoint = target->GetBreakpointByID (cur_bp_id.GetBreakpointID()).get();
1468 AddBreakpointDescription (&output_stream, breakpoint, m_options.m_level);
1469 }
1470 result.SetStatus (eReturnStatusSuccessFinishNoResult);
1471 }
1472 else
1473 {
1474 result.AppendError ("Invalid breakpoint id.");
1475 result.SetStatus (eReturnStatusFailed);
1476 }
1477 }
1478
1479 return result.Succeeded();
Chris Lattner30fdc8d2010-06-08 16:52:24 +00001480 }
1481
Jim Ingham5a988412012-06-08 21:56:10 +00001482private:
1483 CommandOptions m_options;
1484};
1485
1486#pragma mark List::CommandOptions
1487OptionDefinition
1488CommandObjectBreakpointList::CommandOptions::g_option_table[] =
1489{
Zachary Turnerd37221d2014-07-09 16:31:49 +00001490 { LLDB_OPT_SET_ALL, false, "internal", 'i', OptionParser::eNoArgument, NULL, NULL, 0, eArgTypeNone,
Jim Ingham5a988412012-06-08 21:56:10 +00001491 "Show debugger internal breakpoints" },
1492
Zachary Turnerd37221d2014-07-09 16:31:49 +00001493 { LLDB_OPT_SET_1, false, "brief", 'b', OptionParser::eNoArgument, NULL, NULL, 0, eArgTypeNone,
Jim Ingham5a988412012-06-08 21:56:10 +00001494 "Give a brief description of the breakpoint (no location info)."},
1495
1496 // FIXME: We need to add an "internal" command, and then add this sort of thing to it.
1497 // But I need to see it for now, and don't want to wait.
Zachary Turnerd37221d2014-07-09 16:31:49 +00001498 { LLDB_OPT_SET_2, false, "full", 'f', OptionParser::eNoArgument, NULL, NULL, 0, eArgTypeNone,
Jim Ingham5a988412012-06-08 21:56:10 +00001499 "Give a full description of the breakpoint and its locations."},
1500
Zachary Turnerd37221d2014-07-09 16:31:49 +00001501 { LLDB_OPT_SET_3, false, "verbose", 'v', OptionParser::eNoArgument, NULL, NULL, 0, eArgTypeNone,
Jim Ingham5a988412012-06-08 21:56:10 +00001502 "Explain everything we know about the breakpoint (for debugging debugger bugs)." },
1503
Jim Ingham33df7cd2014-12-06 01:28:03 +00001504 { LLDB_OPT_SET_ALL, false, "dummy-breakpoints", 'D', OptionParser::eNoArgument, NULL, NULL, 0, eArgTypeNone,
1505 "List Dummy breakpoints - i.e. breakpoints set before a file is provided, which prime new targets."},
1506
Zachary Turnerd37221d2014-07-09 16:31:49 +00001507 { 0, false, NULL, 0, 0, NULL, NULL, 0, eArgTypeNone, NULL }
Jim Ingham5a988412012-06-08 21:56:10 +00001508};
1509
1510//-------------------------------------------------------------------------
1511// CommandObjectBreakpointClear
1512//-------------------------------------------------------------------------
1513#pragma mark Clear
1514
1515class CommandObjectBreakpointClear : public CommandObjectParsed
1516{
1517public:
1518
1519 typedef enum BreakpointClearType
1520 {
1521 eClearTypeInvalid,
1522 eClearTypeFileAndLine
1523 } BreakpointClearType;
1524
1525 CommandObjectBreakpointClear (CommandInterpreter &interpreter) :
1526 CommandObjectParsed (interpreter,
1527 "breakpoint clear",
1528 "Clears a breakpoint or set of breakpoints in the executable.",
1529 "breakpoint clear <cmd-options>"),
1530 m_options (interpreter)
1531 {
1532 }
1533
1534 virtual
1535 ~CommandObjectBreakpointClear () {}
1536
1537 virtual Options *
1538 GetOptions ()
1539 {
1540 return &m_options;
1541 }
1542
1543 class CommandOptions : public Options
1544 {
1545 public:
1546
1547 CommandOptions (CommandInterpreter &interpreter) :
1548 Options (interpreter),
1549 m_filename (),
1550 m_line_num (0)
1551 {
1552 }
1553
1554 virtual
1555 ~CommandOptions () {}
1556
1557 virtual Error
1558 SetOptionValue (uint32_t option_idx, const char *option_arg)
1559 {
1560 Error error;
Greg Clayton3bcdfc02012-12-04 00:32:51 +00001561 const int short_option = m_getopt_table[option_idx].val;
Jim Ingham5a988412012-06-08 21:56:10 +00001562
1563 switch (short_option)
1564 {
1565 case 'f':
1566 m_filename.assign (option_arg);
1567 break;
1568
1569 case 'l':
Vince Harron5275aaa2015-01-15 20:08:35 +00001570 m_line_num = StringConvert::ToUInt32 (option_arg, 0);
Jim Ingham5a988412012-06-08 21:56:10 +00001571 break;
1572
1573 default:
1574 error.SetErrorStringWithFormat ("unrecognized option '%c'", short_option);
1575 break;
1576 }
1577
1578 return error;
1579 }
1580
1581 void
1582 OptionParsingStarting ()
1583 {
1584 m_filename.clear();
1585 m_line_num = 0;
1586 }
1587
1588 const OptionDefinition*
1589 GetDefinitions ()
1590 {
1591 return g_option_table;
1592 }
1593
1594 // Options table: Required for subclasses of Options.
1595
1596 static OptionDefinition g_option_table[];
1597
1598 // Instance variables to hold the values for command options.
1599
1600 std::string m_filename;
1601 uint32_t m_line_num;
1602
1603 };
1604
1605protected:
1606 virtual bool
1607 DoExecute (Args& command, CommandReturnObject &result)
1608 {
Jim Ingham893c9322014-11-22 01:42:44 +00001609 Target *target = GetSelectedOrDummyTarget();
Jim Ingham5a988412012-06-08 21:56:10 +00001610 if (target == NULL)
1611 {
1612 result.AppendError ("Invalid target. No existing target or breakpoints.");
1613 result.SetStatus (eReturnStatusFailed);
1614 return false;
1615 }
1616
1617 // The following are the various types of breakpoints that could be cleared:
1618 // 1). -f -l (clearing breakpoint by source location)
1619
1620 BreakpointClearType break_type = eClearTypeInvalid;
1621
1622 if (m_options.m_line_num != 0)
1623 break_type = eClearTypeFileAndLine;
1624
1625 Mutex::Locker locker;
1626 target->GetBreakpointList().GetListMutex(locker);
1627
1628 BreakpointList &breakpoints = target->GetBreakpointList();
1629 size_t num_breakpoints = breakpoints.GetSize();
1630
1631 // Early return if there's no breakpoint at all.
1632 if (num_breakpoints == 0)
1633 {
1634 result.AppendError ("Breakpoint clear: No breakpoint cleared.");
1635 result.SetStatus (eReturnStatusFailed);
1636 return result.Succeeded();
1637 }
1638
1639 // Find matching breakpoints and delete them.
1640
1641 // First create a copy of all the IDs.
1642 std::vector<break_id_t> BreakIDs;
1643 for (size_t i = 0; i < num_breakpoints; ++i)
1644 BreakIDs.push_back(breakpoints.GetBreakpointAtIndex(i).get()->GetID());
1645
1646 int num_cleared = 0;
1647 StreamString ss;
1648 switch (break_type)
1649 {
1650 case eClearTypeFileAndLine: // Breakpoint by source position
1651 {
1652 const ConstString filename(m_options.m_filename.c_str());
1653 BreakpointLocationCollection loc_coll;
1654
1655 for (size_t i = 0; i < num_breakpoints; ++i)
1656 {
1657 Breakpoint *bp = breakpoints.FindBreakpointByID(BreakIDs[i]).get();
1658
1659 if (bp->GetMatchingFileLine(filename, m_options.m_line_num, loc_coll))
1660 {
1661 // If the collection size is 0, it's a full match and we can just remove the breakpoint.
1662 if (loc_coll.GetSize() == 0)
1663 {
1664 bp->GetDescription(&ss, lldb::eDescriptionLevelBrief);
1665 ss.EOL();
1666 target->RemoveBreakpointByID (bp->GetID());
1667 ++num_cleared;
1668 }
1669 }
1670 }
1671 }
1672 break;
1673
1674 default:
1675 break;
1676 }
1677
1678 if (num_cleared > 0)
1679 {
1680 Stream &output_stream = result.GetOutputStream();
1681 output_stream.Printf ("%d breakpoints cleared:\n", num_cleared);
1682 output_stream << ss.GetData();
1683 output_stream.EOL();
1684 result.SetStatus (eReturnStatusSuccessFinishNoResult);
1685 }
1686 else
1687 {
1688 result.AppendError ("Breakpoint clear: No breakpoint cleared.");
1689 result.SetStatus (eReturnStatusFailed);
1690 }
1691
1692 return result.Succeeded();
1693 }
1694
1695private:
1696 CommandOptions m_options;
1697};
1698
1699#pragma mark Clear::CommandOptions
1700
1701OptionDefinition
1702CommandObjectBreakpointClear::CommandOptions::g_option_table[] =
1703{
Zachary Turnerd37221d2014-07-09 16:31:49 +00001704 { LLDB_OPT_SET_1, false, "file", 'f', OptionParser::eRequiredArgument, NULL, NULL, CommandCompletions::eSourceFileCompletion, eArgTypeFilename,
Jim Ingham5a988412012-06-08 21:56:10 +00001705 "Specify the breakpoint by source location in this particular file."},
1706
Zachary Turnerd37221d2014-07-09 16:31:49 +00001707 { LLDB_OPT_SET_1, true, "line", 'l', OptionParser::eRequiredArgument, NULL, NULL, 0, eArgTypeLineNum,
Jim Ingham5a988412012-06-08 21:56:10 +00001708 "Specify the breakpoint by source location at this particular line."},
1709
Zachary Turnerd37221d2014-07-09 16:31:49 +00001710 { 0, false, NULL, 0, 0, NULL, NULL, 0, eArgTypeNone, NULL }
Jim Ingham5a988412012-06-08 21:56:10 +00001711};
1712
1713//-------------------------------------------------------------------------
1714// CommandObjectBreakpointDelete
1715//-------------------------------------------------------------------------
1716#pragma mark Delete
1717
1718class CommandObjectBreakpointDelete : public CommandObjectParsed
1719{
1720public:
1721 CommandObjectBreakpointDelete (CommandInterpreter &interpreter) :
1722 CommandObjectParsed (interpreter,
1723 "breakpoint delete",
1724 "Delete the specified breakpoint(s). If no breakpoints are specified, delete them all.",
Jim Ingham33df7cd2014-12-06 01:28:03 +00001725 NULL),
1726 m_options (interpreter)
Jim Ingham5a988412012-06-08 21:56:10 +00001727 {
1728 CommandArgumentEntry arg;
1729 CommandObject::AddIDsArgumentData(arg, eArgTypeBreakpointID, eArgTypeBreakpointIDRange);
1730 // Add the entry for the first argument for this command to the object's arguments vector.
1731 m_arguments.push_back (arg);
1732 }
1733
1734 virtual
1735 ~CommandObjectBreakpointDelete () {}
1736
Jim Ingham33df7cd2014-12-06 01:28:03 +00001737 virtual Options *
1738 GetOptions ()
1739 {
1740 return &m_options;
1741 }
1742
1743 class CommandOptions : public Options
1744 {
1745 public:
1746
1747 CommandOptions (CommandInterpreter &interpreter) :
1748 Options (interpreter),
1749 m_use_dummy (false),
1750 m_force (false)
1751 {
1752 }
1753
1754 virtual
1755 ~CommandOptions () {}
1756
1757 virtual Error
1758 SetOptionValue (uint32_t option_idx, const char *option_arg)
1759 {
1760 Error error;
1761 const int short_option = m_getopt_table[option_idx].val;
1762
1763 switch (short_option)
1764 {
1765 case 'f':
1766 m_force = true;
1767 break;
1768
1769 case 'D':
1770 m_use_dummy = true;
1771 break;
1772
1773 default:
1774 error.SetErrorStringWithFormat ("unrecognized option '%c'", short_option);
1775 break;
1776 }
1777
1778 return error;
1779 }
1780
1781 void
1782 OptionParsingStarting ()
1783 {
1784 m_use_dummy = false;
1785 m_force = false;
1786 }
1787
1788 const OptionDefinition*
1789 GetDefinitions ()
1790 {
1791 return g_option_table;
1792 }
1793
1794 // Options table: Required for subclasses of Options.
1795
1796 static OptionDefinition g_option_table[];
1797
1798 // Instance variables to hold the values for command options.
1799 bool m_use_dummy;
1800 bool m_force;
1801 };
1802
Jim Ingham5a988412012-06-08 21:56:10 +00001803protected:
1804 virtual bool
1805 DoExecute (Args& command, CommandReturnObject &result)
1806 {
Jim Ingham33df7cd2014-12-06 01:28:03 +00001807 Target *target = GetSelectedOrDummyTarget(m_options.m_use_dummy);
1808
Jim Ingham5a988412012-06-08 21:56:10 +00001809 if (target == NULL)
1810 {
1811 result.AppendError ("Invalid target. No existing target or breakpoints.");
1812 result.SetStatus (eReturnStatusFailed);
1813 return false;
1814 }
1815
1816 Mutex::Locker locker;
1817 target->GetBreakpointList().GetListMutex(locker);
1818
1819 const BreakpointList &breakpoints = target->GetBreakpointList();
1820
1821 size_t num_breakpoints = breakpoints.GetSize();
1822
1823 if (num_breakpoints == 0)
1824 {
1825 result.AppendError ("No breakpoints exist to be deleted.");
1826 result.SetStatus (eReturnStatusFailed);
1827 return false;
1828 }
1829
1830 if (command.GetArgumentCount() == 0)
1831 {
Jim Ingham33df7cd2014-12-06 01:28:03 +00001832 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 +00001833 {
1834 result.AppendMessage("Operation cancelled...");
1835 }
1836 else
1837 {
1838 target->RemoveAllBreakpoints ();
Greg Clayton6fea17e2014-03-03 19:15:20 +00001839 result.AppendMessageWithFormat ("All breakpoints removed. (%" PRIu64 " breakpoint%s)\n", (uint64_t)num_breakpoints, num_breakpoints > 1 ? "s" : "");
Jim Ingham5a988412012-06-08 21:56:10 +00001840 }
1841 result.SetStatus (eReturnStatusSuccessFinishNoResult);
1842 }
1843 else
1844 {
1845 // Particular breakpoint selected; disable that breakpoint.
1846 BreakpointIDList valid_bp_ids;
Jim Ingham5e09c8c2014-12-16 23:40:14 +00001847 CommandObjectMultiwordBreakpoint::VerifyBreakpointOrLocationIDs (command, target, result, &valid_bp_ids);
Jim Ingham5a988412012-06-08 21:56:10 +00001848
1849 if (result.Succeeded())
1850 {
1851 int delete_count = 0;
1852 int disable_count = 0;
1853 const size_t count = valid_bp_ids.GetSize();
1854 for (size_t i = 0; i < count; ++i)
1855 {
1856 BreakpointID cur_bp_id = valid_bp_ids.GetBreakpointIDAtIndex (i);
1857
1858 if (cur_bp_id.GetBreakpointID() != LLDB_INVALID_BREAK_ID)
1859 {
1860 if (cur_bp_id.GetLocationID() != LLDB_INVALID_BREAK_ID)
1861 {
1862 Breakpoint *breakpoint = target->GetBreakpointByID (cur_bp_id.GetBreakpointID()).get();
1863 BreakpointLocation *location = breakpoint->FindLocationByID (cur_bp_id.GetLocationID()).get();
1864 // It makes no sense to try to delete individual locations, so we disable them instead.
1865 if (location)
1866 {
1867 location->SetEnabled (false);
1868 ++disable_count;
1869 }
1870 }
1871 else
1872 {
1873 target->RemoveBreakpointByID (cur_bp_id.GetBreakpointID());
1874 ++delete_count;
1875 }
1876 }
1877 }
1878 result.AppendMessageWithFormat ("%d breakpoints deleted; %d breakpoint locations disabled.\n",
1879 delete_count, disable_count);
1880 result.SetStatus (eReturnStatusSuccessFinishNoResult);
1881 }
1882 }
1883 return result.Succeeded();
1884 }
Jim Ingham33df7cd2014-12-06 01:28:03 +00001885private:
1886 CommandOptions m_options;
1887};
1888
1889OptionDefinition
1890CommandObjectBreakpointDelete::CommandOptions::g_option_table[] =
1891{
1892 { LLDB_OPT_SET_1, false, "force", 'f', OptionParser::eNoArgument, NULL, NULL, 0, eArgTypeNone,
1893 "Delete all breakpoints without querying for confirmation."},
1894
1895 { LLDB_OPT_SET_1, false, "dummy-breakpoints", 'D', OptionParser::eNoArgument, NULL, NULL, 0, eArgTypeNone,
1896 "Delete Dummy breakpoints - i.e. breakpoints set before a file is provided, which prime new targets."},
1897
1898 { 0, false, NULL, 0, 0, NULL, NULL, 0, eArgTypeNone, NULL }
Jim Ingham5a988412012-06-08 21:56:10 +00001899};
Chris Lattner30fdc8d2010-06-08 16:52:24 +00001900
Chris Lattner30fdc8d2010-06-08 16:52:24 +00001901//-------------------------------------------------------------------------
Jim Ingham5e09c8c2014-12-16 23:40:14 +00001902// CommandObjectBreakpointName
1903//-------------------------------------------------------------------------
1904
1905static OptionDefinition
1906g_breakpoint_name_options[] =
1907{
1908 { LLDB_OPT_SET_1, false, "name", 'N', OptionParser::eRequiredArgument, NULL, NULL, 0, eArgTypeBreakpointName, "Specifies a breakpoint name to use."},
1909 { LLDB_OPT_SET_2, false, "breakpoint-id", 'B', OptionParser::eRequiredArgument, NULL, NULL, 0, eArgTypeBreakpointID, "Specify a breakpoint id to use."},
1910 { LLDB_OPT_SET_ALL, false, "dummy-breakpoints", 'D', OptionParser::eNoArgument, NULL, NULL, 0, eArgTypeNone,
1911 "Operate on Dummy breakpoints - i.e. breakpoints set before a file is provided, which prime new targets."},
1912};
1913class BreakpointNameOptionGroup : public OptionGroup
1914{
1915public:
1916 BreakpointNameOptionGroup() :
1917 OptionGroup(),
1918 m_breakpoint(LLDB_INVALID_BREAK_ID),
1919 m_use_dummy (false)
1920 {
1921
1922 }
1923
1924 virtual
1925 ~BreakpointNameOptionGroup ()
1926 {
1927 }
1928
1929 virtual uint32_t
1930 GetNumDefinitions ()
1931 {
1932 return sizeof (g_breakpoint_name_options) / sizeof (OptionDefinition);
1933 }
1934
1935 virtual const OptionDefinition*
1936 GetDefinitions ()
1937 {
1938 return g_breakpoint_name_options;
1939 }
1940
1941 virtual Error
1942 SetOptionValue (CommandInterpreter &interpreter,
1943 uint32_t option_idx,
1944 const char *option_value)
1945 {
1946 Error error;
1947 const int short_option = g_breakpoint_name_options[option_idx].short_option;
1948
1949 switch (short_option)
1950 {
1951 case 'N':
1952 if (BreakpointID::StringIsBreakpointName(option_value, error) && error.Success())
Pavel Labathc95f7e22015-02-20 11:14:59 +00001953 m_name.SetValueFromString(option_value);
Jim Ingham5e09c8c2014-12-16 23:40:14 +00001954 break;
1955
1956 case 'B':
Pavel Labathc95f7e22015-02-20 11:14:59 +00001957 if (m_breakpoint.SetValueFromString(option_value).Fail())
Jim Ingham5e09c8c2014-12-16 23:40:14 +00001958 error.SetErrorStringWithFormat ("unrecognized value \"%s\" for breakpoint", option_value);
1959 break;
1960 case 'D':
Pavel Labathc95f7e22015-02-20 11:14:59 +00001961 if (m_use_dummy.SetValueFromString(option_value).Fail())
Jim Ingham5e09c8c2014-12-16 23:40:14 +00001962 error.SetErrorStringWithFormat ("unrecognized value \"%s\" for use-dummy", option_value);
1963 break;
1964
1965 default:
1966 error.SetErrorStringWithFormat("unrecognized short option '%c'", short_option);
1967 break;
1968 }
1969 return error;
1970 }
1971
1972 virtual void
1973 OptionParsingStarting (CommandInterpreter &interpreter)
1974 {
1975 m_name.Clear();
1976 m_breakpoint.Clear();
1977 m_use_dummy.Clear();
1978 m_use_dummy.SetDefaultValue(false);
1979 }
1980
1981 OptionValueString m_name;
1982 OptionValueUInt64 m_breakpoint;
1983 OptionValueBoolean m_use_dummy;
1984};
1985
1986
1987class CommandObjectBreakpointNameAdd : public CommandObjectParsed
1988{
1989public:
1990 CommandObjectBreakpointNameAdd (CommandInterpreter &interpreter) :
1991 CommandObjectParsed (interpreter,
1992 "add",
1993 "Add a name to the breakpoints provided.",
1994 "breakpoint name add <command-options> <breakpoint-id-list>"),
1995 m_name_options(),
1996 m_option_group(interpreter)
1997 {
1998 // Create the first variant for the first (and only) argument for this command.
1999 CommandArgumentEntry arg1;
2000 CommandArgumentData id_arg;
2001 id_arg.arg_type = eArgTypeBreakpointID;
2002 id_arg.arg_repetition = eArgRepeatOptional;
2003 arg1.push_back(id_arg);
2004 m_arguments.push_back (arg1);
2005
2006 m_option_group.Append (&m_name_options, LLDB_OPT_SET_1, LLDB_OPT_SET_ALL);
2007 m_option_group.Finalize();
2008 }
2009
2010 virtual
2011 ~CommandObjectBreakpointNameAdd () {}
2012
2013 Options *
2014 GetOptions ()
2015 {
2016 return &m_option_group;
2017 }
2018
2019protected:
2020 virtual bool
2021 DoExecute (Args& command, CommandReturnObject &result)
2022 {
2023 if (!m_name_options.m_name.OptionWasSet())
2024 {
2025 result.SetError("No name option provided.");
2026 return false;
2027 }
2028
2029 Target *target = GetSelectedOrDummyTarget(m_name_options.m_use_dummy.GetCurrentValue());
2030
2031 if (target == NULL)
2032 {
2033 result.AppendError ("Invalid target. No existing target or breakpoints.");
2034 result.SetStatus (eReturnStatusFailed);
2035 return false;
2036 }
2037
2038 Mutex::Locker locker;
2039 target->GetBreakpointList().GetListMutex(locker);
2040
2041 const BreakpointList &breakpoints = target->GetBreakpointList();
2042
2043 size_t num_breakpoints = breakpoints.GetSize();
2044 if (num_breakpoints == 0)
2045 {
2046 result.SetError("No breakpoints, cannot add names.");
2047 result.SetStatus (eReturnStatusFailed);
2048 return false;
2049 }
2050
2051 // Particular breakpoint selected; disable that breakpoint.
2052 BreakpointIDList valid_bp_ids;
2053 CommandObjectMultiwordBreakpoint::VerifyBreakpointIDs (command, target, result, &valid_bp_ids);
2054
2055 if (result.Succeeded())
2056 {
2057 if (valid_bp_ids.GetSize() == 0)
2058 {
2059 result.SetError("No breakpoints specified, cannot add names.");
2060 result.SetStatus (eReturnStatusFailed);
2061 return false;
2062 }
2063 size_t num_valid_ids = valid_bp_ids.GetSize();
2064 for (size_t index = 0; index < num_valid_ids; index++)
2065 {
2066 lldb::break_id_t bp_id = valid_bp_ids.GetBreakpointIDAtIndex(index).GetBreakpointID();
2067 BreakpointSP bp_sp = breakpoints.FindBreakpointByID(bp_id);
2068 Error error; // We don't need to check the error here, since the option parser checked it...
2069 bp_sp->AddName(m_name_options.m_name.GetCurrentValue(), error);
2070 }
2071 }
2072
2073 return true;
2074 }
2075
2076private:
2077 BreakpointNameOptionGroup m_name_options;
2078 OptionGroupOptions m_option_group;
2079};
2080
2081
2082
2083class CommandObjectBreakpointNameDelete : public CommandObjectParsed
2084{
2085public:
2086 CommandObjectBreakpointNameDelete (CommandInterpreter &interpreter) :
2087 CommandObjectParsed (interpreter,
2088 "delete",
2089 "Delete a name from the breakpoints provided.",
2090 "breakpoint name delete <command-options> <breakpoint-id-list>"),
2091 m_name_options(),
2092 m_option_group(interpreter)
2093 {
2094 // Create the first variant for the first (and only) argument for this command.
2095 CommandArgumentEntry arg1;
2096 CommandArgumentData id_arg;
2097 id_arg.arg_type = eArgTypeBreakpointID;
2098 id_arg.arg_repetition = eArgRepeatOptional;
2099 arg1.push_back(id_arg);
2100 m_arguments.push_back (arg1);
2101
2102 m_option_group.Append (&m_name_options, LLDB_OPT_SET_1, LLDB_OPT_SET_ALL);
2103 m_option_group.Finalize();
2104 }
2105
2106 virtual
2107 ~CommandObjectBreakpointNameDelete () {}
2108
2109 Options *
2110 GetOptions ()
2111 {
2112 return &m_option_group;
2113 }
2114
2115protected:
2116 virtual bool
2117 DoExecute (Args& command, CommandReturnObject &result)
2118 {
2119 if (!m_name_options.m_name.OptionWasSet())
2120 {
2121 result.SetError("No name option provided.");
2122 return false;
2123 }
2124
2125 Target *target = GetSelectedOrDummyTarget(m_name_options.m_use_dummy.GetCurrentValue());
2126
2127 if (target == NULL)
2128 {
2129 result.AppendError ("Invalid target. No existing target or breakpoints.");
2130 result.SetStatus (eReturnStatusFailed);
2131 return false;
2132 }
2133
2134 Mutex::Locker locker;
2135 target->GetBreakpointList().GetListMutex(locker);
2136
2137 const BreakpointList &breakpoints = target->GetBreakpointList();
2138
2139 size_t num_breakpoints = breakpoints.GetSize();
2140 if (num_breakpoints == 0)
2141 {
2142 result.SetError("No breakpoints, cannot delete names.");
2143 result.SetStatus (eReturnStatusFailed);
2144 return false;
2145 }
2146
2147 // Particular breakpoint selected; disable that breakpoint.
2148 BreakpointIDList valid_bp_ids;
2149 CommandObjectMultiwordBreakpoint::VerifyBreakpointIDs (command, target, result, &valid_bp_ids);
2150
2151 if (result.Succeeded())
2152 {
2153 if (valid_bp_ids.GetSize() == 0)
2154 {
2155 result.SetError("No breakpoints specified, cannot delete names.");
2156 result.SetStatus (eReturnStatusFailed);
2157 return false;
2158 }
2159 size_t num_valid_ids = valid_bp_ids.GetSize();
2160 for (size_t index = 0; index < num_valid_ids; index++)
2161 {
2162 lldb::break_id_t bp_id = valid_bp_ids.GetBreakpointIDAtIndex(index).GetBreakpointID();
2163 BreakpointSP bp_sp = breakpoints.FindBreakpointByID(bp_id);
2164 bp_sp->RemoveName(m_name_options.m_name.GetCurrentValue());
2165 }
2166 }
2167
2168 return true;
2169 }
2170
2171private:
2172 BreakpointNameOptionGroup m_name_options;
2173 OptionGroupOptions m_option_group;
2174};
2175
2176class CommandObjectBreakpointNameList : public CommandObjectParsed
2177{
2178public:
2179 CommandObjectBreakpointNameList (CommandInterpreter &interpreter) :
2180 CommandObjectParsed (interpreter,
2181 "list",
2182 "List either the names for a breakpoint or the breakpoints for a given name.",
2183 "breakpoint name list <command-options>"),
2184 m_name_options(),
2185 m_option_group(interpreter)
2186 {
2187 m_option_group.Append (&m_name_options);
2188 m_option_group.Finalize();
2189 }
2190
2191 virtual
2192 ~CommandObjectBreakpointNameList () {}
2193
2194 Options *
2195 GetOptions ()
2196 {
2197 return &m_option_group;
2198 }
2199
2200protected:
2201protected:
2202 virtual bool
2203 DoExecute (Args& command, CommandReturnObject &result)
2204 {
2205 Target *target = GetSelectedOrDummyTarget(m_name_options.m_use_dummy.GetCurrentValue());
2206
2207 if (target == NULL)
2208 {
2209 result.AppendError ("Invalid target. No existing target or breakpoints.");
2210 result.SetStatus (eReturnStatusFailed);
2211 return false;
2212 }
2213
2214 if (m_name_options.m_name.OptionWasSet())
2215 {
2216 const char *name = m_name_options.m_name.GetCurrentValue();
2217 Mutex::Locker locker;
2218 target->GetBreakpointList().GetListMutex(locker);
2219
2220 BreakpointList &breakpoints = target->GetBreakpointList();
2221 for (BreakpointSP bp_sp : breakpoints.Breakpoints())
2222 {
2223 if (bp_sp->MatchesName(name))
2224 {
2225 StreamString s;
2226 bp_sp->GetDescription(&s, eDescriptionLevelBrief);
2227 s.EOL();
2228 result.AppendMessage(s.GetData());
2229 }
2230 }
2231
2232 }
2233 else if (m_name_options.m_breakpoint.OptionWasSet())
2234 {
2235 BreakpointSP bp_sp = target->GetBreakpointList().FindBreakpointByID(m_name_options.m_breakpoint.GetCurrentValue());
2236 if (bp_sp)
2237 {
2238 std::vector<std::string> names;
2239 bp_sp->GetNames (names);
2240 result.AppendMessage ("Names:");
2241 for (auto name : names)
2242 result.AppendMessageWithFormat (" %s\n", name.c_str());
2243 }
2244 else
2245 {
2246 result.AppendErrorWithFormat ("Could not find breakpoint %" PRId64 ".\n",
2247 m_name_options.m_breakpoint.GetCurrentValue());
2248 result.SetStatus (eReturnStatusFailed);
2249 return false;
2250 }
2251 }
2252 else
2253 {
2254 result.SetError ("Must specify -N or -B option to list.");
2255 result.SetStatus (eReturnStatusFailed);
2256 return false;
2257 }
2258 return true;
2259 }
2260
2261private:
2262 BreakpointNameOptionGroup m_name_options;
2263 OptionGroupOptions m_option_group;
2264};
2265
2266//-------------------------------------------------------------------------
2267// CommandObjectMultiwordBreakpoint
2268//-------------------------------------------------------------------------
2269class CommandObjectBreakpointName : public CommandObjectMultiword
2270{
2271public:
2272 CommandObjectBreakpointName (CommandInterpreter &interpreter) :
2273 CommandObjectMultiword(interpreter,
2274 "name",
2275 "A set of commands to manage name tags for breakpoints",
2276 "breakpoint name <command> [<command-options>]")
2277 {
2278 CommandObjectSP add_command_object (new CommandObjectBreakpointNameAdd (interpreter));
2279 CommandObjectSP delete_command_object (new CommandObjectBreakpointNameDelete (interpreter));
2280 CommandObjectSP list_command_object (new CommandObjectBreakpointNameList (interpreter));
2281
2282 LoadSubCommand ("add", add_command_object);
2283 LoadSubCommand ("delete", delete_command_object);
2284 LoadSubCommand ("list", list_command_object);
2285
2286 }
2287
2288 virtual
2289 ~CommandObjectBreakpointName ()
2290 {
2291 }
2292
2293};
2294
2295
2296//-------------------------------------------------------------------------
Chris Lattner30fdc8d2010-06-08 16:52:24 +00002297// CommandObjectMultiwordBreakpoint
2298//-------------------------------------------------------------------------
Jim Inghamae1c4cf2010-06-18 00:58:52 +00002299#pragma mark MultiwordBreakpoint
Chris Lattner30fdc8d2010-06-08 16:52:24 +00002300
Greg Clayton66111032010-06-23 01:19:29 +00002301CommandObjectMultiwordBreakpoint::CommandObjectMultiwordBreakpoint (CommandInterpreter &interpreter) :
Greg Claytona7015092010-09-18 01:14:36 +00002302 CommandObjectMultiword (interpreter,
2303 "breakpoint",
Jim Ingham46fbc602011-05-26 20:39:01 +00002304 "A set of commands for operating on breakpoints. Also see _regexp-break.",
Greg Claytona7015092010-09-18 01:14:36 +00002305 "breakpoint <command> [<command-options>]")
Chris Lattner30fdc8d2010-06-08 16:52:24 +00002306{
Greg Claytona7015092010-09-18 01:14:36 +00002307 CommandObjectSP list_command_object (new CommandObjectBreakpointList (interpreter));
Greg Claytona7015092010-09-18 01:14:36 +00002308 CommandObjectSP enable_command_object (new CommandObjectBreakpointEnable (interpreter));
2309 CommandObjectSP disable_command_object (new CommandObjectBreakpointDisable (interpreter));
Johnny Chenb7234e42010-10-28 17:27:46 +00002310 CommandObjectSP clear_command_object (new CommandObjectBreakpointClear (interpreter));
2311 CommandObjectSP delete_command_object (new CommandObjectBreakpointDelete (interpreter));
Greg Claytona7015092010-09-18 01:14:36 +00002312 CommandObjectSP set_command_object (new CommandObjectBreakpointSet (interpreter));
Chris Lattner30fdc8d2010-06-08 16:52:24 +00002313 CommandObjectSP command_command_object (new CommandObjectBreakpointCommand (interpreter));
Greg Claytona7015092010-09-18 01:14:36 +00002314 CommandObjectSP modify_command_object (new CommandObjectBreakpointModify(interpreter));
Jim Ingham5e09c8c2014-12-16 23:40:14 +00002315 CommandObjectSP name_command_object (new CommandObjectBreakpointName(interpreter));
Chris Lattner30fdc8d2010-06-08 16:52:24 +00002316
Johnny Chenb7234e42010-10-28 17:27:46 +00002317 list_command_object->SetCommandName ("breakpoint list");
Chris Lattner30fdc8d2010-06-08 16:52:24 +00002318 enable_command_object->SetCommandName("breakpoint enable");
2319 disable_command_object->SetCommandName("breakpoint disable");
Johnny Chenb7234e42010-10-28 17:27:46 +00002320 clear_command_object->SetCommandName("breakpoint clear");
2321 delete_command_object->SetCommandName("breakpoint delete");
Jim Inghamae1c4cf2010-06-18 00:58:52 +00002322 set_command_object->SetCommandName("breakpoint set");
Johnny Chenb7234e42010-10-28 17:27:46 +00002323 command_command_object->SetCommandName ("breakpoint command");
2324 modify_command_object->SetCommandName ("breakpoint modify");
Jim Ingham5e09c8c2014-12-16 23:40:14 +00002325 name_command_object->SetCommandName ("breakpoint name");
Chris Lattner30fdc8d2010-06-08 16:52:24 +00002326
Greg Clayton23f59502012-07-17 03:23:13 +00002327 LoadSubCommand ("list", list_command_object);
2328 LoadSubCommand ("enable", enable_command_object);
2329 LoadSubCommand ("disable", disable_command_object);
2330 LoadSubCommand ("clear", clear_command_object);
2331 LoadSubCommand ("delete", delete_command_object);
2332 LoadSubCommand ("set", set_command_object);
2333 LoadSubCommand ("command", command_command_object);
2334 LoadSubCommand ("modify", modify_command_object);
Jim Ingham5e09c8c2014-12-16 23:40:14 +00002335 LoadSubCommand ("name", name_command_object);
Chris Lattner30fdc8d2010-06-08 16:52:24 +00002336}
2337
2338CommandObjectMultiwordBreakpoint::~CommandObjectMultiwordBreakpoint ()
2339{
2340}
2341
2342void
Jim Ingham5e09c8c2014-12-16 23:40:14 +00002343CommandObjectMultiwordBreakpoint::VerifyIDs (Args &args,
2344 Target *target,
2345 bool allow_locations,
2346 CommandReturnObject &result,
2347 BreakpointIDList *valid_ids)
Chris Lattner30fdc8d2010-06-08 16:52:24 +00002348{
2349 // args can be strings representing 1). integers (for breakpoint ids)
2350 // 2). the full breakpoint & location canonical representation
2351 // 3). the word "to" or a hyphen, representing a range (in which case there
2352 // had *better* be an entry both before & after of one of the first two types.
Jim Ingham5e09c8c2014-12-16 23:40:14 +00002353 // 4). A breakpoint name
Jim Ingham36f3b362010-10-14 23:45:03 +00002354 // If args is empty, we will use the last created breakpoint (if there is one.)
Chris Lattner30fdc8d2010-06-08 16:52:24 +00002355
2356 Args temp_args;
2357
Jim Ingham36f3b362010-10-14 23:45:03 +00002358 if (args.GetArgumentCount() == 0)
2359 {
Greg Clayton4d122c42011-09-17 08:33:22 +00002360 if (target->GetLastCreatedBreakpoint())
Jim Ingham36f3b362010-10-14 23:45:03 +00002361 {
2362 valid_ids->AddBreakpointID (BreakpointID(target->GetLastCreatedBreakpoint()->GetID(), LLDB_INVALID_BREAK_ID));
2363 result.SetStatus (eReturnStatusSuccessFinishNoResult);
2364 }
2365 else
2366 {
2367 result.AppendError("No breakpoint specified and no last created breakpoint.");
2368 result.SetStatus (eReturnStatusFailed);
2369 }
2370 return;
2371 }
2372
Chris Lattner30fdc8d2010-06-08 16:52:24 +00002373 // Create a new Args variable to use; copy any non-breakpoint-id-ranges stuff directly from the old ARGS to
2374 // the new TEMP_ARGS. Do not copy breakpoint id range strings over; instead generate a list of strings for
2375 // all the breakpoint ids in the range, and shove all of those breakpoint id strings into TEMP_ARGS.
2376
Jim Ingham5e09c8c2014-12-16 23:40:14 +00002377 BreakpointIDList::FindAndReplaceIDRanges (args, target, allow_locations, result, temp_args);
Chris Lattner30fdc8d2010-06-08 16:52:24 +00002378
2379 // NOW, convert the list of breakpoint id strings in TEMP_ARGS into an actual BreakpointIDList:
2380
Greg Claytonc982c762010-07-09 20:39:50 +00002381 valid_ids->InsertStringArray (temp_args.GetConstArgumentVector(), temp_args.GetArgumentCount(), result);
Chris Lattner30fdc8d2010-06-08 16:52:24 +00002382
2383 // At this point, all of the breakpoint ids that the user passed in have been converted to breakpoint IDs
2384 // and put into valid_ids.
2385
2386 if (result.Succeeded())
2387 {
2388 // Now that we've converted everything from args into a list of breakpoint ids, go through our tentative list
2389 // of breakpoint id's and verify that they correspond to valid/currently set breakpoints.
2390
Greg Claytonc982c762010-07-09 20:39:50 +00002391 const size_t count = valid_ids->GetSize();
2392 for (size_t i = 0; i < count; ++i)
Chris Lattner30fdc8d2010-06-08 16:52:24 +00002393 {
2394 BreakpointID cur_bp_id = valid_ids->GetBreakpointIDAtIndex (i);
2395 Breakpoint *breakpoint = target->GetBreakpointByID (cur_bp_id.GetBreakpointID()).get();
2396 if (breakpoint != NULL)
2397 {
Greg Claytonc7bece562013-01-25 18:06:21 +00002398 const size_t num_locations = breakpoint->GetNumLocations();
Saleem Abdulrasool3985c8c2014-04-02 03:51:35 +00002399 if (static_cast<size_t>(cur_bp_id.GetLocationID()) > num_locations)
Chris Lattner30fdc8d2010-06-08 16:52:24 +00002400 {
2401 StreamString id_str;
Greg Claytonc982c762010-07-09 20:39:50 +00002402 BreakpointID::GetCanonicalReference (&id_str,
2403 cur_bp_id.GetBreakpointID(),
2404 cur_bp_id.GetLocationID());
2405 i = valid_ids->GetSize() + 1;
Chris Lattner30fdc8d2010-06-08 16:52:24 +00002406 result.AppendErrorWithFormat ("'%s' is not a currently valid breakpoint/location id.\n",
2407 id_str.GetData());
2408 result.SetStatus (eReturnStatusFailed);
2409 }
2410 }
2411 else
2412 {
Greg Claytonc982c762010-07-09 20:39:50 +00002413 i = valid_ids->GetSize() + 1;
Chris Lattner30fdc8d2010-06-08 16:52:24 +00002414 result.AppendErrorWithFormat ("'%d' is not a currently valid breakpoint id.\n", cur_bp_id.GetBreakpointID());
2415 result.SetStatus (eReturnStatusFailed);
2416 }
2417 }
2418 }
2419}