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 // C Includes 1130fdc8d8SChris Lattner // C++ Includes 129e85e5a8SEugene Zelenko #include <vector> 139e85e5a8SEugene Zelenko 1430fdc8d8SChris Lattner // Other libraries and framework includes 1530fdc8d8SChris Lattner // Project includes 169e85e5a8SEugene Zelenko #include "CommandObjectBreakpoint.h" 179e85e5a8SEugene Zelenko #include "CommandObjectBreakpointCommand.h" 1830fdc8d8SChris Lattner #include "lldb/Breakpoint/Breakpoint.h" 1930fdc8d8SChris Lattner #include "lldb/Breakpoint/BreakpointIDList.h" 2030fdc8d8SChris Lattner #include "lldb/Breakpoint/BreakpointLocation.h" 215275aaa0SVince Harron #include "lldb/Host/StringConvert.h" 2240af72e1SJim Ingham #include "lldb/Interpreter/Options.h" 2332abc6edSZachary Turner #include "lldb/Interpreter/OptionValueBoolean.h" 245e09c8c3SJim Ingham #include "lldb/Interpreter/OptionValueString.h" 255e09c8c3SJim Ingham #include "lldb/Interpreter/OptionValueUInt64.h" 2630fdc8d8SChris Lattner #include "lldb/Core/RegularExpression.h" 2730fdc8d8SChris Lattner #include "lldb/Core/StreamString.h" 2830fdc8d8SChris Lattner #include "lldb/Interpreter/CommandInterpreter.h" 2930fdc8d8SChris Lattner #include "lldb/Interpreter/CommandReturnObject.h" 300e0984eeSJim Ingham #include "lldb/Target/Language.h" 3130fdc8d8SChris Lattner #include "lldb/Target/Target.h" 3230fdc8d8SChris Lattner #include "lldb/Interpreter/CommandCompletions.h" 33b57e4a1bSJason Molenda #include "lldb/Target/StackFrame.h" 341b54c88cSJim Ingham #include "lldb/Target/Thread.h" 351b54c88cSJim Ingham #include "lldb/Target/ThreadSpec.h" 3630fdc8d8SChris Lattner 3730fdc8d8SChris Lattner using namespace lldb; 3830fdc8d8SChris Lattner using namespace lldb_private; 3930fdc8d8SChris Lattner 4030fdc8d8SChris Lattner static void 4185e8b814SJim Ingham AddBreakpointDescription (Stream *s, Breakpoint *bp, lldb::DescriptionLevel level) 4230fdc8d8SChris Lattner { 4330fdc8d8SChris Lattner s->IndentMore(); 4430fdc8d8SChris Lattner bp->GetDescription (s, level, true); 4530fdc8d8SChris Lattner s->IndentLess(); 4630fdc8d8SChris Lattner s->EOL(); 4730fdc8d8SChris Lattner } 4830fdc8d8SChris Lattner 4930fdc8d8SChris Lattner //------------------------------------------------------------------------- 505a988416SJim Ingham // CommandObjectBreakpointSet 5130fdc8d8SChris Lattner //------------------------------------------------------------------------- 5230fdc8d8SChris Lattner 535a988416SJim Ingham class CommandObjectBreakpointSet : public CommandObjectParsed 545a988416SJim Ingham { 555a988416SJim Ingham public: 565a988416SJim Ingham typedef enum BreakpointSetType 575a988416SJim Ingham { 585a988416SJim Ingham eSetTypeInvalid, 595a988416SJim Ingham eSetTypeFileAndLine, 605a988416SJim Ingham eSetTypeAddress, 615a988416SJim Ingham eSetTypeFunctionName, 625a988416SJim Ingham eSetTypeFunctionRegexp, 635a988416SJim Ingham eSetTypeSourceRegexp, 645a988416SJim Ingham eSetTypeException 655a988416SJim Ingham } BreakpointSetType; 665a988416SJim Ingham 675a988416SJim Ingham CommandObjectBreakpointSet (CommandInterpreter &interpreter) : 685a988416SJim Ingham CommandObjectParsed (interpreter, 695a988416SJim Ingham "breakpoint set", 705a988416SJim Ingham "Sets a breakpoint or set of breakpoints in the executable.", 715a988416SJim Ingham "breakpoint set <cmd-options>"), 72e1cfbc79STodd Fiala m_options () 735a988416SJim Ingham { 745a988416SJim Ingham } 755a988416SJim Ingham 769e85e5a8SEugene Zelenko ~CommandObjectBreakpointSet() override = default; 775a988416SJim Ingham 7813d21e9aSBruce Mitchener Options * 7913d21e9aSBruce Mitchener GetOptions () override 805a988416SJim Ingham { 815a988416SJim Ingham return &m_options; 825a988416SJim Ingham } 835a988416SJim Ingham 845a988416SJim Ingham class CommandOptions : public Options 855a988416SJim Ingham { 865a988416SJim Ingham public: 87e1cfbc79STodd Fiala CommandOptions () : 88e1cfbc79STodd Fiala Options (), 897d49c9c8SJohnny Chen m_condition (), 9087df91b8SJim Ingham m_filenames (), 9130fdc8d8SChris Lattner m_line_num (0), 9230fdc8d8SChris Lattner m_column (0), 93fab10e89SJim Ingham m_func_names (), 94fab10e89SJim Ingham m_func_name_type_mask (eFunctionNameTypeNone), 9530fdc8d8SChris Lattner m_func_regexp (), 96969795f1SJim Ingham m_source_text_regexp(), 9730fdc8d8SChris Lattner m_modules (), 981b54c88cSJim Ingham m_load_addr(), 99c982c768SGreg Clayton m_ignore_count (0), 1001b54c88cSJim Ingham m_thread_id(LLDB_INVALID_THREAD_ID), 101c982c768SGreg Clayton m_thread_index (UINT32_MAX), 1021b54c88cSJim Ingham m_thread_name(), 103fab10e89SJim Ingham m_queue_name(), 104fab10e89SJim Ingham m_catch_bp (false), 1051f746071SGreg Clayton m_throw_bp (true), 106eb023e75SGreg Clayton m_hardware (false), 107a72b31c7SJim Ingham m_exception_language (eLanguageTypeUnknown), 10823b1decbSDawn Perchik m_language (lldb::eLanguageTypeUnknown), 109ca36cd16SJim Ingham m_skip_prologue (eLazyBoolCalculate), 110e732052fSJim Ingham m_one_shot (false), 111055ad9beSIlia K m_all_files (false), 112055ad9beSIlia K m_move_to_nearest_code (eLazyBoolCalculate) 11330fdc8d8SChris Lattner { 11430fdc8d8SChris Lattner } 11530fdc8d8SChris Lattner 1169e85e5a8SEugene Zelenko ~CommandOptions() override = default; 11787df91b8SJim Ingham 11813d21e9aSBruce Mitchener Error 119e1cfbc79STodd Fiala SetOptionValue (uint32_t option_idx, const char *option_arg, 120e1cfbc79STodd Fiala ExecutionContext *execution_context) override 12130fdc8d8SChris Lattner { 12230fdc8d8SChris Lattner Error error; 1233bcdfc0eSGreg Clayton const int short_option = m_getopt_table[option_idx].val; 12430fdc8d8SChris Lattner 12530fdc8d8SChris Lattner switch (short_option) 12630fdc8d8SChris Lattner { 12730fdc8d8SChris Lattner case 'a': 128b9d5df58SGreg Clayton { 129e1cfbc79STodd Fiala m_load_addr = 130e1cfbc79STodd Fiala Args::StringToAddress(execution_context, option_arg, 131e1cfbc79STodd Fiala LLDB_INVALID_ADDRESS, &error); 132b9d5df58SGreg Clayton } 13330fdc8d8SChris Lattner break; 13430fdc8d8SChris Lattner 135e732052fSJim Ingham case 'A': 136e732052fSJim Ingham m_all_files = true; 137e732052fSJim Ingham break; 138e732052fSJim Ingham 139ca36cd16SJim Ingham case 'b': 140ca36cd16SJim Ingham m_func_names.push_back (option_arg); 141ca36cd16SJim Ingham m_func_name_type_mask |= eFunctionNameTypeBase; 142ca36cd16SJim Ingham break; 143ca36cd16SJim Ingham 1447d49c9c8SJohnny Chen case 'C': 1456312991cSJim Ingham { 1466312991cSJim Ingham bool success; 1476312991cSJim Ingham m_column = StringConvert::ToUInt32 (option_arg, 0, 0, &success); 1486312991cSJim Ingham if (!success) 1496312991cSJim Ingham error.SetErrorStringWithFormat("invalid column number: %s", option_arg); 15030fdc8d8SChris Lattner break; 1516312991cSJim Ingham } 1529e85e5a8SEugene Zelenko 1537d49c9c8SJohnny Chen case 'c': 1547d49c9c8SJohnny Chen m_condition.assign(option_arg); 1557d49c9c8SJohnny Chen break; 1567d49c9c8SJohnny Chen 15733df7cd3SJim Ingham case 'D': 15833df7cd3SJim Ingham m_use_dummy = true; 15933df7cd3SJim Ingham break; 16033df7cd3SJim Ingham 161fab10e89SJim Ingham case 'E': 162fab10e89SJim Ingham { 1630e0984eeSJim Ingham LanguageType language = Language::GetLanguageTypeFromString (option_arg); 164fab10e89SJim Ingham 165fab10e89SJim Ingham switch (language) 166fab10e89SJim Ingham { 167fab10e89SJim Ingham case eLanguageTypeC89: 168fab10e89SJim Ingham case eLanguageTypeC: 169fab10e89SJim Ingham case eLanguageTypeC99: 1701d0089faSBruce Mitchener case eLanguageTypeC11: 171a72b31c7SJim Ingham m_exception_language = eLanguageTypeC; 172fab10e89SJim Ingham break; 173fab10e89SJim Ingham case eLanguageTypeC_plus_plus: 1741d0089faSBruce Mitchener case eLanguageTypeC_plus_plus_03: 1751d0089faSBruce Mitchener case eLanguageTypeC_plus_plus_11: 1762ba84a6aSBruce Mitchener case eLanguageTypeC_plus_plus_14: 177a72b31c7SJim Ingham m_exception_language = eLanguageTypeC_plus_plus; 178fab10e89SJim Ingham break; 179fab10e89SJim Ingham case eLanguageTypeObjC: 180a72b31c7SJim Ingham m_exception_language = eLanguageTypeObjC; 181fab10e89SJim Ingham break; 182fab10e89SJim Ingham case eLanguageTypeObjC_plus_plus: 183fab10e89SJim Ingham error.SetErrorStringWithFormat ("Set exception breakpoints separately for c++ and objective-c"); 184fab10e89SJim Ingham break; 185fab10e89SJim Ingham case eLanguageTypeUnknown: 186fab10e89SJim Ingham error.SetErrorStringWithFormat ("Unknown language type: '%s' for exception breakpoint", option_arg); 187fab10e89SJim Ingham break; 188fab10e89SJim Ingham default: 189fab10e89SJim Ingham error.SetErrorStringWithFormat ("Unsupported language type: '%s' for exception breakpoint", option_arg); 190fab10e89SJim Ingham } 191fab10e89SJim Ingham } 192fab10e89SJim Ingham break; 193ca36cd16SJim Ingham 194ca36cd16SJim Ingham case 'f': 195ca36cd16SJim Ingham m_filenames.AppendIfUnique (FileSpec(option_arg, false)); 196fab10e89SJim Ingham break; 197ca36cd16SJim Ingham 198ca36cd16SJim Ingham case 'F': 199ca36cd16SJim Ingham m_func_names.push_back (option_arg); 200ca36cd16SJim Ingham m_func_name_type_mask |= eFunctionNameTypeFull; 201ca36cd16SJim Ingham break; 202ca36cd16SJim Ingham 203fab10e89SJim Ingham case 'h': 204fab10e89SJim Ingham { 205fab10e89SJim Ingham bool success; 206fab10e89SJim Ingham m_catch_bp = Args::StringToBoolean (option_arg, true, &success); 207fab10e89SJim Ingham if (!success) 208fab10e89SJim Ingham error.SetErrorStringWithFormat ("Invalid boolean value for on-catch option: '%s'", option_arg); 209fab10e89SJim Ingham } 210168d469aSJim Ingham break; 211eb023e75SGreg Clayton 212eb023e75SGreg Clayton case 'H': 213eb023e75SGreg Clayton m_hardware = true; 214eb023e75SGreg Clayton break; 215eb023e75SGreg Clayton 216ca36cd16SJim Ingham case 'i': 2175275aaa0SVince Harron m_ignore_count = StringConvert::ToUInt32(option_arg, UINT32_MAX, 0); 218ca36cd16SJim Ingham if (m_ignore_count == UINT32_MAX) 219ca36cd16SJim Ingham error.SetErrorStringWithFormat ("invalid ignore count '%s'", option_arg); 220ca36cd16SJim Ingham break; 221ca36cd16SJim Ingham 222a8558b62SJim Ingham case 'K': 223a8558b62SJim Ingham { 224a8558b62SJim Ingham bool success; 225a8558b62SJim Ingham bool value; 226a8558b62SJim Ingham value = Args::StringToBoolean (option_arg, true, &success); 227a8558b62SJim Ingham if (value) 228a8558b62SJim Ingham m_skip_prologue = eLazyBoolYes; 229a8558b62SJim Ingham else 230a8558b62SJim Ingham m_skip_prologue = eLazyBoolNo; 231a8558b62SJim Ingham 232a8558b62SJim Ingham if (!success) 233a8558b62SJim Ingham error.SetErrorStringWithFormat ("Invalid boolean value for skip prologue option: '%s'", option_arg); 234a8558b62SJim Ingham } 235fab10e89SJim Ingham break; 236ca36cd16SJim Ingham 237ca36cd16SJim Ingham case 'l': 2386312991cSJim Ingham { 2396312991cSJim Ingham bool success; 2406312991cSJim Ingham m_line_num = StringConvert::ToUInt32 (option_arg, 0, 0, &success); 2416312991cSJim Ingham if (!success) 2426312991cSJim Ingham error.SetErrorStringWithFormat ("invalid line number: %s.", option_arg); 243ca36cd16SJim Ingham break; 2446312991cSJim Ingham } 245055ad9beSIlia K 24623b1decbSDawn Perchik case 'L': 2470e0984eeSJim Ingham m_language = Language::GetLanguageTypeFromString (option_arg); 24823b1decbSDawn Perchik if (m_language == eLanguageTypeUnknown) 24923b1decbSDawn Perchik error.SetErrorStringWithFormat ("Unknown language type: '%s' for breakpoint", option_arg); 25023b1decbSDawn Perchik break; 25123b1decbSDawn Perchik 252055ad9beSIlia K case 'm': 253055ad9beSIlia K { 254055ad9beSIlia K bool success; 255055ad9beSIlia K bool value; 256055ad9beSIlia K value = Args::StringToBoolean (option_arg, true, &success); 257055ad9beSIlia K if (value) 258055ad9beSIlia K m_move_to_nearest_code = eLazyBoolYes; 259055ad9beSIlia K else 260055ad9beSIlia K m_move_to_nearest_code = eLazyBoolNo; 261055ad9beSIlia K 262055ad9beSIlia K if (!success) 263055ad9beSIlia K error.SetErrorStringWithFormat ("Invalid boolean value for move-to-nearest-code option: '%s'", option_arg); 264055ad9beSIlia K break; 265055ad9beSIlia K } 266055ad9beSIlia K 267ca36cd16SJim Ingham case 'M': 268ca36cd16SJim Ingham m_func_names.push_back (option_arg); 269ca36cd16SJim Ingham m_func_name_type_mask |= eFunctionNameTypeMethod; 270ca36cd16SJim Ingham break; 271ca36cd16SJim Ingham 272ca36cd16SJim Ingham case 'n': 273ca36cd16SJim Ingham m_func_names.push_back (option_arg); 274ca36cd16SJim Ingham m_func_name_type_mask |= eFunctionNameTypeAuto; 275ca36cd16SJim Ingham break; 276ca36cd16SJim Ingham 2775e09c8c3SJim Ingham case 'N': 2785e09c8c3SJim Ingham if (BreakpointID::StringIsBreakpointName(option_arg, error)) 2795e09c8c3SJim Ingham m_breakpoint_names.push_back (option_arg); 2805e09c8c3SJim Ingham break; 2815e09c8c3SJim Ingham 2822411167fSJim Ingham case 'R': 2832411167fSJim Ingham { 2842411167fSJim Ingham lldb::addr_t tmp_offset_addr; 285e1cfbc79STodd Fiala tmp_offset_addr = 286e1cfbc79STodd Fiala Args::StringToAddress(execution_context, option_arg, 287e1cfbc79STodd Fiala 0, &error); 2882411167fSJim Ingham if (error.Success()) 2892411167fSJim Ingham m_offset_addr = tmp_offset_addr; 2902411167fSJim Ingham } 2912411167fSJim Ingham break; 2922411167fSJim Ingham 293ca36cd16SJim Ingham case 'o': 294ca36cd16SJim Ingham m_one_shot = true; 295ca36cd16SJim Ingham break; 296ca36cd16SJim Ingham 297a72b31c7SJim Ingham case 'O': 298a72b31c7SJim Ingham m_exception_extra_args.AppendArgument ("-O"); 299a72b31c7SJim Ingham m_exception_extra_args.AppendArgument (option_arg); 300a72b31c7SJim Ingham break; 301a72b31c7SJim Ingham 302ca36cd16SJim Ingham case 'p': 303ca36cd16SJim Ingham m_source_text_regexp.assign (option_arg); 304ca36cd16SJim Ingham break; 305ca36cd16SJim Ingham 306ca36cd16SJim Ingham case 'q': 307ca36cd16SJim Ingham m_queue_name.assign (option_arg); 308ca36cd16SJim Ingham break; 309ca36cd16SJim Ingham 310ca36cd16SJim Ingham case 'r': 311ca36cd16SJim Ingham m_func_regexp.assign (option_arg); 312ca36cd16SJim Ingham break; 313ca36cd16SJim Ingham 314ca36cd16SJim Ingham case 's': 315ca36cd16SJim Ingham m_modules.AppendIfUnique (FileSpec (option_arg, false)); 316ca36cd16SJim Ingham break; 317ca36cd16SJim Ingham 318ca36cd16SJim Ingham case 'S': 319ca36cd16SJim Ingham m_func_names.push_back (option_arg); 320ca36cd16SJim Ingham m_func_name_type_mask |= eFunctionNameTypeSelector; 321ca36cd16SJim Ingham break; 322ca36cd16SJim Ingham 323ca36cd16SJim Ingham case 't' : 3245275aaa0SVince Harron m_thread_id = StringConvert::ToUInt64(option_arg, LLDB_INVALID_THREAD_ID, 0); 325ca36cd16SJim Ingham if (m_thread_id == LLDB_INVALID_THREAD_ID) 326ca36cd16SJim Ingham error.SetErrorStringWithFormat ("invalid thread id string '%s'", option_arg); 327ca36cd16SJim Ingham break; 328ca36cd16SJim Ingham 329ca36cd16SJim Ingham case 'T': 330ca36cd16SJim Ingham m_thread_name.assign (option_arg); 331ca36cd16SJim Ingham break; 332ca36cd16SJim Ingham 333ca36cd16SJim Ingham case 'w': 334ca36cd16SJim Ingham { 335ca36cd16SJim Ingham bool success; 336ca36cd16SJim Ingham m_throw_bp = Args::StringToBoolean (option_arg, true, &success); 337ca36cd16SJim Ingham if (!success) 338ca36cd16SJim Ingham error.SetErrorStringWithFormat ("Invalid boolean value for on-throw option: '%s'", option_arg); 339ca36cd16SJim Ingham } 340ca36cd16SJim Ingham break; 341ca36cd16SJim Ingham 342ca36cd16SJim Ingham case 'x': 3435275aaa0SVince Harron m_thread_index = StringConvert::ToUInt32(option_arg, UINT32_MAX, 0); 344ca36cd16SJim Ingham if (m_thread_id == UINT32_MAX) 345ca36cd16SJim Ingham error.SetErrorStringWithFormat ("invalid thread index string '%s'", option_arg); 346ca36cd16SJim Ingham break; 347ca36cd16SJim Ingham 34876bb8d67SJim Ingham case 'X': 34976bb8d67SJim Ingham m_source_regex_func_names.insert(option_arg); 35076bb8d67SJim Ingham break; 35176bb8d67SJim Ingham 35230fdc8d8SChris Lattner default: 35386edbf41SGreg Clayton error.SetErrorStringWithFormat ("unrecognized option '%c'", short_option); 35430fdc8d8SChris Lattner break; 35530fdc8d8SChris Lattner } 35630fdc8d8SChris Lattner 35730fdc8d8SChris Lattner return error; 35830fdc8d8SChris Lattner } 3599e85e5a8SEugene Zelenko 36030fdc8d8SChris Lattner void 361e1cfbc79STodd Fiala OptionParsingStarting (ExecutionContext *execution_context) override 36230fdc8d8SChris Lattner { 3637d49c9c8SJohnny Chen m_condition.clear(); 36487df91b8SJim Ingham m_filenames.Clear(); 36530fdc8d8SChris Lattner m_line_num = 0; 36630fdc8d8SChris Lattner m_column = 0; 367fab10e89SJim Ingham m_func_names.clear(); 3681f746071SGreg Clayton m_func_name_type_mask = eFunctionNameTypeNone; 36930fdc8d8SChris Lattner m_func_regexp.clear(); 3701f746071SGreg Clayton m_source_text_regexp.clear(); 37187df91b8SJim Ingham m_modules.Clear(); 3721f746071SGreg Clayton m_load_addr = LLDB_INVALID_ADDRESS; 3732411167fSJim Ingham m_offset_addr = 0; 374c982c768SGreg Clayton m_ignore_count = 0; 3751b54c88cSJim Ingham m_thread_id = LLDB_INVALID_THREAD_ID; 376c982c768SGreg Clayton m_thread_index = UINT32_MAX; 3771b54c88cSJim Ingham m_thread_name.clear(); 3781b54c88cSJim Ingham m_queue_name.clear(); 379fab10e89SJim Ingham m_catch_bp = false; 380fab10e89SJim Ingham m_throw_bp = true; 381eb023e75SGreg Clayton m_hardware = false; 382a72b31c7SJim Ingham m_exception_language = eLanguageTypeUnknown; 38323b1decbSDawn Perchik m_language = lldb::eLanguageTypeUnknown; 384a8558b62SJim Ingham m_skip_prologue = eLazyBoolCalculate; 385ca36cd16SJim Ingham m_one_shot = false; 38633df7cd3SJim Ingham m_use_dummy = false; 3875e09c8c3SJim Ingham m_breakpoint_names.clear(); 388e732052fSJim Ingham m_all_files = false; 389a72b31c7SJim Ingham m_exception_extra_args.Clear(); 390055ad9beSIlia K m_move_to_nearest_code = eLazyBoolCalculate; 39176bb8d67SJim Ingham m_source_regex_func_names.clear(); 39230fdc8d8SChris Lattner } 39330fdc8d8SChris Lattner 3945a988416SJim Ingham const OptionDefinition* 39513d21e9aSBruce Mitchener GetDefinitions () override 39630fdc8d8SChris Lattner { 3975a988416SJim Ingham return g_option_table; 39830fdc8d8SChris Lattner } 39930fdc8d8SChris Lattner 4005a988416SJim Ingham // Options table: Required for subclasses of Options. 40130fdc8d8SChris Lattner 4025a988416SJim Ingham static OptionDefinition g_option_table[]; 40330fdc8d8SChris Lattner 4045a988416SJim Ingham // Instance variables to hold the values for command options. 405969795f1SJim Ingham 4065a988416SJim Ingham std::string m_condition; 4075a988416SJim Ingham FileSpecList m_filenames; 4085a988416SJim Ingham uint32_t m_line_num; 4095a988416SJim Ingham uint32_t m_column; 4105a988416SJim Ingham std::vector<std::string> m_func_names; 4115e09c8c3SJim Ingham std::vector<std::string> m_breakpoint_names; 4125a988416SJim Ingham uint32_t m_func_name_type_mask; 4135a988416SJim Ingham std::string m_func_regexp; 4145a988416SJim Ingham std::string m_source_text_regexp; 4155a988416SJim Ingham FileSpecList m_modules; 4165a988416SJim Ingham lldb::addr_t m_load_addr; 4172411167fSJim Ingham lldb::addr_t m_offset_addr; 4185a988416SJim Ingham uint32_t m_ignore_count; 4195a988416SJim Ingham lldb::tid_t m_thread_id; 4205a988416SJim Ingham uint32_t m_thread_index; 4215a988416SJim Ingham std::string m_thread_name; 4225a988416SJim Ingham std::string m_queue_name; 4235a988416SJim Ingham bool m_catch_bp; 4245a988416SJim Ingham bool m_throw_bp; 425eb023e75SGreg Clayton bool m_hardware; // Request to use hardware breakpoints 426a72b31c7SJim Ingham lldb::LanguageType m_exception_language; 42723b1decbSDawn Perchik lldb::LanguageType m_language; 4285a988416SJim Ingham LazyBool m_skip_prologue; 429ca36cd16SJim Ingham bool m_one_shot; 43033df7cd3SJim Ingham bool m_use_dummy; 431e732052fSJim Ingham bool m_all_files; 432a72b31c7SJim Ingham Args m_exception_extra_args; 433055ad9beSIlia K LazyBool m_move_to_nearest_code; 43476bb8d67SJim Ingham std::unordered_set<std::string> m_source_regex_func_names; 4355a988416SJim Ingham }; 4365a988416SJim Ingham 4375a988416SJim Ingham protected: 43813d21e9aSBruce Mitchener bool 4395a988416SJim Ingham DoExecute (Args& command, 44013d21e9aSBruce Mitchener CommandReturnObject &result) override 44130fdc8d8SChris Lattner { 44233df7cd3SJim Ingham Target *target = GetSelectedOrDummyTarget(m_options.m_use_dummy); 44333df7cd3SJim Ingham 444893c932aSJim Ingham if (target == nullptr) 44530fdc8d8SChris Lattner { 446effe5c95SGreg Clayton result.AppendError ("Invalid target. Must set target before setting breakpoints (see 'target create' command)."); 44730fdc8d8SChris Lattner result.SetStatus (eReturnStatusFailed); 44830fdc8d8SChris Lattner return false; 44930fdc8d8SChris Lattner } 45030fdc8d8SChris Lattner 45130fdc8d8SChris Lattner // The following are the various types of breakpoints that could be set: 45230fdc8d8SChris Lattner // 1). -f -l -p [-s -g] (setting breakpoint by source location) 45330fdc8d8SChris Lattner // 2). -a [-s -g] (setting breakpoint by address) 45430fdc8d8SChris Lattner // 3). -n [-s -g] (setting breakpoint by function name) 45530fdc8d8SChris Lattner // 4). -r [-s -g] (setting breakpoint by function name regular expression) 456969795f1SJim Ingham // 5). -p -f (setting a breakpoint by comparing a reg-exp to source text) 457fab10e89SJim Ingham // 6). -E [-w -h] (setting a breakpoint for exceptions for a given language.) 45830fdc8d8SChris Lattner 45930fdc8d8SChris Lattner BreakpointSetType break_type = eSetTypeInvalid; 46030fdc8d8SChris Lattner 46130fdc8d8SChris Lattner if (m_options.m_line_num != 0) 46230fdc8d8SChris Lattner break_type = eSetTypeFileAndLine; 46330fdc8d8SChris Lattner else if (m_options.m_load_addr != LLDB_INVALID_ADDRESS) 46430fdc8d8SChris Lattner break_type = eSetTypeAddress; 465fab10e89SJim Ingham else if (!m_options.m_func_names.empty()) 46630fdc8d8SChris Lattner break_type = eSetTypeFunctionName; 46730fdc8d8SChris Lattner else if (!m_options.m_func_regexp.empty()) 46830fdc8d8SChris Lattner break_type = eSetTypeFunctionRegexp; 469969795f1SJim Ingham else if (!m_options.m_source_text_regexp.empty()) 470969795f1SJim Ingham break_type = eSetTypeSourceRegexp; 471a72b31c7SJim Ingham else if (m_options.m_exception_language != eLanguageTypeUnknown) 472fab10e89SJim Ingham break_type = eSetTypeException; 47330fdc8d8SChris Lattner 4749e85e5a8SEugene Zelenko Breakpoint *bp = nullptr; 475274060b6SGreg Clayton FileSpec module_spec; 476a8558b62SJim Ingham const bool internal = false; 477a8558b62SJim Ingham 4782411167fSJim Ingham // If the user didn't specify skip-prologue, having an offset should turn that off. 4792411167fSJim Ingham if (m_options.m_offset_addr != 0 && m_options.m_skip_prologue == eLazyBoolCalculate) 4802411167fSJim Ingham m_options.m_skip_prologue = eLazyBoolNo; 4812411167fSJim Ingham 48230fdc8d8SChris Lattner switch (break_type) 48330fdc8d8SChris Lattner { 48430fdc8d8SChris Lattner case eSetTypeFileAndLine: // Breakpoint by source position 48530fdc8d8SChris Lattner { 48630fdc8d8SChris Lattner FileSpec file; 487c7bece56SGreg Clayton const size_t num_files = m_options.m_filenames.GetSize(); 48887df91b8SJim Ingham if (num_files == 0) 48987df91b8SJim Ingham { 49087df91b8SJim Ingham if (!GetDefaultFile (target, file, result)) 49187df91b8SJim Ingham { 49287df91b8SJim Ingham result.AppendError("No file supplied and no default file available."); 49387df91b8SJim Ingham result.SetStatus (eReturnStatusFailed); 49487df91b8SJim Ingham return false; 49587df91b8SJim Ingham } 49687df91b8SJim Ingham } 49787df91b8SJim Ingham else if (num_files > 1) 49887df91b8SJim Ingham { 49987df91b8SJim Ingham result.AppendError("Only one file at a time is allowed for file and line breakpoints."); 50087df91b8SJim Ingham result.SetStatus (eReturnStatusFailed); 50187df91b8SJim Ingham return false; 50287df91b8SJim Ingham } 50387df91b8SJim Ingham else 50487df91b8SJim Ingham file = m_options.m_filenames.GetFileSpecAtIndex(0); 50530fdc8d8SChris Lattner 5061f746071SGreg Clayton // Only check for inline functions if 5071f746071SGreg Clayton LazyBool check_inlines = eLazyBoolCalculate; 5081f746071SGreg Clayton 50987df91b8SJim Ingham bp = target->CreateBreakpoint (&(m_options.m_modules), 51030fdc8d8SChris Lattner file, 51130fdc8d8SChris Lattner m_options.m_line_num, 5122411167fSJim Ingham m_options.m_offset_addr, 5131f746071SGreg Clayton check_inlines, 514a8558b62SJim Ingham m_options.m_skip_prologue, 515eb023e75SGreg Clayton internal, 516055ad9beSIlia K m_options.m_hardware, 517055ad9beSIlia K m_options.m_move_to_nearest_code).get(); 51830fdc8d8SChris Lattner } 51930fdc8d8SChris Lattner break; 5206eee5aa0SGreg Clayton 52130fdc8d8SChris Lattner case eSetTypeAddress: // Breakpoint by address 522055a08a4SJim Ingham { 523055a08a4SJim Ingham // If a shared library has been specified, make an lldb_private::Address with the library, and 524055a08a4SJim Ingham // use that. That way the address breakpoint will track the load location of the library. 525055a08a4SJim Ingham size_t num_modules_specified = m_options.m_modules.GetSize(); 526055a08a4SJim Ingham if (num_modules_specified == 1) 527055a08a4SJim Ingham { 528055a08a4SJim Ingham const FileSpec *file_spec = m_options.m_modules.GetFileSpecPointerAtIndex(0); 529055a08a4SJim Ingham bp = target->CreateAddressInModuleBreakpoint (m_options.m_load_addr, 530055a08a4SJim Ingham internal, 531055a08a4SJim Ingham file_spec, 532055a08a4SJim Ingham m_options.m_hardware).get(); 533055a08a4SJim Ingham } 534055a08a4SJim Ingham else if (num_modules_specified == 0) 535055a08a4SJim Ingham { 536eb023e75SGreg Clayton bp = target->CreateBreakpoint (m_options.m_load_addr, 537eb023e75SGreg Clayton internal, 538eb023e75SGreg Clayton m_options.m_hardware).get(); 539055a08a4SJim Ingham } 540055a08a4SJim Ingham else 541055a08a4SJim Ingham { 542055a08a4SJim Ingham result.AppendError("Only one shared library can be specified for address breakpoints."); 543055a08a4SJim Ingham result.SetStatus(eReturnStatusFailed); 544055a08a4SJim Ingham return false; 545055a08a4SJim Ingham } 54630fdc8d8SChris Lattner break; 547055a08a4SJim Ingham } 54830fdc8d8SChris Lattner case eSetTypeFunctionName: // Breakpoint by function name 5490c5cd90dSGreg Clayton { 5500c5cd90dSGreg Clayton uint32_t name_type_mask = m_options.m_func_name_type_mask; 5510c5cd90dSGreg Clayton 5520c5cd90dSGreg Clayton if (name_type_mask == 0) 553e02b8504SGreg Clayton name_type_mask = eFunctionNameTypeAuto; 5540c5cd90dSGreg Clayton 55587df91b8SJim Ingham bp = target->CreateBreakpoint (&(m_options.m_modules), 55687df91b8SJim Ingham &(m_options.m_filenames), 557fab10e89SJim Ingham m_options.m_func_names, 558274060b6SGreg Clayton name_type_mask, 55923b1decbSDawn Perchik m_options.m_language, 5602411167fSJim Ingham m_options.m_offset_addr, 561a8558b62SJim Ingham m_options.m_skip_prologue, 562eb023e75SGreg Clayton internal, 563eb023e75SGreg Clayton m_options.m_hardware).get(); 5640c5cd90dSGreg Clayton } 56530fdc8d8SChris Lattner break; 5660c5cd90dSGreg Clayton 56730fdc8d8SChris Lattner case eSetTypeFunctionRegexp: // Breakpoint by regular expression function name 56830fdc8d8SChris Lattner { 56930fdc8d8SChris Lattner RegularExpression regexp(m_options.m_func_regexp.c_str()); 570969795f1SJim Ingham if (!regexp.IsValid()) 57130fdc8d8SChris Lattner { 572969795f1SJim Ingham char err_str[1024]; 573969795f1SJim Ingham regexp.GetErrorAsCString(err_str, sizeof(err_str)); 574969795f1SJim Ingham result.AppendErrorWithFormat("Function name regular expression could not be compiled: \"%s\"", 575969795f1SJim Ingham err_str); 57630fdc8d8SChris Lattner result.SetStatus (eReturnStatusFailed); 577969795f1SJim Ingham return false; 57830fdc8d8SChris Lattner } 57987df91b8SJim Ingham 580a8558b62SJim Ingham bp = target->CreateFuncRegexBreakpoint (&(m_options.m_modules), 581a8558b62SJim Ingham &(m_options.m_filenames), 582a8558b62SJim Ingham regexp, 5830fcdac36SJim Ingham m_options.m_language, 584a8558b62SJim Ingham m_options.m_skip_prologue, 585eb023e75SGreg Clayton internal, 586eb023e75SGreg Clayton m_options.m_hardware).get(); 58730fdc8d8SChris Lattner } 58830fdc8d8SChris Lattner break; 589969795f1SJim Ingham case eSetTypeSourceRegexp: // Breakpoint by regexp on source text. 590969795f1SJim Ingham { 591c7bece56SGreg Clayton const size_t num_files = m_options.m_filenames.GetSize(); 59287df91b8SJim Ingham 593e732052fSJim Ingham if (num_files == 0 && !m_options.m_all_files) 59487df91b8SJim Ingham { 595969795f1SJim Ingham FileSpec file; 59687df91b8SJim Ingham if (!GetDefaultFile (target, file, result)) 59787df91b8SJim Ingham { 59887df91b8SJim Ingham result.AppendError ("No files provided and could not find default file."); 59987df91b8SJim Ingham result.SetStatus (eReturnStatusFailed); 60087df91b8SJim Ingham return false; 60187df91b8SJim Ingham } 60287df91b8SJim Ingham else 60387df91b8SJim Ingham { 60487df91b8SJim Ingham m_options.m_filenames.Append (file); 60587df91b8SJim Ingham } 60687df91b8SJim Ingham } 6070c5cd90dSGreg Clayton 608969795f1SJim Ingham RegularExpression regexp(m_options.m_source_text_regexp.c_str()); 609969795f1SJim Ingham if (!regexp.IsValid()) 610969795f1SJim Ingham { 611969795f1SJim Ingham char err_str[1024]; 612969795f1SJim Ingham regexp.GetErrorAsCString(err_str, sizeof(err_str)); 613969795f1SJim Ingham result.AppendErrorWithFormat("Source text regular expression could not be compiled: \"%s\"", 614969795f1SJim Ingham err_str); 615969795f1SJim Ingham result.SetStatus (eReturnStatusFailed); 616969795f1SJim Ingham return false; 617969795f1SJim Ingham } 618eb023e75SGreg Clayton bp = target->CreateSourceRegexBreakpoint (&(m_options.m_modules), 619eb023e75SGreg Clayton &(m_options.m_filenames), 62076bb8d67SJim Ingham m_options.m_source_regex_func_names, 621eb023e75SGreg Clayton regexp, 622eb023e75SGreg Clayton internal, 623055ad9beSIlia K m_options.m_hardware, 624055ad9beSIlia K m_options.m_move_to_nearest_code).get(); 625969795f1SJim Ingham } 626969795f1SJim Ingham break; 627fab10e89SJim Ingham case eSetTypeException: 628fab10e89SJim Ingham { 629a72b31c7SJim Ingham Error precond_error; 630a72b31c7SJim Ingham bp = target->CreateExceptionBreakpoint (m_options.m_exception_language, 631eb023e75SGreg Clayton m_options.m_catch_bp, 632eb023e75SGreg Clayton m_options.m_throw_bp, 633a72b31c7SJim Ingham internal, 634a72b31c7SJim Ingham &m_options.m_exception_extra_args, 635a72b31c7SJim Ingham &precond_error).get(); 636a72b31c7SJim Ingham if (precond_error.Fail()) 637a72b31c7SJim Ingham { 638a72b31c7SJim Ingham result.AppendErrorWithFormat("Error setting extra exception arguments: %s", 639a72b31c7SJim Ingham precond_error.AsCString()); 640a72b31c7SJim Ingham target->RemoveBreakpointByID(bp->GetID()); 641a72b31c7SJim Ingham result.SetStatus(eReturnStatusFailed); 642a72b31c7SJim Ingham return false; 643a72b31c7SJim Ingham } 644fab10e89SJim Ingham } 645fab10e89SJim Ingham break; 64630fdc8d8SChris Lattner default: 64730fdc8d8SChris Lattner break; 64830fdc8d8SChris Lattner } 64930fdc8d8SChris Lattner 6501b54c88cSJim Ingham // Now set the various options that were passed in: 6511b54c88cSJim Ingham if (bp) 6521b54c88cSJim Ingham { 6531b54c88cSJim Ingham if (m_options.m_thread_id != LLDB_INVALID_THREAD_ID) 6541b54c88cSJim Ingham bp->SetThreadID (m_options.m_thread_id); 6551b54c88cSJim Ingham 656c982c768SGreg Clayton if (m_options.m_thread_index != UINT32_MAX) 6571b54c88cSJim Ingham bp->GetOptions()->GetThreadSpec()->SetIndex(m_options.m_thread_index); 6581b54c88cSJim Ingham 6591b54c88cSJim Ingham if (!m_options.m_thread_name.empty()) 6601b54c88cSJim Ingham bp->GetOptions()->GetThreadSpec()->SetName(m_options.m_thread_name.c_str()); 6611b54c88cSJim Ingham 6621b54c88cSJim Ingham if (!m_options.m_queue_name.empty()) 6631b54c88cSJim Ingham bp->GetOptions()->GetThreadSpec()->SetQueueName(m_options.m_queue_name.c_str()); 6641b54c88cSJim Ingham 665c982c768SGreg Clayton if (m_options.m_ignore_count != 0) 6661b54c88cSJim Ingham bp->GetOptions()->SetIgnoreCount(m_options.m_ignore_count); 6677d49c9c8SJohnny Chen 6687d49c9c8SJohnny Chen if (!m_options.m_condition.empty()) 6697d49c9c8SJohnny Chen bp->GetOptions()->SetCondition(m_options.m_condition.c_str()); 670ca36cd16SJim Ingham 6715e09c8c3SJim Ingham if (!m_options.m_breakpoint_names.empty()) 6725e09c8c3SJim Ingham { 6735e09c8c3SJim Ingham Error error; // We don't need to check the error here, since the option parser checked it... 6745e09c8c3SJim Ingham for (auto name : m_options.m_breakpoint_names) 6755e09c8c3SJim Ingham bp->AddName(name.c_str(), error); 6765e09c8c3SJim Ingham } 6775e09c8c3SJim Ingham 678ca36cd16SJim Ingham bp->SetOneShot (m_options.m_one_shot); 6791b54c88cSJim Ingham } 6801b54c88cSJim Ingham 681969795f1SJim Ingham if (bp) 68230fdc8d8SChris Lattner { 68385e8b814SJim Ingham Stream &output_stream = result.GetOutputStream(); 6841391cc7dSJim Ingham const bool show_locations = false; 6851391cc7dSJim Ingham bp->GetDescription(&output_stream, lldb::eDescriptionLevelInitial, show_locations); 6864aeb1989SJim Ingham if (target == m_interpreter.GetDebugger().GetDummyTarget()) 6874aeb1989SJim Ingham output_stream.Printf ("Breakpoint set in dummy target, will get copied into future targets.\n"); 6884aeb1989SJim Ingham else 6894aeb1989SJim Ingham { 690fab10e89SJim Ingham // Don't print out this warning for exception breakpoints. They can get set before the target 691fab10e89SJim Ingham // is set, but we won't know how to actually set the breakpoint till we run. 692fab10e89SJim Ingham if (bp->GetNumLocations() == 0 && break_type != eSetTypeException) 6934aeb1989SJim Ingham { 694be484f41SCaroline Tice output_stream.Printf ("WARNING: Unable to resolve breakpoint to any actual locations.\n"); 6954aeb1989SJim Ingham } 6964aeb1989SJim Ingham } 69730fdc8d8SChris Lattner result.SetStatus (eReturnStatusSuccessFinishResult); 69830fdc8d8SChris Lattner } 69930fdc8d8SChris Lattner else if (!bp) 70030fdc8d8SChris Lattner { 70130fdc8d8SChris Lattner result.AppendError ("Breakpoint creation failed: No breakpoint created."); 70230fdc8d8SChris Lattner result.SetStatus (eReturnStatusFailed); 70330fdc8d8SChris Lattner } 70430fdc8d8SChris Lattner 70530fdc8d8SChris Lattner return result.Succeeded(); 70630fdc8d8SChris Lattner } 70730fdc8d8SChris Lattner 7085a988416SJim Ingham private: 7095a988416SJim Ingham bool 7105a988416SJim Ingham GetDefaultFile (Target *target, FileSpec &file, CommandReturnObject &result) 7115a988416SJim Ingham { 7125a988416SJim Ingham uint32_t default_line; 7135a988416SJim Ingham // First use the Source Manager's default file. 7145a988416SJim Ingham // Then use the current stack frame's file. 7155a988416SJim Ingham if (!target->GetSourceManager().GetDefaultFileAndLine(file, default_line)) 7165a988416SJim Ingham { 717b57e4a1bSJason Molenda StackFrame *cur_frame = m_exe_ctx.GetFramePtr(); 7189e85e5a8SEugene Zelenko if (cur_frame == nullptr) 7195a988416SJim Ingham { 7205a988416SJim Ingham result.AppendError ("No selected frame to use to find the default file."); 7215a988416SJim Ingham result.SetStatus (eReturnStatusFailed); 7225a988416SJim Ingham return false; 7235a988416SJim Ingham } 7245a988416SJim Ingham else if (!cur_frame->HasDebugInformation()) 7255a988416SJim Ingham { 7265a988416SJim Ingham result.AppendError ("Cannot use the selected frame to find the default file, it has no debug info."); 7275a988416SJim Ingham result.SetStatus (eReturnStatusFailed); 7285a988416SJim Ingham return false; 7295a988416SJim Ingham } 7305a988416SJim Ingham else 7315a988416SJim Ingham { 7325a988416SJim Ingham const SymbolContext &sc = cur_frame->GetSymbolContext (eSymbolContextLineEntry); 7335a988416SJim Ingham if (sc.line_entry.file) 7345a988416SJim Ingham { 7355a988416SJim Ingham file = sc.line_entry.file; 7365a988416SJim Ingham } 7375a988416SJim Ingham else 7385a988416SJim Ingham { 7395a988416SJim Ingham result.AppendError ("Can't find the file for the selected frame to use as the default file."); 7405a988416SJim Ingham result.SetStatus (eReturnStatusFailed); 7415a988416SJim Ingham return false; 7425a988416SJim Ingham } 7435a988416SJim Ingham } 7445a988416SJim Ingham } 7455a988416SJim Ingham return true; 7465a988416SJim Ingham } 7475a988416SJim Ingham 7485a988416SJim Ingham CommandOptions m_options; 7495a988416SJim Ingham }; 7509e85e5a8SEugene Zelenko 7515a988416SJim Ingham // If an additional option set beyond LLDB_OPTION_SET_10 is added, make sure to 7525a988416SJim Ingham // update the numbers passed to LLDB_OPT_SET_FROM_TO(...) appropriately. 7535a988416SJim Ingham #define LLDB_OPT_FILE ( LLDB_OPT_SET_FROM_TO(1, 9) & ~LLDB_OPT_SET_2 ) 7545a988416SJim Ingham #define LLDB_OPT_NOT_10 ( LLDB_OPT_SET_FROM_TO(1, 10) & ~LLDB_OPT_SET_10 ) 7555a988416SJim Ingham #define LLDB_OPT_SKIP_PROLOGUE ( LLDB_OPT_SET_1 | LLDB_OPT_SET_FROM_TO(3,8) ) 7562411167fSJim Ingham #define LLDB_OPT_OFFSET_APPLIES (LLDB_OPT_SET_1 | LLDB_OPT_SET_FROM_TO(3,8) ) 757055ad9beSIlia K #define LLDB_OPT_MOVE_TO_NEAREST_CODE ( LLDB_OPT_SET_1 | LLDB_OPT_SET_9 ) 7580fcdac36SJim Ingham #define LLDB_OPT_EXPR_LANGUAGE ( LLDB_OPT_SET_FROM_TO(3, 8) ) 7595a988416SJim Ingham 7605a988416SJim Ingham OptionDefinition 7615a988416SJim Ingham CommandObjectBreakpointSet::CommandOptions::g_option_table[] = 7625a988416SJim Ingham { 763*ac9c3a62SKate Stone // clang-format off 764*ac9c3a62SKate Stone {LLDB_OPT_NOT_10, false, "shlib", 's', OptionParser::eRequiredArgument, nullptr, nullptr, CommandCompletions::eModuleCompletion, eArgTypeShlibName, "Set the breakpoint only in this shared library. Can repeat this option " 765*ac9c3a62SKate Stone "multiple times to specify multiple shared libraries."}, 766*ac9c3a62SKate Stone {LLDB_OPT_SET_ALL, false, "ignore-count", 'i', OptionParser::eRequiredArgument, nullptr, nullptr, 0, eArgTypeCount, "Set the number of times this breakpoint is skipped before stopping." }, 767*ac9c3a62SKate Stone {LLDB_OPT_SET_ALL, false, "one-shot", 'o', OptionParser::eNoArgument, nullptr, nullptr, 0, eArgTypeNone, "The breakpoint is deleted the first time it causes a stop." }, 768*ac9c3a62SKate Stone {LLDB_OPT_SET_ALL, false, "condition", 'c', OptionParser::eRequiredArgument, nullptr, nullptr, 0, eArgTypeExpression, "The breakpoint stops only if this condition expression evaluates to true."}, 769*ac9c3a62SKate Stone {LLDB_OPT_SET_ALL, false, "thread-index", 'x', OptionParser::eRequiredArgument, nullptr, nullptr, 0, eArgTypeThreadIndex, "The breakpoint stops only for the thread whose indeX matches this argument."}, 770*ac9c3a62SKate Stone {LLDB_OPT_SET_ALL, false, "thread-id", 't', OptionParser::eRequiredArgument, nullptr, nullptr, 0, eArgTypeThreadID, "The breakpoint stops only for the thread whose TID matches this argument."}, 771*ac9c3a62SKate Stone {LLDB_OPT_SET_ALL, false, "thread-name", 'T', OptionParser::eRequiredArgument, nullptr, nullptr, 0, eArgTypeThreadName, "The breakpoint stops only for the thread whose thread name matches this " 772*ac9c3a62SKate Stone "argument."}, 773*ac9c3a62SKate Stone {LLDB_OPT_SET_ALL, false, "hardware", 'H', OptionParser::eNoArgument, nullptr, nullptr, 0, eArgTypeNone, "Require the breakpoint to use hardware breakpoints."}, 774*ac9c3a62SKate Stone {LLDB_OPT_SET_ALL, false, "queue-name", 'q', OptionParser::eRequiredArgument, nullptr, nullptr, 0, eArgTypeQueueName, "The breakpoint stops only for threads in the queue whose name is given by " 775*ac9c3a62SKate Stone "this argument."}, 776*ac9c3a62SKate Stone {LLDB_OPT_FILE, false, "file", 'f', OptionParser::eRequiredArgument, nullptr, nullptr, CommandCompletions::eSourceFileCompletion, eArgTypeFilename, "Specifies the source file in which to set this breakpoint. Note, by default " 777*ac9c3a62SKate Stone "lldb only looks for files that are #included if they use the standard include " 778*ac9c3a62SKate Stone "file extensions. To set breakpoints on .c/.cpp/.m/.mm files that are " 779*ac9c3a62SKate Stone "#included, set target.inline-breakpoint-strategy to \"always\"."}, 780*ac9c3a62SKate Stone {LLDB_OPT_SET_1, true, "line", 'l', OptionParser::eRequiredArgument, nullptr, nullptr, 0, eArgTypeLineNum, "Specifies the line number on which to set this breakpoint."}, 7815a988416SJim Ingham 7825a988416SJim Ingham // Comment out this option for the moment, as we don't actually use it, but will in the future. 7835a988416SJim Ingham // This way users won't see it, but the infrastructure is left in place. 7849e85e5a8SEugene Zelenko // { 0, false, "column", 'C', OptionParser::eRequiredArgument, nullptr, "<column>", 7855a988416SJim Ingham // "Set the breakpoint by source location at this particular column."}, 7865a988416SJim Ingham 787*ac9c3a62SKate Stone {LLDB_OPT_SET_2, true, "address", 'a', OptionParser::eRequiredArgument, nullptr, nullptr, 0, eArgTypeAddressOrExpression, "Set the breakpoint at the specified address. If the address maps uniquely to " 788*ac9c3a62SKate Stone "a particular binary, then the address will be converted to a \"file\" " 789*ac9c3a62SKate Stone "address, so that the breakpoint will track that binary+offset no matter where " 790*ac9c3a62SKate Stone "the binary eventually loads. Alternately, if you also specify the module - " 791*ac9c3a62SKate Stone "with the -s option - then the address will be treated as a file address in " 792*ac9c3a62SKate Stone "that module, and resolved accordingly. Again, this will allow lldb to track " 793*ac9c3a62SKate Stone "that offset on subsequent reloads. The module need not have been loaded at " 794*ac9c3a62SKate Stone "the time you specify this breakpoint, and will get resolved when the module " 795*ac9c3a62SKate Stone "is loaded."}, 796*ac9c3a62SKate Stone {LLDB_OPT_SET_3, true, "name", 'n', OptionParser::eRequiredArgument, nullptr, nullptr, CommandCompletions::eSymbolCompletion, eArgTypeFunctionName, "Set the breakpoint by function name. Can be repeated multiple times to make " 797*ac9c3a62SKate Stone "one breakpoint for multiple names"}, 798*ac9c3a62SKate Stone {LLDB_OPT_SET_9, false, "source-regexp-function", 'X', OptionParser::eRequiredArgument, nullptr, nullptr, CommandCompletions::eSymbolCompletion, eArgTypeFunctionName, "When used with '-p' limits the source regex to source contained in the named " 799*ac9c3a62SKate Stone "functions. Can be repeated multiple times."}, 800*ac9c3a62SKate Stone {LLDB_OPT_SET_4, true, "fullname", 'F', OptionParser::eRequiredArgument, nullptr, nullptr, CommandCompletions::eSymbolCompletion, eArgTypeFullName, "Set the breakpoint by fully qualified function names. For C++ this means " 801*ac9c3a62SKate Stone "namespaces and all arguments, and for Objective C this means a full function " 802*ac9c3a62SKate Stone "prototype with class and selector. Can be repeated multiple times to make " 803*ac9c3a62SKate Stone "one breakpoint for multiple names."}, 804*ac9c3a62SKate Stone {LLDB_OPT_SET_5, true, "selector", 'S', OptionParser::eRequiredArgument, nullptr, nullptr, 0, eArgTypeSelector, "Set the breakpoint by ObjC selector name. Can be repeated multiple times to " 805*ac9c3a62SKate Stone "make one breakpoint for multiple Selectors."}, 806*ac9c3a62SKate Stone {LLDB_OPT_SET_6, true, "method", 'M', OptionParser::eRequiredArgument, nullptr, nullptr, 0, eArgTypeMethod, "Set the breakpoint by C++ method names. Can be repeated multiple times to " 807*ac9c3a62SKate Stone "make one breakpoint for multiple methods."}, 808*ac9c3a62SKate Stone {LLDB_OPT_SET_7, true, "func-regex", 'r', OptionParser::eRequiredArgument, nullptr, nullptr, 0, eArgTypeRegularExpression, "Set the breakpoint by function name, evaluating a regular-expression to find " 809*ac9c3a62SKate Stone "the function name(s)."}, 810*ac9c3a62SKate Stone {LLDB_OPT_SET_8, true, "basename", 'b', OptionParser::eRequiredArgument, nullptr, nullptr, CommandCompletions::eSymbolCompletion, eArgTypeFunctionName, "Set the breakpoint by function basename (C++ namespaces and arguments will be " 811*ac9c3a62SKate Stone "ignored). Can be repeated multiple times to make one breakpoint for multiple " 812*ac9c3a62SKate Stone "symbols."}, 813*ac9c3a62SKate Stone {LLDB_OPT_SET_9, true, "source-pattern-regexp", 'p', OptionParser::eRequiredArgument, nullptr, nullptr, 0, eArgTypeRegularExpression, "Set the breakpoint by specifying a regular expression which is matched " 814*ac9c3a62SKate Stone "against the source text in a source file or files specified with the -f " 815*ac9c3a62SKate Stone "option. The -f option can be specified more than once. If no source files " 816*ac9c3a62SKate Stone "are specified, uses the current \"default source file\". If you want to " 817*ac9c3a62SKate Stone "match against all source files, pass the \"--all-files\" option."}, 818*ac9c3a62SKate Stone {LLDB_OPT_SET_9, false, "all-files", 'A', OptionParser::eNoArgument, nullptr, nullptr, 0, eArgTypeNone, "All files are searched for source pattern matches."}, 819*ac9c3a62SKate Stone {LLDB_OPT_SET_10, true, "language-exception", 'E', OptionParser::eRequiredArgument, nullptr, nullptr, 0, eArgTypeLanguage, "Set the breakpoint on exceptions thrown by the specified language (without " 820*ac9c3a62SKate Stone "options, on throw but not catch.)"}, 821*ac9c3a62SKate Stone {LLDB_OPT_SET_10, false, "on-throw", 'w', OptionParser::eRequiredArgument, nullptr, nullptr, 0, eArgTypeBoolean, "Set the breakpoint on exception throW."}, 822*ac9c3a62SKate Stone {LLDB_OPT_SET_10, false, "on-catch", 'h', OptionParser::eRequiredArgument, nullptr, nullptr, 0, eArgTypeBoolean, "Set the breakpoint on exception catcH."}, 8235a988416SJim Ingham 824a72b31c7SJim Ingham // Don't add this option till it actually does something useful... 8259e85e5a8SEugene Zelenko // { LLDB_OPT_SET_10, false, "exception-typename", 'O', OptionParser::eRequiredArgument, nullptr, nullptr, 0, eArgTypeTypeName, 826a72b31c7SJim 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" }, 827a72b31c7SJim Ingham 828*ac9c3a62SKate Stone {LLDB_OPT_EXPR_LANGUAGE, false, "language", 'L', OptionParser::eRequiredArgument, nullptr, nullptr, 0, eArgTypeLanguage, "Specifies the Language to use when interpreting the breakpoint's expression " 829*ac9c3a62SKate Stone "(note: currently only implemented for setting breakpoints on identifiers). " 830*ac9c3a62SKate Stone "If not set the target.language setting is used."}, 831*ac9c3a62SKate Stone {LLDB_OPT_SKIP_PROLOGUE, false, "skip-prologue", 'K', OptionParser::eRequiredArgument, nullptr, nullptr, 0, eArgTypeBoolean, "sKip the prologue if the breakpoint is at the beginning of a function. " 832*ac9c3a62SKate Stone "If not set the target.skip-prologue setting is used."}, 833*ac9c3a62SKate Stone {LLDB_OPT_SET_ALL, false, "dummy-breakpoints", 'D', OptionParser::eNoArgument, nullptr, nullptr, 0, eArgTypeNone, "Sets Dummy breakpoints - i.e. breakpoints set before a file is provided, " 834*ac9c3a62SKate Stone "which prime new targets."}, 835*ac9c3a62SKate Stone {LLDB_OPT_SET_ALL, false, "breakpoint-name", 'N', OptionParser::eRequiredArgument, nullptr, nullptr, 0, eArgTypeBreakpointName, "Adds this to the list of names for this breakpoint."}, 836*ac9c3a62SKate Stone {LLDB_OPT_OFFSET_APPLIES, false, "address-slide", 'R', OptionParser::eRequiredArgument, nullptr, nullptr, 0, eArgTypeAddress, "Add the specified offset to whatever address(es) the breakpoint resolves to. " 8372411167fSJim Ingham "At present this applies the offset directly as given, and doesn't try to align it to instruction boundaries."}, 838*ac9c3a62SKate Stone {LLDB_OPT_MOVE_TO_NEAREST_CODE, false, "move-to-nearest-code", 'm', OptionParser::eRequiredArgument, nullptr, nullptr, 0, eArgTypeBoolean, "Move breakpoints to nearest code. If not set the target.move-to-nearest-code " 839*ac9c3a62SKate Stone "setting is used."}, 8409e85e5a8SEugene Zelenko {0, false, nullptr, 0, 0, nullptr, nullptr, 0, eArgTypeNone, nullptr} 841*ac9c3a62SKate Stone // clang-format on 8425a988416SJim Ingham }; 8435a988416SJim Ingham 8445a988416SJim Ingham //------------------------------------------------------------------------- 8455a988416SJim Ingham // CommandObjectBreakpointModify 8465a988416SJim Ingham //------------------------------------------------------------------------- 8475a988416SJim Ingham #pragma mark Modify 8485a988416SJim Ingham 8495a988416SJim Ingham class CommandObjectBreakpointModify : public CommandObjectParsed 8505a988416SJim Ingham { 8515a988416SJim Ingham public: 8525a988416SJim Ingham CommandObjectBreakpointModify (CommandInterpreter &interpreter) : 8535a988416SJim Ingham CommandObjectParsed(interpreter, 8545a988416SJim Ingham "breakpoint modify", 8555a988416SJim Ingham "Modify the options on a breakpoint or set of breakpoints in the executable. " 8565a988416SJim Ingham "If no breakpoint is specified, acts on the last created breakpoint. " 8575a988416SJim Ingham "With the exception of -e, -d and -i, passing an empty argument clears the modification.", 8589e85e5a8SEugene Zelenko nullptr), 859e1cfbc79STodd Fiala m_options () 8605a988416SJim Ingham { 8615a988416SJim Ingham CommandArgumentEntry arg; 8625a988416SJim Ingham CommandObject::AddIDsArgumentData(arg, eArgTypeBreakpointID, eArgTypeBreakpointIDRange); 8635a988416SJim Ingham // Add the entry for the first argument for this command to the object's arguments vector. 8645a988416SJim Ingham m_arguments.push_back (arg); 8655a988416SJim Ingham } 8665a988416SJim Ingham 8679e85e5a8SEugene Zelenko ~CommandObjectBreakpointModify() override = default; 8685a988416SJim Ingham 86913d21e9aSBruce Mitchener Options * 87013d21e9aSBruce Mitchener GetOptions () override 8715a988416SJim Ingham { 8725a988416SJim Ingham return &m_options; 8735a988416SJim Ingham } 8745a988416SJim Ingham 8755a988416SJim Ingham class CommandOptions : public Options 8765a988416SJim Ingham { 8775a988416SJim Ingham public: 878e1cfbc79STodd Fiala CommandOptions () : 879e1cfbc79STodd Fiala Options (), 8805a988416SJim Ingham m_ignore_count (0), 8815a988416SJim Ingham m_thread_id(LLDB_INVALID_THREAD_ID), 8825a988416SJim Ingham m_thread_id_passed(false), 8835a988416SJim Ingham m_thread_index (UINT32_MAX), 8845a988416SJim Ingham m_thread_index_passed(false), 8855a988416SJim Ingham m_thread_name(), 8865a988416SJim Ingham m_queue_name(), 8875a988416SJim Ingham m_condition (), 888ca36cd16SJim Ingham m_one_shot (false), 8895a988416SJim Ingham m_enable_passed (false), 8905a988416SJim Ingham m_enable_value (false), 8915a988416SJim Ingham m_name_passed (false), 8925a988416SJim Ingham m_queue_passed (false), 893ca36cd16SJim Ingham m_condition_passed (false), 89433df7cd3SJim Ingham m_one_shot_passed (false), 89533df7cd3SJim Ingham m_use_dummy (false) 8965a988416SJim Ingham { 8975a988416SJim Ingham } 8985a988416SJim Ingham 8999e85e5a8SEugene Zelenko ~CommandOptions() override = default; 9005a988416SJim Ingham 90113d21e9aSBruce Mitchener Error 902e1cfbc79STodd Fiala SetOptionValue (uint32_t option_idx, const char *option_arg, 903e1cfbc79STodd Fiala ExecutionContext *execution_context) override 9045a988416SJim Ingham { 9055a988416SJim Ingham Error error; 9063bcdfc0eSGreg Clayton const int short_option = m_getopt_table[option_idx].val; 9075a988416SJim Ingham 9085a988416SJim Ingham switch (short_option) 9095a988416SJim Ingham { 9105a988416SJim Ingham case 'c': 9119e85e5a8SEugene Zelenko if (option_arg != nullptr) 9125a988416SJim Ingham m_condition.assign (option_arg); 9135a988416SJim Ingham else 9145a988416SJim Ingham m_condition.clear(); 9155a988416SJim Ingham m_condition_passed = true; 9165a988416SJim Ingham break; 9175a988416SJim Ingham case 'd': 9185a988416SJim Ingham m_enable_passed = true; 9195a988416SJim Ingham m_enable_value = false; 9205a988416SJim Ingham break; 92133df7cd3SJim Ingham case 'D': 92233df7cd3SJim Ingham m_use_dummy = true; 92333df7cd3SJim Ingham break; 9245a988416SJim Ingham case 'e': 9255a988416SJim Ingham m_enable_passed = true; 9265a988416SJim Ingham m_enable_value = true; 9275a988416SJim Ingham break; 9285a988416SJim Ingham case 'i': 9295275aaa0SVince Harron m_ignore_count = StringConvert::ToUInt32(option_arg, UINT32_MAX, 0); 9305a988416SJim Ingham if (m_ignore_count == UINT32_MAX) 9315a988416SJim Ingham error.SetErrorStringWithFormat ("invalid ignore count '%s'", option_arg); 9325a988416SJim Ingham break; 933ca36cd16SJim Ingham case 'o': 934ca36cd16SJim Ingham { 935ca36cd16SJim Ingham bool value, success; 936ca36cd16SJim Ingham value = Args::StringToBoolean(option_arg, false, &success); 937ca36cd16SJim Ingham if (success) 938ca36cd16SJim Ingham { 939ca36cd16SJim Ingham m_one_shot_passed = true; 940ca36cd16SJim Ingham m_one_shot = value; 941ca36cd16SJim Ingham } 942ca36cd16SJim Ingham else 943ca36cd16SJim Ingham error.SetErrorStringWithFormat("invalid boolean value '%s' passed for -o option", option_arg); 944ca36cd16SJim Ingham } 945ca36cd16SJim Ingham break; 9465a988416SJim Ingham case 't' : 9475a988416SJim Ingham if (option_arg[0] == '\0') 9485a988416SJim Ingham { 9495a988416SJim Ingham m_thread_id = LLDB_INVALID_THREAD_ID; 9505a988416SJim Ingham m_thread_id_passed = true; 9515a988416SJim Ingham } 9525a988416SJim Ingham else 9535a988416SJim Ingham { 9545275aaa0SVince Harron m_thread_id = StringConvert::ToUInt64(option_arg, LLDB_INVALID_THREAD_ID, 0); 9555a988416SJim Ingham if (m_thread_id == LLDB_INVALID_THREAD_ID) 9565a988416SJim Ingham error.SetErrorStringWithFormat ("invalid thread id string '%s'", option_arg); 9575a988416SJim Ingham else 9585a988416SJim Ingham m_thread_id_passed = true; 9595a988416SJim Ingham } 9605a988416SJim Ingham break; 9615a988416SJim Ingham case 'T': 9629e85e5a8SEugene Zelenko if (option_arg != nullptr) 9635a988416SJim Ingham m_thread_name.assign (option_arg); 9645a988416SJim Ingham else 9655a988416SJim Ingham m_thread_name.clear(); 9665a988416SJim Ingham m_name_passed = true; 9675a988416SJim Ingham break; 9685a988416SJim Ingham case 'q': 9699e85e5a8SEugene Zelenko if (option_arg != nullptr) 9705a988416SJim Ingham m_queue_name.assign (option_arg); 9715a988416SJim Ingham else 9725a988416SJim Ingham m_queue_name.clear(); 9735a988416SJim Ingham m_queue_passed = true; 9745a988416SJim Ingham break; 9755a988416SJim Ingham case 'x': 9765a988416SJim Ingham if (option_arg[0] == '\n') 9775a988416SJim Ingham { 9785a988416SJim Ingham m_thread_index = UINT32_MAX; 9795a988416SJim Ingham m_thread_index_passed = true; 9805a988416SJim Ingham } 9815a988416SJim Ingham else 9825a988416SJim Ingham { 9835275aaa0SVince Harron m_thread_index = StringConvert::ToUInt32 (option_arg, UINT32_MAX, 0); 9845a988416SJim Ingham if (m_thread_id == UINT32_MAX) 9855a988416SJim Ingham error.SetErrorStringWithFormat ("invalid thread index string '%s'", option_arg); 9865a988416SJim Ingham else 9875a988416SJim Ingham m_thread_index_passed = true; 9885a988416SJim Ingham } 9895a988416SJim Ingham break; 9905a988416SJim Ingham default: 9915a988416SJim Ingham error.SetErrorStringWithFormat ("unrecognized option '%c'", short_option); 9925a988416SJim Ingham break; 9935a988416SJim Ingham } 9945a988416SJim Ingham 9955a988416SJim Ingham return error; 9965a988416SJim Ingham } 9979e85e5a8SEugene Zelenko 9985a988416SJim Ingham void 999e1cfbc79STodd Fiala OptionParsingStarting (ExecutionContext *execution_context) override 10005a988416SJim Ingham { 10015a988416SJim Ingham m_ignore_count = 0; 10025a988416SJim Ingham m_thread_id = LLDB_INVALID_THREAD_ID; 10035a988416SJim Ingham m_thread_id_passed = false; 10045a988416SJim Ingham m_thread_index = UINT32_MAX; 10055a988416SJim Ingham m_thread_index_passed = false; 10065a988416SJim Ingham m_thread_name.clear(); 10075a988416SJim Ingham m_queue_name.clear(); 10085a988416SJim Ingham m_condition.clear(); 1009ca36cd16SJim Ingham m_one_shot = false; 10105a988416SJim Ingham m_enable_passed = false; 10115a988416SJim Ingham m_queue_passed = false; 10125a988416SJim Ingham m_name_passed = false; 10135a988416SJim Ingham m_condition_passed = false; 1014ca36cd16SJim Ingham m_one_shot_passed = false; 101533df7cd3SJim Ingham m_use_dummy = false; 10165a988416SJim Ingham } 10175a988416SJim Ingham 10185a988416SJim Ingham const OptionDefinition* 101913d21e9aSBruce Mitchener GetDefinitions () override 10205a988416SJim Ingham { 10215a988416SJim Ingham return g_option_table; 10225a988416SJim Ingham } 10235a988416SJim Ingham 10245a988416SJim Ingham // Options table: Required for subclasses of Options. 10255a988416SJim Ingham 10265a988416SJim Ingham static OptionDefinition g_option_table[]; 10275a988416SJim Ingham 10285a988416SJim Ingham // Instance variables to hold the values for command options. 10295a988416SJim Ingham 10305a988416SJim Ingham uint32_t m_ignore_count; 10315a988416SJim Ingham lldb::tid_t m_thread_id; 10325a988416SJim Ingham bool m_thread_id_passed; 10335a988416SJim Ingham uint32_t m_thread_index; 10345a988416SJim Ingham bool m_thread_index_passed; 10355a988416SJim Ingham std::string m_thread_name; 10365a988416SJim Ingham std::string m_queue_name; 10375a988416SJim Ingham std::string m_condition; 1038ca36cd16SJim Ingham bool m_one_shot; 10395a988416SJim Ingham bool m_enable_passed; 10405a988416SJim Ingham bool m_enable_value; 10415a988416SJim Ingham bool m_name_passed; 10425a988416SJim Ingham bool m_queue_passed; 10435a988416SJim Ingham bool m_condition_passed; 1044ca36cd16SJim Ingham bool m_one_shot_passed; 104533df7cd3SJim Ingham bool m_use_dummy; 10465a988416SJim Ingham }; 10475a988416SJim Ingham 10485a988416SJim Ingham protected: 104913d21e9aSBruce Mitchener bool 105013d21e9aSBruce Mitchener DoExecute (Args& command, CommandReturnObject &result) override 10515a988416SJim Ingham { 105233df7cd3SJim Ingham Target *target = GetSelectedOrDummyTarget(m_options.m_use_dummy); 10539e85e5a8SEugene Zelenko if (target == nullptr) 10545a988416SJim Ingham { 10555a988416SJim Ingham result.AppendError ("Invalid target. No existing target or breakpoints."); 10565a988416SJim Ingham result.SetStatus (eReturnStatusFailed); 10575a988416SJim Ingham return false; 10585a988416SJim Ingham } 10595a988416SJim Ingham 1060bb19a13cSSaleem Abdulrasool std::unique_lock<std::recursive_mutex> lock; 1061bb19a13cSSaleem Abdulrasool target->GetBreakpointList().GetListMutex(lock); 10625a988416SJim Ingham 10635a988416SJim Ingham BreakpointIDList valid_bp_ids; 10645a988416SJim Ingham 10655e09c8c3SJim Ingham CommandObjectMultiwordBreakpoint::VerifyBreakpointOrLocationIDs (command, target, result, &valid_bp_ids); 10665a988416SJim Ingham 10675a988416SJim Ingham if (result.Succeeded()) 10685a988416SJim Ingham { 10695a988416SJim Ingham const size_t count = valid_bp_ids.GetSize(); 10705a988416SJim Ingham for (size_t i = 0; i < count; ++i) 10715a988416SJim Ingham { 10725a988416SJim Ingham BreakpointID cur_bp_id = valid_bp_ids.GetBreakpointIDAtIndex (i); 10735a988416SJim Ingham 10745a988416SJim Ingham if (cur_bp_id.GetBreakpointID() != LLDB_INVALID_BREAK_ID) 10755a988416SJim Ingham { 10765a988416SJim Ingham Breakpoint *bp = target->GetBreakpointByID (cur_bp_id.GetBreakpointID()).get(); 10775a988416SJim Ingham if (cur_bp_id.GetLocationID() != LLDB_INVALID_BREAK_ID) 10785a988416SJim Ingham { 10795a988416SJim Ingham BreakpointLocation *location = bp->FindLocationByID (cur_bp_id.GetLocationID()).get(); 10805a988416SJim Ingham if (location) 10815a988416SJim Ingham { 10825a988416SJim Ingham if (m_options.m_thread_id_passed) 10835a988416SJim Ingham location->SetThreadID (m_options.m_thread_id); 10845a988416SJim Ingham 10855a988416SJim Ingham if (m_options.m_thread_index_passed) 10865a988416SJim Ingham location->SetThreadIndex(m_options.m_thread_index); 10875a988416SJim Ingham 10885a988416SJim Ingham if (m_options.m_name_passed) 10895a988416SJim Ingham location->SetThreadName(m_options.m_thread_name.c_str()); 10905a988416SJim Ingham 10915a988416SJim Ingham if (m_options.m_queue_passed) 10925a988416SJim Ingham location->SetQueueName(m_options.m_queue_name.c_str()); 10935a988416SJim Ingham 10945a988416SJim Ingham if (m_options.m_ignore_count != 0) 10955a988416SJim Ingham location->SetIgnoreCount(m_options.m_ignore_count); 10965a988416SJim Ingham 10975a988416SJim Ingham if (m_options.m_enable_passed) 10985a988416SJim Ingham location->SetEnabled (m_options.m_enable_value); 10995a988416SJim Ingham 11005a988416SJim Ingham if (m_options.m_condition_passed) 11015a988416SJim Ingham location->SetCondition (m_options.m_condition.c_str()); 11025a988416SJim Ingham } 11035a988416SJim Ingham } 11045a988416SJim Ingham else 11055a988416SJim Ingham { 11065a988416SJim Ingham if (m_options.m_thread_id_passed) 11075a988416SJim Ingham bp->SetThreadID (m_options.m_thread_id); 11085a988416SJim Ingham 11095a988416SJim Ingham if (m_options.m_thread_index_passed) 11105a988416SJim Ingham bp->SetThreadIndex(m_options.m_thread_index); 11115a988416SJim Ingham 11125a988416SJim Ingham if (m_options.m_name_passed) 11135a988416SJim Ingham bp->SetThreadName(m_options.m_thread_name.c_str()); 11145a988416SJim Ingham 11155a988416SJim Ingham if (m_options.m_queue_passed) 11165a988416SJim Ingham bp->SetQueueName(m_options.m_queue_name.c_str()); 11175a988416SJim Ingham 11185a988416SJim Ingham if (m_options.m_ignore_count != 0) 11195a988416SJim Ingham bp->SetIgnoreCount(m_options.m_ignore_count); 11205a988416SJim Ingham 11215a988416SJim Ingham if (m_options.m_enable_passed) 11225a988416SJim Ingham bp->SetEnabled (m_options.m_enable_value); 11235a988416SJim Ingham 11245a988416SJim Ingham if (m_options.m_condition_passed) 11255a988416SJim Ingham bp->SetCondition (m_options.m_condition.c_str()); 11265a988416SJim Ingham } 11275a988416SJim Ingham } 11285a988416SJim Ingham } 11295a988416SJim Ingham } 11305a988416SJim Ingham 11315a988416SJim Ingham return result.Succeeded(); 11325a988416SJim Ingham } 11335a988416SJim Ingham 11345a988416SJim Ingham private: 11355a988416SJim Ingham CommandOptions m_options; 11365a988416SJim Ingham }; 11375a988416SJim Ingham 11385a988416SJim Ingham #pragma mark Modify::CommandOptions 11395a988416SJim Ingham OptionDefinition 11405a988416SJim Ingham CommandObjectBreakpointModify::CommandOptions::g_option_table[] = 11415a988416SJim Ingham { 1142*ac9c3a62SKate Stone // clang-format off 11439e85e5a8SEugene Zelenko {LLDB_OPT_SET_ALL, false, "ignore-count", 'i', OptionParser::eRequiredArgument, nullptr, nullptr, 0, eArgTypeCount, "Set the number of times this breakpoint is skipped before stopping."}, 11449e85e5a8SEugene Zelenko {LLDB_OPT_SET_ALL, false, "one-shot", 'o', OptionParser::eRequiredArgument, nullptr, nullptr, 0, eArgTypeBoolean, "The breakpoint is deleted the first time it stop causes a stop."}, 11459e85e5a8SEugene Zelenko {LLDB_OPT_SET_ALL, false, "thread-index", 'x', OptionParser::eRequiredArgument, nullptr, nullptr, 0, eArgTypeThreadIndex, "The breakpoint stops only for the thread whose index matches this argument."}, 11469e85e5a8SEugene Zelenko {LLDB_OPT_SET_ALL, false, "thread-id", 't', OptionParser::eRequiredArgument, nullptr, nullptr, 0, eArgTypeThreadID, "The breakpoint stops only for the thread whose TID matches this argument."}, 11479e85e5a8SEugene Zelenko {LLDB_OPT_SET_ALL, false, "thread-name", 'T', OptionParser::eRequiredArgument, nullptr, nullptr, 0, eArgTypeThreadName, "The breakpoint stops only for the thread whose thread name matches this argument."}, 11489e85e5a8SEugene Zelenko {LLDB_OPT_SET_ALL, false, "queue-name", 'q', OptionParser::eRequiredArgument, nullptr, nullptr, 0, eArgTypeQueueName, "The breakpoint stops only for threads in the queue whose name is given by this argument."}, 11499e85e5a8SEugene Zelenko {LLDB_OPT_SET_ALL, false, "condition", 'c', OptionParser::eRequiredArgument, nullptr, nullptr, 0, eArgTypeExpression, "The breakpoint stops only if this condition expression evaluates to true."}, 11509e85e5a8SEugene Zelenko {LLDB_OPT_SET_1, false, "enable", 'e', OptionParser::eNoArgument, nullptr, nullptr, 0, eArgTypeNone, "Enable the breakpoint."}, 11519e85e5a8SEugene Zelenko {LLDB_OPT_SET_2, false, "disable", 'd', OptionParser::eNoArgument, nullptr, nullptr, 0, eArgTypeNone, "Disable the breakpoint."}, 11529e85e5a8SEugene Zelenko {LLDB_OPT_SET_ALL, false, "dummy-breakpoints", 'D', OptionParser::eNoArgument, nullptr, nullptr, 0, eArgTypeNone, "Sets Dummy breakpoints - i.e. breakpoints set before a file is provided, which prime new targets."}, 11539e85e5a8SEugene Zelenko {0, false, nullptr, 0, 0, nullptr, nullptr, 0, eArgTypeNone, nullptr} 1154*ac9c3a62SKate Stone // clang-format on 11555a988416SJim Ingham }; 11565a988416SJim Ingham 11575a988416SJim Ingham //------------------------------------------------------------------------- 11585a988416SJim Ingham // CommandObjectBreakpointEnable 11595a988416SJim Ingham //------------------------------------------------------------------------- 11605a988416SJim Ingham #pragma mark Enable 11615a988416SJim Ingham 11625a988416SJim Ingham class CommandObjectBreakpointEnable : public CommandObjectParsed 11635a988416SJim Ingham { 11645a988416SJim Ingham public: 11655a988416SJim Ingham CommandObjectBreakpointEnable (CommandInterpreter &interpreter) : 11665a988416SJim Ingham CommandObjectParsed(interpreter, 11675a988416SJim Ingham "enable", 11685a988416SJim Ingham "Enable the specified disabled breakpoint(s). If no breakpoints are specified, enable all of them.", 11699e85e5a8SEugene Zelenko nullptr) 11705a988416SJim Ingham { 11715a988416SJim Ingham CommandArgumentEntry arg; 11725a988416SJim Ingham CommandObject::AddIDsArgumentData(arg, eArgTypeBreakpointID, eArgTypeBreakpointIDRange); 11735a988416SJim Ingham // Add the entry for the first argument for this command to the object's arguments vector. 11745a988416SJim Ingham m_arguments.push_back (arg); 11755a988416SJim Ingham } 11765a988416SJim Ingham 11779e85e5a8SEugene Zelenko ~CommandObjectBreakpointEnable() override = default; 11785a988416SJim Ingham 11795a988416SJim Ingham protected: 118013d21e9aSBruce Mitchener bool 118113d21e9aSBruce Mitchener DoExecute (Args& command, CommandReturnObject &result) override 11825a988416SJim Ingham { 1183893c932aSJim Ingham Target *target = GetSelectedOrDummyTarget(); 11849e85e5a8SEugene Zelenko if (target == nullptr) 11855a988416SJim Ingham { 11865a988416SJim Ingham result.AppendError ("Invalid target. No existing target or breakpoints."); 11875a988416SJim Ingham result.SetStatus (eReturnStatusFailed); 11885a988416SJim Ingham return false; 11895a988416SJim Ingham } 11905a988416SJim Ingham 1191bb19a13cSSaleem Abdulrasool std::unique_lock<std::recursive_mutex> lock; 1192bb19a13cSSaleem Abdulrasool target->GetBreakpointList().GetListMutex(lock); 11935a988416SJim Ingham 11945a988416SJim Ingham const BreakpointList &breakpoints = target->GetBreakpointList(); 11955a988416SJim Ingham 11965a988416SJim Ingham size_t num_breakpoints = breakpoints.GetSize(); 11975a988416SJim Ingham 11985a988416SJim Ingham if (num_breakpoints == 0) 11995a988416SJim Ingham { 12005a988416SJim Ingham result.AppendError ("No breakpoints exist to be enabled."); 12015a988416SJim Ingham result.SetStatus (eReturnStatusFailed); 12025a988416SJim Ingham return false; 12035a988416SJim Ingham } 12045a988416SJim Ingham 12055a988416SJim Ingham if (command.GetArgumentCount() == 0) 12065a988416SJim Ingham { 12075a988416SJim Ingham // No breakpoint selected; enable all currently set breakpoints. 12085a988416SJim Ingham target->EnableAllBreakpoints (); 12096fea17e8SGreg Clayton result.AppendMessageWithFormat ("All breakpoints enabled. (%" PRIu64 " breakpoints)\n", (uint64_t)num_breakpoints); 12105a988416SJim Ingham result.SetStatus (eReturnStatusSuccessFinishNoResult); 12115a988416SJim Ingham } 12125a988416SJim Ingham else 12135a988416SJim Ingham { 12145a988416SJim Ingham // Particular breakpoint selected; enable that breakpoint. 12155a988416SJim Ingham BreakpointIDList valid_bp_ids; 12165e09c8c3SJim Ingham CommandObjectMultiwordBreakpoint::VerifyBreakpointOrLocationIDs (command, target, result, &valid_bp_ids); 12175a988416SJim Ingham 12185a988416SJim Ingham if (result.Succeeded()) 12195a988416SJim Ingham { 12205a988416SJim Ingham int enable_count = 0; 12215a988416SJim Ingham int loc_count = 0; 12225a988416SJim Ingham const size_t count = valid_bp_ids.GetSize(); 12235a988416SJim Ingham for (size_t i = 0; i < count; ++i) 12245a988416SJim Ingham { 12255a988416SJim Ingham BreakpointID cur_bp_id = valid_bp_ids.GetBreakpointIDAtIndex (i); 12265a988416SJim Ingham 12275a988416SJim Ingham if (cur_bp_id.GetBreakpointID() != LLDB_INVALID_BREAK_ID) 12285a988416SJim Ingham { 12295a988416SJim Ingham Breakpoint *breakpoint = target->GetBreakpointByID (cur_bp_id.GetBreakpointID()).get(); 12305a988416SJim Ingham if (cur_bp_id.GetLocationID() != LLDB_INVALID_BREAK_ID) 12315a988416SJim Ingham { 12325a988416SJim Ingham BreakpointLocation *location = breakpoint->FindLocationByID (cur_bp_id.GetLocationID()).get(); 12335a988416SJim Ingham if (location) 12345a988416SJim Ingham { 12355a988416SJim Ingham location->SetEnabled (true); 12365a988416SJim Ingham ++loc_count; 12375a988416SJim Ingham } 12385a988416SJim Ingham } 12395a988416SJim Ingham else 12405a988416SJim Ingham { 12415a988416SJim Ingham breakpoint->SetEnabled (true); 12425a988416SJim Ingham ++enable_count; 12435a988416SJim Ingham } 12445a988416SJim Ingham } 12455a988416SJim Ingham } 12465a988416SJim Ingham result.AppendMessageWithFormat ("%d breakpoints enabled.\n", enable_count + loc_count); 12475a988416SJim Ingham result.SetStatus (eReturnStatusSuccessFinishNoResult); 12485a988416SJim Ingham } 12495a988416SJim Ingham } 12505a988416SJim Ingham 12515a988416SJim Ingham return result.Succeeded(); 12525a988416SJim Ingham } 12535a988416SJim Ingham }; 12545a988416SJim Ingham 12555a988416SJim Ingham //------------------------------------------------------------------------- 12565a988416SJim Ingham // CommandObjectBreakpointDisable 12575a988416SJim Ingham //------------------------------------------------------------------------- 12585a988416SJim Ingham #pragma mark Disable 12595a988416SJim Ingham 12605a988416SJim Ingham class CommandObjectBreakpointDisable : public CommandObjectParsed 12615a988416SJim Ingham { 12625a988416SJim Ingham public: 12637428a18cSKate Stone CommandObjectBreakpointDisable(CommandInterpreter &interpreter) 12647428a18cSKate Stone : CommandObjectParsed(interpreter, "breakpoint disable", "Disable the specified breakpoint(s) without deleting " 12657428a18cSKate Stone "them. If none are specified, disable all " 12667428a18cSKate Stone "breakpoints.", 12679e85e5a8SEugene Zelenko nullptr) 12685a988416SJim Ingham { 12697428a18cSKate Stone SetHelpLong("Disable the specified breakpoint(s) without deleting them. \ 12707428a18cSKate Stone If none are specified, disable all breakpoints." 12717428a18cSKate Stone R"( 1272ea671fbdSKate Stone 12737428a18cSKate Stone )" 12747428a18cSKate Stone "Note: disabling a breakpoint will cause none of its locations to be hit \ 12757428a18cSKate Stone regardless of whether individual locations are enabled or disabled. After the sequence:" 12767428a18cSKate Stone R"( 1277ea671fbdSKate Stone 1278ea671fbdSKate Stone (lldb) break disable 1 1279ea671fbdSKate Stone (lldb) break enable 1.1 1280ea671fbdSKate Stone 1281ea671fbdSKate Stone execution will NOT stop at location 1.1. To achieve that, type: 1282ea671fbdSKate Stone 1283ea671fbdSKate Stone (lldb) break disable 1.* 1284ea671fbdSKate Stone (lldb) break enable 1.1 1285ea671fbdSKate Stone 12867428a18cSKate Stone )" 12877428a18cSKate Stone "The first command disables all locations for breakpoint 1, \ 12887428a18cSKate Stone the second re-enables the first location."); 1289b0fac509SJim Ingham 12905a988416SJim Ingham CommandArgumentEntry arg; 12915a988416SJim Ingham CommandObject::AddIDsArgumentData(arg, eArgTypeBreakpointID, eArgTypeBreakpointIDRange); 12925a988416SJim Ingham // Add the entry for the first argument for this command to the object's arguments vector. 12935a988416SJim Ingham m_arguments.push_back (arg); 12945a988416SJim Ingham } 12955a988416SJim Ingham 12969e85e5a8SEugene Zelenko ~CommandObjectBreakpointDisable() override = default; 12975a988416SJim Ingham 12985a988416SJim Ingham protected: 129913d21e9aSBruce Mitchener bool 130013d21e9aSBruce Mitchener DoExecute (Args& command, CommandReturnObject &result) override 13015a988416SJim Ingham { 1302893c932aSJim Ingham Target *target = GetSelectedOrDummyTarget(); 13039e85e5a8SEugene Zelenko if (target == nullptr) 13045a988416SJim Ingham { 13055a988416SJim Ingham result.AppendError ("Invalid target. No existing target or breakpoints."); 13065a988416SJim Ingham result.SetStatus (eReturnStatusFailed); 13075a988416SJim Ingham return false; 13085a988416SJim Ingham } 13095a988416SJim Ingham 1310bb19a13cSSaleem Abdulrasool std::unique_lock<std::recursive_mutex> lock; 1311bb19a13cSSaleem Abdulrasool target->GetBreakpointList().GetListMutex(lock); 13125a988416SJim Ingham 13135a988416SJim Ingham const BreakpointList &breakpoints = target->GetBreakpointList(); 13145a988416SJim Ingham size_t num_breakpoints = breakpoints.GetSize(); 13155a988416SJim Ingham 13165a988416SJim Ingham if (num_breakpoints == 0) 13175a988416SJim Ingham { 13185a988416SJim Ingham result.AppendError ("No breakpoints exist to be disabled."); 13195a988416SJim Ingham result.SetStatus (eReturnStatusFailed); 13205a988416SJim Ingham return false; 13215a988416SJim Ingham } 13225a988416SJim Ingham 13235a988416SJim Ingham if (command.GetArgumentCount() == 0) 13245a988416SJim Ingham { 13255a988416SJim Ingham // No breakpoint selected; disable all currently set breakpoints. 13265a988416SJim Ingham target->DisableAllBreakpoints (); 13276fea17e8SGreg Clayton result.AppendMessageWithFormat ("All breakpoints disabled. (%" PRIu64 " breakpoints)\n", (uint64_t)num_breakpoints); 13285a988416SJim Ingham result.SetStatus (eReturnStatusSuccessFinishNoResult); 13295a988416SJim Ingham } 13305a988416SJim Ingham else 13315a988416SJim Ingham { 13325a988416SJim Ingham // Particular breakpoint selected; disable that breakpoint. 13335a988416SJim Ingham BreakpointIDList valid_bp_ids; 13345a988416SJim Ingham 13355e09c8c3SJim Ingham CommandObjectMultiwordBreakpoint::VerifyBreakpointOrLocationIDs (command, target, result, &valid_bp_ids); 13365a988416SJim Ingham 13375a988416SJim Ingham if (result.Succeeded()) 13385a988416SJim Ingham { 13395a988416SJim Ingham int disable_count = 0; 13405a988416SJim Ingham int loc_count = 0; 13415a988416SJim Ingham const size_t count = valid_bp_ids.GetSize(); 13425a988416SJim Ingham for (size_t i = 0; i < count; ++i) 13435a988416SJim Ingham { 13445a988416SJim Ingham BreakpointID cur_bp_id = valid_bp_ids.GetBreakpointIDAtIndex (i); 13455a988416SJim Ingham 13465a988416SJim Ingham if (cur_bp_id.GetBreakpointID() != LLDB_INVALID_BREAK_ID) 13475a988416SJim Ingham { 13485a988416SJim Ingham Breakpoint *breakpoint = target->GetBreakpointByID (cur_bp_id.GetBreakpointID()).get(); 13495a988416SJim Ingham if (cur_bp_id.GetLocationID() != LLDB_INVALID_BREAK_ID) 13505a988416SJim Ingham { 13515a988416SJim Ingham BreakpointLocation *location = breakpoint->FindLocationByID (cur_bp_id.GetLocationID()).get(); 13525a988416SJim Ingham if (location) 13535a988416SJim Ingham { 13545a988416SJim Ingham location->SetEnabled (false); 13555a988416SJim Ingham ++loc_count; 13565a988416SJim Ingham } 13575a988416SJim Ingham } 13585a988416SJim Ingham else 13595a988416SJim Ingham { 13605a988416SJim Ingham breakpoint->SetEnabled (false); 13615a988416SJim Ingham ++disable_count; 13625a988416SJim Ingham } 13635a988416SJim Ingham } 13645a988416SJim Ingham } 13655a988416SJim Ingham result.AppendMessageWithFormat ("%d breakpoints disabled.\n", disable_count + loc_count); 13665a988416SJim Ingham result.SetStatus (eReturnStatusSuccessFinishNoResult); 13675a988416SJim Ingham } 13685a988416SJim Ingham } 13695a988416SJim Ingham 13705a988416SJim Ingham return result.Succeeded(); 13715a988416SJim Ingham } 13725a988416SJim Ingham }; 13735a988416SJim Ingham 13745a988416SJim Ingham //------------------------------------------------------------------------- 13755a988416SJim Ingham // CommandObjectBreakpointList 13765a988416SJim Ingham //------------------------------------------------------------------------- 13775a988416SJim Ingham #pragma mark List 13785a988416SJim Ingham 13795a988416SJim Ingham class CommandObjectBreakpointList : public CommandObjectParsed 13805a988416SJim Ingham { 13815a988416SJim Ingham public: 13825a988416SJim Ingham CommandObjectBreakpointList (CommandInterpreter &interpreter) : 13835a988416SJim Ingham CommandObjectParsed(interpreter, 13845a988416SJim Ingham "breakpoint list", 13855a988416SJim Ingham "List some or all breakpoints at configurable levels of detail.", 13869e85e5a8SEugene Zelenko nullptr), 1387e1cfbc79STodd Fiala m_options () 13885a988416SJim Ingham { 13895a988416SJim Ingham CommandArgumentEntry arg; 13905a988416SJim Ingham CommandArgumentData bp_id_arg; 13915a988416SJim Ingham 13925a988416SJim Ingham // Define the first (and only) variant of this arg. 13935a988416SJim Ingham bp_id_arg.arg_type = eArgTypeBreakpointID; 13945a988416SJim Ingham bp_id_arg.arg_repetition = eArgRepeatOptional; 13955a988416SJim Ingham 13965a988416SJim Ingham // There is only one variant this argument could be; put it into the argument entry. 13975a988416SJim Ingham arg.push_back (bp_id_arg); 13985a988416SJim Ingham 13995a988416SJim Ingham // Push the data for the first argument into the m_arguments vector. 14005a988416SJim Ingham m_arguments.push_back (arg); 14015a988416SJim Ingham } 14025a988416SJim Ingham 14039e85e5a8SEugene Zelenko ~CommandObjectBreakpointList() override = default; 14045a988416SJim Ingham 140513d21e9aSBruce Mitchener Options * 140613d21e9aSBruce Mitchener GetOptions () override 14075a988416SJim Ingham { 14085a988416SJim Ingham return &m_options; 14095a988416SJim Ingham } 14105a988416SJim Ingham 14115a988416SJim Ingham class CommandOptions : public Options 14125a988416SJim Ingham { 14135a988416SJim Ingham public: 1414e1cfbc79STodd Fiala CommandOptions () : 1415e1cfbc79STodd Fiala Options (), 141633df7cd3SJim Ingham m_level (lldb::eDescriptionLevelBrief), 141733df7cd3SJim Ingham m_use_dummy(false) 14185a988416SJim Ingham { 14195a988416SJim Ingham } 14205a988416SJim Ingham 14219e85e5a8SEugene Zelenko ~CommandOptions() override = default; 14225a988416SJim Ingham 142313d21e9aSBruce Mitchener Error 1424e1cfbc79STodd Fiala SetOptionValue (uint32_t option_idx, const char *option_arg, 1425e1cfbc79STodd Fiala ExecutionContext *execution_context) override 14265a988416SJim Ingham { 14275a988416SJim Ingham Error error; 14283bcdfc0eSGreg Clayton const int short_option = m_getopt_table[option_idx].val; 14295a988416SJim Ingham 14305a988416SJim Ingham switch (short_option) 14315a988416SJim Ingham { 14325a988416SJim Ingham case 'b': 14335a988416SJim Ingham m_level = lldb::eDescriptionLevelBrief; 14345a988416SJim Ingham break; 143533df7cd3SJim Ingham case 'D': 143633df7cd3SJim Ingham m_use_dummy = true; 143733df7cd3SJim Ingham break; 14385a988416SJim Ingham case 'f': 14395a988416SJim Ingham m_level = lldb::eDescriptionLevelFull; 14405a988416SJim Ingham break; 14415a988416SJim Ingham case 'v': 14425a988416SJim Ingham m_level = lldb::eDescriptionLevelVerbose; 14435a988416SJim Ingham break; 14445a988416SJim Ingham case 'i': 14455a988416SJim Ingham m_internal = true; 14465a988416SJim Ingham break; 14475a988416SJim Ingham default: 14485a988416SJim Ingham error.SetErrorStringWithFormat ("unrecognized option '%c'", short_option); 14495a988416SJim Ingham break; 14505a988416SJim Ingham } 14515a988416SJim Ingham 14525a988416SJim Ingham return error; 14535a988416SJim Ingham } 14545a988416SJim Ingham 14555a988416SJim Ingham void 1456e1cfbc79STodd Fiala OptionParsingStarting (ExecutionContext *execution_context) override 14575a988416SJim Ingham { 14585a988416SJim Ingham m_level = lldb::eDescriptionLevelFull; 14595a988416SJim Ingham m_internal = false; 146033df7cd3SJim Ingham m_use_dummy = false; 14615a988416SJim Ingham } 14625a988416SJim Ingham 14635a988416SJim Ingham const OptionDefinition * 146413d21e9aSBruce Mitchener GetDefinitions () override 14655a988416SJim Ingham { 14665a988416SJim Ingham return g_option_table; 14675a988416SJim Ingham } 14685a988416SJim Ingham 14695a988416SJim Ingham // Options table: Required for subclasses of Options. 14705a988416SJim Ingham 14715a988416SJim Ingham static OptionDefinition g_option_table[]; 14725a988416SJim Ingham 14735a988416SJim Ingham // Instance variables to hold the values for command options. 14745a988416SJim Ingham 14755a988416SJim Ingham lldb::DescriptionLevel m_level; 14765a988416SJim Ingham 14775a988416SJim Ingham bool m_internal; 147833df7cd3SJim Ingham bool m_use_dummy; 14795a988416SJim Ingham }; 14805a988416SJim Ingham 14815a988416SJim Ingham protected: 148213d21e9aSBruce Mitchener bool 148313d21e9aSBruce Mitchener DoExecute (Args& command, CommandReturnObject &result) override 14845a988416SJim Ingham { 148533df7cd3SJim Ingham Target *target = GetSelectedOrDummyTarget(m_options.m_use_dummy); 148633df7cd3SJim Ingham 14879e85e5a8SEugene Zelenko if (target == nullptr) 14885a988416SJim Ingham { 14895a988416SJim Ingham result.AppendError ("Invalid target. No current target or breakpoints."); 14905a988416SJim Ingham result.SetStatus (eReturnStatusSuccessFinishNoResult); 14915a988416SJim Ingham return true; 14925a988416SJim Ingham } 14935a988416SJim Ingham 14945a988416SJim Ingham const BreakpointList &breakpoints = target->GetBreakpointList(m_options.m_internal); 1495bb19a13cSSaleem Abdulrasool std::unique_lock<std::recursive_mutex> lock; 1496bb19a13cSSaleem Abdulrasool target->GetBreakpointList(m_options.m_internal).GetListMutex(lock); 14975a988416SJim Ingham 14985a988416SJim Ingham size_t num_breakpoints = breakpoints.GetSize(); 14995a988416SJim Ingham 15005a988416SJim Ingham if (num_breakpoints == 0) 15015a988416SJim Ingham { 15025a988416SJim Ingham result.AppendMessage ("No breakpoints currently set."); 15035a988416SJim Ingham result.SetStatus (eReturnStatusSuccessFinishNoResult); 15045a988416SJim Ingham return true; 15055a988416SJim Ingham } 15065a988416SJim Ingham 15075a988416SJim Ingham Stream &output_stream = result.GetOutputStream(); 15085a988416SJim Ingham 15095a988416SJim Ingham if (command.GetArgumentCount() == 0) 15105a988416SJim Ingham { 15115a988416SJim Ingham // No breakpoint selected; show info about all currently set breakpoints. 15125a988416SJim Ingham result.AppendMessage ("Current breakpoints:"); 15135a988416SJim Ingham for (size_t i = 0; i < num_breakpoints; ++i) 15145a988416SJim Ingham { 15155a988416SJim Ingham Breakpoint *breakpoint = breakpoints.GetBreakpointAtIndex (i).get(); 15165a988416SJim Ingham AddBreakpointDescription (&output_stream, breakpoint, m_options.m_level); 15175a988416SJim Ingham } 15185a988416SJim Ingham result.SetStatus (eReturnStatusSuccessFinishNoResult); 15195a988416SJim Ingham } 15205a988416SJim Ingham else 15215a988416SJim Ingham { 15225a988416SJim Ingham // Particular breakpoints selected; show info about that breakpoint. 15235a988416SJim Ingham BreakpointIDList valid_bp_ids; 15245e09c8c3SJim Ingham CommandObjectMultiwordBreakpoint::VerifyBreakpointOrLocationIDs (command, target, result, &valid_bp_ids); 15255a988416SJim Ingham 15265a988416SJim Ingham if (result.Succeeded()) 15275a988416SJim Ingham { 15285a988416SJim Ingham for (size_t i = 0; i < valid_bp_ids.GetSize(); ++i) 15295a988416SJim Ingham { 15305a988416SJim Ingham BreakpointID cur_bp_id = valid_bp_ids.GetBreakpointIDAtIndex (i); 15315a988416SJim Ingham Breakpoint *breakpoint = target->GetBreakpointByID (cur_bp_id.GetBreakpointID()).get(); 15325a988416SJim Ingham AddBreakpointDescription (&output_stream, breakpoint, m_options.m_level); 15335a988416SJim Ingham } 15345a988416SJim Ingham result.SetStatus (eReturnStatusSuccessFinishNoResult); 15355a988416SJim Ingham } 15365a988416SJim Ingham else 15375a988416SJim Ingham { 15387428a18cSKate Stone result.AppendError("Invalid breakpoint ID."); 15395a988416SJim Ingham result.SetStatus (eReturnStatusFailed); 15405a988416SJim Ingham } 15415a988416SJim Ingham } 15425a988416SJim Ingham 15435a988416SJim Ingham return result.Succeeded(); 15445a988416SJim Ingham } 15455a988416SJim Ingham 15465a988416SJim Ingham private: 15475a988416SJim Ingham CommandOptions m_options; 15485a988416SJim Ingham }; 15495a988416SJim Ingham 15505a988416SJim Ingham #pragma mark List::CommandOptions 15515a988416SJim Ingham OptionDefinition 15525a988416SJim Ingham CommandObjectBreakpointList::CommandOptions::g_option_table[] = 15535a988416SJim Ingham { 1554*ac9c3a62SKate Stone // clang-format off 1555*ac9c3a62SKate Stone {LLDB_OPT_SET_ALL, false, "internal", 'i', OptionParser::eNoArgument, nullptr, nullptr, 0, eArgTypeNone, "Show debugger internal breakpoints" }, 1556*ac9c3a62SKate Stone {LLDB_OPT_SET_1, false, "brief", 'b', OptionParser::eNoArgument, nullptr, nullptr, 0, eArgTypeNone, "Give a brief description of the breakpoint (no location info)."}, 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. 1559*ac9c3a62SKate Stone {LLDB_OPT_SET_2, false, "full", 'f', OptionParser::eNoArgument, nullptr, nullptr, 0, eArgTypeNone, "Give a full description of the breakpoint and its locations."}, 1560*ac9c3a62SKate Stone {LLDB_OPT_SET_3, false, "verbose", 'v', OptionParser::eNoArgument, nullptr, nullptr, 0, eArgTypeNone, "Explain everything we know about the breakpoint (for debugging debugger bugs)."}, 1561*ac9c3a62SKate Stone {LLDB_OPT_SET_ALL, false, "dummy-breakpoints", 'D', OptionParser::eNoArgument, nullptr, nullptr, 0, eArgTypeNone, "List Dummy breakpoints - i.e. breakpoints set before a file is provided, which prime new targets."}, 15629e85e5a8SEugene Zelenko {0, false, nullptr, 0, 0, nullptr, nullptr, 0, eArgTypeNone, nullptr} 1563*ac9c3a62SKate Stone // clang-format on 15645a988416SJim Ingham }; 15655a988416SJim Ingham 15665a988416SJim Ingham //------------------------------------------------------------------------- 15675a988416SJim Ingham // CommandObjectBreakpointClear 15685a988416SJim Ingham //------------------------------------------------------------------------- 15695a988416SJim Ingham #pragma mark Clear 15705a988416SJim Ingham 15715a988416SJim Ingham class CommandObjectBreakpointClear : public CommandObjectParsed 15725a988416SJim Ingham { 15735a988416SJim Ingham public: 15745a988416SJim Ingham typedef enum BreakpointClearType 15755a988416SJim Ingham { 15765a988416SJim Ingham eClearTypeInvalid, 15775a988416SJim Ingham eClearTypeFileAndLine 15785a988416SJim Ingham } BreakpointClearType; 15795a988416SJim Ingham 15807428a18cSKate Stone CommandObjectBreakpointClear(CommandInterpreter &interpreter) 15817428a18cSKate Stone : CommandObjectParsed(interpreter, "breakpoint clear", 15827428a18cSKate Stone "Delete or disable breakpoints matching the specified source file and line.", 15835a988416SJim Ingham "breakpoint clear <cmd-options>"), 1584e1cfbc79STodd Fiala m_options() 15855a988416SJim Ingham { 15865a988416SJim Ingham } 15875a988416SJim Ingham 15889e85e5a8SEugene Zelenko ~CommandObjectBreakpointClear() override = default; 15895a988416SJim Ingham 159013d21e9aSBruce Mitchener Options * 159113d21e9aSBruce Mitchener GetOptions () override 15925a988416SJim Ingham { 15935a988416SJim Ingham return &m_options; 15945a988416SJim Ingham } 15955a988416SJim Ingham 15965a988416SJim Ingham class CommandOptions : public Options 15975a988416SJim Ingham { 15985a988416SJim Ingham public: 1599e1cfbc79STodd Fiala CommandOptions () : 1600e1cfbc79STodd Fiala Options (), 16015a988416SJim Ingham m_filename (), 16025a988416SJim Ingham m_line_num (0) 16035a988416SJim Ingham { 16045a988416SJim Ingham } 16055a988416SJim Ingham 16069e85e5a8SEugene Zelenko ~CommandOptions() override = default; 16075a988416SJim Ingham 160813d21e9aSBruce Mitchener Error 1609e1cfbc79STodd Fiala SetOptionValue (uint32_t option_idx, const char *option_arg, 1610e1cfbc79STodd Fiala ExecutionContext *execution_context) override 16115a988416SJim Ingham { 16125a988416SJim Ingham Error error; 16133bcdfc0eSGreg Clayton const int short_option = m_getopt_table[option_idx].val; 16145a988416SJim Ingham 16155a988416SJim Ingham switch (short_option) 16165a988416SJim Ingham { 16175a988416SJim Ingham case 'f': 16185a988416SJim Ingham m_filename.assign (option_arg); 16195a988416SJim Ingham break; 16205a988416SJim Ingham 16215a988416SJim Ingham case 'l': 16225275aaa0SVince Harron m_line_num = StringConvert::ToUInt32 (option_arg, 0); 16235a988416SJim Ingham break; 16245a988416SJim Ingham 16255a988416SJim Ingham default: 16265a988416SJim Ingham error.SetErrorStringWithFormat ("unrecognized option '%c'", short_option); 16275a988416SJim Ingham break; 16285a988416SJim Ingham } 16295a988416SJim Ingham 16305a988416SJim Ingham return error; 16315a988416SJim Ingham } 16325a988416SJim Ingham 16335a988416SJim Ingham void 1634e1cfbc79STodd Fiala OptionParsingStarting (ExecutionContext *execution_context) override 16355a988416SJim Ingham { 16365a988416SJim Ingham m_filename.clear(); 16375a988416SJim Ingham m_line_num = 0; 16385a988416SJim Ingham } 16395a988416SJim Ingham 16405a988416SJim Ingham const OptionDefinition* 164113d21e9aSBruce Mitchener GetDefinitions () override 16425a988416SJim Ingham { 16435a988416SJim Ingham return g_option_table; 16445a988416SJim Ingham } 16455a988416SJim Ingham 16465a988416SJim Ingham // Options table: Required for subclasses of Options. 16475a988416SJim Ingham 16485a988416SJim Ingham static OptionDefinition g_option_table[]; 16495a988416SJim Ingham 16505a988416SJim Ingham // Instance variables to hold the values for command options. 16515a988416SJim Ingham 16525a988416SJim Ingham std::string m_filename; 16535a988416SJim Ingham uint32_t m_line_num; 16545a988416SJim Ingham 16555a988416SJim Ingham }; 16565a988416SJim Ingham 16575a988416SJim Ingham protected: 165813d21e9aSBruce Mitchener bool 165913d21e9aSBruce Mitchener DoExecute (Args& command, CommandReturnObject &result) override 16605a988416SJim Ingham { 1661893c932aSJim Ingham Target *target = GetSelectedOrDummyTarget(); 16629e85e5a8SEugene Zelenko if (target == nullptr) 16635a988416SJim Ingham { 16645a988416SJim Ingham result.AppendError ("Invalid target. No existing target or breakpoints."); 16655a988416SJim Ingham result.SetStatus (eReturnStatusFailed); 16665a988416SJim Ingham return false; 16675a988416SJim Ingham } 16685a988416SJim Ingham 16695a988416SJim Ingham // The following are the various types of breakpoints that could be cleared: 16705a988416SJim Ingham // 1). -f -l (clearing breakpoint by source location) 16715a988416SJim Ingham 16725a988416SJim Ingham BreakpointClearType break_type = eClearTypeInvalid; 16735a988416SJim Ingham 16745a988416SJim Ingham if (m_options.m_line_num != 0) 16755a988416SJim Ingham break_type = eClearTypeFileAndLine; 16765a988416SJim Ingham 1677bb19a13cSSaleem Abdulrasool std::unique_lock<std::recursive_mutex> lock; 1678bb19a13cSSaleem Abdulrasool target->GetBreakpointList().GetListMutex(lock); 16795a988416SJim Ingham 16805a988416SJim Ingham BreakpointList &breakpoints = target->GetBreakpointList(); 16815a988416SJim Ingham size_t num_breakpoints = breakpoints.GetSize(); 16825a988416SJim Ingham 16835a988416SJim Ingham // Early return if there's no breakpoint at all. 16845a988416SJim Ingham if (num_breakpoints == 0) 16855a988416SJim Ingham { 16865a988416SJim Ingham result.AppendError ("Breakpoint clear: No breakpoint cleared."); 16875a988416SJim Ingham result.SetStatus (eReturnStatusFailed); 16885a988416SJim Ingham return result.Succeeded(); 16895a988416SJim Ingham } 16905a988416SJim Ingham 16915a988416SJim Ingham // Find matching breakpoints and delete them. 16925a988416SJim Ingham 16935a988416SJim Ingham // First create a copy of all the IDs. 16945a988416SJim Ingham std::vector<break_id_t> BreakIDs; 16955a988416SJim Ingham for (size_t i = 0; i < num_breakpoints; ++i) 16969e85e5a8SEugene Zelenko BreakIDs.push_back(breakpoints.GetBreakpointAtIndex(i)->GetID()); 16975a988416SJim Ingham 16985a988416SJim Ingham int num_cleared = 0; 16995a988416SJim Ingham StreamString ss; 17005a988416SJim Ingham switch (break_type) 17015a988416SJim Ingham { 17025a988416SJim Ingham case eClearTypeFileAndLine: // Breakpoint by source position 17035a988416SJim Ingham { 17045a988416SJim Ingham const ConstString filename(m_options.m_filename.c_str()); 17055a988416SJim Ingham BreakpointLocationCollection loc_coll; 17065a988416SJim Ingham 17075a988416SJim Ingham for (size_t i = 0; i < num_breakpoints; ++i) 17085a988416SJim Ingham { 17095a988416SJim Ingham Breakpoint *bp = breakpoints.FindBreakpointByID(BreakIDs[i]).get(); 17105a988416SJim Ingham 17115a988416SJim Ingham if (bp->GetMatchingFileLine(filename, m_options.m_line_num, loc_coll)) 17125a988416SJim Ingham { 17135a988416SJim Ingham // If the collection size is 0, it's a full match and we can just remove the breakpoint. 17145a988416SJim Ingham if (loc_coll.GetSize() == 0) 17155a988416SJim Ingham { 17165a988416SJim Ingham bp->GetDescription(&ss, lldb::eDescriptionLevelBrief); 17175a988416SJim Ingham ss.EOL(); 17185a988416SJim Ingham target->RemoveBreakpointByID (bp->GetID()); 17195a988416SJim Ingham ++num_cleared; 17205a988416SJim Ingham } 17215a988416SJim Ingham } 17225a988416SJim Ingham } 17235a988416SJim Ingham } 17245a988416SJim Ingham break; 17255a988416SJim Ingham 17265a988416SJim Ingham default: 17275a988416SJim Ingham break; 17285a988416SJim Ingham } 17295a988416SJim Ingham 17305a988416SJim Ingham if (num_cleared > 0) 17315a988416SJim Ingham { 17325a988416SJim Ingham Stream &output_stream = result.GetOutputStream(); 17335a988416SJim Ingham output_stream.Printf ("%d breakpoints cleared:\n", num_cleared); 17345a988416SJim Ingham output_stream << ss.GetData(); 17355a988416SJim Ingham output_stream.EOL(); 17365a988416SJim Ingham result.SetStatus (eReturnStatusSuccessFinishNoResult); 17375a988416SJim Ingham } 17385a988416SJim Ingham else 17395a988416SJim Ingham { 17405a988416SJim Ingham result.AppendError ("Breakpoint clear: No breakpoint cleared."); 17415a988416SJim Ingham result.SetStatus (eReturnStatusFailed); 17425a988416SJim Ingham } 17435a988416SJim Ingham 17445a988416SJim Ingham return result.Succeeded(); 17455a988416SJim Ingham } 17465a988416SJim Ingham 17475a988416SJim Ingham private: 17485a988416SJim Ingham CommandOptions m_options; 17495a988416SJim Ingham }; 17505a988416SJim Ingham 17515a988416SJim Ingham #pragma mark Clear::CommandOptions 17525a988416SJim Ingham 17535a988416SJim Ingham OptionDefinition 17545a988416SJim Ingham CommandObjectBreakpointClear::CommandOptions::g_option_table[] = 17555a988416SJim Ingham { 1756*ac9c3a62SKate Stone // clang-format off 1757*ac9c3a62SKate Stone {LLDB_OPT_SET_1, false, "file", 'f', OptionParser::eRequiredArgument, nullptr, nullptr, CommandCompletions::eSourceFileCompletion, eArgTypeFilename, "Specify the breakpoint by source location in this particular file."}, 1758*ac9c3a62SKate Stone {LLDB_OPT_SET_1, true, "line", 'l', OptionParser::eRequiredArgument, nullptr, nullptr, 0, eArgTypeLineNum, "Specify the breakpoint by source location at this particular line."}, 17599e85e5a8SEugene Zelenko {0, false, nullptr, 0, 0, nullptr, nullptr, 0, eArgTypeNone, nullptr} 1760*ac9c3a62SKate Stone // clang-format on 17615a988416SJim Ingham }; 17625a988416SJim Ingham 17635a988416SJim Ingham //------------------------------------------------------------------------- 17645a988416SJim Ingham // CommandObjectBreakpointDelete 17655a988416SJim Ingham //------------------------------------------------------------------------- 17665a988416SJim Ingham #pragma mark Delete 17675a988416SJim Ingham 17685a988416SJim Ingham class CommandObjectBreakpointDelete : public CommandObjectParsed 17695a988416SJim Ingham { 17705a988416SJim Ingham public: 17715a988416SJim Ingham CommandObjectBreakpointDelete (CommandInterpreter &interpreter) : 17725a988416SJim Ingham CommandObjectParsed(interpreter, 17735a988416SJim Ingham "breakpoint delete", 17745a988416SJim Ingham "Delete the specified breakpoint(s). If no breakpoints are specified, delete them all.", 17759e85e5a8SEugene Zelenko nullptr), 1776e1cfbc79STodd Fiala m_options() 17775a988416SJim Ingham { 17785a988416SJim Ingham CommandArgumentEntry arg; 17795a988416SJim Ingham CommandObject::AddIDsArgumentData(arg, eArgTypeBreakpointID, eArgTypeBreakpointIDRange); 17805a988416SJim Ingham // Add the entry for the first argument for this command to the object's arguments vector. 17815a988416SJim Ingham m_arguments.push_back (arg); 17825a988416SJim Ingham } 17835a988416SJim Ingham 17849e85e5a8SEugene Zelenko ~CommandObjectBreakpointDelete() override = default; 17855a988416SJim Ingham 178613d21e9aSBruce Mitchener Options * 178713d21e9aSBruce Mitchener GetOptions () override 178833df7cd3SJim Ingham { 178933df7cd3SJim Ingham return &m_options; 179033df7cd3SJim Ingham } 179133df7cd3SJim Ingham 179233df7cd3SJim Ingham class CommandOptions : public Options 179333df7cd3SJim Ingham { 179433df7cd3SJim Ingham public: 1795e1cfbc79STodd Fiala CommandOptions () : 1796e1cfbc79STodd Fiala Options (), 179733df7cd3SJim Ingham m_use_dummy (false), 179833df7cd3SJim Ingham m_force (false) 179933df7cd3SJim Ingham { 180033df7cd3SJim Ingham } 180133df7cd3SJim Ingham 18029e85e5a8SEugene Zelenko ~CommandOptions() override = default; 180333df7cd3SJim Ingham 180413d21e9aSBruce Mitchener Error 1805e1cfbc79STodd Fiala SetOptionValue (uint32_t option_idx, const char *option_arg, 1806e1cfbc79STodd Fiala ExecutionContext *execution_context) override 180733df7cd3SJim Ingham { 180833df7cd3SJim Ingham Error error; 180933df7cd3SJim Ingham const int short_option = m_getopt_table[option_idx].val; 181033df7cd3SJim Ingham 181133df7cd3SJim Ingham switch (short_option) 181233df7cd3SJim Ingham { 181333df7cd3SJim Ingham case 'f': 181433df7cd3SJim Ingham m_force = true; 181533df7cd3SJim Ingham break; 181633df7cd3SJim Ingham 181733df7cd3SJim Ingham case 'D': 181833df7cd3SJim Ingham m_use_dummy = true; 181933df7cd3SJim Ingham break; 182033df7cd3SJim Ingham 182133df7cd3SJim Ingham default: 182233df7cd3SJim Ingham error.SetErrorStringWithFormat ("unrecognized option '%c'", short_option); 182333df7cd3SJim Ingham break; 182433df7cd3SJim Ingham } 182533df7cd3SJim Ingham 182633df7cd3SJim Ingham return error; 182733df7cd3SJim Ingham } 182833df7cd3SJim Ingham 182933df7cd3SJim Ingham void 1830e1cfbc79STodd Fiala OptionParsingStarting (ExecutionContext *execution_context) override 183133df7cd3SJim Ingham { 183233df7cd3SJim Ingham m_use_dummy = false; 183333df7cd3SJim Ingham m_force = false; 183433df7cd3SJim Ingham } 183533df7cd3SJim Ingham 183633df7cd3SJim Ingham const OptionDefinition* 183713d21e9aSBruce Mitchener GetDefinitions () override 183833df7cd3SJim Ingham { 183933df7cd3SJim Ingham return g_option_table; 184033df7cd3SJim Ingham } 184133df7cd3SJim Ingham 184233df7cd3SJim Ingham // Options table: Required for subclasses of Options. 184333df7cd3SJim Ingham 184433df7cd3SJim Ingham static OptionDefinition g_option_table[]; 184533df7cd3SJim Ingham 184633df7cd3SJim Ingham // Instance variables to hold the values for command options. 184733df7cd3SJim Ingham bool m_use_dummy; 184833df7cd3SJim Ingham bool m_force; 184933df7cd3SJim Ingham }; 185033df7cd3SJim Ingham 18515a988416SJim Ingham protected: 185213d21e9aSBruce Mitchener bool 185313d21e9aSBruce Mitchener DoExecute (Args& command, CommandReturnObject &result) override 18545a988416SJim Ingham { 185533df7cd3SJim Ingham Target *target = GetSelectedOrDummyTarget(m_options.m_use_dummy); 185633df7cd3SJim Ingham 18579e85e5a8SEugene Zelenko if (target == nullptr) 18585a988416SJim Ingham { 18595a988416SJim Ingham result.AppendError ("Invalid target. No existing target or breakpoints."); 18605a988416SJim Ingham result.SetStatus (eReturnStatusFailed); 18615a988416SJim Ingham return false; 18625a988416SJim Ingham } 18635a988416SJim Ingham 1864bb19a13cSSaleem Abdulrasool std::unique_lock<std::recursive_mutex> lock; 1865bb19a13cSSaleem Abdulrasool target->GetBreakpointList().GetListMutex(lock); 18665a988416SJim Ingham 18675a988416SJim Ingham const BreakpointList &breakpoints = target->GetBreakpointList(); 18685a988416SJim Ingham 18695a988416SJim Ingham size_t num_breakpoints = breakpoints.GetSize(); 18705a988416SJim Ingham 18715a988416SJim Ingham if (num_breakpoints == 0) 18725a988416SJim Ingham { 18735a988416SJim Ingham result.AppendError ("No breakpoints exist to be deleted."); 18745a988416SJim Ingham result.SetStatus (eReturnStatusFailed); 18755a988416SJim Ingham return false; 18765a988416SJim Ingham } 18775a988416SJim Ingham 18785a988416SJim Ingham if (command.GetArgumentCount() == 0) 18795a988416SJim Ingham { 188033df7cd3SJim Ingham if (!m_options.m_force && !m_interpreter.Confirm ("About to delete all breakpoints, do you want to do that?", true)) 18815a988416SJim Ingham { 18825a988416SJim Ingham result.AppendMessage("Operation cancelled..."); 18835a988416SJim Ingham } 18845a988416SJim Ingham else 18855a988416SJim Ingham { 18865a988416SJim Ingham target->RemoveAllBreakpoints (); 18876fea17e8SGreg Clayton result.AppendMessageWithFormat ("All breakpoints removed. (%" PRIu64 " breakpoint%s)\n", (uint64_t)num_breakpoints, num_breakpoints > 1 ? "s" : ""); 18885a988416SJim Ingham } 18895a988416SJim Ingham result.SetStatus (eReturnStatusSuccessFinishNoResult); 18905a988416SJim Ingham } 18915a988416SJim Ingham else 18925a988416SJim Ingham { 18935a988416SJim Ingham // Particular breakpoint selected; disable that breakpoint. 18945a988416SJim Ingham BreakpointIDList valid_bp_ids; 18955e09c8c3SJim Ingham CommandObjectMultiwordBreakpoint::VerifyBreakpointOrLocationIDs (command, target, result, &valid_bp_ids); 18965a988416SJim Ingham 18975a988416SJim Ingham if (result.Succeeded()) 18985a988416SJim Ingham { 18995a988416SJim Ingham int delete_count = 0; 19005a988416SJim Ingham int disable_count = 0; 19015a988416SJim Ingham const size_t count = valid_bp_ids.GetSize(); 19025a988416SJim Ingham for (size_t i = 0; i < count; ++i) 19035a988416SJim Ingham { 19045a988416SJim Ingham BreakpointID cur_bp_id = valid_bp_ids.GetBreakpointIDAtIndex (i); 19055a988416SJim Ingham 19065a988416SJim Ingham if (cur_bp_id.GetBreakpointID() != LLDB_INVALID_BREAK_ID) 19075a988416SJim Ingham { 19085a988416SJim Ingham if (cur_bp_id.GetLocationID() != LLDB_INVALID_BREAK_ID) 19095a988416SJim Ingham { 19105a988416SJim Ingham Breakpoint *breakpoint = target->GetBreakpointByID (cur_bp_id.GetBreakpointID()).get(); 19115a988416SJim Ingham BreakpointLocation *location = breakpoint->FindLocationByID (cur_bp_id.GetLocationID()).get(); 19125a988416SJim Ingham // It makes no sense to try to delete individual locations, so we disable them instead. 19135a988416SJim Ingham if (location) 19145a988416SJim Ingham { 19155a988416SJim Ingham location->SetEnabled (false); 19165a988416SJim Ingham ++disable_count; 19175a988416SJim Ingham } 19185a988416SJim Ingham } 19195a988416SJim Ingham else 19205a988416SJim Ingham { 19215a988416SJim Ingham target->RemoveBreakpointByID (cur_bp_id.GetBreakpointID()); 19225a988416SJim Ingham ++delete_count; 19235a988416SJim Ingham } 19245a988416SJim Ingham } 19255a988416SJim Ingham } 19265a988416SJim Ingham result.AppendMessageWithFormat ("%d breakpoints deleted; %d breakpoint locations disabled.\n", 19275a988416SJim Ingham delete_count, disable_count); 19285a988416SJim Ingham result.SetStatus (eReturnStatusSuccessFinishNoResult); 19295a988416SJim Ingham } 19305a988416SJim Ingham } 19315a988416SJim Ingham return result.Succeeded(); 19325a988416SJim Ingham } 19339e85e5a8SEugene Zelenko 193433df7cd3SJim Ingham private: 193533df7cd3SJim Ingham CommandOptions m_options; 193633df7cd3SJim Ingham }; 193733df7cd3SJim Ingham 193833df7cd3SJim Ingham OptionDefinition 193933df7cd3SJim Ingham CommandObjectBreakpointDelete::CommandOptions::g_option_table[] = 194033df7cd3SJim Ingham { 1941*ac9c3a62SKate Stone // clang-format off 1942*ac9c3a62SKate Stone {LLDB_OPT_SET_1, false, "force", 'f', OptionParser::eNoArgument, nullptr, nullptr, 0, eArgTypeNone, "Delete all breakpoints without querying for confirmation."}, 1943*ac9c3a62SKate Stone {LLDB_OPT_SET_1, false, "dummy-breakpoints", 'D', OptionParser::eNoArgument, nullptr, nullptr, 0, eArgTypeNone, "Delete Dummy breakpoints - i.e. breakpoints set before a file is provided, which prime new targets."}, 19449e85e5a8SEugene Zelenko {0, false, nullptr, 0, 0, nullptr, nullptr, 0, eArgTypeNone, nullptr} 1945*ac9c3a62SKate Stone // clang-format on 19465a988416SJim Ingham }; 19475a988416SJim Ingham 194830fdc8d8SChris Lattner //------------------------------------------------------------------------- 19495e09c8c3SJim Ingham // CommandObjectBreakpointName 19505e09c8c3SJim Ingham //------------------------------------------------------------------------- 19515e09c8c3SJim Ingham 19527428a18cSKate Stone static OptionDefinition g_breakpoint_name_options[] = { 1953*ac9c3a62SKate Stone // clang-format off 1954*ac9c3a62SKate Stone {LLDB_OPT_SET_1, false, "name", 'N', OptionParser::eRequiredArgument, nullptr, nullptr, 0, eArgTypeBreakpointName, "Specifies a breakpoint name to use."}, 1955*ac9c3a62SKate Stone {LLDB_OPT_SET_2, false, "breakpoint-id", 'B', OptionParser::eRequiredArgument, nullptr, nullptr, 0, eArgTypeBreakpointID, "Specify a breakpoint ID to use."}, 1956*ac9c3a62SKate Stone {LLDB_OPT_SET_ALL, false, "dummy-breakpoints", 'D', OptionParser::eNoArgument, nullptr, nullptr, 0, eArgTypeNone, "Operate on Dummy breakpoints - i.e. breakpoints set before a file is provided, which prime new targets."}, 1957*ac9c3a62SKate Stone // clang-format on 19585e09c8c3SJim Ingham }; 19595e09c8c3SJim Ingham class BreakpointNameOptionGroup : public OptionGroup 19605e09c8c3SJim Ingham { 19615e09c8c3SJim Ingham public: 19625e09c8c3SJim Ingham BreakpointNameOptionGroup() : 19635e09c8c3SJim Ingham OptionGroup(), 19645e09c8c3SJim Ingham m_breakpoint(LLDB_INVALID_BREAK_ID), 19655e09c8c3SJim Ingham m_use_dummy (false) 19665e09c8c3SJim Ingham { 19675e09c8c3SJim Ingham } 19685e09c8c3SJim Ingham 19699e85e5a8SEugene Zelenko ~BreakpointNameOptionGroup() override = default; 19705e09c8c3SJim Ingham 197113d21e9aSBruce Mitchener uint32_t 197213d21e9aSBruce Mitchener GetNumDefinitions () override 19735e09c8c3SJim Ingham { 19745e09c8c3SJim Ingham return sizeof (g_breakpoint_name_options) / sizeof (OptionDefinition); 19755e09c8c3SJim Ingham } 19765e09c8c3SJim Ingham 197713d21e9aSBruce Mitchener const OptionDefinition* 197813d21e9aSBruce Mitchener GetDefinitions () override 19795e09c8c3SJim Ingham { 19805e09c8c3SJim Ingham return g_breakpoint_name_options; 19815e09c8c3SJim Ingham } 19825e09c8c3SJim Ingham 198313d21e9aSBruce Mitchener Error 1984e1cfbc79STodd Fiala SetOptionValue (uint32_t option_idx, 1985e1cfbc79STodd Fiala const char *option_value, 1986e1cfbc79STodd Fiala ExecutionContext *execution_context) override 19875e09c8c3SJim Ingham { 19885e09c8c3SJim Ingham Error error; 19895e09c8c3SJim Ingham const int short_option = g_breakpoint_name_options[option_idx].short_option; 19905e09c8c3SJim Ingham 19915e09c8c3SJim Ingham switch (short_option) 19925e09c8c3SJim Ingham { 19935e09c8c3SJim Ingham case 'N': 19945e09c8c3SJim Ingham if (BreakpointID::StringIsBreakpointName(option_value, error) && error.Success()) 1995c95f7e2aSPavel Labath m_name.SetValueFromString(option_value); 19965e09c8c3SJim Ingham break; 19975e09c8c3SJim Ingham 19985e09c8c3SJim Ingham case 'B': 1999c95f7e2aSPavel Labath if (m_breakpoint.SetValueFromString(option_value).Fail()) 20005e09c8c3SJim Ingham error.SetErrorStringWithFormat ("unrecognized value \"%s\" for breakpoint", option_value); 20015e09c8c3SJim Ingham break; 20025e09c8c3SJim Ingham case 'D': 2003c95f7e2aSPavel Labath if (m_use_dummy.SetValueFromString(option_value).Fail()) 20045e09c8c3SJim Ingham error.SetErrorStringWithFormat ("unrecognized value \"%s\" for use-dummy", option_value); 20055e09c8c3SJim Ingham break; 20065e09c8c3SJim Ingham 20075e09c8c3SJim Ingham default: 20085e09c8c3SJim Ingham error.SetErrorStringWithFormat("unrecognized short option '%c'", short_option); 20095e09c8c3SJim Ingham break; 20105e09c8c3SJim Ingham } 20115e09c8c3SJim Ingham return error; 20125e09c8c3SJim Ingham } 20135e09c8c3SJim Ingham 201413d21e9aSBruce Mitchener void 2015e1cfbc79STodd Fiala OptionParsingStarting (ExecutionContext *execution_context) override 20165e09c8c3SJim Ingham { 20175e09c8c3SJim Ingham m_name.Clear(); 20185e09c8c3SJim Ingham m_breakpoint.Clear(); 20195e09c8c3SJim Ingham m_use_dummy.Clear(); 20205e09c8c3SJim Ingham m_use_dummy.SetDefaultValue(false); 20215e09c8c3SJim Ingham } 20225e09c8c3SJim Ingham 20235e09c8c3SJim Ingham OptionValueString m_name; 20245e09c8c3SJim Ingham OptionValueUInt64 m_breakpoint; 20255e09c8c3SJim Ingham OptionValueBoolean m_use_dummy; 20265e09c8c3SJim Ingham }; 20275e09c8c3SJim Ingham 20285e09c8c3SJim Ingham class CommandObjectBreakpointNameAdd : public CommandObjectParsed 20295e09c8c3SJim Ingham { 20305e09c8c3SJim Ingham public: 20315e09c8c3SJim Ingham CommandObjectBreakpointNameAdd (CommandInterpreter &interpreter) : 20325e09c8c3SJim Ingham CommandObjectParsed (interpreter, 20335e09c8c3SJim Ingham "add", 20345e09c8c3SJim Ingham "Add a name to the breakpoints provided.", 20355e09c8c3SJim Ingham "breakpoint name add <command-options> <breakpoint-id-list>"), 20365e09c8c3SJim Ingham m_name_options(), 2037e1cfbc79STodd Fiala m_option_group() 20385e09c8c3SJim Ingham { 20395e09c8c3SJim Ingham // Create the first variant for the first (and only) argument for this command. 20405e09c8c3SJim Ingham CommandArgumentEntry arg1; 20415e09c8c3SJim Ingham CommandArgumentData id_arg; 20425e09c8c3SJim Ingham id_arg.arg_type = eArgTypeBreakpointID; 20435e09c8c3SJim Ingham id_arg.arg_repetition = eArgRepeatOptional; 20445e09c8c3SJim Ingham arg1.push_back(id_arg); 20455e09c8c3SJim Ingham m_arguments.push_back (arg1); 20465e09c8c3SJim Ingham 20475e09c8c3SJim Ingham m_option_group.Append (&m_name_options, LLDB_OPT_SET_1, LLDB_OPT_SET_ALL); 20485e09c8c3SJim Ingham m_option_group.Finalize(); 20495e09c8c3SJim Ingham } 20505e09c8c3SJim Ingham 20519e85e5a8SEugene Zelenko ~CommandObjectBreakpointNameAdd() override = default; 20525e09c8c3SJim Ingham 20535e09c8c3SJim Ingham Options * 205413d21e9aSBruce Mitchener GetOptions() override 20555e09c8c3SJim Ingham { 20565e09c8c3SJim Ingham return &m_option_group; 20575e09c8c3SJim Ingham } 20585e09c8c3SJim Ingham 20595e09c8c3SJim Ingham protected: 206013d21e9aSBruce Mitchener bool 206113d21e9aSBruce Mitchener DoExecute (Args& command, CommandReturnObject &result) override 20625e09c8c3SJim Ingham { 20635e09c8c3SJim Ingham if (!m_name_options.m_name.OptionWasSet()) 20645e09c8c3SJim Ingham { 20655e09c8c3SJim Ingham result.SetError("No name option provided."); 20665e09c8c3SJim Ingham return false; 20675e09c8c3SJim Ingham } 20685e09c8c3SJim Ingham 20695e09c8c3SJim Ingham Target *target = GetSelectedOrDummyTarget(m_name_options.m_use_dummy.GetCurrentValue()); 20705e09c8c3SJim Ingham 20719e85e5a8SEugene Zelenko if (target == nullptr) 20725e09c8c3SJim Ingham { 20735e09c8c3SJim Ingham result.AppendError ("Invalid target. No existing target or breakpoints."); 20745e09c8c3SJim Ingham result.SetStatus (eReturnStatusFailed); 20755e09c8c3SJim Ingham return false; 20765e09c8c3SJim Ingham } 20775e09c8c3SJim Ingham 2078bb19a13cSSaleem Abdulrasool std::unique_lock<std::recursive_mutex> lock; 2079bb19a13cSSaleem Abdulrasool target->GetBreakpointList().GetListMutex(lock); 20805e09c8c3SJim Ingham 20815e09c8c3SJim Ingham const BreakpointList &breakpoints = target->GetBreakpointList(); 20825e09c8c3SJim Ingham 20835e09c8c3SJim Ingham size_t num_breakpoints = breakpoints.GetSize(); 20845e09c8c3SJim Ingham if (num_breakpoints == 0) 20855e09c8c3SJim Ingham { 20865e09c8c3SJim Ingham result.SetError("No breakpoints, cannot add names."); 20875e09c8c3SJim Ingham result.SetStatus (eReturnStatusFailed); 20885e09c8c3SJim Ingham return false; 20895e09c8c3SJim Ingham } 20905e09c8c3SJim Ingham 20915e09c8c3SJim Ingham // Particular breakpoint selected; disable that breakpoint. 20925e09c8c3SJim Ingham BreakpointIDList valid_bp_ids; 20935e09c8c3SJim Ingham CommandObjectMultiwordBreakpoint::VerifyBreakpointIDs (command, target, result, &valid_bp_ids); 20945e09c8c3SJim Ingham 20955e09c8c3SJim Ingham if (result.Succeeded()) 20965e09c8c3SJim Ingham { 20975e09c8c3SJim Ingham if (valid_bp_ids.GetSize() == 0) 20985e09c8c3SJim Ingham { 20995e09c8c3SJim Ingham result.SetError("No breakpoints specified, cannot add names."); 21005e09c8c3SJim Ingham result.SetStatus (eReturnStatusFailed); 21015e09c8c3SJim Ingham return false; 21025e09c8c3SJim Ingham } 21035e09c8c3SJim Ingham size_t num_valid_ids = valid_bp_ids.GetSize(); 21045e09c8c3SJim Ingham for (size_t index = 0; index < num_valid_ids; index++) 21055e09c8c3SJim Ingham { 21065e09c8c3SJim Ingham lldb::break_id_t bp_id = valid_bp_ids.GetBreakpointIDAtIndex(index).GetBreakpointID(); 21075e09c8c3SJim Ingham BreakpointSP bp_sp = breakpoints.FindBreakpointByID(bp_id); 21085e09c8c3SJim Ingham Error error; // We don't need to check the error here, since the option parser checked it... 21095e09c8c3SJim Ingham bp_sp->AddName(m_name_options.m_name.GetCurrentValue(), error); 21105e09c8c3SJim Ingham } 21115e09c8c3SJim Ingham } 21125e09c8c3SJim Ingham 21135e09c8c3SJim Ingham return true; 21145e09c8c3SJim Ingham } 21155e09c8c3SJim Ingham 21165e09c8c3SJim Ingham private: 21175e09c8c3SJim Ingham BreakpointNameOptionGroup m_name_options; 21185e09c8c3SJim Ingham OptionGroupOptions m_option_group; 21195e09c8c3SJim Ingham }; 21205e09c8c3SJim Ingham 21215e09c8c3SJim Ingham class CommandObjectBreakpointNameDelete : public CommandObjectParsed 21225e09c8c3SJim Ingham { 21235e09c8c3SJim Ingham public: 21245e09c8c3SJim Ingham CommandObjectBreakpointNameDelete (CommandInterpreter &interpreter) : 21255e09c8c3SJim Ingham CommandObjectParsed (interpreter, 21265e09c8c3SJim Ingham "delete", 21275e09c8c3SJim Ingham "Delete a name from the breakpoints provided.", 21285e09c8c3SJim Ingham "breakpoint name delete <command-options> <breakpoint-id-list>"), 21295e09c8c3SJim Ingham m_name_options(), 2130e1cfbc79STodd Fiala m_option_group() 21315e09c8c3SJim Ingham { 21325e09c8c3SJim Ingham // Create the first variant for the first (and only) argument for this command. 21335e09c8c3SJim Ingham CommandArgumentEntry arg1; 21345e09c8c3SJim Ingham CommandArgumentData id_arg; 21355e09c8c3SJim Ingham id_arg.arg_type = eArgTypeBreakpointID; 21365e09c8c3SJim Ingham id_arg.arg_repetition = eArgRepeatOptional; 21375e09c8c3SJim Ingham arg1.push_back(id_arg); 21385e09c8c3SJim Ingham m_arguments.push_back (arg1); 21395e09c8c3SJim Ingham 21405e09c8c3SJim Ingham m_option_group.Append (&m_name_options, LLDB_OPT_SET_1, LLDB_OPT_SET_ALL); 21415e09c8c3SJim Ingham m_option_group.Finalize(); 21425e09c8c3SJim Ingham } 21435e09c8c3SJim Ingham 21449e85e5a8SEugene Zelenko ~CommandObjectBreakpointNameDelete() override = default; 21455e09c8c3SJim Ingham 21465e09c8c3SJim Ingham Options * 214713d21e9aSBruce Mitchener GetOptions() override 21485e09c8c3SJim Ingham { 21495e09c8c3SJim Ingham return &m_option_group; 21505e09c8c3SJim Ingham } 21515e09c8c3SJim Ingham 21525e09c8c3SJim Ingham protected: 215313d21e9aSBruce Mitchener bool 215413d21e9aSBruce Mitchener DoExecute (Args& command, CommandReturnObject &result) override 21555e09c8c3SJim Ingham { 21565e09c8c3SJim Ingham if (!m_name_options.m_name.OptionWasSet()) 21575e09c8c3SJim Ingham { 21585e09c8c3SJim Ingham result.SetError("No name option provided."); 21595e09c8c3SJim Ingham return false; 21605e09c8c3SJim Ingham } 21615e09c8c3SJim Ingham 21625e09c8c3SJim Ingham Target *target = GetSelectedOrDummyTarget(m_name_options.m_use_dummy.GetCurrentValue()); 21635e09c8c3SJim Ingham 21649e85e5a8SEugene Zelenko if (target == nullptr) 21655e09c8c3SJim Ingham { 21665e09c8c3SJim Ingham result.AppendError ("Invalid target. No existing target or breakpoints."); 21675e09c8c3SJim Ingham result.SetStatus (eReturnStatusFailed); 21685e09c8c3SJim Ingham return false; 21695e09c8c3SJim Ingham } 21705e09c8c3SJim Ingham 2171bb19a13cSSaleem Abdulrasool std::unique_lock<std::recursive_mutex> lock; 2172bb19a13cSSaleem Abdulrasool target->GetBreakpointList().GetListMutex(lock); 21735e09c8c3SJim Ingham 21745e09c8c3SJim Ingham const BreakpointList &breakpoints = target->GetBreakpointList(); 21755e09c8c3SJim Ingham 21765e09c8c3SJim Ingham size_t num_breakpoints = breakpoints.GetSize(); 21775e09c8c3SJim Ingham if (num_breakpoints == 0) 21785e09c8c3SJim Ingham { 21795e09c8c3SJim Ingham result.SetError("No breakpoints, cannot delete names."); 21805e09c8c3SJim Ingham result.SetStatus (eReturnStatusFailed); 21815e09c8c3SJim Ingham return false; 21825e09c8c3SJim Ingham } 21835e09c8c3SJim Ingham 21845e09c8c3SJim Ingham // Particular breakpoint selected; disable that breakpoint. 21855e09c8c3SJim Ingham BreakpointIDList valid_bp_ids; 21865e09c8c3SJim Ingham CommandObjectMultiwordBreakpoint::VerifyBreakpointIDs (command, target, result, &valid_bp_ids); 21875e09c8c3SJim Ingham 21885e09c8c3SJim Ingham if (result.Succeeded()) 21895e09c8c3SJim Ingham { 21905e09c8c3SJim Ingham if (valid_bp_ids.GetSize() == 0) 21915e09c8c3SJim Ingham { 21925e09c8c3SJim Ingham result.SetError("No breakpoints specified, cannot delete names."); 21935e09c8c3SJim Ingham result.SetStatus (eReturnStatusFailed); 21945e09c8c3SJim Ingham return false; 21955e09c8c3SJim Ingham } 21965e09c8c3SJim Ingham size_t num_valid_ids = valid_bp_ids.GetSize(); 21975e09c8c3SJim Ingham for (size_t index = 0; index < num_valid_ids; index++) 21985e09c8c3SJim Ingham { 21995e09c8c3SJim Ingham lldb::break_id_t bp_id = valid_bp_ids.GetBreakpointIDAtIndex(index).GetBreakpointID(); 22005e09c8c3SJim Ingham BreakpointSP bp_sp = breakpoints.FindBreakpointByID(bp_id); 22015e09c8c3SJim Ingham bp_sp->RemoveName(m_name_options.m_name.GetCurrentValue()); 22025e09c8c3SJim Ingham } 22035e09c8c3SJim Ingham } 22045e09c8c3SJim Ingham 22055e09c8c3SJim Ingham return true; 22065e09c8c3SJim Ingham } 22075e09c8c3SJim Ingham 22085e09c8c3SJim Ingham private: 22095e09c8c3SJim Ingham BreakpointNameOptionGroup m_name_options; 22105e09c8c3SJim Ingham OptionGroupOptions m_option_group; 22115e09c8c3SJim Ingham }; 22125e09c8c3SJim Ingham 22135e09c8c3SJim Ingham class CommandObjectBreakpointNameList : public CommandObjectParsed 22145e09c8c3SJim Ingham { 22155e09c8c3SJim Ingham public: 22165e09c8c3SJim Ingham CommandObjectBreakpointNameList (CommandInterpreter &interpreter) : 22175e09c8c3SJim Ingham CommandObjectParsed (interpreter, 22185e09c8c3SJim Ingham "list", 22195e09c8c3SJim Ingham "List either the names for a breakpoint or the breakpoints for a given name.", 22205e09c8c3SJim Ingham "breakpoint name list <command-options>"), 22215e09c8c3SJim Ingham m_name_options(), 2222e1cfbc79STodd Fiala m_option_group() 22235e09c8c3SJim Ingham { 22245e09c8c3SJim Ingham m_option_group.Append (&m_name_options); 22255e09c8c3SJim Ingham m_option_group.Finalize(); 22265e09c8c3SJim Ingham } 22275e09c8c3SJim Ingham 22289e85e5a8SEugene Zelenko ~CommandObjectBreakpointNameList() override = default; 22295e09c8c3SJim Ingham 22305e09c8c3SJim Ingham Options * 223113d21e9aSBruce Mitchener GetOptions() override 22325e09c8c3SJim Ingham { 22335e09c8c3SJim Ingham return &m_option_group; 22345e09c8c3SJim Ingham } 22355e09c8c3SJim Ingham 22365e09c8c3SJim Ingham protected: 223713d21e9aSBruce Mitchener bool 223813d21e9aSBruce Mitchener DoExecute (Args& command, CommandReturnObject &result) override 22395e09c8c3SJim Ingham { 22405e09c8c3SJim Ingham Target *target = GetSelectedOrDummyTarget(m_name_options.m_use_dummy.GetCurrentValue()); 22415e09c8c3SJim Ingham 22429e85e5a8SEugene Zelenko if (target == nullptr) 22435e09c8c3SJim Ingham { 22445e09c8c3SJim Ingham result.AppendError ("Invalid target. No existing target or breakpoints."); 22455e09c8c3SJim Ingham result.SetStatus (eReturnStatusFailed); 22465e09c8c3SJim Ingham return false; 22475e09c8c3SJim Ingham } 22485e09c8c3SJim Ingham 22495e09c8c3SJim Ingham if (m_name_options.m_name.OptionWasSet()) 22505e09c8c3SJim Ingham { 22515e09c8c3SJim Ingham const char *name = m_name_options.m_name.GetCurrentValue(); 2252bb19a13cSSaleem Abdulrasool std::unique_lock<std::recursive_mutex> lock; 2253bb19a13cSSaleem Abdulrasool target->GetBreakpointList().GetListMutex(lock); 22545e09c8c3SJim Ingham 22555e09c8c3SJim Ingham BreakpointList &breakpoints = target->GetBreakpointList(); 22565e09c8c3SJim Ingham for (BreakpointSP bp_sp : breakpoints.Breakpoints()) 22575e09c8c3SJim Ingham { 22585e09c8c3SJim Ingham if (bp_sp->MatchesName(name)) 22595e09c8c3SJim Ingham { 22605e09c8c3SJim Ingham StreamString s; 22615e09c8c3SJim Ingham bp_sp->GetDescription(&s, eDescriptionLevelBrief); 22625e09c8c3SJim Ingham s.EOL(); 22635e09c8c3SJim Ingham result.AppendMessage(s.GetData()); 22645e09c8c3SJim Ingham } 22655e09c8c3SJim Ingham } 22665e09c8c3SJim Ingham 22675e09c8c3SJim Ingham } 22685e09c8c3SJim Ingham else if (m_name_options.m_breakpoint.OptionWasSet()) 22695e09c8c3SJim Ingham { 22705e09c8c3SJim Ingham BreakpointSP bp_sp = target->GetBreakpointList().FindBreakpointByID(m_name_options.m_breakpoint.GetCurrentValue()); 22715e09c8c3SJim Ingham if (bp_sp) 22725e09c8c3SJim Ingham { 22735e09c8c3SJim Ingham std::vector<std::string> names; 22745e09c8c3SJim Ingham bp_sp->GetNames (names); 22755e09c8c3SJim Ingham result.AppendMessage ("Names:"); 22765e09c8c3SJim Ingham for (auto name : names) 22775e09c8c3SJim Ingham result.AppendMessageWithFormat (" %s\n", name.c_str()); 22785e09c8c3SJim Ingham } 22795e09c8c3SJim Ingham else 22805e09c8c3SJim Ingham { 22815e09c8c3SJim Ingham result.AppendErrorWithFormat ("Could not find breakpoint %" PRId64 ".\n", 22825e09c8c3SJim Ingham m_name_options.m_breakpoint.GetCurrentValue()); 22835e09c8c3SJim Ingham result.SetStatus (eReturnStatusFailed); 22845e09c8c3SJim Ingham return false; 22855e09c8c3SJim Ingham } 22865e09c8c3SJim Ingham } 22875e09c8c3SJim Ingham else 22885e09c8c3SJim Ingham { 22895e09c8c3SJim Ingham result.SetError ("Must specify -N or -B option to list."); 22905e09c8c3SJim Ingham result.SetStatus (eReturnStatusFailed); 22915e09c8c3SJim Ingham return false; 22925e09c8c3SJim Ingham } 22935e09c8c3SJim Ingham return true; 22945e09c8c3SJim Ingham } 22955e09c8c3SJim Ingham 22965e09c8c3SJim Ingham private: 22975e09c8c3SJim Ingham BreakpointNameOptionGroup m_name_options; 22985e09c8c3SJim Ingham OptionGroupOptions m_option_group; 22995e09c8c3SJim Ingham }; 23005e09c8c3SJim Ingham 23015e09c8c3SJim Ingham //------------------------------------------------------------------------- 23025e09c8c3SJim Ingham // CommandObjectMultiwordBreakpoint 23035e09c8c3SJim Ingham //------------------------------------------------------------------------- 23045e09c8c3SJim Ingham class CommandObjectBreakpointName : public CommandObjectMultiword 23055e09c8c3SJim Ingham { 23065e09c8c3SJim Ingham public: 23077428a18cSKate Stone CommandObjectBreakpointName(CommandInterpreter &interpreter) 23087428a18cSKate Stone : CommandObjectMultiword(interpreter, "name", "Commands to manage name tags for breakpoints", 23097428a18cSKate Stone "breakpoint name <subcommand> [<command-options>]") 23105e09c8c3SJim Ingham { 23115e09c8c3SJim Ingham CommandObjectSP add_command_object (new CommandObjectBreakpointNameAdd (interpreter)); 23125e09c8c3SJim Ingham CommandObjectSP delete_command_object (new CommandObjectBreakpointNameDelete (interpreter)); 23135e09c8c3SJim Ingham CommandObjectSP list_command_object (new CommandObjectBreakpointNameList (interpreter)); 23145e09c8c3SJim Ingham 23155e09c8c3SJim Ingham LoadSubCommand ("add", add_command_object); 23165e09c8c3SJim Ingham LoadSubCommand ("delete", delete_command_object); 23175e09c8c3SJim Ingham LoadSubCommand ("list", list_command_object); 23185e09c8c3SJim Ingham } 23195e09c8c3SJim Ingham 23209e85e5a8SEugene Zelenko ~CommandObjectBreakpointName() override = default; 23215e09c8c3SJim Ingham }; 23225e09c8c3SJim Ingham 23235e09c8c3SJim Ingham //------------------------------------------------------------------------- 232430fdc8d8SChris Lattner // CommandObjectMultiwordBreakpoint 232530fdc8d8SChris Lattner //------------------------------------------------------------------------- 2326ae1c4cf5SJim Ingham #pragma mark MultiwordBreakpoint 232730fdc8d8SChris Lattner 23287428a18cSKate Stone CommandObjectMultiwordBreakpoint::CommandObjectMultiwordBreakpoint(CommandInterpreter &interpreter) 23297428a18cSKate Stone : CommandObjectMultiword(interpreter, "breakpoint", 23307428a18cSKate Stone "Commands for operating on breakpoints (see 'help b' for shorthand.)", 23317428a18cSKate Stone "breakpoint <subcommand> [<command-options>]") 233230fdc8d8SChris Lattner { 2333a7015092SGreg Clayton CommandObjectSP list_command_object (new CommandObjectBreakpointList (interpreter)); 2334a7015092SGreg Clayton CommandObjectSP enable_command_object (new CommandObjectBreakpointEnable (interpreter)); 2335a7015092SGreg Clayton CommandObjectSP disable_command_object (new CommandObjectBreakpointDisable (interpreter)); 2336b7234e40SJohnny Chen CommandObjectSP clear_command_object (new CommandObjectBreakpointClear (interpreter)); 2337b7234e40SJohnny Chen CommandObjectSP delete_command_object (new CommandObjectBreakpointDelete (interpreter)); 2338a7015092SGreg Clayton CommandObjectSP set_command_object (new CommandObjectBreakpointSet (interpreter)); 233930fdc8d8SChris Lattner CommandObjectSP command_command_object (new CommandObjectBreakpointCommand (interpreter)); 2340a7015092SGreg Clayton CommandObjectSP modify_command_object (new CommandObjectBreakpointModify(interpreter)); 23415e09c8c3SJim Ingham CommandObjectSP name_command_object (new CommandObjectBreakpointName(interpreter)); 234230fdc8d8SChris Lattner 2343b7234e40SJohnny Chen list_command_object->SetCommandName ("breakpoint list"); 234430fdc8d8SChris Lattner enable_command_object->SetCommandName("breakpoint enable"); 234530fdc8d8SChris Lattner disable_command_object->SetCommandName("breakpoint disable"); 2346b7234e40SJohnny Chen clear_command_object->SetCommandName("breakpoint clear"); 2347b7234e40SJohnny Chen delete_command_object->SetCommandName("breakpoint delete"); 2348ae1c4cf5SJim Ingham set_command_object->SetCommandName("breakpoint set"); 2349b7234e40SJohnny Chen command_command_object->SetCommandName ("breakpoint command"); 2350b7234e40SJohnny Chen modify_command_object->SetCommandName ("breakpoint modify"); 23515e09c8c3SJim Ingham name_command_object->SetCommandName ("breakpoint name"); 235230fdc8d8SChris Lattner 235323f59509SGreg Clayton LoadSubCommand ("list", list_command_object); 235423f59509SGreg Clayton LoadSubCommand ("enable", enable_command_object); 235523f59509SGreg Clayton LoadSubCommand ("disable", disable_command_object); 235623f59509SGreg Clayton LoadSubCommand ("clear", clear_command_object); 235723f59509SGreg Clayton LoadSubCommand ("delete", delete_command_object); 235823f59509SGreg Clayton LoadSubCommand ("set", set_command_object); 235923f59509SGreg Clayton LoadSubCommand ("command", command_command_object); 236023f59509SGreg Clayton LoadSubCommand ("modify", modify_command_object); 23615e09c8c3SJim Ingham LoadSubCommand ("name", name_command_object); 236230fdc8d8SChris Lattner } 236330fdc8d8SChris Lattner 23649e85e5a8SEugene Zelenko CommandObjectMultiwordBreakpoint::~CommandObjectMultiwordBreakpoint() = default; 236530fdc8d8SChris Lattner 236630fdc8d8SChris Lattner void 23675e09c8c3SJim Ingham CommandObjectMultiwordBreakpoint::VerifyIDs (Args &args, 23685e09c8c3SJim Ingham Target *target, 23695e09c8c3SJim Ingham bool allow_locations, 23705e09c8c3SJim Ingham CommandReturnObject &result, 237130fdc8d8SChris Lattner BreakpointIDList *valid_ids) 237230fdc8d8SChris Lattner { 237330fdc8d8SChris Lattner // args can be strings representing 1). integers (for breakpoint ids) 237430fdc8d8SChris Lattner // 2). the full breakpoint & location canonical representation 237530fdc8d8SChris Lattner // 3). the word "to" or a hyphen, representing a range (in which case there 237630fdc8d8SChris Lattner // had *better* be an entry both before & after of one of the first two types. 23775e09c8c3SJim Ingham // 4). A breakpoint name 237836f3b369SJim Ingham // If args is empty, we will use the last created breakpoint (if there is one.) 237930fdc8d8SChris Lattner 238030fdc8d8SChris Lattner Args temp_args; 238130fdc8d8SChris Lattner 238236f3b369SJim Ingham if (args.GetArgumentCount() == 0) 238336f3b369SJim Ingham { 23844d122c40SGreg Clayton if (target->GetLastCreatedBreakpoint()) 238536f3b369SJim Ingham { 238636f3b369SJim Ingham valid_ids->AddBreakpointID (BreakpointID(target->GetLastCreatedBreakpoint()->GetID(), LLDB_INVALID_BREAK_ID)); 238736f3b369SJim Ingham result.SetStatus (eReturnStatusSuccessFinishNoResult); 238836f3b369SJim Ingham } 238936f3b369SJim Ingham else 239036f3b369SJim Ingham { 239136f3b369SJim Ingham result.AppendError("No breakpoint specified and no last created breakpoint."); 239236f3b369SJim Ingham result.SetStatus (eReturnStatusFailed); 239336f3b369SJim Ingham } 239436f3b369SJim Ingham return; 239536f3b369SJim Ingham } 239636f3b369SJim Ingham 239730fdc8d8SChris Lattner // Create a new Args variable to use; copy any non-breakpoint-id-ranges stuff directly from the old ARGS to 239830fdc8d8SChris Lattner // the new TEMP_ARGS. Do not copy breakpoint id range strings over; instead generate a list of strings for 239930fdc8d8SChris Lattner // all the breakpoint ids in the range, and shove all of those breakpoint id strings into TEMP_ARGS. 240030fdc8d8SChris Lattner 24015e09c8c3SJim Ingham BreakpointIDList::FindAndReplaceIDRanges (args, target, allow_locations, result, temp_args); 240230fdc8d8SChris Lattner 240330fdc8d8SChris Lattner // NOW, convert the list of breakpoint id strings in TEMP_ARGS into an actual BreakpointIDList: 240430fdc8d8SChris Lattner 2405c982c768SGreg Clayton valid_ids->InsertStringArray (temp_args.GetConstArgumentVector(), temp_args.GetArgumentCount(), result); 240630fdc8d8SChris Lattner 240730fdc8d8SChris Lattner // At this point, all of the breakpoint ids that the user passed in have been converted to breakpoint IDs 240830fdc8d8SChris Lattner // and put into valid_ids. 240930fdc8d8SChris Lattner 241030fdc8d8SChris Lattner if (result.Succeeded()) 241130fdc8d8SChris Lattner { 241230fdc8d8SChris Lattner // Now that we've converted everything from args into a list of breakpoint ids, go through our tentative list 241330fdc8d8SChris Lattner // of breakpoint id's and verify that they correspond to valid/currently set breakpoints. 241430fdc8d8SChris Lattner 2415c982c768SGreg Clayton const size_t count = valid_ids->GetSize(); 2416c982c768SGreg Clayton for (size_t i = 0; i < count; ++i) 241730fdc8d8SChris Lattner { 241830fdc8d8SChris Lattner BreakpointID cur_bp_id = valid_ids->GetBreakpointIDAtIndex (i); 241930fdc8d8SChris Lattner Breakpoint *breakpoint = target->GetBreakpointByID (cur_bp_id.GetBreakpointID()).get(); 24209e85e5a8SEugene Zelenko if (breakpoint != nullptr) 242130fdc8d8SChris Lattner { 2422c7bece56SGreg Clayton const size_t num_locations = breakpoint->GetNumLocations(); 24233985c8c6SSaleem Abdulrasool if (static_cast<size_t>(cur_bp_id.GetLocationID()) > num_locations) 242430fdc8d8SChris Lattner { 242530fdc8d8SChris Lattner StreamString id_str; 2426c982c768SGreg Clayton BreakpointID::GetCanonicalReference (&id_str, 2427c982c768SGreg Clayton cur_bp_id.GetBreakpointID(), 242830fdc8d8SChris Lattner cur_bp_id.GetLocationID()); 2429c982c768SGreg Clayton i = valid_ids->GetSize() + 1; 243030fdc8d8SChris Lattner result.AppendErrorWithFormat ("'%s' is not a currently valid breakpoint/location id.\n", 243130fdc8d8SChris Lattner id_str.GetData()); 243230fdc8d8SChris Lattner result.SetStatus (eReturnStatusFailed); 243330fdc8d8SChris Lattner } 243430fdc8d8SChris Lattner } 243530fdc8d8SChris Lattner else 243630fdc8d8SChris Lattner { 2437c982c768SGreg Clayton i = valid_ids->GetSize() + 1; 24387428a18cSKate Stone result.AppendErrorWithFormat("'%d' is not a currently valid breakpoint ID.\n", 24397428a18cSKate Stone cur_bp_id.GetBreakpointID()); 244030fdc8d8SChris Lattner result.SetStatus (eReturnStatusFailed); 244130fdc8d8SChris Lattner } 244230fdc8d8SChris Lattner } 244330fdc8d8SChris Lattner } 244430fdc8d8SChris Lattner } 2445