1ac7ddfbfSEd Maste //===-- CommandObjectBreakpointCommand.cpp ----------------------*- C++ -*-===// 2ac7ddfbfSEd Maste // 3ac7ddfbfSEd Maste // The LLVM Compiler Infrastructure 4ac7ddfbfSEd Maste // 5ac7ddfbfSEd Maste // This file is distributed under the University of Illinois Open Source 6ac7ddfbfSEd Maste // License. See LICENSE.TXT for details. 7ac7ddfbfSEd Maste // 8ac7ddfbfSEd Maste //===----------------------------------------------------------------------===// 9ac7ddfbfSEd Maste 10ac7ddfbfSEd Maste // C Includes 11ac7ddfbfSEd Maste // C++ Includes 12ac7ddfbfSEd Maste 13ac7ddfbfSEd Maste 14ac7ddfbfSEd Maste #include "CommandObjectBreakpointCommand.h" 15ac7ddfbfSEd Maste #include "CommandObjectBreakpoint.h" 16ac7ddfbfSEd Maste 1712b93ac6SEd Maste #include "lldb/Core/IOHandler.h" 18ac7ddfbfSEd Maste #include "lldb/Interpreter/CommandInterpreter.h" 19ac7ddfbfSEd Maste #include "lldb/Interpreter/CommandReturnObject.h" 20ac7ddfbfSEd Maste #include "lldb/Target/Target.h" 21ac7ddfbfSEd Maste #include "lldb/Target/Thread.h" 22ac7ddfbfSEd Maste #include "lldb/Breakpoint/BreakpointIDList.h" 23ac7ddfbfSEd Maste #include "lldb/Breakpoint/Breakpoint.h" 24ac7ddfbfSEd Maste #include "lldb/Breakpoint/BreakpointLocation.h" 25ac7ddfbfSEd Maste #include "lldb/Breakpoint/StoppointCallbackContext.h" 26ac7ddfbfSEd Maste #include "lldb/Core/State.h" 27ac7ddfbfSEd Maste 28ac7ddfbfSEd Maste using namespace lldb; 29ac7ddfbfSEd Maste using namespace lldb_private; 30ac7ddfbfSEd Maste 31ac7ddfbfSEd Maste //------------------------------------------------------------------------- 32ac7ddfbfSEd Maste // CommandObjectBreakpointCommandAdd 33ac7ddfbfSEd Maste //------------------------------------------------------------------------- 34ac7ddfbfSEd Maste 35ac7ddfbfSEd Maste 3612b93ac6SEd Maste class CommandObjectBreakpointCommandAdd : 3712b93ac6SEd Maste public CommandObjectParsed, 3812b93ac6SEd Maste public IOHandlerDelegateMultiline 39ac7ddfbfSEd Maste { 40ac7ddfbfSEd Maste public: 41ac7ddfbfSEd Maste 42ac7ddfbfSEd Maste CommandObjectBreakpointCommandAdd (CommandInterpreter &interpreter) : 43ac7ddfbfSEd Maste CommandObjectParsed (interpreter, 44ac7ddfbfSEd Maste "add", 450127ef0fSEd Maste "Add a set of commands to a breakpoint, to be executed whenever the breakpoint is hit." 460127ef0fSEd Maste " If no breakpoint is specified, adds the commands to the last created breakpoint.", 47ac7ddfbfSEd Maste NULL), 4812b93ac6SEd Maste IOHandlerDelegateMultiline ("DONE", IOHandlerDelegate::Completion::LLDBCommand), 49ac7ddfbfSEd Maste m_options (interpreter) 50ac7ddfbfSEd Maste { 51ac7ddfbfSEd Maste SetHelpLong ( 52b91a7dfcSDimitry Andric R"( 53b91a7dfcSDimitry Andric General information about entering breakpoint commands 54b91a7dfcSDimitry Andric ------------------------------------------------------ 55b91a7dfcSDimitry Andric 56b91a7dfcSDimitry Andric )" "This command will prompt for commands to be executed when the specified \ 57b91a7dfcSDimitry Andric breakpoint is hit. Each command is typed on its own line following the '> ' \ 58b91a7dfcSDimitry Andric prompt until 'DONE' is entered." R"( 59b91a7dfcSDimitry Andric 60b91a7dfcSDimitry Andric )" "Syntactic errors may not be detected when initially entered, and many \ 61b91a7dfcSDimitry Andric malformed commands can silently fail when executed. If your breakpoint commands \ 62b91a7dfcSDimitry Andric do not appear to be executing, double-check the command syntax." R"( 63b91a7dfcSDimitry Andric 64b91a7dfcSDimitry Andric )" "Note: You may enter any debugger command exactly as you would at the debugger \ 65b91a7dfcSDimitry Andric prompt. There is no limit to the number of commands supplied, but do NOT enter \ 66b91a7dfcSDimitry Andric more than one command per line." R"( 67b91a7dfcSDimitry Andric 68b91a7dfcSDimitry Andric Special information about PYTHON breakpoint commands 69b91a7dfcSDimitry Andric ---------------------------------------------------- 70b91a7dfcSDimitry Andric 71b91a7dfcSDimitry Andric )" "You may enter either one or more lines of Python, including function \ 72b91a7dfcSDimitry Andric definitions or calls to functions that will have been imported by the time \ 73b91a7dfcSDimitry Andric the code executes. Single line breakpoint commands will be interpreted 'as is' \ 74b91a7dfcSDimitry Andric when the breakpoint is hit. Multiple lines of Python will be wrapped in a \ 75b91a7dfcSDimitry Andric generated function, and a call to the function will be attached to the breakpoint." R"( 76b91a7dfcSDimitry Andric 77b91a7dfcSDimitry Andric This auto-generated function is passed in three arguments: 78b91a7dfcSDimitry Andric 79b91a7dfcSDimitry Andric frame: an lldb.SBFrame object for the frame which hit breakpoint. 80b91a7dfcSDimitry Andric 81b91a7dfcSDimitry Andric bp_loc: an lldb.SBBreakpointLocation object that represents the breakpoint location that was hit. 82b91a7dfcSDimitry Andric 83b91a7dfcSDimitry Andric dict: the python session dictionary hit. 84b91a7dfcSDimitry Andric 85b91a7dfcSDimitry Andric )" "When specifying a python function with the --python-function option, you need \ 86b91a7dfcSDimitry Andric to supply the function name prepended by the module name:" R"( 87b91a7dfcSDimitry Andric 88b91a7dfcSDimitry Andric --python-function myutils.breakpoint_callback 89b91a7dfcSDimitry Andric 90b91a7dfcSDimitry Andric The function itself must have the following prototype: 91b91a7dfcSDimitry Andric 92b91a7dfcSDimitry Andric def breakpoint_callback(frame, bp_loc, dict): 93b91a7dfcSDimitry Andric # Your code goes here 94b91a7dfcSDimitry Andric 95b91a7dfcSDimitry Andric )" "The arguments are the same as the arguments passed to generated functions as \ 96b91a7dfcSDimitry Andric described above. Note that the global variable 'lldb.frame' will NOT be updated when \ 97b91a7dfcSDimitry Andric this function is called, so be sure to use the 'frame' argument. The 'frame' argument \ 98b91a7dfcSDimitry Andric can get you to the thread via frame.GetThread(), the thread can get you to the \ 99b91a7dfcSDimitry Andric process via thread.GetProcess(), and the process can get you back to the target \ 100b91a7dfcSDimitry Andric via process.GetTarget()." R"( 101b91a7dfcSDimitry Andric 102b91a7dfcSDimitry Andric )" "Important Note: As Python code gets collected into functions, access to global \ 103b91a7dfcSDimitry Andric variables requires explicit scoping using the 'global' keyword. Be sure to use correct \ 104b91a7dfcSDimitry Andric Python syntax, including indentation, when entering Python breakpoint commands." R"( 105b91a7dfcSDimitry Andric 106b91a7dfcSDimitry Andric Example Python one-line breakpoint command: 107b91a7dfcSDimitry Andric 108b91a7dfcSDimitry Andric (lldb) breakpoint command add -s python 1 109b91a7dfcSDimitry Andric Enter your Python command(s). Type 'DONE' to end. 110b91a7dfcSDimitry Andric > print "Hit this breakpoint!" 111b91a7dfcSDimitry Andric > DONE 112b91a7dfcSDimitry Andric 113b91a7dfcSDimitry Andric As a convenience, this also works for a short Python one-liner: 114b91a7dfcSDimitry Andric 115b91a7dfcSDimitry Andric (lldb) breakpoint command add -s python 1 -o 'import time; print time.asctime()' 116b91a7dfcSDimitry Andric (lldb) run 117b91a7dfcSDimitry Andric Launching '.../a.out' (x86_64) 118b91a7dfcSDimitry Andric (lldb) Fri Sep 10 12:17:45 2010 119b91a7dfcSDimitry Andric Process 21778 Stopped 120b91a7dfcSDimitry Andric * thread #1: tid = 0x2e03, 0x0000000100000de8 a.out`c + 7 at main.c:39, stop reason = breakpoint 1.1, queue = com.apple.main-thread 121b91a7dfcSDimitry Andric 36 122b91a7dfcSDimitry Andric 37 int c(int val) 123b91a7dfcSDimitry Andric 38 { 124b91a7dfcSDimitry Andric 39 -> return val + 3; 125b91a7dfcSDimitry Andric 40 } 126b91a7dfcSDimitry Andric 41 127b91a7dfcSDimitry Andric 42 int main (int argc, char const *argv[]) 128b91a7dfcSDimitry Andric 129b91a7dfcSDimitry Andric Example multiple line Python breakpoint command: 130b91a7dfcSDimitry Andric 131b91a7dfcSDimitry Andric (lldb) breakpoint command add -s p 1 132b91a7dfcSDimitry Andric Enter your Python command(s). Type 'DONE' to end. 133b91a7dfcSDimitry Andric > global bp_count 134b91a7dfcSDimitry Andric > bp_count = bp_count + 1 135b91a7dfcSDimitry Andric > print "Hit this breakpoint " + repr(bp_count) + " times!" 136b91a7dfcSDimitry Andric > DONE 137b91a7dfcSDimitry Andric 138b91a7dfcSDimitry Andric Example multiple line Python breakpoint command, using function definition: 139b91a7dfcSDimitry Andric 140b91a7dfcSDimitry Andric (lldb) breakpoint command add -s python 1 141b91a7dfcSDimitry Andric Enter your Python command(s). Type 'DONE' to end. 142b91a7dfcSDimitry Andric > def breakpoint_output (bp_no): 143b91a7dfcSDimitry Andric > out_string = "Hit breakpoint number " + repr (bp_no) 144b91a7dfcSDimitry Andric > print out_string 145b91a7dfcSDimitry Andric > return True 146b91a7dfcSDimitry Andric > breakpoint_output (1) 147b91a7dfcSDimitry Andric > DONE 148b91a7dfcSDimitry Andric 149b91a7dfcSDimitry Andric )" "In this case, since there is a reference to a global variable, \ 150b91a7dfcSDimitry Andric 'bp_count', you will also need to make sure 'bp_count' exists and is \ 151b91a7dfcSDimitry Andric initialized:" R"( 152b91a7dfcSDimitry Andric 153b91a7dfcSDimitry Andric (lldb) script 154b91a7dfcSDimitry Andric >>> bp_count = 0 155b91a7dfcSDimitry Andric >>> quit() 156b91a7dfcSDimitry Andric 157b91a7dfcSDimitry Andric )" "Your Python code, however organized, can optionally return a value. \ 158b91a7dfcSDimitry Andric If the returned value is False, that tells LLDB not to stop at the breakpoint \ 159b91a7dfcSDimitry Andric to which the code is associated. Returning anything other than False, or even \ 160b91a7dfcSDimitry Andric returning None, or even omitting a return statement entirely, will cause \ 161b91a7dfcSDimitry Andric LLDB to stop." R"( 162b91a7dfcSDimitry Andric 163b91a7dfcSDimitry Andric )" "Final Note: A warning that no breakpoint command was generated when there \ 164b91a7dfcSDimitry Andric are no syntax errors may indicate that a function was declared but never called." 165b91a7dfcSDimitry Andric ); 166ac7ddfbfSEd Maste 167ac7ddfbfSEd Maste CommandArgumentEntry arg; 168ac7ddfbfSEd Maste CommandArgumentData bp_id_arg; 169ac7ddfbfSEd Maste 170ac7ddfbfSEd Maste // Define the first (and only) variant of this arg. 171ac7ddfbfSEd Maste bp_id_arg.arg_type = eArgTypeBreakpointID; 1720127ef0fSEd Maste bp_id_arg.arg_repetition = eArgRepeatOptional; 173ac7ddfbfSEd Maste 174ac7ddfbfSEd Maste // There is only one variant this argument could be; put it into the argument entry. 175ac7ddfbfSEd Maste arg.push_back (bp_id_arg); 176ac7ddfbfSEd Maste 177ac7ddfbfSEd Maste // Push the data for the first argument into the m_arguments vector. 178ac7ddfbfSEd Maste m_arguments.push_back (arg); 179ac7ddfbfSEd Maste } 180ac7ddfbfSEd Maste 1819f2f44ceSEd Maste ~CommandObjectBreakpointCommandAdd () override {} 182ac7ddfbfSEd Maste 1839f2f44ceSEd Maste Options * 1849f2f44ceSEd Maste GetOptions () override 185ac7ddfbfSEd Maste { 186ac7ddfbfSEd Maste return &m_options; 187ac7ddfbfSEd Maste } 188ac7ddfbfSEd Maste 1899f2f44ceSEd Maste void 1909f2f44ceSEd Maste IOHandlerActivated (IOHandler &io_handler) override 19112b93ac6SEd Maste { 19212b93ac6SEd Maste StreamFileSP output_sp(io_handler.GetOutputStreamFile()); 19312b93ac6SEd Maste if (output_sp) 19412b93ac6SEd Maste { 19512b93ac6SEd Maste output_sp->PutCString(g_reader_instructions); 19612b93ac6SEd Maste output_sp->Flush(); 19712b93ac6SEd Maste } 19812b93ac6SEd Maste } 19912b93ac6SEd Maste 20012b93ac6SEd Maste 2019f2f44ceSEd Maste void 2029f2f44ceSEd Maste IOHandlerInputComplete (IOHandler &io_handler, std::string &line) override 20312b93ac6SEd Maste { 20412b93ac6SEd Maste io_handler.SetIsDone(true); 20512b93ac6SEd Maste 2060127ef0fSEd Maste std::vector<BreakpointOptions *> *bp_options_vec = (std::vector<BreakpointOptions *> *)io_handler.GetUserData(); 2070127ef0fSEd Maste for (BreakpointOptions *bp_options : *bp_options_vec) 20812b93ac6SEd Maste { 2090127ef0fSEd Maste if (!bp_options) 2100127ef0fSEd Maste continue; 2110127ef0fSEd Maste 21212b93ac6SEd Maste std::unique_ptr<BreakpointOptions::CommandData> data_ap(new BreakpointOptions::CommandData()); 21312b93ac6SEd Maste if (data_ap.get()) 21412b93ac6SEd Maste { 21512b93ac6SEd Maste data_ap->user_source.SplitIntoLines (line.c_str(), line.size()); 21612b93ac6SEd Maste BatonSP baton_sp (new BreakpointOptions::CommandBaton (data_ap.release())); 21712b93ac6SEd Maste bp_options->SetCallback (BreakpointOptionsCallbackFunction, baton_sp); 21812b93ac6SEd Maste } 21912b93ac6SEd Maste } 22012b93ac6SEd Maste } 22112b93ac6SEd Maste 222ac7ddfbfSEd Maste void 2230127ef0fSEd Maste CollectDataForBreakpointCommandCallback (std::vector<BreakpointOptions *> &bp_options_vec, 224ac7ddfbfSEd Maste CommandReturnObject &result) 225ac7ddfbfSEd Maste { 22612b93ac6SEd Maste m_interpreter.GetLLDBCommandsFromIOHandler ("> ", // Prompt 22712b93ac6SEd Maste *this, // IOHandlerDelegate 22812b93ac6SEd Maste true, // Run IOHandler in async mode 2290127ef0fSEd Maste &bp_options_vec); // Baton for the "io_handler" that will be passed back into our IOHandlerDelegate functions 230ac7ddfbfSEd Maste } 231ac7ddfbfSEd Maste 232ac7ddfbfSEd Maste /// Set a one-liner as the callback for the breakpoint. 233ac7ddfbfSEd Maste void 2340127ef0fSEd Maste SetBreakpointCommandCallback (std::vector<BreakpointOptions *> &bp_options_vec, 235ac7ddfbfSEd Maste const char *oneliner) 236ac7ddfbfSEd Maste { 2370127ef0fSEd Maste for (auto bp_options : bp_options_vec) 2380127ef0fSEd Maste { 239ac7ddfbfSEd Maste std::unique_ptr<BreakpointOptions::CommandData> data_ap(new BreakpointOptions::CommandData()); 240ac7ddfbfSEd Maste 241ac7ddfbfSEd Maste // It's necessary to set both user_source and script_source to the oneliner. 242ac7ddfbfSEd Maste // The former is used to generate callback description (as in breakpoint command list) 243ac7ddfbfSEd Maste // while the latter is used for Python to interpret during the actual callback. 244ac7ddfbfSEd Maste data_ap->user_source.AppendString (oneliner); 245ac7ddfbfSEd Maste data_ap->script_source.assign (oneliner); 246ac7ddfbfSEd Maste data_ap->stop_on_error = m_options.m_stop_on_error; 247ac7ddfbfSEd Maste 248ac7ddfbfSEd Maste BatonSP baton_sp (new BreakpointOptions::CommandBaton (data_ap.release())); 249ac7ddfbfSEd Maste bp_options->SetCallback (BreakpointOptionsCallbackFunction, baton_sp); 2500127ef0fSEd Maste } 251ac7ddfbfSEd Maste return; 252ac7ddfbfSEd Maste } 253ac7ddfbfSEd Maste 254ac7ddfbfSEd Maste static bool 255ac7ddfbfSEd Maste BreakpointOptionsCallbackFunction (void *baton, 256ac7ddfbfSEd Maste StoppointCallbackContext *context, 257ac7ddfbfSEd Maste lldb::user_id_t break_id, 258ac7ddfbfSEd Maste lldb::user_id_t break_loc_id) 259ac7ddfbfSEd Maste { 260ac7ddfbfSEd Maste bool ret_value = true; 261ac7ddfbfSEd Maste if (baton == NULL) 262ac7ddfbfSEd Maste return true; 263ac7ddfbfSEd Maste 264ac7ddfbfSEd Maste 265ac7ddfbfSEd Maste BreakpointOptions::CommandData *data = (BreakpointOptions::CommandData *) baton; 266ac7ddfbfSEd Maste StringList &commands = data->user_source; 267ac7ddfbfSEd Maste 268ac7ddfbfSEd Maste if (commands.GetSize() > 0) 269ac7ddfbfSEd Maste { 270ac7ddfbfSEd Maste ExecutionContext exe_ctx (context->exe_ctx_ref); 271ac7ddfbfSEd Maste Target *target = exe_ctx.GetTargetPtr(); 272ac7ddfbfSEd Maste if (target) 273ac7ddfbfSEd Maste { 274ac7ddfbfSEd Maste CommandReturnObject result; 275ac7ddfbfSEd Maste Debugger &debugger = target->GetDebugger(); 276ac7ddfbfSEd Maste // Rig up the results secondary output stream to the debugger's, so the output will come out synchronously 277ac7ddfbfSEd Maste // if the debugger is set up that way. 278ac7ddfbfSEd Maste 279ac7ddfbfSEd Maste StreamSP output_stream (debugger.GetAsyncOutputStream()); 280ac7ddfbfSEd Maste StreamSP error_stream (debugger.GetAsyncErrorStream()); 281ac7ddfbfSEd Maste result.SetImmediateOutputStream (output_stream); 282ac7ddfbfSEd Maste result.SetImmediateErrorStream (error_stream); 283ac7ddfbfSEd Maste 2847aa51b79SEd Maste CommandInterpreterRunOptions options; 2857aa51b79SEd Maste options.SetStopOnContinue(true); 2867aa51b79SEd Maste options.SetStopOnError (data->stop_on_error); 2877aa51b79SEd Maste options.SetEchoCommands (true); 2887aa51b79SEd Maste options.SetPrintResults (true); 2897aa51b79SEd Maste options.SetAddToHistory (false); 290ac7ddfbfSEd Maste 291ac7ddfbfSEd Maste debugger.GetCommandInterpreter().HandleCommands (commands, 292ac7ddfbfSEd Maste &exe_ctx, 2937aa51b79SEd Maste options, 294ac7ddfbfSEd Maste result); 295ac7ddfbfSEd Maste result.GetImmediateOutputStream()->Flush(); 296ac7ddfbfSEd Maste result.GetImmediateErrorStream()->Flush(); 297ac7ddfbfSEd Maste } 298ac7ddfbfSEd Maste } 299ac7ddfbfSEd Maste return ret_value; 300ac7ddfbfSEd Maste } 301ac7ddfbfSEd Maste 302ac7ddfbfSEd Maste class CommandOptions : public Options 303ac7ddfbfSEd Maste { 304ac7ddfbfSEd Maste public: 305ac7ddfbfSEd Maste 306ac7ddfbfSEd Maste CommandOptions (CommandInterpreter &interpreter) : 307ac7ddfbfSEd Maste Options (interpreter), 308ac7ddfbfSEd Maste m_use_commands (false), 309ac7ddfbfSEd Maste m_use_script_language (false), 310ac7ddfbfSEd Maste m_script_language (eScriptLanguageNone), 311ac7ddfbfSEd Maste m_use_one_liner (false), 312ac7ddfbfSEd Maste m_one_liner(), 313ac7ddfbfSEd Maste m_function_name() 314ac7ddfbfSEd Maste { 315ac7ddfbfSEd Maste } 316ac7ddfbfSEd Maste 3179f2f44ceSEd Maste ~CommandOptions () override {} 318ac7ddfbfSEd Maste 3199f2f44ceSEd Maste Error 3209f2f44ceSEd Maste SetOptionValue (uint32_t option_idx, const char *option_arg) override 321ac7ddfbfSEd Maste { 322ac7ddfbfSEd Maste Error error; 323ac7ddfbfSEd Maste const int short_option = m_getopt_table[option_idx].val; 324ac7ddfbfSEd Maste 325ac7ddfbfSEd Maste switch (short_option) 326ac7ddfbfSEd Maste { 327ac7ddfbfSEd Maste case 'o': 328ac7ddfbfSEd Maste m_use_one_liner = true; 329ac7ddfbfSEd Maste m_one_liner = option_arg; 330ac7ddfbfSEd Maste break; 331ac7ddfbfSEd Maste 332ac7ddfbfSEd Maste case 's': 333ac7ddfbfSEd Maste m_script_language = (lldb::ScriptLanguage) Args::StringToOptionEnum (option_arg, 334ac7ddfbfSEd Maste g_option_table[option_idx].enum_values, 335ac7ddfbfSEd Maste eScriptLanguageNone, 336ac7ddfbfSEd Maste error); 337ac7ddfbfSEd Maste 338ac7ddfbfSEd Maste if (m_script_language == eScriptLanguagePython || m_script_language == eScriptLanguageDefault) 339ac7ddfbfSEd Maste { 340ac7ddfbfSEd Maste m_use_script_language = true; 341ac7ddfbfSEd Maste } 342ac7ddfbfSEd Maste else 343ac7ddfbfSEd Maste { 344ac7ddfbfSEd Maste m_use_script_language = false; 345ac7ddfbfSEd Maste } 346ac7ddfbfSEd Maste break; 347ac7ddfbfSEd Maste 348ac7ddfbfSEd Maste case 'e': 349ac7ddfbfSEd Maste { 350ac7ddfbfSEd Maste bool success = false; 351ac7ddfbfSEd Maste m_stop_on_error = Args::StringToBoolean(option_arg, false, &success); 352ac7ddfbfSEd Maste if (!success) 353ac7ddfbfSEd Maste error.SetErrorStringWithFormat("invalid value for stop-on-error: \"%s\"", option_arg); 354ac7ddfbfSEd Maste } 355ac7ddfbfSEd Maste break; 356ac7ddfbfSEd Maste 357ac7ddfbfSEd Maste case 'F': 358ac7ddfbfSEd Maste { 359ac7ddfbfSEd Maste m_use_one_liner = false; 360ac7ddfbfSEd Maste m_use_script_language = true; 361ac7ddfbfSEd Maste m_function_name.assign(option_arg); 362ac7ddfbfSEd Maste } 363ac7ddfbfSEd Maste break; 364ac7ddfbfSEd Maste 3657aa51b79SEd Maste case 'D': 3667aa51b79SEd Maste m_use_dummy = true; 3677aa51b79SEd Maste break; 3687aa51b79SEd Maste 369ac7ddfbfSEd Maste default: 370ac7ddfbfSEd Maste break; 371ac7ddfbfSEd Maste } 372ac7ddfbfSEd Maste return error; 373ac7ddfbfSEd Maste } 374ac7ddfbfSEd Maste void 3759f2f44ceSEd Maste OptionParsingStarting () override 376ac7ddfbfSEd Maste { 377ac7ddfbfSEd Maste m_use_commands = true; 378ac7ddfbfSEd Maste m_use_script_language = false; 379ac7ddfbfSEd Maste m_script_language = eScriptLanguageNone; 380ac7ddfbfSEd Maste 381ac7ddfbfSEd Maste m_use_one_liner = false; 382ac7ddfbfSEd Maste m_stop_on_error = true; 383ac7ddfbfSEd Maste m_one_liner.clear(); 384ac7ddfbfSEd Maste m_function_name.clear(); 3857aa51b79SEd Maste m_use_dummy = false; 386ac7ddfbfSEd Maste } 387ac7ddfbfSEd Maste 388ac7ddfbfSEd Maste const OptionDefinition* 3899f2f44ceSEd Maste GetDefinitions () override 390ac7ddfbfSEd Maste { 391ac7ddfbfSEd Maste return g_option_table; 392ac7ddfbfSEd Maste } 393ac7ddfbfSEd Maste 394ac7ddfbfSEd Maste // Options table: Required for subclasses of Options. 395ac7ddfbfSEd Maste 396ac7ddfbfSEd Maste static OptionDefinition g_option_table[]; 397ac7ddfbfSEd Maste 398ac7ddfbfSEd Maste // Instance variables to hold the values for command options. 399ac7ddfbfSEd Maste 400ac7ddfbfSEd Maste bool m_use_commands; 401ac7ddfbfSEd Maste bool m_use_script_language; 402ac7ddfbfSEd Maste lldb::ScriptLanguage m_script_language; 403ac7ddfbfSEd Maste 404ac7ddfbfSEd Maste // Instance variables to hold the values for one_liner options. 405ac7ddfbfSEd Maste bool m_use_one_liner; 406ac7ddfbfSEd Maste std::string m_one_liner; 407ac7ddfbfSEd Maste bool m_stop_on_error; 408ac7ddfbfSEd Maste std::string m_function_name; 4097aa51b79SEd Maste bool m_use_dummy; 410ac7ddfbfSEd Maste }; 411ac7ddfbfSEd Maste 412ac7ddfbfSEd Maste protected: 4139f2f44ceSEd Maste bool 4149f2f44ceSEd Maste DoExecute (Args& command, CommandReturnObject &result) override 415ac7ddfbfSEd Maste { 4167aa51b79SEd Maste Target *target = GetSelectedOrDummyTarget(m_options.m_use_dummy); 417ac7ddfbfSEd Maste 418ac7ddfbfSEd Maste if (target == NULL) 419ac7ddfbfSEd Maste { 420ac7ddfbfSEd Maste result.AppendError ("There is not a current executable; there are no breakpoints to which to add commands"); 421ac7ddfbfSEd Maste result.SetStatus (eReturnStatusFailed); 422ac7ddfbfSEd Maste return false; 423ac7ddfbfSEd Maste } 424ac7ddfbfSEd Maste 425ac7ddfbfSEd Maste const BreakpointList &breakpoints = target->GetBreakpointList(); 426ac7ddfbfSEd Maste size_t num_breakpoints = breakpoints.GetSize(); 427ac7ddfbfSEd Maste 428ac7ddfbfSEd Maste if (num_breakpoints == 0) 429ac7ddfbfSEd Maste { 430ac7ddfbfSEd Maste result.AppendError ("No breakpoints exist to have commands added"); 431ac7ddfbfSEd Maste result.SetStatus (eReturnStatusFailed); 432ac7ddfbfSEd Maste return false; 433ac7ddfbfSEd Maste } 434ac7ddfbfSEd Maste 435ac7ddfbfSEd Maste if (m_options.m_use_script_language == false && m_options.m_function_name.size()) 436ac7ddfbfSEd Maste { 437ac7ddfbfSEd Maste result.AppendError ("need to enable scripting to have a function run as a breakpoint command"); 438ac7ddfbfSEd Maste result.SetStatus (eReturnStatusFailed); 439ac7ddfbfSEd Maste return false; 440ac7ddfbfSEd Maste } 441ac7ddfbfSEd Maste 442ac7ddfbfSEd Maste BreakpointIDList valid_bp_ids; 4437aa51b79SEd Maste CommandObjectMultiwordBreakpoint::VerifyBreakpointOrLocationIDs (command, target, result, &valid_bp_ids); 444ac7ddfbfSEd Maste 4450127ef0fSEd Maste m_bp_options_vec.clear(); 4460127ef0fSEd Maste 447ac7ddfbfSEd Maste if (result.Succeeded()) 448ac7ddfbfSEd Maste { 449ac7ddfbfSEd Maste const size_t count = valid_bp_ids.GetSize(); 450ac7ddfbfSEd Maste 451ac7ddfbfSEd Maste for (size_t i = 0; i < count; ++i) 452ac7ddfbfSEd Maste { 453ac7ddfbfSEd Maste BreakpointID cur_bp_id = valid_bp_ids.GetBreakpointIDAtIndex (i); 454ac7ddfbfSEd Maste if (cur_bp_id.GetBreakpointID() != LLDB_INVALID_BREAK_ID) 455ac7ddfbfSEd Maste { 456ac7ddfbfSEd Maste Breakpoint *bp = target->GetBreakpointByID (cur_bp_id.GetBreakpointID()).get(); 457ac7ddfbfSEd Maste BreakpointOptions *bp_options = NULL; 458ac7ddfbfSEd Maste if (cur_bp_id.GetLocationID() == LLDB_INVALID_BREAK_ID) 459ac7ddfbfSEd Maste { 460ac7ddfbfSEd Maste // This breakpoint does not have an associated location. 461ac7ddfbfSEd Maste bp_options = bp->GetOptions(); 462ac7ddfbfSEd Maste } 463ac7ddfbfSEd Maste else 464ac7ddfbfSEd Maste { 465ac7ddfbfSEd Maste BreakpointLocationSP bp_loc_sp(bp->FindLocationByID (cur_bp_id.GetLocationID())); 466ac7ddfbfSEd Maste // This breakpoint does have an associated location. 467ac7ddfbfSEd Maste // Get its breakpoint options. 468ac7ddfbfSEd Maste if (bp_loc_sp) 469ac7ddfbfSEd Maste bp_options = bp_loc_sp->GetLocationOptions(); 470ac7ddfbfSEd Maste } 4710127ef0fSEd Maste if (bp_options) 4720127ef0fSEd Maste m_bp_options_vec.push_back (bp_options); 4730127ef0fSEd Maste } 4740127ef0fSEd Maste } 475ac7ddfbfSEd Maste 476ac7ddfbfSEd Maste // If we are using script language, get the script interpreter 477ac7ddfbfSEd Maste // in order to set or collect command callback. Otherwise, call 478ac7ddfbfSEd Maste // the methods associated with this object. 479ac7ddfbfSEd Maste if (m_options.m_use_script_language) 480ac7ddfbfSEd Maste { 4810127ef0fSEd Maste ScriptInterpreter *script_interp = m_interpreter.GetScriptInterpreter(); 482ac7ddfbfSEd Maste // Special handling for one-liner specified inline. 483ac7ddfbfSEd Maste if (m_options.m_use_one_liner) 484ac7ddfbfSEd Maste { 4850127ef0fSEd Maste script_interp->SetBreakpointCommandCallback (m_bp_options_vec, 486ac7ddfbfSEd Maste m_options.m_one_liner.c_str()); 487ac7ddfbfSEd Maste } 488ac7ddfbfSEd Maste else if (m_options.m_function_name.size()) 489ac7ddfbfSEd Maste { 4900127ef0fSEd Maste script_interp->SetBreakpointCommandCallbackFunction (m_bp_options_vec, 4910127ef0fSEd Maste m_options.m_function_name.c_str()); 492ac7ddfbfSEd Maste } 493ac7ddfbfSEd Maste else 494ac7ddfbfSEd Maste { 4950127ef0fSEd Maste script_interp->CollectDataForBreakpointCommandCallback (m_bp_options_vec, 496ac7ddfbfSEd Maste result); 497ac7ddfbfSEd Maste } 498ac7ddfbfSEd Maste } 499ac7ddfbfSEd Maste else 500ac7ddfbfSEd Maste { 501ac7ddfbfSEd Maste // Special handling for one-liner specified inline. 502ac7ddfbfSEd Maste if (m_options.m_use_one_liner) 5030127ef0fSEd Maste SetBreakpointCommandCallback (m_bp_options_vec, 504ac7ddfbfSEd Maste m_options.m_one_liner.c_str()); 505ac7ddfbfSEd Maste else 5060127ef0fSEd Maste CollectDataForBreakpointCommandCallback (m_bp_options_vec, 507ac7ddfbfSEd Maste result); 508ac7ddfbfSEd Maste } 5090127ef0fSEd Maste 510ac7ddfbfSEd Maste } 511ac7ddfbfSEd Maste 512ac7ddfbfSEd Maste return result.Succeeded(); 513ac7ddfbfSEd Maste } 514ac7ddfbfSEd Maste 515ac7ddfbfSEd Maste private: 516ac7ddfbfSEd Maste CommandOptions m_options; 5170127ef0fSEd Maste std::vector<BreakpointOptions *> m_bp_options_vec; // This stores the breakpoint options that we are currently 5180127ef0fSEd Maste // collecting commands for. In the CollectData... calls we need 5190127ef0fSEd Maste // to hand this off to the IOHandler, which may run asynchronously. 5200127ef0fSEd Maste // So we have to have some way to keep it alive, and not leak it. 5210127ef0fSEd Maste // Making it an ivar of the command object, which never goes away 5220127ef0fSEd Maste // achieves this. Note that if we were able to run 5230127ef0fSEd Maste // the same command concurrently in one interpreter we'd have to 5240127ef0fSEd Maste // make this "per invocation". But there are many more reasons 5250127ef0fSEd Maste // why it is not in general safe to do that in lldb at present, 5260127ef0fSEd Maste // so it isn't worthwhile to come up with a more complex mechanism 5270127ef0fSEd Maste // to address this particular weakness right now. 528ac7ddfbfSEd Maste static const char *g_reader_instructions; 529ac7ddfbfSEd Maste 530ac7ddfbfSEd Maste }; 531ac7ddfbfSEd Maste 532ac7ddfbfSEd Maste const char * 53312b93ac6SEd Maste CommandObjectBreakpointCommandAdd::g_reader_instructions = "Enter your debugger command(s). Type 'DONE' to end.\n"; 534ac7ddfbfSEd Maste 535ac7ddfbfSEd Maste // FIXME: "script-type" needs to have its contents determined dynamically, so somebody can add a new scripting 536ac7ddfbfSEd Maste // language to lldb and have it pickable here without having to change this enumeration by hand and rebuild lldb proper. 537ac7ddfbfSEd Maste 538ac7ddfbfSEd Maste static OptionEnumValueElement 539ac7ddfbfSEd Maste g_script_option_enumeration[4] = 540ac7ddfbfSEd Maste { 541ac7ddfbfSEd Maste { eScriptLanguageNone, "command", "Commands are in the lldb command interpreter language"}, 542ac7ddfbfSEd Maste { eScriptLanguagePython, "python", "Commands are in the Python language."}, 543ac7ddfbfSEd Maste { eSortOrderByName, "default-script", "Commands are in the default scripting language."}, 544ac7ddfbfSEd Maste { 0, NULL, NULL } 545ac7ddfbfSEd Maste }; 546ac7ddfbfSEd Maste 547ac7ddfbfSEd Maste OptionDefinition 548ac7ddfbfSEd Maste CommandObjectBreakpointCommandAdd::CommandOptions::g_option_table[] = 549ac7ddfbfSEd Maste { 5500127ef0fSEd Maste { LLDB_OPT_SET_1, false, "one-liner", 'o', OptionParser::eRequiredArgument, NULL, NULL, 0, eArgTypeOneLiner, 551ac7ddfbfSEd Maste "Specify a one-line breakpoint command inline. Be sure to surround it with quotes." }, 552ac7ddfbfSEd Maste 5530127ef0fSEd Maste { LLDB_OPT_SET_ALL, false, "stop-on-error", 'e', OptionParser::eRequiredArgument, NULL, NULL, 0, eArgTypeBoolean, 554ac7ddfbfSEd Maste "Specify whether breakpoint command execution should terminate on error." }, 555ac7ddfbfSEd Maste 5560127ef0fSEd Maste { LLDB_OPT_SET_ALL, false, "script-type", 's', OptionParser::eRequiredArgument, NULL, g_script_option_enumeration, 0, eArgTypeNone, 557ac7ddfbfSEd Maste "Specify the language for the commands - if none is specified, the lldb command interpreter will be used."}, 558ac7ddfbfSEd Maste 5590127ef0fSEd Maste { LLDB_OPT_SET_2, false, "python-function", 'F', OptionParser::eRequiredArgument, NULL, NULL, 0, eArgTypePythonFunction, 560ac7ddfbfSEd Maste "Give the name of a Python function to run as command for this breakpoint. Be sure to give a module name if appropriate."}, 561ac7ddfbfSEd Maste 5627aa51b79SEd Maste { LLDB_OPT_SET_ALL, false, "dummy-breakpoints", 'D', OptionParser::eNoArgument, NULL, NULL, 0, eArgTypeNone, 5637aa51b79SEd Maste "Sets Dummy breakpoints - i.e. breakpoints set before a file is provided, which prime new targets."}, 5647aa51b79SEd Maste 5650127ef0fSEd Maste { 0, false, NULL, 0, 0, NULL, NULL, 0, eArgTypeNone, NULL } 566ac7ddfbfSEd Maste }; 567ac7ddfbfSEd Maste 568ac7ddfbfSEd Maste //------------------------------------------------------------------------- 569ac7ddfbfSEd Maste // CommandObjectBreakpointCommandDelete 570ac7ddfbfSEd Maste //------------------------------------------------------------------------- 571ac7ddfbfSEd Maste 572ac7ddfbfSEd Maste class CommandObjectBreakpointCommandDelete : public CommandObjectParsed 573ac7ddfbfSEd Maste { 574ac7ddfbfSEd Maste public: 575ac7ddfbfSEd Maste CommandObjectBreakpointCommandDelete (CommandInterpreter &interpreter) : 576ac7ddfbfSEd Maste CommandObjectParsed (interpreter, 577ac7ddfbfSEd Maste "delete", 578ac7ddfbfSEd Maste "Delete the set of commands from a breakpoint.", 5797aa51b79SEd Maste NULL), 5807aa51b79SEd Maste m_options (interpreter) 581ac7ddfbfSEd Maste { 582ac7ddfbfSEd Maste CommandArgumentEntry arg; 583ac7ddfbfSEd Maste CommandArgumentData bp_id_arg; 584ac7ddfbfSEd Maste 585ac7ddfbfSEd Maste // Define the first (and only) variant of this arg. 586ac7ddfbfSEd Maste bp_id_arg.arg_type = eArgTypeBreakpointID; 587ac7ddfbfSEd Maste bp_id_arg.arg_repetition = eArgRepeatPlain; 588ac7ddfbfSEd Maste 589ac7ddfbfSEd Maste // There is only one variant this argument could be; put it into the argument entry. 590ac7ddfbfSEd Maste arg.push_back (bp_id_arg); 591ac7ddfbfSEd Maste 592ac7ddfbfSEd Maste // Push the data for the first argument into the m_arguments vector. 593ac7ddfbfSEd Maste m_arguments.push_back (arg); 594ac7ddfbfSEd Maste } 595ac7ddfbfSEd Maste 596ac7ddfbfSEd Maste 5979f2f44ceSEd Maste ~CommandObjectBreakpointCommandDelete () override {} 598ac7ddfbfSEd Maste 5999f2f44ceSEd Maste Options * 6009f2f44ceSEd Maste GetOptions () override 6017aa51b79SEd Maste { 6027aa51b79SEd Maste return &m_options; 6037aa51b79SEd Maste } 6047aa51b79SEd Maste 6057aa51b79SEd Maste class CommandOptions : public Options 6067aa51b79SEd Maste { 6077aa51b79SEd Maste public: 6087aa51b79SEd Maste 6097aa51b79SEd Maste CommandOptions (CommandInterpreter &interpreter) : 6107aa51b79SEd Maste Options (interpreter), 6117aa51b79SEd Maste m_use_dummy (false) 6127aa51b79SEd Maste { 6137aa51b79SEd Maste } 6147aa51b79SEd Maste 6159f2f44ceSEd Maste ~CommandOptions () override {} 6167aa51b79SEd Maste 6179f2f44ceSEd Maste Error 6189f2f44ceSEd Maste SetOptionValue (uint32_t option_idx, const char *option_arg) override 6197aa51b79SEd Maste { 6207aa51b79SEd Maste Error error; 6217aa51b79SEd Maste const int short_option = m_getopt_table[option_idx].val; 6227aa51b79SEd Maste 6237aa51b79SEd Maste switch (short_option) 6247aa51b79SEd Maste { 6257aa51b79SEd Maste case 'D': 6267aa51b79SEd Maste m_use_dummy = true; 6277aa51b79SEd Maste break; 6287aa51b79SEd Maste 6297aa51b79SEd Maste default: 6307aa51b79SEd Maste error.SetErrorStringWithFormat ("unrecognized option '%c'", short_option); 6317aa51b79SEd Maste break; 6327aa51b79SEd Maste } 6337aa51b79SEd Maste 6347aa51b79SEd Maste return error; 6357aa51b79SEd Maste } 6367aa51b79SEd Maste 6377aa51b79SEd Maste void 6389f2f44ceSEd Maste OptionParsingStarting () override 6397aa51b79SEd Maste { 6407aa51b79SEd Maste m_use_dummy = false; 6417aa51b79SEd Maste } 6427aa51b79SEd Maste 6437aa51b79SEd Maste const OptionDefinition* 6449f2f44ceSEd Maste GetDefinitions () override 6457aa51b79SEd Maste { 6467aa51b79SEd Maste return g_option_table; 6477aa51b79SEd Maste } 6487aa51b79SEd Maste 6497aa51b79SEd Maste // Options table: Required for subclasses of Options. 6507aa51b79SEd Maste 6517aa51b79SEd Maste static OptionDefinition g_option_table[]; 6527aa51b79SEd Maste 6537aa51b79SEd Maste // Instance variables to hold the values for command options. 6547aa51b79SEd Maste bool m_use_dummy; 6557aa51b79SEd Maste }; 6567aa51b79SEd Maste 657ac7ddfbfSEd Maste protected: 6589f2f44ceSEd Maste bool 6599f2f44ceSEd Maste DoExecute (Args& command, CommandReturnObject &result) override 660ac7ddfbfSEd Maste { 6617aa51b79SEd Maste Target *target = GetSelectedOrDummyTarget(m_options.m_use_dummy); 662ac7ddfbfSEd Maste 663ac7ddfbfSEd Maste if (target == NULL) 664ac7ddfbfSEd Maste { 665ac7ddfbfSEd Maste result.AppendError ("There is not a current executable; there are no breakpoints from which to delete commands"); 666ac7ddfbfSEd Maste result.SetStatus (eReturnStatusFailed); 667ac7ddfbfSEd Maste return false; 668ac7ddfbfSEd Maste } 669ac7ddfbfSEd Maste 670ac7ddfbfSEd Maste const BreakpointList &breakpoints = target->GetBreakpointList(); 671ac7ddfbfSEd Maste size_t num_breakpoints = breakpoints.GetSize(); 672ac7ddfbfSEd Maste 673ac7ddfbfSEd Maste if (num_breakpoints == 0) 674ac7ddfbfSEd Maste { 675ac7ddfbfSEd Maste result.AppendError ("No breakpoints exist to have commands deleted"); 676ac7ddfbfSEd Maste result.SetStatus (eReturnStatusFailed); 677ac7ddfbfSEd Maste return false; 678ac7ddfbfSEd Maste } 679ac7ddfbfSEd Maste 680ac7ddfbfSEd Maste if (command.GetArgumentCount() == 0) 681ac7ddfbfSEd Maste { 682ac7ddfbfSEd Maste result.AppendError ("No breakpoint specified from which to delete the commands"); 683ac7ddfbfSEd Maste result.SetStatus (eReturnStatusFailed); 684ac7ddfbfSEd Maste return false; 685ac7ddfbfSEd Maste } 686ac7ddfbfSEd Maste 687ac7ddfbfSEd Maste BreakpointIDList valid_bp_ids; 6887aa51b79SEd Maste CommandObjectMultiwordBreakpoint::VerifyBreakpointOrLocationIDs (command, target, result, &valid_bp_ids); 689ac7ddfbfSEd Maste 690ac7ddfbfSEd Maste if (result.Succeeded()) 691ac7ddfbfSEd Maste { 692ac7ddfbfSEd Maste const size_t count = valid_bp_ids.GetSize(); 693ac7ddfbfSEd Maste for (size_t i = 0; i < count; ++i) 694ac7ddfbfSEd Maste { 695ac7ddfbfSEd Maste BreakpointID cur_bp_id = valid_bp_ids.GetBreakpointIDAtIndex (i); 696ac7ddfbfSEd Maste if (cur_bp_id.GetBreakpointID() != LLDB_INVALID_BREAK_ID) 697ac7ddfbfSEd Maste { 698ac7ddfbfSEd Maste Breakpoint *bp = target->GetBreakpointByID (cur_bp_id.GetBreakpointID()).get(); 699ac7ddfbfSEd Maste if (cur_bp_id.GetLocationID() != LLDB_INVALID_BREAK_ID) 700ac7ddfbfSEd Maste { 701ac7ddfbfSEd Maste BreakpointLocationSP bp_loc_sp (bp->FindLocationByID (cur_bp_id.GetLocationID())); 702ac7ddfbfSEd Maste if (bp_loc_sp) 703ac7ddfbfSEd Maste bp_loc_sp->ClearCallback(); 704ac7ddfbfSEd Maste else 705ac7ddfbfSEd Maste { 706ac7ddfbfSEd Maste result.AppendErrorWithFormat("Invalid breakpoint ID: %u.%u.\n", 707ac7ddfbfSEd Maste cur_bp_id.GetBreakpointID(), 708ac7ddfbfSEd Maste cur_bp_id.GetLocationID()); 709ac7ddfbfSEd Maste result.SetStatus (eReturnStatusFailed); 710ac7ddfbfSEd Maste return false; 711ac7ddfbfSEd Maste } 712ac7ddfbfSEd Maste } 713ac7ddfbfSEd Maste else 714ac7ddfbfSEd Maste { 715ac7ddfbfSEd Maste bp->ClearCallback(); 716ac7ddfbfSEd Maste } 717ac7ddfbfSEd Maste } 718ac7ddfbfSEd Maste } 719ac7ddfbfSEd Maste } 720ac7ddfbfSEd Maste return result.Succeeded(); 721ac7ddfbfSEd Maste } 7227aa51b79SEd Maste private: 7237aa51b79SEd Maste CommandOptions m_options; 724ac7ddfbfSEd Maste }; 725ac7ddfbfSEd Maste 7267aa51b79SEd Maste OptionDefinition 7277aa51b79SEd Maste CommandObjectBreakpointCommandDelete::CommandOptions::g_option_table[] = 7287aa51b79SEd Maste { 7297aa51b79SEd Maste { LLDB_OPT_SET_1, false, "dummy-breakpoints", 'D', OptionParser::eNoArgument, NULL, NULL, 0, eArgTypeNone, 7307aa51b79SEd Maste "Delete commands from Dummy breakpoints - i.e. breakpoints set before a file is provided, which prime new targets."}, 7317aa51b79SEd Maste 7327aa51b79SEd Maste { 0, false, NULL, 0, 0, NULL, NULL, 0, eArgTypeNone, NULL } 7337aa51b79SEd Maste }; 7347aa51b79SEd Maste 7357aa51b79SEd Maste 736ac7ddfbfSEd Maste //------------------------------------------------------------------------- 737ac7ddfbfSEd Maste // CommandObjectBreakpointCommandList 738ac7ddfbfSEd Maste //------------------------------------------------------------------------- 739ac7ddfbfSEd Maste 740ac7ddfbfSEd Maste class CommandObjectBreakpointCommandList : public CommandObjectParsed 741ac7ddfbfSEd Maste { 742ac7ddfbfSEd Maste public: 743ac7ddfbfSEd Maste CommandObjectBreakpointCommandList (CommandInterpreter &interpreter) : 744ac7ddfbfSEd Maste CommandObjectParsed (interpreter, 745ac7ddfbfSEd Maste "list", 746ac7ddfbfSEd Maste "List the script or set of commands to be executed when the breakpoint is hit.", 747ac7ddfbfSEd Maste NULL) 748ac7ddfbfSEd Maste { 749ac7ddfbfSEd Maste CommandArgumentEntry arg; 750ac7ddfbfSEd Maste CommandArgumentData bp_id_arg; 751ac7ddfbfSEd Maste 752ac7ddfbfSEd Maste // Define the first (and only) variant of this arg. 753ac7ddfbfSEd Maste bp_id_arg.arg_type = eArgTypeBreakpointID; 754ac7ddfbfSEd Maste bp_id_arg.arg_repetition = eArgRepeatPlain; 755ac7ddfbfSEd Maste 756ac7ddfbfSEd Maste // There is only one variant this argument could be; put it into the argument entry. 757ac7ddfbfSEd Maste arg.push_back (bp_id_arg); 758ac7ddfbfSEd Maste 759ac7ddfbfSEd Maste // Push the data for the first argument into the m_arguments vector. 760ac7ddfbfSEd Maste m_arguments.push_back (arg); 761ac7ddfbfSEd Maste } 762ac7ddfbfSEd Maste 7639f2f44ceSEd Maste ~CommandObjectBreakpointCommandList () override {} 764ac7ddfbfSEd Maste 765ac7ddfbfSEd Maste protected: 7669f2f44ceSEd Maste bool 767ac7ddfbfSEd Maste DoExecute (Args& command, 7689f2f44ceSEd Maste CommandReturnObject &result) override 769ac7ddfbfSEd Maste { 770ac7ddfbfSEd Maste Target *target = m_interpreter.GetDebugger().GetSelectedTarget().get(); 771ac7ddfbfSEd Maste 772ac7ddfbfSEd Maste if (target == NULL) 773ac7ddfbfSEd Maste { 774ac7ddfbfSEd Maste result.AppendError ("There is not a current executable; there are no breakpoints for which to list commands"); 775ac7ddfbfSEd Maste result.SetStatus (eReturnStatusFailed); 776ac7ddfbfSEd Maste return false; 777ac7ddfbfSEd Maste } 778ac7ddfbfSEd Maste 779ac7ddfbfSEd Maste const BreakpointList &breakpoints = target->GetBreakpointList(); 780ac7ddfbfSEd Maste size_t num_breakpoints = breakpoints.GetSize(); 781ac7ddfbfSEd Maste 782ac7ddfbfSEd Maste if (num_breakpoints == 0) 783ac7ddfbfSEd Maste { 784ac7ddfbfSEd Maste result.AppendError ("No breakpoints exist for which to list commands"); 785ac7ddfbfSEd Maste result.SetStatus (eReturnStatusFailed); 786ac7ddfbfSEd Maste return false; 787ac7ddfbfSEd Maste } 788ac7ddfbfSEd Maste 789ac7ddfbfSEd Maste if (command.GetArgumentCount() == 0) 790ac7ddfbfSEd Maste { 791ac7ddfbfSEd Maste result.AppendError ("No breakpoint specified for which to list the commands"); 792ac7ddfbfSEd Maste result.SetStatus (eReturnStatusFailed); 793ac7ddfbfSEd Maste return false; 794ac7ddfbfSEd Maste } 795ac7ddfbfSEd Maste 796ac7ddfbfSEd Maste BreakpointIDList valid_bp_ids; 7977aa51b79SEd Maste CommandObjectMultiwordBreakpoint::VerifyBreakpointOrLocationIDs (command, target, result, &valid_bp_ids); 798ac7ddfbfSEd Maste 799ac7ddfbfSEd Maste if (result.Succeeded()) 800ac7ddfbfSEd Maste { 801ac7ddfbfSEd Maste const size_t count = valid_bp_ids.GetSize(); 802ac7ddfbfSEd Maste for (size_t i = 0; i < count; ++i) 803ac7ddfbfSEd Maste { 804ac7ddfbfSEd Maste BreakpointID cur_bp_id = valid_bp_ids.GetBreakpointIDAtIndex (i); 805ac7ddfbfSEd Maste if (cur_bp_id.GetBreakpointID() != LLDB_INVALID_BREAK_ID) 806ac7ddfbfSEd Maste { 807ac7ddfbfSEd Maste Breakpoint *bp = target->GetBreakpointByID (cur_bp_id.GetBreakpointID()).get(); 808ac7ddfbfSEd Maste 809ac7ddfbfSEd Maste if (bp) 810ac7ddfbfSEd Maste { 811ac7ddfbfSEd Maste const BreakpointOptions *bp_options = NULL; 812ac7ddfbfSEd Maste if (cur_bp_id.GetLocationID() != LLDB_INVALID_BREAK_ID) 813ac7ddfbfSEd Maste { 814ac7ddfbfSEd Maste BreakpointLocationSP bp_loc_sp(bp->FindLocationByID (cur_bp_id.GetLocationID())); 815ac7ddfbfSEd Maste if (bp_loc_sp) 816ac7ddfbfSEd Maste bp_options = bp_loc_sp->GetOptionsNoCreate(); 817ac7ddfbfSEd Maste else 818ac7ddfbfSEd Maste { 819ac7ddfbfSEd Maste result.AppendErrorWithFormat("Invalid breakpoint ID: %u.%u.\n", 820ac7ddfbfSEd Maste cur_bp_id.GetBreakpointID(), 821ac7ddfbfSEd Maste cur_bp_id.GetLocationID()); 822ac7ddfbfSEd Maste result.SetStatus (eReturnStatusFailed); 823ac7ddfbfSEd Maste return false; 824ac7ddfbfSEd Maste } 825ac7ddfbfSEd Maste } 826ac7ddfbfSEd Maste else 827ac7ddfbfSEd Maste { 828ac7ddfbfSEd Maste bp_options = bp->GetOptions(); 829ac7ddfbfSEd Maste } 830ac7ddfbfSEd Maste 831ac7ddfbfSEd Maste if (bp_options) 832ac7ddfbfSEd Maste { 833ac7ddfbfSEd Maste StreamString id_str; 834ac7ddfbfSEd Maste BreakpointID::GetCanonicalReference (&id_str, 835ac7ddfbfSEd Maste cur_bp_id.GetBreakpointID(), 836ac7ddfbfSEd Maste cur_bp_id.GetLocationID()); 837ac7ddfbfSEd Maste const Baton *baton = bp_options->GetBaton(); 838ac7ddfbfSEd Maste if (baton) 839ac7ddfbfSEd Maste { 840ac7ddfbfSEd Maste result.GetOutputStream().Printf ("Breakpoint %s:\n", id_str.GetData()); 841ac7ddfbfSEd Maste result.GetOutputStream().IndentMore (); 842ac7ddfbfSEd Maste baton->GetDescription(&result.GetOutputStream(), eDescriptionLevelFull); 843ac7ddfbfSEd Maste result.GetOutputStream().IndentLess (); 844ac7ddfbfSEd Maste } 845ac7ddfbfSEd Maste else 846ac7ddfbfSEd Maste { 847ac7ddfbfSEd Maste result.AppendMessageWithFormat ("Breakpoint %s does not have an associated command.\n", 848ac7ddfbfSEd Maste id_str.GetData()); 849ac7ddfbfSEd Maste } 850ac7ddfbfSEd Maste } 851ac7ddfbfSEd Maste result.SetStatus (eReturnStatusSuccessFinishResult); 852ac7ddfbfSEd Maste } 853ac7ddfbfSEd Maste else 854ac7ddfbfSEd Maste { 855ac7ddfbfSEd Maste result.AppendErrorWithFormat("Invalid breakpoint ID: %u.\n", cur_bp_id.GetBreakpointID()); 856ac7ddfbfSEd Maste result.SetStatus (eReturnStatusFailed); 857ac7ddfbfSEd Maste } 858ac7ddfbfSEd Maste 859ac7ddfbfSEd Maste } 860ac7ddfbfSEd Maste } 861ac7ddfbfSEd Maste } 862ac7ddfbfSEd Maste 863ac7ddfbfSEd Maste return result.Succeeded(); 864ac7ddfbfSEd Maste } 865ac7ddfbfSEd Maste }; 866ac7ddfbfSEd Maste 867ac7ddfbfSEd Maste //------------------------------------------------------------------------- 868ac7ddfbfSEd Maste // CommandObjectBreakpointCommand 869ac7ddfbfSEd Maste //------------------------------------------------------------------------- 870ac7ddfbfSEd Maste 871ac7ddfbfSEd Maste CommandObjectBreakpointCommand::CommandObjectBreakpointCommand (CommandInterpreter &interpreter) : 872ac7ddfbfSEd Maste CommandObjectMultiword (interpreter, 873ac7ddfbfSEd Maste "command", 8740127ef0fSEd Maste "A set of commands for adding, removing and examining bits of code to be executed when the breakpoint is hit (breakpoint 'commands').", 875ac7ddfbfSEd Maste "command <sub-command> [<sub-command-options>] <breakpoint-id>") 876ac7ddfbfSEd Maste { 877ac7ddfbfSEd Maste CommandObjectSP add_command_object (new CommandObjectBreakpointCommandAdd (interpreter)); 878ac7ddfbfSEd Maste CommandObjectSP delete_command_object (new CommandObjectBreakpointCommandDelete (interpreter)); 879ac7ddfbfSEd Maste CommandObjectSP list_command_object (new CommandObjectBreakpointCommandList (interpreter)); 880ac7ddfbfSEd Maste 881ac7ddfbfSEd Maste add_command_object->SetCommandName ("breakpoint command add"); 882ac7ddfbfSEd Maste delete_command_object->SetCommandName ("breakpoint command delete"); 883ac7ddfbfSEd Maste list_command_object->SetCommandName ("breakpoint command list"); 884ac7ddfbfSEd Maste 885ac7ddfbfSEd Maste LoadSubCommand ("add", add_command_object); 886ac7ddfbfSEd Maste LoadSubCommand ("delete", delete_command_object); 887ac7ddfbfSEd Maste LoadSubCommand ("list", list_command_object); 888ac7ddfbfSEd Maste } 889ac7ddfbfSEd Maste 890ac7ddfbfSEd Maste CommandObjectBreakpointCommand::~CommandObjectBreakpointCommand () 891ac7ddfbfSEd Maste { 892ac7ddfbfSEd Maste } 893ac7ddfbfSEd Maste 894ac7ddfbfSEd Maste 895