blob: bb8617f9780589b63b9ec92b02a3c02bf2600ad4 [file] [log] [blame]
Chris Lattner24943d22010-06-08 16:52:24 +00001//===-- CommandObjectBreakpoint.cpp -----------------------------*- C++ -*-===//
2//
3// The LLVM Compiler Infrastructure
4//
5// This file is distributed under the University of Illinois Open Source
6// License. See LICENSE.TXT for details.
7//
8//===----------------------------------------------------------------------===//
9
10#include "CommandObjectBreakpoint.h"
11#include "CommandObjectBreakpointCommand.h"
12
13// C Includes
14// C++ Includes
15// Other libraries and framework includes
16// Project includes
17#include "lldb/Breakpoint/Breakpoint.h"
18#include "lldb/Breakpoint/BreakpointIDList.h"
19#include "lldb/Breakpoint/BreakpointLocation.h"
Jim Ingham84cdc152010-06-15 19:49:27 +000020#include "lldb/Interpreter/Options.h"
Chris Lattner24943d22010-06-08 16:52:24 +000021#include "lldb/Core/RegularExpression.h"
22#include "lldb/Core/StreamString.h"
23#include "lldb/Interpreter/CommandInterpreter.h"
24#include "lldb/Interpreter/CommandReturnObject.h"
25#include "lldb/Target/Target.h"
26#include "lldb/Interpreter/CommandCompletions.h"
27#include "lldb/Target/StackFrame.h"
Jim Ingham3c7b5b92010-06-16 02:00:15 +000028#include "lldb/Target/Thread.h"
29#include "lldb/Target/ThreadSpec.h"
Chris Lattner24943d22010-06-08 16:52:24 +000030
Johnny Chena62ad7c2010-10-28 17:27:46 +000031#include <vector>
32
Chris Lattner24943d22010-06-08 16:52:24 +000033using namespace lldb;
34using namespace lldb_private;
35
36static void
Jim Ingham2e8cb8a2011-02-19 02:53:09 +000037AddBreakpointDescription (Stream *s, Breakpoint *bp, lldb::DescriptionLevel level)
Chris Lattner24943d22010-06-08 16:52:24 +000038{
39 s->IndentMore();
40 bp->GetDescription (s, level, true);
41 s->IndentLess();
42 s->EOL();
43}
44
45//-------------------------------------------------------------------------
Jim Inghamda26bd22012-06-08 21:56:10 +000046// CommandObjectBreakpointSet
Chris Lattner24943d22010-06-08 16:52:24 +000047//-------------------------------------------------------------------------
48
Jim Inghamda26bd22012-06-08 21:56:10 +000049
50class CommandObjectBreakpointSet : public CommandObjectParsed
Chris Lattner24943d22010-06-08 16:52:24 +000051{
Jim Inghamda26bd22012-06-08 21:56:10 +000052public:
Chris Lattner24943d22010-06-08 16:52:24 +000053
Jim Inghamda26bd22012-06-08 21:56:10 +000054 typedef enum BreakpointSetType
55 {
56 eSetTypeInvalid,
57 eSetTypeFileAndLine,
58 eSetTypeAddress,
59 eSetTypeFunctionName,
60 eSetTypeFunctionRegexp,
61 eSetTypeSourceRegexp,
62 eSetTypeException
63 } BreakpointSetType;
Chris Lattner24943d22010-06-08 16:52:24 +000064
Jim Inghamda26bd22012-06-08 21:56:10 +000065 CommandObjectBreakpointSet (CommandInterpreter &interpreter) :
66 CommandObjectParsed (interpreter,
67 "breakpoint set",
68 "Sets a breakpoint or set of breakpoints in the executable.",
69 "breakpoint set <cmd-options>"),
70 m_options (interpreter)
71 {
72 }
73
74
75 virtual
76 ~CommandObjectBreakpointSet () {}
77
78 virtual Options *
79 GetOptions ()
80 {
81 return &m_options;
82 }
83
84 class CommandOptions : public Options
85 {
86 public:
87
88 CommandOptions (CommandInterpreter &interpreter) :
89 Options (interpreter),
90 m_condition (),
91 m_filenames (),
92 m_line_num (0),
93 m_column (0),
Jim Inghamda26bd22012-06-08 21:56:10 +000094 m_func_names (),
95 m_func_name_type_mask (eFunctionNameTypeNone),
96 m_func_regexp (),
97 m_source_text_regexp(),
98 m_modules (),
99 m_load_addr(),
100 m_ignore_count (0),
101 m_thread_id(LLDB_INVALID_THREAD_ID),
102 m_thread_index (UINT32_MAX),
103 m_thread_name(),
104 m_queue_name(),
105 m_catch_bp (false),
Greg Clayton49ce8962012-08-29 21:13:06 +0000106 m_throw_bp (true),
Jim Inghamda26bd22012-06-08 21:56:10 +0000107 m_language (eLanguageTypeUnknown),
Jim Ingham2753a022012-10-05 19:16:31 +0000108 m_skip_prologue (eLazyBoolCalculate),
109 m_one_shot (false)
Jim Inghamda26bd22012-06-08 21:56:10 +0000110 {
111 }
112
113
114 virtual
115 ~CommandOptions () {}
116
117 virtual Error
118 SetOptionValue (uint32_t option_idx, const char *option_arg)
119 {
120 Error error;
Greg Clayton6475c422012-12-04 00:32:51 +0000121 const int short_option = m_getopt_table[option_idx].val;
Jim Inghamda26bd22012-06-08 21:56:10 +0000122
123 switch (short_option)
124 {
125 case 'a':
126 m_load_addr = Args::StringToUInt64(option_arg, LLDB_INVALID_ADDRESS, 0);
127 if (m_load_addr == LLDB_INVALID_ADDRESS)
128 m_load_addr = Args::StringToUInt64(option_arg, LLDB_INVALID_ADDRESS, 16);
129
130 if (m_load_addr == LLDB_INVALID_ADDRESS)
131 error.SetErrorStringWithFormat ("invalid address string '%s'", option_arg);
132 break;
133
Jim Ingham2753a022012-10-05 19:16:31 +0000134 case 'b':
135 m_func_names.push_back (option_arg);
136 m_func_name_type_mask |= eFunctionNameTypeBase;
137 break;
138
Jim Inghamda26bd22012-06-08 21:56:10 +0000139 case 'C':
140 m_column = Args::StringToUInt32 (option_arg, 0);
141 break;
142
143 case 'c':
144 m_condition.assign(option_arg);
145 break;
146
Jim Inghamda26bd22012-06-08 21:56:10 +0000147 case 'E':
148 {
149 LanguageType language = LanguageRuntime::GetLanguageTypeFromString (option_arg);
150
151 switch (language)
152 {
153 case eLanguageTypeC89:
154 case eLanguageTypeC:
155 case eLanguageTypeC99:
156 m_language = eLanguageTypeC;
157 break;
158 case eLanguageTypeC_plus_plus:
159 m_language = eLanguageTypeC_plus_plus;
160 break;
161 case eLanguageTypeObjC:
162 m_language = eLanguageTypeObjC;
163 break;
164 case eLanguageTypeObjC_plus_plus:
165 error.SetErrorStringWithFormat ("Set exception breakpoints separately for c++ and objective-c");
166 break;
167 case eLanguageTypeUnknown:
168 error.SetErrorStringWithFormat ("Unknown language type: '%s' for exception breakpoint", option_arg);
169 break;
170 default:
171 error.SetErrorStringWithFormat ("Unsupported language type: '%s' for exception breakpoint", option_arg);
172 }
173 }
174 break;
Jim Ingham2753a022012-10-05 19:16:31 +0000175
176 case 'f':
177 m_filenames.AppendIfUnique (FileSpec(option_arg, false));
178 break;
179
180 case 'F':
181 m_func_names.push_back (option_arg);
182 m_func_name_type_mask |= eFunctionNameTypeFull;
183 break;
184
Jim Inghamda26bd22012-06-08 21:56:10 +0000185 case 'h':
186 {
187 bool success;
188 m_catch_bp = Args::StringToBoolean (option_arg, true, &success);
189 if (!success)
190 error.SetErrorStringWithFormat ("Invalid boolean value for on-catch option: '%s'", option_arg);
191 }
Jim Ingham2753a022012-10-05 19:16:31 +0000192
193 case 'i':
194 {
195 m_ignore_count = Args::StringToUInt32(option_arg, UINT32_MAX, 0);
196 if (m_ignore_count == UINT32_MAX)
197 error.SetErrorStringWithFormat ("invalid ignore count '%s'", option_arg);
198 break;
199 }
200
Jim Inghamda26bd22012-06-08 21:56:10 +0000201 case 'K':
202 {
203 bool success;
204 bool value;
205 value = Args::StringToBoolean (option_arg, true, &success);
206 if (value)
207 m_skip_prologue = eLazyBoolYes;
208 else
209 m_skip_prologue = eLazyBoolNo;
210
211 if (!success)
212 error.SetErrorStringWithFormat ("Invalid boolean value for skip prologue option: '%s'", option_arg);
213 }
214 break;
Jim Ingham2753a022012-10-05 19:16:31 +0000215
216 case 'l':
217 m_line_num = Args::StringToUInt32 (option_arg, 0);
218 break;
219
220 case 'M':
221 m_func_names.push_back (option_arg);
222 m_func_name_type_mask |= eFunctionNameTypeMethod;
223 break;
224
225 case 'n':
226 m_func_names.push_back (option_arg);
227 m_func_name_type_mask |= eFunctionNameTypeAuto;
228 break;
229
230 case 'o':
231 m_one_shot = true;
232 break;
233
234 case 'p':
235 m_source_text_regexp.assign (option_arg);
236 break;
237
238 case 'q':
239 m_queue_name.assign (option_arg);
240 break;
241
242 case 'r':
243 m_func_regexp.assign (option_arg);
244 break;
245
246 case 's':
247 {
248 m_modules.AppendIfUnique (FileSpec (option_arg, false));
249 break;
250 }
251
252 case 'S':
253 m_func_names.push_back (option_arg);
254 m_func_name_type_mask |= eFunctionNameTypeSelector;
255 break;
256
257 case 't' :
258 {
259 m_thread_id = Args::StringToUInt64(option_arg, LLDB_INVALID_THREAD_ID, 0);
260 if (m_thread_id == LLDB_INVALID_THREAD_ID)
261 error.SetErrorStringWithFormat ("invalid thread id string '%s'", option_arg);
262 }
263 break;
264
265 case 'T':
266 m_thread_name.assign (option_arg);
267 break;
268
269 case 'w':
270 {
271 bool success;
272 m_throw_bp = Args::StringToBoolean (option_arg, true, &success);
273 if (!success)
274 error.SetErrorStringWithFormat ("Invalid boolean value for on-throw option: '%s'", option_arg);
275 }
276 break;
277
278 case 'x':
279 {
280 m_thread_index = Args::StringToUInt32(option_arg, UINT32_MAX, 0);
281 if (m_thread_id == UINT32_MAX)
282 error.SetErrorStringWithFormat ("invalid thread index string '%s'", option_arg);
283
284 }
285 break;
286
Jim Inghamda26bd22012-06-08 21:56:10 +0000287 default:
288 error.SetErrorStringWithFormat ("unrecognized option '%c'", short_option);
289 break;
290 }
291
292 return error;
293 }
294 void
295 OptionParsingStarting ()
296 {
297 m_condition.clear();
298 m_filenames.Clear();
299 m_line_num = 0;
300 m_column = 0;
301 m_func_names.clear();
Greg Clayton49ce8962012-08-29 21:13:06 +0000302 m_func_name_type_mask = eFunctionNameTypeNone;
Jim Inghamda26bd22012-06-08 21:56:10 +0000303 m_func_regexp.clear();
Greg Clayton49ce8962012-08-29 21:13:06 +0000304 m_source_text_regexp.clear();
Jim Inghamda26bd22012-06-08 21:56:10 +0000305 m_modules.Clear();
Greg Clayton49ce8962012-08-29 21:13:06 +0000306 m_load_addr = LLDB_INVALID_ADDRESS;
Jim Inghamda26bd22012-06-08 21:56:10 +0000307 m_ignore_count = 0;
308 m_thread_id = LLDB_INVALID_THREAD_ID;
309 m_thread_index = UINT32_MAX;
310 m_thread_name.clear();
311 m_queue_name.clear();
Jim Inghamda26bd22012-06-08 21:56:10 +0000312 m_catch_bp = false;
313 m_throw_bp = true;
Greg Clayton49ce8962012-08-29 21:13:06 +0000314 m_language = eLanguageTypeUnknown;
Jim Inghamda26bd22012-06-08 21:56:10 +0000315 m_skip_prologue = eLazyBoolCalculate;
Jim Ingham2753a022012-10-05 19:16:31 +0000316 m_one_shot = false;
Jim Inghamda26bd22012-06-08 21:56:10 +0000317 }
318
319 const OptionDefinition*
320 GetDefinitions ()
321 {
322 return g_option_table;
323 }
324
325 // Options table: Required for subclasses of Options.
326
327 static OptionDefinition g_option_table[];
328
329 // Instance variables to hold the values for command options.
330
331 std::string m_condition;
332 FileSpecList m_filenames;
333 uint32_t m_line_num;
334 uint32_t m_column;
Jim Inghamda26bd22012-06-08 21:56:10 +0000335 std::vector<std::string> m_func_names;
336 uint32_t m_func_name_type_mask;
337 std::string m_func_regexp;
338 std::string m_source_text_regexp;
339 FileSpecList m_modules;
340 lldb::addr_t m_load_addr;
341 uint32_t m_ignore_count;
342 lldb::tid_t m_thread_id;
343 uint32_t m_thread_index;
344 std::string m_thread_name;
345 std::string m_queue_name;
346 bool m_catch_bp;
347 bool m_throw_bp;
348 lldb::LanguageType m_language;
349 LazyBool m_skip_prologue;
Jim Ingham2753a022012-10-05 19:16:31 +0000350 bool m_one_shot;
Jim Inghamda26bd22012-06-08 21:56:10 +0000351
352 };
353
354protected:
355 virtual bool
356 DoExecute (Args& command,
357 CommandReturnObject &result)
358 {
359 Target *target = m_interpreter.GetDebugger().GetSelectedTarget().get();
360 if (target == NULL)
361 {
362 result.AppendError ("Invalid target. Must set target before setting breakpoints (see 'target create' command).");
363 result.SetStatus (eReturnStatusFailed);
364 return false;
365 }
366
367 // The following are the various types of breakpoints that could be set:
368 // 1). -f -l -p [-s -g] (setting breakpoint by source location)
369 // 2). -a [-s -g] (setting breakpoint by address)
370 // 3). -n [-s -g] (setting breakpoint by function name)
371 // 4). -r [-s -g] (setting breakpoint by function name regular expression)
372 // 5). -p -f (setting a breakpoint by comparing a reg-exp to source text)
373 // 6). -E [-w -h] (setting a breakpoint for exceptions for a given language.)
374
375 BreakpointSetType break_type = eSetTypeInvalid;
376
377 if (m_options.m_line_num != 0)
378 break_type = eSetTypeFileAndLine;
379 else if (m_options.m_load_addr != LLDB_INVALID_ADDRESS)
380 break_type = eSetTypeAddress;
381 else if (!m_options.m_func_names.empty())
382 break_type = eSetTypeFunctionName;
383 else if (!m_options.m_func_regexp.empty())
384 break_type = eSetTypeFunctionRegexp;
385 else if (!m_options.m_source_text_regexp.empty())
386 break_type = eSetTypeSourceRegexp;
387 else if (m_options.m_language != eLanguageTypeUnknown)
388 break_type = eSetTypeException;
389
390 Breakpoint *bp = NULL;
391 FileSpec module_spec;
Jim Inghamda26bd22012-06-08 21:56:10 +0000392 const bool internal = false;
393
Jim Inghamda26bd22012-06-08 21:56:10 +0000394 switch (break_type)
395 {
396 case eSetTypeFileAndLine: // Breakpoint by source position
397 {
398 FileSpec file;
399 uint32_t num_files = m_options.m_filenames.GetSize();
400 if (num_files == 0)
401 {
402 if (!GetDefaultFile (target, file, result))
403 {
404 result.AppendError("No file supplied and no default file available.");
405 result.SetStatus (eReturnStatusFailed);
406 return false;
407 }
408 }
409 else if (num_files > 1)
410 {
411 result.AppendError("Only one file at a time is allowed for file and line breakpoints.");
412 result.SetStatus (eReturnStatusFailed);
413 return false;
414 }
415 else
416 file = m_options.m_filenames.GetFileSpecAtIndex(0);
Greg Clayton49ce8962012-08-29 21:13:06 +0000417
418 // Only check for inline functions if
419 LazyBool check_inlines = eLazyBoolCalculate;
420
Jim Inghamda26bd22012-06-08 21:56:10 +0000421 bp = target->CreateBreakpoint (&(m_options.m_modules),
422 file,
423 m_options.m_line_num,
Greg Clayton49ce8962012-08-29 21:13:06 +0000424 check_inlines,
Jim Inghamda26bd22012-06-08 21:56:10 +0000425 m_options.m_skip_prologue,
426 internal).get();
427 }
428 break;
429
430 case eSetTypeAddress: // Breakpoint by address
431 bp = target->CreateBreakpoint (m_options.m_load_addr, false).get();
432 break;
433
434 case eSetTypeFunctionName: // Breakpoint by function name
435 {
436 uint32_t name_type_mask = m_options.m_func_name_type_mask;
437
438 if (name_type_mask == 0)
439 name_type_mask = eFunctionNameTypeAuto;
440
441 bp = target->CreateBreakpoint (&(m_options.m_modules),
442 &(m_options.m_filenames),
443 m_options.m_func_names,
444 name_type_mask,
445 m_options.m_skip_prologue,
446 internal).get();
447 }
448 break;
449
450 case eSetTypeFunctionRegexp: // Breakpoint by regular expression function name
451 {
452 RegularExpression regexp(m_options.m_func_regexp.c_str());
453 if (!regexp.IsValid())
454 {
455 char err_str[1024];
456 regexp.GetErrorAsCString(err_str, sizeof(err_str));
457 result.AppendErrorWithFormat("Function name regular expression could not be compiled: \"%s\"",
458 err_str);
459 result.SetStatus (eReturnStatusFailed);
460 return false;
461 }
462
463 bp = target->CreateFuncRegexBreakpoint (&(m_options.m_modules),
464 &(m_options.m_filenames),
465 regexp,
466 m_options.m_skip_prologue,
467 internal).get();
468 }
469 break;
470 case eSetTypeSourceRegexp: // Breakpoint by regexp on source text.
471 {
472 int num_files = m_options.m_filenames.GetSize();
473
474 if (num_files == 0)
475 {
476 FileSpec file;
477 if (!GetDefaultFile (target, file, result))
478 {
479 result.AppendError ("No files provided and could not find default file.");
480 result.SetStatus (eReturnStatusFailed);
481 return false;
482 }
483 else
484 {
485 m_options.m_filenames.Append (file);
486 }
487 }
488
489 RegularExpression regexp(m_options.m_source_text_regexp.c_str());
490 if (!regexp.IsValid())
491 {
492 char err_str[1024];
493 regexp.GetErrorAsCString(err_str, sizeof(err_str));
494 result.AppendErrorWithFormat("Source text regular expression could not be compiled: \"%s\"",
495 err_str);
496 result.SetStatus (eReturnStatusFailed);
497 return false;
498 }
499 bp = target->CreateSourceRegexBreakpoint (&(m_options.m_modules), &(m_options.m_filenames), regexp).get();
500 }
501 break;
502 case eSetTypeException:
503 {
504 bp = target->CreateExceptionBreakpoint (m_options.m_language, m_options.m_catch_bp, m_options.m_throw_bp).get();
505 }
506 break;
507 default:
508 break;
509 }
510
511 // Now set the various options that were passed in:
512 if (bp)
513 {
514 if (m_options.m_thread_id != LLDB_INVALID_THREAD_ID)
515 bp->SetThreadID (m_options.m_thread_id);
516
517 if (m_options.m_thread_index != UINT32_MAX)
518 bp->GetOptions()->GetThreadSpec()->SetIndex(m_options.m_thread_index);
519
520 if (!m_options.m_thread_name.empty())
521 bp->GetOptions()->GetThreadSpec()->SetName(m_options.m_thread_name.c_str());
522
523 if (!m_options.m_queue_name.empty())
524 bp->GetOptions()->GetThreadSpec()->SetQueueName(m_options.m_queue_name.c_str());
525
526 if (m_options.m_ignore_count != 0)
527 bp->GetOptions()->SetIgnoreCount(m_options.m_ignore_count);
528
529 if (!m_options.m_condition.empty())
530 bp->GetOptions()->SetCondition(m_options.m_condition.c_str());
Jim Ingham2753a022012-10-05 19:16:31 +0000531
532 bp->SetOneShot (m_options.m_one_shot);
Jim Inghamda26bd22012-06-08 21:56:10 +0000533 }
534
535 if (bp)
536 {
537 Stream &output_stream = result.GetOutputStream();
Jim Ingham4f61ba92012-09-22 00:04:04 +0000538 const bool show_locations = false;
539 bp->GetDescription(&output_stream, lldb::eDescriptionLevelInitial, show_locations);
Jim Inghamda26bd22012-06-08 21:56:10 +0000540 // Don't print out this warning for exception breakpoints. They can get set before the target
541 // is set, but we won't know how to actually set the breakpoint till we run.
542 if (bp->GetNumLocations() == 0 && break_type != eSetTypeException)
543 output_stream.Printf ("WARNING: Unable to resolve breakpoint to any actual locations.\n");
544 result.SetStatus (eReturnStatusSuccessFinishResult);
545 }
546 else if (!bp)
547 {
548 result.AppendError ("Breakpoint creation failed: No breakpoint created.");
549 result.SetStatus (eReturnStatusFailed);
550 }
551
552 return result.Succeeded();
553 }
554
555private:
556 bool
557 GetDefaultFile (Target *target, FileSpec &file, CommandReturnObject &result)
558 {
559 uint32_t default_line;
560 // First use the Source Manager's default file.
561 // Then use the current stack frame's file.
562 if (!target->GetSourceManager().GetDefaultFileAndLine(file, default_line))
563 {
564 StackFrame *cur_frame = m_interpreter.GetExecutionContext().GetFramePtr();
565 if (cur_frame == NULL)
566 {
567 result.AppendError ("No selected frame to use to find the default file.");
568 result.SetStatus (eReturnStatusFailed);
569 return false;
570 }
571 else if (!cur_frame->HasDebugInformation())
572 {
573 result.AppendError ("Cannot use the selected frame to find the default file, it has no debug info.");
574 result.SetStatus (eReturnStatusFailed);
575 return false;
576 }
577 else
578 {
579 const SymbolContext &sc = cur_frame->GetSymbolContext (eSymbolContextLineEntry);
580 if (sc.line_entry.file)
581 {
582 file = sc.line_entry.file;
583 }
584 else
585 {
586 result.AppendError ("Can't find the file for the selected frame to use as the default file.");
587 result.SetStatus (eReturnStatusFailed);
588 return false;
589 }
590 }
591 }
592 return true;
593 }
594
595 CommandOptions m_options;
596};
Johnny Chen8d03c6f2012-05-08 00:43:20 +0000597// If an additional option set beyond LLDB_OPTION_SET_10 is added, make sure to
598// update the numbers passed to LLDB_OPT_SET_FROM_TO(...) appropriately.
Johnny Chen6f4a1152012-05-07 23:23:41 +0000599#define LLDB_OPT_FILE ( LLDB_OPT_SET_FROM_TO(1, 9) & ~LLDB_OPT_SET_2 )
600#define LLDB_OPT_NOT_10 ( LLDB_OPT_SET_FROM_TO(1, 10) & ~LLDB_OPT_SET_10 )
Jim Ingham2cf5ccb2012-05-22 00:12:20 +0000601#define LLDB_OPT_SKIP_PROLOGUE ( LLDB_OPT_SET_1 | LLDB_OPT_SET_FROM_TO(3,8) )
Jim Inghamd6d47972011-09-23 00:54:11 +0000602
Greg Claytonb3448432011-03-24 21:19:54 +0000603OptionDefinition
Chris Lattner24943d22010-06-08 16:52:24 +0000604CommandObjectBreakpointSet::CommandOptions::g_option_table[] =
605{
Jim Ingham4722b102012-03-06 00:37:27 +0000606 { LLDB_OPT_NOT_10, false, "shlib", 's', required_argument, NULL, CommandCompletions::eModuleCompletion, eArgTypeShlibName,
Jim Inghamee033f22012-05-03 20:30:08 +0000607 "Set the breakpoint only in this shared library. "
608 "Can repeat this option multiple times to specify multiple shared libraries."},
Jim Ingham34e9a982010-06-15 18:47:14 +0000609
Caroline Tice4d6675c2010-10-01 19:59:14 +0000610 { LLDB_OPT_SET_ALL, false, "ignore-count", 'i', required_argument, NULL, 0, eArgTypeCount,
611 "Set the number of times this breakpoint is skipped before stopping." },
Jim Ingham3c7b5b92010-06-16 02:00:15 +0000612
Jim Ingham2753a022012-10-05 19:16:31 +0000613 { LLDB_OPT_SET_ALL, false, "one-shot", 'o', no_argument, NULL, 0, eArgTypeNone,
614 "The breakpoint is deleted the first time it stop causes a stop." },
615
Johnny Chene4f3cd72012-05-25 21:10:46 +0000616 { LLDB_OPT_SET_ALL, false, "condition", 'c', required_argument, NULL, 0, eArgTypeExpression,
617 "The breakpoint stops only if this condition expression evaluates to true."},
618
Bill Wendlingff7df6d2012-04-03 04:13:41 +0000619 { LLDB_OPT_SET_ALL, false, "thread-index", 'x', required_argument, NULL, 0, eArgTypeThreadIndex,
Greg Claytonfe424a92010-09-18 03:37:20 +0000620 "The breakpoint stops only for the thread whose index matches this argument."},
Jim Ingham3c7b5b92010-06-16 02:00:15 +0000621
Bill Wendlingff7df6d2012-04-03 04:13:41 +0000622 { LLDB_OPT_SET_ALL, false, "thread-id", 't', required_argument, NULL, 0, eArgTypeThreadID,
Jim Ingham3c7b5b92010-06-16 02:00:15 +0000623 "The breakpoint stops only for the thread whose TID matches this argument."},
624
Bill Wendlingff7df6d2012-04-03 04:13:41 +0000625 { LLDB_OPT_SET_ALL, false, "thread-name", 'T', required_argument, NULL, 0, eArgTypeThreadName,
Jim Ingham3c7b5b92010-06-16 02:00:15 +0000626 "The breakpoint stops only for the thread whose thread name matches this argument."},
627
Bill Wendlingff7df6d2012-04-03 04:13:41 +0000628 { LLDB_OPT_SET_ALL, false, "queue-name", 'q', required_argument, NULL, 0, eArgTypeQueueName,
Jim Ingham3c7b5b92010-06-16 02:00:15 +0000629 "The breakpoint stops only for threads in the queue whose name is given by this argument."},
630
Jim Inghamd6d47972011-09-23 00:54:11 +0000631 { LLDB_OPT_FILE, false, "file", 'f', required_argument, NULL, CommandCompletions::eSourceFileCompletion, eArgTypeFilename,
632 "Specifies the source file in which to set this breakpoint."},
Chris Lattner24943d22010-06-08 16:52:24 +0000633
Caroline Tice4d6675c2010-10-01 19:59:14 +0000634 { LLDB_OPT_SET_1, true, "line", 'l', required_argument, NULL, 0, eArgTypeLineNum,
Jim Inghamd6d47972011-09-23 00:54:11 +0000635 "Specifies the line number on which to set this breakpoint."},
Chris Lattner24943d22010-06-08 16:52:24 +0000636
Chris Lattner24943d22010-06-08 16:52:24 +0000637 // Comment out this option for the moment, as we don't actually use it, but will in the future.
638 // This way users won't see it, but the infrastructure is left in place.
Johnny Chene4f3cd72012-05-25 21:10:46 +0000639 // { 0, false, "column", 'C', required_argument, NULL, "<column>",
Chris Lattner24943d22010-06-08 16:52:24 +0000640 // "Set the breakpoint by source location at this particular column."},
641
Caroline Tice4d6675c2010-10-01 19:59:14 +0000642 { LLDB_OPT_SET_2, true, "address", 'a', required_argument, NULL, 0, eArgTypeAddress,
Chris Lattner24943d22010-06-08 16:52:24 +0000643 "Set the breakpoint by address, at the specified address."},
644
Caroline Tice4d6675c2010-10-01 19:59:14 +0000645 { LLDB_OPT_SET_3, true, "name", 'n', required_argument, NULL, CommandCompletions::eSymbolCompletion, eArgTypeFunctionName,
Jim Inghamee033f22012-05-03 20:30:08 +0000646 "Set the breakpoint by function name. Can be repeated multiple times to make one breakpoint for multiple snames" },
Chris Lattner24943d22010-06-08 16:52:24 +0000647
Caroline Tice4d6675c2010-10-01 19:59:14 +0000648 { LLDB_OPT_SET_4, true, "fullname", 'F', required_argument, NULL, CommandCompletions::eSymbolCompletion, eArgTypeFullName,
Jim Inghamee033f22012-05-03 20:30:08 +0000649 "Set the breakpoint by fully qualified function names. For C++ this means namespaces and all arguments, and "
650 "for Objective C this means a full function prototype with class and selector. "
651 "Can be repeated multiple times to make one breakpoint for multiple names." },
Greg Clayton12bec712010-06-28 21:30:43 +0000652
Caroline Tice4d6675c2010-10-01 19:59:14 +0000653 { LLDB_OPT_SET_5, true, "selector", 'S', required_argument, NULL, 0, eArgTypeSelector,
Jim Inghamee033f22012-05-03 20:30:08 +0000654 "Set the breakpoint by ObjC selector name. Can be repeated multiple times to make one breakpoint for multiple Selectors." },
Greg Clayton12bec712010-06-28 21:30:43 +0000655
Caroline Tice4d6675c2010-10-01 19:59:14 +0000656 { LLDB_OPT_SET_6, true, "method", 'M', required_argument, NULL, 0, eArgTypeMethod,
Jim Inghamee033f22012-05-03 20:30:08 +0000657 "Set the breakpoint by C++ method names. Can be repeated multiple times to make one breakpoint for multiple methods." },
Greg Clayton12bec712010-06-28 21:30:43 +0000658
Caroline Tice4d6675c2010-10-01 19:59:14 +0000659 { LLDB_OPT_SET_7, true, "func-regex", 'r', required_argument, NULL, 0, eArgTypeRegularExpression,
Chris Lattner24943d22010-06-08 16:52:24 +0000660 "Set the breakpoint by function name, evaluating a regular-expression to find the function name(s)." },
661
Greg Clayton48fbdf72010-10-12 04:29:14 +0000662 { LLDB_OPT_SET_8, true, "basename", 'b', required_argument, NULL, CommandCompletions::eSymbolCompletion, eArgTypeFunctionName,
Jim Inghamee033f22012-05-03 20:30:08 +0000663 "Set the breakpoint by function basename (C++ namespaces and arguments will be ignored). "
664 "Can be repeated multiple times to make one breakpoint for multiple symbols." },
Greg Clayton48fbdf72010-10-12 04:29:14 +0000665
Jim Ingham03c8ee52011-09-21 01:17:13 +0000666 { LLDB_OPT_SET_9, true, "source-pattern-regexp", 'p', required_argument, NULL, 0, eArgTypeRegularExpression,
667 "Set the breakpoint specifying a regular expression to match a pattern in the source text in a given source file." },
668
Jim Ingham4722b102012-03-06 00:37:27 +0000669 { LLDB_OPT_SET_10, true, "language-exception", 'E', required_argument, NULL, 0, eArgTypeLanguage,
670 "Set the breakpoint on exceptions thrown by the specified language (without options, on throw but not catch.)" },
671
672 { LLDB_OPT_SET_10, false, "on-throw", 'w', required_argument, NULL, 0, eArgTypeBoolean,
673 "Set the breakpoint on exception throW." },
674
675 { LLDB_OPT_SET_10, false, "on-catch", 'h', required_argument, NULL, 0, eArgTypeBoolean,
676 "Set the breakpoint on exception catcH." },
Jim Ingham03c8ee52011-09-21 01:17:13 +0000677
Jim Ingham2cf5ccb2012-05-22 00:12:20 +0000678 { LLDB_OPT_SKIP_PROLOGUE, false, "skip-prologue", 'K', required_argument, NULL, 0, eArgTypeBoolean,
679 "sKip the prologue if the breakpoint is at the beginning of a function. If not set the target.skip-prologue setting is used." },
680
Caroline Tice4d6675c2010-10-01 19:59:14 +0000681 { 0, false, NULL, 0, 0, NULL, 0, eArgTypeNone, NULL }
Chris Lattner24943d22010-06-08 16:52:24 +0000682};
683
Jim Inghamda26bd22012-06-08 21:56:10 +0000684//-------------------------------------------------------------------------
685// CommandObjectBreakpointModify
686//-------------------------------------------------------------------------
687#pragma mark Modify
Chris Lattner24943d22010-06-08 16:52:24 +0000688
Jim Inghamda26bd22012-06-08 21:56:10 +0000689class CommandObjectBreakpointModify : public CommandObjectParsed
Chris Lattner24943d22010-06-08 16:52:24 +0000690{
Jim Inghamda26bd22012-06-08 21:56:10 +0000691public:
Chris Lattner24943d22010-06-08 16:52:24 +0000692
Jim Inghamda26bd22012-06-08 21:56:10 +0000693 CommandObjectBreakpointModify (CommandInterpreter &interpreter) :
694 CommandObjectParsed (interpreter,
695 "breakpoint modify",
696 "Modify the options on a breakpoint or set of breakpoints in the executable. "
697 "If no breakpoint is specified, acts on the last created breakpoint. "
698 "With the exception of -e, -d and -i, passing an empty argument clears the modification.",
699 NULL),
700 m_options (interpreter)
Chris Lattner24943d22010-06-08 16:52:24 +0000701 {
Jim Inghamda26bd22012-06-08 21:56:10 +0000702 CommandArgumentEntry arg;
703 CommandObject::AddIDsArgumentData(arg, eArgTypeBreakpointID, eArgTypeBreakpointIDRange);
704 // Add the entry for the first argument for this command to the object's arguments vector.
705 m_arguments.push_back (arg);
706 }
Chris Lattner24943d22010-06-08 16:52:24 +0000707
Chris Lattner24943d22010-06-08 16:52:24 +0000708
Jim Inghamda26bd22012-06-08 21:56:10 +0000709 virtual
710 ~CommandObjectBreakpointModify () {}
Greg Clayton12bec712010-06-28 21:30:43 +0000711
Jim Inghamda26bd22012-06-08 21:56:10 +0000712 virtual Options *
713 GetOptions ()
714 {
715 return &m_options;
716 }
Johnny Chene4f3cd72012-05-25 21:10:46 +0000717
Jim Inghamda26bd22012-06-08 21:56:10 +0000718 class CommandOptions : public Options
719 {
720 public:
Greg Clayton12bec712010-06-28 21:30:43 +0000721
Jim Inghamda26bd22012-06-08 21:56:10 +0000722 CommandOptions (CommandInterpreter &interpreter) :
723 Options (interpreter),
724 m_ignore_count (0),
725 m_thread_id(LLDB_INVALID_THREAD_ID),
726 m_thread_id_passed(false),
727 m_thread_index (UINT32_MAX),
728 m_thread_index_passed(false),
729 m_thread_name(),
730 m_queue_name(),
731 m_condition (),
Jim Ingham2753a022012-10-05 19:16:31 +0000732 m_one_shot (false),
Jim Inghamda26bd22012-06-08 21:56:10 +0000733 m_enable_passed (false),
734 m_enable_value (false),
735 m_name_passed (false),
736 m_queue_passed (false),
Jim Ingham2753a022012-10-05 19:16:31 +0000737 m_condition_passed (false),
738 m_one_shot_passed (false)
Jim Inghamda26bd22012-06-08 21:56:10 +0000739 {
740 }
Greg Clayton12bec712010-06-28 21:30:43 +0000741
Jim Inghamda26bd22012-06-08 21:56:10 +0000742 virtual
743 ~CommandOptions () {}
Greg Clayton12bec712010-06-28 21:30:43 +0000744
Jim Inghamda26bd22012-06-08 21:56:10 +0000745 virtual Error
746 SetOptionValue (uint32_t option_idx, const char *option_arg)
747 {
748 Error error;
Greg Clayton6475c422012-12-04 00:32:51 +0000749 const int short_option = m_getopt_table[option_idx].val;
Greg Clayton48fbdf72010-10-12 04:29:14 +0000750
Jim Inghamda26bd22012-06-08 21:56:10 +0000751 switch (short_option)
Chris Lattner24943d22010-06-08 16:52:24 +0000752 {
Jim Inghamda26bd22012-06-08 21:56:10 +0000753 case 'c':
754 if (option_arg != NULL)
755 m_condition.assign (option_arg);
756 else
757 m_condition.clear();
758 m_condition_passed = true;
759 break;
760 case 'd':
761 m_enable_passed = true;
762 m_enable_value = false;
763 break;
764 case 'e':
765 m_enable_passed = true;
766 m_enable_value = true;
767 break;
768 case 'i':
769 {
770 m_ignore_count = Args::StringToUInt32(option_arg, UINT32_MAX, 0);
771 if (m_ignore_count == UINT32_MAX)
772 error.SetErrorStringWithFormat ("invalid ignore count '%s'", option_arg);
773 }
Chris Lattner24943d22010-06-08 16:52:24 +0000774 break;
Jim Ingham2753a022012-10-05 19:16:31 +0000775 case 'o':
776 {
777 bool value, success;
778 value = Args::StringToBoolean(option_arg, false, &success);
779 if (success)
780 {
781 m_one_shot_passed = true;
782 m_one_shot = value;
783 }
784 else
785 error.SetErrorStringWithFormat("invalid boolean value '%s' passed for -o option", option_arg);
786 }
787 break;
Jim Inghamda26bd22012-06-08 21:56:10 +0000788 case 't' :
Jim Inghamd6d47972011-09-23 00:54:11 +0000789 {
Jim Inghamda26bd22012-06-08 21:56:10 +0000790 if (option_arg[0] == '\0')
Jim Inghamd6d47972011-09-23 00:54:11 +0000791 {
Jim Inghamda26bd22012-06-08 21:56:10 +0000792 m_thread_id = LLDB_INVALID_THREAD_ID;
793 m_thread_id_passed = true;
Jim Inghamd6d47972011-09-23 00:54:11 +0000794 }
795 else
796 {
Jim Inghamda26bd22012-06-08 21:56:10 +0000797 m_thread_id = Args::StringToUInt64(option_arg, LLDB_INVALID_THREAD_ID, 0);
798 if (m_thread_id == LLDB_INVALID_THREAD_ID)
799 error.SetErrorStringWithFormat ("invalid thread id string '%s'", option_arg);
800 else
801 m_thread_id_passed = true;
Jim Inghamd6d47972011-09-23 00:54:11 +0000802 }
803 }
Jim Inghamda26bd22012-06-08 21:56:10 +0000804 break;
805 case 'T':
806 if (option_arg != NULL)
807 m_thread_name.assign (option_arg);
808 else
809 m_thread_name.clear();
810 m_name_passed = true;
811 break;
812 case 'q':
813 if (option_arg != NULL)
814 m_queue_name.assign (option_arg);
815 else
816 m_queue_name.clear();
817 m_queue_passed = true;
818 break;
819 case 'x':
Jim Ingham03c8ee52011-09-21 01:17:13 +0000820 {
Jim Inghamda26bd22012-06-08 21:56:10 +0000821 if (option_arg[0] == '\n')
822 {
823 m_thread_index = UINT32_MAX;
824 m_thread_index_passed = true;
825 }
826 else
827 {
828 m_thread_index = Args::StringToUInt32 (option_arg, UINT32_MAX, 0);
829 if (m_thread_id == UINT32_MAX)
830 error.SetErrorStringWithFormat ("invalid thread index string '%s'", option_arg);
831 else
832 m_thread_index_passed = true;
833 }
Jim Ingham03c8ee52011-09-21 01:17:13 +0000834 }
Jim Inghamda26bd22012-06-08 21:56:10 +0000835 break;
836 default:
837 error.SetErrorStringWithFormat ("unrecognized option '%c'", short_option);
838 break;
Jim Ingham03c8ee52011-09-21 01:17:13 +0000839 }
Jim Inghamda26bd22012-06-08 21:56:10 +0000840
841 return error;
842 }
843 void
844 OptionParsingStarting ()
845 {
846 m_ignore_count = 0;
847 m_thread_id = LLDB_INVALID_THREAD_ID;
848 m_thread_id_passed = false;
849 m_thread_index = UINT32_MAX;
850 m_thread_index_passed = false;
851 m_thread_name.clear();
852 m_queue_name.clear();
853 m_condition.clear();
Jim Ingham2753a022012-10-05 19:16:31 +0000854 m_one_shot = false;
Jim Inghamda26bd22012-06-08 21:56:10 +0000855 m_enable_passed = false;
856 m_queue_passed = false;
857 m_name_passed = false;
858 m_condition_passed = false;
Jim Ingham2753a022012-10-05 19:16:31 +0000859 m_one_shot_passed = false;
Jim Inghamda26bd22012-06-08 21:56:10 +0000860 }
861
862 const OptionDefinition*
863 GetDefinitions ()
864 {
865 return g_option_table;
866 }
867
868
869 // Options table: Required for subclasses of Options.
870
871 static OptionDefinition g_option_table[];
872
873 // Instance variables to hold the values for command options.
874
875 uint32_t m_ignore_count;
876 lldb::tid_t m_thread_id;
877 bool m_thread_id_passed;
878 uint32_t m_thread_index;
879 bool m_thread_index_passed;
880 std::string m_thread_name;
881 std::string m_queue_name;
882 std::string m_condition;
Jim Ingham2753a022012-10-05 19:16:31 +0000883 bool m_one_shot;
Jim Inghamda26bd22012-06-08 21:56:10 +0000884 bool m_enable_passed;
885 bool m_enable_value;
886 bool m_name_passed;
887 bool m_queue_passed;
888 bool m_condition_passed;
Jim Ingham2753a022012-10-05 19:16:31 +0000889 bool m_one_shot_passed;
Jim Inghamda26bd22012-06-08 21:56:10 +0000890
891 };
892
893protected:
894 virtual bool
895 DoExecute (Args& command, CommandReturnObject &result)
896 {
897 Target *target = m_interpreter.GetDebugger().GetSelectedTarget().get();
898 if (target == NULL)
899 {
900 result.AppendError ("Invalid target. No existing target or breakpoints.");
901 result.SetStatus (eReturnStatusFailed);
902 return false;
903 }
904
905 Mutex::Locker locker;
906 target->GetBreakpointList().GetListMutex(locker);
907
908 BreakpointIDList valid_bp_ids;
909
910 CommandObjectMultiwordBreakpoint::VerifyBreakpointIDs (command, target, result, &valid_bp_ids);
911
912 if (result.Succeeded())
913 {
914 const size_t count = valid_bp_ids.GetSize();
915 for (size_t i = 0; i < count; ++i)
Jim Ingham4722b102012-03-06 00:37:27 +0000916 {
Jim Inghamda26bd22012-06-08 21:56:10 +0000917 BreakpointID cur_bp_id = valid_bp_ids.GetBreakpointIDAtIndex (i);
918
919 if (cur_bp_id.GetBreakpointID() != LLDB_INVALID_BREAK_ID)
920 {
921 Breakpoint *bp = target->GetBreakpointByID (cur_bp_id.GetBreakpointID()).get();
922 if (cur_bp_id.GetLocationID() != LLDB_INVALID_BREAK_ID)
923 {
924 BreakpointLocation *location = bp->FindLocationByID (cur_bp_id.GetLocationID()).get();
925 if (location)
926 {
927 if (m_options.m_thread_id_passed)
928 location->SetThreadID (m_options.m_thread_id);
929
930 if (m_options.m_thread_index_passed)
931 location->SetThreadIndex(m_options.m_thread_index);
932
933 if (m_options.m_name_passed)
934 location->SetThreadName(m_options.m_thread_name.c_str());
935
936 if (m_options.m_queue_passed)
937 location->SetQueueName(m_options.m_queue_name.c_str());
938
939 if (m_options.m_ignore_count != 0)
940 location->SetIgnoreCount(m_options.m_ignore_count);
941
942 if (m_options.m_enable_passed)
943 location->SetEnabled (m_options.m_enable_value);
944
945 if (m_options.m_condition_passed)
946 location->SetCondition (m_options.m_condition.c_str());
947 }
948 }
949 else
950 {
951 if (m_options.m_thread_id_passed)
952 bp->SetThreadID (m_options.m_thread_id);
953
954 if (m_options.m_thread_index_passed)
955 bp->SetThreadIndex(m_options.m_thread_index);
956
957 if (m_options.m_name_passed)
958 bp->SetThreadName(m_options.m_thread_name.c_str());
959
960 if (m_options.m_queue_passed)
961 bp->SetQueueName(m_options.m_queue_name.c_str());
962
963 if (m_options.m_ignore_count != 0)
964 bp->SetIgnoreCount(m_options.m_ignore_count);
965
966 if (m_options.m_enable_passed)
967 bp->SetEnabled (m_options.m_enable_value);
968
969 if (m_options.m_condition_passed)
970 bp->SetCondition (m_options.m_condition.c_str());
971 }
972 }
Jim Ingham4722b102012-03-06 00:37:27 +0000973 }
Jim Inghamda26bd22012-06-08 21:56:10 +0000974 }
975
976 return result.Succeeded();
Chris Lattner24943d22010-06-08 16:52:24 +0000977 }
978
Jim Inghamda26bd22012-06-08 21:56:10 +0000979private:
980 CommandOptions m_options;
981};
Johnny Chene4f3cd72012-05-25 21:10:46 +0000982
Jim Inghamda26bd22012-06-08 21:56:10 +0000983#pragma mark Modify::CommandOptions
984OptionDefinition
985CommandObjectBreakpointModify::CommandOptions::g_option_table[] =
986{
987{ LLDB_OPT_SET_ALL, false, "ignore-count", 'i', required_argument, NULL, 0, eArgTypeCount, "Set the number of times this breakpoint is skipped before stopping." },
Jim Ingham2753a022012-10-05 19:16:31 +0000988{ LLDB_OPT_SET_ALL, false, "one-shot", 'o', required_argument, NULL, 0, eArgTypeBoolean, "The breakpoint is deleted the first time it stop causes a stop." },
Jim Inghamda26bd22012-06-08 21:56:10 +0000989{ LLDB_OPT_SET_ALL, false, "thread-index", 'x', required_argument, NULL, 0, eArgTypeThreadIndex, "The breakpoint stops only for the thread whose indeX matches this argument."},
990{ LLDB_OPT_SET_ALL, false, "thread-id", 't', required_argument, NULL, 0, eArgTypeThreadID, "The breakpoint stops only for the thread whose TID matches this argument."},
991{ LLDB_OPT_SET_ALL, false, "thread-name", 'T', required_argument, NULL, 0, eArgTypeThreadName, "The breakpoint stops only for the thread whose thread name matches this argument."},
992{ LLDB_OPT_SET_ALL, false, "queue-name", 'q', required_argument, NULL, 0, eArgTypeQueueName, "The breakpoint stops only for threads in the queue whose name is given by this argument."},
993{ LLDB_OPT_SET_ALL, false, "condition", 'c', required_argument, NULL, 0, eArgTypeExpression, "The breakpoint stops only if this condition expression evaluates to true."},
994{ LLDB_OPT_SET_1, false, "enable", 'e', no_argument, NULL, 0, eArgTypeNone, "Enable the breakpoint."},
995{ LLDB_OPT_SET_2, false, "disable", 'd', no_argument, NULL, 0, eArgTypeNone, "Disable the breakpoint."},
Jim Ingham2753a022012-10-05 19:16:31 +0000996{ 0, false, NULL, 0 , 0, NULL, 0, eArgTypeNone, NULL }
Jim Inghamda26bd22012-06-08 21:56:10 +0000997};
998
999//-------------------------------------------------------------------------
1000// CommandObjectBreakpointEnable
1001//-------------------------------------------------------------------------
1002#pragma mark Enable
1003
1004class CommandObjectBreakpointEnable : public CommandObjectParsed
1005{
1006public:
1007 CommandObjectBreakpointEnable (CommandInterpreter &interpreter) :
1008 CommandObjectParsed (interpreter,
1009 "enable",
1010 "Enable the specified disabled breakpoint(s). If no breakpoints are specified, enable all of them.",
1011 NULL)
1012 {
1013 CommandArgumentEntry arg;
1014 CommandObject::AddIDsArgumentData(arg, eArgTypeBreakpointID, eArgTypeBreakpointIDRange);
1015 // Add the entry for the first argument for this command to the object's arguments vector.
1016 m_arguments.push_back (arg);
1017 }
1018
1019
1020 virtual
1021 ~CommandObjectBreakpointEnable () {}
1022
1023protected:
1024 virtual bool
1025 DoExecute (Args& command, CommandReturnObject &result)
1026 {
1027 Target *target = m_interpreter.GetDebugger().GetSelectedTarget().get();
1028 if (target == NULL)
1029 {
1030 result.AppendError ("Invalid target. No existing target or breakpoints.");
1031 result.SetStatus (eReturnStatusFailed);
1032 return false;
1033 }
1034
1035 Mutex::Locker locker;
1036 target->GetBreakpointList().GetListMutex(locker);
1037
1038 const BreakpointList &breakpoints = target->GetBreakpointList();
1039
1040 size_t num_breakpoints = breakpoints.GetSize();
1041
1042 if (num_breakpoints == 0)
1043 {
1044 result.AppendError ("No breakpoints exist to be enabled.");
1045 result.SetStatus (eReturnStatusFailed);
1046 return false;
1047 }
1048
1049 if (command.GetArgumentCount() == 0)
1050 {
1051 // No breakpoint selected; enable all currently set breakpoints.
1052 target->EnableAllBreakpoints ();
1053 result.AppendMessageWithFormat ("All breakpoints enabled. (%lu breakpoints)\n", num_breakpoints);
1054 result.SetStatus (eReturnStatusSuccessFinishNoResult);
1055 }
1056 else
1057 {
1058 // Particular breakpoint selected; enable that breakpoint.
1059 BreakpointIDList valid_bp_ids;
1060 CommandObjectMultiwordBreakpoint::VerifyBreakpointIDs (command, target, result, &valid_bp_ids);
1061
1062 if (result.Succeeded())
1063 {
1064 int enable_count = 0;
1065 int loc_count = 0;
1066 const size_t count = valid_bp_ids.GetSize();
1067 for (size_t i = 0; i < count; ++i)
1068 {
1069 BreakpointID cur_bp_id = valid_bp_ids.GetBreakpointIDAtIndex (i);
1070
1071 if (cur_bp_id.GetBreakpointID() != LLDB_INVALID_BREAK_ID)
1072 {
1073 Breakpoint *breakpoint = target->GetBreakpointByID (cur_bp_id.GetBreakpointID()).get();
1074 if (cur_bp_id.GetLocationID() != LLDB_INVALID_BREAK_ID)
1075 {
1076 BreakpointLocation *location = breakpoint->FindLocationByID (cur_bp_id.GetLocationID()).get();
1077 if (location)
1078 {
1079 location->SetEnabled (true);
1080 ++loc_count;
1081 }
1082 }
1083 else
1084 {
1085 breakpoint->SetEnabled (true);
1086 ++enable_count;
1087 }
1088 }
1089 }
1090 result.AppendMessageWithFormat ("%d breakpoints enabled.\n", enable_count + loc_count);
1091 result.SetStatus (eReturnStatusSuccessFinishNoResult);
1092 }
1093 }
1094
1095 return result.Succeeded();
1096 }
1097};
1098
1099//-------------------------------------------------------------------------
1100// CommandObjectBreakpointDisable
1101//-------------------------------------------------------------------------
1102#pragma mark Disable
1103
1104class CommandObjectBreakpointDisable : public CommandObjectParsed
1105{
1106public:
1107 CommandObjectBreakpointDisable (CommandInterpreter &interpreter) :
1108 CommandObjectParsed (interpreter,
1109 "breakpoint disable",
1110 "Disable the specified breakpoint(s) without removing it/them. If no breakpoints are specified, disable them all.",
1111 NULL)
1112 {
1113 CommandArgumentEntry arg;
1114 CommandObject::AddIDsArgumentData(arg, eArgTypeBreakpointID, eArgTypeBreakpointIDRange);
1115 // Add the entry for the first argument for this command to the object's arguments vector.
1116 m_arguments.push_back (arg);
1117 }
1118
1119
1120 virtual
1121 ~CommandObjectBreakpointDisable () {}
1122
1123protected:
1124 virtual bool
1125 DoExecute (Args& command, CommandReturnObject &result)
1126 {
1127 Target *target = m_interpreter.GetDebugger().GetSelectedTarget().get();
1128 if (target == NULL)
1129 {
1130 result.AppendError ("Invalid target. No existing target or breakpoints.");
1131 result.SetStatus (eReturnStatusFailed);
1132 return false;
1133 }
1134
1135 Mutex::Locker locker;
1136 target->GetBreakpointList().GetListMutex(locker);
1137
1138 const BreakpointList &breakpoints = target->GetBreakpointList();
1139 size_t num_breakpoints = breakpoints.GetSize();
1140
1141 if (num_breakpoints == 0)
1142 {
1143 result.AppendError ("No breakpoints exist to be disabled.");
1144 result.SetStatus (eReturnStatusFailed);
1145 return false;
1146 }
1147
1148 if (command.GetArgumentCount() == 0)
1149 {
1150 // No breakpoint selected; disable all currently set breakpoints.
1151 target->DisableAllBreakpoints ();
1152 result.AppendMessageWithFormat ("All breakpoints disabled. (%lu breakpoints)\n", num_breakpoints);
1153 result.SetStatus (eReturnStatusSuccessFinishNoResult);
1154 }
1155 else
1156 {
1157 // Particular breakpoint selected; disable that breakpoint.
1158 BreakpointIDList valid_bp_ids;
1159
1160 CommandObjectMultiwordBreakpoint::VerifyBreakpointIDs (command, target, result, &valid_bp_ids);
1161
1162 if (result.Succeeded())
1163 {
1164 int disable_count = 0;
1165 int loc_count = 0;
1166 const size_t count = valid_bp_ids.GetSize();
1167 for (size_t i = 0; i < count; ++i)
1168 {
1169 BreakpointID cur_bp_id = valid_bp_ids.GetBreakpointIDAtIndex (i);
1170
1171 if (cur_bp_id.GetBreakpointID() != LLDB_INVALID_BREAK_ID)
1172 {
1173 Breakpoint *breakpoint = target->GetBreakpointByID (cur_bp_id.GetBreakpointID()).get();
1174 if (cur_bp_id.GetLocationID() != LLDB_INVALID_BREAK_ID)
1175 {
1176 BreakpointLocation *location = breakpoint->FindLocationByID (cur_bp_id.GetLocationID()).get();
1177 if (location)
1178 {
1179 location->SetEnabled (false);
1180 ++loc_count;
1181 }
1182 }
1183 else
1184 {
1185 breakpoint->SetEnabled (false);
1186 ++disable_count;
1187 }
1188 }
1189 }
1190 result.AppendMessageWithFormat ("%d breakpoints disabled.\n", disable_count + loc_count);
1191 result.SetStatus (eReturnStatusSuccessFinishNoResult);
1192 }
1193 }
1194
1195 return result.Succeeded();
1196 }
1197
1198};
1199
1200//-------------------------------------------------------------------------
1201// CommandObjectBreakpointList
1202//-------------------------------------------------------------------------
1203#pragma mark List
1204
1205class CommandObjectBreakpointList : public CommandObjectParsed
1206{
1207public:
1208 CommandObjectBreakpointList (CommandInterpreter &interpreter) :
1209 CommandObjectParsed (interpreter,
1210 "breakpoint list",
1211 "List some or all breakpoints at configurable levels of detail.",
1212 NULL),
1213 m_options (interpreter)
1214 {
1215 CommandArgumentEntry arg;
1216 CommandArgumentData bp_id_arg;
1217
1218 // Define the first (and only) variant of this arg.
1219 bp_id_arg.arg_type = eArgTypeBreakpointID;
1220 bp_id_arg.arg_repetition = eArgRepeatOptional;
1221
1222 // There is only one variant this argument could be; put it into the argument entry.
1223 arg.push_back (bp_id_arg);
1224
1225 // Push the data for the first argument into the m_arguments vector.
1226 m_arguments.push_back (arg);
1227 }
1228
1229
1230 virtual
1231 ~CommandObjectBreakpointList () {}
1232
1233 virtual Options *
1234 GetOptions ()
1235 {
1236 return &m_options;
Jim Ingham3c7b5b92010-06-16 02:00:15 +00001237 }
1238
Jim Inghamda26bd22012-06-08 21:56:10 +00001239 class CommandOptions : public Options
Chris Lattner24943d22010-06-08 16:52:24 +00001240 {
Jim Inghamda26bd22012-06-08 21:56:10 +00001241 public:
1242
1243 CommandOptions (CommandInterpreter &interpreter) :
1244 Options (interpreter),
1245 m_level (lldb::eDescriptionLevelBrief) // Breakpoint List defaults to brief descriptions
1246 {
1247 }
1248
1249 virtual
1250 ~CommandOptions () {}
1251
1252 virtual Error
1253 SetOptionValue (uint32_t option_idx, const char *option_arg)
1254 {
1255 Error error;
Greg Clayton6475c422012-12-04 00:32:51 +00001256 const int short_option = m_getopt_table[option_idx].val;
Jim Inghamda26bd22012-06-08 21:56:10 +00001257
1258 switch (short_option)
1259 {
1260 case 'b':
1261 m_level = lldb::eDescriptionLevelBrief;
1262 break;
1263 case 'f':
1264 m_level = lldb::eDescriptionLevelFull;
1265 break;
1266 case 'v':
1267 m_level = lldb::eDescriptionLevelVerbose;
1268 break;
1269 case 'i':
1270 m_internal = true;
1271 break;
1272 default:
1273 error.SetErrorStringWithFormat ("unrecognized option '%c'", short_option);
1274 break;
1275 }
1276
1277 return error;
1278 }
1279
1280 void
1281 OptionParsingStarting ()
1282 {
1283 m_level = lldb::eDescriptionLevelFull;
1284 m_internal = false;
1285 }
1286
1287 const OptionDefinition *
1288 GetDefinitions ()
1289 {
1290 return g_option_table;
1291 }
1292
1293 // Options table: Required for subclasses of Options.
1294
1295 static OptionDefinition g_option_table[];
1296
1297 // Instance variables to hold the values for command options.
1298
1299 lldb::DescriptionLevel m_level;
1300
1301 bool m_internal;
1302 };
1303
1304protected:
1305 virtual bool
1306 DoExecute (Args& command, CommandReturnObject &result)
1307 {
1308 Target *target = m_interpreter.GetDebugger().GetSelectedTarget().get();
1309 if (target == NULL)
1310 {
1311 result.AppendError ("Invalid target. No current target or breakpoints.");
1312 result.SetStatus (eReturnStatusSuccessFinishNoResult);
1313 return true;
1314 }
1315
1316 const BreakpointList &breakpoints = target->GetBreakpointList(m_options.m_internal);
1317 Mutex::Locker locker;
1318 target->GetBreakpointList(m_options.m_internal).GetListMutex(locker);
1319
1320 size_t num_breakpoints = breakpoints.GetSize();
1321
1322 if (num_breakpoints == 0)
1323 {
1324 result.AppendMessage ("No breakpoints currently set.");
1325 result.SetStatus (eReturnStatusSuccessFinishNoResult);
1326 return true;
1327 }
1328
Jim Ingham2e8cb8a2011-02-19 02:53:09 +00001329 Stream &output_stream = result.GetOutputStream();
Jim Inghamda26bd22012-06-08 21:56:10 +00001330
1331 if (command.GetArgumentCount() == 0)
1332 {
1333 // No breakpoint selected; show info about all currently set breakpoints.
1334 result.AppendMessage ("Current breakpoints:");
1335 for (size_t i = 0; i < num_breakpoints; ++i)
1336 {
1337 Breakpoint *breakpoint = breakpoints.GetBreakpointAtIndex (i).get();
1338 AddBreakpointDescription (&output_stream, breakpoint, m_options.m_level);
1339 }
1340 result.SetStatus (eReturnStatusSuccessFinishNoResult);
1341 }
1342 else
1343 {
1344 // Particular breakpoints selected; show info about that breakpoint.
1345 BreakpointIDList valid_bp_ids;
1346 CommandObjectMultiwordBreakpoint::VerifyBreakpointIDs (command, target, result, &valid_bp_ids);
1347
1348 if (result.Succeeded())
1349 {
1350 for (size_t i = 0; i < valid_bp_ids.GetSize(); ++i)
1351 {
1352 BreakpointID cur_bp_id = valid_bp_ids.GetBreakpointIDAtIndex (i);
1353 Breakpoint *breakpoint = target->GetBreakpointByID (cur_bp_id.GetBreakpointID()).get();
1354 AddBreakpointDescription (&output_stream, breakpoint, m_options.m_level);
1355 }
1356 result.SetStatus (eReturnStatusSuccessFinishNoResult);
1357 }
1358 else
1359 {
1360 result.AppendError ("Invalid breakpoint id.");
1361 result.SetStatus (eReturnStatusFailed);
1362 }
1363 }
1364
1365 return result.Succeeded();
Chris Lattner24943d22010-06-08 16:52:24 +00001366 }
1367
Jim Inghamda26bd22012-06-08 21:56:10 +00001368private:
1369 CommandOptions m_options;
1370};
1371
1372#pragma mark List::CommandOptions
1373OptionDefinition
1374CommandObjectBreakpointList::CommandOptions::g_option_table[] =
1375{
1376 { LLDB_OPT_SET_ALL, false, "internal", 'i', no_argument, NULL, 0, eArgTypeNone,
1377 "Show debugger internal breakpoints" },
1378
1379 { LLDB_OPT_SET_1, false, "brief", 'b', no_argument, NULL, 0, eArgTypeNone,
1380 "Give a brief description of the breakpoint (no location info)."},
1381
1382 // FIXME: We need to add an "internal" command, and then add this sort of thing to it.
1383 // But I need to see it for now, and don't want to wait.
1384 { LLDB_OPT_SET_2, false, "full", 'f', no_argument, NULL, 0, eArgTypeNone,
1385 "Give a full description of the breakpoint and its locations."},
1386
1387 { LLDB_OPT_SET_3, false, "verbose", 'v', no_argument, NULL, 0, eArgTypeNone,
1388 "Explain everything we know about the breakpoint (for debugging debugger bugs)." },
1389
1390 { 0, false, NULL, 0, 0, NULL, 0, eArgTypeNone, NULL }
1391};
1392
1393//-------------------------------------------------------------------------
1394// CommandObjectBreakpointClear
1395//-------------------------------------------------------------------------
1396#pragma mark Clear
1397
1398class CommandObjectBreakpointClear : public CommandObjectParsed
1399{
1400public:
1401
1402 typedef enum BreakpointClearType
1403 {
1404 eClearTypeInvalid,
1405 eClearTypeFileAndLine
1406 } BreakpointClearType;
1407
1408 CommandObjectBreakpointClear (CommandInterpreter &interpreter) :
1409 CommandObjectParsed (interpreter,
1410 "breakpoint clear",
1411 "Clears a breakpoint or set of breakpoints in the executable.",
1412 "breakpoint clear <cmd-options>"),
1413 m_options (interpreter)
1414 {
1415 }
1416
1417 virtual
1418 ~CommandObjectBreakpointClear () {}
1419
1420 virtual Options *
1421 GetOptions ()
1422 {
1423 return &m_options;
1424 }
1425
1426 class CommandOptions : public Options
1427 {
1428 public:
1429
1430 CommandOptions (CommandInterpreter &interpreter) :
1431 Options (interpreter),
1432 m_filename (),
1433 m_line_num (0)
1434 {
1435 }
1436
1437 virtual
1438 ~CommandOptions () {}
1439
1440 virtual Error
1441 SetOptionValue (uint32_t option_idx, const char *option_arg)
1442 {
1443 Error error;
Greg Clayton6475c422012-12-04 00:32:51 +00001444 const int short_option = m_getopt_table[option_idx].val;
Jim Inghamda26bd22012-06-08 21:56:10 +00001445
1446 switch (short_option)
1447 {
1448 case 'f':
1449 m_filename.assign (option_arg);
1450 break;
1451
1452 case 'l':
1453 m_line_num = Args::StringToUInt32 (option_arg, 0);
1454 break;
1455
1456 default:
1457 error.SetErrorStringWithFormat ("unrecognized option '%c'", short_option);
1458 break;
1459 }
1460
1461 return error;
1462 }
1463
1464 void
1465 OptionParsingStarting ()
1466 {
1467 m_filename.clear();
1468 m_line_num = 0;
1469 }
1470
1471 const OptionDefinition*
1472 GetDefinitions ()
1473 {
1474 return g_option_table;
1475 }
1476
1477 // Options table: Required for subclasses of Options.
1478
1479 static OptionDefinition g_option_table[];
1480
1481 // Instance variables to hold the values for command options.
1482
1483 std::string m_filename;
1484 uint32_t m_line_num;
1485
1486 };
1487
1488protected:
1489 virtual bool
1490 DoExecute (Args& command, CommandReturnObject &result)
1491 {
1492 Target *target = m_interpreter.GetDebugger().GetSelectedTarget().get();
1493 if (target == NULL)
1494 {
1495 result.AppendError ("Invalid target. No existing target or breakpoints.");
1496 result.SetStatus (eReturnStatusFailed);
1497 return false;
1498 }
1499
1500 // The following are the various types of breakpoints that could be cleared:
1501 // 1). -f -l (clearing breakpoint by source location)
1502
1503 BreakpointClearType break_type = eClearTypeInvalid;
1504
1505 if (m_options.m_line_num != 0)
1506 break_type = eClearTypeFileAndLine;
1507
1508 Mutex::Locker locker;
1509 target->GetBreakpointList().GetListMutex(locker);
1510
1511 BreakpointList &breakpoints = target->GetBreakpointList();
1512 size_t num_breakpoints = breakpoints.GetSize();
1513
1514 // Early return if there's no breakpoint at all.
1515 if (num_breakpoints == 0)
1516 {
1517 result.AppendError ("Breakpoint clear: No breakpoint cleared.");
1518 result.SetStatus (eReturnStatusFailed);
1519 return result.Succeeded();
1520 }
1521
1522 // Find matching breakpoints and delete them.
1523
1524 // First create a copy of all the IDs.
1525 std::vector<break_id_t> BreakIDs;
1526 for (size_t i = 0; i < num_breakpoints; ++i)
1527 BreakIDs.push_back(breakpoints.GetBreakpointAtIndex(i).get()->GetID());
1528
1529 int num_cleared = 0;
1530 StreamString ss;
1531 switch (break_type)
1532 {
1533 case eClearTypeFileAndLine: // Breakpoint by source position
1534 {
1535 const ConstString filename(m_options.m_filename.c_str());
1536 BreakpointLocationCollection loc_coll;
1537
1538 for (size_t i = 0; i < num_breakpoints; ++i)
1539 {
1540 Breakpoint *bp = breakpoints.FindBreakpointByID(BreakIDs[i]).get();
1541
1542 if (bp->GetMatchingFileLine(filename, m_options.m_line_num, loc_coll))
1543 {
1544 // If the collection size is 0, it's a full match and we can just remove the breakpoint.
1545 if (loc_coll.GetSize() == 0)
1546 {
1547 bp->GetDescription(&ss, lldb::eDescriptionLevelBrief);
1548 ss.EOL();
1549 target->RemoveBreakpointByID (bp->GetID());
1550 ++num_cleared;
1551 }
1552 }
1553 }
1554 }
1555 break;
1556
1557 default:
1558 break;
1559 }
1560
1561 if (num_cleared > 0)
1562 {
1563 Stream &output_stream = result.GetOutputStream();
1564 output_stream.Printf ("%d breakpoints cleared:\n", num_cleared);
1565 output_stream << ss.GetData();
1566 output_stream.EOL();
1567 result.SetStatus (eReturnStatusSuccessFinishNoResult);
1568 }
1569 else
1570 {
1571 result.AppendError ("Breakpoint clear: No breakpoint cleared.");
1572 result.SetStatus (eReturnStatusFailed);
1573 }
1574
1575 return result.Succeeded();
1576 }
1577
1578private:
1579 CommandOptions m_options;
1580};
1581
1582#pragma mark Clear::CommandOptions
1583
1584OptionDefinition
1585CommandObjectBreakpointClear::CommandOptions::g_option_table[] =
1586{
1587 { LLDB_OPT_SET_1, false, "file", 'f', required_argument, NULL, CommandCompletions::eSourceFileCompletion, eArgTypeFilename,
1588 "Specify the breakpoint by source location in this particular file."},
1589
1590 { LLDB_OPT_SET_1, true, "line", 'l', required_argument, NULL, 0, eArgTypeLineNum,
1591 "Specify the breakpoint by source location at this particular line."},
1592
1593 { 0, false, NULL, 0, 0, NULL, 0, eArgTypeNone, NULL }
1594};
1595
1596//-------------------------------------------------------------------------
1597// CommandObjectBreakpointDelete
1598//-------------------------------------------------------------------------
1599#pragma mark Delete
1600
1601class CommandObjectBreakpointDelete : public CommandObjectParsed
1602{
1603public:
1604 CommandObjectBreakpointDelete (CommandInterpreter &interpreter) :
1605 CommandObjectParsed (interpreter,
1606 "breakpoint delete",
1607 "Delete the specified breakpoint(s). If no breakpoints are specified, delete them all.",
1608 NULL)
1609 {
1610 CommandArgumentEntry arg;
1611 CommandObject::AddIDsArgumentData(arg, eArgTypeBreakpointID, eArgTypeBreakpointIDRange);
1612 // Add the entry for the first argument for this command to the object's arguments vector.
1613 m_arguments.push_back (arg);
1614 }
1615
1616 virtual
1617 ~CommandObjectBreakpointDelete () {}
1618
1619protected:
1620 virtual bool
1621 DoExecute (Args& command, CommandReturnObject &result)
1622 {
1623 Target *target = m_interpreter.GetDebugger().GetSelectedTarget().get();
1624 if (target == NULL)
1625 {
1626 result.AppendError ("Invalid target. No existing target or breakpoints.");
1627 result.SetStatus (eReturnStatusFailed);
1628 return false;
1629 }
1630
1631 Mutex::Locker locker;
1632 target->GetBreakpointList().GetListMutex(locker);
1633
1634 const BreakpointList &breakpoints = target->GetBreakpointList();
1635
1636 size_t num_breakpoints = breakpoints.GetSize();
1637
1638 if (num_breakpoints == 0)
1639 {
1640 result.AppendError ("No breakpoints exist to be deleted.");
1641 result.SetStatus (eReturnStatusFailed);
1642 return false;
1643 }
1644
1645 if (command.GetArgumentCount() == 0)
1646 {
1647 if (!m_interpreter.Confirm ("About to delete all breakpoints, do you want to do that?", true))
1648 {
1649 result.AppendMessage("Operation cancelled...");
1650 }
1651 else
1652 {
1653 target->RemoveAllBreakpoints ();
1654 result.AppendMessageWithFormat ("All breakpoints removed. (%lu breakpoints)\n", num_breakpoints);
1655 }
1656 result.SetStatus (eReturnStatusSuccessFinishNoResult);
1657 }
1658 else
1659 {
1660 // Particular breakpoint selected; disable that breakpoint.
1661 BreakpointIDList valid_bp_ids;
1662 CommandObjectMultiwordBreakpoint::VerifyBreakpointIDs (command, target, result, &valid_bp_ids);
1663
1664 if (result.Succeeded())
1665 {
1666 int delete_count = 0;
1667 int disable_count = 0;
1668 const size_t count = valid_bp_ids.GetSize();
1669 for (size_t i = 0; i < count; ++i)
1670 {
1671 BreakpointID cur_bp_id = valid_bp_ids.GetBreakpointIDAtIndex (i);
1672
1673 if (cur_bp_id.GetBreakpointID() != LLDB_INVALID_BREAK_ID)
1674 {
1675 if (cur_bp_id.GetLocationID() != LLDB_INVALID_BREAK_ID)
1676 {
1677 Breakpoint *breakpoint = target->GetBreakpointByID (cur_bp_id.GetBreakpointID()).get();
1678 BreakpointLocation *location = breakpoint->FindLocationByID (cur_bp_id.GetLocationID()).get();
1679 // It makes no sense to try to delete individual locations, so we disable them instead.
1680 if (location)
1681 {
1682 location->SetEnabled (false);
1683 ++disable_count;
1684 }
1685 }
1686 else
1687 {
1688 target->RemoveBreakpointByID (cur_bp_id.GetBreakpointID());
1689 ++delete_count;
1690 }
1691 }
1692 }
1693 result.AppendMessageWithFormat ("%d breakpoints deleted; %d breakpoint locations disabled.\n",
1694 delete_count, disable_count);
1695 result.SetStatus (eReturnStatusSuccessFinishNoResult);
1696 }
1697 }
1698 return result.Succeeded();
1699 }
1700};
Chris Lattner24943d22010-06-08 16:52:24 +00001701
Chris Lattner24943d22010-06-08 16:52:24 +00001702//-------------------------------------------------------------------------
1703// CommandObjectMultiwordBreakpoint
1704//-------------------------------------------------------------------------
Jim Ingham10622a22010-06-18 00:58:52 +00001705#pragma mark MultiwordBreakpoint
Chris Lattner24943d22010-06-08 16:52:24 +00001706
Greg Clayton63094e02010-06-23 01:19:29 +00001707CommandObjectMultiwordBreakpoint::CommandObjectMultiwordBreakpoint (CommandInterpreter &interpreter) :
Greg Clayton238c0a12010-09-18 01:14:36 +00001708 CommandObjectMultiword (interpreter,
1709 "breakpoint",
Jim Ingham7224aab2011-05-26 20:39:01 +00001710 "A set of commands for operating on breakpoints. Also see _regexp-break.",
Greg Clayton238c0a12010-09-18 01:14:36 +00001711 "breakpoint <command> [<command-options>]")
Chris Lattner24943d22010-06-08 16:52:24 +00001712{
Greg Clayton238c0a12010-09-18 01:14:36 +00001713 CommandObjectSP list_command_object (new CommandObjectBreakpointList (interpreter));
Greg Clayton238c0a12010-09-18 01:14:36 +00001714 CommandObjectSP enable_command_object (new CommandObjectBreakpointEnable (interpreter));
1715 CommandObjectSP disable_command_object (new CommandObjectBreakpointDisable (interpreter));
Johnny Chena62ad7c2010-10-28 17:27:46 +00001716 CommandObjectSP clear_command_object (new CommandObjectBreakpointClear (interpreter));
1717 CommandObjectSP delete_command_object (new CommandObjectBreakpointDelete (interpreter));
Greg Clayton238c0a12010-09-18 01:14:36 +00001718 CommandObjectSP set_command_object (new CommandObjectBreakpointSet (interpreter));
Chris Lattner24943d22010-06-08 16:52:24 +00001719 CommandObjectSP command_command_object (new CommandObjectBreakpointCommand (interpreter));
Greg Clayton238c0a12010-09-18 01:14:36 +00001720 CommandObjectSP modify_command_object (new CommandObjectBreakpointModify(interpreter));
Chris Lattner24943d22010-06-08 16:52:24 +00001721
Johnny Chena62ad7c2010-10-28 17:27:46 +00001722 list_command_object->SetCommandName ("breakpoint list");
Chris Lattner24943d22010-06-08 16:52:24 +00001723 enable_command_object->SetCommandName("breakpoint enable");
1724 disable_command_object->SetCommandName("breakpoint disable");
Johnny Chena62ad7c2010-10-28 17:27:46 +00001725 clear_command_object->SetCommandName("breakpoint clear");
1726 delete_command_object->SetCommandName("breakpoint delete");
Jim Ingham10622a22010-06-18 00:58:52 +00001727 set_command_object->SetCommandName("breakpoint set");
Johnny Chena62ad7c2010-10-28 17:27:46 +00001728 command_command_object->SetCommandName ("breakpoint command");
1729 modify_command_object->SetCommandName ("breakpoint modify");
Chris Lattner24943d22010-06-08 16:52:24 +00001730
Greg Clayton4a379b12012-07-17 03:23:13 +00001731 LoadSubCommand ("list", list_command_object);
1732 LoadSubCommand ("enable", enable_command_object);
1733 LoadSubCommand ("disable", disable_command_object);
1734 LoadSubCommand ("clear", clear_command_object);
1735 LoadSubCommand ("delete", delete_command_object);
1736 LoadSubCommand ("set", set_command_object);
1737 LoadSubCommand ("command", command_command_object);
1738 LoadSubCommand ("modify", modify_command_object);
Chris Lattner24943d22010-06-08 16:52:24 +00001739}
1740
1741CommandObjectMultiwordBreakpoint::~CommandObjectMultiwordBreakpoint ()
1742{
1743}
1744
1745void
1746CommandObjectMultiwordBreakpoint::VerifyBreakpointIDs (Args &args, Target *target, CommandReturnObject &result,
1747 BreakpointIDList *valid_ids)
1748{
1749 // args can be strings representing 1). integers (for breakpoint ids)
1750 // 2). the full breakpoint & location canonical representation
1751 // 3). the word "to" or a hyphen, representing a range (in which case there
1752 // had *better* be an entry both before & after of one of the first two types.
Jim Inghamd1686902010-10-14 23:45:03 +00001753 // If args is empty, we will use the last created breakpoint (if there is one.)
Chris Lattner24943d22010-06-08 16:52:24 +00001754
1755 Args temp_args;
1756
Jim Inghamd1686902010-10-14 23:45:03 +00001757 if (args.GetArgumentCount() == 0)
1758 {
Greg Clayton987c7eb2011-09-17 08:33:22 +00001759 if (target->GetLastCreatedBreakpoint())
Jim Inghamd1686902010-10-14 23:45:03 +00001760 {
1761 valid_ids->AddBreakpointID (BreakpointID(target->GetLastCreatedBreakpoint()->GetID(), LLDB_INVALID_BREAK_ID));
1762 result.SetStatus (eReturnStatusSuccessFinishNoResult);
1763 }
1764 else
1765 {
1766 result.AppendError("No breakpoint specified and no last created breakpoint.");
1767 result.SetStatus (eReturnStatusFailed);
1768 }
1769 return;
1770 }
1771
Chris Lattner24943d22010-06-08 16:52:24 +00001772 // Create a new Args variable to use; copy any non-breakpoint-id-ranges stuff directly from the old ARGS to
1773 // the new TEMP_ARGS. Do not copy breakpoint id range strings over; instead generate a list of strings for
1774 // all the breakpoint ids in the range, and shove all of those breakpoint id strings into TEMP_ARGS.
1775
1776 BreakpointIDList::FindAndReplaceIDRanges (args, target, result, temp_args);
1777
1778 // NOW, convert the list of breakpoint id strings in TEMP_ARGS into an actual BreakpointIDList:
1779
Greg Clayton54e7afa2010-07-09 20:39:50 +00001780 valid_ids->InsertStringArray (temp_args.GetConstArgumentVector(), temp_args.GetArgumentCount(), result);
Chris Lattner24943d22010-06-08 16:52:24 +00001781
1782 // At this point, all of the breakpoint ids that the user passed in have been converted to breakpoint IDs
1783 // and put into valid_ids.
1784
1785 if (result.Succeeded())
1786 {
1787 // Now that we've converted everything from args into a list of breakpoint ids, go through our tentative list
1788 // of breakpoint id's and verify that they correspond to valid/currently set breakpoints.
1789
Greg Clayton54e7afa2010-07-09 20:39:50 +00001790 const size_t count = valid_ids->GetSize();
1791 for (size_t i = 0; i < count; ++i)
Chris Lattner24943d22010-06-08 16:52:24 +00001792 {
1793 BreakpointID cur_bp_id = valid_ids->GetBreakpointIDAtIndex (i);
1794 Breakpoint *breakpoint = target->GetBreakpointByID (cur_bp_id.GetBreakpointID()).get();
1795 if (breakpoint != NULL)
1796 {
1797 int num_locations = breakpoint->GetNumLocations();
1798 if (cur_bp_id.GetLocationID() > num_locations)
1799 {
1800 StreamString id_str;
Greg Clayton54e7afa2010-07-09 20:39:50 +00001801 BreakpointID::GetCanonicalReference (&id_str,
1802 cur_bp_id.GetBreakpointID(),
1803 cur_bp_id.GetLocationID());
1804 i = valid_ids->GetSize() + 1;
Chris Lattner24943d22010-06-08 16:52:24 +00001805 result.AppendErrorWithFormat ("'%s' is not a currently valid breakpoint/location id.\n",
1806 id_str.GetData());
1807 result.SetStatus (eReturnStatusFailed);
1808 }
1809 }
1810 else
1811 {
Greg Clayton54e7afa2010-07-09 20:39:50 +00001812 i = valid_ids->GetSize() + 1;
Chris Lattner24943d22010-06-08 16:52:24 +00001813 result.AppendErrorWithFormat ("'%d' is not a currently valid breakpoint id.\n", cur_bp_id.GetBreakpointID());
1814 result.SetStatus (eReturnStatusFailed);
1815 }
1816 }
1817 }
1818}