130fdc8d8SChris Lattner //===-- CommandObjectBreakpointCommand.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 // C Includes 1130fdc8d8SChris Lattner // C++ Includes 1230fdc8d8SChris Lattner 1330fdc8d8SChris Lattner 1430fdc8d8SChris Lattner #include "CommandObjectBreakpointCommand.h" 1530fdc8d8SChris Lattner #include "CommandObjectBreakpoint.h" 1630fdc8d8SChris Lattner 1744d93782SGreg Clayton #include "lldb/Core/IOHandler.h" 1830fdc8d8SChris Lattner #include "lldb/Interpreter/CommandInterpreter.h" 1930fdc8d8SChris Lattner #include "lldb/Interpreter/CommandReturnObject.h" 2030fdc8d8SChris Lattner #include "lldb/Target/Target.h" 2130fdc8d8SChris Lattner #include "lldb/Target/Thread.h" 2230fdc8d8SChris Lattner #include "lldb/Breakpoint/BreakpointIDList.h" 2330fdc8d8SChris Lattner #include "lldb/Breakpoint/Breakpoint.h" 2430fdc8d8SChris Lattner #include "lldb/Breakpoint/BreakpointLocation.h" 2530fdc8d8SChris Lattner #include "lldb/Breakpoint/StoppointCallbackContext.h" 2630fdc8d8SChris Lattner #include "lldb/Core/State.h" 2730fdc8d8SChris Lattner 2830fdc8d8SChris Lattner using namespace lldb; 2930fdc8d8SChris Lattner using namespace lldb_private; 3030fdc8d8SChris Lattner 3130fdc8d8SChris Lattner //------------------------------------------------------------------------- 3230fdc8d8SChris Lattner // CommandObjectBreakpointCommandAdd 3330fdc8d8SChris Lattner //------------------------------------------------------------------------- 3430fdc8d8SChris Lattner 3530fdc8d8SChris Lattner 3644d93782SGreg Clayton class CommandObjectBreakpointCommandAdd : 3744d93782SGreg Clayton public CommandObjectParsed, 3844d93782SGreg Clayton public IOHandlerDelegateMultiline 395a988416SJim Ingham { 405a988416SJim Ingham public: 415a988416SJim Ingham 425a988416SJim Ingham CommandObjectBreakpointCommandAdd (CommandInterpreter &interpreter) : 435a988416SJim Ingham CommandObjectParsed (interpreter, 44a7015092SGreg Clayton "add", 451bb0750bSJim Ingham "Add a set of commands to a breakpoint, to be executed whenever the breakpoint is hit." 461bb0750bSJim Ingham " If no breakpoint is specified, adds the commands to the last created breakpoint.", 47eb0103f2SGreg Clayton NULL), 48c3d874a5SGreg Clayton IOHandlerDelegateMultiline ("DONE", IOHandlerDelegate::Completion::LLDBCommand), 49eb0103f2SGreg Clayton m_options (interpreter) 5030fdc8d8SChris Lattner { 5130fdc8d8SChris Lattner SetHelpLong ( 52ea671fbdSKate Stone R"( 53ea671fbdSKate Stone General information about entering breakpoint commands 54ea671fbdSKate Stone ------------------------------------------------------ 55ea671fbdSKate Stone 56ea671fbdSKate Stone )" "This command will prompt for commands to be executed when the specified \ 57ea671fbdSKate Stone breakpoint is hit. Each command is typed on its own line following the '> ' \ 58ea671fbdSKate Stone prompt until 'DONE' is entered." R"( 59ea671fbdSKate Stone 60ea671fbdSKate Stone )" "Syntactic errors may not be detected when initially entered, and many \ 61ea671fbdSKate Stone malformed commands can silently fail when executed. If your breakpoint commands \ 62ea671fbdSKate Stone do not appear to be executing, double-check the command syntax." R"( 63ea671fbdSKate Stone 64ea671fbdSKate Stone )" "Note: You may enter any debugger command exactly as you would at the debugger \ 65ea671fbdSKate Stone prompt. There is no limit to the number of commands supplied, but do NOT enter \ 66ea671fbdSKate Stone more than one command per line." R"( 67ea671fbdSKate Stone 68ea671fbdSKate Stone Special information about PYTHON breakpoint commands 69ea671fbdSKate Stone ---------------------------------------------------- 70ea671fbdSKate Stone 71ea671fbdSKate Stone )" "You may enter either one or more lines of Python, including function \ 72ea671fbdSKate Stone definitions or calls to functions that will have been imported by the time \ 73ea671fbdSKate Stone the code executes. Single line breakpoint commands will be interpreted 'as is' \ 74ea671fbdSKate Stone when the breakpoint is hit. Multiple lines of Python will be wrapped in a \ 75ea671fbdSKate Stone generated function, and a call to the function will be attached to the breakpoint." R"( 76ea671fbdSKate Stone 77ea671fbdSKate Stone This auto-generated function is passed in three arguments: 78ea671fbdSKate Stone 79ea671fbdSKate Stone frame: an lldb.SBFrame object for the frame which hit breakpoint. 80ea671fbdSKate Stone 81ea671fbdSKate Stone bp_loc: an lldb.SBBreakpointLocation object that represents the breakpoint location that was hit. 82ea671fbdSKate Stone 83ea671fbdSKate Stone dict: the python session dictionary hit. 84ea671fbdSKate Stone 85ea671fbdSKate Stone )" "When specifying a python function with the --python-function option, you need \ 86ea671fbdSKate Stone to supply the function name prepended by the module name:" R"( 87ea671fbdSKate Stone 88ea671fbdSKate Stone --python-function myutils.breakpoint_callback 89ea671fbdSKate Stone 90ea671fbdSKate Stone The function itself must have the following prototype: 91ea671fbdSKate Stone 92ea671fbdSKate Stone def breakpoint_callback(frame, bp_loc, dict): 93ea671fbdSKate Stone # Your code goes here 94ea671fbdSKate Stone 95ea671fbdSKate Stone )" "The arguments are the same as the arguments passed to generated functions as \ 96ea671fbdSKate Stone described above. Note that the global variable 'lldb.frame' will NOT be updated when \ 97ea671fbdSKate Stone this function is called, so be sure to use the 'frame' argument. The 'frame' argument \ 98ea671fbdSKate Stone can get you to the thread via frame.GetThread(), the thread can get you to the \ 99ea671fbdSKate Stone process via thread.GetProcess(), and the process can get you back to the target \ 100ea671fbdSKate Stone via process.GetTarget()." R"( 101ea671fbdSKate Stone 102ea671fbdSKate Stone )" "Important Note: As Python code gets collected into functions, access to global \ 103ea671fbdSKate Stone variables requires explicit scoping using the 'global' keyword. Be sure to use correct \ 104ea671fbdSKate Stone Python syntax, including indentation, when entering Python breakpoint commands." R"( 105ea671fbdSKate Stone 106ea671fbdSKate Stone Example Python one-line breakpoint command: 107ea671fbdSKate Stone 108ea671fbdSKate Stone (lldb) breakpoint command add -s python 1 109ea671fbdSKate Stone Enter your Python command(s). Type 'DONE' to end. 110ea671fbdSKate Stone > print "Hit this breakpoint!" 111ea671fbdSKate Stone > DONE 112ea671fbdSKate Stone 113ea671fbdSKate Stone As a convenience, this also works for a short Python one-liner: 114ea671fbdSKate Stone 115ea671fbdSKate Stone (lldb) breakpoint command add -s python 1 -o 'import time; print time.asctime()' 116ea671fbdSKate Stone (lldb) run 117ea671fbdSKate Stone Launching '.../a.out' (x86_64) 118ea671fbdSKate Stone (lldb) Fri Sep 10 12:17:45 2010 119ea671fbdSKate Stone Process 21778 Stopped 120ea671fbdSKate Stone * thread #1: tid = 0x2e03, 0x0000000100000de8 a.out`c + 7 at main.c:39, stop reason = breakpoint 1.1, queue = com.apple.main-thread 121ea671fbdSKate Stone 36 122ea671fbdSKate Stone 37 int c(int val) 123ea671fbdSKate Stone 38 { 124ea671fbdSKate Stone 39 -> return val + 3; 125ea671fbdSKate Stone 40 } 126ea671fbdSKate Stone 41 127ea671fbdSKate Stone 42 int main (int argc, char const *argv[]) 128ea671fbdSKate Stone 129ea671fbdSKate Stone Example multiple line Python breakpoint command: 130ea671fbdSKate Stone 131ea671fbdSKate Stone (lldb) breakpoint command add -s p 1 132ea671fbdSKate Stone Enter your Python command(s). Type 'DONE' to end. 133ea671fbdSKate Stone > global bp_count 134ea671fbdSKate Stone > bp_count = bp_count + 1 135ea671fbdSKate Stone > print "Hit this breakpoint " + repr(bp_count) + " times!" 136ea671fbdSKate Stone > DONE 137ea671fbdSKate Stone 138ea671fbdSKate Stone Example multiple line Python breakpoint command, using function definition: 139ea671fbdSKate Stone 140ea671fbdSKate Stone (lldb) breakpoint command add -s python 1 141ea671fbdSKate Stone Enter your Python command(s). Type 'DONE' to end. 142ea671fbdSKate Stone > def breakpoint_output (bp_no): 143ea671fbdSKate Stone > out_string = "Hit breakpoint number " + repr (bp_no) 144ea671fbdSKate Stone > print out_string 145ea671fbdSKate Stone > return True 146ea671fbdSKate Stone > breakpoint_output (1) 147ea671fbdSKate Stone > DONE 148ea671fbdSKate Stone 149ea671fbdSKate Stone )" "In this case, since there is a reference to a global variable, \ 150ea671fbdSKate Stone 'bp_count', you will also need to make sure 'bp_count' exists and is \ 151ea671fbdSKate Stone initialized:" R"( 152ea671fbdSKate Stone 153ea671fbdSKate Stone (lldb) script 154ea671fbdSKate Stone >>> bp_count = 0 155ea671fbdSKate Stone >>> quit() 156ea671fbdSKate Stone 157ea671fbdSKate Stone )" "Your Python code, however organized, can optionally return a value. \ 158ea671fbdSKate Stone If the returned value is False, that tells LLDB not to stop at the breakpoint \ 159ea671fbdSKate Stone to which the code is associated. Returning anything other than False, or even \ 160ea671fbdSKate Stone returning None, or even omitting a return statement entirely, will cause \ 161ea671fbdSKate Stone LLDB to stop." R"( 162ea671fbdSKate Stone 163ea671fbdSKate Stone )" "Final Note: A warning that no breakpoint command was generated when there \ 164ea671fbdSKate Stone are no syntax errors may indicate that a function was declared but never called." 165ea671fbdSKate Stone ); 166405fe67fSCaroline Tice 167405fe67fSCaroline Tice CommandArgumentEntry arg; 168405fe67fSCaroline Tice CommandArgumentData bp_id_arg; 169405fe67fSCaroline Tice 170405fe67fSCaroline Tice // Define the first (and only) variant of this arg. 171405fe67fSCaroline Tice bp_id_arg.arg_type = eArgTypeBreakpointID; 1721bb0750bSJim Ingham bp_id_arg.arg_repetition = eArgRepeatOptional; 173405fe67fSCaroline Tice 174405fe67fSCaroline Tice // There is only one variant this argument could be; put it into the argument entry. 175405fe67fSCaroline Tice arg.push_back (bp_id_arg); 176405fe67fSCaroline Tice 177405fe67fSCaroline Tice // Push the data for the first argument into the m_arguments vector. 178405fe67fSCaroline Tice m_arguments.push_back (arg); 17930fdc8d8SChris Lattner } 18030fdc8d8SChris Lattner 181*13d21e9aSBruce Mitchener ~CommandObjectBreakpointCommandAdd () override {} 1825a988416SJim Ingham 183*13d21e9aSBruce Mitchener Options * 184*13d21e9aSBruce Mitchener GetOptions () override 1855a988416SJim Ingham { 1865a988416SJim Ingham return &m_options; 1875a988416SJim Ingham } 1885a988416SJim Ingham 189*13d21e9aSBruce Mitchener void 190*13d21e9aSBruce Mitchener IOHandlerActivated (IOHandler &io_handler) override 19144d93782SGreg Clayton { 19244d93782SGreg Clayton StreamFileSP output_sp(io_handler.GetOutputStreamFile()); 19344d93782SGreg Clayton if (output_sp) 19444d93782SGreg Clayton { 19544d93782SGreg Clayton output_sp->PutCString(g_reader_instructions); 19644d93782SGreg Clayton output_sp->Flush(); 19744d93782SGreg Clayton } 19844d93782SGreg Clayton } 19944d93782SGreg Clayton 20044d93782SGreg Clayton 201*13d21e9aSBruce Mitchener void 202*13d21e9aSBruce Mitchener IOHandlerInputComplete (IOHandler &io_handler, std::string &line) override 20344d93782SGreg Clayton { 20444d93782SGreg Clayton io_handler.SetIsDone(true); 20544d93782SGreg Clayton 206b5796cb4SJim Ingham std::vector<BreakpointOptions *> *bp_options_vec = (std::vector<BreakpointOptions *> *)io_handler.GetUserData(); 207b5796cb4SJim Ingham for (BreakpointOptions *bp_options : *bp_options_vec) 20844d93782SGreg Clayton { 209b5796cb4SJim Ingham if (!bp_options) 210b5796cb4SJim Ingham continue; 211b5796cb4SJim Ingham 21244d93782SGreg Clayton std::unique_ptr<BreakpointOptions::CommandData> data_ap(new BreakpointOptions::CommandData()); 21344d93782SGreg Clayton if (data_ap.get()) 21444d93782SGreg Clayton { 21544d93782SGreg Clayton data_ap->user_source.SplitIntoLines (line.c_str(), line.size()); 21644d93782SGreg Clayton BatonSP baton_sp (new BreakpointOptions::CommandBaton (data_ap.release())); 21744d93782SGreg Clayton bp_options->SetCallback (BreakpointOptionsCallbackFunction, baton_sp); 21844d93782SGreg Clayton } 21944d93782SGreg Clayton } 22044d93782SGreg Clayton } 22144d93782SGreg Clayton 2225a988416SJim Ingham void 223b5796cb4SJim Ingham CollectDataForBreakpointCommandCallback (std::vector<BreakpointOptions *> &bp_options_vec, 2245a988416SJim Ingham CommandReturnObject &result) 2255a988416SJim Ingham { 22644d93782SGreg Clayton m_interpreter.GetLLDBCommandsFromIOHandler ("> ", // Prompt 22744d93782SGreg Clayton *this, // IOHandlerDelegate 22844d93782SGreg Clayton true, // Run IOHandler in async mode 229b5796cb4SJim Ingham &bp_options_vec); // Baton for the "io_handler" that will be passed back into our IOHandlerDelegate functions 2305a988416SJim Ingham } 2315a988416SJim Ingham 2325a988416SJim Ingham /// Set a one-liner as the callback for the breakpoint. 2335a988416SJim Ingham void 234b5796cb4SJim Ingham SetBreakpointCommandCallback (std::vector<BreakpointOptions *> &bp_options_vec, 2355a988416SJim Ingham const char *oneliner) 2365a988416SJim Ingham { 237b5796cb4SJim Ingham for (auto bp_options : bp_options_vec) 238b5796cb4SJim Ingham { 2397b0992d9SGreg Clayton std::unique_ptr<BreakpointOptions::CommandData> data_ap(new BreakpointOptions::CommandData()); 2405a988416SJim Ingham 2415a988416SJim Ingham // It's necessary to set both user_source and script_source to the oneliner. 2425a988416SJim Ingham // The former is used to generate callback description (as in breakpoint command list) 2435a988416SJim Ingham // while the latter is used for Python to interpret during the actual callback. 2445a988416SJim Ingham data_ap->user_source.AppendString (oneliner); 2455a988416SJim Ingham data_ap->script_source.assign (oneliner); 2465a988416SJim Ingham data_ap->stop_on_error = m_options.m_stop_on_error; 2475a988416SJim Ingham 2485a988416SJim Ingham BatonSP baton_sp (new BreakpointOptions::CommandBaton (data_ap.release())); 2495a988416SJim Ingham bp_options->SetCallback (BreakpointOptionsCallbackFunction, baton_sp); 250b5796cb4SJim Ingham } 2515a988416SJim Ingham return; 2525a988416SJim Ingham } 2535a988416SJim Ingham 2545a988416SJim Ingham static bool 2555a988416SJim Ingham BreakpointOptionsCallbackFunction (void *baton, 2565a988416SJim Ingham StoppointCallbackContext *context, 2575a988416SJim Ingham lldb::user_id_t break_id, 2585a988416SJim Ingham lldb::user_id_t break_loc_id) 2595a988416SJim Ingham { 2605a988416SJim Ingham bool ret_value = true; 2615a988416SJim Ingham if (baton == NULL) 2625a988416SJim Ingham return true; 2635a988416SJim Ingham 2645a988416SJim Ingham 2655a988416SJim Ingham BreakpointOptions::CommandData *data = (BreakpointOptions::CommandData *) baton; 2665a988416SJim Ingham StringList &commands = data->user_source; 2675a988416SJim Ingham 2685a988416SJim Ingham if (commands.GetSize() > 0) 2695a988416SJim Ingham { 2705a988416SJim Ingham ExecutionContext exe_ctx (context->exe_ctx_ref); 2715a988416SJim Ingham Target *target = exe_ctx.GetTargetPtr(); 2725a988416SJim Ingham if (target) 2735a988416SJim Ingham { 2745a988416SJim Ingham CommandReturnObject result; 2755a988416SJim Ingham Debugger &debugger = target->GetDebugger(); 2765a988416SJim Ingham // Rig up the results secondary output stream to the debugger's, so the output will come out synchronously 2775a988416SJim Ingham // if the debugger is set up that way. 2785a988416SJim Ingham 2795a988416SJim Ingham StreamSP output_stream (debugger.GetAsyncOutputStream()); 2805a988416SJim Ingham StreamSP error_stream (debugger.GetAsyncErrorStream()); 2815a988416SJim Ingham result.SetImmediateOutputStream (output_stream); 2825a988416SJim Ingham result.SetImmediateErrorStream (error_stream); 2835a988416SJim Ingham 28426c7bf93SJim Ingham CommandInterpreterRunOptions options; 28526c7bf93SJim Ingham options.SetStopOnContinue(true); 28626c7bf93SJim Ingham options.SetStopOnError (data->stop_on_error); 28726c7bf93SJim Ingham options.SetEchoCommands (true); 28826c7bf93SJim Ingham options.SetPrintResults (true); 28926c7bf93SJim Ingham options.SetAddToHistory (false); 2905a988416SJim Ingham 2915a988416SJim Ingham debugger.GetCommandInterpreter().HandleCommands (commands, 2925a988416SJim Ingham &exe_ctx, 29326c7bf93SJim Ingham options, 2945a988416SJim Ingham result); 2955a988416SJim Ingham result.GetImmediateOutputStream()->Flush(); 2965a988416SJim Ingham result.GetImmediateErrorStream()->Flush(); 2975a988416SJim Ingham } 2985a988416SJim Ingham } 2995a988416SJim Ingham return ret_value; 3005a988416SJim Ingham } 3015a988416SJim Ingham 3025a988416SJim Ingham class CommandOptions : public Options 3035a988416SJim Ingham { 3045a988416SJim Ingham public: 3055a988416SJim Ingham 3065a988416SJim Ingham CommandOptions (CommandInterpreter &interpreter) : 3075a988416SJim Ingham Options (interpreter), 3085a988416SJim Ingham m_use_commands (false), 3095a988416SJim Ingham m_use_script_language (false), 3105a988416SJim Ingham m_script_language (eScriptLanguageNone), 3115a988416SJim Ingham m_use_one_liner (false), 3125a988416SJim Ingham m_one_liner(), 3135a988416SJim Ingham m_function_name() 31430fdc8d8SChris Lattner { 31530fdc8d8SChris Lattner } 31630fdc8d8SChris Lattner 317*13d21e9aSBruce Mitchener ~CommandOptions () override {} 3185a988416SJim Ingham 319*13d21e9aSBruce Mitchener Error 320*13d21e9aSBruce Mitchener SetOptionValue (uint32_t option_idx, const char *option_arg) override 3215a988416SJim Ingham { 3225a988416SJim Ingham Error error; 3233bcdfc0eSGreg Clayton const int short_option = m_getopt_table[option_idx].val; 3245a988416SJim Ingham 3255a988416SJim Ingham switch (short_option) 3265a988416SJim Ingham { 3275a988416SJim Ingham case 'o': 3285a988416SJim Ingham m_use_one_liner = true; 3295a988416SJim Ingham m_one_liner = option_arg; 3305a988416SJim Ingham break; 3315a988416SJim Ingham 3325a988416SJim Ingham case 's': 3335a988416SJim Ingham m_script_language = (lldb::ScriptLanguage) Args::StringToOptionEnum (option_arg, 3345a988416SJim Ingham g_option_table[option_idx].enum_values, 3355a988416SJim Ingham eScriptLanguageNone, 3365a988416SJim Ingham error); 3375a988416SJim Ingham 3385a988416SJim Ingham if (m_script_language == eScriptLanguagePython || m_script_language == eScriptLanguageDefault) 3395a988416SJim Ingham { 3405a988416SJim Ingham m_use_script_language = true; 3415a988416SJim Ingham } 3425a988416SJim Ingham else 3435a988416SJim Ingham { 3445a988416SJim Ingham m_use_script_language = false; 3455a988416SJim Ingham } 3465a988416SJim Ingham break; 3475a988416SJim Ingham 3485a988416SJim Ingham case 'e': 3495a988416SJim Ingham { 3505a988416SJim Ingham bool success = false; 3515a988416SJim Ingham m_stop_on_error = Args::StringToBoolean(option_arg, false, &success); 3525a988416SJim Ingham if (!success) 3535a988416SJim Ingham error.SetErrorStringWithFormat("invalid value for stop-on-error: \"%s\"", option_arg); 3545a988416SJim Ingham } 3555a988416SJim Ingham break; 3565a988416SJim Ingham 3575a988416SJim Ingham case 'F': 3585a988416SJim Ingham { 3595a988416SJim Ingham m_use_one_liner = false; 3605a988416SJim Ingham m_use_script_language = true; 3615a988416SJim Ingham m_function_name.assign(option_arg); 3625a988416SJim Ingham } 3635a988416SJim Ingham break; 3645a988416SJim Ingham 36533df7cd3SJim Ingham case 'D': 36633df7cd3SJim Ingham m_use_dummy = true; 36733df7cd3SJim Ingham break; 36833df7cd3SJim Ingham 3695a988416SJim Ingham default: 3705a988416SJim Ingham break; 3715a988416SJim Ingham } 3725a988416SJim Ingham return error; 3735a988416SJim Ingham } 3745a988416SJim Ingham void 375*13d21e9aSBruce Mitchener OptionParsingStarting () override 3765a988416SJim Ingham { 3775a988416SJim Ingham m_use_commands = true; 3785a988416SJim Ingham m_use_script_language = false; 3795a988416SJim Ingham m_script_language = eScriptLanguageNone; 3805a988416SJim Ingham 3815a988416SJim Ingham m_use_one_liner = false; 3825a988416SJim Ingham m_stop_on_error = true; 3835a988416SJim Ingham m_one_liner.clear(); 3845a988416SJim Ingham m_function_name.clear(); 38533df7cd3SJim Ingham m_use_dummy = false; 3865a988416SJim Ingham } 3875a988416SJim Ingham 3885a988416SJim Ingham const OptionDefinition* 389*13d21e9aSBruce Mitchener GetDefinitions () override 3905a988416SJim Ingham { 3915a988416SJim Ingham return g_option_table; 3925a988416SJim Ingham } 3935a988416SJim Ingham 3945a988416SJim Ingham // Options table: Required for subclasses of Options. 3955a988416SJim Ingham 3965a988416SJim Ingham static OptionDefinition g_option_table[]; 3975a988416SJim Ingham 3985a988416SJim Ingham // Instance variables to hold the values for command options. 3995a988416SJim Ingham 4005a988416SJim Ingham bool m_use_commands; 4015a988416SJim Ingham bool m_use_script_language; 4025a988416SJim Ingham lldb::ScriptLanguage m_script_language; 4035a988416SJim Ingham 4045a988416SJim Ingham // Instance variables to hold the values for one_liner options. 4055a988416SJim Ingham bool m_use_one_liner; 4065a988416SJim Ingham std::string m_one_liner; 4075a988416SJim Ingham bool m_stop_on_error; 4085a988416SJim Ingham std::string m_function_name; 40933df7cd3SJim Ingham bool m_use_dummy; 4105a988416SJim Ingham }; 4115a988416SJim Ingham 4125a988416SJim Ingham protected: 413*13d21e9aSBruce Mitchener bool 414*13d21e9aSBruce Mitchener DoExecute (Args& command, CommandReturnObject &result) override 41530fdc8d8SChris Lattner { 41633df7cd3SJim Ingham Target *target = GetSelectedOrDummyTarget(m_options.m_use_dummy); 41730fdc8d8SChris Lattner 41830fdc8d8SChris Lattner if (target == NULL) 41930fdc8d8SChris Lattner { 42030fdc8d8SChris Lattner result.AppendError ("There is not a current executable; there are no breakpoints to which to add commands"); 42130fdc8d8SChris Lattner result.SetStatus (eReturnStatusFailed); 42230fdc8d8SChris Lattner return false; 42330fdc8d8SChris Lattner } 42430fdc8d8SChris Lattner 42530fdc8d8SChris Lattner const BreakpointList &breakpoints = target->GetBreakpointList(); 42630fdc8d8SChris Lattner size_t num_breakpoints = breakpoints.GetSize(); 42730fdc8d8SChris Lattner 42830fdc8d8SChris Lattner if (num_breakpoints == 0) 42930fdc8d8SChris Lattner { 43030fdc8d8SChris Lattner result.AppendError ("No breakpoints exist to have commands added"); 43130fdc8d8SChris Lattner result.SetStatus (eReturnStatusFailed); 43230fdc8d8SChris Lattner return false; 43330fdc8d8SChris Lattner } 43430fdc8d8SChris Lattner 4358d4a8010SEnrico Granata if (m_options.m_use_script_language == false && m_options.m_function_name.size()) 4368d4a8010SEnrico Granata { 4378d4a8010SEnrico Granata result.AppendError ("need to enable scripting to have a function run as a breakpoint command"); 4388d4a8010SEnrico Granata result.SetStatus (eReturnStatusFailed); 4398d4a8010SEnrico Granata return false; 4408d4a8010SEnrico Granata } 4418d4a8010SEnrico Granata 44230fdc8d8SChris Lattner BreakpointIDList valid_bp_ids; 4435e09c8c3SJim Ingham CommandObjectMultiwordBreakpoint::VerifyBreakpointOrLocationIDs (command, target, result, &valid_bp_ids); 44430fdc8d8SChris Lattner 445b5796cb4SJim Ingham m_bp_options_vec.clear(); 446b5796cb4SJim Ingham 44730fdc8d8SChris Lattner if (result.Succeeded()) 44830fdc8d8SChris Lattner { 449c982c768SGreg Clayton const size_t count = valid_bp_ids.GetSize(); 450d9916eaeSJim Ingham 451c982c768SGreg Clayton for (size_t i = 0; i < count; ++i) 45230fdc8d8SChris Lattner { 45330fdc8d8SChris Lattner BreakpointID cur_bp_id = valid_bp_ids.GetBreakpointIDAtIndex (i); 45430fdc8d8SChris Lattner if (cur_bp_id.GetBreakpointID() != LLDB_INVALID_BREAK_ID) 45530fdc8d8SChris Lattner { 45630fdc8d8SChris Lattner Breakpoint *bp = target->GetBreakpointByID (cur_bp_id.GetBreakpointID()).get(); 45739d7d4f0SJohnny Chen BreakpointOptions *bp_options = NULL; 45839d7d4f0SJohnny Chen if (cur_bp_id.GetLocationID() == LLDB_INVALID_BREAK_ID) 45939d7d4f0SJohnny Chen { 46039d7d4f0SJohnny Chen // This breakpoint does not have an associated location. 46139d7d4f0SJohnny Chen bp_options = bp->GetOptions(); 46239d7d4f0SJohnny Chen } 46339d7d4f0SJohnny Chen else 46430fdc8d8SChris Lattner { 46530fdc8d8SChris Lattner BreakpointLocationSP bp_loc_sp(bp->FindLocationByID (cur_bp_id.GetLocationID())); 46639d7d4f0SJohnny Chen // This breakpoint does have an associated location. 46739d7d4f0SJohnny Chen // Get its breakpoint options. 46830fdc8d8SChris Lattner if (bp_loc_sp) 46939d7d4f0SJohnny Chen bp_options = bp_loc_sp->GetLocationOptions(); 47039d7d4f0SJohnny Chen } 471b5796cb4SJim Ingham if (bp_options) 472b5796cb4SJim Ingham m_bp_options_vec.push_back (bp_options); 473b5796cb4SJim Ingham } 474b5796cb4SJim Ingham } 47539d7d4f0SJohnny Chen 47639d7d4f0SJohnny Chen // If we are using script language, get the script interpreter 47739d7d4f0SJohnny Chen // in order to set or collect command callback. Otherwise, call 47839d7d4f0SJohnny Chen // the methods associated with this object. 47930fdc8d8SChris Lattner if (m_options.m_use_script_language) 48030fdc8d8SChris Lattner { 481b5796cb4SJim Ingham ScriptInterpreter *script_interp = m_interpreter.GetScriptInterpreter(); 48239d7d4f0SJohnny Chen // Special handling for one-liner specified inline. 48339d7d4f0SJohnny Chen if (m_options.m_use_one_liner) 4848d4a8010SEnrico Granata { 485b5796cb4SJim Ingham script_interp->SetBreakpointCommandCallback (m_bp_options_vec, 48639d7d4f0SJohnny Chen m_options.m_one_liner.c_str()); 4878d4a8010SEnrico Granata } 4888d4a8010SEnrico Granata else if (m_options.m_function_name.size()) 4898d4a8010SEnrico Granata { 490b5796cb4SJim Ingham script_interp->SetBreakpointCommandCallbackFunction (m_bp_options_vec, 491d80102e4SJim Ingham m_options.m_function_name.c_str()); 4928d4a8010SEnrico Granata } 49394de55d5SJohnny Chen else 4948d4a8010SEnrico Granata { 495b5796cb4SJim Ingham script_interp->CollectDataForBreakpointCommandCallback (m_bp_options_vec, 49630fdc8d8SChris Lattner result); 49730fdc8d8SChris Lattner } 4988d4a8010SEnrico Granata } 49930fdc8d8SChris Lattner else 50030fdc8d8SChris Lattner { 50139d7d4f0SJohnny Chen // Special handling for one-liner specified inline. 50239d7d4f0SJohnny Chen if (m_options.m_use_one_liner) 503b5796cb4SJim Ingham SetBreakpointCommandCallback (m_bp_options_vec, 50439d7d4f0SJohnny Chen m_options.m_one_liner.c_str()); 50539d7d4f0SJohnny Chen else 506b5796cb4SJim Ingham CollectDataForBreakpointCommandCallback (m_bp_options_vec, 507b132097bSGreg Clayton result); 50830fdc8d8SChris Lattner } 509b5796cb4SJim Ingham 51030fdc8d8SChris Lattner } 51130fdc8d8SChris Lattner 51230fdc8d8SChris Lattner return result.Succeeded(); 51330fdc8d8SChris Lattner } 51430fdc8d8SChris Lattner 5155a988416SJim Ingham private: 5165a988416SJim Ingham CommandOptions m_options; 517b5796cb4SJim Ingham std::vector<BreakpointOptions *> m_bp_options_vec; // This stores the breakpoint options that we are currently 518b5796cb4SJim Ingham // collecting commands for. In the CollectData... calls we need 519b5796cb4SJim Ingham // to hand this off to the IOHandler, which may run asynchronously. 520b5796cb4SJim Ingham // So we have to have some way to keep it alive, and not leak it. 521b5796cb4SJim Ingham // Making it an ivar of the command object, which never goes away 522b5796cb4SJim Ingham // achieves this. Note that if we were able to run 523b5796cb4SJim Ingham // the same command concurrently in one interpreter we'd have to 524b5796cb4SJim Ingham // make this "per invocation". But there are many more reasons 525b5796cb4SJim Ingham // why it is not in general safe to do that in lldb at present, 526b5796cb4SJim Ingham // so it isn't worthwhile to come up with a more complex mechanism 527b5796cb4SJim Ingham // to address this particular weakness right now. 5285a988416SJim Ingham static const char *g_reader_instructions; 5295a988416SJim Ingham 5305a988416SJim Ingham }; 5315a988416SJim Ingham 5325a988416SJim Ingham const char * 53344d93782SGreg Clayton CommandObjectBreakpointCommandAdd::g_reader_instructions = "Enter your debugger command(s). Type 'DONE' to end.\n"; 5345a988416SJim Ingham 5355a988416SJim Ingham // FIXME: "script-type" needs to have its contents determined dynamically, so somebody can add a new scripting 5365a988416SJim Ingham // language to lldb and have it pickable here without having to change this enumeration by hand and rebuild lldb proper. 5375a988416SJim Ingham 5385a988416SJim Ingham static OptionEnumValueElement 5395a988416SJim Ingham g_script_option_enumeration[4] = 54030fdc8d8SChris Lattner { 5415a988416SJim Ingham { eScriptLanguageNone, "command", "Commands are in the lldb command interpreter language"}, 5425a988416SJim Ingham { eScriptLanguagePython, "python", "Commands are in the Python language."}, 5435a988416SJim Ingham { eSortOrderByName, "default-script", "Commands are in the default scripting language."}, 5445a988416SJim Ingham { 0, NULL, NULL } 5455a988416SJim Ingham }; 54630fdc8d8SChris Lattner 5475a988416SJim Ingham OptionDefinition 5485a988416SJim Ingham CommandObjectBreakpointCommandAdd::CommandOptions::g_option_table[] = 54930fdc8d8SChris Lattner { 550d37221dcSZachary Turner { LLDB_OPT_SET_1, false, "one-liner", 'o', OptionParser::eRequiredArgument, NULL, NULL, 0, eArgTypeOneLiner, 5515a988416SJim Ingham "Specify a one-line breakpoint command inline. Be sure to surround it with quotes." }, 55230fdc8d8SChris Lattner 553d37221dcSZachary Turner { LLDB_OPT_SET_ALL, false, "stop-on-error", 'e', OptionParser::eRequiredArgument, NULL, NULL, 0, eArgTypeBoolean, 5545a988416SJim Ingham "Specify whether breakpoint command execution should terminate on error." }, 55530fdc8d8SChris Lattner 556d37221dcSZachary Turner { LLDB_OPT_SET_ALL, false, "script-type", 's', OptionParser::eRequiredArgument, NULL, g_script_option_enumeration, 0, eArgTypeNone, 5575a988416SJim Ingham "Specify the language for the commands - if none is specified, the lldb command interpreter will be used."}, 55830fdc8d8SChris Lattner 559d37221dcSZachary Turner { LLDB_OPT_SET_2, false, "python-function", 'F', OptionParser::eRequiredArgument, NULL, NULL, 0, eArgTypePythonFunction, 5605a988416SJim Ingham "Give the name of a Python function to run as command for this breakpoint. Be sure to give a module name if appropriate."}, 56139d7d4f0SJohnny Chen 56233df7cd3SJim Ingham { LLDB_OPT_SET_ALL, false, "dummy-breakpoints", 'D', OptionParser::eNoArgument, NULL, NULL, 0, eArgTypeNone, 56333df7cd3SJim Ingham "Sets Dummy breakpoints - i.e. breakpoints set before a file is provided, which prime new targets."}, 56433df7cd3SJim Ingham 565d37221dcSZachary Turner { 0, false, NULL, 0, 0, NULL, NULL, 0, eArgTypeNone, NULL } 5665a988416SJim Ingham }; 56730fdc8d8SChris Lattner 56830fdc8d8SChris Lattner //------------------------------------------------------------------------- 56993e0f19fSCaroline Tice // CommandObjectBreakpointCommandDelete 57030fdc8d8SChris Lattner //------------------------------------------------------------------------- 57130fdc8d8SChris Lattner 5725a988416SJim Ingham class CommandObjectBreakpointCommandDelete : public CommandObjectParsed 5735a988416SJim Ingham { 5745a988416SJim Ingham public: 5755a988416SJim Ingham CommandObjectBreakpointCommandDelete (CommandInterpreter &interpreter) : 5765a988416SJim Ingham CommandObjectParsed (interpreter, 57793e0f19fSCaroline Tice "delete", 57893e0f19fSCaroline Tice "Delete the set of commands from a breakpoint.", 57933df7cd3SJim Ingham NULL), 58033df7cd3SJim Ingham m_options (interpreter) 58130fdc8d8SChris Lattner { 582405fe67fSCaroline Tice CommandArgumentEntry arg; 583405fe67fSCaroline Tice CommandArgumentData bp_id_arg; 584405fe67fSCaroline Tice 585405fe67fSCaroline Tice // Define the first (and only) variant of this arg. 586405fe67fSCaroline Tice bp_id_arg.arg_type = eArgTypeBreakpointID; 587405fe67fSCaroline Tice bp_id_arg.arg_repetition = eArgRepeatPlain; 588405fe67fSCaroline Tice 589405fe67fSCaroline Tice // There is only one variant this argument could be; put it into the argument entry. 590405fe67fSCaroline Tice arg.push_back (bp_id_arg); 591405fe67fSCaroline Tice 592405fe67fSCaroline Tice // Push the data for the first argument into the m_arguments vector. 593405fe67fSCaroline Tice m_arguments.push_back (arg); 59430fdc8d8SChris Lattner } 59530fdc8d8SChris Lattner 59630fdc8d8SChris Lattner 597*13d21e9aSBruce Mitchener ~CommandObjectBreakpointCommandDelete () override {} 5985a988416SJim Ingham 599*13d21e9aSBruce Mitchener Options * 600*13d21e9aSBruce Mitchener GetOptions () override 60133df7cd3SJim Ingham { 60233df7cd3SJim Ingham return &m_options; 60333df7cd3SJim Ingham } 60433df7cd3SJim Ingham 60533df7cd3SJim Ingham class CommandOptions : public Options 60633df7cd3SJim Ingham { 60733df7cd3SJim Ingham public: 60833df7cd3SJim Ingham 60933df7cd3SJim Ingham CommandOptions (CommandInterpreter &interpreter) : 61033df7cd3SJim Ingham Options (interpreter), 61133df7cd3SJim Ingham m_use_dummy (false) 61233df7cd3SJim Ingham { 61333df7cd3SJim Ingham } 61433df7cd3SJim Ingham 615*13d21e9aSBruce Mitchener ~CommandOptions () override {} 61633df7cd3SJim Ingham 617*13d21e9aSBruce Mitchener Error 618*13d21e9aSBruce Mitchener SetOptionValue (uint32_t option_idx, const char *option_arg) override 61933df7cd3SJim Ingham { 62033df7cd3SJim Ingham Error error; 62133df7cd3SJim Ingham const int short_option = m_getopt_table[option_idx].val; 62233df7cd3SJim Ingham 62333df7cd3SJim Ingham switch (short_option) 62433df7cd3SJim Ingham { 62533df7cd3SJim Ingham case 'D': 62633df7cd3SJim Ingham m_use_dummy = true; 62733df7cd3SJim Ingham break; 62833df7cd3SJim Ingham 62933df7cd3SJim Ingham default: 63033df7cd3SJim Ingham error.SetErrorStringWithFormat ("unrecognized option '%c'", short_option); 63133df7cd3SJim Ingham break; 63233df7cd3SJim Ingham } 63333df7cd3SJim Ingham 63433df7cd3SJim Ingham return error; 63533df7cd3SJim Ingham } 63633df7cd3SJim Ingham 63733df7cd3SJim Ingham void 638*13d21e9aSBruce Mitchener OptionParsingStarting () override 63933df7cd3SJim Ingham { 64033df7cd3SJim Ingham m_use_dummy = false; 64133df7cd3SJim Ingham } 64233df7cd3SJim Ingham 64333df7cd3SJim Ingham const OptionDefinition* 644*13d21e9aSBruce Mitchener GetDefinitions () override 64533df7cd3SJim Ingham { 64633df7cd3SJim Ingham return g_option_table; 64733df7cd3SJim Ingham } 64833df7cd3SJim Ingham 64933df7cd3SJim Ingham // Options table: Required for subclasses of Options. 65033df7cd3SJim Ingham 65133df7cd3SJim Ingham static OptionDefinition g_option_table[]; 65233df7cd3SJim Ingham 65333df7cd3SJim Ingham // Instance variables to hold the values for command options. 65433df7cd3SJim Ingham bool m_use_dummy; 65533df7cd3SJim Ingham }; 65633df7cd3SJim Ingham 6575a988416SJim Ingham protected: 658*13d21e9aSBruce Mitchener bool 659*13d21e9aSBruce Mitchener DoExecute (Args& command, CommandReturnObject &result) override 66030fdc8d8SChris Lattner { 66133df7cd3SJim Ingham Target *target = GetSelectedOrDummyTarget(m_options.m_use_dummy); 66230fdc8d8SChris Lattner 66330fdc8d8SChris Lattner if (target == NULL) 66430fdc8d8SChris Lattner { 66593e0f19fSCaroline Tice result.AppendError ("There is not a current executable; there are no breakpoints from which to delete commands"); 66630fdc8d8SChris Lattner result.SetStatus (eReturnStatusFailed); 66730fdc8d8SChris Lattner return false; 66830fdc8d8SChris Lattner } 66930fdc8d8SChris Lattner 67030fdc8d8SChris Lattner const BreakpointList &breakpoints = target->GetBreakpointList(); 67130fdc8d8SChris Lattner size_t num_breakpoints = breakpoints.GetSize(); 67230fdc8d8SChris Lattner 67330fdc8d8SChris Lattner if (num_breakpoints == 0) 67430fdc8d8SChris Lattner { 67593e0f19fSCaroline Tice result.AppendError ("No breakpoints exist to have commands deleted"); 67630fdc8d8SChris Lattner result.SetStatus (eReturnStatusFailed); 67730fdc8d8SChris Lattner return false; 67830fdc8d8SChris Lattner } 67930fdc8d8SChris Lattner 68030fdc8d8SChris Lattner if (command.GetArgumentCount() == 0) 68130fdc8d8SChris Lattner { 68293e0f19fSCaroline Tice result.AppendError ("No breakpoint specified from which to delete the commands"); 68330fdc8d8SChris Lattner result.SetStatus (eReturnStatusFailed); 68430fdc8d8SChris Lattner return false; 68530fdc8d8SChris Lattner } 68630fdc8d8SChris Lattner 68730fdc8d8SChris Lattner BreakpointIDList valid_bp_ids; 6885e09c8c3SJim Ingham CommandObjectMultiwordBreakpoint::VerifyBreakpointOrLocationIDs (command, target, result, &valid_bp_ids); 68930fdc8d8SChris Lattner 69030fdc8d8SChris Lattner if (result.Succeeded()) 69130fdc8d8SChris Lattner { 692c982c768SGreg Clayton const size_t count = valid_bp_ids.GetSize(); 693c982c768SGreg Clayton for (size_t i = 0; i < count; ++i) 69430fdc8d8SChris Lattner { 69530fdc8d8SChris Lattner BreakpointID cur_bp_id = valid_bp_ids.GetBreakpointIDAtIndex (i); 69630fdc8d8SChris Lattner if (cur_bp_id.GetBreakpointID() != LLDB_INVALID_BREAK_ID) 69730fdc8d8SChris Lattner { 69830fdc8d8SChris Lattner Breakpoint *bp = target->GetBreakpointByID (cur_bp_id.GetBreakpointID()).get(); 69930fdc8d8SChris Lattner if (cur_bp_id.GetLocationID() != LLDB_INVALID_BREAK_ID) 70030fdc8d8SChris Lattner { 70130fdc8d8SChris Lattner BreakpointLocationSP bp_loc_sp (bp->FindLocationByID (cur_bp_id.GetLocationID())); 70230fdc8d8SChris Lattner if (bp_loc_sp) 70330fdc8d8SChris Lattner bp_loc_sp->ClearCallback(); 70430fdc8d8SChris Lattner else 70530fdc8d8SChris Lattner { 70630fdc8d8SChris Lattner result.AppendErrorWithFormat("Invalid breakpoint ID: %u.%u.\n", 70730fdc8d8SChris Lattner cur_bp_id.GetBreakpointID(), 70830fdc8d8SChris Lattner cur_bp_id.GetLocationID()); 70930fdc8d8SChris Lattner result.SetStatus (eReturnStatusFailed); 71030fdc8d8SChris Lattner return false; 71130fdc8d8SChris Lattner } 71230fdc8d8SChris Lattner } 71330fdc8d8SChris Lattner else 71430fdc8d8SChris Lattner { 71530fdc8d8SChris Lattner bp->ClearCallback(); 71630fdc8d8SChris Lattner } 71730fdc8d8SChris Lattner } 71830fdc8d8SChris Lattner } 71930fdc8d8SChris Lattner } 72030fdc8d8SChris Lattner return result.Succeeded(); 72130fdc8d8SChris Lattner } 72233df7cd3SJim Ingham private: 72333df7cd3SJim Ingham CommandOptions m_options; 7245a988416SJim Ingham }; 72530fdc8d8SChris Lattner 72633df7cd3SJim Ingham OptionDefinition 72733df7cd3SJim Ingham CommandObjectBreakpointCommandDelete::CommandOptions::g_option_table[] = 72833df7cd3SJim Ingham { 72933df7cd3SJim Ingham { LLDB_OPT_SET_1, false, "dummy-breakpoints", 'D', OptionParser::eNoArgument, NULL, NULL, 0, eArgTypeNone, 73033df7cd3SJim Ingham "Delete commands from Dummy breakpoints - i.e. breakpoints set before a file is provided, which prime new targets."}, 73133df7cd3SJim Ingham 73233df7cd3SJim Ingham { 0, false, NULL, 0, 0, NULL, NULL, 0, eArgTypeNone, NULL } 73333df7cd3SJim Ingham }; 73433df7cd3SJim Ingham 73533df7cd3SJim Ingham 73630fdc8d8SChris Lattner //------------------------------------------------------------------------- 73730fdc8d8SChris Lattner // CommandObjectBreakpointCommandList 73830fdc8d8SChris Lattner //------------------------------------------------------------------------- 73930fdc8d8SChris Lattner 7405a988416SJim Ingham class CommandObjectBreakpointCommandList : public CommandObjectParsed 7415a988416SJim Ingham { 7425a988416SJim Ingham public: 7435a988416SJim Ingham CommandObjectBreakpointCommandList (CommandInterpreter &interpreter) : 7445a988416SJim Ingham CommandObjectParsed (interpreter, 745a7015092SGreg Clayton "list", 74630fdc8d8SChris Lattner "List the script or set of commands to be executed when the breakpoint is hit.", 747405fe67fSCaroline Tice NULL) 74830fdc8d8SChris Lattner { 749405fe67fSCaroline Tice CommandArgumentEntry arg; 750405fe67fSCaroline Tice CommandArgumentData bp_id_arg; 751405fe67fSCaroline Tice 752405fe67fSCaroline Tice // Define the first (and only) variant of this arg. 753405fe67fSCaroline Tice bp_id_arg.arg_type = eArgTypeBreakpointID; 754405fe67fSCaroline Tice bp_id_arg.arg_repetition = eArgRepeatPlain; 755405fe67fSCaroline Tice 756405fe67fSCaroline Tice // There is only one variant this argument could be; put it into the argument entry. 757405fe67fSCaroline Tice arg.push_back (bp_id_arg); 758405fe67fSCaroline Tice 759405fe67fSCaroline Tice // Push the data for the first argument into the m_arguments vector. 760405fe67fSCaroline Tice m_arguments.push_back (arg); 76130fdc8d8SChris Lattner } 76230fdc8d8SChris Lattner 763*13d21e9aSBruce Mitchener ~CommandObjectBreakpointCommandList () override {} 76430fdc8d8SChris Lattner 7655a988416SJim Ingham protected: 766*13d21e9aSBruce Mitchener bool 7675a988416SJim Ingham DoExecute (Args& command, 768*13d21e9aSBruce Mitchener CommandReturnObject &result) override 76930fdc8d8SChris Lattner { 770a7015092SGreg Clayton Target *target = m_interpreter.GetDebugger().GetSelectedTarget().get(); 77130fdc8d8SChris Lattner 77230fdc8d8SChris Lattner if (target == NULL) 77330fdc8d8SChris Lattner { 77430fdc8d8SChris Lattner result.AppendError ("There is not a current executable; there are no breakpoints for which to list commands"); 77530fdc8d8SChris Lattner result.SetStatus (eReturnStatusFailed); 77630fdc8d8SChris Lattner return false; 77730fdc8d8SChris Lattner } 77830fdc8d8SChris Lattner 77930fdc8d8SChris Lattner const BreakpointList &breakpoints = target->GetBreakpointList(); 78030fdc8d8SChris Lattner size_t num_breakpoints = breakpoints.GetSize(); 78130fdc8d8SChris Lattner 78230fdc8d8SChris Lattner if (num_breakpoints == 0) 78330fdc8d8SChris Lattner { 78430fdc8d8SChris Lattner result.AppendError ("No breakpoints exist for which to list commands"); 78530fdc8d8SChris Lattner result.SetStatus (eReturnStatusFailed); 78630fdc8d8SChris Lattner return false; 78730fdc8d8SChris Lattner } 78830fdc8d8SChris Lattner 78930fdc8d8SChris Lattner if (command.GetArgumentCount() == 0) 79030fdc8d8SChris Lattner { 79130fdc8d8SChris Lattner result.AppendError ("No breakpoint specified for which to list the commands"); 79230fdc8d8SChris Lattner result.SetStatus (eReturnStatusFailed); 79330fdc8d8SChris Lattner return false; 79430fdc8d8SChris Lattner } 79530fdc8d8SChris Lattner 79630fdc8d8SChris Lattner BreakpointIDList valid_bp_ids; 7975e09c8c3SJim Ingham CommandObjectMultiwordBreakpoint::VerifyBreakpointOrLocationIDs (command, target, result, &valid_bp_ids); 79830fdc8d8SChris Lattner 79930fdc8d8SChris Lattner if (result.Succeeded()) 80030fdc8d8SChris Lattner { 801c982c768SGreg Clayton const size_t count = valid_bp_ids.GetSize(); 802c982c768SGreg Clayton for (size_t i = 0; i < count; ++i) 80330fdc8d8SChris Lattner { 80430fdc8d8SChris Lattner BreakpointID cur_bp_id = valid_bp_ids.GetBreakpointIDAtIndex (i); 80530fdc8d8SChris Lattner if (cur_bp_id.GetBreakpointID() != LLDB_INVALID_BREAK_ID) 80630fdc8d8SChris Lattner { 80730fdc8d8SChris Lattner Breakpoint *bp = target->GetBreakpointByID (cur_bp_id.GetBreakpointID()).get(); 80830fdc8d8SChris Lattner 80930fdc8d8SChris Lattner if (bp) 81030fdc8d8SChris Lattner { 8111b54c88cSJim Ingham const BreakpointOptions *bp_options = NULL; 81230fdc8d8SChris Lattner if (cur_bp_id.GetLocationID() != LLDB_INVALID_BREAK_ID) 81330fdc8d8SChris Lattner { 81430fdc8d8SChris Lattner BreakpointLocationSP bp_loc_sp(bp->FindLocationByID (cur_bp_id.GetLocationID())); 81530fdc8d8SChris Lattner if (bp_loc_sp) 81605407f6bSJim Ingham bp_options = bp_loc_sp->GetOptionsNoCreate(); 81730fdc8d8SChris Lattner else 81830fdc8d8SChris Lattner { 81930fdc8d8SChris Lattner result.AppendErrorWithFormat("Invalid breakpoint ID: %u.%u.\n", 82030fdc8d8SChris Lattner cur_bp_id.GetBreakpointID(), 82130fdc8d8SChris Lattner cur_bp_id.GetLocationID()); 82230fdc8d8SChris Lattner result.SetStatus (eReturnStatusFailed); 82330fdc8d8SChris Lattner return false; 82430fdc8d8SChris Lattner } 82530fdc8d8SChris Lattner } 82630fdc8d8SChris Lattner else 82730fdc8d8SChris Lattner { 82830fdc8d8SChris Lattner bp_options = bp->GetOptions(); 82930fdc8d8SChris Lattner } 83030fdc8d8SChris Lattner 83130fdc8d8SChris Lattner if (bp_options) 83230fdc8d8SChris Lattner { 83330fdc8d8SChris Lattner StreamString id_str; 834e16c50a1SJim Ingham BreakpointID::GetCanonicalReference (&id_str, 835e16c50a1SJim Ingham cur_bp_id.GetBreakpointID(), 836e16c50a1SJim Ingham cur_bp_id.GetLocationID()); 8371b54c88cSJim Ingham const Baton *baton = bp_options->GetBaton(); 83830fdc8d8SChris Lattner if (baton) 83930fdc8d8SChris Lattner { 84030fdc8d8SChris Lattner result.GetOutputStream().Printf ("Breakpoint %s:\n", id_str.GetData()); 84130fdc8d8SChris Lattner result.GetOutputStream().IndentMore (); 84230fdc8d8SChris Lattner baton->GetDescription(&result.GetOutputStream(), eDescriptionLevelFull); 84330fdc8d8SChris Lattner result.GetOutputStream().IndentLess (); 84430fdc8d8SChris Lattner } 84530fdc8d8SChris Lattner else 84630fdc8d8SChris Lattner { 847e16c50a1SJim Ingham result.AppendMessageWithFormat ("Breakpoint %s does not have an associated command.\n", 848e16c50a1SJim Ingham id_str.GetData()); 84930fdc8d8SChris Lattner } 85030fdc8d8SChris Lattner } 85130fdc8d8SChris Lattner result.SetStatus (eReturnStatusSuccessFinishResult); 85230fdc8d8SChris Lattner } 85330fdc8d8SChris Lattner else 85430fdc8d8SChris Lattner { 85530fdc8d8SChris Lattner result.AppendErrorWithFormat("Invalid breakpoint ID: %u.\n", cur_bp_id.GetBreakpointID()); 85630fdc8d8SChris Lattner result.SetStatus (eReturnStatusFailed); 85730fdc8d8SChris Lattner } 85830fdc8d8SChris Lattner 85930fdc8d8SChris Lattner } 86030fdc8d8SChris Lattner } 86130fdc8d8SChris Lattner } 86230fdc8d8SChris Lattner 86330fdc8d8SChris Lattner return result.Succeeded(); 86430fdc8d8SChris Lattner } 8655a988416SJim Ingham }; 86630fdc8d8SChris Lattner 86730fdc8d8SChris Lattner //------------------------------------------------------------------------- 86830fdc8d8SChris Lattner // CommandObjectBreakpointCommand 86930fdc8d8SChris Lattner //------------------------------------------------------------------------- 87030fdc8d8SChris Lattner 8716611103cSGreg Clayton CommandObjectBreakpointCommand::CommandObjectBreakpointCommand (CommandInterpreter &interpreter) : 872a7015092SGreg Clayton CommandObjectMultiword (interpreter, 873a7015092SGreg Clayton "command", 8747050e0b1SSean Callanan "A set of commands for adding, removing and examining bits of code to be executed when the breakpoint is hit (breakpoint 'commands').", 87530fdc8d8SChris Lattner "command <sub-command> [<sub-command-options>] <breakpoint-id>") 87630fdc8d8SChris Lattner { 877a7015092SGreg Clayton CommandObjectSP add_command_object (new CommandObjectBreakpointCommandAdd (interpreter)); 87893e0f19fSCaroline Tice CommandObjectSP delete_command_object (new CommandObjectBreakpointCommandDelete (interpreter)); 879a7015092SGreg Clayton CommandObjectSP list_command_object (new CommandObjectBreakpointCommandList (interpreter)); 88030fdc8d8SChris Lattner 88130fdc8d8SChris Lattner add_command_object->SetCommandName ("breakpoint command add"); 88293e0f19fSCaroline Tice delete_command_object->SetCommandName ("breakpoint command delete"); 88330fdc8d8SChris Lattner list_command_object->SetCommandName ("breakpoint command list"); 88430fdc8d8SChris Lattner 88523f59509SGreg Clayton LoadSubCommand ("add", add_command_object); 88623f59509SGreg Clayton LoadSubCommand ("delete", delete_command_object); 88723f59509SGreg Clayton LoadSubCommand ("list", list_command_object); 88830fdc8d8SChris Lattner } 88930fdc8d8SChris Lattner 89030fdc8d8SChris Lattner CommandObjectBreakpointCommand::~CommandObjectBreakpointCommand () 89130fdc8d8SChris Lattner { 89230fdc8d8SChris Lattner } 89330fdc8d8SChris Lattner 89430fdc8d8SChris Lattner 895