130fdc8d8SChris Lattner //===-- CommandObjectBreakpoint.cpp -----------------------------*- C++ -*-===// 230fdc8d8SChris Lattner // 32946cd70SChandler Carruth // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. 42946cd70SChandler Carruth // See https://llvm.org/LICENSE.txt for license information. 52946cd70SChandler Carruth // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception 630fdc8d8SChris Lattner // 730fdc8d8SChris Lattner //===----------------------------------------------------------------------===// 830fdc8d8SChris Lattner 99e85e5a8SEugene Zelenko #include "CommandObjectBreakpoint.h" 109e85e5a8SEugene Zelenko #include "CommandObjectBreakpointCommand.h" 1130fdc8d8SChris Lattner #include "lldb/Breakpoint/Breakpoint.h" 1230fdc8d8SChris Lattner #include "lldb/Breakpoint/BreakpointIDList.h" 1330fdc8d8SChris Lattner #include "lldb/Breakpoint/BreakpointLocation.h" 143eb2b44dSZachary Turner #include "lldb/Host/OptionParser.h" 15b9c1b51eSKate Stone #include "lldb/Interpreter/CommandCompletions.h" 16b9c1b51eSKate Stone #include "lldb/Interpreter/CommandInterpreter.h" 17b9c1b51eSKate Stone #include "lldb/Interpreter/CommandReturnObject.h" 1847cbf4a0SPavel Labath #include "lldb/Interpreter/OptionArgParser.h" 19943a2481SJim Ingham #include "lldb/Interpreter/OptionGroupPythonClassWithDict.h" 2032abc6edSZachary Turner #include "lldb/Interpreter/OptionValueBoolean.h" 215e09c8c3SJim Ingham #include "lldb/Interpreter/OptionValueString.h" 225e09c8c3SJim Ingham #include "lldb/Interpreter/OptionValueUInt64.h" 23b9c1b51eSKate Stone #include "lldb/Interpreter/Options.h" 240e0984eeSJim Ingham #include "lldb/Target/Language.h" 25b57e4a1bSJason Molenda #include "lldb/Target/StackFrame.h" 26b9c1b51eSKate Stone #include "lldb/Target/Target.h" 271b54c88cSJim Ingham #include "lldb/Target/Thread.h" 281b54c88cSJim Ingham #include "lldb/Target/ThreadSpec.h" 29bf9a7730SZachary Turner #include "lldb/Utility/RegularExpression.h" 30bf9a7730SZachary Turner #include "lldb/Utility/StreamString.h" 3130fdc8d8SChris Lattner 32796ac80bSJonas Devlieghere #include <memory> 33796ac80bSJonas Devlieghere #include <vector> 34796ac80bSJonas Devlieghere 3530fdc8d8SChris Lattner using namespace lldb; 3630fdc8d8SChris Lattner using namespace lldb_private; 3730fdc8d8SChris Lattner 38b9c1b51eSKate Stone static void AddBreakpointDescription(Stream *s, Breakpoint *bp, 39b9c1b51eSKate Stone lldb::DescriptionLevel level) { 4030fdc8d8SChris Lattner s->IndentMore(); 4130fdc8d8SChris Lattner bp->GetDescription(s, level, true); 4230fdc8d8SChris Lattner s->IndentLess(); 4330fdc8d8SChris Lattner s->EOL(); 4430fdc8d8SChris Lattner } 4530fdc8d8SChris Lattner 46b842f2ecSJim Ingham // Modifiable Breakpoint Options 47b842f2ecSJim Ingham #pragma mark Modify::CommandOptions 48f94668e3SRaphael Isemann #define LLDB_OPTIONS_breakpoint_modify 49f94668e3SRaphael Isemann #include "CommandOptions.inc" 50bd68a052SRaphael Isemann 51b842f2ecSJim Ingham class lldb_private::BreakpointOptionGroup : public OptionGroup 52b842f2ecSJim Ingham { 53b842f2ecSJim Ingham public: 54b842f2ecSJim Ingham BreakpointOptionGroup() : 55b842f2ecSJim Ingham OptionGroup(), 56b842f2ecSJim Ingham m_bp_opts(false) {} 57b842f2ecSJim Ingham 58b842f2ecSJim Ingham ~BreakpointOptionGroup() override = default; 59b842f2ecSJim Ingham 60b842f2ecSJim Ingham llvm::ArrayRef<OptionDefinition> GetDefinitions() override { 61b842f2ecSJim Ingham return llvm::makeArrayRef(g_breakpoint_modify_options); 62b842f2ecSJim Ingham } 63b842f2ecSJim Ingham 64b842f2ecSJim Ingham Status SetOptionValue(uint32_t option_idx, llvm::StringRef option_arg, 65b842f2ecSJim Ingham ExecutionContext *execution_context) override { 66b842f2ecSJim Ingham Status error; 67b842f2ecSJim Ingham const int short_option = g_breakpoint_modify_options[option_idx].short_option; 68b842f2ecSJim Ingham 69b842f2ecSJim Ingham switch (short_option) { 70b842f2ecSJim Ingham case 'c': 7105097246SAdrian Prantl // Normally an empty breakpoint condition marks is as unset. But we need 7205097246SAdrian Prantl // to say it was passed in. 73b842f2ecSJim Ingham m_bp_opts.SetCondition(option_arg.str().c_str()); 74b842f2ecSJim Ingham m_bp_opts.m_set_flags.Set(BreakpointOptions::eCondition); 75b842f2ecSJim Ingham break; 76b842f2ecSJim Ingham case 'C': 77b842f2ecSJim Ingham m_commands.push_back(option_arg); 78b842f2ecSJim Ingham break; 79b842f2ecSJim Ingham case 'd': 80b842f2ecSJim Ingham m_bp_opts.SetEnabled(false); 81b842f2ecSJim Ingham break; 82b842f2ecSJim Ingham case 'e': 83b842f2ecSJim Ingham m_bp_opts.SetEnabled(true); 84b842f2ecSJim Ingham break; 85b842f2ecSJim Ingham case 'G': { 86b842f2ecSJim Ingham bool value, success; 8747cbf4a0SPavel Labath value = OptionArgParser::ToBoolean(option_arg, false, &success); 88b842f2ecSJim Ingham if (success) { 89b842f2ecSJim Ingham m_bp_opts.SetAutoContinue(value); 90b842f2ecSJim Ingham } else 91b842f2ecSJim Ingham error.SetErrorStringWithFormat( 92b842f2ecSJim Ingham "invalid boolean value '%s' passed for -G option", 93b842f2ecSJim Ingham option_arg.str().c_str()); 94b842f2ecSJim Ingham } 95b842f2ecSJim Ingham break; 96b842f2ecSJim Ingham case 'i': 97b842f2ecSJim Ingham { 98b842f2ecSJim Ingham uint32_t ignore_count; 99b842f2ecSJim Ingham if (option_arg.getAsInteger(0, ignore_count)) 100b842f2ecSJim Ingham error.SetErrorStringWithFormat("invalid ignore count '%s'", 101b842f2ecSJim Ingham option_arg.str().c_str()); 102b842f2ecSJim Ingham else 103b842f2ecSJim Ingham m_bp_opts.SetIgnoreCount(ignore_count); 104b842f2ecSJim Ingham } 105b842f2ecSJim Ingham break; 106b842f2ecSJim Ingham case 'o': { 107b842f2ecSJim Ingham bool value, success; 10847cbf4a0SPavel Labath value = OptionArgParser::ToBoolean(option_arg, false, &success); 109b842f2ecSJim Ingham if (success) { 110b842f2ecSJim Ingham m_bp_opts.SetOneShot(value); 111b842f2ecSJim Ingham } else 112b842f2ecSJim Ingham error.SetErrorStringWithFormat( 113b842f2ecSJim Ingham "invalid boolean value '%s' passed for -o option", 114b842f2ecSJim Ingham option_arg.str().c_str()); 115b842f2ecSJim Ingham } break; 116b842f2ecSJim Ingham case 't': 117b842f2ecSJim Ingham { 118b842f2ecSJim Ingham lldb::tid_t thread_id = LLDB_INVALID_THREAD_ID; 119b842f2ecSJim Ingham if (option_arg[0] != '\0') { 120b842f2ecSJim Ingham if (option_arg.getAsInteger(0, thread_id)) 121b842f2ecSJim Ingham error.SetErrorStringWithFormat("invalid thread id string '%s'", 122b842f2ecSJim Ingham option_arg.str().c_str()); 123b842f2ecSJim Ingham } 124b842f2ecSJim Ingham m_bp_opts.SetThreadID(thread_id); 125b842f2ecSJim Ingham } 126b842f2ecSJim Ingham break; 127b842f2ecSJim Ingham case 'T': 128b842f2ecSJim Ingham m_bp_opts.GetThreadSpec()->SetName(option_arg.str().c_str()); 129b842f2ecSJim Ingham break; 130b842f2ecSJim Ingham case 'q': 131b842f2ecSJim Ingham m_bp_opts.GetThreadSpec()->SetQueueName(option_arg.str().c_str()); 132b842f2ecSJim Ingham break; 133b842f2ecSJim Ingham case 'x': 134b842f2ecSJim Ingham { 135b842f2ecSJim Ingham uint32_t thread_index = UINT32_MAX; 136b842f2ecSJim Ingham if (option_arg[0] != '\n') { 137b842f2ecSJim Ingham if (option_arg.getAsInteger(0, thread_index)) 138b842f2ecSJim Ingham error.SetErrorStringWithFormat("invalid thread index string '%s'", 139b842f2ecSJim Ingham option_arg.str().c_str()); 140b842f2ecSJim Ingham } 141b842f2ecSJim Ingham m_bp_opts.GetThreadSpec()->SetIndex(thread_index); 142b842f2ecSJim Ingham } 143b842f2ecSJim Ingham break; 144b842f2ecSJim Ingham default: 14536162014SRaphael Isemann llvm_unreachable("Unimplemented option"); 146b842f2ecSJim Ingham } 147b842f2ecSJim Ingham 148b842f2ecSJim Ingham return error; 149b842f2ecSJim Ingham } 150b842f2ecSJim Ingham 151b842f2ecSJim Ingham void OptionParsingStarting(ExecutionContext *execution_context) override { 152b842f2ecSJim Ingham m_bp_opts.Clear(); 153b842f2ecSJim Ingham m_commands.clear(); 154b842f2ecSJim Ingham } 155b842f2ecSJim Ingham 156b842f2ecSJim Ingham Status OptionParsingFinished(ExecutionContext *execution_context) override { 157b842f2ecSJim Ingham if (!m_commands.empty()) 158b842f2ecSJim Ingham { 159b842f2ecSJim Ingham if (!m_commands.empty()) 160b842f2ecSJim Ingham { 161a8f3ae7cSJonas Devlieghere auto cmd_data = std::make_unique<BreakpointOptions::CommandData>(); 162b842f2ecSJim Ingham 163b842f2ecSJim Ingham for (std::string &str : m_commands) 164b842f2ecSJim Ingham cmd_data->user_source.AppendString(str); 165b842f2ecSJim Ingham 166b842f2ecSJim Ingham cmd_data->stop_on_error = true; 167b842f2ecSJim Ingham m_bp_opts.SetCommandDataCallback(cmd_data); 168b842f2ecSJim Ingham } 169b842f2ecSJim Ingham } 170b842f2ecSJim Ingham return Status(); 171b842f2ecSJim Ingham } 172b842f2ecSJim Ingham 173b842f2ecSJim Ingham const BreakpointOptions &GetBreakpointOptions() 174b842f2ecSJim Ingham { 175b842f2ecSJim Ingham return m_bp_opts; 176b842f2ecSJim Ingham } 177b842f2ecSJim Ingham 178b842f2ecSJim Ingham std::vector<std::string> m_commands; 179b842f2ecSJim Ingham BreakpointOptions m_bp_opts; 180b842f2ecSJim Ingham 181b842f2ecSJim Ingham }; 182bd68a052SRaphael Isemann 183f94668e3SRaphael Isemann #define LLDB_OPTIONS_breakpoint_dummy 184f94668e3SRaphael Isemann #include "CommandOptions.inc" 185b842f2ecSJim Ingham 186b842f2ecSJim Ingham class BreakpointDummyOptionGroup : public OptionGroup 187b842f2ecSJim Ingham { 188b842f2ecSJim Ingham public: 189b842f2ecSJim Ingham BreakpointDummyOptionGroup() : 190b842f2ecSJim Ingham OptionGroup() {} 191b842f2ecSJim Ingham 192b842f2ecSJim Ingham ~BreakpointDummyOptionGroup() override = default; 193b842f2ecSJim Ingham 194b842f2ecSJim Ingham llvm::ArrayRef<OptionDefinition> GetDefinitions() override { 195b842f2ecSJim Ingham return llvm::makeArrayRef(g_breakpoint_dummy_options); 196b842f2ecSJim Ingham } 197b842f2ecSJim Ingham 198b842f2ecSJim Ingham Status SetOptionValue(uint32_t option_idx, llvm::StringRef option_arg, 199b842f2ecSJim Ingham ExecutionContext *execution_context) override { 200b842f2ecSJim Ingham Status error; 201b842f2ecSJim Ingham const int short_option = g_breakpoint_modify_options[option_idx].short_option; 202b842f2ecSJim Ingham 203b842f2ecSJim Ingham switch (short_option) { 204b842f2ecSJim Ingham case 'D': 205b842f2ecSJim Ingham m_use_dummy = true; 206b842f2ecSJim Ingham break; 207b842f2ecSJim Ingham default: 20836162014SRaphael Isemann llvm_unreachable("Unimplemented option"); 209b842f2ecSJim Ingham } 210b842f2ecSJim Ingham 211b842f2ecSJim Ingham return error; 212b842f2ecSJim Ingham } 213b842f2ecSJim Ingham 214b842f2ecSJim Ingham void OptionParsingStarting(ExecutionContext *execution_context) override { 215b842f2ecSJim Ingham m_use_dummy = false; 216b842f2ecSJim Ingham } 217b842f2ecSJim Ingham 218b842f2ecSJim Ingham bool m_use_dummy; 219b842f2ecSJim Ingham 220b842f2ecSJim Ingham }; 221b842f2ecSJim Ingham 222f94668e3SRaphael Isemann #define LLDB_OPTIONS_breakpoint_set 223f94668e3SRaphael Isemann #include "CommandOptions.inc" 2241f0f5b5bSZachary Turner 2255a988416SJim Ingham // CommandObjectBreakpointSet 22630fdc8d8SChris Lattner 227b9c1b51eSKate Stone class CommandObjectBreakpointSet : public CommandObjectParsed { 2285a988416SJim Ingham public: 229efe8e7e3SFangrui Song enum BreakpointSetType { 2305a988416SJim Ingham eSetTypeInvalid, 2315a988416SJim Ingham eSetTypeFileAndLine, 2325a988416SJim Ingham eSetTypeAddress, 2335a988416SJim Ingham eSetTypeFunctionName, 2345a988416SJim Ingham eSetTypeFunctionRegexp, 2355a988416SJim Ingham eSetTypeSourceRegexp, 2363815e702SJim Ingham eSetTypeException, 2373815e702SJim Ingham eSetTypeScripted, 238efe8e7e3SFangrui Song }; 2395a988416SJim Ingham 240b9c1b51eSKate Stone CommandObjectBreakpointSet(CommandInterpreter &interpreter) 241b9c1b51eSKate Stone : CommandObjectParsed( 242b9c1b51eSKate Stone interpreter, "breakpoint set", 2435a988416SJim Ingham "Sets a breakpoint or set of breakpoints in the executable.", 2445a988416SJim Ingham "breakpoint set <cmd-options>"), 245*f6a2086dSSam McCall m_bp_opts(), m_python_class_options("scripted breakpoint", 'P'), 246*f6a2086dSSam McCall m_options() { 247b842f2ecSJim Ingham // We're picking up all the normal options, commands and disable. 248943a2481SJim Ingham m_all_options.Append(&m_python_class_options, LLDB_OPT_SET_1, 249943a2481SJim Ingham LLDB_OPT_SET_11); 250b842f2ecSJim Ingham m_all_options.Append(&m_bp_opts, 251b842f2ecSJim Ingham LLDB_OPT_SET_1 | LLDB_OPT_SET_3 | LLDB_OPT_SET_4, 252b842f2ecSJim Ingham LLDB_OPT_SET_ALL); 253*f6a2086dSSam McCall m_all_options.Append(&m_dummy_options, LLDB_OPT_SET_1, LLDB_OPT_SET_ALL); 254b842f2ecSJim Ingham m_all_options.Append(&m_options); 255b842f2ecSJim Ingham m_all_options.Finalize(); 256b842f2ecSJim Ingham } 2575a988416SJim Ingham 2589e85e5a8SEugene Zelenko ~CommandObjectBreakpointSet() override = default; 2595a988416SJim Ingham 260b842f2ecSJim Ingham Options *GetOptions() override { return &m_all_options; } 2615a988416SJim Ingham 262b842f2ecSJim Ingham class CommandOptions : public OptionGroup { 2635a988416SJim Ingham public: 264b9c1b51eSKate Stone CommandOptions() 265b842f2ecSJim Ingham : OptionGroup(), m_condition(), m_filenames(), m_line_num(0), m_column(0), 266b9c1b51eSKate Stone m_func_names(), m_func_name_type_mask(eFunctionNameTypeNone), 267b9c1b51eSKate Stone m_func_regexp(), m_source_text_regexp(), m_modules(), m_load_addr(), 268b9c1b51eSKate Stone m_catch_bp(false), m_throw_bp(true), m_hardware(false), 269a72b31c7SJim Ingham m_exception_language(eLanguageTypeUnknown), 27023b1decbSDawn Perchik m_language(lldb::eLanguageTypeUnknown), 271b842f2ecSJim Ingham m_skip_prologue(eLazyBoolCalculate), 272b9c1b51eSKate Stone m_all_files(false), m_move_to_nearest_code(eLazyBoolCalculate) {} 27330fdc8d8SChris Lattner 2749e85e5a8SEugene Zelenko ~CommandOptions() override = default; 27587df91b8SJim Ingham 27697206d57SZachary Turner Status SetOptionValue(uint32_t option_idx, llvm::StringRef option_arg, 277b9c1b51eSKate Stone ExecutionContext *execution_context) override { 27897206d57SZachary Turner Status error; 279b842f2ecSJim Ingham const int short_option = g_breakpoint_set_options[option_idx].short_option; 28030fdc8d8SChris Lattner 281b9c1b51eSKate Stone switch (short_option) { 282b9c1b51eSKate Stone case 'a': { 28347cbf4a0SPavel Labath m_load_addr = OptionArgParser::ToAddress(execution_context, option_arg, 284e1cfbc79STodd Fiala LLDB_INVALID_ADDRESS, &error); 285b9c1b51eSKate Stone } break; 28630fdc8d8SChris Lattner 287e732052fSJim Ingham case 'A': 288e732052fSJim Ingham m_all_files = true; 289e732052fSJim Ingham break; 290e732052fSJim Ingham 291ca36cd16SJim Ingham case 'b': 292ca36cd16SJim Ingham m_func_names.push_back(option_arg); 293ca36cd16SJim Ingham m_func_name_type_mask |= eFunctionNameTypeBase; 294ca36cd16SJim Ingham break; 295ca36cd16SJim Ingham 296fe11483bSZachary Turner case 'C': 297fe11483bSZachary Turner if (option_arg.getAsInteger(0, m_column)) 298b9c1b51eSKate Stone error.SetErrorStringWithFormat("invalid column number: %s", 299fe11483bSZachary Turner option_arg.str().c_str()); 30030fdc8d8SChris Lattner break; 3019e85e5a8SEugene Zelenko 302b9c1b51eSKate Stone case 'E': { 303fe11483bSZachary Turner LanguageType language = Language::GetLanguageTypeFromString(option_arg); 304fab10e89SJim Ingham 305b9c1b51eSKate Stone switch (language) { 306fab10e89SJim Ingham case eLanguageTypeC89: 307fab10e89SJim Ingham case eLanguageTypeC: 308fab10e89SJim Ingham case eLanguageTypeC99: 3091d0089faSBruce Mitchener case eLanguageTypeC11: 310a72b31c7SJim Ingham m_exception_language = eLanguageTypeC; 311fab10e89SJim Ingham break; 312fab10e89SJim Ingham case eLanguageTypeC_plus_plus: 3131d0089faSBruce Mitchener case eLanguageTypeC_plus_plus_03: 3141d0089faSBruce Mitchener case eLanguageTypeC_plus_plus_11: 3152ba84a6aSBruce Mitchener case eLanguageTypeC_plus_plus_14: 316a72b31c7SJim Ingham m_exception_language = eLanguageTypeC_plus_plus; 317fab10e89SJim Ingham break; 318fab10e89SJim Ingham case eLanguageTypeObjC: 319a72b31c7SJim Ingham m_exception_language = eLanguageTypeObjC; 320fab10e89SJim Ingham break; 321fab10e89SJim Ingham case eLanguageTypeObjC_plus_plus: 322b9c1b51eSKate Stone error.SetErrorStringWithFormat( 323b9c1b51eSKate Stone "Set exception breakpoints separately for c++ and objective-c"); 324fab10e89SJim Ingham break; 325fab10e89SJim Ingham case eLanguageTypeUnknown: 326b9c1b51eSKate Stone error.SetErrorStringWithFormat( 327b9c1b51eSKate Stone "Unknown language type: '%s' for exception breakpoint", 328fe11483bSZachary Turner option_arg.str().c_str()); 329fab10e89SJim Ingham break; 330fab10e89SJim Ingham default: 331b9c1b51eSKate Stone error.SetErrorStringWithFormat( 332b9c1b51eSKate Stone "Unsupported language type: '%s' for exception breakpoint", 333fe11483bSZachary Turner option_arg.str().c_str()); 334fab10e89SJim Ingham } 335b9c1b51eSKate Stone } break; 336ca36cd16SJim Ingham 337ca36cd16SJim Ingham case 'f': 3388f3be7a3SJonas Devlieghere m_filenames.AppendIfUnique(FileSpec(option_arg)); 339fab10e89SJim Ingham break; 340ca36cd16SJim Ingham 341ca36cd16SJim Ingham case 'F': 342ca36cd16SJim Ingham m_func_names.push_back(option_arg); 343ca36cd16SJim Ingham m_func_name_type_mask |= eFunctionNameTypeFull; 344ca36cd16SJim Ingham break; 345ca36cd16SJim Ingham 346b9c1b51eSKate Stone case 'h': { 347fab10e89SJim Ingham bool success; 34847cbf4a0SPavel Labath m_catch_bp = OptionArgParser::ToBoolean(option_arg, true, &success); 349fab10e89SJim Ingham if (!success) 350b9c1b51eSKate Stone error.SetErrorStringWithFormat( 351fe11483bSZachary Turner "Invalid boolean value for on-catch option: '%s'", 352fe11483bSZachary Turner option_arg.str().c_str()); 353b9c1b51eSKate Stone } break; 354eb023e75SGreg Clayton 355eb023e75SGreg Clayton case 'H': 356eb023e75SGreg Clayton m_hardware = true; 357eb023e75SGreg Clayton break; 358eb023e75SGreg Clayton 359b9c1b51eSKate Stone case 'K': { 360a8558b62SJim Ingham bool success; 361a8558b62SJim Ingham bool value; 36247cbf4a0SPavel Labath value = OptionArgParser::ToBoolean(option_arg, true, &success); 363a8558b62SJim Ingham if (value) 364a8558b62SJim Ingham m_skip_prologue = eLazyBoolYes; 365a8558b62SJim Ingham else 366a8558b62SJim Ingham m_skip_prologue = eLazyBoolNo; 367a8558b62SJim Ingham 368a8558b62SJim Ingham if (!success) 369b9c1b51eSKate Stone error.SetErrorStringWithFormat( 370b9c1b51eSKate Stone "Invalid boolean value for skip prologue option: '%s'", 371fe11483bSZachary Turner option_arg.str().c_str()); 372b9c1b51eSKate Stone } break; 373ca36cd16SJim Ingham 374fe11483bSZachary Turner case 'l': 375fe11483bSZachary Turner if (option_arg.getAsInteger(0, m_line_num)) 376b9c1b51eSKate Stone error.SetErrorStringWithFormat("invalid line number: %s.", 377fe11483bSZachary Turner option_arg.str().c_str()); 378ca36cd16SJim Ingham break; 379055ad9beSIlia K 38023b1decbSDawn Perchik case 'L': 381fe11483bSZachary Turner m_language = Language::GetLanguageTypeFromString(option_arg); 38223b1decbSDawn Perchik if (m_language == eLanguageTypeUnknown) 383b9c1b51eSKate Stone error.SetErrorStringWithFormat( 384fe11483bSZachary Turner "Unknown language type: '%s' for breakpoint", 385fe11483bSZachary Turner option_arg.str().c_str()); 38623b1decbSDawn Perchik break; 38723b1decbSDawn Perchik 388b9c1b51eSKate Stone case 'm': { 389055ad9beSIlia K bool success; 390055ad9beSIlia K bool value; 39147cbf4a0SPavel Labath value = OptionArgParser::ToBoolean(option_arg, true, &success); 392055ad9beSIlia K if (value) 393055ad9beSIlia K m_move_to_nearest_code = eLazyBoolYes; 394055ad9beSIlia K else 395055ad9beSIlia K m_move_to_nearest_code = eLazyBoolNo; 396055ad9beSIlia K 397055ad9beSIlia K if (!success) 398b9c1b51eSKate Stone error.SetErrorStringWithFormat( 399b9c1b51eSKate Stone "Invalid boolean value for move-to-nearest-code option: '%s'", 400fe11483bSZachary Turner option_arg.str().c_str()); 401055ad9beSIlia K break; 402055ad9beSIlia K } 403055ad9beSIlia K 404ca36cd16SJim Ingham case 'M': 405ca36cd16SJim Ingham m_func_names.push_back(option_arg); 406ca36cd16SJim Ingham m_func_name_type_mask |= eFunctionNameTypeMethod; 407ca36cd16SJim Ingham break; 408ca36cd16SJim Ingham 409ca36cd16SJim Ingham case 'n': 410ca36cd16SJim Ingham m_func_names.push_back(option_arg); 411ca36cd16SJim Ingham m_func_name_type_mask |= eFunctionNameTypeAuto; 412ca36cd16SJim Ingham break; 413ca36cd16SJim Ingham 4146fa7681bSZachary Turner case 'N': { 415fe11483bSZachary Turner if (BreakpointID::StringIsBreakpointName(option_arg, error)) 4165e09c8c3SJim Ingham m_breakpoint_names.push_back(option_arg); 417ff9a91eaSJim Ingham else 418ff9a91eaSJim Ingham error.SetErrorStringWithFormat("Invalid breakpoint name: %s", 419fe11483bSZachary Turner option_arg.str().c_str()); 4205e09c8c3SJim Ingham break; 4216fa7681bSZachary Turner } 4225e09c8c3SJim Ingham 423b9c1b51eSKate Stone case 'R': { 4242411167fSJim Ingham lldb::addr_t tmp_offset_addr; 42547cbf4a0SPavel Labath tmp_offset_addr = OptionArgParser::ToAddress(execution_context, 42647cbf4a0SPavel Labath option_arg, 0, &error); 4272411167fSJim Ingham if (error.Success()) 4282411167fSJim Ingham m_offset_addr = tmp_offset_addr; 429b9c1b51eSKate Stone } break; 4302411167fSJim Ingham 431a72b31c7SJim Ingham case 'O': 432fe11483bSZachary Turner m_exception_extra_args.AppendArgument("-O"); 433fe11483bSZachary Turner m_exception_extra_args.AppendArgument(option_arg); 434a72b31c7SJim Ingham break; 435a72b31c7SJim Ingham 436ca36cd16SJim Ingham case 'p': 437ca36cd16SJim Ingham m_source_text_regexp.assign(option_arg); 438ca36cd16SJim Ingham break; 439ca36cd16SJim Ingham 440ca36cd16SJim Ingham case 'r': 441ca36cd16SJim Ingham m_func_regexp.assign(option_arg); 442ca36cd16SJim Ingham break; 443ca36cd16SJim Ingham 444ca36cd16SJim Ingham case 's': 4458f3be7a3SJonas Devlieghere m_modules.AppendIfUnique(FileSpec(option_arg)); 446ca36cd16SJim Ingham break; 447ca36cd16SJim Ingham 448ca36cd16SJim Ingham case 'S': 449ca36cd16SJim Ingham m_func_names.push_back(option_arg); 450ca36cd16SJim Ingham m_func_name_type_mask |= eFunctionNameTypeSelector; 451ca36cd16SJim Ingham break; 452ca36cd16SJim Ingham 453b9c1b51eSKate Stone case 'w': { 454ca36cd16SJim Ingham bool success; 45547cbf4a0SPavel Labath m_throw_bp = OptionArgParser::ToBoolean(option_arg, true, &success); 456ca36cd16SJim Ingham if (!success) 457b9c1b51eSKate Stone error.SetErrorStringWithFormat( 458fe11483bSZachary Turner "Invalid boolean value for on-throw option: '%s'", 459fe11483bSZachary Turner option_arg.str().c_str()); 460b9c1b51eSKate Stone } break; 461ca36cd16SJim Ingham 46276bb8d67SJim Ingham case 'X': 46376bb8d67SJim Ingham m_source_regex_func_names.insert(option_arg); 46476bb8d67SJim Ingham break; 46576bb8d67SJim Ingham 46630fdc8d8SChris Lattner default: 46736162014SRaphael Isemann llvm_unreachable("Unimplemented option"); 46830fdc8d8SChris Lattner } 46930fdc8d8SChris Lattner 47030fdc8d8SChris Lattner return error; 47130fdc8d8SChris Lattner } 4729e85e5a8SEugene Zelenko 473b9c1b51eSKate Stone void OptionParsingStarting(ExecutionContext *execution_context) override { 47487df91b8SJim Ingham m_filenames.Clear(); 47530fdc8d8SChris Lattner m_line_num = 0; 47630fdc8d8SChris Lattner m_column = 0; 477fab10e89SJim Ingham m_func_names.clear(); 4781f746071SGreg Clayton m_func_name_type_mask = eFunctionNameTypeNone; 47930fdc8d8SChris Lattner m_func_regexp.clear(); 4801f746071SGreg Clayton m_source_text_regexp.clear(); 48187df91b8SJim Ingham m_modules.Clear(); 4821f746071SGreg Clayton m_load_addr = LLDB_INVALID_ADDRESS; 4832411167fSJim Ingham m_offset_addr = 0; 484fab10e89SJim Ingham m_catch_bp = false; 485fab10e89SJim Ingham m_throw_bp = true; 486eb023e75SGreg Clayton m_hardware = false; 487a72b31c7SJim Ingham m_exception_language = eLanguageTypeUnknown; 48823b1decbSDawn Perchik m_language = lldb::eLanguageTypeUnknown; 489a8558b62SJim Ingham m_skip_prologue = eLazyBoolCalculate; 4905e09c8c3SJim Ingham m_breakpoint_names.clear(); 491e732052fSJim Ingham m_all_files = false; 492a72b31c7SJim Ingham m_exception_extra_args.Clear(); 493055ad9beSIlia K m_move_to_nearest_code = eLazyBoolCalculate; 49476bb8d67SJim Ingham m_source_regex_func_names.clear(); 4953815e702SJim Ingham m_current_key.clear(); 49630fdc8d8SChris Lattner } 49730fdc8d8SChris Lattner 4981f0f5b5bSZachary Turner llvm::ArrayRef<OptionDefinition> GetDefinitions() override { 49970602439SZachary Turner return llvm::makeArrayRef(g_breakpoint_set_options); 5001f0f5b5bSZachary Turner } 50130fdc8d8SChris Lattner 5025a988416SJim Ingham // Instance variables to hold the values for command options. 503969795f1SJim Ingham 5045a988416SJim Ingham std::string m_condition; 5055a988416SJim Ingham FileSpecList m_filenames; 5065a988416SJim Ingham uint32_t m_line_num; 5075a988416SJim Ingham uint32_t m_column; 5085a988416SJim Ingham std::vector<std::string> m_func_names; 5095e09c8c3SJim Ingham std::vector<std::string> m_breakpoint_names; 510117b1fa1SZachary Turner lldb::FunctionNameType m_func_name_type_mask; 5115a988416SJim Ingham std::string m_func_regexp; 5125a988416SJim Ingham std::string m_source_text_regexp; 5135a988416SJim Ingham FileSpecList m_modules; 5145a988416SJim Ingham lldb::addr_t m_load_addr; 5152411167fSJim Ingham lldb::addr_t m_offset_addr; 5165a988416SJim Ingham bool m_catch_bp; 5175a988416SJim Ingham bool m_throw_bp; 518eb023e75SGreg Clayton bool m_hardware; // Request to use hardware breakpoints 519a72b31c7SJim Ingham lldb::LanguageType m_exception_language; 52023b1decbSDawn Perchik lldb::LanguageType m_language; 5215a988416SJim Ingham LazyBool m_skip_prologue; 522e732052fSJim Ingham bool m_all_files; 523a72b31c7SJim Ingham Args m_exception_extra_args; 524055ad9beSIlia K LazyBool m_move_to_nearest_code; 52576bb8d67SJim Ingham std::unordered_set<std::string> m_source_regex_func_names; 5263815e702SJim Ingham std::string m_current_key; 5275a988416SJim Ingham }; 5285a988416SJim Ingham 5295a988416SJim Ingham protected: 530b9c1b51eSKate Stone bool DoExecute(Args &command, CommandReturnObject &result) override { 531cb2380c9SRaphael Isemann Target &target = GetSelectedOrDummyTarget(m_dummy_options.m_use_dummy); 53230fdc8d8SChris Lattner 53330fdc8d8SChris Lattner // The following are the various types of breakpoints that could be set: 53430fdc8d8SChris Lattner // 1). -f -l -p [-s -g] (setting breakpoint by source location) 53530fdc8d8SChris Lattner // 2). -a [-s -g] (setting breakpoint by address) 53630fdc8d8SChris Lattner // 3). -n [-s -g] (setting breakpoint by function name) 537b9c1b51eSKate Stone // 4). -r [-s -g] (setting breakpoint by function name regular 538b9c1b51eSKate Stone // expression) 539b9c1b51eSKate Stone // 5). -p -f (setting a breakpoint by comparing a reg-exp 540b9c1b51eSKate Stone // to source text) 541b9c1b51eSKate Stone // 6). -E [-w -h] (setting a breakpoint for exceptions for a 542b9c1b51eSKate Stone // given language.) 54330fdc8d8SChris Lattner 54430fdc8d8SChris Lattner BreakpointSetType break_type = eSetTypeInvalid; 54530fdc8d8SChris Lattner 546943a2481SJim Ingham if (!m_python_class_options.GetClassName().empty()) 5473815e702SJim Ingham break_type = eSetTypeScripted; 5483815e702SJim Ingham else if (m_options.m_line_num != 0) 54930fdc8d8SChris Lattner break_type = eSetTypeFileAndLine; 55030fdc8d8SChris Lattner else if (m_options.m_load_addr != LLDB_INVALID_ADDRESS) 55130fdc8d8SChris Lattner break_type = eSetTypeAddress; 552fab10e89SJim Ingham else if (!m_options.m_func_names.empty()) 55330fdc8d8SChris Lattner break_type = eSetTypeFunctionName; 55430fdc8d8SChris Lattner else if (!m_options.m_func_regexp.empty()) 55530fdc8d8SChris Lattner break_type = eSetTypeFunctionRegexp; 556969795f1SJim Ingham else if (!m_options.m_source_text_regexp.empty()) 557969795f1SJim Ingham break_type = eSetTypeSourceRegexp; 558a72b31c7SJim Ingham else if (m_options.m_exception_language != eLanguageTypeUnknown) 559fab10e89SJim Ingham break_type = eSetTypeException; 56030fdc8d8SChris Lattner 561b842f2ecSJim Ingham BreakpointSP bp_sp = nullptr; 562274060b6SGreg Clayton FileSpec module_spec; 563a8558b62SJim Ingham const bool internal = false; 564a8558b62SJim Ingham 565b9c1b51eSKate Stone // If the user didn't specify skip-prologue, having an offset should turn 566b9c1b51eSKate Stone // that off. 567b9c1b51eSKate Stone if (m_options.m_offset_addr != 0 && 568b9c1b51eSKate Stone m_options.m_skip_prologue == eLazyBoolCalculate) 5692411167fSJim Ingham m_options.m_skip_prologue = eLazyBoolNo; 5702411167fSJim Ingham 571b9c1b51eSKate Stone switch (break_type) { 57230fdc8d8SChris Lattner case eSetTypeFileAndLine: // Breakpoint by source position 57330fdc8d8SChris Lattner { 57430fdc8d8SChris Lattner FileSpec file; 575c7bece56SGreg Clayton const size_t num_files = m_options.m_filenames.GetSize(); 576b9c1b51eSKate Stone if (num_files == 0) { 577b9c1b51eSKate Stone if (!GetDefaultFile(target, file, result)) { 57887df91b8SJim Ingham result.AppendError("No file supplied and no default file available."); 57987df91b8SJim Ingham result.SetStatus(eReturnStatusFailed); 58087df91b8SJim Ingham return false; 58187df91b8SJim Ingham } 582b9c1b51eSKate Stone } else if (num_files > 1) { 583b9c1b51eSKate Stone result.AppendError("Only one file at a time is allowed for file and " 584b9c1b51eSKate Stone "line breakpoints."); 58587df91b8SJim Ingham result.SetStatus(eReturnStatusFailed); 58687df91b8SJim Ingham return false; 587b9c1b51eSKate Stone } else 58887df91b8SJim Ingham file = m_options.m_filenames.GetFileSpecAtIndex(0); 58930fdc8d8SChris Lattner 5901f746071SGreg Clayton // Only check for inline functions if 5911f746071SGreg Clayton LazyBool check_inlines = eLazyBoolCalculate; 5921f746071SGreg Clayton 593cb2380c9SRaphael Isemann bp_sp = target.CreateBreakpoint( 594cb2380c9SRaphael Isemann &(m_options.m_modules), file, m_options.m_line_num, 595cb2380c9SRaphael Isemann m_options.m_column, m_options.m_offset_addr, check_inlines, 596cb2380c9SRaphael Isemann m_options.m_skip_prologue, internal, m_options.m_hardware, 597b842f2ecSJim Ingham m_options.m_move_to_nearest_code); 598b9c1b51eSKate Stone } break; 5996eee5aa0SGreg Clayton 60030fdc8d8SChris Lattner case eSetTypeAddress: // Breakpoint by address 601055a08a4SJim Ingham { 602b9c1b51eSKate Stone // If a shared library has been specified, make an lldb_private::Address 603b842f2ecSJim Ingham // with the library, and use that. That way the address breakpoint 604b842f2ecSJim Ingham // will track the load location of the library. 605055a08a4SJim Ingham size_t num_modules_specified = m_options.m_modules.GetSize(); 606b9c1b51eSKate Stone if (num_modules_specified == 1) { 607b9c1b51eSKate Stone const FileSpec *file_spec = 608b9c1b51eSKate Stone m_options.m_modules.GetFileSpecPointerAtIndex(0); 609cb2380c9SRaphael Isemann bp_sp = target.CreateAddressInModuleBreakpoint( 610cb2380c9SRaphael Isemann m_options.m_load_addr, internal, file_spec, m_options.m_hardware); 611b9c1b51eSKate Stone } else if (num_modules_specified == 0) { 612cb2380c9SRaphael Isemann bp_sp = target.CreateBreakpoint(m_options.m_load_addr, internal, 613b842f2ecSJim Ingham m_options.m_hardware); 614b9c1b51eSKate Stone } else { 615b9c1b51eSKate Stone result.AppendError("Only one shared library can be specified for " 616b9c1b51eSKate Stone "address breakpoints."); 617055a08a4SJim Ingham result.SetStatus(eReturnStatusFailed); 618055a08a4SJim Ingham return false; 619055a08a4SJim Ingham } 62030fdc8d8SChris Lattner break; 621055a08a4SJim Ingham } 62230fdc8d8SChris Lattner case eSetTypeFunctionName: // Breakpoint by function name 6230c5cd90dSGreg Clayton { 624117b1fa1SZachary Turner FunctionNameType name_type_mask = m_options.m_func_name_type_mask; 6250c5cd90dSGreg Clayton 6260c5cd90dSGreg Clayton if (name_type_mask == 0) 627e02b8504SGreg Clayton name_type_mask = eFunctionNameTypeAuto; 6280c5cd90dSGreg Clayton 629cb2380c9SRaphael Isemann bp_sp = target.CreateBreakpoint( 630cb2380c9SRaphael Isemann &(m_options.m_modules), &(m_options.m_filenames), 631cb2380c9SRaphael Isemann m_options.m_func_names, name_type_mask, m_options.m_language, 632cb2380c9SRaphael Isemann m_options.m_offset_addr, m_options.m_skip_prologue, internal, 633b842f2ecSJim Ingham m_options.m_hardware); 634b9c1b51eSKate Stone } break; 6350c5cd90dSGreg Clayton 636b9c1b51eSKate Stone case eSetTypeFunctionRegexp: // Breakpoint by regular expression function 637b9c1b51eSKate Stone // name 63830fdc8d8SChris Lattner { 63995eae423SZachary Turner RegularExpression regexp(m_options.m_func_regexp); 6403af3f1e8SJonas Devlieghere if (llvm::Error err = regexp.GetError()) { 641b9c1b51eSKate Stone result.AppendErrorWithFormat( 642b9c1b51eSKate Stone "Function name regular expression could not be compiled: \"%s\"", 6433af3f1e8SJonas Devlieghere llvm::toString(std::move(err)).c_str()); 64430fdc8d8SChris Lattner result.SetStatus(eReturnStatusFailed); 645969795f1SJim Ingham return false; 64630fdc8d8SChris Lattner } 64787df91b8SJim Ingham 648cb2380c9SRaphael Isemann bp_sp = target.CreateFuncRegexBreakpoint( 6495aa1d819SJan Kratochvil &(m_options.m_modules), &(m_options.m_filenames), std::move(regexp), 650cb2380c9SRaphael Isemann m_options.m_language, m_options.m_skip_prologue, internal, 651b842f2ecSJim Ingham m_options.m_hardware); 652e14dc268SJim Ingham } 653e14dc268SJim Ingham break; 654969795f1SJim Ingham case eSetTypeSourceRegexp: // Breakpoint by regexp on source text. 655969795f1SJim Ingham { 656c7bece56SGreg Clayton const size_t num_files = m_options.m_filenames.GetSize(); 65787df91b8SJim Ingham 658b9c1b51eSKate Stone if (num_files == 0 && !m_options.m_all_files) { 659969795f1SJim Ingham FileSpec file; 660b9c1b51eSKate Stone if (!GetDefaultFile(target, file, result)) { 661b9c1b51eSKate Stone result.AppendError( 662b9c1b51eSKate Stone "No files provided and could not find default file."); 66387df91b8SJim Ingham result.SetStatus(eReturnStatusFailed); 66487df91b8SJim Ingham return false; 665b9c1b51eSKate Stone } else { 66687df91b8SJim Ingham m_options.m_filenames.Append(file); 66787df91b8SJim Ingham } 66887df91b8SJim Ingham } 6690c5cd90dSGreg Clayton 67095eae423SZachary Turner RegularExpression regexp(m_options.m_source_text_regexp); 6713af3f1e8SJonas Devlieghere if (llvm::Error err = regexp.GetError()) { 672b9c1b51eSKate Stone result.AppendErrorWithFormat( 673b9c1b51eSKate Stone "Source text regular expression could not be compiled: \"%s\"", 6743af3f1e8SJonas Devlieghere llvm::toString(std::move(err)).c_str()); 675969795f1SJim Ingham result.SetStatus(eReturnStatusFailed); 676969795f1SJim Ingham return false; 677969795f1SJim Ingham } 678cb2380c9SRaphael Isemann bp_sp = target.CreateSourceRegexBreakpoint( 679cb2380c9SRaphael Isemann &(m_options.m_modules), &(m_options.m_filenames), 6805aa1d819SJan Kratochvil m_options.m_source_regex_func_names, std::move(regexp), internal, 681cb2380c9SRaphael Isemann m_options.m_hardware, m_options.m_move_to_nearest_code); 682b9c1b51eSKate Stone } break; 683b9c1b51eSKate Stone case eSetTypeException: { 68497206d57SZachary Turner Status precond_error; 685cb2380c9SRaphael Isemann bp_sp = target.CreateExceptionBreakpoint( 686cb2380c9SRaphael Isemann m_options.m_exception_language, m_options.m_catch_bp, 687cb2380c9SRaphael Isemann m_options.m_throw_bp, internal, &m_options.m_exception_extra_args, 688b842f2ecSJim Ingham &precond_error); 689b9c1b51eSKate Stone if (precond_error.Fail()) { 690b9c1b51eSKate Stone result.AppendErrorWithFormat( 691b9c1b51eSKate Stone "Error setting extra exception arguments: %s", 692a72b31c7SJim Ingham precond_error.AsCString()); 693cb2380c9SRaphael Isemann target.RemoveBreakpointByID(bp_sp->GetID()); 694a72b31c7SJim Ingham result.SetStatus(eReturnStatusFailed); 695a72b31c7SJim Ingham return false; 696a72b31c7SJim Ingham } 697b9c1b51eSKate Stone } break; 6983815e702SJim Ingham case eSetTypeScripted: { 6993815e702SJim Ingham 7003815e702SJim Ingham Status error; 701cb2380c9SRaphael Isemann bp_sp = target.CreateScriptedBreakpoint( 702943a2481SJim Ingham m_python_class_options.GetClassName().c_str(), &(m_options.m_modules), 703cb2380c9SRaphael Isemann &(m_options.m_filenames), false, m_options.m_hardware, 704943a2481SJim Ingham m_python_class_options.GetStructuredData(), &error); 7053815e702SJim Ingham if (error.Fail()) { 7063815e702SJim Ingham result.AppendErrorWithFormat( 7073815e702SJim Ingham "Error setting extra exception arguments: %s", 7083815e702SJim Ingham error.AsCString()); 709cb2380c9SRaphael Isemann target.RemoveBreakpointByID(bp_sp->GetID()); 7103815e702SJim Ingham result.SetStatus(eReturnStatusFailed); 7113815e702SJim Ingham return false; 7123815e702SJim Ingham } 7133815e702SJim Ingham } break; 71430fdc8d8SChris Lattner default: 71530fdc8d8SChris Lattner break; 71630fdc8d8SChris Lattner } 71730fdc8d8SChris Lattner 7181b54c88cSJim Ingham // Now set the various options that were passed in: 719b842f2ecSJim Ingham if (bp_sp) { 720b842f2ecSJim Ingham bp_sp->GetOptions()->CopyOverSetOptions(m_bp_opts.GetBreakpointOptions()); 721ca36cd16SJim Ingham 722b9c1b51eSKate Stone if (!m_options.m_breakpoint_names.empty()) { 72397206d57SZachary Turner Status name_error; 724ff9a91eaSJim Ingham for (auto name : m_options.m_breakpoint_names) { 725cb2380c9SRaphael Isemann target.AddNameToBreakpoint(bp_sp, name.c_str(), name_error); 726ff9a91eaSJim Ingham if (name_error.Fail()) { 727ff9a91eaSJim Ingham result.AppendErrorWithFormat("Invalid breakpoint name: %s", 728ff9a91eaSJim Ingham name.c_str()); 729cb2380c9SRaphael Isemann target.RemoveBreakpointByID(bp_sp->GetID()); 730ff9a91eaSJim Ingham result.SetStatus(eReturnStatusFailed); 731ff9a91eaSJim Ingham return false; 732ff9a91eaSJim Ingham } 733ff9a91eaSJim Ingham } 7345e09c8c3SJim Ingham } 7351b54c88cSJim Ingham } 7361b54c88cSJim Ingham 737b842f2ecSJim Ingham if (bp_sp) { 73885e8b814SJim Ingham Stream &output_stream = result.GetOutputStream(); 7391391cc7dSJim Ingham const bool show_locations = false; 740b842f2ecSJim Ingham bp_sp->GetDescription(&output_stream, lldb::eDescriptionLevelInitial, 741b9c1b51eSKate Stone show_locations); 742cb2380c9SRaphael Isemann if (&target == &GetDummyTarget()) 743b9c1b51eSKate Stone output_stream.Printf("Breakpoint set in dummy target, will get copied " 744b9c1b51eSKate Stone "into future targets.\n"); 745b9c1b51eSKate Stone else { 74605097246SAdrian Prantl // Don't print out this warning for exception breakpoints. They can 74705097246SAdrian Prantl // get set before the target is set, but we won't know how to actually 74805097246SAdrian Prantl // set the breakpoint till we run. 749b842f2ecSJim Ingham if (bp_sp->GetNumLocations() == 0 && break_type != eSetTypeException) { 750b9c1b51eSKate Stone output_stream.Printf("WARNING: Unable to resolve breakpoint to any " 751b9c1b51eSKate Stone "actual locations.\n"); 7524aeb1989SJim Ingham } 7534aeb1989SJim Ingham } 75430fdc8d8SChris Lattner result.SetStatus(eReturnStatusSuccessFinishResult); 755b842f2ecSJim Ingham } else if (!bp_sp) { 75630fdc8d8SChris Lattner result.AppendError("Breakpoint creation failed: No breakpoint created."); 75730fdc8d8SChris Lattner result.SetStatus(eReturnStatusFailed); 75830fdc8d8SChris Lattner } 75930fdc8d8SChris Lattner 76030fdc8d8SChris Lattner return result.Succeeded(); 76130fdc8d8SChris Lattner } 76230fdc8d8SChris Lattner 7635a988416SJim Ingham private: 764cb2380c9SRaphael Isemann bool GetDefaultFile(Target &target, FileSpec &file, 765b9c1b51eSKate Stone CommandReturnObject &result) { 7665a988416SJim Ingham uint32_t default_line; 76705097246SAdrian Prantl // First use the Source Manager's default file. Then use the current stack 76805097246SAdrian Prantl // frame's file. 769cb2380c9SRaphael Isemann if (!target.GetSourceManager().GetDefaultFileAndLine(file, default_line)) { 770b57e4a1bSJason Molenda StackFrame *cur_frame = m_exe_ctx.GetFramePtr(); 771b9c1b51eSKate Stone if (cur_frame == nullptr) { 772b9c1b51eSKate Stone result.AppendError( 773b9c1b51eSKate Stone "No selected frame to use to find the default file."); 7745a988416SJim Ingham result.SetStatus(eReturnStatusFailed); 7755a988416SJim Ingham return false; 776b9c1b51eSKate Stone } else if (!cur_frame->HasDebugInformation()) { 777b9c1b51eSKate Stone result.AppendError("Cannot use the selected frame to find the default " 778b9c1b51eSKate Stone "file, it has no debug info."); 7795a988416SJim Ingham result.SetStatus(eReturnStatusFailed); 7805a988416SJim Ingham return false; 781b9c1b51eSKate Stone } else { 782b9c1b51eSKate Stone const SymbolContext &sc = 783b9c1b51eSKate Stone cur_frame->GetSymbolContext(eSymbolContextLineEntry); 784b9c1b51eSKate Stone if (sc.line_entry.file) { 7855a988416SJim Ingham file = sc.line_entry.file; 786b9c1b51eSKate Stone } else { 787b9c1b51eSKate Stone result.AppendError("Can't find the file for the selected frame to " 788b9c1b51eSKate Stone "use as the default file."); 7895a988416SJim Ingham result.SetStatus(eReturnStatusFailed); 7905a988416SJim Ingham return false; 7915a988416SJim Ingham } 7925a988416SJim Ingham } 7935a988416SJim Ingham } 7945a988416SJim Ingham return true; 7955a988416SJim Ingham } 7965a988416SJim Ingham 797b842f2ecSJim Ingham BreakpointOptionGroup m_bp_opts; 798b842f2ecSJim Ingham BreakpointDummyOptionGroup m_dummy_options; 799943a2481SJim Ingham OptionGroupPythonClassWithDict m_python_class_options; 8005a988416SJim Ingham CommandOptions m_options; 801b842f2ecSJim Ingham OptionGroupOptions m_all_options; 8025a988416SJim Ingham }; 8039e85e5a8SEugene Zelenko 8045a988416SJim Ingham // CommandObjectBreakpointModify 8055a988416SJim Ingham #pragma mark Modify 8065a988416SJim Ingham 807b9c1b51eSKate Stone class CommandObjectBreakpointModify : public CommandObjectParsed { 8085a988416SJim Ingham public: 809b9c1b51eSKate Stone CommandObjectBreakpointModify(CommandInterpreter &interpreter) 810b9c1b51eSKate Stone : CommandObjectParsed(interpreter, "breakpoint modify", 811b9c1b51eSKate Stone "Modify the options on a breakpoint or set of " 812b9c1b51eSKate Stone "breakpoints in the executable. " 813b9c1b51eSKate Stone "If no breakpoint is specified, acts on the last " 814b9c1b51eSKate Stone "created breakpoint. " 815b9c1b51eSKate Stone "With the exception of -e, -d and -i, passing an " 816b9c1b51eSKate Stone "empty argument clears the modification.", 8179e85e5a8SEugene Zelenko nullptr), 818b9c1b51eSKate Stone m_options() { 8195a988416SJim Ingham CommandArgumentEntry arg; 820b9c1b51eSKate Stone CommandObject::AddIDsArgumentData(arg, eArgTypeBreakpointID, 821b9c1b51eSKate Stone eArgTypeBreakpointIDRange); 822b9c1b51eSKate Stone // Add the entry for the first argument for this command to the object's 823b9c1b51eSKate Stone // arguments vector. 8245a988416SJim Ingham m_arguments.push_back(arg); 825b842f2ecSJim Ingham 826b842f2ecSJim Ingham m_options.Append(&m_bp_opts, 827b842f2ecSJim Ingham LLDB_OPT_SET_1 | LLDB_OPT_SET_2 | LLDB_OPT_SET_3, 828b842f2ecSJim Ingham LLDB_OPT_SET_ALL); 829b842f2ecSJim Ingham m_options.Append(&m_dummy_opts, LLDB_OPT_SET_1, LLDB_OPT_SET_ALL); 830b842f2ecSJim Ingham m_options.Finalize(); 8315a988416SJim Ingham } 8325a988416SJim Ingham 8339e85e5a8SEugene Zelenko ~CommandObjectBreakpointModify() override = default; 8345a988416SJim Ingham 835b9c1b51eSKate Stone Options *GetOptions() override { return &m_options; } 8365a988416SJim Ingham 8375a988416SJim Ingham protected: 838b9c1b51eSKate Stone bool DoExecute(Args &command, CommandReturnObject &result) override { 839cb2380c9SRaphael Isemann Target &target = GetSelectedOrDummyTarget(m_dummy_opts.m_use_dummy); 8405a988416SJim Ingham 841bb19a13cSSaleem Abdulrasool std::unique_lock<std::recursive_mutex> lock; 842cb2380c9SRaphael Isemann target.GetBreakpointList().GetListMutex(lock); 8435a988416SJim Ingham 8445a988416SJim Ingham BreakpointIDList valid_bp_ids; 8455a988416SJim Ingham 846b9c1b51eSKate Stone CommandObjectMultiwordBreakpoint::VerifyBreakpointOrLocationIDs( 847cb2380c9SRaphael Isemann command, &target, result, &valid_bp_ids, 848b842f2ecSJim Ingham BreakpointName::Permissions::PermissionKinds::disablePerm); 8495a988416SJim Ingham 850b9c1b51eSKate Stone if (result.Succeeded()) { 8515a988416SJim Ingham const size_t count = valid_bp_ids.GetSize(); 852b9c1b51eSKate Stone for (size_t i = 0; i < count; ++i) { 8535a988416SJim Ingham BreakpointID cur_bp_id = valid_bp_ids.GetBreakpointIDAtIndex(i); 8545a988416SJim Ingham 855b9c1b51eSKate Stone if (cur_bp_id.GetBreakpointID() != LLDB_INVALID_BREAK_ID) { 856b9c1b51eSKate Stone Breakpoint *bp = 857cb2380c9SRaphael Isemann target.GetBreakpointByID(cur_bp_id.GetBreakpointID()).get(); 858b9c1b51eSKate Stone if (cur_bp_id.GetLocationID() != LLDB_INVALID_BREAK_ID) { 859b9c1b51eSKate Stone BreakpointLocation *location = 860b9c1b51eSKate Stone bp->FindLocationByID(cur_bp_id.GetLocationID()).get(); 861b842f2ecSJim Ingham if (location) 862b842f2ecSJim Ingham location->GetLocationOptions() 863b842f2ecSJim Ingham ->CopyOverSetOptions(m_bp_opts.GetBreakpointOptions()); 864b9c1b51eSKate Stone } else { 865b842f2ecSJim Ingham bp->GetOptions() 866b842f2ecSJim Ingham ->CopyOverSetOptions(m_bp_opts.GetBreakpointOptions()); 8675a988416SJim Ingham } 8685a988416SJim Ingham } 8695a988416SJim Ingham } 8705a988416SJim Ingham } 8715a988416SJim Ingham 8725a988416SJim Ingham return result.Succeeded(); 8735a988416SJim Ingham } 8745a988416SJim Ingham 8755a988416SJim Ingham private: 876b842f2ecSJim Ingham BreakpointOptionGroup m_bp_opts; 877b842f2ecSJim Ingham BreakpointDummyOptionGroup m_dummy_opts; 878b842f2ecSJim Ingham OptionGroupOptions m_options; 8795a988416SJim Ingham }; 8805a988416SJim Ingham 8815a988416SJim Ingham // CommandObjectBreakpointEnable 8825a988416SJim Ingham #pragma mark Enable 8835a988416SJim Ingham 884b9c1b51eSKate Stone class CommandObjectBreakpointEnable : public CommandObjectParsed { 8855a988416SJim Ingham public: 886b9c1b51eSKate Stone CommandObjectBreakpointEnable(CommandInterpreter &interpreter) 887b9c1b51eSKate Stone : CommandObjectParsed(interpreter, "enable", 888b9c1b51eSKate Stone "Enable the specified disabled breakpoint(s). If " 889b9c1b51eSKate Stone "no breakpoints are specified, enable all of them.", 890b9c1b51eSKate Stone nullptr) { 8915a988416SJim Ingham CommandArgumentEntry arg; 892b9c1b51eSKate Stone CommandObject::AddIDsArgumentData(arg, eArgTypeBreakpointID, 893b9c1b51eSKate Stone eArgTypeBreakpointIDRange); 894b9c1b51eSKate Stone // Add the entry for the first argument for this command to the object's 895b9c1b51eSKate Stone // arguments vector. 8965a988416SJim Ingham m_arguments.push_back(arg); 8975a988416SJim Ingham } 8985a988416SJim Ingham 8999e85e5a8SEugene Zelenko ~CommandObjectBreakpointEnable() override = default; 9005a988416SJim Ingham 9015a988416SJim Ingham protected: 902b9c1b51eSKate Stone bool DoExecute(Args &command, CommandReturnObject &result) override { 903cb2380c9SRaphael Isemann Target &target = GetSelectedOrDummyTarget(); 9045a988416SJim Ingham 905bb19a13cSSaleem Abdulrasool std::unique_lock<std::recursive_mutex> lock; 906cb2380c9SRaphael Isemann target.GetBreakpointList().GetListMutex(lock); 9075a988416SJim Ingham 908cb2380c9SRaphael Isemann const BreakpointList &breakpoints = target.GetBreakpointList(); 9095a988416SJim Ingham 9105a988416SJim Ingham size_t num_breakpoints = breakpoints.GetSize(); 9115a988416SJim Ingham 912b9c1b51eSKate Stone if (num_breakpoints == 0) { 9135a988416SJim Ingham result.AppendError("No breakpoints exist to be enabled."); 9145a988416SJim Ingham result.SetStatus(eReturnStatusFailed); 9155a988416SJim Ingham return false; 9165a988416SJim Ingham } 9175a988416SJim Ingham 91811eb9c64SZachary Turner if (command.empty()) { 9195a988416SJim Ingham // No breakpoint selected; enable all currently set breakpoints. 920cb2380c9SRaphael Isemann target.EnableAllowedBreakpoints(); 921b9c1b51eSKate Stone result.AppendMessageWithFormat("All breakpoints enabled. (%" PRIu64 922b9c1b51eSKate Stone " breakpoints)\n", 923b9c1b51eSKate Stone (uint64_t)num_breakpoints); 9245a988416SJim Ingham result.SetStatus(eReturnStatusSuccessFinishNoResult); 925b9c1b51eSKate Stone } else { 9265a988416SJim Ingham // Particular breakpoint selected; enable that breakpoint. 9275a988416SJim Ingham BreakpointIDList valid_bp_ids; 928b9c1b51eSKate Stone CommandObjectMultiwordBreakpoint::VerifyBreakpointOrLocationIDs( 929cb2380c9SRaphael Isemann command, &target, result, &valid_bp_ids, 930b842f2ecSJim Ingham BreakpointName::Permissions::PermissionKinds::disablePerm); 9315a988416SJim Ingham 932b9c1b51eSKate Stone if (result.Succeeded()) { 9335a988416SJim Ingham int enable_count = 0; 9345a988416SJim Ingham int loc_count = 0; 9355a988416SJim Ingham const size_t count = valid_bp_ids.GetSize(); 936b9c1b51eSKate Stone for (size_t i = 0; i < count; ++i) { 9375a988416SJim Ingham BreakpointID cur_bp_id = valid_bp_ids.GetBreakpointIDAtIndex(i); 9385a988416SJim Ingham 939b9c1b51eSKate Stone if (cur_bp_id.GetBreakpointID() != LLDB_INVALID_BREAK_ID) { 940b9c1b51eSKate Stone Breakpoint *breakpoint = 941cb2380c9SRaphael Isemann target.GetBreakpointByID(cur_bp_id.GetBreakpointID()).get(); 942b9c1b51eSKate Stone if (cur_bp_id.GetLocationID() != LLDB_INVALID_BREAK_ID) { 943b9c1b51eSKate Stone BreakpointLocation *location = 944b9c1b51eSKate Stone breakpoint->FindLocationByID(cur_bp_id.GetLocationID()).get(); 945b9c1b51eSKate Stone if (location) { 9465a988416SJim Ingham location->SetEnabled(true); 9475a988416SJim Ingham ++loc_count; 9485a988416SJim Ingham } 949b9c1b51eSKate Stone } else { 9505a988416SJim Ingham breakpoint->SetEnabled(true); 9515a988416SJim Ingham ++enable_count; 9525a988416SJim Ingham } 9535a988416SJim Ingham } 9545a988416SJim Ingham } 955b9c1b51eSKate Stone result.AppendMessageWithFormat("%d breakpoints enabled.\n", 956b9c1b51eSKate Stone enable_count + loc_count); 9575a988416SJim Ingham result.SetStatus(eReturnStatusSuccessFinishNoResult); 9585a988416SJim Ingham } 9595a988416SJim Ingham } 9605a988416SJim Ingham 9615a988416SJim Ingham return result.Succeeded(); 9625a988416SJim Ingham } 9635a988416SJim Ingham }; 9645a988416SJim Ingham 9655a988416SJim Ingham // CommandObjectBreakpointDisable 9665a988416SJim Ingham #pragma mark Disable 9675a988416SJim Ingham 968b9c1b51eSKate Stone class CommandObjectBreakpointDisable : public CommandObjectParsed { 9695a988416SJim Ingham public: 9707428a18cSKate Stone CommandObjectBreakpointDisable(CommandInterpreter &interpreter) 971b9c1b51eSKate Stone : CommandObjectParsed( 972b9c1b51eSKate Stone interpreter, "breakpoint disable", 973b9c1b51eSKate Stone "Disable the specified breakpoint(s) without deleting " 9747428a18cSKate Stone "them. If none are specified, disable all " 9757428a18cSKate Stone "breakpoints.", 976b9c1b51eSKate Stone nullptr) { 977b9c1b51eSKate Stone SetHelpLong( 978b9c1b51eSKate Stone "Disable the specified breakpoint(s) without deleting them. \ 9797428a18cSKate Stone If none are specified, disable all breakpoints." 9807428a18cSKate Stone R"( 981ea671fbdSKate Stone 9827428a18cSKate Stone )" 9837428a18cSKate Stone "Note: disabling a breakpoint will cause none of its locations to be hit \ 9847428a18cSKate Stone regardless of whether individual locations are enabled or disabled. After the sequence:" 9857428a18cSKate Stone R"( 986ea671fbdSKate Stone 987ea671fbdSKate Stone (lldb) break disable 1 988ea671fbdSKate Stone (lldb) break enable 1.1 989ea671fbdSKate Stone 990ea671fbdSKate Stone execution will NOT stop at location 1.1. To achieve that, type: 991ea671fbdSKate Stone 992ea671fbdSKate Stone (lldb) break disable 1.* 993ea671fbdSKate Stone (lldb) break enable 1.1 994ea671fbdSKate Stone 9957428a18cSKate Stone )" 9967428a18cSKate Stone "The first command disables all locations for breakpoint 1, \ 9977428a18cSKate Stone the second re-enables the first location."); 998b0fac509SJim Ingham 9995a988416SJim Ingham CommandArgumentEntry arg; 1000b9c1b51eSKate Stone CommandObject::AddIDsArgumentData(arg, eArgTypeBreakpointID, 1001b9c1b51eSKate Stone eArgTypeBreakpointIDRange); 1002b9c1b51eSKate Stone // Add the entry for the first argument for this command to the object's 1003b9c1b51eSKate Stone // arguments vector. 10045a988416SJim Ingham m_arguments.push_back(arg); 10055a988416SJim Ingham } 10065a988416SJim Ingham 10079e85e5a8SEugene Zelenko ~CommandObjectBreakpointDisable() override = default; 10085a988416SJim Ingham 10095a988416SJim Ingham protected: 1010b9c1b51eSKate Stone bool DoExecute(Args &command, CommandReturnObject &result) override { 1011cb2380c9SRaphael Isemann Target &target = GetSelectedOrDummyTarget(); 1012bb19a13cSSaleem Abdulrasool std::unique_lock<std::recursive_mutex> lock; 1013cb2380c9SRaphael Isemann target.GetBreakpointList().GetListMutex(lock); 10145a988416SJim Ingham 1015cb2380c9SRaphael Isemann const BreakpointList &breakpoints = target.GetBreakpointList(); 10165a988416SJim Ingham size_t num_breakpoints = breakpoints.GetSize(); 10175a988416SJim Ingham 1018b9c1b51eSKate Stone if (num_breakpoints == 0) { 10195a988416SJim Ingham result.AppendError("No breakpoints exist to be disabled."); 10205a988416SJim Ingham result.SetStatus(eReturnStatusFailed); 10215a988416SJim Ingham return false; 10225a988416SJim Ingham } 10235a988416SJim Ingham 102411eb9c64SZachary Turner if (command.empty()) { 10255a988416SJim Ingham // No breakpoint selected; disable all currently set breakpoints. 1026cb2380c9SRaphael Isemann target.DisableAllowedBreakpoints(); 1027b9c1b51eSKate Stone result.AppendMessageWithFormat("All breakpoints disabled. (%" PRIu64 1028b9c1b51eSKate Stone " breakpoints)\n", 1029b9c1b51eSKate Stone (uint64_t)num_breakpoints); 10305a988416SJim Ingham result.SetStatus(eReturnStatusSuccessFinishNoResult); 1031b9c1b51eSKate Stone } else { 10325a988416SJim Ingham // Particular breakpoint selected; disable that breakpoint. 10335a988416SJim Ingham BreakpointIDList valid_bp_ids; 10345a988416SJim Ingham 1035b9c1b51eSKate Stone CommandObjectMultiwordBreakpoint::VerifyBreakpointOrLocationIDs( 1036cb2380c9SRaphael Isemann command, &target, result, &valid_bp_ids, 1037b842f2ecSJim Ingham BreakpointName::Permissions::PermissionKinds::disablePerm); 10385a988416SJim Ingham 1039b9c1b51eSKate Stone if (result.Succeeded()) { 10405a988416SJim Ingham int disable_count = 0; 10415a988416SJim Ingham int loc_count = 0; 10425a988416SJim Ingham const size_t count = valid_bp_ids.GetSize(); 1043b9c1b51eSKate Stone for (size_t i = 0; i < count; ++i) { 10445a988416SJim Ingham BreakpointID cur_bp_id = valid_bp_ids.GetBreakpointIDAtIndex(i); 10455a988416SJim Ingham 1046b9c1b51eSKate Stone if (cur_bp_id.GetBreakpointID() != LLDB_INVALID_BREAK_ID) { 1047b9c1b51eSKate Stone Breakpoint *breakpoint = 1048cb2380c9SRaphael Isemann target.GetBreakpointByID(cur_bp_id.GetBreakpointID()).get(); 1049b9c1b51eSKate Stone if (cur_bp_id.GetLocationID() != LLDB_INVALID_BREAK_ID) { 1050b9c1b51eSKate Stone BreakpointLocation *location = 1051b9c1b51eSKate Stone breakpoint->FindLocationByID(cur_bp_id.GetLocationID()).get(); 1052b9c1b51eSKate Stone if (location) { 10535a988416SJim Ingham location->SetEnabled(false); 10545a988416SJim Ingham ++loc_count; 10555a988416SJim Ingham } 1056b9c1b51eSKate Stone } else { 10575a988416SJim Ingham breakpoint->SetEnabled(false); 10585a988416SJim Ingham ++disable_count; 10595a988416SJim Ingham } 10605a988416SJim Ingham } 10615a988416SJim Ingham } 1062b9c1b51eSKate Stone result.AppendMessageWithFormat("%d breakpoints disabled.\n", 1063b9c1b51eSKate Stone disable_count + loc_count); 10645a988416SJim Ingham result.SetStatus(eReturnStatusSuccessFinishNoResult); 10655a988416SJim Ingham } 10665a988416SJim Ingham } 10675a988416SJim Ingham 10685a988416SJim Ingham return result.Succeeded(); 10695a988416SJim Ingham } 10705a988416SJim Ingham }; 10715a988416SJim Ingham 10725a988416SJim Ingham // CommandObjectBreakpointList 10731f0f5b5bSZachary Turner 10741f0f5b5bSZachary Turner #pragma mark List::CommandOptions 10756f4fb4e7SRaphael Isemann #define LLDB_OPTIONS_breakpoint_list 1076c5a2d747SRaphael Isemann #include "CommandOptions.inc" 10771f0f5b5bSZachary Turner 10785a988416SJim Ingham #pragma mark List 10795a988416SJim Ingham 1080b9c1b51eSKate Stone class CommandObjectBreakpointList : public CommandObjectParsed { 10815a988416SJim Ingham public: 1082b9c1b51eSKate Stone CommandObjectBreakpointList(CommandInterpreter &interpreter) 1083b9c1b51eSKate Stone : CommandObjectParsed( 1084b9c1b51eSKate Stone interpreter, "breakpoint list", 10855a988416SJim Ingham "List some or all breakpoints at configurable levels of detail.", 10869e85e5a8SEugene Zelenko nullptr), 1087b9c1b51eSKate Stone m_options() { 10885a988416SJim Ingham CommandArgumentEntry arg; 10895a988416SJim Ingham CommandArgumentData bp_id_arg; 10905a988416SJim Ingham 10915a988416SJim Ingham // Define the first (and only) variant of this arg. 10925a988416SJim Ingham bp_id_arg.arg_type = eArgTypeBreakpointID; 10935a988416SJim Ingham bp_id_arg.arg_repetition = eArgRepeatOptional; 10945a988416SJim Ingham 1095b9c1b51eSKate Stone // There is only one variant this argument could be; put it into the 1096b9c1b51eSKate Stone // argument entry. 10975a988416SJim Ingham arg.push_back(bp_id_arg); 10985a988416SJim Ingham 10995a988416SJim Ingham // Push the data for the first argument into the m_arguments vector. 11005a988416SJim Ingham m_arguments.push_back(arg); 11015a988416SJim Ingham } 11025a988416SJim Ingham 11039e85e5a8SEugene Zelenko ~CommandObjectBreakpointList() override = default; 11045a988416SJim Ingham 1105b9c1b51eSKate Stone Options *GetOptions() override { return &m_options; } 11065a988416SJim Ingham 1107b9c1b51eSKate Stone class CommandOptions : public Options { 11085a988416SJim Ingham public: 1109b9c1b51eSKate Stone CommandOptions() 1110b9c1b51eSKate Stone : Options(), m_level(lldb::eDescriptionLevelBrief), m_use_dummy(false) { 11115a988416SJim Ingham } 11125a988416SJim Ingham 11139e85e5a8SEugene Zelenko ~CommandOptions() override = default; 11145a988416SJim Ingham 111597206d57SZachary Turner Status SetOptionValue(uint32_t option_idx, llvm::StringRef option_arg, 1116b9c1b51eSKate Stone ExecutionContext *execution_context) override { 111797206d57SZachary Turner Status error; 11183bcdfc0eSGreg Clayton const int short_option = m_getopt_table[option_idx].val; 11195a988416SJim Ingham 1120b9c1b51eSKate Stone switch (short_option) { 11215a988416SJim Ingham case 'b': 11225a988416SJim Ingham m_level = lldb::eDescriptionLevelBrief; 11235a988416SJim Ingham break; 112433df7cd3SJim Ingham case 'D': 112533df7cd3SJim Ingham m_use_dummy = true; 112633df7cd3SJim Ingham break; 11275a988416SJim Ingham case 'f': 11285a988416SJim Ingham m_level = lldb::eDescriptionLevelFull; 11295a988416SJim Ingham break; 11305a988416SJim Ingham case 'v': 11315a988416SJim Ingham m_level = lldb::eDescriptionLevelVerbose; 11325a988416SJim Ingham break; 11335a988416SJim Ingham case 'i': 11345a988416SJim Ingham m_internal = true; 11355a988416SJim Ingham break; 11365a988416SJim Ingham default: 113736162014SRaphael Isemann llvm_unreachable("Unimplemented option"); 11385a988416SJim Ingham } 11395a988416SJim Ingham 11405a988416SJim Ingham return error; 11415a988416SJim Ingham } 11425a988416SJim Ingham 1143b9c1b51eSKate Stone void OptionParsingStarting(ExecutionContext *execution_context) override { 11445a988416SJim Ingham m_level = lldb::eDescriptionLevelFull; 11455a988416SJim Ingham m_internal = false; 114633df7cd3SJim Ingham m_use_dummy = false; 11475a988416SJim Ingham } 11485a988416SJim Ingham 11491f0f5b5bSZachary Turner llvm::ArrayRef<OptionDefinition> GetDefinitions() override { 115070602439SZachary Turner return llvm::makeArrayRef(g_breakpoint_list_options); 11511f0f5b5bSZachary Turner } 11525a988416SJim Ingham 11535a988416SJim Ingham // Instance variables to hold the values for command options. 11545a988416SJim Ingham 11555a988416SJim Ingham lldb::DescriptionLevel m_level; 11565a988416SJim Ingham 11575a988416SJim Ingham bool m_internal; 115833df7cd3SJim Ingham bool m_use_dummy; 11595a988416SJim Ingham }; 11605a988416SJim Ingham 11615a988416SJim Ingham protected: 1162b9c1b51eSKate Stone bool DoExecute(Args &command, CommandReturnObject &result) override { 1163cb2380c9SRaphael Isemann Target &target = GetSelectedOrDummyTarget(m_options.m_use_dummy); 11645a988416SJim Ingham 1165b9c1b51eSKate Stone const BreakpointList &breakpoints = 1166cb2380c9SRaphael Isemann target.GetBreakpointList(m_options.m_internal); 1167bb19a13cSSaleem Abdulrasool std::unique_lock<std::recursive_mutex> lock; 1168cb2380c9SRaphael Isemann target.GetBreakpointList(m_options.m_internal).GetListMutex(lock); 11695a988416SJim Ingham 11705a988416SJim Ingham size_t num_breakpoints = breakpoints.GetSize(); 11715a988416SJim Ingham 1172b9c1b51eSKate Stone if (num_breakpoints == 0) { 11735a988416SJim Ingham result.AppendMessage("No breakpoints currently set."); 11745a988416SJim Ingham result.SetStatus(eReturnStatusSuccessFinishNoResult); 11755a988416SJim Ingham return true; 11765a988416SJim Ingham } 11775a988416SJim Ingham 11785a988416SJim Ingham Stream &output_stream = result.GetOutputStream(); 11795a988416SJim Ingham 118011eb9c64SZachary Turner if (command.empty()) { 11815a988416SJim Ingham // No breakpoint selected; show info about all currently set breakpoints. 11825a988416SJim Ingham result.AppendMessage("Current breakpoints:"); 1183b9c1b51eSKate Stone for (size_t i = 0; i < num_breakpoints; ++i) { 11845a988416SJim Ingham Breakpoint *breakpoint = breakpoints.GetBreakpointAtIndex(i).get(); 1185b842f2ecSJim Ingham if (breakpoint->AllowList()) 1186b842f2ecSJim Ingham AddBreakpointDescription(&output_stream, breakpoint, 1187b842f2ecSJim Ingham m_options.m_level); 11885a988416SJim Ingham } 11895a988416SJim Ingham result.SetStatus(eReturnStatusSuccessFinishNoResult); 1190b9c1b51eSKate Stone } else { 11915a988416SJim Ingham // Particular breakpoints selected; show info about that breakpoint. 11925a988416SJim Ingham BreakpointIDList valid_bp_ids; 1193b9c1b51eSKate Stone CommandObjectMultiwordBreakpoint::VerifyBreakpointOrLocationIDs( 1194cb2380c9SRaphael Isemann command, &target, result, &valid_bp_ids, 1195b842f2ecSJim Ingham BreakpointName::Permissions::PermissionKinds::listPerm); 11965a988416SJim Ingham 1197b9c1b51eSKate Stone if (result.Succeeded()) { 1198b9c1b51eSKate Stone for (size_t i = 0; i < valid_bp_ids.GetSize(); ++i) { 11995a988416SJim Ingham BreakpointID cur_bp_id = valid_bp_ids.GetBreakpointIDAtIndex(i); 1200b9c1b51eSKate Stone Breakpoint *breakpoint = 1201cb2380c9SRaphael Isemann target.GetBreakpointByID(cur_bp_id.GetBreakpointID()).get(); 1202b9c1b51eSKate Stone AddBreakpointDescription(&output_stream, breakpoint, 1203b9c1b51eSKate Stone m_options.m_level); 12045a988416SJim Ingham } 12055a988416SJim Ingham result.SetStatus(eReturnStatusSuccessFinishNoResult); 1206b9c1b51eSKate Stone } else { 12077428a18cSKate Stone result.AppendError("Invalid breakpoint ID."); 12085a988416SJim Ingham result.SetStatus(eReturnStatusFailed); 12095a988416SJim Ingham } 12105a988416SJim Ingham } 12115a988416SJim Ingham 12125a988416SJim Ingham return result.Succeeded(); 12135a988416SJim Ingham } 12145a988416SJim Ingham 12155a988416SJim Ingham private: 12165a988416SJim Ingham CommandOptions m_options; 12175a988416SJim Ingham }; 12185a988416SJim Ingham 12195a988416SJim Ingham // CommandObjectBreakpointClear 12201f0f5b5bSZachary Turner #pragma mark Clear::CommandOptions 12211f0f5b5bSZachary Turner 1222f94668e3SRaphael Isemann #define LLDB_OPTIONS_breakpoint_clear 1223f94668e3SRaphael Isemann #include "CommandOptions.inc" 12241f0f5b5bSZachary Turner 12255a988416SJim Ingham #pragma mark Clear 12265a988416SJim Ingham 1227b9c1b51eSKate Stone class CommandObjectBreakpointClear : public CommandObjectParsed { 12285a988416SJim Ingham public: 1229efe8e7e3SFangrui Song enum BreakpointClearType { eClearTypeInvalid, eClearTypeFileAndLine }; 12305a988416SJim Ingham 12317428a18cSKate Stone CommandObjectBreakpointClear(CommandInterpreter &interpreter) 12327428a18cSKate Stone : CommandObjectParsed(interpreter, "breakpoint clear", 1233b9c1b51eSKate Stone "Delete or disable breakpoints matching the " 1234b9c1b51eSKate Stone "specified source file and line.", 12355a988416SJim Ingham "breakpoint clear <cmd-options>"), 1236b9c1b51eSKate Stone m_options() {} 12375a988416SJim Ingham 12389e85e5a8SEugene Zelenko ~CommandObjectBreakpointClear() override = default; 12395a988416SJim Ingham 1240b9c1b51eSKate Stone Options *GetOptions() override { return &m_options; } 12415a988416SJim Ingham 1242b9c1b51eSKate Stone class CommandOptions : public Options { 12435a988416SJim Ingham public: 1244b9c1b51eSKate Stone CommandOptions() : Options(), m_filename(), m_line_num(0) {} 12455a988416SJim Ingham 12469e85e5a8SEugene Zelenko ~CommandOptions() override = default; 12475a988416SJim Ingham 124897206d57SZachary Turner Status SetOptionValue(uint32_t option_idx, llvm::StringRef option_arg, 1249b9c1b51eSKate Stone ExecutionContext *execution_context) override { 125097206d57SZachary Turner Status error; 12513bcdfc0eSGreg Clayton const int short_option = m_getopt_table[option_idx].val; 12525a988416SJim Ingham 1253b9c1b51eSKate Stone switch (short_option) { 12545a988416SJim Ingham case 'f': 12555a988416SJim Ingham m_filename.assign(option_arg); 12565a988416SJim Ingham break; 12575a988416SJim Ingham 12585a988416SJim Ingham case 'l': 1259fe11483bSZachary Turner option_arg.getAsInteger(0, m_line_num); 12605a988416SJim Ingham break; 12615a988416SJim Ingham 12625a988416SJim Ingham default: 126336162014SRaphael Isemann llvm_unreachable("Unimplemented option"); 12645a988416SJim Ingham } 12655a988416SJim Ingham 12665a988416SJim Ingham return error; 12675a988416SJim Ingham } 12685a988416SJim Ingham 1269b9c1b51eSKate Stone void OptionParsingStarting(ExecutionContext *execution_context) override { 12705a988416SJim Ingham m_filename.clear(); 12715a988416SJim Ingham m_line_num = 0; 12725a988416SJim Ingham } 12735a988416SJim Ingham 12741f0f5b5bSZachary Turner llvm::ArrayRef<OptionDefinition> GetDefinitions() override { 127570602439SZachary Turner return llvm::makeArrayRef(g_breakpoint_clear_options); 12761f0f5b5bSZachary Turner } 12775a988416SJim Ingham 12785a988416SJim Ingham // Instance variables to hold the values for command options. 12795a988416SJim Ingham 12805a988416SJim Ingham std::string m_filename; 12815a988416SJim Ingham uint32_t m_line_num; 12825a988416SJim Ingham }; 12835a988416SJim Ingham 12845a988416SJim Ingham protected: 1285b9c1b51eSKate Stone bool DoExecute(Args &command, CommandReturnObject &result) override { 1286cb2380c9SRaphael Isemann Target &target = GetSelectedOrDummyTarget(); 12875a988416SJim Ingham 128805097246SAdrian Prantl // The following are the various types of breakpoints that could be 128905097246SAdrian Prantl // cleared: 12905a988416SJim Ingham // 1). -f -l (clearing breakpoint by source location) 12915a988416SJim Ingham 12925a988416SJim Ingham BreakpointClearType break_type = eClearTypeInvalid; 12935a988416SJim Ingham 12945a988416SJim Ingham if (m_options.m_line_num != 0) 12955a988416SJim Ingham break_type = eClearTypeFileAndLine; 12965a988416SJim Ingham 1297bb19a13cSSaleem Abdulrasool std::unique_lock<std::recursive_mutex> lock; 1298cb2380c9SRaphael Isemann target.GetBreakpointList().GetListMutex(lock); 12995a988416SJim Ingham 1300cb2380c9SRaphael Isemann BreakpointList &breakpoints = target.GetBreakpointList(); 13015a988416SJim Ingham size_t num_breakpoints = breakpoints.GetSize(); 13025a988416SJim Ingham 13035a988416SJim Ingham // Early return if there's no breakpoint at all. 1304b9c1b51eSKate Stone if (num_breakpoints == 0) { 13055a988416SJim Ingham result.AppendError("Breakpoint clear: No breakpoint cleared."); 13065a988416SJim Ingham result.SetStatus(eReturnStatusFailed); 13075a988416SJim Ingham return result.Succeeded(); 13085a988416SJim Ingham } 13095a988416SJim Ingham 13105a988416SJim Ingham // Find matching breakpoints and delete them. 13115a988416SJim Ingham 13125a988416SJim Ingham // First create a copy of all the IDs. 13135a988416SJim Ingham std::vector<break_id_t> BreakIDs; 13145a988416SJim Ingham for (size_t i = 0; i < num_breakpoints; ++i) 13159e85e5a8SEugene Zelenko BreakIDs.push_back(breakpoints.GetBreakpointAtIndex(i)->GetID()); 13165a988416SJim Ingham 13175a988416SJim Ingham int num_cleared = 0; 13185a988416SJim Ingham StreamString ss; 1319b9c1b51eSKate Stone switch (break_type) { 13205a988416SJim Ingham case eClearTypeFileAndLine: // Breakpoint by source position 13215a988416SJim Ingham { 13225a988416SJim Ingham const ConstString filename(m_options.m_filename.c_str()); 13235a988416SJim Ingham BreakpointLocationCollection loc_coll; 13245a988416SJim Ingham 1325b9c1b51eSKate Stone for (size_t i = 0; i < num_breakpoints; ++i) { 13265a988416SJim Ingham Breakpoint *bp = breakpoints.FindBreakpointByID(BreakIDs[i]).get(); 13275a988416SJim Ingham 1328b9c1b51eSKate Stone if (bp->GetMatchingFileLine(filename, m_options.m_line_num, loc_coll)) { 1329b9c1b51eSKate Stone // If the collection size is 0, it's a full match and we can just 1330b9c1b51eSKate Stone // remove the breakpoint. 1331b9c1b51eSKate Stone if (loc_coll.GetSize() == 0) { 13325a988416SJim Ingham bp->GetDescription(&ss, lldb::eDescriptionLevelBrief); 13335a988416SJim Ingham ss.EOL(); 1334cb2380c9SRaphael Isemann target.RemoveBreakpointByID(bp->GetID()); 13355a988416SJim Ingham ++num_cleared; 13365a988416SJim Ingham } 13375a988416SJim Ingham } 13385a988416SJim Ingham } 1339b9c1b51eSKate Stone } break; 13405a988416SJim Ingham 13415a988416SJim Ingham default: 13425a988416SJim Ingham break; 13435a988416SJim Ingham } 13445a988416SJim Ingham 1345b9c1b51eSKate Stone if (num_cleared > 0) { 13465a988416SJim Ingham Stream &output_stream = result.GetOutputStream(); 13475a988416SJim Ingham output_stream.Printf("%d breakpoints cleared:\n", num_cleared); 1348c156427dSZachary Turner output_stream << ss.GetString(); 13495a988416SJim Ingham output_stream.EOL(); 13505a988416SJim Ingham result.SetStatus(eReturnStatusSuccessFinishNoResult); 1351b9c1b51eSKate Stone } else { 13525a988416SJim Ingham result.AppendError("Breakpoint clear: No breakpoint cleared."); 13535a988416SJim Ingham result.SetStatus(eReturnStatusFailed); 13545a988416SJim Ingham } 13555a988416SJim Ingham 13565a988416SJim Ingham return result.Succeeded(); 13575a988416SJim Ingham } 13585a988416SJim Ingham 13595a988416SJim Ingham private: 13605a988416SJim Ingham CommandOptions m_options; 13615a988416SJim Ingham }; 13625a988416SJim Ingham 13635a988416SJim Ingham // CommandObjectBreakpointDelete 1364f94668e3SRaphael Isemann #define LLDB_OPTIONS_breakpoint_delete 1365f94668e3SRaphael Isemann #include "CommandOptions.inc" 13661f0f5b5bSZachary Turner 13675a988416SJim Ingham #pragma mark Delete 13685a988416SJim Ingham 1369b9c1b51eSKate Stone class CommandObjectBreakpointDelete : public CommandObjectParsed { 13705a988416SJim Ingham public: 1371b9c1b51eSKate Stone CommandObjectBreakpointDelete(CommandInterpreter &interpreter) 1372b9c1b51eSKate Stone : CommandObjectParsed(interpreter, "breakpoint delete", 1373b9c1b51eSKate Stone "Delete the specified breakpoint(s). If no " 1374b9c1b51eSKate Stone "breakpoints are specified, delete them all.", 13759e85e5a8SEugene Zelenko nullptr), 1376b9c1b51eSKate Stone m_options() { 13775a988416SJim Ingham CommandArgumentEntry arg; 1378b9c1b51eSKate Stone CommandObject::AddIDsArgumentData(arg, eArgTypeBreakpointID, 1379b9c1b51eSKate Stone eArgTypeBreakpointIDRange); 1380b9c1b51eSKate Stone // Add the entry for the first argument for this command to the object's 1381b9c1b51eSKate Stone // arguments vector. 13825a988416SJim Ingham m_arguments.push_back(arg); 13835a988416SJim Ingham } 13845a988416SJim Ingham 13859e85e5a8SEugene Zelenko ~CommandObjectBreakpointDelete() override = default; 13865a988416SJim Ingham 1387b9c1b51eSKate Stone Options *GetOptions() override { return &m_options; } 138833df7cd3SJim Ingham 1389b9c1b51eSKate Stone class CommandOptions : public Options { 139033df7cd3SJim Ingham public: 1391b9c1b51eSKate Stone CommandOptions() : Options(), m_use_dummy(false), m_force(false) {} 139233df7cd3SJim Ingham 13939e85e5a8SEugene Zelenko ~CommandOptions() override = default; 139433df7cd3SJim Ingham 139597206d57SZachary Turner Status SetOptionValue(uint32_t option_idx, llvm::StringRef option_arg, 1396b9c1b51eSKate Stone ExecutionContext *execution_context) override { 139797206d57SZachary Turner Status error; 139833df7cd3SJim Ingham const int short_option = m_getopt_table[option_idx].val; 139933df7cd3SJim Ingham 1400b9c1b51eSKate Stone switch (short_option) { 140133df7cd3SJim Ingham case 'f': 140233df7cd3SJim Ingham m_force = true; 140333df7cd3SJim Ingham break; 140433df7cd3SJim Ingham 140533df7cd3SJim Ingham case 'D': 140633df7cd3SJim Ingham m_use_dummy = true; 140733df7cd3SJim Ingham break; 140833df7cd3SJim Ingham 140933df7cd3SJim Ingham default: 141036162014SRaphael Isemann llvm_unreachable("Unimplemented option"); 141133df7cd3SJim Ingham } 141233df7cd3SJim Ingham 141333df7cd3SJim Ingham return error; 141433df7cd3SJim Ingham } 141533df7cd3SJim Ingham 1416b9c1b51eSKate Stone void OptionParsingStarting(ExecutionContext *execution_context) override { 141733df7cd3SJim Ingham m_use_dummy = false; 141833df7cd3SJim Ingham m_force = false; 141933df7cd3SJim Ingham } 142033df7cd3SJim Ingham 14211f0f5b5bSZachary Turner llvm::ArrayRef<OptionDefinition> GetDefinitions() override { 142270602439SZachary Turner return llvm::makeArrayRef(g_breakpoint_delete_options); 14231f0f5b5bSZachary Turner } 142433df7cd3SJim Ingham 142533df7cd3SJim Ingham // Instance variables to hold the values for command options. 142633df7cd3SJim Ingham bool m_use_dummy; 142733df7cd3SJim Ingham bool m_force; 142833df7cd3SJim Ingham }; 142933df7cd3SJim Ingham 14305a988416SJim Ingham protected: 1431b9c1b51eSKate Stone bool DoExecute(Args &command, CommandReturnObject &result) override { 1432cb2380c9SRaphael Isemann Target &target = GetSelectedOrDummyTarget(m_options.m_use_dummy); 14335a988416SJim Ingham 1434bb19a13cSSaleem Abdulrasool std::unique_lock<std::recursive_mutex> lock; 1435cb2380c9SRaphael Isemann target.GetBreakpointList().GetListMutex(lock); 14365a988416SJim Ingham 1437cb2380c9SRaphael Isemann const BreakpointList &breakpoints = target.GetBreakpointList(); 14385a988416SJim Ingham 14395a988416SJim Ingham size_t num_breakpoints = breakpoints.GetSize(); 14405a988416SJim Ingham 1441b9c1b51eSKate Stone if (num_breakpoints == 0) { 14425a988416SJim Ingham result.AppendError("No breakpoints exist to be deleted."); 14435a988416SJim Ingham result.SetStatus(eReturnStatusFailed); 14445a988416SJim Ingham return false; 14455a988416SJim Ingham } 14465a988416SJim Ingham 144711eb9c64SZachary Turner if (command.empty()) { 1448b9c1b51eSKate Stone if (!m_options.m_force && 1449b9c1b51eSKate Stone !m_interpreter.Confirm( 1450b9c1b51eSKate Stone "About to delete all breakpoints, do you want to do that?", 1451b9c1b51eSKate Stone true)) { 14525a988416SJim Ingham result.AppendMessage("Operation cancelled..."); 1453b9c1b51eSKate Stone } else { 1454cb2380c9SRaphael Isemann target.RemoveAllowedBreakpoints(); 1455b9c1b51eSKate Stone result.AppendMessageWithFormat( 1456b9c1b51eSKate Stone "All breakpoints removed. (%" PRIu64 " breakpoint%s)\n", 1457b9c1b51eSKate Stone (uint64_t)num_breakpoints, num_breakpoints > 1 ? "s" : ""); 14585a988416SJim Ingham } 14595a988416SJim Ingham result.SetStatus(eReturnStatusSuccessFinishNoResult); 1460b9c1b51eSKate Stone } else { 14615a988416SJim Ingham // Particular breakpoint selected; disable that breakpoint. 14625a988416SJim Ingham BreakpointIDList valid_bp_ids; 1463b9c1b51eSKate Stone CommandObjectMultiwordBreakpoint::VerifyBreakpointOrLocationIDs( 1464cb2380c9SRaphael Isemann command, &target, result, &valid_bp_ids, 1465b842f2ecSJim Ingham BreakpointName::Permissions::PermissionKinds::deletePerm); 14665a988416SJim Ingham 1467b9c1b51eSKate Stone if (result.Succeeded()) { 14685a988416SJim Ingham int delete_count = 0; 14695a988416SJim Ingham int disable_count = 0; 14705a988416SJim Ingham const size_t count = valid_bp_ids.GetSize(); 1471b9c1b51eSKate Stone for (size_t i = 0; i < count; ++i) { 14725a988416SJim Ingham BreakpointID cur_bp_id = valid_bp_ids.GetBreakpointIDAtIndex(i); 14735a988416SJim Ingham 1474b9c1b51eSKate Stone if (cur_bp_id.GetBreakpointID() != LLDB_INVALID_BREAK_ID) { 1475b9c1b51eSKate Stone if (cur_bp_id.GetLocationID() != LLDB_INVALID_BREAK_ID) { 1476b9c1b51eSKate Stone Breakpoint *breakpoint = 1477cb2380c9SRaphael Isemann target.GetBreakpointByID(cur_bp_id.GetBreakpointID()).get(); 1478b9c1b51eSKate Stone BreakpointLocation *location = 1479b9c1b51eSKate Stone breakpoint->FindLocationByID(cur_bp_id.GetLocationID()).get(); 1480b9c1b51eSKate Stone // It makes no sense to try to delete individual locations, so we 1481b9c1b51eSKate Stone // disable them instead. 1482b9c1b51eSKate Stone if (location) { 14835a988416SJim Ingham location->SetEnabled(false); 14845a988416SJim Ingham ++disable_count; 14855a988416SJim Ingham } 1486b9c1b51eSKate Stone } else { 1487cb2380c9SRaphael Isemann target.RemoveBreakpointByID(cur_bp_id.GetBreakpointID()); 14885a988416SJim Ingham ++delete_count; 14895a988416SJim Ingham } 14905a988416SJim Ingham } 14915a988416SJim Ingham } 1492b9c1b51eSKate Stone result.AppendMessageWithFormat( 1493b9c1b51eSKate Stone "%d breakpoints deleted; %d breakpoint locations disabled.\n", 14945a988416SJim Ingham delete_count, disable_count); 14955a988416SJim Ingham result.SetStatus(eReturnStatusSuccessFinishNoResult); 14965a988416SJim Ingham } 14975a988416SJim Ingham } 14985a988416SJim Ingham return result.Succeeded(); 14995a988416SJim Ingham } 15009e85e5a8SEugene Zelenko 150133df7cd3SJim Ingham private: 150233df7cd3SJim Ingham CommandOptions m_options; 150333df7cd3SJim Ingham }; 150433df7cd3SJim Ingham 15055e09c8c3SJim Ingham // CommandObjectBreakpointName 1506f94668e3SRaphael Isemann #define LLDB_OPTIONS_breakpoint_name 1507f94668e3SRaphael Isemann #include "CommandOptions.inc" 1508bd68a052SRaphael Isemann 1509b9c1b51eSKate Stone class BreakpointNameOptionGroup : public OptionGroup { 15105e09c8c3SJim Ingham public: 1511b9c1b51eSKate Stone BreakpointNameOptionGroup() 1512b9c1b51eSKate Stone : OptionGroup(), m_breakpoint(LLDB_INVALID_BREAK_ID), m_use_dummy(false) { 15135e09c8c3SJim Ingham } 15145e09c8c3SJim Ingham 15159e85e5a8SEugene Zelenko ~BreakpointNameOptionGroup() override = default; 15165e09c8c3SJim Ingham 15171f0f5b5bSZachary Turner llvm::ArrayRef<OptionDefinition> GetDefinitions() override { 151870602439SZachary Turner return llvm::makeArrayRef(g_breakpoint_name_options); 15195e09c8c3SJim Ingham } 15205e09c8c3SJim Ingham 152197206d57SZachary Turner Status SetOptionValue(uint32_t option_idx, llvm::StringRef option_arg, 1522b9c1b51eSKate Stone ExecutionContext *execution_context) override { 152397206d57SZachary Turner Status error; 15245e09c8c3SJim Ingham const int short_option = g_breakpoint_name_options[option_idx].short_option; 15255e09c8c3SJim Ingham 1526b9c1b51eSKate Stone switch (short_option) { 15275e09c8c3SJim Ingham case 'N': 1528fe11483bSZachary Turner if (BreakpointID::StringIsBreakpointName(option_arg, error) && 1529b9c1b51eSKate Stone error.Success()) 1530fe11483bSZachary Turner m_name.SetValueFromString(option_arg); 15315e09c8c3SJim Ingham break; 15325e09c8c3SJim Ingham case 'B': 1533fe11483bSZachary Turner if (m_breakpoint.SetValueFromString(option_arg).Fail()) 1534b9c1b51eSKate Stone error.SetErrorStringWithFormat( 15358cef4b0bSZachary Turner "unrecognized value \"%s\" for breakpoint", 1536fe11483bSZachary Turner option_arg.str().c_str()); 15375e09c8c3SJim Ingham break; 15385e09c8c3SJim Ingham case 'D': 1539fe11483bSZachary Turner if (m_use_dummy.SetValueFromString(option_arg).Fail()) 1540b9c1b51eSKate Stone error.SetErrorStringWithFormat( 15418cef4b0bSZachary Turner "unrecognized value \"%s\" for use-dummy", 1542fe11483bSZachary Turner option_arg.str().c_str()); 15435e09c8c3SJim Ingham break; 1544e9632ebaSJim Ingham case 'H': 1545e9632ebaSJim Ingham m_help_string.SetValueFromString(option_arg); 1546e9632ebaSJim Ingham break; 15475e09c8c3SJim Ingham 15485e09c8c3SJim Ingham default: 154936162014SRaphael Isemann llvm_unreachable("Unimplemented option"); 15505e09c8c3SJim Ingham } 15515e09c8c3SJim Ingham return error; 15525e09c8c3SJim Ingham } 15535e09c8c3SJim Ingham 1554b9c1b51eSKate Stone void OptionParsingStarting(ExecutionContext *execution_context) override { 15555e09c8c3SJim Ingham m_name.Clear(); 15565e09c8c3SJim Ingham m_breakpoint.Clear(); 15575e09c8c3SJim Ingham m_use_dummy.Clear(); 15585e09c8c3SJim Ingham m_use_dummy.SetDefaultValue(false); 1559e9632ebaSJim Ingham m_help_string.Clear(); 15605e09c8c3SJim Ingham } 15615e09c8c3SJim Ingham 15625e09c8c3SJim Ingham OptionValueString m_name; 15635e09c8c3SJim Ingham OptionValueUInt64 m_breakpoint; 15645e09c8c3SJim Ingham OptionValueBoolean m_use_dummy; 1565e9632ebaSJim Ingham OptionValueString m_help_string; 15665e09c8c3SJim Ingham }; 15675e09c8c3SJim Ingham 1568f94668e3SRaphael Isemann #define LLDB_OPTIONS_breakpoint_access 1569f94668e3SRaphael Isemann #include "CommandOptions.inc" 1570b842f2ecSJim Ingham 15718fe53c49STatyana Krasnukha class BreakpointAccessOptionGroup : public OptionGroup { 1572b842f2ecSJim Ingham public: 15738fe53c49STatyana Krasnukha BreakpointAccessOptionGroup() : OptionGroup() {} 1574b842f2ecSJim Ingham 1575b842f2ecSJim Ingham ~BreakpointAccessOptionGroup() override = default; 1576b842f2ecSJim Ingham 1577b842f2ecSJim Ingham llvm::ArrayRef<OptionDefinition> GetDefinitions() override { 1578b842f2ecSJim Ingham return llvm::makeArrayRef(g_breakpoint_access_options); 1579b842f2ecSJim Ingham } 1580b842f2ecSJim Ingham Status SetOptionValue(uint32_t option_idx, llvm::StringRef option_arg, 1581b842f2ecSJim Ingham ExecutionContext *execution_context) override { 1582b842f2ecSJim Ingham Status error; 1583b842f2ecSJim Ingham const int short_option 1584b842f2ecSJim Ingham = g_breakpoint_access_options[option_idx].short_option; 1585b842f2ecSJim Ingham 1586b842f2ecSJim Ingham switch (short_option) { 1587b842f2ecSJim Ingham case 'L': { 1588b842f2ecSJim Ingham bool value, success; 158947cbf4a0SPavel Labath value = OptionArgParser::ToBoolean(option_arg, false, &success); 1590b842f2ecSJim Ingham if (success) { 1591b842f2ecSJim Ingham m_permissions.SetAllowList(value); 1592b842f2ecSJim Ingham } else 1593b842f2ecSJim Ingham error.SetErrorStringWithFormat( 1594b842f2ecSJim Ingham "invalid boolean value '%s' passed for -L option", 1595b842f2ecSJim Ingham option_arg.str().c_str()); 1596b842f2ecSJim Ingham } break; 1597b842f2ecSJim Ingham case 'A': { 1598b842f2ecSJim Ingham bool value, success; 159947cbf4a0SPavel Labath value = OptionArgParser::ToBoolean(option_arg, false, &success); 1600b842f2ecSJim Ingham if (success) { 1601b842f2ecSJim Ingham m_permissions.SetAllowDisable(value); 1602b842f2ecSJim Ingham } else 1603b842f2ecSJim Ingham error.SetErrorStringWithFormat( 1604b842f2ecSJim Ingham "invalid boolean value '%s' passed for -L option", 1605b842f2ecSJim Ingham option_arg.str().c_str()); 1606b842f2ecSJim Ingham } break; 1607b842f2ecSJim Ingham case 'D': { 1608b842f2ecSJim Ingham bool value, success; 160947cbf4a0SPavel Labath value = OptionArgParser::ToBoolean(option_arg, false, &success); 1610b842f2ecSJim Ingham if (success) { 1611b842f2ecSJim Ingham m_permissions.SetAllowDelete(value); 1612b842f2ecSJim Ingham } else 1613b842f2ecSJim Ingham error.SetErrorStringWithFormat( 1614b842f2ecSJim Ingham "invalid boolean value '%s' passed for -L option", 1615b842f2ecSJim Ingham option_arg.str().c_str()); 1616b842f2ecSJim Ingham } break; 161736162014SRaphael Isemann default: 161836162014SRaphael Isemann llvm_unreachable("Unimplemented option"); 1619b842f2ecSJim Ingham } 1620b842f2ecSJim Ingham 1621b842f2ecSJim Ingham return error; 1622b842f2ecSJim Ingham } 1623b842f2ecSJim Ingham 1624b842f2ecSJim Ingham void OptionParsingStarting(ExecutionContext *execution_context) override { 1625b842f2ecSJim Ingham } 1626b842f2ecSJim Ingham 1627b842f2ecSJim Ingham const BreakpointName::Permissions &GetPermissions() const 1628b842f2ecSJim Ingham { 1629b842f2ecSJim Ingham return m_permissions; 1630b842f2ecSJim Ingham } 1631b842f2ecSJim Ingham BreakpointName::Permissions m_permissions; 1632b842f2ecSJim Ingham }; 1633b842f2ecSJim Ingham 1634b842f2ecSJim Ingham class CommandObjectBreakpointNameConfigure : public CommandObjectParsed { 1635b842f2ecSJim Ingham public: 1636b842f2ecSJim Ingham CommandObjectBreakpointNameConfigure(CommandInterpreter &interpreter) 1637b842f2ecSJim Ingham : CommandObjectParsed( 1638b842f2ecSJim Ingham interpreter, "configure", "Configure the options for the breakpoint" 1639b842f2ecSJim Ingham " name provided. " 1640b842f2ecSJim Ingham "If you provide a breakpoint id, the options will be copied from " 1641b842f2ecSJim Ingham "the breakpoint, otherwise only the options specified will be set " 1642b842f2ecSJim Ingham "on the name.", 1643b842f2ecSJim Ingham "breakpoint name configure <command-options> " 1644b842f2ecSJim Ingham "<breakpoint-name-list>"), 1645b842f2ecSJim Ingham m_bp_opts(), m_option_group() { 1646b842f2ecSJim Ingham // Create the first variant for the first (and only) argument for this 1647b842f2ecSJim Ingham // command. 1648b842f2ecSJim Ingham CommandArgumentEntry arg1; 1649b842f2ecSJim Ingham CommandArgumentData id_arg; 1650b842f2ecSJim Ingham id_arg.arg_type = eArgTypeBreakpointName; 1651b842f2ecSJim Ingham id_arg.arg_repetition = eArgRepeatOptional; 1652b842f2ecSJim Ingham arg1.push_back(id_arg); 1653b842f2ecSJim Ingham m_arguments.push_back(arg1); 1654b842f2ecSJim Ingham 1655b842f2ecSJim Ingham m_option_group.Append(&m_bp_opts, 1656b842f2ecSJim Ingham LLDB_OPT_SET_ALL, 1657b842f2ecSJim Ingham LLDB_OPT_SET_1); 1658b842f2ecSJim Ingham m_option_group.Append(&m_access_options, 1659b842f2ecSJim Ingham LLDB_OPT_SET_ALL, 1660b842f2ecSJim Ingham LLDB_OPT_SET_ALL); 1661e9632ebaSJim Ingham m_option_group.Append(&m_bp_id, 1662e9632ebaSJim Ingham LLDB_OPT_SET_2|LLDB_OPT_SET_4, 1663e9632ebaSJim Ingham LLDB_OPT_SET_ALL); 1664b842f2ecSJim Ingham m_option_group.Finalize(); 1665b842f2ecSJim Ingham } 1666b842f2ecSJim Ingham 1667b842f2ecSJim Ingham ~CommandObjectBreakpointNameConfigure() override = default; 1668b842f2ecSJim Ingham 1669b842f2ecSJim Ingham Options *GetOptions() override { return &m_option_group; } 1670b842f2ecSJim Ingham 1671b842f2ecSJim Ingham protected: 1672b842f2ecSJim Ingham bool DoExecute(Args &command, CommandReturnObject &result) override { 1673b842f2ecSJim Ingham 1674b842f2ecSJim Ingham const size_t argc = command.GetArgumentCount(); 1675b842f2ecSJim Ingham if (argc == 0) { 1676b842f2ecSJim Ingham result.AppendError("No names provided."); 1677b842f2ecSJim Ingham result.SetStatus(eReturnStatusFailed); 1678b842f2ecSJim Ingham return false; 1679b842f2ecSJim Ingham } 1680b842f2ecSJim Ingham 1681cb2380c9SRaphael Isemann Target &target = GetSelectedOrDummyTarget(false); 1682b842f2ecSJim Ingham 1683b842f2ecSJim Ingham std::unique_lock<std::recursive_mutex> lock; 1684cb2380c9SRaphael Isemann target.GetBreakpointList().GetListMutex(lock); 1685b842f2ecSJim Ingham 1686b842f2ecSJim Ingham // Make a pass through first to see that all the names are legal. 1687b842f2ecSJim Ingham for (auto &entry : command.entries()) { 1688b842f2ecSJim Ingham Status error; 16890d9a201eSRaphael Isemann if (!BreakpointID::StringIsBreakpointName(entry.ref(), error)) 1690b842f2ecSJim Ingham { 1691b842f2ecSJim Ingham result.AppendErrorWithFormat("Invalid breakpoint name: %s - %s", 1692b842f2ecSJim Ingham entry.c_str(), error.AsCString()); 1693b842f2ecSJim Ingham result.SetStatus(eReturnStatusFailed); 1694b842f2ecSJim Ingham return false; 1695b842f2ecSJim Ingham } 1696b842f2ecSJim Ingham } 169705097246SAdrian Prantl // Now configure them, we already pre-checked the names so we don't need to 169805097246SAdrian Prantl // check the error: 1699b842f2ecSJim Ingham BreakpointSP bp_sp; 1700b842f2ecSJim Ingham if (m_bp_id.m_breakpoint.OptionWasSet()) 1701b842f2ecSJim Ingham { 1702b842f2ecSJim Ingham lldb::break_id_t bp_id = m_bp_id.m_breakpoint.GetUInt64Value(); 1703cb2380c9SRaphael Isemann bp_sp = target.GetBreakpointByID(bp_id); 1704b842f2ecSJim Ingham if (!bp_sp) 1705b842f2ecSJim Ingham { 1706b842f2ecSJim Ingham result.AppendErrorWithFormatv("Could not find specified breakpoint {0}", 1707b842f2ecSJim Ingham bp_id); 1708b842f2ecSJim Ingham result.SetStatus(eReturnStatusFailed); 1709b842f2ecSJim Ingham return false; 1710b842f2ecSJim Ingham } 1711b842f2ecSJim Ingham } 1712b842f2ecSJim Ingham 1713b842f2ecSJim Ingham Status error; 1714b842f2ecSJim Ingham for (auto &entry : command.entries()) { 1715b842f2ecSJim Ingham ConstString name(entry.c_str()); 1716cb2380c9SRaphael Isemann BreakpointName *bp_name = target.FindBreakpointName(name, true, error); 1717b842f2ecSJim Ingham if (!bp_name) 1718b842f2ecSJim Ingham continue; 1719e9632ebaSJim Ingham if (m_bp_id.m_help_string.OptionWasSet()) 1720e9632ebaSJim Ingham bp_name->SetHelp(m_bp_id.m_help_string.GetStringValue().str().c_str()); 1721e9632ebaSJim Ingham 1722b842f2ecSJim Ingham if (bp_sp) 1723cb2380c9SRaphael Isemann target.ConfigureBreakpointName(*bp_name, *bp_sp->GetOptions(), 1724b842f2ecSJim Ingham m_access_options.GetPermissions()); 1725b842f2ecSJim Ingham else 1726cb2380c9SRaphael Isemann target.ConfigureBreakpointName(*bp_name, 1727b842f2ecSJim Ingham m_bp_opts.GetBreakpointOptions(), 1728b842f2ecSJim Ingham m_access_options.GetPermissions()); 1729b842f2ecSJim Ingham } 1730b842f2ecSJim Ingham return true; 1731b842f2ecSJim Ingham } 1732b842f2ecSJim Ingham 1733b842f2ecSJim Ingham private: 1734b842f2ecSJim Ingham BreakpointNameOptionGroup m_bp_id; // Only using the id part of this. 1735b842f2ecSJim Ingham BreakpointOptionGroup m_bp_opts; 1736b842f2ecSJim Ingham BreakpointAccessOptionGroup m_access_options; 1737b842f2ecSJim Ingham OptionGroupOptions m_option_group; 1738b842f2ecSJim Ingham }; 1739b842f2ecSJim Ingham 1740b9c1b51eSKate Stone class CommandObjectBreakpointNameAdd : public CommandObjectParsed { 17415e09c8c3SJim Ingham public: 1742b9c1b51eSKate Stone CommandObjectBreakpointNameAdd(CommandInterpreter &interpreter) 1743b9c1b51eSKate Stone : CommandObjectParsed( 1744b9c1b51eSKate Stone interpreter, "add", "Add a name to the breakpoints provided.", 17455e09c8c3SJim Ingham "breakpoint name add <command-options> <breakpoint-id-list>"), 1746b9c1b51eSKate Stone m_name_options(), m_option_group() { 1747b9c1b51eSKate Stone // Create the first variant for the first (and only) argument for this 1748b9c1b51eSKate Stone // command. 17495e09c8c3SJim Ingham CommandArgumentEntry arg1; 17505e09c8c3SJim Ingham CommandArgumentData id_arg; 17515e09c8c3SJim Ingham id_arg.arg_type = eArgTypeBreakpointID; 17525e09c8c3SJim Ingham id_arg.arg_repetition = eArgRepeatOptional; 17535e09c8c3SJim Ingham arg1.push_back(id_arg); 17545e09c8c3SJim Ingham m_arguments.push_back(arg1); 17555e09c8c3SJim Ingham 17565e09c8c3SJim Ingham m_option_group.Append(&m_name_options, LLDB_OPT_SET_1, LLDB_OPT_SET_ALL); 17575e09c8c3SJim Ingham m_option_group.Finalize(); 17585e09c8c3SJim Ingham } 17595e09c8c3SJim Ingham 17609e85e5a8SEugene Zelenko ~CommandObjectBreakpointNameAdd() override = default; 17615e09c8c3SJim Ingham 1762b9c1b51eSKate Stone Options *GetOptions() override { return &m_option_group; } 17635e09c8c3SJim Ingham 17645e09c8c3SJim Ingham protected: 1765b9c1b51eSKate Stone bool DoExecute(Args &command, CommandReturnObject &result) override { 1766b9c1b51eSKate Stone if (!m_name_options.m_name.OptionWasSet()) { 17675e09c8c3SJim Ingham result.SetError("No name option provided."); 17685e09c8c3SJim Ingham return false; 17695e09c8c3SJim Ingham } 17705e09c8c3SJim Ingham 1771cb2380c9SRaphael Isemann Target &target = 1772b9c1b51eSKate Stone GetSelectedOrDummyTarget(m_name_options.m_use_dummy.GetCurrentValue()); 17735e09c8c3SJim Ingham 1774bb19a13cSSaleem Abdulrasool std::unique_lock<std::recursive_mutex> lock; 1775cb2380c9SRaphael Isemann target.GetBreakpointList().GetListMutex(lock); 17765e09c8c3SJim Ingham 1777cb2380c9SRaphael Isemann const BreakpointList &breakpoints = target.GetBreakpointList(); 17785e09c8c3SJim Ingham 17795e09c8c3SJim Ingham size_t num_breakpoints = breakpoints.GetSize(); 1780b9c1b51eSKate Stone if (num_breakpoints == 0) { 17815e09c8c3SJim Ingham result.SetError("No breakpoints, cannot add names."); 17825e09c8c3SJim Ingham result.SetStatus(eReturnStatusFailed); 17835e09c8c3SJim Ingham return false; 17845e09c8c3SJim Ingham } 17855e09c8c3SJim Ingham 17865e09c8c3SJim Ingham // Particular breakpoint selected; disable that breakpoint. 17875e09c8c3SJim Ingham BreakpointIDList valid_bp_ids; 1788b9c1b51eSKate Stone CommandObjectMultiwordBreakpoint::VerifyBreakpointIDs( 1789cb2380c9SRaphael Isemann command, &target, result, &valid_bp_ids, 1790b842f2ecSJim Ingham BreakpointName::Permissions::PermissionKinds::listPerm); 17915e09c8c3SJim Ingham 1792b9c1b51eSKate Stone if (result.Succeeded()) { 1793b9c1b51eSKate Stone if (valid_bp_ids.GetSize() == 0) { 17945e09c8c3SJim Ingham result.SetError("No breakpoints specified, cannot add names."); 17955e09c8c3SJim Ingham result.SetStatus(eReturnStatusFailed); 17965e09c8c3SJim Ingham return false; 17975e09c8c3SJim Ingham } 17985e09c8c3SJim Ingham size_t num_valid_ids = valid_bp_ids.GetSize(); 1799b842f2ecSJim Ingham const char *bp_name = m_name_options.m_name.GetCurrentValue(); 1800b842f2ecSJim Ingham Status error; // This error reports illegal names, but we've already 1801b842f2ecSJim Ingham // checked that, so we don't need to check it again here. 1802b9c1b51eSKate Stone for (size_t index = 0; index < num_valid_ids; index++) { 1803b9c1b51eSKate Stone lldb::break_id_t bp_id = 1804b9c1b51eSKate Stone valid_bp_ids.GetBreakpointIDAtIndex(index).GetBreakpointID(); 18055e09c8c3SJim Ingham BreakpointSP bp_sp = breakpoints.FindBreakpointByID(bp_id); 1806cb2380c9SRaphael Isemann target.AddNameToBreakpoint(bp_sp, bp_name, error); 18075e09c8c3SJim Ingham } 18085e09c8c3SJim Ingham } 18095e09c8c3SJim Ingham 18105e09c8c3SJim Ingham return true; 18115e09c8c3SJim Ingham } 18125e09c8c3SJim Ingham 18135e09c8c3SJim Ingham private: 18145e09c8c3SJim Ingham BreakpointNameOptionGroup m_name_options; 18155e09c8c3SJim Ingham OptionGroupOptions m_option_group; 18165e09c8c3SJim Ingham }; 18175e09c8c3SJim Ingham 1818b9c1b51eSKate Stone class CommandObjectBreakpointNameDelete : public CommandObjectParsed { 18195e09c8c3SJim Ingham public: 1820b9c1b51eSKate Stone CommandObjectBreakpointNameDelete(CommandInterpreter &interpreter) 1821b9c1b51eSKate Stone : CommandObjectParsed( 1822b9c1b51eSKate Stone interpreter, "delete", 18235e09c8c3SJim Ingham "Delete a name from the breakpoints provided.", 18245e09c8c3SJim Ingham "breakpoint name delete <command-options> <breakpoint-id-list>"), 1825b9c1b51eSKate Stone m_name_options(), m_option_group() { 1826b9c1b51eSKate Stone // Create the first variant for the first (and only) argument for this 1827b9c1b51eSKate Stone // command. 18285e09c8c3SJim Ingham CommandArgumentEntry arg1; 18295e09c8c3SJim Ingham CommandArgumentData id_arg; 18305e09c8c3SJim Ingham id_arg.arg_type = eArgTypeBreakpointID; 18315e09c8c3SJim Ingham id_arg.arg_repetition = eArgRepeatOptional; 18325e09c8c3SJim Ingham arg1.push_back(id_arg); 18335e09c8c3SJim Ingham m_arguments.push_back(arg1); 18345e09c8c3SJim Ingham 18355e09c8c3SJim Ingham m_option_group.Append(&m_name_options, LLDB_OPT_SET_1, LLDB_OPT_SET_ALL); 18365e09c8c3SJim Ingham m_option_group.Finalize(); 18375e09c8c3SJim Ingham } 18385e09c8c3SJim Ingham 18399e85e5a8SEugene Zelenko ~CommandObjectBreakpointNameDelete() override = default; 18405e09c8c3SJim Ingham 1841b9c1b51eSKate Stone Options *GetOptions() override { return &m_option_group; } 18425e09c8c3SJim Ingham 18435e09c8c3SJim Ingham protected: 1844b9c1b51eSKate Stone bool DoExecute(Args &command, CommandReturnObject &result) override { 1845b9c1b51eSKate Stone if (!m_name_options.m_name.OptionWasSet()) { 18465e09c8c3SJim Ingham result.SetError("No name option provided."); 18475e09c8c3SJim Ingham return false; 18485e09c8c3SJim Ingham } 18495e09c8c3SJim Ingham 1850cb2380c9SRaphael Isemann Target &target = 1851b9c1b51eSKate Stone GetSelectedOrDummyTarget(m_name_options.m_use_dummy.GetCurrentValue()); 18525e09c8c3SJim Ingham 1853bb19a13cSSaleem Abdulrasool std::unique_lock<std::recursive_mutex> lock; 1854cb2380c9SRaphael Isemann target.GetBreakpointList().GetListMutex(lock); 18555e09c8c3SJim Ingham 1856cb2380c9SRaphael Isemann const BreakpointList &breakpoints = target.GetBreakpointList(); 18575e09c8c3SJim Ingham 18585e09c8c3SJim Ingham size_t num_breakpoints = breakpoints.GetSize(); 1859b9c1b51eSKate Stone if (num_breakpoints == 0) { 18605e09c8c3SJim Ingham result.SetError("No breakpoints, cannot delete names."); 18615e09c8c3SJim Ingham result.SetStatus(eReturnStatusFailed); 18625e09c8c3SJim Ingham return false; 18635e09c8c3SJim Ingham } 18645e09c8c3SJim Ingham 18655e09c8c3SJim Ingham // Particular breakpoint selected; disable that breakpoint. 18665e09c8c3SJim Ingham BreakpointIDList valid_bp_ids; 1867b9c1b51eSKate Stone CommandObjectMultiwordBreakpoint::VerifyBreakpointIDs( 1868cb2380c9SRaphael Isemann command, &target, result, &valid_bp_ids, 1869b842f2ecSJim Ingham BreakpointName::Permissions::PermissionKinds::deletePerm); 18705e09c8c3SJim Ingham 1871b9c1b51eSKate Stone if (result.Succeeded()) { 1872b9c1b51eSKate Stone if (valid_bp_ids.GetSize() == 0) { 18735e09c8c3SJim Ingham result.SetError("No breakpoints specified, cannot delete names."); 18745e09c8c3SJim Ingham result.SetStatus(eReturnStatusFailed); 18755e09c8c3SJim Ingham return false; 18765e09c8c3SJim Ingham } 1877b842f2ecSJim Ingham ConstString bp_name(m_name_options.m_name.GetCurrentValue()); 18785e09c8c3SJim Ingham size_t num_valid_ids = valid_bp_ids.GetSize(); 1879b9c1b51eSKate Stone for (size_t index = 0; index < num_valid_ids; index++) { 1880b9c1b51eSKate Stone lldb::break_id_t bp_id = 1881b9c1b51eSKate Stone valid_bp_ids.GetBreakpointIDAtIndex(index).GetBreakpointID(); 18825e09c8c3SJim Ingham BreakpointSP bp_sp = breakpoints.FindBreakpointByID(bp_id); 1883cb2380c9SRaphael Isemann target.RemoveNameFromBreakpoint(bp_sp, bp_name); 18845e09c8c3SJim Ingham } 18855e09c8c3SJim Ingham } 18865e09c8c3SJim Ingham 18875e09c8c3SJim Ingham return true; 18885e09c8c3SJim Ingham } 18895e09c8c3SJim Ingham 18905e09c8c3SJim Ingham private: 18915e09c8c3SJim Ingham BreakpointNameOptionGroup m_name_options; 18925e09c8c3SJim Ingham OptionGroupOptions m_option_group; 18935e09c8c3SJim Ingham }; 18945e09c8c3SJim Ingham 1895b9c1b51eSKate Stone class CommandObjectBreakpointNameList : public CommandObjectParsed { 18965e09c8c3SJim Ingham public: 1897b9c1b51eSKate Stone CommandObjectBreakpointNameList(CommandInterpreter &interpreter) 1898b9c1b51eSKate Stone : CommandObjectParsed(interpreter, "list", 1899b842f2ecSJim Ingham "List either the names for a breakpoint or info " 1900b842f2ecSJim Ingham "about a given name. With no arguments, lists all " 1901b842f2ecSJim Ingham "names", 19025e09c8c3SJim Ingham "breakpoint name list <command-options>"), 1903b9c1b51eSKate Stone m_name_options(), m_option_group() { 1904b842f2ecSJim Ingham m_option_group.Append(&m_name_options, LLDB_OPT_SET_3, LLDB_OPT_SET_ALL); 19055e09c8c3SJim Ingham m_option_group.Finalize(); 19065e09c8c3SJim Ingham } 19075e09c8c3SJim Ingham 19089e85e5a8SEugene Zelenko ~CommandObjectBreakpointNameList() override = default; 19095e09c8c3SJim Ingham 1910b9c1b51eSKate Stone Options *GetOptions() override { return &m_option_group; } 19115e09c8c3SJim Ingham 19125e09c8c3SJim Ingham protected: 1913b9c1b51eSKate Stone bool DoExecute(Args &command, CommandReturnObject &result) override { 1914cb2380c9SRaphael Isemann Target &target = 1915b9c1b51eSKate Stone GetSelectedOrDummyTarget(m_name_options.m_use_dummy.GetCurrentValue()); 19165e09c8c3SJim Ingham 1917b842f2ecSJim Ingham std::vector<std::string> name_list; 1918b842f2ecSJim Ingham if (command.empty()) { 1919cb2380c9SRaphael Isemann target.GetBreakpointNames(name_list); 1920b842f2ecSJim Ingham } else { 1921b842f2ecSJim Ingham for (const Args::ArgEntry &arg : command) 1922b842f2ecSJim Ingham { 1923b842f2ecSJim Ingham name_list.push_back(arg.c_str()); 1924b842f2ecSJim Ingham } 1925b842f2ecSJim Ingham } 1926b842f2ecSJim Ingham 1927b842f2ecSJim Ingham if (name_list.empty()) { 1928b842f2ecSJim Ingham result.AppendMessage("No breakpoint names found."); 1929b842f2ecSJim Ingham } else { 1930b842f2ecSJim Ingham for (const std::string &name_str : name_list) { 1931b842f2ecSJim Ingham const char *name = name_str.c_str(); 1932b842f2ecSJim Ingham // First print out the options for the name: 1933b842f2ecSJim Ingham Status error; 1934cb2380c9SRaphael Isemann BreakpointName *bp_name = 1935cb2380c9SRaphael Isemann target.FindBreakpointName(ConstString(name), false, error); 1936b842f2ecSJim Ingham if (bp_name) 1937b842f2ecSJim Ingham { 1938b842f2ecSJim Ingham StreamString s; 1939b842f2ecSJim Ingham result.AppendMessageWithFormat("Name: %s\n", name); 1940b842f2ecSJim Ingham if (bp_name->GetDescription(&s, eDescriptionLevelFull)) 1941b842f2ecSJim Ingham { 1942b842f2ecSJim Ingham result.AppendMessage(s.GetString()); 1943b842f2ecSJim Ingham } 1944b842f2ecSJim Ingham 1945bb19a13cSSaleem Abdulrasool std::unique_lock<std::recursive_mutex> lock; 1946cb2380c9SRaphael Isemann target.GetBreakpointList().GetListMutex(lock); 19475e09c8c3SJim Ingham 1948cb2380c9SRaphael Isemann BreakpointList &breakpoints = target.GetBreakpointList(); 1949b842f2ecSJim Ingham bool any_set = false; 1950b9c1b51eSKate Stone for (BreakpointSP bp_sp : breakpoints.Breakpoints()) { 1951b9c1b51eSKate Stone if (bp_sp->MatchesName(name)) { 19525e09c8c3SJim Ingham StreamString s; 1953b842f2ecSJim Ingham any_set = true; 19545e09c8c3SJim Ingham bp_sp->GetDescription(&s, eDescriptionLevelBrief); 19555e09c8c3SJim Ingham s.EOL(); 1956c156427dSZachary Turner result.AppendMessage(s.GetString()); 19575e09c8c3SJim Ingham } 19585e09c8c3SJim Ingham } 1959b842f2ecSJim Ingham if (!any_set) 1960b842f2ecSJim Ingham result.AppendMessage("No breakpoints using this name."); 1961b9c1b51eSKate Stone } else { 1962b842f2ecSJim Ingham result.AppendMessageWithFormat("Name: %s not found.\n", name); 19635e09c8c3SJim Ingham } 1964b842f2ecSJim Ingham } 19655e09c8c3SJim Ingham } 19665e09c8c3SJim Ingham return true; 19675e09c8c3SJim Ingham } 19685e09c8c3SJim Ingham 19695e09c8c3SJim Ingham private: 19705e09c8c3SJim Ingham BreakpointNameOptionGroup m_name_options; 19715e09c8c3SJim Ingham OptionGroupOptions m_option_group; 19725e09c8c3SJim Ingham }; 19735e09c8c3SJim Ingham 1974e14dc268SJim Ingham // CommandObjectBreakpointName 1975b9c1b51eSKate Stone class CommandObjectBreakpointName : public CommandObjectMultiword { 19765e09c8c3SJim Ingham public: 19777428a18cSKate Stone CommandObjectBreakpointName(CommandInterpreter &interpreter) 1978b9c1b51eSKate Stone : CommandObjectMultiword( 1979b9c1b51eSKate Stone interpreter, "name", "Commands to manage name tags for breakpoints", 1980b9c1b51eSKate Stone "breakpoint name <subcommand> [<command-options>]") { 1981b9c1b51eSKate Stone CommandObjectSP add_command_object( 1982b9c1b51eSKate Stone new CommandObjectBreakpointNameAdd(interpreter)); 1983b9c1b51eSKate Stone CommandObjectSP delete_command_object( 1984b9c1b51eSKate Stone new CommandObjectBreakpointNameDelete(interpreter)); 1985b9c1b51eSKate Stone CommandObjectSP list_command_object( 1986b9c1b51eSKate Stone new CommandObjectBreakpointNameList(interpreter)); 1987b842f2ecSJim Ingham CommandObjectSP configure_command_object( 1988b842f2ecSJim Ingham new CommandObjectBreakpointNameConfigure(interpreter)); 19895e09c8c3SJim Ingham 19905e09c8c3SJim Ingham LoadSubCommand("add", add_command_object); 19915e09c8c3SJim Ingham LoadSubCommand("delete", delete_command_object); 19925e09c8c3SJim Ingham LoadSubCommand("list", list_command_object); 1993b842f2ecSJim Ingham LoadSubCommand("configure", configure_command_object); 19945e09c8c3SJim Ingham } 19955e09c8c3SJim Ingham 19969e85e5a8SEugene Zelenko ~CommandObjectBreakpointName() override = default; 19975e09c8c3SJim Ingham }; 19985e09c8c3SJim Ingham 1999e14dc268SJim Ingham // CommandObjectBreakpointRead 20003acdf385SJim Ingham #pragma mark Read::CommandOptions 2001f94668e3SRaphael Isemann #define LLDB_OPTIONS_breakpoint_read 2002f94668e3SRaphael Isemann #include "CommandOptions.inc" 20031f0f5b5bSZachary Turner 20041f0f5b5bSZachary Turner #pragma mark Read 2005e14dc268SJim Ingham 2006e14dc268SJim Ingham class CommandObjectBreakpointRead : public CommandObjectParsed { 2007e14dc268SJim Ingham public: 2008e14dc268SJim Ingham CommandObjectBreakpointRead(CommandInterpreter &interpreter) 2009e14dc268SJim Ingham : CommandObjectParsed(interpreter, "breakpoint read", 2010e14dc268SJim Ingham "Read and set the breakpoints previously saved to " 2011e14dc268SJim Ingham "a file with \"breakpoint write\". ", 2012e14dc268SJim Ingham nullptr), 2013e14dc268SJim Ingham m_options() { 2014e14dc268SJim Ingham CommandArgumentEntry arg; 2015e14dc268SJim Ingham CommandObject::AddIDsArgumentData(arg, eArgTypeBreakpointID, 2016e14dc268SJim Ingham eArgTypeBreakpointIDRange); 2017e14dc268SJim Ingham // Add the entry for the first argument for this command to the object's 2018e14dc268SJim Ingham // arguments vector. 2019e14dc268SJim Ingham m_arguments.push_back(arg); 2020e14dc268SJim Ingham } 2021e14dc268SJim Ingham 2022e14dc268SJim Ingham ~CommandObjectBreakpointRead() override = default; 2023e14dc268SJim Ingham 2024e14dc268SJim Ingham Options *GetOptions() override { return &m_options; } 2025e14dc268SJim Ingham 2026e14dc268SJim Ingham class CommandOptions : public Options { 2027e14dc268SJim Ingham public: 2028e14dc268SJim Ingham CommandOptions() : Options() {} 2029e14dc268SJim Ingham 2030e14dc268SJim Ingham ~CommandOptions() override = default; 2031e14dc268SJim Ingham 203297206d57SZachary Turner Status SetOptionValue(uint32_t option_idx, llvm::StringRef option_arg, 2033e14dc268SJim Ingham ExecutionContext *execution_context) override { 203497206d57SZachary Turner Status error; 2035e14dc268SJim Ingham const int short_option = m_getopt_table[option_idx].val; 2036e14dc268SJim Ingham 2037e14dc268SJim Ingham switch (short_option) { 2038e14dc268SJim Ingham case 'f': 2039e14dc268SJim Ingham m_filename.assign(option_arg); 2040e14dc268SJim Ingham break; 20413acdf385SJim Ingham case 'N': { 204297206d57SZachary Turner Status name_error; 20433acdf385SJim Ingham if (!BreakpointID::StringIsBreakpointName(llvm::StringRef(option_arg), 20443acdf385SJim Ingham name_error)) { 20453acdf385SJim Ingham error.SetErrorStringWithFormat("Invalid breakpoint name: %s", 20463acdf385SJim Ingham name_error.AsCString()); 20473acdf385SJim Ingham } 20483acdf385SJim Ingham m_names.push_back(option_arg); 20493acdf385SJim Ingham break; 20503acdf385SJim Ingham } 2051e14dc268SJim Ingham default: 205236162014SRaphael Isemann llvm_unreachable("Unimplemented option"); 2053e14dc268SJim Ingham } 2054e14dc268SJim Ingham 2055e14dc268SJim Ingham return error; 2056e14dc268SJim Ingham } 2057e14dc268SJim Ingham 2058e14dc268SJim Ingham void OptionParsingStarting(ExecutionContext *execution_context) override { 2059e14dc268SJim Ingham m_filename.clear(); 20603acdf385SJim Ingham m_names.clear(); 2061e14dc268SJim Ingham } 2062e14dc268SJim Ingham 20631f0f5b5bSZachary Turner llvm::ArrayRef<OptionDefinition> GetDefinitions() override { 206470602439SZachary Turner return llvm::makeArrayRef(g_breakpoint_read_options); 20651f0f5b5bSZachary Turner } 2066e14dc268SJim Ingham 2067e14dc268SJim Ingham // Instance variables to hold the values for command options. 2068e14dc268SJim Ingham 2069e14dc268SJim Ingham std::string m_filename; 20703acdf385SJim Ingham std::vector<std::string> m_names; 2071e14dc268SJim Ingham }; 2072e14dc268SJim Ingham 2073e14dc268SJim Ingham protected: 2074e14dc268SJim Ingham bool DoExecute(Args &command, CommandReturnObject &result) override { 2075cb2380c9SRaphael Isemann Target &target = GetSelectedOrDummyTarget(); 2076e14dc268SJim Ingham 20773acdf385SJim Ingham std::unique_lock<std::recursive_mutex> lock; 2078cb2380c9SRaphael Isemann target.GetBreakpointList().GetListMutex(lock); 20793acdf385SJim Ingham 20808f3be7a3SJonas Devlieghere FileSpec input_spec(m_options.m_filename); 20818f3be7a3SJonas Devlieghere FileSystem::Instance().Resolve(input_spec); 208201f16664SJim Ingham BreakpointIDList new_bps; 2083cb2380c9SRaphael Isemann Status error = target.CreateBreakpointsFromFile(input_spec, 2084cb2380c9SRaphael Isemann m_options.m_names, new_bps); 2085e14dc268SJim Ingham 2086e14dc268SJim Ingham if (!error.Success()) { 208701f16664SJim Ingham result.AppendError(error.AsCString()); 2088e14dc268SJim Ingham result.SetStatus(eReturnStatusFailed); 208901f16664SJim Ingham return false; 2090e14dc268SJim Ingham } 20913acdf385SJim Ingham 20923acdf385SJim Ingham Stream &output_stream = result.GetOutputStream(); 20933acdf385SJim Ingham 20943acdf385SJim Ingham size_t num_breakpoints = new_bps.GetSize(); 20953acdf385SJim Ingham if (num_breakpoints == 0) { 20963acdf385SJim Ingham result.AppendMessage("No breakpoints added."); 20973acdf385SJim Ingham } else { 20983acdf385SJim Ingham // No breakpoint selected; show info about all currently set breakpoints. 20993acdf385SJim Ingham result.AppendMessage("New breakpoints:"); 21003acdf385SJim Ingham for (size_t i = 0; i < num_breakpoints; ++i) { 21013acdf385SJim Ingham BreakpointID bp_id = new_bps.GetBreakpointIDAtIndex(i); 2102cb2380c9SRaphael Isemann Breakpoint *bp = target.GetBreakpointList() 21033acdf385SJim Ingham .FindBreakpointByID(bp_id.GetBreakpointID()) 21043acdf385SJim Ingham .get(); 21053acdf385SJim Ingham if (bp) 21063acdf385SJim Ingham bp->GetDescription(&output_stream, lldb::eDescriptionLevelInitial, 21073acdf385SJim Ingham false); 21083acdf385SJim Ingham } 21093acdf385SJim Ingham } 2110e14dc268SJim Ingham return result.Succeeded(); 2111e14dc268SJim Ingham } 2112e14dc268SJim Ingham 2113e14dc268SJim Ingham private: 2114e14dc268SJim Ingham CommandOptions m_options; 2115e14dc268SJim Ingham }; 2116e14dc268SJim Ingham 2117e14dc268SJim Ingham // CommandObjectBreakpointWrite 21181f0f5b5bSZachary Turner #pragma mark Write::CommandOptions 2119f94668e3SRaphael Isemann #define LLDB_OPTIONS_breakpoint_write 2120f94668e3SRaphael Isemann #include "CommandOptions.inc" 21211f0f5b5bSZachary Turner 21221f0f5b5bSZachary Turner #pragma mark Write 2123e14dc268SJim Ingham class CommandObjectBreakpointWrite : public CommandObjectParsed { 2124e14dc268SJim Ingham public: 2125e14dc268SJim Ingham CommandObjectBreakpointWrite(CommandInterpreter &interpreter) 2126e14dc268SJim Ingham : CommandObjectParsed(interpreter, "breakpoint write", 2127e14dc268SJim Ingham "Write the breakpoints listed to a file that can " 2128e14dc268SJim Ingham "be read in with \"breakpoint read\". " 2129e14dc268SJim Ingham "If given no arguments, writes all breakpoints.", 2130e14dc268SJim Ingham nullptr), 2131e14dc268SJim Ingham m_options() { 2132e14dc268SJim Ingham CommandArgumentEntry arg; 2133e14dc268SJim Ingham CommandObject::AddIDsArgumentData(arg, eArgTypeBreakpointID, 2134e14dc268SJim Ingham eArgTypeBreakpointIDRange); 2135e14dc268SJim Ingham // Add the entry for the first argument for this command to the object's 2136e14dc268SJim Ingham // arguments vector. 2137e14dc268SJim Ingham m_arguments.push_back(arg); 2138e14dc268SJim Ingham } 2139e14dc268SJim Ingham 2140e14dc268SJim Ingham ~CommandObjectBreakpointWrite() override = default; 2141e14dc268SJim Ingham 2142e14dc268SJim Ingham Options *GetOptions() override { return &m_options; } 2143e14dc268SJim Ingham 2144e14dc268SJim Ingham class CommandOptions : public Options { 2145e14dc268SJim Ingham public: 2146e14dc268SJim Ingham CommandOptions() : Options() {} 2147e14dc268SJim Ingham 2148e14dc268SJim Ingham ~CommandOptions() override = default; 2149e14dc268SJim Ingham 215097206d57SZachary Turner Status SetOptionValue(uint32_t option_idx, llvm::StringRef option_arg, 2151e14dc268SJim Ingham ExecutionContext *execution_context) override { 215297206d57SZachary Turner Status error; 2153e14dc268SJim Ingham const int short_option = m_getopt_table[option_idx].val; 2154e14dc268SJim Ingham 2155e14dc268SJim Ingham switch (short_option) { 2156e14dc268SJim Ingham case 'f': 2157e14dc268SJim Ingham m_filename.assign(option_arg); 2158e14dc268SJim Ingham break; 21592d3628e1SJim Ingham case 'a': 21602d3628e1SJim Ingham m_append = true; 21612d3628e1SJim Ingham break; 2162e14dc268SJim Ingham default: 216336162014SRaphael Isemann llvm_unreachable("Unimplemented option"); 2164e14dc268SJim Ingham } 2165e14dc268SJim Ingham 2166e14dc268SJim Ingham return error; 2167e14dc268SJim Ingham } 2168e14dc268SJim Ingham 2169e14dc268SJim Ingham void OptionParsingStarting(ExecutionContext *execution_context) override { 2170e14dc268SJim Ingham m_filename.clear(); 21712d3628e1SJim Ingham m_append = false; 2172e14dc268SJim Ingham } 2173e14dc268SJim Ingham 21741f0f5b5bSZachary Turner llvm::ArrayRef<OptionDefinition> GetDefinitions() override { 217570602439SZachary Turner return llvm::makeArrayRef(g_breakpoint_write_options); 21761f0f5b5bSZachary Turner } 2177e14dc268SJim Ingham 2178e14dc268SJim Ingham // Instance variables to hold the values for command options. 2179e14dc268SJim Ingham 2180e14dc268SJim Ingham std::string m_filename; 21812d3628e1SJim Ingham bool m_append = false; 2182e14dc268SJim Ingham }; 2183e14dc268SJim Ingham 2184e14dc268SJim Ingham protected: 2185e14dc268SJim Ingham bool DoExecute(Args &command, CommandReturnObject &result) override { 2186cb2380c9SRaphael Isemann Target &target = GetSelectedOrDummyTarget(); 2187e14dc268SJim Ingham 2188e14dc268SJim Ingham std::unique_lock<std::recursive_mutex> lock; 2189cb2380c9SRaphael Isemann target.GetBreakpointList().GetListMutex(lock); 2190e14dc268SJim Ingham 2191e14dc268SJim Ingham BreakpointIDList valid_bp_ids; 219211eb9c64SZachary Turner if (!command.empty()) { 2193e14dc268SJim Ingham CommandObjectMultiwordBreakpoint::VerifyBreakpointIDs( 2194cb2380c9SRaphael Isemann command, &target, result, &valid_bp_ids, 2195b842f2ecSJim Ingham BreakpointName::Permissions::PermissionKinds::listPerm); 2196e14dc268SJim Ingham 219701f16664SJim Ingham if (!result.Succeeded()) { 2198e14dc268SJim Ingham result.SetStatus(eReturnStatusFailed); 2199e14dc268SJim Ingham return false; 2200e14dc268SJim Ingham } 2201e14dc268SJim Ingham } 22028f3be7a3SJonas Devlieghere FileSpec file_spec(m_options.m_filename); 22038f3be7a3SJonas Devlieghere FileSystem::Instance().Resolve(file_spec); 2204cb2380c9SRaphael Isemann Status error = target.SerializeBreakpointsToFile(file_spec, valid_bp_ids, 22058f3be7a3SJonas Devlieghere m_options.m_append); 220601f16664SJim Ingham if (!error.Success()) { 220701f16664SJim Ingham result.AppendErrorWithFormat("error serializing breakpoints: %s.", 220801f16664SJim Ingham error.AsCString()); 220901f16664SJim Ingham result.SetStatus(eReturnStatusFailed); 2210e14dc268SJim Ingham } 2211e14dc268SJim Ingham return result.Succeeded(); 2212e14dc268SJim Ingham } 2213e14dc268SJim Ingham 2214e14dc268SJim Ingham private: 2215e14dc268SJim Ingham CommandOptions m_options; 2216e14dc268SJim Ingham }; 2217e14dc268SJim Ingham 221830fdc8d8SChris Lattner // CommandObjectMultiwordBreakpoint 2219ae1c4cf5SJim Ingham #pragma mark MultiwordBreakpoint 222030fdc8d8SChris Lattner 2221b9c1b51eSKate Stone CommandObjectMultiwordBreakpoint::CommandObjectMultiwordBreakpoint( 2222b9c1b51eSKate Stone CommandInterpreter &interpreter) 2223b9c1b51eSKate Stone : CommandObjectMultiword( 2224b9c1b51eSKate Stone interpreter, "breakpoint", 22257428a18cSKate Stone "Commands for operating on breakpoints (see 'help b' for shorthand.)", 2226b9c1b51eSKate Stone "breakpoint <subcommand> [<command-options>]") { 2227b9c1b51eSKate Stone CommandObjectSP list_command_object( 2228b9c1b51eSKate Stone new CommandObjectBreakpointList(interpreter)); 2229b9c1b51eSKate Stone CommandObjectSP enable_command_object( 2230b9c1b51eSKate Stone new CommandObjectBreakpointEnable(interpreter)); 2231b9c1b51eSKate Stone CommandObjectSP disable_command_object( 2232b9c1b51eSKate Stone new CommandObjectBreakpointDisable(interpreter)); 2233b9c1b51eSKate Stone CommandObjectSP clear_command_object( 2234b9c1b51eSKate Stone new CommandObjectBreakpointClear(interpreter)); 2235b9c1b51eSKate Stone CommandObjectSP delete_command_object( 2236b9c1b51eSKate Stone new CommandObjectBreakpointDelete(interpreter)); 2237b9c1b51eSKate Stone CommandObjectSP set_command_object( 2238b9c1b51eSKate Stone new CommandObjectBreakpointSet(interpreter)); 2239b9c1b51eSKate Stone CommandObjectSP command_command_object( 2240b9c1b51eSKate Stone new CommandObjectBreakpointCommand(interpreter)); 2241b9c1b51eSKate Stone CommandObjectSP modify_command_object( 2242b9c1b51eSKate Stone new CommandObjectBreakpointModify(interpreter)); 2243b9c1b51eSKate Stone CommandObjectSP name_command_object( 2244b9c1b51eSKate Stone new CommandObjectBreakpointName(interpreter)); 2245e14dc268SJim Ingham CommandObjectSP write_command_object( 2246e14dc268SJim Ingham new CommandObjectBreakpointWrite(interpreter)); 2247e14dc268SJim Ingham CommandObjectSP read_command_object( 2248e14dc268SJim Ingham new CommandObjectBreakpointRead(interpreter)); 224930fdc8d8SChris Lattner 2250b7234e40SJohnny Chen list_command_object->SetCommandName("breakpoint list"); 225130fdc8d8SChris Lattner enable_command_object->SetCommandName("breakpoint enable"); 225230fdc8d8SChris Lattner disable_command_object->SetCommandName("breakpoint disable"); 2253b7234e40SJohnny Chen clear_command_object->SetCommandName("breakpoint clear"); 2254b7234e40SJohnny Chen delete_command_object->SetCommandName("breakpoint delete"); 2255ae1c4cf5SJim Ingham set_command_object->SetCommandName("breakpoint set"); 2256b7234e40SJohnny Chen command_command_object->SetCommandName("breakpoint command"); 2257b7234e40SJohnny Chen modify_command_object->SetCommandName("breakpoint modify"); 22585e09c8c3SJim Ingham name_command_object->SetCommandName("breakpoint name"); 2259e14dc268SJim Ingham write_command_object->SetCommandName("breakpoint write"); 2260e14dc268SJim Ingham read_command_object->SetCommandName("breakpoint read"); 226130fdc8d8SChris Lattner 226223f59509SGreg Clayton LoadSubCommand("list", list_command_object); 226323f59509SGreg Clayton LoadSubCommand("enable", enable_command_object); 226423f59509SGreg Clayton LoadSubCommand("disable", disable_command_object); 226523f59509SGreg Clayton LoadSubCommand("clear", clear_command_object); 226623f59509SGreg Clayton LoadSubCommand("delete", delete_command_object); 226723f59509SGreg Clayton LoadSubCommand("set", set_command_object); 226823f59509SGreg Clayton LoadSubCommand("command", command_command_object); 226923f59509SGreg Clayton LoadSubCommand("modify", modify_command_object); 22705e09c8c3SJim Ingham LoadSubCommand("name", name_command_object); 2271e14dc268SJim Ingham LoadSubCommand("write", write_command_object); 2272e14dc268SJim Ingham LoadSubCommand("read", read_command_object); 227330fdc8d8SChris Lattner } 227430fdc8d8SChris Lattner 22759e85e5a8SEugene Zelenko CommandObjectMultiwordBreakpoint::~CommandObjectMultiwordBreakpoint() = default; 227630fdc8d8SChris Lattner 2277b9c1b51eSKate Stone void CommandObjectMultiwordBreakpoint::VerifyIDs(Args &args, Target *target, 22785e09c8c3SJim Ingham bool allow_locations, 22795e09c8c3SJim Ingham CommandReturnObject &result, 2280b842f2ecSJim Ingham BreakpointIDList *valid_ids, 2281b842f2ecSJim Ingham BreakpointName::Permissions 2282b842f2ecSJim Ingham ::PermissionKinds 2283b842f2ecSJim Ingham purpose) { 228430fdc8d8SChris Lattner // args can be strings representing 1). integers (for breakpoint ids) 2285b9c1b51eSKate Stone // 2). the full breakpoint & location 2286b9c1b51eSKate Stone // canonical representation 2287b9c1b51eSKate Stone // 3). the word "to" or a hyphen, 2288b9c1b51eSKate Stone // representing a range (in which case there 2289b9c1b51eSKate Stone // had *better* be an entry both before & 2290b9c1b51eSKate Stone // after of one of the first two types. 22915e09c8c3SJim Ingham // 4). A breakpoint name 2292b9c1b51eSKate Stone // If args is empty, we will use the last created breakpoint (if there is 2293b9c1b51eSKate Stone // one.) 229430fdc8d8SChris Lattner 229530fdc8d8SChris Lattner Args temp_args; 229630fdc8d8SChris Lattner 229711eb9c64SZachary Turner if (args.empty()) { 2298b9c1b51eSKate Stone if (target->GetLastCreatedBreakpoint()) { 2299b9c1b51eSKate Stone valid_ids->AddBreakpointID(BreakpointID( 2300b9c1b51eSKate Stone target->GetLastCreatedBreakpoint()->GetID(), LLDB_INVALID_BREAK_ID)); 230136f3b369SJim Ingham result.SetStatus(eReturnStatusSuccessFinishNoResult); 2302b9c1b51eSKate Stone } else { 2303b9c1b51eSKate Stone result.AppendError( 2304b9c1b51eSKate Stone "No breakpoint specified and no last created breakpoint."); 230536f3b369SJim Ingham result.SetStatus(eReturnStatusFailed); 230636f3b369SJim Ingham } 230736f3b369SJim Ingham return; 230836f3b369SJim Ingham } 230936f3b369SJim Ingham 2310b9c1b51eSKate Stone // Create a new Args variable to use; copy any non-breakpoint-id-ranges stuff 231105097246SAdrian Prantl // directly from the old ARGS to the new TEMP_ARGS. Do not copy breakpoint 231205097246SAdrian Prantl // id range strings over; instead generate a list of strings for all the 231305097246SAdrian Prantl // breakpoint ids in the range, and shove all of those breakpoint id strings 231405097246SAdrian Prantl // into TEMP_ARGS. 231530fdc8d8SChris Lattner 2316b9c1b51eSKate Stone BreakpointIDList::FindAndReplaceIDRanges(args, target, allow_locations, 2317b842f2ecSJim Ingham purpose, result, temp_args); 231830fdc8d8SChris Lattner 2319b9c1b51eSKate Stone // NOW, convert the list of breakpoint id strings in TEMP_ARGS into an actual 2320b9c1b51eSKate Stone // BreakpointIDList: 232130fdc8d8SChris Lattner 232216662f3cSPavel Labath valid_ids->InsertStringArray(temp_args.GetArgumentArrayRef(), result); 232330fdc8d8SChris Lattner 232405097246SAdrian Prantl // At this point, all of the breakpoint ids that the user passed in have 232505097246SAdrian Prantl // been converted to breakpoint IDs and put into valid_ids. 232630fdc8d8SChris Lattner 2327b9c1b51eSKate Stone if (result.Succeeded()) { 2328b9c1b51eSKate Stone // Now that we've converted everything from args into a list of breakpoint 232905097246SAdrian Prantl // ids, go through our tentative list of breakpoint id's and verify that 233005097246SAdrian Prantl // they correspond to valid/currently set breakpoints. 233130fdc8d8SChris Lattner 2332c982c768SGreg Clayton const size_t count = valid_ids->GetSize(); 2333b9c1b51eSKate Stone for (size_t i = 0; i < count; ++i) { 233430fdc8d8SChris Lattner BreakpointID cur_bp_id = valid_ids->GetBreakpointIDAtIndex(i); 2335b9c1b51eSKate Stone Breakpoint *breakpoint = 2336b9c1b51eSKate Stone target->GetBreakpointByID(cur_bp_id.GetBreakpointID()).get(); 2337b9c1b51eSKate Stone if (breakpoint != nullptr) { 2338c7bece56SGreg Clayton const size_t num_locations = breakpoint->GetNumLocations(); 2339b9c1b51eSKate Stone if (static_cast<size_t>(cur_bp_id.GetLocationID()) > num_locations) { 234030fdc8d8SChris Lattner StreamString id_str; 2341b9c1b51eSKate Stone BreakpointID::GetCanonicalReference( 2342b9c1b51eSKate Stone &id_str, cur_bp_id.GetBreakpointID(), cur_bp_id.GetLocationID()); 2343c982c768SGreg Clayton i = valid_ids->GetSize() + 1; 2344b9c1b51eSKate Stone result.AppendErrorWithFormat( 2345b9c1b51eSKate Stone "'%s' is not a currently valid breakpoint/location id.\n", 234630fdc8d8SChris Lattner id_str.GetData()); 234730fdc8d8SChris Lattner result.SetStatus(eReturnStatusFailed); 234830fdc8d8SChris Lattner } 2349b9c1b51eSKate Stone } else { 2350c982c768SGreg Clayton i = valid_ids->GetSize() + 1; 2351b9c1b51eSKate Stone result.AppendErrorWithFormat( 2352b9c1b51eSKate Stone "'%d' is not a currently valid breakpoint ID.\n", 23537428a18cSKate Stone cur_bp_id.GetBreakpointID()); 235430fdc8d8SChris Lattner result.SetStatus(eReturnStatusFailed); 235530fdc8d8SChris Lattner } 235630fdc8d8SChris Lattner } 235730fdc8d8SChris Lattner } 235830fdc8d8SChris Lattner } 2359