130fdc8d8SChris Lattner //===-- CommandObjectBreakpoint.cpp -----------------------------*- C++ -*-===// 230fdc8d8SChris Lattner // 330fdc8d8SChris Lattner // The LLVM Compiler Infrastructure 430fdc8d8SChris Lattner // 530fdc8d8SChris Lattner // This file is distributed under the University of Illinois Open Source 630fdc8d8SChris Lattner // License. See LICENSE.TXT for details. 730fdc8d8SChris Lattner // 830fdc8d8SChris Lattner //===----------------------------------------------------------------------===// 930fdc8d8SChris Lattner 1093a64300SDaniel Malea #include "lldb/lldb-python.h" 1193a64300SDaniel Malea 1230fdc8d8SChris Lattner #include "CommandObjectBreakpoint.h" 1330fdc8d8SChris Lattner #include "CommandObjectBreakpointCommand.h" 1430fdc8d8SChris Lattner 1530fdc8d8SChris Lattner // C Includes 1630fdc8d8SChris Lattner // C++ Includes 1730fdc8d8SChris Lattner // Other libraries and framework includes 1830fdc8d8SChris Lattner // Project includes 1930fdc8d8SChris Lattner #include "lldb/Breakpoint/Breakpoint.h" 2030fdc8d8SChris Lattner #include "lldb/Breakpoint/BreakpointIDList.h" 2130fdc8d8SChris Lattner #include "lldb/Breakpoint/BreakpointLocation.h" 2240af72e1SJim Ingham #include "lldb/Interpreter/Options.h" 2330fdc8d8SChris Lattner #include "lldb/Core/RegularExpression.h" 2430fdc8d8SChris Lattner #include "lldb/Core/StreamString.h" 2530fdc8d8SChris Lattner #include "lldb/Interpreter/CommandInterpreter.h" 2630fdc8d8SChris Lattner #include "lldb/Interpreter/CommandReturnObject.h" 2730fdc8d8SChris Lattner #include "lldb/Target/Target.h" 2830fdc8d8SChris Lattner #include "lldb/Interpreter/CommandCompletions.h" 2930fdc8d8SChris Lattner #include "lldb/Target/StackFrame.h" 301b54c88cSJim Ingham #include "lldb/Target/Thread.h" 311b54c88cSJim Ingham #include "lldb/Target/ThreadSpec.h" 3230fdc8d8SChris Lattner 33b7234e40SJohnny Chen #include <vector> 34b7234e40SJohnny Chen 3530fdc8d8SChris Lattner using namespace lldb; 3630fdc8d8SChris Lattner using namespace lldb_private; 3730fdc8d8SChris Lattner 3830fdc8d8SChris Lattner static void 3985e8b814SJim Ingham AddBreakpointDescription (Stream *s, Breakpoint *bp, lldb::DescriptionLevel level) 4030fdc8d8SChris Lattner { 4130fdc8d8SChris Lattner s->IndentMore(); 4230fdc8d8SChris Lattner bp->GetDescription (s, level, true); 4330fdc8d8SChris Lattner s->IndentLess(); 4430fdc8d8SChris Lattner s->EOL(); 4530fdc8d8SChris Lattner } 4630fdc8d8SChris Lattner 4730fdc8d8SChris Lattner //------------------------------------------------------------------------- 485a988416SJim Ingham // CommandObjectBreakpointSet 4930fdc8d8SChris Lattner //------------------------------------------------------------------------- 5030fdc8d8SChris Lattner 515a988416SJim Ingham 525a988416SJim Ingham class CommandObjectBreakpointSet : public CommandObjectParsed 535a988416SJim Ingham { 545a988416SJim Ingham public: 555a988416SJim Ingham 565a988416SJim Ingham typedef enum BreakpointSetType 575a988416SJim Ingham { 585a988416SJim Ingham eSetTypeInvalid, 595a988416SJim Ingham eSetTypeFileAndLine, 605a988416SJim Ingham eSetTypeAddress, 615a988416SJim Ingham eSetTypeFunctionName, 625a988416SJim Ingham eSetTypeFunctionRegexp, 635a988416SJim Ingham eSetTypeSourceRegexp, 645a988416SJim Ingham eSetTypeException 655a988416SJim Ingham } BreakpointSetType; 665a988416SJim Ingham 675a988416SJim Ingham CommandObjectBreakpointSet (CommandInterpreter &interpreter) : 685a988416SJim Ingham CommandObjectParsed (interpreter, 695a988416SJim Ingham "breakpoint set", 705a988416SJim Ingham "Sets a breakpoint or set of breakpoints in the executable.", 715a988416SJim Ingham "breakpoint set <cmd-options>"), 725a988416SJim Ingham m_options (interpreter) 735a988416SJim Ingham { 745a988416SJim Ingham } 755a988416SJim Ingham 765a988416SJim Ingham 775a988416SJim Ingham virtual 785a988416SJim Ingham ~CommandObjectBreakpointSet () {} 795a988416SJim Ingham 805a988416SJim Ingham virtual Options * 815a988416SJim Ingham GetOptions () 825a988416SJim Ingham { 835a988416SJim Ingham return &m_options; 845a988416SJim Ingham } 855a988416SJim Ingham 865a988416SJim Ingham class CommandOptions : public Options 875a988416SJim Ingham { 885a988416SJim Ingham public: 895a988416SJim Ingham 905a988416SJim Ingham CommandOptions (CommandInterpreter &interpreter) : 91eb0103f2SGreg Clayton Options (interpreter), 927d49c9c8SJohnny Chen m_condition (), 9387df91b8SJim Ingham m_filenames (), 9430fdc8d8SChris Lattner m_line_num (0), 9530fdc8d8SChris Lattner m_column (0), 96fab10e89SJim Ingham m_func_names (), 97fab10e89SJim Ingham m_func_name_type_mask (eFunctionNameTypeNone), 9830fdc8d8SChris Lattner m_func_regexp (), 99969795f1SJim Ingham m_source_text_regexp(), 10030fdc8d8SChris Lattner m_modules (), 1011b54c88cSJim Ingham m_load_addr(), 102c982c768SGreg Clayton m_ignore_count (0), 1031b54c88cSJim Ingham m_thread_id(LLDB_INVALID_THREAD_ID), 104c982c768SGreg Clayton m_thread_index (UINT32_MAX), 1051b54c88cSJim Ingham m_thread_name(), 106fab10e89SJim Ingham m_queue_name(), 107fab10e89SJim Ingham m_catch_bp (false), 1081f746071SGreg Clayton m_throw_bp (true), 109a8558b62SJim Ingham m_language (eLanguageTypeUnknown), 110ca36cd16SJim Ingham m_skip_prologue (eLazyBoolCalculate), 111ca36cd16SJim Ingham m_one_shot (false) 11230fdc8d8SChris Lattner { 11330fdc8d8SChris Lattner } 11430fdc8d8SChris Lattner 11530fdc8d8SChris Lattner 1165a988416SJim Ingham virtual 1175a988416SJim Ingham ~CommandOptions () {} 11887df91b8SJim Ingham 1195a988416SJim Ingham virtual Error 1205a988416SJim Ingham SetOptionValue (uint32_t option_idx, const char *option_arg) 12130fdc8d8SChris Lattner { 12230fdc8d8SChris Lattner Error error; 1233bcdfc0eSGreg Clayton const int short_option = m_getopt_table[option_idx].val; 12430fdc8d8SChris Lattner 12530fdc8d8SChris Lattner switch (short_option) 12630fdc8d8SChris Lattner { 12730fdc8d8SChris Lattner case 'a': 128b9d5df58SGreg Clayton { 129b9d5df58SGreg Clayton ExecutionContext exe_ctx (m_interpreter.GetExecutionContext()); 130b9d5df58SGreg Clayton m_load_addr = Args::StringToAddress(&exe_ctx, option_arg, LLDB_INVALID_ADDRESS, &error); 131b9d5df58SGreg Clayton } 13230fdc8d8SChris Lattner break; 13330fdc8d8SChris Lattner 134ca36cd16SJim Ingham case 'b': 135ca36cd16SJim Ingham m_func_names.push_back (option_arg); 136ca36cd16SJim Ingham m_func_name_type_mask |= eFunctionNameTypeBase; 137ca36cd16SJim Ingham break; 138ca36cd16SJim Ingham 1397d49c9c8SJohnny Chen case 'C': 14030fdc8d8SChris Lattner m_column = Args::StringToUInt32 (option_arg, 0); 14130fdc8d8SChris Lattner break; 1420c5cd90dSGreg Clayton 1437d49c9c8SJohnny Chen case 'c': 1447d49c9c8SJohnny Chen m_condition.assign(option_arg); 1457d49c9c8SJohnny Chen break; 1467d49c9c8SJohnny Chen 147fab10e89SJim Ingham case 'E': 148fab10e89SJim Ingham { 149fab10e89SJim Ingham LanguageType language = LanguageRuntime::GetLanguageTypeFromString (option_arg); 150fab10e89SJim Ingham 151fab10e89SJim Ingham switch (language) 152fab10e89SJim Ingham { 153fab10e89SJim Ingham case eLanguageTypeC89: 154fab10e89SJim Ingham case eLanguageTypeC: 155fab10e89SJim Ingham case eLanguageTypeC99: 156fab10e89SJim Ingham m_language = eLanguageTypeC; 157fab10e89SJim Ingham break; 158fab10e89SJim Ingham case eLanguageTypeC_plus_plus: 159fab10e89SJim Ingham m_language = eLanguageTypeC_plus_plus; 160fab10e89SJim Ingham break; 161fab10e89SJim Ingham case eLanguageTypeObjC: 162fab10e89SJim Ingham m_language = eLanguageTypeObjC; 163fab10e89SJim Ingham break; 164fab10e89SJim Ingham case eLanguageTypeObjC_plus_plus: 165fab10e89SJim Ingham error.SetErrorStringWithFormat ("Set exception breakpoints separately for c++ and objective-c"); 166fab10e89SJim Ingham break; 167fab10e89SJim Ingham case eLanguageTypeUnknown: 168fab10e89SJim Ingham error.SetErrorStringWithFormat ("Unknown language type: '%s' for exception breakpoint", option_arg); 169fab10e89SJim Ingham break; 170fab10e89SJim Ingham default: 171fab10e89SJim Ingham error.SetErrorStringWithFormat ("Unsupported language type: '%s' for exception breakpoint", option_arg); 172fab10e89SJim Ingham } 173fab10e89SJim Ingham } 174fab10e89SJim Ingham break; 175ca36cd16SJim Ingham 176ca36cd16SJim Ingham case 'f': 177ca36cd16SJim Ingham m_filenames.AppendIfUnique (FileSpec(option_arg, false)); 178fab10e89SJim Ingham break; 179ca36cd16SJim Ingham 180ca36cd16SJim Ingham case 'F': 181ca36cd16SJim Ingham m_func_names.push_back (option_arg); 182ca36cd16SJim Ingham m_func_name_type_mask |= eFunctionNameTypeFull; 183ca36cd16SJim Ingham break; 184ca36cd16SJim Ingham 185fab10e89SJim Ingham case 'h': 186fab10e89SJim Ingham { 187fab10e89SJim Ingham bool success; 188fab10e89SJim Ingham m_catch_bp = Args::StringToBoolean (option_arg, true, &success); 189fab10e89SJim Ingham if (!success) 190fab10e89SJim Ingham error.SetErrorStringWithFormat ("Invalid boolean value for on-catch option: '%s'", option_arg); 191fab10e89SJim Ingham } 192ca36cd16SJim Ingham 193ca36cd16SJim Ingham case 'i': 194ca36cd16SJim Ingham { 195ca36cd16SJim Ingham m_ignore_count = Args::StringToUInt32(option_arg, UINT32_MAX, 0); 196ca36cd16SJim Ingham if (m_ignore_count == UINT32_MAX) 197ca36cd16SJim Ingham error.SetErrorStringWithFormat ("invalid ignore count '%s'", option_arg); 198ca36cd16SJim Ingham break; 199ca36cd16SJim Ingham } 200ca36cd16SJim Ingham 201a8558b62SJim Ingham case 'K': 202a8558b62SJim Ingham { 203a8558b62SJim Ingham bool success; 204a8558b62SJim Ingham bool value; 205a8558b62SJim Ingham value = Args::StringToBoolean (option_arg, true, &success); 206a8558b62SJim Ingham if (value) 207a8558b62SJim Ingham m_skip_prologue = eLazyBoolYes; 208a8558b62SJim Ingham else 209a8558b62SJim Ingham m_skip_prologue = eLazyBoolNo; 210a8558b62SJim Ingham 211a8558b62SJim Ingham if (!success) 212a8558b62SJim Ingham error.SetErrorStringWithFormat ("Invalid boolean value for skip prologue option: '%s'", option_arg); 213a8558b62SJim Ingham } 214fab10e89SJim Ingham break; 215ca36cd16SJim Ingham 216ca36cd16SJim Ingham case 'l': 217ca36cd16SJim Ingham m_line_num = Args::StringToUInt32 (option_arg, 0); 218ca36cd16SJim Ingham break; 219ca36cd16SJim Ingham 220ca36cd16SJim Ingham case 'M': 221ca36cd16SJim Ingham m_func_names.push_back (option_arg); 222ca36cd16SJim Ingham m_func_name_type_mask |= eFunctionNameTypeMethod; 223ca36cd16SJim Ingham break; 224ca36cd16SJim Ingham 225ca36cd16SJim Ingham case 'n': 226ca36cd16SJim Ingham m_func_names.push_back (option_arg); 227ca36cd16SJim Ingham m_func_name_type_mask |= eFunctionNameTypeAuto; 228ca36cd16SJim Ingham break; 229ca36cd16SJim Ingham 230ca36cd16SJim Ingham case 'o': 231ca36cd16SJim Ingham m_one_shot = true; 232ca36cd16SJim Ingham break; 233ca36cd16SJim Ingham 234ca36cd16SJim Ingham case 'p': 235ca36cd16SJim Ingham m_source_text_regexp.assign (option_arg); 236ca36cd16SJim Ingham break; 237ca36cd16SJim Ingham 238ca36cd16SJim Ingham case 'q': 239ca36cd16SJim Ingham m_queue_name.assign (option_arg); 240ca36cd16SJim Ingham break; 241ca36cd16SJim Ingham 242ca36cd16SJim Ingham case 'r': 243ca36cd16SJim Ingham m_func_regexp.assign (option_arg); 244ca36cd16SJim Ingham break; 245ca36cd16SJim Ingham 246ca36cd16SJim Ingham case 's': 247ca36cd16SJim Ingham { 248ca36cd16SJim Ingham m_modules.AppendIfUnique (FileSpec (option_arg, false)); 249ca36cd16SJim Ingham break; 250ca36cd16SJim Ingham } 251ca36cd16SJim Ingham 252ca36cd16SJim Ingham case 'S': 253ca36cd16SJim Ingham m_func_names.push_back (option_arg); 254ca36cd16SJim Ingham m_func_name_type_mask |= eFunctionNameTypeSelector; 255ca36cd16SJim Ingham break; 256ca36cd16SJim Ingham 257ca36cd16SJim Ingham case 't' : 258ca36cd16SJim Ingham { 259ca36cd16SJim Ingham m_thread_id = Args::StringToUInt64(option_arg, LLDB_INVALID_THREAD_ID, 0); 260ca36cd16SJim Ingham if (m_thread_id == LLDB_INVALID_THREAD_ID) 261ca36cd16SJim Ingham error.SetErrorStringWithFormat ("invalid thread id string '%s'", option_arg); 262ca36cd16SJim Ingham } 263ca36cd16SJim Ingham break; 264ca36cd16SJim Ingham 265ca36cd16SJim Ingham case 'T': 266ca36cd16SJim Ingham m_thread_name.assign (option_arg); 267ca36cd16SJim Ingham break; 268ca36cd16SJim Ingham 269ca36cd16SJim Ingham case 'w': 270ca36cd16SJim Ingham { 271ca36cd16SJim Ingham bool success; 272ca36cd16SJim Ingham m_throw_bp = Args::StringToBoolean (option_arg, true, &success); 273ca36cd16SJim Ingham if (!success) 274ca36cd16SJim Ingham error.SetErrorStringWithFormat ("Invalid boolean value for on-throw option: '%s'", option_arg); 275ca36cd16SJim Ingham } 276ca36cd16SJim Ingham break; 277ca36cd16SJim Ingham 278ca36cd16SJim Ingham case 'x': 279ca36cd16SJim Ingham { 280ca36cd16SJim Ingham m_thread_index = Args::StringToUInt32(option_arg, UINT32_MAX, 0); 281ca36cd16SJim Ingham if (m_thread_id == UINT32_MAX) 282ca36cd16SJim Ingham error.SetErrorStringWithFormat ("invalid thread index string '%s'", option_arg); 283ca36cd16SJim Ingham 284ca36cd16SJim Ingham } 285ca36cd16SJim Ingham break; 286ca36cd16SJim Ingham 28730fdc8d8SChris Lattner default: 28886edbf41SGreg Clayton error.SetErrorStringWithFormat ("unrecognized option '%c'", short_option); 28930fdc8d8SChris Lattner break; 29030fdc8d8SChris Lattner } 29130fdc8d8SChris Lattner 29230fdc8d8SChris Lattner return error; 29330fdc8d8SChris Lattner } 29430fdc8d8SChris Lattner void 2955a988416SJim Ingham OptionParsingStarting () 29630fdc8d8SChris Lattner { 2977d49c9c8SJohnny Chen m_condition.clear(); 29887df91b8SJim Ingham m_filenames.Clear(); 29930fdc8d8SChris Lattner m_line_num = 0; 30030fdc8d8SChris Lattner m_column = 0; 301fab10e89SJim Ingham m_func_names.clear(); 3021f746071SGreg Clayton m_func_name_type_mask = eFunctionNameTypeNone; 30330fdc8d8SChris Lattner m_func_regexp.clear(); 3041f746071SGreg Clayton m_source_text_regexp.clear(); 30587df91b8SJim Ingham m_modules.Clear(); 3061f746071SGreg Clayton m_load_addr = LLDB_INVALID_ADDRESS; 307c982c768SGreg Clayton m_ignore_count = 0; 3081b54c88cSJim Ingham m_thread_id = LLDB_INVALID_THREAD_ID; 309c982c768SGreg Clayton m_thread_index = UINT32_MAX; 3101b54c88cSJim Ingham m_thread_name.clear(); 3111b54c88cSJim Ingham m_queue_name.clear(); 312fab10e89SJim Ingham m_catch_bp = false; 313fab10e89SJim Ingham m_throw_bp = true; 3141f746071SGreg Clayton m_language = eLanguageTypeUnknown; 315a8558b62SJim Ingham m_skip_prologue = eLazyBoolCalculate; 316ca36cd16SJim Ingham m_one_shot = false; 31730fdc8d8SChris Lattner } 31830fdc8d8SChris Lattner 3195a988416SJim Ingham const OptionDefinition* 3205a988416SJim Ingham GetDefinitions () 32130fdc8d8SChris Lattner { 3225a988416SJim Ingham return g_option_table; 32330fdc8d8SChris Lattner } 32430fdc8d8SChris Lattner 3255a988416SJim Ingham // Options table: Required for subclasses of Options. 32630fdc8d8SChris Lattner 3275a988416SJim Ingham static OptionDefinition g_option_table[]; 32830fdc8d8SChris Lattner 3295a988416SJim Ingham // Instance variables to hold the values for command options. 330969795f1SJim Ingham 3315a988416SJim Ingham std::string m_condition; 3325a988416SJim Ingham FileSpecList m_filenames; 3335a988416SJim Ingham uint32_t m_line_num; 3345a988416SJim Ingham uint32_t m_column; 3355a988416SJim Ingham std::vector<std::string> m_func_names; 3365a988416SJim Ingham uint32_t m_func_name_type_mask; 3375a988416SJim Ingham std::string m_func_regexp; 3385a988416SJim Ingham std::string m_source_text_regexp; 3395a988416SJim Ingham FileSpecList m_modules; 3405a988416SJim Ingham lldb::addr_t m_load_addr; 3415a988416SJim Ingham uint32_t m_ignore_count; 3425a988416SJim Ingham lldb::tid_t m_thread_id; 3435a988416SJim Ingham uint32_t m_thread_index; 3445a988416SJim Ingham std::string m_thread_name; 3455a988416SJim Ingham std::string m_queue_name; 3465a988416SJim Ingham bool m_catch_bp; 3475a988416SJim Ingham bool m_throw_bp; 3485a988416SJim Ingham lldb::LanguageType m_language; 3495a988416SJim Ingham LazyBool m_skip_prologue; 350ca36cd16SJim Ingham bool m_one_shot; 3515a988416SJim Ingham 3525a988416SJim Ingham }; 3535a988416SJim Ingham 3545a988416SJim Ingham protected: 3555a988416SJim Ingham virtual bool 3565a988416SJim Ingham DoExecute (Args& command, 3575a988416SJim Ingham CommandReturnObject &result) 35830fdc8d8SChris Lattner { 359a7015092SGreg Clayton Target *target = m_interpreter.GetDebugger().GetSelectedTarget().get(); 36030fdc8d8SChris Lattner if (target == NULL) 36130fdc8d8SChris Lattner { 362effe5c95SGreg Clayton result.AppendError ("Invalid target. Must set target before setting breakpoints (see 'target create' command)."); 36330fdc8d8SChris Lattner result.SetStatus (eReturnStatusFailed); 36430fdc8d8SChris Lattner return false; 36530fdc8d8SChris Lattner } 36630fdc8d8SChris Lattner 36730fdc8d8SChris Lattner // The following are the various types of breakpoints that could be set: 36830fdc8d8SChris Lattner // 1). -f -l -p [-s -g] (setting breakpoint by source location) 36930fdc8d8SChris Lattner // 2). -a [-s -g] (setting breakpoint by address) 37030fdc8d8SChris Lattner // 3). -n [-s -g] (setting breakpoint by function name) 37130fdc8d8SChris Lattner // 4). -r [-s -g] (setting breakpoint by function name regular expression) 372969795f1SJim Ingham // 5). -p -f (setting a breakpoint by comparing a reg-exp to source text) 373fab10e89SJim Ingham // 6). -E [-w -h] (setting a breakpoint for exceptions for a given language.) 37430fdc8d8SChris Lattner 37530fdc8d8SChris Lattner BreakpointSetType break_type = eSetTypeInvalid; 37630fdc8d8SChris Lattner 37730fdc8d8SChris Lattner if (m_options.m_line_num != 0) 37830fdc8d8SChris Lattner break_type = eSetTypeFileAndLine; 37930fdc8d8SChris Lattner else if (m_options.m_load_addr != LLDB_INVALID_ADDRESS) 38030fdc8d8SChris Lattner break_type = eSetTypeAddress; 381fab10e89SJim Ingham else if (!m_options.m_func_names.empty()) 38230fdc8d8SChris Lattner break_type = eSetTypeFunctionName; 38330fdc8d8SChris Lattner else if (!m_options.m_func_regexp.empty()) 38430fdc8d8SChris Lattner break_type = eSetTypeFunctionRegexp; 385969795f1SJim Ingham else if (!m_options.m_source_text_regexp.empty()) 386969795f1SJim Ingham break_type = eSetTypeSourceRegexp; 387fab10e89SJim Ingham else if (m_options.m_language != eLanguageTypeUnknown) 388fab10e89SJim Ingham break_type = eSetTypeException; 38930fdc8d8SChris Lattner 39030fdc8d8SChris Lattner Breakpoint *bp = NULL; 391274060b6SGreg Clayton FileSpec module_spec; 392a8558b62SJim Ingham const bool internal = false; 393a8558b62SJim Ingham 39430fdc8d8SChris Lattner switch (break_type) 39530fdc8d8SChris Lattner { 39630fdc8d8SChris Lattner case eSetTypeFileAndLine: // Breakpoint by source position 39730fdc8d8SChris Lattner { 39830fdc8d8SChris Lattner FileSpec file; 399c7bece56SGreg Clayton const size_t num_files = m_options.m_filenames.GetSize(); 40087df91b8SJim Ingham if (num_files == 0) 40187df91b8SJim Ingham { 40287df91b8SJim Ingham if (!GetDefaultFile (target, file, result)) 40387df91b8SJim Ingham { 40487df91b8SJim Ingham result.AppendError("No file supplied and no default file available."); 40587df91b8SJim Ingham result.SetStatus (eReturnStatusFailed); 40687df91b8SJim Ingham return false; 40787df91b8SJim Ingham } 40887df91b8SJim Ingham } 40987df91b8SJim Ingham else if (num_files > 1) 41087df91b8SJim Ingham { 41187df91b8SJim Ingham result.AppendError("Only one file at a time is allowed for file and line breakpoints."); 41287df91b8SJim Ingham result.SetStatus (eReturnStatusFailed); 41387df91b8SJim Ingham return false; 41487df91b8SJim Ingham } 41587df91b8SJim Ingham else 41687df91b8SJim Ingham file = m_options.m_filenames.GetFileSpecAtIndex(0); 41730fdc8d8SChris Lattner 4181f746071SGreg Clayton // Only check for inline functions if 4191f746071SGreg Clayton LazyBool check_inlines = eLazyBoolCalculate; 4201f746071SGreg Clayton 42187df91b8SJim Ingham bp = target->CreateBreakpoint (&(m_options.m_modules), 42230fdc8d8SChris Lattner file, 42330fdc8d8SChris Lattner m_options.m_line_num, 4241f746071SGreg Clayton check_inlines, 425a8558b62SJim Ingham m_options.m_skip_prologue, 426a8558b62SJim Ingham internal).get(); 42730fdc8d8SChris Lattner } 42830fdc8d8SChris Lattner break; 4296eee5aa0SGreg Clayton 43030fdc8d8SChris Lattner case eSetTypeAddress: // Breakpoint by address 43130fdc8d8SChris Lattner bp = target->CreateBreakpoint (m_options.m_load_addr, false).get(); 43230fdc8d8SChris Lattner break; 4330c5cd90dSGreg Clayton 43430fdc8d8SChris Lattner case eSetTypeFunctionName: // Breakpoint by function name 4350c5cd90dSGreg Clayton { 4360c5cd90dSGreg Clayton uint32_t name_type_mask = m_options.m_func_name_type_mask; 4370c5cd90dSGreg Clayton 4380c5cd90dSGreg Clayton if (name_type_mask == 0) 439e02b8504SGreg Clayton name_type_mask = eFunctionNameTypeAuto; 4400c5cd90dSGreg Clayton 44187df91b8SJim Ingham bp = target->CreateBreakpoint (&(m_options.m_modules), 44287df91b8SJim Ingham &(m_options.m_filenames), 443fab10e89SJim Ingham m_options.m_func_names, 444274060b6SGreg Clayton name_type_mask, 445a8558b62SJim Ingham m_options.m_skip_prologue, 446a8558b62SJim Ingham internal).get(); 4470c5cd90dSGreg Clayton } 44830fdc8d8SChris Lattner break; 4490c5cd90dSGreg Clayton 45030fdc8d8SChris Lattner case eSetTypeFunctionRegexp: // Breakpoint by regular expression function name 45130fdc8d8SChris Lattner { 45230fdc8d8SChris Lattner RegularExpression regexp(m_options.m_func_regexp.c_str()); 453969795f1SJim Ingham if (!regexp.IsValid()) 45430fdc8d8SChris Lattner { 455969795f1SJim Ingham char err_str[1024]; 456969795f1SJim Ingham regexp.GetErrorAsCString(err_str, sizeof(err_str)); 457969795f1SJim Ingham result.AppendErrorWithFormat("Function name regular expression could not be compiled: \"%s\"", 458969795f1SJim Ingham err_str); 45930fdc8d8SChris Lattner result.SetStatus (eReturnStatusFailed); 460969795f1SJim Ingham return false; 46130fdc8d8SChris Lattner } 46287df91b8SJim Ingham 463a8558b62SJim Ingham bp = target->CreateFuncRegexBreakpoint (&(m_options.m_modules), 464a8558b62SJim Ingham &(m_options.m_filenames), 465a8558b62SJim Ingham regexp, 466a8558b62SJim Ingham m_options.m_skip_prologue, 467a8558b62SJim Ingham internal).get(); 46830fdc8d8SChris Lattner } 46930fdc8d8SChris Lattner break; 470969795f1SJim Ingham case eSetTypeSourceRegexp: // Breakpoint by regexp on source text. 471969795f1SJim Ingham { 472c7bece56SGreg Clayton const size_t num_files = m_options.m_filenames.GetSize(); 47387df91b8SJim Ingham 47487df91b8SJim Ingham if (num_files == 0) 47587df91b8SJim Ingham { 476969795f1SJim Ingham FileSpec file; 47787df91b8SJim Ingham if (!GetDefaultFile (target, file, result)) 47887df91b8SJim Ingham { 47987df91b8SJim Ingham result.AppendError ("No files provided and could not find default file."); 48087df91b8SJim Ingham result.SetStatus (eReturnStatusFailed); 48187df91b8SJim Ingham return false; 48287df91b8SJim Ingham } 48387df91b8SJim Ingham else 48487df91b8SJim Ingham { 48587df91b8SJim Ingham m_options.m_filenames.Append (file); 48687df91b8SJim Ingham } 48787df91b8SJim Ingham } 4880c5cd90dSGreg Clayton 489969795f1SJim Ingham RegularExpression regexp(m_options.m_source_text_regexp.c_str()); 490969795f1SJim Ingham if (!regexp.IsValid()) 491969795f1SJim Ingham { 492969795f1SJim Ingham char err_str[1024]; 493969795f1SJim Ingham regexp.GetErrorAsCString(err_str, sizeof(err_str)); 494969795f1SJim Ingham result.AppendErrorWithFormat("Source text regular expression could not be compiled: \"%s\"", 495969795f1SJim Ingham err_str); 496969795f1SJim Ingham result.SetStatus (eReturnStatusFailed); 497969795f1SJim Ingham return false; 498969795f1SJim Ingham } 49987df91b8SJim Ingham bp = target->CreateSourceRegexBreakpoint (&(m_options.m_modules), &(m_options.m_filenames), regexp).get(); 500969795f1SJim Ingham } 501969795f1SJim Ingham break; 502fab10e89SJim Ingham case eSetTypeException: 503fab10e89SJim Ingham { 504fab10e89SJim Ingham bp = target->CreateExceptionBreakpoint (m_options.m_language, m_options.m_catch_bp, m_options.m_throw_bp).get(); 505fab10e89SJim Ingham } 506fab10e89SJim Ingham break; 50730fdc8d8SChris Lattner default: 50830fdc8d8SChris Lattner break; 50930fdc8d8SChris Lattner } 51030fdc8d8SChris Lattner 5111b54c88cSJim Ingham // Now set the various options that were passed in: 5121b54c88cSJim Ingham if (bp) 5131b54c88cSJim Ingham { 5141b54c88cSJim Ingham if (m_options.m_thread_id != LLDB_INVALID_THREAD_ID) 5151b54c88cSJim Ingham bp->SetThreadID (m_options.m_thread_id); 5161b54c88cSJim Ingham 517c982c768SGreg Clayton if (m_options.m_thread_index != UINT32_MAX) 5181b54c88cSJim Ingham bp->GetOptions()->GetThreadSpec()->SetIndex(m_options.m_thread_index); 5191b54c88cSJim Ingham 5201b54c88cSJim Ingham if (!m_options.m_thread_name.empty()) 5211b54c88cSJim Ingham bp->GetOptions()->GetThreadSpec()->SetName(m_options.m_thread_name.c_str()); 5221b54c88cSJim Ingham 5231b54c88cSJim Ingham if (!m_options.m_queue_name.empty()) 5241b54c88cSJim Ingham bp->GetOptions()->GetThreadSpec()->SetQueueName(m_options.m_queue_name.c_str()); 5251b54c88cSJim Ingham 526c982c768SGreg Clayton if (m_options.m_ignore_count != 0) 5271b54c88cSJim Ingham bp->GetOptions()->SetIgnoreCount(m_options.m_ignore_count); 5287d49c9c8SJohnny Chen 5297d49c9c8SJohnny Chen if (!m_options.m_condition.empty()) 5307d49c9c8SJohnny Chen bp->GetOptions()->SetCondition(m_options.m_condition.c_str()); 531ca36cd16SJim Ingham 532ca36cd16SJim Ingham bp->SetOneShot (m_options.m_one_shot); 5331b54c88cSJim Ingham } 5341b54c88cSJim Ingham 535969795f1SJim Ingham if (bp) 53630fdc8d8SChris Lattner { 53785e8b814SJim Ingham Stream &output_stream = result.GetOutputStream(); 5381391cc7dSJim Ingham const bool show_locations = false; 5391391cc7dSJim Ingham bp->GetDescription(&output_stream, lldb::eDescriptionLevelInitial, show_locations); 540fab10e89SJim Ingham // Don't print out this warning for exception breakpoints. They can get set before the target 541fab10e89SJim Ingham // is set, but we won't know how to actually set the breakpoint till we run. 542fab10e89SJim Ingham if (bp->GetNumLocations() == 0 && break_type != eSetTypeException) 543be484f41SCaroline Tice output_stream.Printf ("WARNING: Unable to resolve breakpoint to any actual locations.\n"); 54430fdc8d8SChris Lattner result.SetStatus (eReturnStatusSuccessFinishResult); 54530fdc8d8SChris Lattner } 54630fdc8d8SChris Lattner else if (!bp) 54730fdc8d8SChris Lattner { 54830fdc8d8SChris Lattner result.AppendError ("Breakpoint creation failed: No breakpoint created."); 54930fdc8d8SChris Lattner result.SetStatus (eReturnStatusFailed); 55030fdc8d8SChris Lattner } 55130fdc8d8SChris Lattner 55230fdc8d8SChris Lattner return result.Succeeded(); 55330fdc8d8SChris Lattner } 55430fdc8d8SChris Lattner 5555a988416SJim Ingham private: 5565a988416SJim Ingham bool 5575a988416SJim Ingham GetDefaultFile (Target *target, FileSpec &file, CommandReturnObject &result) 5585a988416SJim Ingham { 5595a988416SJim Ingham uint32_t default_line; 5605a988416SJim Ingham // First use the Source Manager's default file. 5615a988416SJim Ingham // Then use the current stack frame's file. 5625a988416SJim Ingham if (!target->GetSourceManager().GetDefaultFileAndLine(file, default_line)) 5635a988416SJim Ingham { 564f9fc609fSGreg Clayton StackFrame *cur_frame = m_exe_ctx.GetFramePtr(); 5655a988416SJim Ingham if (cur_frame == NULL) 5665a988416SJim Ingham { 5675a988416SJim Ingham result.AppendError ("No selected frame to use to find the default file."); 5685a988416SJim Ingham result.SetStatus (eReturnStatusFailed); 5695a988416SJim Ingham return false; 5705a988416SJim Ingham } 5715a988416SJim Ingham else if (!cur_frame->HasDebugInformation()) 5725a988416SJim Ingham { 5735a988416SJim Ingham result.AppendError ("Cannot use the selected frame to find the default file, it has no debug info."); 5745a988416SJim Ingham result.SetStatus (eReturnStatusFailed); 5755a988416SJim Ingham return false; 5765a988416SJim Ingham } 5775a988416SJim Ingham else 5785a988416SJim Ingham { 5795a988416SJim Ingham const SymbolContext &sc = cur_frame->GetSymbolContext (eSymbolContextLineEntry); 5805a988416SJim Ingham if (sc.line_entry.file) 5815a988416SJim Ingham { 5825a988416SJim Ingham file = sc.line_entry.file; 5835a988416SJim Ingham } 5845a988416SJim Ingham else 5855a988416SJim Ingham { 5865a988416SJim Ingham result.AppendError ("Can't find the file for the selected frame to use as the default file."); 5875a988416SJim Ingham result.SetStatus (eReturnStatusFailed); 5885a988416SJim Ingham return false; 5895a988416SJim Ingham } 5905a988416SJim Ingham } 5915a988416SJim Ingham } 5925a988416SJim Ingham return true; 5935a988416SJim Ingham } 5945a988416SJim Ingham 5955a988416SJim Ingham CommandOptions m_options; 5965a988416SJim Ingham }; 5975a988416SJim Ingham // If an additional option set beyond LLDB_OPTION_SET_10 is added, make sure to 5985a988416SJim Ingham // update the numbers passed to LLDB_OPT_SET_FROM_TO(...) appropriately. 5995a988416SJim Ingham #define LLDB_OPT_FILE ( LLDB_OPT_SET_FROM_TO(1, 9) & ~LLDB_OPT_SET_2 ) 6005a988416SJim Ingham #define LLDB_OPT_NOT_10 ( LLDB_OPT_SET_FROM_TO(1, 10) & ~LLDB_OPT_SET_10 ) 6015a988416SJim Ingham #define LLDB_OPT_SKIP_PROLOGUE ( LLDB_OPT_SET_1 | LLDB_OPT_SET_FROM_TO(3,8) ) 6025a988416SJim Ingham 6035a988416SJim Ingham OptionDefinition 6045a988416SJim Ingham CommandObjectBreakpointSet::CommandOptions::g_option_table[] = 6055a988416SJim Ingham { 6065a988416SJim Ingham { LLDB_OPT_NOT_10, false, "shlib", 's', required_argument, NULL, CommandCompletions::eModuleCompletion, eArgTypeShlibName, 6075a988416SJim Ingham "Set the breakpoint only in this shared library. " 6085a988416SJim Ingham "Can repeat this option multiple times to specify multiple shared libraries."}, 6095a988416SJim Ingham 6105a988416SJim Ingham { LLDB_OPT_SET_ALL, false, "ignore-count", 'i', required_argument, NULL, 0, eArgTypeCount, 6115a988416SJim Ingham "Set the number of times this breakpoint is skipped before stopping." }, 6125a988416SJim Ingham 613ca36cd16SJim Ingham { LLDB_OPT_SET_ALL, false, "one-shot", 'o', no_argument, NULL, 0, eArgTypeNone, 614ca36cd16SJim Ingham "The breakpoint is deleted the first time it stop causes a stop." }, 615ca36cd16SJim Ingham 6165a988416SJim Ingham { LLDB_OPT_SET_ALL, false, "condition", 'c', required_argument, NULL, 0, eArgTypeExpression, 6175a988416SJim Ingham "The breakpoint stops only if this condition expression evaluates to true."}, 6185a988416SJim Ingham 6195a988416SJim Ingham { LLDB_OPT_SET_ALL, false, "thread-index", 'x', required_argument, NULL, 0, eArgTypeThreadIndex, 6205a988416SJim Ingham "The breakpoint stops only for the thread whose index matches this argument."}, 6215a988416SJim Ingham 6225a988416SJim Ingham { LLDB_OPT_SET_ALL, false, "thread-id", 't', required_argument, NULL, 0, eArgTypeThreadID, 6235a988416SJim Ingham "The breakpoint stops only for the thread whose TID matches this argument."}, 6245a988416SJim Ingham 6255a988416SJim Ingham { LLDB_OPT_SET_ALL, false, "thread-name", 'T', required_argument, NULL, 0, eArgTypeThreadName, 6265a988416SJim Ingham "The breakpoint stops only for the thread whose thread name matches this argument."}, 6275a988416SJim Ingham 6285a988416SJim Ingham { LLDB_OPT_SET_ALL, false, "queue-name", 'q', required_argument, NULL, 0, eArgTypeQueueName, 6295a988416SJim Ingham "The breakpoint stops only for threads in the queue whose name is given by this argument."}, 6305a988416SJim Ingham 6315a988416SJim Ingham { LLDB_OPT_FILE, false, "file", 'f', required_argument, NULL, CommandCompletions::eSourceFileCompletion, eArgTypeFilename, 632289aca64SJim Ingham "Specifies the source file in which to set this breakpoint. " 633289aca64SJim Ingham "Note, by default lldb only looks for files that are #included if they use the standard include file extensions. " 6346394479eSJim Ingham "To set breakpoints on .c/.cpp/.m/.mm files that are #included, set target.inline-breakpoint-strategy" 635289aca64SJim Ingham " to \"always\"."}, 6365a988416SJim Ingham 6375a988416SJim Ingham { LLDB_OPT_SET_1, true, "line", 'l', required_argument, NULL, 0, eArgTypeLineNum, 6385a988416SJim Ingham "Specifies the line number on which to set this breakpoint."}, 6395a988416SJim Ingham 6405a988416SJim Ingham // Comment out this option for the moment, as we don't actually use it, but will in the future. 6415a988416SJim Ingham // This way users won't see it, but the infrastructure is left in place. 6425a988416SJim Ingham // { 0, false, "column", 'C', required_argument, NULL, "<column>", 6435a988416SJim Ingham // "Set the breakpoint by source location at this particular column."}, 6445a988416SJim Ingham 645b84a9dbfSEnrico Granata { LLDB_OPT_SET_2, true, "address", 'a', required_argument, NULL, 0, eArgTypeAddressOrExpression, 6465a988416SJim Ingham "Set the breakpoint by address, at the specified address."}, 6475a988416SJim Ingham 6485a988416SJim Ingham { LLDB_OPT_SET_3, true, "name", 'n', required_argument, NULL, CommandCompletions::eSymbolCompletion, eArgTypeFunctionName, 6495a988416SJim Ingham "Set the breakpoint by function name. Can be repeated multiple times to make one breakpoint for multiple snames" }, 6505a988416SJim Ingham 6515a988416SJim Ingham { LLDB_OPT_SET_4, true, "fullname", 'F', required_argument, NULL, CommandCompletions::eSymbolCompletion, eArgTypeFullName, 6525a988416SJim Ingham "Set the breakpoint by fully qualified function names. For C++ this means namespaces and all arguments, and " 6535a988416SJim Ingham "for Objective C this means a full function prototype with class and selector. " 6545a988416SJim Ingham "Can be repeated multiple times to make one breakpoint for multiple names." }, 6555a988416SJim Ingham 6565a988416SJim Ingham { LLDB_OPT_SET_5, true, "selector", 'S', required_argument, NULL, 0, eArgTypeSelector, 6575a988416SJim Ingham "Set the breakpoint by ObjC selector name. Can be repeated multiple times to make one breakpoint for multiple Selectors." }, 6585a988416SJim Ingham 6595a988416SJim Ingham { LLDB_OPT_SET_6, true, "method", 'M', required_argument, NULL, 0, eArgTypeMethod, 6605a988416SJim Ingham "Set the breakpoint by C++ method names. Can be repeated multiple times to make one breakpoint for multiple methods." }, 6615a988416SJim Ingham 6625a988416SJim Ingham { LLDB_OPT_SET_7, true, "func-regex", 'r', required_argument, NULL, 0, eArgTypeRegularExpression, 6635a988416SJim Ingham "Set the breakpoint by function name, evaluating a regular-expression to find the function name(s)." }, 6645a988416SJim Ingham 6655a988416SJim Ingham { LLDB_OPT_SET_8, true, "basename", 'b', required_argument, NULL, CommandCompletions::eSymbolCompletion, eArgTypeFunctionName, 6665a988416SJim Ingham "Set the breakpoint by function basename (C++ namespaces and arguments will be ignored). " 6675a988416SJim Ingham "Can be repeated multiple times to make one breakpoint for multiple symbols." }, 6685a988416SJim Ingham 6695a988416SJim Ingham { LLDB_OPT_SET_9, true, "source-pattern-regexp", 'p', required_argument, NULL, 0, eArgTypeRegularExpression, 6705a988416SJim Ingham "Set the breakpoint specifying a regular expression to match a pattern in the source text in a given source file." }, 6715a988416SJim Ingham 6725a988416SJim Ingham { LLDB_OPT_SET_10, true, "language-exception", 'E', required_argument, NULL, 0, eArgTypeLanguage, 6735a988416SJim Ingham "Set the breakpoint on exceptions thrown by the specified language (without options, on throw but not catch.)" }, 6745a988416SJim Ingham 6755a988416SJim Ingham { LLDB_OPT_SET_10, false, "on-throw", 'w', required_argument, NULL, 0, eArgTypeBoolean, 6765a988416SJim Ingham "Set the breakpoint on exception throW." }, 6775a988416SJim Ingham 6785a988416SJim Ingham { LLDB_OPT_SET_10, false, "on-catch", 'h', required_argument, NULL, 0, eArgTypeBoolean, 6795a988416SJim Ingham "Set the breakpoint on exception catcH." }, 6805a988416SJim Ingham 6815a988416SJim Ingham { LLDB_OPT_SKIP_PROLOGUE, false, "skip-prologue", 'K', required_argument, NULL, 0, eArgTypeBoolean, 6825a988416SJim Ingham "sKip the prologue if the breakpoint is at the beginning of a function. If not set the target.skip-prologue setting is used." }, 6835a988416SJim Ingham 6845a988416SJim Ingham { 0, false, NULL, 0, 0, NULL, 0, eArgTypeNone, NULL } 6855a988416SJim Ingham }; 6865a988416SJim Ingham 6875a988416SJim Ingham //------------------------------------------------------------------------- 6885a988416SJim Ingham // CommandObjectBreakpointModify 6895a988416SJim Ingham //------------------------------------------------------------------------- 6905a988416SJim Ingham #pragma mark Modify 6915a988416SJim Ingham 6925a988416SJim Ingham class CommandObjectBreakpointModify : public CommandObjectParsed 6935a988416SJim Ingham { 6945a988416SJim Ingham public: 6955a988416SJim Ingham 6965a988416SJim Ingham CommandObjectBreakpointModify (CommandInterpreter &interpreter) : 6975a988416SJim Ingham CommandObjectParsed (interpreter, 6985a988416SJim Ingham "breakpoint modify", 6995a988416SJim Ingham "Modify the options on a breakpoint or set of breakpoints in the executable. " 7005a988416SJim Ingham "If no breakpoint is specified, acts on the last created breakpoint. " 7015a988416SJim Ingham "With the exception of -e, -d and -i, passing an empty argument clears the modification.", 7025a988416SJim Ingham NULL), 7035a988416SJim Ingham m_options (interpreter) 7045a988416SJim Ingham { 7055a988416SJim Ingham CommandArgumentEntry arg; 7065a988416SJim Ingham CommandObject::AddIDsArgumentData(arg, eArgTypeBreakpointID, eArgTypeBreakpointIDRange); 7075a988416SJim Ingham // Add the entry for the first argument for this command to the object's arguments vector. 7085a988416SJim Ingham m_arguments.push_back (arg); 7095a988416SJim Ingham } 7105a988416SJim Ingham 7115a988416SJim Ingham 7125a988416SJim Ingham virtual 7135a988416SJim Ingham ~CommandObjectBreakpointModify () {} 7145a988416SJim Ingham 7155a988416SJim Ingham virtual Options * 7165a988416SJim Ingham GetOptions () 7175a988416SJim Ingham { 7185a988416SJim Ingham return &m_options; 7195a988416SJim Ingham } 7205a988416SJim Ingham 7215a988416SJim Ingham class CommandOptions : public Options 7225a988416SJim Ingham { 7235a988416SJim Ingham public: 7245a988416SJim Ingham 7255a988416SJim Ingham CommandOptions (CommandInterpreter &interpreter) : 7265a988416SJim Ingham Options (interpreter), 7275a988416SJim Ingham m_ignore_count (0), 7285a988416SJim Ingham m_thread_id(LLDB_INVALID_THREAD_ID), 7295a988416SJim Ingham m_thread_id_passed(false), 7305a988416SJim Ingham m_thread_index (UINT32_MAX), 7315a988416SJim Ingham m_thread_index_passed(false), 7325a988416SJim Ingham m_thread_name(), 7335a988416SJim Ingham m_queue_name(), 7345a988416SJim Ingham m_condition (), 735ca36cd16SJim Ingham m_one_shot (false), 7365a988416SJim Ingham m_enable_passed (false), 7375a988416SJim Ingham m_enable_value (false), 7385a988416SJim Ingham m_name_passed (false), 7395a988416SJim Ingham m_queue_passed (false), 740ca36cd16SJim Ingham m_condition_passed (false), 741ca36cd16SJim Ingham m_one_shot_passed (false) 7425a988416SJim Ingham { 7435a988416SJim Ingham } 7445a988416SJim Ingham 7455a988416SJim Ingham virtual 7465a988416SJim Ingham ~CommandOptions () {} 7475a988416SJim Ingham 7485a988416SJim Ingham virtual Error 7495a988416SJim Ingham SetOptionValue (uint32_t option_idx, const char *option_arg) 7505a988416SJim Ingham { 7515a988416SJim Ingham Error error; 7523bcdfc0eSGreg Clayton const int short_option = m_getopt_table[option_idx].val; 7535a988416SJim Ingham 7545a988416SJim Ingham switch (short_option) 7555a988416SJim Ingham { 7565a988416SJim Ingham case 'c': 7575a988416SJim Ingham if (option_arg != NULL) 7585a988416SJim Ingham m_condition.assign (option_arg); 7595a988416SJim Ingham else 7605a988416SJim Ingham m_condition.clear(); 7615a988416SJim Ingham m_condition_passed = true; 7625a988416SJim Ingham break; 7635a988416SJim Ingham case 'd': 7645a988416SJim Ingham m_enable_passed = true; 7655a988416SJim Ingham m_enable_value = false; 7665a988416SJim Ingham break; 7675a988416SJim Ingham case 'e': 7685a988416SJim Ingham m_enable_passed = true; 7695a988416SJim Ingham m_enable_value = true; 7705a988416SJim Ingham break; 7715a988416SJim Ingham case 'i': 7725a988416SJim Ingham { 7735a988416SJim Ingham m_ignore_count = Args::StringToUInt32(option_arg, UINT32_MAX, 0); 7745a988416SJim Ingham if (m_ignore_count == UINT32_MAX) 7755a988416SJim Ingham error.SetErrorStringWithFormat ("invalid ignore count '%s'", option_arg); 7765a988416SJim Ingham } 7775a988416SJim Ingham break; 778ca36cd16SJim Ingham case 'o': 779ca36cd16SJim Ingham { 780ca36cd16SJim Ingham bool value, success; 781ca36cd16SJim Ingham value = Args::StringToBoolean(option_arg, false, &success); 782ca36cd16SJim Ingham if (success) 783ca36cd16SJim Ingham { 784ca36cd16SJim Ingham m_one_shot_passed = true; 785ca36cd16SJim Ingham m_one_shot = value; 786ca36cd16SJim Ingham } 787ca36cd16SJim Ingham else 788ca36cd16SJim Ingham error.SetErrorStringWithFormat("invalid boolean value '%s' passed for -o option", option_arg); 789ca36cd16SJim Ingham } 790ca36cd16SJim Ingham break; 7915a988416SJim Ingham case 't' : 7925a988416SJim Ingham { 7935a988416SJim Ingham if (option_arg[0] == '\0') 7945a988416SJim Ingham { 7955a988416SJim Ingham m_thread_id = LLDB_INVALID_THREAD_ID; 7965a988416SJim Ingham m_thread_id_passed = true; 7975a988416SJim Ingham } 7985a988416SJim Ingham else 7995a988416SJim Ingham { 8005a988416SJim Ingham m_thread_id = Args::StringToUInt64(option_arg, LLDB_INVALID_THREAD_ID, 0); 8015a988416SJim Ingham if (m_thread_id == LLDB_INVALID_THREAD_ID) 8025a988416SJim Ingham error.SetErrorStringWithFormat ("invalid thread id string '%s'", option_arg); 8035a988416SJim Ingham else 8045a988416SJim Ingham m_thread_id_passed = true; 8055a988416SJim Ingham } 8065a988416SJim Ingham } 8075a988416SJim Ingham break; 8085a988416SJim Ingham case 'T': 8095a988416SJim Ingham if (option_arg != NULL) 8105a988416SJim Ingham m_thread_name.assign (option_arg); 8115a988416SJim Ingham else 8125a988416SJim Ingham m_thread_name.clear(); 8135a988416SJim Ingham m_name_passed = true; 8145a988416SJim Ingham break; 8155a988416SJim Ingham case 'q': 8165a988416SJim Ingham if (option_arg != NULL) 8175a988416SJim Ingham m_queue_name.assign (option_arg); 8185a988416SJim Ingham else 8195a988416SJim Ingham m_queue_name.clear(); 8205a988416SJim Ingham m_queue_passed = true; 8215a988416SJim Ingham break; 8225a988416SJim Ingham case 'x': 8235a988416SJim Ingham { 8245a988416SJim Ingham if (option_arg[0] == '\n') 8255a988416SJim Ingham { 8265a988416SJim Ingham m_thread_index = UINT32_MAX; 8275a988416SJim Ingham m_thread_index_passed = true; 8285a988416SJim Ingham } 8295a988416SJim Ingham else 8305a988416SJim Ingham { 8315a988416SJim Ingham m_thread_index = Args::StringToUInt32 (option_arg, UINT32_MAX, 0); 8325a988416SJim Ingham if (m_thread_id == UINT32_MAX) 8335a988416SJim Ingham error.SetErrorStringWithFormat ("invalid thread index string '%s'", option_arg); 8345a988416SJim Ingham else 8355a988416SJim Ingham m_thread_index_passed = true; 8365a988416SJim Ingham } 8375a988416SJim Ingham } 8385a988416SJim Ingham break; 8395a988416SJim Ingham default: 8405a988416SJim Ingham error.SetErrorStringWithFormat ("unrecognized option '%c'", short_option); 8415a988416SJim Ingham break; 8425a988416SJim Ingham } 8435a988416SJim Ingham 8445a988416SJim Ingham return error; 8455a988416SJim Ingham } 8465a988416SJim Ingham void 8475a988416SJim Ingham OptionParsingStarting () 8485a988416SJim Ingham { 8495a988416SJim Ingham m_ignore_count = 0; 8505a988416SJim Ingham m_thread_id = LLDB_INVALID_THREAD_ID; 8515a988416SJim Ingham m_thread_id_passed = false; 8525a988416SJim Ingham m_thread_index = UINT32_MAX; 8535a988416SJim Ingham m_thread_index_passed = false; 8545a988416SJim Ingham m_thread_name.clear(); 8555a988416SJim Ingham m_queue_name.clear(); 8565a988416SJim Ingham m_condition.clear(); 857ca36cd16SJim Ingham m_one_shot = false; 8585a988416SJim Ingham m_enable_passed = false; 8595a988416SJim Ingham m_queue_passed = false; 8605a988416SJim Ingham m_name_passed = false; 8615a988416SJim Ingham m_condition_passed = false; 862ca36cd16SJim Ingham m_one_shot_passed = false; 8635a988416SJim Ingham } 8645a988416SJim Ingham 8655a988416SJim Ingham const OptionDefinition* 8665a988416SJim Ingham GetDefinitions () 8675a988416SJim Ingham { 8685a988416SJim Ingham return g_option_table; 8695a988416SJim Ingham } 8705a988416SJim Ingham 8715a988416SJim Ingham 8725a988416SJim Ingham // Options table: Required for subclasses of Options. 8735a988416SJim Ingham 8745a988416SJim Ingham static OptionDefinition g_option_table[]; 8755a988416SJim Ingham 8765a988416SJim Ingham // Instance variables to hold the values for command options. 8775a988416SJim Ingham 8785a988416SJim Ingham uint32_t m_ignore_count; 8795a988416SJim Ingham lldb::tid_t m_thread_id; 8805a988416SJim Ingham bool m_thread_id_passed; 8815a988416SJim Ingham uint32_t m_thread_index; 8825a988416SJim Ingham bool m_thread_index_passed; 8835a988416SJim Ingham std::string m_thread_name; 8845a988416SJim Ingham std::string m_queue_name; 8855a988416SJim Ingham std::string m_condition; 886ca36cd16SJim Ingham bool m_one_shot; 8875a988416SJim Ingham bool m_enable_passed; 8885a988416SJim Ingham bool m_enable_value; 8895a988416SJim Ingham bool m_name_passed; 8905a988416SJim Ingham bool m_queue_passed; 8915a988416SJim Ingham bool m_condition_passed; 892ca36cd16SJim Ingham bool m_one_shot_passed; 8935a988416SJim Ingham 8945a988416SJim Ingham }; 8955a988416SJim Ingham 8965a988416SJim Ingham protected: 8975a988416SJim Ingham virtual bool 8985a988416SJim Ingham DoExecute (Args& command, CommandReturnObject &result) 8995a988416SJim Ingham { 9005a988416SJim Ingham Target *target = m_interpreter.GetDebugger().GetSelectedTarget().get(); 9015a988416SJim Ingham if (target == NULL) 9025a988416SJim Ingham { 9035a988416SJim Ingham result.AppendError ("Invalid target. No existing target or breakpoints."); 9045a988416SJim Ingham result.SetStatus (eReturnStatusFailed); 9055a988416SJim Ingham return false; 9065a988416SJim Ingham } 9075a988416SJim Ingham 9085a988416SJim Ingham Mutex::Locker locker; 9095a988416SJim Ingham target->GetBreakpointList().GetListMutex(locker); 9105a988416SJim Ingham 9115a988416SJim Ingham BreakpointIDList valid_bp_ids; 9125a988416SJim Ingham 9135a988416SJim Ingham CommandObjectMultiwordBreakpoint::VerifyBreakpointIDs (command, target, result, &valid_bp_ids); 9145a988416SJim Ingham 9155a988416SJim Ingham if (result.Succeeded()) 9165a988416SJim Ingham { 9175a988416SJim Ingham const size_t count = valid_bp_ids.GetSize(); 9185a988416SJim Ingham for (size_t i = 0; i < count; ++i) 9195a988416SJim Ingham { 9205a988416SJim Ingham BreakpointID cur_bp_id = valid_bp_ids.GetBreakpointIDAtIndex (i); 9215a988416SJim Ingham 9225a988416SJim Ingham if (cur_bp_id.GetBreakpointID() != LLDB_INVALID_BREAK_ID) 9235a988416SJim Ingham { 9245a988416SJim Ingham Breakpoint *bp = target->GetBreakpointByID (cur_bp_id.GetBreakpointID()).get(); 9255a988416SJim Ingham if (cur_bp_id.GetLocationID() != LLDB_INVALID_BREAK_ID) 9265a988416SJim Ingham { 9275a988416SJim Ingham BreakpointLocation *location = bp->FindLocationByID (cur_bp_id.GetLocationID()).get(); 9285a988416SJim Ingham if (location) 9295a988416SJim Ingham { 9305a988416SJim Ingham if (m_options.m_thread_id_passed) 9315a988416SJim Ingham location->SetThreadID (m_options.m_thread_id); 9325a988416SJim Ingham 9335a988416SJim Ingham if (m_options.m_thread_index_passed) 9345a988416SJim Ingham location->SetThreadIndex(m_options.m_thread_index); 9355a988416SJim Ingham 9365a988416SJim Ingham if (m_options.m_name_passed) 9375a988416SJim Ingham location->SetThreadName(m_options.m_thread_name.c_str()); 9385a988416SJim Ingham 9395a988416SJim Ingham if (m_options.m_queue_passed) 9405a988416SJim Ingham location->SetQueueName(m_options.m_queue_name.c_str()); 9415a988416SJim Ingham 9425a988416SJim Ingham if (m_options.m_ignore_count != 0) 9435a988416SJim Ingham location->SetIgnoreCount(m_options.m_ignore_count); 9445a988416SJim Ingham 9455a988416SJim Ingham if (m_options.m_enable_passed) 9465a988416SJim Ingham location->SetEnabled (m_options.m_enable_value); 9475a988416SJim Ingham 9485a988416SJim Ingham if (m_options.m_condition_passed) 9495a988416SJim Ingham location->SetCondition (m_options.m_condition.c_str()); 9505a988416SJim Ingham } 9515a988416SJim Ingham } 9525a988416SJim Ingham else 9535a988416SJim Ingham { 9545a988416SJim Ingham if (m_options.m_thread_id_passed) 9555a988416SJim Ingham bp->SetThreadID (m_options.m_thread_id); 9565a988416SJim Ingham 9575a988416SJim Ingham if (m_options.m_thread_index_passed) 9585a988416SJim Ingham bp->SetThreadIndex(m_options.m_thread_index); 9595a988416SJim Ingham 9605a988416SJim Ingham if (m_options.m_name_passed) 9615a988416SJim Ingham bp->SetThreadName(m_options.m_thread_name.c_str()); 9625a988416SJim Ingham 9635a988416SJim Ingham if (m_options.m_queue_passed) 9645a988416SJim Ingham bp->SetQueueName(m_options.m_queue_name.c_str()); 9655a988416SJim Ingham 9665a988416SJim Ingham if (m_options.m_ignore_count != 0) 9675a988416SJim Ingham bp->SetIgnoreCount(m_options.m_ignore_count); 9685a988416SJim Ingham 9695a988416SJim Ingham if (m_options.m_enable_passed) 9705a988416SJim Ingham bp->SetEnabled (m_options.m_enable_value); 9715a988416SJim Ingham 9725a988416SJim Ingham if (m_options.m_condition_passed) 9735a988416SJim Ingham bp->SetCondition (m_options.m_condition.c_str()); 9745a988416SJim Ingham } 9755a988416SJim Ingham } 9765a988416SJim Ingham } 9775a988416SJim Ingham } 9785a988416SJim Ingham 9795a988416SJim Ingham return result.Succeeded(); 9805a988416SJim Ingham } 9815a988416SJim Ingham 9825a988416SJim Ingham private: 9835a988416SJim Ingham CommandOptions m_options; 9845a988416SJim Ingham }; 9855a988416SJim Ingham 9865a988416SJim Ingham #pragma mark Modify::CommandOptions 9875a988416SJim Ingham OptionDefinition 9885a988416SJim Ingham CommandObjectBreakpointModify::CommandOptions::g_option_table[] = 9895a988416SJim Ingham { 9905a988416SJim Ingham { LLDB_OPT_SET_ALL, false, "ignore-count", 'i', required_argument, NULL, 0, eArgTypeCount, "Set the number of times this breakpoint is skipped before stopping." }, 991ca36cd16SJim Ingham { LLDB_OPT_SET_ALL, false, "one-shot", 'o', required_argument, NULL, 0, eArgTypeBoolean, "The breakpoint is deleted the first time it stop causes a stop." }, 9925a988416SJim Ingham { LLDB_OPT_SET_ALL, false, "thread-index", 'x', required_argument, NULL, 0, eArgTypeThreadIndex, "The breakpoint stops only for the thread whose indeX matches this argument."}, 9935a988416SJim Ingham { LLDB_OPT_SET_ALL, false, "thread-id", 't', required_argument, NULL, 0, eArgTypeThreadID, "The breakpoint stops only for the thread whose TID matches this argument."}, 9945a988416SJim Ingham { LLDB_OPT_SET_ALL, false, "thread-name", 'T', required_argument, NULL, 0, eArgTypeThreadName, "The breakpoint stops only for the thread whose thread name matches this argument."}, 9955a988416SJim Ingham { LLDB_OPT_SET_ALL, false, "queue-name", 'q', required_argument, NULL, 0, eArgTypeQueueName, "The breakpoint stops only for threads in the queue whose name is given by this argument."}, 9965a988416SJim Ingham { LLDB_OPT_SET_ALL, false, "condition", 'c', required_argument, NULL, 0, eArgTypeExpression, "The breakpoint stops only if this condition expression evaluates to true."}, 9975a988416SJim Ingham { LLDB_OPT_SET_1, false, "enable", 'e', no_argument, NULL, 0, eArgTypeNone, "Enable the breakpoint."}, 9985a988416SJim Ingham { LLDB_OPT_SET_2, false, "disable", 'd', no_argument, NULL, 0, eArgTypeNone, "Disable the breakpoint."}, 9995a988416SJim Ingham { 0, false, NULL, 0 , 0, NULL, 0, eArgTypeNone, NULL } 10005a988416SJim Ingham }; 10015a988416SJim Ingham 10025a988416SJim Ingham //------------------------------------------------------------------------- 10035a988416SJim Ingham // CommandObjectBreakpointEnable 10045a988416SJim Ingham //------------------------------------------------------------------------- 10055a988416SJim Ingham #pragma mark Enable 10065a988416SJim Ingham 10075a988416SJim Ingham class CommandObjectBreakpointEnable : public CommandObjectParsed 10085a988416SJim Ingham { 10095a988416SJim Ingham public: 10105a988416SJim Ingham CommandObjectBreakpointEnable (CommandInterpreter &interpreter) : 10115a988416SJim Ingham CommandObjectParsed (interpreter, 10125a988416SJim Ingham "enable", 10135a988416SJim Ingham "Enable the specified disabled breakpoint(s). If no breakpoints are specified, enable all of them.", 10145a988416SJim Ingham NULL) 10155a988416SJim Ingham { 10165a988416SJim Ingham CommandArgumentEntry arg; 10175a988416SJim Ingham CommandObject::AddIDsArgumentData(arg, eArgTypeBreakpointID, eArgTypeBreakpointIDRange); 10185a988416SJim Ingham // Add the entry for the first argument for this command to the object's arguments vector. 10195a988416SJim Ingham m_arguments.push_back (arg); 10205a988416SJim Ingham } 10215a988416SJim Ingham 10225a988416SJim Ingham 10235a988416SJim Ingham virtual 10245a988416SJim Ingham ~CommandObjectBreakpointEnable () {} 10255a988416SJim Ingham 10265a988416SJim Ingham protected: 10275a988416SJim Ingham virtual bool 10285a988416SJim Ingham DoExecute (Args& command, CommandReturnObject &result) 10295a988416SJim Ingham { 10305a988416SJim Ingham Target *target = m_interpreter.GetDebugger().GetSelectedTarget().get(); 10315a988416SJim Ingham if (target == NULL) 10325a988416SJim Ingham { 10335a988416SJim Ingham result.AppendError ("Invalid target. No existing target or breakpoints."); 10345a988416SJim Ingham result.SetStatus (eReturnStatusFailed); 10355a988416SJim Ingham return false; 10365a988416SJim Ingham } 10375a988416SJim Ingham 10385a988416SJim Ingham Mutex::Locker locker; 10395a988416SJim Ingham target->GetBreakpointList().GetListMutex(locker); 10405a988416SJim Ingham 10415a988416SJim Ingham const BreakpointList &breakpoints = target->GetBreakpointList(); 10425a988416SJim Ingham 10435a988416SJim Ingham size_t num_breakpoints = breakpoints.GetSize(); 10445a988416SJim Ingham 10455a988416SJim Ingham if (num_breakpoints == 0) 10465a988416SJim Ingham { 10475a988416SJim Ingham result.AppendError ("No breakpoints exist to be enabled."); 10485a988416SJim Ingham result.SetStatus (eReturnStatusFailed); 10495a988416SJim Ingham return false; 10505a988416SJim Ingham } 10515a988416SJim Ingham 10525a988416SJim Ingham if (command.GetArgumentCount() == 0) 10535a988416SJim Ingham { 10545a988416SJim Ingham // No breakpoint selected; enable all currently set breakpoints. 10555a988416SJim Ingham target->EnableAllBreakpoints (); 10565a988416SJim Ingham result.AppendMessageWithFormat ("All breakpoints enabled. (%lu breakpoints)\n", num_breakpoints); 10575a988416SJim Ingham result.SetStatus (eReturnStatusSuccessFinishNoResult); 10585a988416SJim Ingham } 10595a988416SJim Ingham else 10605a988416SJim Ingham { 10615a988416SJim Ingham // Particular breakpoint selected; enable that breakpoint. 10625a988416SJim Ingham BreakpointIDList valid_bp_ids; 10635a988416SJim Ingham CommandObjectMultiwordBreakpoint::VerifyBreakpointIDs (command, target, result, &valid_bp_ids); 10645a988416SJim Ingham 10655a988416SJim Ingham if (result.Succeeded()) 10665a988416SJim Ingham { 10675a988416SJim Ingham int enable_count = 0; 10685a988416SJim Ingham int loc_count = 0; 10695a988416SJim Ingham const size_t count = valid_bp_ids.GetSize(); 10705a988416SJim Ingham for (size_t i = 0; i < count; ++i) 10715a988416SJim Ingham { 10725a988416SJim Ingham BreakpointID cur_bp_id = valid_bp_ids.GetBreakpointIDAtIndex (i); 10735a988416SJim Ingham 10745a988416SJim Ingham if (cur_bp_id.GetBreakpointID() != LLDB_INVALID_BREAK_ID) 10755a988416SJim Ingham { 10765a988416SJim Ingham Breakpoint *breakpoint = target->GetBreakpointByID (cur_bp_id.GetBreakpointID()).get(); 10775a988416SJim Ingham if (cur_bp_id.GetLocationID() != LLDB_INVALID_BREAK_ID) 10785a988416SJim Ingham { 10795a988416SJim Ingham BreakpointLocation *location = breakpoint->FindLocationByID (cur_bp_id.GetLocationID()).get(); 10805a988416SJim Ingham if (location) 10815a988416SJim Ingham { 10825a988416SJim Ingham location->SetEnabled (true); 10835a988416SJim Ingham ++loc_count; 10845a988416SJim Ingham } 10855a988416SJim Ingham } 10865a988416SJim Ingham else 10875a988416SJim Ingham { 10885a988416SJim Ingham breakpoint->SetEnabled (true); 10895a988416SJim Ingham ++enable_count; 10905a988416SJim Ingham } 10915a988416SJim Ingham } 10925a988416SJim Ingham } 10935a988416SJim Ingham result.AppendMessageWithFormat ("%d breakpoints enabled.\n", enable_count + loc_count); 10945a988416SJim Ingham result.SetStatus (eReturnStatusSuccessFinishNoResult); 10955a988416SJim Ingham } 10965a988416SJim Ingham } 10975a988416SJim Ingham 10985a988416SJim Ingham return result.Succeeded(); 10995a988416SJim Ingham } 11005a988416SJim Ingham }; 11015a988416SJim Ingham 11025a988416SJim Ingham //------------------------------------------------------------------------- 11035a988416SJim Ingham // CommandObjectBreakpointDisable 11045a988416SJim Ingham //------------------------------------------------------------------------- 11055a988416SJim Ingham #pragma mark Disable 11065a988416SJim Ingham 11075a988416SJim Ingham class CommandObjectBreakpointDisable : public CommandObjectParsed 11085a988416SJim Ingham { 11095a988416SJim Ingham public: 11105a988416SJim Ingham CommandObjectBreakpointDisable (CommandInterpreter &interpreter) : 11115a988416SJim Ingham CommandObjectParsed (interpreter, 11125a988416SJim Ingham "breakpoint disable", 11135a988416SJim Ingham "Disable the specified breakpoint(s) without removing it/them. If no breakpoints are specified, disable them all.", 11145a988416SJim Ingham NULL) 11155a988416SJim Ingham { 1116*b0fac509SJim Ingham SetHelpLong( 1117*b0fac509SJim Ingham "Disable the specified breakpoint(s) without removing it/them. \n\ 1118*b0fac509SJim Ingham If no breakpoints are specified, disable them all.\n\ 1119*b0fac509SJim Ingham \n\ 1120*b0fac509SJim Ingham Note: disabling a breakpoint will cause none of its locations to be hit\n\ 1121*b0fac509SJim Ingham regardless of whether they are enabled or disabled. So the sequence: \n\ 1122*b0fac509SJim Ingham \n\ 1123*b0fac509SJim Ingham (lldb) break disable 1\n\ 1124*b0fac509SJim Ingham (lldb) break enable 1.1\n\ 1125*b0fac509SJim Ingham \n\ 1126*b0fac509SJim Ingham will NOT cause location 1.1 to get hit. To achieve that, do:\n\ 1127*b0fac509SJim Ingham \n\ 1128*b0fac509SJim Ingham (lldb) break disable 1.*\n\ 1129*b0fac509SJim Ingham (lldb) break enable 1.1\n\ 1130*b0fac509SJim Ingham \n\ 1131*b0fac509SJim Ingham The first command disables all the locations of breakpoint 1, \n\ 1132*b0fac509SJim Ingham the second re-enables the first location." 1133*b0fac509SJim Ingham ); 1134*b0fac509SJim Ingham 11355a988416SJim Ingham CommandArgumentEntry arg; 11365a988416SJim Ingham CommandObject::AddIDsArgumentData(arg, eArgTypeBreakpointID, eArgTypeBreakpointIDRange); 11375a988416SJim Ingham // Add the entry for the first argument for this command to the object's arguments vector. 11385a988416SJim Ingham m_arguments.push_back (arg); 1139*b0fac509SJim Ingham 11405a988416SJim Ingham } 11415a988416SJim Ingham 11425a988416SJim Ingham 11435a988416SJim Ingham virtual 11445a988416SJim Ingham ~CommandObjectBreakpointDisable () {} 11455a988416SJim Ingham 11465a988416SJim Ingham protected: 11475a988416SJim Ingham virtual bool 11485a988416SJim Ingham DoExecute (Args& command, CommandReturnObject &result) 11495a988416SJim Ingham { 11505a988416SJim Ingham Target *target = m_interpreter.GetDebugger().GetSelectedTarget().get(); 11515a988416SJim Ingham if (target == NULL) 11525a988416SJim Ingham { 11535a988416SJim Ingham result.AppendError ("Invalid target. No existing target or breakpoints."); 11545a988416SJim Ingham result.SetStatus (eReturnStatusFailed); 11555a988416SJim Ingham return false; 11565a988416SJim Ingham } 11575a988416SJim Ingham 11585a988416SJim Ingham Mutex::Locker locker; 11595a988416SJim Ingham target->GetBreakpointList().GetListMutex(locker); 11605a988416SJim Ingham 11615a988416SJim Ingham const BreakpointList &breakpoints = target->GetBreakpointList(); 11625a988416SJim Ingham size_t num_breakpoints = breakpoints.GetSize(); 11635a988416SJim Ingham 11645a988416SJim Ingham if (num_breakpoints == 0) 11655a988416SJim Ingham { 11665a988416SJim Ingham result.AppendError ("No breakpoints exist to be disabled."); 11675a988416SJim Ingham result.SetStatus (eReturnStatusFailed); 11685a988416SJim Ingham return false; 11695a988416SJim Ingham } 11705a988416SJim Ingham 11715a988416SJim Ingham if (command.GetArgumentCount() == 0) 11725a988416SJim Ingham { 11735a988416SJim Ingham // No breakpoint selected; disable all currently set breakpoints. 11745a988416SJim Ingham target->DisableAllBreakpoints (); 11755a988416SJim Ingham result.AppendMessageWithFormat ("All breakpoints disabled. (%lu breakpoints)\n", num_breakpoints); 11765a988416SJim Ingham result.SetStatus (eReturnStatusSuccessFinishNoResult); 11775a988416SJim Ingham } 11785a988416SJim Ingham else 11795a988416SJim Ingham { 11805a988416SJim Ingham // Particular breakpoint selected; disable that breakpoint. 11815a988416SJim Ingham BreakpointIDList valid_bp_ids; 11825a988416SJim Ingham 11835a988416SJim Ingham CommandObjectMultiwordBreakpoint::VerifyBreakpointIDs (command, target, result, &valid_bp_ids); 11845a988416SJim Ingham 11855a988416SJim Ingham if (result.Succeeded()) 11865a988416SJim Ingham { 11875a988416SJim Ingham int disable_count = 0; 11885a988416SJim Ingham int loc_count = 0; 11895a988416SJim Ingham const size_t count = valid_bp_ids.GetSize(); 11905a988416SJim Ingham for (size_t i = 0; i < count; ++i) 11915a988416SJim Ingham { 11925a988416SJim Ingham BreakpointID cur_bp_id = valid_bp_ids.GetBreakpointIDAtIndex (i); 11935a988416SJim Ingham 11945a988416SJim Ingham if (cur_bp_id.GetBreakpointID() != LLDB_INVALID_BREAK_ID) 11955a988416SJim Ingham { 11965a988416SJim Ingham Breakpoint *breakpoint = target->GetBreakpointByID (cur_bp_id.GetBreakpointID()).get(); 11975a988416SJim Ingham if (cur_bp_id.GetLocationID() != LLDB_INVALID_BREAK_ID) 11985a988416SJim Ingham { 11995a988416SJim Ingham BreakpointLocation *location = breakpoint->FindLocationByID (cur_bp_id.GetLocationID()).get(); 12005a988416SJim Ingham if (location) 12015a988416SJim Ingham { 12025a988416SJim Ingham location->SetEnabled (false); 12035a988416SJim Ingham ++loc_count; 12045a988416SJim Ingham } 12055a988416SJim Ingham } 12065a988416SJim Ingham else 12075a988416SJim Ingham { 12085a988416SJim Ingham breakpoint->SetEnabled (false); 12095a988416SJim Ingham ++disable_count; 12105a988416SJim Ingham } 12115a988416SJim Ingham } 12125a988416SJim Ingham } 12135a988416SJim Ingham result.AppendMessageWithFormat ("%d breakpoints disabled.\n", disable_count + loc_count); 12145a988416SJim Ingham result.SetStatus (eReturnStatusSuccessFinishNoResult); 12155a988416SJim Ingham } 12165a988416SJim Ingham } 12175a988416SJim Ingham 12185a988416SJim Ingham return result.Succeeded(); 12195a988416SJim Ingham } 12205a988416SJim Ingham 12215a988416SJim Ingham }; 12225a988416SJim Ingham 12235a988416SJim Ingham //------------------------------------------------------------------------- 12245a988416SJim Ingham // CommandObjectBreakpointList 12255a988416SJim Ingham //------------------------------------------------------------------------- 12265a988416SJim Ingham #pragma mark List 12275a988416SJim Ingham 12285a988416SJim Ingham class CommandObjectBreakpointList : public CommandObjectParsed 12295a988416SJim Ingham { 12305a988416SJim Ingham public: 12315a988416SJim Ingham CommandObjectBreakpointList (CommandInterpreter &interpreter) : 12325a988416SJim Ingham CommandObjectParsed (interpreter, 12335a988416SJim Ingham "breakpoint list", 12345a988416SJim Ingham "List some or all breakpoints at configurable levels of detail.", 12355a988416SJim Ingham NULL), 12365a988416SJim Ingham m_options (interpreter) 12375a988416SJim Ingham { 12385a988416SJim Ingham CommandArgumentEntry arg; 12395a988416SJim Ingham CommandArgumentData bp_id_arg; 12405a988416SJim Ingham 12415a988416SJim Ingham // Define the first (and only) variant of this arg. 12425a988416SJim Ingham bp_id_arg.arg_type = eArgTypeBreakpointID; 12435a988416SJim Ingham bp_id_arg.arg_repetition = eArgRepeatOptional; 12445a988416SJim Ingham 12455a988416SJim Ingham // There is only one variant this argument could be; put it into the argument entry. 12465a988416SJim Ingham arg.push_back (bp_id_arg); 12475a988416SJim Ingham 12485a988416SJim Ingham // Push the data for the first argument into the m_arguments vector. 12495a988416SJim Ingham m_arguments.push_back (arg); 12505a988416SJim Ingham } 12515a988416SJim Ingham 12525a988416SJim Ingham 12535a988416SJim Ingham virtual 12545a988416SJim Ingham ~CommandObjectBreakpointList () {} 12555a988416SJim Ingham 12565a988416SJim Ingham virtual Options * 12575a988416SJim Ingham GetOptions () 12585a988416SJim Ingham { 12595a988416SJim Ingham return &m_options; 12605a988416SJim Ingham } 12615a988416SJim Ingham 12625a988416SJim Ingham class CommandOptions : public Options 12635a988416SJim Ingham { 12645a988416SJim Ingham public: 12655a988416SJim Ingham 12665a988416SJim Ingham CommandOptions (CommandInterpreter &interpreter) : 12675a988416SJim Ingham Options (interpreter), 12685a988416SJim Ingham m_level (lldb::eDescriptionLevelBrief) // Breakpoint List defaults to brief descriptions 12695a988416SJim Ingham { 12705a988416SJim Ingham } 12715a988416SJim Ingham 12725a988416SJim Ingham virtual 12735a988416SJim Ingham ~CommandOptions () {} 12745a988416SJim Ingham 12755a988416SJim Ingham virtual Error 12765a988416SJim Ingham SetOptionValue (uint32_t option_idx, const char *option_arg) 12775a988416SJim Ingham { 12785a988416SJim Ingham Error error; 12793bcdfc0eSGreg Clayton const int short_option = m_getopt_table[option_idx].val; 12805a988416SJim Ingham 12815a988416SJim Ingham switch (short_option) 12825a988416SJim Ingham { 12835a988416SJim Ingham case 'b': 12845a988416SJim Ingham m_level = lldb::eDescriptionLevelBrief; 12855a988416SJim Ingham break; 12865a988416SJim Ingham case 'f': 12875a988416SJim Ingham m_level = lldb::eDescriptionLevelFull; 12885a988416SJim Ingham break; 12895a988416SJim Ingham case 'v': 12905a988416SJim Ingham m_level = lldb::eDescriptionLevelVerbose; 12915a988416SJim Ingham break; 12925a988416SJim Ingham case 'i': 12935a988416SJim Ingham m_internal = true; 12945a988416SJim Ingham break; 12955a988416SJim Ingham default: 12965a988416SJim Ingham error.SetErrorStringWithFormat ("unrecognized option '%c'", short_option); 12975a988416SJim Ingham break; 12985a988416SJim Ingham } 12995a988416SJim Ingham 13005a988416SJim Ingham return error; 13015a988416SJim Ingham } 13025a988416SJim Ingham 13035a988416SJim Ingham void 13045a988416SJim Ingham OptionParsingStarting () 13055a988416SJim Ingham { 13065a988416SJim Ingham m_level = lldb::eDescriptionLevelFull; 13075a988416SJim Ingham m_internal = false; 13085a988416SJim Ingham } 13095a988416SJim Ingham 13105a988416SJim Ingham const OptionDefinition * 13115a988416SJim Ingham GetDefinitions () 13125a988416SJim Ingham { 13135a988416SJim Ingham return g_option_table; 13145a988416SJim Ingham } 13155a988416SJim Ingham 13165a988416SJim Ingham // Options table: Required for subclasses of Options. 13175a988416SJim Ingham 13185a988416SJim Ingham static OptionDefinition g_option_table[]; 13195a988416SJim Ingham 13205a988416SJim Ingham // Instance variables to hold the values for command options. 13215a988416SJim Ingham 13225a988416SJim Ingham lldb::DescriptionLevel m_level; 13235a988416SJim Ingham 13245a988416SJim Ingham bool m_internal; 13255a988416SJim Ingham }; 13265a988416SJim Ingham 13275a988416SJim Ingham protected: 13285a988416SJim Ingham virtual bool 13295a988416SJim Ingham DoExecute (Args& command, CommandReturnObject &result) 13305a988416SJim Ingham { 13315a988416SJim Ingham Target *target = m_interpreter.GetDebugger().GetSelectedTarget().get(); 13325a988416SJim Ingham if (target == NULL) 13335a988416SJim Ingham { 13345a988416SJim Ingham result.AppendError ("Invalid target. No current target or breakpoints."); 13355a988416SJim Ingham result.SetStatus (eReturnStatusSuccessFinishNoResult); 13365a988416SJim Ingham return true; 13375a988416SJim Ingham } 13385a988416SJim Ingham 13395a988416SJim Ingham const BreakpointList &breakpoints = target->GetBreakpointList(m_options.m_internal); 13405a988416SJim Ingham Mutex::Locker locker; 13415a988416SJim Ingham target->GetBreakpointList(m_options.m_internal).GetListMutex(locker); 13425a988416SJim Ingham 13435a988416SJim Ingham size_t num_breakpoints = breakpoints.GetSize(); 13445a988416SJim Ingham 13455a988416SJim Ingham if (num_breakpoints == 0) 13465a988416SJim Ingham { 13475a988416SJim Ingham result.AppendMessage ("No breakpoints currently set."); 13485a988416SJim Ingham result.SetStatus (eReturnStatusSuccessFinishNoResult); 13495a988416SJim Ingham return true; 13505a988416SJim Ingham } 13515a988416SJim Ingham 13525a988416SJim Ingham Stream &output_stream = result.GetOutputStream(); 13535a988416SJim Ingham 13545a988416SJim Ingham if (command.GetArgumentCount() == 0) 13555a988416SJim Ingham { 13565a988416SJim Ingham // No breakpoint selected; show info about all currently set breakpoints. 13575a988416SJim Ingham result.AppendMessage ("Current breakpoints:"); 13585a988416SJim Ingham for (size_t i = 0; i < num_breakpoints; ++i) 13595a988416SJim Ingham { 13605a988416SJim Ingham Breakpoint *breakpoint = breakpoints.GetBreakpointAtIndex (i).get(); 13615a988416SJim Ingham AddBreakpointDescription (&output_stream, breakpoint, m_options.m_level); 13625a988416SJim Ingham } 13635a988416SJim Ingham result.SetStatus (eReturnStatusSuccessFinishNoResult); 13645a988416SJim Ingham } 13655a988416SJim Ingham else 13665a988416SJim Ingham { 13675a988416SJim Ingham // Particular breakpoints selected; show info about that breakpoint. 13685a988416SJim Ingham BreakpointIDList valid_bp_ids; 13695a988416SJim Ingham CommandObjectMultiwordBreakpoint::VerifyBreakpointIDs (command, target, result, &valid_bp_ids); 13705a988416SJim Ingham 13715a988416SJim Ingham if (result.Succeeded()) 13725a988416SJim Ingham { 13735a988416SJim Ingham for (size_t i = 0; i < valid_bp_ids.GetSize(); ++i) 13745a988416SJim Ingham { 13755a988416SJim Ingham BreakpointID cur_bp_id = valid_bp_ids.GetBreakpointIDAtIndex (i); 13765a988416SJim Ingham Breakpoint *breakpoint = target->GetBreakpointByID (cur_bp_id.GetBreakpointID()).get(); 13775a988416SJim Ingham AddBreakpointDescription (&output_stream, breakpoint, m_options.m_level); 13785a988416SJim Ingham } 13795a988416SJim Ingham result.SetStatus (eReturnStatusSuccessFinishNoResult); 13805a988416SJim Ingham } 13815a988416SJim Ingham else 13825a988416SJim Ingham { 13835a988416SJim Ingham result.AppendError ("Invalid breakpoint id."); 13845a988416SJim Ingham result.SetStatus (eReturnStatusFailed); 13855a988416SJim Ingham } 13865a988416SJim Ingham } 13875a988416SJim Ingham 13885a988416SJim Ingham return result.Succeeded(); 13895a988416SJim Ingham } 13905a988416SJim Ingham 13915a988416SJim Ingham private: 13925a988416SJim Ingham CommandOptions m_options; 13935a988416SJim Ingham }; 13945a988416SJim Ingham 13955a988416SJim Ingham #pragma mark List::CommandOptions 13965a988416SJim Ingham OptionDefinition 13975a988416SJim Ingham CommandObjectBreakpointList::CommandOptions::g_option_table[] = 13985a988416SJim Ingham { 13995a988416SJim Ingham { LLDB_OPT_SET_ALL, false, "internal", 'i', no_argument, NULL, 0, eArgTypeNone, 14005a988416SJim Ingham "Show debugger internal breakpoints" }, 14015a988416SJim Ingham 14025a988416SJim Ingham { LLDB_OPT_SET_1, false, "brief", 'b', no_argument, NULL, 0, eArgTypeNone, 14035a988416SJim Ingham "Give a brief description of the breakpoint (no location info)."}, 14045a988416SJim Ingham 14055a988416SJim Ingham // FIXME: We need to add an "internal" command, and then add this sort of thing to it. 14065a988416SJim Ingham // But I need to see it for now, and don't want to wait. 14075a988416SJim Ingham { LLDB_OPT_SET_2, false, "full", 'f', no_argument, NULL, 0, eArgTypeNone, 14085a988416SJim Ingham "Give a full description of the breakpoint and its locations."}, 14095a988416SJim Ingham 14105a988416SJim Ingham { LLDB_OPT_SET_3, false, "verbose", 'v', no_argument, NULL, 0, eArgTypeNone, 14115a988416SJim Ingham "Explain everything we know about the breakpoint (for debugging debugger bugs)." }, 14125a988416SJim Ingham 14135a988416SJim Ingham { 0, false, NULL, 0, 0, NULL, 0, eArgTypeNone, NULL } 14145a988416SJim Ingham }; 14155a988416SJim Ingham 14165a988416SJim Ingham //------------------------------------------------------------------------- 14175a988416SJim Ingham // CommandObjectBreakpointClear 14185a988416SJim Ingham //------------------------------------------------------------------------- 14195a988416SJim Ingham #pragma mark Clear 14205a988416SJim Ingham 14215a988416SJim Ingham class CommandObjectBreakpointClear : public CommandObjectParsed 14225a988416SJim Ingham { 14235a988416SJim Ingham public: 14245a988416SJim Ingham 14255a988416SJim Ingham typedef enum BreakpointClearType 14265a988416SJim Ingham { 14275a988416SJim Ingham eClearTypeInvalid, 14285a988416SJim Ingham eClearTypeFileAndLine 14295a988416SJim Ingham } BreakpointClearType; 14305a988416SJim Ingham 14315a988416SJim Ingham CommandObjectBreakpointClear (CommandInterpreter &interpreter) : 14325a988416SJim Ingham CommandObjectParsed (interpreter, 14335a988416SJim Ingham "breakpoint clear", 14345a988416SJim Ingham "Clears a breakpoint or set of breakpoints in the executable.", 14355a988416SJim Ingham "breakpoint clear <cmd-options>"), 14365a988416SJim Ingham m_options (interpreter) 14375a988416SJim Ingham { 14385a988416SJim Ingham } 14395a988416SJim Ingham 14405a988416SJim Ingham virtual 14415a988416SJim Ingham ~CommandObjectBreakpointClear () {} 14425a988416SJim Ingham 14435a988416SJim Ingham virtual Options * 14445a988416SJim Ingham GetOptions () 14455a988416SJim Ingham { 14465a988416SJim Ingham return &m_options; 14475a988416SJim Ingham } 14485a988416SJim Ingham 14495a988416SJim Ingham class CommandOptions : public Options 14505a988416SJim Ingham { 14515a988416SJim Ingham public: 14525a988416SJim Ingham 14535a988416SJim Ingham CommandOptions (CommandInterpreter &interpreter) : 14545a988416SJim Ingham Options (interpreter), 14555a988416SJim Ingham m_filename (), 14565a988416SJim Ingham m_line_num (0) 14575a988416SJim Ingham { 14585a988416SJim Ingham } 14595a988416SJim Ingham 14605a988416SJim Ingham virtual 14615a988416SJim Ingham ~CommandOptions () {} 14625a988416SJim Ingham 14635a988416SJim Ingham virtual Error 14645a988416SJim Ingham SetOptionValue (uint32_t option_idx, const char *option_arg) 14655a988416SJim Ingham { 14665a988416SJim Ingham Error error; 14673bcdfc0eSGreg Clayton const int short_option = m_getopt_table[option_idx].val; 14685a988416SJim Ingham 14695a988416SJim Ingham switch (short_option) 14705a988416SJim Ingham { 14715a988416SJim Ingham case 'f': 14725a988416SJim Ingham m_filename.assign (option_arg); 14735a988416SJim Ingham break; 14745a988416SJim Ingham 14755a988416SJim Ingham case 'l': 14765a988416SJim Ingham m_line_num = Args::StringToUInt32 (option_arg, 0); 14775a988416SJim Ingham break; 14785a988416SJim Ingham 14795a988416SJim Ingham default: 14805a988416SJim Ingham error.SetErrorStringWithFormat ("unrecognized option '%c'", short_option); 14815a988416SJim Ingham break; 14825a988416SJim Ingham } 14835a988416SJim Ingham 14845a988416SJim Ingham return error; 14855a988416SJim Ingham } 14865a988416SJim Ingham 14875a988416SJim Ingham void 14885a988416SJim Ingham OptionParsingStarting () 14895a988416SJim Ingham { 14905a988416SJim Ingham m_filename.clear(); 14915a988416SJim Ingham m_line_num = 0; 14925a988416SJim Ingham } 14935a988416SJim Ingham 14945a988416SJim Ingham const OptionDefinition* 14955a988416SJim Ingham GetDefinitions () 14965a988416SJim Ingham { 14975a988416SJim Ingham return g_option_table; 14985a988416SJim Ingham } 14995a988416SJim Ingham 15005a988416SJim Ingham // Options table: Required for subclasses of Options. 15015a988416SJim Ingham 15025a988416SJim Ingham static OptionDefinition g_option_table[]; 15035a988416SJim Ingham 15045a988416SJim Ingham // Instance variables to hold the values for command options. 15055a988416SJim Ingham 15065a988416SJim Ingham std::string m_filename; 15075a988416SJim Ingham uint32_t m_line_num; 15085a988416SJim Ingham 15095a988416SJim Ingham }; 15105a988416SJim Ingham 15115a988416SJim Ingham protected: 15125a988416SJim Ingham virtual bool 15135a988416SJim Ingham DoExecute (Args& command, CommandReturnObject &result) 15145a988416SJim Ingham { 15155a988416SJim Ingham Target *target = m_interpreter.GetDebugger().GetSelectedTarget().get(); 15165a988416SJim Ingham if (target == NULL) 15175a988416SJim Ingham { 15185a988416SJim Ingham result.AppendError ("Invalid target. No existing target or breakpoints."); 15195a988416SJim Ingham result.SetStatus (eReturnStatusFailed); 15205a988416SJim Ingham return false; 15215a988416SJim Ingham } 15225a988416SJim Ingham 15235a988416SJim Ingham // The following are the various types of breakpoints that could be cleared: 15245a988416SJim Ingham // 1). -f -l (clearing breakpoint by source location) 15255a988416SJim Ingham 15265a988416SJim Ingham BreakpointClearType break_type = eClearTypeInvalid; 15275a988416SJim Ingham 15285a988416SJim Ingham if (m_options.m_line_num != 0) 15295a988416SJim Ingham break_type = eClearTypeFileAndLine; 15305a988416SJim Ingham 15315a988416SJim Ingham Mutex::Locker locker; 15325a988416SJim Ingham target->GetBreakpointList().GetListMutex(locker); 15335a988416SJim Ingham 15345a988416SJim Ingham BreakpointList &breakpoints = target->GetBreakpointList(); 15355a988416SJim Ingham size_t num_breakpoints = breakpoints.GetSize(); 15365a988416SJim Ingham 15375a988416SJim Ingham // Early return if there's no breakpoint at all. 15385a988416SJim Ingham if (num_breakpoints == 0) 15395a988416SJim Ingham { 15405a988416SJim Ingham result.AppendError ("Breakpoint clear: No breakpoint cleared."); 15415a988416SJim Ingham result.SetStatus (eReturnStatusFailed); 15425a988416SJim Ingham return result.Succeeded(); 15435a988416SJim Ingham } 15445a988416SJim Ingham 15455a988416SJim Ingham // Find matching breakpoints and delete them. 15465a988416SJim Ingham 15475a988416SJim Ingham // First create a copy of all the IDs. 15485a988416SJim Ingham std::vector<break_id_t> BreakIDs; 15495a988416SJim Ingham for (size_t i = 0; i < num_breakpoints; ++i) 15505a988416SJim Ingham BreakIDs.push_back(breakpoints.GetBreakpointAtIndex(i).get()->GetID()); 15515a988416SJim Ingham 15525a988416SJim Ingham int num_cleared = 0; 15535a988416SJim Ingham StreamString ss; 15545a988416SJim Ingham switch (break_type) 15555a988416SJim Ingham { 15565a988416SJim Ingham case eClearTypeFileAndLine: // Breakpoint by source position 15575a988416SJim Ingham { 15585a988416SJim Ingham const ConstString filename(m_options.m_filename.c_str()); 15595a988416SJim Ingham BreakpointLocationCollection loc_coll; 15605a988416SJim Ingham 15615a988416SJim Ingham for (size_t i = 0; i < num_breakpoints; ++i) 15625a988416SJim Ingham { 15635a988416SJim Ingham Breakpoint *bp = breakpoints.FindBreakpointByID(BreakIDs[i]).get(); 15645a988416SJim Ingham 15655a988416SJim Ingham if (bp->GetMatchingFileLine(filename, m_options.m_line_num, loc_coll)) 15665a988416SJim Ingham { 15675a988416SJim Ingham // If the collection size is 0, it's a full match and we can just remove the breakpoint. 15685a988416SJim Ingham if (loc_coll.GetSize() == 0) 15695a988416SJim Ingham { 15705a988416SJim Ingham bp->GetDescription(&ss, lldb::eDescriptionLevelBrief); 15715a988416SJim Ingham ss.EOL(); 15725a988416SJim Ingham target->RemoveBreakpointByID (bp->GetID()); 15735a988416SJim Ingham ++num_cleared; 15745a988416SJim Ingham } 15755a988416SJim Ingham } 15765a988416SJim Ingham } 15775a988416SJim Ingham } 15785a988416SJim Ingham break; 15795a988416SJim Ingham 15805a988416SJim Ingham default: 15815a988416SJim Ingham break; 15825a988416SJim Ingham } 15835a988416SJim Ingham 15845a988416SJim Ingham if (num_cleared > 0) 15855a988416SJim Ingham { 15865a988416SJim Ingham Stream &output_stream = result.GetOutputStream(); 15875a988416SJim Ingham output_stream.Printf ("%d breakpoints cleared:\n", num_cleared); 15885a988416SJim Ingham output_stream << ss.GetData(); 15895a988416SJim Ingham output_stream.EOL(); 15905a988416SJim Ingham result.SetStatus (eReturnStatusSuccessFinishNoResult); 15915a988416SJim Ingham } 15925a988416SJim Ingham else 15935a988416SJim Ingham { 15945a988416SJim Ingham result.AppendError ("Breakpoint clear: No breakpoint cleared."); 15955a988416SJim Ingham result.SetStatus (eReturnStatusFailed); 15965a988416SJim Ingham } 15975a988416SJim Ingham 15985a988416SJim Ingham return result.Succeeded(); 15995a988416SJim Ingham } 16005a988416SJim Ingham 16015a988416SJim Ingham private: 16025a988416SJim Ingham CommandOptions m_options; 16035a988416SJim Ingham }; 16045a988416SJim Ingham 16055a988416SJim Ingham #pragma mark Clear::CommandOptions 16065a988416SJim Ingham 16075a988416SJim Ingham OptionDefinition 16085a988416SJim Ingham CommandObjectBreakpointClear::CommandOptions::g_option_table[] = 16095a988416SJim Ingham { 16105a988416SJim Ingham { LLDB_OPT_SET_1, false, "file", 'f', required_argument, NULL, CommandCompletions::eSourceFileCompletion, eArgTypeFilename, 16115a988416SJim Ingham "Specify the breakpoint by source location in this particular file."}, 16125a988416SJim Ingham 16135a988416SJim Ingham { LLDB_OPT_SET_1, true, "line", 'l', required_argument, NULL, 0, eArgTypeLineNum, 16145a988416SJim Ingham "Specify the breakpoint by source location at this particular line."}, 16155a988416SJim Ingham 16165a988416SJim Ingham { 0, false, NULL, 0, 0, NULL, 0, eArgTypeNone, NULL } 16175a988416SJim Ingham }; 16185a988416SJim Ingham 16195a988416SJim Ingham //------------------------------------------------------------------------- 16205a988416SJim Ingham // CommandObjectBreakpointDelete 16215a988416SJim Ingham //------------------------------------------------------------------------- 16225a988416SJim Ingham #pragma mark Delete 16235a988416SJim Ingham 16245a988416SJim Ingham class CommandObjectBreakpointDelete : public CommandObjectParsed 16255a988416SJim Ingham { 16265a988416SJim Ingham public: 16275a988416SJim Ingham CommandObjectBreakpointDelete (CommandInterpreter &interpreter) : 16285a988416SJim Ingham CommandObjectParsed (interpreter, 16295a988416SJim Ingham "breakpoint delete", 16305a988416SJim Ingham "Delete the specified breakpoint(s). If no breakpoints are specified, delete them all.", 16315a988416SJim Ingham NULL) 16325a988416SJim Ingham { 16335a988416SJim Ingham CommandArgumentEntry arg; 16345a988416SJim Ingham CommandObject::AddIDsArgumentData(arg, eArgTypeBreakpointID, eArgTypeBreakpointIDRange); 16355a988416SJim Ingham // Add the entry for the first argument for this command to the object's arguments vector. 16365a988416SJim Ingham m_arguments.push_back (arg); 16375a988416SJim Ingham } 16385a988416SJim Ingham 16395a988416SJim Ingham virtual 16405a988416SJim Ingham ~CommandObjectBreakpointDelete () {} 16415a988416SJim Ingham 16425a988416SJim Ingham protected: 16435a988416SJim Ingham virtual bool 16445a988416SJim Ingham DoExecute (Args& command, CommandReturnObject &result) 16455a988416SJim Ingham { 16465a988416SJim Ingham Target *target = m_interpreter.GetDebugger().GetSelectedTarget().get(); 16475a988416SJim Ingham if (target == NULL) 16485a988416SJim Ingham { 16495a988416SJim Ingham result.AppendError ("Invalid target. No existing target or breakpoints."); 16505a988416SJim Ingham result.SetStatus (eReturnStatusFailed); 16515a988416SJim Ingham return false; 16525a988416SJim Ingham } 16535a988416SJim Ingham 16545a988416SJim Ingham Mutex::Locker locker; 16555a988416SJim Ingham target->GetBreakpointList().GetListMutex(locker); 16565a988416SJim Ingham 16575a988416SJim Ingham const BreakpointList &breakpoints = target->GetBreakpointList(); 16585a988416SJim Ingham 16595a988416SJim Ingham size_t num_breakpoints = breakpoints.GetSize(); 16605a988416SJim Ingham 16615a988416SJim Ingham if (num_breakpoints == 0) 16625a988416SJim Ingham { 16635a988416SJim Ingham result.AppendError ("No breakpoints exist to be deleted."); 16645a988416SJim Ingham result.SetStatus (eReturnStatusFailed); 16655a988416SJim Ingham return false; 16665a988416SJim Ingham } 16675a988416SJim Ingham 16685a988416SJim Ingham if (command.GetArgumentCount() == 0) 16695a988416SJim Ingham { 16705a988416SJim Ingham if (!m_interpreter.Confirm ("About to delete all breakpoints, do you want to do that?", true)) 16715a988416SJim Ingham { 16725a988416SJim Ingham result.AppendMessage("Operation cancelled..."); 16735a988416SJim Ingham } 16745a988416SJim Ingham else 16755a988416SJim Ingham { 16765a988416SJim Ingham target->RemoveAllBreakpoints (); 16775a988416SJim Ingham result.AppendMessageWithFormat ("All breakpoints removed. (%lu breakpoints)\n", num_breakpoints); 16785a988416SJim Ingham } 16795a988416SJim Ingham result.SetStatus (eReturnStatusSuccessFinishNoResult); 16805a988416SJim Ingham } 16815a988416SJim Ingham else 16825a988416SJim Ingham { 16835a988416SJim Ingham // Particular breakpoint selected; disable that breakpoint. 16845a988416SJim Ingham BreakpointIDList valid_bp_ids; 16855a988416SJim Ingham CommandObjectMultiwordBreakpoint::VerifyBreakpointIDs (command, target, result, &valid_bp_ids); 16865a988416SJim Ingham 16875a988416SJim Ingham if (result.Succeeded()) 16885a988416SJim Ingham { 16895a988416SJim Ingham int delete_count = 0; 16905a988416SJim Ingham int disable_count = 0; 16915a988416SJim Ingham const size_t count = valid_bp_ids.GetSize(); 16925a988416SJim Ingham for (size_t i = 0; i < count; ++i) 16935a988416SJim Ingham { 16945a988416SJim Ingham BreakpointID cur_bp_id = valid_bp_ids.GetBreakpointIDAtIndex (i); 16955a988416SJim Ingham 16965a988416SJim Ingham if (cur_bp_id.GetBreakpointID() != LLDB_INVALID_BREAK_ID) 16975a988416SJim Ingham { 16985a988416SJim Ingham if (cur_bp_id.GetLocationID() != LLDB_INVALID_BREAK_ID) 16995a988416SJim Ingham { 17005a988416SJim Ingham Breakpoint *breakpoint = target->GetBreakpointByID (cur_bp_id.GetBreakpointID()).get(); 17015a988416SJim Ingham BreakpointLocation *location = breakpoint->FindLocationByID (cur_bp_id.GetLocationID()).get(); 17025a988416SJim Ingham // It makes no sense to try to delete individual locations, so we disable them instead. 17035a988416SJim Ingham if (location) 17045a988416SJim Ingham { 17055a988416SJim Ingham location->SetEnabled (false); 17065a988416SJim Ingham ++disable_count; 17075a988416SJim Ingham } 17085a988416SJim Ingham } 17095a988416SJim Ingham else 17105a988416SJim Ingham { 17115a988416SJim Ingham target->RemoveBreakpointByID (cur_bp_id.GetBreakpointID()); 17125a988416SJim Ingham ++delete_count; 17135a988416SJim Ingham } 17145a988416SJim Ingham } 17155a988416SJim Ingham } 17165a988416SJim Ingham result.AppendMessageWithFormat ("%d breakpoints deleted; %d breakpoint locations disabled.\n", 17175a988416SJim Ingham delete_count, disable_count); 17185a988416SJim Ingham result.SetStatus (eReturnStatusSuccessFinishNoResult); 17195a988416SJim Ingham } 17205a988416SJim Ingham } 17215a988416SJim Ingham return result.Succeeded(); 17225a988416SJim Ingham } 17235a988416SJim Ingham }; 17245a988416SJim Ingham 172530fdc8d8SChris Lattner //------------------------------------------------------------------------- 172630fdc8d8SChris Lattner // CommandObjectMultiwordBreakpoint 172730fdc8d8SChris Lattner //------------------------------------------------------------------------- 1728ae1c4cf5SJim Ingham #pragma mark MultiwordBreakpoint 172930fdc8d8SChris Lattner 17306611103cSGreg Clayton CommandObjectMultiwordBreakpoint::CommandObjectMultiwordBreakpoint (CommandInterpreter &interpreter) : 1731a7015092SGreg Clayton CommandObjectMultiword (interpreter, 1732a7015092SGreg Clayton "breakpoint", 173346fbc60fSJim Ingham "A set of commands for operating on breakpoints. Also see _regexp-break.", 173430fdc8d8SChris Lattner "breakpoint <command> [<command-options>]") 173530fdc8d8SChris Lattner { 1736a7015092SGreg Clayton CommandObjectSP list_command_object (new CommandObjectBreakpointList (interpreter)); 1737a7015092SGreg Clayton CommandObjectSP enable_command_object (new CommandObjectBreakpointEnable (interpreter)); 1738a7015092SGreg Clayton CommandObjectSP disable_command_object (new CommandObjectBreakpointDisable (interpreter)); 1739b7234e40SJohnny Chen CommandObjectSP clear_command_object (new CommandObjectBreakpointClear (interpreter)); 1740b7234e40SJohnny Chen CommandObjectSP delete_command_object (new CommandObjectBreakpointDelete (interpreter)); 1741a7015092SGreg Clayton CommandObjectSP set_command_object (new CommandObjectBreakpointSet (interpreter)); 174230fdc8d8SChris Lattner CommandObjectSP command_command_object (new CommandObjectBreakpointCommand (interpreter)); 1743a7015092SGreg Clayton CommandObjectSP modify_command_object (new CommandObjectBreakpointModify(interpreter)); 174430fdc8d8SChris Lattner 1745b7234e40SJohnny Chen list_command_object->SetCommandName ("breakpoint list"); 174630fdc8d8SChris Lattner enable_command_object->SetCommandName("breakpoint enable"); 174730fdc8d8SChris Lattner disable_command_object->SetCommandName("breakpoint disable"); 1748b7234e40SJohnny Chen clear_command_object->SetCommandName("breakpoint clear"); 1749b7234e40SJohnny Chen delete_command_object->SetCommandName("breakpoint delete"); 1750ae1c4cf5SJim Ingham set_command_object->SetCommandName("breakpoint set"); 1751b7234e40SJohnny Chen command_command_object->SetCommandName ("breakpoint command"); 1752b7234e40SJohnny Chen modify_command_object->SetCommandName ("breakpoint modify"); 175330fdc8d8SChris Lattner 175423f59509SGreg Clayton LoadSubCommand ("list", list_command_object); 175523f59509SGreg Clayton LoadSubCommand ("enable", enable_command_object); 175623f59509SGreg Clayton LoadSubCommand ("disable", disable_command_object); 175723f59509SGreg Clayton LoadSubCommand ("clear", clear_command_object); 175823f59509SGreg Clayton LoadSubCommand ("delete", delete_command_object); 175923f59509SGreg Clayton LoadSubCommand ("set", set_command_object); 176023f59509SGreg Clayton LoadSubCommand ("command", command_command_object); 176123f59509SGreg Clayton LoadSubCommand ("modify", modify_command_object); 176230fdc8d8SChris Lattner } 176330fdc8d8SChris Lattner 176430fdc8d8SChris Lattner CommandObjectMultiwordBreakpoint::~CommandObjectMultiwordBreakpoint () 176530fdc8d8SChris Lattner { 176630fdc8d8SChris Lattner } 176730fdc8d8SChris Lattner 176830fdc8d8SChris Lattner void 176930fdc8d8SChris Lattner CommandObjectMultiwordBreakpoint::VerifyBreakpointIDs (Args &args, Target *target, CommandReturnObject &result, 177030fdc8d8SChris Lattner BreakpointIDList *valid_ids) 177130fdc8d8SChris Lattner { 177230fdc8d8SChris Lattner // args can be strings representing 1). integers (for breakpoint ids) 177330fdc8d8SChris Lattner // 2). the full breakpoint & location canonical representation 177430fdc8d8SChris Lattner // 3). the word "to" or a hyphen, representing a range (in which case there 177530fdc8d8SChris Lattner // had *better* be an entry both before & after of one of the first two types. 177636f3b369SJim Ingham // If args is empty, we will use the last created breakpoint (if there is one.) 177730fdc8d8SChris Lattner 177830fdc8d8SChris Lattner Args temp_args; 177930fdc8d8SChris Lattner 178036f3b369SJim Ingham if (args.GetArgumentCount() == 0) 178136f3b369SJim Ingham { 17824d122c40SGreg Clayton if (target->GetLastCreatedBreakpoint()) 178336f3b369SJim Ingham { 178436f3b369SJim Ingham valid_ids->AddBreakpointID (BreakpointID(target->GetLastCreatedBreakpoint()->GetID(), LLDB_INVALID_BREAK_ID)); 178536f3b369SJim Ingham result.SetStatus (eReturnStatusSuccessFinishNoResult); 178636f3b369SJim Ingham } 178736f3b369SJim Ingham else 178836f3b369SJim Ingham { 178936f3b369SJim Ingham result.AppendError("No breakpoint specified and no last created breakpoint."); 179036f3b369SJim Ingham result.SetStatus (eReturnStatusFailed); 179136f3b369SJim Ingham } 179236f3b369SJim Ingham return; 179336f3b369SJim Ingham } 179436f3b369SJim Ingham 179530fdc8d8SChris Lattner // Create a new Args variable to use; copy any non-breakpoint-id-ranges stuff directly from the old ARGS to 179630fdc8d8SChris Lattner // the new TEMP_ARGS. Do not copy breakpoint id range strings over; instead generate a list of strings for 179730fdc8d8SChris Lattner // all the breakpoint ids in the range, and shove all of those breakpoint id strings into TEMP_ARGS. 179830fdc8d8SChris Lattner 179930fdc8d8SChris Lattner BreakpointIDList::FindAndReplaceIDRanges (args, target, result, temp_args); 180030fdc8d8SChris Lattner 180130fdc8d8SChris Lattner // NOW, convert the list of breakpoint id strings in TEMP_ARGS into an actual BreakpointIDList: 180230fdc8d8SChris Lattner 1803c982c768SGreg Clayton valid_ids->InsertStringArray (temp_args.GetConstArgumentVector(), temp_args.GetArgumentCount(), result); 180430fdc8d8SChris Lattner 180530fdc8d8SChris Lattner // At this point, all of the breakpoint ids that the user passed in have been converted to breakpoint IDs 180630fdc8d8SChris Lattner // and put into valid_ids. 180730fdc8d8SChris Lattner 180830fdc8d8SChris Lattner if (result.Succeeded()) 180930fdc8d8SChris Lattner { 181030fdc8d8SChris Lattner // Now that we've converted everything from args into a list of breakpoint ids, go through our tentative list 181130fdc8d8SChris Lattner // of breakpoint id's and verify that they correspond to valid/currently set breakpoints. 181230fdc8d8SChris Lattner 1813c982c768SGreg Clayton const size_t count = valid_ids->GetSize(); 1814c982c768SGreg Clayton for (size_t i = 0; i < count; ++i) 181530fdc8d8SChris Lattner { 181630fdc8d8SChris Lattner BreakpointID cur_bp_id = valid_ids->GetBreakpointIDAtIndex (i); 181730fdc8d8SChris Lattner Breakpoint *breakpoint = target->GetBreakpointByID (cur_bp_id.GetBreakpointID()).get(); 181830fdc8d8SChris Lattner if (breakpoint != NULL) 181930fdc8d8SChris Lattner { 1820c7bece56SGreg Clayton const size_t num_locations = breakpoint->GetNumLocations(); 182130fdc8d8SChris Lattner if (cur_bp_id.GetLocationID() > num_locations) 182230fdc8d8SChris Lattner { 182330fdc8d8SChris Lattner StreamString id_str; 1824c982c768SGreg Clayton BreakpointID::GetCanonicalReference (&id_str, 1825c982c768SGreg Clayton cur_bp_id.GetBreakpointID(), 182630fdc8d8SChris Lattner cur_bp_id.GetLocationID()); 1827c982c768SGreg Clayton i = valid_ids->GetSize() + 1; 182830fdc8d8SChris Lattner result.AppendErrorWithFormat ("'%s' is not a currently valid breakpoint/location id.\n", 182930fdc8d8SChris Lattner id_str.GetData()); 183030fdc8d8SChris Lattner result.SetStatus (eReturnStatusFailed); 183130fdc8d8SChris Lattner } 183230fdc8d8SChris Lattner } 183330fdc8d8SChris Lattner else 183430fdc8d8SChris Lattner { 1835c982c768SGreg Clayton i = valid_ids->GetSize() + 1; 183630fdc8d8SChris Lattner result.AppendErrorWithFormat ("'%d' is not a currently valid breakpoint id.\n", cur_bp_id.GetBreakpointID()); 183730fdc8d8SChris Lattner result.SetStatus (eReturnStatusFailed); 183830fdc8d8SChris Lattner } 183930fdc8d8SChris Lattner } 184030fdc8d8SChris Lattner } 184130fdc8d8SChris Lattner } 1842