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"
2040af72e1SJim 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"
281b54c88cSJim Ingham #include "lldb/Target/Thread.h"
291b54c88cSJim Ingham #include "lldb/Target/ThreadSpec.h"
3030fdc8d8SChris Lattner 
3130fdc8d8SChris Lattner using namespace lldb;
3230fdc8d8SChris Lattner using namespace lldb_private;
3330fdc8d8SChris Lattner 
3430fdc8d8SChris Lattner static void
356611103cSGreg Clayton AddBreakpointDescription (StreamString *s, Breakpoint *bp, lldb::DescriptionLevel level)
3630fdc8d8SChris Lattner {
3730fdc8d8SChris Lattner     s->IndentMore();
3830fdc8d8SChris Lattner     bp->GetDescription (s, level, true);
3930fdc8d8SChris Lattner     s->IndentLess();
4030fdc8d8SChris Lattner     s->EOL();
4130fdc8d8SChris Lattner }
4230fdc8d8SChris Lattner 
4330fdc8d8SChris Lattner //-------------------------------------------------------------------------
4430fdc8d8SChris Lattner // CommandObjectBreakpointSet::CommandOptions
4530fdc8d8SChris Lattner //-------------------------------------------------------------------------
46ae1c4cf5SJim Ingham #pragma mark Set::CommandOptions
4730fdc8d8SChris Lattner 
4830fdc8d8SChris Lattner CommandObjectBreakpointSet::CommandOptions::CommandOptions() :
4930fdc8d8SChris Lattner     Options (),
5030fdc8d8SChris Lattner     m_filename (),
5130fdc8d8SChris Lattner     m_line_num (0),
5230fdc8d8SChris Lattner     m_column (0),
5330fdc8d8SChris Lattner     m_ignore_inlines (false),
5430fdc8d8SChris Lattner     m_func_name (),
55*0c5cd90dSGreg Clayton     m_func_name_type_mask (0),
5630fdc8d8SChris Lattner     m_func_regexp (),
5730fdc8d8SChris Lattner     m_modules (),
581b54c88cSJim Ingham     m_load_addr(),
591b54c88cSJim Ingham     m_thread_id(LLDB_INVALID_THREAD_ID),
601b54c88cSJim Ingham     m_thread_index (-1),
611b54c88cSJim Ingham     m_thread_name(),
621b54c88cSJim Ingham     m_queue_name(),
631b54c88cSJim Ingham     m_ignore_count (-1)
6430fdc8d8SChris Lattner {
6530fdc8d8SChris Lattner }
6630fdc8d8SChris Lattner 
6730fdc8d8SChris Lattner CommandObjectBreakpointSet::CommandOptions::~CommandOptions ()
6830fdc8d8SChris Lattner {
6930fdc8d8SChris Lattner }
7030fdc8d8SChris Lattner 
7130fdc8d8SChris Lattner lldb::OptionDefinition
7230fdc8d8SChris Lattner CommandObjectBreakpointSet::CommandOptions::g_option_table[] =
7330fdc8d8SChris Lattner {
748651121cSJim Ingham     { LLDB_OPT_SET_ALL, false, "shlib", 's', required_argument, NULL, CommandCompletions::eModuleCompletion, "<shlib-name>",
758651121cSJim Ingham         "Set the breakpoint only in this shared library (can use this option multiple times for multiple shlibs)."},
768651121cSJim Ingham 
77*0c5cd90dSGreg Clayton     { LLDB_OPT_SET_ALL, false, "ignore_count", 'k', required_argument,   NULL, 0, "<n>",
781b54c88cSJim Ingham         "Set the number of times this breakpoint is sKipped before stopping." },
791b54c88cSJim Ingham 
801b54c88cSJim Ingham     { LLDB_OPT_SET_ALL, false, "thread_index", 'x', required_argument, NULL, NULL, "<thread_index>",
811b54c88cSJim Ingham         "The breakpoint stops only for the thread whose indeX matches this argument."},
821b54c88cSJim Ingham 
831b54c88cSJim Ingham     { LLDB_OPT_SET_ALL, false, "thread_id", 't', required_argument, NULL, NULL, "<thread_id>",
841b54c88cSJim Ingham         "The breakpoint stops only for the thread whose TID matches this argument."},
851b54c88cSJim Ingham 
861b54c88cSJim Ingham     { LLDB_OPT_SET_ALL, false, "thread_name", 'T', required_argument, NULL, NULL, "<thread_name>",
871b54c88cSJim Ingham         "The breakpoint stops only for the thread whose thread name matches this argument."},
881b54c88cSJim Ingham 
891b54c88cSJim Ingham     { LLDB_OPT_SET_ALL, false, "queue_name", 'q', required_argument, NULL, NULL, "<queue_name>",
901b54c88cSJim Ingham         "The breakpoint stops only for threads in the queue whose name is given by this argument."},
911b54c88cSJim Ingham 
928651121cSJim Ingham     { LLDB_OPT_SET_1, false, "file", 'f', required_argument, NULL, CommandCompletions::eSourceFileCompletion, "<filename>",
9330fdc8d8SChris Lattner         "Set the breakpoint by source location in this particular file."},
9430fdc8d8SChris Lattner 
958651121cSJim Ingham     { LLDB_OPT_SET_1, true, "line", 'l', required_argument, NULL, 0, "<linenum>",
9630fdc8d8SChris Lattner         "Set the breakpoint by source location at this particular line."},
9730fdc8d8SChris Lattner 
9830fdc8d8SChris Lattner     // Comment out this option for the moment, as we don't actually use it, but will in the future.
9930fdc8d8SChris Lattner     // This way users won't see it, but the infrastructure is left in place.
10030fdc8d8SChris Lattner     //    { 0, false, "column",     'c', required_argument, NULL, "<column>",
10130fdc8d8SChris Lattner     //    "Set the breakpoint by source location at this particular column."},
10230fdc8d8SChris Lattner 
1038651121cSJim Ingham     { LLDB_OPT_SET_2, true, "address", 'a', required_argument, NULL, 0, "<address>",
10430fdc8d8SChris Lattner         "Set the breakpoint by address, at the specified address."},
10530fdc8d8SChris Lattner 
106*0c5cd90dSGreg Clayton     { LLDB_OPT_SET_3, true, "name", 'n', required_argument, NULL, CommandCompletions::eSymbolCompletion, "<name>",
10730fdc8d8SChris Lattner         "Set the breakpoint by function name." },
10830fdc8d8SChris Lattner 
109*0c5cd90dSGreg Clayton     { LLDB_OPT_SET_3, false, "basename", 'b', no_argument, NULL, 0, NULL,
110*0c5cd90dSGreg Clayton         "Used in conjuction with --name <name> to search function basenames." },
111*0c5cd90dSGreg Clayton 
112*0c5cd90dSGreg Clayton     { LLDB_OPT_SET_3, false, "fullname", 'F', no_argument, NULL, 0, NULL,
113*0c5cd90dSGreg Clayton         "Used in conjuction with --name <name> to search fully qualified function names. For C++ this means namespaces and all arguemnts, and for Objective C this means a full function prototype with class and selector." },
114*0c5cd90dSGreg Clayton 
115*0c5cd90dSGreg Clayton     { LLDB_OPT_SET_3, false, "selector", 'S', no_argument, NULL, 0, NULL,
116*0c5cd90dSGreg Clayton         "Used in conjuction with --name <name> to search objective C selector names." },
117*0c5cd90dSGreg Clayton 
118*0c5cd90dSGreg Clayton     { LLDB_OPT_SET_3, false, "method", 'm', no_argument, NULL, 0, NULL,
119*0c5cd90dSGreg Clayton         "Used in conjuction with --name <name> to search objective C selector C++ method names." },
120*0c5cd90dSGreg Clayton 
1218651121cSJim Ingham     { LLDB_OPT_SET_4, true, "func_regex", 'r', required_argument, NULL, 0, "<regular-expression>",
12230fdc8d8SChris Lattner         "Set the breakpoint by function name, evaluating a regular-expression to find the function name(s)." },
12330fdc8d8SChris Lattner 
12430fdc8d8SChris Lattner     { 0, false, NULL, 0, 0, NULL, 0, NULL, NULL }
12530fdc8d8SChris Lattner };
12630fdc8d8SChris Lattner 
12730fdc8d8SChris Lattner const lldb::OptionDefinition*
12830fdc8d8SChris Lattner CommandObjectBreakpointSet::CommandOptions::GetDefinitions ()
12930fdc8d8SChris Lattner {
13030fdc8d8SChris Lattner     return g_option_table;
13130fdc8d8SChris Lattner }
13230fdc8d8SChris Lattner 
13330fdc8d8SChris Lattner Error
13430fdc8d8SChris Lattner CommandObjectBreakpointSet::CommandOptions::SetOptionValue (int option_idx, const char *option_arg)
13530fdc8d8SChris Lattner {
13630fdc8d8SChris Lattner     Error error;
13730fdc8d8SChris Lattner     char short_option = (char) m_getopt_table[option_idx].val;
13830fdc8d8SChris Lattner 
13930fdc8d8SChris Lattner     switch (short_option)
14030fdc8d8SChris Lattner     {
14130fdc8d8SChris Lattner         case 'a':
14230fdc8d8SChris Lattner             m_load_addr = Args::StringToUInt64(optarg, LLDB_INVALID_ADDRESS, 0);
14330fdc8d8SChris Lattner             if (m_load_addr == LLDB_INVALID_ADDRESS)
14430fdc8d8SChris Lattner                 m_load_addr = Args::StringToUInt64(optarg, LLDB_INVALID_ADDRESS, 16);
14530fdc8d8SChris Lattner 
14630fdc8d8SChris Lattner             if (m_load_addr == LLDB_INVALID_ADDRESS)
14730fdc8d8SChris Lattner                 error.SetErrorStringWithFormat ("Invalid address string '%s'.\n", optarg);
14830fdc8d8SChris Lattner             break;
14930fdc8d8SChris Lattner 
15030fdc8d8SChris Lattner         case 'c':
15130fdc8d8SChris Lattner             m_column = Args::StringToUInt32 (option_arg, 0);
15230fdc8d8SChris Lattner             break;
153*0c5cd90dSGreg Clayton 
15430fdc8d8SChris Lattner         case 'f':
15530fdc8d8SChris Lattner             m_filename = option_arg;
15630fdc8d8SChris Lattner             break;
157*0c5cd90dSGreg Clayton 
15830fdc8d8SChris Lattner         case 'l':
15930fdc8d8SChris Lattner             m_line_num = Args::StringToUInt32 (option_arg, 0);
16030fdc8d8SChris Lattner             break;
161*0c5cd90dSGreg Clayton 
16230fdc8d8SChris Lattner         case 'n':
16330fdc8d8SChris Lattner             m_func_name = option_arg;
16430fdc8d8SChris Lattner             break;
165*0c5cd90dSGreg Clayton 
166*0c5cd90dSGreg Clayton         case 'b':
167*0c5cd90dSGreg Clayton             m_func_name_type_mask |= eFunctionNameTypeBase;
168*0c5cd90dSGreg Clayton             break;
169*0c5cd90dSGreg Clayton 
170*0c5cd90dSGreg Clayton         case 'F':
171*0c5cd90dSGreg Clayton             m_func_name_type_mask |= eFunctionNameTypeFull;
172*0c5cd90dSGreg Clayton             break;
173*0c5cd90dSGreg Clayton 
174*0c5cd90dSGreg Clayton         case 'S':
175*0c5cd90dSGreg Clayton             m_func_name_type_mask |= eFunctionNameTypeSelector;
176*0c5cd90dSGreg Clayton             break;
177*0c5cd90dSGreg Clayton 
178*0c5cd90dSGreg Clayton         case 'm':
179*0c5cd90dSGreg Clayton             m_func_name_type_mask |= eFunctionNameTypeMethod;
180*0c5cd90dSGreg Clayton             break;
181*0c5cd90dSGreg Clayton 
18230fdc8d8SChris Lattner         case 'r':
18330fdc8d8SChris Lattner             m_func_regexp = option_arg;
18430fdc8d8SChris Lattner             break;
185*0c5cd90dSGreg Clayton 
18630fdc8d8SChris Lattner         case 's':
18730fdc8d8SChris Lattner             {
18830fdc8d8SChris Lattner                 m_modules.push_back (std::string (option_arg));
18930fdc8d8SChris Lattner                 break;
19030fdc8d8SChris Lattner             }
1911b54c88cSJim Ingham         case 'k':
1921b54c88cSJim Ingham         {
1931b54c88cSJim Ingham             m_ignore_count = Args::StringToSInt32(optarg, -1, 0);
1941b54c88cSJim Ingham             if (m_ignore_count == -1)
1951b54c88cSJim Ingham                error.SetErrorStringWithFormat ("Invalid ignore count '%s'.\n", optarg);
1961b54c88cSJim Ingham         }
197ae1c4cf5SJim Ingham         break;
1981b54c88cSJim Ingham         case 't' :
1991b54c88cSJim Ingham         {
2001b54c88cSJim Ingham             m_thread_id = Args::StringToUInt64(optarg, LLDB_INVALID_THREAD_ID, 0);
2011b54c88cSJim Ingham             if (m_thread_id == LLDB_INVALID_THREAD_ID)
2021b54c88cSJim Ingham                error.SetErrorStringWithFormat ("Invalid thread id string '%s'.\n", optarg);
2031b54c88cSJim Ingham         }
2041b54c88cSJim Ingham         break;
2051b54c88cSJim Ingham         case 'T':
2061b54c88cSJim Ingham             m_thread_name = option_arg;
2071b54c88cSJim Ingham             break;
2081b54c88cSJim Ingham         case 'q':
2091b54c88cSJim Ingham             m_queue_name = option_arg;
2101b54c88cSJim Ingham             break;
2111b54c88cSJim Ingham         case 'x':
2121b54c88cSJim Ingham         {
2131b54c88cSJim Ingham             m_thread_index = Args::StringToUInt64(optarg, -1, 0);
2141b54c88cSJim Ingham             if (m_thread_id == -1)
2151b54c88cSJim Ingham                error.SetErrorStringWithFormat ("Invalid thread index string '%s'.\n", optarg);
2161b54c88cSJim Ingham 
2171b54c88cSJim Ingham         }
2181b54c88cSJim Ingham         break;
21930fdc8d8SChris Lattner         default:
22030fdc8d8SChris Lattner             error.SetErrorStringWithFormat ("Unrecognized option '%c'.\n", short_option);
22130fdc8d8SChris Lattner             break;
22230fdc8d8SChris Lattner     }
22330fdc8d8SChris Lattner 
22430fdc8d8SChris Lattner     return error;
22530fdc8d8SChris Lattner }
22630fdc8d8SChris Lattner 
22730fdc8d8SChris Lattner void
22830fdc8d8SChris Lattner CommandObjectBreakpointSet::CommandOptions::ResetOptionValues ()
22930fdc8d8SChris Lattner {
23030fdc8d8SChris Lattner     Options::ResetOptionValues();
23130fdc8d8SChris Lattner 
23230fdc8d8SChris Lattner     m_filename.clear();
23330fdc8d8SChris Lattner     m_line_num = 0;
23430fdc8d8SChris Lattner     m_column = 0;
23530fdc8d8SChris Lattner     m_func_name.clear();
236*0c5cd90dSGreg Clayton     m_func_name_type_mask = 0;
23730fdc8d8SChris Lattner     m_func_regexp.clear();
23830fdc8d8SChris Lattner     m_load_addr = LLDB_INVALID_ADDRESS;
23930fdc8d8SChris Lattner     m_modules.clear();
2401b54c88cSJim Ingham     m_ignore_count = -1;
2411b54c88cSJim Ingham     m_thread_id = LLDB_INVALID_THREAD_ID;
2421b54c88cSJim Ingham     m_thread_index = -1;
2431b54c88cSJim Ingham     m_thread_name.clear();
2441b54c88cSJim Ingham     m_queue_name.clear();
24530fdc8d8SChris Lattner }
24630fdc8d8SChris Lattner 
24730fdc8d8SChris Lattner //-------------------------------------------------------------------------
24830fdc8d8SChris Lattner // CommandObjectBreakpointSet
24930fdc8d8SChris Lattner //-------------------------------------------------------------------------
250ae1c4cf5SJim Ingham #pragma mark Set
25130fdc8d8SChris Lattner 
25230fdc8d8SChris Lattner CommandObjectBreakpointSet::CommandObjectBreakpointSet () :
25330fdc8d8SChris Lattner     CommandObject ("breakpoint set", "Sets a breakpoint or set of breakpoints in the executable.",
25430fdc8d8SChris Lattner                    "breakpoint set <cmd-options>")
25530fdc8d8SChris Lattner {
25630fdc8d8SChris Lattner }
25730fdc8d8SChris Lattner 
25830fdc8d8SChris Lattner CommandObjectBreakpointSet::~CommandObjectBreakpointSet ()
25930fdc8d8SChris Lattner {
26030fdc8d8SChris Lattner }
26130fdc8d8SChris Lattner 
26230fdc8d8SChris Lattner Options *
26330fdc8d8SChris Lattner CommandObjectBreakpointSet::GetOptions ()
26430fdc8d8SChris Lattner {
26530fdc8d8SChris Lattner     return &m_options;
26630fdc8d8SChris Lattner }
26730fdc8d8SChris Lattner 
26830fdc8d8SChris Lattner bool
26930fdc8d8SChris Lattner CommandObjectBreakpointSet::Execute
27030fdc8d8SChris Lattner (
2716611103cSGreg Clayton     CommandInterpreter &interpreter,
27230fdc8d8SChris Lattner     Args& command,
27330fdc8d8SChris Lattner     CommandReturnObject &result
27430fdc8d8SChris Lattner )
27530fdc8d8SChris Lattner {
2766611103cSGreg Clayton     Target *target = interpreter.GetDebugger().GetCurrentTarget().get();
27730fdc8d8SChris Lattner     if (target == NULL)
27830fdc8d8SChris Lattner     {
27930fdc8d8SChris Lattner         result.AppendError ("Invalid target, set executable file using 'file' command.");
28030fdc8d8SChris Lattner         result.SetStatus (eReturnStatusFailed);
28130fdc8d8SChris Lattner         return false;
28230fdc8d8SChris Lattner     }
28330fdc8d8SChris Lattner 
28430fdc8d8SChris Lattner     // The following are the various types of breakpoints that could be set:
28530fdc8d8SChris Lattner     //   1).  -f -l -p  [-s -g]   (setting breakpoint by source location)
28630fdc8d8SChris Lattner     //   2).  -a  [-s -g]         (setting breakpoint by address)
28730fdc8d8SChris Lattner     //   3).  -n  [-s -g]         (setting breakpoint by function name)
28830fdc8d8SChris Lattner     //   4).  -r  [-s -g]         (setting breakpoint by function name regular expression)
28930fdc8d8SChris Lattner 
29030fdc8d8SChris Lattner     BreakpointSetType break_type = eSetTypeInvalid;
29130fdc8d8SChris Lattner 
29230fdc8d8SChris Lattner     if (m_options.m_line_num != 0)
29330fdc8d8SChris Lattner         break_type = eSetTypeFileAndLine;
29430fdc8d8SChris Lattner     else if (m_options.m_load_addr != LLDB_INVALID_ADDRESS)
29530fdc8d8SChris Lattner         break_type = eSetTypeAddress;
29630fdc8d8SChris Lattner     else if (!m_options.m_func_name.empty())
29730fdc8d8SChris Lattner         break_type = eSetTypeFunctionName;
29830fdc8d8SChris Lattner     else if  (!m_options.m_func_regexp.empty())
29930fdc8d8SChris Lattner         break_type = eSetTypeFunctionRegexp;
30030fdc8d8SChris Lattner 
30130fdc8d8SChris Lattner     ModuleSP module_sp = target->GetExecutableModule();
30230fdc8d8SChris Lattner     Breakpoint *bp = NULL;
30330fdc8d8SChris Lattner     FileSpec module;
30430fdc8d8SChris Lattner     bool use_module = false;
30530fdc8d8SChris Lattner     int num_modules = m_options.m_modules.size();
30630fdc8d8SChris Lattner 
30730fdc8d8SChris Lattner     if ((num_modules > 0) && (break_type != eSetTypeAddress))
30830fdc8d8SChris Lattner         use_module = true;
30930fdc8d8SChris Lattner 
31030fdc8d8SChris Lattner     switch (break_type)
31130fdc8d8SChris Lattner     {
31230fdc8d8SChris Lattner         case eSetTypeFileAndLine: // Breakpoint by source position
31330fdc8d8SChris Lattner         {
31430fdc8d8SChris Lattner             FileSpec file;
31530fdc8d8SChris Lattner             if (m_options.m_filename.empty())
31630fdc8d8SChris Lattner             {
3176611103cSGreg Clayton                 StackFrame *cur_frame = interpreter.GetDebugger().GetExecutionContext().frame;
31830fdc8d8SChris Lattner                 if (cur_frame == NULL)
31930fdc8d8SChris Lattner                 {
32030fdc8d8SChris Lattner                     result.AppendError ("Attempting to set breakpoint by line number alone with no selected frame.");
32130fdc8d8SChris Lattner                     result.SetStatus (eReturnStatusFailed);
32230fdc8d8SChris Lattner                     break;
32330fdc8d8SChris Lattner                 }
32430fdc8d8SChris Lattner                 else if (!cur_frame->HasDebugInformation())
32530fdc8d8SChris Lattner                 {
32630fdc8d8SChris Lattner                     result.AppendError ("Attempting to set breakpoint by line number alone but selected frame has no debug info.");
32730fdc8d8SChris Lattner                     result.SetStatus (eReturnStatusFailed);
32830fdc8d8SChris Lattner                     break;
32930fdc8d8SChris Lattner                 }
33030fdc8d8SChris Lattner                 else
33130fdc8d8SChris Lattner                 {
33230fdc8d8SChris Lattner                     const SymbolContext &context = cur_frame->GetSymbolContext(true);
33330fdc8d8SChris Lattner                     if (context.line_entry.file)
33430fdc8d8SChris Lattner                     {
33530fdc8d8SChris Lattner                         file = context.line_entry.file;
33630fdc8d8SChris Lattner                     }
33730fdc8d8SChris Lattner                     else if (context.comp_unit != NULL)
33830fdc8d8SChris Lattner                     {    file = context.comp_unit;
33930fdc8d8SChris Lattner                     }
34030fdc8d8SChris Lattner                     else
34130fdc8d8SChris Lattner                     {
34230fdc8d8SChris Lattner                         result.AppendError ("Attempting to set breakpoint by line number alone but can't find the file for the selected frame.");
34330fdc8d8SChris Lattner                         result.SetStatus (eReturnStatusFailed);
34430fdc8d8SChris Lattner                         break;
34530fdc8d8SChris Lattner                     }
34630fdc8d8SChris Lattner                 }
34730fdc8d8SChris Lattner             }
34830fdc8d8SChris Lattner             else
34930fdc8d8SChris Lattner             {
35030fdc8d8SChris Lattner                 file.SetFile(m_options.m_filename.c_str());
35130fdc8d8SChris Lattner             }
35230fdc8d8SChris Lattner 
35330fdc8d8SChris Lattner             if (use_module)
35430fdc8d8SChris Lattner             {
35530fdc8d8SChris Lattner                 for (int i = 0; i < num_modules; ++i)
35630fdc8d8SChris Lattner                 {
35730fdc8d8SChris Lattner                     module.SetFile(m_options.m_modules[i].c_str());
35830fdc8d8SChris Lattner                     bp = target->CreateBreakpoint (&module,
35930fdc8d8SChris Lattner                                                    file,
36030fdc8d8SChris Lattner                                                    m_options.m_line_num,
36130fdc8d8SChris Lattner                                                    m_options.m_ignore_inlines).get();
36230fdc8d8SChris Lattner                     if (bp)
36330fdc8d8SChris Lattner                     {
36430fdc8d8SChris Lattner                         StreamString &output_stream = result.GetOutputStream();
36530fdc8d8SChris Lattner                         output_stream.Printf ("Breakpoint created: ");
36630fdc8d8SChris Lattner                         bp->GetDescription(&output_stream, lldb::eDescriptionLevelBrief);
36730fdc8d8SChris Lattner                         output_stream.EOL();
36830fdc8d8SChris Lattner                         result.SetStatus (eReturnStatusSuccessFinishResult);
36930fdc8d8SChris Lattner                     }
37030fdc8d8SChris Lattner                     else
37130fdc8d8SChris Lattner                     {
37230fdc8d8SChris Lattner                         result.AppendErrorWithFormat("Breakpoint creation failed: No breakpoint created in module '%s'.\n",
37330fdc8d8SChris Lattner                                                     m_options.m_modules[i].c_str());
37430fdc8d8SChris Lattner                         result.SetStatus (eReturnStatusFailed);
37530fdc8d8SChris Lattner                     }
37630fdc8d8SChris Lattner                 }
37730fdc8d8SChris Lattner             }
37830fdc8d8SChris Lattner             else
37930fdc8d8SChris Lattner                 bp = target->CreateBreakpoint (NULL,
38030fdc8d8SChris Lattner                                                file,
38130fdc8d8SChris Lattner                                                m_options.m_line_num,
38230fdc8d8SChris Lattner                                                m_options.m_ignore_inlines).get();
38330fdc8d8SChris Lattner         }
38430fdc8d8SChris Lattner         break;
38530fdc8d8SChris Lattner         case eSetTypeAddress: // Breakpoint by address
38630fdc8d8SChris Lattner             bp = target->CreateBreakpoint (m_options.m_load_addr, false).get();
38730fdc8d8SChris Lattner             break;
388*0c5cd90dSGreg Clayton 
38930fdc8d8SChris Lattner         case eSetTypeFunctionName: // Breakpoint by function name
390*0c5cd90dSGreg Clayton             {
391*0c5cd90dSGreg Clayton                 uint32_t name_type_mask = m_options.m_func_name_type_mask;
392*0c5cd90dSGreg Clayton 
393*0c5cd90dSGreg Clayton                 if (name_type_mask == 0)
394*0c5cd90dSGreg Clayton                 {
395*0c5cd90dSGreg Clayton 
396*0c5cd90dSGreg Clayton                     if (m_options.m_func_name.find('(') != std::string::npos ||
397*0c5cd90dSGreg Clayton                         m_options.m_func_name.find("-[") == 0 ||
398*0c5cd90dSGreg Clayton                         m_options.m_func_name.find("+[") == 0)
399*0c5cd90dSGreg Clayton                         name_type_mask |= eFunctionNameTypeFull;
400*0c5cd90dSGreg Clayton                     else
401*0c5cd90dSGreg Clayton                         name_type_mask |= eFunctionNameTypeBase;
402*0c5cd90dSGreg Clayton                 }
403*0c5cd90dSGreg Clayton 
404*0c5cd90dSGreg Clayton 
40530fdc8d8SChris Lattner                 if (use_module)
40630fdc8d8SChris Lattner                 {
40730fdc8d8SChris Lattner                     for (int i = 0; i < num_modules; ++i)
40830fdc8d8SChris Lattner                     {
40930fdc8d8SChris Lattner                         module.SetFile(m_options.m_modules[i].c_str());
410*0c5cd90dSGreg Clayton                         bp = target->CreateBreakpoint (&module, m_options.m_func_name.c_str(), name_type_mask, Breakpoint::Exact).get();
41130fdc8d8SChris Lattner                         if (bp)
41230fdc8d8SChris Lattner                         {
41330fdc8d8SChris Lattner                             StreamString &output_stream = result.GetOutputStream();
41430fdc8d8SChris Lattner                             output_stream.Printf ("Breakpoint created: ");
41530fdc8d8SChris Lattner                             bp->GetDescription(&output_stream, lldb::eDescriptionLevelBrief);
41630fdc8d8SChris Lattner                             output_stream.EOL();
41730fdc8d8SChris Lattner                             result.SetStatus (eReturnStatusSuccessFinishResult);
41830fdc8d8SChris Lattner                         }
41930fdc8d8SChris Lattner                         else
42030fdc8d8SChris Lattner                         {
42130fdc8d8SChris Lattner                             result.AppendErrorWithFormat("Breakpoint creation failed: No breakpoint created in module '%s'.\n",
42230fdc8d8SChris Lattner                                                         m_options.m_modules[i].c_str());
42330fdc8d8SChris Lattner                             result.SetStatus (eReturnStatusFailed);
42430fdc8d8SChris Lattner                         }
42530fdc8d8SChris Lattner                     }
42630fdc8d8SChris Lattner                 }
42730fdc8d8SChris Lattner                 else
428*0c5cd90dSGreg Clayton                     bp = target->CreateBreakpoint (NULL, m_options.m_func_name.c_str(), name_type_mask, Breakpoint::Exact).get();
429*0c5cd90dSGreg Clayton             }
43030fdc8d8SChris Lattner             break;
431*0c5cd90dSGreg Clayton 
43230fdc8d8SChris Lattner         case eSetTypeFunctionRegexp: // Breakpoint by regular expression function name
43330fdc8d8SChris Lattner             {
43430fdc8d8SChris Lattner                 RegularExpression regexp(m_options.m_func_regexp.c_str());
43530fdc8d8SChris Lattner                 if (use_module)
43630fdc8d8SChris Lattner                 {
43730fdc8d8SChris Lattner                     for (int i = 0; i < num_modules; ++i)
43830fdc8d8SChris Lattner                     {
43930fdc8d8SChris Lattner                         module.SetFile(m_options.m_modules[i].c_str());
44030fdc8d8SChris Lattner                         bp = target->CreateBreakpoint (&module, regexp).get();
44130fdc8d8SChris Lattner                         if (bp)
44230fdc8d8SChris Lattner                         {
44330fdc8d8SChris Lattner                             StreamString &output_stream = result.GetOutputStream();
44430fdc8d8SChris Lattner                             output_stream.Printf ("Breakpoint created: ");
44530fdc8d8SChris Lattner                             bp->GetDescription(&output_stream, lldb::eDescriptionLevelBrief);
44630fdc8d8SChris Lattner                             output_stream.EOL();
44730fdc8d8SChris Lattner                             result.SetStatus (eReturnStatusSuccessFinishResult);
44830fdc8d8SChris Lattner                         }
44930fdc8d8SChris Lattner                         else
45030fdc8d8SChris Lattner                         {
45130fdc8d8SChris Lattner                             result.AppendErrorWithFormat("Breakpoint creation failed: No breakpoint created in module '%s'.\n",
45230fdc8d8SChris Lattner                                                         m_options.m_modules[i].c_str());
45330fdc8d8SChris Lattner                             result.SetStatus (eReturnStatusFailed);
45430fdc8d8SChris Lattner                         }
45530fdc8d8SChris Lattner                     }
45630fdc8d8SChris Lattner                 }
45730fdc8d8SChris Lattner                 else
45830fdc8d8SChris Lattner                     bp = target->CreateBreakpoint (NULL, regexp).get();
45930fdc8d8SChris Lattner             }
46030fdc8d8SChris Lattner             break;
461*0c5cd90dSGreg Clayton 
46230fdc8d8SChris Lattner         default:
46330fdc8d8SChris Lattner             break;
46430fdc8d8SChris Lattner     }
46530fdc8d8SChris Lattner 
4661b54c88cSJim Ingham     // Now set the various options that were passed in:
4671b54c88cSJim Ingham     if (bp)
4681b54c88cSJim Ingham     {
4691b54c88cSJim Ingham         if (m_options.m_thread_id != LLDB_INVALID_THREAD_ID)
4701b54c88cSJim Ingham             bp->SetThreadID (m_options.m_thread_id);
4711b54c88cSJim Ingham 
4721b54c88cSJim Ingham         if (m_options.m_thread_index != -1)
4731b54c88cSJim Ingham             bp->GetOptions()->GetThreadSpec()->SetIndex(m_options.m_thread_index);
4741b54c88cSJim Ingham 
4751b54c88cSJim Ingham         if (!m_options.m_thread_name.empty())
4761b54c88cSJim Ingham             bp->GetOptions()->GetThreadSpec()->SetName(m_options.m_thread_name.c_str());
4771b54c88cSJim Ingham 
4781b54c88cSJim Ingham         if (!m_options.m_queue_name.empty())
4791b54c88cSJim Ingham             bp->GetOptions()->GetThreadSpec()->SetQueueName(m_options.m_queue_name.c_str());
4801b54c88cSJim Ingham 
4811b54c88cSJim Ingham         if (m_options.m_ignore_count != -1)
4821b54c88cSJim Ingham             bp->GetOptions()->SetIgnoreCount(m_options.m_ignore_count);
4831b54c88cSJim Ingham     }
4841b54c88cSJim Ingham 
48530fdc8d8SChris Lattner     if (bp && !use_module)
48630fdc8d8SChris Lattner     {
48730fdc8d8SChris Lattner         StreamString &output_stream = result.GetOutputStream();
48830fdc8d8SChris Lattner         output_stream.Printf ("Breakpoint created: ");
48930fdc8d8SChris Lattner         bp->GetDescription(&output_stream, lldb::eDescriptionLevelBrief);
49030fdc8d8SChris Lattner         output_stream.EOL();
49130fdc8d8SChris Lattner         result.SetStatus (eReturnStatusSuccessFinishResult);
49230fdc8d8SChris Lattner     }
49330fdc8d8SChris Lattner     else if (!bp)
49430fdc8d8SChris Lattner     {
49530fdc8d8SChris Lattner         result.AppendError ("Breakpoint creation failed: No breakpoint created.");
49630fdc8d8SChris Lattner         result.SetStatus (eReturnStatusFailed);
49730fdc8d8SChris Lattner     }
49830fdc8d8SChris Lattner 
49930fdc8d8SChris Lattner     return result.Succeeded();
50030fdc8d8SChris Lattner }
50130fdc8d8SChris Lattner 
50230fdc8d8SChris Lattner //-------------------------------------------------------------------------
50330fdc8d8SChris Lattner // CommandObjectMultiwordBreakpoint
50430fdc8d8SChris Lattner //-------------------------------------------------------------------------
505ae1c4cf5SJim Ingham #pragma mark MultiwordBreakpoint
50630fdc8d8SChris Lattner 
5076611103cSGreg Clayton CommandObjectMultiwordBreakpoint::CommandObjectMultiwordBreakpoint (CommandInterpreter &interpreter) :
50830fdc8d8SChris Lattner     CommandObjectMultiword ("breakpoint",
50930fdc8d8SChris Lattner                               "A set of commands for operating on breakpoints.",
51030fdc8d8SChris Lattner                               "breakpoint <command> [<command-options>]")
51130fdc8d8SChris Lattner {
51230fdc8d8SChris Lattner     bool status;
51330fdc8d8SChris Lattner 
51430fdc8d8SChris Lattner     CommandObjectSP list_command_object (new CommandObjectBreakpointList ());
51530fdc8d8SChris Lattner     CommandObjectSP delete_command_object (new CommandObjectBreakpointDelete ());
51630fdc8d8SChris Lattner     CommandObjectSP enable_command_object (new CommandObjectBreakpointEnable ());
51730fdc8d8SChris Lattner     CommandObjectSP disable_command_object (new CommandObjectBreakpointDisable ());
51830fdc8d8SChris Lattner     CommandObjectSP set_command_object (new CommandObjectBreakpointSet ());
51930fdc8d8SChris Lattner     CommandObjectSP command_command_object (new CommandObjectBreakpointCommand (interpreter));
520ae1c4cf5SJim Ingham     CommandObjectSP modify_command_object (new CommandObjectBreakpointModify());
52130fdc8d8SChris Lattner 
522ae1c4cf5SJim Ingham     command_command_object->SetCommandName ("breakpoint command");
52330fdc8d8SChris Lattner     enable_command_object->SetCommandName("breakpoint enable");
52430fdc8d8SChris Lattner     disable_command_object->SetCommandName("breakpoint disable");
52530fdc8d8SChris Lattner     list_command_object->SetCommandName ("breakpoint list");
526ae1c4cf5SJim Ingham     modify_command_object->SetCommandName ("breakpoint modify");
527ae1c4cf5SJim Ingham     set_command_object->SetCommandName("breakpoint set");
52830fdc8d8SChris Lattner 
5296611103cSGreg Clayton     status = LoadSubCommand (interpreter, "list",       list_command_object);
5306611103cSGreg Clayton     status = LoadSubCommand (interpreter, "enable",     enable_command_object);
5316611103cSGreg Clayton     status = LoadSubCommand (interpreter, "disable",    disable_command_object);
5326611103cSGreg Clayton     status = LoadSubCommand (interpreter, "delete",     delete_command_object);
5336611103cSGreg Clayton     status = LoadSubCommand (interpreter, "set",        set_command_object);
5346611103cSGreg Clayton     status = LoadSubCommand (interpreter, "command",    command_command_object);
5356611103cSGreg Clayton     status = LoadSubCommand (interpreter, "modify",     modify_command_object);
53630fdc8d8SChris Lattner }
53730fdc8d8SChris Lattner 
53830fdc8d8SChris Lattner CommandObjectMultiwordBreakpoint::~CommandObjectMultiwordBreakpoint ()
53930fdc8d8SChris Lattner {
54030fdc8d8SChris Lattner }
54130fdc8d8SChris Lattner 
54230fdc8d8SChris Lattner void
54330fdc8d8SChris Lattner CommandObjectMultiwordBreakpoint::VerifyBreakpointIDs (Args &args, Target *target, CommandReturnObject &result,
54430fdc8d8SChris Lattner                                                          BreakpointIDList *valid_ids)
54530fdc8d8SChris Lattner {
54630fdc8d8SChris Lattner     // args can be strings representing 1). integers (for breakpoint ids)
54730fdc8d8SChris Lattner     //                                  2). the full breakpoint & location canonical representation
54830fdc8d8SChris Lattner     //                                  3). the word "to" or a hyphen, representing a range (in which case there
54930fdc8d8SChris Lattner     //                                      had *better* be an entry both before & after of one of the first two types.
55030fdc8d8SChris Lattner 
55130fdc8d8SChris Lattner     Args temp_args;
55230fdc8d8SChris Lattner 
55330fdc8d8SChris Lattner     // Create a new Args variable to use; copy any non-breakpoint-id-ranges stuff directly from the old ARGS to
55430fdc8d8SChris Lattner     // the new TEMP_ARGS.  Do not copy breakpoint id range strings over; instead generate a list of strings for
55530fdc8d8SChris Lattner     // all the breakpoint ids in the range, and shove all of those breakpoint id strings into TEMP_ARGS.
55630fdc8d8SChris Lattner 
55730fdc8d8SChris Lattner     BreakpointIDList::FindAndReplaceIDRanges (args, target, result, temp_args);
55830fdc8d8SChris Lattner 
55930fdc8d8SChris Lattner     // NOW, convert the list of breakpoint id strings in TEMP_ARGS into an actual BreakpointIDList:
56030fdc8d8SChris Lattner 
56130fdc8d8SChris Lattner     valid_ids->InsertStringArray ((const char **) temp_args.GetArgumentVector(), temp_args.GetArgumentCount(), result);
56230fdc8d8SChris Lattner 
56330fdc8d8SChris Lattner     // At this point,  all of the breakpoint ids that the user passed in have been converted to breakpoint IDs
56430fdc8d8SChris Lattner     // and put into valid_ids.
56530fdc8d8SChris Lattner 
56630fdc8d8SChris Lattner     if (result.Succeeded())
56730fdc8d8SChris Lattner     {
56830fdc8d8SChris Lattner         // Now that we've converted everything from args into a list of breakpoint ids, go through our tentative list
56930fdc8d8SChris Lattner         // of breakpoint id's and verify that they correspond to valid/currently set breakpoints.
57030fdc8d8SChris Lattner 
57130fdc8d8SChris Lattner         for (int i = 0; i < valid_ids->Size(); ++i)
57230fdc8d8SChris Lattner         {
57330fdc8d8SChris Lattner             BreakpointID cur_bp_id = valid_ids->GetBreakpointIDAtIndex (i);
57430fdc8d8SChris Lattner             Breakpoint *breakpoint = target->GetBreakpointByID (cur_bp_id.GetBreakpointID()).get();
57530fdc8d8SChris Lattner             if (breakpoint != NULL)
57630fdc8d8SChris Lattner             {
57730fdc8d8SChris Lattner                 int num_locations = breakpoint->GetNumLocations();
57830fdc8d8SChris Lattner                 if (cur_bp_id.GetLocationID() > num_locations)
57930fdc8d8SChris Lattner                 {
58030fdc8d8SChris Lattner                     StreamString id_str;
58130fdc8d8SChris Lattner                     BreakpointID::GetCanonicalReference (&id_str, cur_bp_id.GetBreakpointID(),
58230fdc8d8SChris Lattner                                                            cur_bp_id.GetLocationID());
58330fdc8d8SChris Lattner                     i = valid_ids->Size() + 1;
58430fdc8d8SChris Lattner                     result.AppendErrorWithFormat ("'%s' is not a currently valid breakpoint/location id.\n",
58530fdc8d8SChris Lattner                                                  id_str.GetData());
58630fdc8d8SChris Lattner                     result.SetStatus (eReturnStatusFailed);
58730fdc8d8SChris Lattner                 }
58830fdc8d8SChris Lattner             }
58930fdc8d8SChris Lattner             else
59030fdc8d8SChris Lattner             {
59130fdc8d8SChris Lattner                 i = valid_ids->Size() + 1;
59230fdc8d8SChris Lattner                 result.AppendErrorWithFormat ("'%d' is not a currently valid breakpoint id.\n", cur_bp_id.GetBreakpointID());
59330fdc8d8SChris Lattner                 result.SetStatus (eReturnStatusFailed);
59430fdc8d8SChris Lattner             }
59530fdc8d8SChris Lattner         }
59630fdc8d8SChris Lattner     }
59730fdc8d8SChris Lattner }
59830fdc8d8SChris Lattner 
59930fdc8d8SChris Lattner //-------------------------------------------------------------------------
60030fdc8d8SChris Lattner // CommandObjectBreakpointList::Options
60130fdc8d8SChris Lattner //-------------------------------------------------------------------------
602ae1c4cf5SJim Ingham #pragma mark List::CommandOptions
60330fdc8d8SChris Lattner 
60430fdc8d8SChris Lattner CommandObjectBreakpointList::CommandOptions::CommandOptions() :
60530fdc8d8SChris Lattner     Options (),
60630fdc8d8SChris Lattner     m_level (lldb::eDescriptionLevelFull)  // Breakpoint List defaults to brief descriptions
60730fdc8d8SChris Lattner {
60830fdc8d8SChris Lattner }
60930fdc8d8SChris Lattner 
61030fdc8d8SChris Lattner CommandObjectBreakpointList::CommandOptions::~CommandOptions ()
61130fdc8d8SChris Lattner {
61230fdc8d8SChris Lattner }
61330fdc8d8SChris Lattner 
61430fdc8d8SChris Lattner lldb::OptionDefinition
61530fdc8d8SChris Lattner CommandObjectBreakpointList::CommandOptions::g_option_table[] =
61630fdc8d8SChris Lattner {
6178651121cSJim Ingham     { LLDB_OPT_SET_ALL, false, "internal", 'i', no_argument, NULL, 0, NULL,
6188651121cSJim Ingham         "Show debugger internal breakpoints" },
6198651121cSJim Ingham 
6208651121cSJim Ingham     { LLDB_OPT_SET_1, false, "brief",    'b', no_argument, NULL, 0, NULL,
62130fdc8d8SChris Lattner         "Give a brief description of the breakpoint (no location info)."},
62230fdc8d8SChris Lattner 
62330fdc8d8SChris Lattner     // FIXME: We need to add an "internal" command, and then add this sort of thing to it.
62430fdc8d8SChris Lattner     // But I need to see it for now, and don't want to wait.
6258651121cSJim Ingham     { LLDB_OPT_SET_2, false, "full",    'f', no_argument, NULL, 0, NULL,
62630fdc8d8SChris Lattner         "Give a full description of the breakpoint and its locations."},
62730fdc8d8SChris Lattner 
6288651121cSJim Ingham     { LLDB_OPT_SET_3, false, "verbose", 'v', no_argument, NULL, 0, NULL,
62930fdc8d8SChris Lattner         "Explain everything we know about the breakpoint (for debugging debugger bugs)." },
63030fdc8d8SChris Lattner 
63130fdc8d8SChris Lattner     { 0, false, NULL, 0, 0, NULL, 0, NULL, NULL }
63230fdc8d8SChris Lattner };
63330fdc8d8SChris Lattner 
63430fdc8d8SChris Lattner const lldb::OptionDefinition*
63530fdc8d8SChris Lattner CommandObjectBreakpointList::CommandOptions::GetDefinitions ()
63630fdc8d8SChris Lattner {
63730fdc8d8SChris Lattner     return g_option_table;
63830fdc8d8SChris Lattner }
63930fdc8d8SChris Lattner 
64030fdc8d8SChris Lattner Error
64130fdc8d8SChris Lattner CommandObjectBreakpointList::CommandOptions::SetOptionValue (int option_idx, const char *option_arg)
64230fdc8d8SChris Lattner {
64330fdc8d8SChris Lattner     Error error;
64430fdc8d8SChris Lattner     char short_option = (char) m_getopt_table[option_idx].val;
64530fdc8d8SChris Lattner 
64630fdc8d8SChris Lattner     switch (short_option)
64730fdc8d8SChris Lattner     {
64830fdc8d8SChris Lattner         case 'b':
64930fdc8d8SChris Lattner             m_level = lldb::eDescriptionLevelBrief;
65030fdc8d8SChris Lattner             break;
65130fdc8d8SChris Lattner         case 'f':
65230fdc8d8SChris Lattner             m_level = lldb::eDescriptionLevelFull;
65330fdc8d8SChris Lattner             break;
65430fdc8d8SChris Lattner         case 'v':
65530fdc8d8SChris Lattner             m_level = lldb::eDescriptionLevelVerbose;
65630fdc8d8SChris Lattner             break;
65730fdc8d8SChris Lattner         case 'i':
65830fdc8d8SChris Lattner             m_internal = true;
65930fdc8d8SChris Lattner             break;
66030fdc8d8SChris Lattner         default:
66130fdc8d8SChris Lattner             error.SetErrorStringWithFormat ("Unrecognized option '%c'.\n", short_option);
66230fdc8d8SChris Lattner             break;
66330fdc8d8SChris Lattner     }
66430fdc8d8SChris Lattner 
66530fdc8d8SChris Lattner     return error;
66630fdc8d8SChris Lattner }
66730fdc8d8SChris Lattner 
66830fdc8d8SChris Lattner void
66930fdc8d8SChris Lattner CommandObjectBreakpointList::CommandOptions::ResetOptionValues ()
67030fdc8d8SChris Lattner {
67130fdc8d8SChris Lattner     Options::ResetOptionValues();
67230fdc8d8SChris Lattner 
67330fdc8d8SChris Lattner     m_level = lldb::eDescriptionLevelFull;
67430fdc8d8SChris Lattner     m_internal = false;
67530fdc8d8SChris Lattner }
67630fdc8d8SChris Lattner 
67730fdc8d8SChris Lattner //-------------------------------------------------------------------------
67830fdc8d8SChris Lattner // CommandObjectBreakpointList
67930fdc8d8SChris Lattner //-------------------------------------------------------------------------
680ae1c4cf5SJim Ingham #pragma mark List
68130fdc8d8SChris Lattner 
68230fdc8d8SChris Lattner CommandObjectBreakpointList::CommandObjectBreakpointList () :
68330fdc8d8SChris Lattner     CommandObject ("breakpoint list",
68430fdc8d8SChris Lattner                      "List some or all breakpoints at configurable levels of detail.",
68530fdc8d8SChris Lattner                      "breakpoint list [<breakpoint-id>]")
68630fdc8d8SChris Lattner {
68730fdc8d8SChris Lattner }
68830fdc8d8SChris Lattner 
68930fdc8d8SChris Lattner CommandObjectBreakpointList::~CommandObjectBreakpointList ()
69030fdc8d8SChris Lattner {
69130fdc8d8SChris Lattner }
69230fdc8d8SChris Lattner 
69330fdc8d8SChris Lattner Options *
69430fdc8d8SChris Lattner CommandObjectBreakpointList::GetOptions ()
69530fdc8d8SChris Lattner {
69630fdc8d8SChris Lattner     return &m_options;
69730fdc8d8SChris Lattner }
69830fdc8d8SChris Lattner 
69930fdc8d8SChris Lattner bool
70030fdc8d8SChris Lattner CommandObjectBreakpointList::Execute
70130fdc8d8SChris Lattner (
7026611103cSGreg Clayton     CommandInterpreter &interpreter,
70330fdc8d8SChris Lattner     Args& args,
70430fdc8d8SChris Lattner     CommandReturnObject &result
70530fdc8d8SChris Lattner )
70630fdc8d8SChris Lattner {
7076611103cSGreg Clayton     Target *target = interpreter.GetDebugger().GetCurrentTarget().get();
70830fdc8d8SChris Lattner     if (target == NULL)
70930fdc8d8SChris Lattner     {
71030fdc8d8SChris Lattner         result.AppendError ("Invalid target, set executable file using 'file' command.");
71130fdc8d8SChris Lattner         result.SetStatus (eReturnStatusSuccessFinishNoResult);
71230fdc8d8SChris Lattner         return true;
71330fdc8d8SChris Lattner     }
71430fdc8d8SChris Lattner 
71530fdc8d8SChris Lattner     const BreakpointList &breakpoints = target->GetBreakpointList(m_options.m_internal);
7161b54c88cSJim Ingham     Mutex::Locker locker;
7171b54c88cSJim Ingham     target->GetBreakpointList(m_options.m_internal).GetListMutex(locker);
7181b54c88cSJim Ingham 
71930fdc8d8SChris Lattner     size_t num_breakpoints = breakpoints.GetSize();
72030fdc8d8SChris Lattner 
72130fdc8d8SChris Lattner     if (num_breakpoints == 0)
72230fdc8d8SChris Lattner     {
72330fdc8d8SChris Lattner         result.AppendMessage ("No breakpoints currently set.");
72430fdc8d8SChris Lattner         result.SetStatus (eReturnStatusSuccessFinishNoResult);
72530fdc8d8SChris Lattner         return true;
72630fdc8d8SChris Lattner     }
72730fdc8d8SChris Lattner 
72830fdc8d8SChris Lattner     StreamString &output_stream = result.GetOutputStream();
72930fdc8d8SChris Lattner 
73030fdc8d8SChris Lattner     if (args.GetArgumentCount() == 0)
73130fdc8d8SChris Lattner     {
73230fdc8d8SChris Lattner         // No breakpoint selected; show info about all currently set breakpoints.
73330fdc8d8SChris Lattner         result.AppendMessage ("Current breakpoints:");
73430fdc8d8SChris Lattner         for (int i = 0; i < num_breakpoints; ++i)
73530fdc8d8SChris Lattner         {
73630fdc8d8SChris Lattner             Breakpoint *breakpoint = breakpoints.GetBreakpointByIndex (i).get();
7376611103cSGreg Clayton             AddBreakpointDescription (&output_stream, breakpoint, m_options.m_level);
73830fdc8d8SChris Lattner         }
73930fdc8d8SChris Lattner         result.SetStatus (eReturnStatusSuccessFinishNoResult);
74030fdc8d8SChris Lattner     }
74130fdc8d8SChris Lattner     else
74230fdc8d8SChris Lattner     {
74330fdc8d8SChris Lattner         // Particular breakpoints selected; show info about that breakpoint.
74430fdc8d8SChris Lattner         BreakpointIDList valid_bp_ids;
74530fdc8d8SChris Lattner         CommandObjectMultiwordBreakpoint::VerifyBreakpointIDs (args, target, result, &valid_bp_ids);
74630fdc8d8SChris Lattner 
74730fdc8d8SChris Lattner         if (result.Succeeded())
74830fdc8d8SChris Lattner         {
74930fdc8d8SChris Lattner             for (int i = 0; i < valid_bp_ids.Size(); ++i)
75030fdc8d8SChris Lattner             {
75130fdc8d8SChris Lattner                 BreakpointID cur_bp_id = valid_bp_ids.GetBreakpointIDAtIndex (i);
75230fdc8d8SChris Lattner                 Breakpoint *breakpoint = target->GetBreakpointByID (cur_bp_id.GetBreakpointID()).get();
7536611103cSGreg Clayton                 AddBreakpointDescription (&output_stream, breakpoint, m_options.m_level);
75430fdc8d8SChris Lattner             }
75530fdc8d8SChris Lattner             result.SetStatus (eReturnStatusSuccessFinishNoResult);
75630fdc8d8SChris Lattner         }
75730fdc8d8SChris Lattner         else
75830fdc8d8SChris Lattner         {
75930fdc8d8SChris Lattner             result.AppendError ("Invalid breakpoint id.");
76030fdc8d8SChris Lattner             result.SetStatus (eReturnStatusFailed);
76130fdc8d8SChris Lattner         }
76230fdc8d8SChris Lattner     }
76330fdc8d8SChris Lattner 
76430fdc8d8SChris Lattner     return result.Succeeded();
76530fdc8d8SChris Lattner }
76630fdc8d8SChris Lattner 
76730fdc8d8SChris Lattner //-------------------------------------------------------------------------
76830fdc8d8SChris Lattner // CommandObjectBreakpointEnable
76930fdc8d8SChris Lattner //-------------------------------------------------------------------------
770ae1c4cf5SJim Ingham #pragma mark Enable
77130fdc8d8SChris Lattner 
77230fdc8d8SChris Lattner CommandObjectBreakpointEnable::CommandObjectBreakpointEnable () :
77330fdc8d8SChris Lattner     CommandObject ("enable",
77430fdc8d8SChris Lattner                      "Enables the specified disabled breakpoint(s).  If no breakpoints are specified, enables all of them.",
77530fdc8d8SChris Lattner                      "breakpoint enable [<breakpoint-id> | <breakpoint-id-list>]")
77630fdc8d8SChris Lattner {
77730fdc8d8SChris Lattner     // This command object can either be called via 'enable' or 'breakpoint enable'.  Because it has two different
77830fdc8d8SChris Lattner     // potential invocation methods, we need to be a little tricky about generating the syntax string.
77930fdc8d8SChris Lattner     //StreamString tmp_string;
78030fdc8d8SChris Lattner     //tmp_string.Printf ("%s <breakpoint-id>", GetCommandName());
78130fdc8d8SChris Lattner     //m_cmd_syntax.assign (tmp_string.GetData(), tmp_string.GetSize());
78230fdc8d8SChris Lattner }
78330fdc8d8SChris Lattner 
78430fdc8d8SChris Lattner 
78530fdc8d8SChris Lattner CommandObjectBreakpointEnable::~CommandObjectBreakpointEnable ()
78630fdc8d8SChris Lattner {
78730fdc8d8SChris Lattner }
78830fdc8d8SChris Lattner 
78930fdc8d8SChris Lattner 
79030fdc8d8SChris Lattner bool
7916611103cSGreg Clayton CommandObjectBreakpointEnable::Execute
7926611103cSGreg Clayton (
7936611103cSGreg Clayton     CommandInterpreter &interpreter,
7946611103cSGreg Clayton     Args& args,
7956611103cSGreg Clayton     CommandReturnObject &result
7966611103cSGreg Clayton )
79730fdc8d8SChris Lattner {
7986611103cSGreg Clayton     Target *target = interpreter.GetDebugger().GetCurrentTarget().get();
79930fdc8d8SChris Lattner     if (target == NULL)
80030fdc8d8SChris Lattner     {
80130fdc8d8SChris Lattner         result.AppendError ("Invalid target, set executable file using 'file' command.");
80230fdc8d8SChris Lattner         result.SetStatus (eReturnStatusFailed);
80330fdc8d8SChris Lattner         return false;
80430fdc8d8SChris Lattner     }
80530fdc8d8SChris Lattner 
8061b54c88cSJim Ingham     Mutex::Locker locker;
8071b54c88cSJim Ingham     target->GetBreakpointList().GetListMutex(locker);
8081b54c88cSJim Ingham 
80930fdc8d8SChris Lattner     const BreakpointList &breakpoints = target->GetBreakpointList();
8101b54c88cSJim Ingham 
81130fdc8d8SChris Lattner     size_t num_breakpoints = breakpoints.GetSize();
81230fdc8d8SChris Lattner 
81330fdc8d8SChris Lattner     if (num_breakpoints == 0)
81430fdc8d8SChris Lattner     {
81530fdc8d8SChris Lattner         result.AppendError ("No breakpoints exist to be enabled.");
81630fdc8d8SChris Lattner         result.SetStatus (eReturnStatusFailed);
81730fdc8d8SChris Lattner         return false;
81830fdc8d8SChris Lattner     }
81930fdc8d8SChris Lattner 
82030fdc8d8SChris Lattner     if (args.GetArgumentCount() == 0)
82130fdc8d8SChris Lattner     {
82230fdc8d8SChris Lattner         // No breakpoint selected; enable all currently set breakpoints.
82330fdc8d8SChris Lattner         target->EnableAllBreakpoints ();
82430fdc8d8SChris Lattner         result.AppendMessageWithFormat ("All breakpoints enabled. (%d breakpoints)\n", num_breakpoints);
82530fdc8d8SChris Lattner         result.SetStatus (eReturnStatusSuccessFinishNoResult);
82630fdc8d8SChris Lattner     }
82730fdc8d8SChris Lattner     else
82830fdc8d8SChris Lattner     {
82930fdc8d8SChris Lattner         // Particular breakpoint selected; enable that breakpoint.
83030fdc8d8SChris Lattner         BreakpointIDList valid_bp_ids;
83130fdc8d8SChris Lattner         CommandObjectMultiwordBreakpoint::VerifyBreakpointIDs (args, target, result, &valid_bp_ids);
83230fdc8d8SChris Lattner 
83330fdc8d8SChris Lattner         if (result.Succeeded())
83430fdc8d8SChris Lattner         {
83530fdc8d8SChris Lattner             int enable_count = 0;
83630fdc8d8SChris Lattner             int loc_count = 0;
83730fdc8d8SChris Lattner             for (int i = 0; i < valid_bp_ids.Size(); ++i)
83830fdc8d8SChris Lattner             {
83930fdc8d8SChris Lattner                 BreakpointID cur_bp_id = valid_bp_ids.GetBreakpointIDAtIndex (i);
84030fdc8d8SChris Lattner 
84130fdc8d8SChris Lattner                 if (cur_bp_id.GetBreakpointID() != LLDB_INVALID_BREAK_ID)
84230fdc8d8SChris Lattner                 {
84330fdc8d8SChris Lattner                     Breakpoint *breakpoint = target->GetBreakpointByID (cur_bp_id.GetBreakpointID()).get();
84430fdc8d8SChris Lattner                     if (cur_bp_id.GetLocationID() != LLDB_INVALID_BREAK_ID)
84530fdc8d8SChris Lattner                     {
84630fdc8d8SChris Lattner                         BreakpointLocation *location = breakpoint->FindLocationByID (cur_bp_id.GetLocationID()).get();
84730fdc8d8SChris Lattner                         if (location)
84830fdc8d8SChris Lattner                         {
84930fdc8d8SChris Lattner                             location->SetEnabled (true);
85030fdc8d8SChris Lattner                             ++loc_count;
85130fdc8d8SChris Lattner                         }
85230fdc8d8SChris Lattner                     }
85330fdc8d8SChris Lattner                     else
85430fdc8d8SChris Lattner                     {
855ae1c4cf5SJim Ingham                         breakpoint->SetEnabled (true);
85630fdc8d8SChris Lattner                         ++enable_count;
85730fdc8d8SChris Lattner                     }
85830fdc8d8SChris Lattner                 }
85930fdc8d8SChris Lattner             }
86030fdc8d8SChris Lattner             result.AppendMessageWithFormat ("%d breakpoints enabled.\n", enable_count + loc_count);
86130fdc8d8SChris Lattner             result.SetStatus (eReturnStatusSuccessFinishNoResult);
86230fdc8d8SChris Lattner         }
86330fdc8d8SChris Lattner     }
86430fdc8d8SChris Lattner 
86530fdc8d8SChris Lattner     return result.Succeeded();
86630fdc8d8SChris Lattner }
86730fdc8d8SChris Lattner 
86830fdc8d8SChris Lattner //-------------------------------------------------------------------------
86930fdc8d8SChris Lattner // CommandObjectBreakpointDisable
87030fdc8d8SChris Lattner //-------------------------------------------------------------------------
871ae1c4cf5SJim Ingham #pragma mark Disable
87230fdc8d8SChris Lattner 
87330fdc8d8SChris Lattner CommandObjectBreakpointDisable::CommandObjectBreakpointDisable () :
87430fdc8d8SChris Lattner     CommandObject ("disable",
87530fdc8d8SChris Lattner                    "Disables the specified breakpoint(s) without removing it/them.  If no breakpoints are specified, disables them all.",
87630fdc8d8SChris Lattner                    "disable [<breakpoint-id> | <breakpoint-id-list>]")
87730fdc8d8SChris Lattner {
87830fdc8d8SChris Lattner     // This command object can either be called via 'enable' or 'breakpoint enable'.  Because it has two different
87930fdc8d8SChris Lattner     // potential invocation methods, we need to be a little tricky about generating the syntax string.
88030fdc8d8SChris Lattner     //StreamString tmp_string;
88130fdc8d8SChris Lattner     //tmp_string.Printf ("%s <breakpoint-id>", GetCommandName());
88230fdc8d8SChris Lattner     //m_cmd_syntax.assign(tmp_string.GetData(), tmp_string.GetSize());
88330fdc8d8SChris Lattner }
88430fdc8d8SChris Lattner 
88530fdc8d8SChris Lattner CommandObjectBreakpointDisable::~CommandObjectBreakpointDisable ()
88630fdc8d8SChris Lattner {
88730fdc8d8SChris Lattner }
88830fdc8d8SChris Lattner 
88930fdc8d8SChris Lattner bool
8906611103cSGreg Clayton CommandObjectBreakpointDisable::Execute
8916611103cSGreg Clayton (
8926611103cSGreg Clayton     CommandInterpreter &interpreter,
8936611103cSGreg Clayton     Args& args,
8946611103cSGreg Clayton     CommandReturnObject &result
8956611103cSGreg Clayton )
89630fdc8d8SChris Lattner {
8976611103cSGreg Clayton     Target *target = interpreter.GetDebugger().GetCurrentTarget().get();
89830fdc8d8SChris Lattner     if (target == NULL)
89930fdc8d8SChris Lattner     {
90030fdc8d8SChris Lattner         result.AppendError ("Invalid target, set executable file using 'file' command.");
90130fdc8d8SChris Lattner         result.SetStatus (eReturnStatusFailed);
90230fdc8d8SChris Lattner         return false;
90330fdc8d8SChris Lattner     }
90430fdc8d8SChris Lattner 
9051b54c88cSJim Ingham     Mutex::Locker locker;
9061b54c88cSJim Ingham     target->GetBreakpointList().GetListMutex(locker);
9071b54c88cSJim Ingham 
90830fdc8d8SChris Lattner     const BreakpointList &breakpoints = target->GetBreakpointList();
90930fdc8d8SChris Lattner     size_t num_breakpoints = breakpoints.GetSize();
91030fdc8d8SChris Lattner 
91130fdc8d8SChris Lattner     if (num_breakpoints == 0)
91230fdc8d8SChris Lattner     {
91330fdc8d8SChris Lattner         result.AppendError ("No breakpoints exist to be disabled.");
91430fdc8d8SChris Lattner         result.SetStatus (eReturnStatusFailed);
91530fdc8d8SChris Lattner         return false;
91630fdc8d8SChris Lattner     }
91730fdc8d8SChris Lattner 
91830fdc8d8SChris Lattner     if (args.GetArgumentCount() == 0)
91930fdc8d8SChris Lattner     {
92030fdc8d8SChris Lattner         // No breakpoint selected; disable all currently set breakpoints.
92130fdc8d8SChris Lattner         target->DisableAllBreakpoints ();
92230fdc8d8SChris Lattner         result.AppendMessageWithFormat ("All breakpoints disabled. (%d breakpoints)\n", num_breakpoints);
92330fdc8d8SChris Lattner         result.SetStatus (eReturnStatusSuccessFinishNoResult);
92430fdc8d8SChris Lattner     }
92530fdc8d8SChris Lattner     else
92630fdc8d8SChris Lattner     {
92730fdc8d8SChris Lattner         // Particular breakpoint selected; disable that breakpoint.
92830fdc8d8SChris Lattner         BreakpointIDList valid_bp_ids;
92930fdc8d8SChris Lattner 
93030fdc8d8SChris Lattner         CommandObjectMultiwordBreakpoint::VerifyBreakpointIDs (args, target, result, &valid_bp_ids);
93130fdc8d8SChris Lattner 
93230fdc8d8SChris Lattner         if (result.Succeeded())
93330fdc8d8SChris Lattner         {
93430fdc8d8SChris Lattner             int disable_count = 0;
93530fdc8d8SChris Lattner             int loc_count = 0;
93630fdc8d8SChris Lattner             for (int i = 0; i < valid_bp_ids.Size(); ++i)
93730fdc8d8SChris Lattner             {
93830fdc8d8SChris Lattner                 BreakpointID cur_bp_id = valid_bp_ids.GetBreakpointIDAtIndex (i);
93930fdc8d8SChris Lattner 
94030fdc8d8SChris Lattner                 if (cur_bp_id.GetBreakpointID() != LLDB_INVALID_BREAK_ID)
94130fdc8d8SChris Lattner                 {
94230fdc8d8SChris Lattner                     Breakpoint *breakpoint = target->GetBreakpointByID (cur_bp_id.GetBreakpointID()).get();
94330fdc8d8SChris Lattner                     if (cur_bp_id.GetLocationID() != LLDB_INVALID_BREAK_ID)
94430fdc8d8SChris Lattner                     {
94530fdc8d8SChris Lattner                         BreakpointLocation *location = breakpoint->FindLocationByID (cur_bp_id.GetLocationID()).get();
94630fdc8d8SChris Lattner                         if (location)
94730fdc8d8SChris Lattner                         {
94830fdc8d8SChris Lattner                             location->SetEnabled (false);
94930fdc8d8SChris Lattner                             ++loc_count;
95030fdc8d8SChris Lattner                         }
95130fdc8d8SChris Lattner                     }
95230fdc8d8SChris Lattner                     else
95330fdc8d8SChris Lattner                     {
954ae1c4cf5SJim Ingham                         breakpoint->SetEnabled (false);
95530fdc8d8SChris Lattner                         ++disable_count;
95630fdc8d8SChris Lattner                     }
95730fdc8d8SChris Lattner                 }
95830fdc8d8SChris Lattner             }
95930fdc8d8SChris Lattner             result.AppendMessageWithFormat ("%d breakpoints disabled.\n", disable_count + loc_count);
96030fdc8d8SChris Lattner             result.SetStatus (eReturnStatusSuccessFinishNoResult);
96130fdc8d8SChris Lattner         }
96230fdc8d8SChris Lattner     }
96330fdc8d8SChris Lattner 
96430fdc8d8SChris Lattner     return result.Succeeded();
96530fdc8d8SChris Lattner }
96630fdc8d8SChris Lattner 
96730fdc8d8SChris Lattner //-------------------------------------------------------------------------
96830fdc8d8SChris Lattner // CommandObjectBreakpointDelete
96930fdc8d8SChris Lattner //-------------------------------------------------------------------------
970ae1c4cf5SJim Ingham #pragma mark Delete
97130fdc8d8SChris Lattner 
97230fdc8d8SChris Lattner CommandObjectBreakpointDelete::CommandObjectBreakpointDelete() :
97330fdc8d8SChris Lattner     CommandObject ("breakpoint delete",
97430fdc8d8SChris Lattner                    "Delete the specified breakpoint(s).  If no breakpoints are specified, deletes them all.",
97530fdc8d8SChris Lattner                    "breakpoint delete [<breakpoint-id> | <breakpoint-id-list>]")
97630fdc8d8SChris Lattner {
97730fdc8d8SChris Lattner }
97830fdc8d8SChris Lattner 
97930fdc8d8SChris Lattner 
98030fdc8d8SChris Lattner CommandObjectBreakpointDelete::~CommandObjectBreakpointDelete ()
98130fdc8d8SChris Lattner {
98230fdc8d8SChris Lattner }
98330fdc8d8SChris Lattner 
98430fdc8d8SChris Lattner bool
9856611103cSGreg Clayton CommandObjectBreakpointDelete::Execute
9866611103cSGreg Clayton (
9876611103cSGreg Clayton     CommandInterpreter &interpreter,
9886611103cSGreg Clayton     Args& args,
9896611103cSGreg Clayton     CommandReturnObject &result
9906611103cSGreg Clayton )
99130fdc8d8SChris Lattner {
9926611103cSGreg Clayton     Target *target = interpreter.GetDebugger().GetCurrentTarget().get();
99330fdc8d8SChris Lattner     if (target == NULL)
99430fdc8d8SChris Lattner     {
99530fdc8d8SChris Lattner         result.AppendError ("Invalid target, set executable file using 'file' command.");
99630fdc8d8SChris Lattner         result.SetStatus (eReturnStatusFailed);
99730fdc8d8SChris Lattner         return false;
99830fdc8d8SChris Lattner     }
99930fdc8d8SChris Lattner 
10001b54c88cSJim Ingham     Mutex::Locker locker;
10011b54c88cSJim Ingham     target->GetBreakpointList().GetListMutex(locker);
10021b54c88cSJim Ingham 
100330fdc8d8SChris Lattner     const BreakpointList &breakpoints = target->GetBreakpointList();
10041b54c88cSJim Ingham 
100530fdc8d8SChris Lattner     size_t num_breakpoints = breakpoints.GetSize();
100630fdc8d8SChris Lattner 
100730fdc8d8SChris Lattner     if (num_breakpoints == 0)
100830fdc8d8SChris Lattner     {
100930fdc8d8SChris Lattner         result.AppendError ("No breakpoints exist to be deleted.");
101030fdc8d8SChris Lattner         result.SetStatus (eReturnStatusFailed);
101130fdc8d8SChris Lattner         return false;
101230fdc8d8SChris Lattner     }
101330fdc8d8SChris Lattner 
101430fdc8d8SChris Lattner     if (args.GetArgumentCount() == 0)
101530fdc8d8SChris Lattner     {
101630fdc8d8SChris Lattner         // No breakpoint selected; disable all currently set breakpoints.
101730fdc8d8SChris Lattner         if (args.GetArgumentCount() != 0)
101830fdc8d8SChris Lattner         {
101930fdc8d8SChris Lattner             result.AppendErrorWithFormat ("Specify breakpoints to delete with the -i option.\n");
102030fdc8d8SChris Lattner             result.SetStatus (eReturnStatusFailed);
102130fdc8d8SChris Lattner             return false;
102230fdc8d8SChris Lattner         }
102330fdc8d8SChris Lattner 
102430fdc8d8SChris Lattner         target->RemoveAllBreakpoints ();
102530fdc8d8SChris Lattner         result.AppendMessageWithFormat ("All breakpoints removed. (%d breakpoints)\n", num_breakpoints);
102630fdc8d8SChris Lattner         result.SetStatus (eReturnStatusSuccessFinishNoResult);
102730fdc8d8SChris Lattner     }
102830fdc8d8SChris Lattner     else
102930fdc8d8SChris Lattner     {
103030fdc8d8SChris Lattner         // Particular breakpoint selected; disable that breakpoint.
103130fdc8d8SChris Lattner         BreakpointIDList valid_bp_ids;
103230fdc8d8SChris Lattner         CommandObjectMultiwordBreakpoint::VerifyBreakpointIDs (args, target, result, &valid_bp_ids);
103330fdc8d8SChris Lattner 
103430fdc8d8SChris Lattner         if (result.Succeeded())
103530fdc8d8SChris Lattner         {
103630fdc8d8SChris Lattner             int delete_count = 0;
103730fdc8d8SChris Lattner             int disable_count = 0;
103830fdc8d8SChris Lattner             for (int i = 0; i < valid_bp_ids.Size(); ++i)
103930fdc8d8SChris Lattner             {
104030fdc8d8SChris Lattner                 BreakpointID cur_bp_id = valid_bp_ids.GetBreakpointIDAtIndex (i);
104130fdc8d8SChris Lattner 
104230fdc8d8SChris Lattner                 if (cur_bp_id.GetBreakpointID() != LLDB_INVALID_BREAK_ID)
104330fdc8d8SChris Lattner                 {
104430fdc8d8SChris Lattner                     if (cur_bp_id.GetLocationID() != LLDB_INVALID_BREAK_ID)
104530fdc8d8SChris Lattner                     {
104630fdc8d8SChris Lattner                         Breakpoint *breakpoint = target->GetBreakpointByID (cur_bp_id.GetBreakpointID()).get();
104730fdc8d8SChris Lattner                         BreakpointLocation *location = breakpoint->FindLocationByID (cur_bp_id.GetLocationID()).get();
104830fdc8d8SChris Lattner                         // It makes no sense to try to delete individual locations, so we disable them instead.
104930fdc8d8SChris Lattner                         if (location)
105030fdc8d8SChris Lattner                         {
105130fdc8d8SChris Lattner                             location->SetEnabled (false);
105230fdc8d8SChris Lattner                             ++disable_count;
105330fdc8d8SChris Lattner                         }
105430fdc8d8SChris Lattner                     }
105530fdc8d8SChris Lattner                     else
105630fdc8d8SChris Lattner                     {
105730fdc8d8SChris Lattner                         target->RemoveBreakpointByID (cur_bp_id.GetBreakpointID());
105830fdc8d8SChris Lattner                         ++delete_count;
105930fdc8d8SChris Lattner                     }
106030fdc8d8SChris Lattner                 }
106130fdc8d8SChris Lattner             }
106230fdc8d8SChris Lattner             result.AppendMessageWithFormat ("%d breakpoints deleted; %d breakpoint locations disabled.\n",
106330fdc8d8SChris Lattner                                            delete_count, disable_count);
106430fdc8d8SChris Lattner             result.SetStatus (eReturnStatusSuccessFinishNoResult);
106530fdc8d8SChris Lattner         }
106630fdc8d8SChris Lattner     }
106730fdc8d8SChris Lattner     return result.Succeeded();
106830fdc8d8SChris Lattner }
10691b54c88cSJim Ingham 
10701b54c88cSJim Ingham //-------------------------------------------------------------------------
1071ae1c4cf5SJim Ingham // CommandObjectBreakpointModify::CommandOptions
10721b54c88cSJim Ingham //-------------------------------------------------------------------------
1073ae1c4cf5SJim Ingham #pragma mark Modify::CommandOptions
10741b54c88cSJim Ingham 
1075ae1c4cf5SJim Ingham CommandObjectBreakpointModify::CommandOptions::CommandOptions() :
10761b54c88cSJim Ingham     Options (),
10771b54c88cSJim Ingham     m_thread_id(LLDB_INVALID_THREAD_ID),
10781b54c88cSJim Ingham     m_thread_index (-1),
10791b54c88cSJim Ingham     m_thread_name(),
10801b54c88cSJim Ingham     m_queue_name(),
1081ae1c4cf5SJim Ingham     m_ignore_count (-1),
1082ae1c4cf5SJim Ingham     m_enable_passed (false)
10831b54c88cSJim Ingham {
10841b54c88cSJim Ingham }
10851b54c88cSJim Ingham 
1086ae1c4cf5SJim Ingham CommandObjectBreakpointModify::CommandOptions::~CommandOptions ()
10871b54c88cSJim Ingham {
10881b54c88cSJim Ingham }
10891b54c88cSJim Ingham 
10901b54c88cSJim Ingham lldb::OptionDefinition
1091ae1c4cf5SJim Ingham CommandObjectBreakpointModify::CommandOptions::g_option_table[] =
10921b54c88cSJim Ingham {
10931b54c88cSJim Ingham     { LLDB_OPT_SET_ALL, false, "ignore_count", 'k', required_argument,   NULL, 0, NULL,
10941b54c88cSJim Ingham         "Set the number of times this breakpoint is sKipped before stopping." },
10951b54c88cSJim Ingham 
10961b54c88cSJim Ingham     { LLDB_OPT_SET_ALL, false, "thread_index",       'x', required_argument, NULL, NULL, "<thread_index>",
10971b54c88cSJim Ingham         "The breakpoint stops only for the thread whose indeX matches this argument."},
10981b54c88cSJim Ingham 
10991b54c88cSJim Ingham     { LLDB_OPT_SET_ALL, false, "thread_id",       't', required_argument, NULL, NULL, "<thread_id>",
11001b54c88cSJim Ingham         "The breakpoint stops only for the thread whose TID matches this argument."},
11011b54c88cSJim Ingham 
11021b54c88cSJim Ingham     { LLDB_OPT_SET_ALL, false, "thread_name",       'T', required_argument, NULL, NULL, "<thread_name>",
11031b54c88cSJim Ingham         "The breakpoint stops only for the thread whose thread name matches this argument."},
11041b54c88cSJim Ingham 
11051b54c88cSJim Ingham     { LLDB_OPT_SET_ALL, false, "queue_name",       'q', required_argument, NULL, NULL, "<queue_name>",
11061b54c88cSJim Ingham         "The breakpoint stops only for threads in the queue whose name is given by this argument."},
11071b54c88cSJim Ingham 
1108ae1c4cf5SJim Ingham     { LLDB_OPT_SET_1, false, "enable",       'e', no_argument, NULL, NULL, NULL,
1109ae1c4cf5SJim Ingham         "Enable the breakpoint."},
1110ae1c4cf5SJim Ingham 
1111ae1c4cf5SJim Ingham     { LLDB_OPT_SET_2, false, "disable",       'd', no_argument, NULL, NULL, NULL,
1112ae1c4cf5SJim Ingham         "Disable the breakpoint."},
1113ae1c4cf5SJim Ingham 
1114ae1c4cf5SJim Ingham 
11151b54c88cSJim Ingham     { 0, false, NULL, 0, 0, NULL, 0, NULL, NULL }
11161b54c88cSJim Ingham };
11171b54c88cSJim Ingham 
11181b54c88cSJim Ingham const lldb::OptionDefinition*
1119ae1c4cf5SJim Ingham CommandObjectBreakpointModify::CommandOptions::GetDefinitions ()
11201b54c88cSJim Ingham {
11211b54c88cSJim Ingham     return g_option_table;
11221b54c88cSJim Ingham }
11231b54c88cSJim Ingham 
11241b54c88cSJim Ingham Error
1125ae1c4cf5SJim Ingham CommandObjectBreakpointModify::CommandOptions::SetOptionValue (int option_idx, const char *option_arg)
11261b54c88cSJim Ingham {
11271b54c88cSJim Ingham     Error error;
11281b54c88cSJim Ingham     char short_option = (char) m_getopt_table[option_idx].val;
11291b54c88cSJim Ingham 
11301b54c88cSJim Ingham     switch (short_option)
11311b54c88cSJim Ingham     {
1132ae1c4cf5SJim Ingham         case 'd':
1133ae1c4cf5SJim Ingham             m_enable_passed = true;
1134ae1c4cf5SJim Ingham             m_enable_value = false;
1135ae1c4cf5SJim Ingham             break;
1136ae1c4cf5SJim Ingham         case 'e':
1137ae1c4cf5SJim Ingham             m_enable_passed = true;
1138ae1c4cf5SJim Ingham             m_enable_value = true;
1139ae1c4cf5SJim Ingham             break;
11401b54c88cSJim Ingham         case 'k':
11411b54c88cSJim Ingham         {
11421b54c88cSJim Ingham             m_ignore_count = Args::StringToSInt32(optarg, -1, 0);
11431b54c88cSJim Ingham             if (m_ignore_count == -1)
11441b54c88cSJim Ingham                error.SetErrorStringWithFormat ("Invalid ignore count '%s'.\n", optarg);
11451b54c88cSJim Ingham         }
1146ae1c4cf5SJim Ingham         break;
11471b54c88cSJim Ingham         case 't' :
11481b54c88cSJim Ingham         {
11491b54c88cSJim Ingham             m_thread_id = Args::StringToUInt64(optarg, LLDB_INVALID_THREAD_ID, 0);
11501b54c88cSJim Ingham             if (m_thread_id == LLDB_INVALID_THREAD_ID)
11511b54c88cSJim Ingham                error.SetErrorStringWithFormat ("Invalid thread id string '%s'.\n", optarg);
11521b54c88cSJim Ingham         }
11531b54c88cSJim Ingham         break;
11541b54c88cSJim Ingham         case 'T':
1155b2a38a72SJim Ingham             if (option_arg != NULL)
11561b54c88cSJim Ingham                 m_thread_name = option_arg;
1157b2a38a72SJim Ingham             else
1158b2a38a72SJim Ingham                 m_thread_name.clear();
1159b2a38a72SJim Ingham             m_name_passed = true;
11601b54c88cSJim Ingham             break;
11611b54c88cSJim Ingham         case 'q':
1162b2a38a72SJim Ingham             if (option_arg != NULL)
11631b54c88cSJim Ingham                 m_queue_name = option_arg;
1164b2a38a72SJim Ingham             else
1165b2a38a72SJim Ingham                 m_queue_name.clear();
1166b2a38a72SJim Ingham             m_queue_passed = true;
11671b54c88cSJim Ingham             break;
11681b54c88cSJim Ingham         case 'x':
11691b54c88cSJim Ingham         {
11701b54c88cSJim Ingham             m_thread_index = Args::StringToUInt64(optarg, -1, 0);
11711b54c88cSJim Ingham             if (m_thread_id == -1)
11721b54c88cSJim Ingham                error.SetErrorStringWithFormat ("Invalid thread index string '%s'.\n", optarg);
11731b54c88cSJim Ingham 
11741b54c88cSJim Ingham         }
11751b54c88cSJim Ingham         break;
11761b54c88cSJim Ingham         default:
11771b54c88cSJim Ingham             error.SetErrorStringWithFormat ("Unrecognized option '%c'.\n", short_option);
11781b54c88cSJim Ingham             break;
11791b54c88cSJim Ingham     }
11801b54c88cSJim Ingham 
11811b54c88cSJim Ingham     return error;
11821b54c88cSJim Ingham }
11831b54c88cSJim Ingham 
11841b54c88cSJim Ingham void
1185ae1c4cf5SJim Ingham CommandObjectBreakpointModify::CommandOptions::ResetOptionValues ()
11861b54c88cSJim Ingham {
11871b54c88cSJim Ingham     Options::ResetOptionValues();
11881b54c88cSJim Ingham 
11891b54c88cSJim Ingham     m_ignore_count = -1;
11901b54c88cSJim Ingham     m_thread_id = LLDB_INVALID_THREAD_ID;
11911b54c88cSJim Ingham     m_thread_index = -1;
11921b54c88cSJim Ingham     m_thread_name.clear();
11931b54c88cSJim Ingham     m_queue_name.clear();
1194ae1c4cf5SJim Ingham     m_enable_passed = false;
1195b2a38a72SJim Ingham     m_queue_passed = false;
1196b2a38a72SJim Ingham     m_name_passed = false;
11971b54c88cSJim Ingham }
11981b54c88cSJim Ingham 
11991b54c88cSJim Ingham //-------------------------------------------------------------------------
1200ae1c4cf5SJim Ingham // CommandObjectBreakpointModify
12011b54c88cSJim Ingham //-------------------------------------------------------------------------
1202ae1c4cf5SJim Ingham #pragma mark Modify
12031b54c88cSJim Ingham 
1204ae1c4cf5SJim Ingham CommandObjectBreakpointModify::CommandObjectBreakpointModify () :
1205ae1c4cf5SJim Ingham     CommandObject ("breakpoint modify", "Modifys the options on a breakpoint or set of breakpoints in the executable.",
1206ae1c4cf5SJim Ingham                    "breakpoint modify <cmd-options> break-id [break-id ...]")
12071b54c88cSJim Ingham {
12081b54c88cSJim Ingham }
12091b54c88cSJim Ingham 
1210ae1c4cf5SJim Ingham CommandObjectBreakpointModify::~CommandObjectBreakpointModify ()
12111b54c88cSJim Ingham {
12121b54c88cSJim Ingham }
12131b54c88cSJim Ingham 
12141b54c88cSJim Ingham Options *
1215ae1c4cf5SJim Ingham CommandObjectBreakpointModify::GetOptions ()
12161b54c88cSJim Ingham {
12171b54c88cSJim Ingham     return &m_options;
12181b54c88cSJim Ingham }
12191b54c88cSJim Ingham 
12201b54c88cSJim Ingham bool
1221ae1c4cf5SJim Ingham CommandObjectBreakpointModify::Execute
12221b54c88cSJim Ingham (
12236611103cSGreg Clayton     CommandInterpreter &interpreter,
12241b54c88cSJim Ingham     Args& command,
12251b54c88cSJim Ingham     CommandReturnObject &result
12261b54c88cSJim Ingham )
12271b54c88cSJim Ingham {
12281b54c88cSJim Ingham     if (command.GetArgumentCount() == 0)
12291b54c88cSJim Ingham     {
12301b54c88cSJim Ingham         result.AppendError ("No breakpoints specified.");
12311b54c88cSJim Ingham         result.SetStatus (eReturnStatusFailed);
12321b54c88cSJim Ingham         return false;
12331b54c88cSJim Ingham     }
12341b54c88cSJim Ingham 
12356611103cSGreg Clayton     Target *target = interpreter.GetDebugger().GetCurrentTarget().get();
12361b54c88cSJim Ingham     if (target == NULL)
12371b54c88cSJim Ingham     {
12381b54c88cSJim Ingham         result.AppendError ("Invalid target, set executable file using 'file' command.");
12391b54c88cSJim Ingham         result.SetStatus (eReturnStatusFailed);
12401b54c88cSJim Ingham         return false;
12411b54c88cSJim Ingham     }
12421b54c88cSJim Ingham 
12431b54c88cSJim Ingham     Mutex::Locker locker;
12441b54c88cSJim Ingham     target->GetBreakpointList().GetListMutex(locker);
12451b54c88cSJim Ingham 
12461b54c88cSJim Ingham     BreakpointIDList valid_bp_ids;
12471b54c88cSJim Ingham 
12481b54c88cSJim Ingham     CommandObjectMultiwordBreakpoint::VerifyBreakpointIDs (command, target, result, &valid_bp_ids);
12491b54c88cSJim Ingham 
12501b54c88cSJim Ingham     if (result.Succeeded())
12511b54c88cSJim Ingham     {
12521b54c88cSJim Ingham         for (int i = 0; i < valid_bp_ids.Size(); ++i)
12531b54c88cSJim Ingham         {
12541b54c88cSJim Ingham             BreakpointID cur_bp_id = valid_bp_ids.GetBreakpointIDAtIndex (i);
12551b54c88cSJim Ingham 
12561b54c88cSJim Ingham             if (cur_bp_id.GetBreakpointID() != LLDB_INVALID_BREAK_ID)
12571b54c88cSJim Ingham             {
12581b54c88cSJim Ingham                 Breakpoint *bp = target->GetBreakpointByID (cur_bp_id.GetBreakpointID()).get();
12591b54c88cSJim Ingham                 if (cur_bp_id.GetLocationID() != LLDB_INVALID_BREAK_ID)
12601b54c88cSJim Ingham                 {
12611b54c88cSJim Ingham                     BreakpointLocation *location = bp->FindLocationByID (cur_bp_id.GetLocationID()).get();
12621b54c88cSJim Ingham                     if (location)
12631b54c88cSJim Ingham                     {
12641b54c88cSJim Ingham                         if (m_options.m_thread_id != LLDB_INVALID_THREAD_ID)
12651b54c88cSJim Ingham                             location->SetThreadID (m_options.m_thread_id);
12661b54c88cSJim Ingham 
12671b54c88cSJim Ingham                         if (m_options.m_thread_index != -1)
12681b54c88cSJim Ingham                             location->GetLocationOptions()->GetThreadSpec()->SetIndex(m_options.m_thread_index);
12691b54c88cSJim Ingham 
1270b2a38a72SJim Ingham                         if (m_options.m_name_passed)
12711b54c88cSJim Ingham                             location->GetLocationOptions()->GetThreadSpec()->SetName(m_options.m_thread_name.c_str());
12721b54c88cSJim Ingham 
1273b2a38a72SJim Ingham                         if (m_options.m_queue_passed)
12741b54c88cSJim Ingham                             location->GetLocationOptions()->GetThreadSpec()->SetQueueName(m_options.m_queue_name.c_str());
12751b54c88cSJim Ingham 
12761b54c88cSJim Ingham                         if (m_options.m_ignore_count != -1)
12771b54c88cSJim Ingham                             location->GetLocationOptions()->SetIgnoreCount(m_options.m_ignore_count);
1278ae1c4cf5SJim Ingham 
1279ae1c4cf5SJim Ingham                         if (m_options.m_enable_passed)
1280ae1c4cf5SJim Ingham                             location->SetEnabled (m_options.m_enable_value);
12811b54c88cSJim Ingham                     }
12821b54c88cSJim Ingham                 }
12831b54c88cSJim Ingham                 else
12841b54c88cSJim Ingham                 {
12851b54c88cSJim Ingham                     if (m_options.m_thread_id != LLDB_INVALID_THREAD_ID)
12861b54c88cSJim Ingham                         bp->SetThreadID (m_options.m_thread_id);
12871b54c88cSJim Ingham 
12881b54c88cSJim Ingham                     if (m_options.m_thread_index != -1)
12891b54c88cSJim Ingham                         bp->GetOptions()->GetThreadSpec()->SetIndex(m_options.m_thread_index);
12901b54c88cSJim Ingham 
1291b2a38a72SJim Ingham                     if (m_options.m_name_passed)
12921b54c88cSJim Ingham                         bp->GetOptions()->GetThreadSpec()->SetName(m_options.m_thread_name.c_str());
12931b54c88cSJim Ingham 
1294b2a38a72SJim Ingham                     if (m_options.m_queue_passed)
12951b54c88cSJim Ingham                         bp->GetOptions()->GetThreadSpec()->SetQueueName(m_options.m_queue_name.c_str());
12961b54c88cSJim Ingham 
12971b54c88cSJim Ingham                     if (m_options.m_ignore_count != -1)
12981b54c88cSJim Ingham                         bp->GetOptions()->SetIgnoreCount(m_options.m_ignore_count);
1299ae1c4cf5SJim Ingham 
1300ae1c4cf5SJim Ingham                     if (m_options.m_enable_passed)
1301ae1c4cf5SJim Ingham                         bp->SetEnabled (m_options.m_enable_value);
1302ae1c4cf5SJim Ingham 
13031b54c88cSJim Ingham                 }
13041b54c88cSJim Ingham             }
13051b54c88cSJim Ingham         }
13061b54c88cSJim Ingham     }
13071b54c88cSJim Ingham 
13081b54c88cSJim Ingham     return result.Succeeded();
13091b54c88cSJim Ingham }
13101b54c88cSJim Ingham 
13111b54c88cSJim Ingham 
1312