130fdc8d8SChris Lattner //===-- CommandObjectBreakpoint.cpp -----------------------------*- C++ -*-===// 230fdc8d8SChris Lattner // 330fdc8d8SChris Lattner // The LLVM Compiler Infrastructure 430fdc8d8SChris Lattner // 530fdc8d8SChris Lattner // This file is distributed under the University of Illinois Open Source 630fdc8d8SChris Lattner // License. See LICENSE.TXT for details. 730fdc8d8SChris Lattner // 830fdc8d8SChris Lattner //===----------------------------------------------------------------------===// 930fdc8d8SChris Lattner 1030fdc8d8SChris Lattner #include "CommandObjectBreakpoint.h" 1130fdc8d8SChris Lattner #include "CommandObjectBreakpointCommand.h" 1230fdc8d8SChris Lattner 1330fdc8d8SChris Lattner // C Includes 1430fdc8d8SChris Lattner // C++ Includes 1530fdc8d8SChris Lattner // Other libraries and framework includes 1630fdc8d8SChris Lattner // Project includes 1730fdc8d8SChris Lattner #include "lldb/Breakpoint/Breakpoint.h" 1830fdc8d8SChris Lattner #include "lldb/Breakpoint/BreakpointIDList.h" 1930fdc8d8SChris Lattner #include "lldb/Breakpoint/BreakpointLocation.h" 205275aaa0SVince Harron #include "lldb/Host/StringConvert.h" 2140af72e1SJim Ingham #include "lldb/Interpreter/Options.h" 2232abc6edSZachary Turner #include "lldb/Interpreter/OptionValueBoolean.h" 235e09c8c3SJim Ingham #include "lldb/Interpreter/OptionValueString.h" 245e09c8c3SJim Ingham #include "lldb/Interpreter/OptionValueUInt64.h" 2530fdc8d8SChris Lattner #include "lldb/Core/RegularExpression.h" 2630fdc8d8SChris Lattner #include "lldb/Core/StreamString.h" 2730fdc8d8SChris Lattner #include "lldb/Interpreter/CommandInterpreter.h" 2830fdc8d8SChris Lattner #include "lldb/Interpreter/CommandReturnObject.h" 290e0984eeSJim Ingham #include "lldb/Target/Language.h" 3030fdc8d8SChris Lattner #include "lldb/Target/Target.h" 3130fdc8d8SChris Lattner #include "lldb/Interpreter/CommandCompletions.h" 32b57e4a1bSJason Molenda #include "lldb/Target/StackFrame.h" 331b54c88cSJim Ingham #include "lldb/Target/Thread.h" 341b54c88cSJim Ingham #include "lldb/Target/ThreadSpec.h" 3530fdc8d8SChris Lattner 36b7234e40SJohnny Chen #include <vector> 37b7234e40SJohnny Chen 3830fdc8d8SChris Lattner using namespace lldb; 3930fdc8d8SChris Lattner using namespace lldb_private; 4030fdc8d8SChris Lattner 4130fdc8d8SChris Lattner static void 4285e8b814SJim Ingham AddBreakpointDescription (Stream *s, Breakpoint *bp, lldb::DescriptionLevel level) 4330fdc8d8SChris Lattner { 4430fdc8d8SChris Lattner s->IndentMore(); 4530fdc8d8SChris Lattner bp->GetDescription (s, level, true); 4630fdc8d8SChris Lattner s->IndentLess(); 4730fdc8d8SChris Lattner s->EOL(); 4830fdc8d8SChris Lattner } 4930fdc8d8SChris Lattner 5030fdc8d8SChris Lattner //------------------------------------------------------------------------- 515a988416SJim Ingham // CommandObjectBreakpointSet 5230fdc8d8SChris Lattner //------------------------------------------------------------------------- 5330fdc8d8SChris Lattner 545a988416SJim Ingham 555a988416SJim Ingham class CommandObjectBreakpointSet : public CommandObjectParsed 565a988416SJim Ingham { 575a988416SJim Ingham public: 585a988416SJim Ingham 595a988416SJim Ingham typedef enum BreakpointSetType 605a988416SJim Ingham { 615a988416SJim Ingham eSetTypeInvalid, 625a988416SJim Ingham eSetTypeFileAndLine, 635a988416SJim Ingham eSetTypeAddress, 645a988416SJim Ingham eSetTypeFunctionName, 655a988416SJim Ingham eSetTypeFunctionRegexp, 665a988416SJim Ingham eSetTypeSourceRegexp, 675a988416SJim Ingham eSetTypeException 685a988416SJim Ingham } BreakpointSetType; 695a988416SJim Ingham 705a988416SJim Ingham CommandObjectBreakpointSet (CommandInterpreter &interpreter) : 715a988416SJim Ingham CommandObjectParsed (interpreter, 725a988416SJim Ingham "breakpoint set", 735a988416SJim Ingham "Sets a breakpoint or set of breakpoints in the executable.", 745a988416SJim Ingham "breakpoint set <cmd-options>"), 755a988416SJim Ingham m_options (interpreter) 765a988416SJim Ingham { 775a988416SJim Ingham } 785a988416SJim Ingham 795a988416SJim Ingham 80*13d21e9aSBruce Mitchener ~CommandObjectBreakpointSet () override {} 815a988416SJim Ingham 82*13d21e9aSBruce Mitchener Options * 83*13d21e9aSBruce Mitchener GetOptions () override 845a988416SJim Ingham { 855a988416SJim Ingham return &m_options; 865a988416SJim Ingham } 875a988416SJim Ingham 885a988416SJim Ingham class CommandOptions : public Options 895a988416SJim Ingham { 905a988416SJim Ingham public: 915a988416SJim Ingham 925a988416SJim Ingham CommandOptions (CommandInterpreter &interpreter) : 93eb0103f2SGreg Clayton Options (interpreter), 947d49c9c8SJohnny Chen m_condition (), 9587df91b8SJim Ingham m_filenames (), 9630fdc8d8SChris Lattner m_line_num (0), 9730fdc8d8SChris Lattner m_column (0), 98fab10e89SJim Ingham m_func_names (), 99fab10e89SJim Ingham m_func_name_type_mask (eFunctionNameTypeNone), 10030fdc8d8SChris Lattner m_func_regexp (), 101969795f1SJim Ingham m_source_text_regexp(), 10230fdc8d8SChris Lattner m_modules (), 1031b54c88cSJim Ingham m_load_addr(), 104c982c768SGreg Clayton m_ignore_count (0), 1051b54c88cSJim Ingham m_thread_id(LLDB_INVALID_THREAD_ID), 106c982c768SGreg Clayton m_thread_index (UINT32_MAX), 1071b54c88cSJim Ingham m_thread_name(), 108fab10e89SJim Ingham m_queue_name(), 109fab10e89SJim Ingham m_catch_bp (false), 1101f746071SGreg Clayton m_throw_bp (true), 111eb023e75SGreg Clayton m_hardware (false), 112a72b31c7SJim Ingham m_exception_language (eLanguageTypeUnknown), 11323b1decbSDawn Perchik m_language (lldb::eLanguageTypeUnknown), 114ca36cd16SJim Ingham m_skip_prologue (eLazyBoolCalculate), 115e732052fSJim Ingham m_one_shot (false), 116055ad9beSIlia K m_all_files (false), 117055ad9beSIlia K m_move_to_nearest_code (eLazyBoolCalculate) 11830fdc8d8SChris Lattner { 11930fdc8d8SChris Lattner } 12030fdc8d8SChris Lattner 12130fdc8d8SChris Lattner 122*13d21e9aSBruce Mitchener ~CommandOptions () override {} 12387df91b8SJim Ingham 124*13d21e9aSBruce Mitchener Error 125*13d21e9aSBruce Mitchener SetOptionValue (uint32_t option_idx, const char *option_arg) override 12630fdc8d8SChris Lattner { 12730fdc8d8SChris Lattner Error error; 1283bcdfc0eSGreg Clayton const int short_option = m_getopt_table[option_idx].val; 12930fdc8d8SChris Lattner 13030fdc8d8SChris Lattner switch (short_option) 13130fdc8d8SChris Lattner { 13230fdc8d8SChris Lattner case 'a': 133b9d5df58SGreg Clayton { 134b9d5df58SGreg Clayton ExecutionContext exe_ctx (m_interpreter.GetExecutionContext()); 135b9d5df58SGreg Clayton m_load_addr = Args::StringToAddress(&exe_ctx, option_arg, LLDB_INVALID_ADDRESS, &error); 136b9d5df58SGreg Clayton } 13730fdc8d8SChris Lattner break; 13830fdc8d8SChris Lattner 139e732052fSJim Ingham case 'A': 140e732052fSJim Ingham m_all_files = true; 141e732052fSJim Ingham break; 142e732052fSJim Ingham 143ca36cd16SJim Ingham case 'b': 144ca36cd16SJim Ingham m_func_names.push_back (option_arg); 145ca36cd16SJim Ingham m_func_name_type_mask |= eFunctionNameTypeBase; 146ca36cd16SJim Ingham break; 147ca36cd16SJim Ingham 1487d49c9c8SJohnny Chen case 'C': 1496312991cSJim Ingham { 1506312991cSJim Ingham bool success; 1516312991cSJim Ingham m_column = StringConvert::ToUInt32 (option_arg, 0, 0, &success); 1526312991cSJim Ingham if (!success) 1536312991cSJim Ingham error.SetErrorStringWithFormat("invalid column number: %s", option_arg); 15430fdc8d8SChris Lattner break; 1556312991cSJim Ingham } 1567d49c9c8SJohnny Chen case 'c': 1577d49c9c8SJohnny Chen m_condition.assign(option_arg); 1587d49c9c8SJohnny Chen break; 1597d49c9c8SJohnny Chen 16033df7cd3SJim Ingham case 'D': 16133df7cd3SJim Ingham m_use_dummy = true; 16233df7cd3SJim Ingham break; 16333df7cd3SJim Ingham 164fab10e89SJim Ingham case 'E': 165fab10e89SJim Ingham { 1660e0984eeSJim Ingham LanguageType language = Language::GetLanguageTypeFromString (option_arg); 167fab10e89SJim Ingham 168fab10e89SJim Ingham switch (language) 169fab10e89SJim Ingham { 170fab10e89SJim Ingham case eLanguageTypeC89: 171fab10e89SJim Ingham case eLanguageTypeC: 172fab10e89SJim Ingham case eLanguageTypeC99: 1731d0089faSBruce Mitchener case eLanguageTypeC11: 174a72b31c7SJim Ingham m_exception_language = eLanguageTypeC; 175fab10e89SJim Ingham break; 176fab10e89SJim Ingham case eLanguageTypeC_plus_plus: 1771d0089faSBruce Mitchener case eLanguageTypeC_plus_plus_03: 1781d0089faSBruce Mitchener case eLanguageTypeC_plus_plus_11: 1792ba84a6aSBruce Mitchener case eLanguageTypeC_plus_plus_14: 180a72b31c7SJim Ingham m_exception_language = eLanguageTypeC_plus_plus; 181fab10e89SJim Ingham break; 182fab10e89SJim Ingham case eLanguageTypeObjC: 183a72b31c7SJim Ingham m_exception_language = eLanguageTypeObjC; 184fab10e89SJim Ingham break; 185fab10e89SJim Ingham case eLanguageTypeObjC_plus_plus: 186fab10e89SJim Ingham error.SetErrorStringWithFormat ("Set exception breakpoints separately for c++ and objective-c"); 187fab10e89SJim Ingham break; 188fab10e89SJim Ingham case eLanguageTypeUnknown: 189fab10e89SJim Ingham error.SetErrorStringWithFormat ("Unknown language type: '%s' for exception breakpoint", option_arg); 190fab10e89SJim Ingham break; 191fab10e89SJim Ingham default: 192fab10e89SJim Ingham error.SetErrorStringWithFormat ("Unsupported language type: '%s' for exception breakpoint", option_arg); 193fab10e89SJim Ingham } 194fab10e89SJim Ingham } 195fab10e89SJim Ingham break; 196ca36cd16SJim Ingham 197ca36cd16SJim Ingham case 'f': 198ca36cd16SJim Ingham m_filenames.AppendIfUnique (FileSpec(option_arg, false)); 199fab10e89SJim Ingham break; 200ca36cd16SJim Ingham 201ca36cd16SJim Ingham case 'F': 202ca36cd16SJim Ingham m_func_names.push_back (option_arg); 203ca36cd16SJim Ingham m_func_name_type_mask |= eFunctionNameTypeFull; 204ca36cd16SJim Ingham break; 205ca36cd16SJim Ingham 206fab10e89SJim Ingham case 'h': 207fab10e89SJim Ingham { 208fab10e89SJim Ingham bool success; 209fab10e89SJim Ingham m_catch_bp = Args::StringToBoolean (option_arg, true, &success); 210fab10e89SJim Ingham if (!success) 211fab10e89SJim Ingham error.SetErrorStringWithFormat ("Invalid boolean value for on-catch option: '%s'", option_arg); 212fab10e89SJim Ingham } 213168d469aSJim Ingham break; 214eb023e75SGreg Clayton 215eb023e75SGreg Clayton case 'H': 216eb023e75SGreg Clayton m_hardware = true; 217eb023e75SGreg Clayton break; 218eb023e75SGreg Clayton 219ca36cd16SJim Ingham case 'i': 220ca36cd16SJim Ingham { 2215275aaa0SVince Harron m_ignore_count = StringConvert::ToUInt32(option_arg, UINT32_MAX, 0); 222ca36cd16SJim Ingham if (m_ignore_count == UINT32_MAX) 223ca36cd16SJim Ingham error.SetErrorStringWithFormat ("invalid ignore count '%s'", option_arg); 224ca36cd16SJim Ingham break; 225ca36cd16SJim Ingham } 226ca36cd16SJim Ingham 227a8558b62SJim Ingham case 'K': 228a8558b62SJim Ingham { 229a8558b62SJim Ingham bool success; 230a8558b62SJim Ingham bool value; 231a8558b62SJim Ingham value = Args::StringToBoolean (option_arg, true, &success); 232a8558b62SJim Ingham if (value) 233a8558b62SJim Ingham m_skip_prologue = eLazyBoolYes; 234a8558b62SJim Ingham else 235a8558b62SJim Ingham m_skip_prologue = eLazyBoolNo; 236a8558b62SJim Ingham 237a8558b62SJim Ingham if (!success) 238a8558b62SJim Ingham error.SetErrorStringWithFormat ("Invalid boolean value for skip prologue option: '%s'", option_arg); 239a8558b62SJim Ingham } 240fab10e89SJim Ingham break; 241ca36cd16SJim Ingham 242ca36cd16SJim Ingham case 'l': 2436312991cSJim Ingham { 2446312991cSJim Ingham bool success; 2456312991cSJim Ingham m_line_num = StringConvert::ToUInt32 (option_arg, 0, 0, &success); 2466312991cSJim Ingham if (!success) 2476312991cSJim Ingham error.SetErrorStringWithFormat ("invalid line number: %s.", option_arg); 248ca36cd16SJim Ingham break; 2496312991cSJim Ingham } 250055ad9beSIlia K 25123b1decbSDawn Perchik case 'L': 2520e0984eeSJim Ingham m_language = Language::GetLanguageTypeFromString (option_arg); 25323b1decbSDawn Perchik if (m_language == eLanguageTypeUnknown) 25423b1decbSDawn Perchik error.SetErrorStringWithFormat ("Unknown language type: '%s' for breakpoint", option_arg); 25523b1decbSDawn Perchik break; 25623b1decbSDawn Perchik 257055ad9beSIlia K case 'm': 258055ad9beSIlia K { 259055ad9beSIlia K bool success; 260055ad9beSIlia K bool value; 261055ad9beSIlia K value = Args::StringToBoolean (option_arg, true, &success); 262055ad9beSIlia K if (value) 263055ad9beSIlia K m_move_to_nearest_code = eLazyBoolYes; 264055ad9beSIlia K else 265055ad9beSIlia K m_move_to_nearest_code = eLazyBoolNo; 266055ad9beSIlia K 267055ad9beSIlia K if (!success) 268055ad9beSIlia K error.SetErrorStringWithFormat ("Invalid boolean value for move-to-nearest-code option: '%s'", option_arg); 269055ad9beSIlia K break; 270055ad9beSIlia K } 271055ad9beSIlia K 272ca36cd16SJim Ingham case 'M': 273ca36cd16SJim Ingham m_func_names.push_back (option_arg); 274ca36cd16SJim Ingham m_func_name_type_mask |= eFunctionNameTypeMethod; 275ca36cd16SJim Ingham break; 276ca36cd16SJim Ingham 277ca36cd16SJim Ingham case 'n': 278ca36cd16SJim Ingham m_func_names.push_back (option_arg); 279ca36cd16SJim Ingham m_func_name_type_mask |= eFunctionNameTypeAuto; 280ca36cd16SJim Ingham break; 281ca36cd16SJim Ingham 2825e09c8c3SJim Ingham case 'N': 2835e09c8c3SJim Ingham if (BreakpointID::StringIsBreakpointName(option_arg, error)) 2845e09c8c3SJim Ingham m_breakpoint_names.push_back (option_arg); 2855e09c8c3SJim Ingham break; 2865e09c8c3SJim Ingham 287ca36cd16SJim Ingham case 'o': 288ca36cd16SJim Ingham m_one_shot = true; 289ca36cd16SJim Ingham break; 290ca36cd16SJim Ingham 291a72b31c7SJim Ingham case 'O': 292a72b31c7SJim Ingham m_exception_extra_args.AppendArgument ("-O"); 293a72b31c7SJim Ingham m_exception_extra_args.AppendArgument (option_arg); 294a72b31c7SJim Ingham break; 295a72b31c7SJim Ingham 296ca36cd16SJim Ingham case 'p': 297ca36cd16SJim Ingham m_source_text_regexp.assign (option_arg); 298ca36cd16SJim Ingham break; 299ca36cd16SJim Ingham 300ca36cd16SJim Ingham case 'q': 301ca36cd16SJim Ingham m_queue_name.assign (option_arg); 302ca36cd16SJim Ingham break; 303ca36cd16SJim Ingham 304ca36cd16SJim Ingham case 'r': 305ca36cd16SJim Ingham m_func_regexp.assign (option_arg); 306ca36cd16SJim Ingham break; 307ca36cd16SJim Ingham 308ca36cd16SJim Ingham case 's': 309ca36cd16SJim Ingham { 310ca36cd16SJim Ingham m_modules.AppendIfUnique (FileSpec (option_arg, false)); 311ca36cd16SJim Ingham break; 312ca36cd16SJim Ingham } 313ca36cd16SJim Ingham 314ca36cd16SJim Ingham case 'S': 315ca36cd16SJim Ingham m_func_names.push_back (option_arg); 316ca36cd16SJim Ingham m_func_name_type_mask |= eFunctionNameTypeSelector; 317ca36cd16SJim Ingham break; 318ca36cd16SJim Ingham 319ca36cd16SJim Ingham case 't' : 320ca36cd16SJim Ingham { 3215275aaa0SVince Harron m_thread_id = StringConvert::ToUInt64(option_arg, LLDB_INVALID_THREAD_ID, 0); 322ca36cd16SJim Ingham if (m_thread_id == LLDB_INVALID_THREAD_ID) 323ca36cd16SJim Ingham error.SetErrorStringWithFormat ("invalid thread id string '%s'", option_arg); 324ca36cd16SJim Ingham } 325ca36cd16SJim Ingham break; 326ca36cd16SJim Ingham 327ca36cd16SJim Ingham case 'T': 328ca36cd16SJim Ingham m_thread_name.assign (option_arg); 329ca36cd16SJim Ingham break; 330ca36cd16SJim Ingham 331ca36cd16SJim Ingham case 'w': 332ca36cd16SJim Ingham { 333ca36cd16SJim Ingham bool success; 334ca36cd16SJim Ingham m_throw_bp = Args::StringToBoolean (option_arg, true, &success); 335ca36cd16SJim Ingham if (!success) 336ca36cd16SJim Ingham error.SetErrorStringWithFormat ("Invalid boolean value for on-throw option: '%s'", option_arg); 337ca36cd16SJim Ingham } 338ca36cd16SJim Ingham break; 339ca36cd16SJim Ingham 340ca36cd16SJim Ingham case 'x': 341ca36cd16SJim Ingham { 3425275aaa0SVince Harron m_thread_index = StringConvert::ToUInt32(option_arg, UINT32_MAX, 0); 343ca36cd16SJim Ingham if (m_thread_id == UINT32_MAX) 344ca36cd16SJim Ingham error.SetErrorStringWithFormat ("invalid thread index string '%s'", option_arg); 345ca36cd16SJim Ingham 346ca36cd16SJim Ingham } 347ca36cd16SJim Ingham break; 348ca36cd16SJim Ingham 34930fdc8d8SChris Lattner default: 35086edbf41SGreg Clayton error.SetErrorStringWithFormat ("unrecognized option '%c'", short_option); 35130fdc8d8SChris Lattner break; 35230fdc8d8SChris Lattner } 35330fdc8d8SChris Lattner 35430fdc8d8SChris Lattner return error; 35530fdc8d8SChris Lattner } 35630fdc8d8SChris Lattner void 357*13d21e9aSBruce Mitchener OptionParsingStarting () override 35830fdc8d8SChris Lattner { 3597d49c9c8SJohnny Chen m_condition.clear(); 36087df91b8SJim Ingham m_filenames.Clear(); 36130fdc8d8SChris Lattner m_line_num = 0; 36230fdc8d8SChris Lattner m_column = 0; 363fab10e89SJim Ingham m_func_names.clear(); 3641f746071SGreg Clayton m_func_name_type_mask = eFunctionNameTypeNone; 36530fdc8d8SChris Lattner m_func_regexp.clear(); 3661f746071SGreg Clayton m_source_text_regexp.clear(); 36787df91b8SJim Ingham m_modules.Clear(); 3681f746071SGreg Clayton m_load_addr = LLDB_INVALID_ADDRESS; 369c982c768SGreg Clayton m_ignore_count = 0; 3701b54c88cSJim Ingham m_thread_id = LLDB_INVALID_THREAD_ID; 371c982c768SGreg Clayton m_thread_index = UINT32_MAX; 3721b54c88cSJim Ingham m_thread_name.clear(); 3731b54c88cSJim Ingham m_queue_name.clear(); 374fab10e89SJim Ingham m_catch_bp = false; 375fab10e89SJim Ingham m_throw_bp = true; 376eb023e75SGreg Clayton m_hardware = false; 377a72b31c7SJim Ingham m_exception_language = eLanguageTypeUnknown; 37823b1decbSDawn Perchik m_language = lldb::eLanguageTypeUnknown; 379a8558b62SJim Ingham m_skip_prologue = eLazyBoolCalculate; 380ca36cd16SJim Ingham m_one_shot = false; 38133df7cd3SJim Ingham m_use_dummy = false; 3825e09c8c3SJim Ingham m_breakpoint_names.clear(); 383e732052fSJim Ingham m_all_files = false; 384a72b31c7SJim Ingham m_exception_extra_args.Clear(); 385055ad9beSIlia K m_move_to_nearest_code = eLazyBoolCalculate; 38630fdc8d8SChris Lattner } 38730fdc8d8SChris Lattner 3885a988416SJim Ingham const OptionDefinition* 389*13d21e9aSBruce Mitchener GetDefinitions () override 39030fdc8d8SChris Lattner { 3915a988416SJim Ingham return g_option_table; 39230fdc8d8SChris Lattner } 39330fdc8d8SChris Lattner 3945a988416SJim Ingham // Options table: Required for subclasses of Options. 39530fdc8d8SChris Lattner 3965a988416SJim Ingham static OptionDefinition g_option_table[]; 39730fdc8d8SChris Lattner 3985a988416SJim Ingham // Instance variables to hold the values for command options. 399969795f1SJim Ingham 4005a988416SJim Ingham std::string m_condition; 4015a988416SJim Ingham FileSpecList m_filenames; 4025a988416SJim Ingham uint32_t m_line_num; 4035a988416SJim Ingham uint32_t m_column; 4045a988416SJim Ingham std::vector<std::string> m_func_names; 4055e09c8c3SJim Ingham std::vector<std::string> m_breakpoint_names; 4065a988416SJim Ingham uint32_t m_func_name_type_mask; 4075a988416SJim Ingham std::string m_func_regexp; 4085a988416SJim Ingham std::string m_source_text_regexp; 4095a988416SJim Ingham FileSpecList m_modules; 4105a988416SJim Ingham lldb::addr_t m_load_addr; 4115a988416SJim Ingham uint32_t m_ignore_count; 4125a988416SJim Ingham lldb::tid_t m_thread_id; 4135a988416SJim Ingham uint32_t m_thread_index; 4145a988416SJim Ingham std::string m_thread_name; 4155a988416SJim Ingham std::string m_queue_name; 4165a988416SJim Ingham bool m_catch_bp; 4175a988416SJim Ingham bool m_throw_bp; 418eb023e75SGreg Clayton bool m_hardware; // Request to use hardware breakpoints 419a72b31c7SJim Ingham lldb::LanguageType m_exception_language; 42023b1decbSDawn Perchik lldb::LanguageType m_language; 4215a988416SJim Ingham LazyBool m_skip_prologue; 422ca36cd16SJim Ingham bool m_one_shot; 42333df7cd3SJim Ingham bool m_use_dummy; 424e732052fSJim Ingham bool m_all_files; 425a72b31c7SJim Ingham Args m_exception_extra_args; 426055ad9beSIlia K LazyBool m_move_to_nearest_code; 4275a988416SJim Ingham 4285a988416SJim Ingham }; 4295a988416SJim Ingham 4305a988416SJim Ingham protected: 431*13d21e9aSBruce Mitchener bool 4325a988416SJim Ingham DoExecute (Args& command, 433*13d21e9aSBruce Mitchener CommandReturnObject &result) override 43430fdc8d8SChris Lattner { 43533df7cd3SJim Ingham Target *target = GetSelectedOrDummyTarget(m_options.m_use_dummy); 43633df7cd3SJim Ingham 437893c932aSJim Ingham if (target == nullptr) 43830fdc8d8SChris Lattner { 439effe5c95SGreg Clayton result.AppendError ("Invalid target. Must set target before setting breakpoints (see 'target create' command)."); 44030fdc8d8SChris Lattner result.SetStatus (eReturnStatusFailed); 44130fdc8d8SChris Lattner return false; 44230fdc8d8SChris Lattner } 44330fdc8d8SChris Lattner 44430fdc8d8SChris Lattner // The following are the various types of breakpoints that could be set: 44530fdc8d8SChris Lattner // 1). -f -l -p [-s -g] (setting breakpoint by source location) 44630fdc8d8SChris Lattner // 2). -a [-s -g] (setting breakpoint by address) 44730fdc8d8SChris Lattner // 3). -n [-s -g] (setting breakpoint by function name) 44830fdc8d8SChris Lattner // 4). -r [-s -g] (setting breakpoint by function name regular expression) 449969795f1SJim Ingham // 5). -p -f (setting a breakpoint by comparing a reg-exp to source text) 450fab10e89SJim Ingham // 6). -E [-w -h] (setting a breakpoint for exceptions for a given language.) 45130fdc8d8SChris Lattner 45230fdc8d8SChris Lattner BreakpointSetType break_type = eSetTypeInvalid; 45330fdc8d8SChris Lattner 45430fdc8d8SChris Lattner if (m_options.m_line_num != 0) 45530fdc8d8SChris Lattner break_type = eSetTypeFileAndLine; 45630fdc8d8SChris Lattner else if (m_options.m_load_addr != LLDB_INVALID_ADDRESS) 45730fdc8d8SChris Lattner break_type = eSetTypeAddress; 458fab10e89SJim Ingham else if (!m_options.m_func_names.empty()) 45930fdc8d8SChris Lattner break_type = eSetTypeFunctionName; 46030fdc8d8SChris Lattner else if (!m_options.m_func_regexp.empty()) 46130fdc8d8SChris Lattner break_type = eSetTypeFunctionRegexp; 462969795f1SJim Ingham else if (!m_options.m_source_text_regexp.empty()) 463969795f1SJim Ingham break_type = eSetTypeSourceRegexp; 464a72b31c7SJim Ingham else if (m_options.m_exception_language != eLanguageTypeUnknown) 465fab10e89SJim Ingham break_type = eSetTypeException; 46630fdc8d8SChris Lattner 46730fdc8d8SChris Lattner Breakpoint *bp = NULL; 468274060b6SGreg Clayton FileSpec module_spec; 469a8558b62SJim Ingham const bool internal = false; 470a8558b62SJim Ingham 47130fdc8d8SChris Lattner switch (break_type) 47230fdc8d8SChris Lattner { 47330fdc8d8SChris Lattner case eSetTypeFileAndLine: // Breakpoint by source position 47430fdc8d8SChris Lattner { 47530fdc8d8SChris Lattner FileSpec file; 476c7bece56SGreg Clayton const size_t num_files = m_options.m_filenames.GetSize(); 47787df91b8SJim Ingham if (num_files == 0) 47887df91b8SJim Ingham { 47987df91b8SJim Ingham if (!GetDefaultFile (target, file, result)) 48087df91b8SJim Ingham { 48187df91b8SJim Ingham result.AppendError("No file supplied and no default file available."); 48287df91b8SJim Ingham result.SetStatus (eReturnStatusFailed); 48387df91b8SJim Ingham return false; 48487df91b8SJim Ingham } 48587df91b8SJim Ingham } 48687df91b8SJim Ingham else if (num_files > 1) 48787df91b8SJim Ingham { 48887df91b8SJim Ingham result.AppendError("Only one file at a time is allowed for file and line breakpoints."); 48987df91b8SJim Ingham result.SetStatus (eReturnStatusFailed); 49087df91b8SJim Ingham return false; 49187df91b8SJim Ingham } 49287df91b8SJim Ingham else 49387df91b8SJim Ingham file = m_options.m_filenames.GetFileSpecAtIndex(0); 49430fdc8d8SChris Lattner 4951f746071SGreg Clayton // Only check for inline functions if 4961f746071SGreg Clayton LazyBool check_inlines = eLazyBoolCalculate; 4971f746071SGreg Clayton 49887df91b8SJim Ingham bp = target->CreateBreakpoint (&(m_options.m_modules), 49930fdc8d8SChris Lattner file, 50030fdc8d8SChris Lattner m_options.m_line_num, 5011f746071SGreg Clayton check_inlines, 502a8558b62SJim Ingham m_options.m_skip_prologue, 503eb023e75SGreg Clayton internal, 504055ad9beSIlia K m_options.m_hardware, 505055ad9beSIlia K m_options.m_move_to_nearest_code).get(); 50630fdc8d8SChris Lattner } 50730fdc8d8SChris Lattner break; 5086eee5aa0SGreg Clayton 50930fdc8d8SChris Lattner case eSetTypeAddress: // Breakpoint by address 510eb023e75SGreg Clayton bp = target->CreateBreakpoint (m_options.m_load_addr, 511eb023e75SGreg Clayton internal, 512eb023e75SGreg Clayton m_options.m_hardware).get(); 51330fdc8d8SChris Lattner break; 5140c5cd90dSGreg Clayton 51530fdc8d8SChris Lattner case eSetTypeFunctionName: // Breakpoint by function name 5160c5cd90dSGreg Clayton { 5170c5cd90dSGreg Clayton uint32_t name_type_mask = m_options.m_func_name_type_mask; 5180c5cd90dSGreg Clayton 5190c5cd90dSGreg Clayton if (name_type_mask == 0) 520e02b8504SGreg Clayton name_type_mask = eFunctionNameTypeAuto; 5210c5cd90dSGreg Clayton 52287df91b8SJim Ingham bp = target->CreateBreakpoint (&(m_options.m_modules), 52387df91b8SJim Ingham &(m_options.m_filenames), 524fab10e89SJim Ingham m_options.m_func_names, 525274060b6SGreg Clayton name_type_mask, 52623b1decbSDawn Perchik m_options.m_language, 527a8558b62SJim Ingham m_options.m_skip_prologue, 528eb023e75SGreg Clayton internal, 529eb023e75SGreg Clayton m_options.m_hardware).get(); 5300c5cd90dSGreg Clayton } 53130fdc8d8SChris Lattner break; 5320c5cd90dSGreg Clayton 53330fdc8d8SChris Lattner case eSetTypeFunctionRegexp: // Breakpoint by regular expression function name 53430fdc8d8SChris Lattner { 53530fdc8d8SChris Lattner RegularExpression regexp(m_options.m_func_regexp.c_str()); 536969795f1SJim Ingham if (!regexp.IsValid()) 53730fdc8d8SChris Lattner { 538969795f1SJim Ingham char err_str[1024]; 539969795f1SJim Ingham regexp.GetErrorAsCString(err_str, sizeof(err_str)); 540969795f1SJim Ingham result.AppendErrorWithFormat("Function name regular expression could not be compiled: \"%s\"", 541969795f1SJim Ingham err_str); 54230fdc8d8SChris Lattner result.SetStatus (eReturnStatusFailed); 543969795f1SJim Ingham return false; 54430fdc8d8SChris Lattner } 54587df91b8SJim Ingham 546a8558b62SJim Ingham bp = target->CreateFuncRegexBreakpoint (&(m_options.m_modules), 547a8558b62SJim Ingham &(m_options.m_filenames), 548a8558b62SJim Ingham regexp, 549a8558b62SJim Ingham m_options.m_skip_prologue, 550eb023e75SGreg Clayton internal, 551eb023e75SGreg Clayton m_options.m_hardware).get(); 55230fdc8d8SChris Lattner } 55330fdc8d8SChris Lattner break; 554969795f1SJim Ingham case eSetTypeSourceRegexp: // Breakpoint by regexp on source text. 555969795f1SJim Ingham { 556c7bece56SGreg Clayton const size_t num_files = m_options.m_filenames.GetSize(); 55787df91b8SJim Ingham 558e732052fSJim Ingham if (num_files == 0 && !m_options.m_all_files) 55987df91b8SJim Ingham { 560969795f1SJim Ingham FileSpec file; 56187df91b8SJim Ingham if (!GetDefaultFile (target, file, result)) 56287df91b8SJim Ingham { 56387df91b8SJim Ingham result.AppendError ("No files provided and could not find default file."); 56487df91b8SJim Ingham result.SetStatus (eReturnStatusFailed); 56587df91b8SJim Ingham return false; 56687df91b8SJim Ingham } 56787df91b8SJim Ingham else 56887df91b8SJim Ingham { 56987df91b8SJim Ingham m_options.m_filenames.Append (file); 57087df91b8SJim Ingham } 57187df91b8SJim Ingham } 5720c5cd90dSGreg Clayton 573969795f1SJim Ingham RegularExpression regexp(m_options.m_source_text_regexp.c_str()); 574969795f1SJim Ingham if (!regexp.IsValid()) 575969795f1SJim Ingham { 576969795f1SJim Ingham char err_str[1024]; 577969795f1SJim Ingham regexp.GetErrorAsCString(err_str, sizeof(err_str)); 578969795f1SJim Ingham result.AppendErrorWithFormat("Source text regular expression could not be compiled: \"%s\"", 579969795f1SJim Ingham err_str); 580969795f1SJim Ingham result.SetStatus (eReturnStatusFailed); 581969795f1SJim Ingham return false; 582969795f1SJim Ingham } 583eb023e75SGreg Clayton bp = target->CreateSourceRegexBreakpoint (&(m_options.m_modules), 584eb023e75SGreg Clayton &(m_options.m_filenames), 585eb023e75SGreg Clayton regexp, 586eb023e75SGreg Clayton internal, 587055ad9beSIlia K m_options.m_hardware, 588055ad9beSIlia K m_options.m_move_to_nearest_code).get(); 589969795f1SJim Ingham } 590969795f1SJim Ingham break; 591fab10e89SJim Ingham case eSetTypeException: 592fab10e89SJim Ingham { 593a72b31c7SJim Ingham Error precond_error; 594a72b31c7SJim Ingham bp = target->CreateExceptionBreakpoint (m_options.m_exception_language, 595eb023e75SGreg Clayton m_options.m_catch_bp, 596eb023e75SGreg Clayton m_options.m_throw_bp, 597a72b31c7SJim Ingham internal, 598a72b31c7SJim Ingham &m_options.m_exception_extra_args, 599a72b31c7SJim Ingham &precond_error).get(); 600a72b31c7SJim Ingham if (precond_error.Fail()) 601a72b31c7SJim Ingham { 602a72b31c7SJim Ingham result.AppendErrorWithFormat("Error setting extra exception arguments: %s", 603a72b31c7SJim Ingham precond_error.AsCString()); 604a72b31c7SJim Ingham target->RemoveBreakpointByID(bp->GetID()); 605a72b31c7SJim Ingham result.SetStatus(eReturnStatusFailed); 606a72b31c7SJim Ingham return false; 607a72b31c7SJim Ingham } 608fab10e89SJim Ingham } 609fab10e89SJim Ingham break; 61030fdc8d8SChris Lattner default: 61130fdc8d8SChris Lattner break; 61230fdc8d8SChris Lattner } 61330fdc8d8SChris Lattner 6141b54c88cSJim Ingham // Now set the various options that were passed in: 6151b54c88cSJim Ingham if (bp) 6161b54c88cSJim Ingham { 6171b54c88cSJim Ingham if (m_options.m_thread_id != LLDB_INVALID_THREAD_ID) 6181b54c88cSJim Ingham bp->SetThreadID (m_options.m_thread_id); 6191b54c88cSJim Ingham 620c982c768SGreg Clayton if (m_options.m_thread_index != UINT32_MAX) 6211b54c88cSJim Ingham bp->GetOptions()->GetThreadSpec()->SetIndex(m_options.m_thread_index); 6221b54c88cSJim Ingham 6231b54c88cSJim Ingham if (!m_options.m_thread_name.empty()) 6241b54c88cSJim Ingham bp->GetOptions()->GetThreadSpec()->SetName(m_options.m_thread_name.c_str()); 6251b54c88cSJim Ingham 6261b54c88cSJim Ingham if (!m_options.m_queue_name.empty()) 6271b54c88cSJim Ingham bp->GetOptions()->GetThreadSpec()->SetQueueName(m_options.m_queue_name.c_str()); 6281b54c88cSJim Ingham 629c982c768SGreg Clayton if (m_options.m_ignore_count != 0) 6301b54c88cSJim Ingham bp->GetOptions()->SetIgnoreCount(m_options.m_ignore_count); 6317d49c9c8SJohnny Chen 6327d49c9c8SJohnny Chen if (!m_options.m_condition.empty()) 6337d49c9c8SJohnny Chen bp->GetOptions()->SetCondition(m_options.m_condition.c_str()); 634ca36cd16SJim Ingham 6355e09c8c3SJim Ingham if (!m_options.m_breakpoint_names.empty()) 6365e09c8c3SJim Ingham { 6375e09c8c3SJim Ingham Error error; // We don't need to check the error here, since the option parser checked it... 6385e09c8c3SJim Ingham for (auto name : m_options.m_breakpoint_names) 6395e09c8c3SJim Ingham bp->AddName(name.c_str(), error); 6405e09c8c3SJim Ingham } 6415e09c8c3SJim Ingham 642ca36cd16SJim Ingham bp->SetOneShot (m_options.m_one_shot); 6431b54c88cSJim Ingham } 6441b54c88cSJim Ingham 645969795f1SJim Ingham if (bp) 64630fdc8d8SChris Lattner { 64785e8b814SJim Ingham Stream &output_stream = result.GetOutputStream(); 6481391cc7dSJim Ingham const bool show_locations = false; 6491391cc7dSJim Ingham bp->GetDescription(&output_stream, lldb::eDescriptionLevelInitial, show_locations); 6504aeb1989SJim Ingham if (target == m_interpreter.GetDebugger().GetDummyTarget()) 6514aeb1989SJim Ingham output_stream.Printf ("Breakpoint set in dummy target, will get copied into future targets.\n"); 6524aeb1989SJim Ingham else 6534aeb1989SJim Ingham { 654fab10e89SJim Ingham // Don't print out this warning for exception breakpoints. They can get set before the target 655fab10e89SJim Ingham // is set, but we won't know how to actually set the breakpoint till we run. 656fab10e89SJim Ingham if (bp->GetNumLocations() == 0 && break_type != eSetTypeException) 6574aeb1989SJim Ingham { 658be484f41SCaroline Tice output_stream.Printf ("WARNING: Unable to resolve breakpoint to any actual locations.\n"); 6594aeb1989SJim Ingham } 6604aeb1989SJim Ingham } 66130fdc8d8SChris Lattner result.SetStatus (eReturnStatusSuccessFinishResult); 66230fdc8d8SChris Lattner } 66330fdc8d8SChris Lattner else if (!bp) 66430fdc8d8SChris Lattner { 66530fdc8d8SChris Lattner result.AppendError ("Breakpoint creation failed: No breakpoint created."); 66630fdc8d8SChris Lattner result.SetStatus (eReturnStatusFailed); 66730fdc8d8SChris Lattner } 66830fdc8d8SChris Lattner 66930fdc8d8SChris Lattner return result.Succeeded(); 67030fdc8d8SChris Lattner } 67130fdc8d8SChris Lattner 6725a988416SJim Ingham private: 6735a988416SJim Ingham bool 6745a988416SJim Ingham GetDefaultFile (Target *target, FileSpec &file, CommandReturnObject &result) 6755a988416SJim Ingham { 6765a988416SJim Ingham uint32_t default_line; 6775a988416SJim Ingham // First use the Source Manager's default file. 6785a988416SJim Ingham // Then use the current stack frame's file. 6795a988416SJim Ingham if (!target->GetSourceManager().GetDefaultFileAndLine(file, default_line)) 6805a988416SJim Ingham { 681b57e4a1bSJason Molenda StackFrame *cur_frame = m_exe_ctx.GetFramePtr(); 6825a988416SJim Ingham if (cur_frame == NULL) 6835a988416SJim Ingham { 6845a988416SJim Ingham result.AppendError ("No selected frame to use to find the default file."); 6855a988416SJim Ingham result.SetStatus (eReturnStatusFailed); 6865a988416SJim Ingham return false; 6875a988416SJim Ingham } 6885a988416SJim Ingham else if (!cur_frame->HasDebugInformation()) 6895a988416SJim Ingham { 6905a988416SJim Ingham result.AppendError ("Cannot use the selected frame to find the default file, it has no debug info."); 6915a988416SJim Ingham result.SetStatus (eReturnStatusFailed); 6925a988416SJim Ingham return false; 6935a988416SJim Ingham } 6945a988416SJim Ingham else 6955a988416SJim Ingham { 6965a988416SJim Ingham const SymbolContext &sc = cur_frame->GetSymbolContext (eSymbolContextLineEntry); 6975a988416SJim Ingham if (sc.line_entry.file) 6985a988416SJim Ingham { 6995a988416SJim Ingham file = sc.line_entry.file; 7005a988416SJim Ingham } 7015a988416SJim Ingham else 7025a988416SJim Ingham { 7035a988416SJim Ingham result.AppendError ("Can't find the file for the selected frame to use as the default file."); 7045a988416SJim Ingham result.SetStatus (eReturnStatusFailed); 7055a988416SJim Ingham return false; 7065a988416SJim Ingham } 7075a988416SJim Ingham } 7085a988416SJim Ingham } 7095a988416SJim Ingham return true; 7105a988416SJim Ingham } 7115a988416SJim Ingham 7125a988416SJim Ingham CommandOptions m_options; 7135a988416SJim Ingham }; 7145a988416SJim Ingham // If an additional option set beyond LLDB_OPTION_SET_10 is added, make sure to 7155a988416SJim Ingham // update the numbers passed to LLDB_OPT_SET_FROM_TO(...) appropriately. 7165a988416SJim Ingham #define LLDB_OPT_FILE ( LLDB_OPT_SET_FROM_TO(1, 9) & ~LLDB_OPT_SET_2 ) 7175a988416SJim Ingham #define LLDB_OPT_NOT_10 ( LLDB_OPT_SET_FROM_TO(1, 10) & ~LLDB_OPT_SET_10 ) 7185a988416SJim Ingham #define LLDB_OPT_SKIP_PROLOGUE ( LLDB_OPT_SET_1 | LLDB_OPT_SET_FROM_TO(3,8) ) 719055ad9beSIlia K #define LLDB_OPT_MOVE_TO_NEAREST_CODE ( LLDB_OPT_SET_1 | LLDB_OPT_SET_9 ) 72023b1decbSDawn Perchik #define LLDB_OPT_EXPR_LANGUAGE ( LLDB_OPT_SET_FROM_TO(3, 8) & ~LLDB_OPT_SET_7 ) 7215a988416SJim Ingham 7225a988416SJim Ingham OptionDefinition 7235a988416SJim Ingham CommandObjectBreakpointSet::CommandOptions::g_option_table[] = 7245a988416SJim Ingham { 725d37221dcSZachary Turner { LLDB_OPT_NOT_10, false, "shlib", 's', OptionParser::eRequiredArgument, NULL, NULL, CommandCompletions::eModuleCompletion, eArgTypeShlibName, 7265a988416SJim Ingham "Set the breakpoint only in this shared library. " 7275a988416SJim Ingham "Can repeat this option multiple times to specify multiple shared libraries."}, 7285a988416SJim Ingham 729d37221dcSZachary Turner { LLDB_OPT_SET_ALL, false, "ignore-count", 'i', OptionParser::eRequiredArgument, NULL, NULL, 0, eArgTypeCount, 7305a988416SJim Ingham "Set the number of times this breakpoint is skipped before stopping." }, 7315a988416SJim Ingham 732d37221dcSZachary Turner { LLDB_OPT_SET_ALL, false, "one-shot", 'o', OptionParser::eNoArgument, NULL, NULL, 0, eArgTypeNone, 733b2b256afSJim Ingham "The breakpoint is deleted the first time it causes a stop." }, 734ca36cd16SJim Ingham 735d37221dcSZachary Turner { LLDB_OPT_SET_ALL, false, "condition", 'c', OptionParser::eRequiredArgument, NULL, NULL, 0, eArgTypeExpression, 7365a988416SJim Ingham "The breakpoint stops only if this condition expression evaluates to true."}, 7375a988416SJim Ingham 738d37221dcSZachary Turner { LLDB_OPT_SET_ALL, false, "thread-index", 'x', OptionParser::eRequiredArgument, NULL, NULL, 0, eArgTypeThreadIndex, 739a89be91fSJim Ingham "The breakpoint stops only for the thread whose indeX matches this argument."}, 7405a988416SJim Ingham 741d37221dcSZachary Turner { LLDB_OPT_SET_ALL, false, "thread-id", 't', OptionParser::eRequiredArgument, NULL, NULL, 0, eArgTypeThreadID, 7425a988416SJim Ingham "The breakpoint stops only for the thread whose TID matches this argument."}, 7435a988416SJim Ingham 744d37221dcSZachary Turner { LLDB_OPT_SET_ALL, false, "thread-name", 'T', OptionParser::eRequiredArgument, NULL, NULL, 0, eArgTypeThreadName, 7455a988416SJim Ingham "The breakpoint stops only for the thread whose thread name matches this argument."}, 7465a988416SJim Ingham 747d37221dcSZachary Turner { LLDB_OPT_SET_ALL, false, "hardware", 'H', OptionParser::eNoArgument, NULL, NULL, 0, eArgTypeNone, 748eb023e75SGreg Clayton "Require the breakpoint to use hardware breakpoints."}, 749eb023e75SGreg Clayton 750d37221dcSZachary Turner { LLDB_OPT_SET_ALL, false, "queue-name", 'q', OptionParser::eRequiredArgument, NULL, NULL, 0, eArgTypeQueueName, 7515a988416SJim Ingham "The breakpoint stops only for threads in the queue whose name is given by this argument."}, 7525a988416SJim Ingham 753d37221dcSZachary Turner { LLDB_OPT_FILE, false, "file", 'f', OptionParser::eRequiredArgument, NULL, NULL, CommandCompletions::eSourceFileCompletion, eArgTypeFilename, 754289aca64SJim Ingham "Specifies the source file in which to set this breakpoint. " 755289aca64SJim Ingham "Note, by default lldb only looks for files that are #included if they use the standard include file extensions. " 7566394479eSJim Ingham "To set breakpoints on .c/.cpp/.m/.mm files that are #included, set target.inline-breakpoint-strategy" 757289aca64SJim Ingham " to \"always\"."}, 7585a988416SJim Ingham 759d37221dcSZachary Turner { LLDB_OPT_SET_1, true, "line", 'l', OptionParser::eRequiredArgument, NULL, NULL, 0, eArgTypeLineNum, 7605a988416SJim Ingham "Specifies the line number on which to set this breakpoint."}, 7615a988416SJim Ingham 7625a988416SJim Ingham // Comment out this option for the moment, as we don't actually use it, but will in the future. 7635a988416SJim Ingham // This way users won't see it, but the infrastructure is left in place. 764e2607b50SVirgile Bello // { 0, false, "column", 'C', OptionParser::eRequiredArgument, NULL, "<column>", 7655a988416SJim Ingham // "Set the breakpoint by source location at this particular column."}, 7665a988416SJim Ingham 767d37221dcSZachary Turner { LLDB_OPT_SET_2, true, "address", 'a', OptionParser::eRequiredArgument, NULL, NULL, 0, eArgTypeAddressOrExpression, 7685a988416SJim Ingham "Set the breakpoint by address, at the specified address."}, 7695a988416SJim Ingham 770d37221dcSZachary Turner { LLDB_OPT_SET_3, true, "name", 'n', OptionParser::eRequiredArgument, NULL, NULL, CommandCompletions::eSymbolCompletion, eArgTypeFunctionName, 771551262d7SJim Ingham "Set the breakpoint by function name. Can be repeated multiple times to make one breakpoint for multiple names" }, 7725a988416SJim Ingham 773d37221dcSZachary Turner { LLDB_OPT_SET_4, true, "fullname", 'F', OptionParser::eRequiredArgument, NULL, NULL, CommandCompletions::eSymbolCompletion, eArgTypeFullName, 7745a988416SJim Ingham "Set the breakpoint by fully qualified function names. For C++ this means namespaces and all arguments, and " 7755a988416SJim Ingham "for Objective C this means a full function prototype with class and selector. " 7765a988416SJim Ingham "Can be repeated multiple times to make one breakpoint for multiple names." }, 7775a988416SJim Ingham 778d37221dcSZachary Turner { LLDB_OPT_SET_5, true, "selector", 'S', OptionParser::eRequiredArgument, NULL, NULL, 0, eArgTypeSelector, 7795a988416SJim Ingham "Set the breakpoint by ObjC selector name. Can be repeated multiple times to make one breakpoint for multiple Selectors." }, 7805a988416SJim Ingham 781d37221dcSZachary Turner { LLDB_OPT_SET_6, true, "method", 'M', OptionParser::eRequiredArgument, NULL, NULL, 0, eArgTypeMethod, 7825a988416SJim Ingham "Set the breakpoint by C++ method names. Can be repeated multiple times to make one breakpoint for multiple methods." }, 7835a988416SJim Ingham 784d37221dcSZachary Turner { LLDB_OPT_SET_7, true, "func-regex", 'r', OptionParser::eRequiredArgument, NULL, NULL, 0, eArgTypeRegularExpression, 7855a988416SJim Ingham "Set the breakpoint by function name, evaluating a regular-expression to find the function name(s)." }, 7865a988416SJim Ingham 787d37221dcSZachary Turner { LLDB_OPT_SET_8, true, "basename", 'b', OptionParser::eRequiredArgument, NULL, NULL, CommandCompletions::eSymbolCompletion, eArgTypeFunctionName, 7885a988416SJim Ingham "Set the breakpoint by function basename (C++ namespaces and arguments will be ignored). " 7895a988416SJim Ingham "Can be repeated multiple times to make one breakpoint for multiple symbols." }, 7905a988416SJim Ingham 791d37221dcSZachary Turner { LLDB_OPT_SET_9, true, "source-pattern-regexp", 'p', OptionParser::eRequiredArgument, NULL, NULL, 0, eArgTypeRegularExpression, 792e96ade8bSJim Ingham "Set the breakpoint by specifying a regular expression which is matched against the source text in a source file or files " 793e96ade8bSJim Ingham "specified with the -f option. The -f option can be specified more than once. " 794e96ade8bSJim Ingham "If no source files are specified, uses the current \"default source file\"" }, 7955a988416SJim Ingham 796e732052fSJim Ingham { LLDB_OPT_SET_9, false, "all-files", 'A', OptionParser::eNoArgument, NULL, NULL, 0, eArgTypeNone, 797e732052fSJim Ingham "All files are searched for source pattern matches." }, 798e732052fSJim Ingham 799d37221dcSZachary Turner { LLDB_OPT_SET_10, true, "language-exception", 'E', OptionParser::eRequiredArgument, NULL, NULL, 0, eArgTypeLanguage, 8005a988416SJim Ingham "Set the breakpoint on exceptions thrown by the specified language (without options, on throw but not catch.)" }, 8015a988416SJim Ingham 802d37221dcSZachary Turner { LLDB_OPT_SET_10, false, "on-throw", 'w', OptionParser::eRequiredArgument, NULL, NULL, 0, eArgTypeBoolean, 8035a988416SJim Ingham "Set the breakpoint on exception throW." }, 8045a988416SJim Ingham 805d37221dcSZachary Turner { LLDB_OPT_SET_10, false, "on-catch", 'h', OptionParser::eRequiredArgument, NULL, NULL, 0, eArgTypeBoolean, 8065a988416SJim Ingham "Set the breakpoint on exception catcH." }, 8075a988416SJim Ingham 808a72b31c7SJim Ingham // Don't add this option till it actually does something useful... 809a72b31c7SJim Ingham // { LLDB_OPT_SET_10, false, "exception-typename", 'O', OptionParser::eRequiredArgument, NULL, NULL, 0, eArgTypeTypeName, 810a72b31c7SJim Ingham // "The breakpoint will only stop if an exception Object of this type is thrown. Can be repeated multiple times to stop for multiple object types" }, 811a72b31c7SJim Ingham 81223b1decbSDawn Perchik { LLDB_OPT_EXPR_LANGUAGE, false, "language", 'L', OptionParser::eRequiredArgument, NULL, NULL, 0, eArgTypeLanguage, 8134112ab98SDawn Perchik "Specifies the Language to use when interpreting the breakpoint's expression (note: currently only implemented for setting breakpoints on identifiers). If not set the target.language setting is used." }, 81423b1decbSDawn Perchik 815d37221dcSZachary Turner { LLDB_OPT_SKIP_PROLOGUE, false, "skip-prologue", 'K', OptionParser::eRequiredArgument, NULL, NULL, 0, eArgTypeBoolean, 8165a988416SJim Ingham "sKip the prologue if the breakpoint is at the beginning of a function. If not set the target.skip-prologue setting is used." }, 8175a988416SJim Ingham 81833df7cd3SJim Ingham { LLDB_OPT_SET_ALL, false, "dummy-breakpoints", 'D', OptionParser::eNoArgument, NULL, NULL, 0, eArgTypeNone, 81933df7cd3SJim Ingham "Sets Dummy breakpoints - i.e. breakpoints set before a file is provided, which prime new targets."}, 82033df7cd3SJim Ingham 8215e09c8c3SJim Ingham { LLDB_OPT_SET_ALL, false, "breakpoint-name", 'N', OptionParser::eRequiredArgument, NULL, NULL, 0, eArgTypeBreakpointName, 8225e09c8c3SJim Ingham "Adds this to the list of names for this breakopint."}, 8235e09c8c3SJim Ingham 824055ad9beSIlia K { LLDB_OPT_MOVE_TO_NEAREST_CODE, false, "move-to-nearest-code", 'm', OptionParser::eRequiredArgument, NULL, NULL, 0, eArgTypeBoolean, 825055ad9beSIlia K "Move breakpoints to nearest code. If not set the target.move-to-nearest-code setting is used." }, 826055ad9beSIlia K 827d37221dcSZachary Turner { 0, false, NULL, 0, 0, NULL, NULL, 0, eArgTypeNone, NULL } 8285a988416SJim Ingham }; 8295a988416SJim Ingham 8305a988416SJim Ingham //------------------------------------------------------------------------- 8315a988416SJim Ingham // CommandObjectBreakpointModify 8325a988416SJim Ingham //------------------------------------------------------------------------- 8335a988416SJim Ingham #pragma mark Modify 8345a988416SJim Ingham 8355a988416SJim Ingham class CommandObjectBreakpointModify : public CommandObjectParsed 8365a988416SJim Ingham { 8375a988416SJim Ingham public: 8385a988416SJim Ingham 8395a988416SJim Ingham CommandObjectBreakpointModify (CommandInterpreter &interpreter) : 8405a988416SJim Ingham CommandObjectParsed (interpreter, 8415a988416SJim Ingham "breakpoint modify", 8425a988416SJim Ingham "Modify the options on a breakpoint or set of breakpoints in the executable. " 8435a988416SJim Ingham "If no breakpoint is specified, acts on the last created breakpoint. " 8445a988416SJim Ingham "With the exception of -e, -d and -i, passing an empty argument clears the modification.", 8455a988416SJim Ingham NULL), 8465a988416SJim Ingham m_options (interpreter) 8475a988416SJim Ingham { 8485a988416SJim Ingham CommandArgumentEntry arg; 8495a988416SJim Ingham CommandObject::AddIDsArgumentData(arg, eArgTypeBreakpointID, eArgTypeBreakpointIDRange); 8505a988416SJim Ingham // Add the entry for the first argument for this command to the object's arguments vector. 8515a988416SJim Ingham m_arguments.push_back (arg); 8525a988416SJim Ingham } 8535a988416SJim Ingham 8545a988416SJim Ingham 855*13d21e9aSBruce Mitchener ~CommandObjectBreakpointModify () override {} 8565a988416SJim Ingham 857*13d21e9aSBruce Mitchener Options * 858*13d21e9aSBruce Mitchener GetOptions () override 8595a988416SJim Ingham { 8605a988416SJim Ingham return &m_options; 8615a988416SJim Ingham } 8625a988416SJim Ingham 8635a988416SJim Ingham class CommandOptions : public Options 8645a988416SJim Ingham { 8655a988416SJim Ingham public: 8665a988416SJim Ingham 8675a988416SJim Ingham CommandOptions (CommandInterpreter &interpreter) : 8685a988416SJim Ingham Options (interpreter), 8695a988416SJim Ingham m_ignore_count (0), 8705a988416SJim Ingham m_thread_id(LLDB_INVALID_THREAD_ID), 8715a988416SJim Ingham m_thread_id_passed(false), 8725a988416SJim Ingham m_thread_index (UINT32_MAX), 8735a988416SJim Ingham m_thread_index_passed(false), 8745a988416SJim Ingham m_thread_name(), 8755a988416SJim Ingham m_queue_name(), 8765a988416SJim Ingham m_condition (), 877ca36cd16SJim Ingham m_one_shot (false), 8785a988416SJim Ingham m_enable_passed (false), 8795a988416SJim Ingham m_enable_value (false), 8805a988416SJim Ingham m_name_passed (false), 8815a988416SJim Ingham m_queue_passed (false), 882ca36cd16SJim Ingham m_condition_passed (false), 88333df7cd3SJim Ingham m_one_shot_passed (false), 88433df7cd3SJim Ingham m_use_dummy (false) 8855a988416SJim Ingham { 8865a988416SJim Ingham } 8875a988416SJim Ingham 888*13d21e9aSBruce Mitchener ~CommandOptions () override {} 8895a988416SJim Ingham 890*13d21e9aSBruce Mitchener Error 891*13d21e9aSBruce Mitchener SetOptionValue (uint32_t option_idx, const char *option_arg) override 8925a988416SJim Ingham { 8935a988416SJim Ingham Error error; 8943bcdfc0eSGreg Clayton const int short_option = m_getopt_table[option_idx].val; 8955a988416SJim Ingham 8965a988416SJim Ingham switch (short_option) 8975a988416SJim Ingham { 8985a988416SJim Ingham case 'c': 8995a988416SJim Ingham if (option_arg != NULL) 9005a988416SJim Ingham m_condition.assign (option_arg); 9015a988416SJim Ingham else 9025a988416SJim Ingham m_condition.clear(); 9035a988416SJim Ingham m_condition_passed = true; 9045a988416SJim Ingham break; 9055a988416SJim Ingham case 'd': 9065a988416SJim Ingham m_enable_passed = true; 9075a988416SJim Ingham m_enable_value = false; 9085a988416SJim Ingham break; 90933df7cd3SJim Ingham case 'D': 91033df7cd3SJim Ingham m_use_dummy = true; 91133df7cd3SJim Ingham break; 9125a988416SJim Ingham case 'e': 9135a988416SJim Ingham m_enable_passed = true; 9145a988416SJim Ingham m_enable_value = true; 9155a988416SJim Ingham break; 9165a988416SJim Ingham case 'i': 9175a988416SJim Ingham { 9185275aaa0SVince Harron m_ignore_count = StringConvert::ToUInt32(option_arg, UINT32_MAX, 0); 9195a988416SJim Ingham if (m_ignore_count == UINT32_MAX) 9205a988416SJim Ingham error.SetErrorStringWithFormat ("invalid ignore count '%s'", option_arg); 9215a988416SJim Ingham } 9225a988416SJim Ingham break; 923ca36cd16SJim Ingham case 'o': 924ca36cd16SJim Ingham { 925ca36cd16SJim Ingham bool value, success; 926ca36cd16SJim Ingham value = Args::StringToBoolean(option_arg, false, &success); 927ca36cd16SJim Ingham if (success) 928ca36cd16SJim Ingham { 929ca36cd16SJim Ingham m_one_shot_passed = true; 930ca36cd16SJim Ingham m_one_shot = value; 931ca36cd16SJim Ingham } 932ca36cd16SJim Ingham else 933ca36cd16SJim Ingham error.SetErrorStringWithFormat("invalid boolean value '%s' passed for -o option", option_arg); 934ca36cd16SJim Ingham } 935ca36cd16SJim Ingham break; 9365a988416SJim Ingham case 't' : 9375a988416SJim Ingham { 9385a988416SJim Ingham if (option_arg[0] == '\0') 9395a988416SJim Ingham { 9405a988416SJim Ingham m_thread_id = LLDB_INVALID_THREAD_ID; 9415a988416SJim Ingham m_thread_id_passed = true; 9425a988416SJim Ingham } 9435a988416SJim Ingham else 9445a988416SJim Ingham { 9455275aaa0SVince Harron m_thread_id = StringConvert::ToUInt64(option_arg, LLDB_INVALID_THREAD_ID, 0); 9465a988416SJim Ingham if (m_thread_id == LLDB_INVALID_THREAD_ID) 9475a988416SJim Ingham error.SetErrorStringWithFormat ("invalid thread id string '%s'", option_arg); 9485a988416SJim Ingham else 9495a988416SJim Ingham m_thread_id_passed = true; 9505a988416SJim Ingham } 9515a988416SJim Ingham } 9525a988416SJim Ingham break; 9535a988416SJim Ingham case 'T': 9545a988416SJim Ingham if (option_arg != NULL) 9555a988416SJim Ingham m_thread_name.assign (option_arg); 9565a988416SJim Ingham else 9575a988416SJim Ingham m_thread_name.clear(); 9585a988416SJim Ingham m_name_passed = true; 9595a988416SJim Ingham break; 9605a988416SJim Ingham case 'q': 9615a988416SJim Ingham if (option_arg != NULL) 9625a988416SJim Ingham m_queue_name.assign (option_arg); 9635a988416SJim Ingham else 9645a988416SJim Ingham m_queue_name.clear(); 9655a988416SJim Ingham m_queue_passed = true; 9665a988416SJim Ingham break; 9675a988416SJim Ingham case 'x': 9685a988416SJim Ingham { 9695a988416SJim Ingham if (option_arg[0] == '\n') 9705a988416SJim Ingham { 9715a988416SJim Ingham m_thread_index = UINT32_MAX; 9725a988416SJim Ingham m_thread_index_passed = true; 9735a988416SJim Ingham } 9745a988416SJim Ingham else 9755a988416SJim Ingham { 9765275aaa0SVince Harron m_thread_index = StringConvert::ToUInt32 (option_arg, UINT32_MAX, 0); 9775a988416SJim Ingham if (m_thread_id == UINT32_MAX) 9785a988416SJim Ingham error.SetErrorStringWithFormat ("invalid thread index string '%s'", option_arg); 9795a988416SJim Ingham else 9805a988416SJim Ingham m_thread_index_passed = true; 9815a988416SJim Ingham } 9825a988416SJim Ingham } 9835a988416SJim Ingham break; 9845a988416SJim Ingham default: 9855a988416SJim Ingham error.SetErrorStringWithFormat ("unrecognized option '%c'", short_option); 9865a988416SJim Ingham break; 9875a988416SJim Ingham } 9885a988416SJim Ingham 9895a988416SJim Ingham return error; 9905a988416SJim Ingham } 9915a988416SJim Ingham void 992*13d21e9aSBruce Mitchener OptionParsingStarting () override 9935a988416SJim Ingham { 9945a988416SJim Ingham m_ignore_count = 0; 9955a988416SJim Ingham m_thread_id = LLDB_INVALID_THREAD_ID; 9965a988416SJim Ingham m_thread_id_passed = false; 9975a988416SJim Ingham m_thread_index = UINT32_MAX; 9985a988416SJim Ingham m_thread_index_passed = false; 9995a988416SJim Ingham m_thread_name.clear(); 10005a988416SJim Ingham m_queue_name.clear(); 10015a988416SJim Ingham m_condition.clear(); 1002ca36cd16SJim Ingham m_one_shot = false; 10035a988416SJim Ingham m_enable_passed = false; 10045a988416SJim Ingham m_queue_passed = false; 10055a988416SJim Ingham m_name_passed = false; 10065a988416SJim Ingham m_condition_passed = false; 1007ca36cd16SJim Ingham m_one_shot_passed = false; 100833df7cd3SJim Ingham m_use_dummy = false; 10095a988416SJim Ingham } 10105a988416SJim Ingham 10115a988416SJim Ingham const OptionDefinition* 1012*13d21e9aSBruce Mitchener GetDefinitions () override 10135a988416SJim Ingham { 10145a988416SJim Ingham return g_option_table; 10155a988416SJim Ingham } 10165a988416SJim Ingham 10175a988416SJim Ingham 10185a988416SJim Ingham // Options table: Required for subclasses of Options. 10195a988416SJim Ingham 10205a988416SJim Ingham static OptionDefinition g_option_table[]; 10215a988416SJim Ingham 10225a988416SJim Ingham // Instance variables to hold the values for command options. 10235a988416SJim Ingham 10245a988416SJim Ingham uint32_t m_ignore_count; 10255a988416SJim Ingham lldb::tid_t m_thread_id; 10265a988416SJim Ingham bool m_thread_id_passed; 10275a988416SJim Ingham uint32_t m_thread_index; 10285a988416SJim Ingham bool m_thread_index_passed; 10295a988416SJim Ingham std::string m_thread_name; 10305a988416SJim Ingham std::string m_queue_name; 10315a988416SJim Ingham std::string m_condition; 1032ca36cd16SJim Ingham bool m_one_shot; 10335a988416SJim Ingham bool m_enable_passed; 10345a988416SJim Ingham bool m_enable_value; 10355a988416SJim Ingham bool m_name_passed; 10365a988416SJim Ingham bool m_queue_passed; 10375a988416SJim Ingham bool m_condition_passed; 1038ca36cd16SJim Ingham bool m_one_shot_passed; 103933df7cd3SJim Ingham bool m_use_dummy; 10405a988416SJim Ingham 10415a988416SJim Ingham }; 10425a988416SJim Ingham 10435a988416SJim Ingham protected: 1044*13d21e9aSBruce Mitchener bool 1045*13d21e9aSBruce Mitchener DoExecute (Args& command, CommandReturnObject &result) override 10465a988416SJim Ingham { 104733df7cd3SJim Ingham Target *target = GetSelectedOrDummyTarget(m_options.m_use_dummy); 10485a988416SJim Ingham if (target == NULL) 10495a988416SJim Ingham { 10505a988416SJim Ingham result.AppendError ("Invalid target. No existing target or breakpoints."); 10515a988416SJim Ingham result.SetStatus (eReturnStatusFailed); 10525a988416SJim Ingham return false; 10535a988416SJim Ingham } 10545a988416SJim Ingham 10555a988416SJim Ingham Mutex::Locker locker; 10565a988416SJim Ingham target->GetBreakpointList().GetListMutex(locker); 10575a988416SJim Ingham 10585a988416SJim Ingham BreakpointIDList valid_bp_ids; 10595a988416SJim Ingham 10605e09c8c3SJim Ingham CommandObjectMultiwordBreakpoint::VerifyBreakpointOrLocationIDs (command, target, result, &valid_bp_ids); 10615a988416SJim Ingham 10625a988416SJim Ingham if (result.Succeeded()) 10635a988416SJim Ingham { 10645a988416SJim Ingham const size_t count = valid_bp_ids.GetSize(); 10655a988416SJim Ingham for (size_t i = 0; i < count; ++i) 10665a988416SJim Ingham { 10675a988416SJim Ingham BreakpointID cur_bp_id = valid_bp_ids.GetBreakpointIDAtIndex (i); 10685a988416SJim Ingham 10695a988416SJim Ingham if (cur_bp_id.GetBreakpointID() != LLDB_INVALID_BREAK_ID) 10705a988416SJim Ingham { 10715a988416SJim Ingham Breakpoint *bp = target->GetBreakpointByID (cur_bp_id.GetBreakpointID()).get(); 10725a988416SJim Ingham if (cur_bp_id.GetLocationID() != LLDB_INVALID_BREAK_ID) 10735a988416SJim Ingham { 10745a988416SJim Ingham BreakpointLocation *location = bp->FindLocationByID (cur_bp_id.GetLocationID()).get(); 10755a988416SJim Ingham if (location) 10765a988416SJim Ingham { 10775a988416SJim Ingham if (m_options.m_thread_id_passed) 10785a988416SJim Ingham location->SetThreadID (m_options.m_thread_id); 10795a988416SJim Ingham 10805a988416SJim Ingham if (m_options.m_thread_index_passed) 10815a988416SJim Ingham location->SetThreadIndex(m_options.m_thread_index); 10825a988416SJim Ingham 10835a988416SJim Ingham if (m_options.m_name_passed) 10845a988416SJim Ingham location->SetThreadName(m_options.m_thread_name.c_str()); 10855a988416SJim Ingham 10865a988416SJim Ingham if (m_options.m_queue_passed) 10875a988416SJim Ingham location->SetQueueName(m_options.m_queue_name.c_str()); 10885a988416SJim Ingham 10895a988416SJim Ingham if (m_options.m_ignore_count != 0) 10905a988416SJim Ingham location->SetIgnoreCount(m_options.m_ignore_count); 10915a988416SJim Ingham 10925a988416SJim Ingham if (m_options.m_enable_passed) 10935a988416SJim Ingham location->SetEnabled (m_options.m_enable_value); 10945a988416SJim Ingham 10955a988416SJim Ingham if (m_options.m_condition_passed) 10965a988416SJim Ingham location->SetCondition (m_options.m_condition.c_str()); 10975a988416SJim Ingham } 10985a988416SJim Ingham } 10995a988416SJim Ingham else 11005a988416SJim Ingham { 11015a988416SJim Ingham if (m_options.m_thread_id_passed) 11025a988416SJim Ingham bp->SetThreadID (m_options.m_thread_id); 11035a988416SJim Ingham 11045a988416SJim Ingham if (m_options.m_thread_index_passed) 11055a988416SJim Ingham bp->SetThreadIndex(m_options.m_thread_index); 11065a988416SJim Ingham 11075a988416SJim Ingham if (m_options.m_name_passed) 11085a988416SJim Ingham bp->SetThreadName(m_options.m_thread_name.c_str()); 11095a988416SJim Ingham 11105a988416SJim Ingham if (m_options.m_queue_passed) 11115a988416SJim Ingham bp->SetQueueName(m_options.m_queue_name.c_str()); 11125a988416SJim Ingham 11135a988416SJim Ingham if (m_options.m_ignore_count != 0) 11145a988416SJim Ingham bp->SetIgnoreCount(m_options.m_ignore_count); 11155a988416SJim Ingham 11165a988416SJim Ingham if (m_options.m_enable_passed) 11175a988416SJim Ingham bp->SetEnabled (m_options.m_enable_value); 11185a988416SJim Ingham 11195a988416SJim Ingham if (m_options.m_condition_passed) 11205a988416SJim Ingham bp->SetCondition (m_options.m_condition.c_str()); 11215a988416SJim Ingham } 11225a988416SJim Ingham } 11235a988416SJim Ingham } 11245a988416SJim Ingham } 11255a988416SJim Ingham 11265a988416SJim Ingham return result.Succeeded(); 11275a988416SJim Ingham } 11285a988416SJim Ingham 11295a988416SJim Ingham private: 11305a988416SJim Ingham CommandOptions m_options; 11315a988416SJim Ingham }; 11325a988416SJim Ingham 11335a988416SJim Ingham #pragma mark Modify::CommandOptions 11345a988416SJim Ingham OptionDefinition 11355a988416SJim Ingham CommandObjectBreakpointModify::CommandOptions::g_option_table[] = 11365a988416SJim Ingham { 1137d37221dcSZachary Turner { LLDB_OPT_SET_ALL, false, "ignore-count", 'i', OptionParser::eRequiredArgument, NULL, NULL, 0, eArgTypeCount, "Set the number of times this breakpoint is skipped before stopping." }, 1138d37221dcSZachary Turner { LLDB_OPT_SET_ALL, false, "one-shot", 'o', OptionParser::eRequiredArgument, NULL, NULL, 0, eArgTypeBoolean, "The breakpoint is deleted the first time it stop causes a stop." }, 1139d37221dcSZachary Turner { LLDB_OPT_SET_ALL, false, "thread-index", 'x', OptionParser::eRequiredArgument, NULL, NULL, 0, eArgTypeThreadIndex, "The breakpoint stops only for the thread whose index matches this argument."}, 1140d37221dcSZachary Turner { LLDB_OPT_SET_ALL, false, "thread-id", 't', OptionParser::eRequiredArgument, NULL, NULL, 0, eArgTypeThreadID, "The breakpoint stops only for the thread whose TID matches this argument."}, 1141d37221dcSZachary Turner { LLDB_OPT_SET_ALL, false, "thread-name", 'T', OptionParser::eRequiredArgument, NULL, NULL, 0, eArgTypeThreadName, "The breakpoint stops only for the thread whose thread name matches this argument."}, 1142d37221dcSZachary Turner { LLDB_OPT_SET_ALL, false, "queue-name", 'q', OptionParser::eRequiredArgument, NULL, NULL, 0, eArgTypeQueueName, "The breakpoint stops only for threads in the queue whose name is given by this argument."}, 1143d37221dcSZachary Turner { LLDB_OPT_SET_ALL, false, "condition", 'c', OptionParser::eRequiredArgument, NULL, NULL, 0, eArgTypeExpression, "The breakpoint stops only if this condition expression evaluates to true."}, 1144d37221dcSZachary Turner { LLDB_OPT_SET_1, false, "enable", 'e', OptionParser::eNoArgument, NULL, NULL, 0, eArgTypeNone, "Enable the breakpoint."}, 1145d37221dcSZachary Turner { LLDB_OPT_SET_2, false, "disable", 'd', OptionParser::eNoArgument, NULL, NULL, 0, eArgTypeNone, "Disable the breakpoint."}, 114633df7cd3SJim Ingham { LLDB_OPT_SET_ALL, false, "dummy-breakpoints", 'D', OptionParser::eNoArgument, NULL, NULL, 0, eArgTypeNone, "Sets Dummy breakpoints - i.e. breakpoints set before a file is provided, which prime new targets."}, 114733df7cd3SJim Ingham 1148d37221dcSZachary Turner { 0, false, NULL, 0 , 0, NULL, NULL, 0, eArgTypeNone, NULL } 11495a988416SJim Ingham }; 11505a988416SJim Ingham 11515a988416SJim Ingham //------------------------------------------------------------------------- 11525a988416SJim Ingham // CommandObjectBreakpointEnable 11535a988416SJim Ingham //------------------------------------------------------------------------- 11545a988416SJim Ingham #pragma mark Enable 11555a988416SJim Ingham 11565a988416SJim Ingham class CommandObjectBreakpointEnable : public CommandObjectParsed 11575a988416SJim Ingham { 11585a988416SJim Ingham public: 11595a988416SJim Ingham CommandObjectBreakpointEnable (CommandInterpreter &interpreter) : 11605a988416SJim Ingham CommandObjectParsed (interpreter, 11615a988416SJim Ingham "enable", 11625a988416SJim Ingham "Enable the specified disabled breakpoint(s). If no breakpoints are specified, enable all of them.", 11635a988416SJim Ingham NULL) 11645a988416SJim Ingham { 11655a988416SJim Ingham CommandArgumentEntry arg; 11665a988416SJim Ingham CommandObject::AddIDsArgumentData(arg, eArgTypeBreakpointID, eArgTypeBreakpointIDRange); 11675a988416SJim Ingham // Add the entry for the first argument for this command to the object's arguments vector. 11685a988416SJim Ingham m_arguments.push_back (arg); 11695a988416SJim Ingham } 11705a988416SJim Ingham 11715a988416SJim Ingham 1172*13d21e9aSBruce Mitchener ~CommandObjectBreakpointEnable () override {} 11735a988416SJim Ingham 11745a988416SJim Ingham protected: 1175*13d21e9aSBruce Mitchener bool 1176*13d21e9aSBruce Mitchener DoExecute (Args& command, CommandReturnObject &result) override 11775a988416SJim Ingham { 1178893c932aSJim Ingham Target *target = GetSelectedOrDummyTarget(); 11795a988416SJim Ingham if (target == NULL) 11805a988416SJim Ingham { 11815a988416SJim Ingham result.AppendError ("Invalid target. No existing target or breakpoints."); 11825a988416SJim Ingham result.SetStatus (eReturnStatusFailed); 11835a988416SJim Ingham return false; 11845a988416SJim Ingham } 11855a988416SJim Ingham 11865a988416SJim Ingham Mutex::Locker locker; 11875a988416SJim Ingham target->GetBreakpointList().GetListMutex(locker); 11885a988416SJim Ingham 11895a988416SJim Ingham const BreakpointList &breakpoints = target->GetBreakpointList(); 11905a988416SJim Ingham 11915a988416SJim Ingham size_t num_breakpoints = breakpoints.GetSize(); 11925a988416SJim Ingham 11935a988416SJim Ingham if (num_breakpoints == 0) 11945a988416SJim Ingham { 11955a988416SJim Ingham result.AppendError ("No breakpoints exist to be enabled."); 11965a988416SJim Ingham result.SetStatus (eReturnStatusFailed); 11975a988416SJim Ingham return false; 11985a988416SJim Ingham } 11995a988416SJim Ingham 12005a988416SJim Ingham if (command.GetArgumentCount() == 0) 12015a988416SJim Ingham { 12025a988416SJim Ingham // No breakpoint selected; enable all currently set breakpoints. 12035a988416SJim Ingham target->EnableAllBreakpoints (); 12046fea17e8SGreg Clayton result.AppendMessageWithFormat ("All breakpoints enabled. (%" PRIu64 " breakpoints)\n", (uint64_t)num_breakpoints); 12055a988416SJim Ingham result.SetStatus (eReturnStatusSuccessFinishNoResult); 12065a988416SJim Ingham } 12075a988416SJim Ingham else 12085a988416SJim Ingham { 12095a988416SJim Ingham // Particular breakpoint selected; enable that breakpoint. 12105a988416SJim Ingham BreakpointIDList valid_bp_ids; 12115e09c8c3SJim Ingham CommandObjectMultiwordBreakpoint::VerifyBreakpointOrLocationIDs (command, target, result, &valid_bp_ids); 12125a988416SJim Ingham 12135a988416SJim Ingham if (result.Succeeded()) 12145a988416SJim Ingham { 12155a988416SJim Ingham int enable_count = 0; 12165a988416SJim Ingham int loc_count = 0; 12175a988416SJim Ingham const size_t count = valid_bp_ids.GetSize(); 12185a988416SJim Ingham for (size_t i = 0; i < count; ++i) 12195a988416SJim Ingham { 12205a988416SJim Ingham BreakpointID cur_bp_id = valid_bp_ids.GetBreakpointIDAtIndex (i); 12215a988416SJim Ingham 12225a988416SJim Ingham if (cur_bp_id.GetBreakpointID() != LLDB_INVALID_BREAK_ID) 12235a988416SJim Ingham { 12245a988416SJim Ingham Breakpoint *breakpoint = target->GetBreakpointByID (cur_bp_id.GetBreakpointID()).get(); 12255a988416SJim Ingham if (cur_bp_id.GetLocationID() != LLDB_INVALID_BREAK_ID) 12265a988416SJim Ingham { 12275a988416SJim Ingham BreakpointLocation *location = breakpoint->FindLocationByID (cur_bp_id.GetLocationID()).get(); 12285a988416SJim Ingham if (location) 12295a988416SJim Ingham { 12305a988416SJim Ingham location->SetEnabled (true); 12315a988416SJim Ingham ++loc_count; 12325a988416SJim Ingham } 12335a988416SJim Ingham } 12345a988416SJim Ingham else 12355a988416SJim Ingham { 12365a988416SJim Ingham breakpoint->SetEnabled (true); 12375a988416SJim Ingham ++enable_count; 12385a988416SJim Ingham } 12395a988416SJim Ingham } 12405a988416SJim Ingham } 12415a988416SJim Ingham result.AppendMessageWithFormat ("%d breakpoints enabled.\n", enable_count + loc_count); 12425a988416SJim Ingham result.SetStatus (eReturnStatusSuccessFinishNoResult); 12435a988416SJim Ingham } 12445a988416SJim Ingham } 12455a988416SJim Ingham 12465a988416SJim Ingham return result.Succeeded(); 12475a988416SJim Ingham } 12485a988416SJim Ingham }; 12495a988416SJim Ingham 12505a988416SJim Ingham //------------------------------------------------------------------------- 12515a988416SJim Ingham // CommandObjectBreakpointDisable 12525a988416SJim Ingham //------------------------------------------------------------------------- 12535a988416SJim Ingham #pragma mark Disable 12545a988416SJim Ingham 12555a988416SJim Ingham class CommandObjectBreakpointDisable : public CommandObjectParsed 12565a988416SJim Ingham { 12575a988416SJim Ingham public: 12585a988416SJim Ingham CommandObjectBreakpointDisable (CommandInterpreter &interpreter) : 12595a988416SJim Ingham CommandObjectParsed (interpreter, 12605a988416SJim Ingham "breakpoint disable", 1261ea671fbdSKate Stone "Disable the specified breakpoint(s) without removing them. If none are specified, disable all breakpoints.", 12625a988416SJim Ingham NULL) 12635a988416SJim Ingham { 1264b0fac509SJim Ingham SetHelpLong( 1265ea671fbdSKate Stone "Disable the specified breakpoint(s) without removing them. \ 1266ea671fbdSKate Stone If none are specified, disable all breakpoints." R"( 1267ea671fbdSKate Stone 1268ea671fbdSKate Stone )" "Note: disabling a breakpoint will cause none of its locations to be hit \ 1269ea671fbdSKate Stone regardless of whether they are enabled or disabled. After the sequence:" R"( 1270ea671fbdSKate Stone 1271ea671fbdSKate Stone (lldb) break disable 1 1272ea671fbdSKate Stone (lldb) break enable 1.1 1273ea671fbdSKate Stone 1274ea671fbdSKate Stone execution will NOT stop at location 1.1. To achieve that, type: 1275ea671fbdSKate Stone 1276ea671fbdSKate Stone (lldb) break disable 1.* 1277ea671fbdSKate Stone (lldb) break enable 1.1 1278ea671fbdSKate Stone 1279ea671fbdSKate Stone )" "The first command disables all the locations of breakpoint 1, \ 1280b0fac509SJim Ingham the second re-enables the first location." 1281b0fac509SJim Ingham ); 1282b0fac509SJim Ingham 12835a988416SJim Ingham CommandArgumentEntry arg; 12845a988416SJim Ingham CommandObject::AddIDsArgumentData(arg, eArgTypeBreakpointID, eArgTypeBreakpointIDRange); 12855a988416SJim Ingham // Add the entry for the first argument for this command to the object's arguments vector. 12865a988416SJim Ingham m_arguments.push_back (arg); 1287b0fac509SJim Ingham 12885a988416SJim Ingham } 12895a988416SJim Ingham 12905a988416SJim Ingham 1291*13d21e9aSBruce Mitchener ~CommandObjectBreakpointDisable () override {} 12925a988416SJim Ingham 12935a988416SJim Ingham protected: 1294*13d21e9aSBruce Mitchener bool 1295*13d21e9aSBruce Mitchener DoExecute (Args& command, CommandReturnObject &result) override 12965a988416SJim Ingham { 1297893c932aSJim Ingham Target *target = GetSelectedOrDummyTarget(); 12985a988416SJim Ingham if (target == NULL) 12995a988416SJim Ingham { 13005a988416SJim Ingham result.AppendError ("Invalid target. No existing target or breakpoints."); 13015a988416SJim Ingham result.SetStatus (eReturnStatusFailed); 13025a988416SJim Ingham return false; 13035a988416SJim Ingham } 13045a988416SJim Ingham 13055a988416SJim Ingham Mutex::Locker locker; 13065a988416SJim Ingham target->GetBreakpointList().GetListMutex(locker); 13075a988416SJim Ingham 13085a988416SJim Ingham const BreakpointList &breakpoints = target->GetBreakpointList(); 13095a988416SJim Ingham size_t num_breakpoints = breakpoints.GetSize(); 13105a988416SJim Ingham 13115a988416SJim Ingham if (num_breakpoints == 0) 13125a988416SJim Ingham { 13135a988416SJim Ingham result.AppendError ("No breakpoints exist to be disabled."); 13145a988416SJim Ingham result.SetStatus (eReturnStatusFailed); 13155a988416SJim Ingham return false; 13165a988416SJim Ingham } 13175a988416SJim Ingham 13185a988416SJim Ingham if (command.GetArgumentCount() == 0) 13195a988416SJim Ingham { 13205a988416SJim Ingham // No breakpoint selected; disable all currently set breakpoints. 13215a988416SJim Ingham target->DisableAllBreakpoints (); 13226fea17e8SGreg Clayton result.AppendMessageWithFormat ("All breakpoints disabled. (%" PRIu64 " breakpoints)\n", (uint64_t)num_breakpoints); 13235a988416SJim Ingham result.SetStatus (eReturnStatusSuccessFinishNoResult); 13245a988416SJim Ingham } 13255a988416SJim Ingham else 13265a988416SJim Ingham { 13275a988416SJim Ingham // Particular breakpoint selected; disable that breakpoint. 13285a988416SJim Ingham BreakpointIDList valid_bp_ids; 13295a988416SJim Ingham 13305e09c8c3SJim Ingham CommandObjectMultiwordBreakpoint::VerifyBreakpointOrLocationIDs (command, target, result, &valid_bp_ids); 13315a988416SJim Ingham 13325a988416SJim Ingham if (result.Succeeded()) 13335a988416SJim Ingham { 13345a988416SJim Ingham int disable_count = 0; 13355a988416SJim Ingham int loc_count = 0; 13365a988416SJim Ingham const size_t count = valid_bp_ids.GetSize(); 13375a988416SJim Ingham for (size_t i = 0; i < count; ++i) 13385a988416SJim Ingham { 13395a988416SJim Ingham BreakpointID cur_bp_id = valid_bp_ids.GetBreakpointIDAtIndex (i); 13405a988416SJim Ingham 13415a988416SJim Ingham if (cur_bp_id.GetBreakpointID() != LLDB_INVALID_BREAK_ID) 13425a988416SJim Ingham { 13435a988416SJim Ingham Breakpoint *breakpoint = target->GetBreakpointByID (cur_bp_id.GetBreakpointID()).get(); 13445a988416SJim Ingham if (cur_bp_id.GetLocationID() != LLDB_INVALID_BREAK_ID) 13455a988416SJim Ingham { 13465a988416SJim Ingham BreakpointLocation *location = breakpoint->FindLocationByID (cur_bp_id.GetLocationID()).get(); 13475a988416SJim Ingham if (location) 13485a988416SJim Ingham { 13495a988416SJim Ingham location->SetEnabled (false); 13505a988416SJim Ingham ++loc_count; 13515a988416SJim Ingham } 13525a988416SJim Ingham } 13535a988416SJim Ingham else 13545a988416SJim Ingham { 13555a988416SJim Ingham breakpoint->SetEnabled (false); 13565a988416SJim Ingham ++disable_count; 13575a988416SJim Ingham } 13585a988416SJim Ingham } 13595a988416SJim Ingham } 13605a988416SJim Ingham result.AppendMessageWithFormat ("%d breakpoints disabled.\n", disable_count + loc_count); 13615a988416SJim Ingham result.SetStatus (eReturnStatusSuccessFinishNoResult); 13625a988416SJim Ingham } 13635a988416SJim Ingham } 13645a988416SJim Ingham 13655a988416SJim Ingham return result.Succeeded(); 13665a988416SJim Ingham } 13675a988416SJim Ingham 13685a988416SJim Ingham }; 13695a988416SJim Ingham 13705a988416SJim Ingham //------------------------------------------------------------------------- 13715a988416SJim Ingham // CommandObjectBreakpointList 13725a988416SJim Ingham //------------------------------------------------------------------------- 13735a988416SJim Ingham #pragma mark List 13745a988416SJim Ingham 13755a988416SJim Ingham class CommandObjectBreakpointList : public CommandObjectParsed 13765a988416SJim Ingham { 13775a988416SJim Ingham public: 13785a988416SJim Ingham CommandObjectBreakpointList (CommandInterpreter &interpreter) : 13795a988416SJim Ingham CommandObjectParsed (interpreter, 13805a988416SJim Ingham "breakpoint list", 13815a988416SJim Ingham "List some or all breakpoints at configurable levels of detail.", 13825a988416SJim Ingham NULL), 13835a988416SJim Ingham m_options (interpreter) 13845a988416SJim Ingham { 13855a988416SJim Ingham CommandArgumentEntry arg; 13865a988416SJim Ingham CommandArgumentData bp_id_arg; 13875a988416SJim Ingham 13885a988416SJim Ingham // Define the first (and only) variant of this arg. 13895a988416SJim Ingham bp_id_arg.arg_type = eArgTypeBreakpointID; 13905a988416SJim Ingham bp_id_arg.arg_repetition = eArgRepeatOptional; 13915a988416SJim Ingham 13925a988416SJim Ingham // There is only one variant this argument could be; put it into the argument entry. 13935a988416SJim Ingham arg.push_back (bp_id_arg); 13945a988416SJim Ingham 13955a988416SJim Ingham // Push the data for the first argument into the m_arguments vector. 13965a988416SJim Ingham m_arguments.push_back (arg); 13975a988416SJim Ingham } 13985a988416SJim Ingham 13995a988416SJim Ingham 1400*13d21e9aSBruce Mitchener ~CommandObjectBreakpointList () override {} 14015a988416SJim Ingham 1402*13d21e9aSBruce Mitchener Options * 1403*13d21e9aSBruce Mitchener GetOptions () override 14045a988416SJim Ingham { 14055a988416SJim Ingham return &m_options; 14065a988416SJim Ingham } 14075a988416SJim Ingham 14085a988416SJim Ingham class CommandOptions : public Options 14095a988416SJim Ingham { 14105a988416SJim Ingham public: 14115a988416SJim Ingham 14125a988416SJim Ingham CommandOptions (CommandInterpreter &interpreter) : 14135a988416SJim Ingham Options (interpreter), 141433df7cd3SJim Ingham m_level (lldb::eDescriptionLevelBrief), 141533df7cd3SJim Ingham m_use_dummy(false) 14165a988416SJim Ingham { 14175a988416SJim Ingham } 14185a988416SJim Ingham 1419*13d21e9aSBruce Mitchener ~CommandOptions () override {} 14205a988416SJim Ingham 1421*13d21e9aSBruce Mitchener Error 1422*13d21e9aSBruce Mitchener SetOptionValue (uint32_t option_idx, const char *option_arg) override 14235a988416SJim Ingham { 14245a988416SJim Ingham Error error; 14253bcdfc0eSGreg Clayton const int short_option = m_getopt_table[option_idx].val; 14265a988416SJim Ingham 14275a988416SJim Ingham switch (short_option) 14285a988416SJim Ingham { 14295a988416SJim Ingham case 'b': 14305a988416SJim Ingham m_level = lldb::eDescriptionLevelBrief; 14315a988416SJim Ingham break; 143233df7cd3SJim Ingham case 'D': 143333df7cd3SJim Ingham m_use_dummy = true; 143433df7cd3SJim Ingham break; 14355a988416SJim Ingham case 'f': 14365a988416SJim Ingham m_level = lldb::eDescriptionLevelFull; 14375a988416SJim Ingham break; 14385a988416SJim Ingham case 'v': 14395a988416SJim Ingham m_level = lldb::eDescriptionLevelVerbose; 14405a988416SJim Ingham break; 14415a988416SJim Ingham case 'i': 14425a988416SJim Ingham m_internal = true; 14435a988416SJim Ingham break; 14445a988416SJim Ingham default: 14455a988416SJim Ingham error.SetErrorStringWithFormat ("unrecognized option '%c'", short_option); 14465a988416SJim Ingham break; 14475a988416SJim Ingham } 14485a988416SJim Ingham 14495a988416SJim Ingham return error; 14505a988416SJim Ingham } 14515a988416SJim Ingham 14525a988416SJim Ingham void 1453*13d21e9aSBruce Mitchener OptionParsingStarting () override 14545a988416SJim Ingham { 14555a988416SJim Ingham m_level = lldb::eDescriptionLevelFull; 14565a988416SJim Ingham m_internal = false; 145733df7cd3SJim Ingham m_use_dummy = false; 14585a988416SJim Ingham } 14595a988416SJim Ingham 14605a988416SJim Ingham const OptionDefinition * 1461*13d21e9aSBruce Mitchener GetDefinitions () override 14625a988416SJim Ingham { 14635a988416SJim Ingham return g_option_table; 14645a988416SJim Ingham } 14655a988416SJim Ingham 14665a988416SJim Ingham // Options table: Required for subclasses of Options. 14675a988416SJim Ingham 14685a988416SJim Ingham static OptionDefinition g_option_table[]; 14695a988416SJim Ingham 14705a988416SJim Ingham // Instance variables to hold the values for command options. 14715a988416SJim Ingham 14725a988416SJim Ingham lldb::DescriptionLevel m_level; 14735a988416SJim Ingham 14745a988416SJim Ingham bool m_internal; 147533df7cd3SJim Ingham bool m_use_dummy; 14765a988416SJim Ingham }; 14775a988416SJim Ingham 14785a988416SJim Ingham protected: 1479*13d21e9aSBruce Mitchener bool 1480*13d21e9aSBruce Mitchener DoExecute (Args& command, CommandReturnObject &result) override 14815a988416SJim Ingham { 148233df7cd3SJim Ingham Target *target = GetSelectedOrDummyTarget(m_options.m_use_dummy); 148333df7cd3SJim Ingham 14845a988416SJim Ingham if (target == NULL) 14855a988416SJim Ingham { 14865a988416SJim Ingham result.AppendError ("Invalid target. No current target or breakpoints."); 14875a988416SJim Ingham result.SetStatus (eReturnStatusSuccessFinishNoResult); 14885a988416SJim Ingham return true; 14895a988416SJim Ingham } 14905a988416SJim Ingham 14915a988416SJim Ingham const BreakpointList &breakpoints = target->GetBreakpointList(m_options.m_internal); 14925a988416SJim Ingham Mutex::Locker locker; 14935a988416SJim Ingham target->GetBreakpointList(m_options.m_internal).GetListMutex(locker); 14945a988416SJim Ingham 14955a988416SJim Ingham size_t num_breakpoints = breakpoints.GetSize(); 14965a988416SJim Ingham 14975a988416SJim Ingham if (num_breakpoints == 0) 14985a988416SJim Ingham { 14995a988416SJim Ingham result.AppendMessage ("No breakpoints currently set."); 15005a988416SJim Ingham result.SetStatus (eReturnStatusSuccessFinishNoResult); 15015a988416SJim Ingham return true; 15025a988416SJim Ingham } 15035a988416SJim Ingham 15045a988416SJim Ingham Stream &output_stream = result.GetOutputStream(); 15055a988416SJim Ingham 15065a988416SJim Ingham if (command.GetArgumentCount() == 0) 15075a988416SJim Ingham { 15085a988416SJim Ingham // No breakpoint selected; show info about all currently set breakpoints. 15095a988416SJim Ingham result.AppendMessage ("Current breakpoints:"); 15105a988416SJim Ingham for (size_t i = 0; i < num_breakpoints; ++i) 15115a988416SJim Ingham { 15125a988416SJim Ingham Breakpoint *breakpoint = breakpoints.GetBreakpointAtIndex (i).get(); 15135a988416SJim Ingham AddBreakpointDescription (&output_stream, breakpoint, m_options.m_level); 15145a988416SJim Ingham } 15155a988416SJim Ingham result.SetStatus (eReturnStatusSuccessFinishNoResult); 15165a988416SJim Ingham } 15175a988416SJim Ingham else 15185a988416SJim Ingham { 15195a988416SJim Ingham // Particular breakpoints selected; show info about that breakpoint. 15205a988416SJim Ingham BreakpointIDList valid_bp_ids; 15215e09c8c3SJim Ingham CommandObjectMultiwordBreakpoint::VerifyBreakpointOrLocationIDs (command, target, result, &valid_bp_ids); 15225a988416SJim Ingham 15235a988416SJim Ingham if (result.Succeeded()) 15245a988416SJim Ingham { 15255a988416SJim Ingham for (size_t i = 0; i < valid_bp_ids.GetSize(); ++i) 15265a988416SJim Ingham { 15275a988416SJim Ingham BreakpointID cur_bp_id = valid_bp_ids.GetBreakpointIDAtIndex (i); 15285a988416SJim Ingham Breakpoint *breakpoint = target->GetBreakpointByID (cur_bp_id.GetBreakpointID()).get(); 15295a988416SJim Ingham AddBreakpointDescription (&output_stream, breakpoint, m_options.m_level); 15305a988416SJim Ingham } 15315a988416SJim Ingham result.SetStatus (eReturnStatusSuccessFinishNoResult); 15325a988416SJim Ingham } 15335a988416SJim Ingham else 15345a988416SJim Ingham { 15355a988416SJim Ingham result.AppendError ("Invalid breakpoint id."); 15365a988416SJim Ingham result.SetStatus (eReturnStatusFailed); 15375a988416SJim Ingham } 15385a988416SJim Ingham } 15395a988416SJim Ingham 15405a988416SJim Ingham return result.Succeeded(); 15415a988416SJim Ingham } 15425a988416SJim Ingham 15435a988416SJim Ingham private: 15445a988416SJim Ingham CommandOptions m_options; 15455a988416SJim Ingham }; 15465a988416SJim Ingham 15475a988416SJim Ingham #pragma mark List::CommandOptions 15485a988416SJim Ingham OptionDefinition 15495a988416SJim Ingham CommandObjectBreakpointList::CommandOptions::g_option_table[] = 15505a988416SJim Ingham { 1551d37221dcSZachary Turner { LLDB_OPT_SET_ALL, false, "internal", 'i', OptionParser::eNoArgument, NULL, NULL, 0, eArgTypeNone, 15525a988416SJim Ingham "Show debugger internal breakpoints" }, 15535a988416SJim Ingham 1554d37221dcSZachary Turner { LLDB_OPT_SET_1, false, "brief", 'b', OptionParser::eNoArgument, NULL, NULL, 0, eArgTypeNone, 15555a988416SJim Ingham "Give a brief description of the breakpoint (no location info)."}, 15565a988416SJim Ingham 15575a988416SJim Ingham // FIXME: We need to add an "internal" command, and then add this sort of thing to it. 15585a988416SJim Ingham // But I need to see it for now, and don't want to wait. 1559d37221dcSZachary Turner { LLDB_OPT_SET_2, false, "full", 'f', OptionParser::eNoArgument, NULL, NULL, 0, eArgTypeNone, 15605a988416SJim Ingham "Give a full description of the breakpoint and its locations."}, 15615a988416SJim Ingham 1562d37221dcSZachary Turner { LLDB_OPT_SET_3, false, "verbose", 'v', OptionParser::eNoArgument, NULL, NULL, 0, eArgTypeNone, 15635a988416SJim Ingham "Explain everything we know about the breakpoint (for debugging debugger bugs)." }, 15645a988416SJim Ingham 156533df7cd3SJim Ingham { LLDB_OPT_SET_ALL, false, "dummy-breakpoints", 'D', OptionParser::eNoArgument, NULL, NULL, 0, eArgTypeNone, 156633df7cd3SJim Ingham "List Dummy breakpoints - i.e. breakpoints set before a file is provided, which prime new targets."}, 156733df7cd3SJim Ingham 1568d37221dcSZachary Turner { 0, false, NULL, 0, 0, NULL, NULL, 0, eArgTypeNone, NULL } 15695a988416SJim Ingham }; 15705a988416SJim Ingham 15715a988416SJim Ingham //------------------------------------------------------------------------- 15725a988416SJim Ingham // CommandObjectBreakpointClear 15735a988416SJim Ingham //------------------------------------------------------------------------- 15745a988416SJim Ingham #pragma mark Clear 15755a988416SJim Ingham 15765a988416SJim Ingham class CommandObjectBreakpointClear : public CommandObjectParsed 15775a988416SJim Ingham { 15785a988416SJim Ingham public: 15795a988416SJim Ingham 15805a988416SJim Ingham typedef enum BreakpointClearType 15815a988416SJim Ingham { 15825a988416SJim Ingham eClearTypeInvalid, 15835a988416SJim Ingham eClearTypeFileAndLine 15845a988416SJim Ingham } BreakpointClearType; 15855a988416SJim Ingham 15865a988416SJim Ingham CommandObjectBreakpointClear (CommandInterpreter &interpreter) : 15875a988416SJim Ingham CommandObjectParsed (interpreter, 15885a988416SJim Ingham "breakpoint clear", 15895a988416SJim Ingham "Clears a breakpoint or set of breakpoints in the executable.", 15905a988416SJim Ingham "breakpoint clear <cmd-options>"), 15915a988416SJim Ingham m_options (interpreter) 15925a988416SJim Ingham { 15935a988416SJim Ingham } 15945a988416SJim Ingham 1595*13d21e9aSBruce Mitchener ~CommandObjectBreakpointClear () override {} 15965a988416SJim Ingham 1597*13d21e9aSBruce Mitchener Options * 1598*13d21e9aSBruce Mitchener GetOptions () override 15995a988416SJim Ingham { 16005a988416SJim Ingham return &m_options; 16015a988416SJim Ingham } 16025a988416SJim Ingham 16035a988416SJim Ingham class CommandOptions : public Options 16045a988416SJim Ingham { 16055a988416SJim Ingham public: 16065a988416SJim Ingham 16075a988416SJim Ingham CommandOptions (CommandInterpreter &interpreter) : 16085a988416SJim Ingham Options (interpreter), 16095a988416SJim Ingham m_filename (), 16105a988416SJim Ingham m_line_num (0) 16115a988416SJim Ingham { 16125a988416SJim Ingham } 16135a988416SJim Ingham 1614*13d21e9aSBruce Mitchener ~CommandOptions () override {} 16155a988416SJim Ingham 1616*13d21e9aSBruce Mitchener Error 1617*13d21e9aSBruce Mitchener SetOptionValue (uint32_t option_idx, const char *option_arg) override 16185a988416SJim Ingham { 16195a988416SJim Ingham Error error; 16203bcdfc0eSGreg Clayton const int short_option = m_getopt_table[option_idx].val; 16215a988416SJim Ingham 16225a988416SJim Ingham switch (short_option) 16235a988416SJim Ingham { 16245a988416SJim Ingham case 'f': 16255a988416SJim Ingham m_filename.assign (option_arg); 16265a988416SJim Ingham break; 16275a988416SJim Ingham 16285a988416SJim Ingham case 'l': 16295275aaa0SVince Harron m_line_num = StringConvert::ToUInt32 (option_arg, 0); 16305a988416SJim Ingham break; 16315a988416SJim Ingham 16325a988416SJim Ingham default: 16335a988416SJim Ingham error.SetErrorStringWithFormat ("unrecognized option '%c'", short_option); 16345a988416SJim Ingham break; 16355a988416SJim Ingham } 16365a988416SJim Ingham 16375a988416SJim Ingham return error; 16385a988416SJim Ingham } 16395a988416SJim Ingham 16405a988416SJim Ingham void 1641*13d21e9aSBruce Mitchener OptionParsingStarting () override 16425a988416SJim Ingham { 16435a988416SJim Ingham m_filename.clear(); 16445a988416SJim Ingham m_line_num = 0; 16455a988416SJim Ingham } 16465a988416SJim Ingham 16475a988416SJim Ingham const OptionDefinition* 1648*13d21e9aSBruce Mitchener GetDefinitions () override 16495a988416SJim Ingham { 16505a988416SJim Ingham return g_option_table; 16515a988416SJim Ingham } 16525a988416SJim Ingham 16535a988416SJim Ingham // Options table: Required for subclasses of Options. 16545a988416SJim Ingham 16555a988416SJim Ingham static OptionDefinition g_option_table[]; 16565a988416SJim Ingham 16575a988416SJim Ingham // Instance variables to hold the values for command options. 16585a988416SJim Ingham 16595a988416SJim Ingham std::string m_filename; 16605a988416SJim Ingham uint32_t m_line_num; 16615a988416SJim Ingham 16625a988416SJim Ingham }; 16635a988416SJim Ingham 16645a988416SJim Ingham protected: 1665*13d21e9aSBruce Mitchener bool 1666*13d21e9aSBruce Mitchener DoExecute (Args& command, CommandReturnObject &result) override 16675a988416SJim Ingham { 1668893c932aSJim Ingham Target *target = GetSelectedOrDummyTarget(); 16695a988416SJim Ingham if (target == NULL) 16705a988416SJim Ingham { 16715a988416SJim Ingham result.AppendError ("Invalid target. No existing target or breakpoints."); 16725a988416SJim Ingham result.SetStatus (eReturnStatusFailed); 16735a988416SJim Ingham return false; 16745a988416SJim Ingham } 16755a988416SJim Ingham 16765a988416SJim Ingham // The following are the various types of breakpoints that could be cleared: 16775a988416SJim Ingham // 1). -f -l (clearing breakpoint by source location) 16785a988416SJim Ingham 16795a988416SJim Ingham BreakpointClearType break_type = eClearTypeInvalid; 16805a988416SJim Ingham 16815a988416SJim Ingham if (m_options.m_line_num != 0) 16825a988416SJim Ingham break_type = eClearTypeFileAndLine; 16835a988416SJim Ingham 16845a988416SJim Ingham Mutex::Locker locker; 16855a988416SJim Ingham target->GetBreakpointList().GetListMutex(locker); 16865a988416SJim Ingham 16875a988416SJim Ingham BreakpointList &breakpoints = target->GetBreakpointList(); 16885a988416SJim Ingham size_t num_breakpoints = breakpoints.GetSize(); 16895a988416SJim Ingham 16905a988416SJim Ingham // Early return if there's no breakpoint at all. 16915a988416SJim Ingham if (num_breakpoints == 0) 16925a988416SJim Ingham { 16935a988416SJim Ingham result.AppendError ("Breakpoint clear: No breakpoint cleared."); 16945a988416SJim Ingham result.SetStatus (eReturnStatusFailed); 16955a988416SJim Ingham return result.Succeeded(); 16965a988416SJim Ingham } 16975a988416SJim Ingham 16985a988416SJim Ingham // Find matching breakpoints and delete them. 16995a988416SJim Ingham 17005a988416SJim Ingham // First create a copy of all the IDs. 17015a988416SJim Ingham std::vector<break_id_t> BreakIDs; 17025a988416SJim Ingham for (size_t i = 0; i < num_breakpoints; ++i) 17035a988416SJim Ingham BreakIDs.push_back(breakpoints.GetBreakpointAtIndex(i).get()->GetID()); 17045a988416SJim Ingham 17055a988416SJim Ingham int num_cleared = 0; 17065a988416SJim Ingham StreamString ss; 17075a988416SJim Ingham switch (break_type) 17085a988416SJim Ingham { 17095a988416SJim Ingham case eClearTypeFileAndLine: // Breakpoint by source position 17105a988416SJim Ingham { 17115a988416SJim Ingham const ConstString filename(m_options.m_filename.c_str()); 17125a988416SJim Ingham BreakpointLocationCollection loc_coll; 17135a988416SJim Ingham 17145a988416SJim Ingham for (size_t i = 0; i < num_breakpoints; ++i) 17155a988416SJim Ingham { 17165a988416SJim Ingham Breakpoint *bp = breakpoints.FindBreakpointByID(BreakIDs[i]).get(); 17175a988416SJim Ingham 17185a988416SJim Ingham if (bp->GetMatchingFileLine(filename, m_options.m_line_num, loc_coll)) 17195a988416SJim Ingham { 17205a988416SJim Ingham // If the collection size is 0, it's a full match and we can just remove the breakpoint. 17215a988416SJim Ingham if (loc_coll.GetSize() == 0) 17225a988416SJim Ingham { 17235a988416SJim Ingham bp->GetDescription(&ss, lldb::eDescriptionLevelBrief); 17245a988416SJim Ingham ss.EOL(); 17255a988416SJim Ingham target->RemoveBreakpointByID (bp->GetID()); 17265a988416SJim Ingham ++num_cleared; 17275a988416SJim Ingham } 17285a988416SJim Ingham } 17295a988416SJim Ingham } 17305a988416SJim Ingham } 17315a988416SJim Ingham break; 17325a988416SJim Ingham 17335a988416SJim Ingham default: 17345a988416SJim Ingham break; 17355a988416SJim Ingham } 17365a988416SJim Ingham 17375a988416SJim Ingham if (num_cleared > 0) 17385a988416SJim Ingham { 17395a988416SJim Ingham Stream &output_stream = result.GetOutputStream(); 17405a988416SJim Ingham output_stream.Printf ("%d breakpoints cleared:\n", num_cleared); 17415a988416SJim Ingham output_stream << ss.GetData(); 17425a988416SJim Ingham output_stream.EOL(); 17435a988416SJim Ingham result.SetStatus (eReturnStatusSuccessFinishNoResult); 17445a988416SJim Ingham } 17455a988416SJim Ingham else 17465a988416SJim Ingham { 17475a988416SJim Ingham result.AppendError ("Breakpoint clear: No breakpoint cleared."); 17485a988416SJim Ingham result.SetStatus (eReturnStatusFailed); 17495a988416SJim Ingham } 17505a988416SJim Ingham 17515a988416SJim Ingham return result.Succeeded(); 17525a988416SJim Ingham } 17535a988416SJim Ingham 17545a988416SJim Ingham private: 17555a988416SJim Ingham CommandOptions m_options; 17565a988416SJim Ingham }; 17575a988416SJim Ingham 17585a988416SJim Ingham #pragma mark Clear::CommandOptions 17595a988416SJim Ingham 17605a988416SJim Ingham OptionDefinition 17615a988416SJim Ingham CommandObjectBreakpointClear::CommandOptions::g_option_table[] = 17625a988416SJim Ingham { 1763d37221dcSZachary Turner { LLDB_OPT_SET_1, false, "file", 'f', OptionParser::eRequiredArgument, NULL, NULL, CommandCompletions::eSourceFileCompletion, eArgTypeFilename, 17645a988416SJim Ingham "Specify the breakpoint by source location in this particular file."}, 17655a988416SJim Ingham 1766d37221dcSZachary Turner { LLDB_OPT_SET_1, true, "line", 'l', OptionParser::eRequiredArgument, NULL, NULL, 0, eArgTypeLineNum, 17675a988416SJim Ingham "Specify the breakpoint by source location at this particular line."}, 17685a988416SJim Ingham 1769d37221dcSZachary Turner { 0, false, NULL, 0, 0, NULL, NULL, 0, eArgTypeNone, NULL } 17705a988416SJim Ingham }; 17715a988416SJim Ingham 17725a988416SJim Ingham //------------------------------------------------------------------------- 17735a988416SJim Ingham // CommandObjectBreakpointDelete 17745a988416SJim Ingham //------------------------------------------------------------------------- 17755a988416SJim Ingham #pragma mark Delete 17765a988416SJim Ingham 17775a988416SJim Ingham class CommandObjectBreakpointDelete : public CommandObjectParsed 17785a988416SJim Ingham { 17795a988416SJim Ingham public: 17805a988416SJim Ingham CommandObjectBreakpointDelete (CommandInterpreter &interpreter) : 17815a988416SJim Ingham CommandObjectParsed (interpreter, 17825a988416SJim Ingham "breakpoint delete", 17835a988416SJim Ingham "Delete the specified breakpoint(s). If no breakpoints are specified, delete them all.", 178433df7cd3SJim Ingham NULL), 178533df7cd3SJim Ingham m_options (interpreter) 17865a988416SJim Ingham { 17875a988416SJim Ingham CommandArgumentEntry arg; 17885a988416SJim Ingham CommandObject::AddIDsArgumentData(arg, eArgTypeBreakpointID, eArgTypeBreakpointIDRange); 17895a988416SJim Ingham // Add the entry for the first argument for this command to the object's arguments vector. 17905a988416SJim Ingham m_arguments.push_back (arg); 17915a988416SJim Ingham } 17925a988416SJim Ingham 1793*13d21e9aSBruce Mitchener ~CommandObjectBreakpointDelete () override {} 17945a988416SJim Ingham 1795*13d21e9aSBruce Mitchener Options * 1796*13d21e9aSBruce Mitchener GetOptions () override 179733df7cd3SJim Ingham { 179833df7cd3SJim Ingham return &m_options; 179933df7cd3SJim Ingham } 180033df7cd3SJim Ingham 180133df7cd3SJim Ingham class CommandOptions : public Options 180233df7cd3SJim Ingham { 180333df7cd3SJim Ingham public: 180433df7cd3SJim Ingham 180533df7cd3SJim Ingham CommandOptions (CommandInterpreter &interpreter) : 180633df7cd3SJim Ingham Options (interpreter), 180733df7cd3SJim Ingham m_use_dummy (false), 180833df7cd3SJim Ingham m_force (false) 180933df7cd3SJim Ingham { 181033df7cd3SJim Ingham } 181133df7cd3SJim Ingham 1812*13d21e9aSBruce Mitchener ~CommandOptions () override {} 181333df7cd3SJim Ingham 1814*13d21e9aSBruce Mitchener Error 1815*13d21e9aSBruce Mitchener SetOptionValue (uint32_t option_idx, const char *option_arg) override 181633df7cd3SJim Ingham { 181733df7cd3SJim Ingham Error error; 181833df7cd3SJim Ingham const int short_option = m_getopt_table[option_idx].val; 181933df7cd3SJim Ingham 182033df7cd3SJim Ingham switch (short_option) 182133df7cd3SJim Ingham { 182233df7cd3SJim Ingham case 'f': 182333df7cd3SJim Ingham m_force = true; 182433df7cd3SJim Ingham break; 182533df7cd3SJim Ingham 182633df7cd3SJim Ingham case 'D': 182733df7cd3SJim Ingham m_use_dummy = true; 182833df7cd3SJim Ingham break; 182933df7cd3SJim Ingham 183033df7cd3SJim Ingham default: 183133df7cd3SJim Ingham error.SetErrorStringWithFormat ("unrecognized option '%c'", short_option); 183233df7cd3SJim Ingham break; 183333df7cd3SJim Ingham } 183433df7cd3SJim Ingham 183533df7cd3SJim Ingham return error; 183633df7cd3SJim Ingham } 183733df7cd3SJim Ingham 183833df7cd3SJim Ingham void 1839*13d21e9aSBruce Mitchener OptionParsingStarting () override 184033df7cd3SJim Ingham { 184133df7cd3SJim Ingham m_use_dummy = false; 184233df7cd3SJim Ingham m_force = false; 184333df7cd3SJim Ingham } 184433df7cd3SJim Ingham 184533df7cd3SJim Ingham const OptionDefinition* 1846*13d21e9aSBruce Mitchener GetDefinitions () override 184733df7cd3SJim Ingham { 184833df7cd3SJim Ingham return g_option_table; 184933df7cd3SJim Ingham } 185033df7cd3SJim Ingham 185133df7cd3SJim Ingham // Options table: Required for subclasses of Options. 185233df7cd3SJim Ingham 185333df7cd3SJim Ingham static OptionDefinition g_option_table[]; 185433df7cd3SJim Ingham 185533df7cd3SJim Ingham // Instance variables to hold the values for command options. 185633df7cd3SJim Ingham bool m_use_dummy; 185733df7cd3SJim Ingham bool m_force; 185833df7cd3SJim Ingham }; 185933df7cd3SJim Ingham 18605a988416SJim Ingham protected: 1861*13d21e9aSBruce Mitchener bool 1862*13d21e9aSBruce Mitchener DoExecute (Args& command, CommandReturnObject &result) override 18635a988416SJim Ingham { 186433df7cd3SJim Ingham Target *target = GetSelectedOrDummyTarget(m_options.m_use_dummy); 186533df7cd3SJim Ingham 18665a988416SJim Ingham if (target == NULL) 18675a988416SJim Ingham { 18685a988416SJim Ingham result.AppendError ("Invalid target. No existing target or breakpoints."); 18695a988416SJim Ingham result.SetStatus (eReturnStatusFailed); 18705a988416SJim Ingham return false; 18715a988416SJim Ingham } 18725a988416SJim Ingham 18735a988416SJim Ingham Mutex::Locker locker; 18745a988416SJim Ingham target->GetBreakpointList().GetListMutex(locker); 18755a988416SJim Ingham 18765a988416SJim Ingham const BreakpointList &breakpoints = target->GetBreakpointList(); 18775a988416SJim Ingham 18785a988416SJim Ingham size_t num_breakpoints = breakpoints.GetSize(); 18795a988416SJim Ingham 18805a988416SJim Ingham if (num_breakpoints == 0) 18815a988416SJim Ingham { 18825a988416SJim Ingham result.AppendError ("No breakpoints exist to be deleted."); 18835a988416SJim Ingham result.SetStatus (eReturnStatusFailed); 18845a988416SJim Ingham return false; 18855a988416SJim Ingham } 18865a988416SJim Ingham 18875a988416SJim Ingham if (command.GetArgumentCount() == 0) 18885a988416SJim Ingham { 188933df7cd3SJim Ingham if (!m_options.m_force && !m_interpreter.Confirm ("About to delete all breakpoints, do you want to do that?", true)) 18905a988416SJim Ingham { 18915a988416SJim Ingham result.AppendMessage("Operation cancelled..."); 18925a988416SJim Ingham } 18935a988416SJim Ingham else 18945a988416SJim Ingham { 18955a988416SJim Ingham target->RemoveAllBreakpoints (); 18966fea17e8SGreg Clayton result.AppendMessageWithFormat ("All breakpoints removed. (%" PRIu64 " breakpoint%s)\n", (uint64_t)num_breakpoints, num_breakpoints > 1 ? "s" : ""); 18975a988416SJim Ingham } 18985a988416SJim Ingham result.SetStatus (eReturnStatusSuccessFinishNoResult); 18995a988416SJim Ingham } 19005a988416SJim Ingham else 19015a988416SJim Ingham { 19025a988416SJim Ingham // Particular breakpoint selected; disable that breakpoint. 19035a988416SJim Ingham BreakpointIDList valid_bp_ids; 19045e09c8c3SJim Ingham CommandObjectMultiwordBreakpoint::VerifyBreakpointOrLocationIDs (command, target, result, &valid_bp_ids); 19055a988416SJim Ingham 19065a988416SJim Ingham if (result.Succeeded()) 19075a988416SJim Ingham { 19085a988416SJim Ingham int delete_count = 0; 19095a988416SJim Ingham int disable_count = 0; 19105a988416SJim Ingham const size_t count = valid_bp_ids.GetSize(); 19115a988416SJim Ingham for (size_t i = 0; i < count; ++i) 19125a988416SJim Ingham { 19135a988416SJim Ingham BreakpointID cur_bp_id = valid_bp_ids.GetBreakpointIDAtIndex (i); 19145a988416SJim Ingham 19155a988416SJim Ingham if (cur_bp_id.GetBreakpointID() != LLDB_INVALID_BREAK_ID) 19165a988416SJim Ingham { 19175a988416SJim Ingham if (cur_bp_id.GetLocationID() != LLDB_INVALID_BREAK_ID) 19185a988416SJim Ingham { 19195a988416SJim Ingham Breakpoint *breakpoint = target->GetBreakpointByID (cur_bp_id.GetBreakpointID()).get(); 19205a988416SJim Ingham BreakpointLocation *location = breakpoint->FindLocationByID (cur_bp_id.GetLocationID()).get(); 19215a988416SJim Ingham // It makes no sense to try to delete individual locations, so we disable them instead. 19225a988416SJim Ingham if (location) 19235a988416SJim Ingham { 19245a988416SJim Ingham location->SetEnabled (false); 19255a988416SJim Ingham ++disable_count; 19265a988416SJim Ingham } 19275a988416SJim Ingham } 19285a988416SJim Ingham else 19295a988416SJim Ingham { 19305a988416SJim Ingham target->RemoveBreakpointByID (cur_bp_id.GetBreakpointID()); 19315a988416SJim Ingham ++delete_count; 19325a988416SJim Ingham } 19335a988416SJim Ingham } 19345a988416SJim Ingham } 19355a988416SJim Ingham result.AppendMessageWithFormat ("%d breakpoints deleted; %d breakpoint locations disabled.\n", 19365a988416SJim Ingham delete_count, disable_count); 19375a988416SJim Ingham result.SetStatus (eReturnStatusSuccessFinishNoResult); 19385a988416SJim Ingham } 19395a988416SJim Ingham } 19405a988416SJim Ingham return result.Succeeded(); 19415a988416SJim Ingham } 194233df7cd3SJim Ingham private: 194333df7cd3SJim Ingham CommandOptions m_options; 194433df7cd3SJim Ingham }; 194533df7cd3SJim Ingham 194633df7cd3SJim Ingham OptionDefinition 194733df7cd3SJim Ingham CommandObjectBreakpointDelete::CommandOptions::g_option_table[] = 194833df7cd3SJim Ingham { 194933df7cd3SJim Ingham { LLDB_OPT_SET_1, false, "force", 'f', OptionParser::eNoArgument, NULL, NULL, 0, eArgTypeNone, 195033df7cd3SJim Ingham "Delete all breakpoints without querying for confirmation."}, 195133df7cd3SJim Ingham 195233df7cd3SJim Ingham { LLDB_OPT_SET_1, false, "dummy-breakpoints", 'D', OptionParser::eNoArgument, NULL, NULL, 0, eArgTypeNone, 195333df7cd3SJim Ingham "Delete Dummy breakpoints - i.e. breakpoints set before a file is provided, which prime new targets."}, 195433df7cd3SJim Ingham 195533df7cd3SJim Ingham { 0, false, NULL, 0, 0, NULL, NULL, 0, eArgTypeNone, NULL } 19565a988416SJim Ingham }; 19575a988416SJim Ingham 195830fdc8d8SChris Lattner //------------------------------------------------------------------------- 19595e09c8c3SJim Ingham // CommandObjectBreakpointName 19605e09c8c3SJim Ingham //------------------------------------------------------------------------- 19615e09c8c3SJim Ingham 19625e09c8c3SJim Ingham static OptionDefinition 19635e09c8c3SJim Ingham g_breakpoint_name_options[] = 19645e09c8c3SJim Ingham { 19655e09c8c3SJim Ingham { LLDB_OPT_SET_1, false, "name", 'N', OptionParser::eRequiredArgument, NULL, NULL, 0, eArgTypeBreakpointName, "Specifies a breakpoint name to use."}, 19665e09c8c3SJim Ingham { LLDB_OPT_SET_2, false, "breakpoint-id", 'B', OptionParser::eRequiredArgument, NULL, NULL, 0, eArgTypeBreakpointID, "Specify a breakpoint id to use."}, 19675e09c8c3SJim Ingham { LLDB_OPT_SET_ALL, false, "dummy-breakpoints", 'D', OptionParser::eNoArgument, NULL, NULL, 0, eArgTypeNone, 19685e09c8c3SJim Ingham "Operate on Dummy breakpoints - i.e. breakpoints set before a file is provided, which prime new targets."}, 19695e09c8c3SJim Ingham }; 19705e09c8c3SJim Ingham class BreakpointNameOptionGroup : public OptionGroup 19715e09c8c3SJim Ingham { 19725e09c8c3SJim Ingham public: 19735e09c8c3SJim Ingham BreakpointNameOptionGroup() : 19745e09c8c3SJim Ingham OptionGroup(), 19755e09c8c3SJim Ingham m_breakpoint(LLDB_INVALID_BREAK_ID), 19765e09c8c3SJim Ingham m_use_dummy (false) 19775e09c8c3SJim Ingham { 19785e09c8c3SJim Ingham 19795e09c8c3SJim Ingham } 19805e09c8c3SJim Ingham 1981*13d21e9aSBruce Mitchener ~BreakpointNameOptionGroup () override 19825e09c8c3SJim Ingham { 19835e09c8c3SJim Ingham } 19845e09c8c3SJim Ingham 1985*13d21e9aSBruce Mitchener uint32_t 1986*13d21e9aSBruce Mitchener GetNumDefinitions () override 19875e09c8c3SJim Ingham { 19885e09c8c3SJim Ingham return sizeof (g_breakpoint_name_options) / sizeof (OptionDefinition); 19895e09c8c3SJim Ingham } 19905e09c8c3SJim Ingham 1991*13d21e9aSBruce Mitchener const OptionDefinition* 1992*13d21e9aSBruce Mitchener GetDefinitions () override 19935e09c8c3SJim Ingham { 19945e09c8c3SJim Ingham return g_breakpoint_name_options; 19955e09c8c3SJim Ingham } 19965e09c8c3SJim Ingham 1997*13d21e9aSBruce Mitchener Error 19985e09c8c3SJim Ingham SetOptionValue (CommandInterpreter &interpreter, 19995e09c8c3SJim Ingham uint32_t option_idx, 2000*13d21e9aSBruce Mitchener const char *option_value) override 20015e09c8c3SJim Ingham { 20025e09c8c3SJim Ingham Error error; 20035e09c8c3SJim Ingham const int short_option = g_breakpoint_name_options[option_idx].short_option; 20045e09c8c3SJim Ingham 20055e09c8c3SJim Ingham switch (short_option) 20065e09c8c3SJim Ingham { 20075e09c8c3SJim Ingham case 'N': 20085e09c8c3SJim Ingham if (BreakpointID::StringIsBreakpointName(option_value, error) && error.Success()) 2009c95f7e2aSPavel Labath m_name.SetValueFromString(option_value); 20105e09c8c3SJim Ingham break; 20115e09c8c3SJim Ingham 20125e09c8c3SJim Ingham case 'B': 2013c95f7e2aSPavel Labath if (m_breakpoint.SetValueFromString(option_value).Fail()) 20145e09c8c3SJim Ingham error.SetErrorStringWithFormat ("unrecognized value \"%s\" for breakpoint", option_value); 20155e09c8c3SJim Ingham break; 20165e09c8c3SJim Ingham case 'D': 2017c95f7e2aSPavel Labath if (m_use_dummy.SetValueFromString(option_value).Fail()) 20185e09c8c3SJim Ingham error.SetErrorStringWithFormat ("unrecognized value \"%s\" for use-dummy", option_value); 20195e09c8c3SJim Ingham break; 20205e09c8c3SJim Ingham 20215e09c8c3SJim Ingham default: 20225e09c8c3SJim Ingham error.SetErrorStringWithFormat("unrecognized short option '%c'", short_option); 20235e09c8c3SJim Ingham break; 20245e09c8c3SJim Ingham } 20255e09c8c3SJim Ingham return error; 20265e09c8c3SJim Ingham } 20275e09c8c3SJim Ingham 2028*13d21e9aSBruce Mitchener void 2029*13d21e9aSBruce Mitchener OptionParsingStarting (CommandInterpreter &interpreter) override 20305e09c8c3SJim Ingham { 20315e09c8c3SJim Ingham m_name.Clear(); 20325e09c8c3SJim Ingham m_breakpoint.Clear(); 20335e09c8c3SJim Ingham m_use_dummy.Clear(); 20345e09c8c3SJim Ingham m_use_dummy.SetDefaultValue(false); 20355e09c8c3SJim Ingham } 20365e09c8c3SJim Ingham 20375e09c8c3SJim Ingham OptionValueString m_name; 20385e09c8c3SJim Ingham OptionValueUInt64 m_breakpoint; 20395e09c8c3SJim Ingham OptionValueBoolean m_use_dummy; 20405e09c8c3SJim Ingham }; 20415e09c8c3SJim Ingham 20425e09c8c3SJim Ingham 20435e09c8c3SJim Ingham class CommandObjectBreakpointNameAdd : public CommandObjectParsed 20445e09c8c3SJim Ingham { 20455e09c8c3SJim Ingham public: 20465e09c8c3SJim Ingham CommandObjectBreakpointNameAdd (CommandInterpreter &interpreter) : 20475e09c8c3SJim Ingham CommandObjectParsed (interpreter, 20485e09c8c3SJim Ingham "add", 20495e09c8c3SJim Ingham "Add a name to the breakpoints provided.", 20505e09c8c3SJim Ingham "breakpoint name add <command-options> <breakpoint-id-list>"), 20515e09c8c3SJim Ingham m_name_options(), 20525e09c8c3SJim Ingham m_option_group(interpreter) 20535e09c8c3SJim Ingham { 20545e09c8c3SJim Ingham // Create the first variant for the first (and only) argument for this command. 20555e09c8c3SJim Ingham CommandArgumentEntry arg1; 20565e09c8c3SJim Ingham CommandArgumentData id_arg; 20575e09c8c3SJim Ingham id_arg.arg_type = eArgTypeBreakpointID; 20585e09c8c3SJim Ingham id_arg.arg_repetition = eArgRepeatOptional; 20595e09c8c3SJim Ingham arg1.push_back(id_arg); 20605e09c8c3SJim Ingham m_arguments.push_back (arg1); 20615e09c8c3SJim Ingham 20625e09c8c3SJim Ingham m_option_group.Append (&m_name_options, LLDB_OPT_SET_1, LLDB_OPT_SET_ALL); 20635e09c8c3SJim Ingham m_option_group.Finalize(); 20645e09c8c3SJim Ingham } 20655e09c8c3SJim Ingham 2066*13d21e9aSBruce Mitchener ~CommandObjectBreakpointNameAdd () override {} 20675e09c8c3SJim Ingham 20685e09c8c3SJim Ingham Options * 2069*13d21e9aSBruce Mitchener GetOptions () override 20705e09c8c3SJim Ingham { 20715e09c8c3SJim Ingham return &m_option_group; 20725e09c8c3SJim Ingham } 20735e09c8c3SJim Ingham 20745e09c8c3SJim Ingham protected: 2075*13d21e9aSBruce Mitchener bool 2076*13d21e9aSBruce Mitchener DoExecute (Args& command, CommandReturnObject &result) override 20775e09c8c3SJim Ingham { 20785e09c8c3SJim Ingham if (!m_name_options.m_name.OptionWasSet()) 20795e09c8c3SJim Ingham { 20805e09c8c3SJim Ingham result.SetError("No name option provided."); 20815e09c8c3SJim Ingham return false; 20825e09c8c3SJim Ingham } 20835e09c8c3SJim Ingham 20845e09c8c3SJim Ingham Target *target = GetSelectedOrDummyTarget(m_name_options.m_use_dummy.GetCurrentValue()); 20855e09c8c3SJim Ingham 20865e09c8c3SJim Ingham if (target == NULL) 20875e09c8c3SJim Ingham { 20885e09c8c3SJim Ingham result.AppendError ("Invalid target. No existing target or breakpoints."); 20895e09c8c3SJim Ingham result.SetStatus (eReturnStatusFailed); 20905e09c8c3SJim Ingham return false; 20915e09c8c3SJim Ingham } 20925e09c8c3SJim Ingham 20935e09c8c3SJim Ingham Mutex::Locker locker; 20945e09c8c3SJim Ingham target->GetBreakpointList().GetListMutex(locker); 20955e09c8c3SJim Ingham 20965e09c8c3SJim Ingham const BreakpointList &breakpoints = target->GetBreakpointList(); 20975e09c8c3SJim Ingham 20985e09c8c3SJim Ingham size_t num_breakpoints = breakpoints.GetSize(); 20995e09c8c3SJim Ingham if (num_breakpoints == 0) 21005e09c8c3SJim Ingham { 21015e09c8c3SJim Ingham result.SetError("No breakpoints, cannot add names."); 21025e09c8c3SJim Ingham result.SetStatus (eReturnStatusFailed); 21035e09c8c3SJim Ingham return false; 21045e09c8c3SJim Ingham } 21055e09c8c3SJim Ingham 21065e09c8c3SJim Ingham // Particular breakpoint selected; disable that breakpoint. 21075e09c8c3SJim Ingham BreakpointIDList valid_bp_ids; 21085e09c8c3SJim Ingham CommandObjectMultiwordBreakpoint::VerifyBreakpointIDs (command, target, result, &valid_bp_ids); 21095e09c8c3SJim Ingham 21105e09c8c3SJim Ingham if (result.Succeeded()) 21115e09c8c3SJim Ingham { 21125e09c8c3SJim Ingham if (valid_bp_ids.GetSize() == 0) 21135e09c8c3SJim Ingham { 21145e09c8c3SJim Ingham result.SetError("No breakpoints specified, cannot add names."); 21155e09c8c3SJim Ingham result.SetStatus (eReturnStatusFailed); 21165e09c8c3SJim Ingham return false; 21175e09c8c3SJim Ingham } 21185e09c8c3SJim Ingham size_t num_valid_ids = valid_bp_ids.GetSize(); 21195e09c8c3SJim Ingham for (size_t index = 0; index < num_valid_ids; index++) 21205e09c8c3SJim Ingham { 21215e09c8c3SJim Ingham lldb::break_id_t bp_id = valid_bp_ids.GetBreakpointIDAtIndex(index).GetBreakpointID(); 21225e09c8c3SJim Ingham BreakpointSP bp_sp = breakpoints.FindBreakpointByID(bp_id); 21235e09c8c3SJim Ingham Error error; // We don't need to check the error here, since the option parser checked it... 21245e09c8c3SJim Ingham bp_sp->AddName(m_name_options.m_name.GetCurrentValue(), error); 21255e09c8c3SJim Ingham } 21265e09c8c3SJim Ingham } 21275e09c8c3SJim Ingham 21285e09c8c3SJim Ingham return true; 21295e09c8c3SJim Ingham } 21305e09c8c3SJim Ingham 21315e09c8c3SJim Ingham private: 21325e09c8c3SJim Ingham BreakpointNameOptionGroup m_name_options; 21335e09c8c3SJim Ingham OptionGroupOptions m_option_group; 21345e09c8c3SJim Ingham }; 21355e09c8c3SJim Ingham 21365e09c8c3SJim Ingham 21375e09c8c3SJim Ingham 21385e09c8c3SJim Ingham class CommandObjectBreakpointNameDelete : public CommandObjectParsed 21395e09c8c3SJim Ingham { 21405e09c8c3SJim Ingham public: 21415e09c8c3SJim Ingham CommandObjectBreakpointNameDelete (CommandInterpreter &interpreter) : 21425e09c8c3SJim Ingham CommandObjectParsed (interpreter, 21435e09c8c3SJim Ingham "delete", 21445e09c8c3SJim Ingham "Delete a name from the breakpoints provided.", 21455e09c8c3SJim Ingham "breakpoint name delete <command-options> <breakpoint-id-list>"), 21465e09c8c3SJim Ingham m_name_options(), 21475e09c8c3SJim Ingham m_option_group(interpreter) 21485e09c8c3SJim Ingham { 21495e09c8c3SJim Ingham // Create the first variant for the first (and only) argument for this command. 21505e09c8c3SJim Ingham CommandArgumentEntry arg1; 21515e09c8c3SJim Ingham CommandArgumentData id_arg; 21525e09c8c3SJim Ingham id_arg.arg_type = eArgTypeBreakpointID; 21535e09c8c3SJim Ingham id_arg.arg_repetition = eArgRepeatOptional; 21545e09c8c3SJim Ingham arg1.push_back(id_arg); 21555e09c8c3SJim Ingham m_arguments.push_back (arg1); 21565e09c8c3SJim Ingham 21575e09c8c3SJim Ingham m_option_group.Append (&m_name_options, LLDB_OPT_SET_1, LLDB_OPT_SET_ALL); 21585e09c8c3SJim Ingham m_option_group.Finalize(); 21595e09c8c3SJim Ingham } 21605e09c8c3SJim Ingham 2161*13d21e9aSBruce Mitchener ~CommandObjectBreakpointNameDelete () override {} 21625e09c8c3SJim Ingham 21635e09c8c3SJim Ingham Options * 2164*13d21e9aSBruce Mitchener GetOptions () override 21655e09c8c3SJim Ingham { 21665e09c8c3SJim Ingham return &m_option_group; 21675e09c8c3SJim Ingham } 21685e09c8c3SJim Ingham 21695e09c8c3SJim Ingham protected: 2170*13d21e9aSBruce Mitchener bool 2171*13d21e9aSBruce Mitchener DoExecute (Args& command, CommandReturnObject &result) override 21725e09c8c3SJim Ingham { 21735e09c8c3SJim Ingham if (!m_name_options.m_name.OptionWasSet()) 21745e09c8c3SJim Ingham { 21755e09c8c3SJim Ingham result.SetError("No name option provided."); 21765e09c8c3SJim Ingham return false; 21775e09c8c3SJim Ingham } 21785e09c8c3SJim Ingham 21795e09c8c3SJim Ingham Target *target = GetSelectedOrDummyTarget(m_name_options.m_use_dummy.GetCurrentValue()); 21805e09c8c3SJim Ingham 21815e09c8c3SJim Ingham if (target == NULL) 21825e09c8c3SJim Ingham { 21835e09c8c3SJim Ingham result.AppendError ("Invalid target. No existing target or breakpoints."); 21845e09c8c3SJim Ingham result.SetStatus (eReturnStatusFailed); 21855e09c8c3SJim Ingham return false; 21865e09c8c3SJim Ingham } 21875e09c8c3SJim Ingham 21885e09c8c3SJim Ingham Mutex::Locker locker; 21895e09c8c3SJim Ingham target->GetBreakpointList().GetListMutex(locker); 21905e09c8c3SJim Ingham 21915e09c8c3SJim Ingham const BreakpointList &breakpoints = target->GetBreakpointList(); 21925e09c8c3SJim Ingham 21935e09c8c3SJim Ingham size_t num_breakpoints = breakpoints.GetSize(); 21945e09c8c3SJim Ingham if (num_breakpoints == 0) 21955e09c8c3SJim Ingham { 21965e09c8c3SJim Ingham result.SetError("No breakpoints, cannot delete names."); 21975e09c8c3SJim Ingham result.SetStatus (eReturnStatusFailed); 21985e09c8c3SJim Ingham return false; 21995e09c8c3SJim Ingham } 22005e09c8c3SJim Ingham 22015e09c8c3SJim Ingham // Particular breakpoint selected; disable that breakpoint. 22025e09c8c3SJim Ingham BreakpointIDList valid_bp_ids; 22035e09c8c3SJim Ingham CommandObjectMultiwordBreakpoint::VerifyBreakpointIDs (command, target, result, &valid_bp_ids); 22045e09c8c3SJim Ingham 22055e09c8c3SJim Ingham if (result.Succeeded()) 22065e09c8c3SJim Ingham { 22075e09c8c3SJim Ingham if (valid_bp_ids.GetSize() == 0) 22085e09c8c3SJim Ingham { 22095e09c8c3SJim Ingham result.SetError("No breakpoints specified, cannot delete names."); 22105e09c8c3SJim Ingham result.SetStatus (eReturnStatusFailed); 22115e09c8c3SJim Ingham return false; 22125e09c8c3SJim Ingham } 22135e09c8c3SJim Ingham size_t num_valid_ids = valid_bp_ids.GetSize(); 22145e09c8c3SJim Ingham for (size_t index = 0; index < num_valid_ids; index++) 22155e09c8c3SJim Ingham { 22165e09c8c3SJim Ingham lldb::break_id_t bp_id = valid_bp_ids.GetBreakpointIDAtIndex(index).GetBreakpointID(); 22175e09c8c3SJim Ingham BreakpointSP bp_sp = breakpoints.FindBreakpointByID(bp_id); 22185e09c8c3SJim Ingham bp_sp->RemoveName(m_name_options.m_name.GetCurrentValue()); 22195e09c8c3SJim Ingham } 22205e09c8c3SJim Ingham } 22215e09c8c3SJim Ingham 22225e09c8c3SJim Ingham return true; 22235e09c8c3SJim Ingham } 22245e09c8c3SJim Ingham 22255e09c8c3SJim Ingham private: 22265e09c8c3SJim Ingham BreakpointNameOptionGroup m_name_options; 22275e09c8c3SJim Ingham OptionGroupOptions m_option_group; 22285e09c8c3SJim Ingham }; 22295e09c8c3SJim Ingham 22305e09c8c3SJim Ingham class CommandObjectBreakpointNameList : public CommandObjectParsed 22315e09c8c3SJim Ingham { 22325e09c8c3SJim Ingham public: 22335e09c8c3SJim Ingham CommandObjectBreakpointNameList (CommandInterpreter &interpreter) : 22345e09c8c3SJim Ingham CommandObjectParsed (interpreter, 22355e09c8c3SJim Ingham "list", 22365e09c8c3SJim Ingham "List either the names for a breakpoint or the breakpoints for a given name.", 22375e09c8c3SJim Ingham "breakpoint name list <command-options>"), 22385e09c8c3SJim Ingham m_name_options(), 22395e09c8c3SJim Ingham m_option_group(interpreter) 22405e09c8c3SJim Ingham { 22415e09c8c3SJim Ingham m_option_group.Append (&m_name_options); 22425e09c8c3SJim Ingham m_option_group.Finalize(); 22435e09c8c3SJim Ingham } 22445e09c8c3SJim Ingham 2245*13d21e9aSBruce Mitchener ~CommandObjectBreakpointNameList () override {} 22465e09c8c3SJim Ingham 22475e09c8c3SJim Ingham Options * 2248*13d21e9aSBruce Mitchener GetOptions () override 22495e09c8c3SJim Ingham { 22505e09c8c3SJim Ingham return &m_option_group; 22515e09c8c3SJim Ingham } 22525e09c8c3SJim Ingham 22535e09c8c3SJim Ingham protected: 2254*13d21e9aSBruce Mitchener bool 2255*13d21e9aSBruce Mitchener DoExecute (Args& command, CommandReturnObject &result) override 22565e09c8c3SJim Ingham { 22575e09c8c3SJim Ingham Target *target = GetSelectedOrDummyTarget(m_name_options.m_use_dummy.GetCurrentValue()); 22585e09c8c3SJim Ingham 22595e09c8c3SJim Ingham if (target == NULL) 22605e09c8c3SJim Ingham { 22615e09c8c3SJim Ingham result.AppendError ("Invalid target. No existing target or breakpoints."); 22625e09c8c3SJim Ingham result.SetStatus (eReturnStatusFailed); 22635e09c8c3SJim Ingham return false; 22645e09c8c3SJim Ingham } 22655e09c8c3SJim Ingham 22665e09c8c3SJim Ingham if (m_name_options.m_name.OptionWasSet()) 22675e09c8c3SJim Ingham { 22685e09c8c3SJim Ingham const char *name = m_name_options.m_name.GetCurrentValue(); 22695e09c8c3SJim Ingham Mutex::Locker locker; 22705e09c8c3SJim Ingham target->GetBreakpointList().GetListMutex(locker); 22715e09c8c3SJim Ingham 22725e09c8c3SJim Ingham BreakpointList &breakpoints = target->GetBreakpointList(); 22735e09c8c3SJim Ingham for (BreakpointSP bp_sp : breakpoints.Breakpoints()) 22745e09c8c3SJim Ingham { 22755e09c8c3SJim Ingham if (bp_sp->MatchesName(name)) 22765e09c8c3SJim Ingham { 22775e09c8c3SJim Ingham StreamString s; 22785e09c8c3SJim Ingham bp_sp->GetDescription(&s, eDescriptionLevelBrief); 22795e09c8c3SJim Ingham s.EOL(); 22805e09c8c3SJim Ingham result.AppendMessage(s.GetData()); 22815e09c8c3SJim Ingham } 22825e09c8c3SJim Ingham } 22835e09c8c3SJim Ingham 22845e09c8c3SJim Ingham } 22855e09c8c3SJim Ingham else if (m_name_options.m_breakpoint.OptionWasSet()) 22865e09c8c3SJim Ingham { 22875e09c8c3SJim Ingham BreakpointSP bp_sp = target->GetBreakpointList().FindBreakpointByID(m_name_options.m_breakpoint.GetCurrentValue()); 22885e09c8c3SJim Ingham if (bp_sp) 22895e09c8c3SJim Ingham { 22905e09c8c3SJim Ingham std::vector<std::string> names; 22915e09c8c3SJim Ingham bp_sp->GetNames (names); 22925e09c8c3SJim Ingham result.AppendMessage ("Names:"); 22935e09c8c3SJim Ingham for (auto name : names) 22945e09c8c3SJim Ingham result.AppendMessageWithFormat (" %s\n", name.c_str()); 22955e09c8c3SJim Ingham } 22965e09c8c3SJim Ingham else 22975e09c8c3SJim Ingham { 22985e09c8c3SJim Ingham result.AppendErrorWithFormat ("Could not find breakpoint %" PRId64 ".\n", 22995e09c8c3SJim Ingham m_name_options.m_breakpoint.GetCurrentValue()); 23005e09c8c3SJim Ingham result.SetStatus (eReturnStatusFailed); 23015e09c8c3SJim Ingham return false; 23025e09c8c3SJim Ingham } 23035e09c8c3SJim Ingham } 23045e09c8c3SJim Ingham else 23055e09c8c3SJim Ingham { 23065e09c8c3SJim Ingham result.SetError ("Must specify -N or -B option to list."); 23075e09c8c3SJim Ingham result.SetStatus (eReturnStatusFailed); 23085e09c8c3SJim Ingham return false; 23095e09c8c3SJim Ingham } 23105e09c8c3SJim Ingham return true; 23115e09c8c3SJim Ingham } 23125e09c8c3SJim Ingham 23135e09c8c3SJim Ingham private: 23145e09c8c3SJim Ingham BreakpointNameOptionGroup m_name_options; 23155e09c8c3SJim Ingham OptionGroupOptions m_option_group; 23165e09c8c3SJim Ingham }; 23175e09c8c3SJim Ingham 23185e09c8c3SJim Ingham //------------------------------------------------------------------------- 23195e09c8c3SJim Ingham // CommandObjectMultiwordBreakpoint 23205e09c8c3SJim Ingham //------------------------------------------------------------------------- 23215e09c8c3SJim Ingham class CommandObjectBreakpointName : public CommandObjectMultiword 23225e09c8c3SJim Ingham { 23235e09c8c3SJim Ingham public: 23245e09c8c3SJim Ingham CommandObjectBreakpointName (CommandInterpreter &interpreter) : 23255e09c8c3SJim Ingham CommandObjectMultiword(interpreter, 23265e09c8c3SJim Ingham "name", 23275e09c8c3SJim Ingham "A set of commands to manage name tags for breakpoints", 23285e09c8c3SJim Ingham "breakpoint name <command> [<command-options>]") 23295e09c8c3SJim Ingham { 23305e09c8c3SJim Ingham CommandObjectSP add_command_object (new CommandObjectBreakpointNameAdd (interpreter)); 23315e09c8c3SJim Ingham CommandObjectSP delete_command_object (new CommandObjectBreakpointNameDelete (interpreter)); 23325e09c8c3SJim Ingham CommandObjectSP list_command_object (new CommandObjectBreakpointNameList (interpreter)); 23335e09c8c3SJim Ingham 23345e09c8c3SJim Ingham LoadSubCommand ("add", add_command_object); 23355e09c8c3SJim Ingham LoadSubCommand ("delete", delete_command_object); 23365e09c8c3SJim Ingham LoadSubCommand ("list", list_command_object); 23375e09c8c3SJim Ingham 23385e09c8c3SJim Ingham } 23395e09c8c3SJim Ingham 2340*13d21e9aSBruce Mitchener ~CommandObjectBreakpointName () override 23415e09c8c3SJim Ingham { 23425e09c8c3SJim Ingham } 23435e09c8c3SJim Ingham 23445e09c8c3SJim Ingham }; 23455e09c8c3SJim Ingham 23465e09c8c3SJim Ingham 23475e09c8c3SJim Ingham //------------------------------------------------------------------------- 234830fdc8d8SChris Lattner // CommandObjectMultiwordBreakpoint 234930fdc8d8SChris Lattner //------------------------------------------------------------------------- 2350ae1c4cf5SJim Ingham #pragma mark MultiwordBreakpoint 235130fdc8d8SChris Lattner 23526611103cSGreg Clayton CommandObjectMultiwordBreakpoint::CommandObjectMultiwordBreakpoint (CommandInterpreter &interpreter) : 2353a7015092SGreg Clayton CommandObjectMultiword (interpreter, 2354a7015092SGreg Clayton "breakpoint", 235546fbc60fSJim Ingham "A set of commands for operating on breakpoints. Also see _regexp-break.", 235630fdc8d8SChris Lattner "breakpoint <command> [<command-options>]") 235730fdc8d8SChris Lattner { 2358a7015092SGreg Clayton CommandObjectSP list_command_object (new CommandObjectBreakpointList (interpreter)); 2359a7015092SGreg Clayton CommandObjectSP enable_command_object (new CommandObjectBreakpointEnable (interpreter)); 2360a7015092SGreg Clayton CommandObjectSP disable_command_object (new CommandObjectBreakpointDisable (interpreter)); 2361b7234e40SJohnny Chen CommandObjectSP clear_command_object (new CommandObjectBreakpointClear (interpreter)); 2362b7234e40SJohnny Chen CommandObjectSP delete_command_object (new CommandObjectBreakpointDelete (interpreter)); 2363a7015092SGreg Clayton CommandObjectSP set_command_object (new CommandObjectBreakpointSet (interpreter)); 236430fdc8d8SChris Lattner CommandObjectSP command_command_object (new CommandObjectBreakpointCommand (interpreter)); 2365a7015092SGreg Clayton CommandObjectSP modify_command_object (new CommandObjectBreakpointModify(interpreter)); 23665e09c8c3SJim Ingham CommandObjectSP name_command_object (new CommandObjectBreakpointName(interpreter)); 236730fdc8d8SChris Lattner 2368b7234e40SJohnny Chen list_command_object->SetCommandName ("breakpoint list"); 236930fdc8d8SChris Lattner enable_command_object->SetCommandName("breakpoint enable"); 237030fdc8d8SChris Lattner disable_command_object->SetCommandName("breakpoint disable"); 2371b7234e40SJohnny Chen clear_command_object->SetCommandName("breakpoint clear"); 2372b7234e40SJohnny Chen delete_command_object->SetCommandName("breakpoint delete"); 2373ae1c4cf5SJim Ingham set_command_object->SetCommandName("breakpoint set"); 2374b7234e40SJohnny Chen command_command_object->SetCommandName ("breakpoint command"); 2375b7234e40SJohnny Chen modify_command_object->SetCommandName ("breakpoint modify"); 23765e09c8c3SJim Ingham name_command_object->SetCommandName ("breakpoint name"); 237730fdc8d8SChris Lattner 237823f59509SGreg Clayton LoadSubCommand ("list", list_command_object); 237923f59509SGreg Clayton LoadSubCommand ("enable", enable_command_object); 238023f59509SGreg Clayton LoadSubCommand ("disable", disable_command_object); 238123f59509SGreg Clayton LoadSubCommand ("clear", clear_command_object); 238223f59509SGreg Clayton LoadSubCommand ("delete", delete_command_object); 238323f59509SGreg Clayton LoadSubCommand ("set", set_command_object); 238423f59509SGreg Clayton LoadSubCommand ("command", command_command_object); 238523f59509SGreg Clayton LoadSubCommand ("modify", modify_command_object); 23865e09c8c3SJim Ingham LoadSubCommand ("name", name_command_object); 238730fdc8d8SChris Lattner } 238830fdc8d8SChris Lattner 238930fdc8d8SChris Lattner CommandObjectMultiwordBreakpoint::~CommandObjectMultiwordBreakpoint () 239030fdc8d8SChris Lattner { 239130fdc8d8SChris Lattner } 239230fdc8d8SChris Lattner 239330fdc8d8SChris Lattner void 23945e09c8c3SJim Ingham CommandObjectMultiwordBreakpoint::VerifyIDs (Args &args, 23955e09c8c3SJim Ingham Target *target, 23965e09c8c3SJim Ingham bool allow_locations, 23975e09c8c3SJim Ingham CommandReturnObject &result, 239830fdc8d8SChris Lattner BreakpointIDList *valid_ids) 239930fdc8d8SChris Lattner { 240030fdc8d8SChris Lattner // args can be strings representing 1). integers (for breakpoint ids) 240130fdc8d8SChris Lattner // 2). the full breakpoint & location canonical representation 240230fdc8d8SChris Lattner // 3). the word "to" or a hyphen, representing a range (in which case there 240330fdc8d8SChris Lattner // had *better* be an entry both before & after of one of the first two types. 24045e09c8c3SJim Ingham // 4). A breakpoint name 240536f3b369SJim Ingham // If args is empty, we will use the last created breakpoint (if there is one.) 240630fdc8d8SChris Lattner 240730fdc8d8SChris Lattner Args temp_args; 240830fdc8d8SChris Lattner 240936f3b369SJim Ingham if (args.GetArgumentCount() == 0) 241036f3b369SJim Ingham { 24114d122c40SGreg Clayton if (target->GetLastCreatedBreakpoint()) 241236f3b369SJim Ingham { 241336f3b369SJim Ingham valid_ids->AddBreakpointID (BreakpointID(target->GetLastCreatedBreakpoint()->GetID(), LLDB_INVALID_BREAK_ID)); 241436f3b369SJim Ingham result.SetStatus (eReturnStatusSuccessFinishNoResult); 241536f3b369SJim Ingham } 241636f3b369SJim Ingham else 241736f3b369SJim Ingham { 241836f3b369SJim Ingham result.AppendError("No breakpoint specified and no last created breakpoint."); 241936f3b369SJim Ingham result.SetStatus (eReturnStatusFailed); 242036f3b369SJim Ingham } 242136f3b369SJim Ingham return; 242236f3b369SJim Ingham } 242336f3b369SJim Ingham 242430fdc8d8SChris Lattner // Create a new Args variable to use; copy any non-breakpoint-id-ranges stuff directly from the old ARGS to 242530fdc8d8SChris Lattner // the new TEMP_ARGS. Do not copy breakpoint id range strings over; instead generate a list of strings for 242630fdc8d8SChris Lattner // all the breakpoint ids in the range, and shove all of those breakpoint id strings into TEMP_ARGS. 242730fdc8d8SChris Lattner 24285e09c8c3SJim Ingham BreakpointIDList::FindAndReplaceIDRanges (args, target, allow_locations, result, temp_args); 242930fdc8d8SChris Lattner 243030fdc8d8SChris Lattner // NOW, convert the list of breakpoint id strings in TEMP_ARGS into an actual BreakpointIDList: 243130fdc8d8SChris Lattner 2432c982c768SGreg Clayton valid_ids->InsertStringArray (temp_args.GetConstArgumentVector(), temp_args.GetArgumentCount(), result); 243330fdc8d8SChris Lattner 243430fdc8d8SChris Lattner // At this point, all of the breakpoint ids that the user passed in have been converted to breakpoint IDs 243530fdc8d8SChris Lattner // and put into valid_ids. 243630fdc8d8SChris Lattner 243730fdc8d8SChris Lattner if (result.Succeeded()) 243830fdc8d8SChris Lattner { 243930fdc8d8SChris Lattner // Now that we've converted everything from args into a list of breakpoint ids, go through our tentative list 244030fdc8d8SChris Lattner // of breakpoint id's and verify that they correspond to valid/currently set breakpoints. 244130fdc8d8SChris Lattner 2442c982c768SGreg Clayton const size_t count = valid_ids->GetSize(); 2443c982c768SGreg Clayton for (size_t i = 0; i < count; ++i) 244430fdc8d8SChris Lattner { 244530fdc8d8SChris Lattner BreakpointID cur_bp_id = valid_ids->GetBreakpointIDAtIndex (i); 244630fdc8d8SChris Lattner Breakpoint *breakpoint = target->GetBreakpointByID (cur_bp_id.GetBreakpointID()).get(); 244730fdc8d8SChris Lattner if (breakpoint != NULL) 244830fdc8d8SChris Lattner { 2449c7bece56SGreg Clayton const size_t num_locations = breakpoint->GetNumLocations(); 24503985c8c6SSaleem Abdulrasool if (static_cast<size_t>(cur_bp_id.GetLocationID()) > num_locations) 245130fdc8d8SChris Lattner { 245230fdc8d8SChris Lattner StreamString id_str; 2453c982c768SGreg Clayton BreakpointID::GetCanonicalReference (&id_str, 2454c982c768SGreg Clayton cur_bp_id.GetBreakpointID(), 245530fdc8d8SChris Lattner cur_bp_id.GetLocationID()); 2456c982c768SGreg Clayton i = valid_ids->GetSize() + 1; 245730fdc8d8SChris Lattner result.AppendErrorWithFormat ("'%s' is not a currently valid breakpoint/location id.\n", 245830fdc8d8SChris Lattner id_str.GetData()); 245930fdc8d8SChris Lattner result.SetStatus (eReturnStatusFailed); 246030fdc8d8SChris Lattner } 246130fdc8d8SChris Lattner } 246230fdc8d8SChris Lattner else 246330fdc8d8SChris Lattner { 2464c982c768SGreg Clayton i = valid_ids->GetSize() + 1; 246530fdc8d8SChris Lattner result.AppendErrorWithFormat ("'%d' is not a currently valid breakpoint id.\n", cur_bp_id.GetBreakpointID()); 246630fdc8d8SChris Lattner result.SetStatus (eReturnStatusFailed); 246730fdc8d8SChris Lattner } 246830fdc8d8SChris Lattner } 246930fdc8d8SChris Lattner } 247030fdc8d8SChris Lattner } 2471