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 124bb0738eSEd Maste // Other libraries and framework includes 134bb0738eSEd Maste // Project includes 14ac7ddfbfSEd Maste #include "CommandObjectBreakpointCommand.h" 15ac7ddfbfSEd Maste #include "CommandObjectBreakpoint.h" 1612b93ac6SEd Maste #include "lldb/Core/IOHandler.h" 17ac7ddfbfSEd Maste #include "lldb/Interpreter/CommandInterpreter.h" 18ac7ddfbfSEd Maste #include "lldb/Interpreter/CommandReturnObject.h" 19ac7ddfbfSEd Maste #include "lldb/Target/Target.h" 20ac7ddfbfSEd Maste #include "lldb/Target/Thread.h" 21ac7ddfbfSEd Maste #include "lldb/Breakpoint/BreakpointIDList.h" 22ac7ddfbfSEd Maste #include "lldb/Breakpoint/Breakpoint.h" 23ac7ddfbfSEd Maste #include "lldb/Breakpoint/BreakpointLocation.h" 24ac7ddfbfSEd Maste #include "lldb/Breakpoint/StoppointCallbackContext.h" 25ac7ddfbfSEd Maste #include "lldb/Core/State.h" 26ac7ddfbfSEd Maste 27ac7ddfbfSEd Maste using namespace lldb; 28ac7ddfbfSEd Maste using namespace lldb_private; 29ac7ddfbfSEd Maste 30ac7ddfbfSEd Maste //------------------------------------------------------------------------- 31ac7ddfbfSEd Maste // CommandObjectBreakpointCommandAdd 32ac7ddfbfSEd Maste //------------------------------------------------------------------------- 33ac7ddfbfSEd Maste 3412b93ac6SEd Maste class CommandObjectBreakpointCommandAdd : 3512b93ac6SEd Maste public CommandObjectParsed, 3612b93ac6SEd Maste public IOHandlerDelegateMultiline 37ac7ddfbfSEd Maste { 38ac7ddfbfSEd Maste public: 394bb0738eSEd Maste CommandObjectBreakpointCommandAdd(CommandInterpreter &interpreter) 404bb0738eSEd Maste : CommandObjectParsed(interpreter, "add", 414bb0738eSEd Maste "Add LLDB commands to a breakpoint, to be executed whenever the breakpoint is hit." 420127ef0fSEd Maste " If no breakpoint is specified, adds the commands to the last created breakpoint.", 434bb0738eSEd Maste nullptr), 4412b93ac6SEd Maste IOHandlerDelegateMultiline("DONE", IOHandlerDelegate::Completion::LLDBCommand), 45ac7ddfbfSEd Maste m_options(interpreter) 46ac7ddfbfSEd Maste { 47ac7ddfbfSEd Maste SetHelpLong ( 48b91a7dfcSDimitry Andric R"( 49b91a7dfcSDimitry Andric General information about entering breakpoint commands 50b91a7dfcSDimitry Andric ------------------------------------------------------ 51b91a7dfcSDimitry Andric 52b91a7dfcSDimitry Andric )" "This command will prompt for commands to be executed when the specified \ 53b91a7dfcSDimitry Andric breakpoint is hit. Each command is typed on its own line following the '> ' \ 54b91a7dfcSDimitry Andric prompt until 'DONE' is entered." R"( 55b91a7dfcSDimitry Andric 56b91a7dfcSDimitry Andric )" "Syntactic errors may not be detected when initially entered, and many \ 57b91a7dfcSDimitry Andric malformed commands can silently fail when executed. If your breakpoint commands \ 58b91a7dfcSDimitry Andric do not appear to be executing, double-check the command syntax." R"( 59b91a7dfcSDimitry Andric 60b91a7dfcSDimitry Andric )" "Note: You may enter any debugger command exactly as you would at the debugger \ 61b91a7dfcSDimitry Andric prompt. There is no limit to the number of commands supplied, but do NOT enter \ 62b91a7dfcSDimitry Andric more than one command per line." R"( 63b91a7dfcSDimitry Andric 64b91a7dfcSDimitry Andric Special information about PYTHON breakpoint commands 65b91a7dfcSDimitry Andric ---------------------------------------------------- 66b91a7dfcSDimitry Andric 67b91a7dfcSDimitry Andric )" "You may enter either one or more lines of Python, including function \ 68b91a7dfcSDimitry Andric definitions or calls to functions that will have been imported by the time \ 69b91a7dfcSDimitry Andric the code executes. Single line breakpoint commands will be interpreted 'as is' \ 70b91a7dfcSDimitry Andric when the breakpoint is hit. Multiple lines of Python will be wrapped in a \ 71b91a7dfcSDimitry Andric generated function, and a call to the function will be attached to the breakpoint." R"( 72b91a7dfcSDimitry Andric 73b91a7dfcSDimitry Andric This auto-generated function is passed in three arguments: 74b91a7dfcSDimitry Andric 75b91a7dfcSDimitry Andric frame: an lldb.SBFrame object for the frame which hit breakpoint. 76b91a7dfcSDimitry Andric 77b91a7dfcSDimitry Andric bp_loc: an lldb.SBBreakpointLocation object that represents the breakpoint location that was hit. 78b91a7dfcSDimitry Andric 79b91a7dfcSDimitry Andric dict: the python session dictionary hit. 80b91a7dfcSDimitry Andric 81b91a7dfcSDimitry Andric )" "When specifying a python function with the --python-function option, you need \ 82b91a7dfcSDimitry Andric to supply the function name prepended by the module name:" R"( 83b91a7dfcSDimitry Andric 84b91a7dfcSDimitry Andric --python-function myutils.breakpoint_callback 85b91a7dfcSDimitry Andric 86b91a7dfcSDimitry Andric The function itself must have the following prototype: 87b91a7dfcSDimitry Andric 88b91a7dfcSDimitry Andric def breakpoint_callback(frame, bp_loc, dict): 89b91a7dfcSDimitry Andric # Your code goes here 90b91a7dfcSDimitry Andric 91b91a7dfcSDimitry Andric )" "The arguments are the same as the arguments passed to generated functions as \ 92b91a7dfcSDimitry Andric described above. Note that the global variable 'lldb.frame' will NOT be updated when \ 93b91a7dfcSDimitry Andric this function is called, so be sure to use the 'frame' argument. The 'frame' argument \ 94b91a7dfcSDimitry Andric can get you to the thread via frame.GetThread(), the thread can get you to the \ 95b91a7dfcSDimitry Andric process via thread.GetProcess(), and the process can get you back to the target \ 96b91a7dfcSDimitry Andric via process.GetTarget()." R"( 97b91a7dfcSDimitry Andric 98b91a7dfcSDimitry Andric )" "Important Note: As Python code gets collected into functions, access to global \ 99b91a7dfcSDimitry Andric variables requires explicit scoping using the 'global' keyword. Be sure to use correct \ 100b91a7dfcSDimitry Andric Python syntax, including indentation, when entering Python breakpoint commands." R"( 101b91a7dfcSDimitry Andric 102b91a7dfcSDimitry Andric Example Python one-line breakpoint command: 103b91a7dfcSDimitry Andric 104b91a7dfcSDimitry Andric (lldb) breakpoint command add -s python 1 105b91a7dfcSDimitry Andric Enter your Python command(s). Type 'DONE' to end. 106b91a7dfcSDimitry Andric > print "Hit this breakpoint!" 107b91a7dfcSDimitry Andric > DONE 108b91a7dfcSDimitry Andric 109b91a7dfcSDimitry Andric As a convenience, this also works for a short Python one-liner: 110b91a7dfcSDimitry Andric 111b91a7dfcSDimitry Andric (lldb) breakpoint command add -s python 1 -o 'import time; print time.asctime()' 112b91a7dfcSDimitry Andric (lldb) run 113b91a7dfcSDimitry Andric Launching '.../a.out' (x86_64) 114b91a7dfcSDimitry Andric (lldb) Fri Sep 10 12:17:45 2010 115b91a7dfcSDimitry Andric Process 21778 Stopped 116b91a7dfcSDimitry Andric * thread #1: tid = 0x2e03, 0x0000000100000de8 a.out`c + 7 at main.c:39, stop reason = breakpoint 1.1, queue = com.apple.main-thread 117b91a7dfcSDimitry Andric 36 118b91a7dfcSDimitry Andric 37 int c(int val) 119b91a7dfcSDimitry Andric 38 { 120b91a7dfcSDimitry Andric 39 -> return val + 3; 121b91a7dfcSDimitry Andric 40 } 122b91a7dfcSDimitry Andric 41 123b91a7dfcSDimitry Andric 42 int main (int argc, char const *argv[]) 124b91a7dfcSDimitry Andric 125b91a7dfcSDimitry Andric Example multiple line Python breakpoint command: 126b91a7dfcSDimitry Andric 127b91a7dfcSDimitry Andric (lldb) breakpoint command add -s p 1 128b91a7dfcSDimitry Andric Enter your Python command(s). Type 'DONE' to end. 129b91a7dfcSDimitry Andric > global bp_count 130b91a7dfcSDimitry Andric > bp_count = bp_count + 1 131b91a7dfcSDimitry Andric > print "Hit this breakpoint " + repr(bp_count) + " times!" 132b91a7dfcSDimitry Andric > DONE 133b91a7dfcSDimitry Andric 134b91a7dfcSDimitry Andric Example multiple line Python breakpoint command, using function definition: 135b91a7dfcSDimitry Andric 136b91a7dfcSDimitry Andric (lldb) breakpoint command add -s python 1 137b91a7dfcSDimitry Andric Enter your Python command(s). Type 'DONE' to end. 138b91a7dfcSDimitry Andric > def breakpoint_output (bp_no): 139b91a7dfcSDimitry Andric > out_string = "Hit breakpoint number " + repr (bp_no) 140b91a7dfcSDimitry Andric > print out_string 141b91a7dfcSDimitry Andric > return True 142b91a7dfcSDimitry Andric > breakpoint_output (1) 143b91a7dfcSDimitry Andric > DONE 144b91a7dfcSDimitry Andric 145b91a7dfcSDimitry Andric )" "In this case, since there is a reference to a global variable, \ 146b91a7dfcSDimitry Andric 'bp_count', you will also need to make sure 'bp_count' exists and is \ 147b91a7dfcSDimitry Andric initialized:" R"( 148b91a7dfcSDimitry Andric 149b91a7dfcSDimitry Andric (lldb) script 150b91a7dfcSDimitry Andric >>> bp_count = 0 151b91a7dfcSDimitry Andric >>> quit() 152b91a7dfcSDimitry Andric 153b91a7dfcSDimitry Andric )" "Your Python code, however organized, can optionally return a value. \ 154b91a7dfcSDimitry Andric If the returned value is False, that tells LLDB not to stop at the breakpoint \ 155b91a7dfcSDimitry Andric to which the code is associated. Returning anything other than False, or even \ 156b91a7dfcSDimitry Andric returning None, or even omitting a return statement entirely, will cause \ 157b91a7dfcSDimitry Andric LLDB to stop." R"( 158b91a7dfcSDimitry Andric 159b91a7dfcSDimitry Andric )" "Final Note: A warning that no breakpoint command was generated when there \ 160b91a7dfcSDimitry Andric are no syntax errors may indicate that a function was declared but never called." 161b91a7dfcSDimitry Andric ); 162ac7ddfbfSEd Maste 163ac7ddfbfSEd Maste CommandArgumentEntry arg; 164ac7ddfbfSEd Maste CommandArgumentData bp_id_arg; 165ac7ddfbfSEd Maste 166ac7ddfbfSEd Maste // Define the first (and only) variant of this arg. 167ac7ddfbfSEd Maste bp_id_arg.arg_type = eArgTypeBreakpointID; 1680127ef0fSEd Maste bp_id_arg.arg_repetition = eArgRepeatOptional; 169ac7ddfbfSEd Maste 170ac7ddfbfSEd Maste // There is only one variant this argument could be; put it into the argument entry. 171ac7ddfbfSEd Maste arg.push_back (bp_id_arg); 172ac7ddfbfSEd Maste 173ac7ddfbfSEd Maste // Push the data for the first argument into the m_arguments vector. 174ac7ddfbfSEd Maste m_arguments.push_back (arg); 175ac7ddfbfSEd Maste } 176ac7ddfbfSEd Maste 1774bb0738eSEd Maste ~CommandObjectBreakpointCommandAdd() override = default; 178ac7ddfbfSEd Maste 1799f2f44ceSEd Maste Options * 1809f2f44ceSEd Maste GetOptions () override 181ac7ddfbfSEd Maste { 182ac7ddfbfSEd Maste return &m_options; 183ac7ddfbfSEd Maste } 184ac7ddfbfSEd Maste 1859f2f44ceSEd Maste void 1869f2f44ceSEd Maste IOHandlerActivated (IOHandler &io_handler) override 18712b93ac6SEd Maste { 18812b93ac6SEd Maste StreamFileSP output_sp(io_handler.GetOutputStreamFile()); 18912b93ac6SEd Maste if (output_sp) 19012b93ac6SEd Maste { 19112b93ac6SEd Maste output_sp->PutCString(g_reader_instructions); 19212b93ac6SEd Maste output_sp->Flush(); 19312b93ac6SEd Maste } 19412b93ac6SEd Maste } 19512b93ac6SEd Maste 1969f2f44ceSEd Maste void 1979f2f44ceSEd Maste IOHandlerInputComplete (IOHandler &io_handler, std::string &line) override 19812b93ac6SEd Maste { 19912b93ac6SEd Maste io_handler.SetIsDone(true); 20012b93ac6SEd Maste 2010127ef0fSEd Maste std::vector<BreakpointOptions *> *bp_options_vec = (std::vector<BreakpointOptions *> *)io_handler.GetUserData(); 2020127ef0fSEd Maste for (BreakpointOptions *bp_options : *bp_options_vec) 20312b93ac6SEd Maste { 2040127ef0fSEd Maste if (!bp_options) 2050127ef0fSEd Maste continue; 2060127ef0fSEd Maste 20712b93ac6SEd Maste std::unique_ptr<BreakpointOptions::CommandData> data_ap(new BreakpointOptions::CommandData()); 2084bb0738eSEd Maste if (data_ap) 20912b93ac6SEd Maste { 21012b93ac6SEd Maste data_ap->user_source.SplitIntoLines (line.c_str(), line.size()); 21112b93ac6SEd Maste BatonSP baton_sp (new BreakpointOptions::CommandBaton (data_ap.release())); 21212b93ac6SEd Maste bp_options->SetCallback (BreakpointOptionsCallbackFunction, baton_sp); 21312b93ac6SEd Maste } 21412b93ac6SEd Maste } 21512b93ac6SEd Maste } 21612b93ac6SEd Maste 217ac7ddfbfSEd Maste void 2180127ef0fSEd Maste CollectDataForBreakpointCommandCallback (std::vector<BreakpointOptions *> &bp_options_vec, 219ac7ddfbfSEd Maste CommandReturnObject &result) 220ac7ddfbfSEd Maste { 22112b93ac6SEd Maste m_interpreter.GetLLDBCommandsFromIOHandler ("> ", // Prompt 22212b93ac6SEd Maste *this, // IOHandlerDelegate 22312b93ac6SEd Maste true, // Run IOHandler in async mode 2240127ef0fSEd Maste &bp_options_vec); // Baton for the "io_handler" that will be passed back into our IOHandlerDelegate functions 225ac7ddfbfSEd Maste } 226ac7ddfbfSEd Maste 227ac7ddfbfSEd Maste /// Set a one-liner as the callback for the breakpoint. 228ac7ddfbfSEd Maste void 2290127ef0fSEd Maste SetBreakpointCommandCallback (std::vector<BreakpointOptions *> &bp_options_vec, 230ac7ddfbfSEd Maste const char *oneliner) 231ac7ddfbfSEd Maste { 2320127ef0fSEd Maste for (auto bp_options : bp_options_vec) 2330127ef0fSEd Maste { 234ac7ddfbfSEd Maste std::unique_ptr<BreakpointOptions::CommandData> data_ap(new BreakpointOptions::CommandData()); 235ac7ddfbfSEd Maste 236ac7ddfbfSEd Maste // It's necessary to set both user_source and script_source to the oneliner. 237ac7ddfbfSEd Maste // The former is used to generate callback description (as in breakpoint command list) 238ac7ddfbfSEd Maste // while the latter is used for Python to interpret during the actual callback. 239ac7ddfbfSEd Maste data_ap->user_source.AppendString (oneliner); 240ac7ddfbfSEd Maste data_ap->script_source.assign (oneliner); 241ac7ddfbfSEd Maste data_ap->stop_on_error = m_options.m_stop_on_error; 242ac7ddfbfSEd Maste 243ac7ddfbfSEd Maste BatonSP baton_sp (new BreakpointOptions::CommandBaton (data_ap.release())); 244ac7ddfbfSEd Maste bp_options->SetCallback (BreakpointOptionsCallbackFunction, baton_sp); 2450127ef0fSEd Maste } 246ac7ddfbfSEd Maste } 247ac7ddfbfSEd Maste 248ac7ddfbfSEd Maste static bool 249ac7ddfbfSEd Maste BreakpointOptionsCallbackFunction (void *baton, 250ac7ddfbfSEd Maste StoppointCallbackContext *context, 251ac7ddfbfSEd Maste lldb::user_id_t break_id, 252ac7ddfbfSEd Maste lldb::user_id_t break_loc_id) 253ac7ddfbfSEd Maste { 254ac7ddfbfSEd Maste bool ret_value = true; 2554bb0738eSEd Maste if (baton == nullptr) 256ac7ddfbfSEd Maste return true; 257ac7ddfbfSEd Maste 258ac7ddfbfSEd Maste BreakpointOptions::CommandData *data = (BreakpointOptions::CommandData *) baton; 259ac7ddfbfSEd Maste StringList &commands = data->user_source; 260ac7ddfbfSEd Maste 261ac7ddfbfSEd Maste if (commands.GetSize() > 0) 262ac7ddfbfSEd Maste { 263ac7ddfbfSEd Maste ExecutionContext exe_ctx (context->exe_ctx_ref); 264ac7ddfbfSEd Maste Target *target = exe_ctx.GetTargetPtr(); 265ac7ddfbfSEd Maste if (target) 266ac7ddfbfSEd Maste { 267ac7ddfbfSEd Maste CommandReturnObject result; 268ac7ddfbfSEd Maste Debugger &debugger = target->GetDebugger(); 269ac7ddfbfSEd Maste // Rig up the results secondary output stream to the debugger's, so the output will come out synchronously 270ac7ddfbfSEd Maste // if the debugger is set up that way. 271ac7ddfbfSEd Maste 272ac7ddfbfSEd Maste StreamSP output_stream (debugger.GetAsyncOutputStream()); 273ac7ddfbfSEd Maste StreamSP error_stream (debugger.GetAsyncErrorStream()); 274ac7ddfbfSEd Maste result.SetImmediateOutputStream (output_stream); 275ac7ddfbfSEd Maste result.SetImmediateErrorStream (error_stream); 276ac7ddfbfSEd Maste 2777aa51b79SEd Maste CommandInterpreterRunOptions options; 2787aa51b79SEd Maste options.SetStopOnContinue(true); 2797aa51b79SEd Maste options.SetStopOnError (data->stop_on_error); 2807aa51b79SEd Maste options.SetEchoCommands (true); 2817aa51b79SEd Maste options.SetPrintResults (true); 2827aa51b79SEd Maste options.SetAddToHistory (false); 283ac7ddfbfSEd Maste 284ac7ddfbfSEd Maste debugger.GetCommandInterpreter().HandleCommands (commands, 285ac7ddfbfSEd Maste &exe_ctx, 2867aa51b79SEd Maste options, 287ac7ddfbfSEd Maste result); 288ac7ddfbfSEd Maste result.GetImmediateOutputStream()->Flush(); 289ac7ddfbfSEd Maste result.GetImmediateErrorStream()->Flush(); 290ac7ddfbfSEd Maste } 291ac7ddfbfSEd Maste } 292ac7ddfbfSEd Maste return ret_value; 293ac7ddfbfSEd Maste } 294ac7ddfbfSEd Maste 295ac7ddfbfSEd Maste class CommandOptions : public Options 296ac7ddfbfSEd Maste { 297ac7ddfbfSEd Maste public: 298ac7ddfbfSEd Maste CommandOptions (CommandInterpreter &interpreter) : 299ac7ddfbfSEd Maste Options (interpreter), 300ac7ddfbfSEd Maste m_use_commands (false), 301ac7ddfbfSEd Maste m_use_script_language (false), 302ac7ddfbfSEd Maste m_script_language (eScriptLanguageNone), 303ac7ddfbfSEd Maste m_use_one_liner (false), 304ac7ddfbfSEd Maste m_one_liner(), 305ac7ddfbfSEd Maste m_function_name() 306ac7ddfbfSEd Maste { 307ac7ddfbfSEd Maste } 308ac7ddfbfSEd Maste 3094bb0738eSEd Maste ~CommandOptions() override = default; 310ac7ddfbfSEd Maste 3119f2f44ceSEd Maste Error 3129f2f44ceSEd Maste SetOptionValue (uint32_t option_idx, const char *option_arg) override 313ac7ddfbfSEd Maste { 314ac7ddfbfSEd Maste Error error; 315ac7ddfbfSEd Maste const int short_option = m_getopt_table[option_idx].val; 316ac7ddfbfSEd Maste 317ac7ddfbfSEd Maste switch (short_option) 318ac7ddfbfSEd Maste { 319ac7ddfbfSEd Maste case 'o': 320ac7ddfbfSEd Maste m_use_one_liner = true; 321ac7ddfbfSEd Maste m_one_liner = option_arg; 322ac7ddfbfSEd Maste break; 323ac7ddfbfSEd Maste 324ac7ddfbfSEd Maste case 's': 325ac7ddfbfSEd Maste m_script_language = (lldb::ScriptLanguage) Args::StringToOptionEnum (option_arg, 326ac7ddfbfSEd Maste g_option_table[option_idx].enum_values, 327ac7ddfbfSEd Maste eScriptLanguageNone, 328ac7ddfbfSEd Maste error); 329ac7ddfbfSEd Maste 330ac7ddfbfSEd Maste if (m_script_language == eScriptLanguagePython || m_script_language == eScriptLanguageDefault) 331ac7ddfbfSEd Maste { 332ac7ddfbfSEd Maste m_use_script_language = true; 333ac7ddfbfSEd Maste } 334ac7ddfbfSEd Maste else 335ac7ddfbfSEd Maste { 336ac7ddfbfSEd Maste m_use_script_language = false; 337ac7ddfbfSEd Maste } 338ac7ddfbfSEd Maste break; 339ac7ddfbfSEd Maste 340ac7ddfbfSEd Maste case 'e': 341ac7ddfbfSEd Maste { 342ac7ddfbfSEd Maste bool success = false; 343ac7ddfbfSEd Maste m_stop_on_error = Args::StringToBoolean(option_arg, false, &success); 344ac7ddfbfSEd Maste if (!success) 345ac7ddfbfSEd Maste error.SetErrorStringWithFormat("invalid value for stop-on-error: \"%s\"", option_arg); 346ac7ddfbfSEd Maste } 347ac7ddfbfSEd Maste break; 348ac7ddfbfSEd Maste 349ac7ddfbfSEd Maste case 'F': 350ac7ddfbfSEd Maste m_use_one_liner = false; 351ac7ddfbfSEd Maste m_use_script_language = true; 352ac7ddfbfSEd Maste m_function_name.assign(option_arg); 353ac7ddfbfSEd Maste break; 354ac7ddfbfSEd Maste 3557aa51b79SEd Maste case 'D': 3567aa51b79SEd Maste m_use_dummy = true; 3577aa51b79SEd Maste break; 3587aa51b79SEd Maste 359ac7ddfbfSEd Maste default: 360ac7ddfbfSEd Maste break; 361ac7ddfbfSEd Maste } 362ac7ddfbfSEd Maste return error; 363ac7ddfbfSEd Maste } 3644bb0738eSEd Maste 365ac7ddfbfSEd Maste void 3669f2f44ceSEd Maste OptionParsingStarting () override 367ac7ddfbfSEd Maste { 368ac7ddfbfSEd Maste m_use_commands = true; 369ac7ddfbfSEd Maste m_use_script_language = false; 370ac7ddfbfSEd Maste m_script_language = eScriptLanguageNone; 371ac7ddfbfSEd Maste 372ac7ddfbfSEd Maste m_use_one_liner = false; 373ac7ddfbfSEd Maste m_stop_on_error = true; 374ac7ddfbfSEd Maste m_one_liner.clear(); 375ac7ddfbfSEd Maste m_function_name.clear(); 3767aa51b79SEd Maste m_use_dummy = false; 377ac7ddfbfSEd Maste } 378ac7ddfbfSEd Maste 379ac7ddfbfSEd Maste const OptionDefinition* 3809f2f44ceSEd Maste GetDefinitions () override 381ac7ddfbfSEd Maste { 382ac7ddfbfSEd Maste return g_option_table; 383ac7ddfbfSEd Maste } 384ac7ddfbfSEd Maste 385ac7ddfbfSEd Maste // Options table: Required for subclasses of Options. 386ac7ddfbfSEd Maste 387ac7ddfbfSEd Maste static OptionDefinition g_option_table[]; 388ac7ddfbfSEd Maste 389ac7ddfbfSEd Maste // Instance variables to hold the values for command options. 390ac7ddfbfSEd Maste 391ac7ddfbfSEd Maste bool m_use_commands; 392ac7ddfbfSEd Maste bool m_use_script_language; 393ac7ddfbfSEd Maste lldb::ScriptLanguage m_script_language; 394ac7ddfbfSEd Maste 395ac7ddfbfSEd Maste // Instance variables to hold the values for one_liner options. 396ac7ddfbfSEd Maste bool m_use_one_liner; 397ac7ddfbfSEd Maste std::string m_one_liner; 398ac7ddfbfSEd Maste bool m_stop_on_error; 399ac7ddfbfSEd Maste std::string m_function_name; 4007aa51b79SEd Maste bool m_use_dummy; 401ac7ddfbfSEd Maste }; 402ac7ddfbfSEd Maste 403ac7ddfbfSEd Maste protected: 4049f2f44ceSEd Maste bool 4059f2f44ceSEd Maste DoExecute (Args& command, CommandReturnObject &result) override 406ac7ddfbfSEd Maste { 4077aa51b79SEd Maste Target *target = GetSelectedOrDummyTarget(m_options.m_use_dummy); 408ac7ddfbfSEd Maste 4094bb0738eSEd Maste if (target == nullptr) 410ac7ddfbfSEd Maste { 411ac7ddfbfSEd Maste result.AppendError ("There is not a current executable; there are no breakpoints to which to add commands"); 412ac7ddfbfSEd Maste result.SetStatus (eReturnStatusFailed); 413ac7ddfbfSEd Maste return false; 414ac7ddfbfSEd Maste } 415ac7ddfbfSEd Maste 416ac7ddfbfSEd Maste const BreakpointList &breakpoints = target->GetBreakpointList(); 417ac7ddfbfSEd Maste size_t num_breakpoints = breakpoints.GetSize(); 418ac7ddfbfSEd Maste 419ac7ddfbfSEd Maste if (num_breakpoints == 0) 420ac7ddfbfSEd Maste { 421ac7ddfbfSEd Maste result.AppendError ("No breakpoints exist to have commands added"); 422ac7ddfbfSEd Maste result.SetStatus (eReturnStatusFailed); 423ac7ddfbfSEd Maste return false; 424ac7ddfbfSEd Maste } 425ac7ddfbfSEd Maste 4264bb0738eSEd Maste if (!m_options.m_use_script_language && !m_options.m_function_name.empty()) 427ac7ddfbfSEd Maste { 428ac7ddfbfSEd Maste result.AppendError ("need to enable scripting to have a function run as a breakpoint command"); 429ac7ddfbfSEd Maste result.SetStatus (eReturnStatusFailed); 430ac7ddfbfSEd Maste return false; 431ac7ddfbfSEd Maste } 432ac7ddfbfSEd Maste 433ac7ddfbfSEd Maste BreakpointIDList valid_bp_ids; 4347aa51b79SEd Maste CommandObjectMultiwordBreakpoint::VerifyBreakpointOrLocationIDs (command, target, result, &valid_bp_ids); 435ac7ddfbfSEd Maste 4360127ef0fSEd Maste m_bp_options_vec.clear(); 4370127ef0fSEd Maste 438ac7ddfbfSEd Maste if (result.Succeeded()) 439ac7ddfbfSEd Maste { 440ac7ddfbfSEd Maste const size_t count = valid_bp_ids.GetSize(); 441ac7ddfbfSEd Maste 442ac7ddfbfSEd Maste for (size_t i = 0; i < count; ++i) 443ac7ddfbfSEd Maste { 444ac7ddfbfSEd Maste BreakpointID cur_bp_id = valid_bp_ids.GetBreakpointIDAtIndex (i); 445ac7ddfbfSEd Maste if (cur_bp_id.GetBreakpointID() != LLDB_INVALID_BREAK_ID) 446ac7ddfbfSEd Maste { 447ac7ddfbfSEd Maste Breakpoint *bp = target->GetBreakpointByID (cur_bp_id.GetBreakpointID()).get(); 4484bb0738eSEd Maste BreakpointOptions *bp_options = nullptr; 449ac7ddfbfSEd Maste if (cur_bp_id.GetLocationID() == LLDB_INVALID_BREAK_ID) 450ac7ddfbfSEd Maste { 451ac7ddfbfSEd Maste // This breakpoint does not have an associated location. 452ac7ddfbfSEd Maste bp_options = bp->GetOptions(); 453ac7ddfbfSEd Maste } 454ac7ddfbfSEd Maste else 455ac7ddfbfSEd Maste { 456ac7ddfbfSEd Maste BreakpointLocationSP bp_loc_sp(bp->FindLocationByID (cur_bp_id.GetLocationID())); 457ac7ddfbfSEd Maste // This breakpoint does have an associated location. 458ac7ddfbfSEd Maste // Get its breakpoint options. 459ac7ddfbfSEd Maste if (bp_loc_sp) 460ac7ddfbfSEd Maste bp_options = bp_loc_sp->GetLocationOptions(); 461ac7ddfbfSEd Maste } 4620127ef0fSEd Maste if (bp_options) 4630127ef0fSEd Maste m_bp_options_vec.push_back (bp_options); 4640127ef0fSEd Maste } 4650127ef0fSEd Maste } 466ac7ddfbfSEd Maste 467ac7ddfbfSEd Maste // If we are using script language, get the script interpreter 468ac7ddfbfSEd Maste // in order to set or collect command callback. Otherwise, call 469ac7ddfbfSEd Maste // the methods associated with this object. 470ac7ddfbfSEd Maste if (m_options.m_use_script_language) 471ac7ddfbfSEd Maste { 4720127ef0fSEd Maste ScriptInterpreter *script_interp = m_interpreter.GetScriptInterpreter(); 473ac7ddfbfSEd Maste // Special handling for one-liner specified inline. 474ac7ddfbfSEd Maste if (m_options.m_use_one_liner) 475ac7ddfbfSEd Maste { 4760127ef0fSEd Maste script_interp->SetBreakpointCommandCallback (m_bp_options_vec, 477ac7ddfbfSEd Maste m_options.m_one_liner.c_str()); 478ac7ddfbfSEd Maste } 4794bb0738eSEd Maste else if (!m_options.m_function_name.empty()) 480ac7ddfbfSEd Maste { 4810127ef0fSEd Maste script_interp->SetBreakpointCommandCallbackFunction (m_bp_options_vec, 4820127ef0fSEd Maste m_options.m_function_name.c_str()); 483ac7ddfbfSEd Maste } 484ac7ddfbfSEd Maste else 485ac7ddfbfSEd Maste { 4860127ef0fSEd Maste script_interp->CollectDataForBreakpointCommandCallback (m_bp_options_vec, 487ac7ddfbfSEd Maste result); 488ac7ddfbfSEd Maste } 489ac7ddfbfSEd Maste } 490ac7ddfbfSEd Maste else 491ac7ddfbfSEd Maste { 492ac7ddfbfSEd Maste // Special handling for one-liner specified inline. 493ac7ddfbfSEd Maste if (m_options.m_use_one_liner) 4940127ef0fSEd Maste SetBreakpointCommandCallback (m_bp_options_vec, 495ac7ddfbfSEd Maste m_options.m_one_liner.c_str()); 496ac7ddfbfSEd Maste else 4970127ef0fSEd Maste CollectDataForBreakpointCommandCallback (m_bp_options_vec, 498ac7ddfbfSEd Maste result); 499ac7ddfbfSEd Maste } 500ac7ddfbfSEd Maste } 501ac7ddfbfSEd Maste 502ac7ddfbfSEd Maste return result.Succeeded(); 503ac7ddfbfSEd Maste } 504ac7ddfbfSEd Maste 505ac7ddfbfSEd Maste private: 506ac7ddfbfSEd Maste CommandOptions m_options; 5070127ef0fSEd Maste std::vector<BreakpointOptions *> m_bp_options_vec; // This stores the breakpoint options that we are currently 5080127ef0fSEd Maste // collecting commands for. In the CollectData... calls we need 5090127ef0fSEd Maste // to hand this off to the IOHandler, which may run asynchronously. 5100127ef0fSEd Maste // So we have to have some way to keep it alive, and not leak it. 5110127ef0fSEd Maste // Making it an ivar of the command object, which never goes away 5120127ef0fSEd Maste // achieves this. Note that if we were able to run 5130127ef0fSEd Maste // the same command concurrently in one interpreter we'd have to 5140127ef0fSEd Maste // make this "per invocation". But there are many more reasons 5150127ef0fSEd Maste // why it is not in general safe to do that in lldb at present, 5160127ef0fSEd Maste // so it isn't worthwhile to come up with a more complex mechanism 5170127ef0fSEd Maste // to address this particular weakness right now. 518ac7ddfbfSEd Maste static const char *g_reader_instructions; 519ac7ddfbfSEd Maste }; 520ac7ddfbfSEd Maste 521ac7ddfbfSEd Maste const char * 52212b93ac6SEd Maste CommandObjectBreakpointCommandAdd::g_reader_instructions = "Enter your debugger command(s). Type 'DONE' to end.\n"; 523ac7ddfbfSEd Maste 524ac7ddfbfSEd Maste // FIXME: "script-type" needs to have its contents determined dynamically, so somebody can add a new scripting 525ac7ddfbfSEd Maste // language to lldb and have it pickable here without having to change this enumeration by hand and rebuild lldb proper. 526ac7ddfbfSEd Maste 527ac7ddfbfSEd Maste static OptionEnumValueElement 528ac7ddfbfSEd Maste g_script_option_enumeration[4] = 529ac7ddfbfSEd Maste { 530ac7ddfbfSEd Maste { eScriptLanguageNone, "command", "Commands are in the lldb command interpreter language"}, 531ac7ddfbfSEd Maste { eScriptLanguagePython, "python", "Commands are in the Python language."}, 532ac7ddfbfSEd Maste { eSortOrderByName, "default-script", "Commands are in the default scripting language."}, 5334bb0738eSEd Maste { 0, nullptr, nullptr } 534ac7ddfbfSEd Maste }; 535ac7ddfbfSEd Maste 536ac7ddfbfSEd Maste OptionDefinition 537ac7ddfbfSEd Maste CommandObjectBreakpointCommandAdd::CommandOptions::g_option_table[] = 538ac7ddfbfSEd Maste { 5394bb0738eSEd Maste { LLDB_OPT_SET_1, false, "one-liner", 'o', OptionParser::eRequiredArgument, nullptr, nullptr, 0, eArgTypeOneLiner, 540ac7ddfbfSEd Maste "Specify a one-line breakpoint command inline. Be sure to surround it with quotes." }, 541ac7ddfbfSEd Maste 5424bb0738eSEd Maste { LLDB_OPT_SET_ALL, false, "stop-on-error", 'e', OptionParser::eRequiredArgument, nullptr, nullptr, 0, eArgTypeBoolean, 543ac7ddfbfSEd Maste "Specify whether breakpoint command execution should terminate on error." }, 544ac7ddfbfSEd Maste 5454bb0738eSEd Maste { LLDB_OPT_SET_ALL, false, "script-type", 's', OptionParser::eRequiredArgument, nullptr, g_script_option_enumeration, 0, eArgTypeNone, 546ac7ddfbfSEd Maste "Specify the language for the commands - if none is specified, the lldb command interpreter will be used."}, 547ac7ddfbfSEd Maste 5484bb0738eSEd Maste { LLDB_OPT_SET_2, false, "python-function", 'F', OptionParser::eRequiredArgument, nullptr, nullptr, 0, eArgTypePythonFunction, 549ac7ddfbfSEd Maste "Give the name of a Python function to run as command for this breakpoint. Be sure to give a module name if appropriate."}, 550ac7ddfbfSEd Maste 5514bb0738eSEd Maste { LLDB_OPT_SET_ALL, false, "dummy-breakpoints", 'D', OptionParser::eNoArgument, nullptr, nullptr, 0, eArgTypeNone, 5527aa51b79SEd Maste "Sets Dummy breakpoints - i.e. breakpoints set before a file is provided, which prime new targets."}, 5537aa51b79SEd Maste 5544bb0738eSEd Maste { 0, false, nullptr, 0, 0, nullptr, nullptr, 0, eArgTypeNone, nullptr } 555ac7ddfbfSEd Maste }; 556ac7ddfbfSEd Maste 557ac7ddfbfSEd Maste //------------------------------------------------------------------------- 558ac7ddfbfSEd Maste // CommandObjectBreakpointCommandDelete 559ac7ddfbfSEd Maste //------------------------------------------------------------------------- 560ac7ddfbfSEd Maste 561ac7ddfbfSEd Maste class CommandObjectBreakpointCommandDelete : public CommandObjectParsed 562ac7ddfbfSEd Maste { 563ac7ddfbfSEd Maste public: 564ac7ddfbfSEd Maste CommandObjectBreakpointCommandDelete (CommandInterpreter &interpreter) : 565ac7ddfbfSEd Maste CommandObjectParsed(interpreter, 566ac7ddfbfSEd Maste "delete", 567ac7ddfbfSEd Maste "Delete the set of commands from a breakpoint.", 5684bb0738eSEd Maste nullptr), 5697aa51b79SEd Maste m_options (interpreter) 570ac7ddfbfSEd Maste { 571ac7ddfbfSEd Maste CommandArgumentEntry arg; 572ac7ddfbfSEd Maste CommandArgumentData bp_id_arg; 573ac7ddfbfSEd Maste 574ac7ddfbfSEd Maste // Define the first (and only) variant of this arg. 575ac7ddfbfSEd Maste bp_id_arg.arg_type = eArgTypeBreakpointID; 576ac7ddfbfSEd Maste bp_id_arg.arg_repetition = eArgRepeatPlain; 577ac7ddfbfSEd Maste 578ac7ddfbfSEd Maste // There is only one variant this argument could be; put it into the argument entry. 579ac7ddfbfSEd Maste arg.push_back (bp_id_arg); 580ac7ddfbfSEd Maste 581ac7ddfbfSEd Maste // Push the data for the first argument into the m_arguments vector. 582ac7ddfbfSEd Maste m_arguments.push_back (arg); 583ac7ddfbfSEd Maste } 584ac7ddfbfSEd Maste 5854bb0738eSEd Maste ~CommandObjectBreakpointCommandDelete() override = default; 586ac7ddfbfSEd Maste 5879f2f44ceSEd Maste Options * 5889f2f44ceSEd Maste GetOptions () override 5897aa51b79SEd Maste { 5907aa51b79SEd Maste return &m_options; 5917aa51b79SEd Maste } 5927aa51b79SEd Maste 5937aa51b79SEd Maste class CommandOptions : public Options 5947aa51b79SEd Maste { 5957aa51b79SEd Maste public: 5967aa51b79SEd Maste CommandOptions (CommandInterpreter &interpreter) : 5977aa51b79SEd Maste Options (interpreter), 5987aa51b79SEd Maste m_use_dummy (false) 5997aa51b79SEd Maste { 6007aa51b79SEd Maste } 6017aa51b79SEd Maste 6024bb0738eSEd Maste ~CommandOptions() override = default; 6037aa51b79SEd Maste 6049f2f44ceSEd Maste Error 6059f2f44ceSEd Maste SetOptionValue (uint32_t option_idx, const char *option_arg) override 6067aa51b79SEd Maste { 6077aa51b79SEd Maste Error error; 6087aa51b79SEd Maste const int short_option = m_getopt_table[option_idx].val; 6097aa51b79SEd Maste 6107aa51b79SEd Maste switch (short_option) 6117aa51b79SEd Maste { 6127aa51b79SEd Maste case 'D': 6137aa51b79SEd Maste m_use_dummy = true; 6147aa51b79SEd Maste break; 6157aa51b79SEd Maste 6167aa51b79SEd Maste default: 6177aa51b79SEd Maste error.SetErrorStringWithFormat ("unrecognized option '%c'", short_option); 6187aa51b79SEd Maste break; 6197aa51b79SEd Maste } 6207aa51b79SEd Maste 6217aa51b79SEd Maste return error; 6227aa51b79SEd Maste } 6237aa51b79SEd Maste 6247aa51b79SEd Maste void 6259f2f44ceSEd Maste OptionParsingStarting () override 6267aa51b79SEd Maste { 6277aa51b79SEd Maste m_use_dummy = false; 6287aa51b79SEd Maste } 6297aa51b79SEd Maste 6307aa51b79SEd Maste const OptionDefinition* 6319f2f44ceSEd Maste GetDefinitions () override 6327aa51b79SEd Maste { 6337aa51b79SEd Maste return g_option_table; 6347aa51b79SEd Maste } 6357aa51b79SEd Maste 6367aa51b79SEd Maste // Options table: Required for subclasses of Options. 6377aa51b79SEd Maste 6387aa51b79SEd Maste static OptionDefinition g_option_table[]; 6397aa51b79SEd Maste 6407aa51b79SEd Maste // Instance variables to hold the values for command options. 6417aa51b79SEd Maste bool m_use_dummy; 6427aa51b79SEd Maste }; 6437aa51b79SEd Maste 644ac7ddfbfSEd Maste protected: 6459f2f44ceSEd Maste bool 6469f2f44ceSEd Maste DoExecute (Args& command, CommandReturnObject &result) override 647ac7ddfbfSEd Maste { 6487aa51b79SEd Maste Target *target = GetSelectedOrDummyTarget(m_options.m_use_dummy); 649ac7ddfbfSEd Maste 6504bb0738eSEd Maste if (target == nullptr) 651ac7ddfbfSEd Maste { 652ac7ddfbfSEd Maste result.AppendError ("There is not a current executable; there are no breakpoints from which to delete commands"); 653ac7ddfbfSEd Maste result.SetStatus (eReturnStatusFailed); 654ac7ddfbfSEd Maste return false; 655ac7ddfbfSEd Maste } 656ac7ddfbfSEd Maste 657ac7ddfbfSEd Maste const BreakpointList &breakpoints = target->GetBreakpointList(); 658ac7ddfbfSEd Maste size_t num_breakpoints = breakpoints.GetSize(); 659ac7ddfbfSEd Maste 660ac7ddfbfSEd Maste if (num_breakpoints == 0) 661ac7ddfbfSEd Maste { 662ac7ddfbfSEd Maste result.AppendError ("No breakpoints exist to have commands deleted"); 663ac7ddfbfSEd Maste result.SetStatus (eReturnStatusFailed); 664ac7ddfbfSEd Maste return false; 665ac7ddfbfSEd Maste } 666ac7ddfbfSEd Maste 667ac7ddfbfSEd Maste if (command.GetArgumentCount() == 0) 668ac7ddfbfSEd Maste { 669ac7ddfbfSEd Maste result.AppendError ("No breakpoint specified from which to delete the commands"); 670ac7ddfbfSEd Maste result.SetStatus (eReturnStatusFailed); 671ac7ddfbfSEd Maste return false; 672ac7ddfbfSEd Maste } 673ac7ddfbfSEd Maste 674ac7ddfbfSEd Maste BreakpointIDList valid_bp_ids; 6757aa51b79SEd Maste CommandObjectMultiwordBreakpoint::VerifyBreakpointOrLocationIDs (command, target, result, &valid_bp_ids); 676ac7ddfbfSEd Maste 677ac7ddfbfSEd Maste if (result.Succeeded()) 678ac7ddfbfSEd Maste { 679ac7ddfbfSEd Maste const size_t count = valid_bp_ids.GetSize(); 680ac7ddfbfSEd Maste for (size_t i = 0; i < count; ++i) 681ac7ddfbfSEd Maste { 682ac7ddfbfSEd Maste BreakpointID cur_bp_id = valid_bp_ids.GetBreakpointIDAtIndex (i); 683ac7ddfbfSEd Maste if (cur_bp_id.GetBreakpointID() != LLDB_INVALID_BREAK_ID) 684ac7ddfbfSEd Maste { 685ac7ddfbfSEd Maste Breakpoint *bp = target->GetBreakpointByID (cur_bp_id.GetBreakpointID()).get(); 686ac7ddfbfSEd Maste if (cur_bp_id.GetLocationID() != LLDB_INVALID_BREAK_ID) 687ac7ddfbfSEd Maste { 688ac7ddfbfSEd Maste BreakpointLocationSP bp_loc_sp (bp->FindLocationByID (cur_bp_id.GetLocationID())); 689ac7ddfbfSEd Maste if (bp_loc_sp) 690ac7ddfbfSEd Maste bp_loc_sp->ClearCallback(); 691ac7ddfbfSEd Maste else 692ac7ddfbfSEd Maste { 693ac7ddfbfSEd Maste result.AppendErrorWithFormat("Invalid breakpoint ID: %u.%u.\n", 694ac7ddfbfSEd Maste cur_bp_id.GetBreakpointID(), 695ac7ddfbfSEd Maste cur_bp_id.GetLocationID()); 696ac7ddfbfSEd Maste result.SetStatus (eReturnStatusFailed); 697ac7ddfbfSEd Maste return false; 698ac7ddfbfSEd Maste } 699ac7ddfbfSEd Maste } 700ac7ddfbfSEd Maste else 701ac7ddfbfSEd Maste { 702ac7ddfbfSEd Maste bp->ClearCallback(); 703ac7ddfbfSEd Maste } 704ac7ddfbfSEd Maste } 705ac7ddfbfSEd Maste } 706ac7ddfbfSEd Maste } 707ac7ddfbfSEd Maste return result.Succeeded(); 708ac7ddfbfSEd Maste } 7094bb0738eSEd Maste 7107aa51b79SEd Maste private: 7117aa51b79SEd Maste CommandOptions m_options; 712ac7ddfbfSEd Maste }; 713ac7ddfbfSEd Maste 7147aa51b79SEd Maste OptionDefinition 7157aa51b79SEd Maste CommandObjectBreakpointCommandDelete::CommandOptions::g_option_table[] = 7167aa51b79SEd Maste { 7174bb0738eSEd Maste { LLDB_OPT_SET_1, false, "dummy-breakpoints", 'D', OptionParser::eNoArgument, nullptr, nullptr, 0, eArgTypeNone, 7187aa51b79SEd Maste "Delete commands from Dummy breakpoints - i.e. breakpoints set before a file is provided, which prime new targets."}, 7197aa51b79SEd Maste 7204bb0738eSEd Maste { 0, false, nullptr, 0, 0, nullptr, nullptr, 0, eArgTypeNone, nullptr } 7217aa51b79SEd Maste }; 7227aa51b79SEd Maste 723ac7ddfbfSEd Maste //------------------------------------------------------------------------- 724ac7ddfbfSEd Maste // CommandObjectBreakpointCommandList 725ac7ddfbfSEd Maste //------------------------------------------------------------------------- 726ac7ddfbfSEd Maste 727ac7ddfbfSEd Maste class CommandObjectBreakpointCommandList : public CommandObjectParsed 728ac7ddfbfSEd Maste { 729ac7ddfbfSEd Maste public: 730ac7ddfbfSEd Maste CommandObjectBreakpointCommandList (CommandInterpreter &interpreter) : 731ac7ddfbfSEd Maste CommandObjectParsed(interpreter, 732ac7ddfbfSEd Maste "list", 733ac7ddfbfSEd Maste "List the script or set of commands to be executed when the breakpoint is hit.", 7344bb0738eSEd Maste nullptr) 735ac7ddfbfSEd Maste { 736ac7ddfbfSEd Maste CommandArgumentEntry arg; 737ac7ddfbfSEd Maste CommandArgumentData bp_id_arg; 738ac7ddfbfSEd Maste 739ac7ddfbfSEd Maste // Define the first (and only) variant of this arg. 740ac7ddfbfSEd Maste bp_id_arg.arg_type = eArgTypeBreakpointID; 741ac7ddfbfSEd Maste bp_id_arg.arg_repetition = eArgRepeatPlain; 742ac7ddfbfSEd Maste 743ac7ddfbfSEd Maste // There is only one variant this argument could be; put it into the argument entry. 744ac7ddfbfSEd Maste arg.push_back (bp_id_arg); 745ac7ddfbfSEd Maste 746ac7ddfbfSEd Maste // Push the data for the first argument into the m_arguments vector. 747ac7ddfbfSEd Maste m_arguments.push_back (arg); 748ac7ddfbfSEd Maste } 749ac7ddfbfSEd Maste 7504bb0738eSEd Maste ~CommandObjectBreakpointCommandList() override = default; 751ac7ddfbfSEd Maste 752ac7ddfbfSEd Maste protected: 7539f2f44ceSEd Maste bool 754ac7ddfbfSEd Maste DoExecute (Args& command, 7559f2f44ceSEd Maste CommandReturnObject &result) override 756ac7ddfbfSEd Maste { 757ac7ddfbfSEd Maste Target *target = m_interpreter.GetDebugger().GetSelectedTarget().get(); 758ac7ddfbfSEd Maste 7594bb0738eSEd Maste if (target == nullptr) 760ac7ddfbfSEd Maste { 761ac7ddfbfSEd Maste result.AppendError ("There is not a current executable; there are no breakpoints for which to list commands"); 762ac7ddfbfSEd Maste result.SetStatus (eReturnStatusFailed); 763ac7ddfbfSEd Maste return false; 764ac7ddfbfSEd Maste } 765ac7ddfbfSEd Maste 766ac7ddfbfSEd Maste const BreakpointList &breakpoints = target->GetBreakpointList(); 767ac7ddfbfSEd Maste size_t num_breakpoints = breakpoints.GetSize(); 768ac7ddfbfSEd Maste 769ac7ddfbfSEd Maste if (num_breakpoints == 0) 770ac7ddfbfSEd Maste { 771ac7ddfbfSEd Maste result.AppendError ("No breakpoints exist for which to list commands"); 772ac7ddfbfSEd Maste result.SetStatus (eReturnStatusFailed); 773ac7ddfbfSEd Maste return false; 774ac7ddfbfSEd Maste } 775ac7ddfbfSEd Maste 776ac7ddfbfSEd Maste if (command.GetArgumentCount() == 0) 777ac7ddfbfSEd Maste { 778ac7ddfbfSEd Maste result.AppendError ("No breakpoint specified for which to list the commands"); 779ac7ddfbfSEd Maste result.SetStatus (eReturnStatusFailed); 780ac7ddfbfSEd Maste return false; 781ac7ddfbfSEd Maste } 782ac7ddfbfSEd Maste 783ac7ddfbfSEd Maste BreakpointIDList valid_bp_ids; 7847aa51b79SEd Maste CommandObjectMultiwordBreakpoint::VerifyBreakpointOrLocationIDs (command, target, result, &valid_bp_ids); 785ac7ddfbfSEd Maste 786ac7ddfbfSEd Maste if (result.Succeeded()) 787ac7ddfbfSEd Maste { 788ac7ddfbfSEd Maste const size_t count = valid_bp_ids.GetSize(); 789ac7ddfbfSEd Maste for (size_t i = 0; i < count; ++i) 790ac7ddfbfSEd Maste { 791ac7ddfbfSEd Maste BreakpointID cur_bp_id = valid_bp_ids.GetBreakpointIDAtIndex (i); 792ac7ddfbfSEd Maste if (cur_bp_id.GetBreakpointID() != LLDB_INVALID_BREAK_ID) 793ac7ddfbfSEd Maste { 794ac7ddfbfSEd Maste Breakpoint *bp = target->GetBreakpointByID (cur_bp_id.GetBreakpointID()).get(); 795ac7ddfbfSEd Maste 796ac7ddfbfSEd Maste if (bp) 797ac7ddfbfSEd Maste { 7984bb0738eSEd Maste const BreakpointOptions *bp_options = nullptr; 799ac7ddfbfSEd Maste if (cur_bp_id.GetLocationID() != LLDB_INVALID_BREAK_ID) 800ac7ddfbfSEd Maste { 801ac7ddfbfSEd Maste BreakpointLocationSP bp_loc_sp(bp->FindLocationByID (cur_bp_id.GetLocationID())); 802ac7ddfbfSEd Maste if (bp_loc_sp) 803ac7ddfbfSEd Maste bp_options = bp_loc_sp->GetOptionsNoCreate(); 804ac7ddfbfSEd Maste else 805ac7ddfbfSEd Maste { 806ac7ddfbfSEd Maste result.AppendErrorWithFormat("Invalid breakpoint ID: %u.%u.\n", 807ac7ddfbfSEd Maste cur_bp_id.GetBreakpointID(), 808ac7ddfbfSEd Maste cur_bp_id.GetLocationID()); 809ac7ddfbfSEd Maste result.SetStatus (eReturnStatusFailed); 810ac7ddfbfSEd Maste return false; 811ac7ddfbfSEd Maste } 812ac7ddfbfSEd Maste } 813ac7ddfbfSEd Maste else 814ac7ddfbfSEd Maste { 815ac7ddfbfSEd Maste bp_options = bp->GetOptions(); 816ac7ddfbfSEd Maste } 817ac7ddfbfSEd Maste 818ac7ddfbfSEd Maste if (bp_options) 819ac7ddfbfSEd Maste { 820ac7ddfbfSEd Maste StreamString id_str; 821ac7ddfbfSEd Maste BreakpointID::GetCanonicalReference (&id_str, 822ac7ddfbfSEd Maste cur_bp_id.GetBreakpointID(), 823ac7ddfbfSEd Maste cur_bp_id.GetLocationID()); 824ac7ddfbfSEd Maste const Baton *baton = bp_options->GetBaton(); 825ac7ddfbfSEd Maste if (baton) 826ac7ddfbfSEd Maste { 827ac7ddfbfSEd Maste result.GetOutputStream().Printf ("Breakpoint %s:\n", id_str.GetData()); 828ac7ddfbfSEd Maste result.GetOutputStream().IndentMore (); 829ac7ddfbfSEd Maste baton->GetDescription(&result.GetOutputStream(), eDescriptionLevelFull); 830ac7ddfbfSEd Maste result.GetOutputStream().IndentLess (); 831ac7ddfbfSEd Maste } 832ac7ddfbfSEd Maste else 833ac7ddfbfSEd Maste { 834ac7ddfbfSEd Maste result.AppendMessageWithFormat ("Breakpoint %s does not have an associated command.\n", 835ac7ddfbfSEd Maste id_str.GetData()); 836ac7ddfbfSEd Maste } 837ac7ddfbfSEd Maste } 838ac7ddfbfSEd Maste result.SetStatus (eReturnStatusSuccessFinishResult); 839ac7ddfbfSEd Maste } 840ac7ddfbfSEd Maste else 841ac7ddfbfSEd Maste { 842ac7ddfbfSEd Maste result.AppendErrorWithFormat("Invalid breakpoint ID: %u.\n", cur_bp_id.GetBreakpointID()); 843ac7ddfbfSEd Maste result.SetStatus (eReturnStatusFailed); 844ac7ddfbfSEd Maste } 845ac7ddfbfSEd Maste } 846ac7ddfbfSEd Maste } 847ac7ddfbfSEd Maste } 848ac7ddfbfSEd Maste 849ac7ddfbfSEd Maste return result.Succeeded(); 850ac7ddfbfSEd Maste } 851ac7ddfbfSEd Maste }; 852ac7ddfbfSEd Maste 853ac7ddfbfSEd Maste //------------------------------------------------------------------------- 854ac7ddfbfSEd Maste // CommandObjectBreakpointCommand 855ac7ddfbfSEd Maste //------------------------------------------------------------------------- 856ac7ddfbfSEd Maste 8574bb0738eSEd Maste CommandObjectBreakpointCommand::CommandObjectBreakpointCommand(CommandInterpreter &interpreter) 8584bb0738eSEd Maste : CommandObjectMultiword( 8594bb0738eSEd Maste interpreter, "command", 8604bb0738eSEd Maste "Commands for adding, removing and listing LLDB commands executed when a breakpoint is hit.", 861ac7ddfbfSEd Maste "command <sub-command> [<sub-command-options>] <breakpoint-id>") 862ac7ddfbfSEd Maste { 863ac7ddfbfSEd Maste CommandObjectSP add_command_object (new CommandObjectBreakpointCommandAdd (interpreter)); 864ac7ddfbfSEd Maste CommandObjectSP delete_command_object (new CommandObjectBreakpointCommandDelete (interpreter)); 865ac7ddfbfSEd Maste CommandObjectSP list_command_object (new CommandObjectBreakpointCommandList (interpreter)); 866ac7ddfbfSEd Maste 867ac7ddfbfSEd Maste add_command_object->SetCommandName ("breakpoint command add"); 868ac7ddfbfSEd Maste delete_command_object->SetCommandName ("breakpoint command delete"); 869ac7ddfbfSEd Maste list_command_object->SetCommandName ("breakpoint command list"); 870ac7ddfbfSEd Maste 871ac7ddfbfSEd Maste LoadSubCommand ("add", add_command_object); 872ac7ddfbfSEd Maste LoadSubCommand ("delete", delete_command_object); 873ac7ddfbfSEd Maste LoadSubCommand ("list", list_command_object); 874ac7ddfbfSEd Maste } 875ac7ddfbfSEd Maste 8764bb0738eSEd Maste CommandObjectBreakpointCommand::~CommandObjectBreakpointCommand() = default; 877