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" 1932abc6edSZachary Turner #include "lldb/Interpreter/OptionValueBoolean.h" 205e09c8c3SJim Ingham #include "lldb/Interpreter/OptionValueString.h" 215e09c8c3SJim Ingham #include "lldb/Interpreter/OptionValueUInt64.h" 22b9c1b51eSKate Stone #include "lldb/Interpreter/Options.h" 230e0984eeSJim Ingham #include "lldb/Target/Language.h" 24b57e4a1bSJason Molenda #include "lldb/Target/StackFrame.h" 25b9c1b51eSKate Stone #include "lldb/Target/Target.h" 261b54c88cSJim Ingham #include "lldb/Target/Thread.h" 271b54c88cSJim Ingham #include "lldb/Target/ThreadSpec.h" 28bf9a7730SZachary Turner #include "lldb/Utility/RegularExpression.h" 29bf9a7730SZachary Turner #include "lldb/Utility/StreamString.h" 3030fdc8d8SChris Lattner 31796ac80bSJonas Devlieghere #include <memory> 32796ac80bSJonas Devlieghere #include <vector> 33796ac80bSJonas Devlieghere 3430fdc8d8SChris Lattner using namespace lldb; 3530fdc8d8SChris Lattner using namespace lldb_private; 3630fdc8d8SChris Lattner 37b9c1b51eSKate Stone static void AddBreakpointDescription(Stream *s, Breakpoint *bp, 38b9c1b51eSKate Stone lldb::DescriptionLevel level) { 3930fdc8d8SChris Lattner s->IndentMore(); 4030fdc8d8SChris Lattner bp->GetDescription(s, level, true); 4130fdc8d8SChris Lattner s->IndentLess(); 4230fdc8d8SChris Lattner s->EOL(); 4330fdc8d8SChris Lattner } 4430fdc8d8SChris Lattner 45b842f2ecSJim Ingham // Modifiable Breakpoint Options 46b842f2ecSJim Ingham #pragma mark Modify::CommandOptions 47f94668e3SRaphael Isemann #define LLDB_OPTIONS_breakpoint_modify 48f94668e3SRaphael Isemann #include "CommandOptions.inc" 49bd68a052SRaphael Isemann 50b842f2ecSJim Ingham class lldb_private::BreakpointOptionGroup : public OptionGroup 51b842f2ecSJim Ingham { 52b842f2ecSJim Ingham public: 53b842f2ecSJim Ingham BreakpointOptionGroup() : 54b842f2ecSJim Ingham OptionGroup(), 55b842f2ecSJim Ingham m_bp_opts(false) {} 56b842f2ecSJim Ingham 57b842f2ecSJim Ingham ~BreakpointOptionGroup() override = default; 58b842f2ecSJim Ingham 59b842f2ecSJim Ingham llvm::ArrayRef<OptionDefinition> GetDefinitions() override { 60b842f2ecSJim Ingham return llvm::makeArrayRef(g_breakpoint_modify_options); 61b842f2ecSJim Ingham } 62b842f2ecSJim Ingham 63b842f2ecSJim Ingham Status SetOptionValue(uint32_t option_idx, llvm::StringRef option_arg, 64b842f2ecSJim Ingham ExecutionContext *execution_context) override { 65b842f2ecSJim Ingham Status error; 66b842f2ecSJim Ingham const int short_option = g_breakpoint_modify_options[option_idx].short_option; 67b842f2ecSJim Ingham 68b842f2ecSJim Ingham switch (short_option) { 69b842f2ecSJim Ingham case 'c': 7005097246SAdrian Prantl // Normally an empty breakpoint condition marks is as unset. But we need 7105097246SAdrian Prantl // to say it was passed in. 72b842f2ecSJim Ingham m_bp_opts.SetCondition(option_arg.str().c_str()); 73b842f2ecSJim Ingham m_bp_opts.m_set_flags.Set(BreakpointOptions::eCondition); 74b842f2ecSJim Ingham break; 75b842f2ecSJim Ingham case 'C': 76b842f2ecSJim Ingham m_commands.push_back(option_arg); 77b842f2ecSJim Ingham break; 78b842f2ecSJim Ingham case 'd': 79b842f2ecSJim Ingham m_bp_opts.SetEnabled(false); 80b842f2ecSJim Ingham break; 81b842f2ecSJim Ingham case 'e': 82b842f2ecSJim Ingham m_bp_opts.SetEnabled(true); 83b842f2ecSJim Ingham break; 84b842f2ecSJim Ingham case 'G': { 85b842f2ecSJim Ingham bool value, success; 8647cbf4a0SPavel Labath value = OptionArgParser::ToBoolean(option_arg, false, &success); 87b842f2ecSJim Ingham if (success) { 88b842f2ecSJim Ingham m_bp_opts.SetAutoContinue(value); 89b842f2ecSJim Ingham } else 90b842f2ecSJim Ingham error.SetErrorStringWithFormat( 91b842f2ecSJim Ingham "invalid boolean value '%s' passed for -G option", 92b842f2ecSJim Ingham option_arg.str().c_str()); 93b842f2ecSJim Ingham } 94b842f2ecSJim Ingham break; 95b842f2ecSJim Ingham case 'i': 96b842f2ecSJim Ingham { 97b842f2ecSJim Ingham uint32_t ignore_count; 98b842f2ecSJim Ingham if (option_arg.getAsInteger(0, ignore_count)) 99b842f2ecSJim Ingham error.SetErrorStringWithFormat("invalid ignore count '%s'", 100b842f2ecSJim Ingham option_arg.str().c_str()); 101b842f2ecSJim Ingham else 102b842f2ecSJim Ingham m_bp_opts.SetIgnoreCount(ignore_count); 103b842f2ecSJim Ingham } 104b842f2ecSJim Ingham break; 105b842f2ecSJim Ingham case 'o': { 106b842f2ecSJim Ingham bool value, success; 10747cbf4a0SPavel Labath value = OptionArgParser::ToBoolean(option_arg, false, &success); 108b842f2ecSJim Ingham if (success) { 109b842f2ecSJim Ingham m_bp_opts.SetOneShot(value); 110b842f2ecSJim Ingham } else 111b842f2ecSJim Ingham error.SetErrorStringWithFormat( 112b842f2ecSJim Ingham "invalid boolean value '%s' passed for -o option", 113b842f2ecSJim Ingham option_arg.str().c_str()); 114b842f2ecSJim Ingham } break; 115b842f2ecSJim Ingham case 't': 116b842f2ecSJim Ingham { 117b842f2ecSJim Ingham lldb::tid_t thread_id = LLDB_INVALID_THREAD_ID; 118b842f2ecSJim Ingham if (option_arg[0] != '\0') { 119b842f2ecSJim Ingham if (option_arg.getAsInteger(0, thread_id)) 120b842f2ecSJim Ingham error.SetErrorStringWithFormat("invalid thread id string '%s'", 121b842f2ecSJim Ingham option_arg.str().c_str()); 122b842f2ecSJim Ingham } 123b842f2ecSJim Ingham m_bp_opts.SetThreadID(thread_id); 124b842f2ecSJim Ingham } 125b842f2ecSJim Ingham break; 126b842f2ecSJim Ingham case 'T': 127b842f2ecSJim Ingham m_bp_opts.GetThreadSpec()->SetName(option_arg.str().c_str()); 128b842f2ecSJim Ingham break; 129b842f2ecSJim Ingham case 'q': 130b842f2ecSJim Ingham m_bp_opts.GetThreadSpec()->SetQueueName(option_arg.str().c_str()); 131b842f2ecSJim Ingham break; 132b842f2ecSJim Ingham case 'x': 133b842f2ecSJim Ingham { 134b842f2ecSJim Ingham uint32_t thread_index = UINT32_MAX; 135b842f2ecSJim Ingham if (option_arg[0] != '\n') { 136b842f2ecSJim Ingham if (option_arg.getAsInteger(0, thread_index)) 137b842f2ecSJim Ingham error.SetErrorStringWithFormat("invalid thread index string '%s'", 138b842f2ecSJim Ingham option_arg.str().c_str()); 139b842f2ecSJim Ingham } 140b842f2ecSJim Ingham m_bp_opts.GetThreadSpec()->SetIndex(thread_index); 141b842f2ecSJim Ingham } 142b842f2ecSJim Ingham break; 143b842f2ecSJim Ingham default: 14436162014SRaphael Isemann llvm_unreachable("Unimplemented option"); 145b842f2ecSJim Ingham } 146b842f2ecSJim Ingham 147b842f2ecSJim Ingham return error; 148b842f2ecSJim Ingham } 149b842f2ecSJim Ingham 150b842f2ecSJim Ingham void OptionParsingStarting(ExecutionContext *execution_context) override { 151b842f2ecSJim Ingham m_bp_opts.Clear(); 152b842f2ecSJim Ingham m_commands.clear(); 153b842f2ecSJim Ingham } 154b842f2ecSJim Ingham 155b842f2ecSJim Ingham Status OptionParsingFinished(ExecutionContext *execution_context) override { 156b842f2ecSJim Ingham if (!m_commands.empty()) 157b842f2ecSJim Ingham { 158b842f2ecSJim Ingham if (!m_commands.empty()) 159b842f2ecSJim Ingham { 160a8f3ae7cSJonas Devlieghere auto cmd_data = std::make_unique<BreakpointOptions::CommandData>(); 161b842f2ecSJim Ingham 162b842f2ecSJim Ingham for (std::string &str : m_commands) 163b842f2ecSJim Ingham cmd_data->user_source.AppendString(str); 164b842f2ecSJim Ingham 165b842f2ecSJim Ingham cmd_data->stop_on_error = true; 166b842f2ecSJim Ingham m_bp_opts.SetCommandDataCallback(cmd_data); 167b842f2ecSJim Ingham } 168b842f2ecSJim Ingham } 169b842f2ecSJim Ingham return Status(); 170b842f2ecSJim Ingham } 171b842f2ecSJim Ingham 172b842f2ecSJim Ingham const BreakpointOptions &GetBreakpointOptions() 173b842f2ecSJim Ingham { 174b842f2ecSJim Ingham return m_bp_opts; 175b842f2ecSJim Ingham } 176b842f2ecSJim Ingham 177b842f2ecSJim Ingham std::vector<std::string> m_commands; 178b842f2ecSJim Ingham BreakpointOptions m_bp_opts; 179b842f2ecSJim Ingham 180b842f2ecSJim Ingham }; 181bd68a052SRaphael Isemann 182f94668e3SRaphael Isemann #define LLDB_OPTIONS_breakpoint_dummy 183f94668e3SRaphael Isemann #include "CommandOptions.inc" 184b842f2ecSJim Ingham 185b842f2ecSJim Ingham class BreakpointDummyOptionGroup : public OptionGroup 186b842f2ecSJim Ingham { 187b842f2ecSJim Ingham public: 188b842f2ecSJim Ingham BreakpointDummyOptionGroup() : 189b842f2ecSJim Ingham OptionGroup() {} 190b842f2ecSJim Ingham 191b842f2ecSJim Ingham ~BreakpointDummyOptionGroup() override = default; 192b842f2ecSJim Ingham 193b842f2ecSJim Ingham llvm::ArrayRef<OptionDefinition> GetDefinitions() override { 194b842f2ecSJim Ingham return llvm::makeArrayRef(g_breakpoint_dummy_options); 195b842f2ecSJim Ingham } 196b842f2ecSJim Ingham 197b842f2ecSJim Ingham Status SetOptionValue(uint32_t option_idx, llvm::StringRef option_arg, 198b842f2ecSJim Ingham ExecutionContext *execution_context) override { 199b842f2ecSJim Ingham Status error; 200b842f2ecSJim Ingham const int short_option = g_breakpoint_modify_options[option_idx].short_option; 201b842f2ecSJim Ingham 202b842f2ecSJim Ingham switch (short_option) { 203b842f2ecSJim Ingham case 'D': 204b842f2ecSJim Ingham m_use_dummy = true; 205b842f2ecSJim Ingham break; 206b842f2ecSJim Ingham default: 20736162014SRaphael Isemann llvm_unreachable("Unimplemented option"); 208b842f2ecSJim Ingham } 209b842f2ecSJim Ingham 210b842f2ecSJim Ingham return error; 211b842f2ecSJim Ingham } 212b842f2ecSJim Ingham 213b842f2ecSJim Ingham void OptionParsingStarting(ExecutionContext *execution_context) override { 214b842f2ecSJim Ingham m_use_dummy = false; 215b842f2ecSJim Ingham } 216b842f2ecSJim Ingham 217b842f2ecSJim Ingham bool m_use_dummy; 218b842f2ecSJim Ingham 219b842f2ecSJim Ingham }; 220b842f2ecSJim Ingham 221f94668e3SRaphael Isemann #define LLDB_OPTIONS_breakpoint_set 222f94668e3SRaphael Isemann #include "CommandOptions.inc" 2231f0f5b5bSZachary Turner 2245a988416SJim Ingham // CommandObjectBreakpointSet 22530fdc8d8SChris Lattner 226b9c1b51eSKate Stone class CommandObjectBreakpointSet : public CommandObjectParsed { 2275a988416SJim Ingham public: 228efe8e7e3SFangrui Song enum BreakpointSetType { 2295a988416SJim Ingham eSetTypeInvalid, 2305a988416SJim Ingham eSetTypeFileAndLine, 2315a988416SJim Ingham eSetTypeAddress, 2325a988416SJim Ingham eSetTypeFunctionName, 2335a988416SJim Ingham eSetTypeFunctionRegexp, 2345a988416SJim Ingham eSetTypeSourceRegexp, 2353815e702SJim Ingham eSetTypeException, 2363815e702SJim Ingham eSetTypeScripted, 237efe8e7e3SFangrui Song }; 2385a988416SJim Ingham 239b9c1b51eSKate Stone CommandObjectBreakpointSet(CommandInterpreter &interpreter) 240b9c1b51eSKate Stone : CommandObjectParsed( 241b9c1b51eSKate Stone interpreter, "breakpoint set", 2425a988416SJim Ingham "Sets a breakpoint or set of breakpoints in the executable.", 2435a988416SJim Ingham "breakpoint set <cmd-options>"), 244b842f2ecSJim Ingham m_bp_opts(), m_options() { 245b842f2ecSJim Ingham // We're picking up all the normal options, commands and disable. 246b842f2ecSJim Ingham m_all_options.Append(&m_bp_opts, 247b842f2ecSJim Ingham LLDB_OPT_SET_1 | LLDB_OPT_SET_3 | LLDB_OPT_SET_4, 248b842f2ecSJim Ingham LLDB_OPT_SET_ALL); 249b842f2ecSJim Ingham m_all_options.Append(&m_dummy_options, LLDB_OPT_SET_1, LLDB_OPT_SET_ALL); 250b842f2ecSJim Ingham m_all_options.Append(&m_options); 251b842f2ecSJim Ingham m_all_options.Finalize(); 252b842f2ecSJim Ingham } 2535a988416SJim Ingham 2549e85e5a8SEugene Zelenko ~CommandObjectBreakpointSet() override = default; 2555a988416SJim Ingham 256b842f2ecSJim Ingham Options *GetOptions() override { return &m_all_options; } 2575a988416SJim Ingham 258b842f2ecSJim Ingham class CommandOptions : public OptionGroup { 2595a988416SJim Ingham public: 260b9c1b51eSKate Stone CommandOptions() 261b842f2ecSJim Ingham : OptionGroup(), m_condition(), m_filenames(), m_line_num(0), m_column(0), 262b9c1b51eSKate Stone m_func_names(), m_func_name_type_mask(eFunctionNameTypeNone), 263b9c1b51eSKate Stone m_func_regexp(), m_source_text_regexp(), m_modules(), m_load_addr(), 264b9c1b51eSKate Stone m_catch_bp(false), m_throw_bp(true), m_hardware(false), 265a72b31c7SJim Ingham m_exception_language(eLanguageTypeUnknown), 26623b1decbSDawn Perchik m_language(lldb::eLanguageTypeUnknown), 267b842f2ecSJim Ingham m_skip_prologue(eLazyBoolCalculate), 268b9c1b51eSKate Stone m_all_files(false), m_move_to_nearest_code(eLazyBoolCalculate) {} 26930fdc8d8SChris Lattner 2709e85e5a8SEugene Zelenko ~CommandOptions() override = default; 27187df91b8SJim Ingham 27297206d57SZachary Turner Status SetOptionValue(uint32_t option_idx, llvm::StringRef option_arg, 273b9c1b51eSKate Stone ExecutionContext *execution_context) override { 27497206d57SZachary Turner Status error; 275b842f2ecSJim Ingham const int short_option = g_breakpoint_set_options[option_idx].short_option; 27630fdc8d8SChris Lattner 277b9c1b51eSKate Stone switch (short_option) { 278b9c1b51eSKate Stone case 'a': { 27947cbf4a0SPavel Labath m_load_addr = OptionArgParser::ToAddress(execution_context, option_arg, 280e1cfbc79STodd Fiala LLDB_INVALID_ADDRESS, &error); 281b9c1b51eSKate Stone } break; 28230fdc8d8SChris Lattner 283e732052fSJim Ingham case 'A': 284e732052fSJim Ingham m_all_files = true; 285e732052fSJim Ingham break; 286e732052fSJim Ingham 287ca36cd16SJim Ingham case 'b': 288ca36cd16SJim Ingham m_func_names.push_back(option_arg); 289ca36cd16SJim Ingham m_func_name_type_mask |= eFunctionNameTypeBase; 290ca36cd16SJim Ingham break; 291ca36cd16SJim Ingham 292fe11483bSZachary Turner case 'C': 293fe11483bSZachary Turner if (option_arg.getAsInteger(0, m_column)) 294b9c1b51eSKate Stone error.SetErrorStringWithFormat("invalid column number: %s", 295fe11483bSZachary Turner option_arg.str().c_str()); 29630fdc8d8SChris Lattner break; 2979e85e5a8SEugene Zelenko 298b9c1b51eSKate Stone case 'E': { 299fe11483bSZachary Turner LanguageType language = Language::GetLanguageTypeFromString(option_arg); 300fab10e89SJim Ingham 301b9c1b51eSKate Stone switch (language) { 302fab10e89SJim Ingham case eLanguageTypeC89: 303fab10e89SJim Ingham case eLanguageTypeC: 304fab10e89SJim Ingham case eLanguageTypeC99: 3051d0089faSBruce Mitchener case eLanguageTypeC11: 306a72b31c7SJim Ingham m_exception_language = eLanguageTypeC; 307fab10e89SJim Ingham break; 308fab10e89SJim Ingham case eLanguageTypeC_plus_plus: 3091d0089faSBruce Mitchener case eLanguageTypeC_plus_plus_03: 3101d0089faSBruce Mitchener case eLanguageTypeC_plus_plus_11: 3112ba84a6aSBruce Mitchener case eLanguageTypeC_plus_plus_14: 312a72b31c7SJim Ingham m_exception_language = eLanguageTypeC_plus_plus; 313fab10e89SJim Ingham break; 314fab10e89SJim Ingham case eLanguageTypeObjC: 315a72b31c7SJim Ingham m_exception_language = eLanguageTypeObjC; 316fab10e89SJim Ingham break; 317fab10e89SJim Ingham case eLanguageTypeObjC_plus_plus: 318b9c1b51eSKate Stone error.SetErrorStringWithFormat( 319b9c1b51eSKate Stone "Set exception breakpoints separately for c++ and objective-c"); 320fab10e89SJim Ingham break; 321fab10e89SJim Ingham case eLanguageTypeUnknown: 322b9c1b51eSKate Stone error.SetErrorStringWithFormat( 323b9c1b51eSKate Stone "Unknown language type: '%s' for exception breakpoint", 324fe11483bSZachary Turner option_arg.str().c_str()); 325fab10e89SJim Ingham break; 326fab10e89SJim Ingham default: 327b9c1b51eSKate Stone error.SetErrorStringWithFormat( 328b9c1b51eSKate Stone "Unsupported language type: '%s' for exception breakpoint", 329fe11483bSZachary Turner option_arg.str().c_str()); 330fab10e89SJim Ingham } 331b9c1b51eSKate Stone } break; 332ca36cd16SJim Ingham 333ca36cd16SJim Ingham case 'f': 3348f3be7a3SJonas Devlieghere m_filenames.AppendIfUnique(FileSpec(option_arg)); 335fab10e89SJim Ingham break; 336ca36cd16SJim Ingham 337ca36cd16SJim Ingham case 'F': 338ca36cd16SJim Ingham m_func_names.push_back(option_arg); 339ca36cd16SJim Ingham m_func_name_type_mask |= eFunctionNameTypeFull; 340ca36cd16SJim Ingham break; 341ca36cd16SJim Ingham 342b9c1b51eSKate Stone case 'h': { 343fab10e89SJim Ingham bool success; 34447cbf4a0SPavel Labath m_catch_bp = OptionArgParser::ToBoolean(option_arg, true, &success); 345fab10e89SJim Ingham if (!success) 346b9c1b51eSKate Stone error.SetErrorStringWithFormat( 347fe11483bSZachary Turner "Invalid boolean value for on-catch option: '%s'", 348fe11483bSZachary Turner option_arg.str().c_str()); 349b9c1b51eSKate Stone } break; 350eb023e75SGreg Clayton 351eb023e75SGreg Clayton case 'H': 352eb023e75SGreg Clayton m_hardware = true; 353eb023e75SGreg Clayton break; 354eb023e75SGreg Clayton 3553815e702SJim Ingham case 'k': { 3563815e702SJim Ingham if (m_current_key.empty()) 3573815e702SJim Ingham m_current_key.assign(option_arg); 3583815e702SJim Ingham else 3593815e702SJim Ingham error.SetErrorStringWithFormat("Key: %s missing value.", 3603815e702SJim Ingham m_current_key.c_str()); 3613815e702SJim Ingham 3623815e702SJim Ingham } break; 363b9c1b51eSKate Stone case 'K': { 364a8558b62SJim Ingham bool success; 365a8558b62SJim Ingham bool value; 36647cbf4a0SPavel Labath value = OptionArgParser::ToBoolean(option_arg, true, &success); 367a8558b62SJim Ingham if (value) 368a8558b62SJim Ingham m_skip_prologue = eLazyBoolYes; 369a8558b62SJim Ingham else 370a8558b62SJim Ingham m_skip_prologue = eLazyBoolNo; 371a8558b62SJim Ingham 372a8558b62SJim Ingham if (!success) 373b9c1b51eSKate Stone error.SetErrorStringWithFormat( 374b9c1b51eSKate Stone "Invalid boolean value for skip prologue option: '%s'", 375fe11483bSZachary Turner option_arg.str().c_str()); 376b9c1b51eSKate Stone } break; 377ca36cd16SJim Ingham 378fe11483bSZachary Turner case 'l': 379fe11483bSZachary Turner if (option_arg.getAsInteger(0, m_line_num)) 380b9c1b51eSKate Stone error.SetErrorStringWithFormat("invalid line number: %s.", 381fe11483bSZachary Turner option_arg.str().c_str()); 382ca36cd16SJim Ingham break; 383055ad9beSIlia K 38423b1decbSDawn Perchik case 'L': 385fe11483bSZachary Turner m_language = Language::GetLanguageTypeFromString(option_arg); 38623b1decbSDawn Perchik if (m_language == eLanguageTypeUnknown) 387b9c1b51eSKate Stone error.SetErrorStringWithFormat( 388fe11483bSZachary Turner "Unknown language type: '%s' for breakpoint", 389fe11483bSZachary Turner option_arg.str().c_str()); 39023b1decbSDawn Perchik break; 39123b1decbSDawn Perchik 392b9c1b51eSKate Stone case 'm': { 393055ad9beSIlia K bool success; 394055ad9beSIlia K bool value; 39547cbf4a0SPavel Labath value = OptionArgParser::ToBoolean(option_arg, true, &success); 396055ad9beSIlia K if (value) 397055ad9beSIlia K m_move_to_nearest_code = eLazyBoolYes; 398055ad9beSIlia K else 399055ad9beSIlia K m_move_to_nearest_code = eLazyBoolNo; 400055ad9beSIlia K 401055ad9beSIlia K if (!success) 402b9c1b51eSKate Stone error.SetErrorStringWithFormat( 403b9c1b51eSKate Stone "Invalid boolean value for move-to-nearest-code option: '%s'", 404fe11483bSZachary Turner option_arg.str().c_str()); 405055ad9beSIlia K break; 406055ad9beSIlia K } 407055ad9beSIlia K 408ca36cd16SJim Ingham case 'M': 409ca36cd16SJim Ingham m_func_names.push_back(option_arg); 410ca36cd16SJim Ingham m_func_name_type_mask |= eFunctionNameTypeMethod; 411ca36cd16SJim Ingham break; 412ca36cd16SJim Ingham 413ca36cd16SJim Ingham case 'n': 414ca36cd16SJim Ingham m_func_names.push_back(option_arg); 415ca36cd16SJim Ingham m_func_name_type_mask |= eFunctionNameTypeAuto; 416ca36cd16SJim Ingham break; 417ca36cd16SJim Ingham 4186fa7681bSZachary Turner case 'N': { 419fe11483bSZachary Turner if (BreakpointID::StringIsBreakpointName(option_arg, error)) 4205e09c8c3SJim Ingham m_breakpoint_names.push_back(option_arg); 421ff9a91eaSJim Ingham else 422ff9a91eaSJim Ingham error.SetErrorStringWithFormat("Invalid breakpoint name: %s", 423fe11483bSZachary Turner option_arg.str().c_str()); 4245e09c8c3SJim Ingham break; 4256fa7681bSZachary Turner } 4265e09c8c3SJim Ingham 427b9c1b51eSKate Stone case 'R': { 4282411167fSJim Ingham lldb::addr_t tmp_offset_addr; 42947cbf4a0SPavel Labath tmp_offset_addr = OptionArgParser::ToAddress(execution_context, 43047cbf4a0SPavel Labath option_arg, 0, &error); 4312411167fSJim Ingham if (error.Success()) 4322411167fSJim Ingham m_offset_addr = tmp_offset_addr; 433b9c1b51eSKate Stone } break; 4342411167fSJim Ingham 435a72b31c7SJim Ingham case 'O': 436fe11483bSZachary Turner m_exception_extra_args.AppendArgument("-O"); 437fe11483bSZachary Turner m_exception_extra_args.AppendArgument(option_arg); 438a72b31c7SJim Ingham break; 439a72b31c7SJim Ingham 440ca36cd16SJim Ingham case 'p': 441ca36cd16SJim Ingham m_source_text_regexp.assign(option_arg); 442ca36cd16SJim Ingham break; 443ca36cd16SJim Ingham 4443815e702SJim Ingham case 'P': 4453815e702SJim Ingham m_python_class.assign(option_arg); 4463815e702SJim Ingham break; 4473815e702SJim Ingham 448ca36cd16SJim Ingham case 'r': 449ca36cd16SJim Ingham m_func_regexp.assign(option_arg); 450ca36cd16SJim Ingham break; 451ca36cd16SJim Ingham 452ca36cd16SJim Ingham case 's': 4538f3be7a3SJonas Devlieghere m_modules.AppendIfUnique(FileSpec(option_arg)); 454ca36cd16SJim Ingham break; 455ca36cd16SJim Ingham 456ca36cd16SJim Ingham case 'S': 457ca36cd16SJim Ingham m_func_names.push_back(option_arg); 458ca36cd16SJim Ingham m_func_name_type_mask |= eFunctionNameTypeSelector; 459ca36cd16SJim Ingham break; 460ca36cd16SJim Ingham 4613815e702SJim Ingham case 'v': { 4623815e702SJim Ingham if (!m_current_key.empty()) { 4633815e702SJim Ingham m_extra_args_sp->AddStringItem(m_current_key, option_arg); 4643815e702SJim Ingham m_current_key.clear(); 4653815e702SJim Ingham } 4663815e702SJim Ingham else 4673815e702SJim Ingham error.SetErrorStringWithFormat("Value \"%s\" missing matching key.", 4683815e702SJim Ingham option_arg.str().c_str()); 4693815e702SJim Ingham } break; 4703815e702SJim Ingham 471b9c1b51eSKate Stone case 'w': { 472ca36cd16SJim Ingham bool success; 47347cbf4a0SPavel Labath m_throw_bp = OptionArgParser::ToBoolean(option_arg, true, &success); 474ca36cd16SJim Ingham if (!success) 475b9c1b51eSKate Stone error.SetErrorStringWithFormat( 476fe11483bSZachary Turner "Invalid boolean value for on-throw option: '%s'", 477fe11483bSZachary Turner option_arg.str().c_str()); 478b9c1b51eSKate Stone } break; 479ca36cd16SJim Ingham 48076bb8d67SJim Ingham case 'X': 48176bb8d67SJim Ingham m_source_regex_func_names.insert(option_arg); 48276bb8d67SJim Ingham break; 48376bb8d67SJim Ingham 48430fdc8d8SChris Lattner default: 48536162014SRaphael Isemann llvm_unreachable("Unimplemented option"); 48630fdc8d8SChris Lattner } 48730fdc8d8SChris Lattner 48830fdc8d8SChris Lattner return error; 48930fdc8d8SChris Lattner } 4909e85e5a8SEugene Zelenko 491b9c1b51eSKate Stone void OptionParsingStarting(ExecutionContext *execution_context) override { 49287df91b8SJim Ingham m_filenames.Clear(); 49330fdc8d8SChris Lattner m_line_num = 0; 49430fdc8d8SChris Lattner m_column = 0; 495fab10e89SJim Ingham m_func_names.clear(); 4961f746071SGreg Clayton m_func_name_type_mask = eFunctionNameTypeNone; 49730fdc8d8SChris Lattner m_func_regexp.clear(); 4981f746071SGreg Clayton m_source_text_regexp.clear(); 49987df91b8SJim Ingham m_modules.Clear(); 5001f746071SGreg Clayton m_load_addr = LLDB_INVALID_ADDRESS; 5012411167fSJim Ingham m_offset_addr = 0; 502fab10e89SJim Ingham m_catch_bp = false; 503fab10e89SJim Ingham m_throw_bp = true; 504eb023e75SGreg Clayton m_hardware = false; 505a72b31c7SJim Ingham m_exception_language = eLanguageTypeUnknown; 50623b1decbSDawn Perchik m_language = lldb::eLanguageTypeUnknown; 507a8558b62SJim Ingham m_skip_prologue = eLazyBoolCalculate; 5085e09c8c3SJim Ingham m_breakpoint_names.clear(); 509e732052fSJim Ingham m_all_files = false; 510a72b31c7SJim Ingham m_exception_extra_args.Clear(); 511055ad9beSIlia K m_move_to_nearest_code = eLazyBoolCalculate; 51276bb8d67SJim Ingham m_source_regex_func_names.clear(); 5133815e702SJim Ingham m_python_class.clear(); 514796ac80bSJonas Devlieghere m_extra_args_sp = std::make_shared<StructuredData::Dictionary>(); 5153815e702SJim Ingham m_current_key.clear(); 51630fdc8d8SChris Lattner } 51730fdc8d8SChris Lattner 5181f0f5b5bSZachary Turner llvm::ArrayRef<OptionDefinition> GetDefinitions() override { 51970602439SZachary Turner return llvm::makeArrayRef(g_breakpoint_set_options); 5201f0f5b5bSZachary Turner } 52130fdc8d8SChris Lattner 5225a988416SJim Ingham // Instance variables to hold the values for command options. 523969795f1SJim Ingham 5245a988416SJim Ingham std::string m_condition; 5255a988416SJim Ingham FileSpecList m_filenames; 5265a988416SJim Ingham uint32_t m_line_num; 5275a988416SJim Ingham uint32_t m_column; 5285a988416SJim Ingham std::vector<std::string> m_func_names; 5295e09c8c3SJim Ingham std::vector<std::string> m_breakpoint_names; 530117b1fa1SZachary Turner lldb::FunctionNameType m_func_name_type_mask; 5315a988416SJim Ingham std::string m_func_regexp; 5325a988416SJim Ingham std::string m_source_text_regexp; 5335a988416SJim Ingham FileSpecList m_modules; 5345a988416SJim Ingham lldb::addr_t m_load_addr; 5352411167fSJim Ingham lldb::addr_t m_offset_addr; 5365a988416SJim Ingham bool m_catch_bp; 5375a988416SJim Ingham bool m_throw_bp; 538eb023e75SGreg Clayton bool m_hardware; // Request to use hardware breakpoints 539a72b31c7SJim Ingham lldb::LanguageType m_exception_language; 54023b1decbSDawn Perchik lldb::LanguageType m_language; 5415a988416SJim Ingham LazyBool m_skip_prologue; 542e732052fSJim Ingham bool m_all_files; 543a72b31c7SJim Ingham Args m_exception_extra_args; 544055ad9beSIlia K LazyBool m_move_to_nearest_code; 54576bb8d67SJim Ingham std::unordered_set<std::string> m_source_regex_func_names; 5463815e702SJim Ingham std::string m_python_class; 5473815e702SJim Ingham StructuredData::DictionarySP m_extra_args_sp; 5483815e702SJim Ingham std::string m_current_key; 5495a988416SJim Ingham }; 5505a988416SJim Ingham 5515a988416SJim Ingham protected: 552b9c1b51eSKate Stone bool DoExecute(Args &command, CommandReturnObject &result) override { 553cb2380c9SRaphael Isemann Target &target = GetSelectedOrDummyTarget(m_dummy_options.m_use_dummy); 55430fdc8d8SChris Lattner 55530fdc8d8SChris Lattner // The following are the various types of breakpoints that could be set: 55630fdc8d8SChris Lattner // 1). -f -l -p [-s -g] (setting breakpoint by source location) 55730fdc8d8SChris Lattner // 2). -a [-s -g] (setting breakpoint by address) 55830fdc8d8SChris Lattner // 3). -n [-s -g] (setting breakpoint by function name) 559b9c1b51eSKate Stone // 4). -r [-s -g] (setting breakpoint by function name regular 560b9c1b51eSKate Stone // expression) 561b9c1b51eSKate Stone // 5). -p -f (setting a breakpoint by comparing a reg-exp 562b9c1b51eSKate Stone // to source text) 563b9c1b51eSKate Stone // 6). -E [-w -h] (setting a breakpoint for exceptions for a 564b9c1b51eSKate Stone // given language.) 56530fdc8d8SChris Lattner 56630fdc8d8SChris Lattner BreakpointSetType break_type = eSetTypeInvalid; 56730fdc8d8SChris Lattner 5683815e702SJim Ingham if (!m_options.m_python_class.empty()) 5693815e702SJim Ingham break_type = eSetTypeScripted; 5703815e702SJim Ingham else if (m_options.m_line_num != 0) 57130fdc8d8SChris Lattner break_type = eSetTypeFileAndLine; 57230fdc8d8SChris Lattner else if (m_options.m_load_addr != LLDB_INVALID_ADDRESS) 57330fdc8d8SChris Lattner break_type = eSetTypeAddress; 574fab10e89SJim Ingham else if (!m_options.m_func_names.empty()) 57530fdc8d8SChris Lattner break_type = eSetTypeFunctionName; 57630fdc8d8SChris Lattner else if (!m_options.m_func_regexp.empty()) 57730fdc8d8SChris Lattner break_type = eSetTypeFunctionRegexp; 578969795f1SJim Ingham else if (!m_options.m_source_text_regexp.empty()) 579969795f1SJim Ingham break_type = eSetTypeSourceRegexp; 580a72b31c7SJim Ingham else if (m_options.m_exception_language != eLanguageTypeUnknown) 581fab10e89SJim Ingham break_type = eSetTypeException; 58230fdc8d8SChris Lattner 583b842f2ecSJim Ingham BreakpointSP bp_sp = nullptr; 584274060b6SGreg Clayton FileSpec module_spec; 585a8558b62SJim Ingham const bool internal = false; 586a8558b62SJim Ingham 587b9c1b51eSKate Stone // If the user didn't specify skip-prologue, having an offset should turn 588b9c1b51eSKate Stone // that off. 589b9c1b51eSKate Stone if (m_options.m_offset_addr != 0 && 590b9c1b51eSKate Stone m_options.m_skip_prologue == eLazyBoolCalculate) 5912411167fSJim Ingham m_options.m_skip_prologue = eLazyBoolNo; 5922411167fSJim Ingham 593b9c1b51eSKate Stone switch (break_type) { 59430fdc8d8SChris Lattner case eSetTypeFileAndLine: // Breakpoint by source position 59530fdc8d8SChris Lattner { 59630fdc8d8SChris Lattner FileSpec file; 597c7bece56SGreg Clayton const size_t num_files = m_options.m_filenames.GetSize(); 598b9c1b51eSKate Stone if (num_files == 0) { 599b9c1b51eSKate Stone if (!GetDefaultFile(target, file, result)) { 60087df91b8SJim Ingham result.AppendError("No file supplied and no default file available."); 60187df91b8SJim Ingham result.SetStatus(eReturnStatusFailed); 60287df91b8SJim Ingham return false; 60387df91b8SJim Ingham } 604b9c1b51eSKate Stone } else if (num_files > 1) { 605b9c1b51eSKate Stone result.AppendError("Only one file at a time is allowed for file and " 606b9c1b51eSKate Stone "line breakpoints."); 60787df91b8SJim Ingham result.SetStatus(eReturnStatusFailed); 60887df91b8SJim Ingham return false; 609b9c1b51eSKate Stone } else 61087df91b8SJim Ingham file = m_options.m_filenames.GetFileSpecAtIndex(0); 61130fdc8d8SChris Lattner 6121f746071SGreg Clayton // Only check for inline functions if 6131f746071SGreg Clayton LazyBool check_inlines = eLazyBoolCalculate; 6141f746071SGreg Clayton 615cb2380c9SRaphael Isemann bp_sp = target.CreateBreakpoint( 616cb2380c9SRaphael Isemann &(m_options.m_modules), file, m_options.m_line_num, 617cb2380c9SRaphael Isemann m_options.m_column, m_options.m_offset_addr, check_inlines, 618cb2380c9SRaphael Isemann m_options.m_skip_prologue, internal, m_options.m_hardware, 619b842f2ecSJim Ingham m_options.m_move_to_nearest_code); 620b9c1b51eSKate Stone } break; 6216eee5aa0SGreg Clayton 62230fdc8d8SChris Lattner case eSetTypeAddress: // Breakpoint by address 623055a08a4SJim Ingham { 624b9c1b51eSKate Stone // If a shared library has been specified, make an lldb_private::Address 625b842f2ecSJim Ingham // with the library, and use that. That way the address breakpoint 626b842f2ecSJim Ingham // will track the load location of the library. 627055a08a4SJim Ingham size_t num_modules_specified = m_options.m_modules.GetSize(); 628b9c1b51eSKate Stone if (num_modules_specified == 1) { 629b9c1b51eSKate Stone const FileSpec *file_spec = 630b9c1b51eSKate Stone m_options.m_modules.GetFileSpecPointerAtIndex(0); 631cb2380c9SRaphael Isemann bp_sp = target.CreateAddressInModuleBreakpoint( 632cb2380c9SRaphael Isemann m_options.m_load_addr, internal, file_spec, m_options.m_hardware); 633b9c1b51eSKate Stone } else if (num_modules_specified == 0) { 634cb2380c9SRaphael Isemann bp_sp = target.CreateBreakpoint(m_options.m_load_addr, internal, 635b842f2ecSJim Ingham m_options.m_hardware); 636b9c1b51eSKate Stone } else { 637b9c1b51eSKate Stone result.AppendError("Only one shared library can be specified for " 638b9c1b51eSKate Stone "address breakpoints."); 639055a08a4SJim Ingham result.SetStatus(eReturnStatusFailed); 640055a08a4SJim Ingham return false; 641055a08a4SJim Ingham } 64230fdc8d8SChris Lattner break; 643055a08a4SJim Ingham } 64430fdc8d8SChris Lattner case eSetTypeFunctionName: // Breakpoint by function name 6450c5cd90dSGreg Clayton { 646117b1fa1SZachary Turner FunctionNameType name_type_mask = m_options.m_func_name_type_mask; 6470c5cd90dSGreg Clayton 6480c5cd90dSGreg Clayton if (name_type_mask == 0) 649e02b8504SGreg Clayton name_type_mask = eFunctionNameTypeAuto; 6500c5cd90dSGreg Clayton 651cb2380c9SRaphael Isemann bp_sp = target.CreateBreakpoint( 652cb2380c9SRaphael Isemann &(m_options.m_modules), &(m_options.m_filenames), 653cb2380c9SRaphael Isemann m_options.m_func_names, name_type_mask, m_options.m_language, 654cb2380c9SRaphael Isemann m_options.m_offset_addr, m_options.m_skip_prologue, internal, 655b842f2ecSJim Ingham m_options.m_hardware); 656b9c1b51eSKate Stone } break; 6570c5cd90dSGreg Clayton 658b9c1b51eSKate Stone case eSetTypeFunctionRegexp: // Breakpoint by regular expression function 659b9c1b51eSKate Stone // name 66030fdc8d8SChris Lattner { 66195eae423SZachary Turner RegularExpression regexp(m_options.m_func_regexp); 6623af3f1e8SJonas Devlieghere if (llvm::Error err = regexp.GetError()) { 663b9c1b51eSKate Stone result.AppendErrorWithFormat( 664b9c1b51eSKate Stone "Function name regular expression could not be compiled: \"%s\"", 6653af3f1e8SJonas Devlieghere llvm::toString(std::move(err)).c_str()); 66630fdc8d8SChris Lattner result.SetStatus(eReturnStatusFailed); 667969795f1SJim Ingham return false; 66830fdc8d8SChris Lattner } 66987df91b8SJim Ingham 670cb2380c9SRaphael Isemann bp_sp = target.CreateFuncRegexBreakpoint( 6715aa1d819SJan Kratochvil &(m_options.m_modules), &(m_options.m_filenames), std::move(regexp), 672cb2380c9SRaphael Isemann m_options.m_language, m_options.m_skip_prologue, internal, 673b842f2ecSJim Ingham m_options.m_hardware); 674e14dc268SJim Ingham } 675e14dc268SJim Ingham break; 676969795f1SJim Ingham case eSetTypeSourceRegexp: // Breakpoint by regexp on source text. 677969795f1SJim Ingham { 678c7bece56SGreg Clayton const size_t num_files = m_options.m_filenames.GetSize(); 67987df91b8SJim Ingham 680b9c1b51eSKate Stone if (num_files == 0 && !m_options.m_all_files) { 681969795f1SJim Ingham FileSpec file; 682b9c1b51eSKate Stone if (!GetDefaultFile(target, file, result)) { 683b9c1b51eSKate Stone result.AppendError( 684b9c1b51eSKate Stone "No files provided and could not find default file."); 68587df91b8SJim Ingham result.SetStatus(eReturnStatusFailed); 68687df91b8SJim Ingham return false; 687b9c1b51eSKate Stone } else { 68887df91b8SJim Ingham m_options.m_filenames.Append(file); 68987df91b8SJim Ingham } 69087df91b8SJim Ingham } 6910c5cd90dSGreg Clayton 69295eae423SZachary Turner RegularExpression regexp(m_options.m_source_text_regexp); 6933af3f1e8SJonas Devlieghere if (llvm::Error err = regexp.GetError()) { 694b9c1b51eSKate Stone result.AppendErrorWithFormat( 695b9c1b51eSKate Stone "Source text regular expression could not be compiled: \"%s\"", 6963af3f1e8SJonas Devlieghere llvm::toString(std::move(err)).c_str()); 697969795f1SJim Ingham result.SetStatus(eReturnStatusFailed); 698969795f1SJim Ingham return false; 699969795f1SJim Ingham } 700cb2380c9SRaphael Isemann bp_sp = target.CreateSourceRegexBreakpoint( 701cb2380c9SRaphael Isemann &(m_options.m_modules), &(m_options.m_filenames), 7025aa1d819SJan Kratochvil m_options.m_source_regex_func_names, std::move(regexp), internal, 703cb2380c9SRaphael Isemann m_options.m_hardware, m_options.m_move_to_nearest_code); 704b9c1b51eSKate Stone } break; 705b9c1b51eSKate Stone case eSetTypeException: { 70697206d57SZachary Turner Status precond_error; 707cb2380c9SRaphael Isemann bp_sp = target.CreateExceptionBreakpoint( 708cb2380c9SRaphael Isemann m_options.m_exception_language, m_options.m_catch_bp, 709cb2380c9SRaphael Isemann m_options.m_throw_bp, internal, &m_options.m_exception_extra_args, 710b842f2ecSJim Ingham &precond_error); 711b9c1b51eSKate Stone if (precond_error.Fail()) { 712b9c1b51eSKate Stone result.AppendErrorWithFormat( 713b9c1b51eSKate Stone "Error setting extra exception arguments: %s", 714a72b31c7SJim Ingham precond_error.AsCString()); 715cb2380c9SRaphael Isemann target.RemoveBreakpointByID(bp_sp->GetID()); 716a72b31c7SJim Ingham result.SetStatus(eReturnStatusFailed); 717a72b31c7SJim Ingham return false; 718a72b31c7SJim Ingham } 719b9c1b51eSKate Stone } break; 7203815e702SJim Ingham case eSetTypeScripted: { 7213815e702SJim Ingham 7223815e702SJim Ingham Status error; 723cb2380c9SRaphael Isemann bp_sp = target.CreateScriptedBreakpoint( 724cb2380c9SRaphael Isemann m_options.m_python_class, &(m_options.m_modules), 725cb2380c9SRaphael Isemann &(m_options.m_filenames), false, m_options.m_hardware, 726cb2380c9SRaphael Isemann m_options.m_extra_args_sp, &error); 7273815e702SJim Ingham if (error.Fail()) { 7283815e702SJim Ingham result.AppendErrorWithFormat( 7293815e702SJim Ingham "Error setting extra exception arguments: %s", 7303815e702SJim Ingham error.AsCString()); 731cb2380c9SRaphael Isemann target.RemoveBreakpointByID(bp_sp->GetID()); 7323815e702SJim Ingham result.SetStatus(eReturnStatusFailed); 7333815e702SJim Ingham return false; 7343815e702SJim Ingham } 7353815e702SJim Ingham } break; 73630fdc8d8SChris Lattner default: 73730fdc8d8SChris Lattner break; 73830fdc8d8SChris Lattner } 73930fdc8d8SChris Lattner 7401b54c88cSJim Ingham // Now set the various options that were passed in: 741b842f2ecSJim Ingham if (bp_sp) { 742b842f2ecSJim Ingham bp_sp->GetOptions()->CopyOverSetOptions(m_bp_opts.GetBreakpointOptions()); 743ca36cd16SJim Ingham 744b9c1b51eSKate Stone if (!m_options.m_breakpoint_names.empty()) { 74597206d57SZachary Turner Status name_error; 746ff9a91eaSJim Ingham for (auto name : m_options.m_breakpoint_names) { 747cb2380c9SRaphael Isemann target.AddNameToBreakpoint(bp_sp, name.c_str(), name_error); 748ff9a91eaSJim Ingham if (name_error.Fail()) { 749ff9a91eaSJim Ingham result.AppendErrorWithFormat("Invalid breakpoint name: %s", 750ff9a91eaSJim Ingham name.c_str()); 751cb2380c9SRaphael Isemann target.RemoveBreakpointByID(bp_sp->GetID()); 752ff9a91eaSJim Ingham result.SetStatus(eReturnStatusFailed); 753ff9a91eaSJim Ingham return false; 754ff9a91eaSJim Ingham } 755ff9a91eaSJim Ingham } 7565e09c8c3SJim Ingham } 7571b54c88cSJim Ingham } 7581b54c88cSJim Ingham 759b842f2ecSJim Ingham if (bp_sp) { 76085e8b814SJim Ingham Stream &output_stream = result.GetOutputStream(); 7611391cc7dSJim Ingham const bool show_locations = false; 762b842f2ecSJim Ingham bp_sp->GetDescription(&output_stream, lldb::eDescriptionLevelInitial, 763b9c1b51eSKate Stone show_locations); 764cb2380c9SRaphael Isemann if (&target == &GetDummyTarget()) 765b9c1b51eSKate Stone output_stream.Printf("Breakpoint set in dummy target, will get copied " 766b9c1b51eSKate Stone "into future targets.\n"); 767b9c1b51eSKate Stone else { 76805097246SAdrian Prantl // Don't print out this warning for exception breakpoints. They can 76905097246SAdrian Prantl // get set before the target is set, but we won't know how to actually 77005097246SAdrian Prantl // set the breakpoint till we run. 771b842f2ecSJim Ingham if (bp_sp->GetNumLocations() == 0 && break_type != eSetTypeException) { 772b9c1b51eSKate Stone output_stream.Printf("WARNING: Unable to resolve breakpoint to any " 773b9c1b51eSKate Stone "actual locations.\n"); 7744aeb1989SJim Ingham } 7754aeb1989SJim Ingham } 77630fdc8d8SChris Lattner result.SetStatus(eReturnStatusSuccessFinishResult); 777b842f2ecSJim Ingham } else if (!bp_sp) { 77830fdc8d8SChris Lattner result.AppendError("Breakpoint creation failed: No breakpoint created."); 77930fdc8d8SChris Lattner result.SetStatus(eReturnStatusFailed); 78030fdc8d8SChris Lattner } 78130fdc8d8SChris Lattner 78230fdc8d8SChris Lattner return result.Succeeded(); 78330fdc8d8SChris Lattner } 78430fdc8d8SChris Lattner 7855a988416SJim Ingham private: 786cb2380c9SRaphael Isemann bool GetDefaultFile(Target &target, FileSpec &file, 787b9c1b51eSKate Stone CommandReturnObject &result) { 7885a988416SJim Ingham uint32_t default_line; 78905097246SAdrian Prantl // First use the Source Manager's default file. Then use the current stack 79005097246SAdrian Prantl // frame's file. 791cb2380c9SRaphael Isemann if (!target.GetSourceManager().GetDefaultFileAndLine(file, default_line)) { 792b57e4a1bSJason Molenda StackFrame *cur_frame = m_exe_ctx.GetFramePtr(); 793b9c1b51eSKate Stone if (cur_frame == nullptr) { 794b9c1b51eSKate Stone result.AppendError( 795b9c1b51eSKate Stone "No selected frame to use to find the default file."); 7965a988416SJim Ingham result.SetStatus(eReturnStatusFailed); 7975a988416SJim Ingham return false; 798b9c1b51eSKate Stone } else if (!cur_frame->HasDebugInformation()) { 799b9c1b51eSKate Stone result.AppendError("Cannot use the selected frame to find the default " 800b9c1b51eSKate Stone "file, it has no debug info."); 8015a988416SJim Ingham result.SetStatus(eReturnStatusFailed); 8025a988416SJim Ingham return false; 803b9c1b51eSKate Stone } else { 804b9c1b51eSKate Stone const SymbolContext &sc = 805b9c1b51eSKate Stone cur_frame->GetSymbolContext(eSymbolContextLineEntry); 806b9c1b51eSKate Stone if (sc.line_entry.file) { 8075a988416SJim Ingham file = sc.line_entry.file; 808b9c1b51eSKate Stone } else { 809b9c1b51eSKate Stone result.AppendError("Can't find the file for the selected frame to " 810b9c1b51eSKate Stone "use as the default file."); 8115a988416SJim Ingham result.SetStatus(eReturnStatusFailed); 8125a988416SJim Ingham return false; 8135a988416SJim Ingham } 8145a988416SJim Ingham } 8155a988416SJim Ingham } 8165a988416SJim Ingham return true; 8175a988416SJim Ingham } 8185a988416SJim Ingham 819b842f2ecSJim Ingham BreakpointOptionGroup m_bp_opts; 820b842f2ecSJim Ingham BreakpointDummyOptionGroup m_dummy_options; 8215a988416SJim Ingham CommandOptions m_options; 822b842f2ecSJim Ingham OptionGroupOptions m_all_options; 8235a988416SJim Ingham }; 8249e85e5a8SEugene Zelenko 8255a988416SJim Ingham // CommandObjectBreakpointModify 8265a988416SJim Ingham #pragma mark Modify 8275a988416SJim Ingham 828b9c1b51eSKate Stone class CommandObjectBreakpointModify : public CommandObjectParsed { 8295a988416SJim Ingham public: 830b9c1b51eSKate Stone CommandObjectBreakpointModify(CommandInterpreter &interpreter) 831b9c1b51eSKate Stone : CommandObjectParsed(interpreter, "breakpoint modify", 832b9c1b51eSKate Stone "Modify the options on a breakpoint or set of " 833b9c1b51eSKate Stone "breakpoints in the executable. " 834b9c1b51eSKate Stone "If no breakpoint is specified, acts on the last " 835b9c1b51eSKate Stone "created breakpoint. " 836b9c1b51eSKate Stone "With the exception of -e, -d and -i, passing an " 837b9c1b51eSKate Stone "empty argument clears the modification.", 8389e85e5a8SEugene Zelenko nullptr), 839b9c1b51eSKate Stone m_options() { 8405a988416SJim Ingham CommandArgumentEntry arg; 841b9c1b51eSKate Stone CommandObject::AddIDsArgumentData(arg, eArgTypeBreakpointID, 842b9c1b51eSKate Stone eArgTypeBreakpointIDRange); 843b9c1b51eSKate Stone // Add the entry for the first argument for this command to the object's 844b9c1b51eSKate Stone // arguments vector. 8455a988416SJim Ingham m_arguments.push_back(arg); 846b842f2ecSJim Ingham 847b842f2ecSJim Ingham m_options.Append(&m_bp_opts, 848b842f2ecSJim Ingham LLDB_OPT_SET_1 | LLDB_OPT_SET_2 | LLDB_OPT_SET_3, 849b842f2ecSJim Ingham LLDB_OPT_SET_ALL); 850b842f2ecSJim Ingham m_options.Append(&m_dummy_opts, LLDB_OPT_SET_1, LLDB_OPT_SET_ALL); 851b842f2ecSJim Ingham m_options.Finalize(); 8525a988416SJim Ingham } 8535a988416SJim Ingham 8549e85e5a8SEugene Zelenko ~CommandObjectBreakpointModify() override = default; 8555a988416SJim Ingham 856b9c1b51eSKate Stone Options *GetOptions() override { return &m_options; } 8575a988416SJim Ingham 8585a988416SJim Ingham protected: 859b9c1b51eSKate Stone bool DoExecute(Args &command, CommandReturnObject &result) override { 860cb2380c9SRaphael Isemann Target &target = GetSelectedOrDummyTarget(m_dummy_opts.m_use_dummy); 8615a988416SJim Ingham 862bb19a13cSSaleem Abdulrasool std::unique_lock<std::recursive_mutex> lock; 863cb2380c9SRaphael Isemann target.GetBreakpointList().GetListMutex(lock); 8645a988416SJim Ingham 8655a988416SJim Ingham BreakpointIDList valid_bp_ids; 8665a988416SJim Ingham 867b9c1b51eSKate Stone CommandObjectMultiwordBreakpoint::VerifyBreakpointOrLocationIDs( 868cb2380c9SRaphael Isemann command, &target, result, &valid_bp_ids, 869b842f2ecSJim Ingham BreakpointName::Permissions::PermissionKinds::disablePerm); 8705a988416SJim Ingham 871b9c1b51eSKate Stone if (result.Succeeded()) { 8725a988416SJim Ingham const size_t count = valid_bp_ids.GetSize(); 873b9c1b51eSKate Stone for (size_t i = 0; i < count; ++i) { 8745a988416SJim Ingham BreakpointID cur_bp_id = valid_bp_ids.GetBreakpointIDAtIndex(i); 8755a988416SJim Ingham 876b9c1b51eSKate Stone if (cur_bp_id.GetBreakpointID() != LLDB_INVALID_BREAK_ID) { 877b9c1b51eSKate Stone Breakpoint *bp = 878cb2380c9SRaphael Isemann target.GetBreakpointByID(cur_bp_id.GetBreakpointID()).get(); 879b9c1b51eSKate Stone if (cur_bp_id.GetLocationID() != LLDB_INVALID_BREAK_ID) { 880b9c1b51eSKate Stone BreakpointLocation *location = 881b9c1b51eSKate Stone bp->FindLocationByID(cur_bp_id.GetLocationID()).get(); 882b842f2ecSJim Ingham if (location) 883b842f2ecSJim Ingham location->GetLocationOptions() 884b842f2ecSJim Ingham ->CopyOverSetOptions(m_bp_opts.GetBreakpointOptions()); 885b9c1b51eSKate Stone } else { 886b842f2ecSJim Ingham bp->GetOptions() 887b842f2ecSJim Ingham ->CopyOverSetOptions(m_bp_opts.GetBreakpointOptions()); 8885a988416SJim Ingham } 8895a988416SJim Ingham } 8905a988416SJim Ingham } 8915a988416SJim Ingham } 8925a988416SJim Ingham 8935a988416SJim Ingham return result.Succeeded(); 8945a988416SJim Ingham } 8955a988416SJim Ingham 8965a988416SJim Ingham private: 897b842f2ecSJim Ingham BreakpointOptionGroup m_bp_opts; 898b842f2ecSJim Ingham BreakpointDummyOptionGroup m_dummy_opts; 899b842f2ecSJim Ingham OptionGroupOptions m_options; 9005a988416SJim Ingham }; 9015a988416SJim Ingham 9025a988416SJim Ingham // CommandObjectBreakpointEnable 9035a988416SJim Ingham #pragma mark Enable 9045a988416SJim Ingham 905b9c1b51eSKate Stone class CommandObjectBreakpointEnable : public CommandObjectParsed { 9065a988416SJim Ingham public: 907b9c1b51eSKate Stone CommandObjectBreakpointEnable(CommandInterpreter &interpreter) 908b9c1b51eSKate Stone : CommandObjectParsed(interpreter, "enable", 909b9c1b51eSKate Stone "Enable the specified disabled breakpoint(s). If " 910b9c1b51eSKate Stone "no breakpoints are specified, enable all of them.", 911b9c1b51eSKate Stone nullptr) { 9125a988416SJim Ingham CommandArgumentEntry arg; 913b9c1b51eSKate Stone CommandObject::AddIDsArgumentData(arg, eArgTypeBreakpointID, 914b9c1b51eSKate Stone eArgTypeBreakpointIDRange); 915b9c1b51eSKate Stone // Add the entry for the first argument for this command to the object's 916b9c1b51eSKate Stone // arguments vector. 9175a988416SJim Ingham m_arguments.push_back(arg); 9185a988416SJim Ingham } 9195a988416SJim Ingham 9209e85e5a8SEugene Zelenko ~CommandObjectBreakpointEnable() override = default; 9215a988416SJim Ingham 9225a988416SJim Ingham protected: 923b9c1b51eSKate Stone bool DoExecute(Args &command, CommandReturnObject &result) override { 924cb2380c9SRaphael Isemann Target &target = GetSelectedOrDummyTarget(); 9255a988416SJim Ingham 926bb19a13cSSaleem Abdulrasool std::unique_lock<std::recursive_mutex> lock; 927cb2380c9SRaphael Isemann target.GetBreakpointList().GetListMutex(lock); 9285a988416SJim Ingham 929cb2380c9SRaphael Isemann const BreakpointList &breakpoints = target.GetBreakpointList(); 9305a988416SJim Ingham 9315a988416SJim Ingham size_t num_breakpoints = breakpoints.GetSize(); 9325a988416SJim Ingham 933b9c1b51eSKate Stone if (num_breakpoints == 0) { 9345a988416SJim Ingham result.AppendError("No breakpoints exist to be enabled."); 9355a988416SJim Ingham result.SetStatus(eReturnStatusFailed); 9365a988416SJim Ingham return false; 9375a988416SJim Ingham } 9385a988416SJim Ingham 93911eb9c64SZachary Turner if (command.empty()) { 9405a988416SJim Ingham // No breakpoint selected; enable all currently set breakpoints. 941cb2380c9SRaphael Isemann target.EnableAllowedBreakpoints(); 942b9c1b51eSKate Stone result.AppendMessageWithFormat("All breakpoints enabled. (%" PRIu64 943b9c1b51eSKate Stone " breakpoints)\n", 944b9c1b51eSKate Stone (uint64_t)num_breakpoints); 9455a988416SJim Ingham result.SetStatus(eReturnStatusSuccessFinishNoResult); 946b9c1b51eSKate Stone } else { 9475a988416SJim Ingham // Particular breakpoint selected; enable that breakpoint. 9485a988416SJim Ingham BreakpointIDList valid_bp_ids; 949b9c1b51eSKate Stone CommandObjectMultiwordBreakpoint::VerifyBreakpointOrLocationIDs( 950cb2380c9SRaphael Isemann command, &target, result, &valid_bp_ids, 951b842f2ecSJim Ingham BreakpointName::Permissions::PermissionKinds::disablePerm); 9525a988416SJim Ingham 953b9c1b51eSKate Stone if (result.Succeeded()) { 9545a988416SJim Ingham int enable_count = 0; 9555a988416SJim Ingham int loc_count = 0; 9565a988416SJim Ingham const size_t count = valid_bp_ids.GetSize(); 957b9c1b51eSKate Stone for (size_t i = 0; i < count; ++i) { 9585a988416SJim Ingham BreakpointID cur_bp_id = valid_bp_ids.GetBreakpointIDAtIndex(i); 9595a988416SJim Ingham 960b9c1b51eSKate Stone if (cur_bp_id.GetBreakpointID() != LLDB_INVALID_BREAK_ID) { 961b9c1b51eSKate Stone Breakpoint *breakpoint = 962cb2380c9SRaphael Isemann target.GetBreakpointByID(cur_bp_id.GetBreakpointID()).get(); 963b9c1b51eSKate Stone if (cur_bp_id.GetLocationID() != LLDB_INVALID_BREAK_ID) { 964b9c1b51eSKate Stone BreakpointLocation *location = 965b9c1b51eSKate Stone breakpoint->FindLocationByID(cur_bp_id.GetLocationID()).get(); 966b9c1b51eSKate Stone if (location) { 9675a988416SJim Ingham location->SetEnabled(true); 9685a988416SJim Ingham ++loc_count; 9695a988416SJim Ingham } 970b9c1b51eSKate Stone } else { 9715a988416SJim Ingham breakpoint->SetEnabled(true); 9725a988416SJim Ingham ++enable_count; 9735a988416SJim Ingham } 9745a988416SJim Ingham } 9755a988416SJim Ingham } 976b9c1b51eSKate Stone result.AppendMessageWithFormat("%d breakpoints enabled.\n", 977b9c1b51eSKate Stone enable_count + loc_count); 9785a988416SJim Ingham result.SetStatus(eReturnStatusSuccessFinishNoResult); 9795a988416SJim Ingham } 9805a988416SJim Ingham } 9815a988416SJim Ingham 9825a988416SJim Ingham return result.Succeeded(); 9835a988416SJim Ingham } 9845a988416SJim Ingham }; 9855a988416SJim Ingham 9865a988416SJim Ingham // CommandObjectBreakpointDisable 9875a988416SJim Ingham #pragma mark Disable 9885a988416SJim Ingham 989b9c1b51eSKate Stone class CommandObjectBreakpointDisable : public CommandObjectParsed { 9905a988416SJim Ingham public: 9917428a18cSKate Stone CommandObjectBreakpointDisable(CommandInterpreter &interpreter) 992b9c1b51eSKate Stone : CommandObjectParsed( 993b9c1b51eSKate Stone interpreter, "breakpoint disable", 994b9c1b51eSKate Stone "Disable the specified breakpoint(s) without deleting " 9957428a18cSKate Stone "them. If none are specified, disable all " 9967428a18cSKate Stone "breakpoints.", 997b9c1b51eSKate Stone nullptr) { 998b9c1b51eSKate Stone SetHelpLong( 999b9c1b51eSKate Stone "Disable the specified breakpoint(s) without deleting them. \ 10007428a18cSKate Stone If none are specified, disable all breakpoints." 10017428a18cSKate Stone R"( 1002ea671fbdSKate Stone 10037428a18cSKate Stone )" 10047428a18cSKate Stone "Note: disabling a breakpoint will cause none of its locations to be hit \ 10057428a18cSKate Stone regardless of whether individual locations are enabled or disabled. After the sequence:" 10067428a18cSKate Stone R"( 1007ea671fbdSKate Stone 1008ea671fbdSKate Stone (lldb) break disable 1 1009ea671fbdSKate Stone (lldb) break enable 1.1 1010ea671fbdSKate Stone 1011ea671fbdSKate Stone execution will NOT stop at location 1.1. To achieve that, type: 1012ea671fbdSKate Stone 1013ea671fbdSKate Stone (lldb) break disable 1.* 1014ea671fbdSKate Stone (lldb) break enable 1.1 1015ea671fbdSKate Stone 10167428a18cSKate Stone )" 10177428a18cSKate Stone "The first command disables all locations for breakpoint 1, \ 10187428a18cSKate Stone the second re-enables the first location."); 1019b0fac509SJim Ingham 10205a988416SJim Ingham CommandArgumentEntry arg; 1021b9c1b51eSKate Stone CommandObject::AddIDsArgumentData(arg, eArgTypeBreakpointID, 1022b9c1b51eSKate Stone eArgTypeBreakpointIDRange); 1023b9c1b51eSKate Stone // Add the entry for the first argument for this command to the object's 1024b9c1b51eSKate Stone // arguments vector. 10255a988416SJim Ingham m_arguments.push_back(arg); 10265a988416SJim Ingham } 10275a988416SJim Ingham 10289e85e5a8SEugene Zelenko ~CommandObjectBreakpointDisable() override = default; 10295a988416SJim Ingham 10305a988416SJim Ingham protected: 1031b9c1b51eSKate Stone bool DoExecute(Args &command, CommandReturnObject &result) override { 1032cb2380c9SRaphael Isemann Target &target = GetSelectedOrDummyTarget(); 1033bb19a13cSSaleem Abdulrasool std::unique_lock<std::recursive_mutex> lock; 1034cb2380c9SRaphael Isemann target.GetBreakpointList().GetListMutex(lock); 10355a988416SJim Ingham 1036cb2380c9SRaphael Isemann const BreakpointList &breakpoints = target.GetBreakpointList(); 10375a988416SJim Ingham size_t num_breakpoints = breakpoints.GetSize(); 10385a988416SJim Ingham 1039b9c1b51eSKate Stone if (num_breakpoints == 0) { 10405a988416SJim Ingham result.AppendError("No breakpoints exist to be disabled."); 10415a988416SJim Ingham result.SetStatus(eReturnStatusFailed); 10425a988416SJim Ingham return false; 10435a988416SJim Ingham } 10445a988416SJim Ingham 104511eb9c64SZachary Turner if (command.empty()) { 10465a988416SJim Ingham // No breakpoint selected; disable all currently set breakpoints. 1047cb2380c9SRaphael Isemann target.DisableAllowedBreakpoints(); 1048b9c1b51eSKate Stone result.AppendMessageWithFormat("All breakpoints disabled. (%" PRIu64 1049b9c1b51eSKate Stone " breakpoints)\n", 1050b9c1b51eSKate Stone (uint64_t)num_breakpoints); 10515a988416SJim Ingham result.SetStatus(eReturnStatusSuccessFinishNoResult); 1052b9c1b51eSKate Stone } else { 10535a988416SJim Ingham // Particular breakpoint selected; disable that breakpoint. 10545a988416SJim Ingham BreakpointIDList valid_bp_ids; 10555a988416SJim Ingham 1056b9c1b51eSKate Stone CommandObjectMultiwordBreakpoint::VerifyBreakpointOrLocationIDs( 1057cb2380c9SRaphael Isemann command, &target, result, &valid_bp_ids, 1058b842f2ecSJim Ingham BreakpointName::Permissions::PermissionKinds::disablePerm); 10595a988416SJim Ingham 1060b9c1b51eSKate Stone if (result.Succeeded()) { 10615a988416SJim Ingham int disable_count = 0; 10625a988416SJim Ingham int loc_count = 0; 10635a988416SJim Ingham const size_t count = valid_bp_ids.GetSize(); 1064b9c1b51eSKate Stone for (size_t i = 0; i < count; ++i) { 10655a988416SJim Ingham BreakpointID cur_bp_id = valid_bp_ids.GetBreakpointIDAtIndex(i); 10665a988416SJim Ingham 1067b9c1b51eSKate Stone if (cur_bp_id.GetBreakpointID() != LLDB_INVALID_BREAK_ID) { 1068b9c1b51eSKate Stone Breakpoint *breakpoint = 1069cb2380c9SRaphael Isemann target.GetBreakpointByID(cur_bp_id.GetBreakpointID()).get(); 1070b9c1b51eSKate Stone if (cur_bp_id.GetLocationID() != LLDB_INVALID_BREAK_ID) { 1071b9c1b51eSKate Stone BreakpointLocation *location = 1072b9c1b51eSKate Stone breakpoint->FindLocationByID(cur_bp_id.GetLocationID()).get(); 1073b9c1b51eSKate Stone if (location) { 10745a988416SJim Ingham location->SetEnabled(false); 10755a988416SJim Ingham ++loc_count; 10765a988416SJim Ingham } 1077b9c1b51eSKate Stone } else { 10785a988416SJim Ingham breakpoint->SetEnabled(false); 10795a988416SJim Ingham ++disable_count; 10805a988416SJim Ingham } 10815a988416SJim Ingham } 10825a988416SJim Ingham } 1083b9c1b51eSKate Stone result.AppendMessageWithFormat("%d breakpoints disabled.\n", 1084b9c1b51eSKate Stone disable_count + loc_count); 10855a988416SJim Ingham result.SetStatus(eReturnStatusSuccessFinishNoResult); 10865a988416SJim Ingham } 10875a988416SJim Ingham } 10885a988416SJim Ingham 10895a988416SJim Ingham return result.Succeeded(); 10905a988416SJim Ingham } 10915a988416SJim Ingham }; 10925a988416SJim Ingham 10935a988416SJim Ingham // CommandObjectBreakpointList 10941f0f5b5bSZachary Turner 10951f0f5b5bSZachary Turner #pragma mark List::CommandOptions 10966f4fb4e7SRaphael Isemann #define LLDB_OPTIONS_breakpoint_list 1097c5a2d747SRaphael Isemann #include "CommandOptions.inc" 10981f0f5b5bSZachary Turner 10995a988416SJim Ingham #pragma mark List 11005a988416SJim Ingham 1101b9c1b51eSKate Stone class CommandObjectBreakpointList : public CommandObjectParsed { 11025a988416SJim Ingham public: 1103b9c1b51eSKate Stone CommandObjectBreakpointList(CommandInterpreter &interpreter) 1104b9c1b51eSKate Stone : CommandObjectParsed( 1105b9c1b51eSKate Stone interpreter, "breakpoint list", 11065a988416SJim Ingham "List some or all breakpoints at configurable levels of detail.", 11079e85e5a8SEugene Zelenko nullptr), 1108b9c1b51eSKate Stone m_options() { 11095a988416SJim Ingham CommandArgumentEntry arg; 11105a988416SJim Ingham CommandArgumentData bp_id_arg; 11115a988416SJim Ingham 11125a988416SJim Ingham // Define the first (and only) variant of this arg. 11135a988416SJim Ingham bp_id_arg.arg_type = eArgTypeBreakpointID; 11145a988416SJim Ingham bp_id_arg.arg_repetition = eArgRepeatOptional; 11155a988416SJim Ingham 1116b9c1b51eSKate Stone // There is only one variant this argument could be; put it into the 1117b9c1b51eSKate Stone // argument entry. 11185a988416SJim Ingham arg.push_back(bp_id_arg); 11195a988416SJim Ingham 11205a988416SJim Ingham // Push the data for the first argument into the m_arguments vector. 11215a988416SJim Ingham m_arguments.push_back(arg); 11225a988416SJim Ingham } 11235a988416SJim Ingham 11249e85e5a8SEugene Zelenko ~CommandObjectBreakpointList() override = default; 11255a988416SJim Ingham 1126b9c1b51eSKate Stone Options *GetOptions() override { return &m_options; } 11275a988416SJim Ingham 1128b9c1b51eSKate Stone class CommandOptions : public Options { 11295a988416SJim Ingham public: 1130b9c1b51eSKate Stone CommandOptions() 1131b9c1b51eSKate Stone : Options(), m_level(lldb::eDescriptionLevelBrief), m_use_dummy(false) { 11325a988416SJim Ingham } 11335a988416SJim Ingham 11349e85e5a8SEugene Zelenko ~CommandOptions() override = default; 11355a988416SJim Ingham 113697206d57SZachary Turner Status SetOptionValue(uint32_t option_idx, llvm::StringRef option_arg, 1137b9c1b51eSKate Stone ExecutionContext *execution_context) override { 113897206d57SZachary Turner Status error; 11393bcdfc0eSGreg Clayton const int short_option = m_getopt_table[option_idx].val; 11405a988416SJim Ingham 1141b9c1b51eSKate Stone switch (short_option) { 11425a988416SJim Ingham case 'b': 11435a988416SJim Ingham m_level = lldb::eDescriptionLevelBrief; 11445a988416SJim Ingham break; 114533df7cd3SJim Ingham case 'D': 114633df7cd3SJim Ingham m_use_dummy = true; 114733df7cd3SJim Ingham break; 11485a988416SJim Ingham case 'f': 11495a988416SJim Ingham m_level = lldb::eDescriptionLevelFull; 11505a988416SJim Ingham break; 11515a988416SJim Ingham case 'v': 11525a988416SJim Ingham m_level = lldb::eDescriptionLevelVerbose; 11535a988416SJim Ingham break; 11545a988416SJim Ingham case 'i': 11555a988416SJim Ingham m_internal = true; 11565a988416SJim Ingham break; 11575a988416SJim Ingham default: 115836162014SRaphael Isemann llvm_unreachable("Unimplemented option"); 11595a988416SJim Ingham } 11605a988416SJim Ingham 11615a988416SJim Ingham return error; 11625a988416SJim Ingham } 11635a988416SJim Ingham 1164b9c1b51eSKate Stone void OptionParsingStarting(ExecutionContext *execution_context) override { 11655a988416SJim Ingham m_level = lldb::eDescriptionLevelFull; 11665a988416SJim Ingham m_internal = false; 116733df7cd3SJim Ingham m_use_dummy = false; 11685a988416SJim Ingham } 11695a988416SJim Ingham 11701f0f5b5bSZachary Turner llvm::ArrayRef<OptionDefinition> GetDefinitions() override { 117170602439SZachary Turner return llvm::makeArrayRef(g_breakpoint_list_options); 11721f0f5b5bSZachary Turner } 11735a988416SJim Ingham 11745a988416SJim Ingham // Instance variables to hold the values for command options. 11755a988416SJim Ingham 11765a988416SJim Ingham lldb::DescriptionLevel m_level; 11775a988416SJim Ingham 11785a988416SJim Ingham bool m_internal; 117933df7cd3SJim Ingham bool m_use_dummy; 11805a988416SJim Ingham }; 11815a988416SJim Ingham 11825a988416SJim Ingham protected: 1183b9c1b51eSKate Stone bool DoExecute(Args &command, CommandReturnObject &result) override { 1184cb2380c9SRaphael Isemann Target &target = GetSelectedOrDummyTarget(m_options.m_use_dummy); 11855a988416SJim Ingham 1186b9c1b51eSKate Stone const BreakpointList &breakpoints = 1187cb2380c9SRaphael Isemann target.GetBreakpointList(m_options.m_internal); 1188bb19a13cSSaleem Abdulrasool std::unique_lock<std::recursive_mutex> lock; 1189cb2380c9SRaphael Isemann target.GetBreakpointList(m_options.m_internal).GetListMutex(lock); 11905a988416SJim Ingham 11915a988416SJim Ingham size_t num_breakpoints = breakpoints.GetSize(); 11925a988416SJim Ingham 1193b9c1b51eSKate Stone if (num_breakpoints == 0) { 11945a988416SJim Ingham result.AppendMessage("No breakpoints currently set."); 11955a988416SJim Ingham result.SetStatus(eReturnStatusSuccessFinishNoResult); 11965a988416SJim Ingham return true; 11975a988416SJim Ingham } 11985a988416SJim Ingham 11995a988416SJim Ingham Stream &output_stream = result.GetOutputStream(); 12005a988416SJim Ingham 120111eb9c64SZachary Turner if (command.empty()) { 12025a988416SJim Ingham // No breakpoint selected; show info about all currently set breakpoints. 12035a988416SJim Ingham result.AppendMessage("Current breakpoints:"); 1204b9c1b51eSKate Stone for (size_t i = 0; i < num_breakpoints; ++i) { 12055a988416SJim Ingham Breakpoint *breakpoint = breakpoints.GetBreakpointAtIndex(i).get(); 1206b842f2ecSJim Ingham if (breakpoint->AllowList()) 1207b842f2ecSJim Ingham AddBreakpointDescription(&output_stream, breakpoint, 1208b842f2ecSJim Ingham m_options.m_level); 12095a988416SJim Ingham } 12105a988416SJim Ingham result.SetStatus(eReturnStatusSuccessFinishNoResult); 1211b9c1b51eSKate Stone } else { 12125a988416SJim Ingham // Particular breakpoints selected; show info about that breakpoint. 12135a988416SJim Ingham BreakpointIDList valid_bp_ids; 1214b9c1b51eSKate Stone CommandObjectMultiwordBreakpoint::VerifyBreakpointOrLocationIDs( 1215cb2380c9SRaphael Isemann command, &target, result, &valid_bp_ids, 1216b842f2ecSJim Ingham BreakpointName::Permissions::PermissionKinds::listPerm); 12175a988416SJim Ingham 1218b9c1b51eSKate Stone if (result.Succeeded()) { 1219b9c1b51eSKate Stone for (size_t i = 0; i < valid_bp_ids.GetSize(); ++i) { 12205a988416SJim Ingham BreakpointID cur_bp_id = valid_bp_ids.GetBreakpointIDAtIndex(i); 1221b9c1b51eSKate Stone Breakpoint *breakpoint = 1222cb2380c9SRaphael Isemann target.GetBreakpointByID(cur_bp_id.GetBreakpointID()).get(); 1223b9c1b51eSKate Stone AddBreakpointDescription(&output_stream, breakpoint, 1224b9c1b51eSKate Stone m_options.m_level); 12255a988416SJim Ingham } 12265a988416SJim Ingham result.SetStatus(eReturnStatusSuccessFinishNoResult); 1227b9c1b51eSKate Stone } else { 12287428a18cSKate Stone result.AppendError("Invalid breakpoint ID."); 12295a988416SJim Ingham result.SetStatus(eReturnStatusFailed); 12305a988416SJim Ingham } 12315a988416SJim Ingham } 12325a988416SJim Ingham 12335a988416SJim Ingham return result.Succeeded(); 12345a988416SJim Ingham } 12355a988416SJim Ingham 12365a988416SJim Ingham private: 12375a988416SJim Ingham CommandOptions m_options; 12385a988416SJim Ingham }; 12395a988416SJim Ingham 12405a988416SJim Ingham // CommandObjectBreakpointClear 12411f0f5b5bSZachary Turner #pragma mark Clear::CommandOptions 12421f0f5b5bSZachary Turner 1243f94668e3SRaphael Isemann #define LLDB_OPTIONS_breakpoint_clear 1244f94668e3SRaphael Isemann #include "CommandOptions.inc" 12451f0f5b5bSZachary Turner 12465a988416SJim Ingham #pragma mark Clear 12475a988416SJim Ingham 1248b9c1b51eSKate Stone class CommandObjectBreakpointClear : public CommandObjectParsed { 12495a988416SJim Ingham public: 1250efe8e7e3SFangrui Song enum BreakpointClearType { eClearTypeInvalid, eClearTypeFileAndLine }; 12515a988416SJim Ingham 12527428a18cSKate Stone CommandObjectBreakpointClear(CommandInterpreter &interpreter) 12537428a18cSKate Stone : CommandObjectParsed(interpreter, "breakpoint clear", 1254b9c1b51eSKate Stone "Delete or disable breakpoints matching the " 1255b9c1b51eSKate Stone "specified source file and line.", 12565a988416SJim Ingham "breakpoint clear <cmd-options>"), 1257b9c1b51eSKate Stone m_options() {} 12585a988416SJim Ingham 12599e85e5a8SEugene Zelenko ~CommandObjectBreakpointClear() override = default; 12605a988416SJim Ingham 1261b9c1b51eSKate Stone Options *GetOptions() override { return &m_options; } 12625a988416SJim Ingham 1263b9c1b51eSKate Stone class CommandOptions : public Options { 12645a988416SJim Ingham public: 1265b9c1b51eSKate Stone CommandOptions() : Options(), m_filename(), m_line_num(0) {} 12665a988416SJim Ingham 12679e85e5a8SEugene Zelenko ~CommandOptions() override = default; 12685a988416SJim Ingham 126997206d57SZachary Turner Status SetOptionValue(uint32_t option_idx, llvm::StringRef option_arg, 1270b9c1b51eSKate Stone ExecutionContext *execution_context) override { 127197206d57SZachary Turner Status error; 12723bcdfc0eSGreg Clayton const int short_option = m_getopt_table[option_idx].val; 12735a988416SJim Ingham 1274b9c1b51eSKate Stone switch (short_option) { 12755a988416SJim Ingham case 'f': 12765a988416SJim Ingham m_filename.assign(option_arg); 12775a988416SJim Ingham break; 12785a988416SJim Ingham 12795a988416SJim Ingham case 'l': 1280fe11483bSZachary Turner option_arg.getAsInteger(0, m_line_num); 12815a988416SJim Ingham break; 12825a988416SJim Ingham 12835a988416SJim Ingham default: 128436162014SRaphael Isemann llvm_unreachable("Unimplemented option"); 12855a988416SJim Ingham } 12865a988416SJim Ingham 12875a988416SJim Ingham return error; 12885a988416SJim Ingham } 12895a988416SJim Ingham 1290b9c1b51eSKate Stone void OptionParsingStarting(ExecutionContext *execution_context) override { 12915a988416SJim Ingham m_filename.clear(); 12925a988416SJim Ingham m_line_num = 0; 12935a988416SJim Ingham } 12945a988416SJim Ingham 12951f0f5b5bSZachary Turner llvm::ArrayRef<OptionDefinition> GetDefinitions() override { 129670602439SZachary Turner return llvm::makeArrayRef(g_breakpoint_clear_options); 12971f0f5b5bSZachary Turner } 12985a988416SJim Ingham 12995a988416SJim Ingham // Instance variables to hold the values for command options. 13005a988416SJim Ingham 13015a988416SJim Ingham std::string m_filename; 13025a988416SJim Ingham uint32_t m_line_num; 13035a988416SJim Ingham }; 13045a988416SJim Ingham 13055a988416SJim Ingham protected: 1306b9c1b51eSKate Stone bool DoExecute(Args &command, CommandReturnObject &result) override { 1307cb2380c9SRaphael Isemann Target &target = GetSelectedOrDummyTarget(); 13085a988416SJim Ingham 130905097246SAdrian Prantl // The following are the various types of breakpoints that could be 131005097246SAdrian Prantl // cleared: 13115a988416SJim Ingham // 1). -f -l (clearing breakpoint by source location) 13125a988416SJim Ingham 13135a988416SJim Ingham BreakpointClearType break_type = eClearTypeInvalid; 13145a988416SJim Ingham 13155a988416SJim Ingham if (m_options.m_line_num != 0) 13165a988416SJim Ingham break_type = eClearTypeFileAndLine; 13175a988416SJim Ingham 1318bb19a13cSSaleem Abdulrasool std::unique_lock<std::recursive_mutex> lock; 1319cb2380c9SRaphael Isemann target.GetBreakpointList().GetListMutex(lock); 13205a988416SJim Ingham 1321cb2380c9SRaphael Isemann BreakpointList &breakpoints = target.GetBreakpointList(); 13225a988416SJim Ingham size_t num_breakpoints = breakpoints.GetSize(); 13235a988416SJim Ingham 13245a988416SJim Ingham // Early return if there's no breakpoint at all. 1325b9c1b51eSKate Stone if (num_breakpoints == 0) { 13265a988416SJim Ingham result.AppendError("Breakpoint clear: No breakpoint cleared."); 13275a988416SJim Ingham result.SetStatus(eReturnStatusFailed); 13285a988416SJim Ingham return result.Succeeded(); 13295a988416SJim Ingham } 13305a988416SJim Ingham 13315a988416SJim Ingham // Find matching breakpoints and delete them. 13325a988416SJim Ingham 13335a988416SJim Ingham // First create a copy of all the IDs. 13345a988416SJim Ingham std::vector<break_id_t> BreakIDs; 13355a988416SJim Ingham for (size_t i = 0; i < num_breakpoints; ++i) 13369e85e5a8SEugene Zelenko BreakIDs.push_back(breakpoints.GetBreakpointAtIndex(i)->GetID()); 13375a988416SJim Ingham 13385a988416SJim Ingham int num_cleared = 0; 13395a988416SJim Ingham StreamString ss; 1340b9c1b51eSKate Stone switch (break_type) { 13415a988416SJim Ingham case eClearTypeFileAndLine: // Breakpoint by source position 13425a988416SJim Ingham { 13435a988416SJim Ingham const ConstString filename(m_options.m_filename.c_str()); 13445a988416SJim Ingham BreakpointLocationCollection loc_coll; 13455a988416SJim Ingham 1346b9c1b51eSKate Stone for (size_t i = 0; i < num_breakpoints; ++i) { 13475a988416SJim Ingham Breakpoint *bp = breakpoints.FindBreakpointByID(BreakIDs[i]).get(); 13485a988416SJim Ingham 1349b9c1b51eSKate Stone if (bp->GetMatchingFileLine(filename, m_options.m_line_num, loc_coll)) { 1350b9c1b51eSKate Stone // If the collection size is 0, it's a full match and we can just 1351b9c1b51eSKate Stone // remove the breakpoint. 1352b9c1b51eSKate Stone if (loc_coll.GetSize() == 0) { 13535a988416SJim Ingham bp->GetDescription(&ss, lldb::eDescriptionLevelBrief); 13545a988416SJim Ingham ss.EOL(); 1355cb2380c9SRaphael Isemann target.RemoveBreakpointByID(bp->GetID()); 13565a988416SJim Ingham ++num_cleared; 13575a988416SJim Ingham } 13585a988416SJim Ingham } 13595a988416SJim Ingham } 1360b9c1b51eSKate Stone } break; 13615a988416SJim Ingham 13625a988416SJim Ingham default: 13635a988416SJim Ingham break; 13645a988416SJim Ingham } 13655a988416SJim Ingham 1366b9c1b51eSKate Stone if (num_cleared > 0) { 13675a988416SJim Ingham Stream &output_stream = result.GetOutputStream(); 13685a988416SJim Ingham output_stream.Printf("%d breakpoints cleared:\n", num_cleared); 1369c156427dSZachary Turner output_stream << ss.GetString(); 13705a988416SJim Ingham output_stream.EOL(); 13715a988416SJim Ingham result.SetStatus(eReturnStatusSuccessFinishNoResult); 1372b9c1b51eSKate Stone } else { 13735a988416SJim Ingham result.AppendError("Breakpoint clear: No breakpoint cleared."); 13745a988416SJim Ingham result.SetStatus(eReturnStatusFailed); 13755a988416SJim Ingham } 13765a988416SJim Ingham 13775a988416SJim Ingham return result.Succeeded(); 13785a988416SJim Ingham } 13795a988416SJim Ingham 13805a988416SJim Ingham private: 13815a988416SJim Ingham CommandOptions m_options; 13825a988416SJim Ingham }; 13835a988416SJim Ingham 13845a988416SJim Ingham // CommandObjectBreakpointDelete 1385f94668e3SRaphael Isemann #define LLDB_OPTIONS_breakpoint_delete 1386f94668e3SRaphael Isemann #include "CommandOptions.inc" 13871f0f5b5bSZachary Turner 13885a988416SJim Ingham #pragma mark Delete 13895a988416SJim Ingham 1390b9c1b51eSKate Stone class CommandObjectBreakpointDelete : public CommandObjectParsed { 13915a988416SJim Ingham public: 1392b9c1b51eSKate Stone CommandObjectBreakpointDelete(CommandInterpreter &interpreter) 1393b9c1b51eSKate Stone : CommandObjectParsed(interpreter, "breakpoint delete", 1394b9c1b51eSKate Stone "Delete the specified breakpoint(s). If no " 1395b9c1b51eSKate Stone "breakpoints are specified, delete them all.", 13969e85e5a8SEugene Zelenko nullptr), 1397b9c1b51eSKate Stone m_options() { 13985a988416SJim Ingham CommandArgumentEntry arg; 1399b9c1b51eSKate Stone CommandObject::AddIDsArgumentData(arg, eArgTypeBreakpointID, 1400b9c1b51eSKate Stone eArgTypeBreakpointIDRange); 1401b9c1b51eSKate Stone // Add the entry for the first argument for this command to the object's 1402b9c1b51eSKate Stone // arguments vector. 14035a988416SJim Ingham m_arguments.push_back(arg); 14045a988416SJim Ingham } 14055a988416SJim Ingham 14069e85e5a8SEugene Zelenko ~CommandObjectBreakpointDelete() override = default; 14075a988416SJim Ingham 1408b9c1b51eSKate Stone Options *GetOptions() override { return &m_options; } 140933df7cd3SJim Ingham 1410b9c1b51eSKate Stone class CommandOptions : public Options { 141133df7cd3SJim Ingham public: 1412b9c1b51eSKate Stone CommandOptions() : Options(), m_use_dummy(false), m_force(false) {} 141333df7cd3SJim Ingham 14149e85e5a8SEugene Zelenko ~CommandOptions() override = default; 141533df7cd3SJim Ingham 141697206d57SZachary Turner Status SetOptionValue(uint32_t option_idx, llvm::StringRef option_arg, 1417b9c1b51eSKate Stone ExecutionContext *execution_context) override { 141897206d57SZachary Turner Status error; 141933df7cd3SJim Ingham const int short_option = m_getopt_table[option_idx].val; 142033df7cd3SJim Ingham 1421b9c1b51eSKate Stone switch (short_option) { 142233df7cd3SJim Ingham case 'f': 142333df7cd3SJim Ingham m_force = true; 142433df7cd3SJim Ingham break; 142533df7cd3SJim Ingham 142633df7cd3SJim Ingham case 'D': 142733df7cd3SJim Ingham m_use_dummy = true; 142833df7cd3SJim Ingham break; 142933df7cd3SJim Ingham 143033df7cd3SJim Ingham default: 143136162014SRaphael Isemann llvm_unreachable("Unimplemented option"); 143233df7cd3SJim Ingham } 143333df7cd3SJim Ingham 143433df7cd3SJim Ingham return error; 143533df7cd3SJim Ingham } 143633df7cd3SJim Ingham 1437b9c1b51eSKate Stone void OptionParsingStarting(ExecutionContext *execution_context) override { 143833df7cd3SJim Ingham m_use_dummy = false; 143933df7cd3SJim Ingham m_force = false; 144033df7cd3SJim Ingham } 144133df7cd3SJim Ingham 14421f0f5b5bSZachary Turner llvm::ArrayRef<OptionDefinition> GetDefinitions() override { 144370602439SZachary Turner return llvm::makeArrayRef(g_breakpoint_delete_options); 14441f0f5b5bSZachary Turner } 144533df7cd3SJim Ingham 144633df7cd3SJim Ingham // Instance variables to hold the values for command options. 144733df7cd3SJim Ingham bool m_use_dummy; 144833df7cd3SJim Ingham bool m_force; 144933df7cd3SJim Ingham }; 145033df7cd3SJim Ingham 14515a988416SJim Ingham protected: 1452b9c1b51eSKate Stone bool DoExecute(Args &command, CommandReturnObject &result) override { 1453cb2380c9SRaphael Isemann Target &target = GetSelectedOrDummyTarget(m_options.m_use_dummy); 14545a988416SJim Ingham 1455bb19a13cSSaleem Abdulrasool std::unique_lock<std::recursive_mutex> lock; 1456cb2380c9SRaphael Isemann target.GetBreakpointList().GetListMutex(lock); 14575a988416SJim Ingham 1458cb2380c9SRaphael Isemann const BreakpointList &breakpoints = target.GetBreakpointList(); 14595a988416SJim Ingham 14605a988416SJim Ingham size_t num_breakpoints = breakpoints.GetSize(); 14615a988416SJim Ingham 1462b9c1b51eSKate Stone if (num_breakpoints == 0) { 14635a988416SJim Ingham result.AppendError("No breakpoints exist to be deleted."); 14645a988416SJim Ingham result.SetStatus(eReturnStatusFailed); 14655a988416SJim Ingham return false; 14665a988416SJim Ingham } 14675a988416SJim Ingham 146811eb9c64SZachary Turner if (command.empty()) { 1469b9c1b51eSKate Stone if (!m_options.m_force && 1470b9c1b51eSKate Stone !m_interpreter.Confirm( 1471b9c1b51eSKate Stone "About to delete all breakpoints, do you want to do that?", 1472b9c1b51eSKate Stone true)) { 14735a988416SJim Ingham result.AppendMessage("Operation cancelled..."); 1474b9c1b51eSKate Stone } else { 1475cb2380c9SRaphael Isemann target.RemoveAllowedBreakpoints(); 1476b9c1b51eSKate Stone result.AppendMessageWithFormat( 1477b9c1b51eSKate Stone "All breakpoints removed. (%" PRIu64 " breakpoint%s)\n", 1478b9c1b51eSKate Stone (uint64_t)num_breakpoints, num_breakpoints > 1 ? "s" : ""); 14795a988416SJim Ingham } 14805a988416SJim Ingham result.SetStatus(eReturnStatusSuccessFinishNoResult); 1481b9c1b51eSKate Stone } else { 14825a988416SJim Ingham // Particular breakpoint selected; disable that breakpoint. 14835a988416SJim Ingham BreakpointIDList valid_bp_ids; 1484b9c1b51eSKate Stone CommandObjectMultiwordBreakpoint::VerifyBreakpointOrLocationIDs( 1485cb2380c9SRaphael Isemann command, &target, result, &valid_bp_ids, 1486b842f2ecSJim Ingham BreakpointName::Permissions::PermissionKinds::deletePerm); 14875a988416SJim Ingham 1488b9c1b51eSKate Stone if (result.Succeeded()) { 14895a988416SJim Ingham int delete_count = 0; 14905a988416SJim Ingham int disable_count = 0; 14915a988416SJim Ingham const size_t count = valid_bp_ids.GetSize(); 1492b9c1b51eSKate Stone for (size_t i = 0; i < count; ++i) { 14935a988416SJim Ingham BreakpointID cur_bp_id = valid_bp_ids.GetBreakpointIDAtIndex(i); 14945a988416SJim Ingham 1495b9c1b51eSKate Stone if (cur_bp_id.GetBreakpointID() != LLDB_INVALID_BREAK_ID) { 1496b9c1b51eSKate Stone if (cur_bp_id.GetLocationID() != LLDB_INVALID_BREAK_ID) { 1497b9c1b51eSKate Stone Breakpoint *breakpoint = 1498cb2380c9SRaphael Isemann target.GetBreakpointByID(cur_bp_id.GetBreakpointID()).get(); 1499b9c1b51eSKate Stone BreakpointLocation *location = 1500b9c1b51eSKate Stone breakpoint->FindLocationByID(cur_bp_id.GetLocationID()).get(); 1501b9c1b51eSKate Stone // It makes no sense to try to delete individual locations, so we 1502b9c1b51eSKate Stone // disable them instead. 1503b9c1b51eSKate Stone if (location) { 15045a988416SJim Ingham location->SetEnabled(false); 15055a988416SJim Ingham ++disable_count; 15065a988416SJim Ingham } 1507b9c1b51eSKate Stone } else { 1508cb2380c9SRaphael Isemann target.RemoveBreakpointByID(cur_bp_id.GetBreakpointID()); 15095a988416SJim Ingham ++delete_count; 15105a988416SJim Ingham } 15115a988416SJim Ingham } 15125a988416SJim Ingham } 1513b9c1b51eSKate Stone result.AppendMessageWithFormat( 1514b9c1b51eSKate Stone "%d breakpoints deleted; %d breakpoint locations disabled.\n", 15155a988416SJim Ingham delete_count, disable_count); 15165a988416SJim Ingham result.SetStatus(eReturnStatusSuccessFinishNoResult); 15175a988416SJim Ingham } 15185a988416SJim Ingham } 15195a988416SJim Ingham return result.Succeeded(); 15205a988416SJim Ingham } 15219e85e5a8SEugene Zelenko 152233df7cd3SJim Ingham private: 152333df7cd3SJim Ingham CommandOptions m_options; 152433df7cd3SJim Ingham }; 152533df7cd3SJim Ingham 15265e09c8c3SJim Ingham // CommandObjectBreakpointName 1527f94668e3SRaphael Isemann #define LLDB_OPTIONS_breakpoint_name 1528f94668e3SRaphael Isemann #include "CommandOptions.inc" 1529bd68a052SRaphael Isemann 1530b9c1b51eSKate Stone class BreakpointNameOptionGroup : public OptionGroup { 15315e09c8c3SJim Ingham public: 1532b9c1b51eSKate Stone BreakpointNameOptionGroup() 1533b9c1b51eSKate Stone : OptionGroup(), m_breakpoint(LLDB_INVALID_BREAK_ID), m_use_dummy(false) { 15345e09c8c3SJim Ingham } 15355e09c8c3SJim Ingham 15369e85e5a8SEugene Zelenko ~BreakpointNameOptionGroup() override = default; 15375e09c8c3SJim Ingham 15381f0f5b5bSZachary Turner llvm::ArrayRef<OptionDefinition> GetDefinitions() override { 153970602439SZachary Turner return llvm::makeArrayRef(g_breakpoint_name_options); 15405e09c8c3SJim Ingham } 15415e09c8c3SJim Ingham 154297206d57SZachary Turner Status SetOptionValue(uint32_t option_idx, llvm::StringRef option_arg, 1543b9c1b51eSKate Stone ExecutionContext *execution_context) override { 154497206d57SZachary Turner Status error; 15455e09c8c3SJim Ingham const int short_option = g_breakpoint_name_options[option_idx].short_option; 15465e09c8c3SJim Ingham 1547b9c1b51eSKate Stone switch (short_option) { 15485e09c8c3SJim Ingham case 'N': 1549fe11483bSZachary Turner if (BreakpointID::StringIsBreakpointName(option_arg, error) && 1550b9c1b51eSKate Stone error.Success()) 1551fe11483bSZachary Turner m_name.SetValueFromString(option_arg); 15525e09c8c3SJim Ingham break; 15535e09c8c3SJim Ingham case 'B': 1554fe11483bSZachary Turner if (m_breakpoint.SetValueFromString(option_arg).Fail()) 1555b9c1b51eSKate Stone error.SetErrorStringWithFormat( 15568cef4b0bSZachary Turner "unrecognized value \"%s\" for breakpoint", 1557fe11483bSZachary Turner option_arg.str().c_str()); 15585e09c8c3SJim Ingham break; 15595e09c8c3SJim Ingham case 'D': 1560fe11483bSZachary Turner if (m_use_dummy.SetValueFromString(option_arg).Fail()) 1561b9c1b51eSKate Stone error.SetErrorStringWithFormat( 15628cef4b0bSZachary Turner "unrecognized value \"%s\" for use-dummy", 1563fe11483bSZachary Turner option_arg.str().c_str()); 15645e09c8c3SJim Ingham break; 1565e9632ebaSJim Ingham case 'H': 1566e9632ebaSJim Ingham m_help_string.SetValueFromString(option_arg); 1567e9632ebaSJim Ingham break; 15685e09c8c3SJim Ingham 15695e09c8c3SJim Ingham default: 157036162014SRaphael Isemann llvm_unreachable("Unimplemented option"); 15715e09c8c3SJim Ingham } 15725e09c8c3SJim Ingham return error; 15735e09c8c3SJim Ingham } 15745e09c8c3SJim Ingham 1575b9c1b51eSKate Stone void OptionParsingStarting(ExecutionContext *execution_context) override { 15765e09c8c3SJim Ingham m_name.Clear(); 15775e09c8c3SJim Ingham m_breakpoint.Clear(); 15785e09c8c3SJim Ingham m_use_dummy.Clear(); 15795e09c8c3SJim Ingham m_use_dummy.SetDefaultValue(false); 1580e9632ebaSJim Ingham m_help_string.Clear(); 15815e09c8c3SJim Ingham } 15825e09c8c3SJim Ingham 15835e09c8c3SJim Ingham OptionValueString m_name; 15845e09c8c3SJim Ingham OptionValueUInt64 m_breakpoint; 15855e09c8c3SJim Ingham OptionValueBoolean m_use_dummy; 1586e9632ebaSJim Ingham OptionValueString m_help_string; 15875e09c8c3SJim Ingham }; 15885e09c8c3SJim Ingham 1589f94668e3SRaphael Isemann #define LLDB_OPTIONS_breakpoint_access 1590f94668e3SRaphael Isemann #include "CommandOptions.inc" 1591b842f2ecSJim Ingham 15928fe53c49STatyana Krasnukha class BreakpointAccessOptionGroup : public OptionGroup { 1593b842f2ecSJim Ingham public: 15948fe53c49STatyana Krasnukha BreakpointAccessOptionGroup() : OptionGroup() {} 1595b842f2ecSJim Ingham 1596b842f2ecSJim Ingham ~BreakpointAccessOptionGroup() override = default; 1597b842f2ecSJim Ingham 1598b842f2ecSJim Ingham llvm::ArrayRef<OptionDefinition> GetDefinitions() override { 1599b842f2ecSJim Ingham return llvm::makeArrayRef(g_breakpoint_access_options); 1600b842f2ecSJim Ingham } 1601b842f2ecSJim Ingham Status SetOptionValue(uint32_t option_idx, llvm::StringRef option_arg, 1602b842f2ecSJim Ingham ExecutionContext *execution_context) override { 1603b842f2ecSJim Ingham Status error; 1604b842f2ecSJim Ingham const int short_option 1605b842f2ecSJim Ingham = g_breakpoint_access_options[option_idx].short_option; 1606b842f2ecSJim Ingham 1607b842f2ecSJim Ingham switch (short_option) { 1608b842f2ecSJim Ingham case 'L': { 1609b842f2ecSJim Ingham bool value, success; 161047cbf4a0SPavel Labath value = OptionArgParser::ToBoolean(option_arg, false, &success); 1611b842f2ecSJim Ingham if (success) { 1612b842f2ecSJim Ingham m_permissions.SetAllowList(value); 1613b842f2ecSJim Ingham } else 1614b842f2ecSJim Ingham error.SetErrorStringWithFormat( 1615b842f2ecSJim Ingham "invalid boolean value '%s' passed for -L option", 1616b842f2ecSJim Ingham option_arg.str().c_str()); 1617b842f2ecSJim Ingham } break; 1618b842f2ecSJim Ingham case 'A': { 1619b842f2ecSJim Ingham bool value, success; 162047cbf4a0SPavel Labath value = OptionArgParser::ToBoolean(option_arg, false, &success); 1621b842f2ecSJim Ingham if (success) { 1622b842f2ecSJim Ingham m_permissions.SetAllowDisable(value); 1623b842f2ecSJim Ingham } else 1624b842f2ecSJim Ingham error.SetErrorStringWithFormat( 1625b842f2ecSJim Ingham "invalid boolean value '%s' passed for -L option", 1626b842f2ecSJim Ingham option_arg.str().c_str()); 1627b842f2ecSJim Ingham } break; 1628b842f2ecSJim Ingham case 'D': { 1629b842f2ecSJim Ingham bool value, success; 163047cbf4a0SPavel Labath value = OptionArgParser::ToBoolean(option_arg, false, &success); 1631b842f2ecSJim Ingham if (success) { 1632b842f2ecSJim Ingham m_permissions.SetAllowDelete(value); 1633b842f2ecSJim Ingham } else 1634b842f2ecSJim Ingham error.SetErrorStringWithFormat( 1635b842f2ecSJim Ingham "invalid boolean value '%s' passed for -L option", 1636b842f2ecSJim Ingham option_arg.str().c_str()); 1637b842f2ecSJim Ingham } break; 163836162014SRaphael Isemann default: 163936162014SRaphael Isemann llvm_unreachable("Unimplemented option"); 1640b842f2ecSJim Ingham } 1641b842f2ecSJim Ingham 1642b842f2ecSJim Ingham return error; 1643b842f2ecSJim Ingham } 1644b842f2ecSJim Ingham 1645b842f2ecSJim Ingham void OptionParsingStarting(ExecutionContext *execution_context) override { 1646b842f2ecSJim Ingham } 1647b842f2ecSJim Ingham 1648b842f2ecSJim Ingham const BreakpointName::Permissions &GetPermissions() const 1649b842f2ecSJim Ingham { 1650b842f2ecSJim Ingham return m_permissions; 1651b842f2ecSJim Ingham } 1652b842f2ecSJim Ingham BreakpointName::Permissions m_permissions; 1653b842f2ecSJim Ingham }; 1654b842f2ecSJim Ingham 1655b842f2ecSJim Ingham class CommandObjectBreakpointNameConfigure : public CommandObjectParsed { 1656b842f2ecSJim Ingham public: 1657b842f2ecSJim Ingham CommandObjectBreakpointNameConfigure(CommandInterpreter &interpreter) 1658b842f2ecSJim Ingham : CommandObjectParsed( 1659b842f2ecSJim Ingham interpreter, "configure", "Configure the options for the breakpoint" 1660b842f2ecSJim Ingham " name provided. " 1661b842f2ecSJim Ingham "If you provide a breakpoint id, the options will be copied from " 1662b842f2ecSJim Ingham "the breakpoint, otherwise only the options specified will be set " 1663b842f2ecSJim Ingham "on the name.", 1664b842f2ecSJim Ingham "breakpoint name configure <command-options> " 1665b842f2ecSJim Ingham "<breakpoint-name-list>"), 1666b842f2ecSJim Ingham m_bp_opts(), m_option_group() { 1667b842f2ecSJim Ingham // Create the first variant for the first (and only) argument for this 1668b842f2ecSJim Ingham // command. 1669b842f2ecSJim Ingham CommandArgumentEntry arg1; 1670b842f2ecSJim Ingham CommandArgumentData id_arg; 1671b842f2ecSJim Ingham id_arg.arg_type = eArgTypeBreakpointName; 1672b842f2ecSJim Ingham id_arg.arg_repetition = eArgRepeatOptional; 1673b842f2ecSJim Ingham arg1.push_back(id_arg); 1674b842f2ecSJim Ingham m_arguments.push_back(arg1); 1675b842f2ecSJim Ingham 1676b842f2ecSJim Ingham m_option_group.Append(&m_bp_opts, 1677b842f2ecSJim Ingham LLDB_OPT_SET_ALL, 1678b842f2ecSJim Ingham LLDB_OPT_SET_1); 1679b842f2ecSJim Ingham m_option_group.Append(&m_access_options, 1680b842f2ecSJim Ingham LLDB_OPT_SET_ALL, 1681b842f2ecSJim Ingham LLDB_OPT_SET_ALL); 1682e9632ebaSJim Ingham m_option_group.Append(&m_bp_id, 1683e9632ebaSJim Ingham LLDB_OPT_SET_2|LLDB_OPT_SET_4, 1684e9632ebaSJim Ingham LLDB_OPT_SET_ALL); 1685b842f2ecSJim Ingham m_option_group.Finalize(); 1686b842f2ecSJim Ingham } 1687b842f2ecSJim Ingham 1688b842f2ecSJim Ingham ~CommandObjectBreakpointNameConfigure() override = default; 1689b842f2ecSJim Ingham 1690b842f2ecSJim Ingham Options *GetOptions() override { return &m_option_group; } 1691b842f2ecSJim Ingham 1692b842f2ecSJim Ingham protected: 1693b842f2ecSJim Ingham bool DoExecute(Args &command, CommandReturnObject &result) override { 1694b842f2ecSJim Ingham 1695b842f2ecSJim Ingham const size_t argc = command.GetArgumentCount(); 1696b842f2ecSJim Ingham if (argc == 0) { 1697b842f2ecSJim Ingham result.AppendError("No names provided."); 1698b842f2ecSJim Ingham result.SetStatus(eReturnStatusFailed); 1699b842f2ecSJim Ingham return false; 1700b842f2ecSJim Ingham } 1701b842f2ecSJim Ingham 1702cb2380c9SRaphael Isemann Target &target = GetSelectedOrDummyTarget(false); 1703b842f2ecSJim Ingham 1704b842f2ecSJim Ingham std::unique_lock<std::recursive_mutex> lock; 1705cb2380c9SRaphael Isemann target.GetBreakpointList().GetListMutex(lock); 1706b842f2ecSJim Ingham 1707b842f2ecSJim Ingham // Make a pass through first to see that all the names are legal. 1708b842f2ecSJim Ingham for (auto &entry : command.entries()) { 1709b842f2ecSJim Ingham Status error; 1710*0d9a201eSRaphael Isemann if (!BreakpointID::StringIsBreakpointName(entry.ref(), error)) 1711b842f2ecSJim Ingham { 1712b842f2ecSJim Ingham result.AppendErrorWithFormat("Invalid breakpoint name: %s - %s", 1713b842f2ecSJim Ingham entry.c_str(), error.AsCString()); 1714b842f2ecSJim Ingham result.SetStatus(eReturnStatusFailed); 1715b842f2ecSJim Ingham return false; 1716b842f2ecSJim Ingham } 1717b842f2ecSJim Ingham } 171805097246SAdrian Prantl // Now configure them, we already pre-checked the names so we don't need to 171905097246SAdrian Prantl // check the error: 1720b842f2ecSJim Ingham BreakpointSP bp_sp; 1721b842f2ecSJim Ingham if (m_bp_id.m_breakpoint.OptionWasSet()) 1722b842f2ecSJim Ingham { 1723b842f2ecSJim Ingham lldb::break_id_t bp_id = m_bp_id.m_breakpoint.GetUInt64Value(); 1724cb2380c9SRaphael Isemann bp_sp = target.GetBreakpointByID(bp_id); 1725b842f2ecSJim Ingham if (!bp_sp) 1726b842f2ecSJim Ingham { 1727b842f2ecSJim Ingham result.AppendErrorWithFormatv("Could not find specified breakpoint {0}", 1728b842f2ecSJim Ingham bp_id); 1729b842f2ecSJim Ingham result.SetStatus(eReturnStatusFailed); 1730b842f2ecSJim Ingham return false; 1731b842f2ecSJim Ingham } 1732b842f2ecSJim Ingham } 1733b842f2ecSJim Ingham 1734b842f2ecSJim Ingham Status error; 1735b842f2ecSJim Ingham for (auto &entry : command.entries()) { 1736b842f2ecSJim Ingham ConstString name(entry.c_str()); 1737cb2380c9SRaphael Isemann BreakpointName *bp_name = target.FindBreakpointName(name, true, error); 1738b842f2ecSJim Ingham if (!bp_name) 1739b842f2ecSJim Ingham continue; 1740e9632ebaSJim Ingham if (m_bp_id.m_help_string.OptionWasSet()) 1741e9632ebaSJim Ingham bp_name->SetHelp(m_bp_id.m_help_string.GetStringValue().str().c_str()); 1742e9632ebaSJim Ingham 1743b842f2ecSJim Ingham if (bp_sp) 1744cb2380c9SRaphael Isemann target.ConfigureBreakpointName(*bp_name, *bp_sp->GetOptions(), 1745b842f2ecSJim Ingham m_access_options.GetPermissions()); 1746b842f2ecSJim Ingham else 1747cb2380c9SRaphael Isemann target.ConfigureBreakpointName(*bp_name, 1748b842f2ecSJim Ingham m_bp_opts.GetBreakpointOptions(), 1749b842f2ecSJim Ingham m_access_options.GetPermissions()); 1750b842f2ecSJim Ingham } 1751b842f2ecSJim Ingham return true; 1752b842f2ecSJim Ingham } 1753b842f2ecSJim Ingham 1754b842f2ecSJim Ingham private: 1755b842f2ecSJim Ingham BreakpointNameOptionGroup m_bp_id; // Only using the id part of this. 1756b842f2ecSJim Ingham BreakpointOptionGroup m_bp_opts; 1757b842f2ecSJim Ingham BreakpointAccessOptionGroup m_access_options; 1758b842f2ecSJim Ingham OptionGroupOptions m_option_group; 1759b842f2ecSJim Ingham }; 1760b842f2ecSJim Ingham 1761b9c1b51eSKate Stone class CommandObjectBreakpointNameAdd : public CommandObjectParsed { 17625e09c8c3SJim Ingham public: 1763b9c1b51eSKate Stone CommandObjectBreakpointNameAdd(CommandInterpreter &interpreter) 1764b9c1b51eSKate Stone : CommandObjectParsed( 1765b9c1b51eSKate Stone interpreter, "add", "Add a name to the breakpoints provided.", 17665e09c8c3SJim Ingham "breakpoint name add <command-options> <breakpoint-id-list>"), 1767b9c1b51eSKate Stone m_name_options(), m_option_group() { 1768b9c1b51eSKate Stone // Create the first variant for the first (and only) argument for this 1769b9c1b51eSKate Stone // command. 17705e09c8c3SJim Ingham CommandArgumentEntry arg1; 17715e09c8c3SJim Ingham CommandArgumentData id_arg; 17725e09c8c3SJim Ingham id_arg.arg_type = eArgTypeBreakpointID; 17735e09c8c3SJim Ingham id_arg.arg_repetition = eArgRepeatOptional; 17745e09c8c3SJim Ingham arg1.push_back(id_arg); 17755e09c8c3SJim Ingham m_arguments.push_back(arg1); 17765e09c8c3SJim Ingham 17775e09c8c3SJim Ingham m_option_group.Append(&m_name_options, LLDB_OPT_SET_1, LLDB_OPT_SET_ALL); 17785e09c8c3SJim Ingham m_option_group.Finalize(); 17795e09c8c3SJim Ingham } 17805e09c8c3SJim Ingham 17819e85e5a8SEugene Zelenko ~CommandObjectBreakpointNameAdd() override = default; 17825e09c8c3SJim Ingham 1783b9c1b51eSKate Stone Options *GetOptions() override { return &m_option_group; } 17845e09c8c3SJim Ingham 17855e09c8c3SJim Ingham protected: 1786b9c1b51eSKate Stone bool DoExecute(Args &command, CommandReturnObject &result) override { 1787b9c1b51eSKate Stone if (!m_name_options.m_name.OptionWasSet()) { 17885e09c8c3SJim Ingham result.SetError("No name option provided."); 17895e09c8c3SJim Ingham return false; 17905e09c8c3SJim Ingham } 17915e09c8c3SJim Ingham 1792cb2380c9SRaphael Isemann Target &target = 1793b9c1b51eSKate Stone GetSelectedOrDummyTarget(m_name_options.m_use_dummy.GetCurrentValue()); 17945e09c8c3SJim Ingham 1795bb19a13cSSaleem Abdulrasool std::unique_lock<std::recursive_mutex> lock; 1796cb2380c9SRaphael Isemann target.GetBreakpointList().GetListMutex(lock); 17975e09c8c3SJim Ingham 1798cb2380c9SRaphael Isemann const BreakpointList &breakpoints = target.GetBreakpointList(); 17995e09c8c3SJim Ingham 18005e09c8c3SJim Ingham size_t num_breakpoints = breakpoints.GetSize(); 1801b9c1b51eSKate Stone if (num_breakpoints == 0) { 18025e09c8c3SJim Ingham result.SetError("No breakpoints, cannot add names."); 18035e09c8c3SJim Ingham result.SetStatus(eReturnStatusFailed); 18045e09c8c3SJim Ingham return false; 18055e09c8c3SJim Ingham } 18065e09c8c3SJim Ingham 18075e09c8c3SJim Ingham // Particular breakpoint selected; disable that breakpoint. 18085e09c8c3SJim Ingham BreakpointIDList valid_bp_ids; 1809b9c1b51eSKate Stone CommandObjectMultiwordBreakpoint::VerifyBreakpointIDs( 1810cb2380c9SRaphael Isemann command, &target, result, &valid_bp_ids, 1811b842f2ecSJim Ingham BreakpointName::Permissions::PermissionKinds::listPerm); 18125e09c8c3SJim Ingham 1813b9c1b51eSKate Stone if (result.Succeeded()) { 1814b9c1b51eSKate Stone if (valid_bp_ids.GetSize() == 0) { 18155e09c8c3SJim Ingham result.SetError("No breakpoints specified, cannot add names."); 18165e09c8c3SJim Ingham result.SetStatus(eReturnStatusFailed); 18175e09c8c3SJim Ingham return false; 18185e09c8c3SJim Ingham } 18195e09c8c3SJim Ingham size_t num_valid_ids = valid_bp_ids.GetSize(); 1820b842f2ecSJim Ingham const char *bp_name = m_name_options.m_name.GetCurrentValue(); 1821b842f2ecSJim Ingham Status error; // This error reports illegal names, but we've already 1822b842f2ecSJim Ingham // checked that, so we don't need to check it again here. 1823b9c1b51eSKate Stone for (size_t index = 0; index < num_valid_ids; index++) { 1824b9c1b51eSKate Stone lldb::break_id_t bp_id = 1825b9c1b51eSKate Stone valid_bp_ids.GetBreakpointIDAtIndex(index).GetBreakpointID(); 18265e09c8c3SJim Ingham BreakpointSP bp_sp = breakpoints.FindBreakpointByID(bp_id); 1827cb2380c9SRaphael Isemann target.AddNameToBreakpoint(bp_sp, bp_name, error); 18285e09c8c3SJim Ingham } 18295e09c8c3SJim Ingham } 18305e09c8c3SJim Ingham 18315e09c8c3SJim Ingham return true; 18325e09c8c3SJim Ingham } 18335e09c8c3SJim Ingham 18345e09c8c3SJim Ingham private: 18355e09c8c3SJim Ingham BreakpointNameOptionGroup m_name_options; 18365e09c8c3SJim Ingham OptionGroupOptions m_option_group; 18375e09c8c3SJim Ingham }; 18385e09c8c3SJim Ingham 1839b9c1b51eSKate Stone class CommandObjectBreakpointNameDelete : public CommandObjectParsed { 18405e09c8c3SJim Ingham public: 1841b9c1b51eSKate Stone CommandObjectBreakpointNameDelete(CommandInterpreter &interpreter) 1842b9c1b51eSKate Stone : CommandObjectParsed( 1843b9c1b51eSKate Stone interpreter, "delete", 18445e09c8c3SJim Ingham "Delete a name from the breakpoints provided.", 18455e09c8c3SJim Ingham "breakpoint name delete <command-options> <breakpoint-id-list>"), 1846b9c1b51eSKate Stone m_name_options(), m_option_group() { 1847b9c1b51eSKate Stone // Create the first variant for the first (and only) argument for this 1848b9c1b51eSKate Stone // command. 18495e09c8c3SJim Ingham CommandArgumentEntry arg1; 18505e09c8c3SJim Ingham CommandArgumentData id_arg; 18515e09c8c3SJim Ingham id_arg.arg_type = eArgTypeBreakpointID; 18525e09c8c3SJim Ingham id_arg.arg_repetition = eArgRepeatOptional; 18535e09c8c3SJim Ingham arg1.push_back(id_arg); 18545e09c8c3SJim Ingham m_arguments.push_back(arg1); 18555e09c8c3SJim Ingham 18565e09c8c3SJim Ingham m_option_group.Append(&m_name_options, LLDB_OPT_SET_1, LLDB_OPT_SET_ALL); 18575e09c8c3SJim Ingham m_option_group.Finalize(); 18585e09c8c3SJim Ingham } 18595e09c8c3SJim Ingham 18609e85e5a8SEugene Zelenko ~CommandObjectBreakpointNameDelete() override = default; 18615e09c8c3SJim Ingham 1862b9c1b51eSKate Stone Options *GetOptions() override { return &m_option_group; } 18635e09c8c3SJim Ingham 18645e09c8c3SJim Ingham protected: 1865b9c1b51eSKate Stone bool DoExecute(Args &command, CommandReturnObject &result) override { 1866b9c1b51eSKate Stone if (!m_name_options.m_name.OptionWasSet()) { 18675e09c8c3SJim Ingham result.SetError("No name option provided."); 18685e09c8c3SJim Ingham return false; 18695e09c8c3SJim Ingham } 18705e09c8c3SJim Ingham 1871cb2380c9SRaphael Isemann Target &target = 1872b9c1b51eSKate Stone GetSelectedOrDummyTarget(m_name_options.m_use_dummy.GetCurrentValue()); 18735e09c8c3SJim Ingham 1874bb19a13cSSaleem Abdulrasool std::unique_lock<std::recursive_mutex> lock; 1875cb2380c9SRaphael Isemann target.GetBreakpointList().GetListMutex(lock); 18765e09c8c3SJim Ingham 1877cb2380c9SRaphael Isemann const BreakpointList &breakpoints = target.GetBreakpointList(); 18785e09c8c3SJim Ingham 18795e09c8c3SJim Ingham size_t num_breakpoints = breakpoints.GetSize(); 1880b9c1b51eSKate Stone if (num_breakpoints == 0) { 18815e09c8c3SJim Ingham result.SetError("No breakpoints, cannot delete names."); 18825e09c8c3SJim Ingham result.SetStatus(eReturnStatusFailed); 18835e09c8c3SJim Ingham return false; 18845e09c8c3SJim Ingham } 18855e09c8c3SJim Ingham 18865e09c8c3SJim Ingham // Particular breakpoint selected; disable that breakpoint. 18875e09c8c3SJim Ingham BreakpointIDList valid_bp_ids; 1888b9c1b51eSKate Stone CommandObjectMultiwordBreakpoint::VerifyBreakpointIDs( 1889cb2380c9SRaphael Isemann command, &target, result, &valid_bp_ids, 1890b842f2ecSJim Ingham BreakpointName::Permissions::PermissionKinds::deletePerm); 18915e09c8c3SJim Ingham 1892b9c1b51eSKate Stone if (result.Succeeded()) { 1893b9c1b51eSKate Stone if (valid_bp_ids.GetSize() == 0) { 18945e09c8c3SJim Ingham result.SetError("No breakpoints specified, cannot delete names."); 18955e09c8c3SJim Ingham result.SetStatus(eReturnStatusFailed); 18965e09c8c3SJim Ingham return false; 18975e09c8c3SJim Ingham } 1898b842f2ecSJim Ingham ConstString bp_name(m_name_options.m_name.GetCurrentValue()); 18995e09c8c3SJim Ingham size_t num_valid_ids = valid_bp_ids.GetSize(); 1900b9c1b51eSKate Stone for (size_t index = 0; index < num_valid_ids; index++) { 1901b9c1b51eSKate Stone lldb::break_id_t bp_id = 1902b9c1b51eSKate Stone valid_bp_ids.GetBreakpointIDAtIndex(index).GetBreakpointID(); 19035e09c8c3SJim Ingham BreakpointSP bp_sp = breakpoints.FindBreakpointByID(bp_id); 1904cb2380c9SRaphael Isemann target.RemoveNameFromBreakpoint(bp_sp, bp_name); 19055e09c8c3SJim Ingham } 19065e09c8c3SJim Ingham } 19075e09c8c3SJim Ingham 19085e09c8c3SJim Ingham return true; 19095e09c8c3SJim Ingham } 19105e09c8c3SJim Ingham 19115e09c8c3SJim Ingham private: 19125e09c8c3SJim Ingham BreakpointNameOptionGroup m_name_options; 19135e09c8c3SJim Ingham OptionGroupOptions m_option_group; 19145e09c8c3SJim Ingham }; 19155e09c8c3SJim Ingham 1916b9c1b51eSKate Stone class CommandObjectBreakpointNameList : public CommandObjectParsed { 19175e09c8c3SJim Ingham public: 1918b9c1b51eSKate Stone CommandObjectBreakpointNameList(CommandInterpreter &interpreter) 1919b9c1b51eSKate Stone : CommandObjectParsed(interpreter, "list", 1920b842f2ecSJim Ingham "List either the names for a breakpoint or info " 1921b842f2ecSJim Ingham "about a given name. With no arguments, lists all " 1922b842f2ecSJim Ingham "names", 19235e09c8c3SJim Ingham "breakpoint name list <command-options>"), 1924b9c1b51eSKate Stone m_name_options(), m_option_group() { 1925b842f2ecSJim Ingham m_option_group.Append(&m_name_options, LLDB_OPT_SET_3, LLDB_OPT_SET_ALL); 19265e09c8c3SJim Ingham m_option_group.Finalize(); 19275e09c8c3SJim Ingham } 19285e09c8c3SJim Ingham 19299e85e5a8SEugene Zelenko ~CommandObjectBreakpointNameList() override = default; 19305e09c8c3SJim Ingham 1931b9c1b51eSKate Stone Options *GetOptions() override { return &m_option_group; } 19325e09c8c3SJim Ingham 19335e09c8c3SJim Ingham protected: 1934b9c1b51eSKate Stone bool DoExecute(Args &command, CommandReturnObject &result) override { 1935cb2380c9SRaphael Isemann Target &target = 1936b9c1b51eSKate Stone GetSelectedOrDummyTarget(m_name_options.m_use_dummy.GetCurrentValue()); 19375e09c8c3SJim Ingham 1938b842f2ecSJim Ingham std::vector<std::string> name_list; 1939b842f2ecSJim Ingham if (command.empty()) { 1940cb2380c9SRaphael Isemann target.GetBreakpointNames(name_list); 1941b842f2ecSJim Ingham } else { 1942b842f2ecSJim Ingham for (const Args::ArgEntry &arg : command) 1943b842f2ecSJim Ingham { 1944b842f2ecSJim Ingham name_list.push_back(arg.c_str()); 1945b842f2ecSJim Ingham } 1946b842f2ecSJim Ingham } 1947b842f2ecSJim Ingham 1948b842f2ecSJim Ingham if (name_list.empty()) { 1949b842f2ecSJim Ingham result.AppendMessage("No breakpoint names found."); 1950b842f2ecSJim Ingham } else { 1951b842f2ecSJim Ingham for (const std::string &name_str : name_list) { 1952b842f2ecSJim Ingham const char *name = name_str.c_str(); 1953b842f2ecSJim Ingham // First print out the options for the name: 1954b842f2ecSJim Ingham Status error; 1955cb2380c9SRaphael Isemann BreakpointName *bp_name = 1956cb2380c9SRaphael Isemann target.FindBreakpointName(ConstString(name), false, error); 1957b842f2ecSJim Ingham if (bp_name) 1958b842f2ecSJim Ingham { 1959b842f2ecSJim Ingham StreamString s; 1960b842f2ecSJim Ingham result.AppendMessageWithFormat("Name: %s\n", name); 1961b842f2ecSJim Ingham if (bp_name->GetDescription(&s, eDescriptionLevelFull)) 1962b842f2ecSJim Ingham { 1963b842f2ecSJim Ingham result.AppendMessage(s.GetString()); 1964b842f2ecSJim Ingham } 1965b842f2ecSJim Ingham 1966bb19a13cSSaleem Abdulrasool std::unique_lock<std::recursive_mutex> lock; 1967cb2380c9SRaphael Isemann target.GetBreakpointList().GetListMutex(lock); 19685e09c8c3SJim Ingham 1969cb2380c9SRaphael Isemann BreakpointList &breakpoints = target.GetBreakpointList(); 1970b842f2ecSJim Ingham bool any_set = false; 1971b9c1b51eSKate Stone for (BreakpointSP bp_sp : breakpoints.Breakpoints()) { 1972b9c1b51eSKate Stone if (bp_sp->MatchesName(name)) { 19735e09c8c3SJim Ingham StreamString s; 1974b842f2ecSJim Ingham any_set = true; 19755e09c8c3SJim Ingham bp_sp->GetDescription(&s, eDescriptionLevelBrief); 19765e09c8c3SJim Ingham s.EOL(); 1977c156427dSZachary Turner result.AppendMessage(s.GetString()); 19785e09c8c3SJim Ingham } 19795e09c8c3SJim Ingham } 1980b842f2ecSJim Ingham if (!any_set) 1981b842f2ecSJim Ingham result.AppendMessage("No breakpoints using this name."); 1982b9c1b51eSKate Stone } else { 1983b842f2ecSJim Ingham result.AppendMessageWithFormat("Name: %s not found.\n", name); 19845e09c8c3SJim Ingham } 1985b842f2ecSJim Ingham } 19865e09c8c3SJim Ingham } 19875e09c8c3SJim Ingham return true; 19885e09c8c3SJim Ingham } 19895e09c8c3SJim Ingham 19905e09c8c3SJim Ingham private: 19915e09c8c3SJim Ingham BreakpointNameOptionGroup m_name_options; 19925e09c8c3SJim Ingham OptionGroupOptions m_option_group; 19935e09c8c3SJim Ingham }; 19945e09c8c3SJim Ingham 1995e14dc268SJim Ingham // CommandObjectBreakpointName 1996b9c1b51eSKate Stone class CommandObjectBreakpointName : public CommandObjectMultiword { 19975e09c8c3SJim Ingham public: 19987428a18cSKate Stone CommandObjectBreakpointName(CommandInterpreter &interpreter) 1999b9c1b51eSKate Stone : CommandObjectMultiword( 2000b9c1b51eSKate Stone interpreter, "name", "Commands to manage name tags for breakpoints", 2001b9c1b51eSKate Stone "breakpoint name <subcommand> [<command-options>]") { 2002b9c1b51eSKate Stone CommandObjectSP add_command_object( 2003b9c1b51eSKate Stone new CommandObjectBreakpointNameAdd(interpreter)); 2004b9c1b51eSKate Stone CommandObjectSP delete_command_object( 2005b9c1b51eSKate Stone new CommandObjectBreakpointNameDelete(interpreter)); 2006b9c1b51eSKate Stone CommandObjectSP list_command_object( 2007b9c1b51eSKate Stone new CommandObjectBreakpointNameList(interpreter)); 2008b842f2ecSJim Ingham CommandObjectSP configure_command_object( 2009b842f2ecSJim Ingham new CommandObjectBreakpointNameConfigure(interpreter)); 20105e09c8c3SJim Ingham 20115e09c8c3SJim Ingham LoadSubCommand("add", add_command_object); 20125e09c8c3SJim Ingham LoadSubCommand("delete", delete_command_object); 20135e09c8c3SJim Ingham LoadSubCommand("list", list_command_object); 2014b842f2ecSJim Ingham LoadSubCommand("configure", configure_command_object); 20155e09c8c3SJim Ingham } 20165e09c8c3SJim Ingham 20179e85e5a8SEugene Zelenko ~CommandObjectBreakpointName() override = default; 20185e09c8c3SJim Ingham }; 20195e09c8c3SJim Ingham 2020e14dc268SJim Ingham // CommandObjectBreakpointRead 20213acdf385SJim Ingham #pragma mark Read::CommandOptions 2022f94668e3SRaphael Isemann #define LLDB_OPTIONS_breakpoint_read 2023f94668e3SRaphael Isemann #include "CommandOptions.inc" 20241f0f5b5bSZachary Turner 20251f0f5b5bSZachary Turner #pragma mark Read 2026e14dc268SJim Ingham 2027e14dc268SJim Ingham class CommandObjectBreakpointRead : public CommandObjectParsed { 2028e14dc268SJim Ingham public: 2029e14dc268SJim Ingham CommandObjectBreakpointRead(CommandInterpreter &interpreter) 2030e14dc268SJim Ingham : CommandObjectParsed(interpreter, "breakpoint read", 2031e14dc268SJim Ingham "Read and set the breakpoints previously saved to " 2032e14dc268SJim Ingham "a file with \"breakpoint write\". ", 2033e14dc268SJim Ingham nullptr), 2034e14dc268SJim Ingham m_options() { 2035e14dc268SJim Ingham CommandArgumentEntry arg; 2036e14dc268SJim Ingham CommandObject::AddIDsArgumentData(arg, eArgTypeBreakpointID, 2037e14dc268SJim Ingham eArgTypeBreakpointIDRange); 2038e14dc268SJim Ingham // Add the entry for the first argument for this command to the object's 2039e14dc268SJim Ingham // arguments vector. 2040e14dc268SJim Ingham m_arguments.push_back(arg); 2041e14dc268SJim Ingham } 2042e14dc268SJim Ingham 2043e14dc268SJim Ingham ~CommandObjectBreakpointRead() override = default; 2044e14dc268SJim Ingham 2045e14dc268SJim Ingham Options *GetOptions() override { return &m_options; } 2046e14dc268SJim Ingham 2047e14dc268SJim Ingham class CommandOptions : public Options { 2048e14dc268SJim Ingham public: 2049e14dc268SJim Ingham CommandOptions() : Options() {} 2050e14dc268SJim Ingham 2051e14dc268SJim Ingham ~CommandOptions() override = default; 2052e14dc268SJim Ingham 205397206d57SZachary Turner Status SetOptionValue(uint32_t option_idx, llvm::StringRef option_arg, 2054e14dc268SJim Ingham ExecutionContext *execution_context) override { 205597206d57SZachary Turner Status error; 2056e14dc268SJim Ingham const int short_option = m_getopt_table[option_idx].val; 2057e14dc268SJim Ingham 2058e14dc268SJim Ingham switch (short_option) { 2059e14dc268SJim Ingham case 'f': 2060e14dc268SJim Ingham m_filename.assign(option_arg); 2061e14dc268SJim Ingham break; 20623acdf385SJim Ingham case 'N': { 206397206d57SZachary Turner Status name_error; 20643acdf385SJim Ingham if (!BreakpointID::StringIsBreakpointName(llvm::StringRef(option_arg), 20653acdf385SJim Ingham name_error)) { 20663acdf385SJim Ingham error.SetErrorStringWithFormat("Invalid breakpoint name: %s", 20673acdf385SJim Ingham name_error.AsCString()); 20683acdf385SJim Ingham } 20693acdf385SJim Ingham m_names.push_back(option_arg); 20703acdf385SJim Ingham break; 20713acdf385SJim Ingham } 2072e14dc268SJim Ingham default: 207336162014SRaphael Isemann llvm_unreachable("Unimplemented option"); 2074e14dc268SJim Ingham } 2075e14dc268SJim Ingham 2076e14dc268SJim Ingham return error; 2077e14dc268SJim Ingham } 2078e14dc268SJim Ingham 2079e14dc268SJim Ingham void OptionParsingStarting(ExecutionContext *execution_context) override { 2080e14dc268SJim Ingham m_filename.clear(); 20813acdf385SJim Ingham m_names.clear(); 2082e14dc268SJim Ingham } 2083e14dc268SJim Ingham 20841f0f5b5bSZachary Turner llvm::ArrayRef<OptionDefinition> GetDefinitions() override { 208570602439SZachary Turner return llvm::makeArrayRef(g_breakpoint_read_options); 20861f0f5b5bSZachary Turner } 2087e14dc268SJim Ingham 2088e14dc268SJim Ingham // Instance variables to hold the values for command options. 2089e14dc268SJim Ingham 2090e14dc268SJim Ingham std::string m_filename; 20913acdf385SJim Ingham std::vector<std::string> m_names; 2092e14dc268SJim Ingham }; 2093e14dc268SJim Ingham 2094e14dc268SJim Ingham protected: 2095e14dc268SJim Ingham bool DoExecute(Args &command, CommandReturnObject &result) override { 2096cb2380c9SRaphael Isemann Target &target = GetSelectedOrDummyTarget(); 2097e14dc268SJim Ingham 20983acdf385SJim Ingham std::unique_lock<std::recursive_mutex> lock; 2099cb2380c9SRaphael Isemann target.GetBreakpointList().GetListMutex(lock); 21003acdf385SJim Ingham 21018f3be7a3SJonas Devlieghere FileSpec input_spec(m_options.m_filename); 21028f3be7a3SJonas Devlieghere FileSystem::Instance().Resolve(input_spec); 210301f16664SJim Ingham BreakpointIDList new_bps; 2104cb2380c9SRaphael Isemann Status error = target.CreateBreakpointsFromFile(input_spec, 2105cb2380c9SRaphael Isemann m_options.m_names, new_bps); 2106e14dc268SJim Ingham 2107e14dc268SJim Ingham if (!error.Success()) { 210801f16664SJim Ingham result.AppendError(error.AsCString()); 2109e14dc268SJim Ingham result.SetStatus(eReturnStatusFailed); 211001f16664SJim Ingham return false; 2111e14dc268SJim Ingham } 21123acdf385SJim Ingham 21133acdf385SJim Ingham Stream &output_stream = result.GetOutputStream(); 21143acdf385SJim Ingham 21153acdf385SJim Ingham size_t num_breakpoints = new_bps.GetSize(); 21163acdf385SJim Ingham if (num_breakpoints == 0) { 21173acdf385SJim Ingham result.AppendMessage("No breakpoints added."); 21183acdf385SJim Ingham } else { 21193acdf385SJim Ingham // No breakpoint selected; show info about all currently set breakpoints. 21203acdf385SJim Ingham result.AppendMessage("New breakpoints:"); 21213acdf385SJim Ingham for (size_t i = 0; i < num_breakpoints; ++i) { 21223acdf385SJim Ingham BreakpointID bp_id = new_bps.GetBreakpointIDAtIndex(i); 2123cb2380c9SRaphael Isemann Breakpoint *bp = target.GetBreakpointList() 21243acdf385SJim Ingham .FindBreakpointByID(bp_id.GetBreakpointID()) 21253acdf385SJim Ingham .get(); 21263acdf385SJim Ingham if (bp) 21273acdf385SJim Ingham bp->GetDescription(&output_stream, lldb::eDescriptionLevelInitial, 21283acdf385SJim Ingham false); 21293acdf385SJim Ingham } 21303acdf385SJim Ingham } 2131e14dc268SJim Ingham return result.Succeeded(); 2132e14dc268SJim Ingham } 2133e14dc268SJim Ingham 2134e14dc268SJim Ingham private: 2135e14dc268SJim Ingham CommandOptions m_options; 2136e14dc268SJim Ingham }; 2137e14dc268SJim Ingham 2138e14dc268SJim Ingham // CommandObjectBreakpointWrite 21391f0f5b5bSZachary Turner #pragma mark Write::CommandOptions 2140f94668e3SRaphael Isemann #define LLDB_OPTIONS_breakpoint_write 2141f94668e3SRaphael Isemann #include "CommandOptions.inc" 21421f0f5b5bSZachary Turner 21431f0f5b5bSZachary Turner #pragma mark Write 2144e14dc268SJim Ingham class CommandObjectBreakpointWrite : public CommandObjectParsed { 2145e14dc268SJim Ingham public: 2146e14dc268SJim Ingham CommandObjectBreakpointWrite(CommandInterpreter &interpreter) 2147e14dc268SJim Ingham : CommandObjectParsed(interpreter, "breakpoint write", 2148e14dc268SJim Ingham "Write the breakpoints listed to a file that can " 2149e14dc268SJim Ingham "be read in with \"breakpoint read\". " 2150e14dc268SJim Ingham "If given no arguments, writes all breakpoints.", 2151e14dc268SJim Ingham nullptr), 2152e14dc268SJim Ingham m_options() { 2153e14dc268SJim Ingham CommandArgumentEntry arg; 2154e14dc268SJim Ingham CommandObject::AddIDsArgumentData(arg, eArgTypeBreakpointID, 2155e14dc268SJim Ingham eArgTypeBreakpointIDRange); 2156e14dc268SJim Ingham // Add the entry for the first argument for this command to the object's 2157e14dc268SJim Ingham // arguments vector. 2158e14dc268SJim Ingham m_arguments.push_back(arg); 2159e14dc268SJim Ingham } 2160e14dc268SJim Ingham 2161e14dc268SJim Ingham ~CommandObjectBreakpointWrite() override = default; 2162e14dc268SJim Ingham 2163e14dc268SJim Ingham Options *GetOptions() override { return &m_options; } 2164e14dc268SJim Ingham 2165e14dc268SJim Ingham class CommandOptions : public Options { 2166e14dc268SJim Ingham public: 2167e14dc268SJim Ingham CommandOptions() : Options() {} 2168e14dc268SJim Ingham 2169e14dc268SJim Ingham ~CommandOptions() override = default; 2170e14dc268SJim Ingham 217197206d57SZachary Turner Status SetOptionValue(uint32_t option_idx, llvm::StringRef option_arg, 2172e14dc268SJim Ingham ExecutionContext *execution_context) override { 217397206d57SZachary Turner Status error; 2174e14dc268SJim Ingham const int short_option = m_getopt_table[option_idx].val; 2175e14dc268SJim Ingham 2176e14dc268SJim Ingham switch (short_option) { 2177e14dc268SJim Ingham case 'f': 2178e14dc268SJim Ingham m_filename.assign(option_arg); 2179e14dc268SJim Ingham break; 21802d3628e1SJim Ingham case 'a': 21812d3628e1SJim Ingham m_append = true; 21822d3628e1SJim Ingham break; 2183e14dc268SJim Ingham default: 218436162014SRaphael Isemann llvm_unreachable("Unimplemented option"); 2185e14dc268SJim Ingham } 2186e14dc268SJim Ingham 2187e14dc268SJim Ingham return error; 2188e14dc268SJim Ingham } 2189e14dc268SJim Ingham 2190e14dc268SJim Ingham void OptionParsingStarting(ExecutionContext *execution_context) override { 2191e14dc268SJim Ingham m_filename.clear(); 21922d3628e1SJim Ingham m_append = false; 2193e14dc268SJim Ingham } 2194e14dc268SJim Ingham 21951f0f5b5bSZachary Turner llvm::ArrayRef<OptionDefinition> GetDefinitions() override { 219670602439SZachary Turner return llvm::makeArrayRef(g_breakpoint_write_options); 21971f0f5b5bSZachary Turner } 2198e14dc268SJim Ingham 2199e14dc268SJim Ingham // Instance variables to hold the values for command options. 2200e14dc268SJim Ingham 2201e14dc268SJim Ingham std::string m_filename; 22022d3628e1SJim Ingham bool m_append = false; 2203e14dc268SJim Ingham }; 2204e14dc268SJim Ingham 2205e14dc268SJim Ingham protected: 2206e14dc268SJim Ingham bool DoExecute(Args &command, CommandReturnObject &result) override { 2207cb2380c9SRaphael Isemann Target &target = GetSelectedOrDummyTarget(); 2208e14dc268SJim Ingham 2209e14dc268SJim Ingham std::unique_lock<std::recursive_mutex> lock; 2210cb2380c9SRaphael Isemann target.GetBreakpointList().GetListMutex(lock); 2211e14dc268SJim Ingham 2212e14dc268SJim Ingham BreakpointIDList valid_bp_ids; 221311eb9c64SZachary Turner if (!command.empty()) { 2214e14dc268SJim Ingham CommandObjectMultiwordBreakpoint::VerifyBreakpointIDs( 2215cb2380c9SRaphael Isemann command, &target, result, &valid_bp_ids, 2216b842f2ecSJim Ingham BreakpointName::Permissions::PermissionKinds::listPerm); 2217e14dc268SJim Ingham 221801f16664SJim Ingham if (!result.Succeeded()) { 2219e14dc268SJim Ingham result.SetStatus(eReturnStatusFailed); 2220e14dc268SJim Ingham return false; 2221e14dc268SJim Ingham } 2222e14dc268SJim Ingham } 22238f3be7a3SJonas Devlieghere FileSpec file_spec(m_options.m_filename); 22248f3be7a3SJonas Devlieghere FileSystem::Instance().Resolve(file_spec); 2225cb2380c9SRaphael Isemann Status error = target.SerializeBreakpointsToFile(file_spec, valid_bp_ids, 22268f3be7a3SJonas Devlieghere m_options.m_append); 222701f16664SJim Ingham if (!error.Success()) { 222801f16664SJim Ingham result.AppendErrorWithFormat("error serializing breakpoints: %s.", 222901f16664SJim Ingham error.AsCString()); 223001f16664SJim Ingham result.SetStatus(eReturnStatusFailed); 2231e14dc268SJim Ingham } 2232e14dc268SJim Ingham return result.Succeeded(); 2233e14dc268SJim Ingham } 2234e14dc268SJim Ingham 2235e14dc268SJim Ingham private: 2236e14dc268SJim Ingham CommandOptions m_options; 2237e14dc268SJim Ingham }; 2238e14dc268SJim Ingham 223930fdc8d8SChris Lattner // CommandObjectMultiwordBreakpoint 2240ae1c4cf5SJim Ingham #pragma mark MultiwordBreakpoint 224130fdc8d8SChris Lattner 2242b9c1b51eSKate Stone CommandObjectMultiwordBreakpoint::CommandObjectMultiwordBreakpoint( 2243b9c1b51eSKate Stone CommandInterpreter &interpreter) 2244b9c1b51eSKate Stone : CommandObjectMultiword( 2245b9c1b51eSKate Stone interpreter, "breakpoint", 22467428a18cSKate Stone "Commands for operating on breakpoints (see 'help b' for shorthand.)", 2247b9c1b51eSKate Stone "breakpoint <subcommand> [<command-options>]") { 2248b9c1b51eSKate Stone CommandObjectSP list_command_object( 2249b9c1b51eSKate Stone new CommandObjectBreakpointList(interpreter)); 2250b9c1b51eSKate Stone CommandObjectSP enable_command_object( 2251b9c1b51eSKate Stone new CommandObjectBreakpointEnable(interpreter)); 2252b9c1b51eSKate Stone CommandObjectSP disable_command_object( 2253b9c1b51eSKate Stone new CommandObjectBreakpointDisable(interpreter)); 2254b9c1b51eSKate Stone CommandObjectSP clear_command_object( 2255b9c1b51eSKate Stone new CommandObjectBreakpointClear(interpreter)); 2256b9c1b51eSKate Stone CommandObjectSP delete_command_object( 2257b9c1b51eSKate Stone new CommandObjectBreakpointDelete(interpreter)); 2258b9c1b51eSKate Stone CommandObjectSP set_command_object( 2259b9c1b51eSKate Stone new CommandObjectBreakpointSet(interpreter)); 2260b9c1b51eSKate Stone CommandObjectSP command_command_object( 2261b9c1b51eSKate Stone new CommandObjectBreakpointCommand(interpreter)); 2262b9c1b51eSKate Stone CommandObjectSP modify_command_object( 2263b9c1b51eSKate Stone new CommandObjectBreakpointModify(interpreter)); 2264b9c1b51eSKate Stone CommandObjectSP name_command_object( 2265b9c1b51eSKate Stone new CommandObjectBreakpointName(interpreter)); 2266e14dc268SJim Ingham CommandObjectSP write_command_object( 2267e14dc268SJim Ingham new CommandObjectBreakpointWrite(interpreter)); 2268e14dc268SJim Ingham CommandObjectSP read_command_object( 2269e14dc268SJim Ingham new CommandObjectBreakpointRead(interpreter)); 227030fdc8d8SChris Lattner 2271b7234e40SJohnny Chen list_command_object->SetCommandName("breakpoint list"); 227230fdc8d8SChris Lattner enable_command_object->SetCommandName("breakpoint enable"); 227330fdc8d8SChris Lattner disable_command_object->SetCommandName("breakpoint disable"); 2274b7234e40SJohnny Chen clear_command_object->SetCommandName("breakpoint clear"); 2275b7234e40SJohnny Chen delete_command_object->SetCommandName("breakpoint delete"); 2276ae1c4cf5SJim Ingham set_command_object->SetCommandName("breakpoint set"); 2277b7234e40SJohnny Chen command_command_object->SetCommandName("breakpoint command"); 2278b7234e40SJohnny Chen modify_command_object->SetCommandName("breakpoint modify"); 22795e09c8c3SJim Ingham name_command_object->SetCommandName("breakpoint name"); 2280e14dc268SJim Ingham write_command_object->SetCommandName("breakpoint write"); 2281e14dc268SJim Ingham read_command_object->SetCommandName("breakpoint read"); 228230fdc8d8SChris Lattner 228323f59509SGreg Clayton LoadSubCommand("list", list_command_object); 228423f59509SGreg Clayton LoadSubCommand("enable", enable_command_object); 228523f59509SGreg Clayton LoadSubCommand("disable", disable_command_object); 228623f59509SGreg Clayton LoadSubCommand("clear", clear_command_object); 228723f59509SGreg Clayton LoadSubCommand("delete", delete_command_object); 228823f59509SGreg Clayton LoadSubCommand("set", set_command_object); 228923f59509SGreg Clayton LoadSubCommand("command", command_command_object); 229023f59509SGreg Clayton LoadSubCommand("modify", modify_command_object); 22915e09c8c3SJim Ingham LoadSubCommand("name", name_command_object); 2292e14dc268SJim Ingham LoadSubCommand("write", write_command_object); 2293e14dc268SJim Ingham LoadSubCommand("read", read_command_object); 229430fdc8d8SChris Lattner } 229530fdc8d8SChris Lattner 22969e85e5a8SEugene Zelenko CommandObjectMultiwordBreakpoint::~CommandObjectMultiwordBreakpoint() = default; 229730fdc8d8SChris Lattner 2298b9c1b51eSKate Stone void CommandObjectMultiwordBreakpoint::VerifyIDs(Args &args, Target *target, 22995e09c8c3SJim Ingham bool allow_locations, 23005e09c8c3SJim Ingham CommandReturnObject &result, 2301b842f2ecSJim Ingham BreakpointIDList *valid_ids, 2302b842f2ecSJim Ingham BreakpointName::Permissions 2303b842f2ecSJim Ingham ::PermissionKinds 2304b842f2ecSJim Ingham purpose) { 230530fdc8d8SChris Lattner // args can be strings representing 1). integers (for breakpoint ids) 2306b9c1b51eSKate Stone // 2). the full breakpoint & location 2307b9c1b51eSKate Stone // canonical representation 2308b9c1b51eSKate Stone // 3). the word "to" or a hyphen, 2309b9c1b51eSKate Stone // representing a range (in which case there 2310b9c1b51eSKate Stone // had *better* be an entry both before & 2311b9c1b51eSKate Stone // after of one of the first two types. 23125e09c8c3SJim Ingham // 4). A breakpoint name 2313b9c1b51eSKate Stone // If args is empty, we will use the last created breakpoint (if there is 2314b9c1b51eSKate Stone // one.) 231530fdc8d8SChris Lattner 231630fdc8d8SChris Lattner Args temp_args; 231730fdc8d8SChris Lattner 231811eb9c64SZachary Turner if (args.empty()) { 2319b9c1b51eSKate Stone if (target->GetLastCreatedBreakpoint()) { 2320b9c1b51eSKate Stone valid_ids->AddBreakpointID(BreakpointID( 2321b9c1b51eSKate Stone target->GetLastCreatedBreakpoint()->GetID(), LLDB_INVALID_BREAK_ID)); 232236f3b369SJim Ingham result.SetStatus(eReturnStatusSuccessFinishNoResult); 2323b9c1b51eSKate Stone } else { 2324b9c1b51eSKate Stone result.AppendError( 2325b9c1b51eSKate Stone "No breakpoint specified and no last created breakpoint."); 232636f3b369SJim Ingham result.SetStatus(eReturnStatusFailed); 232736f3b369SJim Ingham } 232836f3b369SJim Ingham return; 232936f3b369SJim Ingham } 233036f3b369SJim Ingham 2331b9c1b51eSKate Stone // Create a new Args variable to use; copy any non-breakpoint-id-ranges stuff 233205097246SAdrian Prantl // directly from the old ARGS to the new TEMP_ARGS. Do not copy breakpoint 233305097246SAdrian Prantl // id range strings over; instead generate a list of strings for all the 233405097246SAdrian Prantl // breakpoint ids in the range, and shove all of those breakpoint id strings 233505097246SAdrian Prantl // into TEMP_ARGS. 233630fdc8d8SChris Lattner 2337b9c1b51eSKate Stone BreakpointIDList::FindAndReplaceIDRanges(args, target, allow_locations, 2338b842f2ecSJim Ingham purpose, result, temp_args); 233930fdc8d8SChris Lattner 2340b9c1b51eSKate Stone // NOW, convert the list of breakpoint id strings in TEMP_ARGS into an actual 2341b9c1b51eSKate Stone // BreakpointIDList: 234230fdc8d8SChris Lattner 234316662f3cSPavel Labath valid_ids->InsertStringArray(temp_args.GetArgumentArrayRef(), result); 234430fdc8d8SChris Lattner 234505097246SAdrian Prantl // At this point, all of the breakpoint ids that the user passed in have 234605097246SAdrian Prantl // been converted to breakpoint IDs and put into valid_ids. 234730fdc8d8SChris Lattner 2348b9c1b51eSKate Stone if (result.Succeeded()) { 2349b9c1b51eSKate Stone // Now that we've converted everything from args into a list of breakpoint 235005097246SAdrian Prantl // ids, go through our tentative list of breakpoint id's and verify that 235105097246SAdrian Prantl // they correspond to valid/currently set breakpoints. 235230fdc8d8SChris Lattner 2353c982c768SGreg Clayton const size_t count = valid_ids->GetSize(); 2354b9c1b51eSKate Stone for (size_t i = 0; i < count; ++i) { 235530fdc8d8SChris Lattner BreakpointID cur_bp_id = valid_ids->GetBreakpointIDAtIndex(i); 2356b9c1b51eSKate Stone Breakpoint *breakpoint = 2357b9c1b51eSKate Stone target->GetBreakpointByID(cur_bp_id.GetBreakpointID()).get(); 2358b9c1b51eSKate Stone if (breakpoint != nullptr) { 2359c7bece56SGreg Clayton const size_t num_locations = breakpoint->GetNumLocations(); 2360b9c1b51eSKate Stone if (static_cast<size_t>(cur_bp_id.GetLocationID()) > num_locations) { 236130fdc8d8SChris Lattner StreamString id_str; 2362b9c1b51eSKate Stone BreakpointID::GetCanonicalReference( 2363b9c1b51eSKate Stone &id_str, cur_bp_id.GetBreakpointID(), cur_bp_id.GetLocationID()); 2364c982c768SGreg Clayton i = valid_ids->GetSize() + 1; 2365b9c1b51eSKate Stone result.AppendErrorWithFormat( 2366b9c1b51eSKate Stone "'%s' is not a currently valid breakpoint/location id.\n", 236730fdc8d8SChris Lattner id_str.GetData()); 236830fdc8d8SChris Lattner result.SetStatus(eReturnStatusFailed); 236930fdc8d8SChris Lattner } 2370b9c1b51eSKate Stone } else { 2371c982c768SGreg Clayton i = valid_ids->GetSize() + 1; 2372b9c1b51eSKate Stone result.AppendErrorWithFormat( 2373b9c1b51eSKate Stone "'%d' is not a currently valid breakpoint ID.\n", 23747428a18cSKate Stone cur_bp_id.GetBreakpointID()); 237530fdc8d8SChris Lattner result.SetStatus(eReturnStatusFailed); 237630fdc8d8SChris Lattner } 237730fdc8d8SChris Lattner } 237830fdc8d8SChris Lattner } 237930fdc8d8SChris Lattner } 2380