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 51a925974bSAdrian Prantl class lldb_private::BreakpointOptionGroup : public OptionGroup { 52b842f2ecSJim Ingham public: 53a925974bSAdrian 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; 64a925974bSAdrian Prantl const int short_option = 65a925974bSAdrian 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()); 92a925974bSAdrian Prantl } break; 93a925974bSAdrian 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); 100a925974bSAdrian 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; 111a925974bSAdrian 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); 119a925974bSAdrian 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; 126a925974bSAdrian 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); 134a925974bSAdrian 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 { 148a925974bSAdrian Prantl if (!m_commands.empty()) { 149a8f3ae7cSJonas Devlieghere auto cmd_data = std::make_unique<BreakpointOptions::CommandData>(); 150b842f2ecSJim Ingham 151b842f2ecSJim Ingham for (std::string &str : m_commands) 152b842f2ecSJim Ingham cmd_data->user_source.AppendString(str); 153b842f2ecSJim Ingham 154b842f2ecSJim Ingham cmd_data->stop_on_error = true; 155b842f2ecSJim Ingham m_bp_opts.SetCommandDataCallback(cmd_data); 156b842f2ecSJim Ingham } 157b842f2ecSJim Ingham return Status(); 158b842f2ecSJim Ingham } 159b842f2ecSJim Ingham 160a925974bSAdrian Prantl const BreakpointOptions &GetBreakpointOptions() { return m_bp_opts; } 161b842f2ecSJim Ingham 162b842f2ecSJim Ingham std::vector<std::string> m_commands; 163b842f2ecSJim Ingham BreakpointOptions m_bp_opts; 164b842f2ecSJim Ingham }; 165bd68a052SRaphael Isemann 166f94668e3SRaphael Isemann #define LLDB_OPTIONS_breakpoint_dummy 167f94668e3SRaphael Isemann #include "CommandOptions.inc" 168b842f2ecSJim Ingham 169a925974bSAdrian Prantl class BreakpointDummyOptionGroup : public OptionGroup { 170b842f2ecSJim Ingham public: 171a925974bSAdrian Prantl BreakpointDummyOptionGroup() : OptionGroup() {} 172b842f2ecSJim Ingham 173b842f2ecSJim Ingham ~BreakpointDummyOptionGroup() override = default; 174b842f2ecSJim Ingham 175b842f2ecSJim Ingham llvm::ArrayRef<OptionDefinition> GetDefinitions() override { 176b842f2ecSJim Ingham return llvm::makeArrayRef(g_breakpoint_dummy_options); 177b842f2ecSJim Ingham } 178b842f2ecSJim Ingham 179b842f2ecSJim Ingham Status SetOptionValue(uint32_t option_idx, llvm::StringRef option_arg, 180b842f2ecSJim Ingham ExecutionContext *execution_context) override { 181b842f2ecSJim Ingham Status error; 182a925974bSAdrian Prantl const int short_option = 183*f1539b9dSJim Ingham g_breakpoint_dummy_options[option_idx].short_option; 184b842f2ecSJim Ingham 185b842f2ecSJim Ingham switch (short_option) { 186b842f2ecSJim Ingham case 'D': 187b842f2ecSJim Ingham m_use_dummy = true; 188b842f2ecSJim Ingham break; 189b842f2ecSJim Ingham default: 19036162014SRaphael Isemann llvm_unreachable("Unimplemented option"); 191b842f2ecSJim Ingham } 192b842f2ecSJim Ingham 193b842f2ecSJim Ingham return error; 194b842f2ecSJim Ingham } 195b842f2ecSJim Ingham 196b842f2ecSJim Ingham void OptionParsingStarting(ExecutionContext *execution_context) override { 197b842f2ecSJim Ingham m_use_dummy = false; 198b842f2ecSJim Ingham } 199b842f2ecSJim Ingham 200b842f2ecSJim Ingham bool m_use_dummy; 201b842f2ecSJim Ingham }; 202b842f2ecSJim Ingham 203f94668e3SRaphael Isemann #define LLDB_OPTIONS_breakpoint_set 204f94668e3SRaphael Isemann #include "CommandOptions.inc" 2051f0f5b5bSZachary Turner 2065a988416SJim Ingham // CommandObjectBreakpointSet 20730fdc8d8SChris Lattner 208b9c1b51eSKate Stone class CommandObjectBreakpointSet : public CommandObjectParsed { 2095a988416SJim Ingham public: 210efe8e7e3SFangrui Song enum BreakpointSetType { 2115a988416SJim Ingham eSetTypeInvalid, 2125a988416SJim Ingham eSetTypeFileAndLine, 2135a988416SJim Ingham eSetTypeAddress, 2145a988416SJim Ingham eSetTypeFunctionName, 2155a988416SJim Ingham eSetTypeFunctionRegexp, 2165a988416SJim Ingham eSetTypeSourceRegexp, 2173815e702SJim Ingham eSetTypeException, 2183815e702SJim Ingham eSetTypeScripted, 219efe8e7e3SFangrui Song }; 2205a988416SJim Ingham 221b9c1b51eSKate Stone CommandObjectBreakpointSet(CommandInterpreter &interpreter) 222b9c1b51eSKate Stone : CommandObjectParsed( 223b9c1b51eSKate Stone interpreter, "breakpoint set", 2245a988416SJim Ingham "Sets a breakpoint or set of breakpoints in the executable.", 2255a988416SJim Ingham "breakpoint set <cmd-options>"), 226738af7a6SJim Ingham m_bp_opts(), m_python_class_options("scripted breakpoint", true, 'P'), 227f6a2086dSSam McCall m_options() { 228b842f2ecSJim Ingham // We're picking up all the normal options, commands and disable. 229a925974bSAdrian Prantl m_all_options.Append(&m_python_class_options, 230a925974bSAdrian Prantl LLDB_OPT_SET_1 | LLDB_OPT_SET_2, LLDB_OPT_SET_11); 231b842f2ecSJim Ingham m_all_options.Append(&m_bp_opts, 232b842f2ecSJim Ingham LLDB_OPT_SET_1 | LLDB_OPT_SET_3 | LLDB_OPT_SET_4, 233b842f2ecSJim Ingham LLDB_OPT_SET_ALL); 234f6a2086dSSam McCall m_all_options.Append(&m_dummy_options, LLDB_OPT_SET_1, LLDB_OPT_SET_ALL); 235b842f2ecSJim Ingham m_all_options.Append(&m_options); 236b842f2ecSJim Ingham m_all_options.Finalize(); 237b842f2ecSJim Ingham } 2385a988416SJim Ingham 2399e85e5a8SEugene Zelenko ~CommandObjectBreakpointSet() override = default; 2405a988416SJim Ingham 241b842f2ecSJim Ingham Options *GetOptions() override { return &m_all_options; } 2425a988416SJim Ingham 243b842f2ecSJim Ingham class CommandOptions : public OptionGroup { 2445a988416SJim Ingham public: 245b9c1b51eSKate Stone CommandOptions() 246a925974bSAdrian Prantl : OptionGroup(), m_condition(), m_filenames(), m_line_num(0), 247a925974bSAdrian Prantl m_column(0), m_func_names(), 248a925974bSAdrian Prantl m_func_name_type_mask(eFunctionNameTypeNone), m_func_regexp(), 249a925974bSAdrian Prantl m_source_text_regexp(), m_modules(), m_load_addr(), m_catch_bp(false), 250a925974bSAdrian Prantl m_throw_bp(true), m_hardware(false), 251a72b31c7SJim Ingham m_exception_language(eLanguageTypeUnknown), 25223b1decbSDawn Perchik m_language(lldb::eLanguageTypeUnknown), 253a925974bSAdrian Prantl m_skip_prologue(eLazyBoolCalculate), m_all_files(false), 254a925974bSAdrian Prantl m_move_to_nearest_code(eLazyBoolCalculate) {} 25530fdc8d8SChris Lattner 2569e85e5a8SEugene Zelenko ~CommandOptions() override = default; 25787df91b8SJim Ingham 25897206d57SZachary Turner Status SetOptionValue(uint32_t option_idx, llvm::StringRef option_arg, 259b9c1b51eSKate Stone ExecutionContext *execution_context) override { 26097206d57SZachary Turner Status error; 261a925974bSAdrian Prantl const int short_option = 262a925974bSAdrian Prantl g_breakpoint_set_options[option_idx].short_option; 26330fdc8d8SChris Lattner 264b9c1b51eSKate Stone switch (short_option) { 265b9c1b51eSKate Stone case 'a': { 26647cbf4a0SPavel Labath m_load_addr = OptionArgParser::ToAddress(execution_context, option_arg, 267e1cfbc79STodd Fiala LLDB_INVALID_ADDRESS, &error); 268b9c1b51eSKate Stone } break; 26930fdc8d8SChris Lattner 270e732052fSJim Ingham case 'A': 271e732052fSJim Ingham m_all_files = true; 272e732052fSJim Ingham break; 273e732052fSJim Ingham 274ca36cd16SJim Ingham case 'b': 275ca36cd16SJim Ingham m_func_names.push_back(option_arg); 276ca36cd16SJim Ingham m_func_name_type_mask |= eFunctionNameTypeBase; 277ca36cd16SJim Ingham break; 278ca36cd16SJim Ingham 279fe11483bSZachary Turner case 'C': 280fe11483bSZachary Turner if (option_arg.getAsInteger(0, m_column)) 281b9c1b51eSKate Stone error.SetErrorStringWithFormat("invalid column number: %s", 282fe11483bSZachary Turner option_arg.str().c_str()); 28330fdc8d8SChris Lattner break; 2849e85e5a8SEugene Zelenko 285b9c1b51eSKate Stone case 'E': { 286fe11483bSZachary Turner LanguageType language = Language::GetLanguageTypeFromString(option_arg); 287fab10e89SJim Ingham 288b9c1b51eSKate Stone switch (language) { 289fab10e89SJim Ingham case eLanguageTypeC89: 290fab10e89SJim Ingham case eLanguageTypeC: 291fab10e89SJim Ingham case eLanguageTypeC99: 2921d0089faSBruce Mitchener case eLanguageTypeC11: 293a72b31c7SJim Ingham m_exception_language = eLanguageTypeC; 294fab10e89SJim Ingham break; 295fab10e89SJim Ingham case eLanguageTypeC_plus_plus: 2961d0089faSBruce Mitchener case eLanguageTypeC_plus_plus_03: 2971d0089faSBruce Mitchener case eLanguageTypeC_plus_plus_11: 2982ba84a6aSBruce Mitchener case eLanguageTypeC_plus_plus_14: 299a72b31c7SJim Ingham m_exception_language = eLanguageTypeC_plus_plus; 300fab10e89SJim Ingham break; 301fab10e89SJim Ingham case eLanguageTypeObjC: 302a72b31c7SJim Ingham m_exception_language = eLanguageTypeObjC; 303fab10e89SJim Ingham break; 304fab10e89SJim Ingham case eLanguageTypeObjC_plus_plus: 305b9c1b51eSKate Stone error.SetErrorStringWithFormat( 306b9c1b51eSKate Stone "Set exception breakpoints separately for c++ and objective-c"); 307fab10e89SJim Ingham break; 308fab10e89SJim Ingham case eLanguageTypeUnknown: 309b9c1b51eSKate Stone error.SetErrorStringWithFormat( 310b9c1b51eSKate Stone "Unknown language type: '%s' for exception breakpoint", 311fe11483bSZachary Turner option_arg.str().c_str()); 312fab10e89SJim Ingham break; 313fab10e89SJim Ingham default: 314b9c1b51eSKate Stone error.SetErrorStringWithFormat( 315b9c1b51eSKate Stone "Unsupported language type: '%s' for exception breakpoint", 316fe11483bSZachary Turner option_arg.str().c_str()); 317fab10e89SJim Ingham } 318b9c1b51eSKate Stone } break; 319ca36cd16SJim Ingham 320ca36cd16SJim Ingham case 'f': 3218f3be7a3SJonas Devlieghere m_filenames.AppendIfUnique(FileSpec(option_arg)); 322fab10e89SJim Ingham break; 323ca36cd16SJim Ingham 324ca36cd16SJim Ingham case 'F': 325ca36cd16SJim Ingham m_func_names.push_back(option_arg); 326ca36cd16SJim Ingham m_func_name_type_mask |= eFunctionNameTypeFull; 327ca36cd16SJim Ingham break; 328ca36cd16SJim Ingham 329b9c1b51eSKate Stone case 'h': { 330fab10e89SJim Ingham bool success; 33147cbf4a0SPavel Labath m_catch_bp = OptionArgParser::ToBoolean(option_arg, true, &success); 332fab10e89SJim Ingham if (!success) 333b9c1b51eSKate Stone error.SetErrorStringWithFormat( 334fe11483bSZachary Turner "Invalid boolean value for on-catch option: '%s'", 335fe11483bSZachary Turner option_arg.str().c_str()); 336b9c1b51eSKate Stone } break; 337eb023e75SGreg Clayton 338eb023e75SGreg Clayton case 'H': 339eb023e75SGreg Clayton m_hardware = true; 340eb023e75SGreg Clayton break; 341eb023e75SGreg Clayton 342b9c1b51eSKate Stone case 'K': { 343a8558b62SJim Ingham bool success; 344a8558b62SJim Ingham bool value; 34547cbf4a0SPavel Labath value = OptionArgParser::ToBoolean(option_arg, true, &success); 346a8558b62SJim Ingham if (value) 347a8558b62SJim Ingham m_skip_prologue = eLazyBoolYes; 348a8558b62SJim Ingham else 349a8558b62SJim Ingham m_skip_prologue = eLazyBoolNo; 350a8558b62SJim Ingham 351a8558b62SJim Ingham if (!success) 352b9c1b51eSKate Stone error.SetErrorStringWithFormat( 353b9c1b51eSKate Stone "Invalid boolean value for skip prologue option: '%s'", 354fe11483bSZachary Turner option_arg.str().c_str()); 355b9c1b51eSKate Stone } break; 356ca36cd16SJim Ingham 357fe11483bSZachary Turner case 'l': 358fe11483bSZachary Turner if (option_arg.getAsInteger(0, m_line_num)) 359b9c1b51eSKate Stone error.SetErrorStringWithFormat("invalid line number: %s.", 360fe11483bSZachary Turner option_arg.str().c_str()); 361ca36cd16SJim Ingham break; 362055ad9beSIlia K 36323b1decbSDawn Perchik case 'L': 364fe11483bSZachary Turner m_language = Language::GetLanguageTypeFromString(option_arg); 36523b1decbSDawn Perchik if (m_language == eLanguageTypeUnknown) 366b9c1b51eSKate Stone error.SetErrorStringWithFormat( 367fe11483bSZachary Turner "Unknown language type: '%s' for breakpoint", 368fe11483bSZachary Turner option_arg.str().c_str()); 36923b1decbSDawn Perchik break; 37023b1decbSDawn Perchik 371b9c1b51eSKate Stone case 'm': { 372055ad9beSIlia K bool success; 373055ad9beSIlia K bool value; 37447cbf4a0SPavel Labath value = OptionArgParser::ToBoolean(option_arg, true, &success); 375055ad9beSIlia K if (value) 376055ad9beSIlia K m_move_to_nearest_code = eLazyBoolYes; 377055ad9beSIlia K else 378055ad9beSIlia K m_move_to_nearest_code = eLazyBoolNo; 379055ad9beSIlia K 380055ad9beSIlia K if (!success) 381b9c1b51eSKate Stone error.SetErrorStringWithFormat( 382b9c1b51eSKate Stone "Invalid boolean value for move-to-nearest-code option: '%s'", 383fe11483bSZachary Turner option_arg.str().c_str()); 384055ad9beSIlia K break; 385055ad9beSIlia K } 386055ad9beSIlia K 387ca36cd16SJim Ingham case 'M': 388ca36cd16SJim Ingham m_func_names.push_back(option_arg); 389ca36cd16SJim Ingham m_func_name_type_mask |= eFunctionNameTypeMethod; 390ca36cd16SJim Ingham break; 391ca36cd16SJim Ingham 392ca36cd16SJim Ingham case 'n': 393ca36cd16SJim Ingham m_func_names.push_back(option_arg); 394ca36cd16SJim Ingham m_func_name_type_mask |= eFunctionNameTypeAuto; 395ca36cd16SJim Ingham break; 396ca36cd16SJim Ingham 3976fa7681bSZachary Turner case 'N': { 398fe11483bSZachary Turner if (BreakpointID::StringIsBreakpointName(option_arg, error)) 3995e09c8c3SJim Ingham m_breakpoint_names.push_back(option_arg); 400ff9a91eaSJim Ingham else 401ff9a91eaSJim Ingham error.SetErrorStringWithFormat("Invalid breakpoint name: %s", 402fe11483bSZachary Turner option_arg.str().c_str()); 4035e09c8c3SJim Ingham break; 4046fa7681bSZachary Turner } 4055e09c8c3SJim Ingham 406b9c1b51eSKate Stone case 'R': { 4072411167fSJim Ingham lldb::addr_t tmp_offset_addr; 40847cbf4a0SPavel Labath tmp_offset_addr = OptionArgParser::ToAddress(execution_context, 40947cbf4a0SPavel Labath option_arg, 0, &error); 4102411167fSJim Ingham if (error.Success()) 4112411167fSJim Ingham m_offset_addr = tmp_offset_addr; 412b9c1b51eSKate Stone } break; 4132411167fSJim Ingham 414a72b31c7SJim Ingham case 'O': 415fe11483bSZachary Turner m_exception_extra_args.AppendArgument("-O"); 416fe11483bSZachary Turner m_exception_extra_args.AppendArgument(option_arg); 417a72b31c7SJim Ingham break; 418a72b31c7SJim Ingham 419ca36cd16SJim Ingham case 'p': 420ca36cd16SJim Ingham m_source_text_regexp.assign(option_arg); 421ca36cd16SJim Ingham break; 422ca36cd16SJim Ingham 423ca36cd16SJim Ingham case 'r': 424ca36cd16SJim Ingham m_func_regexp.assign(option_arg); 425ca36cd16SJim Ingham break; 426ca36cd16SJim Ingham 427ca36cd16SJim Ingham case 's': 4288f3be7a3SJonas Devlieghere m_modules.AppendIfUnique(FileSpec(option_arg)); 429ca36cd16SJim Ingham break; 430ca36cd16SJim Ingham 431ca36cd16SJim Ingham case 'S': 432ca36cd16SJim Ingham m_func_names.push_back(option_arg); 433ca36cd16SJim Ingham m_func_name_type_mask |= eFunctionNameTypeSelector; 434ca36cd16SJim Ingham break; 435ca36cd16SJim Ingham 436b9c1b51eSKate Stone case 'w': { 437ca36cd16SJim Ingham bool success; 43847cbf4a0SPavel Labath m_throw_bp = OptionArgParser::ToBoolean(option_arg, true, &success); 439ca36cd16SJim Ingham if (!success) 440b9c1b51eSKate Stone error.SetErrorStringWithFormat( 441fe11483bSZachary Turner "Invalid boolean value for on-throw option: '%s'", 442fe11483bSZachary Turner option_arg.str().c_str()); 443b9c1b51eSKate Stone } break; 444ca36cd16SJim Ingham 44576bb8d67SJim Ingham case 'X': 44676bb8d67SJim Ingham m_source_regex_func_names.insert(option_arg); 44776bb8d67SJim Ingham break; 44876bb8d67SJim Ingham 44930fdc8d8SChris Lattner default: 45036162014SRaphael Isemann llvm_unreachable("Unimplemented option"); 45130fdc8d8SChris Lattner } 45230fdc8d8SChris Lattner 45330fdc8d8SChris Lattner return error; 45430fdc8d8SChris Lattner } 4559e85e5a8SEugene Zelenko 456b9c1b51eSKate Stone void OptionParsingStarting(ExecutionContext *execution_context) override { 45787df91b8SJim Ingham m_filenames.Clear(); 45830fdc8d8SChris Lattner m_line_num = 0; 45930fdc8d8SChris Lattner m_column = 0; 460fab10e89SJim Ingham m_func_names.clear(); 4611f746071SGreg Clayton m_func_name_type_mask = eFunctionNameTypeNone; 46230fdc8d8SChris Lattner m_func_regexp.clear(); 4631f746071SGreg Clayton m_source_text_regexp.clear(); 46487df91b8SJim Ingham m_modules.Clear(); 4651f746071SGreg Clayton m_load_addr = LLDB_INVALID_ADDRESS; 4662411167fSJim Ingham m_offset_addr = 0; 467fab10e89SJim Ingham m_catch_bp = false; 468fab10e89SJim Ingham m_throw_bp = true; 469eb023e75SGreg Clayton m_hardware = false; 470a72b31c7SJim Ingham m_exception_language = eLanguageTypeUnknown; 47123b1decbSDawn Perchik m_language = lldb::eLanguageTypeUnknown; 472a8558b62SJim Ingham m_skip_prologue = eLazyBoolCalculate; 4735e09c8c3SJim Ingham m_breakpoint_names.clear(); 474e732052fSJim Ingham m_all_files = false; 475a72b31c7SJim Ingham m_exception_extra_args.Clear(); 476055ad9beSIlia K m_move_to_nearest_code = eLazyBoolCalculate; 47776bb8d67SJim Ingham m_source_regex_func_names.clear(); 4783815e702SJim Ingham m_current_key.clear(); 47930fdc8d8SChris Lattner } 48030fdc8d8SChris Lattner 4811f0f5b5bSZachary Turner llvm::ArrayRef<OptionDefinition> GetDefinitions() override { 48270602439SZachary Turner return llvm::makeArrayRef(g_breakpoint_set_options); 4831f0f5b5bSZachary Turner } 48430fdc8d8SChris Lattner 4855a988416SJim Ingham // Instance variables to hold the values for command options. 486969795f1SJim Ingham 4875a988416SJim Ingham std::string m_condition; 4885a988416SJim Ingham FileSpecList m_filenames; 4895a988416SJim Ingham uint32_t m_line_num; 4905a988416SJim Ingham uint32_t m_column; 4915a988416SJim Ingham std::vector<std::string> m_func_names; 4925e09c8c3SJim Ingham std::vector<std::string> m_breakpoint_names; 493117b1fa1SZachary Turner lldb::FunctionNameType m_func_name_type_mask; 4945a988416SJim Ingham std::string m_func_regexp; 4955a988416SJim Ingham std::string m_source_text_regexp; 4965a988416SJim Ingham FileSpecList m_modules; 4975a988416SJim Ingham lldb::addr_t m_load_addr; 4982411167fSJim Ingham lldb::addr_t m_offset_addr; 4995a988416SJim Ingham bool m_catch_bp; 5005a988416SJim Ingham bool m_throw_bp; 501eb023e75SGreg Clayton bool m_hardware; // Request to use hardware breakpoints 502a72b31c7SJim Ingham lldb::LanguageType m_exception_language; 50323b1decbSDawn Perchik lldb::LanguageType m_language; 5045a988416SJim Ingham LazyBool m_skip_prologue; 505e732052fSJim Ingham bool m_all_files; 506a72b31c7SJim Ingham Args m_exception_extra_args; 507055ad9beSIlia K LazyBool m_move_to_nearest_code; 50876bb8d67SJim Ingham std::unordered_set<std::string> m_source_regex_func_names; 5093815e702SJim Ingham std::string m_current_key; 5105a988416SJim Ingham }; 5115a988416SJim Ingham 5125a988416SJim Ingham protected: 513b9c1b51eSKate Stone bool DoExecute(Args &command, CommandReturnObject &result) override { 514cb2380c9SRaphael Isemann Target &target = GetSelectedOrDummyTarget(m_dummy_options.m_use_dummy); 51530fdc8d8SChris Lattner 51630fdc8d8SChris Lattner // The following are the various types of breakpoints that could be set: 51730fdc8d8SChris Lattner // 1). -f -l -p [-s -g] (setting breakpoint by source location) 51830fdc8d8SChris Lattner // 2). -a [-s -g] (setting breakpoint by address) 51930fdc8d8SChris Lattner // 3). -n [-s -g] (setting breakpoint by function name) 520b9c1b51eSKate Stone // 4). -r [-s -g] (setting breakpoint by function name regular 521b9c1b51eSKate Stone // expression) 522b9c1b51eSKate Stone // 5). -p -f (setting a breakpoint by comparing a reg-exp 523b9c1b51eSKate Stone // to source text) 524b9c1b51eSKate Stone // 6). -E [-w -h] (setting a breakpoint for exceptions for a 525b9c1b51eSKate Stone // given language.) 52630fdc8d8SChris Lattner 52730fdc8d8SChris Lattner BreakpointSetType break_type = eSetTypeInvalid; 52830fdc8d8SChris Lattner 529738af7a6SJim Ingham if (!m_python_class_options.GetName().empty()) 5303815e702SJim Ingham break_type = eSetTypeScripted; 5313815e702SJim Ingham else if (m_options.m_line_num != 0) 53230fdc8d8SChris Lattner break_type = eSetTypeFileAndLine; 53330fdc8d8SChris Lattner else if (m_options.m_load_addr != LLDB_INVALID_ADDRESS) 53430fdc8d8SChris Lattner break_type = eSetTypeAddress; 535fab10e89SJim Ingham else if (!m_options.m_func_names.empty()) 53630fdc8d8SChris Lattner break_type = eSetTypeFunctionName; 53730fdc8d8SChris Lattner else if (!m_options.m_func_regexp.empty()) 53830fdc8d8SChris Lattner break_type = eSetTypeFunctionRegexp; 539969795f1SJim Ingham else if (!m_options.m_source_text_regexp.empty()) 540969795f1SJim Ingham break_type = eSetTypeSourceRegexp; 541a72b31c7SJim Ingham else if (m_options.m_exception_language != eLanguageTypeUnknown) 542fab10e89SJim Ingham break_type = eSetTypeException; 54330fdc8d8SChris Lattner 544b842f2ecSJim Ingham BreakpointSP bp_sp = nullptr; 545274060b6SGreg Clayton FileSpec module_spec; 546a8558b62SJim Ingham const bool internal = false; 547a8558b62SJim Ingham 548b9c1b51eSKate Stone // If the user didn't specify skip-prologue, having an offset should turn 549b9c1b51eSKate Stone // that off. 550b9c1b51eSKate Stone if (m_options.m_offset_addr != 0 && 551b9c1b51eSKate Stone m_options.m_skip_prologue == eLazyBoolCalculate) 5522411167fSJim Ingham m_options.m_skip_prologue = eLazyBoolNo; 5532411167fSJim Ingham 554b9c1b51eSKate Stone switch (break_type) { 55530fdc8d8SChris Lattner case eSetTypeFileAndLine: // Breakpoint by source position 55630fdc8d8SChris Lattner { 55730fdc8d8SChris Lattner FileSpec file; 558c7bece56SGreg Clayton const size_t num_files = m_options.m_filenames.GetSize(); 559b9c1b51eSKate Stone if (num_files == 0) { 560b9c1b51eSKate Stone if (!GetDefaultFile(target, file, result)) { 56187df91b8SJim Ingham result.AppendError("No file supplied and no default file available."); 56287df91b8SJim Ingham result.SetStatus(eReturnStatusFailed); 56387df91b8SJim Ingham return false; 56487df91b8SJim Ingham } 565b9c1b51eSKate Stone } else if (num_files > 1) { 566b9c1b51eSKate Stone result.AppendError("Only one file at a time is allowed for file and " 567b9c1b51eSKate Stone "line breakpoints."); 56887df91b8SJim Ingham result.SetStatus(eReturnStatusFailed); 56987df91b8SJim Ingham return false; 570b9c1b51eSKate Stone } else 57187df91b8SJim Ingham file = m_options.m_filenames.GetFileSpecAtIndex(0); 57230fdc8d8SChris Lattner 5731f746071SGreg Clayton // Only check for inline functions if 5741f746071SGreg Clayton LazyBool check_inlines = eLazyBoolCalculate; 5751f746071SGreg Clayton 576cb2380c9SRaphael Isemann bp_sp = target.CreateBreakpoint( 577cb2380c9SRaphael Isemann &(m_options.m_modules), file, m_options.m_line_num, 578cb2380c9SRaphael Isemann m_options.m_column, m_options.m_offset_addr, check_inlines, 579cb2380c9SRaphael Isemann m_options.m_skip_prologue, internal, m_options.m_hardware, 580b842f2ecSJim Ingham m_options.m_move_to_nearest_code); 581b9c1b51eSKate Stone } break; 5826eee5aa0SGreg Clayton 58330fdc8d8SChris Lattner case eSetTypeAddress: // Breakpoint by address 584055a08a4SJim Ingham { 585b9c1b51eSKate Stone // If a shared library has been specified, make an lldb_private::Address 586b842f2ecSJim Ingham // with the library, and use that. That way the address breakpoint 587b842f2ecSJim Ingham // will track the load location of the library. 588055a08a4SJim Ingham size_t num_modules_specified = m_options.m_modules.GetSize(); 589b9c1b51eSKate Stone if (num_modules_specified == 1) { 590b9c1b51eSKate Stone const FileSpec *file_spec = 591b9c1b51eSKate Stone m_options.m_modules.GetFileSpecPointerAtIndex(0); 592cb2380c9SRaphael Isemann bp_sp = target.CreateAddressInModuleBreakpoint( 593cb2380c9SRaphael Isemann m_options.m_load_addr, internal, file_spec, m_options.m_hardware); 594b9c1b51eSKate Stone } else if (num_modules_specified == 0) { 595cb2380c9SRaphael Isemann bp_sp = target.CreateBreakpoint(m_options.m_load_addr, internal, 596b842f2ecSJim Ingham m_options.m_hardware); 597b9c1b51eSKate Stone } else { 598b9c1b51eSKate Stone result.AppendError("Only one shared library can be specified for " 599b9c1b51eSKate Stone "address breakpoints."); 600055a08a4SJim Ingham result.SetStatus(eReturnStatusFailed); 601055a08a4SJim Ingham return false; 602055a08a4SJim Ingham } 60330fdc8d8SChris Lattner break; 604055a08a4SJim Ingham } 60530fdc8d8SChris Lattner case eSetTypeFunctionName: // Breakpoint by function name 6060c5cd90dSGreg Clayton { 607117b1fa1SZachary Turner FunctionNameType name_type_mask = m_options.m_func_name_type_mask; 6080c5cd90dSGreg Clayton 6090c5cd90dSGreg Clayton if (name_type_mask == 0) 610e02b8504SGreg Clayton name_type_mask = eFunctionNameTypeAuto; 6110c5cd90dSGreg Clayton 612cb2380c9SRaphael Isemann bp_sp = target.CreateBreakpoint( 613cb2380c9SRaphael Isemann &(m_options.m_modules), &(m_options.m_filenames), 614cb2380c9SRaphael Isemann m_options.m_func_names, name_type_mask, m_options.m_language, 615cb2380c9SRaphael Isemann m_options.m_offset_addr, m_options.m_skip_prologue, internal, 616b842f2ecSJim Ingham m_options.m_hardware); 617b9c1b51eSKate Stone } break; 6180c5cd90dSGreg Clayton 619b9c1b51eSKate Stone case eSetTypeFunctionRegexp: // Breakpoint by regular expression function 620b9c1b51eSKate Stone // name 62130fdc8d8SChris Lattner { 62295eae423SZachary Turner RegularExpression regexp(m_options.m_func_regexp); 6233af3f1e8SJonas Devlieghere if (llvm::Error err = regexp.GetError()) { 624b9c1b51eSKate Stone result.AppendErrorWithFormat( 625b9c1b51eSKate Stone "Function name regular expression could not be compiled: \"%s\"", 6263af3f1e8SJonas Devlieghere llvm::toString(std::move(err)).c_str()); 62730fdc8d8SChris Lattner result.SetStatus(eReturnStatusFailed); 628969795f1SJim Ingham return false; 62930fdc8d8SChris Lattner } 63087df91b8SJim Ingham 631cb2380c9SRaphael Isemann bp_sp = target.CreateFuncRegexBreakpoint( 6325aa1d819SJan Kratochvil &(m_options.m_modules), &(m_options.m_filenames), std::move(regexp), 633cb2380c9SRaphael Isemann m_options.m_language, m_options.m_skip_prologue, internal, 634b842f2ecSJim Ingham m_options.m_hardware); 635a925974bSAdrian Prantl } break; 636969795f1SJim Ingham case eSetTypeSourceRegexp: // Breakpoint by regexp on source text. 637969795f1SJim Ingham { 638c7bece56SGreg Clayton const size_t num_files = m_options.m_filenames.GetSize(); 63987df91b8SJim Ingham 640b9c1b51eSKate Stone if (num_files == 0 && !m_options.m_all_files) { 641969795f1SJim Ingham FileSpec file; 642b9c1b51eSKate Stone if (!GetDefaultFile(target, file, result)) { 643b9c1b51eSKate Stone result.AppendError( 644b9c1b51eSKate Stone "No files provided and could not find default file."); 64587df91b8SJim Ingham result.SetStatus(eReturnStatusFailed); 64687df91b8SJim Ingham return false; 647b9c1b51eSKate Stone } else { 64887df91b8SJim Ingham m_options.m_filenames.Append(file); 64987df91b8SJim Ingham } 65087df91b8SJim Ingham } 6510c5cd90dSGreg Clayton 65295eae423SZachary Turner RegularExpression regexp(m_options.m_source_text_regexp); 6533af3f1e8SJonas Devlieghere if (llvm::Error err = regexp.GetError()) { 654b9c1b51eSKate Stone result.AppendErrorWithFormat( 655b9c1b51eSKate Stone "Source text regular expression could not be compiled: \"%s\"", 6563af3f1e8SJonas Devlieghere llvm::toString(std::move(err)).c_str()); 657969795f1SJim Ingham result.SetStatus(eReturnStatusFailed); 658969795f1SJim Ingham return false; 659969795f1SJim Ingham } 660cb2380c9SRaphael Isemann bp_sp = target.CreateSourceRegexBreakpoint( 661cb2380c9SRaphael Isemann &(m_options.m_modules), &(m_options.m_filenames), 6625aa1d819SJan Kratochvil m_options.m_source_regex_func_names, std::move(regexp), internal, 663cb2380c9SRaphael Isemann m_options.m_hardware, m_options.m_move_to_nearest_code); 664b9c1b51eSKate Stone } break; 665b9c1b51eSKate Stone case eSetTypeException: { 66697206d57SZachary Turner Status precond_error; 667cb2380c9SRaphael Isemann bp_sp = target.CreateExceptionBreakpoint( 668cb2380c9SRaphael Isemann m_options.m_exception_language, m_options.m_catch_bp, 669cb2380c9SRaphael Isemann m_options.m_throw_bp, internal, &m_options.m_exception_extra_args, 670b842f2ecSJim Ingham &precond_error); 671b9c1b51eSKate Stone if (precond_error.Fail()) { 672b9c1b51eSKate Stone result.AppendErrorWithFormat( 673b9c1b51eSKate Stone "Error setting extra exception arguments: %s", 674a72b31c7SJim Ingham precond_error.AsCString()); 675cb2380c9SRaphael Isemann target.RemoveBreakpointByID(bp_sp->GetID()); 676a72b31c7SJim Ingham result.SetStatus(eReturnStatusFailed); 677a72b31c7SJim Ingham return false; 678a72b31c7SJim Ingham } 679b9c1b51eSKate Stone } break; 6803815e702SJim Ingham case eSetTypeScripted: { 6813815e702SJim Ingham 6823815e702SJim Ingham Status error; 683cb2380c9SRaphael Isemann bp_sp = target.CreateScriptedBreakpoint( 684738af7a6SJim Ingham m_python_class_options.GetName().c_str(), &(m_options.m_modules), 685cb2380c9SRaphael Isemann &(m_options.m_filenames), false, m_options.m_hardware, 686943a2481SJim Ingham m_python_class_options.GetStructuredData(), &error); 6873815e702SJim Ingham if (error.Fail()) { 6883815e702SJim Ingham result.AppendErrorWithFormat( 689a925974bSAdrian Prantl "Error setting extra exception arguments: %s", error.AsCString()); 690cb2380c9SRaphael Isemann target.RemoveBreakpointByID(bp_sp->GetID()); 6913815e702SJim Ingham result.SetStatus(eReturnStatusFailed); 6923815e702SJim Ingham return false; 6933815e702SJim Ingham } 6943815e702SJim Ingham } break; 69530fdc8d8SChris Lattner default: 69630fdc8d8SChris Lattner break; 69730fdc8d8SChris Lattner } 69830fdc8d8SChris Lattner 6991b54c88cSJim Ingham // Now set the various options that were passed in: 700b842f2ecSJim Ingham if (bp_sp) { 701b842f2ecSJim Ingham bp_sp->GetOptions()->CopyOverSetOptions(m_bp_opts.GetBreakpointOptions()); 702ca36cd16SJim Ingham 703b9c1b51eSKate Stone if (!m_options.m_breakpoint_names.empty()) { 70497206d57SZachary Turner Status name_error; 705ff9a91eaSJim Ingham for (auto name : m_options.m_breakpoint_names) { 706cb2380c9SRaphael Isemann target.AddNameToBreakpoint(bp_sp, name.c_str(), name_error); 707ff9a91eaSJim Ingham if (name_error.Fail()) { 708ff9a91eaSJim Ingham result.AppendErrorWithFormat("Invalid breakpoint name: %s", 709ff9a91eaSJim Ingham name.c_str()); 710cb2380c9SRaphael Isemann target.RemoveBreakpointByID(bp_sp->GetID()); 711ff9a91eaSJim Ingham result.SetStatus(eReturnStatusFailed); 712ff9a91eaSJim Ingham return false; 713ff9a91eaSJim Ingham } 714ff9a91eaSJim Ingham } 7155e09c8c3SJim Ingham } 7161b54c88cSJim Ingham } 7171b54c88cSJim Ingham 718b842f2ecSJim Ingham if (bp_sp) { 71985e8b814SJim Ingham Stream &output_stream = result.GetOutputStream(); 7201391cc7dSJim Ingham const bool show_locations = false; 721b842f2ecSJim Ingham bp_sp->GetDescription(&output_stream, lldb::eDescriptionLevelInitial, 722b9c1b51eSKate Stone show_locations); 723cb2380c9SRaphael Isemann if (&target == &GetDummyTarget()) 724b9c1b51eSKate Stone output_stream.Printf("Breakpoint set in dummy target, will get copied " 725b9c1b51eSKate Stone "into future targets.\n"); 726b9c1b51eSKate Stone else { 72705097246SAdrian Prantl // Don't print out this warning for exception breakpoints. They can 72805097246SAdrian Prantl // get set before the target is set, but we won't know how to actually 72905097246SAdrian Prantl // set the breakpoint till we run. 730b842f2ecSJim Ingham if (bp_sp->GetNumLocations() == 0 && break_type != eSetTypeException) { 731b9c1b51eSKate Stone output_stream.Printf("WARNING: Unable to resolve breakpoint to any " 732b9c1b51eSKate Stone "actual locations.\n"); 7334aeb1989SJim Ingham } 7344aeb1989SJim Ingham } 73530fdc8d8SChris Lattner result.SetStatus(eReturnStatusSuccessFinishResult); 736b842f2ecSJim Ingham } else if (!bp_sp) { 73730fdc8d8SChris Lattner result.AppendError("Breakpoint creation failed: No breakpoint created."); 73830fdc8d8SChris Lattner result.SetStatus(eReturnStatusFailed); 73930fdc8d8SChris Lattner } 74030fdc8d8SChris Lattner 74130fdc8d8SChris Lattner return result.Succeeded(); 74230fdc8d8SChris Lattner } 74330fdc8d8SChris Lattner 7445a988416SJim Ingham private: 745cb2380c9SRaphael Isemann bool GetDefaultFile(Target &target, FileSpec &file, 746b9c1b51eSKate Stone CommandReturnObject &result) { 7475a988416SJim Ingham uint32_t default_line; 74805097246SAdrian Prantl // First use the Source Manager's default file. Then use the current stack 74905097246SAdrian Prantl // frame's file. 750cb2380c9SRaphael Isemann if (!target.GetSourceManager().GetDefaultFileAndLine(file, default_line)) { 751b57e4a1bSJason Molenda StackFrame *cur_frame = m_exe_ctx.GetFramePtr(); 752b9c1b51eSKate Stone if (cur_frame == nullptr) { 753b9c1b51eSKate Stone result.AppendError( 754b9c1b51eSKate Stone "No selected frame to use to find the default file."); 7555a988416SJim Ingham result.SetStatus(eReturnStatusFailed); 7565a988416SJim Ingham return false; 757b9c1b51eSKate Stone } else if (!cur_frame->HasDebugInformation()) { 758b9c1b51eSKate Stone result.AppendError("Cannot use the selected frame to find the default " 759b9c1b51eSKate Stone "file, it has no debug info."); 7605a988416SJim Ingham result.SetStatus(eReturnStatusFailed); 7615a988416SJim Ingham return false; 762b9c1b51eSKate Stone } else { 763b9c1b51eSKate Stone const SymbolContext &sc = 764b9c1b51eSKate Stone cur_frame->GetSymbolContext(eSymbolContextLineEntry); 765b9c1b51eSKate Stone if (sc.line_entry.file) { 7665a988416SJim Ingham file = sc.line_entry.file; 767b9c1b51eSKate Stone } else { 768b9c1b51eSKate Stone result.AppendError("Can't find the file for the selected frame to " 769b9c1b51eSKate Stone "use as the default file."); 7705a988416SJim Ingham result.SetStatus(eReturnStatusFailed); 7715a988416SJim Ingham return false; 7725a988416SJim Ingham } 7735a988416SJim Ingham } 7745a988416SJim Ingham } 7755a988416SJim Ingham return true; 7765a988416SJim Ingham } 7775a988416SJim Ingham 778b842f2ecSJim Ingham BreakpointOptionGroup m_bp_opts; 779b842f2ecSJim Ingham BreakpointDummyOptionGroup m_dummy_options; 780943a2481SJim Ingham OptionGroupPythonClassWithDict m_python_class_options; 7815a988416SJim Ingham CommandOptions m_options; 782b842f2ecSJim Ingham OptionGroupOptions m_all_options; 7835a988416SJim Ingham }; 7849e85e5a8SEugene Zelenko 7855a988416SJim Ingham // CommandObjectBreakpointModify 7865a988416SJim Ingham #pragma mark Modify 7875a988416SJim Ingham 788b9c1b51eSKate Stone class CommandObjectBreakpointModify : public CommandObjectParsed { 7895a988416SJim Ingham public: 790b9c1b51eSKate Stone CommandObjectBreakpointModify(CommandInterpreter &interpreter) 791b9c1b51eSKate Stone : CommandObjectParsed(interpreter, "breakpoint modify", 792b9c1b51eSKate Stone "Modify the options on a breakpoint or set of " 793b9c1b51eSKate Stone "breakpoints in the executable. " 794b9c1b51eSKate Stone "If no breakpoint is specified, acts on the last " 795b9c1b51eSKate Stone "created breakpoint. " 796b9c1b51eSKate Stone "With the exception of -e, -d and -i, passing an " 797b9c1b51eSKate Stone "empty argument clears the modification.", 7989e85e5a8SEugene Zelenko nullptr), 799b9c1b51eSKate Stone m_options() { 8005a988416SJim Ingham CommandArgumentEntry arg; 801b9c1b51eSKate Stone CommandObject::AddIDsArgumentData(arg, eArgTypeBreakpointID, 802b9c1b51eSKate Stone eArgTypeBreakpointIDRange); 803b9c1b51eSKate Stone // Add the entry for the first argument for this command to the object's 804b9c1b51eSKate Stone // arguments vector. 8055a988416SJim Ingham m_arguments.push_back(arg); 806b842f2ecSJim Ingham 807b842f2ecSJim Ingham m_options.Append(&m_bp_opts, 808b842f2ecSJim Ingham LLDB_OPT_SET_1 | LLDB_OPT_SET_2 | LLDB_OPT_SET_3, 809b842f2ecSJim Ingham LLDB_OPT_SET_ALL); 810b842f2ecSJim Ingham m_options.Append(&m_dummy_opts, LLDB_OPT_SET_1, LLDB_OPT_SET_ALL); 811b842f2ecSJim Ingham m_options.Finalize(); 8125a988416SJim Ingham } 8135a988416SJim Ingham 8149e85e5a8SEugene Zelenko ~CommandObjectBreakpointModify() override = default; 8155a988416SJim Ingham 816b9c1b51eSKate Stone Options *GetOptions() override { return &m_options; } 8175a988416SJim Ingham 8185a988416SJim Ingham protected: 819b9c1b51eSKate Stone bool DoExecute(Args &command, CommandReturnObject &result) override { 820cb2380c9SRaphael Isemann Target &target = GetSelectedOrDummyTarget(m_dummy_opts.m_use_dummy); 8215a988416SJim Ingham 822bb19a13cSSaleem Abdulrasool std::unique_lock<std::recursive_mutex> lock; 823cb2380c9SRaphael Isemann target.GetBreakpointList().GetListMutex(lock); 8245a988416SJim Ingham 8255a988416SJim Ingham BreakpointIDList valid_bp_ids; 8265a988416SJim Ingham 827b9c1b51eSKate Stone CommandObjectMultiwordBreakpoint::VerifyBreakpointOrLocationIDs( 828cb2380c9SRaphael Isemann command, &target, result, &valid_bp_ids, 829b842f2ecSJim Ingham BreakpointName::Permissions::PermissionKinds::disablePerm); 8305a988416SJim Ingham 831b9c1b51eSKate Stone if (result.Succeeded()) { 8325a988416SJim Ingham const size_t count = valid_bp_ids.GetSize(); 833b9c1b51eSKate Stone for (size_t i = 0; i < count; ++i) { 8345a988416SJim Ingham BreakpointID cur_bp_id = valid_bp_ids.GetBreakpointIDAtIndex(i); 8355a988416SJim Ingham 836b9c1b51eSKate Stone if (cur_bp_id.GetBreakpointID() != LLDB_INVALID_BREAK_ID) { 837b9c1b51eSKate Stone Breakpoint *bp = 838cb2380c9SRaphael Isemann target.GetBreakpointByID(cur_bp_id.GetBreakpointID()).get(); 839b9c1b51eSKate Stone if (cur_bp_id.GetLocationID() != LLDB_INVALID_BREAK_ID) { 840b9c1b51eSKate Stone BreakpointLocation *location = 841b9c1b51eSKate Stone bp->FindLocationByID(cur_bp_id.GetLocationID()).get(); 842b842f2ecSJim Ingham if (location) 843a925974bSAdrian Prantl location->GetLocationOptions()->CopyOverSetOptions( 844a925974bSAdrian Prantl m_bp_opts.GetBreakpointOptions()); 845b9c1b51eSKate Stone } else { 846a925974bSAdrian Prantl bp->GetOptions()->CopyOverSetOptions( 847a925974bSAdrian Prantl m_bp_opts.GetBreakpointOptions()); 8485a988416SJim Ingham } 8495a988416SJim Ingham } 8505a988416SJim Ingham } 8515a988416SJim Ingham } 8525a988416SJim Ingham 8535a988416SJim Ingham return result.Succeeded(); 8545a988416SJim Ingham } 8555a988416SJim Ingham 8565a988416SJim Ingham private: 857b842f2ecSJim Ingham BreakpointOptionGroup m_bp_opts; 858b842f2ecSJim Ingham BreakpointDummyOptionGroup m_dummy_opts; 859b842f2ecSJim Ingham OptionGroupOptions m_options; 8605a988416SJim Ingham }; 8615a988416SJim Ingham 8625a988416SJim Ingham // CommandObjectBreakpointEnable 8635a988416SJim Ingham #pragma mark Enable 8645a988416SJim Ingham 865b9c1b51eSKate Stone class CommandObjectBreakpointEnable : public CommandObjectParsed { 8665a988416SJim Ingham public: 867b9c1b51eSKate Stone CommandObjectBreakpointEnable(CommandInterpreter &interpreter) 868b9c1b51eSKate Stone : CommandObjectParsed(interpreter, "enable", 869b9c1b51eSKate Stone "Enable the specified disabled breakpoint(s). If " 870b9c1b51eSKate Stone "no breakpoints are specified, enable all of them.", 871b9c1b51eSKate Stone nullptr) { 8725a988416SJim Ingham CommandArgumentEntry arg; 873b9c1b51eSKate Stone CommandObject::AddIDsArgumentData(arg, eArgTypeBreakpointID, 874b9c1b51eSKate Stone eArgTypeBreakpointIDRange); 875b9c1b51eSKate Stone // Add the entry for the first argument for this command to the object's 876b9c1b51eSKate Stone // arguments vector. 8775a988416SJim Ingham m_arguments.push_back(arg); 8785a988416SJim Ingham } 8795a988416SJim Ingham 8809e85e5a8SEugene Zelenko ~CommandObjectBreakpointEnable() override = default; 8815a988416SJim Ingham 8825a988416SJim Ingham protected: 883b9c1b51eSKate Stone bool DoExecute(Args &command, CommandReturnObject &result) override { 884cb2380c9SRaphael Isemann Target &target = GetSelectedOrDummyTarget(); 8855a988416SJim Ingham 886bb19a13cSSaleem Abdulrasool std::unique_lock<std::recursive_mutex> lock; 887cb2380c9SRaphael Isemann target.GetBreakpointList().GetListMutex(lock); 8885a988416SJim Ingham 889cb2380c9SRaphael Isemann const BreakpointList &breakpoints = target.GetBreakpointList(); 8905a988416SJim Ingham 8915a988416SJim Ingham size_t num_breakpoints = breakpoints.GetSize(); 8925a988416SJim Ingham 893b9c1b51eSKate Stone if (num_breakpoints == 0) { 8945a988416SJim Ingham result.AppendError("No breakpoints exist to be enabled."); 8955a988416SJim Ingham result.SetStatus(eReturnStatusFailed); 8965a988416SJim Ingham return false; 8975a988416SJim Ingham } 8985a988416SJim Ingham 89911eb9c64SZachary Turner if (command.empty()) { 9005a988416SJim Ingham // No breakpoint selected; enable all currently set breakpoints. 901cb2380c9SRaphael Isemann target.EnableAllowedBreakpoints(); 902b9c1b51eSKate Stone result.AppendMessageWithFormat("All breakpoints enabled. (%" PRIu64 903b9c1b51eSKate Stone " breakpoints)\n", 904b9c1b51eSKate Stone (uint64_t)num_breakpoints); 9055a988416SJim Ingham result.SetStatus(eReturnStatusSuccessFinishNoResult); 906b9c1b51eSKate Stone } else { 9075a988416SJim Ingham // Particular breakpoint selected; enable that breakpoint. 9085a988416SJim Ingham BreakpointIDList valid_bp_ids; 909b9c1b51eSKate Stone CommandObjectMultiwordBreakpoint::VerifyBreakpointOrLocationIDs( 910cb2380c9SRaphael Isemann command, &target, result, &valid_bp_ids, 911b842f2ecSJim Ingham BreakpointName::Permissions::PermissionKinds::disablePerm); 9125a988416SJim Ingham 913b9c1b51eSKate Stone if (result.Succeeded()) { 9145a988416SJim Ingham int enable_count = 0; 9155a988416SJim Ingham int loc_count = 0; 9165a988416SJim Ingham const size_t count = valid_bp_ids.GetSize(); 917b9c1b51eSKate Stone for (size_t i = 0; i < count; ++i) { 9185a988416SJim Ingham BreakpointID cur_bp_id = valid_bp_ids.GetBreakpointIDAtIndex(i); 9195a988416SJim Ingham 920b9c1b51eSKate Stone if (cur_bp_id.GetBreakpointID() != LLDB_INVALID_BREAK_ID) { 921b9c1b51eSKate Stone Breakpoint *breakpoint = 922cb2380c9SRaphael Isemann target.GetBreakpointByID(cur_bp_id.GetBreakpointID()).get(); 923b9c1b51eSKate Stone if (cur_bp_id.GetLocationID() != LLDB_INVALID_BREAK_ID) { 924b9c1b51eSKate Stone BreakpointLocation *location = 925b9c1b51eSKate Stone breakpoint->FindLocationByID(cur_bp_id.GetLocationID()).get(); 926b9c1b51eSKate Stone if (location) { 9275a988416SJim Ingham location->SetEnabled(true); 9285a988416SJim Ingham ++loc_count; 9295a988416SJim Ingham } 930b9c1b51eSKate Stone } else { 9315a988416SJim Ingham breakpoint->SetEnabled(true); 9325a988416SJim Ingham ++enable_count; 9335a988416SJim Ingham } 9345a988416SJim Ingham } 9355a988416SJim Ingham } 936b9c1b51eSKate Stone result.AppendMessageWithFormat("%d breakpoints enabled.\n", 937b9c1b51eSKate Stone enable_count + loc_count); 9385a988416SJim Ingham result.SetStatus(eReturnStatusSuccessFinishNoResult); 9395a988416SJim Ingham } 9405a988416SJim Ingham } 9415a988416SJim Ingham 9425a988416SJim Ingham return result.Succeeded(); 9435a988416SJim Ingham } 9445a988416SJim Ingham }; 9455a988416SJim Ingham 9465a988416SJim Ingham // CommandObjectBreakpointDisable 9475a988416SJim Ingham #pragma mark Disable 9485a988416SJim Ingham 949b9c1b51eSKate Stone class CommandObjectBreakpointDisable : public CommandObjectParsed { 9505a988416SJim Ingham public: 9517428a18cSKate Stone CommandObjectBreakpointDisable(CommandInterpreter &interpreter) 952b9c1b51eSKate Stone : CommandObjectParsed( 953b9c1b51eSKate Stone interpreter, "breakpoint disable", 954b9c1b51eSKate Stone "Disable the specified breakpoint(s) without deleting " 9557428a18cSKate Stone "them. If none are specified, disable all " 9567428a18cSKate Stone "breakpoints.", 957b9c1b51eSKate Stone nullptr) { 958b9c1b51eSKate Stone SetHelpLong( 959b9c1b51eSKate Stone "Disable the specified breakpoint(s) without deleting them. \ 9607428a18cSKate Stone If none are specified, disable all breakpoints." 9617428a18cSKate Stone R"( 962ea671fbdSKate Stone 9637428a18cSKate Stone )" 9647428a18cSKate Stone "Note: disabling a breakpoint will cause none of its locations to be hit \ 9657428a18cSKate Stone regardless of whether individual locations are enabled or disabled. After the sequence:" 9667428a18cSKate Stone R"( 967ea671fbdSKate Stone 968ea671fbdSKate Stone (lldb) break disable 1 969ea671fbdSKate Stone (lldb) break enable 1.1 970ea671fbdSKate Stone 971ea671fbdSKate Stone execution will NOT stop at location 1.1. To achieve that, type: 972ea671fbdSKate Stone 973ea671fbdSKate Stone (lldb) break disable 1.* 974ea671fbdSKate Stone (lldb) break enable 1.1 975ea671fbdSKate Stone 9767428a18cSKate Stone )" 9777428a18cSKate Stone "The first command disables all locations for breakpoint 1, \ 9787428a18cSKate Stone the second re-enables the first location."); 979b0fac509SJim Ingham 9805a988416SJim Ingham CommandArgumentEntry arg; 981b9c1b51eSKate Stone CommandObject::AddIDsArgumentData(arg, eArgTypeBreakpointID, 982b9c1b51eSKate Stone eArgTypeBreakpointIDRange); 983b9c1b51eSKate Stone // Add the entry for the first argument for this command to the object's 984b9c1b51eSKate Stone // arguments vector. 9855a988416SJim Ingham m_arguments.push_back(arg); 9865a988416SJim Ingham } 9875a988416SJim Ingham 9889e85e5a8SEugene Zelenko ~CommandObjectBreakpointDisable() override = default; 9895a988416SJim Ingham 9905a988416SJim Ingham protected: 991b9c1b51eSKate Stone bool DoExecute(Args &command, CommandReturnObject &result) override { 992cb2380c9SRaphael Isemann Target &target = GetSelectedOrDummyTarget(); 993bb19a13cSSaleem Abdulrasool std::unique_lock<std::recursive_mutex> lock; 994cb2380c9SRaphael Isemann target.GetBreakpointList().GetListMutex(lock); 9955a988416SJim Ingham 996cb2380c9SRaphael Isemann const BreakpointList &breakpoints = target.GetBreakpointList(); 9975a988416SJim Ingham size_t num_breakpoints = breakpoints.GetSize(); 9985a988416SJim Ingham 999b9c1b51eSKate Stone if (num_breakpoints == 0) { 10005a988416SJim Ingham result.AppendError("No breakpoints exist to be disabled."); 10015a988416SJim Ingham result.SetStatus(eReturnStatusFailed); 10025a988416SJim Ingham return false; 10035a988416SJim Ingham } 10045a988416SJim Ingham 100511eb9c64SZachary Turner if (command.empty()) { 10065a988416SJim Ingham // No breakpoint selected; disable all currently set breakpoints. 1007cb2380c9SRaphael Isemann target.DisableAllowedBreakpoints(); 1008b9c1b51eSKate Stone result.AppendMessageWithFormat("All breakpoints disabled. (%" PRIu64 1009b9c1b51eSKate Stone " breakpoints)\n", 1010b9c1b51eSKate Stone (uint64_t)num_breakpoints); 10115a988416SJim Ingham result.SetStatus(eReturnStatusSuccessFinishNoResult); 1012b9c1b51eSKate Stone } else { 10135a988416SJim Ingham // Particular breakpoint selected; disable that breakpoint. 10145a988416SJim Ingham BreakpointIDList valid_bp_ids; 10155a988416SJim Ingham 1016b9c1b51eSKate Stone CommandObjectMultiwordBreakpoint::VerifyBreakpointOrLocationIDs( 1017cb2380c9SRaphael Isemann command, &target, result, &valid_bp_ids, 1018b842f2ecSJim Ingham BreakpointName::Permissions::PermissionKinds::disablePerm); 10195a988416SJim Ingham 1020b9c1b51eSKate Stone if (result.Succeeded()) { 10215a988416SJim Ingham int disable_count = 0; 10225a988416SJim Ingham int loc_count = 0; 10235a988416SJim Ingham const size_t count = valid_bp_ids.GetSize(); 1024b9c1b51eSKate Stone for (size_t i = 0; i < count; ++i) { 10255a988416SJim Ingham BreakpointID cur_bp_id = valid_bp_ids.GetBreakpointIDAtIndex(i); 10265a988416SJim Ingham 1027b9c1b51eSKate Stone if (cur_bp_id.GetBreakpointID() != LLDB_INVALID_BREAK_ID) { 1028b9c1b51eSKate Stone Breakpoint *breakpoint = 1029cb2380c9SRaphael Isemann target.GetBreakpointByID(cur_bp_id.GetBreakpointID()).get(); 1030b9c1b51eSKate Stone if (cur_bp_id.GetLocationID() != LLDB_INVALID_BREAK_ID) { 1031b9c1b51eSKate Stone BreakpointLocation *location = 1032b9c1b51eSKate Stone breakpoint->FindLocationByID(cur_bp_id.GetLocationID()).get(); 1033b9c1b51eSKate Stone if (location) { 10345a988416SJim Ingham location->SetEnabled(false); 10355a988416SJim Ingham ++loc_count; 10365a988416SJim Ingham } 1037b9c1b51eSKate Stone } else { 10385a988416SJim Ingham breakpoint->SetEnabled(false); 10395a988416SJim Ingham ++disable_count; 10405a988416SJim Ingham } 10415a988416SJim Ingham } 10425a988416SJim Ingham } 1043b9c1b51eSKate Stone result.AppendMessageWithFormat("%d breakpoints disabled.\n", 1044b9c1b51eSKate Stone disable_count + loc_count); 10455a988416SJim Ingham result.SetStatus(eReturnStatusSuccessFinishNoResult); 10465a988416SJim Ingham } 10475a988416SJim Ingham } 10485a988416SJim Ingham 10495a988416SJim Ingham return result.Succeeded(); 10505a988416SJim Ingham } 10515a988416SJim Ingham }; 10525a988416SJim Ingham 10535a988416SJim Ingham // CommandObjectBreakpointList 10541f0f5b5bSZachary Turner 10551f0f5b5bSZachary Turner #pragma mark List::CommandOptions 10566f4fb4e7SRaphael Isemann #define LLDB_OPTIONS_breakpoint_list 1057c5a2d747SRaphael Isemann #include "CommandOptions.inc" 10581f0f5b5bSZachary Turner 10595a988416SJim Ingham #pragma mark List 10605a988416SJim Ingham 1061b9c1b51eSKate Stone class CommandObjectBreakpointList : public CommandObjectParsed { 10625a988416SJim Ingham public: 1063b9c1b51eSKate Stone CommandObjectBreakpointList(CommandInterpreter &interpreter) 1064b9c1b51eSKate Stone : CommandObjectParsed( 1065b9c1b51eSKate Stone interpreter, "breakpoint list", 10665a988416SJim Ingham "List some or all breakpoints at configurable levels of detail.", 10679e85e5a8SEugene Zelenko nullptr), 1068b9c1b51eSKate Stone m_options() { 10695a988416SJim Ingham CommandArgumentEntry arg; 10705a988416SJim Ingham CommandArgumentData bp_id_arg; 10715a988416SJim Ingham 10725a988416SJim Ingham // Define the first (and only) variant of this arg. 10735a988416SJim Ingham bp_id_arg.arg_type = eArgTypeBreakpointID; 10745a988416SJim Ingham bp_id_arg.arg_repetition = eArgRepeatOptional; 10755a988416SJim Ingham 1076b9c1b51eSKate Stone // There is only one variant this argument could be; put it into the 1077b9c1b51eSKate Stone // argument entry. 10785a988416SJim Ingham arg.push_back(bp_id_arg); 10795a988416SJim Ingham 10805a988416SJim Ingham // Push the data for the first argument into the m_arguments vector. 10815a988416SJim Ingham m_arguments.push_back(arg); 10825a988416SJim Ingham } 10835a988416SJim Ingham 10849e85e5a8SEugene Zelenko ~CommandObjectBreakpointList() override = default; 10855a988416SJim Ingham 1086b9c1b51eSKate Stone Options *GetOptions() override { return &m_options; } 10875a988416SJim Ingham 1088b9c1b51eSKate Stone class CommandOptions : public Options { 10895a988416SJim Ingham public: 1090b9c1b51eSKate Stone CommandOptions() 1091b9c1b51eSKate Stone : Options(), m_level(lldb::eDescriptionLevelBrief), m_use_dummy(false) { 10925a988416SJim Ingham } 10935a988416SJim Ingham 10949e85e5a8SEugene Zelenko ~CommandOptions() override = default; 10955a988416SJim Ingham 109697206d57SZachary Turner Status SetOptionValue(uint32_t option_idx, llvm::StringRef option_arg, 1097b9c1b51eSKate Stone ExecutionContext *execution_context) override { 109897206d57SZachary Turner Status error; 10993bcdfc0eSGreg Clayton const int short_option = m_getopt_table[option_idx].val; 11005a988416SJim Ingham 1101b9c1b51eSKate Stone switch (short_option) { 11025a988416SJim Ingham case 'b': 11035a988416SJim Ingham m_level = lldb::eDescriptionLevelBrief; 11045a988416SJim Ingham break; 110533df7cd3SJim Ingham case 'D': 110633df7cd3SJim Ingham m_use_dummy = true; 110733df7cd3SJim Ingham break; 11085a988416SJim Ingham case 'f': 11095a988416SJim Ingham m_level = lldb::eDescriptionLevelFull; 11105a988416SJim Ingham break; 11115a988416SJim Ingham case 'v': 11125a988416SJim Ingham m_level = lldb::eDescriptionLevelVerbose; 11135a988416SJim Ingham break; 11145a988416SJim Ingham case 'i': 11155a988416SJim Ingham m_internal = true; 11165a988416SJim Ingham break; 11175a988416SJim Ingham default: 111836162014SRaphael Isemann llvm_unreachable("Unimplemented option"); 11195a988416SJim Ingham } 11205a988416SJim Ingham 11215a988416SJim Ingham return error; 11225a988416SJim Ingham } 11235a988416SJim Ingham 1124b9c1b51eSKate Stone void OptionParsingStarting(ExecutionContext *execution_context) override { 11255a988416SJim Ingham m_level = lldb::eDescriptionLevelFull; 11265a988416SJim Ingham m_internal = false; 112733df7cd3SJim Ingham m_use_dummy = false; 11285a988416SJim Ingham } 11295a988416SJim Ingham 11301f0f5b5bSZachary Turner llvm::ArrayRef<OptionDefinition> GetDefinitions() override { 113170602439SZachary Turner return llvm::makeArrayRef(g_breakpoint_list_options); 11321f0f5b5bSZachary Turner } 11335a988416SJim Ingham 11345a988416SJim Ingham // Instance variables to hold the values for command options. 11355a988416SJim Ingham 11365a988416SJim Ingham lldb::DescriptionLevel m_level; 11375a988416SJim Ingham 11385a988416SJim Ingham bool m_internal; 113933df7cd3SJim Ingham bool m_use_dummy; 11405a988416SJim Ingham }; 11415a988416SJim Ingham 11425a988416SJim Ingham protected: 1143b9c1b51eSKate Stone bool DoExecute(Args &command, CommandReturnObject &result) override { 1144cb2380c9SRaphael Isemann Target &target = GetSelectedOrDummyTarget(m_options.m_use_dummy); 11455a988416SJim Ingham 1146b9c1b51eSKate Stone const BreakpointList &breakpoints = 1147cb2380c9SRaphael Isemann target.GetBreakpointList(m_options.m_internal); 1148bb19a13cSSaleem Abdulrasool std::unique_lock<std::recursive_mutex> lock; 1149cb2380c9SRaphael Isemann target.GetBreakpointList(m_options.m_internal).GetListMutex(lock); 11505a988416SJim Ingham 11515a988416SJim Ingham size_t num_breakpoints = breakpoints.GetSize(); 11525a988416SJim Ingham 1153b9c1b51eSKate Stone if (num_breakpoints == 0) { 11545a988416SJim Ingham result.AppendMessage("No breakpoints currently set."); 11555a988416SJim Ingham result.SetStatus(eReturnStatusSuccessFinishNoResult); 11565a988416SJim Ingham return true; 11575a988416SJim Ingham } 11585a988416SJim Ingham 11595a988416SJim Ingham Stream &output_stream = result.GetOutputStream(); 11605a988416SJim Ingham 116111eb9c64SZachary Turner if (command.empty()) { 11625a988416SJim Ingham // No breakpoint selected; show info about all currently set breakpoints. 11635a988416SJim Ingham result.AppendMessage("Current breakpoints:"); 1164b9c1b51eSKate Stone for (size_t i = 0; i < num_breakpoints; ++i) { 11655a988416SJim Ingham Breakpoint *breakpoint = breakpoints.GetBreakpointAtIndex(i).get(); 1166b842f2ecSJim Ingham if (breakpoint->AllowList()) 1167b842f2ecSJim Ingham AddBreakpointDescription(&output_stream, breakpoint, 1168b842f2ecSJim Ingham m_options.m_level); 11695a988416SJim Ingham } 11705a988416SJim Ingham result.SetStatus(eReturnStatusSuccessFinishNoResult); 1171b9c1b51eSKate Stone } else { 11725a988416SJim Ingham // Particular breakpoints selected; show info about that breakpoint. 11735a988416SJim Ingham BreakpointIDList valid_bp_ids; 1174b9c1b51eSKate Stone CommandObjectMultiwordBreakpoint::VerifyBreakpointOrLocationIDs( 1175cb2380c9SRaphael Isemann command, &target, result, &valid_bp_ids, 1176b842f2ecSJim Ingham BreakpointName::Permissions::PermissionKinds::listPerm); 11775a988416SJim Ingham 1178b9c1b51eSKate Stone if (result.Succeeded()) { 1179b9c1b51eSKate Stone for (size_t i = 0; i < valid_bp_ids.GetSize(); ++i) { 11805a988416SJim Ingham BreakpointID cur_bp_id = valid_bp_ids.GetBreakpointIDAtIndex(i); 1181b9c1b51eSKate Stone Breakpoint *breakpoint = 1182cb2380c9SRaphael Isemann target.GetBreakpointByID(cur_bp_id.GetBreakpointID()).get(); 1183b9c1b51eSKate Stone AddBreakpointDescription(&output_stream, breakpoint, 1184b9c1b51eSKate Stone m_options.m_level); 11855a988416SJim Ingham } 11865a988416SJim Ingham result.SetStatus(eReturnStatusSuccessFinishNoResult); 1187b9c1b51eSKate Stone } else { 11887428a18cSKate Stone result.AppendError("Invalid breakpoint ID."); 11895a988416SJim Ingham result.SetStatus(eReturnStatusFailed); 11905a988416SJim Ingham } 11915a988416SJim Ingham } 11925a988416SJim Ingham 11935a988416SJim Ingham return result.Succeeded(); 11945a988416SJim Ingham } 11955a988416SJim Ingham 11965a988416SJim Ingham private: 11975a988416SJim Ingham CommandOptions m_options; 11985a988416SJim Ingham }; 11995a988416SJim Ingham 12005a988416SJim Ingham // CommandObjectBreakpointClear 12011f0f5b5bSZachary Turner #pragma mark Clear::CommandOptions 12021f0f5b5bSZachary Turner 1203f94668e3SRaphael Isemann #define LLDB_OPTIONS_breakpoint_clear 1204f94668e3SRaphael Isemann #include "CommandOptions.inc" 12051f0f5b5bSZachary Turner 12065a988416SJim Ingham #pragma mark Clear 12075a988416SJim Ingham 1208b9c1b51eSKate Stone class CommandObjectBreakpointClear : public CommandObjectParsed { 12095a988416SJim Ingham public: 1210efe8e7e3SFangrui Song enum BreakpointClearType { eClearTypeInvalid, eClearTypeFileAndLine }; 12115a988416SJim Ingham 12127428a18cSKate Stone CommandObjectBreakpointClear(CommandInterpreter &interpreter) 12137428a18cSKate Stone : CommandObjectParsed(interpreter, "breakpoint clear", 1214b9c1b51eSKate Stone "Delete or disable breakpoints matching the " 1215b9c1b51eSKate Stone "specified source file and line.", 12165a988416SJim Ingham "breakpoint clear <cmd-options>"), 1217b9c1b51eSKate Stone m_options() {} 12185a988416SJim Ingham 12199e85e5a8SEugene Zelenko ~CommandObjectBreakpointClear() override = default; 12205a988416SJim Ingham 1221b9c1b51eSKate Stone Options *GetOptions() override { return &m_options; } 12225a988416SJim Ingham 1223b9c1b51eSKate Stone class CommandOptions : public Options { 12245a988416SJim Ingham public: 1225b9c1b51eSKate Stone CommandOptions() : Options(), m_filename(), m_line_num(0) {} 12265a988416SJim Ingham 12279e85e5a8SEugene Zelenko ~CommandOptions() override = default; 12285a988416SJim Ingham 122997206d57SZachary Turner Status SetOptionValue(uint32_t option_idx, llvm::StringRef option_arg, 1230b9c1b51eSKate Stone ExecutionContext *execution_context) override { 123197206d57SZachary Turner Status error; 12323bcdfc0eSGreg Clayton const int short_option = m_getopt_table[option_idx].val; 12335a988416SJim Ingham 1234b9c1b51eSKate Stone switch (short_option) { 12355a988416SJim Ingham case 'f': 12365a988416SJim Ingham m_filename.assign(option_arg); 12375a988416SJim Ingham break; 12385a988416SJim Ingham 12395a988416SJim Ingham case 'l': 1240fe11483bSZachary Turner option_arg.getAsInteger(0, m_line_num); 12415a988416SJim Ingham break; 12425a988416SJim Ingham 12435a988416SJim Ingham default: 124436162014SRaphael Isemann llvm_unreachable("Unimplemented option"); 12455a988416SJim Ingham } 12465a988416SJim Ingham 12475a988416SJim Ingham return error; 12485a988416SJim Ingham } 12495a988416SJim Ingham 1250b9c1b51eSKate Stone void OptionParsingStarting(ExecutionContext *execution_context) override { 12515a988416SJim Ingham m_filename.clear(); 12525a988416SJim Ingham m_line_num = 0; 12535a988416SJim Ingham } 12545a988416SJim Ingham 12551f0f5b5bSZachary Turner llvm::ArrayRef<OptionDefinition> GetDefinitions() override { 125670602439SZachary Turner return llvm::makeArrayRef(g_breakpoint_clear_options); 12571f0f5b5bSZachary Turner } 12585a988416SJim Ingham 12595a988416SJim Ingham // Instance variables to hold the values for command options. 12605a988416SJim Ingham 12615a988416SJim Ingham std::string m_filename; 12625a988416SJim Ingham uint32_t m_line_num; 12635a988416SJim Ingham }; 12645a988416SJim Ingham 12655a988416SJim Ingham protected: 1266b9c1b51eSKate Stone bool DoExecute(Args &command, CommandReturnObject &result) override { 1267cb2380c9SRaphael Isemann Target &target = GetSelectedOrDummyTarget(); 12685a988416SJim Ingham 126905097246SAdrian Prantl // The following are the various types of breakpoints that could be 127005097246SAdrian Prantl // cleared: 12715a988416SJim Ingham // 1). -f -l (clearing breakpoint by source location) 12725a988416SJim Ingham 12735a988416SJim Ingham BreakpointClearType break_type = eClearTypeInvalid; 12745a988416SJim Ingham 12755a988416SJim Ingham if (m_options.m_line_num != 0) 12765a988416SJim Ingham break_type = eClearTypeFileAndLine; 12775a988416SJim Ingham 1278bb19a13cSSaleem Abdulrasool std::unique_lock<std::recursive_mutex> lock; 1279cb2380c9SRaphael Isemann target.GetBreakpointList().GetListMutex(lock); 12805a988416SJim Ingham 1281cb2380c9SRaphael Isemann BreakpointList &breakpoints = target.GetBreakpointList(); 12825a988416SJim Ingham size_t num_breakpoints = breakpoints.GetSize(); 12835a988416SJim Ingham 12845a988416SJim Ingham // Early return if there's no breakpoint at all. 1285b9c1b51eSKate Stone if (num_breakpoints == 0) { 12865a988416SJim Ingham result.AppendError("Breakpoint clear: No breakpoint cleared."); 12875a988416SJim Ingham result.SetStatus(eReturnStatusFailed); 12885a988416SJim Ingham return result.Succeeded(); 12895a988416SJim Ingham } 12905a988416SJim Ingham 12915a988416SJim Ingham // Find matching breakpoints and delete them. 12925a988416SJim Ingham 12935a988416SJim Ingham // First create a copy of all the IDs. 12945a988416SJim Ingham std::vector<break_id_t> BreakIDs; 12955a988416SJim Ingham for (size_t i = 0; i < num_breakpoints; ++i) 12969e85e5a8SEugene Zelenko BreakIDs.push_back(breakpoints.GetBreakpointAtIndex(i)->GetID()); 12975a988416SJim Ingham 12985a988416SJim Ingham int num_cleared = 0; 12995a988416SJim Ingham StreamString ss; 1300b9c1b51eSKate Stone switch (break_type) { 13015a988416SJim Ingham case eClearTypeFileAndLine: // Breakpoint by source position 13025a988416SJim Ingham { 13035a988416SJim Ingham const ConstString filename(m_options.m_filename.c_str()); 13045a988416SJim Ingham BreakpointLocationCollection loc_coll; 13055a988416SJim Ingham 1306b9c1b51eSKate Stone for (size_t i = 0; i < num_breakpoints; ++i) { 13075a988416SJim Ingham Breakpoint *bp = breakpoints.FindBreakpointByID(BreakIDs[i]).get(); 13085a988416SJim Ingham 1309b9c1b51eSKate Stone if (bp->GetMatchingFileLine(filename, m_options.m_line_num, loc_coll)) { 1310b9c1b51eSKate Stone // If the collection size is 0, it's a full match and we can just 1311b9c1b51eSKate Stone // remove the breakpoint. 1312b9c1b51eSKate Stone if (loc_coll.GetSize() == 0) { 13135a988416SJim Ingham bp->GetDescription(&ss, lldb::eDescriptionLevelBrief); 13145a988416SJim Ingham ss.EOL(); 1315cb2380c9SRaphael Isemann target.RemoveBreakpointByID(bp->GetID()); 13165a988416SJim Ingham ++num_cleared; 13175a988416SJim Ingham } 13185a988416SJim Ingham } 13195a988416SJim Ingham } 1320b9c1b51eSKate Stone } break; 13215a988416SJim Ingham 13225a988416SJim Ingham default: 13235a988416SJim Ingham break; 13245a988416SJim Ingham } 13255a988416SJim Ingham 1326b9c1b51eSKate Stone if (num_cleared > 0) { 13275a988416SJim Ingham Stream &output_stream = result.GetOutputStream(); 13285a988416SJim Ingham output_stream.Printf("%d breakpoints cleared:\n", num_cleared); 1329c156427dSZachary Turner output_stream << ss.GetString(); 13305a988416SJim Ingham output_stream.EOL(); 13315a988416SJim Ingham result.SetStatus(eReturnStatusSuccessFinishNoResult); 1332b9c1b51eSKate Stone } else { 13335a988416SJim Ingham result.AppendError("Breakpoint clear: No breakpoint cleared."); 13345a988416SJim Ingham result.SetStatus(eReturnStatusFailed); 13355a988416SJim Ingham } 13365a988416SJim Ingham 13375a988416SJim Ingham return result.Succeeded(); 13385a988416SJim Ingham } 13395a988416SJim Ingham 13405a988416SJim Ingham private: 13415a988416SJim Ingham CommandOptions m_options; 13425a988416SJim Ingham }; 13435a988416SJim Ingham 13445a988416SJim Ingham // CommandObjectBreakpointDelete 1345f94668e3SRaphael Isemann #define LLDB_OPTIONS_breakpoint_delete 1346f94668e3SRaphael Isemann #include "CommandOptions.inc" 13471f0f5b5bSZachary Turner 13485a988416SJim Ingham #pragma mark Delete 13495a988416SJim Ingham 1350b9c1b51eSKate Stone class CommandObjectBreakpointDelete : public CommandObjectParsed { 13515a988416SJim Ingham public: 1352b9c1b51eSKate Stone CommandObjectBreakpointDelete(CommandInterpreter &interpreter) 1353b9c1b51eSKate Stone : CommandObjectParsed(interpreter, "breakpoint delete", 1354b9c1b51eSKate Stone "Delete the specified breakpoint(s). If no " 1355b9c1b51eSKate Stone "breakpoints are specified, delete them all.", 13569e85e5a8SEugene Zelenko nullptr), 1357b9c1b51eSKate Stone m_options() { 13585a988416SJim Ingham CommandArgumentEntry arg; 1359b9c1b51eSKate Stone CommandObject::AddIDsArgumentData(arg, eArgTypeBreakpointID, 1360b9c1b51eSKate Stone eArgTypeBreakpointIDRange); 1361b9c1b51eSKate Stone // Add the entry for the first argument for this command to the object's 1362b9c1b51eSKate Stone // arguments vector. 13635a988416SJim Ingham m_arguments.push_back(arg); 13645a988416SJim Ingham } 13655a988416SJim Ingham 13669e85e5a8SEugene Zelenko ~CommandObjectBreakpointDelete() override = default; 13675a988416SJim Ingham 1368b9c1b51eSKate Stone Options *GetOptions() override { return &m_options; } 136933df7cd3SJim Ingham 1370b9c1b51eSKate Stone class CommandOptions : public Options { 137133df7cd3SJim Ingham public: 1372b9c1b51eSKate Stone CommandOptions() : Options(), m_use_dummy(false), m_force(false) {} 137333df7cd3SJim Ingham 13749e85e5a8SEugene Zelenko ~CommandOptions() override = default; 137533df7cd3SJim Ingham 137697206d57SZachary Turner Status SetOptionValue(uint32_t option_idx, llvm::StringRef option_arg, 1377b9c1b51eSKate Stone ExecutionContext *execution_context) override { 137897206d57SZachary Turner Status error; 137933df7cd3SJim Ingham const int short_option = m_getopt_table[option_idx].val; 138033df7cd3SJim Ingham 1381b9c1b51eSKate Stone switch (short_option) { 138233df7cd3SJim Ingham case 'f': 138333df7cd3SJim Ingham m_force = true; 138433df7cd3SJim Ingham break; 138533df7cd3SJim Ingham 138633df7cd3SJim Ingham case 'D': 138733df7cd3SJim Ingham m_use_dummy = true; 138833df7cd3SJim Ingham break; 138933df7cd3SJim Ingham 139033df7cd3SJim Ingham default: 139136162014SRaphael Isemann llvm_unreachable("Unimplemented option"); 139233df7cd3SJim Ingham } 139333df7cd3SJim Ingham 139433df7cd3SJim Ingham return error; 139533df7cd3SJim Ingham } 139633df7cd3SJim Ingham 1397b9c1b51eSKate Stone void OptionParsingStarting(ExecutionContext *execution_context) override { 139833df7cd3SJim Ingham m_use_dummy = false; 139933df7cd3SJim Ingham m_force = false; 140033df7cd3SJim Ingham } 140133df7cd3SJim Ingham 14021f0f5b5bSZachary Turner llvm::ArrayRef<OptionDefinition> GetDefinitions() override { 140370602439SZachary Turner return llvm::makeArrayRef(g_breakpoint_delete_options); 14041f0f5b5bSZachary Turner } 140533df7cd3SJim Ingham 140633df7cd3SJim Ingham // Instance variables to hold the values for command options. 140733df7cd3SJim Ingham bool m_use_dummy; 140833df7cd3SJim Ingham bool m_force; 140933df7cd3SJim Ingham }; 141033df7cd3SJim Ingham 14115a988416SJim Ingham protected: 1412b9c1b51eSKate Stone bool DoExecute(Args &command, CommandReturnObject &result) override { 1413cb2380c9SRaphael Isemann Target &target = GetSelectedOrDummyTarget(m_options.m_use_dummy); 14145a988416SJim Ingham 1415bb19a13cSSaleem Abdulrasool std::unique_lock<std::recursive_mutex> lock; 1416cb2380c9SRaphael Isemann target.GetBreakpointList().GetListMutex(lock); 14175a988416SJim Ingham 1418cb2380c9SRaphael Isemann const BreakpointList &breakpoints = target.GetBreakpointList(); 14195a988416SJim Ingham 14205a988416SJim Ingham size_t num_breakpoints = breakpoints.GetSize(); 14215a988416SJim Ingham 1422b9c1b51eSKate Stone if (num_breakpoints == 0) { 14235a988416SJim Ingham result.AppendError("No breakpoints exist to be deleted."); 14245a988416SJim Ingham result.SetStatus(eReturnStatusFailed); 14255a988416SJim Ingham return false; 14265a988416SJim Ingham } 14275a988416SJim Ingham 142811eb9c64SZachary Turner if (command.empty()) { 1429b9c1b51eSKate Stone if (!m_options.m_force && 1430b9c1b51eSKate Stone !m_interpreter.Confirm( 1431b9c1b51eSKate Stone "About to delete all breakpoints, do you want to do that?", 1432b9c1b51eSKate Stone true)) { 14335a988416SJim Ingham result.AppendMessage("Operation cancelled..."); 1434b9c1b51eSKate Stone } else { 1435cb2380c9SRaphael Isemann target.RemoveAllowedBreakpoints(); 1436b9c1b51eSKate Stone result.AppendMessageWithFormat( 1437b9c1b51eSKate Stone "All breakpoints removed. (%" PRIu64 " breakpoint%s)\n", 1438b9c1b51eSKate Stone (uint64_t)num_breakpoints, num_breakpoints > 1 ? "s" : ""); 14395a988416SJim Ingham } 14405a988416SJim Ingham result.SetStatus(eReturnStatusSuccessFinishNoResult); 1441b9c1b51eSKate Stone } else { 14425a988416SJim Ingham // Particular breakpoint selected; disable that breakpoint. 14435a988416SJim Ingham BreakpointIDList valid_bp_ids; 1444b9c1b51eSKate Stone CommandObjectMultiwordBreakpoint::VerifyBreakpointOrLocationIDs( 1445cb2380c9SRaphael Isemann command, &target, result, &valid_bp_ids, 1446b842f2ecSJim Ingham BreakpointName::Permissions::PermissionKinds::deletePerm); 14475a988416SJim Ingham 1448b9c1b51eSKate Stone if (result.Succeeded()) { 14495a988416SJim Ingham int delete_count = 0; 14505a988416SJim Ingham int disable_count = 0; 14515a988416SJim Ingham const size_t count = valid_bp_ids.GetSize(); 1452b9c1b51eSKate Stone for (size_t i = 0; i < count; ++i) { 14535a988416SJim Ingham BreakpointID cur_bp_id = valid_bp_ids.GetBreakpointIDAtIndex(i); 14545a988416SJim Ingham 1455b9c1b51eSKate Stone if (cur_bp_id.GetBreakpointID() != LLDB_INVALID_BREAK_ID) { 1456b9c1b51eSKate Stone if (cur_bp_id.GetLocationID() != LLDB_INVALID_BREAK_ID) { 1457b9c1b51eSKate Stone Breakpoint *breakpoint = 1458cb2380c9SRaphael Isemann target.GetBreakpointByID(cur_bp_id.GetBreakpointID()).get(); 1459b9c1b51eSKate Stone BreakpointLocation *location = 1460b9c1b51eSKate Stone breakpoint->FindLocationByID(cur_bp_id.GetLocationID()).get(); 1461b9c1b51eSKate Stone // It makes no sense to try to delete individual locations, so we 1462b9c1b51eSKate Stone // disable them instead. 1463b9c1b51eSKate Stone if (location) { 14645a988416SJim Ingham location->SetEnabled(false); 14655a988416SJim Ingham ++disable_count; 14665a988416SJim Ingham } 1467b9c1b51eSKate Stone } else { 1468cb2380c9SRaphael Isemann target.RemoveBreakpointByID(cur_bp_id.GetBreakpointID()); 14695a988416SJim Ingham ++delete_count; 14705a988416SJim Ingham } 14715a988416SJim Ingham } 14725a988416SJim Ingham } 1473b9c1b51eSKate Stone result.AppendMessageWithFormat( 1474b9c1b51eSKate Stone "%d breakpoints deleted; %d breakpoint locations disabled.\n", 14755a988416SJim Ingham delete_count, disable_count); 14765a988416SJim Ingham result.SetStatus(eReturnStatusSuccessFinishNoResult); 14775a988416SJim Ingham } 14785a988416SJim Ingham } 14795a988416SJim Ingham return result.Succeeded(); 14805a988416SJim Ingham } 14819e85e5a8SEugene Zelenko 148233df7cd3SJim Ingham private: 148333df7cd3SJim Ingham CommandOptions m_options; 148433df7cd3SJim Ingham }; 148533df7cd3SJim Ingham 14865e09c8c3SJim Ingham // CommandObjectBreakpointName 1487f94668e3SRaphael Isemann #define LLDB_OPTIONS_breakpoint_name 1488f94668e3SRaphael Isemann #include "CommandOptions.inc" 1489bd68a052SRaphael Isemann 1490b9c1b51eSKate Stone class BreakpointNameOptionGroup : public OptionGroup { 14915e09c8c3SJim Ingham public: 1492b9c1b51eSKate Stone BreakpointNameOptionGroup() 1493b9c1b51eSKate Stone : OptionGroup(), m_breakpoint(LLDB_INVALID_BREAK_ID), m_use_dummy(false) { 14945e09c8c3SJim Ingham } 14955e09c8c3SJim Ingham 14969e85e5a8SEugene Zelenko ~BreakpointNameOptionGroup() override = default; 14975e09c8c3SJim Ingham 14981f0f5b5bSZachary Turner llvm::ArrayRef<OptionDefinition> GetDefinitions() override { 149970602439SZachary Turner return llvm::makeArrayRef(g_breakpoint_name_options); 15005e09c8c3SJim Ingham } 15015e09c8c3SJim Ingham 150297206d57SZachary Turner Status SetOptionValue(uint32_t option_idx, llvm::StringRef option_arg, 1503b9c1b51eSKate Stone ExecutionContext *execution_context) override { 150497206d57SZachary Turner Status error; 15055e09c8c3SJim Ingham const int short_option = g_breakpoint_name_options[option_idx].short_option; 15065e09c8c3SJim Ingham 1507b9c1b51eSKate Stone switch (short_option) { 15085e09c8c3SJim Ingham case 'N': 1509fe11483bSZachary Turner if (BreakpointID::StringIsBreakpointName(option_arg, error) && 1510b9c1b51eSKate Stone error.Success()) 1511fe11483bSZachary Turner m_name.SetValueFromString(option_arg); 15125e09c8c3SJim Ingham break; 15135e09c8c3SJim Ingham case 'B': 1514fe11483bSZachary Turner if (m_breakpoint.SetValueFromString(option_arg).Fail()) 1515b9c1b51eSKate Stone error.SetErrorStringWithFormat( 15168cef4b0bSZachary Turner "unrecognized value \"%s\" for breakpoint", 1517fe11483bSZachary Turner option_arg.str().c_str()); 15185e09c8c3SJim Ingham break; 15195e09c8c3SJim Ingham case 'D': 1520fe11483bSZachary Turner if (m_use_dummy.SetValueFromString(option_arg).Fail()) 1521b9c1b51eSKate Stone error.SetErrorStringWithFormat( 15228cef4b0bSZachary Turner "unrecognized value \"%s\" for use-dummy", 1523fe11483bSZachary Turner option_arg.str().c_str()); 15245e09c8c3SJim Ingham break; 1525e9632ebaSJim Ingham case 'H': 1526e9632ebaSJim Ingham m_help_string.SetValueFromString(option_arg); 1527e9632ebaSJim Ingham break; 15285e09c8c3SJim Ingham 15295e09c8c3SJim Ingham default: 153036162014SRaphael Isemann llvm_unreachable("Unimplemented option"); 15315e09c8c3SJim Ingham } 15325e09c8c3SJim Ingham return error; 15335e09c8c3SJim Ingham } 15345e09c8c3SJim Ingham 1535b9c1b51eSKate Stone void OptionParsingStarting(ExecutionContext *execution_context) override { 15365e09c8c3SJim Ingham m_name.Clear(); 15375e09c8c3SJim Ingham m_breakpoint.Clear(); 15385e09c8c3SJim Ingham m_use_dummy.Clear(); 15395e09c8c3SJim Ingham m_use_dummy.SetDefaultValue(false); 1540e9632ebaSJim Ingham m_help_string.Clear(); 15415e09c8c3SJim Ingham } 15425e09c8c3SJim Ingham 15435e09c8c3SJim Ingham OptionValueString m_name; 15445e09c8c3SJim Ingham OptionValueUInt64 m_breakpoint; 15455e09c8c3SJim Ingham OptionValueBoolean m_use_dummy; 1546e9632ebaSJim Ingham OptionValueString m_help_string; 15475e09c8c3SJim Ingham }; 15485e09c8c3SJim Ingham 1549f94668e3SRaphael Isemann #define LLDB_OPTIONS_breakpoint_access 1550f94668e3SRaphael Isemann #include "CommandOptions.inc" 1551b842f2ecSJim Ingham 15528fe53c49STatyana Krasnukha class BreakpointAccessOptionGroup : public OptionGroup { 1553b842f2ecSJim Ingham public: 15548fe53c49STatyana Krasnukha BreakpointAccessOptionGroup() : OptionGroup() {} 1555b842f2ecSJim Ingham 1556b842f2ecSJim Ingham ~BreakpointAccessOptionGroup() override = default; 1557b842f2ecSJim Ingham 1558b842f2ecSJim Ingham llvm::ArrayRef<OptionDefinition> GetDefinitions() override { 1559b842f2ecSJim Ingham return llvm::makeArrayRef(g_breakpoint_access_options); 1560b842f2ecSJim Ingham } 1561b842f2ecSJim Ingham Status SetOptionValue(uint32_t option_idx, llvm::StringRef option_arg, 1562b842f2ecSJim Ingham ExecutionContext *execution_context) override { 1563b842f2ecSJim Ingham Status error; 1564a925974bSAdrian Prantl const int short_option = 1565a925974bSAdrian Prantl g_breakpoint_access_options[option_idx].short_option; 1566b842f2ecSJim Ingham 1567b842f2ecSJim Ingham switch (short_option) { 1568b842f2ecSJim Ingham case 'L': { 1569b842f2ecSJim Ingham bool value, success; 157047cbf4a0SPavel Labath value = OptionArgParser::ToBoolean(option_arg, false, &success); 1571b842f2ecSJim Ingham if (success) { 1572b842f2ecSJim Ingham m_permissions.SetAllowList(value); 1573b842f2ecSJim Ingham } else 1574b842f2ecSJim Ingham error.SetErrorStringWithFormat( 1575b842f2ecSJim Ingham "invalid boolean value '%s' passed for -L option", 1576b842f2ecSJim Ingham option_arg.str().c_str()); 1577b842f2ecSJim Ingham } break; 1578b842f2ecSJim Ingham case 'A': { 1579b842f2ecSJim Ingham bool value, success; 158047cbf4a0SPavel Labath value = OptionArgParser::ToBoolean(option_arg, false, &success); 1581b842f2ecSJim Ingham if (success) { 1582b842f2ecSJim Ingham m_permissions.SetAllowDisable(value); 1583b842f2ecSJim Ingham } else 1584b842f2ecSJim Ingham error.SetErrorStringWithFormat( 1585b842f2ecSJim Ingham "invalid boolean value '%s' passed for -L option", 1586b842f2ecSJim Ingham option_arg.str().c_str()); 1587b842f2ecSJim Ingham } break; 1588b842f2ecSJim Ingham case 'D': { 1589b842f2ecSJim Ingham bool value, success; 159047cbf4a0SPavel Labath value = OptionArgParser::ToBoolean(option_arg, false, &success); 1591b842f2ecSJim Ingham if (success) { 1592b842f2ecSJim Ingham m_permissions.SetAllowDelete(value); 1593b842f2ecSJim Ingham } else 1594b842f2ecSJim Ingham error.SetErrorStringWithFormat( 1595b842f2ecSJim Ingham "invalid boolean value '%s' passed for -L option", 1596b842f2ecSJim Ingham option_arg.str().c_str()); 1597b842f2ecSJim Ingham } break; 159836162014SRaphael Isemann default: 159936162014SRaphael Isemann llvm_unreachable("Unimplemented option"); 1600b842f2ecSJim Ingham } 1601b842f2ecSJim Ingham 1602b842f2ecSJim Ingham return error; 1603b842f2ecSJim Ingham } 1604b842f2ecSJim Ingham 1605a925974bSAdrian Prantl void OptionParsingStarting(ExecutionContext *execution_context) override {} 1606b842f2ecSJim Ingham 1607a925974bSAdrian Prantl const BreakpointName::Permissions &GetPermissions() const { 1608b842f2ecSJim Ingham return m_permissions; 1609b842f2ecSJim Ingham } 1610b842f2ecSJim Ingham BreakpointName::Permissions m_permissions; 1611b842f2ecSJim Ingham }; 1612b842f2ecSJim Ingham 1613b842f2ecSJim Ingham class CommandObjectBreakpointNameConfigure : public CommandObjectParsed { 1614b842f2ecSJim Ingham public: 1615b842f2ecSJim Ingham CommandObjectBreakpointNameConfigure(CommandInterpreter &interpreter) 1616b842f2ecSJim Ingham : CommandObjectParsed( 1617a925974bSAdrian Prantl interpreter, "configure", 1618a925974bSAdrian Prantl "Configure the options for the breakpoint" 1619b842f2ecSJim Ingham " name provided. " 1620b842f2ecSJim Ingham "If you provide a breakpoint id, the options will be copied from " 1621b842f2ecSJim Ingham "the breakpoint, otherwise only the options specified will be set " 1622b842f2ecSJim Ingham "on the name.", 1623b842f2ecSJim Ingham "breakpoint name configure <command-options> " 1624b842f2ecSJim Ingham "<breakpoint-name-list>"), 1625b842f2ecSJim Ingham m_bp_opts(), m_option_group() { 1626b842f2ecSJim Ingham // Create the first variant for the first (and only) argument for this 1627b842f2ecSJim Ingham // command. 1628b842f2ecSJim Ingham CommandArgumentEntry arg1; 1629b842f2ecSJim Ingham CommandArgumentData id_arg; 1630b842f2ecSJim Ingham id_arg.arg_type = eArgTypeBreakpointName; 1631b842f2ecSJim Ingham id_arg.arg_repetition = eArgRepeatOptional; 1632b842f2ecSJim Ingham arg1.push_back(id_arg); 1633b842f2ecSJim Ingham m_arguments.push_back(arg1); 1634b842f2ecSJim Ingham 1635a925974bSAdrian Prantl m_option_group.Append(&m_bp_opts, LLDB_OPT_SET_ALL, LLDB_OPT_SET_1); 1636a925974bSAdrian Prantl m_option_group.Append(&m_access_options, LLDB_OPT_SET_ALL, 1637b842f2ecSJim Ingham LLDB_OPT_SET_ALL); 1638a925974bSAdrian Prantl m_option_group.Append(&m_bp_id, LLDB_OPT_SET_2 | LLDB_OPT_SET_4, 1639e9632ebaSJim Ingham LLDB_OPT_SET_ALL); 1640b842f2ecSJim Ingham m_option_group.Finalize(); 1641b842f2ecSJim Ingham } 1642b842f2ecSJim Ingham 1643b842f2ecSJim Ingham ~CommandObjectBreakpointNameConfigure() override = default; 1644b842f2ecSJim Ingham 1645b842f2ecSJim Ingham Options *GetOptions() override { return &m_option_group; } 1646b842f2ecSJim Ingham 1647b842f2ecSJim Ingham protected: 1648b842f2ecSJim Ingham bool DoExecute(Args &command, CommandReturnObject &result) override { 1649b842f2ecSJim Ingham 1650b842f2ecSJim Ingham const size_t argc = command.GetArgumentCount(); 1651b842f2ecSJim Ingham if (argc == 0) { 1652b842f2ecSJim Ingham result.AppendError("No names provided."); 1653b842f2ecSJim Ingham result.SetStatus(eReturnStatusFailed); 1654b842f2ecSJim Ingham return false; 1655b842f2ecSJim Ingham } 1656b842f2ecSJim Ingham 1657cb2380c9SRaphael Isemann Target &target = GetSelectedOrDummyTarget(false); 1658b842f2ecSJim Ingham 1659b842f2ecSJim Ingham std::unique_lock<std::recursive_mutex> lock; 1660cb2380c9SRaphael Isemann target.GetBreakpointList().GetListMutex(lock); 1661b842f2ecSJim Ingham 1662b842f2ecSJim Ingham // Make a pass through first to see that all the names are legal. 1663b842f2ecSJim Ingham for (auto &entry : command.entries()) { 1664b842f2ecSJim Ingham Status error; 1665a925974bSAdrian Prantl if (!BreakpointID::StringIsBreakpointName(entry.ref(), error)) { 1666b842f2ecSJim Ingham result.AppendErrorWithFormat("Invalid breakpoint name: %s - %s", 1667b842f2ecSJim Ingham entry.c_str(), error.AsCString()); 1668b842f2ecSJim Ingham result.SetStatus(eReturnStatusFailed); 1669b842f2ecSJim Ingham return false; 1670b842f2ecSJim Ingham } 1671b842f2ecSJim Ingham } 167205097246SAdrian Prantl // Now configure them, we already pre-checked the names so we don't need to 167305097246SAdrian Prantl // check the error: 1674b842f2ecSJim Ingham BreakpointSP bp_sp; 1675a925974bSAdrian Prantl if (m_bp_id.m_breakpoint.OptionWasSet()) { 1676b842f2ecSJim Ingham lldb::break_id_t bp_id = m_bp_id.m_breakpoint.GetUInt64Value(); 1677cb2380c9SRaphael Isemann bp_sp = target.GetBreakpointByID(bp_id); 1678a925974bSAdrian Prantl if (!bp_sp) { 1679b842f2ecSJim Ingham result.AppendErrorWithFormatv("Could not find specified breakpoint {0}", 1680b842f2ecSJim Ingham bp_id); 1681b842f2ecSJim Ingham result.SetStatus(eReturnStatusFailed); 1682b842f2ecSJim Ingham return false; 1683b842f2ecSJim Ingham } 1684b842f2ecSJim Ingham } 1685b842f2ecSJim Ingham 1686b842f2ecSJim Ingham Status error; 1687b842f2ecSJim Ingham for (auto &entry : command.entries()) { 1688b842f2ecSJim Ingham ConstString name(entry.c_str()); 1689cb2380c9SRaphael Isemann BreakpointName *bp_name = target.FindBreakpointName(name, true, error); 1690b842f2ecSJim Ingham if (!bp_name) 1691b842f2ecSJim Ingham continue; 1692e9632ebaSJim Ingham if (m_bp_id.m_help_string.OptionWasSet()) 1693e9632ebaSJim Ingham bp_name->SetHelp(m_bp_id.m_help_string.GetStringValue().str().c_str()); 1694e9632ebaSJim Ingham 1695b842f2ecSJim Ingham if (bp_sp) 1696cb2380c9SRaphael Isemann target.ConfigureBreakpointName(*bp_name, *bp_sp->GetOptions(), 1697b842f2ecSJim Ingham m_access_options.GetPermissions()); 1698b842f2ecSJim Ingham else 1699cb2380c9SRaphael Isemann target.ConfigureBreakpointName(*bp_name, 1700b842f2ecSJim Ingham m_bp_opts.GetBreakpointOptions(), 1701b842f2ecSJim Ingham m_access_options.GetPermissions()); 1702b842f2ecSJim Ingham } 1703b842f2ecSJim Ingham return true; 1704b842f2ecSJim Ingham } 1705b842f2ecSJim Ingham 1706b842f2ecSJim Ingham private: 1707b842f2ecSJim Ingham BreakpointNameOptionGroup m_bp_id; // Only using the id part of this. 1708b842f2ecSJim Ingham BreakpointOptionGroup m_bp_opts; 1709b842f2ecSJim Ingham BreakpointAccessOptionGroup m_access_options; 1710b842f2ecSJim Ingham OptionGroupOptions m_option_group; 1711b842f2ecSJim Ingham }; 1712b842f2ecSJim Ingham 1713b9c1b51eSKate Stone class CommandObjectBreakpointNameAdd : public CommandObjectParsed { 17145e09c8c3SJim Ingham public: 1715b9c1b51eSKate Stone CommandObjectBreakpointNameAdd(CommandInterpreter &interpreter) 1716b9c1b51eSKate Stone : CommandObjectParsed( 1717b9c1b51eSKate Stone interpreter, "add", "Add a name to the breakpoints provided.", 17185e09c8c3SJim Ingham "breakpoint name add <command-options> <breakpoint-id-list>"), 1719b9c1b51eSKate Stone m_name_options(), m_option_group() { 1720b9c1b51eSKate Stone // Create the first variant for the first (and only) argument for this 1721b9c1b51eSKate Stone // command. 17225e09c8c3SJim Ingham CommandArgumentEntry arg1; 17235e09c8c3SJim Ingham CommandArgumentData id_arg; 17245e09c8c3SJim Ingham id_arg.arg_type = eArgTypeBreakpointID; 17255e09c8c3SJim Ingham id_arg.arg_repetition = eArgRepeatOptional; 17265e09c8c3SJim Ingham arg1.push_back(id_arg); 17275e09c8c3SJim Ingham m_arguments.push_back(arg1); 17285e09c8c3SJim Ingham 17295e09c8c3SJim Ingham m_option_group.Append(&m_name_options, LLDB_OPT_SET_1, LLDB_OPT_SET_ALL); 17305e09c8c3SJim Ingham m_option_group.Finalize(); 17315e09c8c3SJim Ingham } 17325e09c8c3SJim Ingham 17339e85e5a8SEugene Zelenko ~CommandObjectBreakpointNameAdd() override = default; 17345e09c8c3SJim Ingham 1735b9c1b51eSKate Stone Options *GetOptions() override { return &m_option_group; } 17365e09c8c3SJim Ingham 17375e09c8c3SJim Ingham protected: 1738b9c1b51eSKate Stone bool DoExecute(Args &command, CommandReturnObject &result) override { 1739b9c1b51eSKate Stone if (!m_name_options.m_name.OptionWasSet()) { 17405e09c8c3SJim Ingham result.SetError("No name option provided."); 17415e09c8c3SJim Ingham return false; 17425e09c8c3SJim Ingham } 17435e09c8c3SJim Ingham 1744cb2380c9SRaphael Isemann Target &target = 1745b9c1b51eSKate Stone GetSelectedOrDummyTarget(m_name_options.m_use_dummy.GetCurrentValue()); 17465e09c8c3SJim Ingham 1747bb19a13cSSaleem Abdulrasool std::unique_lock<std::recursive_mutex> lock; 1748cb2380c9SRaphael Isemann target.GetBreakpointList().GetListMutex(lock); 17495e09c8c3SJim Ingham 1750cb2380c9SRaphael Isemann const BreakpointList &breakpoints = target.GetBreakpointList(); 17515e09c8c3SJim Ingham 17525e09c8c3SJim Ingham size_t num_breakpoints = breakpoints.GetSize(); 1753b9c1b51eSKate Stone if (num_breakpoints == 0) { 17545e09c8c3SJim Ingham result.SetError("No breakpoints, cannot add names."); 17555e09c8c3SJim Ingham result.SetStatus(eReturnStatusFailed); 17565e09c8c3SJim Ingham return false; 17575e09c8c3SJim Ingham } 17585e09c8c3SJim Ingham 17595e09c8c3SJim Ingham // Particular breakpoint selected; disable that breakpoint. 17605e09c8c3SJim Ingham BreakpointIDList valid_bp_ids; 1761b9c1b51eSKate Stone CommandObjectMultiwordBreakpoint::VerifyBreakpointIDs( 1762cb2380c9SRaphael Isemann command, &target, result, &valid_bp_ids, 1763b842f2ecSJim Ingham BreakpointName::Permissions::PermissionKinds::listPerm); 17645e09c8c3SJim Ingham 1765b9c1b51eSKate Stone if (result.Succeeded()) { 1766b9c1b51eSKate Stone if (valid_bp_ids.GetSize() == 0) { 17675e09c8c3SJim Ingham result.SetError("No breakpoints specified, cannot add names."); 17685e09c8c3SJim Ingham result.SetStatus(eReturnStatusFailed); 17695e09c8c3SJim Ingham return false; 17705e09c8c3SJim Ingham } 17715e09c8c3SJim Ingham size_t num_valid_ids = valid_bp_ids.GetSize(); 1772b842f2ecSJim Ingham const char *bp_name = m_name_options.m_name.GetCurrentValue(); 1773b842f2ecSJim Ingham Status error; // This error reports illegal names, but we've already 1774b842f2ecSJim Ingham // checked that, so we don't need to check it again here. 1775b9c1b51eSKate Stone for (size_t index = 0; index < num_valid_ids; index++) { 1776b9c1b51eSKate Stone lldb::break_id_t bp_id = 1777b9c1b51eSKate Stone valid_bp_ids.GetBreakpointIDAtIndex(index).GetBreakpointID(); 17785e09c8c3SJim Ingham BreakpointSP bp_sp = breakpoints.FindBreakpointByID(bp_id); 1779cb2380c9SRaphael Isemann target.AddNameToBreakpoint(bp_sp, bp_name, error); 17805e09c8c3SJim Ingham } 17815e09c8c3SJim Ingham } 17825e09c8c3SJim Ingham 17835e09c8c3SJim Ingham return true; 17845e09c8c3SJim Ingham } 17855e09c8c3SJim Ingham 17865e09c8c3SJim Ingham private: 17875e09c8c3SJim Ingham BreakpointNameOptionGroup m_name_options; 17885e09c8c3SJim Ingham OptionGroupOptions m_option_group; 17895e09c8c3SJim Ingham }; 17905e09c8c3SJim Ingham 1791b9c1b51eSKate Stone class CommandObjectBreakpointNameDelete : public CommandObjectParsed { 17925e09c8c3SJim Ingham public: 1793b9c1b51eSKate Stone CommandObjectBreakpointNameDelete(CommandInterpreter &interpreter) 1794b9c1b51eSKate Stone : CommandObjectParsed( 1795b9c1b51eSKate Stone interpreter, "delete", 17965e09c8c3SJim Ingham "Delete a name from the breakpoints provided.", 17975e09c8c3SJim Ingham "breakpoint name delete <command-options> <breakpoint-id-list>"), 1798b9c1b51eSKate Stone m_name_options(), m_option_group() { 1799b9c1b51eSKate Stone // Create the first variant for the first (and only) argument for this 1800b9c1b51eSKate Stone // command. 18015e09c8c3SJim Ingham CommandArgumentEntry arg1; 18025e09c8c3SJim Ingham CommandArgumentData id_arg; 18035e09c8c3SJim Ingham id_arg.arg_type = eArgTypeBreakpointID; 18045e09c8c3SJim Ingham id_arg.arg_repetition = eArgRepeatOptional; 18055e09c8c3SJim Ingham arg1.push_back(id_arg); 18065e09c8c3SJim Ingham m_arguments.push_back(arg1); 18075e09c8c3SJim Ingham 18085e09c8c3SJim Ingham m_option_group.Append(&m_name_options, LLDB_OPT_SET_1, LLDB_OPT_SET_ALL); 18095e09c8c3SJim Ingham m_option_group.Finalize(); 18105e09c8c3SJim Ingham } 18115e09c8c3SJim Ingham 18129e85e5a8SEugene Zelenko ~CommandObjectBreakpointNameDelete() override = default; 18135e09c8c3SJim Ingham 1814b9c1b51eSKate Stone Options *GetOptions() override { return &m_option_group; } 18155e09c8c3SJim Ingham 18165e09c8c3SJim Ingham protected: 1817b9c1b51eSKate Stone bool DoExecute(Args &command, CommandReturnObject &result) override { 1818b9c1b51eSKate Stone if (!m_name_options.m_name.OptionWasSet()) { 18195e09c8c3SJim Ingham result.SetError("No name option provided."); 18205e09c8c3SJim Ingham return false; 18215e09c8c3SJim Ingham } 18225e09c8c3SJim Ingham 1823cb2380c9SRaphael Isemann Target &target = 1824b9c1b51eSKate Stone GetSelectedOrDummyTarget(m_name_options.m_use_dummy.GetCurrentValue()); 18255e09c8c3SJim Ingham 1826bb19a13cSSaleem Abdulrasool std::unique_lock<std::recursive_mutex> lock; 1827cb2380c9SRaphael Isemann target.GetBreakpointList().GetListMutex(lock); 18285e09c8c3SJim Ingham 1829cb2380c9SRaphael Isemann const BreakpointList &breakpoints = target.GetBreakpointList(); 18305e09c8c3SJim Ingham 18315e09c8c3SJim Ingham size_t num_breakpoints = breakpoints.GetSize(); 1832b9c1b51eSKate Stone if (num_breakpoints == 0) { 18335e09c8c3SJim Ingham result.SetError("No breakpoints, cannot delete names."); 18345e09c8c3SJim Ingham result.SetStatus(eReturnStatusFailed); 18355e09c8c3SJim Ingham return false; 18365e09c8c3SJim Ingham } 18375e09c8c3SJim Ingham 18385e09c8c3SJim Ingham // Particular breakpoint selected; disable that breakpoint. 18395e09c8c3SJim Ingham BreakpointIDList valid_bp_ids; 1840b9c1b51eSKate Stone CommandObjectMultiwordBreakpoint::VerifyBreakpointIDs( 1841cb2380c9SRaphael Isemann command, &target, result, &valid_bp_ids, 1842b842f2ecSJim Ingham BreakpointName::Permissions::PermissionKinds::deletePerm); 18435e09c8c3SJim Ingham 1844b9c1b51eSKate Stone if (result.Succeeded()) { 1845b9c1b51eSKate Stone if (valid_bp_ids.GetSize() == 0) { 18465e09c8c3SJim Ingham result.SetError("No breakpoints specified, cannot delete names."); 18475e09c8c3SJim Ingham result.SetStatus(eReturnStatusFailed); 18485e09c8c3SJim Ingham return false; 18495e09c8c3SJim Ingham } 1850b842f2ecSJim Ingham ConstString bp_name(m_name_options.m_name.GetCurrentValue()); 18515e09c8c3SJim Ingham size_t num_valid_ids = valid_bp_ids.GetSize(); 1852b9c1b51eSKate Stone for (size_t index = 0; index < num_valid_ids; index++) { 1853b9c1b51eSKate Stone lldb::break_id_t bp_id = 1854b9c1b51eSKate Stone valid_bp_ids.GetBreakpointIDAtIndex(index).GetBreakpointID(); 18555e09c8c3SJim Ingham BreakpointSP bp_sp = breakpoints.FindBreakpointByID(bp_id); 1856cb2380c9SRaphael Isemann target.RemoveNameFromBreakpoint(bp_sp, bp_name); 18575e09c8c3SJim Ingham } 18585e09c8c3SJim Ingham } 18595e09c8c3SJim Ingham 18605e09c8c3SJim Ingham return true; 18615e09c8c3SJim Ingham } 18625e09c8c3SJim Ingham 18635e09c8c3SJim Ingham private: 18645e09c8c3SJim Ingham BreakpointNameOptionGroup m_name_options; 18655e09c8c3SJim Ingham OptionGroupOptions m_option_group; 18665e09c8c3SJim Ingham }; 18675e09c8c3SJim Ingham 1868b9c1b51eSKate Stone class CommandObjectBreakpointNameList : public CommandObjectParsed { 18695e09c8c3SJim Ingham public: 1870b9c1b51eSKate Stone CommandObjectBreakpointNameList(CommandInterpreter &interpreter) 1871b9c1b51eSKate Stone : CommandObjectParsed(interpreter, "list", 1872b842f2ecSJim Ingham "List either the names for a breakpoint or info " 1873b842f2ecSJim Ingham "about a given name. With no arguments, lists all " 1874b842f2ecSJim Ingham "names", 18755e09c8c3SJim Ingham "breakpoint name list <command-options>"), 1876b9c1b51eSKate Stone m_name_options(), m_option_group() { 1877b842f2ecSJim Ingham m_option_group.Append(&m_name_options, LLDB_OPT_SET_3, LLDB_OPT_SET_ALL); 18785e09c8c3SJim Ingham m_option_group.Finalize(); 18795e09c8c3SJim Ingham } 18805e09c8c3SJim Ingham 18819e85e5a8SEugene Zelenko ~CommandObjectBreakpointNameList() override = default; 18825e09c8c3SJim Ingham 1883b9c1b51eSKate Stone Options *GetOptions() override { return &m_option_group; } 18845e09c8c3SJim Ingham 18855e09c8c3SJim Ingham protected: 1886b9c1b51eSKate Stone bool DoExecute(Args &command, CommandReturnObject &result) override { 1887cb2380c9SRaphael Isemann Target &target = 1888b9c1b51eSKate Stone GetSelectedOrDummyTarget(m_name_options.m_use_dummy.GetCurrentValue()); 18895e09c8c3SJim Ingham 1890b842f2ecSJim Ingham std::vector<std::string> name_list; 1891b842f2ecSJim Ingham if (command.empty()) { 1892cb2380c9SRaphael Isemann target.GetBreakpointNames(name_list); 1893b842f2ecSJim Ingham } else { 1894a925974bSAdrian Prantl for (const Args::ArgEntry &arg : command) { 1895b842f2ecSJim Ingham name_list.push_back(arg.c_str()); 1896b842f2ecSJim Ingham } 1897b842f2ecSJim Ingham } 1898b842f2ecSJim Ingham 1899b842f2ecSJim Ingham if (name_list.empty()) { 1900b842f2ecSJim Ingham result.AppendMessage("No breakpoint names found."); 1901b842f2ecSJim Ingham } else { 1902b842f2ecSJim Ingham for (const std::string &name_str : name_list) { 1903b842f2ecSJim Ingham const char *name = name_str.c_str(); 1904b842f2ecSJim Ingham // First print out the options for the name: 1905b842f2ecSJim Ingham Status error; 1906cb2380c9SRaphael Isemann BreakpointName *bp_name = 1907cb2380c9SRaphael Isemann target.FindBreakpointName(ConstString(name), false, error); 1908a925974bSAdrian Prantl if (bp_name) { 1909b842f2ecSJim Ingham StreamString s; 1910b842f2ecSJim Ingham result.AppendMessageWithFormat("Name: %s\n", name); 1911a925974bSAdrian Prantl if (bp_name->GetDescription(&s, eDescriptionLevelFull)) { 1912b842f2ecSJim Ingham result.AppendMessage(s.GetString()); 1913b842f2ecSJim Ingham } 1914b842f2ecSJim Ingham 1915bb19a13cSSaleem Abdulrasool std::unique_lock<std::recursive_mutex> lock; 1916cb2380c9SRaphael Isemann target.GetBreakpointList().GetListMutex(lock); 19175e09c8c3SJim Ingham 1918cb2380c9SRaphael Isemann BreakpointList &breakpoints = target.GetBreakpointList(); 1919b842f2ecSJim Ingham bool any_set = false; 1920b9c1b51eSKate Stone for (BreakpointSP bp_sp : breakpoints.Breakpoints()) { 1921b9c1b51eSKate Stone if (bp_sp->MatchesName(name)) { 19225e09c8c3SJim Ingham StreamString s; 1923b842f2ecSJim Ingham any_set = true; 19245e09c8c3SJim Ingham bp_sp->GetDescription(&s, eDescriptionLevelBrief); 19255e09c8c3SJim Ingham s.EOL(); 1926c156427dSZachary Turner result.AppendMessage(s.GetString()); 19275e09c8c3SJim Ingham } 19285e09c8c3SJim Ingham } 1929b842f2ecSJim Ingham if (!any_set) 1930b842f2ecSJim Ingham result.AppendMessage("No breakpoints using this name."); 1931b9c1b51eSKate Stone } else { 1932b842f2ecSJim Ingham result.AppendMessageWithFormat("Name: %s not found.\n", name); 19335e09c8c3SJim Ingham } 1934b842f2ecSJim Ingham } 19355e09c8c3SJim Ingham } 19365e09c8c3SJim Ingham return true; 19375e09c8c3SJim Ingham } 19385e09c8c3SJim Ingham 19395e09c8c3SJim Ingham private: 19405e09c8c3SJim Ingham BreakpointNameOptionGroup m_name_options; 19415e09c8c3SJim Ingham OptionGroupOptions m_option_group; 19425e09c8c3SJim Ingham }; 19435e09c8c3SJim Ingham 1944e14dc268SJim Ingham // CommandObjectBreakpointName 1945b9c1b51eSKate Stone class CommandObjectBreakpointName : public CommandObjectMultiword { 19465e09c8c3SJim Ingham public: 19477428a18cSKate Stone CommandObjectBreakpointName(CommandInterpreter &interpreter) 1948b9c1b51eSKate Stone : CommandObjectMultiword( 1949b9c1b51eSKate Stone interpreter, "name", "Commands to manage name tags for breakpoints", 1950b9c1b51eSKate Stone "breakpoint name <subcommand> [<command-options>]") { 1951b9c1b51eSKate Stone CommandObjectSP add_command_object( 1952b9c1b51eSKate Stone new CommandObjectBreakpointNameAdd(interpreter)); 1953b9c1b51eSKate Stone CommandObjectSP delete_command_object( 1954b9c1b51eSKate Stone new CommandObjectBreakpointNameDelete(interpreter)); 1955b9c1b51eSKate Stone CommandObjectSP list_command_object( 1956b9c1b51eSKate Stone new CommandObjectBreakpointNameList(interpreter)); 1957b842f2ecSJim Ingham CommandObjectSP configure_command_object( 1958b842f2ecSJim Ingham new CommandObjectBreakpointNameConfigure(interpreter)); 19595e09c8c3SJim Ingham 19605e09c8c3SJim Ingham LoadSubCommand("add", add_command_object); 19615e09c8c3SJim Ingham LoadSubCommand("delete", delete_command_object); 19625e09c8c3SJim Ingham LoadSubCommand("list", list_command_object); 1963b842f2ecSJim Ingham LoadSubCommand("configure", configure_command_object); 19645e09c8c3SJim Ingham } 19655e09c8c3SJim Ingham 19669e85e5a8SEugene Zelenko ~CommandObjectBreakpointName() override = default; 19675e09c8c3SJim Ingham }; 19685e09c8c3SJim Ingham 1969e14dc268SJim Ingham // CommandObjectBreakpointRead 19703acdf385SJim Ingham #pragma mark Read::CommandOptions 1971f94668e3SRaphael Isemann #define LLDB_OPTIONS_breakpoint_read 1972f94668e3SRaphael Isemann #include "CommandOptions.inc" 19731f0f5b5bSZachary Turner 19741f0f5b5bSZachary Turner #pragma mark Read 1975e14dc268SJim Ingham 1976e14dc268SJim Ingham class CommandObjectBreakpointRead : public CommandObjectParsed { 1977e14dc268SJim Ingham public: 1978e14dc268SJim Ingham CommandObjectBreakpointRead(CommandInterpreter &interpreter) 1979e14dc268SJim Ingham : CommandObjectParsed(interpreter, "breakpoint read", 1980e14dc268SJim Ingham "Read and set the breakpoints previously saved to " 1981e14dc268SJim Ingham "a file with \"breakpoint write\". ", 1982e14dc268SJim Ingham nullptr), 1983e14dc268SJim Ingham m_options() { 1984e14dc268SJim Ingham CommandArgumentEntry arg; 1985e14dc268SJim Ingham CommandObject::AddIDsArgumentData(arg, eArgTypeBreakpointID, 1986e14dc268SJim Ingham eArgTypeBreakpointIDRange); 1987e14dc268SJim Ingham // Add the entry for the first argument for this command to the object's 1988e14dc268SJim Ingham // arguments vector. 1989e14dc268SJim Ingham m_arguments.push_back(arg); 1990e14dc268SJim Ingham } 1991e14dc268SJim Ingham 1992e14dc268SJim Ingham ~CommandObjectBreakpointRead() override = default; 1993e14dc268SJim Ingham 1994e14dc268SJim Ingham Options *GetOptions() override { return &m_options; } 1995e14dc268SJim Ingham 1996e14dc268SJim Ingham class CommandOptions : public Options { 1997e14dc268SJim Ingham public: 1998e14dc268SJim Ingham CommandOptions() : Options() {} 1999e14dc268SJim Ingham 2000e14dc268SJim Ingham ~CommandOptions() override = default; 2001e14dc268SJim Ingham 200297206d57SZachary Turner Status SetOptionValue(uint32_t option_idx, llvm::StringRef option_arg, 2003e14dc268SJim Ingham ExecutionContext *execution_context) override { 200497206d57SZachary Turner Status error; 2005e14dc268SJim Ingham const int short_option = m_getopt_table[option_idx].val; 2006e14dc268SJim Ingham 2007e14dc268SJim Ingham switch (short_option) { 2008e14dc268SJim Ingham case 'f': 2009e14dc268SJim Ingham m_filename.assign(option_arg); 2010e14dc268SJim Ingham break; 20113acdf385SJim Ingham case 'N': { 201297206d57SZachary Turner Status name_error; 20133acdf385SJim Ingham if (!BreakpointID::StringIsBreakpointName(llvm::StringRef(option_arg), 20143acdf385SJim Ingham name_error)) { 20153acdf385SJim Ingham error.SetErrorStringWithFormat("Invalid breakpoint name: %s", 20163acdf385SJim Ingham name_error.AsCString()); 20173acdf385SJim Ingham } 20183acdf385SJim Ingham m_names.push_back(option_arg); 20193acdf385SJim Ingham break; 20203acdf385SJim Ingham } 2021e14dc268SJim Ingham default: 202236162014SRaphael Isemann llvm_unreachable("Unimplemented option"); 2023e14dc268SJim Ingham } 2024e14dc268SJim Ingham 2025e14dc268SJim Ingham return error; 2026e14dc268SJim Ingham } 2027e14dc268SJim Ingham 2028e14dc268SJim Ingham void OptionParsingStarting(ExecutionContext *execution_context) override { 2029e14dc268SJim Ingham m_filename.clear(); 20303acdf385SJim Ingham m_names.clear(); 2031e14dc268SJim Ingham } 2032e14dc268SJim Ingham 20331f0f5b5bSZachary Turner llvm::ArrayRef<OptionDefinition> GetDefinitions() override { 203470602439SZachary Turner return llvm::makeArrayRef(g_breakpoint_read_options); 20351f0f5b5bSZachary Turner } 2036e14dc268SJim Ingham 2037e14dc268SJim Ingham // Instance variables to hold the values for command options. 2038e14dc268SJim Ingham 2039e14dc268SJim Ingham std::string m_filename; 20403acdf385SJim Ingham std::vector<std::string> m_names; 2041e14dc268SJim Ingham }; 2042e14dc268SJim Ingham 2043e14dc268SJim Ingham protected: 2044e14dc268SJim Ingham bool DoExecute(Args &command, CommandReturnObject &result) override { 2045cb2380c9SRaphael Isemann Target &target = GetSelectedOrDummyTarget(); 2046e14dc268SJim Ingham 20473acdf385SJim Ingham std::unique_lock<std::recursive_mutex> lock; 2048cb2380c9SRaphael Isemann target.GetBreakpointList().GetListMutex(lock); 20493acdf385SJim Ingham 20508f3be7a3SJonas Devlieghere FileSpec input_spec(m_options.m_filename); 20518f3be7a3SJonas Devlieghere FileSystem::Instance().Resolve(input_spec); 205201f16664SJim Ingham BreakpointIDList new_bps; 2053cb2380c9SRaphael Isemann Status error = target.CreateBreakpointsFromFile(input_spec, 2054cb2380c9SRaphael Isemann m_options.m_names, new_bps); 2055e14dc268SJim Ingham 2056e14dc268SJim Ingham if (!error.Success()) { 205701f16664SJim Ingham result.AppendError(error.AsCString()); 2058e14dc268SJim Ingham result.SetStatus(eReturnStatusFailed); 205901f16664SJim Ingham return false; 2060e14dc268SJim Ingham } 20613acdf385SJim Ingham 20623acdf385SJim Ingham Stream &output_stream = result.GetOutputStream(); 20633acdf385SJim Ingham 20643acdf385SJim Ingham size_t num_breakpoints = new_bps.GetSize(); 20653acdf385SJim Ingham if (num_breakpoints == 0) { 20663acdf385SJim Ingham result.AppendMessage("No breakpoints added."); 20673acdf385SJim Ingham } else { 20683acdf385SJim Ingham // No breakpoint selected; show info about all currently set breakpoints. 20693acdf385SJim Ingham result.AppendMessage("New breakpoints:"); 20703acdf385SJim Ingham for (size_t i = 0; i < num_breakpoints; ++i) { 20713acdf385SJim Ingham BreakpointID bp_id = new_bps.GetBreakpointIDAtIndex(i); 2072cb2380c9SRaphael Isemann Breakpoint *bp = target.GetBreakpointList() 20733acdf385SJim Ingham .FindBreakpointByID(bp_id.GetBreakpointID()) 20743acdf385SJim Ingham .get(); 20753acdf385SJim Ingham if (bp) 20763acdf385SJim Ingham bp->GetDescription(&output_stream, lldb::eDescriptionLevelInitial, 20773acdf385SJim Ingham false); 20783acdf385SJim Ingham } 20793acdf385SJim Ingham } 2080e14dc268SJim Ingham return result.Succeeded(); 2081e14dc268SJim Ingham } 2082e14dc268SJim Ingham 2083e14dc268SJim Ingham private: 2084e14dc268SJim Ingham CommandOptions m_options; 2085e14dc268SJim Ingham }; 2086e14dc268SJim Ingham 2087e14dc268SJim Ingham // CommandObjectBreakpointWrite 20881f0f5b5bSZachary Turner #pragma mark Write::CommandOptions 2089f94668e3SRaphael Isemann #define LLDB_OPTIONS_breakpoint_write 2090f94668e3SRaphael Isemann #include "CommandOptions.inc" 20911f0f5b5bSZachary Turner 20921f0f5b5bSZachary Turner #pragma mark Write 2093e14dc268SJim Ingham class CommandObjectBreakpointWrite : public CommandObjectParsed { 2094e14dc268SJim Ingham public: 2095e14dc268SJim Ingham CommandObjectBreakpointWrite(CommandInterpreter &interpreter) 2096e14dc268SJim Ingham : CommandObjectParsed(interpreter, "breakpoint write", 2097e14dc268SJim Ingham "Write the breakpoints listed to a file that can " 2098e14dc268SJim Ingham "be read in with \"breakpoint read\". " 2099e14dc268SJim Ingham "If given no arguments, writes all breakpoints.", 2100e14dc268SJim Ingham nullptr), 2101e14dc268SJim Ingham m_options() { 2102e14dc268SJim Ingham CommandArgumentEntry arg; 2103e14dc268SJim Ingham CommandObject::AddIDsArgumentData(arg, eArgTypeBreakpointID, 2104e14dc268SJim Ingham eArgTypeBreakpointIDRange); 2105e14dc268SJim Ingham // Add the entry for the first argument for this command to the object's 2106e14dc268SJim Ingham // arguments vector. 2107e14dc268SJim Ingham m_arguments.push_back(arg); 2108e14dc268SJim Ingham } 2109e14dc268SJim Ingham 2110e14dc268SJim Ingham ~CommandObjectBreakpointWrite() override = default; 2111e14dc268SJim Ingham 2112e14dc268SJim Ingham Options *GetOptions() override { return &m_options; } 2113e14dc268SJim Ingham 2114e14dc268SJim Ingham class CommandOptions : public Options { 2115e14dc268SJim Ingham public: 2116e14dc268SJim Ingham CommandOptions() : Options() {} 2117e14dc268SJim Ingham 2118e14dc268SJim Ingham ~CommandOptions() override = default; 2119e14dc268SJim Ingham 212097206d57SZachary Turner Status SetOptionValue(uint32_t option_idx, llvm::StringRef option_arg, 2121e14dc268SJim Ingham ExecutionContext *execution_context) override { 212297206d57SZachary Turner Status error; 2123e14dc268SJim Ingham const int short_option = m_getopt_table[option_idx].val; 2124e14dc268SJim Ingham 2125e14dc268SJim Ingham switch (short_option) { 2126e14dc268SJim Ingham case 'f': 2127e14dc268SJim Ingham m_filename.assign(option_arg); 2128e14dc268SJim Ingham break; 21292d3628e1SJim Ingham case 'a': 21302d3628e1SJim Ingham m_append = true; 21312d3628e1SJim Ingham break; 2132e14dc268SJim Ingham default: 213336162014SRaphael Isemann llvm_unreachable("Unimplemented option"); 2134e14dc268SJim Ingham } 2135e14dc268SJim Ingham 2136e14dc268SJim Ingham return error; 2137e14dc268SJim Ingham } 2138e14dc268SJim Ingham 2139e14dc268SJim Ingham void OptionParsingStarting(ExecutionContext *execution_context) override { 2140e14dc268SJim Ingham m_filename.clear(); 21412d3628e1SJim Ingham m_append = false; 2142e14dc268SJim Ingham } 2143e14dc268SJim Ingham 21441f0f5b5bSZachary Turner llvm::ArrayRef<OptionDefinition> GetDefinitions() override { 214570602439SZachary Turner return llvm::makeArrayRef(g_breakpoint_write_options); 21461f0f5b5bSZachary Turner } 2147e14dc268SJim Ingham 2148e14dc268SJim Ingham // Instance variables to hold the values for command options. 2149e14dc268SJim Ingham 2150e14dc268SJim Ingham std::string m_filename; 21512d3628e1SJim Ingham bool m_append = false; 2152e14dc268SJim Ingham }; 2153e14dc268SJim Ingham 2154e14dc268SJim Ingham protected: 2155e14dc268SJim Ingham bool DoExecute(Args &command, CommandReturnObject &result) override { 2156cb2380c9SRaphael Isemann Target &target = GetSelectedOrDummyTarget(); 2157e14dc268SJim Ingham 2158e14dc268SJim Ingham std::unique_lock<std::recursive_mutex> lock; 2159cb2380c9SRaphael Isemann target.GetBreakpointList().GetListMutex(lock); 2160e14dc268SJim Ingham 2161e14dc268SJim Ingham BreakpointIDList valid_bp_ids; 216211eb9c64SZachary Turner if (!command.empty()) { 2163e14dc268SJim Ingham CommandObjectMultiwordBreakpoint::VerifyBreakpointIDs( 2164cb2380c9SRaphael Isemann command, &target, result, &valid_bp_ids, 2165b842f2ecSJim Ingham BreakpointName::Permissions::PermissionKinds::listPerm); 2166e14dc268SJim Ingham 216701f16664SJim Ingham if (!result.Succeeded()) { 2168e14dc268SJim Ingham result.SetStatus(eReturnStatusFailed); 2169e14dc268SJim Ingham return false; 2170e14dc268SJim Ingham } 2171e14dc268SJim Ingham } 21728f3be7a3SJonas Devlieghere FileSpec file_spec(m_options.m_filename); 21738f3be7a3SJonas Devlieghere FileSystem::Instance().Resolve(file_spec); 2174cb2380c9SRaphael Isemann Status error = target.SerializeBreakpointsToFile(file_spec, valid_bp_ids, 21758f3be7a3SJonas Devlieghere m_options.m_append); 217601f16664SJim Ingham if (!error.Success()) { 217701f16664SJim Ingham result.AppendErrorWithFormat("error serializing breakpoints: %s.", 217801f16664SJim Ingham error.AsCString()); 217901f16664SJim Ingham result.SetStatus(eReturnStatusFailed); 2180e14dc268SJim Ingham } 2181e14dc268SJim Ingham return result.Succeeded(); 2182e14dc268SJim Ingham } 2183e14dc268SJim Ingham 2184e14dc268SJim Ingham private: 2185e14dc268SJim Ingham CommandOptions m_options; 2186e14dc268SJim Ingham }; 2187e14dc268SJim Ingham 218830fdc8d8SChris Lattner // CommandObjectMultiwordBreakpoint 2189ae1c4cf5SJim Ingham #pragma mark MultiwordBreakpoint 219030fdc8d8SChris Lattner 2191b9c1b51eSKate Stone CommandObjectMultiwordBreakpoint::CommandObjectMultiwordBreakpoint( 2192b9c1b51eSKate Stone CommandInterpreter &interpreter) 2193b9c1b51eSKate Stone : CommandObjectMultiword( 2194b9c1b51eSKate Stone interpreter, "breakpoint", 21957428a18cSKate Stone "Commands for operating on breakpoints (see 'help b' for shorthand.)", 2196b9c1b51eSKate Stone "breakpoint <subcommand> [<command-options>]") { 2197b9c1b51eSKate Stone CommandObjectSP list_command_object( 2198b9c1b51eSKate Stone new CommandObjectBreakpointList(interpreter)); 2199b9c1b51eSKate Stone CommandObjectSP enable_command_object( 2200b9c1b51eSKate Stone new CommandObjectBreakpointEnable(interpreter)); 2201b9c1b51eSKate Stone CommandObjectSP disable_command_object( 2202b9c1b51eSKate Stone new CommandObjectBreakpointDisable(interpreter)); 2203b9c1b51eSKate Stone CommandObjectSP clear_command_object( 2204b9c1b51eSKate Stone new CommandObjectBreakpointClear(interpreter)); 2205b9c1b51eSKate Stone CommandObjectSP delete_command_object( 2206b9c1b51eSKate Stone new CommandObjectBreakpointDelete(interpreter)); 2207b9c1b51eSKate Stone CommandObjectSP set_command_object( 2208b9c1b51eSKate Stone new CommandObjectBreakpointSet(interpreter)); 2209b9c1b51eSKate Stone CommandObjectSP command_command_object( 2210b9c1b51eSKate Stone new CommandObjectBreakpointCommand(interpreter)); 2211b9c1b51eSKate Stone CommandObjectSP modify_command_object( 2212b9c1b51eSKate Stone new CommandObjectBreakpointModify(interpreter)); 2213b9c1b51eSKate Stone CommandObjectSP name_command_object( 2214b9c1b51eSKate Stone new CommandObjectBreakpointName(interpreter)); 2215e14dc268SJim Ingham CommandObjectSP write_command_object( 2216e14dc268SJim Ingham new CommandObjectBreakpointWrite(interpreter)); 2217e14dc268SJim Ingham CommandObjectSP read_command_object( 2218e14dc268SJim Ingham new CommandObjectBreakpointRead(interpreter)); 221930fdc8d8SChris Lattner 2220b7234e40SJohnny Chen list_command_object->SetCommandName("breakpoint list"); 222130fdc8d8SChris Lattner enable_command_object->SetCommandName("breakpoint enable"); 222230fdc8d8SChris Lattner disable_command_object->SetCommandName("breakpoint disable"); 2223b7234e40SJohnny Chen clear_command_object->SetCommandName("breakpoint clear"); 2224b7234e40SJohnny Chen delete_command_object->SetCommandName("breakpoint delete"); 2225ae1c4cf5SJim Ingham set_command_object->SetCommandName("breakpoint set"); 2226b7234e40SJohnny Chen command_command_object->SetCommandName("breakpoint command"); 2227b7234e40SJohnny Chen modify_command_object->SetCommandName("breakpoint modify"); 22285e09c8c3SJim Ingham name_command_object->SetCommandName("breakpoint name"); 2229e14dc268SJim Ingham write_command_object->SetCommandName("breakpoint write"); 2230e14dc268SJim Ingham read_command_object->SetCommandName("breakpoint read"); 223130fdc8d8SChris Lattner 223223f59509SGreg Clayton LoadSubCommand("list", list_command_object); 223323f59509SGreg Clayton LoadSubCommand("enable", enable_command_object); 223423f59509SGreg Clayton LoadSubCommand("disable", disable_command_object); 223523f59509SGreg Clayton LoadSubCommand("clear", clear_command_object); 223623f59509SGreg Clayton LoadSubCommand("delete", delete_command_object); 223723f59509SGreg Clayton LoadSubCommand("set", set_command_object); 223823f59509SGreg Clayton LoadSubCommand("command", command_command_object); 223923f59509SGreg Clayton LoadSubCommand("modify", modify_command_object); 22405e09c8c3SJim Ingham LoadSubCommand("name", name_command_object); 2241e14dc268SJim Ingham LoadSubCommand("write", write_command_object); 2242e14dc268SJim Ingham LoadSubCommand("read", read_command_object); 224330fdc8d8SChris Lattner } 224430fdc8d8SChris Lattner 22459e85e5a8SEugene Zelenko CommandObjectMultiwordBreakpoint::~CommandObjectMultiwordBreakpoint() = default; 224630fdc8d8SChris Lattner 2247a925974bSAdrian Prantl void CommandObjectMultiwordBreakpoint::VerifyIDs( 2248a925974bSAdrian Prantl Args &args, Target *target, bool allow_locations, 2249a925974bSAdrian Prantl CommandReturnObject &result, BreakpointIDList *valid_ids, 2250a925974bSAdrian Prantl BreakpointName::Permissions ::PermissionKinds purpose) { 225130fdc8d8SChris Lattner // args can be strings representing 1). integers (for breakpoint ids) 2252b9c1b51eSKate Stone // 2). the full breakpoint & location 2253b9c1b51eSKate Stone // canonical representation 2254b9c1b51eSKate Stone // 3). the word "to" or a hyphen, 2255b9c1b51eSKate Stone // representing a range (in which case there 2256b9c1b51eSKate Stone // had *better* be an entry both before & 2257b9c1b51eSKate Stone // after of one of the first two types. 22585e09c8c3SJim Ingham // 4). A breakpoint name 2259b9c1b51eSKate Stone // If args is empty, we will use the last created breakpoint (if there is 2260b9c1b51eSKate Stone // one.) 226130fdc8d8SChris Lattner 226230fdc8d8SChris Lattner Args temp_args; 226330fdc8d8SChris Lattner 226411eb9c64SZachary Turner if (args.empty()) { 2265b9c1b51eSKate Stone if (target->GetLastCreatedBreakpoint()) { 2266b9c1b51eSKate Stone valid_ids->AddBreakpointID(BreakpointID( 2267b9c1b51eSKate Stone target->GetLastCreatedBreakpoint()->GetID(), LLDB_INVALID_BREAK_ID)); 226836f3b369SJim Ingham result.SetStatus(eReturnStatusSuccessFinishNoResult); 2269b9c1b51eSKate Stone } else { 2270b9c1b51eSKate Stone result.AppendError( 2271b9c1b51eSKate Stone "No breakpoint specified and no last created breakpoint."); 227236f3b369SJim Ingham result.SetStatus(eReturnStatusFailed); 227336f3b369SJim Ingham } 227436f3b369SJim Ingham return; 227536f3b369SJim Ingham } 227636f3b369SJim Ingham 2277b9c1b51eSKate Stone // Create a new Args variable to use; copy any non-breakpoint-id-ranges stuff 227805097246SAdrian Prantl // directly from the old ARGS to the new TEMP_ARGS. Do not copy breakpoint 227905097246SAdrian Prantl // id range strings over; instead generate a list of strings for all the 228005097246SAdrian Prantl // breakpoint ids in the range, and shove all of those breakpoint id strings 228105097246SAdrian Prantl // into TEMP_ARGS. 228230fdc8d8SChris Lattner 2283b9c1b51eSKate Stone BreakpointIDList::FindAndReplaceIDRanges(args, target, allow_locations, 2284b842f2ecSJim Ingham purpose, result, temp_args); 228530fdc8d8SChris Lattner 2286b9c1b51eSKate Stone // NOW, convert the list of breakpoint id strings in TEMP_ARGS into an actual 2287b9c1b51eSKate Stone // BreakpointIDList: 228830fdc8d8SChris Lattner 228916662f3cSPavel Labath valid_ids->InsertStringArray(temp_args.GetArgumentArrayRef(), result); 229030fdc8d8SChris Lattner 229105097246SAdrian Prantl // At this point, all of the breakpoint ids that the user passed in have 229205097246SAdrian Prantl // been converted to breakpoint IDs and put into valid_ids. 229330fdc8d8SChris Lattner 2294b9c1b51eSKate Stone if (result.Succeeded()) { 2295b9c1b51eSKate Stone // Now that we've converted everything from args into a list of breakpoint 229605097246SAdrian Prantl // ids, go through our tentative list of breakpoint id's and verify that 229705097246SAdrian Prantl // they correspond to valid/currently set breakpoints. 229830fdc8d8SChris Lattner 2299c982c768SGreg Clayton const size_t count = valid_ids->GetSize(); 2300b9c1b51eSKate Stone for (size_t i = 0; i < count; ++i) { 230130fdc8d8SChris Lattner BreakpointID cur_bp_id = valid_ids->GetBreakpointIDAtIndex(i); 2302b9c1b51eSKate Stone Breakpoint *breakpoint = 2303b9c1b51eSKate Stone target->GetBreakpointByID(cur_bp_id.GetBreakpointID()).get(); 2304b9c1b51eSKate Stone if (breakpoint != nullptr) { 2305c7bece56SGreg Clayton const size_t num_locations = breakpoint->GetNumLocations(); 2306b9c1b51eSKate Stone if (static_cast<size_t>(cur_bp_id.GetLocationID()) > num_locations) { 230730fdc8d8SChris Lattner StreamString id_str; 2308b9c1b51eSKate Stone BreakpointID::GetCanonicalReference( 2309b9c1b51eSKate Stone &id_str, cur_bp_id.GetBreakpointID(), cur_bp_id.GetLocationID()); 2310c982c768SGreg Clayton i = valid_ids->GetSize() + 1; 2311b9c1b51eSKate Stone result.AppendErrorWithFormat( 2312b9c1b51eSKate Stone "'%s' is not a currently valid breakpoint/location id.\n", 231330fdc8d8SChris Lattner id_str.GetData()); 231430fdc8d8SChris Lattner result.SetStatus(eReturnStatusFailed); 231530fdc8d8SChris Lattner } 2316b9c1b51eSKate Stone } else { 2317c982c768SGreg Clayton i = valid_ids->GetSize() + 1; 2318b9c1b51eSKate Stone result.AppendErrorWithFormat( 2319b9c1b51eSKate Stone "'%d' is not a currently valid breakpoint ID.\n", 23207428a18cSKate Stone cur_bp_id.GetBreakpointID()); 232130fdc8d8SChris Lattner result.SetStatus(eReturnStatusFailed); 232230fdc8d8SChris Lattner } 232330fdc8d8SChris Lattner } 232430fdc8d8SChris Lattner } 232530fdc8d8SChris Lattner } 2326