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), 109*eb023e75SGreg Clayton m_hardware (false), 110a8558b62SJim Ingham m_language (eLanguageTypeUnknown), 111ca36cd16SJim Ingham m_skip_prologue (eLazyBoolCalculate), 112ca36cd16SJim Ingham m_one_shot (false) 11330fdc8d8SChris Lattner { 11430fdc8d8SChris Lattner } 11530fdc8d8SChris Lattner 11630fdc8d8SChris Lattner 1175a988416SJim Ingham virtual 1185a988416SJim Ingham ~CommandOptions () {} 11987df91b8SJim Ingham 1205a988416SJim Ingham virtual Error 1215a988416SJim Ingham SetOptionValue (uint32_t option_idx, const char *option_arg) 12230fdc8d8SChris Lattner { 12330fdc8d8SChris Lattner Error error; 1243bcdfc0eSGreg Clayton const int short_option = m_getopt_table[option_idx].val; 12530fdc8d8SChris Lattner 12630fdc8d8SChris Lattner switch (short_option) 12730fdc8d8SChris Lattner { 12830fdc8d8SChris Lattner case 'a': 129b9d5df58SGreg Clayton { 130b9d5df58SGreg Clayton ExecutionContext exe_ctx (m_interpreter.GetExecutionContext()); 131b9d5df58SGreg Clayton m_load_addr = Args::StringToAddress(&exe_ctx, option_arg, LLDB_INVALID_ADDRESS, &error); 132b9d5df58SGreg Clayton } 13330fdc8d8SChris Lattner break; 13430fdc8d8SChris Lattner 135ca36cd16SJim Ingham case 'b': 136ca36cd16SJim Ingham m_func_names.push_back (option_arg); 137ca36cd16SJim Ingham m_func_name_type_mask |= eFunctionNameTypeBase; 138ca36cd16SJim Ingham break; 139ca36cd16SJim Ingham 1407d49c9c8SJohnny Chen case 'C': 14130fdc8d8SChris Lattner m_column = Args::StringToUInt32 (option_arg, 0); 14230fdc8d8SChris Lattner break; 1430c5cd90dSGreg Clayton 1447d49c9c8SJohnny Chen case 'c': 1457d49c9c8SJohnny Chen m_condition.assign(option_arg); 1467d49c9c8SJohnny Chen break; 1477d49c9c8SJohnny Chen 148fab10e89SJim Ingham case 'E': 149fab10e89SJim Ingham { 150fab10e89SJim Ingham LanguageType language = LanguageRuntime::GetLanguageTypeFromString (option_arg); 151fab10e89SJim Ingham 152fab10e89SJim Ingham switch (language) 153fab10e89SJim Ingham { 154fab10e89SJim Ingham case eLanguageTypeC89: 155fab10e89SJim Ingham case eLanguageTypeC: 156fab10e89SJim Ingham case eLanguageTypeC99: 157fab10e89SJim Ingham m_language = eLanguageTypeC; 158fab10e89SJim Ingham break; 159fab10e89SJim Ingham case eLanguageTypeC_plus_plus: 160fab10e89SJim Ingham m_language = eLanguageTypeC_plus_plus; 161fab10e89SJim Ingham break; 162fab10e89SJim Ingham case eLanguageTypeObjC: 163fab10e89SJim Ingham m_language = eLanguageTypeObjC; 164fab10e89SJim Ingham break; 165fab10e89SJim Ingham case eLanguageTypeObjC_plus_plus: 166fab10e89SJim Ingham error.SetErrorStringWithFormat ("Set exception breakpoints separately for c++ and objective-c"); 167fab10e89SJim Ingham break; 168fab10e89SJim Ingham case eLanguageTypeUnknown: 169fab10e89SJim Ingham error.SetErrorStringWithFormat ("Unknown language type: '%s' for exception breakpoint", option_arg); 170fab10e89SJim Ingham break; 171fab10e89SJim Ingham default: 172fab10e89SJim Ingham error.SetErrorStringWithFormat ("Unsupported language type: '%s' for exception breakpoint", option_arg); 173fab10e89SJim Ingham } 174fab10e89SJim Ingham } 175fab10e89SJim Ingham break; 176ca36cd16SJim Ingham 177ca36cd16SJim Ingham case 'f': 178ca36cd16SJim Ingham m_filenames.AppendIfUnique (FileSpec(option_arg, false)); 179fab10e89SJim Ingham break; 180ca36cd16SJim Ingham 181ca36cd16SJim Ingham case 'F': 182ca36cd16SJim Ingham m_func_names.push_back (option_arg); 183ca36cd16SJim Ingham m_func_name_type_mask |= eFunctionNameTypeFull; 184ca36cd16SJim Ingham break; 185ca36cd16SJim Ingham 186fab10e89SJim Ingham case 'h': 187fab10e89SJim Ingham { 188fab10e89SJim Ingham bool success; 189fab10e89SJim Ingham m_catch_bp = Args::StringToBoolean (option_arg, true, &success); 190fab10e89SJim Ingham if (!success) 191fab10e89SJim Ingham error.SetErrorStringWithFormat ("Invalid boolean value for on-catch option: '%s'", option_arg); 192fab10e89SJim Ingham } 193168d469aSJim Ingham break; 194*eb023e75SGreg Clayton 195*eb023e75SGreg Clayton case 'H': 196*eb023e75SGreg Clayton m_hardware = true; 197*eb023e75SGreg Clayton break; 198*eb023e75SGreg Clayton 199ca36cd16SJim Ingham case 'i': 200ca36cd16SJim Ingham { 201ca36cd16SJim Ingham m_ignore_count = Args::StringToUInt32(option_arg, UINT32_MAX, 0); 202ca36cd16SJim Ingham if (m_ignore_count == UINT32_MAX) 203ca36cd16SJim Ingham error.SetErrorStringWithFormat ("invalid ignore count '%s'", option_arg); 204ca36cd16SJim Ingham break; 205ca36cd16SJim Ingham } 206ca36cd16SJim Ingham 207a8558b62SJim Ingham case 'K': 208a8558b62SJim Ingham { 209a8558b62SJim Ingham bool success; 210a8558b62SJim Ingham bool value; 211a8558b62SJim Ingham value = Args::StringToBoolean (option_arg, true, &success); 212a8558b62SJim Ingham if (value) 213a8558b62SJim Ingham m_skip_prologue = eLazyBoolYes; 214a8558b62SJim Ingham else 215a8558b62SJim Ingham m_skip_prologue = eLazyBoolNo; 216a8558b62SJim Ingham 217a8558b62SJim Ingham if (!success) 218a8558b62SJim Ingham error.SetErrorStringWithFormat ("Invalid boolean value for skip prologue option: '%s'", option_arg); 219a8558b62SJim Ingham } 220fab10e89SJim Ingham break; 221ca36cd16SJim Ingham 222ca36cd16SJim Ingham case 'l': 223ca36cd16SJim Ingham m_line_num = Args::StringToUInt32 (option_arg, 0); 224ca36cd16SJim Ingham break; 225ca36cd16SJim Ingham 226ca36cd16SJim Ingham case 'M': 227ca36cd16SJim Ingham m_func_names.push_back (option_arg); 228ca36cd16SJim Ingham m_func_name_type_mask |= eFunctionNameTypeMethod; 229ca36cd16SJim Ingham break; 230ca36cd16SJim Ingham 231ca36cd16SJim Ingham case 'n': 232ca36cd16SJim Ingham m_func_names.push_back (option_arg); 233ca36cd16SJim Ingham m_func_name_type_mask |= eFunctionNameTypeAuto; 234ca36cd16SJim Ingham break; 235ca36cd16SJim Ingham 236ca36cd16SJim Ingham case 'o': 237ca36cd16SJim Ingham m_one_shot = true; 238ca36cd16SJim Ingham break; 239ca36cd16SJim Ingham 240ca36cd16SJim Ingham case 'p': 241ca36cd16SJim Ingham m_source_text_regexp.assign (option_arg); 242ca36cd16SJim Ingham break; 243ca36cd16SJim Ingham 244ca36cd16SJim Ingham case 'q': 245ca36cd16SJim Ingham m_queue_name.assign (option_arg); 246ca36cd16SJim Ingham break; 247ca36cd16SJim Ingham 248ca36cd16SJim Ingham case 'r': 249ca36cd16SJim Ingham m_func_regexp.assign (option_arg); 250ca36cd16SJim Ingham break; 251ca36cd16SJim Ingham 252ca36cd16SJim Ingham case 's': 253ca36cd16SJim Ingham { 254ca36cd16SJim Ingham m_modules.AppendIfUnique (FileSpec (option_arg, false)); 255ca36cd16SJim Ingham break; 256ca36cd16SJim Ingham } 257ca36cd16SJim Ingham 258ca36cd16SJim Ingham case 'S': 259ca36cd16SJim Ingham m_func_names.push_back (option_arg); 260ca36cd16SJim Ingham m_func_name_type_mask |= eFunctionNameTypeSelector; 261ca36cd16SJim Ingham break; 262ca36cd16SJim Ingham 263ca36cd16SJim Ingham case 't' : 264ca36cd16SJim Ingham { 265ca36cd16SJim Ingham m_thread_id = Args::StringToUInt64(option_arg, LLDB_INVALID_THREAD_ID, 0); 266ca36cd16SJim Ingham if (m_thread_id == LLDB_INVALID_THREAD_ID) 267ca36cd16SJim Ingham error.SetErrorStringWithFormat ("invalid thread id string '%s'", option_arg); 268ca36cd16SJim Ingham } 269ca36cd16SJim Ingham break; 270ca36cd16SJim Ingham 271ca36cd16SJim Ingham case 'T': 272ca36cd16SJim Ingham m_thread_name.assign (option_arg); 273ca36cd16SJim Ingham break; 274ca36cd16SJim Ingham 275ca36cd16SJim Ingham case 'w': 276ca36cd16SJim Ingham { 277ca36cd16SJim Ingham bool success; 278ca36cd16SJim Ingham m_throw_bp = Args::StringToBoolean (option_arg, true, &success); 279ca36cd16SJim Ingham if (!success) 280ca36cd16SJim Ingham error.SetErrorStringWithFormat ("Invalid boolean value for on-throw option: '%s'", option_arg); 281ca36cd16SJim Ingham } 282ca36cd16SJim Ingham break; 283ca36cd16SJim Ingham 284ca36cd16SJim Ingham case 'x': 285ca36cd16SJim Ingham { 286ca36cd16SJim Ingham m_thread_index = Args::StringToUInt32(option_arg, UINT32_MAX, 0); 287ca36cd16SJim Ingham if (m_thread_id == UINT32_MAX) 288ca36cd16SJim Ingham error.SetErrorStringWithFormat ("invalid thread index string '%s'", option_arg); 289ca36cd16SJim Ingham 290ca36cd16SJim Ingham } 291ca36cd16SJim Ingham break; 292ca36cd16SJim Ingham 29330fdc8d8SChris Lattner default: 29486edbf41SGreg Clayton error.SetErrorStringWithFormat ("unrecognized option '%c'", short_option); 29530fdc8d8SChris Lattner break; 29630fdc8d8SChris Lattner } 29730fdc8d8SChris Lattner 29830fdc8d8SChris Lattner return error; 29930fdc8d8SChris Lattner } 30030fdc8d8SChris Lattner void 3015a988416SJim Ingham OptionParsingStarting () 30230fdc8d8SChris Lattner { 3037d49c9c8SJohnny Chen m_condition.clear(); 30487df91b8SJim Ingham m_filenames.Clear(); 30530fdc8d8SChris Lattner m_line_num = 0; 30630fdc8d8SChris Lattner m_column = 0; 307fab10e89SJim Ingham m_func_names.clear(); 3081f746071SGreg Clayton m_func_name_type_mask = eFunctionNameTypeNone; 30930fdc8d8SChris Lattner m_func_regexp.clear(); 3101f746071SGreg Clayton m_source_text_regexp.clear(); 31187df91b8SJim Ingham m_modules.Clear(); 3121f746071SGreg Clayton m_load_addr = LLDB_INVALID_ADDRESS; 313c982c768SGreg Clayton m_ignore_count = 0; 3141b54c88cSJim Ingham m_thread_id = LLDB_INVALID_THREAD_ID; 315c982c768SGreg Clayton m_thread_index = UINT32_MAX; 3161b54c88cSJim Ingham m_thread_name.clear(); 3171b54c88cSJim Ingham m_queue_name.clear(); 318fab10e89SJim Ingham m_catch_bp = false; 319fab10e89SJim Ingham m_throw_bp = true; 320*eb023e75SGreg Clayton m_hardware = false; 3211f746071SGreg Clayton m_language = eLanguageTypeUnknown; 322a8558b62SJim Ingham m_skip_prologue = eLazyBoolCalculate; 323ca36cd16SJim Ingham m_one_shot = false; 32430fdc8d8SChris Lattner } 32530fdc8d8SChris Lattner 3265a988416SJim Ingham const OptionDefinition* 3275a988416SJim Ingham GetDefinitions () 32830fdc8d8SChris Lattner { 3295a988416SJim Ingham return g_option_table; 33030fdc8d8SChris Lattner } 33130fdc8d8SChris Lattner 3325a988416SJim Ingham // Options table: Required for subclasses of Options. 33330fdc8d8SChris Lattner 3345a988416SJim Ingham static OptionDefinition g_option_table[]; 33530fdc8d8SChris Lattner 3365a988416SJim Ingham // Instance variables to hold the values for command options. 337969795f1SJim Ingham 3385a988416SJim Ingham std::string m_condition; 3395a988416SJim Ingham FileSpecList m_filenames; 3405a988416SJim Ingham uint32_t m_line_num; 3415a988416SJim Ingham uint32_t m_column; 3425a988416SJim Ingham std::vector<std::string> m_func_names; 3435a988416SJim Ingham uint32_t m_func_name_type_mask; 3445a988416SJim Ingham std::string m_func_regexp; 3455a988416SJim Ingham std::string m_source_text_regexp; 3465a988416SJim Ingham FileSpecList m_modules; 3475a988416SJim Ingham lldb::addr_t m_load_addr; 3485a988416SJim Ingham uint32_t m_ignore_count; 3495a988416SJim Ingham lldb::tid_t m_thread_id; 3505a988416SJim Ingham uint32_t m_thread_index; 3515a988416SJim Ingham std::string m_thread_name; 3525a988416SJim Ingham std::string m_queue_name; 3535a988416SJim Ingham bool m_catch_bp; 3545a988416SJim Ingham bool m_throw_bp; 355*eb023e75SGreg Clayton bool m_hardware; // Request to use hardware breakpoints 3565a988416SJim Ingham lldb::LanguageType m_language; 3575a988416SJim Ingham LazyBool m_skip_prologue; 358ca36cd16SJim Ingham bool m_one_shot; 3595a988416SJim Ingham 3605a988416SJim Ingham }; 3615a988416SJim Ingham 3625a988416SJim Ingham protected: 3635a988416SJim Ingham virtual bool 3645a988416SJim Ingham DoExecute (Args& command, 3655a988416SJim Ingham CommandReturnObject &result) 36630fdc8d8SChris Lattner { 367a7015092SGreg Clayton Target *target = m_interpreter.GetDebugger().GetSelectedTarget().get(); 36830fdc8d8SChris Lattner if (target == NULL) 36930fdc8d8SChris Lattner { 370effe5c95SGreg Clayton result.AppendError ("Invalid target. Must set target before setting breakpoints (see 'target create' command)."); 37130fdc8d8SChris Lattner result.SetStatus (eReturnStatusFailed); 37230fdc8d8SChris Lattner return false; 37330fdc8d8SChris Lattner } 37430fdc8d8SChris Lattner 37530fdc8d8SChris Lattner // The following are the various types of breakpoints that could be set: 37630fdc8d8SChris Lattner // 1). -f -l -p [-s -g] (setting breakpoint by source location) 37730fdc8d8SChris Lattner // 2). -a [-s -g] (setting breakpoint by address) 37830fdc8d8SChris Lattner // 3). -n [-s -g] (setting breakpoint by function name) 37930fdc8d8SChris Lattner // 4). -r [-s -g] (setting breakpoint by function name regular expression) 380969795f1SJim Ingham // 5). -p -f (setting a breakpoint by comparing a reg-exp to source text) 381fab10e89SJim Ingham // 6). -E [-w -h] (setting a breakpoint for exceptions for a given language.) 38230fdc8d8SChris Lattner 38330fdc8d8SChris Lattner BreakpointSetType break_type = eSetTypeInvalid; 38430fdc8d8SChris Lattner 38530fdc8d8SChris Lattner if (m_options.m_line_num != 0) 38630fdc8d8SChris Lattner break_type = eSetTypeFileAndLine; 38730fdc8d8SChris Lattner else if (m_options.m_load_addr != LLDB_INVALID_ADDRESS) 38830fdc8d8SChris Lattner break_type = eSetTypeAddress; 389fab10e89SJim Ingham else if (!m_options.m_func_names.empty()) 39030fdc8d8SChris Lattner break_type = eSetTypeFunctionName; 39130fdc8d8SChris Lattner else if (!m_options.m_func_regexp.empty()) 39230fdc8d8SChris Lattner break_type = eSetTypeFunctionRegexp; 393969795f1SJim Ingham else if (!m_options.m_source_text_regexp.empty()) 394969795f1SJim Ingham break_type = eSetTypeSourceRegexp; 395fab10e89SJim Ingham else if (m_options.m_language != eLanguageTypeUnknown) 396fab10e89SJim Ingham break_type = eSetTypeException; 39730fdc8d8SChris Lattner 39830fdc8d8SChris Lattner Breakpoint *bp = NULL; 399274060b6SGreg Clayton FileSpec module_spec; 400a8558b62SJim Ingham const bool internal = false; 401a8558b62SJim Ingham 40230fdc8d8SChris Lattner switch (break_type) 40330fdc8d8SChris Lattner { 40430fdc8d8SChris Lattner case eSetTypeFileAndLine: // Breakpoint by source position 40530fdc8d8SChris Lattner { 40630fdc8d8SChris Lattner FileSpec file; 407c7bece56SGreg Clayton const size_t num_files = m_options.m_filenames.GetSize(); 40887df91b8SJim Ingham if (num_files == 0) 40987df91b8SJim Ingham { 41087df91b8SJim Ingham if (!GetDefaultFile (target, file, result)) 41187df91b8SJim Ingham { 41287df91b8SJim Ingham result.AppendError("No file supplied and no default file available."); 41387df91b8SJim Ingham result.SetStatus (eReturnStatusFailed); 41487df91b8SJim Ingham return false; 41587df91b8SJim Ingham } 41687df91b8SJim Ingham } 41787df91b8SJim Ingham else if (num_files > 1) 41887df91b8SJim Ingham { 41987df91b8SJim Ingham result.AppendError("Only one file at a time is allowed for file and line breakpoints."); 42087df91b8SJim Ingham result.SetStatus (eReturnStatusFailed); 42187df91b8SJim Ingham return false; 42287df91b8SJim Ingham } 42387df91b8SJim Ingham else 42487df91b8SJim Ingham file = m_options.m_filenames.GetFileSpecAtIndex(0); 42530fdc8d8SChris Lattner 4261f746071SGreg Clayton // Only check for inline functions if 4271f746071SGreg Clayton LazyBool check_inlines = eLazyBoolCalculate; 4281f746071SGreg Clayton 42987df91b8SJim Ingham bp = target->CreateBreakpoint (&(m_options.m_modules), 43030fdc8d8SChris Lattner file, 43130fdc8d8SChris Lattner m_options.m_line_num, 4321f746071SGreg Clayton check_inlines, 433a8558b62SJim Ingham m_options.m_skip_prologue, 434*eb023e75SGreg Clayton internal, 435*eb023e75SGreg Clayton m_options.m_hardware).get(); 43630fdc8d8SChris Lattner } 43730fdc8d8SChris Lattner break; 4386eee5aa0SGreg Clayton 43930fdc8d8SChris Lattner case eSetTypeAddress: // Breakpoint by address 440*eb023e75SGreg Clayton bp = target->CreateBreakpoint (m_options.m_load_addr, 441*eb023e75SGreg Clayton internal, 442*eb023e75SGreg Clayton m_options.m_hardware).get(); 44330fdc8d8SChris Lattner break; 4440c5cd90dSGreg Clayton 44530fdc8d8SChris Lattner case eSetTypeFunctionName: // Breakpoint by function name 4460c5cd90dSGreg Clayton { 4470c5cd90dSGreg Clayton uint32_t name_type_mask = m_options.m_func_name_type_mask; 4480c5cd90dSGreg Clayton 4490c5cd90dSGreg Clayton if (name_type_mask == 0) 450e02b8504SGreg Clayton name_type_mask = eFunctionNameTypeAuto; 4510c5cd90dSGreg Clayton 45287df91b8SJim Ingham bp = target->CreateBreakpoint (&(m_options.m_modules), 45387df91b8SJim Ingham &(m_options.m_filenames), 454fab10e89SJim Ingham m_options.m_func_names, 455274060b6SGreg Clayton name_type_mask, 456a8558b62SJim Ingham m_options.m_skip_prologue, 457*eb023e75SGreg Clayton internal, 458*eb023e75SGreg Clayton m_options.m_hardware).get(); 4590c5cd90dSGreg Clayton } 46030fdc8d8SChris Lattner break; 4610c5cd90dSGreg Clayton 46230fdc8d8SChris Lattner case eSetTypeFunctionRegexp: // Breakpoint by regular expression function name 46330fdc8d8SChris Lattner { 46430fdc8d8SChris Lattner RegularExpression regexp(m_options.m_func_regexp.c_str()); 465969795f1SJim Ingham if (!regexp.IsValid()) 46630fdc8d8SChris Lattner { 467969795f1SJim Ingham char err_str[1024]; 468969795f1SJim Ingham regexp.GetErrorAsCString(err_str, sizeof(err_str)); 469969795f1SJim Ingham result.AppendErrorWithFormat("Function name regular expression could not be compiled: \"%s\"", 470969795f1SJim Ingham err_str); 47130fdc8d8SChris Lattner result.SetStatus (eReturnStatusFailed); 472969795f1SJim Ingham return false; 47330fdc8d8SChris Lattner } 47487df91b8SJim Ingham 475a8558b62SJim Ingham bp = target->CreateFuncRegexBreakpoint (&(m_options.m_modules), 476a8558b62SJim Ingham &(m_options.m_filenames), 477a8558b62SJim Ingham regexp, 478a8558b62SJim Ingham m_options.m_skip_prologue, 479*eb023e75SGreg Clayton internal, 480*eb023e75SGreg Clayton m_options.m_hardware).get(); 48130fdc8d8SChris Lattner } 48230fdc8d8SChris Lattner break; 483969795f1SJim Ingham case eSetTypeSourceRegexp: // Breakpoint by regexp on source text. 484969795f1SJim Ingham { 485c7bece56SGreg Clayton const size_t num_files = m_options.m_filenames.GetSize(); 48687df91b8SJim Ingham 48787df91b8SJim Ingham if (num_files == 0) 48887df91b8SJim Ingham { 489969795f1SJim Ingham FileSpec file; 49087df91b8SJim Ingham if (!GetDefaultFile (target, file, result)) 49187df91b8SJim Ingham { 49287df91b8SJim Ingham result.AppendError ("No files provided and could not find default file."); 49387df91b8SJim Ingham result.SetStatus (eReturnStatusFailed); 49487df91b8SJim Ingham return false; 49587df91b8SJim Ingham } 49687df91b8SJim Ingham else 49787df91b8SJim Ingham { 49887df91b8SJim Ingham m_options.m_filenames.Append (file); 49987df91b8SJim Ingham } 50087df91b8SJim Ingham } 5010c5cd90dSGreg Clayton 502969795f1SJim Ingham RegularExpression regexp(m_options.m_source_text_regexp.c_str()); 503969795f1SJim Ingham if (!regexp.IsValid()) 504969795f1SJim Ingham { 505969795f1SJim Ingham char err_str[1024]; 506969795f1SJim Ingham regexp.GetErrorAsCString(err_str, sizeof(err_str)); 507969795f1SJim Ingham result.AppendErrorWithFormat("Source text regular expression could not be compiled: \"%s\"", 508969795f1SJim Ingham err_str); 509969795f1SJim Ingham result.SetStatus (eReturnStatusFailed); 510969795f1SJim Ingham return false; 511969795f1SJim Ingham } 512*eb023e75SGreg Clayton bp = target->CreateSourceRegexBreakpoint (&(m_options.m_modules), 513*eb023e75SGreg Clayton &(m_options.m_filenames), 514*eb023e75SGreg Clayton regexp, 515*eb023e75SGreg Clayton internal, 516*eb023e75SGreg Clayton m_options.m_hardware).get(); 517969795f1SJim Ingham } 518969795f1SJim Ingham break; 519fab10e89SJim Ingham case eSetTypeException: 520fab10e89SJim Ingham { 521*eb023e75SGreg Clayton bp = target->CreateExceptionBreakpoint (m_options.m_language, 522*eb023e75SGreg Clayton m_options.m_catch_bp, 523*eb023e75SGreg Clayton m_options.m_throw_bp, 524*eb023e75SGreg Clayton m_options.m_hardware).get(); 525fab10e89SJim Ingham } 526fab10e89SJim Ingham break; 52730fdc8d8SChris Lattner default: 52830fdc8d8SChris Lattner break; 52930fdc8d8SChris Lattner } 53030fdc8d8SChris Lattner 5311b54c88cSJim Ingham // Now set the various options that were passed in: 5321b54c88cSJim Ingham if (bp) 5331b54c88cSJim Ingham { 5341b54c88cSJim Ingham if (m_options.m_thread_id != LLDB_INVALID_THREAD_ID) 5351b54c88cSJim Ingham bp->SetThreadID (m_options.m_thread_id); 5361b54c88cSJim Ingham 537c982c768SGreg Clayton if (m_options.m_thread_index != UINT32_MAX) 5381b54c88cSJim Ingham bp->GetOptions()->GetThreadSpec()->SetIndex(m_options.m_thread_index); 5391b54c88cSJim Ingham 5401b54c88cSJim Ingham if (!m_options.m_thread_name.empty()) 5411b54c88cSJim Ingham bp->GetOptions()->GetThreadSpec()->SetName(m_options.m_thread_name.c_str()); 5421b54c88cSJim Ingham 5431b54c88cSJim Ingham if (!m_options.m_queue_name.empty()) 5441b54c88cSJim Ingham bp->GetOptions()->GetThreadSpec()->SetQueueName(m_options.m_queue_name.c_str()); 5451b54c88cSJim Ingham 546c982c768SGreg Clayton if (m_options.m_ignore_count != 0) 5471b54c88cSJim Ingham bp->GetOptions()->SetIgnoreCount(m_options.m_ignore_count); 5487d49c9c8SJohnny Chen 5497d49c9c8SJohnny Chen if (!m_options.m_condition.empty()) 5507d49c9c8SJohnny Chen bp->GetOptions()->SetCondition(m_options.m_condition.c_str()); 551ca36cd16SJim Ingham 552ca36cd16SJim Ingham bp->SetOneShot (m_options.m_one_shot); 5531b54c88cSJim Ingham } 5541b54c88cSJim Ingham 555969795f1SJim Ingham if (bp) 55630fdc8d8SChris Lattner { 55785e8b814SJim Ingham Stream &output_stream = result.GetOutputStream(); 5581391cc7dSJim Ingham const bool show_locations = false; 5591391cc7dSJim Ingham bp->GetDescription(&output_stream, lldb::eDescriptionLevelInitial, show_locations); 560fab10e89SJim Ingham // Don't print out this warning for exception breakpoints. They can get set before the target 561fab10e89SJim Ingham // is set, but we won't know how to actually set the breakpoint till we run. 562fab10e89SJim Ingham if (bp->GetNumLocations() == 0 && break_type != eSetTypeException) 563be484f41SCaroline Tice output_stream.Printf ("WARNING: Unable to resolve breakpoint to any actual locations.\n"); 56430fdc8d8SChris Lattner result.SetStatus (eReturnStatusSuccessFinishResult); 56530fdc8d8SChris Lattner } 56630fdc8d8SChris Lattner else if (!bp) 56730fdc8d8SChris Lattner { 56830fdc8d8SChris Lattner result.AppendError ("Breakpoint creation failed: No breakpoint created."); 56930fdc8d8SChris Lattner result.SetStatus (eReturnStatusFailed); 57030fdc8d8SChris Lattner } 57130fdc8d8SChris Lattner 57230fdc8d8SChris Lattner return result.Succeeded(); 57330fdc8d8SChris Lattner } 57430fdc8d8SChris Lattner 5755a988416SJim Ingham private: 5765a988416SJim Ingham bool 5775a988416SJim Ingham GetDefaultFile (Target *target, FileSpec &file, CommandReturnObject &result) 5785a988416SJim Ingham { 5795a988416SJim Ingham uint32_t default_line; 5805a988416SJim Ingham // First use the Source Manager's default file. 5815a988416SJim Ingham // Then use the current stack frame's file. 5825a988416SJim Ingham if (!target->GetSourceManager().GetDefaultFileAndLine(file, default_line)) 5835a988416SJim Ingham { 584f9fc609fSGreg Clayton StackFrame *cur_frame = m_exe_ctx.GetFramePtr(); 5855a988416SJim Ingham if (cur_frame == NULL) 5865a988416SJim Ingham { 5875a988416SJim Ingham result.AppendError ("No selected frame to use to find the default file."); 5885a988416SJim Ingham result.SetStatus (eReturnStatusFailed); 5895a988416SJim Ingham return false; 5905a988416SJim Ingham } 5915a988416SJim Ingham else if (!cur_frame->HasDebugInformation()) 5925a988416SJim Ingham { 5935a988416SJim Ingham result.AppendError ("Cannot use the selected frame to find the default file, it has no debug info."); 5945a988416SJim Ingham result.SetStatus (eReturnStatusFailed); 5955a988416SJim Ingham return false; 5965a988416SJim Ingham } 5975a988416SJim Ingham else 5985a988416SJim Ingham { 5995a988416SJim Ingham const SymbolContext &sc = cur_frame->GetSymbolContext (eSymbolContextLineEntry); 6005a988416SJim Ingham if (sc.line_entry.file) 6015a988416SJim Ingham { 6025a988416SJim Ingham file = sc.line_entry.file; 6035a988416SJim Ingham } 6045a988416SJim Ingham else 6055a988416SJim Ingham { 6065a988416SJim Ingham result.AppendError ("Can't find the file for the selected frame to use as the default file."); 6075a988416SJim Ingham result.SetStatus (eReturnStatusFailed); 6085a988416SJim Ingham return false; 6095a988416SJim Ingham } 6105a988416SJim Ingham } 6115a988416SJim Ingham } 6125a988416SJim Ingham return true; 6135a988416SJim Ingham } 6145a988416SJim Ingham 6155a988416SJim Ingham CommandOptions m_options; 6165a988416SJim Ingham }; 6175a988416SJim Ingham // If an additional option set beyond LLDB_OPTION_SET_10 is added, make sure to 6185a988416SJim Ingham // update the numbers passed to LLDB_OPT_SET_FROM_TO(...) appropriately. 6195a988416SJim Ingham #define LLDB_OPT_FILE ( LLDB_OPT_SET_FROM_TO(1, 9) & ~LLDB_OPT_SET_2 ) 6205a988416SJim Ingham #define LLDB_OPT_NOT_10 ( LLDB_OPT_SET_FROM_TO(1, 10) & ~LLDB_OPT_SET_10 ) 6215a988416SJim Ingham #define LLDB_OPT_SKIP_PROLOGUE ( LLDB_OPT_SET_1 | LLDB_OPT_SET_FROM_TO(3,8) ) 6225a988416SJim Ingham 6235a988416SJim Ingham OptionDefinition 6245a988416SJim Ingham CommandObjectBreakpointSet::CommandOptions::g_option_table[] = 6255a988416SJim Ingham { 626e2607b50SVirgile Bello { LLDB_OPT_NOT_10, false, "shlib", 's', OptionParser::eRequiredArgument, NULL, CommandCompletions::eModuleCompletion, eArgTypeShlibName, 6275a988416SJim Ingham "Set the breakpoint only in this shared library. " 6285a988416SJim Ingham "Can repeat this option multiple times to specify multiple shared libraries."}, 6295a988416SJim Ingham 630e2607b50SVirgile Bello { LLDB_OPT_SET_ALL, false, "ignore-count", 'i', OptionParser::eRequiredArgument, NULL, 0, eArgTypeCount, 6315a988416SJim Ingham "Set the number of times this breakpoint is skipped before stopping." }, 6325a988416SJim Ingham 633e2607b50SVirgile Bello { LLDB_OPT_SET_ALL, false, "one-shot", 'o', OptionParser::eNoArgument, NULL, 0, eArgTypeNone, 634b2b256afSJim Ingham "The breakpoint is deleted the first time it causes a stop." }, 635ca36cd16SJim Ingham 636e2607b50SVirgile Bello { LLDB_OPT_SET_ALL, false, "condition", 'c', OptionParser::eRequiredArgument, NULL, 0, eArgTypeExpression, 6375a988416SJim Ingham "The breakpoint stops only if this condition expression evaluates to true."}, 6385a988416SJim Ingham 639e2607b50SVirgile Bello { LLDB_OPT_SET_ALL, false, "thread-index", 'x', OptionParser::eRequiredArgument, NULL, 0, eArgTypeThreadIndex, 640a89be91fSJim Ingham "The breakpoint stops only for the thread whose indeX matches this argument."}, 6415a988416SJim Ingham 642e2607b50SVirgile Bello { LLDB_OPT_SET_ALL, false, "thread-id", 't', OptionParser::eRequiredArgument, NULL, 0, eArgTypeThreadID, 6435a988416SJim Ingham "The breakpoint stops only for the thread whose TID matches this argument."}, 6445a988416SJim Ingham 645e2607b50SVirgile Bello { LLDB_OPT_SET_ALL, false, "thread-name", 'T', OptionParser::eRequiredArgument, NULL, 0, eArgTypeThreadName, 6465a988416SJim Ingham "The breakpoint stops only for the thread whose thread name matches this argument."}, 6475a988416SJim Ingham 648*eb023e75SGreg Clayton { LLDB_OPT_SET_ALL, false, "hardware", 'H', OptionParser::eNoArgument, NULL, 0, eArgTypeNone, 649*eb023e75SGreg Clayton "Require the breakpoint to use hardware breakpoints."}, 650*eb023e75SGreg Clayton 651e2607b50SVirgile Bello { LLDB_OPT_SET_ALL, false, "queue-name", 'q', OptionParser::eRequiredArgument, NULL, 0, eArgTypeQueueName, 6525a988416SJim Ingham "The breakpoint stops only for threads in the queue whose name is given by this argument."}, 6535a988416SJim Ingham 654e2607b50SVirgile Bello { LLDB_OPT_FILE, false, "file", 'f', OptionParser::eRequiredArgument, NULL, CommandCompletions::eSourceFileCompletion, eArgTypeFilename, 655289aca64SJim Ingham "Specifies the source file in which to set this breakpoint. " 656289aca64SJim Ingham "Note, by default lldb only looks for files that are #included if they use the standard include file extensions. " 6576394479eSJim Ingham "To set breakpoints on .c/.cpp/.m/.mm files that are #included, set target.inline-breakpoint-strategy" 658289aca64SJim Ingham " to \"always\"."}, 6595a988416SJim Ingham 660e2607b50SVirgile Bello { LLDB_OPT_SET_1, true, "line", 'l', OptionParser::eRequiredArgument, NULL, 0, eArgTypeLineNum, 6615a988416SJim Ingham "Specifies the line number on which to set this breakpoint."}, 6625a988416SJim Ingham 6635a988416SJim Ingham // Comment out this option for the moment, as we don't actually use it, but will in the future. 6645a988416SJim Ingham // This way users won't see it, but the infrastructure is left in place. 665e2607b50SVirgile Bello // { 0, false, "column", 'C', OptionParser::eRequiredArgument, NULL, "<column>", 6665a988416SJim Ingham // "Set the breakpoint by source location at this particular column."}, 6675a988416SJim Ingham 668e2607b50SVirgile Bello { LLDB_OPT_SET_2, true, "address", 'a', OptionParser::eRequiredArgument, NULL, 0, eArgTypeAddressOrExpression, 6695a988416SJim Ingham "Set the breakpoint by address, at the specified address."}, 6705a988416SJim Ingham 671e2607b50SVirgile Bello { LLDB_OPT_SET_3, true, "name", 'n', OptionParser::eRequiredArgument, NULL, CommandCompletions::eSymbolCompletion, eArgTypeFunctionName, 672551262d7SJim Ingham "Set the breakpoint by function name. Can be repeated multiple times to make one breakpoint for multiple names" }, 6735a988416SJim Ingham 674e2607b50SVirgile Bello { LLDB_OPT_SET_4, true, "fullname", 'F', OptionParser::eRequiredArgument, NULL, CommandCompletions::eSymbolCompletion, eArgTypeFullName, 6755a988416SJim Ingham "Set the breakpoint by fully qualified function names. For C++ this means namespaces and all arguments, and " 6765a988416SJim Ingham "for Objective C this means a full function prototype with class and selector. " 6775a988416SJim Ingham "Can be repeated multiple times to make one breakpoint for multiple names." }, 6785a988416SJim Ingham 679e2607b50SVirgile Bello { LLDB_OPT_SET_5, true, "selector", 'S', OptionParser::eRequiredArgument, NULL, 0, eArgTypeSelector, 6805a988416SJim Ingham "Set the breakpoint by ObjC selector name. Can be repeated multiple times to make one breakpoint for multiple Selectors." }, 6815a988416SJim Ingham 682e2607b50SVirgile Bello { LLDB_OPT_SET_6, true, "method", 'M', OptionParser::eRequiredArgument, NULL, 0, eArgTypeMethod, 6835a988416SJim Ingham "Set the breakpoint by C++ method names. Can be repeated multiple times to make one breakpoint for multiple methods." }, 6845a988416SJim Ingham 685e2607b50SVirgile Bello { LLDB_OPT_SET_7, true, "func-regex", 'r', OptionParser::eRequiredArgument, NULL, 0, eArgTypeRegularExpression, 6865a988416SJim Ingham "Set the breakpoint by function name, evaluating a regular-expression to find the function name(s)." }, 6875a988416SJim Ingham 688e2607b50SVirgile Bello { LLDB_OPT_SET_8, true, "basename", 'b', OptionParser::eRequiredArgument, NULL, CommandCompletions::eSymbolCompletion, eArgTypeFunctionName, 6895a988416SJim Ingham "Set the breakpoint by function basename (C++ namespaces and arguments will be ignored). " 6905a988416SJim Ingham "Can be repeated multiple times to make one breakpoint for multiple symbols." }, 6915a988416SJim Ingham 692e2607b50SVirgile Bello { LLDB_OPT_SET_9, true, "source-pattern-regexp", 'p', OptionParser::eRequiredArgument, NULL, 0, eArgTypeRegularExpression, 693e96ade8bSJim Ingham "Set the breakpoint by specifying a regular expression which is matched against the source text in a source file or files " 694e96ade8bSJim Ingham "specified with the -f option. The -f option can be specified more than once. " 695e96ade8bSJim Ingham "If no source files are specified, uses the current \"default source file\"" }, 6965a988416SJim Ingham 697e2607b50SVirgile Bello { LLDB_OPT_SET_10, true, "language-exception", 'E', OptionParser::eRequiredArgument, NULL, 0, eArgTypeLanguage, 6985a988416SJim Ingham "Set the breakpoint on exceptions thrown by the specified language (without options, on throw but not catch.)" }, 6995a988416SJim Ingham 700e2607b50SVirgile Bello { LLDB_OPT_SET_10, false, "on-throw", 'w', OptionParser::eRequiredArgument, NULL, 0, eArgTypeBoolean, 7015a988416SJim Ingham "Set the breakpoint on exception throW." }, 7025a988416SJim Ingham 703e2607b50SVirgile Bello { LLDB_OPT_SET_10, false, "on-catch", 'h', OptionParser::eRequiredArgument, NULL, 0, eArgTypeBoolean, 7045a988416SJim Ingham "Set the breakpoint on exception catcH." }, 7055a988416SJim Ingham 706e2607b50SVirgile Bello { LLDB_OPT_SKIP_PROLOGUE, false, "skip-prologue", 'K', OptionParser::eRequiredArgument, NULL, 0, eArgTypeBoolean, 7075a988416SJim Ingham "sKip the prologue if the breakpoint is at the beginning of a function. If not set the target.skip-prologue setting is used." }, 7085a988416SJim Ingham 7095a988416SJim Ingham { 0, false, NULL, 0, 0, NULL, 0, eArgTypeNone, NULL } 7105a988416SJim Ingham }; 7115a988416SJim Ingham 7125a988416SJim Ingham //------------------------------------------------------------------------- 7135a988416SJim Ingham // CommandObjectBreakpointModify 7145a988416SJim Ingham //------------------------------------------------------------------------- 7155a988416SJim Ingham #pragma mark Modify 7165a988416SJim Ingham 7175a988416SJim Ingham class CommandObjectBreakpointModify : public CommandObjectParsed 7185a988416SJim Ingham { 7195a988416SJim Ingham public: 7205a988416SJim Ingham 7215a988416SJim Ingham CommandObjectBreakpointModify (CommandInterpreter &interpreter) : 7225a988416SJim Ingham CommandObjectParsed (interpreter, 7235a988416SJim Ingham "breakpoint modify", 7245a988416SJim Ingham "Modify the options on a breakpoint or set of breakpoints in the executable. " 7255a988416SJim Ingham "If no breakpoint is specified, acts on the last created breakpoint. " 7265a988416SJim Ingham "With the exception of -e, -d and -i, passing an empty argument clears the modification.", 7275a988416SJim Ingham NULL), 7285a988416SJim Ingham m_options (interpreter) 7295a988416SJim Ingham { 7305a988416SJim Ingham CommandArgumentEntry arg; 7315a988416SJim Ingham CommandObject::AddIDsArgumentData(arg, eArgTypeBreakpointID, eArgTypeBreakpointIDRange); 7325a988416SJim Ingham // Add the entry for the first argument for this command to the object's arguments vector. 7335a988416SJim Ingham m_arguments.push_back (arg); 7345a988416SJim Ingham } 7355a988416SJim Ingham 7365a988416SJim Ingham 7375a988416SJim Ingham virtual 7385a988416SJim Ingham ~CommandObjectBreakpointModify () {} 7395a988416SJim Ingham 7405a988416SJim Ingham virtual Options * 7415a988416SJim Ingham GetOptions () 7425a988416SJim Ingham { 7435a988416SJim Ingham return &m_options; 7445a988416SJim Ingham } 7455a988416SJim Ingham 7465a988416SJim Ingham class CommandOptions : public Options 7475a988416SJim Ingham { 7485a988416SJim Ingham public: 7495a988416SJim Ingham 7505a988416SJim Ingham CommandOptions (CommandInterpreter &interpreter) : 7515a988416SJim Ingham Options (interpreter), 7525a988416SJim Ingham m_ignore_count (0), 7535a988416SJim Ingham m_thread_id(LLDB_INVALID_THREAD_ID), 7545a988416SJim Ingham m_thread_id_passed(false), 7555a988416SJim Ingham m_thread_index (UINT32_MAX), 7565a988416SJim Ingham m_thread_index_passed(false), 7575a988416SJim Ingham m_thread_name(), 7585a988416SJim Ingham m_queue_name(), 7595a988416SJim Ingham m_condition (), 760ca36cd16SJim Ingham m_one_shot (false), 7615a988416SJim Ingham m_enable_passed (false), 7625a988416SJim Ingham m_enable_value (false), 7635a988416SJim Ingham m_name_passed (false), 7645a988416SJim Ingham m_queue_passed (false), 765ca36cd16SJim Ingham m_condition_passed (false), 766ca36cd16SJim Ingham m_one_shot_passed (false) 7675a988416SJim Ingham { 7685a988416SJim Ingham } 7695a988416SJim Ingham 7705a988416SJim Ingham virtual 7715a988416SJim Ingham ~CommandOptions () {} 7725a988416SJim Ingham 7735a988416SJim Ingham virtual Error 7745a988416SJim Ingham SetOptionValue (uint32_t option_idx, const char *option_arg) 7755a988416SJim Ingham { 7765a988416SJim Ingham Error error; 7773bcdfc0eSGreg Clayton const int short_option = m_getopt_table[option_idx].val; 7785a988416SJim Ingham 7795a988416SJim Ingham switch (short_option) 7805a988416SJim Ingham { 7815a988416SJim Ingham case 'c': 7825a988416SJim Ingham if (option_arg != NULL) 7835a988416SJim Ingham m_condition.assign (option_arg); 7845a988416SJim Ingham else 7855a988416SJim Ingham m_condition.clear(); 7865a988416SJim Ingham m_condition_passed = true; 7875a988416SJim Ingham break; 7885a988416SJim Ingham case 'd': 7895a988416SJim Ingham m_enable_passed = true; 7905a988416SJim Ingham m_enable_value = false; 7915a988416SJim Ingham break; 7925a988416SJim Ingham case 'e': 7935a988416SJim Ingham m_enable_passed = true; 7945a988416SJim Ingham m_enable_value = true; 7955a988416SJim Ingham break; 7965a988416SJim Ingham case 'i': 7975a988416SJim Ingham { 7985a988416SJim Ingham m_ignore_count = Args::StringToUInt32(option_arg, UINT32_MAX, 0); 7995a988416SJim Ingham if (m_ignore_count == UINT32_MAX) 8005a988416SJim Ingham error.SetErrorStringWithFormat ("invalid ignore count '%s'", option_arg); 8015a988416SJim Ingham } 8025a988416SJim Ingham break; 803ca36cd16SJim Ingham case 'o': 804ca36cd16SJim Ingham { 805ca36cd16SJim Ingham bool value, success; 806ca36cd16SJim Ingham value = Args::StringToBoolean(option_arg, false, &success); 807ca36cd16SJim Ingham if (success) 808ca36cd16SJim Ingham { 809ca36cd16SJim Ingham m_one_shot_passed = true; 810ca36cd16SJim Ingham m_one_shot = value; 811ca36cd16SJim Ingham } 812ca36cd16SJim Ingham else 813ca36cd16SJim Ingham error.SetErrorStringWithFormat("invalid boolean value '%s' passed for -o option", option_arg); 814ca36cd16SJim Ingham } 815ca36cd16SJim Ingham break; 8165a988416SJim Ingham case 't' : 8175a988416SJim Ingham { 8185a988416SJim Ingham if (option_arg[0] == '\0') 8195a988416SJim Ingham { 8205a988416SJim Ingham m_thread_id = LLDB_INVALID_THREAD_ID; 8215a988416SJim Ingham m_thread_id_passed = true; 8225a988416SJim Ingham } 8235a988416SJim Ingham else 8245a988416SJim Ingham { 8255a988416SJim Ingham m_thread_id = Args::StringToUInt64(option_arg, LLDB_INVALID_THREAD_ID, 0); 8265a988416SJim Ingham if (m_thread_id == LLDB_INVALID_THREAD_ID) 8275a988416SJim Ingham error.SetErrorStringWithFormat ("invalid thread id string '%s'", option_arg); 8285a988416SJim Ingham else 8295a988416SJim Ingham m_thread_id_passed = true; 8305a988416SJim Ingham } 8315a988416SJim Ingham } 8325a988416SJim Ingham break; 8335a988416SJim Ingham case 'T': 8345a988416SJim Ingham if (option_arg != NULL) 8355a988416SJim Ingham m_thread_name.assign (option_arg); 8365a988416SJim Ingham else 8375a988416SJim Ingham m_thread_name.clear(); 8385a988416SJim Ingham m_name_passed = true; 8395a988416SJim Ingham break; 8405a988416SJim Ingham case 'q': 8415a988416SJim Ingham if (option_arg != NULL) 8425a988416SJim Ingham m_queue_name.assign (option_arg); 8435a988416SJim Ingham else 8445a988416SJim Ingham m_queue_name.clear(); 8455a988416SJim Ingham m_queue_passed = true; 8465a988416SJim Ingham break; 8475a988416SJim Ingham case 'x': 8485a988416SJim Ingham { 8495a988416SJim Ingham if (option_arg[0] == '\n') 8505a988416SJim Ingham { 8515a988416SJim Ingham m_thread_index = UINT32_MAX; 8525a988416SJim Ingham m_thread_index_passed = true; 8535a988416SJim Ingham } 8545a988416SJim Ingham else 8555a988416SJim Ingham { 8565a988416SJim Ingham m_thread_index = Args::StringToUInt32 (option_arg, UINT32_MAX, 0); 8575a988416SJim Ingham if (m_thread_id == UINT32_MAX) 8585a988416SJim Ingham error.SetErrorStringWithFormat ("invalid thread index string '%s'", option_arg); 8595a988416SJim Ingham else 8605a988416SJim Ingham m_thread_index_passed = true; 8615a988416SJim Ingham } 8625a988416SJim Ingham } 8635a988416SJim Ingham break; 8645a988416SJim Ingham default: 8655a988416SJim Ingham error.SetErrorStringWithFormat ("unrecognized option '%c'", short_option); 8665a988416SJim Ingham break; 8675a988416SJim Ingham } 8685a988416SJim Ingham 8695a988416SJim Ingham return error; 8705a988416SJim Ingham } 8715a988416SJim Ingham void 8725a988416SJim Ingham OptionParsingStarting () 8735a988416SJim Ingham { 8745a988416SJim Ingham m_ignore_count = 0; 8755a988416SJim Ingham m_thread_id = LLDB_INVALID_THREAD_ID; 8765a988416SJim Ingham m_thread_id_passed = false; 8775a988416SJim Ingham m_thread_index = UINT32_MAX; 8785a988416SJim Ingham m_thread_index_passed = false; 8795a988416SJim Ingham m_thread_name.clear(); 8805a988416SJim Ingham m_queue_name.clear(); 8815a988416SJim Ingham m_condition.clear(); 882ca36cd16SJim Ingham m_one_shot = false; 8835a988416SJim Ingham m_enable_passed = false; 8845a988416SJim Ingham m_queue_passed = false; 8855a988416SJim Ingham m_name_passed = false; 8865a988416SJim Ingham m_condition_passed = false; 887ca36cd16SJim Ingham m_one_shot_passed = false; 8885a988416SJim Ingham } 8895a988416SJim Ingham 8905a988416SJim Ingham const OptionDefinition* 8915a988416SJim Ingham GetDefinitions () 8925a988416SJim Ingham { 8935a988416SJim Ingham return g_option_table; 8945a988416SJim Ingham } 8955a988416SJim Ingham 8965a988416SJim Ingham 8975a988416SJim Ingham // Options table: Required for subclasses of Options. 8985a988416SJim Ingham 8995a988416SJim Ingham static OptionDefinition g_option_table[]; 9005a988416SJim Ingham 9015a988416SJim Ingham // Instance variables to hold the values for command options. 9025a988416SJim Ingham 9035a988416SJim Ingham uint32_t m_ignore_count; 9045a988416SJim Ingham lldb::tid_t m_thread_id; 9055a988416SJim Ingham bool m_thread_id_passed; 9065a988416SJim Ingham uint32_t m_thread_index; 9075a988416SJim Ingham bool m_thread_index_passed; 9085a988416SJim Ingham std::string m_thread_name; 9095a988416SJim Ingham std::string m_queue_name; 9105a988416SJim Ingham std::string m_condition; 911ca36cd16SJim Ingham bool m_one_shot; 9125a988416SJim Ingham bool m_enable_passed; 9135a988416SJim Ingham bool m_enable_value; 9145a988416SJim Ingham bool m_name_passed; 9155a988416SJim Ingham bool m_queue_passed; 9165a988416SJim Ingham bool m_condition_passed; 917ca36cd16SJim Ingham bool m_one_shot_passed; 9185a988416SJim Ingham 9195a988416SJim Ingham }; 9205a988416SJim Ingham 9215a988416SJim Ingham protected: 9225a988416SJim Ingham virtual bool 9235a988416SJim Ingham DoExecute (Args& command, CommandReturnObject &result) 9245a988416SJim Ingham { 9255a988416SJim Ingham Target *target = m_interpreter.GetDebugger().GetSelectedTarget().get(); 9265a988416SJim Ingham if (target == NULL) 9275a988416SJim Ingham { 9285a988416SJim Ingham result.AppendError ("Invalid target. No existing target or breakpoints."); 9295a988416SJim Ingham result.SetStatus (eReturnStatusFailed); 9305a988416SJim Ingham return false; 9315a988416SJim Ingham } 9325a988416SJim Ingham 9335a988416SJim Ingham Mutex::Locker locker; 9345a988416SJim Ingham target->GetBreakpointList().GetListMutex(locker); 9355a988416SJim Ingham 9365a988416SJim Ingham BreakpointIDList valid_bp_ids; 9375a988416SJim Ingham 9385a988416SJim Ingham CommandObjectMultiwordBreakpoint::VerifyBreakpointIDs (command, target, result, &valid_bp_ids); 9395a988416SJim Ingham 9405a988416SJim Ingham if (result.Succeeded()) 9415a988416SJim Ingham { 9425a988416SJim Ingham const size_t count = valid_bp_ids.GetSize(); 9435a988416SJim Ingham for (size_t i = 0; i < count; ++i) 9445a988416SJim Ingham { 9455a988416SJim Ingham BreakpointID cur_bp_id = valid_bp_ids.GetBreakpointIDAtIndex (i); 9465a988416SJim Ingham 9475a988416SJim Ingham if (cur_bp_id.GetBreakpointID() != LLDB_INVALID_BREAK_ID) 9485a988416SJim Ingham { 9495a988416SJim Ingham Breakpoint *bp = target->GetBreakpointByID (cur_bp_id.GetBreakpointID()).get(); 9505a988416SJim Ingham if (cur_bp_id.GetLocationID() != LLDB_INVALID_BREAK_ID) 9515a988416SJim Ingham { 9525a988416SJim Ingham BreakpointLocation *location = bp->FindLocationByID (cur_bp_id.GetLocationID()).get(); 9535a988416SJim Ingham if (location) 9545a988416SJim Ingham { 9555a988416SJim Ingham if (m_options.m_thread_id_passed) 9565a988416SJim Ingham location->SetThreadID (m_options.m_thread_id); 9575a988416SJim Ingham 9585a988416SJim Ingham if (m_options.m_thread_index_passed) 9595a988416SJim Ingham location->SetThreadIndex(m_options.m_thread_index); 9605a988416SJim Ingham 9615a988416SJim Ingham if (m_options.m_name_passed) 9625a988416SJim Ingham location->SetThreadName(m_options.m_thread_name.c_str()); 9635a988416SJim Ingham 9645a988416SJim Ingham if (m_options.m_queue_passed) 9655a988416SJim Ingham location->SetQueueName(m_options.m_queue_name.c_str()); 9665a988416SJim Ingham 9675a988416SJim Ingham if (m_options.m_ignore_count != 0) 9685a988416SJim Ingham location->SetIgnoreCount(m_options.m_ignore_count); 9695a988416SJim Ingham 9705a988416SJim Ingham if (m_options.m_enable_passed) 9715a988416SJim Ingham location->SetEnabled (m_options.m_enable_value); 9725a988416SJim Ingham 9735a988416SJim Ingham if (m_options.m_condition_passed) 9745a988416SJim Ingham location->SetCondition (m_options.m_condition.c_str()); 9755a988416SJim Ingham } 9765a988416SJim Ingham } 9775a988416SJim Ingham else 9785a988416SJim Ingham { 9795a988416SJim Ingham if (m_options.m_thread_id_passed) 9805a988416SJim Ingham bp->SetThreadID (m_options.m_thread_id); 9815a988416SJim Ingham 9825a988416SJim Ingham if (m_options.m_thread_index_passed) 9835a988416SJim Ingham bp->SetThreadIndex(m_options.m_thread_index); 9845a988416SJim Ingham 9855a988416SJim Ingham if (m_options.m_name_passed) 9865a988416SJim Ingham bp->SetThreadName(m_options.m_thread_name.c_str()); 9875a988416SJim Ingham 9885a988416SJim Ingham if (m_options.m_queue_passed) 9895a988416SJim Ingham bp->SetQueueName(m_options.m_queue_name.c_str()); 9905a988416SJim Ingham 9915a988416SJim Ingham if (m_options.m_ignore_count != 0) 9925a988416SJim Ingham bp->SetIgnoreCount(m_options.m_ignore_count); 9935a988416SJim Ingham 9945a988416SJim Ingham if (m_options.m_enable_passed) 9955a988416SJim Ingham bp->SetEnabled (m_options.m_enable_value); 9965a988416SJim Ingham 9975a988416SJim Ingham if (m_options.m_condition_passed) 9985a988416SJim Ingham bp->SetCondition (m_options.m_condition.c_str()); 9995a988416SJim Ingham } 10005a988416SJim Ingham } 10015a988416SJim Ingham } 10025a988416SJim Ingham } 10035a988416SJim Ingham 10045a988416SJim Ingham return result.Succeeded(); 10055a988416SJim Ingham } 10065a988416SJim Ingham 10075a988416SJim Ingham private: 10085a988416SJim Ingham CommandOptions m_options; 10095a988416SJim Ingham }; 10105a988416SJim Ingham 10115a988416SJim Ingham #pragma mark Modify::CommandOptions 10125a988416SJim Ingham OptionDefinition 10135a988416SJim Ingham CommandObjectBreakpointModify::CommandOptions::g_option_table[] = 10145a988416SJim Ingham { 1015e2607b50SVirgile Bello { LLDB_OPT_SET_ALL, false, "ignore-count", 'i', OptionParser::eRequiredArgument, NULL, 0, eArgTypeCount, "Set the number of times this breakpoint is skipped before stopping." }, 1016e2607b50SVirgile Bello { LLDB_OPT_SET_ALL, false, "one-shot", 'o', OptionParser::eRequiredArgument, NULL, 0, eArgTypeBoolean, "The breakpoint is deleted the first time it stop causes a stop." }, 1017e2607b50SVirgile Bello { LLDB_OPT_SET_ALL, false, "thread-index", 'x', OptionParser::eRequiredArgument, NULL, 0, eArgTypeThreadIndex, "The breakpoint stops only for the thread whose index matches this argument."}, 1018e2607b50SVirgile Bello { LLDB_OPT_SET_ALL, false, "thread-id", 't', OptionParser::eRequiredArgument, NULL, 0, eArgTypeThreadID, "The breakpoint stops only for the thread whose TID matches this argument."}, 1019e2607b50SVirgile Bello { LLDB_OPT_SET_ALL, false, "thread-name", 'T', OptionParser::eRequiredArgument, NULL, 0, eArgTypeThreadName, "The breakpoint stops only for the thread whose thread name matches this argument."}, 1020e2607b50SVirgile Bello { LLDB_OPT_SET_ALL, false, "queue-name", 'q', OptionParser::eRequiredArgument, NULL, 0, eArgTypeQueueName, "The breakpoint stops only for threads in the queue whose name is given by this argument."}, 1021e2607b50SVirgile Bello { LLDB_OPT_SET_ALL, false, "condition", 'c', OptionParser::eRequiredArgument, NULL, 0, eArgTypeExpression, "The breakpoint stops only if this condition expression evaluates to true."}, 1022e2607b50SVirgile Bello { LLDB_OPT_SET_1, false, "enable", 'e', OptionParser::eNoArgument, NULL, 0, eArgTypeNone, "Enable the breakpoint."}, 1023e2607b50SVirgile Bello { LLDB_OPT_SET_2, false, "disable", 'd', OptionParser::eNoArgument, NULL, 0, eArgTypeNone, "Disable the breakpoint."}, 10245a988416SJim Ingham { 0, false, NULL, 0 , 0, NULL, 0, eArgTypeNone, NULL } 10255a988416SJim Ingham }; 10265a988416SJim Ingham 10275a988416SJim Ingham //------------------------------------------------------------------------- 10285a988416SJim Ingham // CommandObjectBreakpointEnable 10295a988416SJim Ingham //------------------------------------------------------------------------- 10305a988416SJim Ingham #pragma mark Enable 10315a988416SJim Ingham 10325a988416SJim Ingham class CommandObjectBreakpointEnable : public CommandObjectParsed 10335a988416SJim Ingham { 10345a988416SJim Ingham public: 10355a988416SJim Ingham CommandObjectBreakpointEnable (CommandInterpreter &interpreter) : 10365a988416SJim Ingham CommandObjectParsed (interpreter, 10375a988416SJim Ingham "enable", 10385a988416SJim Ingham "Enable the specified disabled breakpoint(s). If no breakpoints are specified, enable all of them.", 10395a988416SJim Ingham NULL) 10405a988416SJim Ingham { 10415a988416SJim Ingham CommandArgumentEntry arg; 10425a988416SJim Ingham CommandObject::AddIDsArgumentData(arg, eArgTypeBreakpointID, eArgTypeBreakpointIDRange); 10435a988416SJim Ingham // Add the entry for the first argument for this command to the object's arguments vector. 10445a988416SJim Ingham m_arguments.push_back (arg); 10455a988416SJim Ingham } 10465a988416SJim Ingham 10475a988416SJim Ingham 10485a988416SJim Ingham virtual 10495a988416SJim Ingham ~CommandObjectBreakpointEnable () {} 10505a988416SJim Ingham 10515a988416SJim Ingham protected: 10525a988416SJim Ingham virtual bool 10535a988416SJim Ingham DoExecute (Args& command, CommandReturnObject &result) 10545a988416SJim Ingham { 10555a988416SJim Ingham Target *target = m_interpreter.GetDebugger().GetSelectedTarget().get(); 10565a988416SJim Ingham if (target == NULL) 10575a988416SJim Ingham { 10585a988416SJim Ingham result.AppendError ("Invalid target. No existing target or breakpoints."); 10595a988416SJim Ingham result.SetStatus (eReturnStatusFailed); 10605a988416SJim Ingham return false; 10615a988416SJim Ingham } 10625a988416SJim Ingham 10635a988416SJim Ingham Mutex::Locker locker; 10645a988416SJim Ingham target->GetBreakpointList().GetListMutex(locker); 10655a988416SJim Ingham 10665a988416SJim Ingham const BreakpointList &breakpoints = target->GetBreakpointList(); 10675a988416SJim Ingham 10685a988416SJim Ingham size_t num_breakpoints = breakpoints.GetSize(); 10695a988416SJim Ingham 10705a988416SJim Ingham if (num_breakpoints == 0) 10715a988416SJim Ingham { 10725a988416SJim Ingham result.AppendError ("No breakpoints exist to be enabled."); 10735a988416SJim Ingham result.SetStatus (eReturnStatusFailed); 10745a988416SJim Ingham return false; 10755a988416SJim Ingham } 10765a988416SJim Ingham 10775a988416SJim Ingham if (command.GetArgumentCount() == 0) 10785a988416SJim Ingham { 10795a988416SJim Ingham // No breakpoint selected; enable all currently set breakpoints. 10805a988416SJim Ingham target->EnableAllBreakpoints (); 10815a988416SJim Ingham result.AppendMessageWithFormat ("All breakpoints enabled. (%lu breakpoints)\n", num_breakpoints); 10825a988416SJim Ingham result.SetStatus (eReturnStatusSuccessFinishNoResult); 10835a988416SJim Ingham } 10845a988416SJim Ingham else 10855a988416SJim Ingham { 10865a988416SJim Ingham // Particular breakpoint selected; enable that breakpoint. 10875a988416SJim Ingham BreakpointIDList valid_bp_ids; 10885a988416SJim Ingham CommandObjectMultiwordBreakpoint::VerifyBreakpointIDs (command, target, result, &valid_bp_ids); 10895a988416SJim Ingham 10905a988416SJim Ingham if (result.Succeeded()) 10915a988416SJim Ingham { 10925a988416SJim Ingham int enable_count = 0; 10935a988416SJim Ingham int loc_count = 0; 10945a988416SJim Ingham const size_t count = valid_bp_ids.GetSize(); 10955a988416SJim Ingham for (size_t i = 0; i < count; ++i) 10965a988416SJim Ingham { 10975a988416SJim Ingham BreakpointID cur_bp_id = valid_bp_ids.GetBreakpointIDAtIndex (i); 10985a988416SJim Ingham 10995a988416SJim Ingham if (cur_bp_id.GetBreakpointID() != LLDB_INVALID_BREAK_ID) 11005a988416SJim Ingham { 11015a988416SJim Ingham Breakpoint *breakpoint = target->GetBreakpointByID (cur_bp_id.GetBreakpointID()).get(); 11025a988416SJim Ingham if (cur_bp_id.GetLocationID() != LLDB_INVALID_BREAK_ID) 11035a988416SJim Ingham { 11045a988416SJim Ingham BreakpointLocation *location = breakpoint->FindLocationByID (cur_bp_id.GetLocationID()).get(); 11055a988416SJim Ingham if (location) 11065a988416SJim Ingham { 11075a988416SJim Ingham location->SetEnabled (true); 11085a988416SJim Ingham ++loc_count; 11095a988416SJim Ingham } 11105a988416SJim Ingham } 11115a988416SJim Ingham else 11125a988416SJim Ingham { 11135a988416SJim Ingham breakpoint->SetEnabled (true); 11145a988416SJim Ingham ++enable_count; 11155a988416SJim Ingham } 11165a988416SJim Ingham } 11175a988416SJim Ingham } 11185a988416SJim Ingham result.AppendMessageWithFormat ("%d breakpoints enabled.\n", enable_count + loc_count); 11195a988416SJim Ingham result.SetStatus (eReturnStatusSuccessFinishNoResult); 11205a988416SJim Ingham } 11215a988416SJim Ingham } 11225a988416SJim Ingham 11235a988416SJim Ingham return result.Succeeded(); 11245a988416SJim Ingham } 11255a988416SJim Ingham }; 11265a988416SJim Ingham 11275a988416SJim Ingham //------------------------------------------------------------------------- 11285a988416SJim Ingham // CommandObjectBreakpointDisable 11295a988416SJim Ingham //------------------------------------------------------------------------- 11305a988416SJim Ingham #pragma mark Disable 11315a988416SJim Ingham 11325a988416SJim Ingham class CommandObjectBreakpointDisable : public CommandObjectParsed 11335a988416SJim Ingham { 11345a988416SJim Ingham public: 11355a988416SJim Ingham CommandObjectBreakpointDisable (CommandInterpreter &interpreter) : 11365a988416SJim Ingham CommandObjectParsed (interpreter, 11375a988416SJim Ingham "breakpoint disable", 11385a988416SJim Ingham "Disable the specified breakpoint(s) without removing it/them. If no breakpoints are specified, disable them all.", 11395a988416SJim Ingham NULL) 11405a988416SJim Ingham { 1141b0fac509SJim Ingham SetHelpLong( 1142b0fac509SJim Ingham "Disable the specified breakpoint(s) without removing it/them. \n\ 1143b0fac509SJim Ingham If no breakpoints are specified, disable them all.\n\ 1144b0fac509SJim Ingham \n\ 1145b0fac509SJim Ingham Note: disabling a breakpoint will cause none of its locations to be hit\n\ 1146b0fac509SJim Ingham regardless of whether they are enabled or disabled. So the sequence: \n\ 1147b0fac509SJim Ingham \n\ 1148b0fac509SJim Ingham (lldb) break disable 1\n\ 1149b0fac509SJim Ingham (lldb) break enable 1.1\n\ 1150b0fac509SJim Ingham \n\ 1151b0fac509SJim Ingham will NOT cause location 1.1 to get hit. To achieve that, do:\n\ 1152b0fac509SJim Ingham \n\ 1153b0fac509SJim Ingham (lldb) break disable 1.*\n\ 1154b0fac509SJim Ingham (lldb) break enable 1.1\n\ 1155b0fac509SJim Ingham \n\ 1156b0fac509SJim Ingham The first command disables all the locations of breakpoint 1, \n\ 1157b0fac509SJim Ingham the second re-enables the first location." 1158b0fac509SJim Ingham ); 1159b0fac509SJim Ingham 11605a988416SJim Ingham CommandArgumentEntry arg; 11615a988416SJim Ingham CommandObject::AddIDsArgumentData(arg, eArgTypeBreakpointID, eArgTypeBreakpointIDRange); 11625a988416SJim Ingham // Add the entry for the first argument for this command to the object's arguments vector. 11635a988416SJim Ingham m_arguments.push_back (arg); 1164b0fac509SJim Ingham 11655a988416SJim Ingham } 11665a988416SJim Ingham 11675a988416SJim Ingham 11685a988416SJim Ingham virtual 11695a988416SJim Ingham ~CommandObjectBreakpointDisable () {} 11705a988416SJim Ingham 11715a988416SJim Ingham protected: 11725a988416SJim Ingham virtual bool 11735a988416SJim Ingham DoExecute (Args& command, CommandReturnObject &result) 11745a988416SJim Ingham { 11755a988416SJim Ingham Target *target = m_interpreter.GetDebugger().GetSelectedTarget().get(); 11765a988416SJim Ingham if (target == NULL) 11775a988416SJim Ingham { 11785a988416SJim Ingham result.AppendError ("Invalid target. No existing target or breakpoints."); 11795a988416SJim Ingham result.SetStatus (eReturnStatusFailed); 11805a988416SJim Ingham return false; 11815a988416SJim Ingham } 11825a988416SJim Ingham 11835a988416SJim Ingham Mutex::Locker locker; 11845a988416SJim Ingham target->GetBreakpointList().GetListMutex(locker); 11855a988416SJim Ingham 11865a988416SJim Ingham const BreakpointList &breakpoints = target->GetBreakpointList(); 11875a988416SJim Ingham size_t num_breakpoints = breakpoints.GetSize(); 11885a988416SJim Ingham 11895a988416SJim Ingham if (num_breakpoints == 0) 11905a988416SJim Ingham { 11915a988416SJim Ingham result.AppendError ("No breakpoints exist to be disabled."); 11925a988416SJim Ingham result.SetStatus (eReturnStatusFailed); 11935a988416SJim Ingham return false; 11945a988416SJim Ingham } 11955a988416SJim Ingham 11965a988416SJim Ingham if (command.GetArgumentCount() == 0) 11975a988416SJim Ingham { 11985a988416SJim Ingham // No breakpoint selected; disable all currently set breakpoints. 11995a988416SJim Ingham target->DisableAllBreakpoints (); 12005a988416SJim Ingham result.AppendMessageWithFormat ("All breakpoints disabled. (%lu breakpoints)\n", num_breakpoints); 12015a988416SJim Ingham result.SetStatus (eReturnStatusSuccessFinishNoResult); 12025a988416SJim Ingham } 12035a988416SJim Ingham else 12045a988416SJim Ingham { 12055a988416SJim Ingham // Particular breakpoint selected; disable that breakpoint. 12065a988416SJim Ingham BreakpointIDList valid_bp_ids; 12075a988416SJim Ingham 12085a988416SJim Ingham CommandObjectMultiwordBreakpoint::VerifyBreakpointIDs (command, target, result, &valid_bp_ids); 12095a988416SJim Ingham 12105a988416SJim Ingham if (result.Succeeded()) 12115a988416SJim Ingham { 12125a988416SJim Ingham int disable_count = 0; 12135a988416SJim Ingham int loc_count = 0; 12145a988416SJim Ingham const size_t count = valid_bp_ids.GetSize(); 12155a988416SJim Ingham for (size_t i = 0; i < count; ++i) 12165a988416SJim Ingham { 12175a988416SJim Ingham BreakpointID cur_bp_id = valid_bp_ids.GetBreakpointIDAtIndex (i); 12185a988416SJim Ingham 12195a988416SJim Ingham if (cur_bp_id.GetBreakpointID() != LLDB_INVALID_BREAK_ID) 12205a988416SJim Ingham { 12215a988416SJim Ingham Breakpoint *breakpoint = target->GetBreakpointByID (cur_bp_id.GetBreakpointID()).get(); 12225a988416SJim Ingham if (cur_bp_id.GetLocationID() != LLDB_INVALID_BREAK_ID) 12235a988416SJim Ingham { 12245a988416SJim Ingham BreakpointLocation *location = breakpoint->FindLocationByID (cur_bp_id.GetLocationID()).get(); 12255a988416SJim Ingham if (location) 12265a988416SJim Ingham { 12275a988416SJim Ingham location->SetEnabled (false); 12285a988416SJim Ingham ++loc_count; 12295a988416SJim Ingham } 12305a988416SJim Ingham } 12315a988416SJim Ingham else 12325a988416SJim Ingham { 12335a988416SJim Ingham breakpoint->SetEnabled (false); 12345a988416SJim Ingham ++disable_count; 12355a988416SJim Ingham } 12365a988416SJim Ingham } 12375a988416SJim Ingham } 12385a988416SJim Ingham result.AppendMessageWithFormat ("%d breakpoints disabled.\n", disable_count + loc_count); 12395a988416SJim Ingham result.SetStatus (eReturnStatusSuccessFinishNoResult); 12405a988416SJim Ingham } 12415a988416SJim Ingham } 12425a988416SJim Ingham 12435a988416SJim Ingham return result.Succeeded(); 12445a988416SJim Ingham } 12455a988416SJim Ingham 12465a988416SJim Ingham }; 12475a988416SJim Ingham 12485a988416SJim Ingham //------------------------------------------------------------------------- 12495a988416SJim Ingham // CommandObjectBreakpointList 12505a988416SJim Ingham //------------------------------------------------------------------------- 12515a988416SJim Ingham #pragma mark List 12525a988416SJim Ingham 12535a988416SJim Ingham class CommandObjectBreakpointList : public CommandObjectParsed 12545a988416SJim Ingham { 12555a988416SJim Ingham public: 12565a988416SJim Ingham CommandObjectBreakpointList (CommandInterpreter &interpreter) : 12575a988416SJim Ingham CommandObjectParsed (interpreter, 12585a988416SJim Ingham "breakpoint list", 12595a988416SJim Ingham "List some or all breakpoints at configurable levels of detail.", 12605a988416SJim Ingham NULL), 12615a988416SJim Ingham m_options (interpreter) 12625a988416SJim Ingham { 12635a988416SJim Ingham CommandArgumentEntry arg; 12645a988416SJim Ingham CommandArgumentData bp_id_arg; 12655a988416SJim Ingham 12665a988416SJim Ingham // Define the first (and only) variant of this arg. 12675a988416SJim Ingham bp_id_arg.arg_type = eArgTypeBreakpointID; 12685a988416SJim Ingham bp_id_arg.arg_repetition = eArgRepeatOptional; 12695a988416SJim Ingham 12705a988416SJim Ingham // There is only one variant this argument could be; put it into the argument entry. 12715a988416SJim Ingham arg.push_back (bp_id_arg); 12725a988416SJim Ingham 12735a988416SJim Ingham // Push the data for the first argument into the m_arguments vector. 12745a988416SJim Ingham m_arguments.push_back (arg); 12755a988416SJim Ingham } 12765a988416SJim Ingham 12775a988416SJim Ingham 12785a988416SJim Ingham virtual 12795a988416SJim Ingham ~CommandObjectBreakpointList () {} 12805a988416SJim Ingham 12815a988416SJim Ingham virtual Options * 12825a988416SJim Ingham GetOptions () 12835a988416SJim Ingham { 12845a988416SJim Ingham return &m_options; 12855a988416SJim Ingham } 12865a988416SJim Ingham 12875a988416SJim Ingham class CommandOptions : public Options 12885a988416SJim Ingham { 12895a988416SJim Ingham public: 12905a988416SJim Ingham 12915a988416SJim Ingham CommandOptions (CommandInterpreter &interpreter) : 12925a988416SJim Ingham Options (interpreter), 12935a988416SJim Ingham m_level (lldb::eDescriptionLevelBrief) // Breakpoint List defaults to brief descriptions 12945a988416SJim Ingham { 12955a988416SJim Ingham } 12965a988416SJim Ingham 12975a988416SJim Ingham virtual 12985a988416SJim Ingham ~CommandOptions () {} 12995a988416SJim Ingham 13005a988416SJim Ingham virtual Error 13015a988416SJim Ingham SetOptionValue (uint32_t option_idx, const char *option_arg) 13025a988416SJim Ingham { 13035a988416SJim Ingham Error error; 13043bcdfc0eSGreg Clayton const int short_option = m_getopt_table[option_idx].val; 13055a988416SJim Ingham 13065a988416SJim Ingham switch (short_option) 13075a988416SJim Ingham { 13085a988416SJim Ingham case 'b': 13095a988416SJim Ingham m_level = lldb::eDescriptionLevelBrief; 13105a988416SJim Ingham break; 13115a988416SJim Ingham case 'f': 13125a988416SJim Ingham m_level = lldb::eDescriptionLevelFull; 13135a988416SJim Ingham break; 13145a988416SJim Ingham case 'v': 13155a988416SJim Ingham m_level = lldb::eDescriptionLevelVerbose; 13165a988416SJim Ingham break; 13175a988416SJim Ingham case 'i': 13185a988416SJim Ingham m_internal = true; 13195a988416SJim Ingham break; 13205a988416SJim Ingham default: 13215a988416SJim Ingham error.SetErrorStringWithFormat ("unrecognized option '%c'", short_option); 13225a988416SJim Ingham break; 13235a988416SJim Ingham } 13245a988416SJim Ingham 13255a988416SJim Ingham return error; 13265a988416SJim Ingham } 13275a988416SJim Ingham 13285a988416SJim Ingham void 13295a988416SJim Ingham OptionParsingStarting () 13305a988416SJim Ingham { 13315a988416SJim Ingham m_level = lldb::eDescriptionLevelFull; 13325a988416SJim Ingham m_internal = false; 13335a988416SJim Ingham } 13345a988416SJim Ingham 13355a988416SJim Ingham const OptionDefinition * 13365a988416SJim Ingham GetDefinitions () 13375a988416SJim Ingham { 13385a988416SJim Ingham return g_option_table; 13395a988416SJim Ingham } 13405a988416SJim Ingham 13415a988416SJim Ingham // Options table: Required for subclasses of Options. 13425a988416SJim Ingham 13435a988416SJim Ingham static OptionDefinition g_option_table[]; 13445a988416SJim Ingham 13455a988416SJim Ingham // Instance variables to hold the values for command options. 13465a988416SJim Ingham 13475a988416SJim Ingham lldb::DescriptionLevel m_level; 13485a988416SJim Ingham 13495a988416SJim Ingham bool m_internal; 13505a988416SJim Ingham }; 13515a988416SJim Ingham 13525a988416SJim Ingham protected: 13535a988416SJim Ingham virtual bool 13545a988416SJim Ingham DoExecute (Args& command, CommandReturnObject &result) 13555a988416SJim Ingham { 13565a988416SJim Ingham Target *target = m_interpreter.GetDebugger().GetSelectedTarget().get(); 13575a988416SJim Ingham if (target == NULL) 13585a988416SJim Ingham { 13595a988416SJim Ingham result.AppendError ("Invalid target. No current target or breakpoints."); 13605a988416SJim Ingham result.SetStatus (eReturnStatusSuccessFinishNoResult); 13615a988416SJim Ingham return true; 13625a988416SJim Ingham } 13635a988416SJim Ingham 13645a988416SJim Ingham const BreakpointList &breakpoints = target->GetBreakpointList(m_options.m_internal); 13655a988416SJim Ingham Mutex::Locker locker; 13665a988416SJim Ingham target->GetBreakpointList(m_options.m_internal).GetListMutex(locker); 13675a988416SJim Ingham 13685a988416SJim Ingham size_t num_breakpoints = breakpoints.GetSize(); 13695a988416SJim Ingham 13705a988416SJim Ingham if (num_breakpoints == 0) 13715a988416SJim Ingham { 13725a988416SJim Ingham result.AppendMessage ("No breakpoints currently set."); 13735a988416SJim Ingham result.SetStatus (eReturnStatusSuccessFinishNoResult); 13745a988416SJim Ingham return true; 13755a988416SJim Ingham } 13765a988416SJim Ingham 13775a988416SJim Ingham Stream &output_stream = result.GetOutputStream(); 13785a988416SJim Ingham 13795a988416SJim Ingham if (command.GetArgumentCount() == 0) 13805a988416SJim Ingham { 13815a988416SJim Ingham // No breakpoint selected; show info about all currently set breakpoints. 13825a988416SJim Ingham result.AppendMessage ("Current breakpoints:"); 13835a988416SJim Ingham for (size_t i = 0; i < num_breakpoints; ++i) 13845a988416SJim Ingham { 13855a988416SJim Ingham Breakpoint *breakpoint = breakpoints.GetBreakpointAtIndex (i).get(); 13865a988416SJim Ingham AddBreakpointDescription (&output_stream, breakpoint, m_options.m_level); 13875a988416SJim Ingham } 13885a988416SJim Ingham result.SetStatus (eReturnStatusSuccessFinishNoResult); 13895a988416SJim Ingham } 13905a988416SJim Ingham else 13915a988416SJim Ingham { 13925a988416SJim Ingham // Particular breakpoints selected; show info about that breakpoint. 13935a988416SJim Ingham BreakpointIDList valid_bp_ids; 13945a988416SJim Ingham CommandObjectMultiwordBreakpoint::VerifyBreakpointIDs (command, target, result, &valid_bp_ids); 13955a988416SJim Ingham 13965a988416SJim Ingham if (result.Succeeded()) 13975a988416SJim Ingham { 13985a988416SJim Ingham for (size_t i = 0; i < valid_bp_ids.GetSize(); ++i) 13995a988416SJim Ingham { 14005a988416SJim Ingham BreakpointID cur_bp_id = valid_bp_ids.GetBreakpointIDAtIndex (i); 14015a988416SJim Ingham Breakpoint *breakpoint = target->GetBreakpointByID (cur_bp_id.GetBreakpointID()).get(); 14025a988416SJim Ingham AddBreakpointDescription (&output_stream, breakpoint, m_options.m_level); 14035a988416SJim Ingham } 14045a988416SJim Ingham result.SetStatus (eReturnStatusSuccessFinishNoResult); 14055a988416SJim Ingham } 14065a988416SJim Ingham else 14075a988416SJim Ingham { 14085a988416SJim Ingham result.AppendError ("Invalid breakpoint id."); 14095a988416SJim Ingham result.SetStatus (eReturnStatusFailed); 14105a988416SJim Ingham } 14115a988416SJim Ingham } 14125a988416SJim Ingham 14135a988416SJim Ingham return result.Succeeded(); 14145a988416SJim Ingham } 14155a988416SJim Ingham 14165a988416SJim Ingham private: 14175a988416SJim Ingham CommandOptions m_options; 14185a988416SJim Ingham }; 14195a988416SJim Ingham 14205a988416SJim Ingham #pragma mark List::CommandOptions 14215a988416SJim Ingham OptionDefinition 14225a988416SJim Ingham CommandObjectBreakpointList::CommandOptions::g_option_table[] = 14235a988416SJim Ingham { 1424e2607b50SVirgile Bello { LLDB_OPT_SET_ALL, false, "internal", 'i', OptionParser::eNoArgument, NULL, 0, eArgTypeNone, 14255a988416SJim Ingham "Show debugger internal breakpoints" }, 14265a988416SJim Ingham 1427e2607b50SVirgile Bello { LLDB_OPT_SET_1, false, "brief", 'b', OptionParser::eNoArgument, NULL, 0, eArgTypeNone, 14285a988416SJim Ingham "Give a brief description of the breakpoint (no location info)."}, 14295a988416SJim Ingham 14305a988416SJim Ingham // FIXME: We need to add an "internal" command, and then add this sort of thing to it. 14315a988416SJim Ingham // But I need to see it for now, and don't want to wait. 1432e2607b50SVirgile Bello { LLDB_OPT_SET_2, false, "full", 'f', OptionParser::eNoArgument, NULL, 0, eArgTypeNone, 14335a988416SJim Ingham "Give a full description of the breakpoint and its locations."}, 14345a988416SJim Ingham 1435e2607b50SVirgile Bello { LLDB_OPT_SET_3, false, "verbose", 'v', OptionParser::eNoArgument, NULL, 0, eArgTypeNone, 14365a988416SJim Ingham "Explain everything we know about the breakpoint (for debugging debugger bugs)." }, 14375a988416SJim Ingham 14385a988416SJim Ingham { 0, false, NULL, 0, 0, NULL, 0, eArgTypeNone, NULL } 14395a988416SJim Ingham }; 14405a988416SJim Ingham 14415a988416SJim Ingham //------------------------------------------------------------------------- 14425a988416SJim Ingham // CommandObjectBreakpointClear 14435a988416SJim Ingham //------------------------------------------------------------------------- 14445a988416SJim Ingham #pragma mark Clear 14455a988416SJim Ingham 14465a988416SJim Ingham class CommandObjectBreakpointClear : public CommandObjectParsed 14475a988416SJim Ingham { 14485a988416SJim Ingham public: 14495a988416SJim Ingham 14505a988416SJim Ingham typedef enum BreakpointClearType 14515a988416SJim Ingham { 14525a988416SJim Ingham eClearTypeInvalid, 14535a988416SJim Ingham eClearTypeFileAndLine 14545a988416SJim Ingham } BreakpointClearType; 14555a988416SJim Ingham 14565a988416SJim Ingham CommandObjectBreakpointClear (CommandInterpreter &interpreter) : 14575a988416SJim Ingham CommandObjectParsed (interpreter, 14585a988416SJim Ingham "breakpoint clear", 14595a988416SJim Ingham "Clears a breakpoint or set of breakpoints in the executable.", 14605a988416SJim Ingham "breakpoint clear <cmd-options>"), 14615a988416SJim Ingham m_options (interpreter) 14625a988416SJim Ingham { 14635a988416SJim Ingham } 14645a988416SJim Ingham 14655a988416SJim Ingham virtual 14665a988416SJim Ingham ~CommandObjectBreakpointClear () {} 14675a988416SJim Ingham 14685a988416SJim Ingham virtual Options * 14695a988416SJim Ingham GetOptions () 14705a988416SJim Ingham { 14715a988416SJim Ingham return &m_options; 14725a988416SJim Ingham } 14735a988416SJim Ingham 14745a988416SJim Ingham class CommandOptions : public Options 14755a988416SJim Ingham { 14765a988416SJim Ingham public: 14775a988416SJim Ingham 14785a988416SJim Ingham CommandOptions (CommandInterpreter &interpreter) : 14795a988416SJim Ingham Options (interpreter), 14805a988416SJim Ingham m_filename (), 14815a988416SJim Ingham m_line_num (0) 14825a988416SJim Ingham { 14835a988416SJim Ingham } 14845a988416SJim Ingham 14855a988416SJim Ingham virtual 14865a988416SJim Ingham ~CommandOptions () {} 14875a988416SJim Ingham 14885a988416SJim Ingham virtual Error 14895a988416SJim Ingham SetOptionValue (uint32_t option_idx, const char *option_arg) 14905a988416SJim Ingham { 14915a988416SJim Ingham Error error; 14923bcdfc0eSGreg Clayton const int short_option = m_getopt_table[option_idx].val; 14935a988416SJim Ingham 14945a988416SJim Ingham switch (short_option) 14955a988416SJim Ingham { 14965a988416SJim Ingham case 'f': 14975a988416SJim Ingham m_filename.assign (option_arg); 14985a988416SJim Ingham break; 14995a988416SJim Ingham 15005a988416SJim Ingham case 'l': 15015a988416SJim Ingham m_line_num = Args::StringToUInt32 (option_arg, 0); 15025a988416SJim Ingham break; 15035a988416SJim Ingham 15045a988416SJim Ingham default: 15055a988416SJim Ingham error.SetErrorStringWithFormat ("unrecognized option '%c'", short_option); 15065a988416SJim Ingham break; 15075a988416SJim Ingham } 15085a988416SJim Ingham 15095a988416SJim Ingham return error; 15105a988416SJim Ingham } 15115a988416SJim Ingham 15125a988416SJim Ingham void 15135a988416SJim Ingham OptionParsingStarting () 15145a988416SJim Ingham { 15155a988416SJim Ingham m_filename.clear(); 15165a988416SJim Ingham m_line_num = 0; 15175a988416SJim Ingham } 15185a988416SJim Ingham 15195a988416SJim Ingham const OptionDefinition* 15205a988416SJim Ingham GetDefinitions () 15215a988416SJim Ingham { 15225a988416SJim Ingham return g_option_table; 15235a988416SJim Ingham } 15245a988416SJim Ingham 15255a988416SJim Ingham // Options table: Required for subclasses of Options. 15265a988416SJim Ingham 15275a988416SJim Ingham static OptionDefinition g_option_table[]; 15285a988416SJim Ingham 15295a988416SJim Ingham // Instance variables to hold the values for command options. 15305a988416SJim Ingham 15315a988416SJim Ingham std::string m_filename; 15325a988416SJim Ingham uint32_t m_line_num; 15335a988416SJim Ingham 15345a988416SJim Ingham }; 15355a988416SJim Ingham 15365a988416SJim Ingham protected: 15375a988416SJim Ingham virtual bool 15385a988416SJim Ingham DoExecute (Args& command, CommandReturnObject &result) 15395a988416SJim Ingham { 15405a988416SJim Ingham Target *target = m_interpreter.GetDebugger().GetSelectedTarget().get(); 15415a988416SJim Ingham if (target == NULL) 15425a988416SJim Ingham { 15435a988416SJim Ingham result.AppendError ("Invalid target. No existing target or breakpoints."); 15445a988416SJim Ingham result.SetStatus (eReturnStatusFailed); 15455a988416SJim Ingham return false; 15465a988416SJim Ingham } 15475a988416SJim Ingham 15485a988416SJim Ingham // The following are the various types of breakpoints that could be cleared: 15495a988416SJim Ingham // 1). -f -l (clearing breakpoint by source location) 15505a988416SJim Ingham 15515a988416SJim Ingham BreakpointClearType break_type = eClearTypeInvalid; 15525a988416SJim Ingham 15535a988416SJim Ingham if (m_options.m_line_num != 0) 15545a988416SJim Ingham break_type = eClearTypeFileAndLine; 15555a988416SJim Ingham 15565a988416SJim Ingham Mutex::Locker locker; 15575a988416SJim Ingham target->GetBreakpointList().GetListMutex(locker); 15585a988416SJim Ingham 15595a988416SJim Ingham BreakpointList &breakpoints = target->GetBreakpointList(); 15605a988416SJim Ingham size_t num_breakpoints = breakpoints.GetSize(); 15615a988416SJim Ingham 15625a988416SJim Ingham // Early return if there's no breakpoint at all. 15635a988416SJim Ingham if (num_breakpoints == 0) 15645a988416SJim Ingham { 15655a988416SJim Ingham result.AppendError ("Breakpoint clear: No breakpoint cleared."); 15665a988416SJim Ingham result.SetStatus (eReturnStatusFailed); 15675a988416SJim Ingham return result.Succeeded(); 15685a988416SJim Ingham } 15695a988416SJim Ingham 15705a988416SJim Ingham // Find matching breakpoints and delete them. 15715a988416SJim Ingham 15725a988416SJim Ingham // First create a copy of all the IDs. 15735a988416SJim Ingham std::vector<break_id_t> BreakIDs; 15745a988416SJim Ingham for (size_t i = 0; i < num_breakpoints; ++i) 15755a988416SJim Ingham BreakIDs.push_back(breakpoints.GetBreakpointAtIndex(i).get()->GetID()); 15765a988416SJim Ingham 15775a988416SJim Ingham int num_cleared = 0; 15785a988416SJim Ingham StreamString ss; 15795a988416SJim Ingham switch (break_type) 15805a988416SJim Ingham { 15815a988416SJim Ingham case eClearTypeFileAndLine: // Breakpoint by source position 15825a988416SJim Ingham { 15835a988416SJim Ingham const ConstString filename(m_options.m_filename.c_str()); 15845a988416SJim Ingham BreakpointLocationCollection loc_coll; 15855a988416SJim Ingham 15865a988416SJim Ingham for (size_t i = 0; i < num_breakpoints; ++i) 15875a988416SJim Ingham { 15885a988416SJim Ingham Breakpoint *bp = breakpoints.FindBreakpointByID(BreakIDs[i]).get(); 15895a988416SJim Ingham 15905a988416SJim Ingham if (bp->GetMatchingFileLine(filename, m_options.m_line_num, loc_coll)) 15915a988416SJim Ingham { 15925a988416SJim Ingham // If the collection size is 0, it's a full match and we can just remove the breakpoint. 15935a988416SJim Ingham if (loc_coll.GetSize() == 0) 15945a988416SJim Ingham { 15955a988416SJim Ingham bp->GetDescription(&ss, lldb::eDescriptionLevelBrief); 15965a988416SJim Ingham ss.EOL(); 15975a988416SJim Ingham target->RemoveBreakpointByID (bp->GetID()); 15985a988416SJim Ingham ++num_cleared; 15995a988416SJim Ingham } 16005a988416SJim Ingham } 16015a988416SJim Ingham } 16025a988416SJim Ingham } 16035a988416SJim Ingham break; 16045a988416SJim Ingham 16055a988416SJim Ingham default: 16065a988416SJim Ingham break; 16075a988416SJim Ingham } 16085a988416SJim Ingham 16095a988416SJim Ingham if (num_cleared > 0) 16105a988416SJim Ingham { 16115a988416SJim Ingham Stream &output_stream = result.GetOutputStream(); 16125a988416SJim Ingham output_stream.Printf ("%d breakpoints cleared:\n", num_cleared); 16135a988416SJim Ingham output_stream << ss.GetData(); 16145a988416SJim Ingham output_stream.EOL(); 16155a988416SJim Ingham result.SetStatus (eReturnStatusSuccessFinishNoResult); 16165a988416SJim Ingham } 16175a988416SJim Ingham else 16185a988416SJim Ingham { 16195a988416SJim Ingham result.AppendError ("Breakpoint clear: No breakpoint cleared."); 16205a988416SJim Ingham result.SetStatus (eReturnStatusFailed); 16215a988416SJim Ingham } 16225a988416SJim Ingham 16235a988416SJim Ingham return result.Succeeded(); 16245a988416SJim Ingham } 16255a988416SJim Ingham 16265a988416SJim Ingham private: 16275a988416SJim Ingham CommandOptions m_options; 16285a988416SJim Ingham }; 16295a988416SJim Ingham 16305a988416SJim Ingham #pragma mark Clear::CommandOptions 16315a988416SJim Ingham 16325a988416SJim Ingham OptionDefinition 16335a988416SJim Ingham CommandObjectBreakpointClear::CommandOptions::g_option_table[] = 16345a988416SJim Ingham { 1635e2607b50SVirgile Bello { LLDB_OPT_SET_1, false, "file", 'f', OptionParser::eRequiredArgument, NULL, CommandCompletions::eSourceFileCompletion, eArgTypeFilename, 16365a988416SJim Ingham "Specify the breakpoint by source location in this particular file."}, 16375a988416SJim Ingham 1638e2607b50SVirgile Bello { LLDB_OPT_SET_1, true, "line", 'l', OptionParser::eRequiredArgument, NULL, 0, eArgTypeLineNum, 16395a988416SJim Ingham "Specify the breakpoint by source location at this particular line."}, 16405a988416SJim Ingham 16415a988416SJim Ingham { 0, false, NULL, 0, 0, NULL, 0, eArgTypeNone, NULL } 16425a988416SJim Ingham }; 16435a988416SJim Ingham 16445a988416SJim Ingham //------------------------------------------------------------------------- 16455a988416SJim Ingham // CommandObjectBreakpointDelete 16465a988416SJim Ingham //------------------------------------------------------------------------- 16475a988416SJim Ingham #pragma mark Delete 16485a988416SJim Ingham 16495a988416SJim Ingham class CommandObjectBreakpointDelete : public CommandObjectParsed 16505a988416SJim Ingham { 16515a988416SJim Ingham public: 16525a988416SJim Ingham CommandObjectBreakpointDelete (CommandInterpreter &interpreter) : 16535a988416SJim Ingham CommandObjectParsed (interpreter, 16545a988416SJim Ingham "breakpoint delete", 16555a988416SJim Ingham "Delete the specified breakpoint(s). If no breakpoints are specified, delete them all.", 16565a988416SJim Ingham NULL) 16575a988416SJim Ingham { 16585a988416SJim Ingham CommandArgumentEntry arg; 16595a988416SJim Ingham CommandObject::AddIDsArgumentData(arg, eArgTypeBreakpointID, eArgTypeBreakpointIDRange); 16605a988416SJim Ingham // Add the entry for the first argument for this command to the object's arguments vector. 16615a988416SJim Ingham m_arguments.push_back (arg); 16625a988416SJim Ingham } 16635a988416SJim Ingham 16645a988416SJim Ingham virtual 16655a988416SJim Ingham ~CommandObjectBreakpointDelete () {} 16665a988416SJim Ingham 16675a988416SJim Ingham protected: 16685a988416SJim Ingham virtual bool 16695a988416SJim Ingham DoExecute (Args& command, CommandReturnObject &result) 16705a988416SJim Ingham { 16715a988416SJim Ingham Target *target = m_interpreter.GetDebugger().GetSelectedTarget().get(); 16725a988416SJim Ingham if (target == NULL) 16735a988416SJim Ingham { 16745a988416SJim Ingham result.AppendError ("Invalid target. No existing target or breakpoints."); 16755a988416SJim Ingham result.SetStatus (eReturnStatusFailed); 16765a988416SJim Ingham return false; 16775a988416SJim Ingham } 16785a988416SJim Ingham 16795a988416SJim Ingham Mutex::Locker locker; 16805a988416SJim Ingham target->GetBreakpointList().GetListMutex(locker); 16815a988416SJim Ingham 16825a988416SJim Ingham const BreakpointList &breakpoints = target->GetBreakpointList(); 16835a988416SJim Ingham 16845a988416SJim Ingham size_t num_breakpoints = breakpoints.GetSize(); 16855a988416SJim Ingham 16865a988416SJim Ingham if (num_breakpoints == 0) 16875a988416SJim Ingham { 16885a988416SJim Ingham result.AppendError ("No breakpoints exist to be deleted."); 16895a988416SJim Ingham result.SetStatus (eReturnStatusFailed); 16905a988416SJim Ingham return false; 16915a988416SJim Ingham } 16925a988416SJim Ingham 16935a988416SJim Ingham if (command.GetArgumentCount() == 0) 16945a988416SJim Ingham { 16955a988416SJim Ingham if (!m_interpreter.Confirm ("About to delete all breakpoints, do you want to do that?", true)) 16965a988416SJim Ingham { 16975a988416SJim Ingham result.AppendMessage("Operation cancelled..."); 16985a988416SJim Ingham } 16995a988416SJim Ingham else 17005a988416SJim Ingham { 17015a988416SJim Ingham target->RemoveAllBreakpoints (); 1702bb03b8f4SJim Ingham result.AppendMessageWithFormat ("All breakpoints removed. (%lu %s)\n", num_breakpoints, num_breakpoints > 1 ? "breakpoints" : "breakpoint"); 17035a988416SJim Ingham } 17045a988416SJim Ingham result.SetStatus (eReturnStatusSuccessFinishNoResult); 17055a988416SJim Ingham } 17065a988416SJim Ingham else 17075a988416SJim Ingham { 17085a988416SJim Ingham // Particular breakpoint selected; disable that breakpoint. 17095a988416SJim Ingham BreakpointIDList valid_bp_ids; 17105a988416SJim Ingham CommandObjectMultiwordBreakpoint::VerifyBreakpointIDs (command, target, result, &valid_bp_ids); 17115a988416SJim Ingham 17125a988416SJim Ingham if (result.Succeeded()) 17135a988416SJim Ingham { 17145a988416SJim Ingham int delete_count = 0; 17155a988416SJim Ingham int disable_count = 0; 17165a988416SJim Ingham const size_t count = valid_bp_ids.GetSize(); 17175a988416SJim Ingham for (size_t i = 0; i < count; ++i) 17185a988416SJim Ingham { 17195a988416SJim Ingham BreakpointID cur_bp_id = valid_bp_ids.GetBreakpointIDAtIndex (i); 17205a988416SJim Ingham 17215a988416SJim Ingham if (cur_bp_id.GetBreakpointID() != LLDB_INVALID_BREAK_ID) 17225a988416SJim Ingham { 17235a988416SJim Ingham if (cur_bp_id.GetLocationID() != LLDB_INVALID_BREAK_ID) 17245a988416SJim Ingham { 17255a988416SJim Ingham Breakpoint *breakpoint = target->GetBreakpointByID (cur_bp_id.GetBreakpointID()).get(); 17265a988416SJim Ingham BreakpointLocation *location = breakpoint->FindLocationByID (cur_bp_id.GetLocationID()).get(); 17275a988416SJim Ingham // It makes no sense to try to delete individual locations, so we disable them instead. 17285a988416SJim Ingham if (location) 17295a988416SJim Ingham { 17305a988416SJim Ingham location->SetEnabled (false); 17315a988416SJim Ingham ++disable_count; 17325a988416SJim Ingham } 17335a988416SJim Ingham } 17345a988416SJim Ingham else 17355a988416SJim Ingham { 17365a988416SJim Ingham target->RemoveBreakpointByID (cur_bp_id.GetBreakpointID()); 17375a988416SJim Ingham ++delete_count; 17385a988416SJim Ingham } 17395a988416SJim Ingham } 17405a988416SJim Ingham } 17415a988416SJim Ingham result.AppendMessageWithFormat ("%d breakpoints deleted; %d breakpoint locations disabled.\n", 17425a988416SJim Ingham delete_count, disable_count); 17435a988416SJim Ingham result.SetStatus (eReturnStatusSuccessFinishNoResult); 17445a988416SJim Ingham } 17455a988416SJim Ingham } 17465a988416SJim Ingham return result.Succeeded(); 17475a988416SJim Ingham } 17485a988416SJim Ingham }; 17495a988416SJim Ingham 175030fdc8d8SChris Lattner //------------------------------------------------------------------------- 175130fdc8d8SChris Lattner // CommandObjectMultiwordBreakpoint 175230fdc8d8SChris Lattner //------------------------------------------------------------------------- 1753ae1c4cf5SJim Ingham #pragma mark MultiwordBreakpoint 175430fdc8d8SChris Lattner 17556611103cSGreg Clayton CommandObjectMultiwordBreakpoint::CommandObjectMultiwordBreakpoint (CommandInterpreter &interpreter) : 1756a7015092SGreg Clayton CommandObjectMultiword (interpreter, 1757a7015092SGreg Clayton "breakpoint", 175846fbc60fSJim Ingham "A set of commands for operating on breakpoints. Also see _regexp-break.", 175930fdc8d8SChris Lattner "breakpoint <command> [<command-options>]") 176030fdc8d8SChris Lattner { 1761a7015092SGreg Clayton CommandObjectSP list_command_object (new CommandObjectBreakpointList (interpreter)); 1762a7015092SGreg Clayton CommandObjectSP enable_command_object (new CommandObjectBreakpointEnable (interpreter)); 1763a7015092SGreg Clayton CommandObjectSP disable_command_object (new CommandObjectBreakpointDisable (interpreter)); 1764b7234e40SJohnny Chen CommandObjectSP clear_command_object (new CommandObjectBreakpointClear (interpreter)); 1765b7234e40SJohnny Chen CommandObjectSP delete_command_object (new CommandObjectBreakpointDelete (interpreter)); 1766a7015092SGreg Clayton CommandObjectSP set_command_object (new CommandObjectBreakpointSet (interpreter)); 176730fdc8d8SChris Lattner CommandObjectSP command_command_object (new CommandObjectBreakpointCommand (interpreter)); 1768a7015092SGreg Clayton CommandObjectSP modify_command_object (new CommandObjectBreakpointModify(interpreter)); 176930fdc8d8SChris Lattner 1770b7234e40SJohnny Chen list_command_object->SetCommandName ("breakpoint list"); 177130fdc8d8SChris Lattner enable_command_object->SetCommandName("breakpoint enable"); 177230fdc8d8SChris Lattner disable_command_object->SetCommandName("breakpoint disable"); 1773b7234e40SJohnny Chen clear_command_object->SetCommandName("breakpoint clear"); 1774b7234e40SJohnny Chen delete_command_object->SetCommandName("breakpoint delete"); 1775ae1c4cf5SJim Ingham set_command_object->SetCommandName("breakpoint set"); 1776b7234e40SJohnny Chen command_command_object->SetCommandName ("breakpoint command"); 1777b7234e40SJohnny Chen modify_command_object->SetCommandName ("breakpoint modify"); 177830fdc8d8SChris Lattner 177923f59509SGreg Clayton LoadSubCommand ("list", list_command_object); 178023f59509SGreg Clayton LoadSubCommand ("enable", enable_command_object); 178123f59509SGreg Clayton LoadSubCommand ("disable", disable_command_object); 178223f59509SGreg Clayton LoadSubCommand ("clear", clear_command_object); 178323f59509SGreg Clayton LoadSubCommand ("delete", delete_command_object); 178423f59509SGreg Clayton LoadSubCommand ("set", set_command_object); 178523f59509SGreg Clayton LoadSubCommand ("command", command_command_object); 178623f59509SGreg Clayton LoadSubCommand ("modify", modify_command_object); 178730fdc8d8SChris Lattner } 178830fdc8d8SChris Lattner 178930fdc8d8SChris Lattner CommandObjectMultiwordBreakpoint::~CommandObjectMultiwordBreakpoint () 179030fdc8d8SChris Lattner { 179130fdc8d8SChris Lattner } 179230fdc8d8SChris Lattner 179330fdc8d8SChris Lattner void 179430fdc8d8SChris Lattner CommandObjectMultiwordBreakpoint::VerifyBreakpointIDs (Args &args, Target *target, CommandReturnObject &result, 179530fdc8d8SChris Lattner BreakpointIDList *valid_ids) 179630fdc8d8SChris Lattner { 179730fdc8d8SChris Lattner // args can be strings representing 1). integers (for breakpoint ids) 179830fdc8d8SChris Lattner // 2). the full breakpoint & location canonical representation 179930fdc8d8SChris Lattner // 3). the word "to" or a hyphen, representing a range (in which case there 180030fdc8d8SChris Lattner // had *better* be an entry both before & after of one of the first two types. 180136f3b369SJim Ingham // If args is empty, we will use the last created breakpoint (if there is one.) 180230fdc8d8SChris Lattner 180330fdc8d8SChris Lattner Args temp_args; 180430fdc8d8SChris Lattner 180536f3b369SJim Ingham if (args.GetArgumentCount() == 0) 180636f3b369SJim Ingham { 18074d122c40SGreg Clayton if (target->GetLastCreatedBreakpoint()) 180836f3b369SJim Ingham { 180936f3b369SJim Ingham valid_ids->AddBreakpointID (BreakpointID(target->GetLastCreatedBreakpoint()->GetID(), LLDB_INVALID_BREAK_ID)); 181036f3b369SJim Ingham result.SetStatus (eReturnStatusSuccessFinishNoResult); 181136f3b369SJim Ingham } 181236f3b369SJim Ingham else 181336f3b369SJim Ingham { 181436f3b369SJim Ingham result.AppendError("No breakpoint specified and no last created breakpoint."); 181536f3b369SJim Ingham result.SetStatus (eReturnStatusFailed); 181636f3b369SJim Ingham } 181736f3b369SJim Ingham return; 181836f3b369SJim Ingham } 181936f3b369SJim Ingham 182030fdc8d8SChris Lattner // Create a new Args variable to use; copy any non-breakpoint-id-ranges stuff directly from the old ARGS to 182130fdc8d8SChris Lattner // the new TEMP_ARGS. Do not copy breakpoint id range strings over; instead generate a list of strings for 182230fdc8d8SChris Lattner // all the breakpoint ids in the range, and shove all of those breakpoint id strings into TEMP_ARGS. 182330fdc8d8SChris Lattner 182430fdc8d8SChris Lattner BreakpointIDList::FindAndReplaceIDRanges (args, target, result, temp_args); 182530fdc8d8SChris Lattner 182630fdc8d8SChris Lattner // NOW, convert the list of breakpoint id strings in TEMP_ARGS into an actual BreakpointIDList: 182730fdc8d8SChris Lattner 1828c982c768SGreg Clayton valid_ids->InsertStringArray (temp_args.GetConstArgumentVector(), temp_args.GetArgumentCount(), result); 182930fdc8d8SChris Lattner 183030fdc8d8SChris Lattner // At this point, all of the breakpoint ids that the user passed in have been converted to breakpoint IDs 183130fdc8d8SChris Lattner // and put into valid_ids. 183230fdc8d8SChris Lattner 183330fdc8d8SChris Lattner if (result.Succeeded()) 183430fdc8d8SChris Lattner { 183530fdc8d8SChris Lattner // Now that we've converted everything from args into a list of breakpoint ids, go through our tentative list 183630fdc8d8SChris Lattner // of breakpoint id's and verify that they correspond to valid/currently set breakpoints. 183730fdc8d8SChris Lattner 1838c982c768SGreg Clayton const size_t count = valid_ids->GetSize(); 1839c982c768SGreg Clayton for (size_t i = 0; i < count; ++i) 184030fdc8d8SChris Lattner { 184130fdc8d8SChris Lattner BreakpointID cur_bp_id = valid_ids->GetBreakpointIDAtIndex (i); 184230fdc8d8SChris Lattner Breakpoint *breakpoint = target->GetBreakpointByID (cur_bp_id.GetBreakpointID()).get(); 184330fdc8d8SChris Lattner if (breakpoint != NULL) 184430fdc8d8SChris Lattner { 1845c7bece56SGreg Clayton const size_t num_locations = breakpoint->GetNumLocations(); 184630fdc8d8SChris Lattner if (cur_bp_id.GetLocationID() > num_locations) 184730fdc8d8SChris Lattner { 184830fdc8d8SChris Lattner StreamString id_str; 1849c982c768SGreg Clayton BreakpointID::GetCanonicalReference (&id_str, 1850c982c768SGreg Clayton cur_bp_id.GetBreakpointID(), 185130fdc8d8SChris Lattner cur_bp_id.GetLocationID()); 1852c982c768SGreg Clayton i = valid_ids->GetSize() + 1; 185330fdc8d8SChris Lattner result.AppendErrorWithFormat ("'%s' is not a currently valid breakpoint/location id.\n", 185430fdc8d8SChris Lattner id_str.GetData()); 185530fdc8d8SChris Lattner result.SetStatus (eReturnStatusFailed); 185630fdc8d8SChris Lattner } 185730fdc8d8SChris Lattner } 185830fdc8d8SChris Lattner else 185930fdc8d8SChris Lattner { 1860c982c768SGreg Clayton i = valid_ids->GetSize() + 1; 186130fdc8d8SChris Lattner result.AppendErrorWithFormat ("'%d' is not a currently valid breakpoint id.\n", cur_bp_id.GetBreakpointID()); 186230fdc8d8SChris Lattner result.SetStatus (eReturnStatusFailed); 186330fdc8d8SChris Lattner } 186430fdc8d8SChris Lattner } 186530fdc8d8SChris Lattner } 186630fdc8d8SChris Lattner } 1867