blob: d24ba8f553b6516bae2920035b9fcc473fb5b104 [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"
20#include "lldb/Core/RegularExpression.h"
21#include "lldb/Core/StreamString.h"
22#include "lldb/Interpreter/CommandInterpreter.h"
23#include "lldb/Interpreter/CommandReturnObject.h"
24#include "lldb/Target/Target.h"
25#include "lldb/Interpreter/CommandCompletions.h"
26#include "lldb/Target/StackFrame.h"
27
28using namespace lldb;
29using namespace lldb_private;
30
31static void
32AddBreakpointDescription (CommandContext *context, StreamString *s, Breakpoint *bp, lldb::DescriptionLevel level)
33{
34 s->IndentMore();
35 bp->GetDescription (s, level, true);
36 s->IndentLess();
37 s->EOL();
38}
39
40//-------------------------------------------------------------------------
41// CommandObjectBreakpointSet::CommandOptions
42//-------------------------------------------------------------------------
43
44CommandObjectBreakpointSet::CommandOptions::CommandOptions() :
45 Options (),
46 m_filename (),
47 m_line_num (0),
48 m_column (0),
49 m_ignore_inlines (false),
50 m_func_name (),
51 m_func_regexp (),
52 m_modules (),
53 m_load_addr()
54{
55 BuildValidOptionSets();
56}
57
58CommandObjectBreakpointSet::CommandOptions::~CommandOptions ()
59{
60}
61
62lldb::OptionDefinition
63CommandObjectBreakpointSet::CommandOptions::g_option_table[] =
64{
65 { 0, false, "file", 'f', required_argument, NULL, CommandCompletions::eSourceFileCompletion, "<filename>",
66 "Set the breakpoint by source location in this particular file."},
67
68 { 0, true, "line", 'l', required_argument, NULL, 0, "<linenum>",
69 "Set the breakpoint by source location at this particular line."},
70
71 { 0, false, "shlib", 's', required_argument, NULL, CommandCompletions::eModuleCompletion, "<shlib-name>",
72 "Set the breakpoint only in this shared library (can use this option multiple times for multiple shlibs)."},
73
74 // Comment out this option for the moment, as we don't actually use it, but will in the future.
75 // This way users won't see it, but the infrastructure is left in place.
76 // { 0, false, "column", 'c', required_argument, NULL, "<column>",
77 // "Set the breakpoint by source location at this particular column."},
78
79 { 0, false, "ignore_inlines", 'i', no_argument, NULL, 0, NULL,
80 "Ignore inlined subroutines when setting the breakppoint." },
81
82 { 1, true, "address", 'a', required_argument, NULL, 0, "<address>",
83 "Set the breakpoint by address, at the specified address."},
84
85 { 1, false, "ignore_inlines", 'i', no_argument, NULL, 0, NULL,
86 "Ignore inlined subroutines when setting the breakppoint." },
87
88 { 2, true, "name", 'n', required_argument, NULL, CommandCompletions::eSymbolCompletion, "<function-name>",
89 "Set the breakpoint by function name." },
90
91 { 2, false, "shlib", 's', required_argument, NULL, CommandCompletions::eModuleCompletion, "<shlib-name>",
92 "Set the breakpoint only in this shared library (can use this option multiple times for multiple shlibs)."},
93
94 { 2, false, "ignore_inlines", 'i', no_argument, NULL, 0, NULL,
95 "Ignore inlined subroutines when setting the breakpoint." },
96
97 { 3, true, "func_regex", 'r', required_argument, NULL, 0, "<regular-expression>",
98 "Set the breakpoint by function name, evaluating a regular-expression to find the function name(s)." },
99
100 { 3, false, "shlib", 's', required_argument, NULL, CommandCompletions::eModuleCompletion, "<shlib-name>",
101 "Set the breakpoint only in this shared library (can use this option multiple times for multiple shlibs)."},
102
103 { 3, false, "ignore_inlines", 'i', no_argument, NULL, 0, NULL,
104 "Ignore inlined subroutines when setting the breakpoint." },
105
106 { 0, false, NULL, 0, 0, NULL, 0, NULL, NULL }
107};
108
109const lldb::OptionDefinition*
110CommandObjectBreakpointSet::CommandOptions::GetDefinitions ()
111{
112 return g_option_table;
113}
114
115Error
116CommandObjectBreakpointSet::CommandOptions::SetOptionValue (int option_idx, const char *option_arg)
117{
118 Error error;
119 char short_option = (char) m_getopt_table[option_idx].val;
120
121 switch (short_option)
122 {
123 case 'a':
124 m_load_addr = Args::StringToUInt64(optarg, LLDB_INVALID_ADDRESS, 0);
125 if (m_load_addr == LLDB_INVALID_ADDRESS)
126 m_load_addr = Args::StringToUInt64(optarg, LLDB_INVALID_ADDRESS, 16);
127
128 if (m_load_addr == LLDB_INVALID_ADDRESS)
129 error.SetErrorStringWithFormat ("Invalid address string '%s'.\n", optarg);
130 break;
131
132 case 'c':
133 m_column = Args::StringToUInt32 (option_arg, 0);
134 break;
135 case 'f':
136 m_filename = option_arg;
137 break;
138 case 'i':
139 m_ignore_inlines = true;
140 break;
141 case 'l':
142 m_line_num = Args::StringToUInt32 (option_arg, 0);
143 break;
144 case 'n':
145 m_func_name = option_arg;
146 break;
147 case 'r':
148 m_func_regexp = option_arg;
149 break;
150 case 's':
151 {
152 m_modules.push_back (std::string (option_arg));
153 break;
154 }
155 default:
156 error.SetErrorStringWithFormat ("Unrecognized option '%c'.\n", short_option);
157 break;
158 }
159
160 return error;
161}
162
163void
164CommandObjectBreakpointSet::CommandOptions::ResetOptionValues ()
165{
166 Options::ResetOptionValues();
167
168 m_filename.clear();
169 m_line_num = 0;
170 m_column = 0;
171 m_ignore_inlines = false;
172 m_func_name.clear();
173 m_func_regexp.clear();
174 m_load_addr = LLDB_INVALID_ADDRESS;
175 m_modules.clear();
176}
177
178//-------------------------------------------------------------------------
179// CommandObjectBreakpointSet
180//-------------------------------------------------------------------------
181
182CommandObjectBreakpointSet::CommandObjectBreakpointSet () :
183 CommandObject ("breakpoint set", "Sets a breakpoint or set of breakpoints in the executable.",
184 "breakpoint set <cmd-options>")
185{
186}
187
188CommandObjectBreakpointSet::~CommandObjectBreakpointSet ()
189{
190}
191
192Options *
193CommandObjectBreakpointSet::GetOptions ()
194{
195 return &m_options;
196}
197
198bool
199CommandObjectBreakpointSet::Execute
200(
201 Args& command,
202 CommandContext *context,
203 CommandInterpreter *interpreter,
204 CommandReturnObject &result
205)
206{
207 Target *target = context->GetTarget();
208 if (target == NULL)
209 {
210 result.AppendError ("Invalid target, set executable file using 'file' command.");
211 result.SetStatus (eReturnStatusFailed);
212 return false;
213 }
214
215 // The following are the various types of breakpoints that could be set:
216 // 1). -f -l -p [-s -g] (setting breakpoint by source location)
217 // 2). -a [-s -g] (setting breakpoint by address)
218 // 3). -n [-s -g] (setting breakpoint by function name)
219 // 4). -r [-s -g] (setting breakpoint by function name regular expression)
220
221 BreakpointSetType break_type = eSetTypeInvalid;
222
223 if (m_options.m_line_num != 0)
224 break_type = eSetTypeFileAndLine;
225 else if (m_options.m_load_addr != LLDB_INVALID_ADDRESS)
226 break_type = eSetTypeAddress;
227 else if (!m_options.m_func_name.empty())
228 break_type = eSetTypeFunctionName;
229 else if (!m_options.m_func_regexp.empty())
230 break_type = eSetTypeFunctionRegexp;
231
232 ModuleSP module_sp = target->GetExecutableModule();
233 Breakpoint *bp = NULL;
234 FileSpec module;
235 bool use_module = false;
236 int num_modules = m_options.m_modules.size();
237
238 if ((num_modules > 0) && (break_type != eSetTypeAddress))
239 use_module = true;
240
241 switch (break_type)
242 {
243 case eSetTypeFileAndLine: // Breakpoint by source position
244 {
245 FileSpec file;
246 if (m_options.m_filename.empty())
247 {
248 StackFrame *cur_frame = context->GetExecutionContext().frame;
249 if (cur_frame == NULL)
250 {
251 result.AppendError ("Attempting to set breakpoint by line number alone with no selected frame.");
252 result.SetStatus (eReturnStatusFailed);
253 break;
254 }
255 else if (!cur_frame->HasDebugInformation())
256 {
257 result.AppendError ("Attempting to set breakpoint by line number alone but selected frame has no debug info.");
258 result.SetStatus (eReturnStatusFailed);
259 break;
260 }
261 else
262 {
263 const SymbolContext &context = cur_frame->GetSymbolContext(true);
264 if (context.line_entry.file)
265 {
266 file = context.line_entry.file;
267 }
268 else if (context.comp_unit != NULL)
269 { file = context.comp_unit;
270 }
271 else
272 {
273 result.AppendError ("Attempting to set breakpoint by line number alone but can't find the file for the selected frame.");
274 result.SetStatus (eReturnStatusFailed);
275 break;
276 }
277 }
278 }
279 else
280 {
281 file.SetFile(m_options.m_filename.c_str());
282 }
283
284 if (use_module)
285 {
286 for (int i = 0; i < num_modules; ++i)
287 {
288 module.SetFile(m_options.m_modules[i].c_str());
289 bp = target->CreateBreakpoint (&module,
290 file,
291 m_options.m_line_num,
292 m_options.m_ignore_inlines).get();
293 if (bp)
294 {
295 StreamString &output_stream = result.GetOutputStream();
296 output_stream.Printf ("Breakpoint created: ");
297 bp->GetDescription(&output_stream, lldb::eDescriptionLevelBrief);
298 output_stream.EOL();
299 result.SetStatus (eReturnStatusSuccessFinishResult);
300 }
301 else
302 {
303 result.AppendErrorWithFormat("Breakpoint creation failed: No breakpoint created in module '%s'.\n",
304 m_options.m_modules[i].c_str());
305 result.SetStatus (eReturnStatusFailed);
306 }
307 }
308 }
309 else
310 bp = target->CreateBreakpoint (NULL,
311 file,
312 m_options.m_line_num,
313 m_options.m_ignore_inlines).get();
314 }
315 break;
316 case eSetTypeAddress: // Breakpoint by address
317 bp = target->CreateBreakpoint (m_options.m_load_addr, false).get();
318 break;
319 case eSetTypeFunctionName: // Breakpoint by function name
320 if (use_module)
321 {
322 for (int i = 0; i < num_modules; ++i)
323 {
324 module.SetFile(m_options.m_modules[i].c_str());
325 bp = target->CreateBreakpoint (&module, m_options.m_func_name.c_str()).get();
326 if (bp)
327 {
328 StreamString &output_stream = result.GetOutputStream();
329 output_stream.Printf ("Breakpoint created: ");
330 bp->GetDescription(&output_stream, lldb::eDescriptionLevelBrief);
331 output_stream.EOL();
332 result.SetStatus (eReturnStatusSuccessFinishResult);
333 }
334 else
335 {
336 result.AppendErrorWithFormat("Breakpoint creation failed: No breakpoint created in module '%s'.\n",
337 m_options.m_modules[i].c_str());
338 result.SetStatus (eReturnStatusFailed);
339 }
340 }
341 }
342 else
343 bp = target->CreateBreakpoint (NULL, m_options.m_func_name.c_str()).get();
344 break;
345 case eSetTypeFunctionRegexp: // Breakpoint by regular expression function name
346 {
347 RegularExpression regexp(m_options.m_func_regexp.c_str());
348 if (use_module)
349 {
350 for (int i = 0; i < num_modules; ++i)
351 {
352 module.SetFile(m_options.m_modules[i].c_str());
353 bp = target->CreateBreakpoint (&module, regexp).get();
354 if (bp)
355 {
356 StreamString &output_stream = result.GetOutputStream();
357 output_stream.Printf ("Breakpoint created: ");
358 bp->GetDescription(&output_stream, lldb::eDescriptionLevelBrief);
359 output_stream.EOL();
360 result.SetStatus (eReturnStatusSuccessFinishResult);
361 }
362 else
363 {
364 result.AppendErrorWithFormat("Breakpoint creation failed: No breakpoint created in module '%s'.\n",
365 m_options.m_modules[i].c_str());
366 result.SetStatus (eReturnStatusFailed);
367 }
368 }
369 }
370 else
371 bp = target->CreateBreakpoint (NULL, regexp).get();
372 }
373 break;
374 default:
375 break;
376 }
377
378 if (bp && !use_module)
379 {
380 StreamString &output_stream = result.GetOutputStream();
381 output_stream.Printf ("Breakpoint created: ");
382 bp->GetDescription(&output_stream, lldb::eDescriptionLevelBrief);
383 output_stream.EOL();
384 result.SetStatus (eReturnStatusSuccessFinishResult);
385 }
386 else if (!bp)
387 {
388 result.AppendError ("Breakpoint creation failed: No breakpoint created.");
389 result.SetStatus (eReturnStatusFailed);
390 }
391
392 return result.Succeeded();
393}
394
395
396
397//-------------------------------------------------------------------------
398// CommandObjectMultiwordBreakpoint
399//-------------------------------------------------------------------------
400
401CommandObjectMultiwordBreakpoint::CommandObjectMultiwordBreakpoint (CommandInterpreter *interpreter) :
402 CommandObjectMultiword ("breakpoint",
403 "A set of commands for operating on breakpoints.",
404 "breakpoint <command> [<command-options>]")
405{
406 bool status;
407
408 CommandObjectSP list_command_object (new CommandObjectBreakpointList ());
409 CommandObjectSP delete_command_object (new CommandObjectBreakpointDelete ());
410 CommandObjectSP enable_command_object (new CommandObjectBreakpointEnable ());
411 CommandObjectSP disable_command_object (new CommandObjectBreakpointDisable ());
412 CommandObjectSP set_command_object (new CommandObjectBreakpointSet ());
413 CommandObjectSP command_command_object (new CommandObjectBreakpointCommand (interpreter));
414
415 enable_command_object->SetCommandName("breakpoint enable");
416 disable_command_object->SetCommandName("breakpoint disable");
417 set_command_object->SetCommandName("breakpoint set");
418 command_command_object->SetCommandName ("breakpoint command");
419 list_command_object->SetCommandName ("breakpoint list");
420
421 status = LoadSubCommand (list_command_object, "list", interpreter);
422 status = LoadSubCommand (enable_command_object, "enable", interpreter);
423 status = LoadSubCommand (disable_command_object, "disable", interpreter);
424 status = LoadSubCommand (delete_command_object, "delete", interpreter);
425 status = LoadSubCommand (set_command_object, "set", interpreter);
426 status = LoadSubCommand (command_command_object, "command", interpreter);
427}
428
429CommandObjectMultiwordBreakpoint::~CommandObjectMultiwordBreakpoint ()
430{
431}
432
433void
434CommandObjectMultiwordBreakpoint::VerifyBreakpointIDs (Args &args, Target *target, CommandReturnObject &result,
435 BreakpointIDList *valid_ids)
436{
437 // args can be strings representing 1). integers (for breakpoint ids)
438 // 2). the full breakpoint & location canonical representation
439 // 3). the word "to" or a hyphen, representing a range (in which case there
440 // had *better* be an entry both before & after of one of the first two types.
441
442 Args temp_args;
443
444 // Create a new Args variable to use; copy any non-breakpoint-id-ranges stuff directly from the old ARGS to
445 // the new TEMP_ARGS. Do not copy breakpoint id range strings over; instead generate a list of strings for
446 // all the breakpoint ids in the range, and shove all of those breakpoint id strings into TEMP_ARGS.
447
448 BreakpointIDList::FindAndReplaceIDRanges (args, target, result, temp_args);
449
450 // NOW, convert the list of breakpoint id strings in TEMP_ARGS into an actual BreakpointIDList:
451
452 valid_ids->InsertStringArray ((const char **) temp_args.GetArgumentVector(), temp_args.GetArgumentCount(), result);
453
454 // At this point, all of the breakpoint ids that the user passed in have been converted to breakpoint IDs
455 // and put into valid_ids.
456
457 if (result.Succeeded())
458 {
459 // Now that we've converted everything from args into a list of breakpoint ids, go through our tentative list
460 // of breakpoint id's and verify that they correspond to valid/currently set breakpoints.
461
462 for (int i = 0; i < valid_ids->Size(); ++i)
463 {
464 BreakpointID cur_bp_id = valid_ids->GetBreakpointIDAtIndex (i);
465 Breakpoint *breakpoint = target->GetBreakpointByID (cur_bp_id.GetBreakpointID()).get();
466 if (breakpoint != NULL)
467 {
468 int num_locations = breakpoint->GetNumLocations();
469 if (cur_bp_id.GetLocationID() > num_locations)
470 {
471 StreamString id_str;
472 BreakpointID::GetCanonicalReference (&id_str, cur_bp_id.GetBreakpointID(),
473 cur_bp_id.GetLocationID());
474 i = valid_ids->Size() + 1;
475 result.AppendErrorWithFormat ("'%s' is not a currently valid breakpoint/location id.\n",
476 id_str.GetData());
477 result.SetStatus (eReturnStatusFailed);
478 }
479 }
480 else
481 {
482 i = valid_ids->Size() + 1;
483 result.AppendErrorWithFormat ("'%d' is not a currently valid breakpoint id.\n", cur_bp_id.GetBreakpointID());
484 result.SetStatus (eReturnStatusFailed);
485 }
486 }
487 }
488}
489
490//-------------------------------------------------------------------------
491// CommandObjectBreakpointList::Options
492//-------------------------------------------------------------------------
493
494CommandObjectBreakpointList::CommandOptions::CommandOptions() :
495 Options (),
496 m_level (lldb::eDescriptionLevelFull) // Breakpoint List defaults to brief descriptions
497{
498 BuildValidOptionSets();
499}
500
501CommandObjectBreakpointList::CommandOptions::~CommandOptions ()
502{
503}
504
505lldb::OptionDefinition
506CommandObjectBreakpointList::CommandOptions::g_option_table[] =
507{
508 { 0, false, "brief", 'b', no_argument, NULL, 0, NULL,
509 "Give a brief description of the breakpoint (no location info)."},
510
511 // FIXME: We need to add an "internal" command, and then add this sort of thing to it.
512 // But I need to see it for now, and don't want to wait.
513 { 0, false, "internal", 'i', no_argument, NULL, 0, NULL,
514 "Show debugger internal breakpoints" },
515
516 { 1, false, "full", 'f', no_argument, NULL, 0, NULL,
517 "Give a full description of the breakpoint and its locations."},
518 // DITTO FIXME
519 { 1, false, "internal", 'i', no_argument, NULL, 0, NULL,
520 "Show debugger internal breakpoints" },
521
522 { 2, false, "verbose", 'v', no_argument, NULL, 0, NULL,
523 "Explain everything we know about the breakpoint (for debugging debugger bugs)." },
524 // DITTO FIXME
525 { 2, false, "internal", 'i', no_argument, NULL, 0, NULL,
526 "Show debugger internal breakpoints" },
527
528 { 0, false, NULL, 0, 0, NULL, 0, NULL, NULL }
529};
530
531const lldb::OptionDefinition*
532CommandObjectBreakpointList::CommandOptions::GetDefinitions ()
533{
534 return g_option_table;
535}
536
537Error
538CommandObjectBreakpointList::CommandOptions::SetOptionValue (int option_idx, const char *option_arg)
539{
540 Error error;
541 char short_option = (char) m_getopt_table[option_idx].val;
542
543 switch (short_option)
544 {
545 case 'b':
546 m_level = lldb::eDescriptionLevelBrief;
547 break;
548 case 'f':
549 m_level = lldb::eDescriptionLevelFull;
550 break;
551 case 'v':
552 m_level = lldb::eDescriptionLevelVerbose;
553 break;
554 case 'i':
555 m_internal = true;
556 break;
557 default:
558 error.SetErrorStringWithFormat ("Unrecognized option '%c'.\n", short_option);
559 break;
560 }
561
562 return error;
563}
564
565void
566CommandObjectBreakpointList::CommandOptions::ResetOptionValues ()
567{
568 Options::ResetOptionValues();
569
570 m_level = lldb::eDescriptionLevelFull;
571 m_internal = false;
572}
573
574//-------------------------------------------------------------------------
575// CommandObjectBreakpointList
576//-------------------------------------------------------------------------
577
578CommandObjectBreakpointList::CommandObjectBreakpointList () :
579 CommandObject ("breakpoint list",
580 "List some or all breakpoints at configurable levels of detail.",
581 "breakpoint list [<breakpoint-id>]")
582{
583}
584
585CommandObjectBreakpointList::~CommandObjectBreakpointList ()
586{
587}
588
589Options *
590CommandObjectBreakpointList::GetOptions ()
591{
592 return &m_options;
593}
594
595bool
596CommandObjectBreakpointList::Execute
597(
598 Args& args,
599 CommandContext *context,
600 CommandInterpreter *interpreter,
601 CommandReturnObject &result
602)
603{
604 Target *target = context->GetTarget();
605 if (target == NULL)
606 {
607 result.AppendError ("Invalid target, set executable file using 'file' command.");
608 result.SetStatus (eReturnStatusSuccessFinishNoResult);
609 return true;
610 }
611
612 const BreakpointList &breakpoints = target->GetBreakpointList(m_options.m_internal);
613 size_t num_breakpoints = breakpoints.GetSize();
614
615 if (num_breakpoints == 0)
616 {
617 result.AppendMessage ("No breakpoints currently set.");
618 result.SetStatus (eReturnStatusSuccessFinishNoResult);
619 return true;
620 }
621
622 StreamString &output_stream = result.GetOutputStream();
623
624 if (args.GetArgumentCount() == 0)
625 {
626 // No breakpoint selected; show info about all currently set breakpoints.
627 result.AppendMessage ("Current breakpoints:");
628 for (int i = 0; i < num_breakpoints; ++i)
629 {
630 Breakpoint *breakpoint = breakpoints.GetBreakpointByIndex (i).get();
631 AddBreakpointDescription (context, &output_stream, breakpoint, m_options.m_level);
632 }
633 result.SetStatus (eReturnStatusSuccessFinishNoResult);
634 }
635 else
636 {
637 // Particular breakpoints selected; show info about that breakpoint.
638 BreakpointIDList valid_bp_ids;
639 CommandObjectMultiwordBreakpoint::VerifyBreakpointIDs (args, target, result, &valid_bp_ids);
640
641 if (result.Succeeded())
642 {
643 for (int i = 0; i < valid_bp_ids.Size(); ++i)
644 {
645 BreakpointID cur_bp_id = valid_bp_ids.GetBreakpointIDAtIndex (i);
646 Breakpoint *breakpoint = target->GetBreakpointByID (cur_bp_id.GetBreakpointID()).get();
647 AddBreakpointDescription (context, &output_stream, breakpoint, m_options.m_level);
648 }
649 result.SetStatus (eReturnStatusSuccessFinishNoResult);
650 }
651 else
652 {
653 result.AppendError ("Invalid breakpoint id.");
654 result.SetStatus (eReturnStatusFailed);
655 }
656 }
657
658 return result.Succeeded();
659}
660
661//-------------------------------------------------------------------------
662// CommandObjectBreakpointEnable
663//-------------------------------------------------------------------------
664
665CommandObjectBreakpointEnable::CommandObjectBreakpointEnable () :
666 CommandObject ("enable",
667 "Enables the specified disabled breakpoint(s). If no breakpoints are specified, enables all of them.",
668 "breakpoint enable [<breakpoint-id> | <breakpoint-id-list>]")
669{
670 // This command object can either be called via 'enable' or 'breakpoint enable'. Because it has two different
671 // potential invocation methods, we need to be a little tricky about generating the syntax string.
672 //StreamString tmp_string;
673 //tmp_string.Printf ("%s <breakpoint-id>", GetCommandName());
674 //m_cmd_syntax.assign (tmp_string.GetData(), tmp_string.GetSize());
675}
676
677
678CommandObjectBreakpointEnable::~CommandObjectBreakpointEnable ()
679{
680}
681
682
683bool
684CommandObjectBreakpointEnable::Execute (Args& args, CommandContext *context,
685 CommandInterpreter *interpreter, CommandReturnObject &result)
686{
687 Target *target = context->GetTarget();
688 if (target == NULL)
689 {
690 result.AppendError ("Invalid target, set executable file using 'file' command.");
691 result.SetStatus (eReturnStatusFailed);
692 return false;
693 }
694
695 const BreakpointList &breakpoints = target->GetBreakpointList();
696 size_t num_breakpoints = breakpoints.GetSize();
697
698 if (num_breakpoints == 0)
699 {
700 result.AppendError ("No breakpoints exist to be enabled.");
701 result.SetStatus (eReturnStatusFailed);
702 return false;
703 }
704
705 if (args.GetArgumentCount() == 0)
706 {
707 // No breakpoint selected; enable all currently set breakpoints.
708 target->EnableAllBreakpoints ();
709 result.AppendMessageWithFormat ("All breakpoints enabled. (%d breakpoints)\n", num_breakpoints);
710 result.SetStatus (eReturnStatusSuccessFinishNoResult);
711 }
712 else
713 {
714 // Particular breakpoint selected; enable that breakpoint.
715 BreakpointIDList valid_bp_ids;
716 CommandObjectMultiwordBreakpoint::VerifyBreakpointIDs (args, target, result, &valid_bp_ids);
717
718 if (result.Succeeded())
719 {
720 int enable_count = 0;
721 int loc_count = 0;
722 for (int i = 0; i < valid_bp_ids.Size(); ++i)
723 {
724 BreakpointID cur_bp_id = valid_bp_ids.GetBreakpointIDAtIndex (i);
725
726 if (cur_bp_id.GetBreakpointID() != LLDB_INVALID_BREAK_ID)
727 {
728 Breakpoint *breakpoint = target->GetBreakpointByID (cur_bp_id.GetBreakpointID()).get();
729 if (cur_bp_id.GetLocationID() != LLDB_INVALID_BREAK_ID)
730 {
731 BreakpointLocation *location = breakpoint->FindLocationByID (cur_bp_id.GetLocationID()).get();
732 if (location)
733 {
734 location->SetEnabled (true);
735 breakpoint->SetEnabled (true);
736 ++loc_count;
737 }
738 }
739 else
740 {
741 target->EnableBreakpointByID (cur_bp_id.GetBreakpointID());
742 ++enable_count;
743
744 int num_locations = breakpoint->GetNumLocations ();
745 for (int j = 0; j < num_locations; ++j)
746 {
747 BreakpointLocation *cur_loc = breakpoint->GetLocationAtIndex(j).get();
748 if (cur_loc)
749 cur_loc->SetEnabled (true);
750 }
751 }
752 }
753 }
754 result.AppendMessageWithFormat ("%d breakpoints enabled.\n", enable_count + loc_count);
755 result.SetStatus (eReturnStatusSuccessFinishNoResult);
756 }
757 }
758
759 return result.Succeeded();
760}
761
762//-------------------------------------------------------------------------
763// CommandObjectBreakpointDisable
764//-------------------------------------------------------------------------
765
766CommandObjectBreakpointDisable::CommandObjectBreakpointDisable () :
767 CommandObject ("disable",
768 "Disables the specified breakpoint(s) without removing it/them. If no breakpoints are specified, disables them all.",
769 "disable [<breakpoint-id> | <breakpoint-id-list>]")
770{
771 // This command object can either be called via 'enable' or 'breakpoint enable'. Because it has two different
772 // potential invocation methods, we need to be a little tricky about generating the syntax string.
773 //StreamString tmp_string;
774 //tmp_string.Printf ("%s <breakpoint-id>", GetCommandName());
775 //m_cmd_syntax.assign(tmp_string.GetData(), tmp_string.GetSize());
776}
777
778CommandObjectBreakpointDisable::~CommandObjectBreakpointDisable ()
779{
780}
781
782bool
783CommandObjectBreakpointDisable::Execute (Args& args, CommandContext *context,
784 CommandInterpreter *interpreter, CommandReturnObject &result)
785{
786 Target *target = context->GetTarget();
787 if (target == NULL)
788 {
789 result.AppendError ("Invalid target, set executable file using 'file' command.");
790 result.SetStatus (eReturnStatusFailed);
791 return false;
792 }
793
794 const BreakpointList &breakpoints = target->GetBreakpointList();
795 size_t num_breakpoints = breakpoints.GetSize();
796
797 if (num_breakpoints == 0)
798 {
799 result.AppendError ("No breakpoints exist to be disabled.");
800 result.SetStatus (eReturnStatusFailed);
801 return false;
802 }
803
804 if (args.GetArgumentCount() == 0)
805 {
806 // No breakpoint selected; disable all currently set breakpoints.
807 target->DisableAllBreakpoints ();
808 result.AppendMessageWithFormat ("All breakpoints disabled. (%d breakpoints)\n", num_breakpoints);
809 result.SetStatus (eReturnStatusSuccessFinishNoResult);
810 }
811 else
812 {
813 // Particular breakpoint selected; disable that breakpoint.
814 BreakpointIDList valid_bp_ids;
815
816 CommandObjectMultiwordBreakpoint::VerifyBreakpointIDs (args, target, result, &valid_bp_ids);
817
818 if (result.Succeeded())
819 {
820 int disable_count = 0;
821 int loc_count = 0;
822 for (int i = 0; i < valid_bp_ids.Size(); ++i)
823 {
824 BreakpointID cur_bp_id = valid_bp_ids.GetBreakpointIDAtIndex (i);
825
826 if (cur_bp_id.GetBreakpointID() != LLDB_INVALID_BREAK_ID)
827 {
828 Breakpoint *breakpoint = target->GetBreakpointByID (cur_bp_id.GetBreakpointID()).get();
829 if (cur_bp_id.GetLocationID() != LLDB_INVALID_BREAK_ID)
830 {
831 BreakpointLocation *location = breakpoint->FindLocationByID (cur_bp_id.GetLocationID()).get();
832 if (location)
833 {
834 location->SetEnabled (false);
835 ++loc_count;
836 }
837 }
838 else
839 {
840 target->DisableBreakpointByID (cur_bp_id.GetBreakpointID());
841 ++disable_count;
842
843 int num_locations = breakpoint->GetNumLocations();
844 for (int j = 0; j < num_locations; ++j)
845 {
846 BreakpointLocation *cur_loc = breakpoint->GetLocationAtIndex(j).get();
847 if (cur_loc)
848 cur_loc->SetEnabled (false);
849 }
850 }
851 }
852 }
853 result.AppendMessageWithFormat ("%d breakpoints disabled.\n", disable_count + loc_count);
854 result.SetStatus (eReturnStatusSuccessFinishNoResult);
855 }
856 }
857
858 return result.Succeeded();
859}
860
861//-------------------------------------------------------------------------
862// CommandObjectBreakpointDelete
863//-------------------------------------------------------------------------
864
865CommandObjectBreakpointDelete::CommandObjectBreakpointDelete() :
866 CommandObject ("breakpoint delete",
867 "Delete the specified breakpoint(s). If no breakpoints are specified, deletes them all.",
868 "breakpoint delete [<breakpoint-id> | <breakpoint-id-list>]")
869{
870}
871
872
873CommandObjectBreakpointDelete::~CommandObjectBreakpointDelete ()
874{
875}
876
877bool
878CommandObjectBreakpointDelete::Execute (Args& args, CommandContext *context,
879 CommandInterpreter *interpreter, CommandReturnObject &result)
880{
881 Target *target = context->GetTarget();
882 if (target == NULL)
883 {
884 result.AppendError ("Invalid target, set executable file using 'file' command.");
885 result.SetStatus (eReturnStatusFailed);
886 return false;
887 }
888
889 const BreakpointList &breakpoints = target->GetBreakpointList();
890 size_t num_breakpoints = breakpoints.GetSize();
891
892 if (num_breakpoints == 0)
893 {
894 result.AppendError ("No breakpoints exist to be deleted.");
895 result.SetStatus (eReturnStatusFailed);
896 return false;
897 }
898
899 if (args.GetArgumentCount() == 0)
900 {
901 // No breakpoint selected; disable all currently set breakpoints.
902 if (args.GetArgumentCount() != 0)
903 {
904 result.AppendErrorWithFormat ("Specify breakpoints to delete with the -i option.\n");
905 result.SetStatus (eReturnStatusFailed);
906 return false;
907 }
908
909 target->RemoveAllBreakpoints ();
910 result.AppendMessageWithFormat ("All breakpoints removed. (%d breakpoints)\n", num_breakpoints);
911 result.SetStatus (eReturnStatusSuccessFinishNoResult);
912 }
913 else
914 {
915 // Particular breakpoint selected; disable that breakpoint.
916 BreakpointIDList valid_bp_ids;
917 CommandObjectMultiwordBreakpoint::VerifyBreakpointIDs (args, target, result, &valid_bp_ids);
918
919 if (result.Succeeded())
920 {
921 int delete_count = 0;
922 int disable_count = 0;
923 for (int i = 0; i < valid_bp_ids.Size(); ++i)
924 {
925 BreakpointID cur_bp_id = valid_bp_ids.GetBreakpointIDAtIndex (i);
926
927 if (cur_bp_id.GetBreakpointID() != LLDB_INVALID_BREAK_ID)
928 {
929 if (cur_bp_id.GetLocationID() != LLDB_INVALID_BREAK_ID)
930 {
931 Breakpoint *breakpoint = target->GetBreakpointByID (cur_bp_id.GetBreakpointID()).get();
932 BreakpointLocation *location = breakpoint->FindLocationByID (cur_bp_id.GetLocationID()).get();
933 // It makes no sense to try to delete individual locations, so we disable them instead.
934 if (location)
935 {
936 location->SetEnabled (false);
937 ++disable_count;
938 }
939 }
940 else
941 {
942 target->RemoveBreakpointByID (cur_bp_id.GetBreakpointID());
943 ++delete_count;
944 }
945 }
946 }
947 result.AppendMessageWithFormat ("%d breakpoints deleted; %d breakpoint locations disabled.\n",
948 delete_count, disable_count);
949 result.SetStatus (eReturnStatusSuccessFinishNoResult);
950 }
951 }
952 return result.Succeeded();
953}