blob: 6f9250680cab8ca6b46671eeb6d4180946df3171 [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
Chris Lattner30fdc8d2010-06-08 16:52:24 +000010// C Includes
11// C++ Includes
Eugene Zelenko9e85e5a2016-02-18 22:39:14 +000012#include <vector>
13
Chris Lattner30fdc8d2010-06-08 16:52:24 +000014// Other libraries and framework includes
15// Project includes
Eugene Zelenko9e85e5a2016-02-18 22:39:14 +000016#include "CommandObjectBreakpoint.h"
17#include "CommandObjectBreakpointCommand.h"
Chris Lattner30fdc8d2010-06-08 16:52:24 +000018#include "lldb/Breakpoint/Breakpoint.h"
19#include "lldb/Breakpoint/BreakpointIDList.h"
20#include "lldb/Breakpoint/BreakpointLocation.h"
Vince Harron5275aaa2015-01-15 20:08:35 +000021#include "lldb/Host/StringConvert.h"
Jim Ingham40af72e2010-06-15 19:49:27 +000022#include "lldb/Interpreter/Options.h"
Zachary Turner32abc6e2015-03-03 19:23:09 +000023#include "lldb/Interpreter/OptionValueBoolean.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"
Jim Ingham0e0984e2015-09-02 01:06:46 +000030#include "lldb/Target/Language.h"
Chris Lattner30fdc8d2010-06-08 16:52:24 +000031#include "lldb/Target/Target.h"
32#include "lldb/Interpreter/CommandCompletions.h"
Jason Molendab57e4a12013-11-04 09:33:30 +000033#include "lldb/Target/StackFrame.h"
Jim Ingham1b54c882010-06-16 02:00:15 +000034#include "lldb/Target/Thread.h"
35#include "lldb/Target/ThreadSpec.h"
Chris Lattner30fdc8d2010-06-08 16:52:24 +000036
37using namespace lldb;
38using namespace lldb_private;
39
40static void
Jim Ingham85e8b812011-02-19 02:53:09 +000041AddBreakpointDescription (Stream *s, Breakpoint *bp, lldb::DescriptionLevel level)
Chris Lattner30fdc8d2010-06-08 16:52:24 +000042{
43 s->IndentMore();
44 bp->GetDescription (s, level, true);
45 s->IndentLess();
46 s->EOL();
47}
48
49//-------------------------------------------------------------------------
Jim Ingham5a988412012-06-08 21:56:10 +000050// CommandObjectBreakpointSet
Chris Lattner30fdc8d2010-06-08 16:52:24 +000051//-------------------------------------------------------------------------
52
Jim Ingham5a988412012-06-08 21:56:10 +000053class CommandObjectBreakpointSet : public CommandObjectParsed
Chris Lattner30fdc8d2010-06-08 16:52:24 +000054{
Jim Ingham5a988412012-06-08 21:56:10 +000055public:
Jim Ingham5a988412012-06-08 21:56:10 +000056 typedef enum BreakpointSetType
57 {
58 eSetTypeInvalid,
59 eSetTypeFileAndLine,
60 eSetTypeAddress,
61 eSetTypeFunctionName,
62 eSetTypeFunctionRegexp,
63 eSetTypeSourceRegexp,
64 eSetTypeException
65 } BreakpointSetType;
Chris Lattner30fdc8d2010-06-08 16:52:24 +000066
Jim Ingham5a988412012-06-08 21:56:10 +000067 CommandObjectBreakpointSet (CommandInterpreter &interpreter) :
68 CommandObjectParsed (interpreter,
69 "breakpoint set",
70 "Sets a breakpoint or set of breakpoints in the executable.",
71 "breakpoint set <cmd-options>"),
Todd Fialae1cfbc72016-08-11 23:51:28 +000072 m_options ()
Jim Ingham5a988412012-06-08 21:56:10 +000073 {
74 }
75
Eugene Zelenko9e85e5a2016-02-18 22:39:14 +000076 ~CommandObjectBreakpointSet() override = default;
Jim Ingham5a988412012-06-08 21:56:10 +000077
Bruce Mitchener13d21e92015-10-07 16:56:17 +000078 Options *
79 GetOptions () override
Jim Ingham5a988412012-06-08 21:56:10 +000080 {
81 return &m_options;
82 }
83
84 class CommandOptions : public Options
85 {
86 public:
Todd Fialae1cfbc72016-08-11 23:51:28 +000087 CommandOptions () :
88 Options (),
Jim Ingham5a988412012-06-08 21:56:10 +000089 m_condition (),
90 m_filenames (),
91 m_line_num (0),
92 m_column (0),
Jim Ingham5a988412012-06-08 21:56:10 +000093 m_func_names (),
94 m_func_name_type_mask (eFunctionNameTypeNone),
95 m_func_regexp (),
96 m_source_text_regexp(),
97 m_modules (),
98 m_load_addr(),
99 m_ignore_count (0),
100 m_thread_id(LLDB_INVALID_THREAD_ID),
101 m_thread_index (UINT32_MAX),
102 m_thread_name(),
103 m_queue_name(),
104 m_catch_bp (false),
Greg Clayton1f746072012-08-29 21:13:06 +0000105 m_throw_bp (true),
Greg Claytoneb023e72013-10-11 19:48:25 +0000106 m_hardware (false),
Jim Inghama72b31c2015-04-22 19:42:18 +0000107 m_exception_language (eLanguageTypeUnknown),
Dawn Perchik23b1dec2015-07-21 22:05:07 +0000108 m_language (lldb::eLanguageTypeUnknown),
Jim Inghamca36cd12012-10-05 19:16:31 +0000109 m_skip_prologue (eLazyBoolCalculate),
Jim Inghame7320522015-02-12 17:37:46 +0000110 m_one_shot (false),
Ilia K055ad9b2015-05-18 13:41:01 +0000111 m_all_files (false),
112 m_move_to_nearest_code (eLazyBoolCalculate)
Jim Ingham5a988412012-06-08 21:56:10 +0000113 {
114 }
115
Eugene Zelenko9e85e5a2016-02-18 22:39:14 +0000116 ~CommandOptions() override = default;
Jim Ingham5a988412012-06-08 21:56:10 +0000117
Bruce Mitchener13d21e92015-10-07 16:56:17 +0000118 Error
Todd Fialae1cfbc72016-08-11 23:51:28 +0000119 SetOptionValue (uint32_t option_idx, const char *option_arg,
120 ExecutionContext *execution_context) override
Jim Ingham5a988412012-06-08 21:56:10 +0000121 {
122 Error error;
Greg Clayton3bcdfc02012-12-04 00:32:51 +0000123 const int short_option = m_getopt_table[option_idx].val;
Jim Ingham5a988412012-06-08 21:56:10 +0000124
125 switch (short_option)
126 {
127 case 'a':
Greg Claytonb9d5df52012-12-06 22:49:16 +0000128 {
Todd Fialae1cfbc72016-08-11 23:51:28 +0000129 m_load_addr =
130 Args::StringToAddress(execution_context, option_arg,
131 LLDB_INVALID_ADDRESS, &error);
Greg Claytonb9d5df52012-12-06 22:49:16 +0000132 }
Jim Ingham5a988412012-06-08 21:56:10 +0000133 break;
134
Jim Inghame7320522015-02-12 17:37:46 +0000135 case 'A':
136 m_all_files = true;
137 break;
138
Jim Inghamca36cd12012-10-05 19:16:31 +0000139 case 'b':
140 m_func_names.push_back (option_arg);
141 m_func_name_type_mask |= eFunctionNameTypeBase;
142 break;
143
Jim Ingham5a988412012-06-08 21:56:10 +0000144 case 'C':
Jim Ingham63129912015-03-16 22:47:38 +0000145 {
146 bool success;
147 m_column = StringConvert::ToUInt32 (option_arg, 0, 0, &success);
148 if (!success)
149 error.SetErrorStringWithFormat("invalid column number: %s", option_arg);
Jim Ingham5a988412012-06-08 21:56:10 +0000150 break;
Jim Ingham63129912015-03-16 22:47:38 +0000151 }
Eugene Zelenko9e85e5a2016-02-18 22:39:14 +0000152
Jim Ingham5a988412012-06-08 21:56:10 +0000153 case 'c':
154 m_condition.assign(option_arg);
155 break;
156
Jim Ingham33df7cd2014-12-06 01:28:03 +0000157 case 'D':
158 m_use_dummy = true;
159 break;
160
Jim Ingham5a988412012-06-08 21:56:10 +0000161 case 'E':
162 {
Jim Ingham0e0984e2015-09-02 01:06:46 +0000163 LanguageType language = Language::GetLanguageTypeFromString (option_arg);
Jim Ingham5a988412012-06-08 21:56:10 +0000164
165 switch (language)
166 {
167 case eLanguageTypeC89:
168 case eLanguageTypeC:
169 case eLanguageTypeC99:
Bruce Mitchener1d0089f2014-07-03 00:49:08 +0000170 case eLanguageTypeC11:
Jim Inghama72b31c2015-04-22 19:42:18 +0000171 m_exception_language = eLanguageTypeC;
Jim Ingham5a988412012-06-08 21:56:10 +0000172 break;
173 case eLanguageTypeC_plus_plus:
Bruce Mitchener1d0089f2014-07-03 00:49:08 +0000174 case eLanguageTypeC_plus_plus_03:
175 case eLanguageTypeC_plus_plus_11:
Bruce Mitchener2ba84a62015-02-06 06:46:52 +0000176 case eLanguageTypeC_plus_plus_14:
Jim Inghama72b31c2015-04-22 19:42:18 +0000177 m_exception_language = eLanguageTypeC_plus_plus;
Jim Ingham5a988412012-06-08 21:56:10 +0000178 break;
179 case eLanguageTypeObjC:
Jim Inghama72b31c2015-04-22 19:42:18 +0000180 m_exception_language = eLanguageTypeObjC;
Jim Ingham5a988412012-06-08 21:56:10 +0000181 break;
182 case eLanguageTypeObjC_plus_plus:
183 error.SetErrorStringWithFormat ("Set exception breakpoints separately for c++ and objective-c");
184 break;
185 case eLanguageTypeUnknown:
186 error.SetErrorStringWithFormat ("Unknown language type: '%s' for exception breakpoint", option_arg);
187 break;
188 default:
189 error.SetErrorStringWithFormat ("Unsupported language type: '%s' for exception breakpoint", option_arg);
190 }
191 }
192 break;
Jim Inghamca36cd12012-10-05 19:16:31 +0000193
194 case 'f':
195 m_filenames.AppendIfUnique (FileSpec(option_arg, false));
196 break;
197
198 case 'F':
199 m_func_names.push_back (option_arg);
200 m_func_name_type_mask |= eFunctionNameTypeFull;
201 break;
202
Jim Ingham5a988412012-06-08 21:56:10 +0000203 case 'h':
Greg Claytoneb023e72013-10-11 19:48:25 +0000204 {
205 bool success;
206 m_catch_bp = Args::StringToBoolean (option_arg, true, &success);
207 if (!success)
208 error.SetErrorStringWithFormat ("Invalid boolean value for on-catch option: '%s'", option_arg);
209 }
210 break;
211
212 case 'H':
213 m_hardware = true;
214 break;
215
Jim Inghamca36cd12012-10-05 19:16:31 +0000216 case 'i':
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;
Jim Inghamca36cd12012-10-05 19:16:31 +0000221
Jim Ingham5a988412012-06-08 21:56:10 +0000222 case 'K':
223 {
224 bool success;
225 bool value;
226 value = Args::StringToBoolean (option_arg, true, &success);
227 if (value)
228 m_skip_prologue = eLazyBoolYes;
229 else
230 m_skip_prologue = eLazyBoolNo;
231
232 if (!success)
233 error.SetErrorStringWithFormat ("Invalid boolean value for skip prologue option: '%s'", option_arg);
234 }
235 break;
Jim Inghamca36cd12012-10-05 19:16:31 +0000236
237 case 'l':
Jim Ingham63129912015-03-16 22:47:38 +0000238 {
239 bool success;
240 m_line_num = StringConvert::ToUInt32 (option_arg, 0, 0, &success);
241 if (!success)
242 error.SetErrorStringWithFormat ("invalid line number: %s.", option_arg);
Jim Inghamca36cd12012-10-05 19:16:31 +0000243 break;
Jim Ingham63129912015-03-16 22:47:38 +0000244 }
Ilia K055ad9b2015-05-18 13:41:01 +0000245
Dawn Perchik23b1dec2015-07-21 22:05:07 +0000246 case 'L':
Jim Ingham0e0984e2015-09-02 01:06:46 +0000247 m_language = Language::GetLanguageTypeFromString (option_arg);
Dawn Perchik23b1dec2015-07-21 22:05:07 +0000248 if (m_language == eLanguageTypeUnknown)
249 error.SetErrorStringWithFormat ("Unknown language type: '%s' for breakpoint", option_arg);
250 break;
251
Ilia K055ad9b2015-05-18 13:41:01 +0000252 case 'm':
253 {
254 bool success;
255 bool value;
256 value = Args::StringToBoolean (option_arg, true, &success);
257 if (value)
258 m_move_to_nearest_code = eLazyBoolYes;
259 else
260 m_move_to_nearest_code = eLazyBoolNo;
261
262 if (!success)
263 error.SetErrorStringWithFormat ("Invalid boolean value for move-to-nearest-code option: '%s'", option_arg);
264 break;
265 }
266
Jim Inghamca36cd12012-10-05 19:16:31 +0000267 case 'M':
268 m_func_names.push_back (option_arg);
269 m_func_name_type_mask |= eFunctionNameTypeMethod;
270 break;
271
272 case 'n':
273 m_func_names.push_back (option_arg);
274 m_func_name_type_mask |= eFunctionNameTypeAuto;
275 break;
276
Jim Ingham5e09c8c2014-12-16 23:40:14 +0000277 case 'N':
278 if (BreakpointID::StringIsBreakpointName(option_arg, error))
279 m_breakpoint_names.push_back (option_arg);
Jim Ingham5e09c8c2014-12-16 23:40:14 +0000280 break;
281
Jim Ingham24111672016-03-09 18:59:13 +0000282 case 'R':
283 {
Jim Ingham24111672016-03-09 18:59:13 +0000284 lldb::addr_t tmp_offset_addr;
Todd Fialae1cfbc72016-08-11 23:51:28 +0000285 tmp_offset_addr =
286 Args::StringToAddress(execution_context, option_arg,
287 0, &error);
Jim Ingham24111672016-03-09 18:59:13 +0000288 if (error.Success())
289 m_offset_addr = tmp_offset_addr;
290 }
291 break;
292
Jim Inghamca36cd12012-10-05 19:16:31 +0000293 case 'o':
294 m_one_shot = true;
295 break;
296
Jim Inghama72b31c2015-04-22 19:42:18 +0000297 case 'O':
298 m_exception_extra_args.AppendArgument ("-O");
299 m_exception_extra_args.AppendArgument (option_arg);
300 break;
301
Jim Inghamca36cd12012-10-05 19:16:31 +0000302 case 'p':
303 m_source_text_regexp.assign (option_arg);
304 break;
305
306 case 'q':
307 m_queue_name.assign (option_arg);
308 break;
309
310 case 'r':
311 m_func_regexp.assign (option_arg);
312 break;
313
314 case 's':
Jim Inghamca36cd12012-10-05 19:16:31 +0000315 m_modules.AppendIfUnique (FileSpec (option_arg, false));
316 break;
Jim Inghamca36cd12012-10-05 19:16:31 +0000317
318 case 'S':
319 m_func_names.push_back (option_arg);
320 m_func_name_type_mask |= eFunctionNameTypeSelector;
321 break;
322
323 case 't' :
Vince Harron5275aaa2015-01-15 20:08:35 +0000324 m_thread_id = StringConvert::ToUInt64(option_arg, LLDB_INVALID_THREAD_ID, 0);
Jim Inghamca36cd12012-10-05 19:16:31 +0000325 if (m_thread_id == LLDB_INVALID_THREAD_ID)
326 error.SetErrorStringWithFormat ("invalid thread id string '%s'", option_arg);
Eugene Zelenko9e85e5a2016-02-18 22:39:14 +0000327 break;
Jim Inghamca36cd12012-10-05 19:16:31 +0000328
329 case 'T':
330 m_thread_name.assign (option_arg);
331 break;
332
333 case 'w':
334 {
335 bool success;
336 m_throw_bp = Args::StringToBoolean (option_arg, true, &success);
337 if (!success)
338 error.SetErrorStringWithFormat ("Invalid boolean value for on-throw option: '%s'", option_arg);
339 }
340 break;
341
342 case 'x':
Vince Harron5275aaa2015-01-15 20:08:35 +0000343 m_thread_index = StringConvert::ToUInt32(option_arg, UINT32_MAX, 0);
Jim Inghamca36cd12012-10-05 19:16:31 +0000344 if (m_thread_id == UINT32_MAX)
345 error.SetErrorStringWithFormat ("invalid thread index string '%s'", option_arg);
Eugene Zelenko9e85e5a2016-02-18 22:39:14 +0000346 break;
Jim Inghamca36cd12012-10-05 19:16:31 +0000347
Jim Ingham76bb8d62016-04-28 01:40:57 +0000348 case 'X':
349 m_source_regex_func_names.insert(option_arg);
350 break;
351
Jim Ingham5a988412012-06-08 21:56:10 +0000352 default:
353 error.SetErrorStringWithFormat ("unrecognized option '%c'", short_option);
354 break;
355 }
356
357 return error;
358 }
Eugene Zelenko9e85e5a2016-02-18 22:39:14 +0000359
Jim Ingham5a988412012-06-08 21:56:10 +0000360 void
Todd Fialae1cfbc72016-08-11 23:51:28 +0000361 OptionParsingStarting (ExecutionContext *execution_context) override
Jim Ingham5a988412012-06-08 21:56:10 +0000362 {
363 m_condition.clear();
364 m_filenames.Clear();
365 m_line_num = 0;
366 m_column = 0;
367 m_func_names.clear();
Greg Clayton1f746072012-08-29 21:13:06 +0000368 m_func_name_type_mask = eFunctionNameTypeNone;
Jim Ingham5a988412012-06-08 21:56:10 +0000369 m_func_regexp.clear();
Greg Clayton1f746072012-08-29 21:13:06 +0000370 m_source_text_regexp.clear();
Jim Ingham5a988412012-06-08 21:56:10 +0000371 m_modules.Clear();
Greg Clayton1f746072012-08-29 21:13:06 +0000372 m_load_addr = LLDB_INVALID_ADDRESS;
Jim Ingham24111672016-03-09 18:59:13 +0000373 m_offset_addr = 0;
Jim Ingham5a988412012-06-08 21:56:10 +0000374 m_ignore_count = 0;
375 m_thread_id = LLDB_INVALID_THREAD_ID;
376 m_thread_index = UINT32_MAX;
377 m_thread_name.clear();
378 m_queue_name.clear();
Jim Ingham5a988412012-06-08 21:56:10 +0000379 m_catch_bp = false;
380 m_throw_bp = true;
Greg Claytoneb023e72013-10-11 19:48:25 +0000381 m_hardware = false;
Jim Inghama72b31c2015-04-22 19:42:18 +0000382 m_exception_language = eLanguageTypeUnknown;
Dawn Perchik23b1dec2015-07-21 22:05:07 +0000383 m_language = lldb::eLanguageTypeUnknown;
Jim Ingham5a988412012-06-08 21:56:10 +0000384 m_skip_prologue = eLazyBoolCalculate;
Jim Inghamca36cd12012-10-05 19:16:31 +0000385 m_one_shot = false;
Jim Ingham33df7cd2014-12-06 01:28:03 +0000386 m_use_dummy = false;
Jim Ingham5e09c8c2014-12-16 23:40:14 +0000387 m_breakpoint_names.clear();
Jim Inghame7320522015-02-12 17:37:46 +0000388 m_all_files = false;
Jim Inghama72b31c2015-04-22 19:42:18 +0000389 m_exception_extra_args.Clear();
Ilia K055ad9b2015-05-18 13:41:01 +0000390 m_move_to_nearest_code = eLazyBoolCalculate;
Jim Ingham76bb8d62016-04-28 01:40:57 +0000391 m_source_regex_func_names.clear();
Jim Ingham5a988412012-06-08 21:56:10 +0000392 }
393
394 const OptionDefinition*
Bruce Mitchener13d21e92015-10-07 16:56:17 +0000395 GetDefinitions () override
Jim Ingham5a988412012-06-08 21:56:10 +0000396 {
397 return g_option_table;
398 }
399
400 // Options table: Required for subclasses of Options.
401
402 static OptionDefinition g_option_table[];
403
404 // Instance variables to hold the values for command options.
405
406 std::string m_condition;
407 FileSpecList m_filenames;
408 uint32_t m_line_num;
409 uint32_t m_column;
Jim Ingham5a988412012-06-08 21:56:10 +0000410 std::vector<std::string> m_func_names;
Jim Ingham5e09c8c2014-12-16 23:40:14 +0000411 std::vector<std::string> m_breakpoint_names;
Jim Ingham5a988412012-06-08 21:56:10 +0000412 uint32_t m_func_name_type_mask;
413 std::string m_func_regexp;
414 std::string m_source_text_regexp;
415 FileSpecList m_modules;
416 lldb::addr_t m_load_addr;
Jim Ingham24111672016-03-09 18:59:13 +0000417 lldb::addr_t m_offset_addr;
Jim Ingham5a988412012-06-08 21:56:10 +0000418 uint32_t m_ignore_count;
419 lldb::tid_t m_thread_id;
420 uint32_t m_thread_index;
421 std::string m_thread_name;
422 std::string m_queue_name;
423 bool m_catch_bp;
424 bool m_throw_bp;
Greg Claytoneb023e72013-10-11 19:48:25 +0000425 bool m_hardware; // Request to use hardware breakpoints
Jim Inghama72b31c2015-04-22 19:42:18 +0000426 lldb::LanguageType m_exception_language;
Dawn Perchik23b1dec2015-07-21 22:05:07 +0000427 lldb::LanguageType m_language;
Jim Ingham5a988412012-06-08 21:56:10 +0000428 LazyBool m_skip_prologue;
Jim Inghamca36cd12012-10-05 19:16:31 +0000429 bool m_one_shot;
Jim Ingham33df7cd2014-12-06 01:28:03 +0000430 bool m_use_dummy;
Jim Inghame7320522015-02-12 17:37:46 +0000431 bool m_all_files;
Jim Inghama72b31c2015-04-22 19:42:18 +0000432 Args m_exception_extra_args;
Ilia K055ad9b2015-05-18 13:41:01 +0000433 LazyBool m_move_to_nearest_code;
Jim Ingham76bb8d62016-04-28 01:40:57 +0000434 std::unordered_set<std::string> m_source_regex_func_names;
Jim Ingham5a988412012-06-08 21:56:10 +0000435 };
436
437protected:
Bruce Mitchener13d21e92015-10-07 16:56:17 +0000438 bool
Jim Ingham5a988412012-06-08 21:56:10 +0000439 DoExecute (Args& command,
Bruce Mitchener13d21e92015-10-07 16:56:17 +0000440 CommandReturnObject &result) override
Jim Ingham5a988412012-06-08 21:56:10 +0000441 {
Jim Ingham33df7cd2014-12-06 01:28:03 +0000442 Target *target = GetSelectedOrDummyTarget(m_options.m_use_dummy);
443
Jim Ingham893c9322014-11-22 01:42:44 +0000444 if (target == nullptr)
Jim Ingham5a988412012-06-08 21:56:10 +0000445 {
446 result.AppendError ("Invalid target. Must set target before setting breakpoints (see 'target create' command).");
447 result.SetStatus (eReturnStatusFailed);
448 return false;
449 }
450
451 // The following are the various types of breakpoints that could be set:
452 // 1). -f -l -p [-s -g] (setting breakpoint by source location)
453 // 2). -a [-s -g] (setting breakpoint by address)
454 // 3). -n [-s -g] (setting breakpoint by function name)
455 // 4). -r [-s -g] (setting breakpoint by function name regular expression)
456 // 5). -p -f (setting a breakpoint by comparing a reg-exp to source text)
457 // 6). -E [-w -h] (setting a breakpoint for exceptions for a given language.)
458
459 BreakpointSetType break_type = eSetTypeInvalid;
460
461 if (m_options.m_line_num != 0)
462 break_type = eSetTypeFileAndLine;
463 else if (m_options.m_load_addr != LLDB_INVALID_ADDRESS)
464 break_type = eSetTypeAddress;
465 else if (!m_options.m_func_names.empty())
466 break_type = eSetTypeFunctionName;
467 else if (!m_options.m_func_regexp.empty())
468 break_type = eSetTypeFunctionRegexp;
469 else if (!m_options.m_source_text_regexp.empty())
470 break_type = eSetTypeSourceRegexp;
Jim Inghama72b31c2015-04-22 19:42:18 +0000471 else if (m_options.m_exception_language != eLanguageTypeUnknown)
Jim Ingham5a988412012-06-08 21:56:10 +0000472 break_type = eSetTypeException;
473
Eugene Zelenko9e85e5a2016-02-18 22:39:14 +0000474 Breakpoint *bp = nullptr;
Jim Ingham5a988412012-06-08 21:56:10 +0000475 FileSpec module_spec;
Jim Ingham5a988412012-06-08 21:56:10 +0000476 const bool internal = false;
Jim Ingham24111672016-03-09 18:59:13 +0000477
478 // If the user didn't specify skip-prologue, having an offset should turn that off.
479 if (m_options.m_offset_addr != 0 && m_options.m_skip_prologue == eLazyBoolCalculate)
480 m_options.m_skip_prologue = eLazyBoolNo;
Jim Ingham5a988412012-06-08 21:56:10 +0000481
Jim Ingham5a988412012-06-08 21:56:10 +0000482 switch (break_type)
483 {
484 case eSetTypeFileAndLine: // Breakpoint by source position
485 {
486 FileSpec file;
Greg Claytonc7bece562013-01-25 18:06:21 +0000487 const size_t num_files = m_options.m_filenames.GetSize();
Jim Ingham5a988412012-06-08 21:56:10 +0000488 if (num_files == 0)
489 {
490 if (!GetDefaultFile (target, file, result))
491 {
492 result.AppendError("No file supplied and no default file available.");
493 result.SetStatus (eReturnStatusFailed);
494 return false;
495 }
496 }
497 else if (num_files > 1)
498 {
499 result.AppendError("Only one file at a time is allowed for file and line breakpoints.");
500 result.SetStatus (eReturnStatusFailed);
501 return false;
502 }
503 else
504 file = m_options.m_filenames.GetFileSpecAtIndex(0);
Greg Clayton1f746072012-08-29 21:13:06 +0000505
506 // Only check for inline functions if
507 LazyBool check_inlines = eLazyBoolCalculate;
508
Jim Ingham5a988412012-06-08 21:56:10 +0000509 bp = target->CreateBreakpoint (&(m_options.m_modules),
510 file,
511 m_options.m_line_num,
Jim Ingham24111672016-03-09 18:59:13 +0000512 m_options.m_offset_addr,
Greg Clayton1f746072012-08-29 21:13:06 +0000513 check_inlines,
Jim Ingham5a988412012-06-08 21:56:10 +0000514 m_options.m_skip_prologue,
Greg Claytoneb023e72013-10-11 19:48:25 +0000515 internal,
Ilia K055ad9b2015-05-18 13:41:01 +0000516 m_options.m_hardware,
517 m_options.m_move_to_nearest_code).get();
Jim Ingham5a988412012-06-08 21:56:10 +0000518 }
519 break;
520
521 case eSetTypeAddress: // Breakpoint by address
Jim Ingham055a08a2015-11-17 03:39:13 +0000522 {
523 // If a shared library has been specified, make an lldb_private::Address with the library, and
524 // use that. That way the address breakpoint will track the load location of the library.
525 size_t num_modules_specified = m_options.m_modules.GetSize();
526 if (num_modules_specified == 1)
527 {
528 const FileSpec *file_spec = m_options.m_modules.GetFileSpecPointerAtIndex(0);
529 bp = target->CreateAddressInModuleBreakpoint (m_options.m_load_addr,
530 internal,
531 file_spec,
532 m_options.m_hardware).get();
533 }
534 else if (num_modules_specified == 0)
535 {
536 bp = target->CreateBreakpoint (m_options.m_load_addr,
537 internal,
538 m_options.m_hardware).get();
539 }
540 else
541 {
542 result.AppendError("Only one shared library can be specified for address breakpoints.");
543 result.SetStatus(eReturnStatusFailed);
544 return false;
545 }
Jim Ingham5a988412012-06-08 21:56:10 +0000546 break;
Jim Ingham055a08a2015-11-17 03:39:13 +0000547 }
Jim Ingham5a988412012-06-08 21:56:10 +0000548 case eSetTypeFunctionName: // Breakpoint by function name
549 {
550 uint32_t name_type_mask = m_options.m_func_name_type_mask;
551
552 if (name_type_mask == 0)
553 name_type_mask = eFunctionNameTypeAuto;
554
555 bp = target->CreateBreakpoint (&(m_options.m_modules),
556 &(m_options.m_filenames),
557 m_options.m_func_names,
558 name_type_mask,
Dawn Perchik23b1dec2015-07-21 22:05:07 +0000559 m_options.m_language,
Jim Ingham24111672016-03-09 18:59:13 +0000560 m_options.m_offset_addr,
Jim Ingham5a988412012-06-08 21:56:10 +0000561 m_options.m_skip_prologue,
Greg Claytoneb023e72013-10-11 19:48:25 +0000562 internal,
563 m_options.m_hardware).get();
Jim Ingham5a988412012-06-08 21:56:10 +0000564 }
565 break;
566
567 case eSetTypeFunctionRegexp: // Breakpoint by regular expression function name
568 {
569 RegularExpression regexp(m_options.m_func_regexp.c_str());
570 if (!regexp.IsValid())
571 {
572 char err_str[1024];
573 regexp.GetErrorAsCString(err_str, sizeof(err_str));
574 result.AppendErrorWithFormat("Function name regular expression could not be compiled: \"%s\"",
575 err_str);
576 result.SetStatus (eReturnStatusFailed);
577 return false;
578 }
579
580 bp = target->CreateFuncRegexBreakpoint (&(m_options.m_modules),
581 &(m_options.m_filenames),
582 regexp,
Jim Ingham0fcdac32015-11-06 22:48:59 +0000583 m_options.m_language,
Jim Ingham5a988412012-06-08 21:56:10 +0000584 m_options.m_skip_prologue,
Greg Claytoneb023e72013-10-11 19:48:25 +0000585 internal,
586 m_options.m_hardware).get();
Jim Ingham5a988412012-06-08 21:56:10 +0000587 }
588 break;
589 case eSetTypeSourceRegexp: // Breakpoint by regexp on source text.
590 {
Greg Claytonc7bece562013-01-25 18:06:21 +0000591 const size_t num_files = m_options.m_filenames.GetSize();
Jim Ingham5a988412012-06-08 21:56:10 +0000592
Jim Inghame7320522015-02-12 17:37:46 +0000593 if (num_files == 0 && !m_options.m_all_files)
Jim Ingham5a988412012-06-08 21:56:10 +0000594 {
595 FileSpec file;
596 if (!GetDefaultFile (target, file, result))
597 {
598 result.AppendError ("No files provided and could not find default file.");
599 result.SetStatus (eReturnStatusFailed);
600 return false;
601 }
602 else
603 {
604 m_options.m_filenames.Append (file);
605 }
606 }
607
608 RegularExpression regexp(m_options.m_source_text_regexp.c_str());
609 if (!regexp.IsValid())
610 {
611 char err_str[1024];
612 regexp.GetErrorAsCString(err_str, sizeof(err_str));
613 result.AppendErrorWithFormat("Source text regular expression could not be compiled: \"%s\"",
614 err_str);
615 result.SetStatus (eReturnStatusFailed);
616 return false;
617 }
Greg Claytoneb023e72013-10-11 19:48:25 +0000618 bp = target->CreateSourceRegexBreakpoint (&(m_options.m_modules),
619 &(m_options.m_filenames),
Jim Ingham76bb8d62016-04-28 01:40:57 +0000620 m_options.m_source_regex_func_names,
Greg Claytoneb023e72013-10-11 19:48:25 +0000621 regexp,
622 internal,
Ilia K055ad9b2015-05-18 13:41:01 +0000623 m_options.m_hardware,
624 m_options.m_move_to_nearest_code).get();
Jim Ingham5a988412012-06-08 21:56:10 +0000625 }
626 break;
627 case eSetTypeException:
628 {
Jim Inghama72b31c2015-04-22 19:42:18 +0000629 Error precond_error;
630 bp = target->CreateExceptionBreakpoint (m_options.m_exception_language,
Greg Claytoneb023e72013-10-11 19:48:25 +0000631 m_options.m_catch_bp,
632 m_options.m_throw_bp,
Jim Inghama72b31c2015-04-22 19:42:18 +0000633 internal,
634 &m_options.m_exception_extra_args,
635 &precond_error).get();
636 if (precond_error.Fail())
637 {
638 result.AppendErrorWithFormat("Error setting extra exception arguments: %s",
639 precond_error.AsCString());
640 target->RemoveBreakpointByID(bp->GetID());
641 result.SetStatus(eReturnStatusFailed);
642 return false;
643 }
Jim Ingham5a988412012-06-08 21:56:10 +0000644 }
645 break;
646 default:
647 break;
648 }
649
650 // Now set the various options that were passed in:
651 if (bp)
652 {
653 if (m_options.m_thread_id != LLDB_INVALID_THREAD_ID)
654 bp->SetThreadID (m_options.m_thread_id);
655
656 if (m_options.m_thread_index != UINT32_MAX)
657 bp->GetOptions()->GetThreadSpec()->SetIndex(m_options.m_thread_index);
658
659 if (!m_options.m_thread_name.empty())
660 bp->GetOptions()->GetThreadSpec()->SetName(m_options.m_thread_name.c_str());
661
662 if (!m_options.m_queue_name.empty())
663 bp->GetOptions()->GetThreadSpec()->SetQueueName(m_options.m_queue_name.c_str());
664
665 if (m_options.m_ignore_count != 0)
666 bp->GetOptions()->SetIgnoreCount(m_options.m_ignore_count);
667
668 if (!m_options.m_condition.empty())
669 bp->GetOptions()->SetCondition(m_options.m_condition.c_str());
Jim Ingham5e09c8c2014-12-16 23:40:14 +0000670
671 if (!m_options.m_breakpoint_names.empty())
672 {
673 Error error; // We don't need to check the error here, since the option parser checked it...
674 for (auto name : m_options.m_breakpoint_names)
675 bp->AddName(name.c_str(), error);
676 }
Jim Inghamca36cd12012-10-05 19:16:31 +0000677
678 bp->SetOneShot (m_options.m_one_shot);
Jim Ingham5a988412012-06-08 21:56:10 +0000679 }
680
681 if (bp)
682 {
683 Stream &output_stream = result.GetOutputStream();
Jim Ingham1391cc72012-09-22 00:04:04 +0000684 const bool show_locations = false;
685 bp->GetDescription(&output_stream, lldb::eDescriptionLevelInitial, show_locations);
Jim Ingham4aeb1982014-12-19 19:45:31 +0000686 if (target == m_interpreter.GetDebugger().GetDummyTarget())
687 output_stream.Printf ("Breakpoint set in dummy target, will get copied into future targets.\n");
688 else
689 {
690 // Don't print out this warning for exception breakpoints. They can get set before the target
691 // is set, but we won't know how to actually set the breakpoint till we run.
692 if (bp->GetNumLocations() == 0 && break_type != eSetTypeException)
693 {
694 output_stream.Printf ("WARNING: Unable to resolve breakpoint to any actual locations.\n");
695 }
696 }
Jim Ingham5a988412012-06-08 21:56:10 +0000697 result.SetStatus (eReturnStatusSuccessFinishResult);
698 }
699 else if (!bp)
700 {
701 result.AppendError ("Breakpoint creation failed: No breakpoint created.");
702 result.SetStatus (eReturnStatusFailed);
703 }
704
705 return result.Succeeded();
706 }
707
708private:
709 bool
710 GetDefaultFile (Target *target, FileSpec &file, CommandReturnObject &result)
711 {
712 uint32_t default_line;
713 // First use the Source Manager's default file.
714 // Then use the current stack frame's file.
715 if (!target->GetSourceManager().GetDefaultFileAndLine(file, default_line))
716 {
Jason Molendab57e4a12013-11-04 09:33:30 +0000717 StackFrame *cur_frame = m_exe_ctx.GetFramePtr();
Eugene Zelenko9e85e5a2016-02-18 22:39:14 +0000718 if (cur_frame == nullptr)
Jim Ingham5a988412012-06-08 21:56:10 +0000719 {
720 result.AppendError ("No selected frame to use to find the default file.");
721 result.SetStatus (eReturnStatusFailed);
722 return false;
723 }
724 else if (!cur_frame->HasDebugInformation())
725 {
726 result.AppendError ("Cannot use the selected frame to find the default file, it has no debug info.");
727 result.SetStatus (eReturnStatusFailed);
728 return false;
729 }
730 else
731 {
732 const SymbolContext &sc = cur_frame->GetSymbolContext (eSymbolContextLineEntry);
733 if (sc.line_entry.file)
734 {
735 file = sc.line_entry.file;
736 }
737 else
738 {
739 result.AppendError ("Can't find the file for the selected frame to use as the default file.");
740 result.SetStatus (eReturnStatusFailed);
741 return false;
742 }
743 }
744 }
745 return true;
746 }
747
748 CommandOptions m_options;
749};
Eugene Zelenko9e85e5a2016-02-18 22:39:14 +0000750
Johnny Chen6943e7c2012-05-08 00:43:20 +0000751// If an additional option set beyond LLDB_OPTION_SET_10 is added, make sure to
752// update the numbers passed to LLDB_OPT_SET_FROM_TO(...) appropriately.
Johnny Chen4ab2e6b2012-05-07 23:23:41 +0000753#define LLDB_OPT_FILE ( LLDB_OPT_SET_FROM_TO(1, 9) & ~LLDB_OPT_SET_2 )
754#define LLDB_OPT_NOT_10 ( LLDB_OPT_SET_FROM_TO(1, 10) & ~LLDB_OPT_SET_10 )
Jim Inghama8558b62012-05-22 00:12:20 +0000755#define LLDB_OPT_SKIP_PROLOGUE ( LLDB_OPT_SET_1 | LLDB_OPT_SET_FROM_TO(3,8) )
Jim Ingham24111672016-03-09 18:59:13 +0000756#define LLDB_OPT_OFFSET_APPLIES (LLDB_OPT_SET_1 | LLDB_OPT_SET_FROM_TO(3,8) )
Ilia K055ad9b2015-05-18 13:41:01 +0000757#define LLDB_OPT_MOVE_TO_NEAREST_CODE ( LLDB_OPT_SET_1 | LLDB_OPT_SET_9 )
Jim Ingham0fcdac32015-11-06 22:48:59 +0000758#define LLDB_OPT_EXPR_LANGUAGE ( LLDB_OPT_SET_FROM_TO(3, 8) )
Jim Ingham87df91b2011-09-23 00:54:11 +0000759
Greg Claytone0d378b2011-03-24 21:19:54 +0000760OptionDefinition
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000761CommandObjectBreakpointSet::CommandOptions::g_option_table[] =
762{
Kate Stoneac9c3a62016-08-26 23:28:47 +0000763 // clang-format off
764 {LLDB_OPT_NOT_10, false, "shlib", 's', OptionParser::eRequiredArgument, nullptr, nullptr, CommandCompletions::eModuleCompletion, eArgTypeShlibName, "Set the breakpoint only in this shared library. Can repeat this option "
765 "multiple times to specify multiple shared libraries."},
766 {LLDB_OPT_SET_ALL, false, "ignore-count", 'i', OptionParser::eRequiredArgument, nullptr, nullptr, 0, eArgTypeCount, "Set the number of times this breakpoint is skipped before stopping." },
767 {LLDB_OPT_SET_ALL, false, "one-shot", 'o', OptionParser::eNoArgument, nullptr, nullptr, 0, eArgTypeNone, "The breakpoint is deleted the first time it causes a stop." },
768 {LLDB_OPT_SET_ALL, false, "condition", 'c', OptionParser::eRequiredArgument, nullptr, nullptr, 0, eArgTypeExpression, "The breakpoint stops only if this condition expression evaluates to true."},
769 {LLDB_OPT_SET_ALL, false, "thread-index", 'x', OptionParser::eRequiredArgument, nullptr, nullptr, 0, eArgTypeThreadIndex, "The breakpoint stops only for the thread whose indeX matches this argument."},
770 {LLDB_OPT_SET_ALL, false, "thread-id", 't', OptionParser::eRequiredArgument, nullptr, nullptr, 0, eArgTypeThreadID, "The breakpoint stops only for the thread whose TID matches this argument."},
771 {LLDB_OPT_SET_ALL, false, "thread-name", 'T', OptionParser::eRequiredArgument, nullptr, nullptr, 0, eArgTypeThreadName, "The breakpoint stops only for the thread whose thread name matches this "
772 "argument."},
773 {LLDB_OPT_SET_ALL, false, "hardware", 'H', OptionParser::eNoArgument, nullptr, nullptr, 0, eArgTypeNone, "Require the breakpoint to use hardware breakpoints."},
774 {LLDB_OPT_SET_ALL, false, "queue-name", 'q', OptionParser::eRequiredArgument, nullptr, nullptr, 0, eArgTypeQueueName, "The breakpoint stops only for threads in the queue whose name is given by "
775 "this argument."},
776 {LLDB_OPT_FILE, false, "file", 'f', OptionParser::eRequiredArgument, nullptr, nullptr, CommandCompletions::eSourceFileCompletion, eArgTypeFilename, "Specifies the source file in which to set this breakpoint. Note, by default "
777 "lldb only looks for files that are #included if they use the standard include "
778 "file extensions. To set breakpoints on .c/.cpp/.m/.mm files that are "
779 "#included, set target.inline-breakpoint-strategy to \"always\"."},
780 {LLDB_OPT_SET_1, true, "line", 'l', OptionParser::eRequiredArgument, nullptr, nullptr, 0, eArgTypeLineNum, "Specifies the line number on which to set this breakpoint."},
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000781
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000782 // Comment out this option for the moment, as we don't actually use it, but will in the future.
783 // This way users won't see it, but the infrastructure is left in place.
Eugene Zelenko9e85e5a2016-02-18 22:39:14 +0000784 // { 0, false, "column", 'C', OptionParser::eRequiredArgument, nullptr, "<column>",
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000785 // "Set the breakpoint by source location at this particular column."},
786
Kate Stoneac9c3a62016-08-26 23:28:47 +0000787 {LLDB_OPT_SET_2, true, "address", 'a', OptionParser::eRequiredArgument, nullptr, nullptr, 0, eArgTypeAddressOrExpression, "Set the breakpoint at the specified address. If the address maps uniquely to "
788 "a particular binary, then the address will be converted to a \"file\" "
789 "address, so that the breakpoint will track that binary+offset no matter where "
790 "the binary eventually loads. Alternately, if you also specify the module - "
791 "with the -s option - then the address will be treated as a file address in "
792 "that module, and resolved accordingly. Again, this will allow lldb to track "
793 "that offset on subsequent reloads. The module need not have been loaded at "
794 "the time you specify this breakpoint, and will get resolved when the module "
795 "is loaded."},
796 {LLDB_OPT_SET_3, true, "name", 'n', OptionParser::eRequiredArgument, nullptr, nullptr, CommandCompletions::eSymbolCompletion, eArgTypeFunctionName, "Set the breakpoint by function name. Can be repeated multiple times to make "
797 "one breakpoint for multiple names"},
798 {LLDB_OPT_SET_9, false, "source-regexp-function", 'X', OptionParser::eRequiredArgument, nullptr, nullptr, CommandCompletions::eSymbolCompletion, eArgTypeFunctionName, "When used with '-p' limits the source regex to source contained in the named "
799 "functions. Can be repeated multiple times."},
800 {LLDB_OPT_SET_4, true, "fullname", 'F', OptionParser::eRequiredArgument, nullptr, nullptr, CommandCompletions::eSymbolCompletion, eArgTypeFullName, "Set the breakpoint by fully qualified function names. For C++ this means "
801 "namespaces and all arguments, and for Objective C this means a full function "
802 "prototype with class and selector. Can be repeated multiple times to make "
803 "one breakpoint for multiple names."},
804 {LLDB_OPT_SET_5, true, "selector", 'S', OptionParser::eRequiredArgument, nullptr, nullptr, 0, eArgTypeSelector, "Set the breakpoint by ObjC selector name. Can be repeated multiple times to "
805 "make one breakpoint for multiple Selectors."},
806 {LLDB_OPT_SET_6, true, "method", 'M', OptionParser::eRequiredArgument, nullptr, nullptr, 0, eArgTypeMethod, "Set the breakpoint by C++ method names. Can be repeated multiple times to "
807 "make one breakpoint for multiple methods."},
808 {LLDB_OPT_SET_7, true, "func-regex", 'r', OptionParser::eRequiredArgument, nullptr, nullptr, 0, eArgTypeRegularExpression, "Set the breakpoint by function name, evaluating a regular-expression to find "
809 "the function name(s)."},
810 {LLDB_OPT_SET_8, true, "basename", 'b', OptionParser::eRequiredArgument, nullptr, nullptr, CommandCompletions::eSymbolCompletion, eArgTypeFunctionName, "Set the breakpoint by function basename (C++ namespaces and arguments will be "
811 "ignored). Can be repeated multiple times to make one breakpoint for multiple "
812 "symbols."},
813 {LLDB_OPT_SET_9, true, "source-pattern-regexp", 'p', OptionParser::eRequiredArgument, nullptr, nullptr, 0, eArgTypeRegularExpression, "Set the breakpoint by specifying a regular expression which is matched "
814 "against the source text in a source file or files specified with the -f "
815 "option. The -f option can be specified more than once. If no source files "
816 "are specified, uses the current \"default source file\". If you want to "
817 "match against all source files, pass the \"--all-files\" option."},
818 {LLDB_OPT_SET_9, false, "all-files", 'A', OptionParser::eNoArgument, nullptr, nullptr, 0, eArgTypeNone, "All files are searched for source pattern matches."},
819 {LLDB_OPT_SET_10, true, "language-exception", 'E', OptionParser::eRequiredArgument, nullptr, nullptr, 0, eArgTypeLanguage, "Set the breakpoint on exceptions thrown by the specified language (without "
820 "options, on throw but not catch.)"},
821 {LLDB_OPT_SET_10, false, "on-throw", 'w', OptionParser::eRequiredArgument, nullptr, nullptr, 0, eArgTypeBoolean, "Set the breakpoint on exception throW."},
822 {LLDB_OPT_SET_10, false, "on-catch", 'h', OptionParser::eRequiredArgument, nullptr, nullptr, 0, eArgTypeBoolean, "Set the breakpoint on exception catcH."},
Jim Ingham969795f2011-09-21 01:17:13 +0000823
Jim Inghama72b31c2015-04-22 19:42:18 +0000824// Don't add this option till it actually does something useful...
Eugene Zelenko9e85e5a2016-02-18 22:39:14 +0000825// { LLDB_OPT_SET_10, false, "exception-typename", 'O', OptionParser::eRequiredArgument, nullptr, nullptr, 0, eArgTypeTypeName,
Jim Inghama72b31c2015-04-22 19:42:18 +0000826// "The breakpoint will only stop if an exception Object of this type is thrown. Can be repeated multiple times to stop for multiple object types" },
827
Kate Stoneac9c3a62016-08-26 23:28:47 +0000828 {LLDB_OPT_EXPR_LANGUAGE, false, "language", 'L', OptionParser::eRequiredArgument, nullptr, nullptr, 0, eArgTypeLanguage, "Specifies the Language to use when interpreting the breakpoint's expression "
829 "(note: currently only implemented for setting breakpoints on identifiers). "
830 "If not set the target.language setting is used."},
831 {LLDB_OPT_SKIP_PROLOGUE, false, "skip-prologue", 'K', OptionParser::eRequiredArgument, nullptr, nullptr, 0, eArgTypeBoolean, "sKip the prologue if the breakpoint is at the beginning of a function. "
832 "If not set the target.skip-prologue setting is used."},
833 {LLDB_OPT_SET_ALL, false, "dummy-breakpoints", 'D', OptionParser::eNoArgument, nullptr, nullptr, 0, eArgTypeNone, "Sets Dummy breakpoints - i.e. breakpoints set before a file is provided, "
834 "which prime new targets."},
835 {LLDB_OPT_SET_ALL, false, "breakpoint-name", 'N', OptionParser::eRequiredArgument, nullptr, nullptr, 0, eArgTypeBreakpointName, "Adds this to the list of names for this breakpoint."},
836 {LLDB_OPT_OFFSET_APPLIES, false, "address-slide", 'R', OptionParser::eRequiredArgument, nullptr, nullptr, 0, eArgTypeAddress, "Add the specified offset to whatever address(es) the breakpoint resolves to. "
Jim Ingham24111672016-03-09 18:59:13 +0000837 "At present this applies the offset directly as given, and doesn't try to align it to instruction boundaries."},
Kate Stoneac9c3a62016-08-26 23:28:47 +0000838 {LLDB_OPT_MOVE_TO_NEAREST_CODE, false, "move-to-nearest-code", 'm', OptionParser::eRequiredArgument, nullptr, nullptr, 0, eArgTypeBoolean, "Move breakpoints to nearest code. If not set the target.move-to-nearest-code "
839 "setting is used."},
840 {0, false, nullptr, 0, 0, nullptr, nullptr, 0, eArgTypeNone, nullptr}
841 // clang-format on
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000842};
843
Jim Ingham5a988412012-06-08 21:56:10 +0000844//-------------------------------------------------------------------------
845// CommandObjectBreakpointModify
846//-------------------------------------------------------------------------
847#pragma mark Modify
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000848
Jim Ingham5a988412012-06-08 21:56:10 +0000849class CommandObjectBreakpointModify : public CommandObjectParsed
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000850{
Jim Ingham5a988412012-06-08 21:56:10 +0000851public:
Jim Ingham5a988412012-06-08 21:56:10 +0000852 CommandObjectBreakpointModify (CommandInterpreter &interpreter) :
Eugene Zelenko9e85e5a2016-02-18 22:39:14 +0000853 CommandObjectParsed(interpreter,
854 "breakpoint modify",
855 "Modify the options on a breakpoint or set of breakpoints in the executable. "
856 "If no breakpoint is specified, acts on the last created breakpoint. "
857 "With the exception of -e, -d and -i, passing an empty argument clears the modification.",
858 nullptr),
Todd Fialae1cfbc72016-08-11 23:51:28 +0000859 m_options ()
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000860 {
Jim Ingham5a988412012-06-08 21:56:10 +0000861 CommandArgumentEntry arg;
862 CommandObject::AddIDsArgumentData(arg, eArgTypeBreakpointID, eArgTypeBreakpointIDRange);
863 // Add the entry for the first argument for this command to the object's arguments vector.
864 m_arguments.push_back (arg);
865 }
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000866
Eugene Zelenko9e85e5a2016-02-18 22:39:14 +0000867 ~CommandObjectBreakpointModify() override = default;
Greg Clayton0c5cd902010-06-28 21:30:43 +0000868
Bruce Mitchener13d21e92015-10-07 16:56:17 +0000869 Options *
870 GetOptions () override
Jim Ingham5a988412012-06-08 21:56:10 +0000871 {
872 return &m_options;
873 }
Johnny Chen7d49c9c2012-05-25 21:10:46 +0000874
Jim Ingham5a988412012-06-08 21:56:10 +0000875 class CommandOptions : public Options
876 {
877 public:
Todd Fialae1cfbc72016-08-11 23:51:28 +0000878 CommandOptions () :
879 Options (),
Jim Ingham5a988412012-06-08 21:56:10 +0000880 m_ignore_count (0),
881 m_thread_id(LLDB_INVALID_THREAD_ID),
882 m_thread_id_passed(false),
883 m_thread_index (UINT32_MAX),
884 m_thread_index_passed(false),
885 m_thread_name(),
886 m_queue_name(),
887 m_condition (),
Jim Inghamca36cd12012-10-05 19:16:31 +0000888 m_one_shot (false),
Jim Ingham5a988412012-06-08 21:56:10 +0000889 m_enable_passed (false),
890 m_enable_value (false),
891 m_name_passed (false),
892 m_queue_passed (false),
Jim Inghamca36cd12012-10-05 19:16:31 +0000893 m_condition_passed (false),
Jim Ingham33df7cd2014-12-06 01:28:03 +0000894 m_one_shot_passed (false),
895 m_use_dummy (false)
Jim Ingham5a988412012-06-08 21:56:10 +0000896 {
897 }
Greg Clayton0c5cd902010-06-28 21:30:43 +0000898
Eugene Zelenko9e85e5a2016-02-18 22:39:14 +0000899 ~CommandOptions() override = default;
Greg Clayton0c5cd902010-06-28 21:30:43 +0000900
Bruce Mitchener13d21e92015-10-07 16:56:17 +0000901 Error
Todd Fialae1cfbc72016-08-11 23:51:28 +0000902 SetOptionValue (uint32_t option_idx, const char *option_arg,
903 ExecutionContext *execution_context) override
Jim Ingham5a988412012-06-08 21:56:10 +0000904 {
905 Error error;
Greg Clayton3bcdfc02012-12-04 00:32:51 +0000906 const int short_option = m_getopt_table[option_idx].val;
Greg Claytone02b8502010-10-12 04:29:14 +0000907
Jim Ingham5a988412012-06-08 21:56:10 +0000908 switch (short_option)
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000909 {
Jim Ingham5a988412012-06-08 21:56:10 +0000910 case 'c':
Eugene Zelenko9e85e5a2016-02-18 22:39:14 +0000911 if (option_arg != nullptr)
Jim Ingham5a988412012-06-08 21:56:10 +0000912 m_condition.assign (option_arg);
913 else
914 m_condition.clear();
915 m_condition_passed = true;
916 break;
917 case 'd':
918 m_enable_passed = true;
919 m_enable_value = false;
920 break;
Jim Ingham33df7cd2014-12-06 01:28:03 +0000921 case 'D':
922 m_use_dummy = true;
923 break;
Jim Ingham5a988412012-06-08 21:56:10 +0000924 case 'e':
925 m_enable_passed = true;
926 m_enable_value = true;
927 break;
928 case 'i':
Vince Harron5275aaa2015-01-15 20:08:35 +0000929 m_ignore_count = StringConvert::ToUInt32(option_arg, UINT32_MAX, 0);
Jim Ingham5a988412012-06-08 21:56:10 +0000930 if (m_ignore_count == UINT32_MAX)
931 error.SetErrorStringWithFormat ("invalid ignore count '%s'", option_arg);
Eugene Zelenko9e85e5a2016-02-18 22:39:14 +0000932 break;
Jim Inghamca36cd12012-10-05 19:16:31 +0000933 case 'o':
934 {
935 bool value, success;
936 value = Args::StringToBoolean(option_arg, false, &success);
937 if (success)
938 {
939 m_one_shot_passed = true;
940 m_one_shot = value;
941 }
942 else
943 error.SetErrorStringWithFormat("invalid boolean value '%s' passed for -o option", option_arg);
944 }
945 break;
Jim Ingham5a988412012-06-08 21:56:10 +0000946 case 't' :
Jim Ingham5a988412012-06-08 21:56:10 +0000947 if (option_arg[0] == '\0')
Jim Ingham87df91b2011-09-23 00:54:11 +0000948 {
Jim Ingham5a988412012-06-08 21:56:10 +0000949 m_thread_id = LLDB_INVALID_THREAD_ID;
950 m_thread_id_passed = true;
Jim Ingham87df91b2011-09-23 00:54:11 +0000951 }
952 else
953 {
Vince Harron5275aaa2015-01-15 20:08:35 +0000954 m_thread_id = StringConvert::ToUInt64(option_arg, LLDB_INVALID_THREAD_ID, 0);
Jim Ingham5a988412012-06-08 21:56:10 +0000955 if (m_thread_id == LLDB_INVALID_THREAD_ID)
956 error.SetErrorStringWithFormat ("invalid thread id string '%s'", option_arg);
957 else
958 m_thread_id_passed = true;
Jim Ingham87df91b2011-09-23 00:54:11 +0000959 }
Eugene Zelenko9e85e5a2016-02-18 22:39:14 +0000960 break;
Jim Ingham5a988412012-06-08 21:56:10 +0000961 case 'T':
Eugene Zelenko9e85e5a2016-02-18 22:39:14 +0000962 if (option_arg != nullptr)
Jim Ingham5a988412012-06-08 21:56:10 +0000963 m_thread_name.assign (option_arg);
964 else
965 m_thread_name.clear();
966 m_name_passed = true;
967 break;
968 case 'q':
Eugene Zelenko9e85e5a2016-02-18 22:39:14 +0000969 if (option_arg != nullptr)
Jim Ingham5a988412012-06-08 21:56:10 +0000970 m_queue_name.assign (option_arg);
971 else
972 m_queue_name.clear();
973 m_queue_passed = true;
974 break;
975 case 'x':
Jim Ingham5a988412012-06-08 21:56:10 +0000976 if (option_arg[0] == '\n')
977 {
978 m_thread_index = UINT32_MAX;
979 m_thread_index_passed = true;
980 }
981 else
982 {
Vince Harron5275aaa2015-01-15 20:08:35 +0000983 m_thread_index = StringConvert::ToUInt32 (option_arg, UINT32_MAX, 0);
Jim Ingham5a988412012-06-08 21:56:10 +0000984 if (m_thread_id == UINT32_MAX)
985 error.SetErrorStringWithFormat ("invalid thread index string '%s'", option_arg);
986 else
987 m_thread_index_passed = true;
988 }
Eugene Zelenko9e85e5a2016-02-18 22:39:14 +0000989 break;
Jim Ingham5a988412012-06-08 21:56:10 +0000990 default:
991 error.SetErrorStringWithFormat ("unrecognized option '%c'", short_option);
992 break;
Jim Ingham969795f2011-09-21 01:17:13 +0000993 }
Jim Ingham5a988412012-06-08 21:56:10 +0000994
995 return error;
996 }
Eugene Zelenko9e85e5a2016-02-18 22:39:14 +0000997
Jim Ingham5a988412012-06-08 21:56:10 +0000998 void
Todd Fialae1cfbc72016-08-11 23:51:28 +0000999 OptionParsingStarting (ExecutionContext *execution_context) override
Jim Ingham5a988412012-06-08 21:56:10 +00001000 {
1001 m_ignore_count = 0;
1002 m_thread_id = LLDB_INVALID_THREAD_ID;
1003 m_thread_id_passed = false;
1004 m_thread_index = UINT32_MAX;
1005 m_thread_index_passed = false;
1006 m_thread_name.clear();
1007 m_queue_name.clear();
1008 m_condition.clear();
Jim Inghamca36cd12012-10-05 19:16:31 +00001009 m_one_shot = false;
Jim Ingham5a988412012-06-08 21:56:10 +00001010 m_enable_passed = false;
1011 m_queue_passed = false;
1012 m_name_passed = false;
1013 m_condition_passed = false;
Jim Inghamca36cd12012-10-05 19:16:31 +00001014 m_one_shot_passed = false;
Jim Ingham33df7cd2014-12-06 01:28:03 +00001015 m_use_dummy = false;
Jim Ingham5a988412012-06-08 21:56:10 +00001016 }
1017
1018 const OptionDefinition*
Bruce Mitchener13d21e92015-10-07 16:56:17 +00001019 GetDefinitions () override
Jim Ingham5a988412012-06-08 21:56:10 +00001020 {
1021 return g_option_table;
1022 }
1023
Jim Ingham5a988412012-06-08 21:56:10 +00001024 // Options table: Required for subclasses of Options.
1025
1026 static OptionDefinition g_option_table[];
1027
1028 // Instance variables to hold the values for command options.
1029
1030 uint32_t m_ignore_count;
1031 lldb::tid_t m_thread_id;
1032 bool m_thread_id_passed;
1033 uint32_t m_thread_index;
1034 bool m_thread_index_passed;
1035 std::string m_thread_name;
1036 std::string m_queue_name;
1037 std::string m_condition;
Jim Inghamca36cd12012-10-05 19:16:31 +00001038 bool m_one_shot;
Jim Ingham5a988412012-06-08 21:56:10 +00001039 bool m_enable_passed;
1040 bool m_enable_value;
1041 bool m_name_passed;
1042 bool m_queue_passed;
1043 bool m_condition_passed;
Jim Inghamca36cd12012-10-05 19:16:31 +00001044 bool m_one_shot_passed;
Jim Ingham33df7cd2014-12-06 01:28:03 +00001045 bool m_use_dummy;
Jim Ingham5a988412012-06-08 21:56:10 +00001046 };
1047
1048protected:
Bruce Mitchener13d21e92015-10-07 16:56:17 +00001049 bool
1050 DoExecute (Args& command, CommandReturnObject &result) override
Jim Ingham5a988412012-06-08 21:56:10 +00001051 {
Jim Ingham33df7cd2014-12-06 01:28:03 +00001052 Target *target = GetSelectedOrDummyTarget(m_options.m_use_dummy);
Eugene Zelenko9e85e5a2016-02-18 22:39:14 +00001053 if (target == nullptr)
Jim Ingham5a988412012-06-08 21:56:10 +00001054 {
1055 result.AppendError ("Invalid target. No existing target or breakpoints.");
1056 result.SetStatus (eReturnStatusFailed);
1057 return false;
1058 }
1059
Saleem Abdulrasoolbb19a132016-05-19 05:13:57 +00001060 std::unique_lock<std::recursive_mutex> lock;
1061 target->GetBreakpointList().GetListMutex(lock);
1062
Jim Ingham5a988412012-06-08 21:56:10 +00001063 BreakpointIDList valid_bp_ids;
1064
Jim Ingham5e09c8c2014-12-16 23:40:14 +00001065 CommandObjectMultiwordBreakpoint::VerifyBreakpointOrLocationIDs (command, target, result, &valid_bp_ids);
Jim Ingham5a988412012-06-08 21:56:10 +00001066
1067 if (result.Succeeded())
1068 {
1069 const size_t count = valid_bp_ids.GetSize();
1070 for (size_t i = 0; i < count; ++i)
Jim Inghamfab10e82012-03-06 00:37:27 +00001071 {
Jim Ingham5a988412012-06-08 21:56:10 +00001072 BreakpointID cur_bp_id = valid_bp_ids.GetBreakpointIDAtIndex (i);
1073
1074 if (cur_bp_id.GetBreakpointID() != LLDB_INVALID_BREAK_ID)
1075 {
1076 Breakpoint *bp = target->GetBreakpointByID (cur_bp_id.GetBreakpointID()).get();
1077 if (cur_bp_id.GetLocationID() != LLDB_INVALID_BREAK_ID)
1078 {
1079 BreakpointLocation *location = bp->FindLocationByID (cur_bp_id.GetLocationID()).get();
1080 if (location)
1081 {
1082 if (m_options.m_thread_id_passed)
1083 location->SetThreadID (m_options.m_thread_id);
1084
1085 if (m_options.m_thread_index_passed)
1086 location->SetThreadIndex(m_options.m_thread_index);
1087
1088 if (m_options.m_name_passed)
1089 location->SetThreadName(m_options.m_thread_name.c_str());
1090
1091 if (m_options.m_queue_passed)
1092 location->SetQueueName(m_options.m_queue_name.c_str());
1093
1094 if (m_options.m_ignore_count != 0)
1095 location->SetIgnoreCount(m_options.m_ignore_count);
1096
1097 if (m_options.m_enable_passed)
1098 location->SetEnabled (m_options.m_enable_value);
1099
1100 if (m_options.m_condition_passed)
1101 location->SetCondition (m_options.m_condition.c_str());
1102 }
1103 }
1104 else
1105 {
1106 if (m_options.m_thread_id_passed)
1107 bp->SetThreadID (m_options.m_thread_id);
1108
1109 if (m_options.m_thread_index_passed)
1110 bp->SetThreadIndex(m_options.m_thread_index);
1111
1112 if (m_options.m_name_passed)
1113 bp->SetThreadName(m_options.m_thread_name.c_str());
1114
1115 if (m_options.m_queue_passed)
1116 bp->SetQueueName(m_options.m_queue_name.c_str());
1117
1118 if (m_options.m_ignore_count != 0)
1119 bp->SetIgnoreCount(m_options.m_ignore_count);
1120
1121 if (m_options.m_enable_passed)
1122 bp->SetEnabled (m_options.m_enable_value);
1123
1124 if (m_options.m_condition_passed)
1125 bp->SetCondition (m_options.m_condition.c_str());
1126 }
1127 }
Jim Inghamfab10e82012-03-06 00:37:27 +00001128 }
Jim Ingham5a988412012-06-08 21:56:10 +00001129 }
1130
1131 return result.Succeeded();
Chris Lattner30fdc8d2010-06-08 16:52:24 +00001132 }
1133
Jim Ingham5a988412012-06-08 21:56:10 +00001134private:
1135 CommandOptions m_options;
1136};
Johnny Chen7d49c9c2012-05-25 21:10:46 +00001137
Jim Ingham5a988412012-06-08 21:56:10 +00001138#pragma mark Modify::CommandOptions
1139OptionDefinition
1140CommandObjectBreakpointModify::CommandOptions::g_option_table[] =
1141{
Kate Stoneac9c3a62016-08-26 23:28:47 +00001142 // clang-format off
1143 {LLDB_OPT_SET_ALL, false, "ignore-count", 'i', OptionParser::eRequiredArgument, nullptr, nullptr, 0, eArgTypeCount, "Set the number of times this breakpoint is skipped before stopping."},
1144 {LLDB_OPT_SET_ALL, false, "one-shot", 'o', OptionParser::eRequiredArgument, nullptr, nullptr, 0, eArgTypeBoolean, "The breakpoint is deleted the first time it stop causes a stop."},
1145 {LLDB_OPT_SET_ALL, false, "thread-index", 'x', OptionParser::eRequiredArgument, nullptr, nullptr, 0, eArgTypeThreadIndex, "The breakpoint stops only for the thread whose index matches this argument."},
1146 {LLDB_OPT_SET_ALL, false, "thread-id", 't', OptionParser::eRequiredArgument, nullptr, nullptr, 0, eArgTypeThreadID, "The breakpoint stops only for the thread whose TID matches this argument."},
1147 {LLDB_OPT_SET_ALL, false, "thread-name", 'T', OptionParser::eRequiredArgument, nullptr, nullptr, 0, eArgTypeThreadName, "The breakpoint stops only for the thread whose thread name matches this argument."},
1148 {LLDB_OPT_SET_ALL, false, "queue-name", 'q', OptionParser::eRequiredArgument, nullptr, nullptr, 0, eArgTypeQueueName, "The breakpoint stops only for threads in the queue whose name is given by this argument."},
1149 {LLDB_OPT_SET_ALL, false, "condition", 'c', OptionParser::eRequiredArgument, nullptr, nullptr, 0, eArgTypeExpression, "The breakpoint stops only if this condition expression evaluates to true."},
1150 {LLDB_OPT_SET_1, false, "enable", 'e', OptionParser::eNoArgument, nullptr, nullptr, 0, eArgTypeNone, "Enable the breakpoint."},
1151 {LLDB_OPT_SET_2, false, "disable", 'd', OptionParser::eNoArgument, nullptr, nullptr, 0, eArgTypeNone, "Disable the breakpoint."},
1152 {LLDB_OPT_SET_ALL, false, "dummy-breakpoints", 'D', OptionParser::eNoArgument, nullptr, nullptr, 0, eArgTypeNone, "Sets Dummy breakpoints - i.e. breakpoints set before a file is provided, which prime new targets."},
1153 {0, false, nullptr, 0, 0, nullptr, nullptr, 0, eArgTypeNone, nullptr}
1154 // clang-format on
Jim Ingham5a988412012-06-08 21:56:10 +00001155};
1156
1157//-------------------------------------------------------------------------
1158// CommandObjectBreakpointEnable
1159//-------------------------------------------------------------------------
1160#pragma mark Enable
1161
1162class CommandObjectBreakpointEnable : public CommandObjectParsed
1163{
1164public:
1165 CommandObjectBreakpointEnable (CommandInterpreter &interpreter) :
Eugene Zelenko9e85e5a2016-02-18 22:39:14 +00001166 CommandObjectParsed(interpreter,
1167 "enable",
1168 "Enable the specified disabled breakpoint(s). If no breakpoints are specified, enable all of them.",
1169 nullptr)
Jim Ingham5a988412012-06-08 21:56:10 +00001170 {
1171 CommandArgumentEntry arg;
1172 CommandObject::AddIDsArgumentData(arg, eArgTypeBreakpointID, eArgTypeBreakpointIDRange);
1173 // Add the entry for the first argument for this command to the object's arguments vector.
1174 m_arguments.push_back (arg);
1175 }
1176
Eugene Zelenko9e85e5a2016-02-18 22:39:14 +00001177 ~CommandObjectBreakpointEnable() override = default;
Jim Ingham5a988412012-06-08 21:56:10 +00001178
1179protected:
Bruce Mitchener13d21e92015-10-07 16:56:17 +00001180 bool
1181 DoExecute (Args& command, CommandReturnObject &result) override
Jim Ingham5a988412012-06-08 21:56:10 +00001182 {
Jim Ingham893c9322014-11-22 01:42:44 +00001183 Target *target = GetSelectedOrDummyTarget();
Eugene Zelenko9e85e5a2016-02-18 22:39:14 +00001184 if (target == nullptr)
Jim Ingham5a988412012-06-08 21:56:10 +00001185 {
1186 result.AppendError ("Invalid target. No existing target or breakpoints.");
1187 result.SetStatus (eReturnStatusFailed);
1188 return false;
1189 }
1190
Saleem Abdulrasoolbb19a132016-05-19 05:13:57 +00001191 std::unique_lock<std::recursive_mutex> lock;
1192 target->GetBreakpointList().GetListMutex(lock);
Jim Ingham5a988412012-06-08 21:56:10 +00001193
1194 const BreakpointList &breakpoints = target->GetBreakpointList();
1195
1196 size_t num_breakpoints = breakpoints.GetSize();
1197
1198 if (num_breakpoints == 0)
1199 {
1200 result.AppendError ("No breakpoints exist to be enabled.");
1201 result.SetStatus (eReturnStatusFailed);
1202 return false;
1203 }
1204
1205 if (command.GetArgumentCount() == 0)
1206 {
1207 // No breakpoint selected; enable all currently set breakpoints.
1208 target->EnableAllBreakpoints ();
Greg Clayton6fea17e2014-03-03 19:15:20 +00001209 result.AppendMessageWithFormat ("All breakpoints enabled. (%" PRIu64 " breakpoints)\n", (uint64_t)num_breakpoints);
Jim Ingham5a988412012-06-08 21:56:10 +00001210 result.SetStatus (eReturnStatusSuccessFinishNoResult);
1211 }
1212 else
1213 {
1214 // Particular breakpoint selected; enable that breakpoint.
1215 BreakpointIDList valid_bp_ids;
Jim Ingham5e09c8c2014-12-16 23:40:14 +00001216 CommandObjectMultiwordBreakpoint::VerifyBreakpointOrLocationIDs (command, target, result, &valid_bp_ids);
Jim Ingham5a988412012-06-08 21:56:10 +00001217
1218 if (result.Succeeded())
1219 {
1220 int enable_count = 0;
1221 int loc_count = 0;
1222 const size_t count = valid_bp_ids.GetSize();
1223 for (size_t i = 0; i < count; ++i)
1224 {
1225 BreakpointID cur_bp_id = valid_bp_ids.GetBreakpointIDAtIndex (i);
1226
1227 if (cur_bp_id.GetBreakpointID() != LLDB_INVALID_BREAK_ID)
1228 {
1229 Breakpoint *breakpoint = target->GetBreakpointByID (cur_bp_id.GetBreakpointID()).get();
1230 if (cur_bp_id.GetLocationID() != LLDB_INVALID_BREAK_ID)
1231 {
1232 BreakpointLocation *location = breakpoint->FindLocationByID (cur_bp_id.GetLocationID()).get();
1233 if (location)
1234 {
1235 location->SetEnabled (true);
1236 ++loc_count;
1237 }
1238 }
1239 else
1240 {
1241 breakpoint->SetEnabled (true);
1242 ++enable_count;
1243 }
1244 }
1245 }
1246 result.AppendMessageWithFormat ("%d breakpoints enabled.\n", enable_count + loc_count);
1247 result.SetStatus (eReturnStatusSuccessFinishNoResult);
1248 }
1249 }
1250
1251 return result.Succeeded();
1252 }
1253};
1254
1255//-------------------------------------------------------------------------
1256// CommandObjectBreakpointDisable
1257//-------------------------------------------------------------------------
1258#pragma mark Disable
1259
1260class CommandObjectBreakpointDisable : public CommandObjectParsed
1261{
1262public:
Kate Stone7428a182016-07-14 22:03:10 +00001263 CommandObjectBreakpointDisable(CommandInterpreter &interpreter)
1264 : CommandObjectParsed(interpreter, "breakpoint disable", "Disable the specified breakpoint(s) without deleting "
1265 "them. If none are specified, disable all "
1266 "breakpoints.",
1267 nullptr)
Jim Ingham5a988412012-06-08 21:56:10 +00001268 {
Kate Stone7428a182016-07-14 22:03:10 +00001269 SetHelpLong("Disable the specified breakpoint(s) without deleting them. \
1270If none are specified, disable all breakpoints."
1271 R"(
Kate Stoneea671fb2015-07-14 05:48:36 +00001272
Kate Stone7428a182016-07-14 22:03:10 +00001273)"
1274 "Note: disabling a breakpoint will cause none of its locations to be hit \
1275regardless of whether individual locations are enabled or disabled. After the sequence:"
1276 R"(
Kate Stoneea671fb2015-07-14 05:48:36 +00001277
1278 (lldb) break disable 1
1279 (lldb) break enable 1.1
1280
1281execution will NOT stop at location 1.1. To achieve that, type:
1282
1283 (lldb) break disable 1.*
1284 (lldb) break enable 1.1
1285
Kate Stone7428a182016-07-14 22:03:10 +00001286)"
1287 "The first command disables all locations for breakpoint 1, \
1288the second re-enables the first location.");
1289
Jim Ingham5a988412012-06-08 21:56:10 +00001290 CommandArgumentEntry arg;
1291 CommandObject::AddIDsArgumentData(arg, eArgTypeBreakpointID, eArgTypeBreakpointIDRange);
1292 // Add the entry for the first argument for this command to the object's arguments vector.
Jim Inghamb0fac502013-03-08 00:31:40 +00001293 m_arguments.push_back (arg);
Jim Ingham5a988412012-06-08 21:56:10 +00001294 }
1295
Eugene Zelenko9e85e5a2016-02-18 22:39:14 +00001296 ~CommandObjectBreakpointDisable() override = default;
Jim Ingham5a988412012-06-08 21:56:10 +00001297
1298protected:
Bruce Mitchener13d21e92015-10-07 16:56:17 +00001299 bool
1300 DoExecute (Args& command, CommandReturnObject &result) override
Jim Ingham5a988412012-06-08 21:56:10 +00001301 {
Jim Ingham893c9322014-11-22 01:42:44 +00001302 Target *target = GetSelectedOrDummyTarget();
Eugene Zelenko9e85e5a2016-02-18 22:39:14 +00001303 if (target == nullptr)
Jim Ingham5a988412012-06-08 21:56:10 +00001304 {
1305 result.AppendError ("Invalid target. No existing target or breakpoints.");
1306 result.SetStatus (eReturnStatusFailed);
1307 return false;
1308 }
1309
Saleem Abdulrasoolbb19a132016-05-19 05:13:57 +00001310 std::unique_lock<std::recursive_mutex> lock;
1311 target->GetBreakpointList().GetListMutex(lock);
Jim Ingham5a988412012-06-08 21:56:10 +00001312
1313 const BreakpointList &breakpoints = target->GetBreakpointList();
1314 size_t num_breakpoints = breakpoints.GetSize();
1315
1316 if (num_breakpoints == 0)
1317 {
1318 result.AppendError ("No breakpoints exist to be disabled.");
1319 result.SetStatus (eReturnStatusFailed);
1320 return false;
1321 }
1322
1323 if (command.GetArgumentCount() == 0)
1324 {
1325 // No breakpoint selected; disable all currently set breakpoints.
1326 target->DisableAllBreakpoints ();
Greg Clayton6fea17e2014-03-03 19:15:20 +00001327 result.AppendMessageWithFormat ("All breakpoints disabled. (%" PRIu64 " breakpoints)\n", (uint64_t)num_breakpoints);
Jim Ingham5a988412012-06-08 21:56:10 +00001328 result.SetStatus (eReturnStatusSuccessFinishNoResult);
1329 }
1330 else
1331 {
1332 // Particular breakpoint selected; disable that breakpoint.
1333 BreakpointIDList valid_bp_ids;
1334
Jim Ingham5e09c8c2014-12-16 23:40:14 +00001335 CommandObjectMultiwordBreakpoint::VerifyBreakpointOrLocationIDs (command, target, result, &valid_bp_ids);
Jim Ingham5a988412012-06-08 21:56:10 +00001336
1337 if (result.Succeeded())
1338 {
1339 int disable_count = 0;
1340 int loc_count = 0;
1341 const size_t count = valid_bp_ids.GetSize();
1342 for (size_t i = 0; i < count; ++i)
1343 {
1344 BreakpointID cur_bp_id = valid_bp_ids.GetBreakpointIDAtIndex (i);
1345
1346 if (cur_bp_id.GetBreakpointID() != LLDB_INVALID_BREAK_ID)
1347 {
1348 Breakpoint *breakpoint = target->GetBreakpointByID (cur_bp_id.GetBreakpointID()).get();
1349 if (cur_bp_id.GetLocationID() != LLDB_INVALID_BREAK_ID)
1350 {
1351 BreakpointLocation *location = breakpoint->FindLocationByID (cur_bp_id.GetLocationID()).get();
1352 if (location)
1353 {
1354 location->SetEnabled (false);
1355 ++loc_count;
1356 }
1357 }
1358 else
1359 {
1360 breakpoint->SetEnabled (false);
1361 ++disable_count;
1362 }
1363 }
1364 }
1365 result.AppendMessageWithFormat ("%d breakpoints disabled.\n", disable_count + loc_count);
1366 result.SetStatus (eReturnStatusSuccessFinishNoResult);
1367 }
1368 }
1369
1370 return result.Succeeded();
1371 }
Jim Ingham5a988412012-06-08 21:56:10 +00001372};
1373
1374//-------------------------------------------------------------------------
1375// CommandObjectBreakpointList
1376//-------------------------------------------------------------------------
1377#pragma mark List
1378
1379class CommandObjectBreakpointList : public CommandObjectParsed
1380{
1381public:
1382 CommandObjectBreakpointList (CommandInterpreter &interpreter) :
Eugene Zelenko9e85e5a2016-02-18 22:39:14 +00001383 CommandObjectParsed(interpreter,
1384 "breakpoint list",
1385 "List some or all breakpoints at configurable levels of detail.",
1386 nullptr),
Todd Fialae1cfbc72016-08-11 23:51:28 +00001387 m_options ()
Jim Ingham5a988412012-06-08 21:56:10 +00001388 {
1389 CommandArgumentEntry arg;
1390 CommandArgumentData bp_id_arg;
1391
1392 // Define the first (and only) variant of this arg.
1393 bp_id_arg.arg_type = eArgTypeBreakpointID;
1394 bp_id_arg.arg_repetition = eArgRepeatOptional;
1395
1396 // There is only one variant this argument could be; put it into the argument entry.
1397 arg.push_back (bp_id_arg);
1398
1399 // Push the data for the first argument into the m_arguments vector.
1400 m_arguments.push_back (arg);
1401 }
1402
Eugene Zelenko9e85e5a2016-02-18 22:39:14 +00001403 ~CommandObjectBreakpointList() override = default;
Jim Ingham5a988412012-06-08 21:56:10 +00001404
Bruce Mitchener13d21e92015-10-07 16:56:17 +00001405 Options *
1406 GetOptions () override
Jim Ingham5a988412012-06-08 21:56:10 +00001407 {
1408 return &m_options;
Jim Ingham1b54c882010-06-16 02:00:15 +00001409 }
1410
Jim Ingham5a988412012-06-08 21:56:10 +00001411 class CommandOptions : public Options
Chris Lattner30fdc8d2010-06-08 16:52:24 +00001412 {
Jim Ingham5a988412012-06-08 21:56:10 +00001413 public:
Todd Fialae1cfbc72016-08-11 23:51:28 +00001414 CommandOptions () :
1415 Options (),
Jim Ingham33df7cd2014-12-06 01:28:03 +00001416 m_level (lldb::eDescriptionLevelBrief),
1417 m_use_dummy(false)
Jim Ingham5a988412012-06-08 21:56:10 +00001418 {
1419 }
1420
Eugene Zelenko9e85e5a2016-02-18 22:39:14 +00001421 ~CommandOptions() override = default;
Jim Ingham5a988412012-06-08 21:56:10 +00001422
Bruce Mitchener13d21e92015-10-07 16:56:17 +00001423 Error
Todd Fialae1cfbc72016-08-11 23:51:28 +00001424 SetOptionValue (uint32_t option_idx, const char *option_arg,
1425 ExecutionContext *execution_context) override
Jim Ingham5a988412012-06-08 21:56:10 +00001426 {
1427 Error error;
Greg Clayton3bcdfc02012-12-04 00:32:51 +00001428 const int short_option = m_getopt_table[option_idx].val;
Jim Ingham5a988412012-06-08 21:56:10 +00001429
1430 switch (short_option)
1431 {
1432 case 'b':
1433 m_level = lldb::eDescriptionLevelBrief;
1434 break;
Jim Ingham33df7cd2014-12-06 01:28:03 +00001435 case 'D':
1436 m_use_dummy = true;
1437 break;
Jim Ingham5a988412012-06-08 21:56:10 +00001438 case 'f':
1439 m_level = lldb::eDescriptionLevelFull;
1440 break;
1441 case 'v':
1442 m_level = lldb::eDescriptionLevelVerbose;
1443 break;
1444 case 'i':
1445 m_internal = true;
1446 break;
1447 default:
1448 error.SetErrorStringWithFormat ("unrecognized option '%c'", short_option);
1449 break;
1450 }
1451
1452 return error;
1453 }
1454
1455 void
Todd Fialae1cfbc72016-08-11 23:51:28 +00001456 OptionParsingStarting (ExecutionContext *execution_context) override
Jim Ingham5a988412012-06-08 21:56:10 +00001457 {
1458 m_level = lldb::eDescriptionLevelFull;
1459 m_internal = false;
Jim Ingham33df7cd2014-12-06 01:28:03 +00001460 m_use_dummy = false;
Jim Ingham5a988412012-06-08 21:56:10 +00001461 }
1462
1463 const OptionDefinition *
Bruce Mitchener13d21e92015-10-07 16:56:17 +00001464 GetDefinitions () override
Jim Ingham5a988412012-06-08 21:56:10 +00001465 {
1466 return g_option_table;
1467 }
1468
1469 // Options table: Required for subclasses of Options.
1470
1471 static OptionDefinition g_option_table[];
1472
1473 // Instance variables to hold the values for command options.
1474
1475 lldb::DescriptionLevel m_level;
1476
1477 bool m_internal;
Jim Ingham33df7cd2014-12-06 01:28:03 +00001478 bool m_use_dummy;
Jim Ingham5a988412012-06-08 21:56:10 +00001479 };
1480
1481protected:
Bruce Mitchener13d21e92015-10-07 16:56:17 +00001482 bool
1483 DoExecute (Args& command, CommandReturnObject &result) override
Jim Ingham5a988412012-06-08 21:56:10 +00001484 {
Jim Ingham33df7cd2014-12-06 01:28:03 +00001485 Target *target = GetSelectedOrDummyTarget(m_options.m_use_dummy);
1486
Eugene Zelenko9e85e5a2016-02-18 22:39:14 +00001487 if (target == nullptr)
Jim Ingham5a988412012-06-08 21:56:10 +00001488 {
1489 result.AppendError ("Invalid target. No current target or breakpoints.");
1490 result.SetStatus (eReturnStatusSuccessFinishNoResult);
1491 return true;
1492 }
1493
1494 const BreakpointList &breakpoints = target->GetBreakpointList(m_options.m_internal);
Saleem Abdulrasoolbb19a132016-05-19 05:13:57 +00001495 std::unique_lock<std::recursive_mutex> lock;
1496 target->GetBreakpointList(m_options.m_internal).GetListMutex(lock);
Jim Ingham5a988412012-06-08 21:56:10 +00001497
1498 size_t num_breakpoints = breakpoints.GetSize();
1499
1500 if (num_breakpoints == 0)
1501 {
1502 result.AppendMessage ("No breakpoints currently set.");
1503 result.SetStatus (eReturnStatusSuccessFinishNoResult);
1504 return true;
1505 }
1506
Jim Ingham85e8b812011-02-19 02:53:09 +00001507 Stream &output_stream = result.GetOutputStream();
Jim Ingham5a988412012-06-08 21:56:10 +00001508
1509 if (command.GetArgumentCount() == 0)
1510 {
1511 // No breakpoint selected; show info about all currently set breakpoints.
1512 result.AppendMessage ("Current breakpoints:");
1513 for (size_t i = 0; i < num_breakpoints; ++i)
1514 {
1515 Breakpoint *breakpoint = breakpoints.GetBreakpointAtIndex (i).get();
1516 AddBreakpointDescription (&output_stream, breakpoint, m_options.m_level);
1517 }
1518 result.SetStatus (eReturnStatusSuccessFinishNoResult);
1519 }
1520 else
1521 {
1522 // Particular breakpoints selected; show info about that breakpoint.
1523 BreakpointIDList valid_bp_ids;
Jim Ingham5e09c8c2014-12-16 23:40:14 +00001524 CommandObjectMultiwordBreakpoint::VerifyBreakpointOrLocationIDs (command, target, result, &valid_bp_ids);
Jim Ingham5a988412012-06-08 21:56:10 +00001525
1526 if (result.Succeeded())
1527 {
1528 for (size_t i = 0; i < valid_bp_ids.GetSize(); ++i)
1529 {
1530 BreakpointID cur_bp_id = valid_bp_ids.GetBreakpointIDAtIndex (i);
1531 Breakpoint *breakpoint = target->GetBreakpointByID (cur_bp_id.GetBreakpointID()).get();
1532 AddBreakpointDescription (&output_stream, breakpoint, m_options.m_level);
1533 }
1534 result.SetStatus (eReturnStatusSuccessFinishNoResult);
1535 }
1536 else
1537 {
Kate Stone7428a182016-07-14 22:03:10 +00001538 result.AppendError("Invalid breakpoint ID.");
Jim Ingham5a988412012-06-08 21:56:10 +00001539 result.SetStatus (eReturnStatusFailed);
1540 }
1541 }
1542
1543 return result.Succeeded();
Chris Lattner30fdc8d2010-06-08 16:52:24 +00001544 }
1545
Jim Ingham5a988412012-06-08 21:56:10 +00001546private:
1547 CommandOptions m_options;
1548};
1549
1550#pragma mark List::CommandOptions
1551OptionDefinition
1552CommandObjectBreakpointList::CommandOptions::g_option_table[] =
1553{
Kate Stoneac9c3a62016-08-26 23:28:47 +00001554 // clang-format off
1555 {LLDB_OPT_SET_ALL, false, "internal", 'i', OptionParser::eNoArgument, nullptr, nullptr, 0, eArgTypeNone, "Show debugger internal breakpoints" },
1556 {LLDB_OPT_SET_1, false, "brief", 'b', OptionParser::eNoArgument, nullptr, nullptr, 0, eArgTypeNone, "Give a brief description of the breakpoint (no location info)."},
Jim Ingham5a988412012-06-08 21:56:10 +00001557 // FIXME: We need to add an "internal" command, and then add this sort of thing to it.
1558 // But I need to see it for now, and don't want to wait.
Kate Stoneac9c3a62016-08-26 23:28:47 +00001559 {LLDB_OPT_SET_2, false, "full", 'f', OptionParser::eNoArgument, nullptr, nullptr, 0, eArgTypeNone, "Give a full description of the breakpoint and its locations."},
1560 {LLDB_OPT_SET_3, false, "verbose", 'v', OptionParser::eNoArgument, nullptr, nullptr, 0, eArgTypeNone, "Explain everything we know about the breakpoint (for debugging debugger bugs)."},
1561 {LLDB_OPT_SET_ALL, false, "dummy-breakpoints", 'D', OptionParser::eNoArgument, nullptr, nullptr, 0, eArgTypeNone, "List Dummy breakpoints - i.e. breakpoints set before a file is provided, which prime new targets."},
1562 {0, false, nullptr, 0, 0, nullptr, nullptr, 0, eArgTypeNone, nullptr}
1563 // clang-format on
Jim Ingham5a988412012-06-08 21:56:10 +00001564};
1565
1566//-------------------------------------------------------------------------
1567// CommandObjectBreakpointClear
1568//-------------------------------------------------------------------------
1569#pragma mark Clear
1570
1571class CommandObjectBreakpointClear : public CommandObjectParsed
1572{
1573public:
Jim Ingham5a988412012-06-08 21:56:10 +00001574 typedef enum BreakpointClearType
1575 {
1576 eClearTypeInvalid,
1577 eClearTypeFileAndLine
1578 } BreakpointClearType;
1579
Kate Stone7428a182016-07-14 22:03:10 +00001580 CommandObjectBreakpointClear(CommandInterpreter &interpreter)
1581 : CommandObjectParsed(interpreter, "breakpoint clear",
1582 "Delete or disable breakpoints matching the specified source file and line.",
1583 "breakpoint clear <cmd-options>"),
Todd Fialae1cfbc72016-08-11 23:51:28 +00001584 m_options()
Jim Ingham5a988412012-06-08 21:56:10 +00001585 {
1586 }
1587
Eugene Zelenko9e85e5a2016-02-18 22:39:14 +00001588 ~CommandObjectBreakpointClear() override = default;
Jim Ingham5a988412012-06-08 21:56:10 +00001589
Bruce Mitchener13d21e92015-10-07 16:56:17 +00001590 Options *
1591 GetOptions () override
Jim Ingham5a988412012-06-08 21:56:10 +00001592 {
1593 return &m_options;
1594 }
1595
1596 class CommandOptions : public Options
1597 {
1598 public:
Todd Fialae1cfbc72016-08-11 23:51:28 +00001599 CommandOptions () :
1600 Options (),
Jim Ingham5a988412012-06-08 21:56:10 +00001601 m_filename (),
1602 m_line_num (0)
1603 {
1604 }
1605
Eugene Zelenko9e85e5a2016-02-18 22:39:14 +00001606 ~CommandOptions() override = default;
Jim Ingham5a988412012-06-08 21:56:10 +00001607
Bruce Mitchener13d21e92015-10-07 16:56:17 +00001608 Error
Todd Fialae1cfbc72016-08-11 23:51:28 +00001609 SetOptionValue (uint32_t option_idx, const char *option_arg,
1610 ExecutionContext *execution_context) override
Jim Ingham5a988412012-06-08 21:56:10 +00001611 {
1612 Error error;
Greg Clayton3bcdfc02012-12-04 00:32:51 +00001613 const int short_option = m_getopt_table[option_idx].val;
Jim Ingham5a988412012-06-08 21:56:10 +00001614
1615 switch (short_option)
1616 {
1617 case 'f':
1618 m_filename.assign (option_arg);
1619 break;
1620
1621 case 'l':
Vince Harron5275aaa2015-01-15 20:08:35 +00001622 m_line_num = StringConvert::ToUInt32 (option_arg, 0);
Jim Ingham5a988412012-06-08 21:56:10 +00001623 break;
1624
1625 default:
1626 error.SetErrorStringWithFormat ("unrecognized option '%c'", short_option);
1627 break;
1628 }
1629
1630 return error;
1631 }
1632
1633 void
Todd Fialae1cfbc72016-08-11 23:51:28 +00001634 OptionParsingStarting (ExecutionContext *execution_context) override
Jim Ingham5a988412012-06-08 21:56:10 +00001635 {
1636 m_filename.clear();
1637 m_line_num = 0;
1638 }
1639
1640 const OptionDefinition*
Bruce Mitchener13d21e92015-10-07 16:56:17 +00001641 GetDefinitions () override
Jim Ingham5a988412012-06-08 21:56:10 +00001642 {
1643 return g_option_table;
1644 }
1645
1646 // Options table: Required for subclasses of Options.
1647
1648 static OptionDefinition g_option_table[];
1649
1650 // Instance variables to hold the values for command options.
1651
1652 std::string m_filename;
1653 uint32_t m_line_num;
1654
1655 };
1656
1657protected:
Bruce Mitchener13d21e92015-10-07 16:56:17 +00001658 bool
1659 DoExecute (Args& command, CommandReturnObject &result) override
Jim Ingham5a988412012-06-08 21:56:10 +00001660 {
Jim Ingham893c9322014-11-22 01:42:44 +00001661 Target *target = GetSelectedOrDummyTarget();
Eugene Zelenko9e85e5a2016-02-18 22:39:14 +00001662 if (target == nullptr)
Jim Ingham5a988412012-06-08 21:56:10 +00001663 {
1664 result.AppendError ("Invalid target. No existing target or breakpoints.");
1665 result.SetStatus (eReturnStatusFailed);
1666 return false;
1667 }
1668
1669 // The following are the various types of breakpoints that could be cleared:
1670 // 1). -f -l (clearing breakpoint by source location)
1671
1672 BreakpointClearType break_type = eClearTypeInvalid;
1673
1674 if (m_options.m_line_num != 0)
1675 break_type = eClearTypeFileAndLine;
1676
Saleem Abdulrasoolbb19a132016-05-19 05:13:57 +00001677 std::unique_lock<std::recursive_mutex> lock;
1678 target->GetBreakpointList().GetListMutex(lock);
Jim Ingham5a988412012-06-08 21:56:10 +00001679
1680 BreakpointList &breakpoints = target->GetBreakpointList();
1681 size_t num_breakpoints = breakpoints.GetSize();
1682
1683 // Early return if there's no breakpoint at all.
1684 if (num_breakpoints == 0)
1685 {
1686 result.AppendError ("Breakpoint clear: No breakpoint cleared.");
1687 result.SetStatus (eReturnStatusFailed);
1688 return result.Succeeded();
1689 }
1690
1691 // Find matching breakpoints and delete them.
1692
1693 // First create a copy of all the IDs.
1694 std::vector<break_id_t> BreakIDs;
1695 for (size_t i = 0; i < num_breakpoints; ++i)
Eugene Zelenko9e85e5a2016-02-18 22:39:14 +00001696 BreakIDs.push_back(breakpoints.GetBreakpointAtIndex(i)->GetID());
Jim Ingham5a988412012-06-08 21:56:10 +00001697
1698 int num_cleared = 0;
1699 StreamString ss;
1700 switch (break_type)
1701 {
1702 case eClearTypeFileAndLine: // Breakpoint by source position
1703 {
1704 const ConstString filename(m_options.m_filename.c_str());
1705 BreakpointLocationCollection loc_coll;
1706
1707 for (size_t i = 0; i < num_breakpoints; ++i)
1708 {
1709 Breakpoint *bp = breakpoints.FindBreakpointByID(BreakIDs[i]).get();
1710
1711 if (bp->GetMatchingFileLine(filename, m_options.m_line_num, loc_coll))
1712 {
1713 // If the collection size is 0, it's a full match and we can just remove the breakpoint.
1714 if (loc_coll.GetSize() == 0)
1715 {
1716 bp->GetDescription(&ss, lldb::eDescriptionLevelBrief);
1717 ss.EOL();
1718 target->RemoveBreakpointByID (bp->GetID());
1719 ++num_cleared;
1720 }
1721 }
1722 }
1723 }
1724 break;
1725
1726 default:
1727 break;
1728 }
1729
1730 if (num_cleared > 0)
1731 {
1732 Stream &output_stream = result.GetOutputStream();
1733 output_stream.Printf ("%d breakpoints cleared:\n", num_cleared);
1734 output_stream << ss.GetData();
1735 output_stream.EOL();
1736 result.SetStatus (eReturnStatusSuccessFinishNoResult);
1737 }
1738 else
1739 {
1740 result.AppendError ("Breakpoint clear: No breakpoint cleared.");
1741 result.SetStatus (eReturnStatusFailed);
1742 }
1743
1744 return result.Succeeded();
1745 }
1746
1747private:
1748 CommandOptions m_options;
1749};
1750
1751#pragma mark Clear::CommandOptions
1752
1753OptionDefinition
1754CommandObjectBreakpointClear::CommandOptions::g_option_table[] =
1755{
Kate Stoneac9c3a62016-08-26 23:28:47 +00001756 // clang-format off
1757 {LLDB_OPT_SET_1, false, "file", 'f', OptionParser::eRequiredArgument, nullptr, nullptr, CommandCompletions::eSourceFileCompletion, eArgTypeFilename, "Specify the breakpoint by source location in this particular file."},
1758 {LLDB_OPT_SET_1, true, "line", 'l', OptionParser::eRequiredArgument, nullptr, nullptr, 0, eArgTypeLineNum, "Specify the breakpoint by source location at this particular line."},
1759 {0, false, nullptr, 0, 0, nullptr, nullptr, 0, eArgTypeNone, nullptr}
1760 // clang-format on
Jim Ingham5a988412012-06-08 21:56:10 +00001761};
1762
1763//-------------------------------------------------------------------------
1764// CommandObjectBreakpointDelete
1765//-------------------------------------------------------------------------
1766#pragma mark Delete
1767
1768class CommandObjectBreakpointDelete : public CommandObjectParsed
1769{
1770public:
1771 CommandObjectBreakpointDelete (CommandInterpreter &interpreter) :
Eugene Zelenko9e85e5a2016-02-18 22:39:14 +00001772 CommandObjectParsed(interpreter,
1773 "breakpoint delete",
1774 "Delete the specified breakpoint(s). If no breakpoints are specified, delete them all.",
1775 nullptr),
Todd Fialae1cfbc72016-08-11 23:51:28 +00001776 m_options()
Jim Ingham5a988412012-06-08 21:56:10 +00001777 {
1778 CommandArgumentEntry arg;
1779 CommandObject::AddIDsArgumentData(arg, eArgTypeBreakpointID, eArgTypeBreakpointIDRange);
1780 // Add the entry for the first argument for this command to the object's arguments vector.
1781 m_arguments.push_back (arg);
1782 }
1783
Eugene Zelenko9e85e5a2016-02-18 22:39:14 +00001784 ~CommandObjectBreakpointDelete() override = default;
Jim Ingham5a988412012-06-08 21:56:10 +00001785
Bruce Mitchener13d21e92015-10-07 16:56:17 +00001786 Options *
1787 GetOptions () override
Jim Ingham33df7cd2014-12-06 01:28:03 +00001788 {
1789 return &m_options;
1790 }
1791
1792 class CommandOptions : public Options
1793 {
1794 public:
Todd Fialae1cfbc72016-08-11 23:51:28 +00001795 CommandOptions () :
1796 Options (),
Jim Ingham33df7cd2014-12-06 01:28:03 +00001797 m_use_dummy (false),
1798 m_force (false)
1799 {
1800 }
1801
Eugene Zelenko9e85e5a2016-02-18 22:39:14 +00001802 ~CommandOptions() override = default;
Jim Ingham33df7cd2014-12-06 01:28:03 +00001803
Bruce Mitchener13d21e92015-10-07 16:56:17 +00001804 Error
Todd Fialae1cfbc72016-08-11 23:51:28 +00001805 SetOptionValue (uint32_t option_idx, const char *option_arg,
1806 ExecutionContext *execution_context) override
Jim Ingham33df7cd2014-12-06 01:28:03 +00001807 {
1808 Error error;
1809 const int short_option = m_getopt_table[option_idx].val;
1810
1811 switch (short_option)
1812 {
1813 case 'f':
1814 m_force = true;
1815 break;
1816
1817 case 'D':
1818 m_use_dummy = true;
1819 break;
1820
1821 default:
1822 error.SetErrorStringWithFormat ("unrecognized option '%c'", short_option);
1823 break;
1824 }
1825
1826 return error;
1827 }
1828
1829 void
Todd Fialae1cfbc72016-08-11 23:51:28 +00001830 OptionParsingStarting (ExecutionContext *execution_context) override
Jim Ingham33df7cd2014-12-06 01:28:03 +00001831 {
1832 m_use_dummy = false;
1833 m_force = false;
1834 }
1835
1836 const OptionDefinition*
Bruce Mitchener13d21e92015-10-07 16:56:17 +00001837 GetDefinitions () override
Jim Ingham33df7cd2014-12-06 01:28:03 +00001838 {
1839 return g_option_table;
1840 }
1841
1842 // Options table: Required for subclasses of Options.
1843
1844 static OptionDefinition g_option_table[];
1845
1846 // Instance variables to hold the values for command options.
1847 bool m_use_dummy;
1848 bool m_force;
1849 };
1850
Jim Ingham5a988412012-06-08 21:56:10 +00001851protected:
Bruce Mitchener13d21e92015-10-07 16:56:17 +00001852 bool
1853 DoExecute (Args& command, CommandReturnObject &result) override
Jim Ingham5a988412012-06-08 21:56:10 +00001854 {
Jim Ingham33df7cd2014-12-06 01:28:03 +00001855 Target *target = GetSelectedOrDummyTarget(m_options.m_use_dummy);
1856
Eugene Zelenko9e85e5a2016-02-18 22:39:14 +00001857 if (target == nullptr)
Jim Ingham5a988412012-06-08 21:56:10 +00001858 {
1859 result.AppendError ("Invalid target. No existing target or breakpoints.");
1860 result.SetStatus (eReturnStatusFailed);
1861 return false;
1862 }
1863
Saleem Abdulrasoolbb19a132016-05-19 05:13:57 +00001864 std::unique_lock<std::recursive_mutex> lock;
1865 target->GetBreakpointList().GetListMutex(lock);
1866
Jim Ingham5a988412012-06-08 21:56:10 +00001867 const BreakpointList &breakpoints = target->GetBreakpointList();
1868
1869 size_t num_breakpoints = breakpoints.GetSize();
1870
1871 if (num_breakpoints == 0)
1872 {
1873 result.AppendError ("No breakpoints exist to be deleted.");
1874 result.SetStatus (eReturnStatusFailed);
1875 return false;
1876 }
1877
1878 if (command.GetArgumentCount() == 0)
1879 {
Jim Ingham33df7cd2014-12-06 01:28:03 +00001880 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 +00001881 {
1882 result.AppendMessage("Operation cancelled...");
1883 }
1884 else
1885 {
1886 target->RemoveAllBreakpoints ();
Greg Clayton6fea17e2014-03-03 19:15:20 +00001887 result.AppendMessageWithFormat ("All breakpoints removed. (%" PRIu64 " breakpoint%s)\n", (uint64_t)num_breakpoints, num_breakpoints > 1 ? "s" : "");
Jim Ingham5a988412012-06-08 21:56:10 +00001888 }
1889 result.SetStatus (eReturnStatusSuccessFinishNoResult);
1890 }
1891 else
1892 {
1893 // Particular breakpoint selected; disable that breakpoint.
1894 BreakpointIDList valid_bp_ids;
Jim Ingham5e09c8c2014-12-16 23:40:14 +00001895 CommandObjectMultiwordBreakpoint::VerifyBreakpointOrLocationIDs (command, target, result, &valid_bp_ids);
Jim Ingham5a988412012-06-08 21:56:10 +00001896
1897 if (result.Succeeded())
1898 {
1899 int delete_count = 0;
1900 int disable_count = 0;
1901 const size_t count = valid_bp_ids.GetSize();
1902 for (size_t i = 0; i < count; ++i)
1903 {
1904 BreakpointID cur_bp_id = valid_bp_ids.GetBreakpointIDAtIndex (i);
1905
1906 if (cur_bp_id.GetBreakpointID() != LLDB_INVALID_BREAK_ID)
1907 {
1908 if (cur_bp_id.GetLocationID() != LLDB_INVALID_BREAK_ID)
1909 {
1910 Breakpoint *breakpoint = target->GetBreakpointByID (cur_bp_id.GetBreakpointID()).get();
1911 BreakpointLocation *location = breakpoint->FindLocationByID (cur_bp_id.GetLocationID()).get();
1912 // It makes no sense to try to delete individual locations, so we disable them instead.
1913 if (location)
1914 {
1915 location->SetEnabled (false);
1916 ++disable_count;
1917 }
1918 }
1919 else
1920 {
1921 target->RemoveBreakpointByID (cur_bp_id.GetBreakpointID());
1922 ++delete_count;
1923 }
1924 }
1925 }
1926 result.AppendMessageWithFormat ("%d breakpoints deleted; %d breakpoint locations disabled.\n",
1927 delete_count, disable_count);
1928 result.SetStatus (eReturnStatusSuccessFinishNoResult);
1929 }
1930 }
1931 return result.Succeeded();
1932 }
Eugene Zelenko9e85e5a2016-02-18 22:39:14 +00001933
Jim Ingham33df7cd2014-12-06 01:28:03 +00001934private:
1935 CommandOptions m_options;
1936};
1937
1938OptionDefinition
1939CommandObjectBreakpointDelete::CommandOptions::g_option_table[] =
1940{
Kate Stoneac9c3a62016-08-26 23:28:47 +00001941 // clang-format off
1942 {LLDB_OPT_SET_1, false, "force", 'f', OptionParser::eNoArgument, nullptr, nullptr, 0, eArgTypeNone, "Delete all breakpoints without querying for confirmation."},
1943 {LLDB_OPT_SET_1, false, "dummy-breakpoints", 'D', OptionParser::eNoArgument, nullptr, nullptr, 0, eArgTypeNone, "Delete Dummy breakpoints - i.e. breakpoints set before a file is provided, which prime new targets."},
1944 {0, false, nullptr, 0, 0, nullptr, nullptr, 0, eArgTypeNone, nullptr}
1945 // clang-format on
Jim Ingham5a988412012-06-08 21:56:10 +00001946};
Chris Lattner30fdc8d2010-06-08 16:52:24 +00001947
Chris Lattner30fdc8d2010-06-08 16:52:24 +00001948//-------------------------------------------------------------------------
Jim Ingham5e09c8c2014-12-16 23:40:14 +00001949// CommandObjectBreakpointName
1950//-------------------------------------------------------------------------
1951
Kate Stone7428a182016-07-14 22:03:10 +00001952static OptionDefinition g_breakpoint_name_options[] = {
Kate Stoneac9c3a62016-08-26 23:28:47 +00001953 // clang-format off
1954 {LLDB_OPT_SET_1, false, "name", 'N', OptionParser::eRequiredArgument, nullptr, nullptr, 0, eArgTypeBreakpointName, "Specifies a breakpoint name to use."},
1955 {LLDB_OPT_SET_2, false, "breakpoint-id", 'B', OptionParser::eRequiredArgument, nullptr, nullptr, 0, eArgTypeBreakpointID, "Specify a breakpoint ID to use."},
1956 {LLDB_OPT_SET_ALL, false, "dummy-breakpoints", 'D', OptionParser::eNoArgument, nullptr, nullptr, 0, eArgTypeNone, "Operate on Dummy breakpoints - i.e. breakpoints set before a file is provided, which prime new targets."},
1957 // clang-format on
Jim Ingham5e09c8c2014-12-16 23:40:14 +00001958};
1959class BreakpointNameOptionGroup : public OptionGroup
1960{
1961public:
1962 BreakpointNameOptionGroup() :
1963 OptionGroup(),
1964 m_breakpoint(LLDB_INVALID_BREAK_ID),
1965 m_use_dummy (false)
1966 {
Jim Ingham5e09c8c2014-12-16 23:40:14 +00001967 }
1968
Eugene Zelenko9e85e5a2016-02-18 22:39:14 +00001969 ~BreakpointNameOptionGroup() override = default;
1970
Bruce Mitchener13d21e92015-10-07 16:56:17 +00001971 uint32_t
1972 GetNumDefinitions () override
Jim Ingham5e09c8c2014-12-16 23:40:14 +00001973 {
1974 return sizeof (g_breakpoint_name_options) / sizeof (OptionDefinition);
1975 }
1976
Bruce Mitchener13d21e92015-10-07 16:56:17 +00001977 const OptionDefinition*
1978 GetDefinitions () override
Jim Ingham5e09c8c2014-12-16 23:40:14 +00001979 {
1980 return g_breakpoint_name_options;
1981 }
1982
Bruce Mitchener13d21e92015-10-07 16:56:17 +00001983 Error
Todd Fialae1cfbc72016-08-11 23:51:28 +00001984 SetOptionValue (uint32_t option_idx,
1985 const char *option_value,
1986 ExecutionContext *execution_context) override
Jim Ingham5e09c8c2014-12-16 23:40:14 +00001987 {
1988 Error error;
1989 const int short_option = g_breakpoint_name_options[option_idx].short_option;
1990
1991 switch (short_option)
1992 {
1993 case 'N':
1994 if (BreakpointID::StringIsBreakpointName(option_value, error) && error.Success())
Pavel Labathc95f7e22015-02-20 11:14:59 +00001995 m_name.SetValueFromString(option_value);
Jim Ingham5e09c8c2014-12-16 23:40:14 +00001996 break;
1997
1998 case 'B':
Pavel Labathc95f7e22015-02-20 11:14:59 +00001999 if (m_breakpoint.SetValueFromString(option_value).Fail())
Jim Ingham5e09c8c2014-12-16 23:40:14 +00002000 error.SetErrorStringWithFormat ("unrecognized value \"%s\" for breakpoint", option_value);
2001 break;
2002 case 'D':
Pavel Labathc95f7e22015-02-20 11:14:59 +00002003 if (m_use_dummy.SetValueFromString(option_value).Fail())
Jim Ingham5e09c8c2014-12-16 23:40:14 +00002004 error.SetErrorStringWithFormat ("unrecognized value \"%s\" for use-dummy", option_value);
2005 break;
2006
2007 default:
2008 error.SetErrorStringWithFormat("unrecognized short option '%c'", short_option);
2009 break;
2010 }
2011 return error;
2012 }
2013
Bruce Mitchener13d21e92015-10-07 16:56:17 +00002014 void
Todd Fialae1cfbc72016-08-11 23:51:28 +00002015 OptionParsingStarting (ExecutionContext *execution_context) override
Jim Ingham5e09c8c2014-12-16 23:40:14 +00002016 {
2017 m_name.Clear();
2018 m_breakpoint.Clear();
2019 m_use_dummy.Clear();
2020 m_use_dummy.SetDefaultValue(false);
2021 }
2022
2023 OptionValueString m_name;
2024 OptionValueUInt64 m_breakpoint;
2025 OptionValueBoolean m_use_dummy;
2026};
2027
Jim Ingham5e09c8c2014-12-16 23:40:14 +00002028class CommandObjectBreakpointNameAdd : public CommandObjectParsed
2029{
2030public:
2031 CommandObjectBreakpointNameAdd (CommandInterpreter &interpreter) :
2032 CommandObjectParsed (interpreter,
2033 "add",
2034 "Add a name to the breakpoints provided.",
2035 "breakpoint name add <command-options> <breakpoint-id-list>"),
2036 m_name_options(),
Todd Fialae1cfbc72016-08-11 23:51:28 +00002037 m_option_group()
Jim Ingham5e09c8c2014-12-16 23:40:14 +00002038 {
2039 // Create the first variant for the first (and only) argument for this command.
2040 CommandArgumentEntry arg1;
2041 CommandArgumentData id_arg;
2042 id_arg.arg_type = eArgTypeBreakpointID;
2043 id_arg.arg_repetition = eArgRepeatOptional;
2044 arg1.push_back(id_arg);
2045 m_arguments.push_back (arg1);
2046
2047 m_option_group.Append (&m_name_options, LLDB_OPT_SET_1, LLDB_OPT_SET_ALL);
2048 m_option_group.Finalize();
2049 }
2050
Eugene Zelenko9e85e5a2016-02-18 22:39:14 +00002051 ~CommandObjectBreakpointNameAdd() override = default;
Jim Ingham5e09c8c2014-12-16 23:40:14 +00002052
Eugene Zelenko9e85e5a2016-02-18 22:39:14 +00002053 Options *
2054 GetOptions() override
2055 {
2056 return &m_option_group;
2057 }
2058
Jim Ingham5e09c8c2014-12-16 23:40:14 +00002059protected:
Bruce Mitchener13d21e92015-10-07 16:56:17 +00002060 bool
2061 DoExecute (Args& command, CommandReturnObject &result) override
Jim Ingham5e09c8c2014-12-16 23:40:14 +00002062 {
2063 if (!m_name_options.m_name.OptionWasSet())
2064 {
2065 result.SetError("No name option provided.");
2066 return false;
2067 }
2068
2069 Target *target = GetSelectedOrDummyTarget(m_name_options.m_use_dummy.GetCurrentValue());
2070
Eugene Zelenko9e85e5a2016-02-18 22:39:14 +00002071 if (target == nullptr)
Jim Ingham5e09c8c2014-12-16 23:40:14 +00002072 {
2073 result.AppendError ("Invalid target. No existing target or breakpoints.");
2074 result.SetStatus (eReturnStatusFailed);
2075 return false;
2076 }
2077
Saleem Abdulrasoolbb19a132016-05-19 05:13:57 +00002078 std::unique_lock<std::recursive_mutex> lock;
2079 target->GetBreakpointList().GetListMutex(lock);
2080
Jim Ingham5e09c8c2014-12-16 23:40:14 +00002081 const BreakpointList &breakpoints = target->GetBreakpointList();
2082
2083 size_t num_breakpoints = breakpoints.GetSize();
2084 if (num_breakpoints == 0)
2085 {
2086 result.SetError("No breakpoints, cannot add names.");
2087 result.SetStatus (eReturnStatusFailed);
2088 return false;
2089 }
2090
2091 // Particular breakpoint selected; disable that breakpoint.
2092 BreakpointIDList valid_bp_ids;
2093 CommandObjectMultiwordBreakpoint::VerifyBreakpointIDs (command, target, result, &valid_bp_ids);
2094
2095 if (result.Succeeded())
2096 {
2097 if (valid_bp_ids.GetSize() == 0)
2098 {
2099 result.SetError("No breakpoints specified, cannot add names.");
2100 result.SetStatus (eReturnStatusFailed);
2101 return false;
2102 }
2103 size_t num_valid_ids = valid_bp_ids.GetSize();
2104 for (size_t index = 0; index < num_valid_ids; index++)
2105 {
2106 lldb::break_id_t bp_id = valid_bp_ids.GetBreakpointIDAtIndex(index).GetBreakpointID();
2107 BreakpointSP bp_sp = breakpoints.FindBreakpointByID(bp_id);
2108 Error error; // We don't need to check the error here, since the option parser checked it...
2109 bp_sp->AddName(m_name_options.m_name.GetCurrentValue(), error);
2110 }
2111 }
2112
2113 return true;
2114 }
2115
2116private:
2117 BreakpointNameOptionGroup m_name_options;
2118 OptionGroupOptions m_option_group;
2119};
2120
Jim Ingham5e09c8c2014-12-16 23:40:14 +00002121class CommandObjectBreakpointNameDelete : public CommandObjectParsed
2122{
2123public:
2124 CommandObjectBreakpointNameDelete (CommandInterpreter &interpreter) :
2125 CommandObjectParsed (interpreter,
2126 "delete",
2127 "Delete a name from the breakpoints provided.",
2128 "breakpoint name delete <command-options> <breakpoint-id-list>"),
2129 m_name_options(),
Todd Fialae1cfbc72016-08-11 23:51:28 +00002130 m_option_group()
Jim Ingham5e09c8c2014-12-16 23:40:14 +00002131 {
2132 // Create the first variant for the first (and only) argument for this command.
2133 CommandArgumentEntry arg1;
2134 CommandArgumentData id_arg;
2135 id_arg.arg_type = eArgTypeBreakpointID;
2136 id_arg.arg_repetition = eArgRepeatOptional;
2137 arg1.push_back(id_arg);
2138 m_arguments.push_back (arg1);
2139
2140 m_option_group.Append (&m_name_options, LLDB_OPT_SET_1, LLDB_OPT_SET_ALL);
2141 m_option_group.Finalize();
2142 }
2143
Eugene Zelenko9e85e5a2016-02-18 22:39:14 +00002144 ~CommandObjectBreakpointNameDelete() override = default;
Jim Ingham5e09c8c2014-12-16 23:40:14 +00002145
Eugene Zelenko9e85e5a2016-02-18 22:39:14 +00002146 Options *
2147 GetOptions() override
2148 {
2149 return &m_option_group;
2150 }
2151
Jim Ingham5e09c8c2014-12-16 23:40:14 +00002152protected:
Bruce Mitchener13d21e92015-10-07 16:56:17 +00002153 bool
2154 DoExecute (Args& command, CommandReturnObject &result) override
Jim Ingham5e09c8c2014-12-16 23:40:14 +00002155 {
2156 if (!m_name_options.m_name.OptionWasSet())
2157 {
2158 result.SetError("No name option provided.");
2159 return false;
2160 }
2161
2162 Target *target = GetSelectedOrDummyTarget(m_name_options.m_use_dummy.GetCurrentValue());
2163
Eugene Zelenko9e85e5a2016-02-18 22:39:14 +00002164 if (target == nullptr)
Jim Ingham5e09c8c2014-12-16 23:40:14 +00002165 {
2166 result.AppendError ("Invalid target. No existing target or breakpoints.");
2167 result.SetStatus (eReturnStatusFailed);
2168 return false;
2169 }
2170
Saleem Abdulrasoolbb19a132016-05-19 05:13:57 +00002171 std::unique_lock<std::recursive_mutex> lock;
2172 target->GetBreakpointList().GetListMutex(lock);
2173
Jim Ingham5e09c8c2014-12-16 23:40:14 +00002174 const BreakpointList &breakpoints = target->GetBreakpointList();
2175
2176 size_t num_breakpoints = breakpoints.GetSize();
2177 if (num_breakpoints == 0)
2178 {
2179 result.SetError("No breakpoints, cannot delete names.");
2180 result.SetStatus (eReturnStatusFailed);
2181 return false;
2182 }
2183
2184 // Particular breakpoint selected; disable that breakpoint.
2185 BreakpointIDList valid_bp_ids;
2186 CommandObjectMultiwordBreakpoint::VerifyBreakpointIDs (command, target, result, &valid_bp_ids);
2187
2188 if (result.Succeeded())
2189 {
2190 if (valid_bp_ids.GetSize() == 0)
2191 {
2192 result.SetError("No breakpoints specified, cannot delete names.");
2193 result.SetStatus (eReturnStatusFailed);
2194 return false;
2195 }
2196 size_t num_valid_ids = valid_bp_ids.GetSize();
2197 for (size_t index = 0; index < num_valid_ids; index++)
2198 {
2199 lldb::break_id_t bp_id = valid_bp_ids.GetBreakpointIDAtIndex(index).GetBreakpointID();
2200 BreakpointSP bp_sp = breakpoints.FindBreakpointByID(bp_id);
2201 bp_sp->RemoveName(m_name_options.m_name.GetCurrentValue());
2202 }
2203 }
2204
2205 return true;
2206 }
2207
2208private:
2209 BreakpointNameOptionGroup m_name_options;
2210 OptionGroupOptions m_option_group;
2211};
2212
2213class CommandObjectBreakpointNameList : public CommandObjectParsed
2214{
2215public:
2216 CommandObjectBreakpointNameList (CommandInterpreter &interpreter) :
2217 CommandObjectParsed (interpreter,
2218 "list",
2219 "List either the names for a breakpoint or the breakpoints for a given name.",
2220 "breakpoint name list <command-options>"),
2221 m_name_options(),
Todd Fialae1cfbc72016-08-11 23:51:28 +00002222 m_option_group()
Jim Ingham5e09c8c2014-12-16 23:40:14 +00002223 {
2224 m_option_group.Append (&m_name_options);
2225 m_option_group.Finalize();
2226 }
2227
Eugene Zelenko9e85e5a2016-02-18 22:39:14 +00002228 ~CommandObjectBreakpointNameList() override = default;
Jim Ingham5e09c8c2014-12-16 23:40:14 +00002229
Eugene Zelenko9e85e5a2016-02-18 22:39:14 +00002230 Options *
2231 GetOptions() override
2232 {
2233 return &m_option_group;
2234 }
2235
Jim Ingham5e09c8c2014-12-16 23:40:14 +00002236protected:
Bruce Mitchener13d21e92015-10-07 16:56:17 +00002237 bool
2238 DoExecute (Args& command, CommandReturnObject &result) override
Jim Ingham5e09c8c2014-12-16 23:40:14 +00002239 {
2240 Target *target = GetSelectedOrDummyTarget(m_name_options.m_use_dummy.GetCurrentValue());
2241
Eugene Zelenko9e85e5a2016-02-18 22:39:14 +00002242 if (target == nullptr)
Jim Ingham5e09c8c2014-12-16 23:40:14 +00002243 {
2244 result.AppendError ("Invalid target. No existing target or breakpoints.");
2245 result.SetStatus (eReturnStatusFailed);
2246 return false;
2247 }
2248
2249 if (m_name_options.m_name.OptionWasSet())
2250 {
2251 const char *name = m_name_options.m_name.GetCurrentValue();
Saleem Abdulrasoolbb19a132016-05-19 05:13:57 +00002252 std::unique_lock<std::recursive_mutex> lock;
2253 target->GetBreakpointList().GetListMutex(lock);
2254
Jim Ingham5e09c8c2014-12-16 23:40:14 +00002255 BreakpointList &breakpoints = target->GetBreakpointList();
2256 for (BreakpointSP bp_sp : breakpoints.Breakpoints())
2257 {
2258 if (bp_sp->MatchesName(name))
2259 {
2260 StreamString s;
2261 bp_sp->GetDescription(&s, eDescriptionLevelBrief);
2262 s.EOL();
2263 result.AppendMessage(s.GetData());
2264 }
2265 }
2266
2267 }
2268 else if (m_name_options.m_breakpoint.OptionWasSet())
2269 {
2270 BreakpointSP bp_sp = target->GetBreakpointList().FindBreakpointByID(m_name_options.m_breakpoint.GetCurrentValue());
2271 if (bp_sp)
2272 {
2273 std::vector<std::string> names;
2274 bp_sp->GetNames (names);
2275 result.AppendMessage ("Names:");
2276 for (auto name : names)
2277 result.AppendMessageWithFormat (" %s\n", name.c_str());
2278 }
2279 else
2280 {
2281 result.AppendErrorWithFormat ("Could not find breakpoint %" PRId64 ".\n",
2282 m_name_options.m_breakpoint.GetCurrentValue());
2283 result.SetStatus (eReturnStatusFailed);
2284 return false;
2285 }
2286 }
2287 else
2288 {
2289 result.SetError ("Must specify -N or -B option to list.");
2290 result.SetStatus (eReturnStatusFailed);
2291 return false;
2292 }
2293 return true;
2294 }
2295
2296private:
2297 BreakpointNameOptionGroup m_name_options;
2298 OptionGroupOptions m_option_group;
2299};
2300
2301//-------------------------------------------------------------------------
2302// CommandObjectMultiwordBreakpoint
2303//-------------------------------------------------------------------------
2304class CommandObjectBreakpointName : public CommandObjectMultiword
2305{
2306public:
Kate Stone7428a182016-07-14 22:03:10 +00002307 CommandObjectBreakpointName(CommandInterpreter &interpreter)
2308 : CommandObjectMultiword(interpreter, "name", "Commands to manage name tags for breakpoints",
2309 "breakpoint name <subcommand> [<command-options>]")
Jim Ingham5e09c8c2014-12-16 23:40:14 +00002310 {
2311 CommandObjectSP add_command_object (new CommandObjectBreakpointNameAdd (interpreter));
2312 CommandObjectSP delete_command_object (new CommandObjectBreakpointNameDelete (interpreter));
2313 CommandObjectSP list_command_object (new CommandObjectBreakpointNameList (interpreter));
2314
2315 LoadSubCommand ("add", add_command_object);
2316 LoadSubCommand ("delete", delete_command_object);
2317 LoadSubCommand ("list", list_command_object);
Jim Ingham5e09c8c2014-12-16 23:40:14 +00002318 }
2319
Eugene Zelenko9e85e5a2016-02-18 22:39:14 +00002320 ~CommandObjectBreakpointName() override = default;
Jim Ingham5e09c8c2014-12-16 23:40:14 +00002321};
2322
Jim Ingham5e09c8c2014-12-16 23:40:14 +00002323//-------------------------------------------------------------------------
Chris Lattner30fdc8d2010-06-08 16:52:24 +00002324// CommandObjectMultiwordBreakpoint
2325//-------------------------------------------------------------------------
Jim Inghamae1c4cf2010-06-18 00:58:52 +00002326#pragma mark MultiwordBreakpoint
Chris Lattner30fdc8d2010-06-08 16:52:24 +00002327
Kate Stone7428a182016-07-14 22:03:10 +00002328CommandObjectMultiwordBreakpoint::CommandObjectMultiwordBreakpoint(CommandInterpreter &interpreter)
2329 : CommandObjectMultiword(interpreter, "breakpoint",
2330 "Commands for operating on breakpoints (see 'help b' for shorthand.)",
2331 "breakpoint <subcommand> [<command-options>]")
Chris Lattner30fdc8d2010-06-08 16:52:24 +00002332{
Greg Claytona7015092010-09-18 01:14:36 +00002333 CommandObjectSP list_command_object (new CommandObjectBreakpointList (interpreter));
Greg Claytona7015092010-09-18 01:14:36 +00002334 CommandObjectSP enable_command_object (new CommandObjectBreakpointEnable (interpreter));
2335 CommandObjectSP disable_command_object (new CommandObjectBreakpointDisable (interpreter));
Johnny Chenb7234e42010-10-28 17:27:46 +00002336 CommandObjectSP clear_command_object (new CommandObjectBreakpointClear (interpreter));
2337 CommandObjectSP delete_command_object (new CommandObjectBreakpointDelete (interpreter));
Greg Claytona7015092010-09-18 01:14:36 +00002338 CommandObjectSP set_command_object (new CommandObjectBreakpointSet (interpreter));
Chris Lattner30fdc8d2010-06-08 16:52:24 +00002339 CommandObjectSP command_command_object (new CommandObjectBreakpointCommand (interpreter));
Greg Claytona7015092010-09-18 01:14:36 +00002340 CommandObjectSP modify_command_object (new CommandObjectBreakpointModify(interpreter));
Jim Ingham5e09c8c2014-12-16 23:40:14 +00002341 CommandObjectSP name_command_object (new CommandObjectBreakpointName(interpreter));
Chris Lattner30fdc8d2010-06-08 16:52:24 +00002342
Johnny Chenb7234e42010-10-28 17:27:46 +00002343 list_command_object->SetCommandName ("breakpoint list");
Chris Lattner30fdc8d2010-06-08 16:52:24 +00002344 enable_command_object->SetCommandName("breakpoint enable");
2345 disable_command_object->SetCommandName("breakpoint disable");
Johnny Chenb7234e42010-10-28 17:27:46 +00002346 clear_command_object->SetCommandName("breakpoint clear");
2347 delete_command_object->SetCommandName("breakpoint delete");
Jim Inghamae1c4cf2010-06-18 00:58:52 +00002348 set_command_object->SetCommandName("breakpoint set");
Johnny Chenb7234e42010-10-28 17:27:46 +00002349 command_command_object->SetCommandName ("breakpoint command");
2350 modify_command_object->SetCommandName ("breakpoint modify");
Jim Ingham5e09c8c2014-12-16 23:40:14 +00002351 name_command_object->SetCommandName ("breakpoint name");
Chris Lattner30fdc8d2010-06-08 16:52:24 +00002352
Greg Clayton23f59502012-07-17 03:23:13 +00002353 LoadSubCommand ("list", list_command_object);
2354 LoadSubCommand ("enable", enable_command_object);
2355 LoadSubCommand ("disable", disable_command_object);
2356 LoadSubCommand ("clear", clear_command_object);
2357 LoadSubCommand ("delete", delete_command_object);
2358 LoadSubCommand ("set", set_command_object);
2359 LoadSubCommand ("command", command_command_object);
2360 LoadSubCommand ("modify", modify_command_object);
Jim Ingham5e09c8c2014-12-16 23:40:14 +00002361 LoadSubCommand ("name", name_command_object);
Chris Lattner30fdc8d2010-06-08 16:52:24 +00002362}
2363
Eugene Zelenko9e85e5a2016-02-18 22:39:14 +00002364CommandObjectMultiwordBreakpoint::~CommandObjectMultiwordBreakpoint() = default;
Chris Lattner30fdc8d2010-06-08 16:52:24 +00002365
2366void
Jim Ingham5e09c8c2014-12-16 23:40:14 +00002367CommandObjectMultiwordBreakpoint::VerifyIDs (Args &args,
2368 Target *target,
2369 bool allow_locations,
2370 CommandReturnObject &result,
2371 BreakpointIDList *valid_ids)
Chris Lattner30fdc8d2010-06-08 16:52:24 +00002372{
2373 // args can be strings representing 1). integers (for breakpoint ids)
2374 // 2). the full breakpoint & location canonical representation
2375 // 3). the word "to" or a hyphen, representing a range (in which case there
2376 // had *better* be an entry both before & after of one of the first two types.
Jim Ingham5e09c8c2014-12-16 23:40:14 +00002377 // 4). A breakpoint name
Jim Ingham36f3b362010-10-14 23:45:03 +00002378 // If args is empty, we will use the last created breakpoint (if there is one.)
Chris Lattner30fdc8d2010-06-08 16:52:24 +00002379
2380 Args temp_args;
2381
Jim Ingham36f3b362010-10-14 23:45:03 +00002382 if (args.GetArgumentCount() == 0)
2383 {
Greg Clayton4d122c42011-09-17 08:33:22 +00002384 if (target->GetLastCreatedBreakpoint())
Jim Ingham36f3b362010-10-14 23:45:03 +00002385 {
2386 valid_ids->AddBreakpointID (BreakpointID(target->GetLastCreatedBreakpoint()->GetID(), LLDB_INVALID_BREAK_ID));
2387 result.SetStatus (eReturnStatusSuccessFinishNoResult);
2388 }
2389 else
2390 {
2391 result.AppendError("No breakpoint specified and no last created breakpoint.");
2392 result.SetStatus (eReturnStatusFailed);
2393 }
2394 return;
2395 }
2396
Chris Lattner30fdc8d2010-06-08 16:52:24 +00002397 // Create a new Args variable to use; copy any non-breakpoint-id-ranges stuff directly from the old ARGS to
2398 // the new TEMP_ARGS. Do not copy breakpoint id range strings over; instead generate a list of strings for
2399 // all the breakpoint ids in the range, and shove all of those breakpoint id strings into TEMP_ARGS.
2400
Jim Ingham5e09c8c2014-12-16 23:40:14 +00002401 BreakpointIDList::FindAndReplaceIDRanges (args, target, allow_locations, result, temp_args);
Chris Lattner30fdc8d2010-06-08 16:52:24 +00002402
2403 // NOW, convert the list of breakpoint id strings in TEMP_ARGS into an actual BreakpointIDList:
2404
Greg Claytonc982c762010-07-09 20:39:50 +00002405 valid_ids->InsertStringArray (temp_args.GetConstArgumentVector(), temp_args.GetArgumentCount(), result);
Chris Lattner30fdc8d2010-06-08 16:52:24 +00002406
2407 // At this point, all of the breakpoint ids that the user passed in have been converted to breakpoint IDs
2408 // and put into valid_ids.
2409
2410 if (result.Succeeded())
2411 {
2412 // Now that we've converted everything from args into a list of breakpoint ids, go through our tentative list
2413 // of breakpoint id's and verify that they correspond to valid/currently set breakpoints.
2414
Greg Claytonc982c762010-07-09 20:39:50 +00002415 const size_t count = valid_ids->GetSize();
2416 for (size_t i = 0; i < count; ++i)
Chris Lattner30fdc8d2010-06-08 16:52:24 +00002417 {
2418 BreakpointID cur_bp_id = valid_ids->GetBreakpointIDAtIndex (i);
2419 Breakpoint *breakpoint = target->GetBreakpointByID (cur_bp_id.GetBreakpointID()).get();
Eugene Zelenko9e85e5a2016-02-18 22:39:14 +00002420 if (breakpoint != nullptr)
Chris Lattner30fdc8d2010-06-08 16:52:24 +00002421 {
Greg Claytonc7bece562013-01-25 18:06:21 +00002422 const size_t num_locations = breakpoint->GetNumLocations();
Saleem Abdulrasool3985c8c2014-04-02 03:51:35 +00002423 if (static_cast<size_t>(cur_bp_id.GetLocationID()) > num_locations)
Chris Lattner30fdc8d2010-06-08 16:52:24 +00002424 {
2425 StreamString id_str;
Greg Claytonc982c762010-07-09 20:39:50 +00002426 BreakpointID::GetCanonicalReference (&id_str,
2427 cur_bp_id.GetBreakpointID(),
2428 cur_bp_id.GetLocationID());
2429 i = valid_ids->GetSize() + 1;
Chris Lattner30fdc8d2010-06-08 16:52:24 +00002430 result.AppendErrorWithFormat ("'%s' is not a currently valid breakpoint/location id.\n",
2431 id_str.GetData());
2432 result.SetStatus (eReturnStatusFailed);
2433 }
2434 }
2435 else
2436 {
Greg Claytonc982c762010-07-09 20:39:50 +00002437 i = valid_ids->GetSize() + 1;
Kate Stone7428a182016-07-14 22:03:10 +00002438 result.AppendErrorWithFormat("'%d' is not a currently valid breakpoint ID.\n",
2439 cur_bp_id.GetBreakpointID());
Chris Lattner30fdc8d2010-06-08 16:52:24 +00002440 result.SetStatus (eReturnStatusFailed);
2441 }
2442 }
2443 }
2444}