1*30fdc8d8SChris Lattner //===-- CommandObjectBreakpointCommand.cpp ----------------------*- C++ -*-===// 2*30fdc8d8SChris Lattner // 3*30fdc8d8SChris Lattner // The LLVM Compiler Infrastructure 4*30fdc8d8SChris Lattner // 5*30fdc8d8SChris Lattner // This file is distributed under the University of Illinois Open Source 6*30fdc8d8SChris Lattner // License. See LICENSE.TXT for details. 7*30fdc8d8SChris Lattner // 8*30fdc8d8SChris Lattner //===----------------------------------------------------------------------===// 9*30fdc8d8SChris Lattner 10*30fdc8d8SChris Lattner // C Includes 11*30fdc8d8SChris Lattner // C++ Includes 12*30fdc8d8SChris Lattner 13*30fdc8d8SChris Lattner 14*30fdc8d8SChris Lattner #include "CommandObjectBreakpointCommand.h" 15*30fdc8d8SChris Lattner #include "CommandObjectBreakpoint.h" 16*30fdc8d8SChris Lattner 17*30fdc8d8SChris Lattner #include "lldb/Interpreter/CommandInterpreter.h" 18*30fdc8d8SChris Lattner #include "lldb/Interpreter/CommandReturnObject.h" 19*30fdc8d8SChris Lattner #include "lldb/Target/Target.h" 20*30fdc8d8SChris Lattner #include "lldb/Target/Thread.h" 21*30fdc8d8SChris Lattner #include "lldb/Breakpoint/BreakpointIDList.h" 22*30fdc8d8SChris Lattner #include "lldb/Breakpoint/Breakpoint.h" 23*30fdc8d8SChris Lattner #include "lldb/Breakpoint/BreakpointLocation.h" 24*30fdc8d8SChris Lattner #include "lldb/Breakpoint/StoppointCallbackContext.h" 25*30fdc8d8SChris Lattner #include "lldb/Core/State.h" 26*30fdc8d8SChris Lattner 27*30fdc8d8SChris Lattner using namespace lldb; 28*30fdc8d8SChris Lattner using namespace lldb_private; 29*30fdc8d8SChris Lattner 30*30fdc8d8SChris Lattner //------------------------------------------------------------------------- 31*30fdc8d8SChris Lattner // CommandObjectBreakpointCommandAdd::CommandOptions 32*30fdc8d8SChris Lattner //------------------------------------------------------------------------- 33*30fdc8d8SChris Lattner 34*30fdc8d8SChris Lattner CommandObjectBreakpointCommandAdd::CommandOptions::CommandOptions () : 35*30fdc8d8SChris Lattner Options () 36*30fdc8d8SChris Lattner { 37*30fdc8d8SChris Lattner BuildValidOptionSets(); 38*30fdc8d8SChris Lattner } 39*30fdc8d8SChris Lattner 40*30fdc8d8SChris Lattner CommandObjectBreakpointCommandAdd::CommandOptions::~CommandOptions () 41*30fdc8d8SChris Lattner { 42*30fdc8d8SChris Lattner } 43*30fdc8d8SChris Lattner 44*30fdc8d8SChris Lattner lldb::OptionDefinition 45*30fdc8d8SChris Lattner CommandObjectBreakpointCommandAdd::CommandOptions::g_option_table[] = 46*30fdc8d8SChris Lattner { 47*30fdc8d8SChris Lattner { 0, true, "script", 's', no_argument, NULL, 0, NULL, 48*30fdc8d8SChris Lattner "Write the breakpoint command script in the default scripting language."}, 49*30fdc8d8SChris Lattner 50*30fdc8d8SChris Lattner { 1, true, "python", 'p', no_argument, NULL, 0, NULL, 51*30fdc8d8SChris Lattner "Write the breakpoint command script in the Python scripting language."}, 52*30fdc8d8SChris Lattner 53*30fdc8d8SChris Lattner { 2, true, "commands", 'c', no_argument, NULL, 0, NULL, 54*30fdc8d8SChris Lattner "Write the breakpoint command script using the command line commands."}, 55*30fdc8d8SChris Lattner 56*30fdc8d8SChris Lattner { 0, false, NULL, 0, 0, NULL, 0, NULL, NULL } 57*30fdc8d8SChris Lattner }; 58*30fdc8d8SChris Lattner 59*30fdc8d8SChris Lattner const lldb::OptionDefinition* 60*30fdc8d8SChris Lattner CommandObjectBreakpointCommandAdd::CommandOptions::GetDefinitions () 61*30fdc8d8SChris Lattner { 62*30fdc8d8SChris Lattner return g_option_table; 63*30fdc8d8SChris Lattner } 64*30fdc8d8SChris Lattner 65*30fdc8d8SChris Lattner 66*30fdc8d8SChris Lattner Error 67*30fdc8d8SChris Lattner CommandObjectBreakpointCommandAdd::CommandOptions::SetOptionValue 68*30fdc8d8SChris Lattner ( 69*30fdc8d8SChris Lattner int option_idx, 70*30fdc8d8SChris Lattner const char *option_arg 71*30fdc8d8SChris Lattner ) 72*30fdc8d8SChris Lattner { 73*30fdc8d8SChris Lattner Error error; 74*30fdc8d8SChris Lattner char short_option = (char) m_getopt_table[option_idx].val; 75*30fdc8d8SChris Lattner 76*30fdc8d8SChris Lattner switch (short_option) 77*30fdc8d8SChris Lattner { 78*30fdc8d8SChris Lattner case 's': 79*30fdc8d8SChris Lattner m_use_commands = false; 80*30fdc8d8SChris Lattner m_use_script_language = true; 81*30fdc8d8SChris Lattner m_script_language = eScriptLanguageDefault; 82*30fdc8d8SChris Lattner break; 83*30fdc8d8SChris Lattner case 'p': 84*30fdc8d8SChris Lattner m_use_commands = false; 85*30fdc8d8SChris Lattner m_use_script_language = true; 86*30fdc8d8SChris Lattner m_script_language = eScriptLanguagePython; 87*30fdc8d8SChris Lattner break; 88*30fdc8d8SChris Lattner case 'c': 89*30fdc8d8SChris Lattner m_use_commands = true; 90*30fdc8d8SChris Lattner m_use_script_language = false; 91*30fdc8d8SChris Lattner m_script_language = eScriptLanguageNone; 92*30fdc8d8SChris Lattner break; 93*30fdc8d8SChris Lattner default: 94*30fdc8d8SChris Lattner break; 95*30fdc8d8SChris Lattner } 96*30fdc8d8SChris Lattner return error; 97*30fdc8d8SChris Lattner } 98*30fdc8d8SChris Lattner 99*30fdc8d8SChris Lattner void 100*30fdc8d8SChris Lattner CommandObjectBreakpointCommandAdd::CommandOptions::ResetOptionValues () 101*30fdc8d8SChris Lattner { 102*30fdc8d8SChris Lattner Options::ResetOptionValues(); 103*30fdc8d8SChris Lattner 104*30fdc8d8SChris Lattner m_use_commands = false; 105*30fdc8d8SChris Lattner m_use_script_language = false; 106*30fdc8d8SChris Lattner m_script_language = eScriptLanguageNone; 107*30fdc8d8SChris Lattner } 108*30fdc8d8SChris Lattner 109*30fdc8d8SChris Lattner //------------------------------------------------------------------------- 110*30fdc8d8SChris Lattner // CommandObjectBreakpointCommandAdd 111*30fdc8d8SChris Lattner //------------------------------------------------------------------------- 112*30fdc8d8SChris Lattner 113*30fdc8d8SChris Lattner 114*30fdc8d8SChris Lattner CommandObjectBreakpointCommandAdd::CommandObjectBreakpointCommandAdd () : 115*30fdc8d8SChris Lattner CommandObject ("add", 116*30fdc8d8SChris Lattner "Adds a set of commands to a breakpoint to be executed whenever a breakpoint is hit.", 117*30fdc8d8SChris Lattner "breakpoint command add <cmd-options> <breakpoint-id>") 118*30fdc8d8SChris Lattner { 119*30fdc8d8SChris Lattner SetHelpLong ( 120*30fdc8d8SChris Lattner "\nGeneral information about entering breakpoint commands \n\ 121*30fdc8d8SChris Lattner ------------------------------------------------------ \n\ 122*30fdc8d8SChris Lattner \n\ 123*30fdc8d8SChris Lattner This command will cause you to be prompted to enter the command or set \n\ 124*30fdc8d8SChris Lattner of commands you wish to be executed when the specified breakpoint is \n\ 125*30fdc8d8SChris Lattner hit. You will be told to enter your command(s), and will see a '> ' \n\ 126*30fdc8d8SChris Lattner prompt. Because you can enter one or many commands to be executed when \n\ 127*30fdc8d8SChris Lattner a breakpoint is hit, you will continue to be prompted after each \n\ 128*30fdc8d8SChris Lattner new-line that you enter, until you enter the word 'DONE', which will \n\ 129*30fdc8d8SChris Lattner cause the commands you have entered to be stored with the breakpoint \n\ 130*30fdc8d8SChris Lattner and executed when the breakpoint is hit. \n\ 131*30fdc8d8SChris Lattner \n\ 132*30fdc8d8SChris Lattner Syntax checking is not necessarily done when breakpoint commands are \n\ 133*30fdc8d8SChris Lattner entered. An improperly written breakpoint command will attempt to get \n\ 134*30fdc8d8SChris Lattner executed when the breakpoint gets hit, and usually silently fail. If \n\ 135*30fdc8d8SChris Lattner your breakpoint command does not appear to be getting executed, go \n\ 136*30fdc8d8SChris Lattner back and check your syntax. \n\ 137*30fdc8d8SChris Lattner \n\ 138*30fdc8d8SChris Lattner \n\ 139*30fdc8d8SChris Lattner Special information about PYTHON breakpoint commands \n\ 140*30fdc8d8SChris Lattner ---------------------------------------------------- \n\ 141*30fdc8d8SChris Lattner \n\ 142*30fdc8d8SChris Lattner You may enter either one line of Python or multiple lines of Python \n\ 143*30fdc8d8SChris Lattner (including defining whole functions, if desired). If you enter a \n\ 144*30fdc8d8SChris Lattner single line of Python, that will be passed to the Python interpreter \n\ 145*30fdc8d8SChris Lattner 'as is' when the breakpoint gets hit. If you enter function \n\ 146*30fdc8d8SChris Lattner definitions, they will be passed to the Python interpreter as soon as \n\ 147*30fdc8d8SChris Lattner you finish entering the breakpoint command, and they can be called \n\ 148*30fdc8d8SChris Lattner later (don't forget to add calls to them, if you want them called when \n\ 149*30fdc8d8SChris Lattner the breakpoint is hit). If you enter multiple lines of Python that \n\ 150*30fdc8d8SChris Lattner are not function definitions, they will be collected into a new, \n\ 151*30fdc8d8SChris Lattner automatically generated Python function, and a call to the newly \n\ 152*30fdc8d8SChris Lattner generated function will be attached to the breakpoint. Important \n\ 153*30fdc8d8SChris Lattner Note: Because loose Python code gets collected into functions, if you \n\ 154*30fdc8d8SChris Lattner want to access global variables in the 'loose' code, you need to \n\ 155*30fdc8d8SChris Lattner specify that they are global, using the 'global' keyword. Be sure to \n\ 156*30fdc8d8SChris Lattner use correct Python syntax, including indentation, when entering Python \n\ 157*30fdc8d8SChris Lattner breakpoint commands. \n\ 158*30fdc8d8SChris Lattner \n\ 159*30fdc8d8SChris Lattner Example Python one-line breakpoint command: \n\ 160*30fdc8d8SChris Lattner \n\ 161*30fdc8d8SChris Lattner (lldb) breakpoint command add -p 1 \n\ 162*30fdc8d8SChris Lattner Enter your Python command(s). Type 'DONE' to end. \n\ 163*30fdc8d8SChris Lattner > print \"Hit this breakpoint!\" \n\ 164*30fdc8d8SChris Lattner > DONE \n\ 165*30fdc8d8SChris Lattner \n\ 166*30fdc8d8SChris Lattner Example multiple line Python breakpoint command, using function definition: \n\ 167*30fdc8d8SChris Lattner \n\ 168*30fdc8d8SChris Lattner (lldb) breakpoint command add -p 1 \n\ 169*30fdc8d8SChris Lattner Enter your Python command(s). Type 'DONE' to end. \n\ 170*30fdc8d8SChris Lattner > def breakpoint_output (bp_no): \n\ 171*30fdc8d8SChris Lattner > out_string = \"Hit breakpoint number \" + repr (bp_no) \n\ 172*30fdc8d8SChris Lattner > print out_string \n\ 173*30fdc8d8SChris Lattner > return True \n\ 174*30fdc8d8SChris Lattner > breakpoint_output (1) \n\ 175*30fdc8d8SChris Lattner > DONE \n\ 176*30fdc8d8SChris Lattner \n\ 177*30fdc8d8SChris Lattner \n\ 178*30fdc8d8SChris Lattner Example multiple line Python breakpoint command, using 'loose' Python: \n\ 179*30fdc8d8SChris Lattner \n\ 180*30fdc8d8SChris Lattner (lldb) breakpoint command add -p 1 \n\ 181*30fdc8d8SChris Lattner Enter your Python command(s). Type 'DONE' to end. \n\ 182*30fdc8d8SChris Lattner > global bp_count \n\ 183*30fdc8d8SChris Lattner > bp_count = bp_count + 1 \n\ 184*30fdc8d8SChris Lattner > print \"Hit this breakpoint \" + repr(bp_count) + \" times!\" \n\ 185*30fdc8d8SChris Lattner > DONE \n\ 186*30fdc8d8SChris Lattner \n\ 187*30fdc8d8SChris Lattner In this case, since there is a reference to a global variable, \n\ 188*30fdc8d8SChris Lattner 'bp_count', you will also need to make sure 'bp_count' exists and is \n\ 189*30fdc8d8SChris Lattner initialized: \n\ 190*30fdc8d8SChris Lattner \n\ 191*30fdc8d8SChris Lattner (lldb) script \n\ 192*30fdc8d8SChris Lattner >>> bp_count = 0 \n\ 193*30fdc8d8SChris Lattner >>> quit() \n\ 194*30fdc8d8SChris Lattner \n\ 195*30fdc8d8SChris Lattner (lldb) \n\ 196*30fdc8d8SChris Lattner \n\ 197*30fdc8d8SChris Lattner Special information debugger command breakpoint commands \n\ 198*30fdc8d8SChris Lattner --------------------------------------------------------- \n\ 199*30fdc8d8SChris Lattner \n\ 200*30fdc8d8SChris Lattner You may enter any debugger command, exactly as you would at the \n\ 201*30fdc8d8SChris Lattner debugger prompt. You may enter as many debugger commands as you like, \n\ 202*30fdc8d8SChris Lattner but do NOT enter more than one command per line. \n" ); 203*30fdc8d8SChris Lattner } 204*30fdc8d8SChris Lattner 205*30fdc8d8SChris Lattner CommandObjectBreakpointCommandAdd::~CommandObjectBreakpointCommandAdd () 206*30fdc8d8SChris Lattner { 207*30fdc8d8SChris Lattner } 208*30fdc8d8SChris Lattner 209*30fdc8d8SChris Lattner bool 210*30fdc8d8SChris Lattner CommandObjectBreakpointCommandAdd::Execute 211*30fdc8d8SChris Lattner ( 212*30fdc8d8SChris Lattner Args& command, 213*30fdc8d8SChris Lattner CommandContext *context, 214*30fdc8d8SChris Lattner CommandInterpreter *interpreter, 215*30fdc8d8SChris Lattner CommandReturnObject &result 216*30fdc8d8SChris Lattner ) 217*30fdc8d8SChris Lattner { 218*30fdc8d8SChris Lattner Target *target = context->GetTarget(); 219*30fdc8d8SChris Lattner 220*30fdc8d8SChris Lattner if (target == NULL) 221*30fdc8d8SChris Lattner { 222*30fdc8d8SChris Lattner result.AppendError ("There is not a current executable; there are no breakpoints to which to add commands"); 223*30fdc8d8SChris Lattner result.SetStatus (eReturnStatusFailed); 224*30fdc8d8SChris Lattner return false; 225*30fdc8d8SChris Lattner } 226*30fdc8d8SChris Lattner 227*30fdc8d8SChris Lattner const BreakpointList &breakpoints = target->GetBreakpointList(); 228*30fdc8d8SChris Lattner size_t num_breakpoints = breakpoints.GetSize(); 229*30fdc8d8SChris Lattner 230*30fdc8d8SChris Lattner if (num_breakpoints == 0) 231*30fdc8d8SChris Lattner { 232*30fdc8d8SChris Lattner result.AppendError ("No breakpoints exist to have commands added"); 233*30fdc8d8SChris Lattner result.SetStatus (eReturnStatusFailed); 234*30fdc8d8SChris Lattner return false; 235*30fdc8d8SChris Lattner } 236*30fdc8d8SChris Lattner 237*30fdc8d8SChris Lattner if (command.GetArgumentCount() == 0) 238*30fdc8d8SChris Lattner { 239*30fdc8d8SChris Lattner result.AppendError ("No breakpoint specified to which to add the commands"); 240*30fdc8d8SChris Lattner result.SetStatus (eReturnStatusFailed); 241*30fdc8d8SChris Lattner return false; 242*30fdc8d8SChris Lattner } 243*30fdc8d8SChris Lattner 244*30fdc8d8SChris Lattner BreakpointIDList valid_bp_ids; 245*30fdc8d8SChris Lattner CommandObjectMultiwordBreakpoint::VerifyBreakpointIDs (command, target, result, &valid_bp_ids); 246*30fdc8d8SChris Lattner 247*30fdc8d8SChris Lattner if (result.Succeeded()) 248*30fdc8d8SChris Lattner { 249*30fdc8d8SChris Lattner for (int i = 0; i < valid_bp_ids.Size(); ++i) 250*30fdc8d8SChris Lattner { 251*30fdc8d8SChris Lattner BreakpointID cur_bp_id = valid_bp_ids.GetBreakpointIDAtIndex (i); 252*30fdc8d8SChris Lattner if (cur_bp_id.GetBreakpointID() != LLDB_INVALID_BREAK_ID) 253*30fdc8d8SChris Lattner { 254*30fdc8d8SChris Lattner Breakpoint *bp = target->GetBreakpointByID (cur_bp_id.GetBreakpointID()).get(); 255*30fdc8d8SChris Lattner if (cur_bp_id.GetLocationID() != LLDB_INVALID_BREAK_ID) 256*30fdc8d8SChris Lattner { 257*30fdc8d8SChris Lattner BreakpointLocationSP bp_loc_sp(bp->FindLocationByID (cur_bp_id.GetLocationID())); 258*30fdc8d8SChris Lattner if (bp_loc_sp) 259*30fdc8d8SChris Lattner { 260*30fdc8d8SChris Lattner if (m_options.m_use_script_language) 261*30fdc8d8SChris Lattner { 262*30fdc8d8SChris Lattner interpreter->GetScriptInterpreter()->CollectDataForBreakpointCommandCallback (bp_loc_sp->GetLocationOptions(), 263*30fdc8d8SChris Lattner result); 264*30fdc8d8SChris Lattner } 265*30fdc8d8SChris Lattner else 266*30fdc8d8SChris Lattner { 267*30fdc8d8SChris Lattner CollectDataForBreakpointCommandCallback (bp_loc_sp->GetLocationOptions(), result); 268*30fdc8d8SChris Lattner } 269*30fdc8d8SChris Lattner } 270*30fdc8d8SChris Lattner } 271*30fdc8d8SChris Lattner else 272*30fdc8d8SChris Lattner { 273*30fdc8d8SChris Lattner if (m_options.m_use_script_language) 274*30fdc8d8SChris Lattner { 275*30fdc8d8SChris Lattner interpreter->GetScriptInterpreter()->CollectDataForBreakpointCommandCallback (bp->GetOptions(), 276*30fdc8d8SChris Lattner result); 277*30fdc8d8SChris Lattner } 278*30fdc8d8SChris Lattner else 279*30fdc8d8SChris Lattner { 280*30fdc8d8SChris Lattner CollectDataForBreakpointCommandCallback (bp->GetOptions(), result); 281*30fdc8d8SChris Lattner } 282*30fdc8d8SChris Lattner } 283*30fdc8d8SChris Lattner } 284*30fdc8d8SChris Lattner } 285*30fdc8d8SChris Lattner } 286*30fdc8d8SChris Lattner 287*30fdc8d8SChris Lattner return result.Succeeded(); 288*30fdc8d8SChris Lattner } 289*30fdc8d8SChris Lattner 290*30fdc8d8SChris Lattner Options * 291*30fdc8d8SChris Lattner CommandObjectBreakpointCommandAdd::GetOptions () 292*30fdc8d8SChris Lattner { 293*30fdc8d8SChris Lattner return &m_options; 294*30fdc8d8SChris Lattner } 295*30fdc8d8SChris Lattner 296*30fdc8d8SChris Lattner const char *g_reader_instructions = "Enter your debugger command(s). Type 'DONE' to end."; 297*30fdc8d8SChris Lattner 298*30fdc8d8SChris Lattner void 299*30fdc8d8SChris Lattner CommandObjectBreakpointCommandAdd::CollectDataForBreakpointCommandCallback 300*30fdc8d8SChris Lattner ( 301*30fdc8d8SChris Lattner BreakpointOptions *bp_options, 302*30fdc8d8SChris Lattner CommandReturnObject &result 303*30fdc8d8SChris Lattner ) 304*30fdc8d8SChris Lattner { 305*30fdc8d8SChris Lattner InputReaderSP reader_sp (new InputReader()); 306*30fdc8d8SChris Lattner std::auto_ptr<BreakpointOptions::CommandData> data_ap(new BreakpointOptions::CommandData()); 307*30fdc8d8SChris Lattner if (reader_sp && data_ap.get()) 308*30fdc8d8SChris Lattner { 309*30fdc8d8SChris Lattner BatonSP baton_sp (new BreakpointOptions::CommandBaton (data_ap.release())); 310*30fdc8d8SChris Lattner bp_options->SetCallback (CommandObjectBreakpointCommand::BreakpointOptionsCallbackFunction, baton_sp); 311*30fdc8d8SChris Lattner 312*30fdc8d8SChris Lattner Error err (reader_sp->Initialize (CommandObjectBreakpointCommandAdd::GenerateBreakpointCommandCallback, 313*30fdc8d8SChris Lattner bp_options, // baton 314*30fdc8d8SChris Lattner eInputReaderGranularityLine, // token size, to pass to callback function 315*30fdc8d8SChris Lattner "DONE", // end token 316*30fdc8d8SChris Lattner "> ", // prompt 317*30fdc8d8SChris Lattner true)); // echo input 318*30fdc8d8SChris Lattner if (err.Success()) 319*30fdc8d8SChris Lattner { 320*30fdc8d8SChris Lattner Debugger::GetSharedInstance().PushInputReader (reader_sp); 321*30fdc8d8SChris Lattner result.SetStatus (eReturnStatusSuccessFinishNoResult); 322*30fdc8d8SChris Lattner } 323*30fdc8d8SChris Lattner else 324*30fdc8d8SChris Lattner { 325*30fdc8d8SChris Lattner result.AppendError (err.AsCString()); 326*30fdc8d8SChris Lattner result.SetStatus (eReturnStatusFailed); 327*30fdc8d8SChris Lattner } 328*30fdc8d8SChris Lattner } 329*30fdc8d8SChris Lattner else 330*30fdc8d8SChris Lattner { 331*30fdc8d8SChris Lattner result.AppendError("out of memory"); 332*30fdc8d8SChris Lattner result.SetStatus (eReturnStatusFailed); 333*30fdc8d8SChris Lattner } 334*30fdc8d8SChris Lattner 335*30fdc8d8SChris Lattner } 336*30fdc8d8SChris Lattner 337*30fdc8d8SChris Lattner size_t 338*30fdc8d8SChris Lattner CommandObjectBreakpointCommandAdd::GenerateBreakpointCommandCallback 339*30fdc8d8SChris Lattner ( 340*30fdc8d8SChris Lattner void *baton, 341*30fdc8d8SChris Lattner InputReader *reader, 342*30fdc8d8SChris Lattner lldb::InputReaderAction notification, 343*30fdc8d8SChris Lattner const char *bytes, 344*30fdc8d8SChris Lattner size_t bytes_len 345*30fdc8d8SChris Lattner ) 346*30fdc8d8SChris Lattner { 347*30fdc8d8SChris Lattner FILE *out_fh = Debugger::GetSharedInstance().GetOutputFileHandle(); 348*30fdc8d8SChris Lattner 349*30fdc8d8SChris Lattner switch (notification) 350*30fdc8d8SChris Lattner { 351*30fdc8d8SChris Lattner case eInputReaderActivate: 352*30fdc8d8SChris Lattner if (out_fh) 353*30fdc8d8SChris Lattner { 354*30fdc8d8SChris Lattner ::fprintf (out_fh, "%s\n", g_reader_instructions); 355*30fdc8d8SChris Lattner if (reader->GetPrompt()) 356*30fdc8d8SChris Lattner ::fprintf (out_fh, "%s", reader->GetPrompt()); 357*30fdc8d8SChris Lattner } 358*30fdc8d8SChris Lattner break; 359*30fdc8d8SChris Lattner 360*30fdc8d8SChris Lattner case eInputReaderDeactivate: 361*30fdc8d8SChris Lattner break; 362*30fdc8d8SChris Lattner 363*30fdc8d8SChris Lattner case eInputReaderReactivate: 364*30fdc8d8SChris Lattner if (out_fh && reader->GetPrompt()) 365*30fdc8d8SChris Lattner ::fprintf (out_fh, "%s", reader->GetPrompt()); 366*30fdc8d8SChris Lattner break; 367*30fdc8d8SChris Lattner 368*30fdc8d8SChris Lattner case eInputReaderGotToken: 369*30fdc8d8SChris Lattner if (bytes && bytes_len && baton) 370*30fdc8d8SChris Lattner { 371*30fdc8d8SChris Lattner BreakpointOptions *bp_options = (BreakpointOptions *) baton; 372*30fdc8d8SChris Lattner if (bp_options) 373*30fdc8d8SChris Lattner { 374*30fdc8d8SChris Lattner Baton *bp_options_baton = bp_options->GetBaton(); 375*30fdc8d8SChris Lattner if (bp_options_baton) 376*30fdc8d8SChris Lattner ((BreakpointOptions::CommandData *)bp_options_baton->m_data)->user_source.AppendString (bytes, bytes_len); 377*30fdc8d8SChris Lattner } 378*30fdc8d8SChris Lattner } 379*30fdc8d8SChris Lattner if (out_fh && !reader->IsDone() && reader->GetPrompt()) 380*30fdc8d8SChris Lattner ::fprintf (out_fh, "%s", reader->GetPrompt()); 381*30fdc8d8SChris Lattner break; 382*30fdc8d8SChris Lattner 383*30fdc8d8SChris Lattner case eInputReaderDone: 384*30fdc8d8SChris Lattner break; 385*30fdc8d8SChris Lattner } 386*30fdc8d8SChris Lattner 387*30fdc8d8SChris Lattner return bytes_len; 388*30fdc8d8SChris Lattner } 389*30fdc8d8SChris Lattner 390*30fdc8d8SChris Lattner 391*30fdc8d8SChris Lattner //------------------------------------------------------------------------- 392*30fdc8d8SChris Lattner // CommandObjectBreakpointCommandRemove 393*30fdc8d8SChris Lattner //------------------------------------------------------------------------- 394*30fdc8d8SChris Lattner 395*30fdc8d8SChris Lattner CommandObjectBreakpointCommandRemove::CommandObjectBreakpointCommandRemove () : 396*30fdc8d8SChris Lattner CommandObject ("remove", 397*30fdc8d8SChris Lattner "Remove the set of commands from a breakpoint.", 398*30fdc8d8SChris Lattner "breakpoint command remove <breakpoint-id>") 399*30fdc8d8SChris Lattner { 400*30fdc8d8SChris Lattner } 401*30fdc8d8SChris Lattner 402*30fdc8d8SChris Lattner CommandObjectBreakpointCommandRemove::~CommandObjectBreakpointCommandRemove () 403*30fdc8d8SChris Lattner { 404*30fdc8d8SChris Lattner } 405*30fdc8d8SChris Lattner 406*30fdc8d8SChris Lattner bool 407*30fdc8d8SChris Lattner CommandObjectBreakpointCommandRemove::Execute (Args& command, 408*30fdc8d8SChris Lattner CommandContext *context, 409*30fdc8d8SChris Lattner CommandInterpreter *interpreter, 410*30fdc8d8SChris Lattner CommandReturnObject &result) 411*30fdc8d8SChris Lattner { 412*30fdc8d8SChris Lattner Target *target = context->GetTarget(); 413*30fdc8d8SChris Lattner 414*30fdc8d8SChris Lattner if (target == NULL) 415*30fdc8d8SChris Lattner { 416*30fdc8d8SChris Lattner result.AppendError ("There is not a current executable; there are no breakpoints from which to remove commands"); 417*30fdc8d8SChris Lattner result.SetStatus (eReturnStatusFailed); 418*30fdc8d8SChris Lattner return false; 419*30fdc8d8SChris Lattner } 420*30fdc8d8SChris Lattner 421*30fdc8d8SChris Lattner const BreakpointList &breakpoints = target->GetBreakpointList(); 422*30fdc8d8SChris Lattner size_t num_breakpoints = breakpoints.GetSize(); 423*30fdc8d8SChris Lattner 424*30fdc8d8SChris Lattner if (num_breakpoints == 0) 425*30fdc8d8SChris Lattner { 426*30fdc8d8SChris Lattner result.AppendError ("No breakpoints exist to have commands removed"); 427*30fdc8d8SChris Lattner result.SetStatus (eReturnStatusFailed); 428*30fdc8d8SChris Lattner return false; 429*30fdc8d8SChris Lattner } 430*30fdc8d8SChris Lattner 431*30fdc8d8SChris Lattner if (command.GetArgumentCount() == 0) 432*30fdc8d8SChris Lattner { 433*30fdc8d8SChris Lattner result.AppendError ("No breakpoint specified from which to remove the commands"); 434*30fdc8d8SChris Lattner result.SetStatus (eReturnStatusFailed); 435*30fdc8d8SChris Lattner return false; 436*30fdc8d8SChris Lattner } 437*30fdc8d8SChris Lattner 438*30fdc8d8SChris Lattner BreakpointIDList valid_bp_ids; 439*30fdc8d8SChris Lattner CommandObjectMultiwordBreakpoint::VerifyBreakpointIDs (command, target, result, &valid_bp_ids); 440*30fdc8d8SChris Lattner 441*30fdc8d8SChris Lattner if (result.Succeeded()) 442*30fdc8d8SChris Lattner { 443*30fdc8d8SChris Lattner for (int i = 0; i < valid_bp_ids.Size(); ++i) 444*30fdc8d8SChris Lattner { 445*30fdc8d8SChris Lattner BreakpointID cur_bp_id = valid_bp_ids.GetBreakpointIDAtIndex (i); 446*30fdc8d8SChris Lattner if (cur_bp_id.GetBreakpointID() != LLDB_INVALID_BREAK_ID) 447*30fdc8d8SChris Lattner { 448*30fdc8d8SChris Lattner Breakpoint *bp = target->GetBreakpointByID (cur_bp_id.GetBreakpointID()).get(); 449*30fdc8d8SChris Lattner if (cur_bp_id.GetLocationID() != LLDB_INVALID_BREAK_ID) 450*30fdc8d8SChris Lattner { 451*30fdc8d8SChris Lattner BreakpointLocationSP bp_loc_sp (bp->FindLocationByID (cur_bp_id.GetLocationID())); 452*30fdc8d8SChris Lattner if (bp_loc_sp) 453*30fdc8d8SChris Lattner bp_loc_sp->ClearCallback(); 454*30fdc8d8SChris Lattner else 455*30fdc8d8SChris Lattner { 456*30fdc8d8SChris Lattner result.AppendErrorWithFormat("Invalid breakpoint ID: %u.%u.\n", 457*30fdc8d8SChris Lattner cur_bp_id.GetBreakpointID(), 458*30fdc8d8SChris Lattner cur_bp_id.GetLocationID()); 459*30fdc8d8SChris Lattner result.SetStatus (eReturnStatusFailed); 460*30fdc8d8SChris Lattner return false; 461*30fdc8d8SChris Lattner } 462*30fdc8d8SChris Lattner } 463*30fdc8d8SChris Lattner else 464*30fdc8d8SChris Lattner { 465*30fdc8d8SChris Lattner bp->ClearCallback(); 466*30fdc8d8SChris Lattner } 467*30fdc8d8SChris Lattner } 468*30fdc8d8SChris Lattner } 469*30fdc8d8SChris Lattner } 470*30fdc8d8SChris Lattner return result.Succeeded(); 471*30fdc8d8SChris Lattner } 472*30fdc8d8SChris Lattner 473*30fdc8d8SChris Lattner 474*30fdc8d8SChris Lattner //------------------------------------------------------------------------- 475*30fdc8d8SChris Lattner // CommandObjectBreakpointCommandList 476*30fdc8d8SChris Lattner //------------------------------------------------------------------------- 477*30fdc8d8SChris Lattner 478*30fdc8d8SChris Lattner CommandObjectBreakpointCommandList::CommandObjectBreakpointCommandList () : 479*30fdc8d8SChris Lattner CommandObject ("List", 480*30fdc8d8SChris Lattner "List the script or set of commands to be executed when the breakpoint is hit.", 481*30fdc8d8SChris Lattner "breakpoint command list <breakpoint-id>") 482*30fdc8d8SChris Lattner { 483*30fdc8d8SChris Lattner } 484*30fdc8d8SChris Lattner 485*30fdc8d8SChris Lattner CommandObjectBreakpointCommandList::~CommandObjectBreakpointCommandList () 486*30fdc8d8SChris Lattner { 487*30fdc8d8SChris Lattner } 488*30fdc8d8SChris Lattner 489*30fdc8d8SChris Lattner bool 490*30fdc8d8SChris Lattner CommandObjectBreakpointCommandList::Execute (Args& command, 491*30fdc8d8SChris Lattner CommandContext *context, 492*30fdc8d8SChris Lattner CommandInterpreter *interpreter, 493*30fdc8d8SChris Lattner CommandReturnObject &result) 494*30fdc8d8SChris Lattner { 495*30fdc8d8SChris Lattner Target *target = context->GetTarget(); 496*30fdc8d8SChris Lattner 497*30fdc8d8SChris Lattner if (target == NULL) 498*30fdc8d8SChris Lattner { 499*30fdc8d8SChris Lattner result.AppendError ("There is not a current executable; there are no breakpoints for which to list commands"); 500*30fdc8d8SChris Lattner result.SetStatus (eReturnStatusFailed); 501*30fdc8d8SChris Lattner return false; 502*30fdc8d8SChris Lattner } 503*30fdc8d8SChris Lattner 504*30fdc8d8SChris Lattner const BreakpointList &breakpoints = target->GetBreakpointList(); 505*30fdc8d8SChris Lattner size_t num_breakpoints = breakpoints.GetSize(); 506*30fdc8d8SChris Lattner 507*30fdc8d8SChris Lattner if (num_breakpoints == 0) 508*30fdc8d8SChris Lattner { 509*30fdc8d8SChris Lattner result.AppendError ("No breakpoints exist for which to list commands"); 510*30fdc8d8SChris Lattner result.SetStatus (eReturnStatusFailed); 511*30fdc8d8SChris Lattner return false; 512*30fdc8d8SChris Lattner } 513*30fdc8d8SChris Lattner 514*30fdc8d8SChris Lattner if (command.GetArgumentCount() == 0) 515*30fdc8d8SChris Lattner { 516*30fdc8d8SChris Lattner result.AppendError ("No breakpoint specified for which to list the commands"); 517*30fdc8d8SChris Lattner result.SetStatus (eReturnStatusFailed); 518*30fdc8d8SChris Lattner return false; 519*30fdc8d8SChris Lattner } 520*30fdc8d8SChris Lattner 521*30fdc8d8SChris Lattner BreakpointIDList valid_bp_ids; 522*30fdc8d8SChris Lattner CommandObjectMultiwordBreakpoint::VerifyBreakpointIDs (command, target, result, &valid_bp_ids); 523*30fdc8d8SChris Lattner 524*30fdc8d8SChris Lattner if (result.Succeeded()) 525*30fdc8d8SChris Lattner { 526*30fdc8d8SChris Lattner for (int i = 0; i < valid_bp_ids.Size(); ++i) 527*30fdc8d8SChris Lattner { 528*30fdc8d8SChris Lattner BreakpointID cur_bp_id = valid_bp_ids.GetBreakpointIDAtIndex (i); 529*30fdc8d8SChris Lattner if (cur_bp_id.GetBreakpointID() != LLDB_INVALID_BREAK_ID) 530*30fdc8d8SChris Lattner { 531*30fdc8d8SChris Lattner Breakpoint *bp = target->GetBreakpointByID (cur_bp_id.GetBreakpointID()).get(); 532*30fdc8d8SChris Lattner 533*30fdc8d8SChris Lattner if (bp) 534*30fdc8d8SChris Lattner { 535*30fdc8d8SChris Lattner BreakpointOptions *bp_options = NULL; 536*30fdc8d8SChris Lattner if (cur_bp_id.GetLocationID() != LLDB_INVALID_BREAK_ID) 537*30fdc8d8SChris Lattner { 538*30fdc8d8SChris Lattner BreakpointLocationSP bp_loc_sp(bp->FindLocationByID (cur_bp_id.GetLocationID())); 539*30fdc8d8SChris Lattner if (bp_loc_sp) 540*30fdc8d8SChris Lattner bp_options = bp_loc_sp->GetOptionsNoCopy(); 541*30fdc8d8SChris Lattner else 542*30fdc8d8SChris Lattner { 543*30fdc8d8SChris Lattner result.AppendErrorWithFormat("Invalid breakpoint ID: %u.%u.\n", 544*30fdc8d8SChris Lattner cur_bp_id.GetBreakpointID(), 545*30fdc8d8SChris Lattner cur_bp_id.GetLocationID()); 546*30fdc8d8SChris Lattner result.SetStatus (eReturnStatusFailed); 547*30fdc8d8SChris Lattner return false; 548*30fdc8d8SChris Lattner } 549*30fdc8d8SChris Lattner } 550*30fdc8d8SChris Lattner else 551*30fdc8d8SChris Lattner { 552*30fdc8d8SChris Lattner bp_options = bp->GetOptions(); 553*30fdc8d8SChris Lattner } 554*30fdc8d8SChris Lattner 555*30fdc8d8SChris Lattner if (bp_options) 556*30fdc8d8SChris Lattner { 557*30fdc8d8SChris Lattner StreamString id_str; 558*30fdc8d8SChris Lattner BreakpointID::GetCanonicalReference (&id_str, cur_bp_id.GetBreakpointID(), cur_bp_id.GetLocationID()); 559*30fdc8d8SChris Lattner Baton *baton = bp_options->GetBaton(); 560*30fdc8d8SChris Lattner if (baton) 561*30fdc8d8SChris Lattner { 562*30fdc8d8SChris Lattner result.GetOutputStream().Printf ("Breakpoint %s:\n", id_str.GetData()); 563*30fdc8d8SChris Lattner result.GetOutputStream().IndentMore (); 564*30fdc8d8SChris Lattner baton->GetDescription(&result.GetOutputStream(), eDescriptionLevelFull); 565*30fdc8d8SChris Lattner result.GetOutputStream().IndentLess (); 566*30fdc8d8SChris Lattner } 567*30fdc8d8SChris Lattner else 568*30fdc8d8SChris Lattner { 569*30fdc8d8SChris Lattner result.AppendMessageWithFormat ("Breakpoint %s does not have an associated command.\n", id_str.GetData()); 570*30fdc8d8SChris Lattner } 571*30fdc8d8SChris Lattner } 572*30fdc8d8SChris Lattner result.SetStatus (eReturnStatusSuccessFinishResult); 573*30fdc8d8SChris Lattner } 574*30fdc8d8SChris Lattner else 575*30fdc8d8SChris Lattner { 576*30fdc8d8SChris Lattner result.AppendErrorWithFormat("Invalid breakpoint ID: %u.\n", cur_bp_id.GetBreakpointID()); 577*30fdc8d8SChris Lattner result.SetStatus (eReturnStatusFailed); 578*30fdc8d8SChris Lattner } 579*30fdc8d8SChris Lattner 580*30fdc8d8SChris Lattner } 581*30fdc8d8SChris Lattner } 582*30fdc8d8SChris Lattner } 583*30fdc8d8SChris Lattner 584*30fdc8d8SChris Lattner return result.Succeeded(); 585*30fdc8d8SChris Lattner } 586*30fdc8d8SChris Lattner 587*30fdc8d8SChris Lattner //------------------------------------------------------------------------- 588*30fdc8d8SChris Lattner // CommandObjectBreakpointCommand 589*30fdc8d8SChris Lattner //------------------------------------------------------------------------- 590*30fdc8d8SChris Lattner 591*30fdc8d8SChris Lattner CommandObjectBreakpointCommand::CommandObjectBreakpointCommand (CommandInterpreter *interpreter) : 592*30fdc8d8SChris Lattner CommandObjectMultiword ("command", 593*30fdc8d8SChris Lattner "A set of commands for adding, removing and examining bits of code to be executed when the breakpoint is hit (breakpoint 'commmands').", 594*30fdc8d8SChris Lattner "command <sub-command> [<sub-command-options>] <breakpoint-id>") 595*30fdc8d8SChris Lattner { 596*30fdc8d8SChris Lattner bool status; 597*30fdc8d8SChris Lattner CommandObjectSP add_command_object (new CommandObjectBreakpointCommandAdd ()); 598*30fdc8d8SChris Lattner CommandObjectSP remove_command_object (new CommandObjectBreakpointCommandRemove ()); 599*30fdc8d8SChris Lattner CommandObjectSP list_command_object (new CommandObjectBreakpointCommandList ()); 600*30fdc8d8SChris Lattner 601*30fdc8d8SChris Lattner add_command_object->SetCommandName ("breakpoint command add"); 602*30fdc8d8SChris Lattner remove_command_object->SetCommandName ("breakpoint command remove"); 603*30fdc8d8SChris Lattner list_command_object->SetCommandName ("breakpoint command list"); 604*30fdc8d8SChris Lattner 605*30fdc8d8SChris Lattner status = LoadSubCommand (add_command_object, "add", interpreter); 606*30fdc8d8SChris Lattner status = LoadSubCommand (remove_command_object, "remove", interpreter); 607*30fdc8d8SChris Lattner status = LoadSubCommand (list_command_object, "list", interpreter); 608*30fdc8d8SChris Lattner } 609*30fdc8d8SChris Lattner 610*30fdc8d8SChris Lattner 611*30fdc8d8SChris Lattner CommandObjectBreakpointCommand::~CommandObjectBreakpointCommand () 612*30fdc8d8SChris Lattner { 613*30fdc8d8SChris Lattner } 614*30fdc8d8SChris Lattner 615*30fdc8d8SChris Lattner bool 616*30fdc8d8SChris Lattner CommandObjectBreakpointCommand::BreakpointOptionsCallbackFunction 617*30fdc8d8SChris Lattner ( 618*30fdc8d8SChris Lattner void *baton, 619*30fdc8d8SChris Lattner StoppointCallbackContext *context, 620*30fdc8d8SChris Lattner lldb::user_id_t break_id, 621*30fdc8d8SChris Lattner lldb::user_id_t break_loc_id 622*30fdc8d8SChris Lattner ) 623*30fdc8d8SChris Lattner { 624*30fdc8d8SChris Lattner bool ret_value = true; 625*30fdc8d8SChris Lattner if (baton == NULL) 626*30fdc8d8SChris Lattner return true; 627*30fdc8d8SChris Lattner 628*30fdc8d8SChris Lattner 629*30fdc8d8SChris Lattner BreakpointOptions::CommandData *data = (BreakpointOptions::CommandData *) baton; 630*30fdc8d8SChris Lattner StringList &commands = data->user_source; 631*30fdc8d8SChris Lattner 632*30fdc8d8SChris Lattner if (commands.GetSize() > 0) 633*30fdc8d8SChris Lattner { 634*30fdc8d8SChris Lattner uint32_t num_commands = commands.GetSize(); 635*30fdc8d8SChris Lattner CommandInterpreter &interpreter = Debugger::GetSharedInstance().GetCommandInterpreter(); 636*30fdc8d8SChris Lattner CommandReturnObject result; 637*30fdc8d8SChris Lattner ExecutionContext exe_ctx = context->context; 638*30fdc8d8SChris Lattner 639*30fdc8d8SChris Lattner FILE *out_fh = Debugger::GetSharedInstance().GetOutputFileHandle(); 640*30fdc8d8SChris Lattner FILE *err_fh = Debugger::GetSharedInstance().GetErrorFileHandle(); 641*30fdc8d8SChris Lattner 642*30fdc8d8SChris Lattner 643*30fdc8d8SChris Lattner uint32_t i; 644*30fdc8d8SChris Lattner for (i = 0; i < num_commands; ++i) 645*30fdc8d8SChris Lattner { 646*30fdc8d8SChris Lattner 647*30fdc8d8SChris Lattner // First time through we use the context from the stoppoint, after that we use whatever 648*30fdc8d8SChris Lattner // has been set by the previous command. 649*30fdc8d8SChris Lattner 650*30fdc8d8SChris Lattner if (!interpreter.HandleCommand (commands.GetStringAtIndex(i), false, result, &exe_ctx)) 651*30fdc8d8SChris Lattner break; 652*30fdc8d8SChris Lattner 653*30fdc8d8SChris Lattner // FIXME: This isn't really the right way to do this. We should be able to peek at the public 654*30fdc8d8SChris Lattner // to see if there is any new events, but that is racey, since the internal process thread has to run and 655*30fdc8d8SChris Lattner // deliver the event to the public queue before a run will show up. So for now we check 656*30fdc8d8SChris Lattner // the internal thread state. 657*30fdc8d8SChris Lattner 658*30fdc8d8SChris Lattner lldb::StateType internal_state = exe_ctx.process->GetPrivateState(); 659*30fdc8d8SChris Lattner if (internal_state != eStateStopped) 660*30fdc8d8SChris Lattner { 661*30fdc8d8SChris Lattner if (i < num_commands - 1) 662*30fdc8d8SChris Lattner { 663*30fdc8d8SChris Lattner if (out_fh) 664*30fdc8d8SChris Lattner ::fprintf (out_fh, "Short-circuiting command execution because target state changed to %s." 665*30fdc8d8SChris Lattner " last command: \"%s\"\n", StateAsCString(internal_state), 666*30fdc8d8SChris Lattner commands.GetStringAtIndex(i)); 667*30fdc8d8SChris Lattner } 668*30fdc8d8SChris Lattner break; 669*30fdc8d8SChris Lattner } 670*30fdc8d8SChris Lattner 671*30fdc8d8SChris Lattner // First time through we use the context from the stoppoint, after that we use whatever 672*30fdc8d8SChris Lattner // has been set by the previous command. 673*30fdc8d8SChris Lattner exe_ctx = Debugger::GetSharedInstance().GetCurrentExecutionContext(); 674*30fdc8d8SChris Lattner 675*30fdc8d8SChris Lattner 676*30fdc8d8SChris Lattner if (out_fh) 677*30fdc8d8SChris Lattner ::fprintf (out_fh, "%s", result.GetErrorStream().GetData()); 678*30fdc8d8SChris Lattner if (err_fh) 679*30fdc8d8SChris Lattner ::fprintf (err_fh, "%s", result.GetOutputStream().GetData()); 680*30fdc8d8SChris Lattner result.Clear(); 681*30fdc8d8SChris Lattner result.SetStatus (eReturnStatusSuccessFinishNoResult); 682*30fdc8d8SChris Lattner } 683*30fdc8d8SChris Lattner 684*30fdc8d8SChris Lattner if (err_fh && !result.Succeeded() && i < num_commands) 685*30fdc8d8SChris Lattner ::fprintf (err_fh, "Attempt to execute '%s' failed.\n", commands.GetStringAtIndex(i)); 686*30fdc8d8SChris Lattner 687*30fdc8d8SChris Lattner if (out_fh) 688*30fdc8d8SChris Lattner ::fprintf (out_fh, "%s", result.GetErrorStream().GetData()); 689*30fdc8d8SChris Lattner 690*30fdc8d8SChris Lattner if (err_fh) 691*30fdc8d8SChris Lattner ::fprintf (err_fh, "%s", result.GetOutputStream().GetData()); 692*30fdc8d8SChris Lattner } 693*30fdc8d8SChris Lattner return ret_value; 694*30fdc8d8SChris Lattner } 695*30fdc8d8SChris Lattner 696