1254721Semaste//===-- CommandObjectBreakpoint.cpp -----------------------------*- C++ -*-===// 2254721Semaste// 3254721Semaste// The LLVM Compiler Infrastructure 4254721Semaste// 5254721Semaste// This file is distributed under the University of Illinois Open Source 6254721Semaste// License. See LICENSE.TXT for details. 7254721Semaste// 8254721Semaste//===----------------------------------------------------------------------===// 9254721Semaste 10254721Semaste#include "lldb/lldb-python.h" 11254721Semaste 12254721Semaste#include "CommandObjectBreakpoint.h" 13254721Semaste#include "CommandObjectBreakpointCommand.h" 14254721Semaste 15254721Semaste// C Includes 16254721Semaste// C++ Includes 17254721Semaste// Other libraries and framework includes 18254721Semaste// Project includes 19254721Semaste#include "lldb/Breakpoint/Breakpoint.h" 20254721Semaste#include "lldb/Breakpoint/BreakpointIDList.h" 21254721Semaste#include "lldb/Breakpoint/BreakpointLocation.h" 22254721Semaste#include "lldb/Interpreter/Options.h" 23254721Semaste#include "lldb/Core/RegularExpression.h" 24254721Semaste#include "lldb/Core/StreamString.h" 25254721Semaste#include "lldb/Interpreter/CommandInterpreter.h" 26254721Semaste#include "lldb/Interpreter/CommandReturnObject.h" 27254721Semaste#include "lldb/Target/Target.h" 28254721Semaste#include "lldb/Interpreter/CommandCompletions.h" 29254721Semaste#include "lldb/Target/StackFrame.h" 30254721Semaste#include "lldb/Target/Thread.h" 31254721Semaste#include "lldb/Target/ThreadSpec.h" 32254721Semaste 33254721Semaste#include <vector> 34254721Semaste 35254721Semasteusing namespace lldb; 36254721Semasteusing namespace lldb_private; 37254721Semaste 38254721Semastestatic void 39254721SemasteAddBreakpointDescription (Stream *s, Breakpoint *bp, lldb::DescriptionLevel level) 40254721Semaste{ 41254721Semaste s->IndentMore(); 42254721Semaste bp->GetDescription (s, level, true); 43254721Semaste s->IndentLess(); 44254721Semaste s->EOL(); 45254721Semaste} 46254721Semaste 47254721Semaste//------------------------------------------------------------------------- 48254721Semaste// CommandObjectBreakpointSet 49254721Semaste//------------------------------------------------------------------------- 50254721Semaste 51254721Semaste 52254721Semasteclass CommandObjectBreakpointSet : public CommandObjectParsed 53254721Semaste{ 54254721Semastepublic: 55254721Semaste 56254721Semaste typedef enum BreakpointSetType 57254721Semaste { 58254721Semaste eSetTypeInvalid, 59254721Semaste eSetTypeFileAndLine, 60254721Semaste eSetTypeAddress, 61254721Semaste eSetTypeFunctionName, 62254721Semaste eSetTypeFunctionRegexp, 63254721Semaste eSetTypeSourceRegexp, 64254721Semaste eSetTypeException 65254721Semaste } BreakpointSetType; 66254721Semaste 67254721Semaste CommandObjectBreakpointSet (CommandInterpreter &interpreter) : 68254721Semaste CommandObjectParsed (interpreter, 69254721Semaste "breakpoint set", 70254721Semaste "Sets a breakpoint or set of breakpoints in the executable.", 71254721Semaste "breakpoint set <cmd-options>"), 72254721Semaste m_options (interpreter) 73254721Semaste { 74254721Semaste } 75254721Semaste 76254721Semaste 77254721Semaste virtual 78254721Semaste ~CommandObjectBreakpointSet () {} 79254721Semaste 80254721Semaste virtual Options * 81254721Semaste GetOptions () 82254721Semaste { 83254721Semaste return &m_options; 84254721Semaste } 85254721Semaste 86254721Semaste class CommandOptions : public Options 87254721Semaste { 88254721Semaste public: 89254721Semaste 90254721Semaste CommandOptions (CommandInterpreter &interpreter) : 91254721Semaste Options (interpreter), 92254721Semaste m_condition (), 93254721Semaste m_filenames (), 94254721Semaste m_line_num (0), 95254721Semaste m_column (0), 96254721Semaste m_func_names (), 97254721Semaste m_func_name_type_mask (eFunctionNameTypeNone), 98254721Semaste m_func_regexp (), 99254721Semaste m_source_text_regexp(), 100254721Semaste m_modules (), 101254721Semaste m_load_addr(), 102254721Semaste m_ignore_count (0), 103254721Semaste m_thread_id(LLDB_INVALID_THREAD_ID), 104254721Semaste m_thread_index (UINT32_MAX), 105254721Semaste m_thread_name(), 106254721Semaste m_queue_name(), 107254721Semaste m_catch_bp (false), 108254721Semaste m_throw_bp (true), 109263363Semaste m_hardware (false), 110254721Semaste m_language (eLanguageTypeUnknown), 111254721Semaste m_skip_prologue (eLazyBoolCalculate), 112254721Semaste m_one_shot (false) 113254721Semaste { 114254721Semaste } 115254721Semaste 116254721Semaste 117254721Semaste virtual 118254721Semaste ~CommandOptions () {} 119254721Semaste 120254721Semaste virtual Error 121254721Semaste SetOptionValue (uint32_t option_idx, const char *option_arg) 122254721Semaste { 123254721Semaste Error error; 124254721Semaste const int short_option = m_getopt_table[option_idx].val; 125254721Semaste 126254721Semaste switch (short_option) 127254721Semaste { 128254721Semaste case 'a': 129254721Semaste { 130254721Semaste ExecutionContext exe_ctx (m_interpreter.GetExecutionContext()); 131254721Semaste m_load_addr = Args::StringToAddress(&exe_ctx, option_arg, LLDB_INVALID_ADDRESS, &error); 132254721Semaste } 133254721Semaste break; 134254721Semaste 135254721Semaste case 'b': 136254721Semaste m_func_names.push_back (option_arg); 137254721Semaste m_func_name_type_mask |= eFunctionNameTypeBase; 138254721Semaste break; 139254721Semaste 140254721Semaste case 'C': 141254721Semaste m_column = Args::StringToUInt32 (option_arg, 0); 142254721Semaste break; 143254721Semaste 144254721Semaste case 'c': 145254721Semaste m_condition.assign(option_arg); 146254721Semaste break; 147254721Semaste 148254721Semaste case 'E': 149254721Semaste { 150254721Semaste LanguageType language = LanguageRuntime::GetLanguageTypeFromString (option_arg); 151254721Semaste 152254721Semaste switch (language) 153254721Semaste { 154254721Semaste case eLanguageTypeC89: 155254721Semaste case eLanguageTypeC: 156254721Semaste case eLanguageTypeC99: 157254721Semaste m_language = eLanguageTypeC; 158254721Semaste break; 159254721Semaste case eLanguageTypeC_plus_plus: 160254721Semaste m_language = eLanguageTypeC_plus_plus; 161254721Semaste break; 162254721Semaste case eLanguageTypeObjC: 163254721Semaste m_language = eLanguageTypeObjC; 164254721Semaste break; 165254721Semaste case eLanguageTypeObjC_plus_plus: 166254721Semaste error.SetErrorStringWithFormat ("Set exception breakpoints separately for c++ and objective-c"); 167254721Semaste break; 168254721Semaste case eLanguageTypeUnknown: 169254721Semaste error.SetErrorStringWithFormat ("Unknown language type: '%s' for exception breakpoint", option_arg); 170254721Semaste break; 171254721Semaste default: 172254721Semaste error.SetErrorStringWithFormat ("Unsupported language type: '%s' for exception breakpoint", option_arg); 173254721Semaste } 174254721Semaste } 175254721Semaste break; 176254721Semaste 177254721Semaste case 'f': 178254721Semaste m_filenames.AppendIfUnique (FileSpec(option_arg, false)); 179254721Semaste break; 180254721Semaste 181254721Semaste case 'F': 182254721Semaste m_func_names.push_back (option_arg); 183254721Semaste m_func_name_type_mask |= eFunctionNameTypeFull; 184254721Semaste break; 185254721Semaste 186254721Semaste case 'h': 187263363Semaste { 188263363Semaste bool success; 189263363Semaste m_catch_bp = Args::StringToBoolean (option_arg, true, &success); 190263363Semaste if (!success) 191263363Semaste error.SetErrorStringWithFormat ("Invalid boolean value for on-catch option: '%s'", option_arg); 192263363Semaste } 193263363Semaste break; 194263363Semaste 195263363Semaste case 'H': 196263363Semaste m_hardware = true; 197263363Semaste break; 198263363Semaste 199254721Semaste case 'i': 200254721Semaste { 201254721Semaste m_ignore_count = Args::StringToUInt32(option_arg, UINT32_MAX, 0); 202254721Semaste if (m_ignore_count == UINT32_MAX) 203254721Semaste error.SetErrorStringWithFormat ("invalid ignore count '%s'", option_arg); 204254721Semaste break; 205254721Semaste } 206254721Semaste 207254721Semaste case 'K': 208254721Semaste { 209254721Semaste bool success; 210254721Semaste bool value; 211254721Semaste value = Args::StringToBoolean (option_arg, true, &success); 212254721Semaste if (value) 213254721Semaste m_skip_prologue = eLazyBoolYes; 214254721Semaste else 215254721Semaste m_skip_prologue = eLazyBoolNo; 216254721Semaste 217254721Semaste if (!success) 218254721Semaste error.SetErrorStringWithFormat ("Invalid boolean value for skip prologue option: '%s'", option_arg); 219254721Semaste } 220254721Semaste break; 221254721Semaste 222254721Semaste case 'l': 223254721Semaste m_line_num = Args::StringToUInt32 (option_arg, 0); 224254721Semaste break; 225254721Semaste 226254721Semaste case 'M': 227254721Semaste m_func_names.push_back (option_arg); 228254721Semaste m_func_name_type_mask |= eFunctionNameTypeMethod; 229254721Semaste break; 230254721Semaste 231254721Semaste case 'n': 232254721Semaste m_func_names.push_back (option_arg); 233254721Semaste m_func_name_type_mask |= eFunctionNameTypeAuto; 234254721Semaste break; 235254721Semaste 236254721Semaste case 'o': 237254721Semaste m_one_shot = true; 238254721Semaste break; 239254721Semaste 240254721Semaste case 'p': 241254721Semaste m_source_text_regexp.assign (option_arg); 242254721Semaste break; 243254721Semaste 244254721Semaste case 'q': 245254721Semaste m_queue_name.assign (option_arg); 246254721Semaste break; 247254721Semaste 248254721Semaste case 'r': 249254721Semaste m_func_regexp.assign (option_arg); 250254721Semaste break; 251254721Semaste 252254721Semaste case 's': 253254721Semaste { 254254721Semaste m_modules.AppendIfUnique (FileSpec (option_arg, false)); 255254721Semaste break; 256254721Semaste } 257254721Semaste 258254721Semaste case 'S': 259254721Semaste m_func_names.push_back (option_arg); 260254721Semaste m_func_name_type_mask |= eFunctionNameTypeSelector; 261254721Semaste break; 262254721Semaste 263254721Semaste case 't' : 264254721Semaste { 265254721Semaste m_thread_id = Args::StringToUInt64(option_arg, LLDB_INVALID_THREAD_ID, 0); 266254721Semaste if (m_thread_id == LLDB_INVALID_THREAD_ID) 267254721Semaste error.SetErrorStringWithFormat ("invalid thread id string '%s'", option_arg); 268254721Semaste } 269254721Semaste break; 270254721Semaste 271254721Semaste case 'T': 272254721Semaste m_thread_name.assign (option_arg); 273254721Semaste break; 274254721Semaste 275254721Semaste case 'w': 276254721Semaste { 277254721Semaste bool success; 278254721Semaste m_throw_bp = Args::StringToBoolean (option_arg, true, &success); 279254721Semaste if (!success) 280254721Semaste error.SetErrorStringWithFormat ("Invalid boolean value for on-throw option: '%s'", option_arg); 281254721Semaste } 282254721Semaste break; 283254721Semaste 284254721Semaste case 'x': 285254721Semaste { 286254721Semaste m_thread_index = Args::StringToUInt32(option_arg, UINT32_MAX, 0); 287254721Semaste if (m_thread_id == UINT32_MAX) 288254721Semaste error.SetErrorStringWithFormat ("invalid thread index string '%s'", option_arg); 289254721Semaste 290254721Semaste } 291254721Semaste break; 292254721Semaste 293254721Semaste default: 294254721Semaste error.SetErrorStringWithFormat ("unrecognized option '%c'", short_option); 295254721Semaste break; 296254721Semaste } 297254721Semaste 298254721Semaste return error; 299254721Semaste } 300254721Semaste void 301254721Semaste OptionParsingStarting () 302254721Semaste { 303254721Semaste m_condition.clear(); 304254721Semaste m_filenames.Clear(); 305254721Semaste m_line_num = 0; 306254721Semaste m_column = 0; 307254721Semaste m_func_names.clear(); 308254721Semaste m_func_name_type_mask = eFunctionNameTypeNone; 309254721Semaste m_func_regexp.clear(); 310254721Semaste m_source_text_regexp.clear(); 311254721Semaste m_modules.Clear(); 312254721Semaste m_load_addr = LLDB_INVALID_ADDRESS; 313254721Semaste m_ignore_count = 0; 314254721Semaste m_thread_id = LLDB_INVALID_THREAD_ID; 315254721Semaste m_thread_index = UINT32_MAX; 316254721Semaste m_thread_name.clear(); 317254721Semaste m_queue_name.clear(); 318254721Semaste m_catch_bp = false; 319254721Semaste m_throw_bp = true; 320263363Semaste m_hardware = false; 321254721Semaste m_language = eLanguageTypeUnknown; 322254721Semaste m_skip_prologue = eLazyBoolCalculate; 323254721Semaste m_one_shot = false; 324254721Semaste } 325254721Semaste 326254721Semaste const OptionDefinition* 327254721Semaste GetDefinitions () 328254721Semaste { 329254721Semaste return g_option_table; 330254721Semaste } 331254721Semaste 332254721Semaste // Options table: Required for subclasses of Options. 333254721Semaste 334254721Semaste static OptionDefinition g_option_table[]; 335254721Semaste 336254721Semaste // Instance variables to hold the values for command options. 337254721Semaste 338254721Semaste std::string m_condition; 339254721Semaste FileSpecList m_filenames; 340254721Semaste uint32_t m_line_num; 341254721Semaste uint32_t m_column; 342254721Semaste std::vector<std::string> m_func_names; 343254721Semaste uint32_t m_func_name_type_mask; 344254721Semaste std::string m_func_regexp; 345254721Semaste std::string m_source_text_regexp; 346254721Semaste FileSpecList m_modules; 347254721Semaste lldb::addr_t m_load_addr; 348254721Semaste uint32_t m_ignore_count; 349254721Semaste lldb::tid_t m_thread_id; 350254721Semaste uint32_t m_thread_index; 351254721Semaste std::string m_thread_name; 352254721Semaste std::string m_queue_name; 353254721Semaste bool m_catch_bp; 354254721Semaste bool m_throw_bp; 355263363Semaste bool m_hardware; // Request to use hardware breakpoints 356254721Semaste lldb::LanguageType m_language; 357254721Semaste LazyBool m_skip_prologue; 358254721Semaste bool m_one_shot; 359254721Semaste 360254721Semaste }; 361254721Semaste 362254721Semasteprotected: 363254721Semaste virtual bool 364254721Semaste DoExecute (Args& command, 365254721Semaste CommandReturnObject &result) 366254721Semaste { 367254721Semaste Target *target = m_interpreter.GetDebugger().GetSelectedTarget().get(); 368254721Semaste if (target == NULL) 369254721Semaste { 370254721Semaste result.AppendError ("Invalid target. Must set target before setting breakpoints (see 'target create' command)."); 371254721Semaste result.SetStatus (eReturnStatusFailed); 372254721Semaste return false; 373254721Semaste } 374254721Semaste 375254721Semaste // The following are the various types of breakpoints that could be set: 376254721Semaste // 1). -f -l -p [-s -g] (setting breakpoint by source location) 377254721Semaste // 2). -a [-s -g] (setting breakpoint by address) 378254721Semaste // 3). -n [-s -g] (setting breakpoint by function name) 379254721Semaste // 4). -r [-s -g] (setting breakpoint by function name regular expression) 380254721Semaste // 5). -p -f (setting a breakpoint by comparing a reg-exp to source text) 381254721Semaste // 6). -E [-w -h] (setting a breakpoint for exceptions for a given language.) 382254721Semaste 383254721Semaste BreakpointSetType break_type = eSetTypeInvalid; 384254721Semaste 385254721Semaste if (m_options.m_line_num != 0) 386254721Semaste break_type = eSetTypeFileAndLine; 387254721Semaste else if (m_options.m_load_addr != LLDB_INVALID_ADDRESS) 388254721Semaste break_type = eSetTypeAddress; 389254721Semaste else if (!m_options.m_func_names.empty()) 390254721Semaste break_type = eSetTypeFunctionName; 391254721Semaste else if (!m_options.m_func_regexp.empty()) 392254721Semaste break_type = eSetTypeFunctionRegexp; 393254721Semaste else if (!m_options.m_source_text_regexp.empty()) 394254721Semaste break_type = eSetTypeSourceRegexp; 395254721Semaste else if (m_options.m_language != eLanguageTypeUnknown) 396254721Semaste break_type = eSetTypeException; 397254721Semaste 398254721Semaste Breakpoint *bp = NULL; 399254721Semaste FileSpec module_spec; 400254721Semaste const bool internal = false; 401254721Semaste 402254721Semaste switch (break_type) 403254721Semaste { 404254721Semaste case eSetTypeFileAndLine: // Breakpoint by source position 405254721Semaste { 406254721Semaste FileSpec file; 407254721Semaste const size_t num_files = m_options.m_filenames.GetSize(); 408254721Semaste if (num_files == 0) 409254721Semaste { 410254721Semaste if (!GetDefaultFile (target, file, result)) 411254721Semaste { 412254721Semaste result.AppendError("No file supplied and no default file available."); 413254721Semaste result.SetStatus (eReturnStatusFailed); 414254721Semaste return false; 415254721Semaste } 416254721Semaste } 417254721Semaste else if (num_files > 1) 418254721Semaste { 419254721Semaste result.AppendError("Only one file at a time is allowed for file and line breakpoints."); 420254721Semaste result.SetStatus (eReturnStatusFailed); 421254721Semaste return false; 422254721Semaste } 423254721Semaste else 424254721Semaste file = m_options.m_filenames.GetFileSpecAtIndex(0); 425254721Semaste 426254721Semaste // Only check for inline functions if 427254721Semaste LazyBool check_inlines = eLazyBoolCalculate; 428254721Semaste 429254721Semaste bp = target->CreateBreakpoint (&(m_options.m_modules), 430254721Semaste file, 431254721Semaste m_options.m_line_num, 432254721Semaste check_inlines, 433254721Semaste m_options.m_skip_prologue, 434263363Semaste internal, 435263363Semaste m_options.m_hardware).get(); 436254721Semaste } 437254721Semaste break; 438254721Semaste 439254721Semaste case eSetTypeAddress: // Breakpoint by address 440263363Semaste bp = target->CreateBreakpoint (m_options.m_load_addr, 441263363Semaste internal, 442263363Semaste m_options.m_hardware).get(); 443254721Semaste break; 444254721Semaste 445254721Semaste case eSetTypeFunctionName: // Breakpoint by function name 446254721Semaste { 447254721Semaste uint32_t name_type_mask = m_options.m_func_name_type_mask; 448254721Semaste 449254721Semaste if (name_type_mask == 0) 450254721Semaste name_type_mask = eFunctionNameTypeAuto; 451254721Semaste 452254721Semaste bp = target->CreateBreakpoint (&(m_options.m_modules), 453254721Semaste &(m_options.m_filenames), 454254721Semaste m_options.m_func_names, 455254721Semaste name_type_mask, 456254721Semaste m_options.m_skip_prologue, 457263363Semaste internal, 458263363Semaste m_options.m_hardware).get(); 459254721Semaste } 460254721Semaste break; 461254721Semaste 462254721Semaste case eSetTypeFunctionRegexp: // Breakpoint by regular expression function name 463254721Semaste { 464254721Semaste RegularExpression regexp(m_options.m_func_regexp.c_str()); 465254721Semaste if (!regexp.IsValid()) 466254721Semaste { 467254721Semaste char err_str[1024]; 468254721Semaste regexp.GetErrorAsCString(err_str, sizeof(err_str)); 469254721Semaste result.AppendErrorWithFormat("Function name regular expression could not be compiled: \"%s\"", 470254721Semaste err_str); 471254721Semaste result.SetStatus (eReturnStatusFailed); 472254721Semaste return false; 473254721Semaste } 474254721Semaste 475254721Semaste bp = target->CreateFuncRegexBreakpoint (&(m_options.m_modules), 476254721Semaste &(m_options.m_filenames), 477254721Semaste regexp, 478254721Semaste m_options.m_skip_prologue, 479263363Semaste internal, 480263363Semaste m_options.m_hardware).get(); 481254721Semaste } 482254721Semaste break; 483254721Semaste case eSetTypeSourceRegexp: // Breakpoint by regexp on source text. 484254721Semaste { 485254721Semaste const size_t num_files = m_options.m_filenames.GetSize(); 486254721Semaste 487254721Semaste if (num_files == 0) 488254721Semaste { 489254721Semaste FileSpec file; 490254721Semaste if (!GetDefaultFile (target, file, result)) 491254721Semaste { 492254721Semaste result.AppendError ("No files provided and could not find default file."); 493254721Semaste result.SetStatus (eReturnStatusFailed); 494254721Semaste return false; 495254721Semaste } 496254721Semaste else 497254721Semaste { 498254721Semaste m_options.m_filenames.Append (file); 499254721Semaste } 500254721Semaste } 501254721Semaste 502254721Semaste RegularExpression regexp(m_options.m_source_text_regexp.c_str()); 503254721Semaste if (!regexp.IsValid()) 504254721Semaste { 505254721Semaste char err_str[1024]; 506254721Semaste regexp.GetErrorAsCString(err_str, sizeof(err_str)); 507254721Semaste result.AppendErrorWithFormat("Source text regular expression could not be compiled: \"%s\"", 508254721Semaste err_str); 509254721Semaste result.SetStatus (eReturnStatusFailed); 510254721Semaste return false; 511254721Semaste } 512263363Semaste bp = target->CreateSourceRegexBreakpoint (&(m_options.m_modules), 513263363Semaste &(m_options.m_filenames), 514263363Semaste regexp, 515263363Semaste internal, 516263363Semaste m_options.m_hardware).get(); 517254721Semaste } 518254721Semaste break; 519254721Semaste case eSetTypeException: 520254721Semaste { 521263363Semaste bp = target->CreateExceptionBreakpoint (m_options.m_language, 522263363Semaste m_options.m_catch_bp, 523263363Semaste m_options.m_throw_bp, 524263363Semaste m_options.m_hardware).get(); 525254721Semaste } 526254721Semaste break; 527254721Semaste default: 528254721Semaste break; 529254721Semaste } 530254721Semaste 531254721Semaste // Now set the various options that were passed in: 532254721Semaste if (bp) 533254721Semaste { 534254721Semaste if (m_options.m_thread_id != LLDB_INVALID_THREAD_ID) 535254721Semaste bp->SetThreadID (m_options.m_thread_id); 536254721Semaste 537254721Semaste if (m_options.m_thread_index != UINT32_MAX) 538254721Semaste bp->GetOptions()->GetThreadSpec()->SetIndex(m_options.m_thread_index); 539254721Semaste 540254721Semaste if (!m_options.m_thread_name.empty()) 541254721Semaste bp->GetOptions()->GetThreadSpec()->SetName(m_options.m_thread_name.c_str()); 542254721Semaste 543254721Semaste if (!m_options.m_queue_name.empty()) 544254721Semaste bp->GetOptions()->GetThreadSpec()->SetQueueName(m_options.m_queue_name.c_str()); 545254721Semaste 546254721Semaste if (m_options.m_ignore_count != 0) 547254721Semaste bp->GetOptions()->SetIgnoreCount(m_options.m_ignore_count); 548254721Semaste 549254721Semaste if (!m_options.m_condition.empty()) 550254721Semaste bp->GetOptions()->SetCondition(m_options.m_condition.c_str()); 551254721Semaste 552254721Semaste bp->SetOneShot (m_options.m_one_shot); 553254721Semaste } 554254721Semaste 555254721Semaste if (bp) 556254721Semaste { 557254721Semaste Stream &output_stream = result.GetOutputStream(); 558254721Semaste const bool show_locations = false; 559254721Semaste bp->GetDescription(&output_stream, lldb::eDescriptionLevelInitial, show_locations); 560254721Semaste // Don't print out this warning for exception breakpoints. They can get set before the target 561254721Semaste // is set, but we won't know how to actually set the breakpoint till we run. 562254721Semaste if (bp->GetNumLocations() == 0 && break_type != eSetTypeException) 563254721Semaste output_stream.Printf ("WARNING: Unable to resolve breakpoint to any actual locations.\n"); 564254721Semaste result.SetStatus (eReturnStatusSuccessFinishResult); 565254721Semaste } 566254721Semaste else if (!bp) 567254721Semaste { 568254721Semaste result.AppendError ("Breakpoint creation failed: No breakpoint created."); 569254721Semaste result.SetStatus (eReturnStatusFailed); 570254721Semaste } 571254721Semaste 572254721Semaste return result.Succeeded(); 573254721Semaste } 574254721Semaste 575254721Semasteprivate: 576254721Semaste bool 577254721Semaste GetDefaultFile (Target *target, FileSpec &file, CommandReturnObject &result) 578254721Semaste { 579254721Semaste uint32_t default_line; 580254721Semaste // First use the Source Manager's default file. 581254721Semaste // Then use the current stack frame's file. 582254721Semaste if (!target->GetSourceManager().GetDefaultFileAndLine(file, default_line)) 583254721Semaste { 584254721Semaste StackFrame *cur_frame = m_exe_ctx.GetFramePtr(); 585254721Semaste if (cur_frame == NULL) 586254721Semaste { 587254721Semaste result.AppendError ("No selected frame to use to find the default file."); 588254721Semaste result.SetStatus (eReturnStatusFailed); 589254721Semaste return false; 590254721Semaste } 591254721Semaste else if (!cur_frame->HasDebugInformation()) 592254721Semaste { 593254721Semaste result.AppendError ("Cannot use the selected frame to find the default file, it has no debug info."); 594254721Semaste result.SetStatus (eReturnStatusFailed); 595254721Semaste return false; 596254721Semaste } 597254721Semaste else 598254721Semaste { 599254721Semaste const SymbolContext &sc = cur_frame->GetSymbolContext (eSymbolContextLineEntry); 600254721Semaste if (sc.line_entry.file) 601254721Semaste { 602254721Semaste file = sc.line_entry.file; 603254721Semaste } 604254721Semaste else 605254721Semaste { 606254721Semaste result.AppendError ("Can't find the file for the selected frame to use as the default file."); 607254721Semaste result.SetStatus (eReturnStatusFailed); 608254721Semaste return false; 609254721Semaste } 610254721Semaste } 611254721Semaste } 612254721Semaste return true; 613254721Semaste } 614254721Semaste 615254721Semaste CommandOptions m_options; 616254721Semaste}; 617254721Semaste// If an additional option set beyond LLDB_OPTION_SET_10 is added, make sure to 618254721Semaste// update the numbers passed to LLDB_OPT_SET_FROM_TO(...) appropriately. 619254721Semaste#define LLDB_OPT_FILE ( LLDB_OPT_SET_FROM_TO(1, 9) & ~LLDB_OPT_SET_2 ) 620254721Semaste#define LLDB_OPT_NOT_10 ( LLDB_OPT_SET_FROM_TO(1, 10) & ~LLDB_OPT_SET_10 ) 621254721Semaste#define LLDB_OPT_SKIP_PROLOGUE ( LLDB_OPT_SET_1 | LLDB_OPT_SET_FROM_TO(3,8) ) 622254721Semaste 623254721SemasteOptionDefinition 624254721SemasteCommandObjectBreakpointSet::CommandOptions::g_option_table[] = 625254721Semaste{ 626263363Semaste { LLDB_OPT_NOT_10, false, "shlib", 's', OptionParser::eRequiredArgument, NULL, CommandCompletions::eModuleCompletion, eArgTypeShlibName, 627254721Semaste "Set the breakpoint only in this shared library. " 628254721Semaste "Can repeat this option multiple times to specify multiple shared libraries."}, 629254721Semaste 630263363Semaste { LLDB_OPT_SET_ALL, false, "ignore-count", 'i', OptionParser::eRequiredArgument, NULL, 0, eArgTypeCount, 631254721Semaste "Set the number of times this breakpoint is skipped before stopping." }, 632254721Semaste 633263363Semaste { LLDB_OPT_SET_ALL, false, "one-shot", 'o', OptionParser::eNoArgument, NULL, 0, eArgTypeNone, 634254721Semaste "The breakpoint is deleted the first time it causes a stop." }, 635254721Semaste 636263363Semaste { LLDB_OPT_SET_ALL, false, "condition", 'c', OptionParser::eRequiredArgument, NULL, 0, eArgTypeExpression, 637254721Semaste "The breakpoint stops only if this condition expression evaluates to true."}, 638254721Semaste 639263363Semaste { LLDB_OPT_SET_ALL, false, "thread-index", 'x', OptionParser::eRequiredArgument, NULL, 0, eArgTypeThreadIndex, 640254721Semaste "The breakpoint stops only for the thread whose indeX matches this argument."}, 641254721Semaste 642263363Semaste { LLDB_OPT_SET_ALL, false, "thread-id", 't', OptionParser::eRequiredArgument, NULL, 0, eArgTypeThreadID, 643254721Semaste "The breakpoint stops only for the thread whose TID matches this argument."}, 644254721Semaste 645263363Semaste { LLDB_OPT_SET_ALL, false, "thread-name", 'T', OptionParser::eRequiredArgument, NULL, 0, eArgTypeThreadName, 646254721Semaste "The breakpoint stops only for the thread whose thread name matches this argument."}, 647254721Semaste 648263363Semaste { LLDB_OPT_SET_ALL, false, "hardware", 'H', OptionParser::eNoArgument, NULL, 0, eArgTypeNone, 649263363Semaste "Require the breakpoint to use hardware breakpoints."}, 650263363Semaste 651263363Semaste { LLDB_OPT_SET_ALL, false, "queue-name", 'q', OptionParser::eRequiredArgument, NULL, 0, eArgTypeQueueName, 652254721Semaste "The breakpoint stops only for threads in the queue whose name is given by this argument."}, 653254721Semaste 654263363Semaste { LLDB_OPT_FILE, false, "file", 'f', OptionParser::eRequiredArgument, NULL, CommandCompletions::eSourceFileCompletion, eArgTypeFilename, 655254721Semaste "Specifies the source file in which to set this breakpoint. " 656254721Semaste "Note, by default lldb only looks for files that are #included if they use the standard include file extensions. " 657254721Semaste "To set breakpoints on .c/.cpp/.m/.mm files that are #included, set target.inline-breakpoint-strategy" 658254721Semaste " to \"always\"."}, 659254721Semaste 660263363Semaste { LLDB_OPT_SET_1, true, "line", 'l', OptionParser::eRequiredArgument, NULL, 0, eArgTypeLineNum, 661254721Semaste "Specifies the line number on which to set this breakpoint."}, 662254721Semaste 663254721Semaste // Comment out this option for the moment, as we don't actually use it, but will in the future. 664254721Semaste // This way users won't see it, but the infrastructure is left in place. 665263363Semaste // { 0, false, "column", 'C', OptionParser::eRequiredArgument, NULL, "<column>", 666254721Semaste // "Set the breakpoint by source location at this particular column."}, 667254721Semaste 668263363Semaste { LLDB_OPT_SET_2, true, "address", 'a', OptionParser::eRequiredArgument, NULL, 0, eArgTypeAddressOrExpression, 669254721Semaste "Set the breakpoint by address, at the specified address."}, 670254721Semaste 671263363Semaste { LLDB_OPT_SET_3, true, "name", 'n', OptionParser::eRequiredArgument, NULL, CommandCompletions::eSymbolCompletion, eArgTypeFunctionName, 672254721Semaste "Set the breakpoint by function name. Can be repeated multiple times to make one breakpoint for multiple names" }, 673254721Semaste 674263363Semaste { LLDB_OPT_SET_4, true, "fullname", 'F', OptionParser::eRequiredArgument, NULL, CommandCompletions::eSymbolCompletion, eArgTypeFullName, 675254721Semaste "Set the breakpoint by fully qualified function names. For C++ this means namespaces and all arguments, and " 676254721Semaste "for Objective C this means a full function prototype with class and selector. " 677254721Semaste "Can be repeated multiple times to make one breakpoint for multiple names." }, 678254721Semaste 679263363Semaste { LLDB_OPT_SET_5, true, "selector", 'S', OptionParser::eRequiredArgument, NULL, 0, eArgTypeSelector, 680254721Semaste "Set the breakpoint by ObjC selector name. Can be repeated multiple times to make one breakpoint for multiple Selectors." }, 681254721Semaste 682263363Semaste { LLDB_OPT_SET_6, true, "method", 'M', OptionParser::eRequiredArgument, NULL, 0, eArgTypeMethod, 683254721Semaste "Set the breakpoint by C++ method names. Can be repeated multiple times to make one breakpoint for multiple methods." }, 684254721Semaste 685263363Semaste { LLDB_OPT_SET_7, true, "func-regex", 'r', OptionParser::eRequiredArgument, NULL, 0, eArgTypeRegularExpression, 686254721Semaste "Set the breakpoint by function name, evaluating a regular-expression to find the function name(s)." }, 687254721Semaste 688263363Semaste { LLDB_OPT_SET_8, true, "basename", 'b', OptionParser::eRequiredArgument, NULL, CommandCompletions::eSymbolCompletion, eArgTypeFunctionName, 689254721Semaste "Set the breakpoint by function basename (C++ namespaces and arguments will be ignored). " 690254721Semaste "Can be repeated multiple times to make one breakpoint for multiple symbols." }, 691254721Semaste 692263363Semaste { LLDB_OPT_SET_9, true, "source-pattern-regexp", 'p', OptionParser::eRequiredArgument, NULL, 0, eArgTypeRegularExpression, 693254721Semaste "Set the breakpoint by specifying a regular expression which is matched against the source text in a source file or files " 694254721Semaste "specified with the -f option. The -f option can be specified more than once. " 695254721Semaste "If no source files are specified, uses the current \"default source file\"" }, 696254721Semaste 697263363Semaste { LLDB_OPT_SET_10, true, "language-exception", 'E', OptionParser::eRequiredArgument, NULL, 0, eArgTypeLanguage, 698254721Semaste "Set the breakpoint on exceptions thrown by the specified language (without options, on throw but not catch.)" }, 699254721Semaste 700263363Semaste { LLDB_OPT_SET_10, false, "on-throw", 'w', OptionParser::eRequiredArgument, NULL, 0, eArgTypeBoolean, 701254721Semaste "Set the breakpoint on exception throW." }, 702254721Semaste 703263363Semaste { LLDB_OPT_SET_10, false, "on-catch", 'h', OptionParser::eRequiredArgument, NULL, 0, eArgTypeBoolean, 704254721Semaste "Set the breakpoint on exception catcH." }, 705254721Semaste 706263363Semaste { LLDB_OPT_SKIP_PROLOGUE, false, "skip-prologue", 'K', OptionParser::eRequiredArgument, NULL, 0, eArgTypeBoolean, 707254721Semaste "sKip the prologue if the breakpoint is at the beginning of a function. If not set the target.skip-prologue setting is used." }, 708254721Semaste 709254721Semaste { 0, false, NULL, 0, 0, NULL, 0, eArgTypeNone, NULL } 710254721Semaste}; 711254721Semaste 712254721Semaste//------------------------------------------------------------------------- 713254721Semaste// CommandObjectBreakpointModify 714254721Semaste//------------------------------------------------------------------------- 715254721Semaste#pragma mark Modify 716254721Semaste 717254721Semasteclass CommandObjectBreakpointModify : public CommandObjectParsed 718254721Semaste{ 719254721Semastepublic: 720254721Semaste 721254721Semaste CommandObjectBreakpointModify (CommandInterpreter &interpreter) : 722254721Semaste CommandObjectParsed (interpreter, 723254721Semaste "breakpoint modify", 724254721Semaste "Modify the options on a breakpoint or set of breakpoints in the executable. " 725254721Semaste "If no breakpoint is specified, acts on the last created breakpoint. " 726254721Semaste "With the exception of -e, -d and -i, passing an empty argument clears the modification.", 727254721Semaste NULL), 728254721Semaste m_options (interpreter) 729254721Semaste { 730254721Semaste CommandArgumentEntry arg; 731254721Semaste CommandObject::AddIDsArgumentData(arg, eArgTypeBreakpointID, eArgTypeBreakpointIDRange); 732254721Semaste // Add the entry for the first argument for this command to the object's arguments vector. 733254721Semaste m_arguments.push_back (arg); 734254721Semaste } 735254721Semaste 736254721Semaste 737254721Semaste virtual 738254721Semaste ~CommandObjectBreakpointModify () {} 739254721Semaste 740254721Semaste virtual Options * 741254721Semaste GetOptions () 742254721Semaste { 743254721Semaste return &m_options; 744254721Semaste } 745254721Semaste 746254721Semaste class CommandOptions : public Options 747254721Semaste { 748254721Semaste public: 749254721Semaste 750254721Semaste CommandOptions (CommandInterpreter &interpreter) : 751254721Semaste Options (interpreter), 752254721Semaste m_ignore_count (0), 753254721Semaste m_thread_id(LLDB_INVALID_THREAD_ID), 754254721Semaste m_thread_id_passed(false), 755254721Semaste m_thread_index (UINT32_MAX), 756254721Semaste m_thread_index_passed(false), 757254721Semaste m_thread_name(), 758254721Semaste m_queue_name(), 759254721Semaste m_condition (), 760254721Semaste m_one_shot (false), 761254721Semaste m_enable_passed (false), 762254721Semaste m_enable_value (false), 763254721Semaste m_name_passed (false), 764254721Semaste m_queue_passed (false), 765254721Semaste m_condition_passed (false), 766254721Semaste m_one_shot_passed (false) 767254721Semaste { 768254721Semaste } 769254721Semaste 770254721Semaste virtual 771254721Semaste ~CommandOptions () {} 772254721Semaste 773254721Semaste virtual Error 774254721Semaste SetOptionValue (uint32_t option_idx, const char *option_arg) 775254721Semaste { 776254721Semaste Error error; 777254721Semaste const int short_option = m_getopt_table[option_idx].val; 778254721Semaste 779254721Semaste switch (short_option) 780254721Semaste { 781254721Semaste case 'c': 782254721Semaste if (option_arg != NULL) 783254721Semaste m_condition.assign (option_arg); 784254721Semaste else 785254721Semaste m_condition.clear(); 786254721Semaste m_condition_passed = true; 787254721Semaste break; 788254721Semaste case 'd': 789254721Semaste m_enable_passed = true; 790254721Semaste m_enable_value = false; 791254721Semaste break; 792254721Semaste case 'e': 793254721Semaste m_enable_passed = true; 794254721Semaste m_enable_value = true; 795254721Semaste break; 796254721Semaste case 'i': 797254721Semaste { 798254721Semaste m_ignore_count = Args::StringToUInt32(option_arg, UINT32_MAX, 0); 799254721Semaste if (m_ignore_count == UINT32_MAX) 800254721Semaste error.SetErrorStringWithFormat ("invalid ignore count '%s'", option_arg); 801254721Semaste } 802254721Semaste break; 803254721Semaste case 'o': 804254721Semaste { 805254721Semaste bool value, success; 806254721Semaste value = Args::StringToBoolean(option_arg, false, &success); 807254721Semaste if (success) 808254721Semaste { 809254721Semaste m_one_shot_passed = true; 810254721Semaste m_one_shot = value; 811254721Semaste } 812254721Semaste else 813254721Semaste error.SetErrorStringWithFormat("invalid boolean value '%s' passed for -o option", option_arg); 814254721Semaste } 815254721Semaste break; 816254721Semaste case 't' : 817254721Semaste { 818254721Semaste if (option_arg[0] == '\0') 819254721Semaste { 820254721Semaste m_thread_id = LLDB_INVALID_THREAD_ID; 821254721Semaste m_thread_id_passed = true; 822254721Semaste } 823254721Semaste else 824254721Semaste { 825254721Semaste m_thread_id = Args::StringToUInt64(option_arg, LLDB_INVALID_THREAD_ID, 0); 826254721Semaste if (m_thread_id == LLDB_INVALID_THREAD_ID) 827254721Semaste error.SetErrorStringWithFormat ("invalid thread id string '%s'", option_arg); 828254721Semaste else 829254721Semaste m_thread_id_passed = true; 830254721Semaste } 831254721Semaste } 832254721Semaste break; 833254721Semaste case 'T': 834254721Semaste if (option_arg != NULL) 835254721Semaste m_thread_name.assign (option_arg); 836254721Semaste else 837254721Semaste m_thread_name.clear(); 838254721Semaste m_name_passed = true; 839254721Semaste break; 840254721Semaste case 'q': 841254721Semaste if (option_arg != NULL) 842254721Semaste m_queue_name.assign (option_arg); 843254721Semaste else 844254721Semaste m_queue_name.clear(); 845254721Semaste m_queue_passed = true; 846254721Semaste break; 847254721Semaste case 'x': 848254721Semaste { 849254721Semaste if (option_arg[0] == '\n') 850254721Semaste { 851254721Semaste m_thread_index = UINT32_MAX; 852254721Semaste m_thread_index_passed = true; 853254721Semaste } 854254721Semaste else 855254721Semaste { 856254721Semaste m_thread_index = Args::StringToUInt32 (option_arg, UINT32_MAX, 0); 857254721Semaste if (m_thread_id == UINT32_MAX) 858254721Semaste error.SetErrorStringWithFormat ("invalid thread index string '%s'", option_arg); 859254721Semaste else 860254721Semaste m_thread_index_passed = true; 861254721Semaste } 862254721Semaste } 863254721Semaste break; 864254721Semaste default: 865254721Semaste error.SetErrorStringWithFormat ("unrecognized option '%c'", short_option); 866254721Semaste break; 867254721Semaste } 868254721Semaste 869254721Semaste return error; 870254721Semaste } 871254721Semaste void 872254721Semaste OptionParsingStarting () 873254721Semaste { 874254721Semaste m_ignore_count = 0; 875254721Semaste m_thread_id = LLDB_INVALID_THREAD_ID; 876254721Semaste m_thread_id_passed = false; 877254721Semaste m_thread_index = UINT32_MAX; 878254721Semaste m_thread_index_passed = false; 879254721Semaste m_thread_name.clear(); 880254721Semaste m_queue_name.clear(); 881254721Semaste m_condition.clear(); 882254721Semaste m_one_shot = false; 883254721Semaste m_enable_passed = false; 884254721Semaste m_queue_passed = false; 885254721Semaste m_name_passed = false; 886254721Semaste m_condition_passed = false; 887254721Semaste m_one_shot_passed = false; 888254721Semaste } 889254721Semaste 890254721Semaste const OptionDefinition* 891254721Semaste GetDefinitions () 892254721Semaste { 893254721Semaste return g_option_table; 894254721Semaste } 895254721Semaste 896254721Semaste 897254721Semaste // Options table: Required for subclasses of Options. 898254721Semaste 899254721Semaste static OptionDefinition g_option_table[]; 900254721Semaste 901254721Semaste // Instance variables to hold the values for command options. 902254721Semaste 903254721Semaste uint32_t m_ignore_count; 904254721Semaste lldb::tid_t m_thread_id; 905254721Semaste bool m_thread_id_passed; 906254721Semaste uint32_t m_thread_index; 907254721Semaste bool m_thread_index_passed; 908254721Semaste std::string m_thread_name; 909254721Semaste std::string m_queue_name; 910254721Semaste std::string m_condition; 911254721Semaste bool m_one_shot; 912254721Semaste bool m_enable_passed; 913254721Semaste bool m_enable_value; 914254721Semaste bool m_name_passed; 915254721Semaste bool m_queue_passed; 916254721Semaste bool m_condition_passed; 917254721Semaste bool m_one_shot_passed; 918254721Semaste 919254721Semaste }; 920254721Semaste 921254721Semasteprotected: 922254721Semaste virtual bool 923254721Semaste DoExecute (Args& command, CommandReturnObject &result) 924254721Semaste { 925254721Semaste Target *target = m_interpreter.GetDebugger().GetSelectedTarget().get(); 926254721Semaste if (target == NULL) 927254721Semaste { 928254721Semaste result.AppendError ("Invalid target. No existing target or breakpoints."); 929254721Semaste result.SetStatus (eReturnStatusFailed); 930254721Semaste return false; 931254721Semaste } 932254721Semaste 933254721Semaste Mutex::Locker locker; 934254721Semaste target->GetBreakpointList().GetListMutex(locker); 935254721Semaste 936254721Semaste BreakpointIDList valid_bp_ids; 937254721Semaste 938254721Semaste CommandObjectMultiwordBreakpoint::VerifyBreakpointIDs (command, target, result, &valid_bp_ids); 939254721Semaste 940254721Semaste if (result.Succeeded()) 941254721Semaste { 942254721Semaste const size_t count = valid_bp_ids.GetSize(); 943254721Semaste for (size_t i = 0; i < count; ++i) 944254721Semaste { 945254721Semaste BreakpointID cur_bp_id = valid_bp_ids.GetBreakpointIDAtIndex (i); 946254721Semaste 947254721Semaste if (cur_bp_id.GetBreakpointID() != LLDB_INVALID_BREAK_ID) 948254721Semaste { 949254721Semaste Breakpoint *bp = target->GetBreakpointByID (cur_bp_id.GetBreakpointID()).get(); 950254721Semaste if (cur_bp_id.GetLocationID() != LLDB_INVALID_BREAK_ID) 951254721Semaste { 952254721Semaste BreakpointLocation *location = bp->FindLocationByID (cur_bp_id.GetLocationID()).get(); 953254721Semaste if (location) 954254721Semaste { 955254721Semaste if (m_options.m_thread_id_passed) 956254721Semaste location->SetThreadID (m_options.m_thread_id); 957254721Semaste 958254721Semaste if (m_options.m_thread_index_passed) 959254721Semaste location->SetThreadIndex(m_options.m_thread_index); 960254721Semaste 961254721Semaste if (m_options.m_name_passed) 962254721Semaste location->SetThreadName(m_options.m_thread_name.c_str()); 963254721Semaste 964254721Semaste if (m_options.m_queue_passed) 965254721Semaste location->SetQueueName(m_options.m_queue_name.c_str()); 966254721Semaste 967254721Semaste if (m_options.m_ignore_count != 0) 968254721Semaste location->SetIgnoreCount(m_options.m_ignore_count); 969254721Semaste 970254721Semaste if (m_options.m_enable_passed) 971254721Semaste location->SetEnabled (m_options.m_enable_value); 972254721Semaste 973254721Semaste if (m_options.m_condition_passed) 974254721Semaste location->SetCondition (m_options.m_condition.c_str()); 975254721Semaste } 976254721Semaste } 977254721Semaste else 978254721Semaste { 979254721Semaste if (m_options.m_thread_id_passed) 980254721Semaste bp->SetThreadID (m_options.m_thread_id); 981254721Semaste 982254721Semaste if (m_options.m_thread_index_passed) 983254721Semaste bp->SetThreadIndex(m_options.m_thread_index); 984254721Semaste 985254721Semaste if (m_options.m_name_passed) 986254721Semaste bp->SetThreadName(m_options.m_thread_name.c_str()); 987254721Semaste 988254721Semaste if (m_options.m_queue_passed) 989254721Semaste bp->SetQueueName(m_options.m_queue_name.c_str()); 990254721Semaste 991254721Semaste if (m_options.m_ignore_count != 0) 992254721Semaste bp->SetIgnoreCount(m_options.m_ignore_count); 993254721Semaste 994254721Semaste if (m_options.m_enable_passed) 995254721Semaste bp->SetEnabled (m_options.m_enable_value); 996254721Semaste 997254721Semaste if (m_options.m_condition_passed) 998254721Semaste bp->SetCondition (m_options.m_condition.c_str()); 999254721Semaste } 1000254721Semaste } 1001254721Semaste } 1002254721Semaste } 1003254721Semaste 1004254721Semaste return result.Succeeded(); 1005254721Semaste } 1006254721Semaste 1007254721Semasteprivate: 1008254721Semaste CommandOptions m_options; 1009254721Semaste}; 1010254721Semaste 1011254721Semaste#pragma mark Modify::CommandOptions 1012254721SemasteOptionDefinition 1013254721SemasteCommandObjectBreakpointModify::CommandOptions::g_option_table[] = 1014254721Semaste{ 1015263363Semaste{ LLDB_OPT_SET_ALL, false, "ignore-count", 'i', OptionParser::eRequiredArgument, NULL, 0, eArgTypeCount, "Set the number of times this breakpoint is skipped before stopping." }, 1016263363Semaste{ 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." }, 1017263363Semaste{ 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."}, 1018263363Semaste{ 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."}, 1019263363Semaste{ 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."}, 1020263363Semaste{ 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."}, 1021263363Semaste{ LLDB_OPT_SET_ALL, false, "condition", 'c', OptionParser::eRequiredArgument, NULL, 0, eArgTypeExpression, "The breakpoint stops only if this condition expression evaluates to true."}, 1022263363Semaste{ LLDB_OPT_SET_1, false, "enable", 'e', OptionParser::eNoArgument, NULL, 0, eArgTypeNone, "Enable the breakpoint."}, 1023263363Semaste{ LLDB_OPT_SET_2, false, "disable", 'd', OptionParser::eNoArgument, NULL, 0, eArgTypeNone, "Disable the breakpoint."}, 1024254721Semaste{ 0, false, NULL, 0 , 0, NULL, 0, eArgTypeNone, NULL } 1025254721Semaste}; 1026254721Semaste 1027254721Semaste//------------------------------------------------------------------------- 1028254721Semaste// CommandObjectBreakpointEnable 1029254721Semaste//------------------------------------------------------------------------- 1030254721Semaste#pragma mark Enable 1031254721Semaste 1032254721Semasteclass CommandObjectBreakpointEnable : public CommandObjectParsed 1033254721Semaste{ 1034254721Semastepublic: 1035254721Semaste CommandObjectBreakpointEnable (CommandInterpreter &interpreter) : 1036254721Semaste CommandObjectParsed (interpreter, 1037254721Semaste "enable", 1038254721Semaste "Enable the specified disabled breakpoint(s). If no breakpoints are specified, enable all of them.", 1039254721Semaste NULL) 1040254721Semaste { 1041254721Semaste CommandArgumentEntry arg; 1042254721Semaste CommandObject::AddIDsArgumentData(arg, eArgTypeBreakpointID, eArgTypeBreakpointIDRange); 1043254721Semaste // Add the entry for the first argument for this command to the object's arguments vector. 1044254721Semaste m_arguments.push_back (arg); 1045254721Semaste } 1046254721Semaste 1047254721Semaste 1048254721Semaste virtual 1049254721Semaste ~CommandObjectBreakpointEnable () {} 1050254721Semaste 1051254721Semasteprotected: 1052254721Semaste virtual bool 1053254721Semaste DoExecute (Args& command, CommandReturnObject &result) 1054254721Semaste { 1055254721Semaste Target *target = m_interpreter.GetDebugger().GetSelectedTarget().get(); 1056254721Semaste if (target == NULL) 1057254721Semaste { 1058254721Semaste result.AppendError ("Invalid target. No existing target or breakpoints."); 1059254721Semaste result.SetStatus (eReturnStatusFailed); 1060254721Semaste return false; 1061254721Semaste } 1062254721Semaste 1063254721Semaste Mutex::Locker locker; 1064254721Semaste target->GetBreakpointList().GetListMutex(locker); 1065254721Semaste 1066254721Semaste const BreakpointList &breakpoints = target->GetBreakpointList(); 1067254721Semaste 1068254721Semaste size_t num_breakpoints = breakpoints.GetSize(); 1069254721Semaste 1070254721Semaste if (num_breakpoints == 0) 1071254721Semaste { 1072254721Semaste result.AppendError ("No breakpoints exist to be enabled."); 1073254721Semaste result.SetStatus (eReturnStatusFailed); 1074254721Semaste return false; 1075254721Semaste } 1076254721Semaste 1077254721Semaste if (command.GetArgumentCount() == 0) 1078254721Semaste { 1079254721Semaste // No breakpoint selected; enable all currently set breakpoints. 1080254721Semaste target->EnableAllBreakpoints (); 1081263363Semaste result.AppendMessageWithFormat ("All breakpoints enabled. (%zu breakpoints)\n", num_breakpoints); 1082254721Semaste result.SetStatus (eReturnStatusSuccessFinishNoResult); 1083254721Semaste } 1084254721Semaste else 1085254721Semaste { 1086254721Semaste // Particular breakpoint selected; enable that breakpoint. 1087254721Semaste BreakpointIDList valid_bp_ids; 1088254721Semaste CommandObjectMultiwordBreakpoint::VerifyBreakpointIDs (command, target, result, &valid_bp_ids); 1089254721Semaste 1090254721Semaste if (result.Succeeded()) 1091254721Semaste { 1092254721Semaste int enable_count = 0; 1093254721Semaste int loc_count = 0; 1094254721Semaste const size_t count = valid_bp_ids.GetSize(); 1095254721Semaste for (size_t i = 0; i < count; ++i) 1096254721Semaste { 1097254721Semaste BreakpointID cur_bp_id = valid_bp_ids.GetBreakpointIDAtIndex (i); 1098254721Semaste 1099254721Semaste if (cur_bp_id.GetBreakpointID() != LLDB_INVALID_BREAK_ID) 1100254721Semaste { 1101254721Semaste Breakpoint *breakpoint = target->GetBreakpointByID (cur_bp_id.GetBreakpointID()).get(); 1102254721Semaste if (cur_bp_id.GetLocationID() != LLDB_INVALID_BREAK_ID) 1103254721Semaste { 1104254721Semaste BreakpointLocation *location = breakpoint->FindLocationByID (cur_bp_id.GetLocationID()).get(); 1105254721Semaste if (location) 1106254721Semaste { 1107254721Semaste location->SetEnabled (true); 1108254721Semaste ++loc_count; 1109254721Semaste } 1110254721Semaste } 1111254721Semaste else 1112254721Semaste { 1113254721Semaste breakpoint->SetEnabled (true); 1114254721Semaste ++enable_count; 1115254721Semaste } 1116254721Semaste } 1117254721Semaste } 1118254721Semaste result.AppendMessageWithFormat ("%d breakpoints enabled.\n", enable_count + loc_count); 1119254721Semaste result.SetStatus (eReturnStatusSuccessFinishNoResult); 1120254721Semaste } 1121254721Semaste } 1122254721Semaste 1123254721Semaste return result.Succeeded(); 1124254721Semaste } 1125254721Semaste}; 1126254721Semaste 1127254721Semaste//------------------------------------------------------------------------- 1128254721Semaste// CommandObjectBreakpointDisable 1129254721Semaste//------------------------------------------------------------------------- 1130254721Semaste#pragma mark Disable 1131254721Semaste 1132254721Semasteclass CommandObjectBreakpointDisable : public CommandObjectParsed 1133254721Semaste{ 1134254721Semastepublic: 1135254721Semaste CommandObjectBreakpointDisable (CommandInterpreter &interpreter) : 1136254721Semaste CommandObjectParsed (interpreter, 1137254721Semaste "breakpoint disable", 1138254721Semaste "Disable the specified breakpoint(s) without removing it/them. If no breakpoints are specified, disable them all.", 1139254721Semaste NULL) 1140254721Semaste { 1141254721Semaste SetHelpLong( 1142254721Semaste"Disable the specified breakpoint(s) without removing it/them. \n\ 1143254721SemasteIf no breakpoints are specified, disable them all.\n\ 1144254721Semaste\n\ 1145254721SemasteNote: disabling a breakpoint will cause none of its locations to be hit\n\ 1146254721Semasteregardless of whether they are enabled or disabled. So the sequence: \n\ 1147254721Semaste\n\ 1148254721Semaste (lldb) break disable 1\n\ 1149254721Semaste (lldb) break enable 1.1\n\ 1150254721Semaste\n\ 1151254721Semastewill NOT cause location 1.1 to get hit. To achieve that, do:\n\ 1152254721Semaste\n\ 1153254721Semaste (lldb) break disable 1.*\n\ 1154254721Semaste (lldb) break enable 1.1\n\ 1155254721Semaste\n\ 1156254721SemasteThe first command disables all the locations of breakpoint 1, \n\ 1157254721Semastethe second re-enables the first location." 1158254721Semaste ); 1159254721Semaste 1160254721Semaste CommandArgumentEntry arg; 1161254721Semaste CommandObject::AddIDsArgumentData(arg, eArgTypeBreakpointID, eArgTypeBreakpointIDRange); 1162254721Semaste // Add the entry for the first argument for this command to the object's arguments vector. 1163254721Semaste m_arguments.push_back (arg); 1164254721Semaste 1165254721Semaste } 1166254721Semaste 1167254721Semaste 1168254721Semaste virtual 1169254721Semaste ~CommandObjectBreakpointDisable () {} 1170254721Semaste 1171254721Semasteprotected: 1172254721Semaste virtual bool 1173254721Semaste DoExecute (Args& command, CommandReturnObject &result) 1174254721Semaste { 1175254721Semaste Target *target = m_interpreter.GetDebugger().GetSelectedTarget().get(); 1176254721Semaste if (target == NULL) 1177254721Semaste { 1178254721Semaste result.AppendError ("Invalid target. No existing target or breakpoints."); 1179254721Semaste result.SetStatus (eReturnStatusFailed); 1180254721Semaste return false; 1181254721Semaste } 1182254721Semaste 1183254721Semaste Mutex::Locker locker; 1184254721Semaste target->GetBreakpointList().GetListMutex(locker); 1185254721Semaste 1186254721Semaste const BreakpointList &breakpoints = target->GetBreakpointList(); 1187254721Semaste size_t num_breakpoints = breakpoints.GetSize(); 1188254721Semaste 1189254721Semaste if (num_breakpoints == 0) 1190254721Semaste { 1191254721Semaste result.AppendError ("No breakpoints exist to be disabled."); 1192254721Semaste result.SetStatus (eReturnStatusFailed); 1193254721Semaste return false; 1194254721Semaste } 1195254721Semaste 1196254721Semaste if (command.GetArgumentCount() == 0) 1197254721Semaste { 1198254721Semaste // No breakpoint selected; disable all currently set breakpoints. 1199254721Semaste target->DisableAllBreakpoints (); 1200263363Semaste result.AppendMessageWithFormat ("All breakpoints disabled. (%zu breakpoints)\n", num_breakpoints); 1201254721Semaste result.SetStatus (eReturnStatusSuccessFinishNoResult); 1202254721Semaste } 1203254721Semaste else 1204254721Semaste { 1205254721Semaste // Particular breakpoint selected; disable that breakpoint. 1206254721Semaste BreakpointIDList valid_bp_ids; 1207254721Semaste 1208254721Semaste CommandObjectMultiwordBreakpoint::VerifyBreakpointIDs (command, target, result, &valid_bp_ids); 1209254721Semaste 1210254721Semaste if (result.Succeeded()) 1211254721Semaste { 1212254721Semaste int disable_count = 0; 1213254721Semaste int loc_count = 0; 1214254721Semaste const size_t count = valid_bp_ids.GetSize(); 1215254721Semaste for (size_t i = 0; i < count; ++i) 1216254721Semaste { 1217254721Semaste BreakpointID cur_bp_id = valid_bp_ids.GetBreakpointIDAtIndex (i); 1218254721Semaste 1219254721Semaste if (cur_bp_id.GetBreakpointID() != LLDB_INVALID_BREAK_ID) 1220254721Semaste { 1221254721Semaste Breakpoint *breakpoint = target->GetBreakpointByID (cur_bp_id.GetBreakpointID()).get(); 1222254721Semaste if (cur_bp_id.GetLocationID() != LLDB_INVALID_BREAK_ID) 1223254721Semaste { 1224254721Semaste BreakpointLocation *location = breakpoint->FindLocationByID (cur_bp_id.GetLocationID()).get(); 1225254721Semaste if (location) 1226254721Semaste { 1227254721Semaste location->SetEnabled (false); 1228254721Semaste ++loc_count; 1229254721Semaste } 1230254721Semaste } 1231254721Semaste else 1232254721Semaste { 1233254721Semaste breakpoint->SetEnabled (false); 1234254721Semaste ++disable_count; 1235254721Semaste } 1236254721Semaste } 1237254721Semaste } 1238254721Semaste result.AppendMessageWithFormat ("%d breakpoints disabled.\n", disable_count + loc_count); 1239254721Semaste result.SetStatus (eReturnStatusSuccessFinishNoResult); 1240254721Semaste } 1241254721Semaste } 1242254721Semaste 1243254721Semaste return result.Succeeded(); 1244254721Semaste } 1245254721Semaste 1246254721Semaste}; 1247254721Semaste 1248254721Semaste//------------------------------------------------------------------------- 1249254721Semaste// CommandObjectBreakpointList 1250254721Semaste//------------------------------------------------------------------------- 1251254721Semaste#pragma mark List 1252254721Semaste 1253254721Semasteclass CommandObjectBreakpointList : public CommandObjectParsed 1254254721Semaste{ 1255254721Semastepublic: 1256254721Semaste CommandObjectBreakpointList (CommandInterpreter &interpreter) : 1257254721Semaste CommandObjectParsed (interpreter, 1258254721Semaste "breakpoint list", 1259254721Semaste "List some or all breakpoints at configurable levels of detail.", 1260254721Semaste NULL), 1261254721Semaste m_options (interpreter) 1262254721Semaste { 1263254721Semaste CommandArgumentEntry arg; 1264254721Semaste CommandArgumentData bp_id_arg; 1265254721Semaste 1266254721Semaste // Define the first (and only) variant of this arg. 1267254721Semaste bp_id_arg.arg_type = eArgTypeBreakpointID; 1268254721Semaste bp_id_arg.arg_repetition = eArgRepeatOptional; 1269254721Semaste 1270254721Semaste // There is only one variant this argument could be; put it into the argument entry. 1271254721Semaste arg.push_back (bp_id_arg); 1272254721Semaste 1273254721Semaste // Push the data for the first argument into the m_arguments vector. 1274254721Semaste m_arguments.push_back (arg); 1275254721Semaste } 1276254721Semaste 1277254721Semaste 1278254721Semaste virtual 1279254721Semaste ~CommandObjectBreakpointList () {} 1280254721Semaste 1281254721Semaste virtual Options * 1282254721Semaste GetOptions () 1283254721Semaste { 1284254721Semaste return &m_options; 1285254721Semaste } 1286254721Semaste 1287254721Semaste class CommandOptions : public Options 1288254721Semaste { 1289254721Semaste public: 1290254721Semaste 1291254721Semaste CommandOptions (CommandInterpreter &interpreter) : 1292254721Semaste Options (interpreter), 1293254721Semaste m_level (lldb::eDescriptionLevelBrief) // Breakpoint List defaults to brief descriptions 1294254721Semaste { 1295254721Semaste } 1296254721Semaste 1297254721Semaste virtual 1298254721Semaste ~CommandOptions () {} 1299254721Semaste 1300254721Semaste virtual Error 1301254721Semaste SetOptionValue (uint32_t option_idx, const char *option_arg) 1302254721Semaste { 1303254721Semaste Error error; 1304254721Semaste const int short_option = m_getopt_table[option_idx].val; 1305254721Semaste 1306254721Semaste switch (short_option) 1307254721Semaste { 1308254721Semaste case 'b': 1309254721Semaste m_level = lldb::eDescriptionLevelBrief; 1310254721Semaste break; 1311254721Semaste case 'f': 1312254721Semaste m_level = lldb::eDescriptionLevelFull; 1313254721Semaste break; 1314254721Semaste case 'v': 1315254721Semaste m_level = lldb::eDescriptionLevelVerbose; 1316254721Semaste break; 1317254721Semaste case 'i': 1318254721Semaste m_internal = true; 1319254721Semaste break; 1320254721Semaste default: 1321254721Semaste error.SetErrorStringWithFormat ("unrecognized option '%c'", short_option); 1322254721Semaste break; 1323254721Semaste } 1324254721Semaste 1325254721Semaste return error; 1326254721Semaste } 1327254721Semaste 1328254721Semaste void 1329254721Semaste OptionParsingStarting () 1330254721Semaste { 1331254721Semaste m_level = lldb::eDescriptionLevelFull; 1332254721Semaste m_internal = false; 1333254721Semaste } 1334254721Semaste 1335254721Semaste const OptionDefinition * 1336254721Semaste GetDefinitions () 1337254721Semaste { 1338254721Semaste return g_option_table; 1339254721Semaste } 1340254721Semaste 1341254721Semaste // Options table: Required for subclasses of Options. 1342254721Semaste 1343254721Semaste static OptionDefinition g_option_table[]; 1344254721Semaste 1345254721Semaste // Instance variables to hold the values for command options. 1346254721Semaste 1347254721Semaste lldb::DescriptionLevel m_level; 1348254721Semaste 1349254721Semaste bool m_internal; 1350254721Semaste }; 1351254721Semaste 1352254721Semasteprotected: 1353254721Semaste virtual bool 1354254721Semaste DoExecute (Args& command, CommandReturnObject &result) 1355254721Semaste { 1356254721Semaste Target *target = m_interpreter.GetDebugger().GetSelectedTarget().get(); 1357254721Semaste if (target == NULL) 1358254721Semaste { 1359254721Semaste result.AppendError ("Invalid target. No current target or breakpoints."); 1360254721Semaste result.SetStatus (eReturnStatusSuccessFinishNoResult); 1361254721Semaste return true; 1362254721Semaste } 1363254721Semaste 1364254721Semaste const BreakpointList &breakpoints = target->GetBreakpointList(m_options.m_internal); 1365254721Semaste Mutex::Locker locker; 1366254721Semaste target->GetBreakpointList(m_options.m_internal).GetListMutex(locker); 1367254721Semaste 1368254721Semaste size_t num_breakpoints = breakpoints.GetSize(); 1369254721Semaste 1370254721Semaste if (num_breakpoints == 0) 1371254721Semaste { 1372254721Semaste result.AppendMessage ("No breakpoints currently set."); 1373254721Semaste result.SetStatus (eReturnStatusSuccessFinishNoResult); 1374254721Semaste return true; 1375254721Semaste } 1376254721Semaste 1377254721Semaste Stream &output_stream = result.GetOutputStream(); 1378254721Semaste 1379254721Semaste if (command.GetArgumentCount() == 0) 1380254721Semaste { 1381254721Semaste // No breakpoint selected; show info about all currently set breakpoints. 1382254721Semaste result.AppendMessage ("Current breakpoints:"); 1383254721Semaste for (size_t i = 0; i < num_breakpoints; ++i) 1384254721Semaste { 1385254721Semaste Breakpoint *breakpoint = breakpoints.GetBreakpointAtIndex (i).get(); 1386254721Semaste AddBreakpointDescription (&output_stream, breakpoint, m_options.m_level); 1387254721Semaste } 1388254721Semaste result.SetStatus (eReturnStatusSuccessFinishNoResult); 1389254721Semaste } 1390254721Semaste else 1391254721Semaste { 1392254721Semaste // Particular breakpoints selected; show info about that breakpoint. 1393254721Semaste BreakpointIDList valid_bp_ids; 1394254721Semaste CommandObjectMultiwordBreakpoint::VerifyBreakpointIDs (command, target, result, &valid_bp_ids); 1395254721Semaste 1396254721Semaste if (result.Succeeded()) 1397254721Semaste { 1398254721Semaste for (size_t i = 0; i < valid_bp_ids.GetSize(); ++i) 1399254721Semaste { 1400254721Semaste BreakpointID cur_bp_id = valid_bp_ids.GetBreakpointIDAtIndex (i); 1401254721Semaste Breakpoint *breakpoint = target->GetBreakpointByID (cur_bp_id.GetBreakpointID()).get(); 1402254721Semaste AddBreakpointDescription (&output_stream, breakpoint, m_options.m_level); 1403254721Semaste } 1404254721Semaste result.SetStatus (eReturnStatusSuccessFinishNoResult); 1405254721Semaste } 1406254721Semaste else 1407254721Semaste { 1408254721Semaste result.AppendError ("Invalid breakpoint id."); 1409254721Semaste result.SetStatus (eReturnStatusFailed); 1410254721Semaste } 1411254721Semaste } 1412254721Semaste 1413254721Semaste return result.Succeeded(); 1414254721Semaste } 1415254721Semaste 1416254721Semasteprivate: 1417254721Semaste CommandOptions m_options; 1418254721Semaste}; 1419254721Semaste 1420254721Semaste#pragma mark List::CommandOptions 1421254721SemasteOptionDefinition 1422254721SemasteCommandObjectBreakpointList::CommandOptions::g_option_table[] = 1423254721Semaste{ 1424263363Semaste { LLDB_OPT_SET_ALL, false, "internal", 'i', OptionParser::eNoArgument, NULL, 0, eArgTypeNone, 1425254721Semaste "Show debugger internal breakpoints" }, 1426254721Semaste 1427263363Semaste { LLDB_OPT_SET_1, false, "brief", 'b', OptionParser::eNoArgument, NULL, 0, eArgTypeNone, 1428254721Semaste "Give a brief description of the breakpoint (no location info)."}, 1429254721Semaste 1430254721Semaste // FIXME: We need to add an "internal" command, and then add this sort of thing to it. 1431254721Semaste // But I need to see it for now, and don't want to wait. 1432263363Semaste { LLDB_OPT_SET_2, false, "full", 'f', OptionParser::eNoArgument, NULL, 0, eArgTypeNone, 1433254721Semaste "Give a full description of the breakpoint and its locations."}, 1434254721Semaste 1435263363Semaste { LLDB_OPT_SET_3, false, "verbose", 'v', OptionParser::eNoArgument, NULL, 0, eArgTypeNone, 1436254721Semaste "Explain everything we know about the breakpoint (for debugging debugger bugs)." }, 1437254721Semaste 1438254721Semaste { 0, false, NULL, 0, 0, NULL, 0, eArgTypeNone, NULL } 1439254721Semaste}; 1440254721Semaste 1441254721Semaste//------------------------------------------------------------------------- 1442254721Semaste// CommandObjectBreakpointClear 1443254721Semaste//------------------------------------------------------------------------- 1444254721Semaste#pragma mark Clear 1445254721Semaste 1446254721Semasteclass CommandObjectBreakpointClear : public CommandObjectParsed 1447254721Semaste{ 1448254721Semastepublic: 1449254721Semaste 1450254721Semaste typedef enum BreakpointClearType 1451254721Semaste { 1452254721Semaste eClearTypeInvalid, 1453254721Semaste eClearTypeFileAndLine 1454254721Semaste } BreakpointClearType; 1455254721Semaste 1456254721Semaste CommandObjectBreakpointClear (CommandInterpreter &interpreter) : 1457254721Semaste CommandObjectParsed (interpreter, 1458254721Semaste "breakpoint clear", 1459254721Semaste "Clears a breakpoint or set of breakpoints in the executable.", 1460254721Semaste "breakpoint clear <cmd-options>"), 1461254721Semaste m_options (interpreter) 1462254721Semaste { 1463254721Semaste } 1464254721Semaste 1465254721Semaste virtual 1466254721Semaste ~CommandObjectBreakpointClear () {} 1467254721Semaste 1468254721Semaste virtual Options * 1469254721Semaste GetOptions () 1470254721Semaste { 1471254721Semaste return &m_options; 1472254721Semaste } 1473254721Semaste 1474254721Semaste class CommandOptions : public Options 1475254721Semaste { 1476254721Semaste public: 1477254721Semaste 1478254721Semaste CommandOptions (CommandInterpreter &interpreter) : 1479254721Semaste Options (interpreter), 1480254721Semaste m_filename (), 1481254721Semaste m_line_num (0) 1482254721Semaste { 1483254721Semaste } 1484254721Semaste 1485254721Semaste virtual 1486254721Semaste ~CommandOptions () {} 1487254721Semaste 1488254721Semaste virtual Error 1489254721Semaste SetOptionValue (uint32_t option_idx, const char *option_arg) 1490254721Semaste { 1491254721Semaste Error error; 1492254721Semaste const int short_option = m_getopt_table[option_idx].val; 1493254721Semaste 1494254721Semaste switch (short_option) 1495254721Semaste { 1496254721Semaste case 'f': 1497254721Semaste m_filename.assign (option_arg); 1498254721Semaste break; 1499254721Semaste 1500254721Semaste case 'l': 1501254721Semaste m_line_num = Args::StringToUInt32 (option_arg, 0); 1502254721Semaste break; 1503254721Semaste 1504254721Semaste default: 1505254721Semaste error.SetErrorStringWithFormat ("unrecognized option '%c'", short_option); 1506254721Semaste break; 1507254721Semaste } 1508254721Semaste 1509254721Semaste return error; 1510254721Semaste } 1511254721Semaste 1512254721Semaste void 1513254721Semaste OptionParsingStarting () 1514254721Semaste { 1515254721Semaste m_filename.clear(); 1516254721Semaste m_line_num = 0; 1517254721Semaste } 1518254721Semaste 1519254721Semaste const OptionDefinition* 1520254721Semaste GetDefinitions () 1521254721Semaste { 1522254721Semaste return g_option_table; 1523254721Semaste } 1524254721Semaste 1525254721Semaste // Options table: Required for subclasses of Options. 1526254721Semaste 1527254721Semaste static OptionDefinition g_option_table[]; 1528254721Semaste 1529254721Semaste // Instance variables to hold the values for command options. 1530254721Semaste 1531254721Semaste std::string m_filename; 1532254721Semaste uint32_t m_line_num; 1533254721Semaste 1534254721Semaste }; 1535254721Semaste 1536254721Semasteprotected: 1537254721Semaste virtual bool 1538254721Semaste DoExecute (Args& command, CommandReturnObject &result) 1539254721Semaste { 1540254721Semaste Target *target = m_interpreter.GetDebugger().GetSelectedTarget().get(); 1541254721Semaste if (target == NULL) 1542254721Semaste { 1543254721Semaste result.AppendError ("Invalid target. No existing target or breakpoints."); 1544254721Semaste result.SetStatus (eReturnStatusFailed); 1545254721Semaste return false; 1546254721Semaste } 1547254721Semaste 1548254721Semaste // The following are the various types of breakpoints that could be cleared: 1549254721Semaste // 1). -f -l (clearing breakpoint by source location) 1550254721Semaste 1551254721Semaste BreakpointClearType break_type = eClearTypeInvalid; 1552254721Semaste 1553254721Semaste if (m_options.m_line_num != 0) 1554254721Semaste break_type = eClearTypeFileAndLine; 1555254721Semaste 1556254721Semaste Mutex::Locker locker; 1557254721Semaste target->GetBreakpointList().GetListMutex(locker); 1558254721Semaste 1559254721Semaste BreakpointList &breakpoints = target->GetBreakpointList(); 1560254721Semaste size_t num_breakpoints = breakpoints.GetSize(); 1561254721Semaste 1562254721Semaste // Early return if there's no breakpoint at all. 1563254721Semaste if (num_breakpoints == 0) 1564254721Semaste { 1565254721Semaste result.AppendError ("Breakpoint clear: No breakpoint cleared."); 1566254721Semaste result.SetStatus (eReturnStatusFailed); 1567254721Semaste return result.Succeeded(); 1568254721Semaste } 1569254721Semaste 1570254721Semaste // Find matching breakpoints and delete them. 1571254721Semaste 1572254721Semaste // First create a copy of all the IDs. 1573254721Semaste std::vector<break_id_t> BreakIDs; 1574254721Semaste for (size_t i = 0; i < num_breakpoints; ++i) 1575254721Semaste BreakIDs.push_back(breakpoints.GetBreakpointAtIndex(i).get()->GetID()); 1576254721Semaste 1577254721Semaste int num_cleared = 0; 1578254721Semaste StreamString ss; 1579254721Semaste switch (break_type) 1580254721Semaste { 1581254721Semaste case eClearTypeFileAndLine: // Breakpoint by source position 1582254721Semaste { 1583254721Semaste const ConstString filename(m_options.m_filename.c_str()); 1584254721Semaste BreakpointLocationCollection loc_coll; 1585254721Semaste 1586254721Semaste for (size_t i = 0; i < num_breakpoints; ++i) 1587254721Semaste { 1588254721Semaste Breakpoint *bp = breakpoints.FindBreakpointByID(BreakIDs[i]).get(); 1589254721Semaste 1590254721Semaste if (bp->GetMatchingFileLine(filename, m_options.m_line_num, loc_coll)) 1591254721Semaste { 1592254721Semaste // If the collection size is 0, it's a full match and we can just remove the breakpoint. 1593254721Semaste if (loc_coll.GetSize() == 0) 1594254721Semaste { 1595254721Semaste bp->GetDescription(&ss, lldb::eDescriptionLevelBrief); 1596254721Semaste ss.EOL(); 1597254721Semaste target->RemoveBreakpointByID (bp->GetID()); 1598254721Semaste ++num_cleared; 1599254721Semaste } 1600254721Semaste } 1601254721Semaste } 1602254721Semaste } 1603254721Semaste break; 1604254721Semaste 1605254721Semaste default: 1606254721Semaste break; 1607254721Semaste } 1608254721Semaste 1609254721Semaste if (num_cleared > 0) 1610254721Semaste { 1611254721Semaste Stream &output_stream = result.GetOutputStream(); 1612254721Semaste output_stream.Printf ("%d breakpoints cleared:\n", num_cleared); 1613254721Semaste output_stream << ss.GetData(); 1614254721Semaste output_stream.EOL(); 1615254721Semaste result.SetStatus (eReturnStatusSuccessFinishNoResult); 1616254721Semaste } 1617254721Semaste else 1618254721Semaste { 1619254721Semaste result.AppendError ("Breakpoint clear: No breakpoint cleared."); 1620254721Semaste result.SetStatus (eReturnStatusFailed); 1621254721Semaste } 1622254721Semaste 1623254721Semaste return result.Succeeded(); 1624254721Semaste } 1625254721Semaste 1626254721Semasteprivate: 1627254721Semaste CommandOptions m_options; 1628254721Semaste}; 1629254721Semaste 1630254721Semaste#pragma mark Clear::CommandOptions 1631254721Semaste 1632254721SemasteOptionDefinition 1633254721SemasteCommandObjectBreakpointClear::CommandOptions::g_option_table[] = 1634254721Semaste{ 1635263363Semaste { LLDB_OPT_SET_1, false, "file", 'f', OptionParser::eRequiredArgument, NULL, CommandCompletions::eSourceFileCompletion, eArgTypeFilename, 1636254721Semaste "Specify the breakpoint by source location in this particular file."}, 1637254721Semaste 1638263363Semaste { LLDB_OPT_SET_1, true, "line", 'l', OptionParser::eRequiredArgument, NULL, 0, eArgTypeLineNum, 1639254721Semaste "Specify the breakpoint by source location at this particular line."}, 1640254721Semaste 1641254721Semaste { 0, false, NULL, 0, 0, NULL, 0, eArgTypeNone, NULL } 1642254721Semaste}; 1643254721Semaste 1644254721Semaste//------------------------------------------------------------------------- 1645254721Semaste// CommandObjectBreakpointDelete 1646254721Semaste//------------------------------------------------------------------------- 1647254721Semaste#pragma mark Delete 1648254721Semaste 1649254721Semasteclass CommandObjectBreakpointDelete : public CommandObjectParsed 1650254721Semaste{ 1651254721Semastepublic: 1652254721Semaste CommandObjectBreakpointDelete (CommandInterpreter &interpreter) : 1653254721Semaste CommandObjectParsed (interpreter, 1654254721Semaste "breakpoint delete", 1655254721Semaste "Delete the specified breakpoint(s). If no breakpoints are specified, delete them all.", 1656254721Semaste NULL) 1657254721Semaste { 1658254721Semaste CommandArgumentEntry arg; 1659254721Semaste CommandObject::AddIDsArgumentData(arg, eArgTypeBreakpointID, eArgTypeBreakpointIDRange); 1660254721Semaste // Add the entry for the first argument for this command to the object's arguments vector. 1661254721Semaste m_arguments.push_back (arg); 1662254721Semaste } 1663254721Semaste 1664254721Semaste virtual 1665254721Semaste ~CommandObjectBreakpointDelete () {} 1666254721Semaste 1667254721Semasteprotected: 1668254721Semaste virtual bool 1669254721Semaste DoExecute (Args& command, CommandReturnObject &result) 1670254721Semaste { 1671254721Semaste Target *target = m_interpreter.GetDebugger().GetSelectedTarget().get(); 1672254721Semaste if (target == NULL) 1673254721Semaste { 1674254721Semaste result.AppendError ("Invalid target. No existing target or breakpoints."); 1675254721Semaste result.SetStatus (eReturnStatusFailed); 1676254721Semaste return false; 1677254721Semaste } 1678254721Semaste 1679254721Semaste Mutex::Locker locker; 1680254721Semaste target->GetBreakpointList().GetListMutex(locker); 1681254721Semaste 1682254721Semaste const BreakpointList &breakpoints = target->GetBreakpointList(); 1683254721Semaste 1684254721Semaste size_t num_breakpoints = breakpoints.GetSize(); 1685254721Semaste 1686254721Semaste if (num_breakpoints == 0) 1687254721Semaste { 1688254721Semaste result.AppendError ("No breakpoints exist to be deleted."); 1689254721Semaste result.SetStatus (eReturnStatusFailed); 1690254721Semaste return false; 1691254721Semaste } 1692254721Semaste 1693254721Semaste if (command.GetArgumentCount() == 0) 1694254721Semaste { 1695254721Semaste if (!m_interpreter.Confirm ("About to delete all breakpoints, do you want to do that?", true)) 1696254721Semaste { 1697254721Semaste result.AppendMessage("Operation cancelled..."); 1698254721Semaste } 1699254721Semaste else 1700254721Semaste { 1701254721Semaste target->RemoveAllBreakpoints (); 1702263363Semaste result.AppendMessageWithFormat ("All breakpoints removed. (%zu %s)\n", num_breakpoints, num_breakpoints > 1 ? "breakpoints" : "breakpoint"); 1703254721Semaste } 1704254721Semaste result.SetStatus (eReturnStatusSuccessFinishNoResult); 1705254721Semaste } 1706254721Semaste else 1707254721Semaste { 1708254721Semaste // Particular breakpoint selected; disable that breakpoint. 1709254721Semaste BreakpointIDList valid_bp_ids; 1710254721Semaste CommandObjectMultiwordBreakpoint::VerifyBreakpointIDs (command, target, result, &valid_bp_ids); 1711254721Semaste 1712254721Semaste if (result.Succeeded()) 1713254721Semaste { 1714254721Semaste int delete_count = 0; 1715254721Semaste int disable_count = 0; 1716254721Semaste const size_t count = valid_bp_ids.GetSize(); 1717254721Semaste for (size_t i = 0; i < count; ++i) 1718254721Semaste { 1719254721Semaste BreakpointID cur_bp_id = valid_bp_ids.GetBreakpointIDAtIndex (i); 1720254721Semaste 1721254721Semaste if (cur_bp_id.GetBreakpointID() != LLDB_INVALID_BREAK_ID) 1722254721Semaste { 1723254721Semaste if (cur_bp_id.GetLocationID() != LLDB_INVALID_BREAK_ID) 1724254721Semaste { 1725254721Semaste Breakpoint *breakpoint = target->GetBreakpointByID (cur_bp_id.GetBreakpointID()).get(); 1726254721Semaste BreakpointLocation *location = breakpoint->FindLocationByID (cur_bp_id.GetLocationID()).get(); 1727254721Semaste // It makes no sense to try to delete individual locations, so we disable them instead. 1728254721Semaste if (location) 1729254721Semaste { 1730254721Semaste location->SetEnabled (false); 1731254721Semaste ++disable_count; 1732254721Semaste } 1733254721Semaste } 1734254721Semaste else 1735254721Semaste { 1736254721Semaste target->RemoveBreakpointByID (cur_bp_id.GetBreakpointID()); 1737254721Semaste ++delete_count; 1738254721Semaste } 1739254721Semaste } 1740254721Semaste } 1741254721Semaste result.AppendMessageWithFormat ("%d breakpoints deleted; %d breakpoint locations disabled.\n", 1742254721Semaste delete_count, disable_count); 1743254721Semaste result.SetStatus (eReturnStatusSuccessFinishNoResult); 1744254721Semaste } 1745254721Semaste } 1746254721Semaste return result.Succeeded(); 1747254721Semaste } 1748254721Semaste}; 1749254721Semaste 1750254721Semaste//------------------------------------------------------------------------- 1751254721Semaste// CommandObjectMultiwordBreakpoint 1752254721Semaste//------------------------------------------------------------------------- 1753254721Semaste#pragma mark MultiwordBreakpoint 1754254721Semaste 1755254721SemasteCommandObjectMultiwordBreakpoint::CommandObjectMultiwordBreakpoint (CommandInterpreter &interpreter) : 1756254721Semaste CommandObjectMultiword (interpreter, 1757254721Semaste "breakpoint", 1758254721Semaste "A set of commands for operating on breakpoints. Also see _regexp-break.", 1759254721Semaste "breakpoint <command> [<command-options>]") 1760254721Semaste{ 1761254721Semaste CommandObjectSP list_command_object (new CommandObjectBreakpointList (interpreter)); 1762254721Semaste CommandObjectSP enable_command_object (new CommandObjectBreakpointEnable (interpreter)); 1763254721Semaste CommandObjectSP disable_command_object (new CommandObjectBreakpointDisable (interpreter)); 1764254721Semaste CommandObjectSP clear_command_object (new CommandObjectBreakpointClear (interpreter)); 1765254721Semaste CommandObjectSP delete_command_object (new CommandObjectBreakpointDelete (interpreter)); 1766254721Semaste CommandObjectSP set_command_object (new CommandObjectBreakpointSet (interpreter)); 1767254721Semaste CommandObjectSP command_command_object (new CommandObjectBreakpointCommand (interpreter)); 1768254721Semaste CommandObjectSP modify_command_object (new CommandObjectBreakpointModify(interpreter)); 1769254721Semaste 1770254721Semaste list_command_object->SetCommandName ("breakpoint list"); 1771254721Semaste enable_command_object->SetCommandName("breakpoint enable"); 1772254721Semaste disable_command_object->SetCommandName("breakpoint disable"); 1773254721Semaste clear_command_object->SetCommandName("breakpoint clear"); 1774254721Semaste delete_command_object->SetCommandName("breakpoint delete"); 1775254721Semaste set_command_object->SetCommandName("breakpoint set"); 1776254721Semaste command_command_object->SetCommandName ("breakpoint command"); 1777254721Semaste modify_command_object->SetCommandName ("breakpoint modify"); 1778254721Semaste 1779254721Semaste LoadSubCommand ("list", list_command_object); 1780254721Semaste LoadSubCommand ("enable", enable_command_object); 1781254721Semaste LoadSubCommand ("disable", disable_command_object); 1782254721Semaste LoadSubCommand ("clear", clear_command_object); 1783254721Semaste LoadSubCommand ("delete", delete_command_object); 1784254721Semaste LoadSubCommand ("set", set_command_object); 1785254721Semaste LoadSubCommand ("command", command_command_object); 1786254721Semaste LoadSubCommand ("modify", modify_command_object); 1787254721Semaste} 1788254721Semaste 1789254721SemasteCommandObjectMultiwordBreakpoint::~CommandObjectMultiwordBreakpoint () 1790254721Semaste{ 1791254721Semaste} 1792254721Semaste 1793254721Semastevoid 1794254721SemasteCommandObjectMultiwordBreakpoint::VerifyBreakpointIDs (Args &args, Target *target, CommandReturnObject &result, 1795254721Semaste BreakpointIDList *valid_ids) 1796254721Semaste{ 1797254721Semaste // args can be strings representing 1). integers (for breakpoint ids) 1798254721Semaste // 2). the full breakpoint & location canonical representation 1799254721Semaste // 3). the word "to" or a hyphen, representing a range (in which case there 1800254721Semaste // had *better* be an entry both before & after of one of the first two types. 1801254721Semaste // If args is empty, we will use the last created breakpoint (if there is one.) 1802254721Semaste 1803254721Semaste Args temp_args; 1804254721Semaste 1805254721Semaste if (args.GetArgumentCount() == 0) 1806254721Semaste { 1807254721Semaste if (target->GetLastCreatedBreakpoint()) 1808254721Semaste { 1809254721Semaste valid_ids->AddBreakpointID (BreakpointID(target->GetLastCreatedBreakpoint()->GetID(), LLDB_INVALID_BREAK_ID)); 1810254721Semaste result.SetStatus (eReturnStatusSuccessFinishNoResult); 1811254721Semaste } 1812254721Semaste else 1813254721Semaste { 1814254721Semaste result.AppendError("No breakpoint specified and no last created breakpoint."); 1815254721Semaste result.SetStatus (eReturnStatusFailed); 1816254721Semaste } 1817254721Semaste return; 1818254721Semaste } 1819254721Semaste 1820254721Semaste // Create a new Args variable to use; copy any non-breakpoint-id-ranges stuff directly from the old ARGS to 1821254721Semaste // the new TEMP_ARGS. Do not copy breakpoint id range strings over; instead generate a list of strings for 1822254721Semaste // all the breakpoint ids in the range, and shove all of those breakpoint id strings into TEMP_ARGS. 1823254721Semaste 1824254721Semaste BreakpointIDList::FindAndReplaceIDRanges (args, target, result, temp_args); 1825254721Semaste 1826254721Semaste // NOW, convert the list of breakpoint id strings in TEMP_ARGS into an actual BreakpointIDList: 1827254721Semaste 1828254721Semaste valid_ids->InsertStringArray (temp_args.GetConstArgumentVector(), temp_args.GetArgumentCount(), result); 1829254721Semaste 1830254721Semaste // At this point, all of the breakpoint ids that the user passed in have been converted to breakpoint IDs 1831254721Semaste // and put into valid_ids. 1832254721Semaste 1833254721Semaste if (result.Succeeded()) 1834254721Semaste { 1835254721Semaste // Now that we've converted everything from args into a list of breakpoint ids, go through our tentative list 1836254721Semaste // of breakpoint id's and verify that they correspond to valid/currently set breakpoints. 1837254721Semaste 1838254721Semaste const size_t count = valid_ids->GetSize(); 1839254721Semaste for (size_t i = 0; i < count; ++i) 1840254721Semaste { 1841254721Semaste BreakpointID cur_bp_id = valid_ids->GetBreakpointIDAtIndex (i); 1842254721Semaste Breakpoint *breakpoint = target->GetBreakpointByID (cur_bp_id.GetBreakpointID()).get(); 1843254721Semaste if (breakpoint != NULL) 1844254721Semaste { 1845254721Semaste const size_t num_locations = breakpoint->GetNumLocations(); 1846254721Semaste if (cur_bp_id.GetLocationID() > num_locations) 1847254721Semaste { 1848254721Semaste StreamString id_str; 1849254721Semaste BreakpointID::GetCanonicalReference (&id_str, 1850254721Semaste cur_bp_id.GetBreakpointID(), 1851254721Semaste cur_bp_id.GetLocationID()); 1852254721Semaste i = valid_ids->GetSize() + 1; 1853254721Semaste result.AppendErrorWithFormat ("'%s' is not a currently valid breakpoint/location id.\n", 1854254721Semaste id_str.GetData()); 1855254721Semaste result.SetStatus (eReturnStatusFailed); 1856254721Semaste } 1857254721Semaste } 1858254721Semaste else 1859254721Semaste { 1860254721Semaste i = valid_ids->GetSize() + 1; 1861254721Semaste result.AppendErrorWithFormat ("'%d' is not a currently valid breakpoint id.\n", cur_bp_id.GetBreakpointID()); 1862254721Semaste result.SetStatus (eReturnStatusFailed); 1863254721Semaste } 1864254721Semaste } 1865254721Semaste } 1866254721Semaste} 1867