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