130fdc8d8SChris Lattner //===-- CommandObjectBreakpoint.cpp -----------------------------*- C++ -*-===//
230fdc8d8SChris Lattner //
330fdc8d8SChris Lattner //                     The LLVM Compiler Infrastructure
430fdc8d8SChris Lattner //
530fdc8d8SChris Lattner // This file is distributed under the University of Illinois Open Source
630fdc8d8SChris Lattner // License. See LICENSE.TXT for details.
730fdc8d8SChris Lattner //
830fdc8d8SChris Lattner //===----------------------------------------------------------------------===//
930fdc8d8SChris Lattner 
1030fdc8d8SChris Lattner #include "CommandObjectBreakpoint.h"
1130fdc8d8SChris Lattner #include "CommandObjectBreakpointCommand.h"
1230fdc8d8SChris Lattner 
1330fdc8d8SChris Lattner // C Includes
1430fdc8d8SChris Lattner // C++ Includes
1530fdc8d8SChris Lattner // Other libraries and framework includes
1630fdc8d8SChris Lattner // Project includes
1730fdc8d8SChris Lattner #include "lldb/Breakpoint/Breakpoint.h"
1830fdc8d8SChris Lattner #include "lldb/Breakpoint/BreakpointIDList.h"
1930fdc8d8SChris Lattner #include "lldb/Breakpoint/BreakpointLocation.h"
20*40af72e1SJim Ingham #include "lldb/Interpreter/Options.h"
2130fdc8d8SChris Lattner #include "lldb/Core/RegularExpression.h"
2230fdc8d8SChris Lattner #include "lldb/Core/StreamString.h"
2330fdc8d8SChris Lattner #include "lldb/Interpreter/CommandInterpreter.h"
2430fdc8d8SChris Lattner #include "lldb/Interpreter/CommandReturnObject.h"
2530fdc8d8SChris Lattner #include "lldb/Target/Target.h"
2630fdc8d8SChris Lattner #include "lldb/Interpreter/CommandCompletions.h"
2730fdc8d8SChris Lattner #include "lldb/Target/StackFrame.h"
2830fdc8d8SChris Lattner 
2930fdc8d8SChris Lattner using namespace lldb;
3030fdc8d8SChris Lattner using namespace lldb_private;
3130fdc8d8SChris Lattner 
3230fdc8d8SChris Lattner static void
3330fdc8d8SChris Lattner AddBreakpointDescription (CommandContext *context, StreamString *s, Breakpoint *bp, lldb::DescriptionLevel level)
3430fdc8d8SChris Lattner {
3530fdc8d8SChris Lattner     s->IndentMore();
3630fdc8d8SChris Lattner     bp->GetDescription (s, level, true);
3730fdc8d8SChris Lattner     s->IndentLess();
3830fdc8d8SChris Lattner     s->EOL();
3930fdc8d8SChris Lattner }
4030fdc8d8SChris Lattner 
4130fdc8d8SChris Lattner //-------------------------------------------------------------------------
4230fdc8d8SChris Lattner // CommandObjectBreakpointSet::CommandOptions
4330fdc8d8SChris Lattner //-------------------------------------------------------------------------
4430fdc8d8SChris Lattner 
4530fdc8d8SChris Lattner CommandObjectBreakpointSet::CommandOptions::CommandOptions() :
4630fdc8d8SChris Lattner     Options (),
4730fdc8d8SChris Lattner     m_filename (),
4830fdc8d8SChris Lattner     m_line_num (0),
4930fdc8d8SChris Lattner     m_column (0),
5030fdc8d8SChris Lattner     m_ignore_inlines (false),
5130fdc8d8SChris Lattner     m_func_name (),
5230fdc8d8SChris Lattner     m_func_regexp (),
5330fdc8d8SChris Lattner     m_modules (),
5430fdc8d8SChris Lattner     m_load_addr()
5530fdc8d8SChris Lattner {
5630fdc8d8SChris Lattner     BuildValidOptionSets();
5730fdc8d8SChris Lattner }
5830fdc8d8SChris Lattner 
5930fdc8d8SChris Lattner CommandObjectBreakpointSet::CommandOptions::~CommandOptions ()
6030fdc8d8SChris Lattner {
6130fdc8d8SChris Lattner }
6230fdc8d8SChris Lattner 
6330fdc8d8SChris Lattner lldb::OptionDefinition
6430fdc8d8SChris Lattner CommandObjectBreakpointSet::CommandOptions::g_option_table[] =
6530fdc8d8SChris Lattner {
668651121cSJim Ingham     { LLDB_OPT_SET_ALL, false, "shlib",       's', required_argument, NULL, CommandCompletions::eModuleCompletion, "<shlib-name>",
678651121cSJim Ingham         "Set the breakpoint only in this shared library (can use this option multiple times for multiple shlibs)."},
688651121cSJim Ingham 
698651121cSJim Ingham     { LLDB_OPT_SET_ALL, false, "ignore_inlines", 'i', no_argument,   NULL, 0, NULL,
708651121cSJim Ingham         "Ignore inlined subroutines when setting the breakppoint." },
718651121cSJim Ingham 
728651121cSJim Ingham     { LLDB_OPT_SET_1, false, "file",       'f', required_argument, NULL, CommandCompletions::eSourceFileCompletion, "<filename>",
7330fdc8d8SChris Lattner         "Set the breakpoint by source location in this particular file."},
7430fdc8d8SChris Lattner 
758651121cSJim Ingham     { LLDB_OPT_SET_1, true, "line",       'l', required_argument, NULL, 0, "<linenum>",
7630fdc8d8SChris Lattner         "Set the breakpoint by source location at this particular line."},
7730fdc8d8SChris Lattner 
7830fdc8d8SChris Lattner     // Comment out this option for the moment, as we don't actually use it, but will in the future.
7930fdc8d8SChris Lattner     // This way users won't see it, but the infrastructure is left in place.
8030fdc8d8SChris Lattner     //    { 0, false, "column",     'c', required_argument, NULL, "<column>",
8130fdc8d8SChris Lattner     //    "Set the breakpoint by source location at this particular column."},
8230fdc8d8SChris Lattner 
838651121cSJim Ingham     { LLDB_OPT_SET_2, true, "address",    'a', required_argument, NULL, 0, "<address>",
8430fdc8d8SChris Lattner         "Set the breakpoint by address, at the specified address."},
8530fdc8d8SChris Lattner 
868651121cSJim Ingham     { LLDB_OPT_SET_3, true, "name",       'n', required_argument, NULL, CommandCompletions::eSymbolCompletion, "<function-name>",
8730fdc8d8SChris Lattner         "Set the breakpoint by function name." },
8830fdc8d8SChris Lattner 
898651121cSJim Ingham     { LLDB_OPT_SET_4, true, "func_regex", 'r', required_argument, NULL, 0, "<regular-expression>",
9030fdc8d8SChris Lattner         "Set the breakpoint by function name, evaluating a regular-expression to find the function name(s)." },
9130fdc8d8SChris Lattner 
9230fdc8d8SChris Lattner     { 0, false, NULL, 0, 0, NULL, 0, NULL, NULL }
9330fdc8d8SChris Lattner };
9430fdc8d8SChris Lattner 
9530fdc8d8SChris Lattner const lldb::OptionDefinition*
9630fdc8d8SChris Lattner CommandObjectBreakpointSet::CommandOptions::GetDefinitions ()
9730fdc8d8SChris Lattner {
9830fdc8d8SChris Lattner     return g_option_table;
9930fdc8d8SChris Lattner }
10030fdc8d8SChris Lattner 
10130fdc8d8SChris Lattner Error
10230fdc8d8SChris Lattner CommandObjectBreakpointSet::CommandOptions::SetOptionValue (int option_idx, const char *option_arg)
10330fdc8d8SChris Lattner {
10430fdc8d8SChris Lattner     Error error;
10530fdc8d8SChris Lattner     char short_option = (char) m_getopt_table[option_idx].val;
10630fdc8d8SChris Lattner 
10730fdc8d8SChris Lattner     switch (short_option)
10830fdc8d8SChris Lattner     {
10930fdc8d8SChris Lattner         case 'a':
11030fdc8d8SChris Lattner             m_load_addr = Args::StringToUInt64(optarg, LLDB_INVALID_ADDRESS, 0);
11130fdc8d8SChris Lattner             if (m_load_addr == LLDB_INVALID_ADDRESS)
11230fdc8d8SChris Lattner                 m_load_addr = Args::StringToUInt64(optarg, LLDB_INVALID_ADDRESS, 16);
11330fdc8d8SChris Lattner 
11430fdc8d8SChris Lattner             if (m_load_addr == LLDB_INVALID_ADDRESS)
11530fdc8d8SChris Lattner                 error.SetErrorStringWithFormat ("Invalid address string '%s'.\n", optarg);
11630fdc8d8SChris Lattner             break;
11730fdc8d8SChris Lattner 
11830fdc8d8SChris Lattner         case 'c':
11930fdc8d8SChris Lattner             m_column = Args::StringToUInt32 (option_arg, 0);
12030fdc8d8SChris Lattner             break;
12130fdc8d8SChris Lattner         case 'f':
12230fdc8d8SChris Lattner             m_filename = option_arg;
12330fdc8d8SChris Lattner             break;
12430fdc8d8SChris Lattner         case 'i':
12530fdc8d8SChris Lattner             m_ignore_inlines = true;
12630fdc8d8SChris Lattner             break;
12730fdc8d8SChris Lattner         case 'l':
12830fdc8d8SChris Lattner             m_line_num = Args::StringToUInt32 (option_arg, 0);
12930fdc8d8SChris Lattner             break;
13030fdc8d8SChris Lattner         case 'n':
13130fdc8d8SChris Lattner             m_func_name = option_arg;
13230fdc8d8SChris Lattner             break;
13330fdc8d8SChris Lattner         case 'r':
13430fdc8d8SChris Lattner             m_func_regexp = option_arg;
13530fdc8d8SChris Lattner             break;
13630fdc8d8SChris Lattner         case 's':
13730fdc8d8SChris Lattner             {
13830fdc8d8SChris Lattner                 m_modules.push_back (std::string (option_arg));
13930fdc8d8SChris Lattner                 break;
14030fdc8d8SChris Lattner             }
14130fdc8d8SChris Lattner         default:
14230fdc8d8SChris Lattner             error.SetErrorStringWithFormat ("Unrecognized option '%c'.\n", short_option);
14330fdc8d8SChris Lattner             break;
14430fdc8d8SChris Lattner     }
14530fdc8d8SChris Lattner 
14630fdc8d8SChris Lattner     return error;
14730fdc8d8SChris Lattner }
14830fdc8d8SChris Lattner 
14930fdc8d8SChris Lattner void
15030fdc8d8SChris Lattner CommandObjectBreakpointSet::CommandOptions::ResetOptionValues ()
15130fdc8d8SChris Lattner {
15230fdc8d8SChris Lattner     Options::ResetOptionValues();
15330fdc8d8SChris Lattner 
15430fdc8d8SChris Lattner     m_filename.clear();
15530fdc8d8SChris Lattner     m_line_num = 0;
15630fdc8d8SChris Lattner     m_column = 0;
15730fdc8d8SChris Lattner     m_ignore_inlines = false;
15830fdc8d8SChris Lattner     m_func_name.clear();
15930fdc8d8SChris Lattner     m_func_regexp.clear();
16030fdc8d8SChris Lattner     m_load_addr = LLDB_INVALID_ADDRESS;
16130fdc8d8SChris Lattner     m_modules.clear();
16230fdc8d8SChris Lattner }
16330fdc8d8SChris Lattner 
16430fdc8d8SChris Lattner //-------------------------------------------------------------------------
16530fdc8d8SChris Lattner // CommandObjectBreakpointSet
16630fdc8d8SChris Lattner //-------------------------------------------------------------------------
16730fdc8d8SChris Lattner 
16830fdc8d8SChris Lattner CommandObjectBreakpointSet::CommandObjectBreakpointSet () :
16930fdc8d8SChris Lattner     CommandObject ("breakpoint set", "Sets a breakpoint or set of breakpoints in the executable.",
17030fdc8d8SChris Lattner                    "breakpoint set <cmd-options>")
17130fdc8d8SChris Lattner {
17230fdc8d8SChris Lattner }
17330fdc8d8SChris Lattner 
17430fdc8d8SChris Lattner CommandObjectBreakpointSet::~CommandObjectBreakpointSet ()
17530fdc8d8SChris Lattner {
17630fdc8d8SChris Lattner }
17730fdc8d8SChris Lattner 
17830fdc8d8SChris Lattner Options *
17930fdc8d8SChris Lattner CommandObjectBreakpointSet::GetOptions ()
18030fdc8d8SChris Lattner {
18130fdc8d8SChris Lattner     return &m_options;
18230fdc8d8SChris Lattner }
18330fdc8d8SChris Lattner 
18430fdc8d8SChris Lattner bool
18530fdc8d8SChris Lattner CommandObjectBreakpointSet::Execute
18630fdc8d8SChris Lattner (
18730fdc8d8SChris Lattner     Args& command,
18830fdc8d8SChris Lattner     CommandContext *context,
18930fdc8d8SChris Lattner     CommandInterpreter *interpreter,
19030fdc8d8SChris Lattner     CommandReturnObject &result
19130fdc8d8SChris Lattner )
19230fdc8d8SChris Lattner {
19330fdc8d8SChris Lattner     Target *target = context->GetTarget();
19430fdc8d8SChris Lattner     if (target == NULL)
19530fdc8d8SChris Lattner     {
19630fdc8d8SChris Lattner         result.AppendError ("Invalid target, set executable file using 'file' command.");
19730fdc8d8SChris Lattner         result.SetStatus (eReturnStatusFailed);
19830fdc8d8SChris Lattner         return false;
19930fdc8d8SChris Lattner     }
20030fdc8d8SChris Lattner 
20130fdc8d8SChris Lattner     // The following are the various types of breakpoints that could be set:
20230fdc8d8SChris Lattner     //   1).  -f -l -p  [-s -g]   (setting breakpoint by source location)
20330fdc8d8SChris Lattner     //   2).  -a  [-s -g]         (setting breakpoint by address)
20430fdc8d8SChris Lattner     //   3).  -n  [-s -g]         (setting breakpoint by function name)
20530fdc8d8SChris Lattner     //   4).  -r  [-s -g]         (setting breakpoint by function name regular expression)
20630fdc8d8SChris Lattner 
20730fdc8d8SChris Lattner     BreakpointSetType break_type = eSetTypeInvalid;
20830fdc8d8SChris Lattner 
20930fdc8d8SChris Lattner     if (m_options.m_line_num != 0)
21030fdc8d8SChris Lattner         break_type = eSetTypeFileAndLine;
21130fdc8d8SChris Lattner     else if (m_options.m_load_addr != LLDB_INVALID_ADDRESS)
21230fdc8d8SChris Lattner         break_type = eSetTypeAddress;
21330fdc8d8SChris Lattner     else if (!m_options.m_func_name.empty())
21430fdc8d8SChris Lattner         break_type = eSetTypeFunctionName;
21530fdc8d8SChris Lattner     else if  (!m_options.m_func_regexp.empty())
21630fdc8d8SChris Lattner         break_type = eSetTypeFunctionRegexp;
21730fdc8d8SChris Lattner 
21830fdc8d8SChris Lattner     ModuleSP module_sp = target->GetExecutableModule();
21930fdc8d8SChris Lattner     Breakpoint *bp = NULL;
22030fdc8d8SChris Lattner     FileSpec module;
22130fdc8d8SChris Lattner     bool use_module = false;
22230fdc8d8SChris Lattner     int num_modules = m_options.m_modules.size();
22330fdc8d8SChris Lattner 
22430fdc8d8SChris Lattner     if ((num_modules > 0) && (break_type != eSetTypeAddress))
22530fdc8d8SChris Lattner         use_module = true;
22630fdc8d8SChris Lattner 
22730fdc8d8SChris Lattner     switch (break_type)
22830fdc8d8SChris Lattner     {
22930fdc8d8SChris Lattner         case eSetTypeFileAndLine: // Breakpoint by source position
23030fdc8d8SChris Lattner         {
23130fdc8d8SChris Lattner             FileSpec file;
23230fdc8d8SChris Lattner             if (m_options.m_filename.empty())
23330fdc8d8SChris Lattner             {
23430fdc8d8SChris Lattner                 StackFrame *cur_frame = context->GetExecutionContext().frame;
23530fdc8d8SChris Lattner                 if (cur_frame == NULL)
23630fdc8d8SChris Lattner                 {
23730fdc8d8SChris Lattner                     result.AppendError ("Attempting to set breakpoint by line number alone with no selected frame.");
23830fdc8d8SChris Lattner                     result.SetStatus (eReturnStatusFailed);
23930fdc8d8SChris Lattner                     break;
24030fdc8d8SChris Lattner                 }
24130fdc8d8SChris Lattner                 else if (!cur_frame->HasDebugInformation())
24230fdc8d8SChris Lattner                 {
24330fdc8d8SChris Lattner                     result.AppendError ("Attempting to set breakpoint by line number alone but selected frame has no debug info.");
24430fdc8d8SChris Lattner                     result.SetStatus (eReturnStatusFailed);
24530fdc8d8SChris Lattner                     break;
24630fdc8d8SChris Lattner                 }
24730fdc8d8SChris Lattner                 else
24830fdc8d8SChris Lattner                 {
24930fdc8d8SChris Lattner                     const SymbolContext &context = cur_frame->GetSymbolContext(true);
25030fdc8d8SChris Lattner                     if (context.line_entry.file)
25130fdc8d8SChris Lattner                     {
25230fdc8d8SChris Lattner                         file = context.line_entry.file;
25330fdc8d8SChris Lattner                     }
25430fdc8d8SChris Lattner                     else if (context.comp_unit != NULL)
25530fdc8d8SChris Lattner                     {    file = context.comp_unit;
25630fdc8d8SChris Lattner                     }
25730fdc8d8SChris Lattner                     else
25830fdc8d8SChris Lattner                     {
25930fdc8d8SChris Lattner                         result.AppendError ("Attempting to set breakpoint by line number alone but can't find the file for the selected frame.");
26030fdc8d8SChris Lattner                         result.SetStatus (eReturnStatusFailed);
26130fdc8d8SChris Lattner                         break;
26230fdc8d8SChris Lattner                     }
26330fdc8d8SChris Lattner                 }
26430fdc8d8SChris Lattner             }
26530fdc8d8SChris Lattner             else
26630fdc8d8SChris Lattner             {
26730fdc8d8SChris Lattner                 file.SetFile(m_options.m_filename.c_str());
26830fdc8d8SChris Lattner             }
26930fdc8d8SChris Lattner 
27030fdc8d8SChris Lattner             if (use_module)
27130fdc8d8SChris Lattner             {
27230fdc8d8SChris Lattner                 for (int i = 0; i < num_modules; ++i)
27330fdc8d8SChris Lattner                 {
27430fdc8d8SChris Lattner                     module.SetFile(m_options.m_modules[i].c_str());
27530fdc8d8SChris Lattner                     bp = target->CreateBreakpoint (&module,
27630fdc8d8SChris Lattner                                                    file,
27730fdc8d8SChris Lattner                                                    m_options.m_line_num,
27830fdc8d8SChris Lattner                                                    m_options.m_ignore_inlines).get();
27930fdc8d8SChris Lattner                     if (bp)
28030fdc8d8SChris Lattner                     {
28130fdc8d8SChris Lattner                         StreamString &output_stream = result.GetOutputStream();
28230fdc8d8SChris Lattner                         output_stream.Printf ("Breakpoint created: ");
28330fdc8d8SChris Lattner                         bp->GetDescription(&output_stream, lldb::eDescriptionLevelBrief);
28430fdc8d8SChris Lattner                         output_stream.EOL();
28530fdc8d8SChris Lattner                         result.SetStatus (eReturnStatusSuccessFinishResult);
28630fdc8d8SChris Lattner                     }
28730fdc8d8SChris Lattner                     else
28830fdc8d8SChris Lattner                     {
28930fdc8d8SChris Lattner                         result.AppendErrorWithFormat("Breakpoint creation failed: No breakpoint created in module '%s'.\n",
29030fdc8d8SChris Lattner                                                     m_options.m_modules[i].c_str());
29130fdc8d8SChris Lattner                         result.SetStatus (eReturnStatusFailed);
29230fdc8d8SChris Lattner                     }
29330fdc8d8SChris Lattner                 }
29430fdc8d8SChris Lattner             }
29530fdc8d8SChris Lattner             else
29630fdc8d8SChris Lattner                 bp = target->CreateBreakpoint (NULL,
29730fdc8d8SChris Lattner                                                file,
29830fdc8d8SChris Lattner                                                m_options.m_line_num,
29930fdc8d8SChris Lattner                                                m_options.m_ignore_inlines).get();
30030fdc8d8SChris Lattner         }
30130fdc8d8SChris Lattner         break;
30230fdc8d8SChris Lattner         case eSetTypeAddress: // Breakpoint by address
30330fdc8d8SChris Lattner             bp = target->CreateBreakpoint (m_options.m_load_addr, false).get();
30430fdc8d8SChris Lattner             break;
30530fdc8d8SChris Lattner         case eSetTypeFunctionName: // Breakpoint by function name
30630fdc8d8SChris Lattner             if (use_module)
30730fdc8d8SChris Lattner             {
30830fdc8d8SChris Lattner                 for (int i = 0; i < num_modules; ++i)
30930fdc8d8SChris Lattner                 {
31030fdc8d8SChris Lattner                     module.SetFile(m_options.m_modules[i].c_str());
31130fdc8d8SChris Lattner                     bp = target->CreateBreakpoint (&module, m_options.m_func_name.c_str()).get();
31230fdc8d8SChris Lattner                     if (bp)
31330fdc8d8SChris Lattner                     {
31430fdc8d8SChris Lattner                         StreamString &output_stream = result.GetOutputStream();
31530fdc8d8SChris Lattner                         output_stream.Printf ("Breakpoint created: ");
31630fdc8d8SChris Lattner                         bp->GetDescription(&output_stream, lldb::eDescriptionLevelBrief);
31730fdc8d8SChris Lattner                         output_stream.EOL();
31830fdc8d8SChris Lattner                         result.SetStatus (eReturnStatusSuccessFinishResult);
31930fdc8d8SChris Lattner                     }
32030fdc8d8SChris Lattner                     else
32130fdc8d8SChris Lattner                     {
32230fdc8d8SChris Lattner                         result.AppendErrorWithFormat("Breakpoint creation failed: No breakpoint created in module '%s'.\n",
32330fdc8d8SChris Lattner                                                     m_options.m_modules[i].c_str());
32430fdc8d8SChris Lattner                         result.SetStatus (eReturnStatusFailed);
32530fdc8d8SChris Lattner                     }
32630fdc8d8SChris Lattner                 }
32730fdc8d8SChris Lattner             }
32830fdc8d8SChris Lattner             else
32930fdc8d8SChris Lattner                 bp = target->CreateBreakpoint (NULL, m_options.m_func_name.c_str()).get();
33030fdc8d8SChris Lattner             break;
33130fdc8d8SChris Lattner         case eSetTypeFunctionRegexp: // Breakpoint by regular expression function name
33230fdc8d8SChris Lattner             {
33330fdc8d8SChris Lattner                 RegularExpression regexp(m_options.m_func_regexp.c_str());
33430fdc8d8SChris Lattner                 if (use_module)
33530fdc8d8SChris Lattner                 {
33630fdc8d8SChris Lattner                     for (int i = 0; i < num_modules; ++i)
33730fdc8d8SChris Lattner                     {
33830fdc8d8SChris Lattner                         module.SetFile(m_options.m_modules[i].c_str());
33930fdc8d8SChris Lattner                         bp = target->CreateBreakpoint (&module, regexp).get();
34030fdc8d8SChris Lattner                         if (bp)
34130fdc8d8SChris Lattner                         {
34230fdc8d8SChris Lattner                             StreamString &output_stream = result.GetOutputStream();
34330fdc8d8SChris Lattner                             output_stream.Printf ("Breakpoint created: ");
34430fdc8d8SChris Lattner                             bp->GetDescription(&output_stream, lldb::eDescriptionLevelBrief);
34530fdc8d8SChris Lattner                             output_stream.EOL();
34630fdc8d8SChris Lattner                             result.SetStatus (eReturnStatusSuccessFinishResult);
34730fdc8d8SChris Lattner                         }
34830fdc8d8SChris Lattner                         else
34930fdc8d8SChris Lattner                         {
35030fdc8d8SChris Lattner                             result.AppendErrorWithFormat("Breakpoint creation failed: No breakpoint created in module '%s'.\n",
35130fdc8d8SChris Lattner                                                         m_options.m_modules[i].c_str());
35230fdc8d8SChris Lattner                             result.SetStatus (eReturnStatusFailed);
35330fdc8d8SChris Lattner                         }
35430fdc8d8SChris Lattner                     }
35530fdc8d8SChris Lattner                 }
35630fdc8d8SChris Lattner                 else
35730fdc8d8SChris Lattner                     bp = target->CreateBreakpoint (NULL, regexp).get();
35830fdc8d8SChris Lattner             }
35930fdc8d8SChris Lattner             break;
36030fdc8d8SChris Lattner         default:
36130fdc8d8SChris Lattner             break;
36230fdc8d8SChris Lattner     }
36330fdc8d8SChris Lattner 
36430fdc8d8SChris Lattner     if (bp && !use_module)
36530fdc8d8SChris Lattner     {
36630fdc8d8SChris Lattner         StreamString &output_stream = result.GetOutputStream();
36730fdc8d8SChris Lattner         output_stream.Printf ("Breakpoint created: ");
36830fdc8d8SChris Lattner         bp->GetDescription(&output_stream, lldb::eDescriptionLevelBrief);
36930fdc8d8SChris Lattner         output_stream.EOL();
37030fdc8d8SChris Lattner         result.SetStatus (eReturnStatusSuccessFinishResult);
37130fdc8d8SChris Lattner     }
37230fdc8d8SChris Lattner     else if (!bp)
37330fdc8d8SChris Lattner     {
37430fdc8d8SChris Lattner         result.AppendError ("Breakpoint creation failed: No breakpoint created.");
37530fdc8d8SChris Lattner         result.SetStatus (eReturnStatusFailed);
37630fdc8d8SChris Lattner     }
37730fdc8d8SChris Lattner 
37830fdc8d8SChris Lattner     return result.Succeeded();
37930fdc8d8SChris Lattner }
38030fdc8d8SChris Lattner 
38130fdc8d8SChris Lattner 
38230fdc8d8SChris Lattner 
38330fdc8d8SChris Lattner //-------------------------------------------------------------------------
38430fdc8d8SChris Lattner // CommandObjectMultiwordBreakpoint
38530fdc8d8SChris Lattner //-------------------------------------------------------------------------
38630fdc8d8SChris Lattner 
38730fdc8d8SChris Lattner CommandObjectMultiwordBreakpoint::CommandObjectMultiwordBreakpoint (CommandInterpreter *interpreter) :
38830fdc8d8SChris Lattner     CommandObjectMultiword ("breakpoint",
38930fdc8d8SChris Lattner                               "A set of commands for operating on breakpoints.",
39030fdc8d8SChris Lattner                               "breakpoint <command> [<command-options>]")
39130fdc8d8SChris Lattner {
39230fdc8d8SChris Lattner     bool status;
39330fdc8d8SChris Lattner 
39430fdc8d8SChris Lattner     CommandObjectSP list_command_object (new CommandObjectBreakpointList ());
39530fdc8d8SChris Lattner     CommandObjectSP delete_command_object (new CommandObjectBreakpointDelete ());
39630fdc8d8SChris Lattner     CommandObjectSP enable_command_object (new CommandObjectBreakpointEnable ());
39730fdc8d8SChris Lattner     CommandObjectSP disable_command_object (new CommandObjectBreakpointDisable ());
39830fdc8d8SChris Lattner     CommandObjectSP set_command_object (new CommandObjectBreakpointSet ());
39930fdc8d8SChris Lattner     CommandObjectSP command_command_object (new CommandObjectBreakpointCommand (interpreter));
40030fdc8d8SChris Lattner 
40130fdc8d8SChris Lattner     enable_command_object->SetCommandName("breakpoint enable");
40230fdc8d8SChris Lattner     disable_command_object->SetCommandName("breakpoint disable");
40330fdc8d8SChris Lattner     set_command_object->SetCommandName("breakpoint set");
40430fdc8d8SChris Lattner     command_command_object->SetCommandName ("breakpoint command");
40530fdc8d8SChris Lattner     list_command_object->SetCommandName ("breakpoint list");
40630fdc8d8SChris Lattner 
40730fdc8d8SChris Lattner     status = LoadSubCommand (list_command_object, "list", interpreter);
40830fdc8d8SChris Lattner     status = LoadSubCommand (enable_command_object, "enable", interpreter);
40930fdc8d8SChris Lattner     status = LoadSubCommand (disable_command_object, "disable", interpreter);
41030fdc8d8SChris Lattner     status = LoadSubCommand (delete_command_object, "delete", interpreter);
41130fdc8d8SChris Lattner     status = LoadSubCommand (set_command_object, "set", interpreter);
41230fdc8d8SChris Lattner     status = LoadSubCommand (command_command_object, "command", interpreter);
41330fdc8d8SChris Lattner }
41430fdc8d8SChris Lattner 
41530fdc8d8SChris Lattner CommandObjectMultiwordBreakpoint::~CommandObjectMultiwordBreakpoint ()
41630fdc8d8SChris Lattner {
41730fdc8d8SChris Lattner }
41830fdc8d8SChris Lattner 
41930fdc8d8SChris Lattner void
42030fdc8d8SChris Lattner CommandObjectMultiwordBreakpoint::VerifyBreakpointIDs (Args &args, Target *target, CommandReturnObject &result,
42130fdc8d8SChris Lattner                                                          BreakpointIDList *valid_ids)
42230fdc8d8SChris Lattner {
42330fdc8d8SChris Lattner     // args can be strings representing 1). integers (for breakpoint ids)
42430fdc8d8SChris Lattner     //                                  2). the full breakpoint & location canonical representation
42530fdc8d8SChris Lattner     //                                  3). the word "to" or a hyphen, representing a range (in which case there
42630fdc8d8SChris Lattner     //                                      had *better* be an entry both before & after of one of the first two types.
42730fdc8d8SChris Lattner 
42830fdc8d8SChris Lattner     Args temp_args;
42930fdc8d8SChris Lattner 
43030fdc8d8SChris Lattner     // Create a new Args variable to use; copy any non-breakpoint-id-ranges stuff directly from the old ARGS to
43130fdc8d8SChris Lattner     // the new TEMP_ARGS.  Do not copy breakpoint id range strings over; instead generate a list of strings for
43230fdc8d8SChris Lattner     // all the breakpoint ids in the range, and shove all of those breakpoint id strings into TEMP_ARGS.
43330fdc8d8SChris Lattner 
43430fdc8d8SChris Lattner     BreakpointIDList::FindAndReplaceIDRanges (args, target, result, temp_args);
43530fdc8d8SChris Lattner 
43630fdc8d8SChris Lattner     // NOW, convert the list of breakpoint id strings in TEMP_ARGS into an actual BreakpointIDList:
43730fdc8d8SChris Lattner 
43830fdc8d8SChris Lattner     valid_ids->InsertStringArray ((const char **) temp_args.GetArgumentVector(), temp_args.GetArgumentCount(), result);
43930fdc8d8SChris Lattner 
44030fdc8d8SChris Lattner     // At this point,  all of the breakpoint ids that the user passed in have been converted to breakpoint IDs
44130fdc8d8SChris Lattner     // and put into valid_ids.
44230fdc8d8SChris Lattner 
44330fdc8d8SChris Lattner     if (result.Succeeded())
44430fdc8d8SChris Lattner     {
44530fdc8d8SChris Lattner         // Now that we've converted everything from args into a list of breakpoint ids, go through our tentative list
44630fdc8d8SChris Lattner         // of breakpoint id's and verify that they correspond to valid/currently set breakpoints.
44730fdc8d8SChris Lattner 
44830fdc8d8SChris Lattner         for (int i = 0; i < valid_ids->Size(); ++i)
44930fdc8d8SChris Lattner         {
45030fdc8d8SChris Lattner             BreakpointID cur_bp_id = valid_ids->GetBreakpointIDAtIndex (i);
45130fdc8d8SChris Lattner             Breakpoint *breakpoint = target->GetBreakpointByID (cur_bp_id.GetBreakpointID()).get();
45230fdc8d8SChris Lattner             if (breakpoint != NULL)
45330fdc8d8SChris Lattner             {
45430fdc8d8SChris Lattner                 int num_locations = breakpoint->GetNumLocations();
45530fdc8d8SChris Lattner                 if (cur_bp_id.GetLocationID() > num_locations)
45630fdc8d8SChris Lattner                 {
45730fdc8d8SChris Lattner                     StreamString id_str;
45830fdc8d8SChris Lattner                     BreakpointID::GetCanonicalReference (&id_str, cur_bp_id.GetBreakpointID(),
45930fdc8d8SChris Lattner                                                            cur_bp_id.GetLocationID());
46030fdc8d8SChris Lattner                     i = valid_ids->Size() + 1;
46130fdc8d8SChris Lattner                     result.AppendErrorWithFormat ("'%s' is not a currently valid breakpoint/location id.\n",
46230fdc8d8SChris Lattner                                                  id_str.GetData());
46330fdc8d8SChris Lattner                     result.SetStatus (eReturnStatusFailed);
46430fdc8d8SChris Lattner                 }
46530fdc8d8SChris Lattner             }
46630fdc8d8SChris Lattner             else
46730fdc8d8SChris Lattner             {
46830fdc8d8SChris Lattner                 i = valid_ids->Size() + 1;
46930fdc8d8SChris Lattner                 result.AppendErrorWithFormat ("'%d' is not a currently valid breakpoint id.\n", cur_bp_id.GetBreakpointID());
47030fdc8d8SChris Lattner                 result.SetStatus (eReturnStatusFailed);
47130fdc8d8SChris Lattner             }
47230fdc8d8SChris Lattner         }
47330fdc8d8SChris Lattner     }
47430fdc8d8SChris Lattner }
47530fdc8d8SChris Lattner 
47630fdc8d8SChris Lattner //-------------------------------------------------------------------------
47730fdc8d8SChris Lattner // CommandObjectBreakpointList::Options
47830fdc8d8SChris Lattner //-------------------------------------------------------------------------
47930fdc8d8SChris Lattner 
48030fdc8d8SChris Lattner CommandObjectBreakpointList::CommandOptions::CommandOptions() :
48130fdc8d8SChris Lattner     Options (),
48230fdc8d8SChris Lattner     m_level (lldb::eDescriptionLevelFull)  // Breakpoint List defaults to brief descriptions
48330fdc8d8SChris Lattner {
48430fdc8d8SChris Lattner     BuildValidOptionSets();
48530fdc8d8SChris Lattner }
48630fdc8d8SChris Lattner 
48730fdc8d8SChris Lattner CommandObjectBreakpointList::CommandOptions::~CommandOptions ()
48830fdc8d8SChris Lattner {
48930fdc8d8SChris Lattner }
49030fdc8d8SChris Lattner 
49130fdc8d8SChris Lattner lldb::OptionDefinition
49230fdc8d8SChris Lattner CommandObjectBreakpointList::CommandOptions::g_option_table[] =
49330fdc8d8SChris Lattner {
4948651121cSJim Ingham     { LLDB_OPT_SET_ALL, false, "internal", 'i', no_argument, NULL, 0, NULL,
4958651121cSJim Ingham         "Show debugger internal breakpoints" },
4968651121cSJim Ingham 
4978651121cSJim Ingham     { LLDB_OPT_SET_1, false, "brief",    'b', no_argument, NULL, 0, NULL,
49830fdc8d8SChris Lattner         "Give a brief description of the breakpoint (no location info)."},
49930fdc8d8SChris Lattner 
50030fdc8d8SChris Lattner     // FIXME: We need to add an "internal" command, and then add this sort of thing to it.
50130fdc8d8SChris Lattner     // But I need to see it for now, and don't want to wait.
5028651121cSJim Ingham     { LLDB_OPT_SET_2, false, "full",    'f', no_argument, NULL, 0, NULL,
50330fdc8d8SChris Lattner         "Give a full description of the breakpoint and its locations."},
50430fdc8d8SChris Lattner 
5058651121cSJim Ingham     { LLDB_OPT_SET_3, false, "verbose", 'v', no_argument, NULL, 0, NULL,
50630fdc8d8SChris Lattner         "Explain everything we know about the breakpoint (for debugging debugger bugs)." },
50730fdc8d8SChris Lattner 
50830fdc8d8SChris Lattner     { 0, false, NULL, 0, 0, NULL, 0, NULL, NULL }
50930fdc8d8SChris Lattner };
51030fdc8d8SChris Lattner 
51130fdc8d8SChris Lattner const lldb::OptionDefinition*
51230fdc8d8SChris Lattner CommandObjectBreakpointList::CommandOptions::GetDefinitions ()
51330fdc8d8SChris Lattner {
51430fdc8d8SChris Lattner     return g_option_table;
51530fdc8d8SChris Lattner }
51630fdc8d8SChris Lattner 
51730fdc8d8SChris Lattner Error
51830fdc8d8SChris Lattner CommandObjectBreakpointList::CommandOptions::SetOptionValue (int option_idx, const char *option_arg)
51930fdc8d8SChris Lattner {
52030fdc8d8SChris Lattner     Error error;
52130fdc8d8SChris Lattner     char short_option = (char) m_getopt_table[option_idx].val;
52230fdc8d8SChris Lattner 
52330fdc8d8SChris Lattner     switch (short_option)
52430fdc8d8SChris Lattner     {
52530fdc8d8SChris Lattner         case 'b':
52630fdc8d8SChris Lattner             m_level = lldb::eDescriptionLevelBrief;
52730fdc8d8SChris Lattner             break;
52830fdc8d8SChris Lattner         case 'f':
52930fdc8d8SChris Lattner             m_level = lldb::eDescriptionLevelFull;
53030fdc8d8SChris Lattner             break;
53130fdc8d8SChris Lattner         case 'v':
53230fdc8d8SChris Lattner             m_level = lldb::eDescriptionLevelVerbose;
53330fdc8d8SChris Lattner             break;
53430fdc8d8SChris Lattner         case 'i':
53530fdc8d8SChris Lattner             m_internal = true;
53630fdc8d8SChris Lattner             break;
53730fdc8d8SChris Lattner         default:
53830fdc8d8SChris Lattner             error.SetErrorStringWithFormat ("Unrecognized option '%c'.\n", short_option);
53930fdc8d8SChris Lattner             break;
54030fdc8d8SChris Lattner     }
54130fdc8d8SChris Lattner 
54230fdc8d8SChris Lattner     return error;
54330fdc8d8SChris Lattner }
54430fdc8d8SChris Lattner 
54530fdc8d8SChris Lattner void
54630fdc8d8SChris Lattner CommandObjectBreakpointList::CommandOptions::ResetOptionValues ()
54730fdc8d8SChris Lattner {
54830fdc8d8SChris Lattner     Options::ResetOptionValues();
54930fdc8d8SChris Lattner 
55030fdc8d8SChris Lattner     m_level = lldb::eDescriptionLevelFull;
55130fdc8d8SChris Lattner     m_internal = false;
55230fdc8d8SChris Lattner }
55330fdc8d8SChris Lattner 
55430fdc8d8SChris Lattner //-------------------------------------------------------------------------
55530fdc8d8SChris Lattner // CommandObjectBreakpointList
55630fdc8d8SChris Lattner //-------------------------------------------------------------------------
55730fdc8d8SChris Lattner 
55830fdc8d8SChris Lattner CommandObjectBreakpointList::CommandObjectBreakpointList () :
55930fdc8d8SChris Lattner     CommandObject ("breakpoint list",
56030fdc8d8SChris Lattner                      "List some or all breakpoints at configurable levels of detail.",
56130fdc8d8SChris Lattner                      "breakpoint list [<breakpoint-id>]")
56230fdc8d8SChris Lattner {
56330fdc8d8SChris Lattner }
56430fdc8d8SChris Lattner 
56530fdc8d8SChris Lattner CommandObjectBreakpointList::~CommandObjectBreakpointList ()
56630fdc8d8SChris Lattner {
56730fdc8d8SChris Lattner }
56830fdc8d8SChris Lattner 
56930fdc8d8SChris Lattner Options *
57030fdc8d8SChris Lattner CommandObjectBreakpointList::GetOptions ()
57130fdc8d8SChris Lattner {
57230fdc8d8SChris Lattner     return &m_options;
57330fdc8d8SChris Lattner }
57430fdc8d8SChris Lattner 
57530fdc8d8SChris Lattner bool
57630fdc8d8SChris Lattner CommandObjectBreakpointList::Execute
57730fdc8d8SChris Lattner (
57830fdc8d8SChris Lattner     Args& args,
57930fdc8d8SChris Lattner     CommandContext *context,
58030fdc8d8SChris Lattner     CommandInterpreter *interpreter,
58130fdc8d8SChris Lattner     CommandReturnObject &result
58230fdc8d8SChris Lattner )
58330fdc8d8SChris Lattner {
58430fdc8d8SChris Lattner     Target *target = context->GetTarget();
58530fdc8d8SChris Lattner     if (target == NULL)
58630fdc8d8SChris Lattner     {
58730fdc8d8SChris Lattner         result.AppendError ("Invalid target, set executable file using 'file' command.");
58830fdc8d8SChris Lattner         result.SetStatus (eReturnStatusSuccessFinishNoResult);
58930fdc8d8SChris Lattner         return true;
59030fdc8d8SChris Lattner     }
59130fdc8d8SChris Lattner 
59230fdc8d8SChris Lattner     const BreakpointList &breakpoints = target->GetBreakpointList(m_options.m_internal);
59330fdc8d8SChris Lattner     size_t num_breakpoints = breakpoints.GetSize();
59430fdc8d8SChris Lattner 
59530fdc8d8SChris Lattner     if (num_breakpoints == 0)
59630fdc8d8SChris Lattner     {
59730fdc8d8SChris Lattner         result.AppendMessage ("No breakpoints currently set.");
59830fdc8d8SChris Lattner         result.SetStatus (eReturnStatusSuccessFinishNoResult);
59930fdc8d8SChris Lattner         return true;
60030fdc8d8SChris Lattner     }
60130fdc8d8SChris Lattner 
60230fdc8d8SChris Lattner     StreamString &output_stream = result.GetOutputStream();
60330fdc8d8SChris Lattner 
60430fdc8d8SChris Lattner     if (args.GetArgumentCount() == 0)
60530fdc8d8SChris Lattner     {
60630fdc8d8SChris Lattner         // No breakpoint selected; show info about all currently set breakpoints.
60730fdc8d8SChris Lattner         result.AppendMessage ("Current breakpoints:");
60830fdc8d8SChris Lattner         for (int i = 0; i < num_breakpoints; ++i)
60930fdc8d8SChris Lattner         {
61030fdc8d8SChris Lattner             Breakpoint *breakpoint = breakpoints.GetBreakpointByIndex (i).get();
61130fdc8d8SChris Lattner             AddBreakpointDescription (context, &output_stream, breakpoint, m_options.m_level);
61230fdc8d8SChris Lattner         }
61330fdc8d8SChris Lattner         result.SetStatus (eReturnStatusSuccessFinishNoResult);
61430fdc8d8SChris Lattner     }
61530fdc8d8SChris Lattner     else
61630fdc8d8SChris Lattner     {
61730fdc8d8SChris Lattner         // Particular breakpoints selected; show info about that breakpoint.
61830fdc8d8SChris Lattner         BreakpointIDList valid_bp_ids;
61930fdc8d8SChris Lattner         CommandObjectMultiwordBreakpoint::VerifyBreakpointIDs (args, target, result, &valid_bp_ids);
62030fdc8d8SChris Lattner 
62130fdc8d8SChris Lattner         if (result.Succeeded())
62230fdc8d8SChris Lattner         {
62330fdc8d8SChris Lattner             for (int i = 0; i < valid_bp_ids.Size(); ++i)
62430fdc8d8SChris Lattner             {
62530fdc8d8SChris Lattner                 BreakpointID cur_bp_id = valid_bp_ids.GetBreakpointIDAtIndex (i);
62630fdc8d8SChris Lattner                 Breakpoint *breakpoint = target->GetBreakpointByID (cur_bp_id.GetBreakpointID()).get();
62730fdc8d8SChris Lattner                 AddBreakpointDescription (context, &output_stream, breakpoint, m_options.m_level);
62830fdc8d8SChris Lattner             }
62930fdc8d8SChris Lattner             result.SetStatus (eReturnStatusSuccessFinishNoResult);
63030fdc8d8SChris Lattner         }
63130fdc8d8SChris Lattner         else
63230fdc8d8SChris Lattner         {
63330fdc8d8SChris Lattner             result.AppendError ("Invalid breakpoint id.");
63430fdc8d8SChris Lattner             result.SetStatus (eReturnStatusFailed);
63530fdc8d8SChris Lattner         }
63630fdc8d8SChris Lattner     }
63730fdc8d8SChris Lattner 
63830fdc8d8SChris Lattner     return result.Succeeded();
63930fdc8d8SChris Lattner }
64030fdc8d8SChris Lattner 
64130fdc8d8SChris Lattner //-------------------------------------------------------------------------
64230fdc8d8SChris Lattner // CommandObjectBreakpointEnable
64330fdc8d8SChris Lattner //-------------------------------------------------------------------------
64430fdc8d8SChris Lattner 
64530fdc8d8SChris Lattner CommandObjectBreakpointEnable::CommandObjectBreakpointEnable () :
64630fdc8d8SChris Lattner     CommandObject ("enable",
64730fdc8d8SChris Lattner                      "Enables the specified disabled breakpoint(s).  If no breakpoints are specified, enables all of them.",
64830fdc8d8SChris Lattner                      "breakpoint enable [<breakpoint-id> | <breakpoint-id-list>]")
64930fdc8d8SChris Lattner {
65030fdc8d8SChris Lattner     // This command object can either be called via 'enable' or 'breakpoint enable'.  Because it has two different
65130fdc8d8SChris Lattner     // potential invocation methods, we need to be a little tricky about generating the syntax string.
65230fdc8d8SChris Lattner     //StreamString tmp_string;
65330fdc8d8SChris Lattner     //tmp_string.Printf ("%s <breakpoint-id>", GetCommandName());
65430fdc8d8SChris Lattner     //m_cmd_syntax.assign (tmp_string.GetData(), tmp_string.GetSize());
65530fdc8d8SChris Lattner }
65630fdc8d8SChris Lattner 
65730fdc8d8SChris Lattner 
65830fdc8d8SChris Lattner CommandObjectBreakpointEnable::~CommandObjectBreakpointEnable ()
65930fdc8d8SChris Lattner {
66030fdc8d8SChris Lattner }
66130fdc8d8SChris Lattner 
66230fdc8d8SChris Lattner 
66330fdc8d8SChris Lattner bool
66430fdc8d8SChris Lattner CommandObjectBreakpointEnable::Execute (Args& args, CommandContext *context,
66530fdc8d8SChris Lattner                                           CommandInterpreter *interpreter, CommandReturnObject &result)
66630fdc8d8SChris Lattner {
66730fdc8d8SChris Lattner     Target *target = context->GetTarget();
66830fdc8d8SChris Lattner     if (target == NULL)
66930fdc8d8SChris Lattner     {
67030fdc8d8SChris Lattner         result.AppendError ("Invalid target, set executable file using 'file' command.");
67130fdc8d8SChris Lattner         result.SetStatus (eReturnStatusFailed);
67230fdc8d8SChris Lattner         return false;
67330fdc8d8SChris Lattner     }
67430fdc8d8SChris Lattner 
67530fdc8d8SChris Lattner     const BreakpointList &breakpoints = target->GetBreakpointList();
67630fdc8d8SChris Lattner     size_t num_breakpoints = breakpoints.GetSize();
67730fdc8d8SChris Lattner 
67830fdc8d8SChris Lattner     if (num_breakpoints == 0)
67930fdc8d8SChris Lattner     {
68030fdc8d8SChris Lattner         result.AppendError ("No breakpoints exist to be enabled.");
68130fdc8d8SChris Lattner         result.SetStatus (eReturnStatusFailed);
68230fdc8d8SChris Lattner         return false;
68330fdc8d8SChris Lattner     }
68430fdc8d8SChris Lattner 
68530fdc8d8SChris Lattner     if (args.GetArgumentCount() == 0)
68630fdc8d8SChris Lattner     {
68730fdc8d8SChris Lattner         // No breakpoint selected; enable all currently set breakpoints.
68830fdc8d8SChris Lattner         target->EnableAllBreakpoints ();
68930fdc8d8SChris Lattner         result.AppendMessageWithFormat ("All breakpoints enabled. (%d breakpoints)\n", num_breakpoints);
69030fdc8d8SChris Lattner         result.SetStatus (eReturnStatusSuccessFinishNoResult);
69130fdc8d8SChris Lattner     }
69230fdc8d8SChris Lattner     else
69330fdc8d8SChris Lattner     {
69430fdc8d8SChris Lattner         // Particular breakpoint selected; enable that breakpoint.
69530fdc8d8SChris Lattner         BreakpointIDList valid_bp_ids;
69630fdc8d8SChris Lattner         CommandObjectMultiwordBreakpoint::VerifyBreakpointIDs (args, target, result, &valid_bp_ids);
69730fdc8d8SChris Lattner 
69830fdc8d8SChris Lattner         if (result.Succeeded())
69930fdc8d8SChris Lattner         {
70030fdc8d8SChris Lattner             int enable_count = 0;
70130fdc8d8SChris Lattner             int loc_count = 0;
70230fdc8d8SChris Lattner             for (int i = 0; i < valid_bp_ids.Size(); ++i)
70330fdc8d8SChris Lattner             {
70430fdc8d8SChris Lattner                 BreakpointID cur_bp_id = valid_bp_ids.GetBreakpointIDAtIndex (i);
70530fdc8d8SChris Lattner 
70630fdc8d8SChris Lattner                 if (cur_bp_id.GetBreakpointID() != LLDB_INVALID_BREAK_ID)
70730fdc8d8SChris Lattner                 {
70830fdc8d8SChris Lattner                     Breakpoint *breakpoint = target->GetBreakpointByID (cur_bp_id.GetBreakpointID()).get();
70930fdc8d8SChris Lattner                     if (cur_bp_id.GetLocationID() != LLDB_INVALID_BREAK_ID)
71030fdc8d8SChris Lattner                     {
71130fdc8d8SChris Lattner                         BreakpointLocation *location = breakpoint->FindLocationByID (cur_bp_id.GetLocationID()).get();
71230fdc8d8SChris Lattner                         if (location)
71330fdc8d8SChris Lattner                         {
71430fdc8d8SChris Lattner                             location->SetEnabled (true);
71530fdc8d8SChris Lattner                             breakpoint->SetEnabled (true);
71630fdc8d8SChris Lattner                             ++loc_count;
71730fdc8d8SChris Lattner                         }
71830fdc8d8SChris Lattner                     }
71930fdc8d8SChris Lattner                     else
72030fdc8d8SChris Lattner                     {
72130fdc8d8SChris Lattner                         target->EnableBreakpointByID (cur_bp_id.GetBreakpointID());
72230fdc8d8SChris Lattner                         ++enable_count;
72330fdc8d8SChris Lattner 
72430fdc8d8SChris Lattner                         int num_locations = breakpoint->GetNumLocations ();
72530fdc8d8SChris Lattner                         for (int j = 0; j < num_locations; ++j)
72630fdc8d8SChris Lattner                         {
72730fdc8d8SChris Lattner                             BreakpointLocation *cur_loc = breakpoint->GetLocationAtIndex(j).get();
72830fdc8d8SChris Lattner                             if (cur_loc)
72930fdc8d8SChris Lattner                                 cur_loc->SetEnabled (true);
73030fdc8d8SChris Lattner                         }
73130fdc8d8SChris Lattner                     }
73230fdc8d8SChris Lattner                 }
73330fdc8d8SChris Lattner             }
73430fdc8d8SChris Lattner             result.AppendMessageWithFormat ("%d breakpoints enabled.\n", enable_count + loc_count);
73530fdc8d8SChris Lattner             result.SetStatus (eReturnStatusSuccessFinishNoResult);
73630fdc8d8SChris Lattner         }
73730fdc8d8SChris Lattner     }
73830fdc8d8SChris Lattner 
73930fdc8d8SChris Lattner     return result.Succeeded();
74030fdc8d8SChris Lattner }
74130fdc8d8SChris Lattner 
74230fdc8d8SChris Lattner //-------------------------------------------------------------------------
74330fdc8d8SChris Lattner // CommandObjectBreakpointDisable
74430fdc8d8SChris Lattner //-------------------------------------------------------------------------
74530fdc8d8SChris Lattner 
74630fdc8d8SChris Lattner CommandObjectBreakpointDisable::CommandObjectBreakpointDisable () :
74730fdc8d8SChris Lattner     CommandObject ("disable",
74830fdc8d8SChris Lattner                    "Disables the specified breakpoint(s) without removing it/them.  If no breakpoints are specified, disables them all.",
74930fdc8d8SChris Lattner                    "disable [<breakpoint-id> | <breakpoint-id-list>]")
75030fdc8d8SChris Lattner {
75130fdc8d8SChris Lattner     // This command object can either be called via 'enable' or 'breakpoint enable'.  Because it has two different
75230fdc8d8SChris Lattner     // potential invocation methods, we need to be a little tricky about generating the syntax string.
75330fdc8d8SChris Lattner     //StreamString tmp_string;
75430fdc8d8SChris Lattner     //tmp_string.Printf ("%s <breakpoint-id>", GetCommandName());
75530fdc8d8SChris Lattner     //m_cmd_syntax.assign(tmp_string.GetData(), tmp_string.GetSize());
75630fdc8d8SChris Lattner }
75730fdc8d8SChris Lattner 
75830fdc8d8SChris Lattner CommandObjectBreakpointDisable::~CommandObjectBreakpointDisable ()
75930fdc8d8SChris Lattner {
76030fdc8d8SChris Lattner }
76130fdc8d8SChris Lattner 
76230fdc8d8SChris Lattner bool
76330fdc8d8SChris Lattner CommandObjectBreakpointDisable::Execute (Args& args, CommandContext *context,
76430fdc8d8SChris Lattner                                            CommandInterpreter *interpreter, CommandReturnObject &result)
76530fdc8d8SChris Lattner {
76630fdc8d8SChris Lattner     Target *target = context->GetTarget();
76730fdc8d8SChris Lattner     if (target == NULL)
76830fdc8d8SChris Lattner     {
76930fdc8d8SChris Lattner         result.AppendError ("Invalid target, set executable file using 'file' command.");
77030fdc8d8SChris Lattner         result.SetStatus (eReturnStatusFailed);
77130fdc8d8SChris Lattner         return false;
77230fdc8d8SChris Lattner     }
77330fdc8d8SChris Lattner 
77430fdc8d8SChris Lattner     const BreakpointList &breakpoints = target->GetBreakpointList();
77530fdc8d8SChris Lattner     size_t num_breakpoints = breakpoints.GetSize();
77630fdc8d8SChris Lattner 
77730fdc8d8SChris Lattner     if (num_breakpoints == 0)
77830fdc8d8SChris Lattner     {
77930fdc8d8SChris Lattner         result.AppendError ("No breakpoints exist to be disabled.");
78030fdc8d8SChris Lattner         result.SetStatus (eReturnStatusFailed);
78130fdc8d8SChris Lattner         return false;
78230fdc8d8SChris Lattner     }
78330fdc8d8SChris Lattner 
78430fdc8d8SChris Lattner     if (args.GetArgumentCount() == 0)
78530fdc8d8SChris Lattner     {
78630fdc8d8SChris Lattner         // No breakpoint selected; disable all currently set breakpoints.
78730fdc8d8SChris Lattner         target->DisableAllBreakpoints ();
78830fdc8d8SChris Lattner         result.AppendMessageWithFormat ("All breakpoints disabled. (%d breakpoints)\n", num_breakpoints);
78930fdc8d8SChris Lattner         result.SetStatus (eReturnStatusSuccessFinishNoResult);
79030fdc8d8SChris Lattner     }
79130fdc8d8SChris Lattner     else
79230fdc8d8SChris Lattner     {
79330fdc8d8SChris Lattner         // Particular breakpoint selected; disable that breakpoint.
79430fdc8d8SChris Lattner         BreakpointIDList valid_bp_ids;
79530fdc8d8SChris Lattner 
79630fdc8d8SChris Lattner         CommandObjectMultiwordBreakpoint::VerifyBreakpointIDs (args, target, result, &valid_bp_ids);
79730fdc8d8SChris Lattner 
79830fdc8d8SChris Lattner         if (result.Succeeded())
79930fdc8d8SChris Lattner         {
80030fdc8d8SChris Lattner             int disable_count = 0;
80130fdc8d8SChris Lattner             int loc_count = 0;
80230fdc8d8SChris Lattner             for (int i = 0; i < valid_bp_ids.Size(); ++i)
80330fdc8d8SChris Lattner             {
80430fdc8d8SChris Lattner                 BreakpointID cur_bp_id = valid_bp_ids.GetBreakpointIDAtIndex (i);
80530fdc8d8SChris Lattner 
80630fdc8d8SChris Lattner                 if (cur_bp_id.GetBreakpointID() != LLDB_INVALID_BREAK_ID)
80730fdc8d8SChris Lattner                 {
80830fdc8d8SChris Lattner                     Breakpoint *breakpoint = target->GetBreakpointByID (cur_bp_id.GetBreakpointID()).get();
80930fdc8d8SChris Lattner                     if (cur_bp_id.GetLocationID() != LLDB_INVALID_BREAK_ID)
81030fdc8d8SChris Lattner                     {
81130fdc8d8SChris Lattner                         BreakpointLocation *location = breakpoint->FindLocationByID (cur_bp_id.GetLocationID()).get();
81230fdc8d8SChris Lattner                         if (location)
81330fdc8d8SChris Lattner                         {
81430fdc8d8SChris Lattner                             location->SetEnabled (false);
81530fdc8d8SChris Lattner                             ++loc_count;
81630fdc8d8SChris Lattner                         }
81730fdc8d8SChris Lattner                     }
81830fdc8d8SChris Lattner                     else
81930fdc8d8SChris Lattner                     {
82030fdc8d8SChris Lattner                         target->DisableBreakpointByID (cur_bp_id.GetBreakpointID());
82130fdc8d8SChris Lattner                         ++disable_count;
82230fdc8d8SChris Lattner 
82330fdc8d8SChris Lattner                         int num_locations = breakpoint->GetNumLocations();
82430fdc8d8SChris Lattner                         for (int j = 0; j < num_locations; ++j)
82530fdc8d8SChris Lattner                         {
82630fdc8d8SChris Lattner                             BreakpointLocation *cur_loc = breakpoint->GetLocationAtIndex(j).get();
82730fdc8d8SChris Lattner                             if (cur_loc)
82830fdc8d8SChris Lattner                                 cur_loc->SetEnabled (false);
82930fdc8d8SChris Lattner                         }
83030fdc8d8SChris Lattner                     }
83130fdc8d8SChris Lattner                 }
83230fdc8d8SChris Lattner             }
83330fdc8d8SChris Lattner             result.AppendMessageWithFormat ("%d breakpoints disabled.\n", disable_count + loc_count);
83430fdc8d8SChris Lattner             result.SetStatus (eReturnStatusSuccessFinishNoResult);
83530fdc8d8SChris Lattner         }
83630fdc8d8SChris Lattner     }
83730fdc8d8SChris Lattner 
83830fdc8d8SChris Lattner     return result.Succeeded();
83930fdc8d8SChris Lattner }
84030fdc8d8SChris Lattner 
84130fdc8d8SChris Lattner //-------------------------------------------------------------------------
84230fdc8d8SChris Lattner // CommandObjectBreakpointDelete
84330fdc8d8SChris Lattner //-------------------------------------------------------------------------
84430fdc8d8SChris Lattner 
84530fdc8d8SChris Lattner CommandObjectBreakpointDelete::CommandObjectBreakpointDelete() :
84630fdc8d8SChris Lattner     CommandObject ("breakpoint delete",
84730fdc8d8SChris Lattner                    "Delete the specified breakpoint(s).  If no breakpoints are specified, deletes them all.",
84830fdc8d8SChris Lattner                    "breakpoint delete [<breakpoint-id> | <breakpoint-id-list>]")
84930fdc8d8SChris Lattner {
85030fdc8d8SChris Lattner }
85130fdc8d8SChris Lattner 
85230fdc8d8SChris Lattner 
85330fdc8d8SChris Lattner CommandObjectBreakpointDelete::~CommandObjectBreakpointDelete ()
85430fdc8d8SChris Lattner {
85530fdc8d8SChris Lattner }
85630fdc8d8SChris Lattner 
85730fdc8d8SChris Lattner bool
85830fdc8d8SChris Lattner CommandObjectBreakpointDelete::Execute (Args& args, CommandContext *context,
85930fdc8d8SChris Lattner                                           CommandInterpreter *interpreter, CommandReturnObject &result)
86030fdc8d8SChris Lattner {
86130fdc8d8SChris Lattner     Target *target = context->GetTarget();
86230fdc8d8SChris Lattner     if (target == NULL)
86330fdc8d8SChris Lattner     {
86430fdc8d8SChris Lattner         result.AppendError ("Invalid target, set executable file using 'file' command.");
86530fdc8d8SChris Lattner         result.SetStatus (eReturnStatusFailed);
86630fdc8d8SChris Lattner         return false;
86730fdc8d8SChris Lattner     }
86830fdc8d8SChris Lattner 
86930fdc8d8SChris Lattner     const BreakpointList &breakpoints = target->GetBreakpointList();
87030fdc8d8SChris Lattner     size_t num_breakpoints = breakpoints.GetSize();
87130fdc8d8SChris Lattner 
87230fdc8d8SChris Lattner     if (num_breakpoints == 0)
87330fdc8d8SChris Lattner     {
87430fdc8d8SChris Lattner         result.AppendError ("No breakpoints exist to be deleted.");
87530fdc8d8SChris Lattner         result.SetStatus (eReturnStatusFailed);
87630fdc8d8SChris Lattner         return false;
87730fdc8d8SChris Lattner     }
87830fdc8d8SChris Lattner 
87930fdc8d8SChris Lattner     if (args.GetArgumentCount() == 0)
88030fdc8d8SChris Lattner     {
88130fdc8d8SChris Lattner         // No breakpoint selected; disable all currently set breakpoints.
88230fdc8d8SChris Lattner         if (args.GetArgumentCount() != 0)
88330fdc8d8SChris Lattner         {
88430fdc8d8SChris Lattner             result.AppendErrorWithFormat ("Specify breakpoints to delete with the -i option.\n");
88530fdc8d8SChris Lattner             result.SetStatus (eReturnStatusFailed);
88630fdc8d8SChris Lattner             return false;
88730fdc8d8SChris Lattner         }
88830fdc8d8SChris Lattner 
88930fdc8d8SChris Lattner         target->RemoveAllBreakpoints ();
89030fdc8d8SChris Lattner         result.AppendMessageWithFormat ("All breakpoints removed. (%d breakpoints)\n", num_breakpoints);
89130fdc8d8SChris Lattner         result.SetStatus (eReturnStatusSuccessFinishNoResult);
89230fdc8d8SChris Lattner     }
89330fdc8d8SChris Lattner     else
89430fdc8d8SChris Lattner     {
89530fdc8d8SChris Lattner         // Particular breakpoint selected; disable that breakpoint.
89630fdc8d8SChris Lattner         BreakpointIDList valid_bp_ids;
89730fdc8d8SChris Lattner         CommandObjectMultiwordBreakpoint::VerifyBreakpointIDs (args, target, result, &valid_bp_ids);
89830fdc8d8SChris Lattner 
89930fdc8d8SChris Lattner         if (result.Succeeded())
90030fdc8d8SChris Lattner         {
90130fdc8d8SChris Lattner             int delete_count = 0;
90230fdc8d8SChris Lattner             int disable_count = 0;
90330fdc8d8SChris Lattner             for (int i = 0; i < valid_bp_ids.Size(); ++i)
90430fdc8d8SChris Lattner             {
90530fdc8d8SChris Lattner                 BreakpointID cur_bp_id = valid_bp_ids.GetBreakpointIDAtIndex (i);
90630fdc8d8SChris Lattner 
90730fdc8d8SChris Lattner                 if (cur_bp_id.GetBreakpointID() != LLDB_INVALID_BREAK_ID)
90830fdc8d8SChris Lattner                 {
90930fdc8d8SChris Lattner                     if (cur_bp_id.GetLocationID() != LLDB_INVALID_BREAK_ID)
91030fdc8d8SChris Lattner                     {
91130fdc8d8SChris Lattner                         Breakpoint *breakpoint = target->GetBreakpointByID (cur_bp_id.GetBreakpointID()).get();
91230fdc8d8SChris Lattner                         BreakpointLocation *location = breakpoint->FindLocationByID (cur_bp_id.GetLocationID()).get();
91330fdc8d8SChris Lattner                         // It makes no sense to try to delete individual locations, so we disable them instead.
91430fdc8d8SChris Lattner                         if (location)
91530fdc8d8SChris Lattner                         {
91630fdc8d8SChris Lattner                             location->SetEnabled (false);
91730fdc8d8SChris Lattner                             ++disable_count;
91830fdc8d8SChris Lattner                         }
91930fdc8d8SChris Lattner                     }
92030fdc8d8SChris Lattner                     else
92130fdc8d8SChris Lattner                     {
92230fdc8d8SChris Lattner                         target->RemoveBreakpointByID (cur_bp_id.GetBreakpointID());
92330fdc8d8SChris Lattner                         ++delete_count;
92430fdc8d8SChris Lattner                     }
92530fdc8d8SChris Lattner                 }
92630fdc8d8SChris Lattner             }
92730fdc8d8SChris Lattner             result.AppendMessageWithFormat ("%d breakpoints deleted; %d breakpoint locations disabled.\n",
92830fdc8d8SChris Lattner                                            delete_count, disable_count);
92930fdc8d8SChris Lattner             result.SetStatus (eReturnStatusSuccessFinishNoResult);
93030fdc8d8SChris Lattner         }
93130fdc8d8SChris Lattner     }
93230fdc8d8SChris Lattner     return result.Succeeded();
93330fdc8d8SChris Lattner }
934