130fdc8d8SChris Lattner //===-- CommandObjectBreakpoint.cpp -----------------------------*- C++ -*-===// 230fdc8d8SChris Lattner // 32946cd70SChandler Carruth // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. 42946cd70SChandler Carruth // See https://llvm.org/LICENSE.txt for license information. 52946cd70SChandler Carruth // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception 630fdc8d8SChris Lattner // 730fdc8d8SChris Lattner //===----------------------------------------------------------------------===// 830fdc8d8SChris Lattner 99e85e5a8SEugene Zelenko #include "CommandObjectBreakpoint.h" 109e85e5a8SEugene Zelenko #include "CommandObjectBreakpointCommand.h" 1130fdc8d8SChris Lattner #include "lldb/Breakpoint/Breakpoint.h" 1230fdc8d8SChris Lattner #include "lldb/Breakpoint/BreakpointIDList.h" 1330fdc8d8SChris Lattner #include "lldb/Breakpoint/BreakpointLocation.h" 143eb2b44dSZachary Turner #include "lldb/Host/OptionParser.h" 15b9c1b51eSKate Stone #include "lldb/Interpreter/CommandCompletions.h" 16b9c1b51eSKate Stone #include "lldb/Interpreter/CommandInterpreter.h" 17b9c1b51eSKate Stone #include "lldb/Interpreter/CommandReturnObject.h" 1847cbf4a0SPavel Labath #include "lldb/Interpreter/OptionArgParser.h" 19943a2481SJim Ingham #include "lldb/Interpreter/OptionGroupPythonClassWithDict.h" 2032abc6edSZachary Turner #include "lldb/Interpreter/OptionValueBoolean.h" 215e09c8c3SJim Ingham #include "lldb/Interpreter/OptionValueString.h" 225e09c8c3SJim Ingham #include "lldb/Interpreter/OptionValueUInt64.h" 23b9c1b51eSKate Stone #include "lldb/Interpreter/Options.h" 240e0984eeSJim Ingham #include "lldb/Target/Language.h" 25b57e4a1bSJason Molenda #include "lldb/Target/StackFrame.h" 26b9c1b51eSKate Stone #include "lldb/Target/Target.h" 271b54c88cSJim Ingham #include "lldb/Target/Thread.h" 281b54c88cSJim Ingham #include "lldb/Target/ThreadSpec.h" 29bf9a7730SZachary Turner #include "lldb/Utility/RegularExpression.h" 30bf9a7730SZachary Turner #include "lldb/Utility/StreamString.h" 3130fdc8d8SChris Lattner 32796ac80bSJonas Devlieghere #include <memory> 33796ac80bSJonas Devlieghere #include <vector> 34796ac80bSJonas Devlieghere 3530fdc8d8SChris Lattner using namespace lldb; 3630fdc8d8SChris Lattner using namespace lldb_private; 3730fdc8d8SChris Lattner 38b9c1b51eSKate Stone static void AddBreakpointDescription(Stream *s, Breakpoint *bp, 39b9c1b51eSKate Stone lldb::DescriptionLevel level) { 4030fdc8d8SChris Lattner s->IndentMore(); 4130fdc8d8SChris Lattner bp->GetDescription(s, level, true); 4230fdc8d8SChris Lattner s->IndentLess(); 4330fdc8d8SChris Lattner s->EOL(); 4430fdc8d8SChris Lattner } 4530fdc8d8SChris Lattner 46b842f2ecSJim Ingham // Modifiable Breakpoint Options 47b842f2ecSJim Ingham #pragma mark Modify::CommandOptions 48f94668e3SRaphael Isemann #define LLDB_OPTIONS_breakpoint_modify 49f94668e3SRaphael Isemann #include "CommandOptions.inc" 50bd68a052SRaphael Isemann 51*a925974bSAdrian Prantl class lldb_private::BreakpointOptionGroup : public OptionGroup { 52b842f2ecSJim Ingham public: 53*a925974bSAdrian Prantl BreakpointOptionGroup() : OptionGroup(), m_bp_opts(false) {} 54b842f2ecSJim Ingham 55b842f2ecSJim Ingham ~BreakpointOptionGroup() override = default; 56b842f2ecSJim Ingham 57b842f2ecSJim Ingham llvm::ArrayRef<OptionDefinition> GetDefinitions() override { 58b842f2ecSJim Ingham return llvm::makeArrayRef(g_breakpoint_modify_options); 59b842f2ecSJim Ingham } 60b842f2ecSJim Ingham 61b842f2ecSJim Ingham Status SetOptionValue(uint32_t option_idx, llvm::StringRef option_arg, 62b842f2ecSJim Ingham ExecutionContext *execution_context) override { 63b842f2ecSJim Ingham Status error; 64*a925974bSAdrian Prantl const int short_option = 65*a925974bSAdrian Prantl g_breakpoint_modify_options[option_idx].short_option; 66b842f2ecSJim Ingham 67b842f2ecSJim Ingham switch (short_option) { 68b842f2ecSJim Ingham case 'c': 6905097246SAdrian Prantl // Normally an empty breakpoint condition marks is as unset. But we need 7005097246SAdrian Prantl // to say it was passed in. 71b842f2ecSJim Ingham m_bp_opts.SetCondition(option_arg.str().c_str()); 72b842f2ecSJim Ingham m_bp_opts.m_set_flags.Set(BreakpointOptions::eCondition); 73b842f2ecSJim Ingham break; 74b842f2ecSJim Ingham case 'C': 75b842f2ecSJim Ingham m_commands.push_back(option_arg); 76b842f2ecSJim Ingham break; 77b842f2ecSJim Ingham case 'd': 78b842f2ecSJim Ingham m_bp_opts.SetEnabled(false); 79b842f2ecSJim Ingham break; 80b842f2ecSJim Ingham case 'e': 81b842f2ecSJim Ingham m_bp_opts.SetEnabled(true); 82b842f2ecSJim Ingham break; 83b842f2ecSJim Ingham case 'G': { 84b842f2ecSJim Ingham bool value, success; 8547cbf4a0SPavel Labath value = OptionArgParser::ToBoolean(option_arg, false, &success); 86b842f2ecSJim Ingham if (success) { 87b842f2ecSJim Ingham m_bp_opts.SetAutoContinue(value); 88b842f2ecSJim Ingham } else 89b842f2ecSJim Ingham error.SetErrorStringWithFormat( 90b842f2ecSJim Ingham "invalid boolean value '%s' passed for -G option", 91b842f2ecSJim Ingham option_arg.str().c_str()); 92*a925974bSAdrian Prantl } break; 93*a925974bSAdrian Prantl case 'i': { 94b842f2ecSJim Ingham uint32_t ignore_count; 95b842f2ecSJim Ingham if (option_arg.getAsInteger(0, ignore_count)) 96b842f2ecSJim Ingham error.SetErrorStringWithFormat("invalid ignore count '%s'", 97b842f2ecSJim Ingham option_arg.str().c_str()); 98b842f2ecSJim Ingham else 99b842f2ecSJim Ingham m_bp_opts.SetIgnoreCount(ignore_count); 100*a925974bSAdrian Prantl } break; 101b842f2ecSJim Ingham case 'o': { 102b842f2ecSJim Ingham bool value, success; 10347cbf4a0SPavel Labath value = OptionArgParser::ToBoolean(option_arg, false, &success); 104b842f2ecSJim Ingham if (success) { 105b842f2ecSJim Ingham m_bp_opts.SetOneShot(value); 106b842f2ecSJim Ingham } else 107b842f2ecSJim Ingham error.SetErrorStringWithFormat( 108b842f2ecSJim Ingham "invalid boolean value '%s' passed for -o option", 109b842f2ecSJim Ingham option_arg.str().c_str()); 110b842f2ecSJim Ingham } break; 111*a925974bSAdrian Prantl case 't': { 112b842f2ecSJim Ingham lldb::tid_t thread_id = LLDB_INVALID_THREAD_ID; 113b842f2ecSJim Ingham if (option_arg[0] != '\0') { 114b842f2ecSJim Ingham if (option_arg.getAsInteger(0, thread_id)) 115b842f2ecSJim Ingham error.SetErrorStringWithFormat("invalid thread id string '%s'", 116b842f2ecSJim Ingham option_arg.str().c_str()); 117b842f2ecSJim Ingham } 118b842f2ecSJim Ingham m_bp_opts.SetThreadID(thread_id); 119*a925974bSAdrian Prantl } break; 120b842f2ecSJim Ingham case 'T': 121b842f2ecSJim Ingham m_bp_opts.GetThreadSpec()->SetName(option_arg.str().c_str()); 122b842f2ecSJim Ingham break; 123b842f2ecSJim Ingham case 'q': 124b842f2ecSJim Ingham m_bp_opts.GetThreadSpec()->SetQueueName(option_arg.str().c_str()); 125b842f2ecSJim Ingham break; 126*a925974bSAdrian Prantl case 'x': { 127b842f2ecSJim Ingham uint32_t thread_index = UINT32_MAX; 128b842f2ecSJim Ingham if (option_arg[0] != '\n') { 129b842f2ecSJim Ingham if (option_arg.getAsInteger(0, thread_index)) 130b842f2ecSJim Ingham error.SetErrorStringWithFormat("invalid thread index string '%s'", 131b842f2ecSJim Ingham option_arg.str().c_str()); 132b842f2ecSJim Ingham } 133b842f2ecSJim Ingham m_bp_opts.GetThreadSpec()->SetIndex(thread_index); 134*a925974bSAdrian Prantl } break; 135b842f2ecSJim Ingham default: 13636162014SRaphael Isemann llvm_unreachable("Unimplemented option"); 137b842f2ecSJim Ingham } 138b842f2ecSJim Ingham 139b842f2ecSJim Ingham return error; 140b842f2ecSJim Ingham } 141b842f2ecSJim Ingham 142b842f2ecSJim Ingham void OptionParsingStarting(ExecutionContext *execution_context) override { 143b842f2ecSJim Ingham m_bp_opts.Clear(); 144b842f2ecSJim Ingham m_commands.clear(); 145b842f2ecSJim Ingham } 146b842f2ecSJim Ingham 147b842f2ecSJim Ingham Status OptionParsingFinished(ExecutionContext *execution_context) override { 148*a925974bSAdrian Prantl if (!m_commands.empty()) { 149*a925974bSAdrian Prantl if (!m_commands.empty()) { 150a8f3ae7cSJonas Devlieghere auto cmd_data = std::make_unique<BreakpointOptions::CommandData>(); 151b842f2ecSJim Ingham 152b842f2ecSJim Ingham for (std::string &str : m_commands) 153b842f2ecSJim Ingham cmd_data->user_source.AppendString(str); 154b842f2ecSJim Ingham 155b842f2ecSJim Ingham cmd_data->stop_on_error = true; 156b842f2ecSJim Ingham m_bp_opts.SetCommandDataCallback(cmd_data); 157b842f2ecSJim Ingham } 158b842f2ecSJim Ingham } 159b842f2ecSJim Ingham return Status(); 160b842f2ecSJim Ingham } 161b842f2ecSJim Ingham 162*a925974bSAdrian Prantl const BreakpointOptions &GetBreakpointOptions() { return m_bp_opts; } 163b842f2ecSJim Ingham 164b842f2ecSJim Ingham std::vector<std::string> m_commands; 165b842f2ecSJim Ingham BreakpointOptions m_bp_opts; 166b842f2ecSJim Ingham }; 167bd68a052SRaphael Isemann 168f94668e3SRaphael Isemann #define LLDB_OPTIONS_breakpoint_dummy 169f94668e3SRaphael Isemann #include "CommandOptions.inc" 170b842f2ecSJim Ingham 171*a925974bSAdrian Prantl class BreakpointDummyOptionGroup : public OptionGroup { 172b842f2ecSJim Ingham public: 173*a925974bSAdrian Prantl BreakpointDummyOptionGroup() : OptionGroup() {} 174b842f2ecSJim Ingham 175b842f2ecSJim Ingham ~BreakpointDummyOptionGroup() override = default; 176b842f2ecSJim Ingham 177b842f2ecSJim Ingham llvm::ArrayRef<OptionDefinition> GetDefinitions() override { 178b842f2ecSJim Ingham return llvm::makeArrayRef(g_breakpoint_dummy_options); 179b842f2ecSJim Ingham } 180b842f2ecSJim Ingham 181b842f2ecSJim Ingham Status SetOptionValue(uint32_t option_idx, llvm::StringRef option_arg, 182b842f2ecSJim Ingham ExecutionContext *execution_context) override { 183b842f2ecSJim Ingham Status error; 184*a925974bSAdrian Prantl const int short_option = 185*a925974bSAdrian Prantl g_breakpoint_modify_options[option_idx].short_option; 186b842f2ecSJim Ingham 187b842f2ecSJim Ingham switch (short_option) { 188b842f2ecSJim Ingham case 'D': 189b842f2ecSJim Ingham m_use_dummy = true; 190b842f2ecSJim Ingham break; 191b842f2ecSJim Ingham default: 19236162014SRaphael Isemann llvm_unreachable("Unimplemented option"); 193b842f2ecSJim Ingham } 194b842f2ecSJim Ingham 195b842f2ecSJim Ingham return error; 196b842f2ecSJim Ingham } 197b842f2ecSJim Ingham 198b842f2ecSJim Ingham void OptionParsingStarting(ExecutionContext *execution_context) override { 199b842f2ecSJim Ingham m_use_dummy = false; 200b842f2ecSJim Ingham } 201b842f2ecSJim Ingham 202b842f2ecSJim Ingham bool m_use_dummy; 203b842f2ecSJim Ingham }; 204b842f2ecSJim Ingham 205f94668e3SRaphael Isemann #define LLDB_OPTIONS_breakpoint_set 206f94668e3SRaphael Isemann #include "CommandOptions.inc" 2071f0f5b5bSZachary Turner 2085a988416SJim Ingham // CommandObjectBreakpointSet 20930fdc8d8SChris Lattner 210b9c1b51eSKate Stone class CommandObjectBreakpointSet : public CommandObjectParsed { 2115a988416SJim Ingham public: 212efe8e7e3SFangrui Song enum BreakpointSetType { 2135a988416SJim Ingham eSetTypeInvalid, 2145a988416SJim Ingham eSetTypeFileAndLine, 2155a988416SJim Ingham eSetTypeAddress, 2165a988416SJim Ingham eSetTypeFunctionName, 2175a988416SJim Ingham eSetTypeFunctionRegexp, 2185a988416SJim Ingham eSetTypeSourceRegexp, 2193815e702SJim Ingham eSetTypeException, 2203815e702SJim Ingham eSetTypeScripted, 221efe8e7e3SFangrui Song }; 2225a988416SJim Ingham 223b9c1b51eSKate Stone CommandObjectBreakpointSet(CommandInterpreter &interpreter) 224b9c1b51eSKate Stone : CommandObjectParsed( 225b9c1b51eSKate Stone interpreter, "breakpoint set", 2265a988416SJim Ingham "Sets a breakpoint or set of breakpoints in the executable.", 2275a988416SJim Ingham "breakpoint set <cmd-options>"), 228738af7a6SJim Ingham m_bp_opts(), m_python_class_options("scripted breakpoint", true, 'P'), 229f6a2086dSSam McCall m_options() { 230b842f2ecSJim Ingham // We're picking up all the normal options, commands and disable. 231*a925974bSAdrian Prantl m_all_options.Append(&m_python_class_options, 232*a925974bSAdrian Prantl LLDB_OPT_SET_1 | LLDB_OPT_SET_2, LLDB_OPT_SET_11); 233b842f2ecSJim Ingham m_all_options.Append(&m_bp_opts, 234b842f2ecSJim Ingham LLDB_OPT_SET_1 | LLDB_OPT_SET_3 | LLDB_OPT_SET_4, 235b842f2ecSJim Ingham LLDB_OPT_SET_ALL); 236f6a2086dSSam McCall m_all_options.Append(&m_dummy_options, LLDB_OPT_SET_1, LLDB_OPT_SET_ALL); 237b842f2ecSJim Ingham m_all_options.Append(&m_options); 238b842f2ecSJim Ingham m_all_options.Finalize(); 239b842f2ecSJim Ingham } 2405a988416SJim Ingham 2419e85e5a8SEugene Zelenko ~CommandObjectBreakpointSet() override = default; 2425a988416SJim Ingham 243b842f2ecSJim Ingham Options *GetOptions() override { return &m_all_options; } 2445a988416SJim Ingham 245b842f2ecSJim Ingham class CommandOptions : public OptionGroup { 2465a988416SJim Ingham public: 247b9c1b51eSKate Stone CommandOptions() 248*a925974bSAdrian Prantl : OptionGroup(), m_condition(), m_filenames(), m_line_num(0), 249*a925974bSAdrian Prantl m_column(0), m_func_names(), 250*a925974bSAdrian Prantl m_func_name_type_mask(eFunctionNameTypeNone), m_func_regexp(), 251*a925974bSAdrian Prantl m_source_text_regexp(), m_modules(), m_load_addr(), m_catch_bp(false), 252*a925974bSAdrian Prantl m_throw_bp(true), m_hardware(false), 253a72b31c7SJim Ingham m_exception_language(eLanguageTypeUnknown), 25423b1decbSDawn Perchik m_language(lldb::eLanguageTypeUnknown), 255*a925974bSAdrian Prantl m_skip_prologue(eLazyBoolCalculate), m_all_files(false), 256*a925974bSAdrian Prantl m_move_to_nearest_code(eLazyBoolCalculate) {} 25730fdc8d8SChris Lattner 2589e85e5a8SEugene Zelenko ~CommandOptions() override = default; 25987df91b8SJim Ingham 26097206d57SZachary Turner Status SetOptionValue(uint32_t option_idx, llvm::StringRef option_arg, 261b9c1b51eSKate Stone ExecutionContext *execution_context) override { 26297206d57SZachary Turner Status error; 263*a925974bSAdrian Prantl const int short_option = 264*a925974bSAdrian Prantl g_breakpoint_set_options[option_idx].short_option; 26530fdc8d8SChris Lattner 266b9c1b51eSKate Stone switch (short_option) { 267b9c1b51eSKate Stone case 'a': { 26847cbf4a0SPavel Labath m_load_addr = OptionArgParser::ToAddress(execution_context, option_arg, 269e1cfbc79STodd Fiala LLDB_INVALID_ADDRESS, &error); 270b9c1b51eSKate Stone } break; 27130fdc8d8SChris Lattner 272e732052fSJim Ingham case 'A': 273e732052fSJim Ingham m_all_files = true; 274e732052fSJim Ingham break; 275e732052fSJim Ingham 276ca36cd16SJim Ingham case 'b': 277ca36cd16SJim Ingham m_func_names.push_back(option_arg); 278ca36cd16SJim Ingham m_func_name_type_mask |= eFunctionNameTypeBase; 279ca36cd16SJim Ingham break; 280ca36cd16SJim Ingham 281fe11483bSZachary Turner case 'C': 282fe11483bSZachary Turner if (option_arg.getAsInteger(0, m_column)) 283b9c1b51eSKate Stone error.SetErrorStringWithFormat("invalid column number: %s", 284fe11483bSZachary Turner option_arg.str().c_str()); 28530fdc8d8SChris Lattner break; 2869e85e5a8SEugene Zelenko 287b9c1b51eSKate Stone case 'E': { 288fe11483bSZachary Turner LanguageType language = Language::GetLanguageTypeFromString(option_arg); 289fab10e89SJim Ingham 290b9c1b51eSKate Stone switch (language) { 291fab10e89SJim Ingham case eLanguageTypeC89: 292fab10e89SJim Ingham case eLanguageTypeC: 293fab10e89SJim Ingham case eLanguageTypeC99: 2941d0089faSBruce Mitchener case eLanguageTypeC11: 295a72b31c7SJim Ingham m_exception_language = eLanguageTypeC; 296fab10e89SJim Ingham break; 297fab10e89SJim Ingham case eLanguageTypeC_plus_plus: 2981d0089faSBruce Mitchener case eLanguageTypeC_plus_plus_03: 2991d0089faSBruce Mitchener case eLanguageTypeC_plus_plus_11: 3002ba84a6aSBruce Mitchener case eLanguageTypeC_plus_plus_14: 301a72b31c7SJim Ingham m_exception_language = eLanguageTypeC_plus_plus; 302fab10e89SJim Ingham break; 303fab10e89SJim Ingham case eLanguageTypeObjC: 304a72b31c7SJim Ingham m_exception_language = eLanguageTypeObjC; 305fab10e89SJim Ingham break; 306fab10e89SJim Ingham case eLanguageTypeObjC_plus_plus: 307b9c1b51eSKate Stone error.SetErrorStringWithFormat( 308b9c1b51eSKate Stone "Set exception breakpoints separately for c++ and objective-c"); 309fab10e89SJim Ingham break; 310fab10e89SJim Ingham case eLanguageTypeUnknown: 311b9c1b51eSKate Stone error.SetErrorStringWithFormat( 312b9c1b51eSKate Stone "Unknown language type: '%s' for exception breakpoint", 313fe11483bSZachary Turner option_arg.str().c_str()); 314fab10e89SJim Ingham break; 315fab10e89SJim Ingham default: 316b9c1b51eSKate Stone error.SetErrorStringWithFormat( 317b9c1b51eSKate Stone "Unsupported language type: '%s' for exception breakpoint", 318fe11483bSZachary Turner option_arg.str().c_str()); 319fab10e89SJim Ingham } 320b9c1b51eSKate Stone } break; 321ca36cd16SJim Ingham 322ca36cd16SJim Ingham case 'f': 3238f3be7a3SJonas Devlieghere m_filenames.AppendIfUnique(FileSpec(option_arg)); 324fab10e89SJim Ingham break; 325ca36cd16SJim Ingham 326ca36cd16SJim Ingham case 'F': 327ca36cd16SJim Ingham m_func_names.push_back(option_arg); 328ca36cd16SJim Ingham m_func_name_type_mask |= eFunctionNameTypeFull; 329ca36cd16SJim Ingham break; 330ca36cd16SJim Ingham 331b9c1b51eSKate Stone case 'h': { 332fab10e89SJim Ingham bool success; 33347cbf4a0SPavel Labath m_catch_bp = OptionArgParser::ToBoolean(option_arg, true, &success); 334fab10e89SJim Ingham if (!success) 335b9c1b51eSKate Stone error.SetErrorStringWithFormat( 336fe11483bSZachary Turner "Invalid boolean value for on-catch option: '%s'", 337fe11483bSZachary Turner option_arg.str().c_str()); 338b9c1b51eSKate Stone } break; 339eb023e75SGreg Clayton 340eb023e75SGreg Clayton case 'H': 341eb023e75SGreg Clayton m_hardware = true; 342eb023e75SGreg Clayton break; 343eb023e75SGreg Clayton 344b9c1b51eSKate Stone case 'K': { 345a8558b62SJim Ingham bool success; 346a8558b62SJim Ingham bool value; 34747cbf4a0SPavel Labath value = OptionArgParser::ToBoolean(option_arg, true, &success); 348a8558b62SJim Ingham if (value) 349a8558b62SJim Ingham m_skip_prologue = eLazyBoolYes; 350a8558b62SJim Ingham else 351a8558b62SJim Ingham m_skip_prologue = eLazyBoolNo; 352a8558b62SJim Ingham 353a8558b62SJim Ingham if (!success) 354b9c1b51eSKate Stone error.SetErrorStringWithFormat( 355b9c1b51eSKate Stone "Invalid boolean value for skip prologue option: '%s'", 356fe11483bSZachary Turner option_arg.str().c_str()); 357b9c1b51eSKate Stone } break; 358ca36cd16SJim Ingham 359fe11483bSZachary Turner case 'l': 360fe11483bSZachary Turner if (option_arg.getAsInteger(0, m_line_num)) 361b9c1b51eSKate Stone error.SetErrorStringWithFormat("invalid line number: %s.", 362fe11483bSZachary Turner option_arg.str().c_str()); 363ca36cd16SJim Ingham break; 364055ad9beSIlia K 36523b1decbSDawn Perchik case 'L': 366fe11483bSZachary Turner m_language = Language::GetLanguageTypeFromString(option_arg); 36723b1decbSDawn Perchik if (m_language == eLanguageTypeUnknown) 368b9c1b51eSKate Stone error.SetErrorStringWithFormat( 369fe11483bSZachary Turner "Unknown language type: '%s' for breakpoint", 370fe11483bSZachary Turner option_arg.str().c_str()); 37123b1decbSDawn Perchik break; 37223b1decbSDawn Perchik 373b9c1b51eSKate Stone case 'm': { 374055ad9beSIlia K bool success; 375055ad9beSIlia K bool value; 37647cbf4a0SPavel Labath value = OptionArgParser::ToBoolean(option_arg, true, &success); 377055ad9beSIlia K if (value) 378055ad9beSIlia K m_move_to_nearest_code = eLazyBoolYes; 379055ad9beSIlia K else 380055ad9beSIlia K m_move_to_nearest_code = eLazyBoolNo; 381055ad9beSIlia K 382055ad9beSIlia K if (!success) 383b9c1b51eSKate Stone error.SetErrorStringWithFormat( 384b9c1b51eSKate Stone "Invalid boolean value for move-to-nearest-code option: '%s'", 385fe11483bSZachary Turner option_arg.str().c_str()); 386055ad9beSIlia K break; 387055ad9beSIlia K } 388055ad9beSIlia K 389ca36cd16SJim Ingham case 'M': 390ca36cd16SJim Ingham m_func_names.push_back(option_arg); 391ca36cd16SJim Ingham m_func_name_type_mask |= eFunctionNameTypeMethod; 392ca36cd16SJim Ingham break; 393ca36cd16SJim Ingham 394ca36cd16SJim Ingham case 'n': 395ca36cd16SJim Ingham m_func_names.push_back(option_arg); 396ca36cd16SJim Ingham m_func_name_type_mask |= eFunctionNameTypeAuto; 397ca36cd16SJim Ingham break; 398ca36cd16SJim Ingham 3996fa7681bSZachary Turner case 'N': { 400fe11483bSZachary Turner if (BreakpointID::StringIsBreakpointName(option_arg, error)) 4015e09c8c3SJim Ingham m_breakpoint_names.push_back(option_arg); 402ff9a91eaSJim Ingham else 403ff9a91eaSJim Ingham error.SetErrorStringWithFormat("Invalid breakpoint name: %s", 404fe11483bSZachary Turner option_arg.str().c_str()); 4055e09c8c3SJim Ingham break; 4066fa7681bSZachary Turner } 4075e09c8c3SJim Ingham 408b9c1b51eSKate Stone case 'R': { 4092411167fSJim Ingham lldb::addr_t tmp_offset_addr; 41047cbf4a0SPavel Labath tmp_offset_addr = OptionArgParser::ToAddress(execution_context, 41147cbf4a0SPavel Labath option_arg, 0, &error); 4122411167fSJim Ingham if (error.Success()) 4132411167fSJim Ingham m_offset_addr = tmp_offset_addr; 414b9c1b51eSKate Stone } break; 4152411167fSJim Ingham 416a72b31c7SJim Ingham case 'O': 417fe11483bSZachary Turner m_exception_extra_args.AppendArgument("-O"); 418fe11483bSZachary Turner m_exception_extra_args.AppendArgument(option_arg); 419a72b31c7SJim Ingham break; 420a72b31c7SJim Ingham 421ca36cd16SJim Ingham case 'p': 422ca36cd16SJim Ingham m_source_text_regexp.assign(option_arg); 423ca36cd16SJim Ingham break; 424ca36cd16SJim Ingham 425ca36cd16SJim Ingham case 'r': 426ca36cd16SJim Ingham m_func_regexp.assign(option_arg); 427ca36cd16SJim Ingham break; 428ca36cd16SJim Ingham 429ca36cd16SJim Ingham case 's': 4308f3be7a3SJonas Devlieghere m_modules.AppendIfUnique(FileSpec(option_arg)); 431ca36cd16SJim Ingham break; 432ca36cd16SJim Ingham 433ca36cd16SJim Ingham case 'S': 434ca36cd16SJim Ingham m_func_names.push_back(option_arg); 435ca36cd16SJim Ingham m_func_name_type_mask |= eFunctionNameTypeSelector; 436ca36cd16SJim Ingham break; 437ca36cd16SJim Ingham 438b9c1b51eSKate Stone case 'w': { 439ca36cd16SJim Ingham bool success; 44047cbf4a0SPavel Labath m_throw_bp = OptionArgParser::ToBoolean(option_arg, true, &success); 441ca36cd16SJim Ingham if (!success) 442b9c1b51eSKate Stone error.SetErrorStringWithFormat( 443fe11483bSZachary Turner "Invalid boolean value for on-throw option: '%s'", 444fe11483bSZachary Turner option_arg.str().c_str()); 445b9c1b51eSKate Stone } break; 446ca36cd16SJim Ingham 44776bb8d67SJim Ingham case 'X': 44876bb8d67SJim Ingham m_source_regex_func_names.insert(option_arg); 44976bb8d67SJim Ingham break; 45076bb8d67SJim Ingham 45130fdc8d8SChris Lattner default: 45236162014SRaphael Isemann llvm_unreachable("Unimplemented option"); 45330fdc8d8SChris Lattner } 45430fdc8d8SChris Lattner 45530fdc8d8SChris Lattner return error; 45630fdc8d8SChris Lattner } 4579e85e5a8SEugene Zelenko 458b9c1b51eSKate Stone void OptionParsingStarting(ExecutionContext *execution_context) override { 45987df91b8SJim Ingham m_filenames.Clear(); 46030fdc8d8SChris Lattner m_line_num = 0; 46130fdc8d8SChris Lattner m_column = 0; 462fab10e89SJim Ingham m_func_names.clear(); 4631f746071SGreg Clayton m_func_name_type_mask = eFunctionNameTypeNone; 46430fdc8d8SChris Lattner m_func_regexp.clear(); 4651f746071SGreg Clayton m_source_text_regexp.clear(); 46687df91b8SJim Ingham m_modules.Clear(); 4671f746071SGreg Clayton m_load_addr = LLDB_INVALID_ADDRESS; 4682411167fSJim Ingham m_offset_addr = 0; 469fab10e89SJim Ingham m_catch_bp = false; 470fab10e89SJim Ingham m_throw_bp = true; 471eb023e75SGreg Clayton m_hardware = false; 472a72b31c7SJim Ingham m_exception_language = eLanguageTypeUnknown; 47323b1decbSDawn Perchik m_language = lldb::eLanguageTypeUnknown; 474a8558b62SJim Ingham m_skip_prologue = eLazyBoolCalculate; 4755e09c8c3SJim Ingham m_breakpoint_names.clear(); 476e732052fSJim Ingham m_all_files = false; 477a72b31c7SJim Ingham m_exception_extra_args.Clear(); 478055ad9beSIlia K m_move_to_nearest_code = eLazyBoolCalculate; 47976bb8d67SJim Ingham m_source_regex_func_names.clear(); 4803815e702SJim Ingham m_current_key.clear(); 48130fdc8d8SChris Lattner } 48230fdc8d8SChris Lattner 4831f0f5b5bSZachary Turner llvm::ArrayRef<OptionDefinition> GetDefinitions() override { 48470602439SZachary Turner return llvm::makeArrayRef(g_breakpoint_set_options); 4851f0f5b5bSZachary Turner } 48630fdc8d8SChris Lattner 4875a988416SJim Ingham // Instance variables to hold the values for command options. 488969795f1SJim Ingham 4895a988416SJim Ingham std::string m_condition; 4905a988416SJim Ingham FileSpecList m_filenames; 4915a988416SJim Ingham uint32_t m_line_num; 4925a988416SJim Ingham uint32_t m_column; 4935a988416SJim Ingham std::vector<std::string> m_func_names; 4945e09c8c3SJim Ingham std::vector<std::string> m_breakpoint_names; 495117b1fa1SZachary Turner lldb::FunctionNameType m_func_name_type_mask; 4965a988416SJim Ingham std::string m_func_regexp; 4975a988416SJim Ingham std::string m_source_text_regexp; 4985a988416SJim Ingham FileSpecList m_modules; 4995a988416SJim Ingham lldb::addr_t m_load_addr; 5002411167fSJim Ingham lldb::addr_t m_offset_addr; 5015a988416SJim Ingham bool m_catch_bp; 5025a988416SJim Ingham bool m_throw_bp; 503eb023e75SGreg Clayton bool m_hardware; // Request to use hardware breakpoints 504a72b31c7SJim Ingham lldb::LanguageType m_exception_language; 50523b1decbSDawn Perchik lldb::LanguageType m_language; 5065a988416SJim Ingham LazyBool m_skip_prologue; 507e732052fSJim Ingham bool m_all_files; 508a72b31c7SJim Ingham Args m_exception_extra_args; 509055ad9beSIlia K LazyBool m_move_to_nearest_code; 51076bb8d67SJim Ingham std::unordered_set<std::string> m_source_regex_func_names; 5113815e702SJim Ingham std::string m_current_key; 5125a988416SJim Ingham }; 5135a988416SJim Ingham 5145a988416SJim Ingham protected: 515b9c1b51eSKate Stone bool DoExecute(Args &command, CommandReturnObject &result) override { 516cb2380c9SRaphael Isemann Target &target = GetSelectedOrDummyTarget(m_dummy_options.m_use_dummy); 51730fdc8d8SChris Lattner 51830fdc8d8SChris Lattner // The following are the various types of breakpoints that could be set: 51930fdc8d8SChris Lattner // 1). -f -l -p [-s -g] (setting breakpoint by source location) 52030fdc8d8SChris Lattner // 2). -a [-s -g] (setting breakpoint by address) 52130fdc8d8SChris Lattner // 3). -n [-s -g] (setting breakpoint by function name) 522b9c1b51eSKate Stone // 4). -r [-s -g] (setting breakpoint by function name regular 523b9c1b51eSKate Stone // expression) 524b9c1b51eSKate Stone // 5). -p -f (setting a breakpoint by comparing a reg-exp 525b9c1b51eSKate Stone // to source text) 526b9c1b51eSKate Stone // 6). -E [-w -h] (setting a breakpoint for exceptions for a 527b9c1b51eSKate Stone // given language.) 52830fdc8d8SChris Lattner 52930fdc8d8SChris Lattner BreakpointSetType break_type = eSetTypeInvalid; 53030fdc8d8SChris Lattner 531738af7a6SJim Ingham if (!m_python_class_options.GetName().empty()) 5323815e702SJim Ingham break_type = eSetTypeScripted; 5333815e702SJim Ingham else if (m_options.m_line_num != 0) 53430fdc8d8SChris Lattner break_type = eSetTypeFileAndLine; 53530fdc8d8SChris Lattner else if (m_options.m_load_addr != LLDB_INVALID_ADDRESS) 53630fdc8d8SChris Lattner break_type = eSetTypeAddress; 537fab10e89SJim Ingham else if (!m_options.m_func_names.empty()) 53830fdc8d8SChris Lattner break_type = eSetTypeFunctionName; 53930fdc8d8SChris Lattner else if (!m_options.m_func_regexp.empty()) 54030fdc8d8SChris Lattner break_type = eSetTypeFunctionRegexp; 541969795f1SJim Ingham else if (!m_options.m_source_text_regexp.empty()) 542969795f1SJim Ingham break_type = eSetTypeSourceRegexp; 543a72b31c7SJim Ingham else if (m_options.m_exception_language != eLanguageTypeUnknown) 544fab10e89SJim Ingham break_type = eSetTypeException; 54530fdc8d8SChris Lattner 546b842f2ecSJim Ingham BreakpointSP bp_sp = nullptr; 547274060b6SGreg Clayton FileSpec module_spec; 548a8558b62SJim Ingham const bool internal = false; 549a8558b62SJim Ingham 550b9c1b51eSKate Stone // If the user didn't specify skip-prologue, having an offset should turn 551b9c1b51eSKate Stone // that off. 552b9c1b51eSKate Stone if (m_options.m_offset_addr != 0 && 553b9c1b51eSKate Stone m_options.m_skip_prologue == eLazyBoolCalculate) 5542411167fSJim Ingham m_options.m_skip_prologue = eLazyBoolNo; 5552411167fSJim Ingham 556b9c1b51eSKate Stone switch (break_type) { 55730fdc8d8SChris Lattner case eSetTypeFileAndLine: // Breakpoint by source position 55830fdc8d8SChris Lattner { 55930fdc8d8SChris Lattner FileSpec file; 560c7bece56SGreg Clayton const size_t num_files = m_options.m_filenames.GetSize(); 561b9c1b51eSKate Stone if (num_files == 0) { 562b9c1b51eSKate Stone if (!GetDefaultFile(target, file, result)) { 56387df91b8SJim Ingham result.AppendError("No file supplied and no default file available."); 56487df91b8SJim Ingham result.SetStatus(eReturnStatusFailed); 56587df91b8SJim Ingham return false; 56687df91b8SJim Ingham } 567b9c1b51eSKate Stone } else if (num_files > 1) { 568b9c1b51eSKate Stone result.AppendError("Only one file at a time is allowed for file and " 569b9c1b51eSKate Stone "line breakpoints."); 57087df91b8SJim Ingham result.SetStatus(eReturnStatusFailed); 57187df91b8SJim Ingham return false; 572b9c1b51eSKate Stone } else 57387df91b8SJim Ingham file = m_options.m_filenames.GetFileSpecAtIndex(0); 57430fdc8d8SChris Lattner 5751f746071SGreg Clayton // Only check for inline functions if 5761f746071SGreg Clayton LazyBool check_inlines = eLazyBoolCalculate; 5771f746071SGreg Clayton 578cb2380c9SRaphael Isemann bp_sp = target.CreateBreakpoint( 579cb2380c9SRaphael Isemann &(m_options.m_modules), file, m_options.m_line_num, 580cb2380c9SRaphael Isemann m_options.m_column, m_options.m_offset_addr, check_inlines, 581cb2380c9SRaphael Isemann m_options.m_skip_prologue, internal, m_options.m_hardware, 582b842f2ecSJim Ingham m_options.m_move_to_nearest_code); 583b9c1b51eSKate Stone } break; 5846eee5aa0SGreg Clayton 58530fdc8d8SChris Lattner case eSetTypeAddress: // Breakpoint by address 586055a08a4SJim Ingham { 587b9c1b51eSKate Stone // If a shared library has been specified, make an lldb_private::Address 588b842f2ecSJim Ingham // with the library, and use that. That way the address breakpoint 589b842f2ecSJim Ingham // will track the load location of the library. 590055a08a4SJim Ingham size_t num_modules_specified = m_options.m_modules.GetSize(); 591b9c1b51eSKate Stone if (num_modules_specified == 1) { 592b9c1b51eSKate Stone const FileSpec *file_spec = 593b9c1b51eSKate Stone m_options.m_modules.GetFileSpecPointerAtIndex(0); 594cb2380c9SRaphael Isemann bp_sp = target.CreateAddressInModuleBreakpoint( 595cb2380c9SRaphael Isemann m_options.m_load_addr, internal, file_spec, m_options.m_hardware); 596b9c1b51eSKate Stone } else if (num_modules_specified == 0) { 597cb2380c9SRaphael Isemann bp_sp = target.CreateBreakpoint(m_options.m_load_addr, internal, 598b842f2ecSJim Ingham m_options.m_hardware); 599b9c1b51eSKate Stone } else { 600b9c1b51eSKate Stone result.AppendError("Only one shared library can be specified for " 601b9c1b51eSKate Stone "address breakpoints."); 602055a08a4SJim Ingham result.SetStatus(eReturnStatusFailed); 603055a08a4SJim Ingham return false; 604055a08a4SJim Ingham } 60530fdc8d8SChris Lattner break; 606055a08a4SJim Ingham } 60730fdc8d8SChris Lattner case eSetTypeFunctionName: // Breakpoint by function name 6080c5cd90dSGreg Clayton { 609117b1fa1SZachary Turner FunctionNameType name_type_mask = m_options.m_func_name_type_mask; 6100c5cd90dSGreg Clayton 6110c5cd90dSGreg Clayton if (name_type_mask == 0) 612e02b8504SGreg Clayton name_type_mask = eFunctionNameTypeAuto; 6130c5cd90dSGreg Clayton 614cb2380c9SRaphael Isemann bp_sp = target.CreateBreakpoint( 615cb2380c9SRaphael Isemann &(m_options.m_modules), &(m_options.m_filenames), 616cb2380c9SRaphael Isemann m_options.m_func_names, name_type_mask, m_options.m_language, 617cb2380c9SRaphael Isemann m_options.m_offset_addr, m_options.m_skip_prologue, internal, 618b842f2ecSJim Ingham m_options.m_hardware); 619b9c1b51eSKate Stone } break; 6200c5cd90dSGreg Clayton 621b9c1b51eSKate Stone case eSetTypeFunctionRegexp: // Breakpoint by regular expression function 622b9c1b51eSKate Stone // name 62330fdc8d8SChris Lattner { 62495eae423SZachary Turner RegularExpression regexp(m_options.m_func_regexp); 6253af3f1e8SJonas Devlieghere if (llvm::Error err = regexp.GetError()) { 626b9c1b51eSKate Stone result.AppendErrorWithFormat( 627b9c1b51eSKate Stone "Function name regular expression could not be compiled: \"%s\"", 6283af3f1e8SJonas Devlieghere llvm::toString(std::move(err)).c_str()); 62930fdc8d8SChris Lattner result.SetStatus(eReturnStatusFailed); 630969795f1SJim Ingham return false; 63130fdc8d8SChris Lattner } 63287df91b8SJim Ingham 633cb2380c9SRaphael Isemann bp_sp = target.CreateFuncRegexBreakpoint( 6345aa1d819SJan Kratochvil &(m_options.m_modules), &(m_options.m_filenames), std::move(regexp), 635cb2380c9SRaphael Isemann m_options.m_language, m_options.m_skip_prologue, internal, 636b842f2ecSJim Ingham m_options.m_hardware); 637*a925974bSAdrian Prantl } break; 638969795f1SJim Ingham case eSetTypeSourceRegexp: // Breakpoint by regexp on source text. 639969795f1SJim Ingham { 640c7bece56SGreg Clayton const size_t num_files = m_options.m_filenames.GetSize(); 64187df91b8SJim Ingham 642b9c1b51eSKate Stone if (num_files == 0 && !m_options.m_all_files) { 643969795f1SJim Ingham FileSpec file; 644b9c1b51eSKate Stone if (!GetDefaultFile(target, file, result)) { 645b9c1b51eSKate Stone result.AppendError( 646b9c1b51eSKate Stone "No files provided and could not find default file."); 64787df91b8SJim Ingham result.SetStatus(eReturnStatusFailed); 64887df91b8SJim Ingham return false; 649b9c1b51eSKate Stone } else { 65087df91b8SJim Ingham m_options.m_filenames.Append(file); 65187df91b8SJim Ingham } 65287df91b8SJim Ingham } 6530c5cd90dSGreg Clayton 65495eae423SZachary Turner RegularExpression regexp(m_options.m_source_text_regexp); 6553af3f1e8SJonas Devlieghere if (llvm::Error err = regexp.GetError()) { 656b9c1b51eSKate Stone result.AppendErrorWithFormat( 657b9c1b51eSKate Stone "Source text regular expression could not be compiled: \"%s\"", 6583af3f1e8SJonas Devlieghere llvm::toString(std::move(err)).c_str()); 659969795f1SJim Ingham result.SetStatus(eReturnStatusFailed); 660969795f1SJim Ingham return false; 661969795f1SJim Ingham } 662cb2380c9SRaphael Isemann bp_sp = target.CreateSourceRegexBreakpoint( 663cb2380c9SRaphael Isemann &(m_options.m_modules), &(m_options.m_filenames), 6645aa1d819SJan Kratochvil m_options.m_source_regex_func_names, std::move(regexp), internal, 665cb2380c9SRaphael Isemann m_options.m_hardware, m_options.m_move_to_nearest_code); 666b9c1b51eSKate Stone } break; 667b9c1b51eSKate Stone case eSetTypeException: { 66897206d57SZachary Turner Status precond_error; 669cb2380c9SRaphael Isemann bp_sp = target.CreateExceptionBreakpoint( 670cb2380c9SRaphael Isemann m_options.m_exception_language, m_options.m_catch_bp, 671cb2380c9SRaphael Isemann m_options.m_throw_bp, internal, &m_options.m_exception_extra_args, 672b842f2ecSJim Ingham &precond_error); 673b9c1b51eSKate Stone if (precond_error.Fail()) { 674b9c1b51eSKate Stone result.AppendErrorWithFormat( 675b9c1b51eSKate Stone "Error setting extra exception arguments: %s", 676a72b31c7SJim Ingham precond_error.AsCString()); 677cb2380c9SRaphael Isemann target.RemoveBreakpointByID(bp_sp->GetID()); 678a72b31c7SJim Ingham result.SetStatus(eReturnStatusFailed); 679a72b31c7SJim Ingham return false; 680a72b31c7SJim Ingham } 681b9c1b51eSKate Stone } break; 6823815e702SJim Ingham case eSetTypeScripted: { 6833815e702SJim Ingham 6843815e702SJim Ingham Status error; 685cb2380c9SRaphael Isemann bp_sp = target.CreateScriptedBreakpoint( 686738af7a6SJim Ingham m_python_class_options.GetName().c_str(), &(m_options.m_modules), 687cb2380c9SRaphael Isemann &(m_options.m_filenames), false, m_options.m_hardware, 688943a2481SJim Ingham m_python_class_options.GetStructuredData(), &error); 6893815e702SJim Ingham if (error.Fail()) { 6903815e702SJim Ingham result.AppendErrorWithFormat( 691*a925974bSAdrian Prantl "Error setting extra exception arguments: %s", error.AsCString()); 692cb2380c9SRaphael Isemann target.RemoveBreakpointByID(bp_sp->GetID()); 6933815e702SJim Ingham result.SetStatus(eReturnStatusFailed); 6943815e702SJim Ingham return false; 6953815e702SJim Ingham } 6963815e702SJim Ingham } break; 69730fdc8d8SChris Lattner default: 69830fdc8d8SChris Lattner break; 69930fdc8d8SChris Lattner } 70030fdc8d8SChris Lattner 7011b54c88cSJim Ingham // Now set the various options that were passed in: 702b842f2ecSJim Ingham if (bp_sp) { 703b842f2ecSJim Ingham bp_sp->GetOptions()->CopyOverSetOptions(m_bp_opts.GetBreakpointOptions()); 704ca36cd16SJim Ingham 705b9c1b51eSKate Stone if (!m_options.m_breakpoint_names.empty()) { 70697206d57SZachary Turner Status name_error; 707ff9a91eaSJim Ingham for (auto name : m_options.m_breakpoint_names) { 708cb2380c9SRaphael Isemann target.AddNameToBreakpoint(bp_sp, name.c_str(), name_error); 709ff9a91eaSJim Ingham if (name_error.Fail()) { 710ff9a91eaSJim Ingham result.AppendErrorWithFormat("Invalid breakpoint name: %s", 711ff9a91eaSJim Ingham name.c_str()); 712cb2380c9SRaphael Isemann target.RemoveBreakpointByID(bp_sp->GetID()); 713ff9a91eaSJim Ingham result.SetStatus(eReturnStatusFailed); 714ff9a91eaSJim Ingham return false; 715ff9a91eaSJim Ingham } 716ff9a91eaSJim Ingham } 7175e09c8c3SJim Ingham } 7181b54c88cSJim Ingham } 7191b54c88cSJim Ingham 720b842f2ecSJim Ingham if (bp_sp) { 72185e8b814SJim Ingham Stream &output_stream = result.GetOutputStream(); 7221391cc7dSJim Ingham const bool show_locations = false; 723b842f2ecSJim Ingham bp_sp->GetDescription(&output_stream, lldb::eDescriptionLevelInitial, 724b9c1b51eSKate Stone show_locations); 725cb2380c9SRaphael Isemann if (&target == &GetDummyTarget()) 726b9c1b51eSKate Stone output_stream.Printf("Breakpoint set in dummy target, will get copied " 727b9c1b51eSKate Stone "into future targets.\n"); 728b9c1b51eSKate Stone else { 72905097246SAdrian Prantl // Don't print out this warning for exception breakpoints. They can 73005097246SAdrian Prantl // get set before the target is set, but we won't know how to actually 73105097246SAdrian Prantl // set the breakpoint till we run. 732b842f2ecSJim Ingham if (bp_sp->GetNumLocations() == 0 && break_type != eSetTypeException) { 733b9c1b51eSKate Stone output_stream.Printf("WARNING: Unable to resolve breakpoint to any " 734b9c1b51eSKate Stone "actual locations.\n"); 7354aeb1989SJim Ingham } 7364aeb1989SJim Ingham } 73730fdc8d8SChris Lattner result.SetStatus(eReturnStatusSuccessFinishResult); 738b842f2ecSJim Ingham } else if (!bp_sp) { 73930fdc8d8SChris Lattner result.AppendError("Breakpoint creation failed: No breakpoint created."); 74030fdc8d8SChris Lattner result.SetStatus(eReturnStatusFailed); 74130fdc8d8SChris Lattner } 74230fdc8d8SChris Lattner 74330fdc8d8SChris Lattner return result.Succeeded(); 74430fdc8d8SChris Lattner } 74530fdc8d8SChris Lattner 7465a988416SJim Ingham private: 747cb2380c9SRaphael Isemann bool GetDefaultFile(Target &target, FileSpec &file, 748b9c1b51eSKate Stone CommandReturnObject &result) { 7495a988416SJim Ingham uint32_t default_line; 75005097246SAdrian Prantl // First use the Source Manager's default file. Then use the current stack 75105097246SAdrian Prantl // frame's file. 752cb2380c9SRaphael Isemann if (!target.GetSourceManager().GetDefaultFileAndLine(file, default_line)) { 753b57e4a1bSJason Molenda StackFrame *cur_frame = m_exe_ctx.GetFramePtr(); 754b9c1b51eSKate Stone if (cur_frame == nullptr) { 755b9c1b51eSKate Stone result.AppendError( 756b9c1b51eSKate Stone "No selected frame to use to find the default file."); 7575a988416SJim Ingham result.SetStatus(eReturnStatusFailed); 7585a988416SJim Ingham return false; 759b9c1b51eSKate Stone } else if (!cur_frame->HasDebugInformation()) { 760b9c1b51eSKate Stone result.AppendError("Cannot use the selected frame to find the default " 761b9c1b51eSKate Stone "file, it has no debug info."); 7625a988416SJim Ingham result.SetStatus(eReturnStatusFailed); 7635a988416SJim Ingham return false; 764b9c1b51eSKate Stone } else { 765b9c1b51eSKate Stone const SymbolContext &sc = 766b9c1b51eSKate Stone cur_frame->GetSymbolContext(eSymbolContextLineEntry); 767b9c1b51eSKate Stone if (sc.line_entry.file) { 7685a988416SJim Ingham file = sc.line_entry.file; 769b9c1b51eSKate Stone } else { 770b9c1b51eSKate Stone result.AppendError("Can't find the file for the selected frame to " 771b9c1b51eSKate Stone "use as the default file."); 7725a988416SJim Ingham result.SetStatus(eReturnStatusFailed); 7735a988416SJim Ingham return false; 7745a988416SJim Ingham } 7755a988416SJim Ingham } 7765a988416SJim Ingham } 7775a988416SJim Ingham return true; 7785a988416SJim Ingham } 7795a988416SJim Ingham 780b842f2ecSJim Ingham BreakpointOptionGroup m_bp_opts; 781b842f2ecSJim Ingham BreakpointDummyOptionGroup m_dummy_options; 782943a2481SJim Ingham OptionGroupPythonClassWithDict m_python_class_options; 7835a988416SJim Ingham CommandOptions m_options; 784b842f2ecSJim Ingham OptionGroupOptions m_all_options; 7855a988416SJim Ingham }; 7869e85e5a8SEugene Zelenko 7875a988416SJim Ingham // CommandObjectBreakpointModify 7885a988416SJim Ingham #pragma mark Modify 7895a988416SJim Ingham 790b9c1b51eSKate Stone class CommandObjectBreakpointModify : public CommandObjectParsed { 7915a988416SJim Ingham public: 792b9c1b51eSKate Stone CommandObjectBreakpointModify(CommandInterpreter &interpreter) 793b9c1b51eSKate Stone : CommandObjectParsed(interpreter, "breakpoint modify", 794b9c1b51eSKate Stone "Modify the options on a breakpoint or set of " 795b9c1b51eSKate Stone "breakpoints in the executable. " 796b9c1b51eSKate Stone "If no breakpoint is specified, acts on the last " 797b9c1b51eSKate Stone "created breakpoint. " 798b9c1b51eSKate Stone "With the exception of -e, -d and -i, passing an " 799b9c1b51eSKate Stone "empty argument clears the modification.", 8009e85e5a8SEugene Zelenko nullptr), 801b9c1b51eSKate Stone m_options() { 8025a988416SJim Ingham CommandArgumentEntry arg; 803b9c1b51eSKate Stone CommandObject::AddIDsArgumentData(arg, eArgTypeBreakpointID, 804b9c1b51eSKate Stone eArgTypeBreakpointIDRange); 805b9c1b51eSKate Stone // Add the entry for the first argument for this command to the object's 806b9c1b51eSKate Stone // arguments vector. 8075a988416SJim Ingham m_arguments.push_back(arg); 808b842f2ecSJim Ingham 809b842f2ecSJim Ingham m_options.Append(&m_bp_opts, 810b842f2ecSJim Ingham LLDB_OPT_SET_1 | LLDB_OPT_SET_2 | LLDB_OPT_SET_3, 811b842f2ecSJim Ingham LLDB_OPT_SET_ALL); 812b842f2ecSJim Ingham m_options.Append(&m_dummy_opts, LLDB_OPT_SET_1, LLDB_OPT_SET_ALL); 813b842f2ecSJim Ingham m_options.Finalize(); 8145a988416SJim Ingham } 8155a988416SJim Ingham 8169e85e5a8SEugene Zelenko ~CommandObjectBreakpointModify() override = default; 8175a988416SJim Ingham 818b9c1b51eSKate Stone Options *GetOptions() override { return &m_options; } 8195a988416SJim Ingham 8205a988416SJim Ingham protected: 821b9c1b51eSKate Stone bool DoExecute(Args &command, CommandReturnObject &result) override { 822cb2380c9SRaphael Isemann Target &target = GetSelectedOrDummyTarget(m_dummy_opts.m_use_dummy); 8235a988416SJim Ingham 824bb19a13cSSaleem Abdulrasool std::unique_lock<std::recursive_mutex> lock; 825cb2380c9SRaphael Isemann target.GetBreakpointList().GetListMutex(lock); 8265a988416SJim Ingham 8275a988416SJim Ingham BreakpointIDList valid_bp_ids; 8285a988416SJim Ingham 829b9c1b51eSKate Stone CommandObjectMultiwordBreakpoint::VerifyBreakpointOrLocationIDs( 830cb2380c9SRaphael Isemann command, &target, result, &valid_bp_ids, 831b842f2ecSJim Ingham BreakpointName::Permissions::PermissionKinds::disablePerm); 8325a988416SJim Ingham 833b9c1b51eSKate Stone if (result.Succeeded()) { 8345a988416SJim Ingham const size_t count = valid_bp_ids.GetSize(); 835b9c1b51eSKate Stone for (size_t i = 0; i < count; ++i) { 8365a988416SJim Ingham BreakpointID cur_bp_id = valid_bp_ids.GetBreakpointIDAtIndex(i); 8375a988416SJim Ingham 838b9c1b51eSKate Stone if (cur_bp_id.GetBreakpointID() != LLDB_INVALID_BREAK_ID) { 839b9c1b51eSKate Stone Breakpoint *bp = 840cb2380c9SRaphael Isemann target.GetBreakpointByID(cur_bp_id.GetBreakpointID()).get(); 841b9c1b51eSKate Stone if (cur_bp_id.GetLocationID() != LLDB_INVALID_BREAK_ID) { 842b9c1b51eSKate Stone BreakpointLocation *location = 843b9c1b51eSKate Stone bp->FindLocationByID(cur_bp_id.GetLocationID()).get(); 844b842f2ecSJim Ingham if (location) 845*a925974bSAdrian Prantl location->GetLocationOptions()->CopyOverSetOptions( 846*a925974bSAdrian Prantl m_bp_opts.GetBreakpointOptions()); 847b9c1b51eSKate Stone } else { 848*a925974bSAdrian Prantl bp->GetOptions()->CopyOverSetOptions( 849*a925974bSAdrian Prantl m_bp_opts.GetBreakpointOptions()); 8505a988416SJim Ingham } 8515a988416SJim Ingham } 8525a988416SJim Ingham } 8535a988416SJim Ingham } 8545a988416SJim Ingham 8555a988416SJim Ingham return result.Succeeded(); 8565a988416SJim Ingham } 8575a988416SJim Ingham 8585a988416SJim Ingham private: 859b842f2ecSJim Ingham BreakpointOptionGroup m_bp_opts; 860b842f2ecSJim Ingham BreakpointDummyOptionGroup m_dummy_opts; 861b842f2ecSJim Ingham OptionGroupOptions m_options; 8625a988416SJim Ingham }; 8635a988416SJim Ingham 8645a988416SJim Ingham // CommandObjectBreakpointEnable 8655a988416SJim Ingham #pragma mark Enable 8665a988416SJim Ingham 867b9c1b51eSKate Stone class CommandObjectBreakpointEnable : public CommandObjectParsed { 8685a988416SJim Ingham public: 869b9c1b51eSKate Stone CommandObjectBreakpointEnable(CommandInterpreter &interpreter) 870b9c1b51eSKate Stone : CommandObjectParsed(interpreter, "enable", 871b9c1b51eSKate Stone "Enable the specified disabled breakpoint(s). If " 872b9c1b51eSKate Stone "no breakpoints are specified, enable all of them.", 873b9c1b51eSKate Stone nullptr) { 8745a988416SJim Ingham CommandArgumentEntry arg; 875b9c1b51eSKate Stone CommandObject::AddIDsArgumentData(arg, eArgTypeBreakpointID, 876b9c1b51eSKate Stone eArgTypeBreakpointIDRange); 877b9c1b51eSKate Stone // Add the entry for the first argument for this command to the object's 878b9c1b51eSKate Stone // arguments vector. 8795a988416SJim Ingham m_arguments.push_back(arg); 8805a988416SJim Ingham } 8815a988416SJim Ingham 8829e85e5a8SEugene Zelenko ~CommandObjectBreakpointEnable() override = default; 8835a988416SJim Ingham 8845a988416SJim Ingham protected: 885b9c1b51eSKate Stone bool DoExecute(Args &command, CommandReturnObject &result) override { 886cb2380c9SRaphael Isemann Target &target = GetSelectedOrDummyTarget(); 8875a988416SJim Ingham 888bb19a13cSSaleem Abdulrasool std::unique_lock<std::recursive_mutex> lock; 889cb2380c9SRaphael Isemann target.GetBreakpointList().GetListMutex(lock); 8905a988416SJim Ingham 891cb2380c9SRaphael Isemann const BreakpointList &breakpoints = target.GetBreakpointList(); 8925a988416SJim Ingham 8935a988416SJim Ingham size_t num_breakpoints = breakpoints.GetSize(); 8945a988416SJim Ingham 895b9c1b51eSKate Stone if (num_breakpoints == 0) { 8965a988416SJim Ingham result.AppendError("No breakpoints exist to be enabled."); 8975a988416SJim Ingham result.SetStatus(eReturnStatusFailed); 8985a988416SJim Ingham return false; 8995a988416SJim Ingham } 9005a988416SJim Ingham 90111eb9c64SZachary Turner if (command.empty()) { 9025a988416SJim Ingham // No breakpoint selected; enable all currently set breakpoints. 903cb2380c9SRaphael Isemann target.EnableAllowedBreakpoints(); 904b9c1b51eSKate Stone result.AppendMessageWithFormat("All breakpoints enabled. (%" PRIu64 905b9c1b51eSKate Stone " breakpoints)\n", 906b9c1b51eSKate Stone (uint64_t)num_breakpoints); 9075a988416SJim Ingham result.SetStatus(eReturnStatusSuccessFinishNoResult); 908b9c1b51eSKate Stone } else { 9095a988416SJim Ingham // Particular breakpoint selected; enable that breakpoint. 9105a988416SJim Ingham BreakpointIDList valid_bp_ids; 911b9c1b51eSKate Stone CommandObjectMultiwordBreakpoint::VerifyBreakpointOrLocationIDs( 912cb2380c9SRaphael Isemann command, &target, result, &valid_bp_ids, 913b842f2ecSJim Ingham BreakpointName::Permissions::PermissionKinds::disablePerm); 9145a988416SJim Ingham 915b9c1b51eSKate Stone if (result.Succeeded()) { 9165a988416SJim Ingham int enable_count = 0; 9175a988416SJim Ingham int loc_count = 0; 9185a988416SJim Ingham const size_t count = valid_bp_ids.GetSize(); 919b9c1b51eSKate Stone for (size_t i = 0; i < count; ++i) { 9205a988416SJim Ingham BreakpointID cur_bp_id = valid_bp_ids.GetBreakpointIDAtIndex(i); 9215a988416SJim Ingham 922b9c1b51eSKate Stone if (cur_bp_id.GetBreakpointID() != LLDB_INVALID_BREAK_ID) { 923b9c1b51eSKate Stone Breakpoint *breakpoint = 924cb2380c9SRaphael Isemann target.GetBreakpointByID(cur_bp_id.GetBreakpointID()).get(); 925b9c1b51eSKate Stone if (cur_bp_id.GetLocationID() != LLDB_INVALID_BREAK_ID) { 926b9c1b51eSKate Stone BreakpointLocation *location = 927b9c1b51eSKate Stone breakpoint->FindLocationByID(cur_bp_id.GetLocationID()).get(); 928b9c1b51eSKate Stone if (location) { 9295a988416SJim Ingham location->SetEnabled(true); 9305a988416SJim Ingham ++loc_count; 9315a988416SJim Ingham } 932b9c1b51eSKate Stone } else { 9335a988416SJim Ingham breakpoint->SetEnabled(true); 9345a988416SJim Ingham ++enable_count; 9355a988416SJim Ingham } 9365a988416SJim Ingham } 9375a988416SJim Ingham } 938b9c1b51eSKate Stone result.AppendMessageWithFormat("%d breakpoints enabled.\n", 939b9c1b51eSKate Stone enable_count + loc_count); 9405a988416SJim Ingham result.SetStatus(eReturnStatusSuccessFinishNoResult); 9415a988416SJim Ingham } 9425a988416SJim Ingham } 9435a988416SJim Ingham 9445a988416SJim Ingham return result.Succeeded(); 9455a988416SJim Ingham } 9465a988416SJim Ingham }; 9475a988416SJim Ingham 9485a988416SJim Ingham // CommandObjectBreakpointDisable 9495a988416SJim Ingham #pragma mark Disable 9505a988416SJim Ingham 951b9c1b51eSKate Stone class CommandObjectBreakpointDisable : public CommandObjectParsed { 9525a988416SJim Ingham public: 9537428a18cSKate Stone CommandObjectBreakpointDisable(CommandInterpreter &interpreter) 954b9c1b51eSKate Stone : CommandObjectParsed( 955b9c1b51eSKate Stone interpreter, "breakpoint disable", 956b9c1b51eSKate Stone "Disable the specified breakpoint(s) without deleting " 9577428a18cSKate Stone "them. If none are specified, disable all " 9587428a18cSKate Stone "breakpoints.", 959b9c1b51eSKate Stone nullptr) { 960b9c1b51eSKate Stone SetHelpLong( 961b9c1b51eSKate Stone "Disable the specified breakpoint(s) without deleting them. \ 9627428a18cSKate Stone If none are specified, disable all breakpoints." 9637428a18cSKate Stone R"( 964ea671fbdSKate Stone 9657428a18cSKate Stone )" 9667428a18cSKate Stone "Note: disabling a breakpoint will cause none of its locations to be hit \ 9677428a18cSKate Stone regardless of whether individual locations are enabled or disabled. After the sequence:" 9687428a18cSKate Stone R"( 969ea671fbdSKate Stone 970ea671fbdSKate Stone (lldb) break disable 1 971ea671fbdSKate Stone (lldb) break enable 1.1 972ea671fbdSKate Stone 973ea671fbdSKate Stone execution will NOT stop at location 1.1. To achieve that, type: 974ea671fbdSKate Stone 975ea671fbdSKate Stone (lldb) break disable 1.* 976ea671fbdSKate Stone (lldb) break enable 1.1 977ea671fbdSKate Stone 9787428a18cSKate Stone )" 9797428a18cSKate Stone "The first command disables all locations for breakpoint 1, \ 9807428a18cSKate Stone the second re-enables the first location."); 981b0fac509SJim Ingham 9825a988416SJim Ingham CommandArgumentEntry arg; 983b9c1b51eSKate Stone CommandObject::AddIDsArgumentData(arg, eArgTypeBreakpointID, 984b9c1b51eSKate Stone eArgTypeBreakpointIDRange); 985b9c1b51eSKate Stone // Add the entry for the first argument for this command to the object's 986b9c1b51eSKate Stone // arguments vector. 9875a988416SJim Ingham m_arguments.push_back(arg); 9885a988416SJim Ingham } 9895a988416SJim Ingham 9909e85e5a8SEugene Zelenko ~CommandObjectBreakpointDisable() override = default; 9915a988416SJim Ingham 9925a988416SJim Ingham protected: 993b9c1b51eSKate Stone bool DoExecute(Args &command, CommandReturnObject &result) override { 994cb2380c9SRaphael Isemann Target &target = GetSelectedOrDummyTarget(); 995bb19a13cSSaleem Abdulrasool std::unique_lock<std::recursive_mutex> lock; 996cb2380c9SRaphael Isemann target.GetBreakpointList().GetListMutex(lock); 9975a988416SJim Ingham 998cb2380c9SRaphael Isemann const BreakpointList &breakpoints = target.GetBreakpointList(); 9995a988416SJim Ingham size_t num_breakpoints = breakpoints.GetSize(); 10005a988416SJim Ingham 1001b9c1b51eSKate Stone if (num_breakpoints == 0) { 10025a988416SJim Ingham result.AppendError("No breakpoints exist to be disabled."); 10035a988416SJim Ingham result.SetStatus(eReturnStatusFailed); 10045a988416SJim Ingham return false; 10055a988416SJim Ingham } 10065a988416SJim Ingham 100711eb9c64SZachary Turner if (command.empty()) { 10085a988416SJim Ingham // No breakpoint selected; disable all currently set breakpoints. 1009cb2380c9SRaphael Isemann target.DisableAllowedBreakpoints(); 1010b9c1b51eSKate Stone result.AppendMessageWithFormat("All breakpoints disabled. (%" PRIu64 1011b9c1b51eSKate Stone " breakpoints)\n", 1012b9c1b51eSKate Stone (uint64_t)num_breakpoints); 10135a988416SJim Ingham result.SetStatus(eReturnStatusSuccessFinishNoResult); 1014b9c1b51eSKate Stone } else { 10155a988416SJim Ingham // Particular breakpoint selected; disable that breakpoint. 10165a988416SJim Ingham BreakpointIDList valid_bp_ids; 10175a988416SJim Ingham 1018b9c1b51eSKate Stone CommandObjectMultiwordBreakpoint::VerifyBreakpointOrLocationIDs( 1019cb2380c9SRaphael Isemann command, &target, result, &valid_bp_ids, 1020b842f2ecSJim Ingham BreakpointName::Permissions::PermissionKinds::disablePerm); 10215a988416SJim Ingham 1022b9c1b51eSKate Stone if (result.Succeeded()) { 10235a988416SJim Ingham int disable_count = 0; 10245a988416SJim Ingham int loc_count = 0; 10255a988416SJim Ingham const size_t count = valid_bp_ids.GetSize(); 1026b9c1b51eSKate Stone for (size_t i = 0; i < count; ++i) { 10275a988416SJim Ingham BreakpointID cur_bp_id = valid_bp_ids.GetBreakpointIDAtIndex(i); 10285a988416SJim Ingham 1029b9c1b51eSKate Stone if (cur_bp_id.GetBreakpointID() != LLDB_INVALID_BREAK_ID) { 1030b9c1b51eSKate Stone Breakpoint *breakpoint = 1031cb2380c9SRaphael Isemann target.GetBreakpointByID(cur_bp_id.GetBreakpointID()).get(); 1032b9c1b51eSKate Stone if (cur_bp_id.GetLocationID() != LLDB_INVALID_BREAK_ID) { 1033b9c1b51eSKate Stone BreakpointLocation *location = 1034b9c1b51eSKate Stone breakpoint->FindLocationByID(cur_bp_id.GetLocationID()).get(); 1035b9c1b51eSKate Stone if (location) { 10365a988416SJim Ingham location->SetEnabled(false); 10375a988416SJim Ingham ++loc_count; 10385a988416SJim Ingham } 1039b9c1b51eSKate Stone } else { 10405a988416SJim Ingham breakpoint->SetEnabled(false); 10415a988416SJim Ingham ++disable_count; 10425a988416SJim Ingham } 10435a988416SJim Ingham } 10445a988416SJim Ingham } 1045b9c1b51eSKate Stone result.AppendMessageWithFormat("%d breakpoints disabled.\n", 1046b9c1b51eSKate Stone disable_count + loc_count); 10475a988416SJim Ingham result.SetStatus(eReturnStatusSuccessFinishNoResult); 10485a988416SJim Ingham } 10495a988416SJim Ingham } 10505a988416SJim Ingham 10515a988416SJim Ingham return result.Succeeded(); 10525a988416SJim Ingham } 10535a988416SJim Ingham }; 10545a988416SJim Ingham 10555a988416SJim Ingham // CommandObjectBreakpointList 10561f0f5b5bSZachary Turner 10571f0f5b5bSZachary Turner #pragma mark List::CommandOptions 10586f4fb4e7SRaphael Isemann #define LLDB_OPTIONS_breakpoint_list 1059c5a2d747SRaphael Isemann #include "CommandOptions.inc" 10601f0f5b5bSZachary Turner 10615a988416SJim Ingham #pragma mark List 10625a988416SJim Ingham 1063b9c1b51eSKate Stone class CommandObjectBreakpointList : public CommandObjectParsed { 10645a988416SJim Ingham public: 1065b9c1b51eSKate Stone CommandObjectBreakpointList(CommandInterpreter &interpreter) 1066b9c1b51eSKate Stone : CommandObjectParsed( 1067b9c1b51eSKate Stone interpreter, "breakpoint list", 10685a988416SJim Ingham "List some or all breakpoints at configurable levels of detail.", 10699e85e5a8SEugene Zelenko nullptr), 1070b9c1b51eSKate Stone m_options() { 10715a988416SJim Ingham CommandArgumentEntry arg; 10725a988416SJim Ingham CommandArgumentData bp_id_arg; 10735a988416SJim Ingham 10745a988416SJim Ingham // Define the first (and only) variant of this arg. 10755a988416SJim Ingham bp_id_arg.arg_type = eArgTypeBreakpointID; 10765a988416SJim Ingham bp_id_arg.arg_repetition = eArgRepeatOptional; 10775a988416SJim Ingham 1078b9c1b51eSKate Stone // There is only one variant this argument could be; put it into the 1079b9c1b51eSKate Stone // argument entry. 10805a988416SJim Ingham arg.push_back(bp_id_arg); 10815a988416SJim Ingham 10825a988416SJim Ingham // Push the data for the first argument into the m_arguments vector. 10835a988416SJim Ingham m_arguments.push_back(arg); 10845a988416SJim Ingham } 10855a988416SJim Ingham 10869e85e5a8SEugene Zelenko ~CommandObjectBreakpointList() override = default; 10875a988416SJim Ingham 1088b9c1b51eSKate Stone Options *GetOptions() override { return &m_options; } 10895a988416SJim Ingham 1090b9c1b51eSKate Stone class CommandOptions : public Options { 10915a988416SJim Ingham public: 1092b9c1b51eSKate Stone CommandOptions() 1093b9c1b51eSKate Stone : Options(), m_level(lldb::eDescriptionLevelBrief), m_use_dummy(false) { 10945a988416SJim Ingham } 10955a988416SJim Ingham 10969e85e5a8SEugene Zelenko ~CommandOptions() override = default; 10975a988416SJim Ingham 109897206d57SZachary Turner Status SetOptionValue(uint32_t option_idx, llvm::StringRef option_arg, 1099b9c1b51eSKate Stone ExecutionContext *execution_context) override { 110097206d57SZachary Turner Status error; 11013bcdfc0eSGreg Clayton const int short_option = m_getopt_table[option_idx].val; 11025a988416SJim Ingham 1103b9c1b51eSKate Stone switch (short_option) { 11045a988416SJim Ingham case 'b': 11055a988416SJim Ingham m_level = lldb::eDescriptionLevelBrief; 11065a988416SJim Ingham break; 110733df7cd3SJim Ingham case 'D': 110833df7cd3SJim Ingham m_use_dummy = true; 110933df7cd3SJim Ingham break; 11105a988416SJim Ingham case 'f': 11115a988416SJim Ingham m_level = lldb::eDescriptionLevelFull; 11125a988416SJim Ingham break; 11135a988416SJim Ingham case 'v': 11145a988416SJim Ingham m_level = lldb::eDescriptionLevelVerbose; 11155a988416SJim Ingham break; 11165a988416SJim Ingham case 'i': 11175a988416SJim Ingham m_internal = true; 11185a988416SJim Ingham break; 11195a988416SJim Ingham default: 112036162014SRaphael Isemann llvm_unreachable("Unimplemented option"); 11215a988416SJim Ingham } 11225a988416SJim Ingham 11235a988416SJim Ingham return error; 11245a988416SJim Ingham } 11255a988416SJim Ingham 1126b9c1b51eSKate Stone void OptionParsingStarting(ExecutionContext *execution_context) override { 11275a988416SJim Ingham m_level = lldb::eDescriptionLevelFull; 11285a988416SJim Ingham m_internal = false; 112933df7cd3SJim Ingham m_use_dummy = false; 11305a988416SJim Ingham } 11315a988416SJim Ingham 11321f0f5b5bSZachary Turner llvm::ArrayRef<OptionDefinition> GetDefinitions() override { 113370602439SZachary Turner return llvm::makeArrayRef(g_breakpoint_list_options); 11341f0f5b5bSZachary Turner } 11355a988416SJim Ingham 11365a988416SJim Ingham // Instance variables to hold the values for command options. 11375a988416SJim Ingham 11385a988416SJim Ingham lldb::DescriptionLevel m_level; 11395a988416SJim Ingham 11405a988416SJim Ingham bool m_internal; 114133df7cd3SJim Ingham bool m_use_dummy; 11425a988416SJim Ingham }; 11435a988416SJim Ingham 11445a988416SJim Ingham protected: 1145b9c1b51eSKate Stone bool DoExecute(Args &command, CommandReturnObject &result) override { 1146cb2380c9SRaphael Isemann Target &target = GetSelectedOrDummyTarget(m_options.m_use_dummy); 11475a988416SJim Ingham 1148b9c1b51eSKate Stone const BreakpointList &breakpoints = 1149cb2380c9SRaphael Isemann target.GetBreakpointList(m_options.m_internal); 1150bb19a13cSSaleem Abdulrasool std::unique_lock<std::recursive_mutex> lock; 1151cb2380c9SRaphael Isemann target.GetBreakpointList(m_options.m_internal).GetListMutex(lock); 11525a988416SJim Ingham 11535a988416SJim Ingham size_t num_breakpoints = breakpoints.GetSize(); 11545a988416SJim Ingham 1155b9c1b51eSKate Stone if (num_breakpoints == 0) { 11565a988416SJim Ingham result.AppendMessage("No breakpoints currently set."); 11575a988416SJim Ingham result.SetStatus(eReturnStatusSuccessFinishNoResult); 11585a988416SJim Ingham return true; 11595a988416SJim Ingham } 11605a988416SJim Ingham 11615a988416SJim Ingham Stream &output_stream = result.GetOutputStream(); 11625a988416SJim Ingham 116311eb9c64SZachary Turner if (command.empty()) { 11645a988416SJim Ingham // No breakpoint selected; show info about all currently set breakpoints. 11655a988416SJim Ingham result.AppendMessage("Current breakpoints:"); 1166b9c1b51eSKate Stone for (size_t i = 0; i < num_breakpoints; ++i) { 11675a988416SJim Ingham Breakpoint *breakpoint = breakpoints.GetBreakpointAtIndex(i).get(); 1168b842f2ecSJim Ingham if (breakpoint->AllowList()) 1169b842f2ecSJim Ingham AddBreakpointDescription(&output_stream, breakpoint, 1170b842f2ecSJim Ingham m_options.m_level); 11715a988416SJim Ingham } 11725a988416SJim Ingham result.SetStatus(eReturnStatusSuccessFinishNoResult); 1173b9c1b51eSKate Stone } else { 11745a988416SJim Ingham // Particular breakpoints selected; show info about that breakpoint. 11755a988416SJim Ingham BreakpointIDList valid_bp_ids; 1176b9c1b51eSKate Stone CommandObjectMultiwordBreakpoint::VerifyBreakpointOrLocationIDs( 1177cb2380c9SRaphael Isemann command, &target, result, &valid_bp_ids, 1178b842f2ecSJim Ingham BreakpointName::Permissions::PermissionKinds::listPerm); 11795a988416SJim Ingham 1180b9c1b51eSKate Stone if (result.Succeeded()) { 1181b9c1b51eSKate Stone for (size_t i = 0; i < valid_bp_ids.GetSize(); ++i) { 11825a988416SJim Ingham BreakpointID cur_bp_id = valid_bp_ids.GetBreakpointIDAtIndex(i); 1183b9c1b51eSKate Stone Breakpoint *breakpoint = 1184cb2380c9SRaphael Isemann target.GetBreakpointByID(cur_bp_id.GetBreakpointID()).get(); 1185b9c1b51eSKate Stone AddBreakpointDescription(&output_stream, breakpoint, 1186b9c1b51eSKate Stone m_options.m_level); 11875a988416SJim Ingham } 11885a988416SJim Ingham result.SetStatus(eReturnStatusSuccessFinishNoResult); 1189b9c1b51eSKate Stone } else { 11907428a18cSKate Stone result.AppendError("Invalid breakpoint ID."); 11915a988416SJim Ingham result.SetStatus(eReturnStatusFailed); 11925a988416SJim Ingham } 11935a988416SJim Ingham } 11945a988416SJim Ingham 11955a988416SJim Ingham return result.Succeeded(); 11965a988416SJim Ingham } 11975a988416SJim Ingham 11985a988416SJim Ingham private: 11995a988416SJim Ingham CommandOptions m_options; 12005a988416SJim Ingham }; 12015a988416SJim Ingham 12025a988416SJim Ingham // CommandObjectBreakpointClear 12031f0f5b5bSZachary Turner #pragma mark Clear::CommandOptions 12041f0f5b5bSZachary Turner 1205f94668e3SRaphael Isemann #define LLDB_OPTIONS_breakpoint_clear 1206f94668e3SRaphael Isemann #include "CommandOptions.inc" 12071f0f5b5bSZachary Turner 12085a988416SJim Ingham #pragma mark Clear 12095a988416SJim Ingham 1210b9c1b51eSKate Stone class CommandObjectBreakpointClear : public CommandObjectParsed { 12115a988416SJim Ingham public: 1212efe8e7e3SFangrui Song enum BreakpointClearType { eClearTypeInvalid, eClearTypeFileAndLine }; 12135a988416SJim Ingham 12147428a18cSKate Stone CommandObjectBreakpointClear(CommandInterpreter &interpreter) 12157428a18cSKate Stone : CommandObjectParsed(interpreter, "breakpoint clear", 1216b9c1b51eSKate Stone "Delete or disable breakpoints matching the " 1217b9c1b51eSKate Stone "specified source file and line.", 12185a988416SJim Ingham "breakpoint clear <cmd-options>"), 1219b9c1b51eSKate Stone m_options() {} 12205a988416SJim Ingham 12219e85e5a8SEugene Zelenko ~CommandObjectBreakpointClear() override = default; 12225a988416SJim Ingham 1223b9c1b51eSKate Stone Options *GetOptions() override { return &m_options; } 12245a988416SJim Ingham 1225b9c1b51eSKate Stone class CommandOptions : public Options { 12265a988416SJim Ingham public: 1227b9c1b51eSKate Stone CommandOptions() : Options(), m_filename(), m_line_num(0) {} 12285a988416SJim Ingham 12299e85e5a8SEugene Zelenko ~CommandOptions() override = default; 12305a988416SJim Ingham 123197206d57SZachary Turner Status SetOptionValue(uint32_t option_idx, llvm::StringRef option_arg, 1232b9c1b51eSKate Stone ExecutionContext *execution_context) override { 123397206d57SZachary Turner Status error; 12343bcdfc0eSGreg Clayton const int short_option = m_getopt_table[option_idx].val; 12355a988416SJim Ingham 1236b9c1b51eSKate Stone switch (short_option) { 12375a988416SJim Ingham case 'f': 12385a988416SJim Ingham m_filename.assign(option_arg); 12395a988416SJim Ingham break; 12405a988416SJim Ingham 12415a988416SJim Ingham case 'l': 1242fe11483bSZachary Turner option_arg.getAsInteger(0, m_line_num); 12435a988416SJim Ingham break; 12445a988416SJim Ingham 12455a988416SJim Ingham default: 124636162014SRaphael Isemann llvm_unreachable("Unimplemented option"); 12475a988416SJim Ingham } 12485a988416SJim Ingham 12495a988416SJim Ingham return error; 12505a988416SJim Ingham } 12515a988416SJim Ingham 1252b9c1b51eSKate Stone void OptionParsingStarting(ExecutionContext *execution_context) override { 12535a988416SJim Ingham m_filename.clear(); 12545a988416SJim Ingham m_line_num = 0; 12555a988416SJim Ingham } 12565a988416SJim Ingham 12571f0f5b5bSZachary Turner llvm::ArrayRef<OptionDefinition> GetDefinitions() override { 125870602439SZachary Turner return llvm::makeArrayRef(g_breakpoint_clear_options); 12591f0f5b5bSZachary Turner } 12605a988416SJim Ingham 12615a988416SJim Ingham // Instance variables to hold the values for command options. 12625a988416SJim Ingham 12635a988416SJim Ingham std::string m_filename; 12645a988416SJim Ingham uint32_t m_line_num; 12655a988416SJim Ingham }; 12665a988416SJim Ingham 12675a988416SJim Ingham protected: 1268b9c1b51eSKate Stone bool DoExecute(Args &command, CommandReturnObject &result) override { 1269cb2380c9SRaphael Isemann Target &target = GetSelectedOrDummyTarget(); 12705a988416SJim Ingham 127105097246SAdrian Prantl // The following are the various types of breakpoints that could be 127205097246SAdrian Prantl // cleared: 12735a988416SJim Ingham // 1). -f -l (clearing breakpoint by source location) 12745a988416SJim Ingham 12755a988416SJim Ingham BreakpointClearType break_type = eClearTypeInvalid; 12765a988416SJim Ingham 12775a988416SJim Ingham if (m_options.m_line_num != 0) 12785a988416SJim Ingham break_type = eClearTypeFileAndLine; 12795a988416SJim Ingham 1280bb19a13cSSaleem Abdulrasool std::unique_lock<std::recursive_mutex> lock; 1281cb2380c9SRaphael Isemann target.GetBreakpointList().GetListMutex(lock); 12825a988416SJim Ingham 1283cb2380c9SRaphael Isemann BreakpointList &breakpoints = target.GetBreakpointList(); 12845a988416SJim Ingham size_t num_breakpoints = breakpoints.GetSize(); 12855a988416SJim Ingham 12865a988416SJim Ingham // Early return if there's no breakpoint at all. 1287b9c1b51eSKate Stone if (num_breakpoints == 0) { 12885a988416SJim Ingham result.AppendError("Breakpoint clear: No breakpoint cleared."); 12895a988416SJim Ingham result.SetStatus(eReturnStatusFailed); 12905a988416SJim Ingham return result.Succeeded(); 12915a988416SJim Ingham } 12925a988416SJim Ingham 12935a988416SJim Ingham // Find matching breakpoints and delete them. 12945a988416SJim Ingham 12955a988416SJim Ingham // First create a copy of all the IDs. 12965a988416SJim Ingham std::vector<break_id_t> BreakIDs; 12975a988416SJim Ingham for (size_t i = 0; i < num_breakpoints; ++i) 12989e85e5a8SEugene Zelenko BreakIDs.push_back(breakpoints.GetBreakpointAtIndex(i)->GetID()); 12995a988416SJim Ingham 13005a988416SJim Ingham int num_cleared = 0; 13015a988416SJim Ingham StreamString ss; 1302b9c1b51eSKate Stone switch (break_type) { 13035a988416SJim Ingham case eClearTypeFileAndLine: // Breakpoint by source position 13045a988416SJim Ingham { 13055a988416SJim Ingham const ConstString filename(m_options.m_filename.c_str()); 13065a988416SJim Ingham BreakpointLocationCollection loc_coll; 13075a988416SJim Ingham 1308b9c1b51eSKate Stone for (size_t i = 0; i < num_breakpoints; ++i) { 13095a988416SJim Ingham Breakpoint *bp = breakpoints.FindBreakpointByID(BreakIDs[i]).get(); 13105a988416SJim Ingham 1311b9c1b51eSKate Stone if (bp->GetMatchingFileLine(filename, m_options.m_line_num, loc_coll)) { 1312b9c1b51eSKate Stone // If the collection size is 0, it's a full match and we can just 1313b9c1b51eSKate Stone // remove the breakpoint. 1314b9c1b51eSKate Stone if (loc_coll.GetSize() == 0) { 13155a988416SJim Ingham bp->GetDescription(&ss, lldb::eDescriptionLevelBrief); 13165a988416SJim Ingham ss.EOL(); 1317cb2380c9SRaphael Isemann target.RemoveBreakpointByID(bp->GetID()); 13185a988416SJim Ingham ++num_cleared; 13195a988416SJim Ingham } 13205a988416SJim Ingham } 13215a988416SJim Ingham } 1322b9c1b51eSKate Stone } break; 13235a988416SJim Ingham 13245a988416SJim Ingham default: 13255a988416SJim Ingham break; 13265a988416SJim Ingham } 13275a988416SJim Ingham 1328b9c1b51eSKate Stone if (num_cleared > 0) { 13295a988416SJim Ingham Stream &output_stream = result.GetOutputStream(); 13305a988416SJim Ingham output_stream.Printf("%d breakpoints cleared:\n", num_cleared); 1331c156427dSZachary Turner output_stream << ss.GetString(); 13325a988416SJim Ingham output_stream.EOL(); 13335a988416SJim Ingham result.SetStatus(eReturnStatusSuccessFinishNoResult); 1334b9c1b51eSKate Stone } else { 13355a988416SJim Ingham result.AppendError("Breakpoint clear: No breakpoint cleared."); 13365a988416SJim Ingham result.SetStatus(eReturnStatusFailed); 13375a988416SJim Ingham } 13385a988416SJim Ingham 13395a988416SJim Ingham return result.Succeeded(); 13405a988416SJim Ingham } 13415a988416SJim Ingham 13425a988416SJim Ingham private: 13435a988416SJim Ingham CommandOptions m_options; 13445a988416SJim Ingham }; 13455a988416SJim Ingham 13465a988416SJim Ingham // CommandObjectBreakpointDelete 1347f94668e3SRaphael Isemann #define LLDB_OPTIONS_breakpoint_delete 1348f94668e3SRaphael Isemann #include "CommandOptions.inc" 13491f0f5b5bSZachary Turner 13505a988416SJim Ingham #pragma mark Delete 13515a988416SJim Ingham 1352b9c1b51eSKate Stone class CommandObjectBreakpointDelete : public CommandObjectParsed { 13535a988416SJim Ingham public: 1354b9c1b51eSKate Stone CommandObjectBreakpointDelete(CommandInterpreter &interpreter) 1355b9c1b51eSKate Stone : CommandObjectParsed(interpreter, "breakpoint delete", 1356b9c1b51eSKate Stone "Delete the specified breakpoint(s). If no " 1357b9c1b51eSKate Stone "breakpoints are specified, delete them all.", 13589e85e5a8SEugene Zelenko nullptr), 1359b9c1b51eSKate Stone m_options() { 13605a988416SJim Ingham CommandArgumentEntry arg; 1361b9c1b51eSKate Stone CommandObject::AddIDsArgumentData(arg, eArgTypeBreakpointID, 1362b9c1b51eSKate Stone eArgTypeBreakpointIDRange); 1363b9c1b51eSKate Stone // Add the entry for the first argument for this command to the object's 1364b9c1b51eSKate Stone // arguments vector. 13655a988416SJim Ingham m_arguments.push_back(arg); 13665a988416SJim Ingham } 13675a988416SJim Ingham 13689e85e5a8SEugene Zelenko ~CommandObjectBreakpointDelete() override = default; 13695a988416SJim Ingham 1370b9c1b51eSKate Stone Options *GetOptions() override { return &m_options; } 137133df7cd3SJim Ingham 1372b9c1b51eSKate Stone class CommandOptions : public Options { 137333df7cd3SJim Ingham public: 1374b9c1b51eSKate Stone CommandOptions() : Options(), m_use_dummy(false), m_force(false) {} 137533df7cd3SJim Ingham 13769e85e5a8SEugene Zelenko ~CommandOptions() override = default; 137733df7cd3SJim Ingham 137897206d57SZachary Turner Status SetOptionValue(uint32_t option_idx, llvm::StringRef option_arg, 1379b9c1b51eSKate Stone ExecutionContext *execution_context) override { 138097206d57SZachary Turner Status error; 138133df7cd3SJim Ingham const int short_option = m_getopt_table[option_idx].val; 138233df7cd3SJim Ingham 1383b9c1b51eSKate Stone switch (short_option) { 138433df7cd3SJim Ingham case 'f': 138533df7cd3SJim Ingham m_force = true; 138633df7cd3SJim Ingham break; 138733df7cd3SJim Ingham 138833df7cd3SJim Ingham case 'D': 138933df7cd3SJim Ingham m_use_dummy = true; 139033df7cd3SJim Ingham break; 139133df7cd3SJim Ingham 139233df7cd3SJim Ingham default: 139336162014SRaphael Isemann llvm_unreachable("Unimplemented option"); 139433df7cd3SJim Ingham } 139533df7cd3SJim Ingham 139633df7cd3SJim Ingham return error; 139733df7cd3SJim Ingham } 139833df7cd3SJim Ingham 1399b9c1b51eSKate Stone void OptionParsingStarting(ExecutionContext *execution_context) override { 140033df7cd3SJim Ingham m_use_dummy = false; 140133df7cd3SJim Ingham m_force = false; 140233df7cd3SJim Ingham } 140333df7cd3SJim Ingham 14041f0f5b5bSZachary Turner llvm::ArrayRef<OptionDefinition> GetDefinitions() override { 140570602439SZachary Turner return llvm::makeArrayRef(g_breakpoint_delete_options); 14061f0f5b5bSZachary Turner } 140733df7cd3SJim Ingham 140833df7cd3SJim Ingham // Instance variables to hold the values for command options. 140933df7cd3SJim Ingham bool m_use_dummy; 141033df7cd3SJim Ingham bool m_force; 141133df7cd3SJim Ingham }; 141233df7cd3SJim Ingham 14135a988416SJim Ingham protected: 1414b9c1b51eSKate Stone bool DoExecute(Args &command, CommandReturnObject &result) override { 1415cb2380c9SRaphael Isemann Target &target = GetSelectedOrDummyTarget(m_options.m_use_dummy); 14165a988416SJim Ingham 1417bb19a13cSSaleem Abdulrasool std::unique_lock<std::recursive_mutex> lock; 1418cb2380c9SRaphael Isemann target.GetBreakpointList().GetListMutex(lock); 14195a988416SJim Ingham 1420cb2380c9SRaphael Isemann const BreakpointList &breakpoints = target.GetBreakpointList(); 14215a988416SJim Ingham 14225a988416SJim Ingham size_t num_breakpoints = breakpoints.GetSize(); 14235a988416SJim Ingham 1424b9c1b51eSKate Stone if (num_breakpoints == 0) { 14255a988416SJim Ingham result.AppendError("No breakpoints exist to be deleted."); 14265a988416SJim Ingham result.SetStatus(eReturnStatusFailed); 14275a988416SJim Ingham return false; 14285a988416SJim Ingham } 14295a988416SJim Ingham 143011eb9c64SZachary Turner if (command.empty()) { 1431b9c1b51eSKate Stone if (!m_options.m_force && 1432b9c1b51eSKate Stone !m_interpreter.Confirm( 1433b9c1b51eSKate Stone "About to delete all breakpoints, do you want to do that?", 1434b9c1b51eSKate Stone true)) { 14355a988416SJim Ingham result.AppendMessage("Operation cancelled..."); 1436b9c1b51eSKate Stone } else { 1437cb2380c9SRaphael Isemann target.RemoveAllowedBreakpoints(); 1438b9c1b51eSKate Stone result.AppendMessageWithFormat( 1439b9c1b51eSKate Stone "All breakpoints removed. (%" PRIu64 " breakpoint%s)\n", 1440b9c1b51eSKate Stone (uint64_t)num_breakpoints, num_breakpoints > 1 ? "s" : ""); 14415a988416SJim Ingham } 14425a988416SJim Ingham result.SetStatus(eReturnStatusSuccessFinishNoResult); 1443b9c1b51eSKate Stone } else { 14445a988416SJim Ingham // Particular breakpoint selected; disable that breakpoint. 14455a988416SJim Ingham BreakpointIDList valid_bp_ids; 1446b9c1b51eSKate Stone CommandObjectMultiwordBreakpoint::VerifyBreakpointOrLocationIDs( 1447cb2380c9SRaphael Isemann command, &target, result, &valid_bp_ids, 1448b842f2ecSJim Ingham BreakpointName::Permissions::PermissionKinds::deletePerm); 14495a988416SJim Ingham 1450b9c1b51eSKate Stone if (result.Succeeded()) { 14515a988416SJim Ingham int delete_count = 0; 14525a988416SJim Ingham int disable_count = 0; 14535a988416SJim Ingham const size_t count = valid_bp_ids.GetSize(); 1454b9c1b51eSKate Stone for (size_t i = 0; i < count; ++i) { 14555a988416SJim Ingham BreakpointID cur_bp_id = valid_bp_ids.GetBreakpointIDAtIndex(i); 14565a988416SJim Ingham 1457b9c1b51eSKate Stone if (cur_bp_id.GetBreakpointID() != LLDB_INVALID_BREAK_ID) { 1458b9c1b51eSKate Stone if (cur_bp_id.GetLocationID() != LLDB_INVALID_BREAK_ID) { 1459b9c1b51eSKate Stone Breakpoint *breakpoint = 1460cb2380c9SRaphael Isemann target.GetBreakpointByID(cur_bp_id.GetBreakpointID()).get(); 1461b9c1b51eSKate Stone BreakpointLocation *location = 1462b9c1b51eSKate Stone breakpoint->FindLocationByID(cur_bp_id.GetLocationID()).get(); 1463b9c1b51eSKate Stone // It makes no sense to try to delete individual locations, so we 1464b9c1b51eSKate Stone // disable them instead. 1465b9c1b51eSKate Stone if (location) { 14665a988416SJim Ingham location->SetEnabled(false); 14675a988416SJim Ingham ++disable_count; 14685a988416SJim Ingham } 1469b9c1b51eSKate Stone } else { 1470cb2380c9SRaphael Isemann target.RemoveBreakpointByID(cur_bp_id.GetBreakpointID()); 14715a988416SJim Ingham ++delete_count; 14725a988416SJim Ingham } 14735a988416SJim Ingham } 14745a988416SJim Ingham } 1475b9c1b51eSKate Stone result.AppendMessageWithFormat( 1476b9c1b51eSKate Stone "%d breakpoints deleted; %d breakpoint locations disabled.\n", 14775a988416SJim Ingham delete_count, disable_count); 14785a988416SJim Ingham result.SetStatus(eReturnStatusSuccessFinishNoResult); 14795a988416SJim Ingham } 14805a988416SJim Ingham } 14815a988416SJim Ingham return result.Succeeded(); 14825a988416SJim Ingham } 14839e85e5a8SEugene Zelenko 148433df7cd3SJim Ingham private: 148533df7cd3SJim Ingham CommandOptions m_options; 148633df7cd3SJim Ingham }; 148733df7cd3SJim Ingham 14885e09c8c3SJim Ingham // CommandObjectBreakpointName 1489f94668e3SRaphael Isemann #define LLDB_OPTIONS_breakpoint_name 1490f94668e3SRaphael Isemann #include "CommandOptions.inc" 1491bd68a052SRaphael Isemann 1492b9c1b51eSKate Stone class BreakpointNameOptionGroup : public OptionGroup { 14935e09c8c3SJim Ingham public: 1494b9c1b51eSKate Stone BreakpointNameOptionGroup() 1495b9c1b51eSKate Stone : OptionGroup(), m_breakpoint(LLDB_INVALID_BREAK_ID), m_use_dummy(false) { 14965e09c8c3SJim Ingham } 14975e09c8c3SJim Ingham 14989e85e5a8SEugene Zelenko ~BreakpointNameOptionGroup() override = default; 14995e09c8c3SJim Ingham 15001f0f5b5bSZachary Turner llvm::ArrayRef<OptionDefinition> GetDefinitions() override { 150170602439SZachary Turner return llvm::makeArrayRef(g_breakpoint_name_options); 15025e09c8c3SJim Ingham } 15035e09c8c3SJim Ingham 150497206d57SZachary Turner Status SetOptionValue(uint32_t option_idx, llvm::StringRef option_arg, 1505b9c1b51eSKate Stone ExecutionContext *execution_context) override { 150697206d57SZachary Turner Status error; 15075e09c8c3SJim Ingham const int short_option = g_breakpoint_name_options[option_idx].short_option; 15085e09c8c3SJim Ingham 1509b9c1b51eSKate Stone switch (short_option) { 15105e09c8c3SJim Ingham case 'N': 1511fe11483bSZachary Turner if (BreakpointID::StringIsBreakpointName(option_arg, error) && 1512b9c1b51eSKate Stone error.Success()) 1513fe11483bSZachary Turner m_name.SetValueFromString(option_arg); 15145e09c8c3SJim Ingham break; 15155e09c8c3SJim Ingham case 'B': 1516fe11483bSZachary Turner if (m_breakpoint.SetValueFromString(option_arg).Fail()) 1517b9c1b51eSKate Stone error.SetErrorStringWithFormat( 15188cef4b0bSZachary Turner "unrecognized value \"%s\" for breakpoint", 1519fe11483bSZachary Turner option_arg.str().c_str()); 15205e09c8c3SJim Ingham break; 15215e09c8c3SJim Ingham case 'D': 1522fe11483bSZachary Turner if (m_use_dummy.SetValueFromString(option_arg).Fail()) 1523b9c1b51eSKate Stone error.SetErrorStringWithFormat( 15248cef4b0bSZachary Turner "unrecognized value \"%s\" for use-dummy", 1525fe11483bSZachary Turner option_arg.str().c_str()); 15265e09c8c3SJim Ingham break; 1527e9632ebaSJim Ingham case 'H': 1528e9632ebaSJim Ingham m_help_string.SetValueFromString(option_arg); 1529e9632ebaSJim Ingham break; 15305e09c8c3SJim Ingham 15315e09c8c3SJim Ingham default: 153236162014SRaphael Isemann llvm_unreachable("Unimplemented option"); 15335e09c8c3SJim Ingham } 15345e09c8c3SJim Ingham return error; 15355e09c8c3SJim Ingham } 15365e09c8c3SJim Ingham 1537b9c1b51eSKate Stone void OptionParsingStarting(ExecutionContext *execution_context) override { 15385e09c8c3SJim Ingham m_name.Clear(); 15395e09c8c3SJim Ingham m_breakpoint.Clear(); 15405e09c8c3SJim Ingham m_use_dummy.Clear(); 15415e09c8c3SJim Ingham m_use_dummy.SetDefaultValue(false); 1542e9632ebaSJim Ingham m_help_string.Clear(); 15435e09c8c3SJim Ingham } 15445e09c8c3SJim Ingham 15455e09c8c3SJim Ingham OptionValueString m_name; 15465e09c8c3SJim Ingham OptionValueUInt64 m_breakpoint; 15475e09c8c3SJim Ingham OptionValueBoolean m_use_dummy; 1548e9632ebaSJim Ingham OptionValueString m_help_string; 15495e09c8c3SJim Ingham }; 15505e09c8c3SJim Ingham 1551f94668e3SRaphael Isemann #define LLDB_OPTIONS_breakpoint_access 1552f94668e3SRaphael Isemann #include "CommandOptions.inc" 1553b842f2ecSJim Ingham 15548fe53c49STatyana Krasnukha class BreakpointAccessOptionGroup : public OptionGroup { 1555b842f2ecSJim Ingham public: 15568fe53c49STatyana Krasnukha BreakpointAccessOptionGroup() : OptionGroup() {} 1557b842f2ecSJim Ingham 1558b842f2ecSJim Ingham ~BreakpointAccessOptionGroup() override = default; 1559b842f2ecSJim Ingham 1560b842f2ecSJim Ingham llvm::ArrayRef<OptionDefinition> GetDefinitions() override { 1561b842f2ecSJim Ingham return llvm::makeArrayRef(g_breakpoint_access_options); 1562b842f2ecSJim Ingham } 1563b842f2ecSJim Ingham Status SetOptionValue(uint32_t option_idx, llvm::StringRef option_arg, 1564b842f2ecSJim Ingham ExecutionContext *execution_context) override { 1565b842f2ecSJim Ingham Status error; 1566*a925974bSAdrian Prantl const int short_option = 1567*a925974bSAdrian Prantl g_breakpoint_access_options[option_idx].short_option; 1568b842f2ecSJim Ingham 1569b842f2ecSJim Ingham switch (short_option) { 1570b842f2ecSJim Ingham case 'L': { 1571b842f2ecSJim Ingham bool value, success; 157247cbf4a0SPavel Labath value = OptionArgParser::ToBoolean(option_arg, false, &success); 1573b842f2ecSJim Ingham if (success) { 1574b842f2ecSJim Ingham m_permissions.SetAllowList(value); 1575b842f2ecSJim Ingham } else 1576b842f2ecSJim Ingham error.SetErrorStringWithFormat( 1577b842f2ecSJim Ingham "invalid boolean value '%s' passed for -L option", 1578b842f2ecSJim Ingham option_arg.str().c_str()); 1579b842f2ecSJim Ingham } break; 1580b842f2ecSJim Ingham case 'A': { 1581b842f2ecSJim Ingham bool value, success; 158247cbf4a0SPavel Labath value = OptionArgParser::ToBoolean(option_arg, false, &success); 1583b842f2ecSJim Ingham if (success) { 1584b842f2ecSJim Ingham m_permissions.SetAllowDisable(value); 1585b842f2ecSJim Ingham } else 1586b842f2ecSJim Ingham error.SetErrorStringWithFormat( 1587b842f2ecSJim Ingham "invalid boolean value '%s' passed for -L option", 1588b842f2ecSJim Ingham option_arg.str().c_str()); 1589b842f2ecSJim Ingham } break; 1590b842f2ecSJim Ingham case 'D': { 1591b842f2ecSJim Ingham bool value, success; 159247cbf4a0SPavel Labath value = OptionArgParser::ToBoolean(option_arg, false, &success); 1593b842f2ecSJim Ingham if (success) { 1594b842f2ecSJim Ingham m_permissions.SetAllowDelete(value); 1595b842f2ecSJim Ingham } else 1596b842f2ecSJim Ingham error.SetErrorStringWithFormat( 1597b842f2ecSJim Ingham "invalid boolean value '%s' passed for -L option", 1598b842f2ecSJim Ingham option_arg.str().c_str()); 1599b842f2ecSJim Ingham } break; 160036162014SRaphael Isemann default: 160136162014SRaphael Isemann llvm_unreachable("Unimplemented option"); 1602b842f2ecSJim Ingham } 1603b842f2ecSJim Ingham 1604b842f2ecSJim Ingham return error; 1605b842f2ecSJim Ingham } 1606b842f2ecSJim Ingham 1607*a925974bSAdrian Prantl void OptionParsingStarting(ExecutionContext *execution_context) override {} 1608b842f2ecSJim Ingham 1609*a925974bSAdrian Prantl const BreakpointName::Permissions &GetPermissions() const { 1610b842f2ecSJim Ingham return m_permissions; 1611b842f2ecSJim Ingham } 1612b842f2ecSJim Ingham BreakpointName::Permissions m_permissions; 1613b842f2ecSJim Ingham }; 1614b842f2ecSJim Ingham 1615b842f2ecSJim Ingham class CommandObjectBreakpointNameConfigure : public CommandObjectParsed { 1616b842f2ecSJim Ingham public: 1617b842f2ecSJim Ingham CommandObjectBreakpointNameConfigure(CommandInterpreter &interpreter) 1618b842f2ecSJim Ingham : CommandObjectParsed( 1619*a925974bSAdrian Prantl interpreter, "configure", 1620*a925974bSAdrian Prantl "Configure the options for the breakpoint" 1621b842f2ecSJim Ingham " name provided. " 1622b842f2ecSJim Ingham "If you provide a breakpoint id, the options will be copied from " 1623b842f2ecSJim Ingham "the breakpoint, otherwise only the options specified will be set " 1624b842f2ecSJim Ingham "on the name.", 1625b842f2ecSJim Ingham "breakpoint name configure <command-options> " 1626b842f2ecSJim Ingham "<breakpoint-name-list>"), 1627b842f2ecSJim Ingham m_bp_opts(), m_option_group() { 1628b842f2ecSJim Ingham // Create the first variant for the first (and only) argument for this 1629b842f2ecSJim Ingham // command. 1630b842f2ecSJim Ingham CommandArgumentEntry arg1; 1631b842f2ecSJim Ingham CommandArgumentData id_arg; 1632b842f2ecSJim Ingham id_arg.arg_type = eArgTypeBreakpointName; 1633b842f2ecSJim Ingham id_arg.arg_repetition = eArgRepeatOptional; 1634b842f2ecSJim Ingham arg1.push_back(id_arg); 1635b842f2ecSJim Ingham m_arguments.push_back(arg1); 1636b842f2ecSJim Ingham 1637*a925974bSAdrian Prantl m_option_group.Append(&m_bp_opts, LLDB_OPT_SET_ALL, LLDB_OPT_SET_1); 1638*a925974bSAdrian Prantl m_option_group.Append(&m_access_options, LLDB_OPT_SET_ALL, 1639b842f2ecSJim Ingham LLDB_OPT_SET_ALL); 1640*a925974bSAdrian Prantl m_option_group.Append(&m_bp_id, LLDB_OPT_SET_2 | LLDB_OPT_SET_4, 1641e9632ebaSJim Ingham LLDB_OPT_SET_ALL); 1642b842f2ecSJim Ingham m_option_group.Finalize(); 1643b842f2ecSJim Ingham } 1644b842f2ecSJim Ingham 1645b842f2ecSJim Ingham ~CommandObjectBreakpointNameConfigure() override = default; 1646b842f2ecSJim Ingham 1647b842f2ecSJim Ingham Options *GetOptions() override { return &m_option_group; } 1648b842f2ecSJim Ingham 1649b842f2ecSJim Ingham protected: 1650b842f2ecSJim Ingham bool DoExecute(Args &command, CommandReturnObject &result) override { 1651b842f2ecSJim Ingham 1652b842f2ecSJim Ingham const size_t argc = command.GetArgumentCount(); 1653b842f2ecSJim Ingham if (argc == 0) { 1654b842f2ecSJim Ingham result.AppendError("No names provided."); 1655b842f2ecSJim Ingham result.SetStatus(eReturnStatusFailed); 1656b842f2ecSJim Ingham return false; 1657b842f2ecSJim Ingham } 1658b842f2ecSJim Ingham 1659cb2380c9SRaphael Isemann Target &target = GetSelectedOrDummyTarget(false); 1660b842f2ecSJim Ingham 1661b842f2ecSJim Ingham std::unique_lock<std::recursive_mutex> lock; 1662cb2380c9SRaphael Isemann target.GetBreakpointList().GetListMutex(lock); 1663b842f2ecSJim Ingham 1664b842f2ecSJim Ingham // Make a pass through first to see that all the names are legal. 1665b842f2ecSJim Ingham for (auto &entry : command.entries()) { 1666b842f2ecSJim Ingham Status error; 1667*a925974bSAdrian Prantl if (!BreakpointID::StringIsBreakpointName(entry.ref(), error)) { 1668b842f2ecSJim Ingham result.AppendErrorWithFormat("Invalid breakpoint name: %s - %s", 1669b842f2ecSJim Ingham entry.c_str(), error.AsCString()); 1670b842f2ecSJim Ingham result.SetStatus(eReturnStatusFailed); 1671b842f2ecSJim Ingham return false; 1672b842f2ecSJim Ingham } 1673b842f2ecSJim Ingham } 167405097246SAdrian Prantl // Now configure them, we already pre-checked the names so we don't need to 167505097246SAdrian Prantl // check the error: 1676b842f2ecSJim Ingham BreakpointSP bp_sp; 1677*a925974bSAdrian Prantl if (m_bp_id.m_breakpoint.OptionWasSet()) { 1678b842f2ecSJim Ingham lldb::break_id_t bp_id = m_bp_id.m_breakpoint.GetUInt64Value(); 1679cb2380c9SRaphael Isemann bp_sp = target.GetBreakpointByID(bp_id); 1680*a925974bSAdrian Prantl if (!bp_sp) { 1681b842f2ecSJim Ingham result.AppendErrorWithFormatv("Could not find specified breakpoint {0}", 1682b842f2ecSJim Ingham bp_id); 1683b842f2ecSJim Ingham result.SetStatus(eReturnStatusFailed); 1684b842f2ecSJim Ingham return false; 1685b842f2ecSJim Ingham } 1686b842f2ecSJim Ingham } 1687b842f2ecSJim Ingham 1688b842f2ecSJim Ingham Status error; 1689b842f2ecSJim Ingham for (auto &entry : command.entries()) { 1690b842f2ecSJim Ingham ConstString name(entry.c_str()); 1691cb2380c9SRaphael Isemann BreakpointName *bp_name = target.FindBreakpointName(name, true, error); 1692b842f2ecSJim Ingham if (!bp_name) 1693b842f2ecSJim Ingham continue; 1694e9632ebaSJim Ingham if (m_bp_id.m_help_string.OptionWasSet()) 1695e9632ebaSJim Ingham bp_name->SetHelp(m_bp_id.m_help_string.GetStringValue().str().c_str()); 1696e9632ebaSJim Ingham 1697b842f2ecSJim Ingham if (bp_sp) 1698cb2380c9SRaphael Isemann target.ConfigureBreakpointName(*bp_name, *bp_sp->GetOptions(), 1699b842f2ecSJim Ingham m_access_options.GetPermissions()); 1700b842f2ecSJim Ingham else 1701cb2380c9SRaphael Isemann target.ConfigureBreakpointName(*bp_name, 1702b842f2ecSJim Ingham m_bp_opts.GetBreakpointOptions(), 1703b842f2ecSJim Ingham m_access_options.GetPermissions()); 1704b842f2ecSJim Ingham } 1705b842f2ecSJim Ingham return true; 1706b842f2ecSJim Ingham } 1707b842f2ecSJim Ingham 1708b842f2ecSJim Ingham private: 1709b842f2ecSJim Ingham BreakpointNameOptionGroup m_bp_id; // Only using the id part of this. 1710b842f2ecSJim Ingham BreakpointOptionGroup m_bp_opts; 1711b842f2ecSJim Ingham BreakpointAccessOptionGroup m_access_options; 1712b842f2ecSJim Ingham OptionGroupOptions m_option_group; 1713b842f2ecSJim Ingham }; 1714b842f2ecSJim Ingham 1715b9c1b51eSKate Stone class CommandObjectBreakpointNameAdd : public CommandObjectParsed { 17165e09c8c3SJim Ingham public: 1717b9c1b51eSKate Stone CommandObjectBreakpointNameAdd(CommandInterpreter &interpreter) 1718b9c1b51eSKate Stone : CommandObjectParsed( 1719b9c1b51eSKate Stone interpreter, "add", "Add a name to the breakpoints provided.", 17205e09c8c3SJim Ingham "breakpoint name add <command-options> <breakpoint-id-list>"), 1721b9c1b51eSKate Stone m_name_options(), m_option_group() { 1722b9c1b51eSKate Stone // Create the first variant for the first (and only) argument for this 1723b9c1b51eSKate Stone // command. 17245e09c8c3SJim Ingham CommandArgumentEntry arg1; 17255e09c8c3SJim Ingham CommandArgumentData id_arg; 17265e09c8c3SJim Ingham id_arg.arg_type = eArgTypeBreakpointID; 17275e09c8c3SJim Ingham id_arg.arg_repetition = eArgRepeatOptional; 17285e09c8c3SJim Ingham arg1.push_back(id_arg); 17295e09c8c3SJim Ingham m_arguments.push_back(arg1); 17305e09c8c3SJim Ingham 17315e09c8c3SJim Ingham m_option_group.Append(&m_name_options, LLDB_OPT_SET_1, LLDB_OPT_SET_ALL); 17325e09c8c3SJim Ingham m_option_group.Finalize(); 17335e09c8c3SJim Ingham } 17345e09c8c3SJim Ingham 17359e85e5a8SEugene Zelenko ~CommandObjectBreakpointNameAdd() override = default; 17365e09c8c3SJim Ingham 1737b9c1b51eSKate Stone Options *GetOptions() override { return &m_option_group; } 17385e09c8c3SJim Ingham 17395e09c8c3SJim Ingham protected: 1740b9c1b51eSKate Stone bool DoExecute(Args &command, CommandReturnObject &result) override { 1741b9c1b51eSKate Stone if (!m_name_options.m_name.OptionWasSet()) { 17425e09c8c3SJim Ingham result.SetError("No name option provided."); 17435e09c8c3SJim Ingham return false; 17445e09c8c3SJim Ingham } 17455e09c8c3SJim Ingham 1746cb2380c9SRaphael Isemann Target &target = 1747b9c1b51eSKate Stone GetSelectedOrDummyTarget(m_name_options.m_use_dummy.GetCurrentValue()); 17485e09c8c3SJim Ingham 1749bb19a13cSSaleem Abdulrasool std::unique_lock<std::recursive_mutex> lock; 1750cb2380c9SRaphael Isemann target.GetBreakpointList().GetListMutex(lock); 17515e09c8c3SJim Ingham 1752cb2380c9SRaphael Isemann const BreakpointList &breakpoints = target.GetBreakpointList(); 17535e09c8c3SJim Ingham 17545e09c8c3SJim Ingham size_t num_breakpoints = breakpoints.GetSize(); 1755b9c1b51eSKate Stone if (num_breakpoints == 0) { 17565e09c8c3SJim Ingham result.SetError("No breakpoints, cannot add names."); 17575e09c8c3SJim Ingham result.SetStatus(eReturnStatusFailed); 17585e09c8c3SJim Ingham return false; 17595e09c8c3SJim Ingham } 17605e09c8c3SJim Ingham 17615e09c8c3SJim Ingham // Particular breakpoint selected; disable that breakpoint. 17625e09c8c3SJim Ingham BreakpointIDList valid_bp_ids; 1763b9c1b51eSKate Stone CommandObjectMultiwordBreakpoint::VerifyBreakpointIDs( 1764cb2380c9SRaphael Isemann command, &target, result, &valid_bp_ids, 1765b842f2ecSJim Ingham BreakpointName::Permissions::PermissionKinds::listPerm); 17665e09c8c3SJim Ingham 1767b9c1b51eSKate Stone if (result.Succeeded()) { 1768b9c1b51eSKate Stone if (valid_bp_ids.GetSize() == 0) { 17695e09c8c3SJim Ingham result.SetError("No breakpoints specified, cannot add names."); 17705e09c8c3SJim Ingham result.SetStatus(eReturnStatusFailed); 17715e09c8c3SJim Ingham return false; 17725e09c8c3SJim Ingham } 17735e09c8c3SJim Ingham size_t num_valid_ids = valid_bp_ids.GetSize(); 1774b842f2ecSJim Ingham const char *bp_name = m_name_options.m_name.GetCurrentValue(); 1775b842f2ecSJim Ingham Status error; // This error reports illegal names, but we've already 1776b842f2ecSJim Ingham // checked that, so we don't need to check it again here. 1777b9c1b51eSKate Stone for (size_t index = 0; index < num_valid_ids; index++) { 1778b9c1b51eSKate Stone lldb::break_id_t bp_id = 1779b9c1b51eSKate Stone valid_bp_ids.GetBreakpointIDAtIndex(index).GetBreakpointID(); 17805e09c8c3SJim Ingham BreakpointSP bp_sp = breakpoints.FindBreakpointByID(bp_id); 1781cb2380c9SRaphael Isemann target.AddNameToBreakpoint(bp_sp, bp_name, error); 17825e09c8c3SJim Ingham } 17835e09c8c3SJim Ingham } 17845e09c8c3SJim Ingham 17855e09c8c3SJim Ingham return true; 17865e09c8c3SJim Ingham } 17875e09c8c3SJim Ingham 17885e09c8c3SJim Ingham private: 17895e09c8c3SJim Ingham BreakpointNameOptionGroup m_name_options; 17905e09c8c3SJim Ingham OptionGroupOptions m_option_group; 17915e09c8c3SJim Ingham }; 17925e09c8c3SJim Ingham 1793b9c1b51eSKate Stone class CommandObjectBreakpointNameDelete : public CommandObjectParsed { 17945e09c8c3SJim Ingham public: 1795b9c1b51eSKate Stone CommandObjectBreakpointNameDelete(CommandInterpreter &interpreter) 1796b9c1b51eSKate Stone : CommandObjectParsed( 1797b9c1b51eSKate Stone interpreter, "delete", 17985e09c8c3SJim Ingham "Delete a name from the breakpoints provided.", 17995e09c8c3SJim Ingham "breakpoint name delete <command-options> <breakpoint-id-list>"), 1800b9c1b51eSKate Stone m_name_options(), m_option_group() { 1801b9c1b51eSKate Stone // Create the first variant for the first (and only) argument for this 1802b9c1b51eSKate Stone // command. 18035e09c8c3SJim Ingham CommandArgumentEntry arg1; 18045e09c8c3SJim Ingham CommandArgumentData id_arg; 18055e09c8c3SJim Ingham id_arg.arg_type = eArgTypeBreakpointID; 18065e09c8c3SJim Ingham id_arg.arg_repetition = eArgRepeatOptional; 18075e09c8c3SJim Ingham arg1.push_back(id_arg); 18085e09c8c3SJim Ingham m_arguments.push_back(arg1); 18095e09c8c3SJim Ingham 18105e09c8c3SJim Ingham m_option_group.Append(&m_name_options, LLDB_OPT_SET_1, LLDB_OPT_SET_ALL); 18115e09c8c3SJim Ingham m_option_group.Finalize(); 18125e09c8c3SJim Ingham } 18135e09c8c3SJim Ingham 18149e85e5a8SEugene Zelenko ~CommandObjectBreakpointNameDelete() override = default; 18155e09c8c3SJim Ingham 1816b9c1b51eSKate Stone Options *GetOptions() override { return &m_option_group; } 18175e09c8c3SJim Ingham 18185e09c8c3SJim Ingham protected: 1819b9c1b51eSKate Stone bool DoExecute(Args &command, CommandReturnObject &result) override { 1820b9c1b51eSKate Stone if (!m_name_options.m_name.OptionWasSet()) { 18215e09c8c3SJim Ingham result.SetError("No name option provided."); 18225e09c8c3SJim Ingham return false; 18235e09c8c3SJim Ingham } 18245e09c8c3SJim Ingham 1825cb2380c9SRaphael Isemann Target &target = 1826b9c1b51eSKate Stone GetSelectedOrDummyTarget(m_name_options.m_use_dummy.GetCurrentValue()); 18275e09c8c3SJim Ingham 1828bb19a13cSSaleem Abdulrasool std::unique_lock<std::recursive_mutex> lock; 1829cb2380c9SRaphael Isemann target.GetBreakpointList().GetListMutex(lock); 18305e09c8c3SJim Ingham 1831cb2380c9SRaphael Isemann const BreakpointList &breakpoints = target.GetBreakpointList(); 18325e09c8c3SJim Ingham 18335e09c8c3SJim Ingham size_t num_breakpoints = breakpoints.GetSize(); 1834b9c1b51eSKate Stone if (num_breakpoints == 0) { 18355e09c8c3SJim Ingham result.SetError("No breakpoints, cannot delete names."); 18365e09c8c3SJim Ingham result.SetStatus(eReturnStatusFailed); 18375e09c8c3SJim Ingham return false; 18385e09c8c3SJim Ingham } 18395e09c8c3SJim Ingham 18405e09c8c3SJim Ingham // Particular breakpoint selected; disable that breakpoint. 18415e09c8c3SJim Ingham BreakpointIDList valid_bp_ids; 1842b9c1b51eSKate Stone CommandObjectMultiwordBreakpoint::VerifyBreakpointIDs( 1843cb2380c9SRaphael Isemann command, &target, result, &valid_bp_ids, 1844b842f2ecSJim Ingham BreakpointName::Permissions::PermissionKinds::deletePerm); 18455e09c8c3SJim Ingham 1846b9c1b51eSKate Stone if (result.Succeeded()) { 1847b9c1b51eSKate Stone if (valid_bp_ids.GetSize() == 0) { 18485e09c8c3SJim Ingham result.SetError("No breakpoints specified, cannot delete names."); 18495e09c8c3SJim Ingham result.SetStatus(eReturnStatusFailed); 18505e09c8c3SJim Ingham return false; 18515e09c8c3SJim Ingham } 1852b842f2ecSJim Ingham ConstString bp_name(m_name_options.m_name.GetCurrentValue()); 18535e09c8c3SJim Ingham size_t num_valid_ids = valid_bp_ids.GetSize(); 1854b9c1b51eSKate Stone for (size_t index = 0; index < num_valid_ids; index++) { 1855b9c1b51eSKate Stone lldb::break_id_t bp_id = 1856b9c1b51eSKate Stone valid_bp_ids.GetBreakpointIDAtIndex(index).GetBreakpointID(); 18575e09c8c3SJim Ingham BreakpointSP bp_sp = breakpoints.FindBreakpointByID(bp_id); 1858cb2380c9SRaphael Isemann target.RemoveNameFromBreakpoint(bp_sp, bp_name); 18595e09c8c3SJim Ingham } 18605e09c8c3SJim Ingham } 18615e09c8c3SJim Ingham 18625e09c8c3SJim Ingham return true; 18635e09c8c3SJim Ingham } 18645e09c8c3SJim Ingham 18655e09c8c3SJim Ingham private: 18665e09c8c3SJim Ingham BreakpointNameOptionGroup m_name_options; 18675e09c8c3SJim Ingham OptionGroupOptions m_option_group; 18685e09c8c3SJim Ingham }; 18695e09c8c3SJim Ingham 1870b9c1b51eSKate Stone class CommandObjectBreakpointNameList : public CommandObjectParsed { 18715e09c8c3SJim Ingham public: 1872b9c1b51eSKate Stone CommandObjectBreakpointNameList(CommandInterpreter &interpreter) 1873b9c1b51eSKate Stone : CommandObjectParsed(interpreter, "list", 1874b842f2ecSJim Ingham "List either the names for a breakpoint or info " 1875b842f2ecSJim Ingham "about a given name. With no arguments, lists all " 1876b842f2ecSJim Ingham "names", 18775e09c8c3SJim Ingham "breakpoint name list <command-options>"), 1878b9c1b51eSKate Stone m_name_options(), m_option_group() { 1879b842f2ecSJim Ingham m_option_group.Append(&m_name_options, LLDB_OPT_SET_3, LLDB_OPT_SET_ALL); 18805e09c8c3SJim Ingham m_option_group.Finalize(); 18815e09c8c3SJim Ingham } 18825e09c8c3SJim Ingham 18839e85e5a8SEugene Zelenko ~CommandObjectBreakpointNameList() override = default; 18845e09c8c3SJim Ingham 1885b9c1b51eSKate Stone Options *GetOptions() override { return &m_option_group; } 18865e09c8c3SJim Ingham 18875e09c8c3SJim Ingham protected: 1888b9c1b51eSKate Stone bool DoExecute(Args &command, CommandReturnObject &result) override { 1889cb2380c9SRaphael Isemann Target &target = 1890b9c1b51eSKate Stone GetSelectedOrDummyTarget(m_name_options.m_use_dummy.GetCurrentValue()); 18915e09c8c3SJim Ingham 1892b842f2ecSJim Ingham std::vector<std::string> name_list; 1893b842f2ecSJim Ingham if (command.empty()) { 1894cb2380c9SRaphael Isemann target.GetBreakpointNames(name_list); 1895b842f2ecSJim Ingham } else { 1896*a925974bSAdrian Prantl for (const Args::ArgEntry &arg : command) { 1897b842f2ecSJim Ingham name_list.push_back(arg.c_str()); 1898b842f2ecSJim Ingham } 1899b842f2ecSJim Ingham } 1900b842f2ecSJim Ingham 1901b842f2ecSJim Ingham if (name_list.empty()) { 1902b842f2ecSJim Ingham result.AppendMessage("No breakpoint names found."); 1903b842f2ecSJim Ingham } else { 1904b842f2ecSJim Ingham for (const std::string &name_str : name_list) { 1905b842f2ecSJim Ingham const char *name = name_str.c_str(); 1906b842f2ecSJim Ingham // First print out the options for the name: 1907b842f2ecSJim Ingham Status error; 1908cb2380c9SRaphael Isemann BreakpointName *bp_name = 1909cb2380c9SRaphael Isemann target.FindBreakpointName(ConstString(name), false, error); 1910*a925974bSAdrian Prantl if (bp_name) { 1911b842f2ecSJim Ingham StreamString s; 1912b842f2ecSJim Ingham result.AppendMessageWithFormat("Name: %s\n", name); 1913*a925974bSAdrian Prantl if (bp_name->GetDescription(&s, eDescriptionLevelFull)) { 1914b842f2ecSJim Ingham result.AppendMessage(s.GetString()); 1915b842f2ecSJim Ingham } 1916b842f2ecSJim Ingham 1917bb19a13cSSaleem Abdulrasool std::unique_lock<std::recursive_mutex> lock; 1918cb2380c9SRaphael Isemann target.GetBreakpointList().GetListMutex(lock); 19195e09c8c3SJim Ingham 1920cb2380c9SRaphael Isemann BreakpointList &breakpoints = target.GetBreakpointList(); 1921b842f2ecSJim Ingham bool any_set = false; 1922b9c1b51eSKate Stone for (BreakpointSP bp_sp : breakpoints.Breakpoints()) { 1923b9c1b51eSKate Stone if (bp_sp->MatchesName(name)) { 19245e09c8c3SJim Ingham StreamString s; 1925b842f2ecSJim Ingham any_set = true; 19265e09c8c3SJim Ingham bp_sp->GetDescription(&s, eDescriptionLevelBrief); 19275e09c8c3SJim Ingham s.EOL(); 1928c156427dSZachary Turner result.AppendMessage(s.GetString()); 19295e09c8c3SJim Ingham } 19305e09c8c3SJim Ingham } 1931b842f2ecSJim Ingham if (!any_set) 1932b842f2ecSJim Ingham result.AppendMessage("No breakpoints using this name."); 1933b9c1b51eSKate Stone } else { 1934b842f2ecSJim Ingham result.AppendMessageWithFormat("Name: %s not found.\n", name); 19355e09c8c3SJim Ingham } 1936b842f2ecSJim Ingham } 19375e09c8c3SJim Ingham } 19385e09c8c3SJim Ingham return true; 19395e09c8c3SJim Ingham } 19405e09c8c3SJim Ingham 19415e09c8c3SJim Ingham private: 19425e09c8c3SJim Ingham BreakpointNameOptionGroup m_name_options; 19435e09c8c3SJim Ingham OptionGroupOptions m_option_group; 19445e09c8c3SJim Ingham }; 19455e09c8c3SJim Ingham 1946e14dc268SJim Ingham // CommandObjectBreakpointName 1947b9c1b51eSKate Stone class CommandObjectBreakpointName : public CommandObjectMultiword { 19485e09c8c3SJim Ingham public: 19497428a18cSKate Stone CommandObjectBreakpointName(CommandInterpreter &interpreter) 1950b9c1b51eSKate Stone : CommandObjectMultiword( 1951b9c1b51eSKate Stone interpreter, "name", "Commands to manage name tags for breakpoints", 1952b9c1b51eSKate Stone "breakpoint name <subcommand> [<command-options>]") { 1953b9c1b51eSKate Stone CommandObjectSP add_command_object( 1954b9c1b51eSKate Stone new CommandObjectBreakpointNameAdd(interpreter)); 1955b9c1b51eSKate Stone CommandObjectSP delete_command_object( 1956b9c1b51eSKate Stone new CommandObjectBreakpointNameDelete(interpreter)); 1957b9c1b51eSKate Stone CommandObjectSP list_command_object( 1958b9c1b51eSKate Stone new CommandObjectBreakpointNameList(interpreter)); 1959b842f2ecSJim Ingham CommandObjectSP configure_command_object( 1960b842f2ecSJim Ingham new CommandObjectBreakpointNameConfigure(interpreter)); 19615e09c8c3SJim Ingham 19625e09c8c3SJim Ingham LoadSubCommand("add", add_command_object); 19635e09c8c3SJim Ingham LoadSubCommand("delete", delete_command_object); 19645e09c8c3SJim Ingham LoadSubCommand("list", list_command_object); 1965b842f2ecSJim Ingham LoadSubCommand("configure", configure_command_object); 19665e09c8c3SJim Ingham } 19675e09c8c3SJim Ingham 19689e85e5a8SEugene Zelenko ~CommandObjectBreakpointName() override = default; 19695e09c8c3SJim Ingham }; 19705e09c8c3SJim Ingham 1971e14dc268SJim Ingham // CommandObjectBreakpointRead 19723acdf385SJim Ingham #pragma mark Read::CommandOptions 1973f94668e3SRaphael Isemann #define LLDB_OPTIONS_breakpoint_read 1974f94668e3SRaphael Isemann #include "CommandOptions.inc" 19751f0f5b5bSZachary Turner 19761f0f5b5bSZachary Turner #pragma mark Read 1977e14dc268SJim Ingham 1978e14dc268SJim Ingham class CommandObjectBreakpointRead : public CommandObjectParsed { 1979e14dc268SJim Ingham public: 1980e14dc268SJim Ingham CommandObjectBreakpointRead(CommandInterpreter &interpreter) 1981e14dc268SJim Ingham : CommandObjectParsed(interpreter, "breakpoint read", 1982e14dc268SJim Ingham "Read and set the breakpoints previously saved to " 1983e14dc268SJim Ingham "a file with \"breakpoint write\". ", 1984e14dc268SJim Ingham nullptr), 1985e14dc268SJim Ingham m_options() { 1986e14dc268SJim Ingham CommandArgumentEntry arg; 1987e14dc268SJim Ingham CommandObject::AddIDsArgumentData(arg, eArgTypeBreakpointID, 1988e14dc268SJim Ingham eArgTypeBreakpointIDRange); 1989e14dc268SJim Ingham // Add the entry for the first argument for this command to the object's 1990e14dc268SJim Ingham // arguments vector. 1991e14dc268SJim Ingham m_arguments.push_back(arg); 1992e14dc268SJim Ingham } 1993e14dc268SJim Ingham 1994e14dc268SJim Ingham ~CommandObjectBreakpointRead() override = default; 1995e14dc268SJim Ingham 1996e14dc268SJim Ingham Options *GetOptions() override { return &m_options; } 1997e14dc268SJim Ingham 1998e14dc268SJim Ingham class CommandOptions : public Options { 1999e14dc268SJim Ingham public: 2000e14dc268SJim Ingham CommandOptions() : Options() {} 2001e14dc268SJim Ingham 2002e14dc268SJim Ingham ~CommandOptions() override = default; 2003e14dc268SJim Ingham 200497206d57SZachary Turner Status SetOptionValue(uint32_t option_idx, llvm::StringRef option_arg, 2005e14dc268SJim Ingham ExecutionContext *execution_context) override { 200697206d57SZachary Turner Status error; 2007e14dc268SJim Ingham const int short_option = m_getopt_table[option_idx].val; 2008e14dc268SJim Ingham 2009e14dc268SJim Ingham switch (short_option) { 2010e14dc268SJim Ingham case 'f': 2011e14dc268SJim Ingham m_filename.assign(option_arg); 2012e14dc268SJim Ingham break; 20133acdf385SJim Ingham case 'N': { 201497206d57SZachary Turner Status name_error; 20153acdf385SJim Ingham if (!BreakpointID::StringIsBreakpointName(llvm::StringRef(option_arg), 20163acdf385SJim Ingham name_error)) { 20173acdf385SJim Ingham error.SetErrorStringWithFormat("Invalid breakpoint name: %s", 20183acdf385SJim Ingham name_error.AsCString()); 20193acdf385SJim Ingham } 20203acdf385SJim Ingham m_names.push_back(option_arg); 20213acdf385SJim Ingham break; 20223acdf385SJim Ingham } 2023e14dc268SJim Ingham default: 202436162014SRaphael Isemann llvm_unreachable("Unimplemented option"); 2025e14dc268SJim Ingham } 2026e14dc268SJim Ingham 2027e14dc268SJim Ingham return error; 2028e14dc268SJim Ingham } 2029e14dc268SJim Ingham 2030e14dc268SJim Ingham void OptionParsingStarting(ExecutionContext *execution_context) override { 2031e14dc268SJim Ingham m_filename.clear(); 20323acdf385SJim Ingham m_names.clear(); 2033e14dc268SJim Ingham } 2034e14dc268SJim Ingham 20351f0f5b5bSZachary Turner llvm::ArrayRef<OptionDefinition> GetDefinitions() override { 203670602439SZachary Turner return llvm::makeArrayRef(g_breakpoint_read_options); 20371f0f5b5bSZachary Turner } 2038e14dc268SJim Ingham 2039e14dc268SJim Ingham // Instance variables to hold the values for command options. 2040e14dc268SJim Ingham 2041e14dc268SJim Ingham std::string m_filename; 20423acdf385SJim Ingham std::vector<std::string> m_names; 2043e14dc268SJim Ingham }; 2044e14dc268SJim Ingham 2045e14dc268SJim Ingham protected: 2046e14dc268SJim Ingham bool DoExecute(Args &command, CommandReturnObject &result) override { 2047cb2380c9SRaphael Isemann Target &target = GetSelectedOrDummyTarget(); 2048e14dc268SJim Ingham 20493acdf385SJim Ingham std::unique_lock<std::recursive_mutex> lock; 2050cb2380c9SRaphael Isemann target.GetBreakpointList().GetListMutex(lock); 20513acdf385SJim Ingham 20528f3be7a3SJonas Devlieghere FileSpec input_spec(m_options.m_filename); 20538f3be7a3SJonas Devlieghere FileSystem::Instance().Resolve(input_spec); 205401f16664SJim Ingham BreakpointIDList new_bps; 2055cb2380c9SRaphael Isemann Status error = target.CreateBreakpointsFromFile(input_spec, 2056cb2380c9SRaphael Isemann m_options.m_names, new_bps); 2057e14dc268SJim Ingham 2058e14dc268SJim Ingham if (!error.Success()) { 205901f16664SJim Ingham result.AppendError(error.AsCString()); 2060e14dc268SJim Ingham result.SetStatus(eReturnStatusFailed); 206101f16664SJim Ingham return false; 2062e14dc268SJim Ingham } 20633acdf385SJim Ingham 20643acdf385SJim Ingham Stream &output_stream = result.GetOutputStream(); 20653acdf385SJim Ingham 20663acdf385SJim Ingham size_t num_breakpoints = new_bps.GetSize(); 20673acdf385SJim Ingham if (num_breakpoints == 0) { 20683acdf385SJim Ingham result.AppendMessage("No breakpoints added."); 20693acdf385SJim Ingham } else { 20703acdf385SJim Ingham // No breakpoint selected; show info about all currently set breakpoints. 20713acdf385SJim Ingham result.AppendMessage("New breakpoints:"); 20723acdf385SJim Ingham for (size_t i = 0; i < num_breakpoints; ++i) { 20733acdf385SJim Ingham BreakpointID bp_id = new_bps.GetBreakpointIDAtIndex(i); 2074cb2380c9SRaphael Isemann Breakpoint *bp = target.GetBreakpointList() 20753acdf385SJim Ingham .FindBreakpointByID(bp_id.GetBreakpointID()) 20763acdf385SJim Ingham .get(); 20773acdf385SJim Ingham if (bp) 20783acdf385SJim Ingham bp->GetDescription(&output_stream, lldb::eDescriptionLevelInitial, 20793acdf385SJim Ingham false); 20803acdf385SJim Ingham } 20813acdf385SJim Ingham } 2082e14dc268SJim Ingham return result.Succeeded(); 2083e14dc268SJim Ingham } 2084e14dc268SJim Ingham 2085e14dc268SJim Ingham private: 2086e14dc268SJim Ingham CommandOptions m_options; 2087e14dc268SJim Ingham }; 2088e14dc268SJim Ingham 2089e14dc268SJim Ingham // CommandObjectBreakpointWrite 20901f0f5b5bSZachary Turner #pragma mark Write::CommandOptions 2091f94668e3SRaphael Isemann #define LLDB_OPTIONS_breakpoint_write 2092f94668e3SRaphael Isemann #include "CommandOptions.inc" 20931f0f5b5bSZachary Turner 20941f0f5b5bSZachary Turner #pragma mark Write 2095e14dc268SJim Ingham class CommandObjectBreakpointWrite : public CommandObjectParsed { 2096e14dc268SJim Ingham public: 2097e14dc268SJim Ingham CommandObjectBreakpointWrite(CommandInterpreter &interpreter) 2098e14dc268SJim Ingham : CommandObjectParsed(interpreter, "breakpoint write", 2099e14dc268SJim Ingham "Write the breakpoints listed to a file that can " 2100e14dc268SJim Ingham "be read in with \"breakpoint read\". " 2101e14dc268SJim Ingham "If given no arguments, writes all breakpoints.", 2102e14dc268SJim Ingham nullptr), 2103e14dc268SJim Ingham m_options() { 2104e14dc268SJim Ingham CommandArgumentEntry arg; 2105e14dc268SJim Ingham CommandObject::AddIDsArgumentData(arg, eArgTypeBreakpointID, 2106e14dc268SJim Ingham eArgTypeBreakpointIDRange); 2107e14dc268SJim Ingham // Add the entry for the first argument for this command to the object's 2108e14dc268SJim Ingham // arguments vector. 2109e14dc268SJim Ingham m_arguments.push_back(arg); 2110e14dc268SJim Ingham } 2111e14dc268SJim Ingham 2112e14dc268SJim Ingham ~CommandObjectBreakpointWrite() override = default; 2113e14dc268SJim Ingham 2114e14dc268SJim Ingham Options *GetOptions() override { return &m_options; } 2115e14dc268SJim Ingham 2116e14dc268SJim Ingham class CommandOptions : public Options { 2117e14dc268SJim Ingham public: 2118e14dc268SJim Ingham CommandOptions() : Options() {} 2119e14dc268SJim Ingham 2120e14dc268SJim Ingham ~CommandOptions() override = default; 2121e14dc268SJim Ingham 212297206d57SZachary Turner Status SetOptionValue(uint32_t option_idx, llvm::StringRef option_arg, 2123e14dc268SJim Ingham ExecutionContext *execution_context) override { 212497206d57SZachary Turner Status error; 2125e14dc268SJim Ingham const int short_option = m_getopt_table[option_idx].val; 2126e14dc268SJim Ingham 2127e14dc268SJim Ingham switch (short_option) { 2128e14dc268SJim Ingham case 'f': 2129e14dc268SJim Ingham m_filename.assign(option_arg); 2130e14dc268SJim Ingham break; 21312d3628e1SJim Ingham case 'a': 21322d3628e1SJim Ingham m_append = true; 21332d3628e1SJim Ingham break; 2134e14dc268SJim Ingham default: 213536162014SRaphael Isemann llvm_unreachable("Unimplemented option"); 2136e14dc268SJim Ingham } 2137e14dc268SJim Ingham 2138e14dc268SJim Ingham return error; 2139e14dc268SJim Ingham } 2140e14dc268SJim Ingham 2141e14dc268SJim Ingham void OptionParsingStarting(ExecutionContext *execution_context) override { 2142e14dc268SJim Ingham m_filename.clear(); 21432d3628e1SJim Ingham m_append = false; 2144e14dc268SJim Ingham } 2145e14dc268SJim Ingham 21461f0f5b5bSZachary Turner llvm::ArrayRef<OptionDefinition> GetDefinitions() override { 214770602439SZachary Turner return llvm::makeArrayRef(g_breakpoint_write_options); 21481f0f5b5bSZachary Turner } 2149e14dc268SJim Ingham 2150e14dc268SJim Ingham // Instance variables to hold the values for command options. 2151e14dc268SJim Ingham 2152e14dc268SJim Ingham std::string m_filename; 21532d3628e1SJim Ingham bool m_append = false; 2154e14dc268SJim Ingham }; 2155e14dc268SJim Ingham 2156e14dc268SJim Ingham protected: 2157e14dc268SJim Ingham bool DoExecute(Args &command, CommandReturnObject &result) override { 2158cb2380c9SRaphael Isemann Target &target = GetSelectedOrDummyTarget(); 2159e14dc268SJim Ingham 2160e14dc268SJim Ingham std::unique_lock<std::recursive_mutex> lock; 2161cb2380c9SRaphael Isemann target.GetBreakpointList().GetListMutex(lock); 2162e14dc268SJim Ingham 2163e14dc268SJim Ingham BreakpointIDList valid_bp_ids; 216411eb9c64SZachary Turner if (!command.empty()) { 2165e14dc268SJim Ingham CommandObjectMultiwordBreakpoint::VerifyBreakpointIDs( 2166cb2380c9SRaphael Isemann command, &target, result, &valid_bp_ids, 2167b842f2ecSJim Ingham BreakpointName::Permissions::PermissionKinds::listPerm); 2168e14dc268SJim Ingham 216901f16664SJim Ingham if (!result.Succeeded()) { 2170e14dc268SJim Ingham result.SetStatus(eReturnStatusFailed); 2171e14dc268SJim Ingham return false; 2172e14dc268SJim Ingham } 2173e14dc268SJim Ingham } 21748f3be7a3SJonas Devlieghere FileSpec file_spec(m_options.m_filename); 21758f3be7a3SJonas Devlieghere FileSystem::Instance().Resolve(file_spec); 2176cb2380c9SRaphael Isemann Status error = target.SerializeBreakpointsToFile(file_spec, valid_bp_ids, 21778f3be7a3SJonas Devlieghere m_options.m_append); 217801f16664SJim Ingham if (!error.Success()) { 217901f16664SJim Ingham result.AppendErrorWithFormat("error serializing breakpoints: %s.", 218001f16664SJim Ingham error.AsCString()); 218101f16664SJim Ingham result.SetStatus(eReturnStatusFailed); 2182e14dc268SJim Ingham } 2183e14dc268SJim Ingham return result.Succeeded(); 2184e14dc268SJim Ingham } 2185e14dc268SJim Ingham 2186e14dc268SJim Ingham private: 2187e14dc268SJim Ingham CommandOptions m_options; 2188e14dc268SJim Ingham }; 2189e14dc268SJim Ingham 219030fdc8d8SChris Lattner // CommandObjectMultiwordBreakpoint 2191ae1c4cf5SJim Ingham #pragma mark MultiwordBreakpoint 219230fdc8d8SChris Lattner 2193b9c1b51eSKate Stone CommandObjectMultiwordBreakpoint::CommandObjectMultiwordBreakpoint( 2194b9c1b51eSKate Stone CommandInterpreter &interpreter) 2195b9c1b51eSKate Stone : CommandObjectMultiword( 2196b9c1b51eSKate Stone interpreter, "breakpoint", 21977428a18cSKate Stone "Commands for operating on breakpoints (see 'help b' for shorthand.)", 2198b9c1b51eSKate Stone "breakpoint <subcommand> [<command-options>]") { 2199b9c1b51eSKate Stone CommandObjectSP list_command_object( 2200b9c1b51eSKate Stone new CommandObjectBreakpointList(interpreter)); 2201b9c1b51eSKate Stone CommandObjectSP enable_command_object( 2202b9c1b51eSKate Stone new CommandObjectBreakpointEnable(interpreter)); 2203b9c1b51eSKate Stone CommandObjectSP disable_command_object( 2204b9c1b51eSKate Stone new CommandObjectBreakpointDisable(interpreter)); 2205b9c1b51eSKate Stone CommandObjectSP clear_command_object( 2206b9c1b51eSKate Stone new CommandObjectBreakpointClear(interpreter)); 2207b9c1b51eSKate Stone CommandObjectSP delete_command_object( 2208b9c1b51eSKate Stone new CommandObjectBreakpointDelete(interpreter)); 2209b9c1b51eSKate Stone CommandObjectSP set_command_object( 2210b9c1b51eSKate Stone new CommandObjectBreakpointSet(interpreter)); 2211b9c1b51eSKate Stone CommandObjectSP command_command_object( 2212b9c1b51eSKate Stone new CommandObjectBreakpointCommand(interpreter)); 2213b9c1b51eSKate Stone CommandObjectSP modify_command_object( 2214b9c1b51eSKate Stone new CommandObjectBreakpointModify(interpreter)); 2215b9c1b51eSKate Stone CommandObjectSP name_command_object( 2216b9c1b51eSKate Stone new CommandObjectBreakpointName(interpreter)); 2217e14dc268SJim Ingham CommandObjectSP write_command_object( 2218e14dc268SJim Ingham new CommandObjectBreakpointWrite(interpreter)); 2219e14dc268SJim Ingham CommandObjectSP read_command_object( 2220e14dc268SJim Ingham new CommandObjectBreakpointRead(interpreter)); 222130fdc8d8SChris Lattner 2222b7234e40SJohnny Chen list_command_object->SetCommandName("breakpoint list"); 222330fdc8d8SChris Lattner enable_command_object->SetCommandName("breakpoint enable"); 222430fdc8d8SChris Lattner disable_command_object->SetCommandName("breakpoint disable"); 2225b7234e40SJohnny Chen clear_command_object->SetCommandName("breakpoint clear"); 2226b7234e40SJohnny Chen delete_command_object->SetCommandName("breakpoint delete"); 2227ae1c4cf5SJim Ingham set_command_object->SetCommandName("breakpoint set"); 2228b7234e40SJohnny Chen command_command_object->SetCommandName("breakpoint command"); 2229b7234e40SJohnny Chen modify_command_object->SetCommandName("breakpoint modify"); 22305e09c8c3SJim Ingham name_command_object->SetCommandName("breakpoint name"); 2231e14dc268SJim Ingham write_command_object->SetCommandName("breakpoint write"); 2232e14dc268SJim Ingham read_command_object->SetCommandName("breakpoint read"); 223330fdc8d8SChris Lattner 223423f59509SGreg Clayton LoadSubCommand("list", list_command_object); 223523f59509SGreg Clayton LoadSubCommand("enable", enable_command_object); 223623f59509SGreg Clayton LoadSubCommand("disable", disable_command_object); 223723f59509SGreg Clayton LoadSubCommand("clear", clear_command_object); 223823f59509SGreg Clayton LoadSubCommand("delete", delete_command_object); 223923f59509SGreg Clayton LoadSubCommand("set", set_command_object); 224023f59509SGreg Clayton LoadSubCommand("command", command_command_object); 224123f59509SGreg Clayton LoadSubCommand("modify", modify_command_object); 22425e09c8c3SJim Ingham LoadSubCommand("name", name_command_object); 2243e14dc268SJim Ingham LoadSubCommand("write", write_command_object); 2244e14dc268SJim Ingham LoadSubCommand("read", read_command_object); 224530fdc8d8SChris Lattner } 224630fdc8d8SChris Lattner 22479e85e5a8SEugene Zelenko CommandObjectMultiwordBreakpoint::~CommandObjectMultiwordBreakpoint() = default; 224830fdc8d8SChris Lattner 2249*a925974bSAdrian Prantl void CommandObjectMultiwordBreakpoint::VerifyIDs( 2250*a925974bSAdrian Prantl Args &args, Target *target, bool allow_locations, 2251*a925974bSAdrian Prantl CommandReturnObject &result, BreakpointIDList *valid_ids, 2252*a925974bSAdrian Prantl BreakpointName::Permissions ::PermissionKinds purpose) { 225330fdc8d8SChris Lattner // args can be strings representing 1). integers (for breakpoint ids) 2254b9c1b51eSKate Stone // 2). the full breakpoint & location 2255b9c1b51eSKate Stone // canonical representation 2256b9c1b51eSKate Stone // 3). the word "to" or a hyphen, 2257b9c1b51eSKate Stone // representing a range (in which case there 2258b9c1b51eSKate Stone // had *better* be an entry both before & 2259b9c1b51eSKate Stone // after of one of the first two types. 22605e09c8c3SJim Ingham // 4). A breakpoint name 2261b9c1b51eSKate Stone // If args is empty, we will use the last created breakpoint (if there is 2262b9c1b51eSKate Stone // one.) 226330fdc8d8SChris Lattner 226430fdc8d8SChris Lattner Args temp_args; 226530fdc8d8SChris Lattner 226611eb9c64SZachary Turner if (args.empty()) { 2267b9c1b51eSKate Stone if (target->GetLastCreatedBreakpoint()) { 2268b9c1b51eSKate Stone valid_ids->AddBreakpointID(BreakpointID( 2269b9c1b51eSKate Stone target->GetLastCreatedBreakpoint()->GetID(), LLDB_INVALID_BREAK_ID)); 227036f3b369SJim Ingham result.SetStatus(eReturnStatusSuccessFinishNoResult); 2271b9c1b51eSKate Stone } else { 2272b9c1b51eSKate Stone result.AppendError( 2273b9c1b51eSKate Stone "No breakpoint specified and no last created breakpoint."); 227436f3b369SJim Ingham result.SetStatus(eReturnStatusFailed); 227536f3b369SJim Ingham } 227636f3b369SJim Ingham return; 227736f3b369SJim Ingham } 227836f3b369SJim Ingham 2279b9c1b51eSKate Stone // Create a new Args variable to use; copy any non-breakpoint-id-ranges stuff 228005097246SAdrian Prantl // directly from the old ARGS to the new TEMP_ARGS. Do not copy breakpoint 228105097246SAdrian Prantl // id range strings over; instead generate a list of strings for all the 228205097246SAdrian Prantl // breakpoint ids in the range, and shove all of those breakpoint id strings 228305097246SAdrian Prantl // into TEMP_ARGS. 228430fdc8d8SChris Lattner 2285b9c1b51eSKate Stone BreakpointIDList::FindAndReplaceIDRanges(args, target, allow_locations, 2286b842f2ecSJim Ingham purpose, result, temp_args); 228730fdc8d8SChris Lattner 2288b9c1b51eSKate Stone // NOW, convert the list of breakpoint id strings in TEMP_ARGS into an actual 2289b9c1b51eSKate Stone // BreakpointIDList: 229030fdc8d8SChris Lattner 229116662f3cSPavel Labath valid_ids->InsertStringArray(temp_args.GetArgumentArrayRef(), result); 229230fdc8d8SChris Lattner 229305097246SAdrian Prantl // At this point, all of the breakpoint ids that the user passed in have 229405097246SAdrian Prantl // been converted to breakpoint IDs and put into valid_ids. 229530fdc8d8SChris Lattner 2296b9c1b51eSKate Stone if (result.Succeeded()) { 2297b9c1b51eSKate Stone // Now that we've converted everything from args into a list of breakpoint 229805097246SAdrian Prantl // ids, go through our tentative list of breakpoint id's and verify that 229905097246SAdrian Prantl // they correspond to valid/currently set breakpoints. 230030fdc8d8SChris Lattner 2301c982c768SGreg Clayton const size_t count = valid_ids->GetSize(); 2302b9c1b51eSKate Stone for (size_t i = 0; i < count; ++i) { 230330fdc8d8SChris Lattner BreakpointID cur_bp_id = valid_ids->GetBreakpointIDAtIndex(i); 2304b9c1b51eSKate Stone Breakpoint *breakpoint = 2305b9c1b51eSKate Stone target->GetBreakpointByID(cur_bp_id.GetBreakpointID()).get(); 2306b9c1b51eSKate Stone if (breakpoint != nullptr) { 2307c7bece56SGreg Clayton const size_t num_locations = breakpoint->GetNumLocations(); 2308b9c1b51eSKate Stone if (static_cast<size_t>(cur_bp_id.GetLocationID()) > num_locations) { 230930fdc8d8SChris Lattner StreamString id_str; 2310b9c1b51eSKate Stone BreakpointID::GetCanonicalReference( 2311b9c1b51eSKate Stone &id_str, cur_bp_id.GetBreakpointID(), cur_bp_id.GetLocationID()); 2312c982c768SGreg Clayton i = valid_ids->GetSize() + 1; 2313b9c1b51eSKate Stone result.AppendErrorWithFormat( 2314b9c1b51eSKate Stone "'%s' is not a currently valid breakpoint/location id.\n", 231530fdc8d8SChris Lattner id_str.GetData()); 231630fdc8d8SChris Lattner result.SetStatus(eReturnStatusFailed); 231730fdc8d8SChris Lattner } 2318b9c1b51eSKate Stone } else { 2319c982c768SGreg Clayton i = valid_ids->GetSize() + 1; 2320b9c1b51eSKate Stone result.AppendErrorWithFormat( 2321b9c1b51eSKate Stone "'%d' is not a currently valid breakpoint ID.\n", 23227428a18cSKate Stone cur_bp_id.GetBreakpointID()); 232330fdc8d8SChris Lattner result.SetStatus(eReturnStatusFailed); 232430fdc8d8SChris Lattner } 232530fdc8d8SChris Lattner } 232630fdc8d8SChris Lattner } 232730fdc8d8SChris Lattner } 2328