blob: bbefb2c5a7f217a937dabc36218b7055a96e1488 [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
31using namespace lldb;
32using namespace lldb_private;
33
34static void
35AddBreakpointDescription (CommandContext *context, StreamString *s, Breakpoint *bp, lldb::DescriptionLevel level)
36{
37 s->IndentMore();
38 bp->GetDescription (s, level, true);
39 s->IndentLess();
40 s->EOL();
41}
42
43//-------------------------------------------------------------------------
44// CommandObjectBreakpointSet::CommandOptions
45//-------------------------------------------------------------------------
Jim Ingham10622a22010-06-18 00:58:52 +000046#pragma mark Set::CommandOptions
Chris Lattner24943d22010-06-08 16:52:24 +000047
48CommandObjectBreakpointSet::CommandOptions::CommandOptions() :
49 Options (),
50 m_filename (),
51 m_line_num (0),
52 m_column (0),
53 m_ignore_inlines (false),
54 m_func_name (),
55 m_func_regexp (),
56 m_modules (),
Jim Ingham3c7b5b92010-06-16 02:00:15 +000057 m_load_addr(),
58 m_thread_id(LLDB_INVALID_THREAD_ID),
59 m_thread_index (-1),
60 m_thread_name(),
61 m_queue_name(),
62 m_ignore_count (-1)
Chris Lattner24943d22010-06-08 16:52:24 +000063{
Chris Lattner24943d22010-06-08 16:52:24 +000064}
65
66CommandObjectBreakpointSet::CommandOptions::~CommandOptions ()
67{
68}
69
70lldb::OptionDefinition
71CommandObjectBreakpointSet::CommandOptions::g_option_table[] =
72{
Jim Ingham34e9a982010-06-15 18:47:14 +000073 { LLDB_OPT_SET_ALL, false, "shlib", 's', required_argument, NULL, CommandCompletions::eModuleCompletion, "<shlib-name>",
74 "Set the breakpoint only in this shared library (can use this option multiple times for multiple shlibs)."},
75
76 { LLDB_OPT_SET_ALL, false, "ignore_inlines", 'i', no_argument, NULL, 0, NULL,
77 "Ignore inlined subroutines when setting the breakppoint." },
78
Jim Ingham3c7b5b92010-06-16 02:00:15 +000079 { LLDB_OPT_SET_ALL, false, "ignore_count", 'k', required_argument, NULL, 0, NULL,
80 "Set the number of times this breakpoint is sKipped before stopping." },
81
82 { LLDB_OPT_SET_ALL, false, "thread_index", 'x', required_argument, NULL, NULL, "<thread_index>",
83 "The breakpoint stops only for the thread whose indeX matches this argument."},
84
85 { LLDB_OPT_SET_ALL, false, "thread_id", 't', required_argument, NULL, NULL, "<thread_id>",
86 "The breakpoint stops only for the thread whose TID matches this argument."},
87
88 { LLDB_OPT_SET_ALL, false, "thread_name", 'T', required_argument, NULL, NULL, "<thread_name>",
89 "The breakpoint stops only for the thread whose thread name matches this argument."},
90
91 { LLDB_OPT_SET_ALL, false, "queue_name", 'q', required_argument, NULL, NULL, "<queue_name>",
92 "The breakpoint stops only for threads in the queue whose name is given by this argument."},
93
Jim Ingham34e9a982010-06-15 18:47:14 +000094 { LLDB_OPT_SET_1, false, "file", 'f', required_argument, NULL, CommandCompletions::eSourceFileCompletion, "<filename>",
Chris Lattner24943d22010-06-08 16:52:24 +000095 "Set the breakpoint by source location in this particular file."},
96
Jim Ingham34e9a982010-06-15 18:47:14 +000097 { LLDB_OPT_SET_1, true, "line", 'l', required_argument, NULL, 0, "<linenum>",
Chris Lattner24943d22010-06-08 16:52:24 +000098 "Set the breakpoint by source location at this particular line."},
99
Chris Lattner24943d22010-06-08 16:52:24 +0000100 // Comment out this option for the moment, as we don't actually use it, but will in the future.
101 // This way users won't see it, but the infrastructure is left in place.
102 // { 0, false, "column", 'c', required_argument, NULL, "<column>",
103 // "Set the breakpoint by source location at this particular column."},
104
Jim Ingham34e9a982010-06-15 18:47:14 +0000105 { LLDB_OPT_SET_2, true, "address", 'a', required_argument, NULL, 0, "<address>",
Chris Lattner24943d22010-06-08 16:52:24 +0000106 "Set the breakpoint by address, at the specified address."},
107
Jim Ingham34e9a982010-06-15 18:47:14 +0000108 { LLDB_OPT_SET_3, true, "name", 'n', required_argument, NULL, CommandCompletions::eSymbolCompletion, "<function-name>",
Chris Lattner24943d22010-06-08 16:52:24 +0000109 "Set the breakpoint by function name." },
110
Jim Ingham34e9a982010-06-15 18:47:14 +0000111 { LLDB_OPT_SET_4, true, "func_regex", 'r', required_argument, NULL, 0, "<regular-expression>",
Chris Lattner24943d22010-06-08 16:52:24 +0000112 "Set the breakpoint by function name, evaluating a regular-expression to find the function name(s)." },
113
Chris Lattner24943d22010-06-08 16:52:24 +0000114 { 0, false, NULL, 0, 0, NULL, 0, NULL, NULL }
115};
116
117const lldb::OptionDefinition*
118CommandObjectBreakpointSet::CommandOptions::GetDefinitions ()
119{
120 return g_option_table;
121}
122
123Error
124CommandObjectBreakpointSet::CommandOptions::SetOptionValue (int option_idx, const char *option_arg)
125{
126 Error error;
127 char short_option = (char) m_getopt_table[option_idx].val;
128
129 switch (short_option)
130 {
131 case 'a':
132 m_load_addr = Args::StringToUInt64(optarg, LLDB_INVALID_ADDRESS, 0);
133 if (m_load_addr == LLDB_INVALID_ADDRESS)
134 m_load_addr = Args::StringToUInt64(optarg, LLDB_INVALID_ADDRESS, 16);
135
136 if (m_load_addr == LLDB_INVALID_ADDRESS)
137 error.SetErrorStringWithFormat ("Invalid address string '%s'.\n", optarg);
138 break;
139
140 case 'c':
141 m_column = Args::StringToUInt32 (option_arg, 0);
142 break;
143 case 'f':
144 m_filename = option_arg;
145 break;
146 case 'i':
147 m_ignore_inlines = true;
148 break;
149 case 'l':
150 m_line_num = Args::StringToUInt32 (option_arg, 0);
151 break;
152 case 'n':
153 m_func_name = option_arg;
154 break;
155 case 'r':
156 m_func_regexp = option_arg;
157 break;
158 case 's':
159 {
160 m_modules.push_back (std::string (option_arg));
161 break;
162 }
Jim Ingham3c7b5b92010-06-16 02:00:15 +0000163 case 'k':
164 {
165 m_ignore_count = Args::StringToSInt32(optarg, -1, 0);
166 if (m_ignore_count == -1)
167 error.SetErrorStringWithFormat ("Invalid ignore count '%s'.\n", optarg);
168 }
Jim Ingham10622a22010-06-18 00:58:52 +0000169 break;
Jim Ingham3c7b5b92010-06-16 02:00:15 +0000170 case 't' :
171 {
172 m_thread_id = Args::StringToUInt64(optarg, LLDB_INVALID_THREAD_ID, 0);
173 if (m_thread_id == LLDB_INVALID_THREAD_ID)
174 error.SetErrorStringWithFormat ("Invalid thread id string '%s'.\n", optarg);
175 }
176 break;
177 case 'T':
178 m_thread_name = option_arg;
179 break;
180 case 'q':
181 m_queue_name = option_arg;
182 break;
183 case 'x':
184 {
185 m_thread_index = Args::StringToUInt64(optarg, -1, 0);
186 if (m_thread_id == -1)
187 error.SetErrorStringWithFormat ("Invalid thread index string '%s'.\n", optarg);
188
189 }
190 break;
Chris Lattner24943d22010-06-08 16:52:24 +0000191 default:
192 error.SetErrorStringWithFormat ("Unrecognized option '%c'.\n", short_option);
193 break;
194 }
195
196 return error;
197}
198
199void
200CommandObjectBreakpointSet::CommandOptions::ResetOptionValues ()
201{
202 Options::ResetOptionValues();
203
204 m_filename.clear();
205 m_line_num = 0;
206 m_column = 0;
207 m_ignore_inlines = false;
208 m_func_name.clear();
209 m_func_regexp.clear();
210 m_load_addr = LLDB_INVALID_ADDRESS;
211 m_modules.clear();
Jim Ingham3c7b5b92010-06-16 02:00:15 +0000212 m_ignore_count = -1;
213 m_thread_id = LLDB_INVALID_THREAD_ID;
214 m_thread_index = -1;
215 m_thread_name.clear();
216 m_queue_name.clear();
Chris Lattner24943d22010-06-08 16:52:24 +0000217}
218
219//-------------------------------------------------------------------------
220// CommandObjectBreakpointSet
221//-------------------------------------------------------------------------
Jim Ingham10622a22010-06-18 00:58:52 +0000222#pragma mark Set
Chris Lattner24943d22010-06-08 16:52:24 +0000223
224CommandObjectBreakpointSet::CommandObjectBreakpointSet () :
225 CommandObject ("breakpoint set", "Sets a breakpoint or set of breakpoints in the executable.",
226 "breakpoint set <cmd-options>")
227{
228}
229
230CommandObjectBreakpointSet::~CommandObjectBreakpointSet ()
231{
232}
233
234Options *
235CommandObjectBreakpointSet::GetOptions ()
236{
237 return &m_options;
238}
239
240bool
241CommandObjectBreakpointSet::Execute
242(
243 Args& command,
244 CommandContext *context,
245 CommandInterpreter *interpreter,
246 CommandReturnObject &result
247)
248{
249 Target *target = context->GetTarget();
250 if (target == NULL)
251 {
252 result.AppendError ("Invalid target, set executable file using 'file' command.");
253 result.SetStatus (eReturnStatusFailed);
254 return false;
255 }
256
257 // The following are the various types of breakpoints that could be set:
258 // 1). -f -l -p [-s -g] (setting breakpoint by source location)
259 // 2). -a [-s -g] (setting breakpoint by address)
260 // 3). -n [-s -g] (setting breakpoint by function name)
261 // 4). -r [-s -g] (setting breakpoint by function name regular expression)
262
263 BreakpointSetType break_type = eSetTypeInvalid;
264
265 if (m_options.m_line_num != 0)
266 break_type = eSetTypeFileAndLine;
267 else if (m_options.m_load_addr != LLDB_INVALID_ADDRESS)
268 break_type = eSetTypeAddress;
269 else if (!m_options.m_func_name.empty())
270 break_type = eSetTypeFunctionName;
271 else if (!m_options.m_func_regexp.empty())
272 break_type = eSetTypeFunctionRegexp;
273
274 ModuleSP module_sp = target->GetExecutableModule();
275 Breakpoint *bp = NULL;
276 FileSpec module;
277 bool use_module = false;
278 int num_modules = m_options.m_modules.size();
279
280 if ((num_modules > 0) && (break_type != eSetTypeAddress))
281 use_module = true;
Jim Ingham3c7b5b92010-06-16 02:00:15 +0000282
Chris Lattner24943d22010-06-08 16:52:24 +0000283 switch (break_type)
284 {
285 case eSetTypeFileAndLine: // Breakpoint by source position
286 {
287 FileSpec file;
288 if (m_options.m_filename.empty())
289 {
290 StackFrame *cur_frame = context->GetExecutionContext().frame;
291 if (cur_frame == NULL)
292 {
293 result.AppendError ("Attempting to set breakpoint by line number alone with no selected frame.");
294 result.SetStatus (eReturnStatusFailed);
295 break;
296 }
297 else if (!cur_frame->HasDebugInformation())
298 {
299 result.AppendError ("Attempting to set breakpoint by line number alone but selected frame has no debug info.");
300 result.SetStatus (eReturnStatusFailed);
301 break;
302 }
303 else
304 {
305 const SymbolContext &context = cur_frame->GetSymbolContext(true);
306 if (context.line_entry.file)
307 {
308 file = context.line_entry.file;
309 }
310 else if (context.comp_unit != NULL)
311 { file = context.comp_unit;
312 }
313 else
314 {
315 result.AppendError ("Attempting to set breakpoint by line number alone but can't find the file for the selected frame.");
316 result.SetStatus (eReturnStatusFailed);
317 break;
318 }
319 }
320 }
321 else
322 {
323 file.SetFile(m_options.m_filename.c_str());
324 }
325
326 if (use_module)
327 {
328 for (int i = 0; i < num_modules; ++i)
329 {
330 module.SetFile(m_options.m_modules[i].c_str());
331 bp = target->CreateBreakpoint (&module,
332 file,
333 m_options.m_line_num,
334 m_options.m_ignore_inlines).get();
335 if (bp)
336 {
337 StreamString &output_stream = result.GetOutputStream();
338 output_stream.Printf ("Breakpoint created: ");
339 bp->GetDescription(&output_stream, lldb::eDescriptionLevelBrief);
340 output_stream.EOL();
341 result.SetStatus (eReturnStatusSuccessFinishResult);
342 }
343 else
344 {
345 result.AppendErrorWithFormat("Breakpoint creation failed: No breakpoint created in module '%s'.\n",
346 m_options.m_modules[i].c_str());
347 result.SetStatus (eReturnStatusFailed);
348 }
349 }
350 }
351 else
352 bp = target->CreateBreakpoint (NULL,
353 file,
354 m_options.m_line_num,
355 m_options.m_ignore_inlines).get();
356 }
357 break;
358 case eSetTypeAddress: // Breakpoint by address
359 bp = target->CreateBreakpoint (m_options.m_load_addr, false).get();
360 break;
361 case eSetTypeFunctionName: // Breakpoint by function name
362 if (use_module)
363 {
364 for (int i = 0; i < num_modules; ++i)
365 {
366 module.SetFile(m_options.m_modules[i].c_str());
367 bp = target->CreateBreakpoint (&module, m_options.m_func_name.c_str()).get();
368 if (bp)
369 {
370 StreamString &output_stream = result.GetOutputStream();
371 output_stream.Printf ("Breakpoint created: ");
372 bp->GetDescription(&output_stream, lldb::eDescriptionLevelBrief);
373 output_stream.EOL();
374 result.SetStatus (eReturnStatusSuccessFinishResult);
375 }
376 else
377 {
378 result.AppendErrorWithFormat("Breakpoint creation failed: No breakpoint created in module '%s'.\n",
379 m_options.m_modules[i].c_str());
380 result.SetStatus (eReturnStatusFailed);
381 }
382 }
383 }
384 else
385 bp = target->CreateBreakpoint (NULL, m_options.m_func_name.c_str()).get();
386 break;
387 case eSetTypeFunctionRegexp: // Breakpoint by regular expression function name
388 {
389 RegularExpression regexp(m_options.m_func_regexp.c_str());
390 if (use_module)
391 {
392 for (int i = 0; i < num_modules; ++i)
393 {
394 module.SetFile(m_options.m_modules[i].c_str());
395 bp = target->CreateBreakpoint (&module, regexp).get();
396 if (bp)
397 {
398 StreamString &output_stream = result.GetOutputStream();
399 output_stream.Printf ("Breakpoint created: ");
400 bp->GetDescription(&output_stream, lldb::eDescriptionLevelBrief);
401 output_stream.EOL();
402 result.SetStatus (eReturnStatusSuccessFinishResult);
403 }
404 else
405 {
406 result.AppendErrorWithFormat("Breakpoint creation failed: No breakpoint created in module '%s'.\n",
407 m_options.m_modules[i].c_str());
408 result.SetStatus (eReturnStatusFailed);
409 }
410 }
411 }
412 else
413 bp = target->CreateBreakpoint (NULL, regexp).get();
414 }
415 break;
416 default:
417 break;
418 }
419
Jim Ingham3c7b5b92010-06-16 02:00:15 +0000420 // Now set the various options that were passed in:
421 if (bp)
422 {
423 if (m_options.m_thread_id != LLDB_INVALID_THREAD_ID)
424 bp->SetThreadID (m_options.m_thread_id);
425
426 if (m_options.m_thread_index != -1)
427 bp->GetOptions()->GetThreadSpec()->SetIndex(m_options.m_thread_index);
428
429 if (!m_options.m_thread_name.empty())
430 bp->GetOptions()->GetThreadSpec()->SetName(m_options.m_thread_name.c_str());
431
432 if (!m_options.m_queue_name.empty())
433 bp->GetOptions()->GetThreadSpec()->SetQueueName(m_options.m_queue_name.c_str());
434
435 if (m_options.m_ignore_count != -1)
436 bp->GetOptions()->SetIgnoreCount(m_options.m_ignore_count);
437 }
438
Chris Lattner24943d22010-06-08 16:52:24 +0000439 if (bp && !use_module)
440 {
441 StreamString &output_stream = result.GetOutputStream();
442 output_stream.Printf ("Breakpoint created: ");
443 bp->GetDescription(&output_stream, lldb::eDescriptionLevelBrief);
444 output_stream.EOL();
445 result.SetStatus (eReturnStatusSuccessFinishResult);
446 }
447 else if (!bp)
448 {
449 result.AppendError ("Breakpoint creation failed: No breakpoint created.");
450 result.SetStatus (eReturnStatusFailed);
451 }
452
453 return result.Succeeded();
454}
455
Chris Lattner24943d22010-06-08 16:52:24 +0000456//-------------------------------------------------------------------------
457// CommandObjectMultiwordBreakpoint
458//-------------------------------------------------------------------------
Jim Ingham10622a22010-06-18 00:58:52 +0000459#pragma mark MultiwordBreakpoint
Chris Lattner24943d22010-06-08 16:52:24 +0000460
461CommandObjectMultiwordBreakpoint::CommandObjectMultiwordBreakpoint (CommandInterpreter *interpreter) :
462 CommandObjectMultiword ("breakpoint",
463 "A set of commands for operating on breakpoints.",
464 "breakpoint <command> [<command-options>]")
465{
466 bool status;
467
468 CommandObjectSP list_command_object (new CommandObjectBreakpointList ());
469 CommandObjectSP delete_command_object (new CommandObjectBreakpointDelete ());
470 CommandObjectSP enable_command_object (new CommandObjectBreakpointEnable ());
471 CommandObjectSP disable_command_object (new CommandObjectBreakpointDisable ());
472 CommandObjectSP set_command_object (new CommandObjectBreakpointSet ());
473 CommandObjectSP command_command_object (new CommandObjectBreakpointCommand (interpreter));
Jim Ingham10622a22010-06-18 00:58:52 +0000474 CommandObjectSP modify_command_object (new CommandObjectBreakpointModify());
Chris Lattner24943d22010-06-08 16:52:24 +0000475
Jim Ingham10622a22010-06-18 00:58:52 +0000476 command_command_object->SetCommandName ("breakpoint command");
Chris Lattner24943d22010-06-08 16:52:24 +0000477 enable_command_object->SetCommandName("breakpoint enable");
478 disable_command_object->SetCommandName("breakpoint disable");
Chris Lattner24943d22010-06-08 16:52:24 +0000479 list_command_object->SetCommandName ("breakpoint list");
Jim Ingham10622a22010-06-18 00:58:52 +0000480 modify_command_object->SetCommandName ("breakpoint modify");
481 set_command_object->SetCommandName("breakpoint set");
Chris Lattner24943d22010-06-08 16:52:24 +0000482
483 status = LoadSubCommand (list_command_object, "list", interpreter);
484 status = LoadSubCommand (enable_command_object, "enable", interpreter);
485 status = LoadSubCommand (disable_command_object, "disable", interpreter);
486 status = LoadSubCommand (delete_command_object, "delete", interpreter);
487 status = LoadSubCommand (set_command_object, "set", interpreter);
488 status = LoadSubCommand (command_command_object, "command", interpreter);
Jim Ingham10622a22010-06-18 00:58:52 +0000489 status = LoadSubCommand (modify_command_object, "modify", interpreter);
Chris Lattner24943d22010-06-08 16:52:24 +0000490}
491
492CommandObjectMultiwordBreakpoint::~CommandObjectMultiwordBreakpoint ()
493{
494}
495
496void
497CommandObjectMultiwordBreakpoint::VerifyBreakpointIDs (Args &args, Target *target, CommandReturnObject &result,
498 BreakpointIDList *valid_ids)
499{
500 // args can be strings representing 1). integers (for breakpoint ids)
501 // 2). the full breakpoint & location canonical representation
502 // 3). the word "to" or a hyphen, representing a range (in which case there
503 // had *better* be an entry both before & after of one of the first two types.
504
505 Args temp_args;
506
507 // Create a new Args variable to use; copy any non-breakpoint-id-ranges stuff directly from the old ARGS to
508 // the new TEMP_ARGS. Do not copy breakpoint id range strings over; instead generate a list of strings for
509 // all the breakpoint ids in the range, and shove all of those breakpoint id strings into TEMP_ARGS.
510
511 BreakpointIDList::FindAndReplaceIDRanges (args, target, result, temp_args);
512
513 // NOW, convert the list of breakpoint id strings in TEMP_ARGS into an actual BreakpointIDList:
514
515 valid_ids->InsertStringArray ((const char **) temp_args.GetArgumentVector(), temp_args.GetArgumentCount(), result);
516
517 // At this point, all of the breakpoint ids that the user passed in have been converted to breakpoint IDs
518 // and put into valid_ids.
519
520 if (result.Succeeded())
521 {
522 // Now that we've converted everything from args into a list of breakpoint ids, go through our tentative list
523 // of breakpoint id's and verify that they correspond to valid/currently set breakpoints.
524
525 for (int i = 0; i < valid_ids->Size(); ++i)
526 {
527 BreakpointID cur_bp_id = valid_ids->GetBreakpointIDAtIndex (i);
528 Breakpoint *breakpoint = target->GetBreakpointByID (cur_bp_id.GetBreakpointID()).get();
529 if (breakpoint != NULL)
530 {
531 int num_locations = breakpoint->GetNumLocations();
532 if (cur_bp_id.GetLocationID() > num_locations)
533 {
534 StreamString id_str;
535 BreakpointID::GetCanonicalReference (&id_str, cur_bp_id.GetBreakpointID(),
536 cur_bp_id.GetLocationID());
537 i = valid_ids->Size() + 1;
538 result.AppendErrorWithFormat ("'%s' is not a currently valid breakpoint/location id.\n",
539 id_str.GetData());
540 result.SetStatus (eReturnStatusFailed);
541 }
542 }
543 else
544 {
545 i = valid_ids->Size() + 1;
546 result.AppendErrorWithFormat ("'%d' is not a currently valid breakpoint id.\n", cur_bp_id.GetBreakpointID());
547 result.SetStatus (eReturnStatusFailed);
548 }
549 }
550 }
551}
552
553//-------------------------------------------------------------------------
554// CommandObjectBreakpointList::Options
555//-------------------------------------------------------------------------
Jim Ingham10622a22010-06-18 00:58:52 +0000556#pragma mark List::CommandOptions
Chris Lattner24943d22010-06-08 16:52:24 +0000557
558CommandObjectBreakpointList::CommandOptions::CommandOptions() :
559 Options (),
560 m_level (lldb::eDescriptionLevelFull) // Breakpoint List defaults to brief descriptions
561{
Chris Lattner24943d22010-06-08 16:52:24 +0000562}
563
564CommandObjectBreakpointList::CommandOptions::~CommandOptions ()
565{
566}
567
568lldb::OptionDefinition
569CommandObjectBreakpointList::CommandOptions::g_option_table[] =
570{
Jim Ingham34e9a982010-06-15 18:47:14 +0000571 { LLDB_OPT_SET_ALL, false, "internal", 'i', no_argument, NULL, 0, NULL,
572 "Show debugger internal breakpoints" },
573
574 { LLDB_OPT_SET_1, false, "brief", 'b', no_argument, NULL, 0, NULL,
Chris Lattner24943d22010-06-08 16:52:24 +0000575 "Give a brief description of the breakpoint (no location info)."},
576
577 // FIXME: We need to add an "internal" command, and then add this sort of thing to it.
578 // But I need to see it for now, and don't want to wait.
Jim Ingham34e9a982010-06-15 18:47:14 +0000579 { LLDB_OPT_SET_2, false, "full", 'f', no_argument, NULL, 0, NULL,
Chris Lattner24943d22010-06-08 16:52:24 +0000580 "Give a full description of the breakpoint and its locations."},
Chris Lattner24943d22010-06-08 16:52:24 +0000581
Jim Ingham34e9a982010-06-15 18:47:14 +0000582 { LLDB_OPT_SET_3, false, "verbose", 'v', no_argument, NULL, 0, NULL,
Chris Lattner24943d22010-06-08 16:52:24 +0000583 "Explain everything we know about the breakpoint (for debugging debugger bugs)." },
Chris Lattner24943d22010-06-08 16:52:24 +0000584
585 { 0, false, NULL, 0, 0, NULL, 0, NULL, NULL }
586};
587
588const lldb::OptionDefinition*
589CommandObjectBreakpointList::CommandOptions::GetDefinitions ()
590{
591 return g_option_table;
592}
593
594Error
595CommandObjectBreakpointList::CommandOptions::SetOptionValue (int option_idx, const char *option_arg)
596{
597 Error error;
598 char short_option = (char) m_getopt_table[option_idx].val;
599
600 switch (short_option)
601 {
602 case 'b':
603 m_level = lldb::eDescriptionLevelBrief;
604 break;
605 case 'f':
606 m_level = lldb::eDescriptionLevelFull;
607 break;
608 case 'v':
609 m_level = lldb::eDescriptionLevelVerbose;
610 break;
611 case 'i':
612 m_internal = true;
613 break;
614 default:
615 error.SetErrorStringWithFormat ("Unrecognized option '%c'.\n", short_option);
616 break;
617 }
618
619 return error;
620}
621
622void
623CommandObjectBreakpointList::CommandOptions::ResetOptionValues ()
624{
625 Options::ResetOptionValues();
626
627 m_level = lldb::eDescriptionLevelFull;
628 m_internal = false;
629}
630
631//-------------------------------------------------------------------------
632// CommandObjectBreakpointList
633//-------------------------------------------------------------------------
Jim Ingham10622a22010-06-18 00:58:52 +0000634#pragma mark List
Chris Lattner24943d22010-06-08 16:52:24 +0000635
636CommandObjectBreakpointList::CommandObjectBreakpointList () :
637 CommandObject ("breakpoint list",
638 "List some or all breakpoints at configurable levels of detail.",
639 "breakpoint list [<breakpoint-id>]")
640{
641}
642
643CommandObjectBreakpointList::~CommandObjectBreakpointList ()
644{
645}
646
647Options *
648CommandObjectBreakpointList::GetOptions ()
649{
650 return &m_options;
651}
652
653bool
654CommandObjectBreakpointList::Execute
655(
656 Args& args,
657 CommandContext *context,
658 CommandInterpreter *interpreter,
659 CommandReturnObject &result
660)
661{
662 Target *target = context->GetTarget();
663 if (target == NULL)
664 {
665 result.AppendError ("Invalid target, set executable file using 'file' command.");
666 result.SetStatus (eReturnStatusSuccessFinishNoResult);
667 return true;
668 }
669
670 const BreakpointList &breakpoints = target->GetBreakpointList(m_options.m_internal);
Jim Ingham3c7b5b92010-06-16 02:00:15 +0000671 Mutex::Locker locker;
672 target->GetBreakpointList(m_options.m_internal).GetListMutex(locker);
673
Chris Lattner24943d22010-06-08 16:52:24 +0000674 size_t num_breakpoints = breakpoints.GetSize();
675
676 if (num_breakpoints == 0)
677 {
678 result.AppendMessage ("No breakpoints currently set.");
679 result.SetStatus (eReturnStatusSuccessFinishNoResult);
680 return true;
681 }
682
683 StreamString &output_stream = result.GetOutputStream();
684
685 if (args.GetArgumentCount() == 0)
686 {
687 // No breakpoint selected; show info about all currently set breakpoints.
688 result.AppendMessage ("Current breakpoints:");
689 for (int i = 0; i < num_breakpoints; ++i)
690 {
691 Breakpoint *breakpoint = breakpoints.GetBreakpointByIndex (i).get();
692 AddBreakpointDescription (context, &output_stream, breakpoint, m_options.m_level);
693 }
694 result.SetStatus (eReturnStatusSuccessFinishNoResult);
695 }
696 else
697 {
698 // Particular breakpoints selected; show info about that breakpoint.
699 BreakpointIDList valid_bp_ids;
700 CommandObjectMultiwordBreakpoint::VerifyBreakpointIDs (args, target, result, &valid_bp_ids);
701
702 if (result.Succeeded())
703 {
704 for (int i = 0; i < valid_bp_ids.Size(); ++i)
705 {
706 BreakpointID cur_bp_id = valid_bp_ids.GetBreakpointIDAtIndex (i);
707 Breakpoint *breakpoint = target->GetBreakpointByID (cur_bp_id.GetBreakpointID()).get();
708 AddBreakpointDescription (context, &output_stream, breakpoint, m_options.m_level);
709 }
710 result.SetStatus (eReturnStatusSuccessFinishNoResult);
711 }
712 else
713 {
714 result.AppendError ("Invalid breakpoint id.");
715 result.SetStatus (eReturnStatusFailed);
716 }
717 }
718
719 return result.Succeeded();
720}
721
722//-------------------------------------------------------------------------
723// CommandObjectBreakpointEnable
724//-------------------------------------------------------------------------
Jim Ingham10622a22010-06-18 00:58:52 +0000725#pragma mark Enable
Chris Lattner24943d22010-06-08 16:52:24 +0000726
727CommandObjectBreakpointEnable::CommandObjectBreakpointEnable () :
728 CommandObject ("enable",
729 "Enables the specified disabled breakpoint(s). If no breakpoints are specified, enables all of them.",
730 "breakpoint enable [<breakpoint-id> | <breakpoint-id-list>]")
731{
732 // This command object can either be called via 'enable' or 'breakpoint enable'. Because it has two different
733 // potential invocation methods, we need to be a little tricky about generating the syntax string.
734 //StreamString tmp_string;
735 //tmp_string.Printf ("%s <breakpoint-id>", GetCommandName());
736 //m_cmd_syntax.assign (tmp_string.GetData(), tmp_string.GetSize());
737}
738
739
740CommandObjectBreakpointEnable::~CommandObjectBreakpointEnable ()
741{
742}
743
744
745bool
746CommandObjectBreakpointEnable::Execute (Args& args, CommandContext *context,
747 CommandInterpreter *interpreter, CommandReturnObject &result)
748{
749 Target *target = context->GetTarget();
750 if (target == NULL)
751 {
752 result.AppendError ("Invalid target, set executable file using 'file' command.");
753 result.SetStatus (eReturnStatusFailed);
754 return false;
755 }
756
Jim Ingham3c7b5b92010-06-16 02:00:15 +0000757 Mutex::Locker locker;
758 target->GetBreakpointList().GetListMutex(locker);
759
Chris Lattner24943d22010-06-08 16:52:24 +0000760 const BreakpointList &breakpoints = target->GetBreakpointList();
Jim Ingham3c7b5b92010-06-16 02:00:15 +0000761
Chris Lattner24943d22010-06-08 16:52:24 +0000762 size_t num_breakpoints = breakpoints.GetSize();
763
764 if (num_breakpoints == 0)
765 {
766 result.AppendError ("No breakpoints exist to be enabled.");
767 result.SetStatus (eReturnStatusFailed);
768 return false;
769 }
770
771 if (args.GetArgumentCount() == 0)
772 {
773 // No breakpoint selected; enable all currently set breakpoints.
774 target->EnableAllBreakpoints ();
775 result.AppendMessageWithFormat ("All breakpoints enabled. (%d breakpoints)\n", num_breakpoints);
776 result.SetStatus (eReturnStatusSuccessFinishNoResult);
777 }
778 else
779 {
780 // Particular breakpoint selected; enable that breakpoint.
781 BreakpointIDList valid_bp_ids;
782 CommandObjectMultiwordBreakpoint::VerifyBreakpointIDs (args, target, result, &valid_bp_ids);
783
784 if (result.Succeeded())
785 {
786 int enable_count = 0;
787 int loc_count = 0;
788 for (int i = 0; i < valid_bp_ids.Size(); ++i)
789 {
790 BreakpointID cur_bp_id = valid_bp_ids.GetBreakpointIDAtIndex (i);
791
792 if (cur_bp_id.GetBreakpointID() != LLDB_INVALID_BREAK_ID)
793 {
794 Breakpoint *breakpoint = target->GetBreakpointByID (cur_bp_id.GetBreakpointID()).get();
795 if (cur_bp_id.GetLocationID() != LLDB_INVALID_BREAK_ID)
796 {
797 BreakpointLocation *location = breakpoint->FindLocationByID (cur_bp_id.GetLocationID()).get();
798 if (location)
799 {
800 location->SetEnabled (true);
Chris Lattner24943d22010-06-08 16:52:24 +0000801 ++loc_count;
802 }
803 }
804 else
805 {
Jim Ingham10622a22010-06-18 00:58:52 +0000806 breakpoint->SetEnabled (true);
Chris Lattner24943d22010-06-08 16:52:24 +0000807 ++enable_count;
Chris Lattner24943d22010-06-08 16:52:24 +0000808 }
809 }
810 }
811 result.AppendMessageWithFormat ("%d breakpoints enabled.\n", enable_count + loc_count);
812 result.SetStatus (eReturnStatusSuccessFinishNoResult);
813 }
814 }
815
816 return result.Succeeded();
817}
818
819//-------------------------------------------------------------------------
820// CommandObjectBreakpointDisable
821//-------------------------------------------------------------------------
Jim Ingham10622a22010-06-18 00:58:52 +0000822#pragma mark Disable
Chris Lattner24943d22010-06-08 16:52:24 +0000823
824CommandObjectBreakpointDisable::CommandObjectBreakpointDisable () :
825 CommandObject ("disable",
826 "Disables the specified breakpoint(s) without removing it/them. If no breakpoints are specified, disables them all.",
827 "disable [<breakpoint-id> | <breakpoint-id-list>]")
828{
829 // This command object can either be called via 'enable' or 'breakpoint enable'. Because it has two different
830 // potential invocation methods, we need to be a little tricky about generating the syntax string.
831 //StreamString tmp_string;
832 //tmp_string.Printf ("%s <breakpoint-id>", GetCommandName());
833 //m_cmd_syntax.assign(tmp_string.GetData(), tmp_string.GetSize());
834}
835
836CommandObjectBreakpointDisable::~CommandObjectBreakpointDisable ()
837{
838}
839
840bool
841CommandObjectBreakpointDisable::Execute (Args& args, CommandContext *context,
842 CommandInterpreter *interpreter, CommandReturnObject &result)
843{
844 Target *target = context->GetTarget();
845 if (target == NULL)
846 {
847 result.AppendError ("Invalid target, set executable file using 'file' command.");
848 result.SetStatus (eReturnStatusFailed);
849 return false;
850 }
851
Jim Ingham3c7b5b92010-06-16 02:00:15 +0000852 Mutex::Locker locker;
853 target->GetBreakpointList().GetListMutex(locker);
854
Chris Lattner24943d22010-06-08 16:52:24 +0000855 const BreakpointList &breakpoints = target->GetBreakpointList();
856 size_t num_breakpoints = breakpoints.GetSize();
857
858 if (num_breakpoints == 0)
859 {
860 result.AppendError ("No breakpoints exist to be disabled.");
861 result.SetStatus (eReturnStatusFailed);
862 return false;
863 }
864
865 if (args.GetArgumentCount() == 0)
866 {
867 // No breakpoint selected; disable all currently set breakpoints.
868 target->DisableAllBreakpoints ();
869 result.AppendMessageWithFormat ("All breakpoints disabled. (%d breakpoints)\n", num_breakpoints);
870 result.SetStatus (eReturnStatusSuccessFinishNoResult);
871 }
872 else
873 {
874 // Particular breakpoint selected; disable that breakpoint.
875 BreakpointIDList valid_bp_ids;
876
877 CommandObjectMultiwordBreakpoint::VerifyBreakpointIDs (args, target, result, &valid_bp_ids);
878
879 if (result.Succeeded())
880 {
881 int disable_count = 0;
882 int loc_count = 0;
883 for (int i = 0; i < valid_bp_ids.Size(); ++i)
884 {
885 BreakpointID cur_bp_id = valid_bp_ids.GetBreakpointIDAtIndex (i);
886
887 if (cur_bp_id.GetBreakpointID() != LLDB_INVALID_BREAK_ID)
888 {
889 Breakpoint *breakpoint = target->GetBreakpointByID (cur_bp_id.GetBreakpointID()).get();
890 if (cur_bp_id.GetLocationID() != LLDB_INVALID_BREAK_ID)
891 {
892 BreakpointLocation *location = breakpoint->FindLocationByID (cur_bp_id.GetLocationID()).get();
893 if (location)
894 {
895 location->SetEnabled (false);
896 ++loc_count;
897 }
898 }
899 else
900 {
Jim Ingham10622a22010-06-18 00:58:52 +0000901 breakpoint->SetEnabled (false);
Chris Lattner24943d22010-06-08 16:52:24 +0000902 ++disable_count;
Chris Lattner24943d22010-06-08 16:52:24 +0000903 }
904 }
905 }
906 result.AppendMessageWithFormat ("%d breakpoints disabled.\n", disable_count + loc_count);
907 result.SetStatus (eReturnStatusSuccessFinishNoResult);
908 }
909 }
910
911 return result.Succeeded();
912}
913
914//-------------------------------------------------------------------------
915// CommandObjectBreakpointDelete
916//-------------------------------------------------------------------------
Jim Ingham10622a22010-06-18 00:58:52 +0000917#pragma mark Delete
Chris Lattner24943d22010-06-08 16:52:24 +0000918
919CommandObjectBreakpointDelete::CommandObjectBreakpointDelete() :
920 CommandObject ("breakpoint delete",
921 "Delete the specified breakpoint(s). If no breakpoints are specified, deletes them all.",
922 "breakpoint delete [<breakpoint-id> | <breakpoint-id-list>]")
923{
924}
925
926
927CommandObjectBreakpointDelete::~CommandObjectBreakpointDelete ()
928{
929}
930
931bool
932CommandObjectBreakpointDelete::Execute (Args& args, CommandContext *context,
933 CommandInterpreter *interpreter, CommandReturnObject &result)
934{
935 Target *target = context->GetTarget();
936 if (target == NULL)
937 {
938 result.AppendError ("Invalid target, set executable file using 'file' command.");
939 result.SetStatus (eReturnStatusFailed);
940 return false;
941 }
942
Jim Ingham3c7b5b92010-06-16 02:00:15 +0000943 Mutex::Locker locker;
944 target->GetBreakpointList().GetListMutex(locker);
945
Chris Lattner24943d22010-06-08 16:52:24 +0000946 const BreakpointList &breakpoints = target->GetBreakpointList();
Jim Ingham3c7b5b92010-06-16 02:00:15 +0000947
Chris Lattner24943d22010-06-08 16:52:24 +0000948 size_t num_breakpoints = breakpoints.GetSize();
949
950 if (num_breakpoints == 0)
951 {
952 result.AppendError ("No breakpoints exist to be deleted.");
953 result.SetStatus (eReturnStatusFailed);
954 return false;
955 }
956
957 if (args.GetArgumentCount() == 0)
958 {
959 // No breakpoint selected; disable all currently set breakpoints.
960 if (args.GetArgumentCount() != 0)
961 {
962 result.AppendErrorWithFormat ("Specify breakpoints to delete with the -i option.\n");
963 result.SetStatus (eReturnStatusFailed);
964 return false;
965 }
966
967 target->RemoveAllBreakpoints ();
968 result.AppendMessageWithFormat ("All breakpoints removed. (%d breakpoints)\n", num_breakpoints);
969 result.SetStatus (eReturnStatusSuccessFinishNoResult);
970 }
971 else
972 {
973 // Particular breakpoint selected; disable that breakpoint.
974 BreakpointIDList valid_bp_ids;
975 CommandObjectMultiwordBreakpoint::VerifyBreakpointIDs (args, target, result, &valid_bp_ids);
976
977 if (result.Succeeded())
978 {
979 int delete_count = 0;
980 int disable_count = 0;
981 for (int i = 0; i < valid_bp_ids.Size(); ++i)
982 {
983 BreakpointID cur_bp_id = valid_bp_ids.GetBreakpointIDAtIndex (i);
984
985 if (cur_bp_id.GetBreakpointID() != LLDB_INVALID_BREAK_ID)
986 {
987 if (cur_bp_id.GetLocationID() != LLDB_INVALID_BREAK_ID)
988 {
989 Breakpoint *breakpoint = target->GetBreakpointByID (cur_bp_id.GetBreakpointID()).get();
990 BreakpointLocation *location = breakpoint->FindLocationByID (cur_bp_id.GetLocationID()).get();
991 // It makes no sense to try to delete individual locations, so we disable them instead.
992 if (location)
993 {
994 location->SetEnabled (false);
995 ++disable_count;
996 }
997 }
998 else
999 {
1000 target->RemoveBreakpointByID (cur_bp_id.GetBreakpointID());
1001 ++delete_count;
1002 }
1003 }
1004 }
1005 result.AppendMessageWithFormat ("%d breakpoints deleted; %d breakpoint locations disabled.\n",
1006 delete_count, disable_count);
1007 result.SetStatus (eReturnStatusSuccessFinishNoResult);
1008 }
1009 }
1010 return result.Succeeded();
1011}
Jim Ingham3c7b5b92010-06-16 02:00:15 +00001012
1013//-------------------------------------------------------------------------
Jim Ingham10622a22010-06-18 00:58:52 +00001014// CommandObjectBreakpointModify::CommandOptions
Jim Ingham3c7b5b92010-06-16 02:00:15 +00001015//-------------------------------------------------------------------------
Jim Ingham10622a22010-06-18 00:58:52 +00001016#pragma mark Modify::CommandOptions
Jim Ingham3c7b5b92010-06-16 02:00:15 +00001017
Jim Ingham10622a22010-06-18 00:58:52 +00001018CommandObjectBreakpointModify::CommandOptions::CommandOptions() :
Jim Ingham3c7b5b92010-06-16 02:00:15 +00001019 Options (),
1020 m_thread_id(LLDB_INVALID_THREAD_ID),
1021 m_thread_index (-1),
1022 m_thread_name(),
1023 m_queue_name(),
Jim Ingham10622a22010-06-18 00:58:52 +00001024 m_ignore_count (-1),
1025 m_enable_passed (false)
Jim Ingham3c7b5b92010-06-16 02:00:15 +00001026{
1027}
1028
Jim Ingham10622a22010-06-18 00:58:52 +00001029CommandObjectBreakpointModify::CommandOptions::~CommandOptions ()
Jim Ingham3c7b5b92010-06-16 02:00:15 +00001030{
1031}
1032
1033lldb::OptionDefinition
Jim Ingham10622a22010-06-18 00:58:52 +00001034CommandObjectBreakpointModify::CommandOptions::g_option_table[] =
Jim Ingham3c7b5b92010-06-16 02:00:15 +00001035{
1036 { LLDB_OPT_SET_ALL, false, "ignore_count", 'k', required_argument, NULL, 0, NULL,
1037 "Set the number of times this breakpoint is sKipped before stopping." },
1038
1039 { LLDB_OPT_SET_ALL, false, "thread_index", 'x', required_argument, NULL, NULL, "<thread_index>",
1040 "The breakpoint stops only for the thread whose indeX matches this argument."},
1041
1042 { LLDB_OPT_SET_ALL, false, "thread_id", 't', required_argument, NULL, NULL, "<thread_id>",
1043 "The breakpoint stops only for the thread whose TID matches this argument."},
1044
1045 { LLDB_OPT_SET_ALL, false, "thread_name", 'T', required_argument, NULL, NULL, "<thread_name>",
1046 "The breakpoint stops only for the thread whose thread name matches this argument."},
1047
1048 { LLDB_OPT_SET_ALL, false, "queue_name", 'q', required_argument, NULL, NULL, "<queue_name>",
1049 "The breakpoint stops only for threads in the queue whose name is given by this argument."},
1050
Jim Ingham10622a22010-06-18 00:58:52 +00001051 { LLDB_OPT_SET_1, false, "enable", 'e', no_argument, NULL, NULL, NULL,
1052 "Enable the breakpoint."},
1053
1054 { LLDB_OPT_SET_2, false, "disable", 'd', no_argument, NULL, NULL, NULL,
1055 "Disable the breakpoint."},
1056
1057
Jim Ingham3c7b5b92010-06-16 02:00:15 +00001058 { 0, false, NULL, 0, 0, NULL, 0, NULL, NULL }
1059};
1060
1061const lldb::OptionDefinition*
Jim Ingham10622a22010-06-18 00:58:52 +00001062CommandObjectBreakpointModify::CommandOptions::GetDefinitions ()
Jim Ingham3c7b5b92010-06-16 02:00:15 +00001063{
1064 return g_option_table;
1065}
1066
1067Error
Jim Ingham10622a22010-06-18 00:58:52 +00001068CommandObjectBreakpointModify::CommandOptions::SetOptionValue (int option_idx, const char *option_arg)
Jim Ingham3c7b5b92010-06-16 02:00:15 +00001069{
1070 Error error;
1071 char short_option = (char) m_getopt_table[option_idx].val;
1072
1073 switch (short_option)
1074 {
Jim Ingham10622a22010-06-18 00:58:52 +00001075 case 'd':
1076 m_enable_passed = true;
1077 m_enable_value = false;
1078 break;
1079 case 'e':
1080 m_enable_passed = true;
1081 m_enable_value = true;
1082 break;
Jim Ingham3c7b5b92010-06-16 02:00:15 +00001083 case 'k':
1084 {
1085 m_ignore_count = Args::StringToSInt32(optarg, -1, 0);
1086 if (m_ignore_count == -1)
1087 error.SetErrorStringWithFormat ("Invalid ignore count '%s'.\n", optarg);
1088 }
Jim Ingham10622a22010-06-18 00:58:52 +00001089 break;
Jim Ingham3c7b5b92010-06-16 02:00:15 +00001090 case 't' :
1091 {
1092 m_thread_id = Args::StringToUInt64(optarg, LLDB_INVALID_THREAD_ID, 0);
1093 if (m_thread_id == LLDB_INVALID_THREAD_ID)
1094 error.SetErrorStringWithFormat ("Invalid thread id string '%s'.\n", optarg);
1095 }
1096 break;
1097 case 'T':
1098 m_thread_name = option_arg;
1099 break;
1100 case 'q':
1101 m_queue_name = option_arg;
1102 break;
1103 case 'x':
1104 {
1105 m_thread_index = Args::StringToUInt64(optarg, -1, 0);
1106 if (m_thread_id == -1)
1107 error.SetErrorStringWithFormat ("Invalid thread index string '%s'.\n", optarg);
1108
1109 }
1110 break;
1111 default:
1112 error.SetErrorStringWithFormat ("Unrecognized option '%c'.\n", short_option);
1113 break;
1114 }
1115
1116 return error;
1117}
1118
1119void
Jim Ingham10622a22010-06-18 00:58:52 +00001120CommandObjectBreakpointModify::CommandOptions::ResetOptionValues ()
Jim Ingham3c7b5b92010-06-16 02:00:15 +00001121{
1122 Options::ResetOptionValues();
1123
1124 m_ignore_count = -1;
1125 m_thread_id = LLDB_INVALID_THREAD_ID;
1126 m_thread_index = -1;
1127 m_thread_name.clear();
1128 m_queue_name.clear();
Jim Ingham10622a22010-06-18 00:58:52 +00001129 m_enable_passed = false;
Jim Ingham3c7b5b92010-06-16 02:00:15 +00001130}
1131
1132//-------------------------------------------------------------------------
Jim Ingham10622a22010-06-18 00:58:52 +00001133// CommandObjectBreakpointModify
Jim Ingham3c7b5b92010-06-16 02:00:15 +00001134//-------------------------------------------------------------------------
Jim Ingham10622a22010-06-18 00:58:52 +00001135#pragma mark Modify
Jim Ingham3c7b5b92010-06-16 02:00:15 +00001136
Jim Ingham10622a22010-06-18 00:58:52 +00001137CommandObjectBreakpointModify::CommandObjectBreakpointModify () :
1138 CommandObject ("breakpoint modify", "Modifys the options on a breakpoint or set of breakpoints in the executable.",
1139 "breakpoint modify <cmd-options> break-id [break-id ...]")
Jim Ingham3c7b5b92010-06-16 02:00:15 +00001140{
1141}
1142
Jim Ingham10622a22010-06-18 00:58:52 +00001143CommandObjectBreakpointModify::~CommandObjectBreakpointModify ()
Jim Ingham3c7b5b92010-06-16 02:00:15 +00001144{
1145}
1146
1147Options *
Jim Ingham10622a22010-06-18 00:58:52 +00001148CommandObjectBreakpointModify::GetOptions ()
Jim Ingham3c7b5b92010-06-16 02:00:15 +00001149{
1150 return &m_options;
1151}
1152
1153bool
Jim Ingham10622a22010-06-18 00:58:52 +00001154CommandObjectBreakpointModify::Execute
Jim Ingham3c7b5b92010-06-16 02:00:15 +00001155(
1156 Args& command,
1157 CommandContext *context,
1158 CommandInterpreter *interpreter,
1159 CommandReturnObject &result
1160)
1161{
1162 if (command.GetArgumentCount() == 0)
1163 {
1164 result.AppendError ("No breakpoints specified.");
1165 result.SetStatus (eReturnStatusFailed);
1166 return false;
1167 }
1168
1169 Target *target = context->GetTarget();
1170 if (target == NULL)
1171 {
1172 result.AppendError ("Invalid target, set executable file using 'file' command.");
1173 result.SetStatus (eReturnStatusFailed);
1174 return false;
1175 }
1176
1177 Mutex::Locker locker;
1178 target->GetBreakpointList().GetListMutex(locker);
1179
1180 BreakpointIDList valid_bp_ids;
1181
1182 CommandObjectMultiwordBreakpoint::VerifyBreakpointIDs (command, target, result, &valid_bp_ids);
1183
1184 if (result.Succeeded())
1185 {
1186 for (int i = 0; i < valid_bp_ids.Size(); ++i)
1187 {
1188 BreakpointID cur_bp_id = valid_bp_ids.GetBreakpointIDAtIndex (i);
1189
1190 if (cur_bp_id.GetBreakpointID() != LLDB_INVALID_BREAK_ID)
1191 {
1192 Breakpoint *bp = target->GetBreakpointByID (cur_bp_id.GetBreakpointID()).get();
1193 if (cur_bp_id.GetLocationID() != LLDB_INVALID_BREAK_ID)
1194 {
1195 BreakpointLocation *location = bp->FindLocationByID (cur_bp_id.GetLocationID()).get();
1196 if (location)
1197 {
1198 if (m_options.m_thread_id != LLDB_INVALID_THREAD_ID)
1199 location->SetThreadID (m_options.m_thread_id);
1200
1201 if (m_options.m_thread_index != -1)
1202 location->GetLocationOptions()->GetThreadSpec()->SetIndex(m_options.m_thread_index);
1203
1204 if (!m_options.m_thread_name.empty())
1205 location->GetLocationOptions()->GetThreadSpec()->SetName(m_options.m_thread_name.c_str());
1206
1207 if (!m_options.m_queue_name.empty())
1208 location->GetLocationOptions()->GetThreadSpec()->SetQueueName(m_options.m_queue_name.c_str());
1209
1210 if (m_options.m_ignore_count != -1)
1211 location->GetLocationOptions()->SetIgnoreCount(m_options.m_ignore_count);
Jim Ingham10622a22010-06-18 00:58:52 +00001212
1213 if (m_options.m_enable_passed)
1214 location->SetEnabled (m_options.m_enable_value);
Jim Ingham3c7b5b92010-06-16 02:00:15 +00001215 }
1216 }
1217 else
1218 {
1219 if (m_options.m_thread_id != LLDB_INVALID_THREAD_ID)
1220 bp->SetThreadID (m_options.m_thread_id);
1221
1222 if (m_options.m_thread_index != -1)
1223 bp->GetOptions()->GetThreadSpec()->SetIndex(m_options.m_thread_index);
1224
1225 if (!m_options.m_thread_name.empty())
1226 bp->GetOptions()->GetThreadSpec()->SetName(m_options.m_thread_name.c_str());
1227
1228 if (!m_options.m_queue_name.empty())
1229 bp->GetOptions()->GetThreadSpec()->SetQueueName(m_options.m_queue_name.c_str());
1230
1231 if (m_options.m_ignore_count != -1)
1232 bp->GetOptions()->SetIgnoreCount(m_options.m_ignore_count);
Jim Ingham10622a22010-06-18 00:58:52 +00001233
1234 if (m_options.m_enable_passed)
1235 bp->SetEnabled (m_options.m_enable_value);
1236
Jim Ingham3c7b5b92010-06-16 02:00:15 +00001237 }
1238 }
1239 }
1240 }
1241
1242 return result.Succeeded();
1243}
1244
1245