summaryrefslogtreecommitdiffstats
path: root/contrib/llvm/tools/lldb/source/Commands/CommandObjectBreakpoint.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'contrib/llvm/tools/lldb/source/Commands/CommandObjectBreakpoint.cpp')
-rw-r--r--contrib/llvm/tools/lldb/source/Commands/CommandObjectBreakpoint.cpp4301
1 files changed, 2127 insertions, 2174 deletions
diff --git a/contrib/llvm/tools/lldb/source/Commands/CommandObjectBreakpoint.cpp b/contrib/llvm/tools/lldb/source/Commands/CommandObjectBreakpoint.cpp
index 6a71389..941dd9a 100644
--- a/contrib/llvm/tools/lldb/source/Commands/CommandObjectBreakpoint.cpp
+++ b/contrib/llvm/tools/lldb/source/Commands/CommandObjectBreakpoint.cpp
@@ -18,1174 +18,1033 @@
#include "lldb/Breakpoint/Breakpoint.h"
#include "lldb/Breakpoint/BreakpointIDList.h"
#include "lldb/Breakpoint/BreakpointLocation.h"
-#include "lldb/Host/StringConvert.h"
-#include "lldb/Interpreter/Options.h"
-#include "lldb/Interpreter/OptionValueBoolean.h"
-#include "lldb/Interpreter/OptionValueString.h"
-#include "lldb/Interpreter/OptionValueUInt64.h"
#include "lldb/Core/RegularExpression.h"
#include "lldb/Core/StreamString.h"
+#include "lldb/Host/StringConvert.h"
+#include "lldb/Interpreter/CommandCompletions.h"
#include "lldb/Interpreter/CommandInterpreter.h"
#include "lldb/Interpreter/CommandReturnObject.h"
+#include "lldb/Interpreter/OptionValueBoolean.h"
+#include "lldb/Interpreter/OptionValueString.h"
+#include "lldb/Interpreter/OptionValueUInt64.h"
+#include "lldb/Interpreter/Options.h"
#include "lldb/Target/Language.h"
-#include "lldb/Target/Target.h"
-#include "lldb/Interpreter/CommandCompletions.h"
#include "lldb/Target/StackFrame.h"
+#include "lldb/Target/Target.h"
#include "lldb/Target/Thread.h"
#include "lldb/Target/ThreadSpec.h"
using namespace lldb;
using namespace lldb_private;
-static void
-AddBreakpointDescription (Stream *s, Breakpoint *bp, lldb::DescriptionLevel level)
-{
- s->IndentMore();
- bp->GetDescription (s, level, true);
- s->IndentLess();
- s->EOL();
+static void AddBreakpointDescription(Stream *s, Breakpoint *bp,
+ lldb::DescriptionLevel level) {
+ s->IndentMore();
+ bp->GetDescription(s, level, true);
+ s->IndentLess();
+ s->EOL();
}
+// If an additional option set beyond LLDB_OPTION_SET_10 is added, make sure to
+// update the numbers passed to LLDB_OPT_SET_FROM_TO(...) appropriately.
+#define LLDB_OPT_FILE (LLDB_OPT_SET_FROM_TO(1, 9) & ~LLDB_OPT_SET_2)
+#define LLDB_OPT_NOT_10 (LLDB_OPT_SET_FROM_TO(1, 10) & ~LLDB_OPT_SET_10)
+#define LLDB_OPT_SKIP_PROLOGUE (LLDB_OPT_SET_1 | LLDB_OPT_SET_FROM_TO(3, 8))
+#define LLDB_OPT_OFFSET_APPLIES (LLDB_OPT_SET_1 | LLDB_OPT_SET_FROM_TO(3, 8))
+#define LLDB_OPT_MOVE_TO_NEAREST_CODE (LLDB_OPT_SET_1 | LLDB_OPT_SET_9)
+#define LLDB_OPT_EXPR_LANGUAGE (LLDB_OPT_SET_FROM_TO(3, 8))
+
+static OptionDefinition g_breakpoint_set_options[] = {
+ // clang-format off
+ { LLDB_OPT_NOT_10, false, "shlib", 's', OptionParser::eRequiredArgument, nullptr, nullptr, CommandCompletions::eModuleCompletion, eArgTypeShlibName, "Set the breakpoint only in this shared library. Can repeat this option "
+ "multiple times to specify multiple shared libraries." },
+ { LLDB_OPT_SET_ALL, false, "ignore-count", 'i', OptionParser::eRequiredArgument, nullptr, nullptr, 0, eArgTypeCount, "Set the number of times this breakpoint is skipped before stopping." },
+ { LLDB_OPT_SET_ALL, false, "one-shot", 'o', OptionParser::eNoArgument, nullptr, nullptr, 0, eArgTypeNone, "The breakpoint is deleted the first time it causes a stop." },
+ { LLDB_OPT_SET_ALL, false, "condition", 'c', OptionParser::eRequiredArgument, nullptr, nullptr, 0, eArgTypeExpression, "The breakpoint stops only if this condition expression evaluates to true." },
+ { LLDB_OPT_SET_ALL, false, "thread-index", 'x', OptionParser::eRequiredArgument, nullptr, nullptr, 0, eArgTypeThreadIndex, "The breakpoint stops only for the thread whose indeX matches this argument." },
+ { LLDB_OPT_SET_ALL, false, "thread-id", 't', OptionParser::eRequiredArgument, nullptr, nullptr, 0, eArgTypeThreadID, "The breakpoint stops only for the thread whose TID matches this argument." },
+ { LLDB_OPT_SET_ALL, false, "thread-name", 'T', OptionParser::eRequiredArgument, nullptr, nullptr, 0, eArgTypeThreadName, "The breakpoint stops only for the thread whose thread name matches this "
+ "argument." },
+ { LLDB_OPT_SET_ALL, false, "hardware", 'H', OptionParser::eNoArgument, nullptr, nullptr, 0, eArgTypeNone, "Require the breakpoint to use hardware breakpoints." },
+ { LLDB_OPT_SET_ALL, false, "queue-name", 'q', OptionParser::eRequiredArgument, nullptr, nullptr, 0, eArgTypeQueueName, "The breakpoint stops only for threads in the queue whose name is given by "
+ "this argument." },
+ { LLDB_OPT_FILE, false, "file", 'f', OptionParser::eRequiredArgument, nullptr, nullptr, CommandCompletions::eSourceFileCompletion, eArgTypeFilename, "Specifies the source file in which to set this breakpoint. Note, by default "
+ "lldb only looks for files that are #included if they use the standard include "
+ "file extensions. To set breakpoints on .c/.cpp/.m/.mm files that are "
+ "#included, set target.inline-breakpoint-strategy to \"always\"." },
+ { LLDB_OPT_SET_1, true, "line", 'l', OptionParser::eRequiredArgument, nullptr, nullptr, 0, eArgTypeLineNum, "Specifies the line number on which to set this breakpoint." },
+
+ // Comment out this option for the moment, as we don't actually use it, but will in the future.
+ // This way users won't see it, but the infrastructure is left in place.
+ // { 0, false, "column", 'C', OptionParser::eRequiredArgument, nullptr, "<column>",
+ // "Set the breakpoint by source location at this particular column."},
+
+ { LLDB_OPT_SET_2, true, "address", 'a', OptionParser::eRequiredArgument, nullptr, nullptr, 0, eArgTypeAddressOrExpression, "Set the breakpoint at the specified address. If the address maps uniquely to "
+ "a particular binary, then the address will be converted to a \"file\" "
+ "address, so that the breakpoint will track that binary+offset no matter where "
+ "the binary eventually loads. Alternately, if you also specify the module - "
+ "with the -s option - then the address will be treated as a file address in "
+ "that module, and resolved accordingly. Again, this will allow lldb to track "
+ "that offset on subsequent reloads. The module need not have been loaded at "
+ "the time you specify this breakpoint, and will get resolved when the module "
+ "is loaded." },
+ { LLDB_OPT_SET_3, true, "name", 'n', OptionParser::eRequiredArgument, nullptr, nullptr, CommandCompletions::eSymbolCompletion, eArgTypeFunctionName, "Set the breakpoint by function name. Can be repeated multiple times to make "
+ "one breakpoint for multiple names" },
+ { LLDB_OPT_SET_9, false, "source-regexp-function", 'X', OptionParser::eRequiredArgument, nullptr, nullptr, CommandCompletions::eSymbolCompletion, eArgTypeFunctionName, "When used with '-p' limits the source regex to source contained in the named "
+ "functions. Can be repeated multiple times." },
+ { LLDB_OPT_SET_4, true, "fullname", 'F', OptionParser::eRequiredArgument, nullptr, nullptr, CommandCompletions::eSymbolCompletion, eArgTypeFullName, "Set the breakpoint by fully qualified function names. For C++ this means "
+ "namespaces and all arguments, and for Objective C this means a full function "
+ "prototype with class and selector. Can be repeated multiple times to make "
+ "one breakpoint for multiple names." },
+ { LLDB_OPT_SET_5, true, "selector", 'S', OptionParser::eRequiredArgument, nullptr, nullptr, 0, eArgTypeSelector, "Set the breakpoint by ObjC selector name. Can be repeated multiple times to "
+ "make one breakpoint for multiple Selectors." },
+ { LLDB_OPT_SET_6, true, "method", 'M', OptionParser::eRequiredArgument, nullptr, nullptr, 0, eArgTypeMethod, "Set the breakpoint by C++ method names. Can be repeated multiple times to "
+ "make one breakpoint for multiple methods." },
+ { LLDB_OPT_SET_7, true, "func-regex", 'r', OptionParser::eRequiredArgument, nullptr, nullptr, 0, eArgTypeRegularExpression, "Set the breakpoint by function name, evaluating a regular-expression to find "
+ "the function name(s)." },
+ { LLDB_OPT_SET_8, true, "basename", 'b', OptionParser::eRequiredArgument, nullptr, nullptr, CommandCompletions::eSymbolCompletion, eArgTypeFunctionName, "Set the breakpoint by function basename (C++ namespaces and arguments will be "
+ "ignored). Can be repeated multiple times to make one breakpoint for multiple "
+ "symbols." },
+ { LLDB_OPT_SET_9, true, "source-pattern-regexp", 'p', OptionParser::eRequiredArgument, nullptr, nullptr, 0, eArgTypeRegularExpression, "Set the breakpoint by specifying a regular expression which is matched "
+ "against the source text in a source file or files specified with the -f "
+ "option. The -f option can be specified more than once. If no source files "
+ "are specified, uses the current \"default source file\". If you want to "
+ "match against all source files, pass the \"--all-files\" option." },
+ { LLDB_OPT_SET_9, false, "all-files", 'A', OptionParser::eNoArgument, nullptr, nullptr, 0, eArgTypeNone, "All files are searched for source pattern matches." },
+ { LLDB_OPT_SET_10, true, "language-exception", 'E', OptionParser::eRequiredArgument, nullptr, nullptr, 0, eArgTypeLanguage, "Set the breakpoint on exceptions thrown by the specified language (without "
+ "options, on throw but not catch.)" },
+ { LLDB_OPT_SET_10, false, "on-throw", 'w', OptionParser::eRequiredArgument, nullptr, nullptr, 0, eArgTypeBoolean, "Set the breakpoint on exception throW." },
+ { LLDB_OPT_SET_10, false, "on-catch", 'h', OptionParser::eRequiredArgument, nullptr, nullptr, 0, eArgTypeBoolean, "Set the breakpoint on exception catcH." },
+
+ // Don't add this option till it actually does something useful...
+ // { LLDB_OPT_SET_10, false, "exception-typename", 'O', OptionParser::eRequiredArgument, nullptr, nullptr, 0, eArgTypeTypeName,
+ // "The breakpoint will only stop if an exception Object of this type is thrown. Can be repeated multiple times to stop for multiple object types" },
+
+ { LLDB_OPT_EXPR_LANGUAGE, false, "language", 'L', OptionParser::eRequiredArgument, nullptr, nullptr, 0, eArgTypeLanguage, "Specifies the Language to use when interpreting the breakpoint's expression "
+ "(note: currently only implemented for setting breakpoints on identifiers). "
+ "If not set the target.language setting is used." },
+ { LLDB_OPT_SKIP_PROLOGUE, false, "skip-prologue", 'K', OptionParser::eRequiredArgument, nullptr, nullptr, 0, eArgTypeBoolean, "sKip the prologue if the breakpoint is at the beginning of a function. "
+ "If not set the target.skip-prologue setting is used." },
+ { LLDB_OPT_SET_ALL, false, "dummy-breakpoints", 'D', OptionParser::eNoArgument, nullptr, nullptr, 0, eArgTypeNone, "Sets Dummy breakpoints - i.e. breakpoints set before a file is provided, "
+ "which prime new targets." },
+ { LLDB_OPT_SET_ALL, false, "breakpoint-name", 'N', OptionParser::eRequiredArgument, nullptr, nullptr, 0, eArgTypeBreakpointName, "Adds this to the list of names for this breakpoint." },
+ { LLDB_OPT_OFFSET_APPLIES, false, "address-slide", 'R', OptionParser::eRequiredArgument, nullptr, nullptr, 0, eArgTypeAddress, "Add the specified offset to whatever address(es) the breakpoint resolves to. "
+ "At present this applies the offset directly as given, and doesn't try to align it to instruction boundaries." },
+ { LLDB_OPT_MOVE_TO_NEAREST_CODE, false, "move-to-nearest-code", 'm', OptionParser::eRequiredArgument, nullptr, nullptr, 0, eArgTypeBoolean, "Move breakpoints to nearest code. If not set the target.move-to-nearest-code "
+ "setting is used." },
+ // clang-format on
+};
+
//-------------------------------------------------------------------------
// CommandObjectBreakpointSet
//-------------------------------------------------------------------------
-class CommandObjectBreakpointSet : public CommandObjectParsed
-{
+class CommandObjectBreakpointSet : public CommandObjectParsed {
public:
- typedef enum BreakpointSetType
- {
- eSetTypeInvalid,
- eSetTypeFileAndLine,
- eSetTypeAddress,
- eSetTypeFunctionName,
- eSetTypeFunctionRegexp,
- eSetTypeSourceRegexp,
- eSetTypeException
- } BreakpointSetType;
-
- CommandObjectBreakpointSet (CommandInterpreter &interpreter) :
- CommandObjectParsed (interpreter,
- "breakpoint set",
- "Sets a breakpoint or set of breakpoints in the executable.",
- "breakpoint set <cmd-options>"),
- m_options (interpreter)
- {
+ typedef enum BreakpointSetType {
+ eSetTypeInvalid,
+ eSetTypeFileAndLine,
+ eSetTypeAddress,
+ eSetTypeFunctionName,
+ eSetTypeFunctionRegexp,
+ eSetTypeSourceRegexp,
+ eSetTypeException
+ } BreakpointSetType;
+
+ CommandObjectBreakpointSet(CommandInterpreter &interpreter)
+ : CommandObjectParsed(
+ interpreter, "breakpoint set",
+ "Sets a breakpoint or set of breakpoints in the executable.",
+ "breakpoint set <cmd-options>"),
+ m_options() {}
+
+ ~CommandObjectBreakpointSet() override = default;
+
+ Options *GetOptions() override { return &m_options; }
+
+ class CommandOptions : public Options {
+ public:
+ CommandOptions()
+ : Options(), m_condition(), m_filenames(), m_line_num(0), m_column(0),
+ m_func_names(), m_func_name_type_mask(eFunctionNameTypeNone),
+ m_func_regexp(), m_source_text_regexp(), m_modules(), m_load_addr(),
+ m_ignore_count(0), m_thread_id(LLDB_INVALID_THREAD_ID),
+ m_thread_index(UINT32_MAX), m_thread_name(), m_queue_name(),
+ m_catch_bp(false), m_throw_bp(true), m_hardware(false),
+ m_exception_language(eLanguageTypeUnknown),
+ m_language(lldb::eLanguageTypeUnknown),
+ m_skip_prologue(eLazyBoolCalculate), m_one_shot(false),
+ m_all_files(false), m_move_to_nearest_code(eLazyBoolCalculate) {}
+
+ ~CommandOptions() override = default;
+
+ Error SetOptionValue(uint32_t option_idx, llvm::StringRef option_arg,
+ ExecutionContext *execution_context) override {
+ Error error;
+ const int short_option = m_getopt_table[option_idx].val;
+
+ switch (short_option) {
+ case 'a': {
+ m_load_addr = Args::StringToAddress(execution_context, option_arg,
+ LLDB_INVALID_ADDRESS, &error);
+ } break;
+
+ case 'A':
+ m_all_files = true;
+ break;
+
+ case 'b':
+ m_func_names.push_back(option_arg);
+ m_func_name_type_mask |= eFunctionNameTypeBase;
+ break;
+
+ case 'C':
+ if (option_arg.getAsInteger(0, m_column))
+ error.SetErrorStringWithFormat("invalid column number: %s",
+ option_arg.str().c_str());
+ break;
+
+ case 'c':
+ m_condition.assign(option_arg);
+ break;
+
+ case 'D':
+ m_use_dummy = true;
+ break;
+
+ case 'E': {
+ LanguageType language = Language::GetLanguageTypeFromString(option_arg);
+
+ switch (language) {
+ case eLanguageTypeC89:
+ case eLanguageTypeC:
+ case eLanguageTypeC99:
+ case eLanguageTypeC11:
+ m_exception_language = eLanguageTypeC;
+ break;
+ case eLanguageTypeC_plus_plus:
+ case eLanguageTypeC_plus_plus_03:
+ case eLanguageTypeC_plus_plus_11:
+ case eLanguageTypeC_plus_plus_14:
+ m_exception_language = eLanguageTypeC_plus_plus;
+ break;
+ case eLanguageTypeObjC:
+ m_exception_language = eLanguageTypeObjC;
+ break;
+ case eLanguageTypeObjC_plus_plus:
+ error.SetErrorStringWithFormat(
+ "Set exception breakpoints separately for c++ and objective-c");
+ break;
+ case eLanguageTypeUnknown:
+ error.SetErrorStringWithFormat(
+ "Unknown language type: '%s' for exception breakpoint",
+ option_arg.str().c_str());
+ break;
+ default:
+ error.SetErrorStringWithFormat(
+ "Unsupported language type: '%s' for exception breakpoint",
+ option_arg.str().c_str());
+ }
+ } break;
+
+ case 'f':
+ m_filenames.AppendIfUnique(FileSpec(option_arg, false));
+ break;
+
+ case 'F':
+ m_func_names.push_back(option_arg);
+ m_func_name_type_mask |= eFunctionNameTypeFull;
+ break;
+
+ case 'h': {
+ bool success;
+ m_catch_bp = Args::StringToBoolean(option_arg, true, &success);
+ if (!success)
+ error.SetErrorStringWithFormat(
+ "Invalid boolean value for on-catch option: '%s'",
+ option_arg.str().c_str());
+ } break;
+
+ case 'H':
+ m_hardware = true;
+ break;
+
+ case 'i':
+ if (option_arg.getAsInteger(0, m_ignore_count))
+ error.SetErrorStringWithFormat("invalid ignore count '%s'",
+ option_arg.str().c_str());
+ break;
+
+ case 'K': {
+ bool success;
+ bool value;
+ value = Args::StringToBoolean(option_arg, true, &success);
+ if (value)
+ m_skip_prologue = eLazyBoolYes;
+ else
+ m_skip_prologue = eLazyBoolNo;
+
+ if (!success)
+ error.SetErrorStringWithFormat(
+ "Invalid boolean value for skip prologue option: '%s'",
+ option_arg.str().c_str());
+ } break;
+
+ case 'l':
+ if (option_arg.getAsInteger(0, m_line_num))
+ error.SetErrorStringWithFormat("invalid line number: %s.",
+ option_arg.str().c_str());
+ break;
+
+ case 'L':
+ m_language = Language::GetLanguageTypeFromString(option_arg);
+ if (m_language == eLanguageTypeUnknown)
+ error.SetErrorStringWithFormat(
+ "Unknown language type: '%s' for breakpoint",
+ option_arg.str().c_str());
+ break;
+
+ case 'm': {
+ bool success;
+ bool value;
+ value = Args::StringToBoolean(option_arg, true, &success);
+ if (value)
+ m_move_to_nearest_code = eLazyBoolYes;
+ else
+ m_move_to_nearest_code = eLazyBoolNo;
+
+ if (!success)
+ error.SetErrorStringWithFormat(
+ "Invalid boolean value for move-to-nearest-code option: '%s'",
+ option_arg.str().c_str());
+ break;
+ }
+
+ case 'M':
+ m_func_names.push_back(option_arg);
+ m_func_name_type_mask |= eFunctionNameTypeMethod;
+ break;
+
+ case 'n':
+ m_func_names.push_back(option_arg);
+ m_func_name_type_mask |= eFunctionNameTypeAuto;
+ break;
+
+ case 'N': {
+ if (BreakpointID::StringIsBreakpointName(option_arg, error))
+ m_breakpoint_names.push_back(option_arg);
+ else
+ error.SetErrorStringWithFormat("Invalid breakpoint name: %s",
+ option_arg.str().c_str());
+ break;
+ }
+
+ case 'R': {
+ lldb::addr_t tmp_offset_addr;
+ tmp_offset_addr =
+ Args::StringToAddress(execution_context, option_arg, 0, &error);
+ if (error.Success())
+ m_offset_addr = tmp_offset_addr;
+ } break;
+
+ case 'o':
+ m_one_shot = true;
+ break;
+
+ case 'O':
+ m_exception_extra_args.AppendArgument("-O");
+ m_exception_extra_args.AppendArgument(option_arg);
+ break;
+
+ case 'p':
+ m_source_text_regexp.assign(option_arg);
+ break;
+
+ case 'q':
+ m_queue_name.assign(option_arg);
+ break;
+
+ case 'r':
+ m_func_regexp.assign(option_arg);
+ break;
+
+ case 's':
+ m_modules.AppendIfUnique(FileSpec(option_arg, false));
+ break;
+
+ case 'S':
+ m_func_names.push_back(option_arg);
+ m_func_name_type_mask |= eFunctionNameTypeSelector;
+ break;
+
+ case 't':
+ if (option_arg.getAsInteger(0, m_thread_id))
+ error.SetErrorStringWithFormat("invalid thread id string '%s'",
+ option_arg.str().c_str());
+ break;
+
+ case 'T':
+ m_thread_name.assign(option_arg);
+ break;
+
+ case 'w': {
+ bool success;
+ m_throw_bp = Args::StringToBoolean(option_arg, true, &success);
+ if (!success)
+ error.SetErrorStringWithFormat(
+ "Invalid boolean value for on-throw option: '%s'",
+ option_arg.str().c_str());
+ } break;
+
+ case 'x':
+ if (option_arg.getAsInteger(0, m_thread_index))
+ error.SetErrorStringWithFormat("invalid thread index string '%s'",
+ option_arg.str().c_str());
+ break;
+
+ case 'X':
+ m_source_regex_func_names.insert(option_arg);
+ break;
+
+ default:
+ error.SetErrorStringWithFormat("unrecognized option '%c'",
+ short_option);
+ break;
+ }
+
+ return error;
}
- ~CommandObjectBreakpointSet() override = default;
-
- Options *
- GetOptions () override
- {
- return &m_options;
+ void OptionParsingStarting(ExecutionContext *execution_context) override {
+ m_condition.clear();
+ m_filenames.Clear();
+ m_line_num = 0;
+ m_column = 0;
+ m_func_names.clear();
+ m_func_name_type_mask = eFunctionNameTypeNone;
+ m_func_regexp.clear();
+ m_source_text_regexp.clear();
+ m_modules.Clear();
+ m_load_addr = LLDB_INVALID_ADDRESS;
+ m_offset_addr = 0;
+ m_ignore_count = 0;
+ m_thread_id = LLDB_INVALID_THREAD_ID;
+ m_thread_index = UINT32_MAX;
+ m_thread_name.clear();
+ m_queue_name.clear();
+ m_catch_bp = false;
+ m_throw_bp = true;
+ m_hardware = false;
+ m_exception_language = eLanguageTypeUnknown;
+ m_language = lldb::eLanguageTypeUnknown;
+ m_skip_prologue = eLazyBoolCalculate;
+ m_one_shot = false;
+ m_use_dummy = false;
+ m_breakpoint_names.clear();
+ m_all_files = false;
+ m_exception_extra_args.Clear();
+ m_move_to_nearest_code = eLazyBoolCalculate;
+ m_source_regex_func_names.clear();
}
- class CommandOptions : public Options
- {
- public:
- CommandOptions (CommandInterpreter &interpreter) :
- Options (interpreter),
- m_condition (),
- m_filenames (),
- m_line_num (0),
- m_column (0),
- m_func_names (),
- m_func_name_type_mask (eFunctionNameTypeNone),
- m_func_regexp (),
- m_source_text_regexp(),
- m_modules (),
- m_load_addr(),
- m_ignore_count (0),
- m_thread_id(LLDB_INVALID_THREAD_ID),
- m_thread_index (UINT32_MAX),
- m_thread_name(),
- m_queue_name(),
- m_catch_bp (false),
- m_throw_bp (true),
- m_hardware (false),
- m_exception_language (eLanguageTypeUnknown),
- m_language (lldb::eLanguageTypeUnknown),
- m_skip_prologue (eLazyBoolCalculate),
- m_one_shot (false),
- m_all_files (false),
- m_move_to_nearest_code (eLazyBoolCalculate)
- {
- }
-
- ~CommandOptions() override = default;
-
- Error
- SetOptionValue (uint32_t option_idx, const char *option_arg) override
- {
- Error error;
- const int short_option = m_getopt_table[option_idx].val;
-
- switch (short_option)
- {
- case 'a':
- {
- ExecutionContext exe_ctx (m_interpreter.GetExecutionContext());
- m_load_addr = Args::StringToAddress(&exe_ctx, option_arg, LLDB_INVALID_ADDRESS, &error);
- }
- break;
-
- case 'A':
- m_all_files = true;
- break;
-
- case 'b':
- m_func_names.push_back (option_arg);
- m_func_name_type_mask |= eFunctionNameTypeBase;
- break;
-
- case 'C':
- {
- bool success;
- m_column = StringConvert::ToUInt32 (option_arg, 0, 0, &success);
- if (!success)
- error.SetErrorStringWithFormat("invalid column number: %s", option_arg);
- break;
- }
-
- case 'c':
- m_condition.assign(option_arg);
- break;
-
- case 'D':
- m_use_dummy = true;
- break;
-
- case 'E':
- {
- LanguageType language = Language::GetLanguageTypeFromString (option_arg);
-
- switch (language)
- {
- case eLanguageTypeC89:
- case eLanguageTypeC:
- case eLanguageTypeC99:
- case eLanguageTypeC11:
- m_exception_language = eLanguageTypeC;
- break;
- case eLanguageTypeC_plus_plus:
- case eLanguageTypeC_plus_plus_03:
- case eLanguageTypeC_plus_plus_11:
- case eLanguageTypeC_plus_plus_14:
- m_exception_language = eLanguageTypeC_plus_plus;
- break;
- case eLanguageTypeObjC:
- m_exception_language = eLanguageTypeObjC;
- break;
- case eLanguageTypeObjC_plus_plus:
- error.SetErrorStringWithFormat ("Set exception breakpoints separately for c++ and objective-c");
- break;
- case eLanguageTypeUnknown:
- error.SetErrorStringWithFormat ("Unknown language type: '%s' for exception breakpoint", option_arg);
- break;
- default:
- error.SetErrorStringWithFormat ("Unsupported language type: '%s' for exception breakpoint", option_arg);
- }
- }
- break;
-
- case 'f':
- m_filenames.AppendIfUnique (FileSpec(option_arg, false));
- break;
-
- case 'F':
- m_func_names.push_back (option_arg);
- m_func_name_type_mask |= eFunctionNameTypeFull;
- break;
-
- case 'h':
- {
- bool success;
- m_catch_bp = Args::StringToBoolean (option_arg, true, &success);
- if (!success)
- error.SetErrorStringWithFormat ("Invalid boolean value for on-catch option: '%s'", option_arg);
- }
- break;
-
- case 'H':
- m_hardware = true;
- break;
-
- case 'i':
- m_ignore_count = StringConvert::ToUInt32(option_arg, UINT32_MAX, 0);
- if (m_ignore_count == UINT32_MAX)
- error.SetErrorStringWithFormat ("invalid ignore count '%s'", option_arg);
- break;
-
- case 'K':
- {
- bool success;
- bool value;
- value = Args::StringToBoolean (option_arg, true, &success);
- if (value)
- m_skip_prologue = eLazyBoolYes;
- else
- m_skip_prologue = eLazyBoolNo;
-
- if (!success)
- error.SetErrorStringWithFormat ("Invalid boolean value for skip prologue option: '%s'", option_arg);
- }
- break;
-
- case 'l':
- {
- bool success;
- m_line_num = StringConvert::ToUInt32 (option_arg, 0, 0, &success);
- if (!success)
- error.SetErrorStringWithFormat ("invalid line number: %s.", option_arg);
- break;
- }
-
- case 'L':
- m_language = Language::GetLanguageTypeFromString (option_arg);
- if (m_language == eLanguageTypeUnknown)
- error.SetErrorStringWithFormat ("Unknown language type: '%s' for breakpoint", option_arg);
- break;
-
- case 'm':
- {
- bool success;
- bool value;
- value = Args::StringToBoolean (option_arg, true, &success);
- if (value)
- m_move_to_nearest_code = eLazyBoolYes;
- else
- m_move_to_nearest_code = eLazyBoolNo;
-
- if (!success)
- error.SetErrorStringWithFormat ("Invalid boolean value for move-to-nearest-code option: '%s'", option_arg);
- break;
- }
-
- case 'M':
- m_func_names.push_back (option_arg);
- m_func_name_type_mask |= eFunctionNameTypeMethod;
- break;
-
- case 'n':
- m_func_names.push_back (option_arg);
- m_func_name_type_mask |= eFunctionNameTypeAuto;
- break;
-
- case 'N':
- if (BreakpointID::StringIsBreakpointName(option_arg, error))
- m_breakpoint_names.push_back (option_arg);
- break;
-
- case 'R':
- {
- ExecutionContext exe_ctx (m_interpreter.GetExecutionContext());
- lldb::addr_t tmp_offset_addr;
- tmp_offset_addr = Args::StringToAddress(&exe_ctx, option_arg, 0, &error);
- if (error.Success())
- m_offset_addr = tmp_offset_addr;
- }
- break;
-
- case 'o':
- m_one_shot = true;
- break;
-
- case 'O':
- m_exception_extra_args.AppendArgument ("-O");
- m_exception_extra_args.AppendArgument (option_arg);
- break;
-
- case 'p':
- m_source_text_regexp.assign (option_arg);
- break;
-
- case 'q':
- m_queue_name.assign (option_arg);
- break;
-
- case 'r':
- m_func_regexp.assign (option_arg);
- break;
-
- case 's':
- m_modules.AppendIfUnique (FileSpec (option_arg, false));
- break;
-
- case 'S':
- m_func_names.push_back (option_arg);
- m_func_name_type_mask |= eFunctionNameTypeSelector;
- break;
-
- case 't' :
- m_thread_id = StringConvert::ToUInt64(option_arg, LLDB_INVALID_THREAD_ID, 0);
- if (m_thread_id == LLDB_INVALID_THREAD_ID)
- error.SetErrorStringWithFormat ("invalid thread id string '%s'", option_arg);
- break;
-
- case 'T':
- m_thread_name.assign (option_arg);
- break;
-
- case 'w':
- {
- bool success;
- m_throw_bp = Args::StringToBoolean (option_arg, true, &success);
- if (!success)
- error.SetErrorStringWithFormat ("Invalid boolean value for on-throw option: '%s'", option_arg);
- }
- break;
-
- case 'x':
- m_thread_index = StringConvert::ToUInt32(option_arg, UINT32_MAX, 0);
- if (m_thread_id == UINT32_MAX)
- error.SetErrorStringWithFormat ("invalid thread index string '%s'", option_arg);
- break;
-
- case 'X':
- m_source_regex_func_names.insert(option_arg);
- break;
-
- default:
- error.SetErrorStringWithFormat ("unrecognized option '%c'", short_option);
- break;
- }
-
- return error;
- }
-
- void
- OptionParsingStarting () override
- {
- m_condition.clear();
- m_filenames.Clear();
- m_line_num = 0;
- m_column = 0;
- m_func_names.clear();
- m_func_name_type_mask = eFunctionNameTypeNone;
- m_func_regexp.clear();
- m_source_text_regexp.clear();
- m_modules.Clear();
- m_load_addr = LLDB_INVALID_ADDRESS;
- m_offset_addr = 0;
- m_ignore_count = 0;
- m_thread_id = LLDB_INVALID_THREAD_ID;
- m_thread_index = UINT32_MAX;
- m_thread_name.clear();
- m_queue_name.clear();
- m_catch_bp = false;
- m_throw_bp = true;
- m_hardware = false;
- m_exception_language = eLanguageTypeUnknown;
- m_language = lldb::eLanguageTypeUnknown;
- m_skip_prologue = eLazyBoolCalculate;
- m_one_shot = false;
- m_use_dummy = false;
- m_breakpoint_names.clear();
- m_all_files = false;
- m_exception_extra_args.Clear();
- m_move_to_nearest_code = eLazyBoolCalculate;
- m_source_regex_func_names.clear();
- }
-
- const OptionDefinition*
- GetDefinitions () override
- {
- return g_option_table;
- }
+ llvm::ArrayRef<OptionDefinition> GetDefinitions() override {
+ return llvm::makeArrayRef(g_breakpoint_set_options);
+ }
- // Options table: Required for subclasses of Options.
-
- static OptionDefinition g_option_table[];
-
- // Instance variables to hold the values for command options.
-
- std::string m_condition;
- FileSpecList m_filenames;
- uint32_t m_line_num;
- uint32_t m_column;
- std::vector<std::string> m_func_names;
- std::vector<std::string> m_breakpoint_names;
- uint32_t m_func_name_type_mask;
- std::string m_func_regexp;
- std::string m_source_text_regexp;
- FileSpecList m_modules;
- lldb::addr_t m_load_addr;
- lldb::addr_t m_offset_addr;
- uint32_t m_ignore_count;
- lldb::tid_t m_thread_id;
- uint32_t m_thread_index;
- std::string m_thread_name;
- std::string m_queue_name;
- bool m_catch_bp;
- bool m_throw_bp;
- bool m_hardware; // Request to use hardware breakpoints
- lldb::LanguageType m_exception_language;
- lldb::LanguageType m_language;
- LazyBool m_skip_prologue;
- bool m_one_shot;
- bool m_use_dummy;
- bool m_all_files;
- Args m_exception_extra_args;
- LazyBool m_move_to_nearest_code;
- std::unordered_set<std::string> m_source_regex_func_names;
- };
+ // Instance variables to hold the values for command options.
+
+ std::string m_condition;
+ FileSpecList m_filenames;
+ uint32_t m_line_num;
+ uint32_t m_column;
+ std::vector<std::string> m_func_names;
+ std::vector<std::string> m_breakpoint_names;
+ uint32_t m_func_name_type_mask;
+ std::string m_func_regexp;
+ std::string m_source_text_regexp;
+ FileSpecList m_modules;
+ lldb::addr_t m_load_addr;
+ lldb::addr_t m_offset_addr;
+ uint32_t m_ignore_count;
+ lldb::tid_t m_thread_id;
+ uint32_t m_thread_index;
+ std::string m_thread_name;
+ std::string m_queue_name;
+ bool m_catch_bp;
+ bool m_throw_bp;
+ bool m_hardware; // Request to use hardware breakpoints
+ lldb::LanguageType m_exception_language;
+ lldb::LanguageType m_language;
+ LazyBool m_skip_prologue;
+ bool m_one_shot;
+ bool m_use_dummy;
+ bool m_all_files;
+ Args m_exception_extra_args;
+ LazyBool m_move_to_nearest_code;
+ std::unordered_set<std::string> m_source_regex_func_names;
+ };
protected:
- bool
- DoExecute (Args& command,
- CommandReturnObject &result) override
+ bool DoExecute(Args &command, CommandReturnObject &result) override {
+ Target *target = GetSelectedOrDummyTarget(m_options.m_use_dummy);
+
+ if (target == nullptr) {
+ result.AppendError("Invalid target. Must set target before setting "
+ "breakpoints (see 'target create' command).");
+ result.SetStatus(eReturnStatusFailed);
+ return false;
+ }
+
+ // The following are the various types of breakpoints that could be set:
+ // 1). -f -l -p [-s -g] (setting breakpoint by source location)
+ // 2). -a [-s -g] (setting breakpoint by address)
+ // 3). -n [-s -g] (setting breakpoint by function name)
+ // 4). -r [-s -g] (setting breakpoint by function name regular
+ // expression)
+ // 5). -p -f (setting a breakpoint by comparing a reg-exp
+ // to source text)
+ // 6). -E [-w -h] (setting a breakpoint for exceptions for a
+ // given language.)
+
+ BreakpointSetType break_type = eSetTypeInvalid;
+
+ if (m_options.m_line_num != 0)
+ break_type = eSetTypeFileAndLine;
+ else if (m_options.m_load_addr != LLDB_INVALID_ADDRESS)
+ break_type = eSetTypeAddress;
+ else if (!m_options.m_func_names.empty())
+ break_type = eSetTypeFunctionName;
+ else if (!m_options.m_func_regexp.empty())
+ break_type = eSetTypeFunctionRegexp;
+ else if (!m_options.m_source_text_regexp.empty())
+ break_type = eSetTypeSourceRegexp;
+ else if (m_options.m_exception_language != eLanguageTypeUnknown)
+ break_type = eSetTypeException;
+
+ Breakpoint *bp = nullptr;
+ FileSpec module_spec;
+ const bool internal = false;
+
+ // If the user didn't specify skip-prologue, having an offset should turn
+ // that off.
+ if (m_options.m_offset_addr != 0 &&
+ m_options.m_skip_prologue == eLazyBoolCalculate)
+ m_options.m_skip_prologue = eLazyBoolNo;
+
+ switch (break_type) {
+ case eSetTypeFileAndLine: // Breakpoint by source position
+ {
+ FileSpec file;
+ const size_t num_files = m_options.m_filenames.GetSize();
+ if (num_files == 0) {
+ if (!GetDefaultFile(target, file, result)) {
+ result.AppendError("No file supplied and no default file available.");
+ result.SetStatus(eReturnStatusFailed);
+ return false;
+ }
+ } else if (num_files > 1) {
+ result.AppendError("Only one file at a time is allowed for file and "
+ "line breakpoints.");
+ result.SetStatus(eReturnStatusFailed);
+ return false;
+ } else
+ file = m_options.m_filenames.GetFileSpecAtIndex(0);
+
+ // Only check for inline functions if
+ LazyBool check_inlines = eLazyBoolCalculate;
+
+ bp = target
+ ->CreateBreakpoint(&(m_options.m_modules), file,
+ m_options.m_line_num, m_options.m_offset_addr,
+ check_inlines, m_options.m_skip_prologue,
+ internal, m_options.m_hardware,
+ m_options.m_move_to_nearest_code)
+ .get();
+ } break;
+
+ case eSetTypeAddress: // Breakpoint by address
+ {
+ // If a shared library has been specified, make an lldb_private::Address
+ // with the library, and
+ // use that. That way the address breakpoint will track the load location
+ // of the library.
+ size_t num_modules_specified = m_options.m_modules.GetSize();
+ if (num_modules_specified == 1) {
+ const FileSpec *file_spec =
+ m_options.m_modules.GetFileSpecPointerAtIndex(0);
+ bp = target
+ ->CreateAddressInModuleBreakpoint(m_options.m_load_addr,
+ internal, file_spec,
+ m_options.m_hardware)
+ .get();
+ } else if (num_modules_specified == 0) {
+ bp = target
+ ->CreateBreakpoint(m_options.m_load_addr, internal,
+ m_options.m_hardware)
+ .get();
+ } else {
+ result.AppendError("Only one shared library can be specified for "
+ "address breakpoints.");
+ result.SetStatus(eReturnStatusFailed);
+ return false;
+ }
+ break;
+ }
+ case eSetTypeFunctionName: // Breakpoint by function name
+ {
+ uint32_t name_type_mask = m_options.m_func_name_type_mask;
+
+ if (name_type_mask == 0)
+ name_type_mask = eFunctionNameTypeAuto;
+
+ bp = target
+ ->CreateBreakpoint(
+ &(m_options.m_modules), &(m_options.m_filenames),
+ m_options.m_func_names, name_type_mask, m_options.m_language,
+ m_options.m_offset_addr, m_options.m_skip_prologue, internal,
+ m_options.m_hardware)
+ .get();
+ } break;
+
+ case eSetTypeFunctionRegexp: // Breakpoint by regular expression function
+ // name
+ {
+ RegularExpression regexp(m_options.m_func_regexp);
+ if (!regexp.IsValid()) {
+ char err_str[1024];
+ regexp.GetErrorAsCString(err_str, sizeof(err_str));
+ result.AppendErrorWithFormat(
+ "Function name regular expression could not be compiled: \"%s\"",
+ err_str);
+ result.SetStatus(eReturnStatusFailed);
+ return false;
+ }
+
+ bp = target
+ ->CreateFuncRegexBreakpoint(
+ &(m_options.m_modules), &(m_options.m_filenames), regexp,
+ m_options.m_language, m_options.m_skip_prologue, internal,
+ m_options.m_hardware)
+ .get();
+ }
+ break;
+ case eSetTypeSourceRegexp: // Breakpoint by regexp on source text.
{
- Target *target = GetSelectedOrDummyTarget(m_options.m_use_dummy);
+ const size_t num_files = m_options.m_filenames.GetSize();
+
+ if (num_files == 0 && !m_options.m_all_files) {
+ FileSpec file;
+ if (!GetDefaultFile(target, file, result)) {
+ result.AppendError(
+ "No files provided and could not find default file.");
+ result.SetStatus(eReturnStatusFailed);
+ return false;
+ } else {
+ m_options.m_filenames.Append(file);
+ }
+ }
+
+ RegularExpression regexp(m_options.m_source_text_regexp);
+ if (!regexp.IsValid()) {
+ char err_str[1024];
+ regexp.GetErrorAsCString(err_str, sizeof(err_str));
+ result.AppendErrorWithFormat(
+ "Source text regular expression could not be compiled: \"%s\"",
+ err_str);
+ result.SetStatus(eReturnStatusFailed);
+ return false;
+ }
+ bp = target
+ ->CreateSourceRegexBreakpoint(
+ &(m_options.m_modules), &(m_options.m_filenames),
+ m_options.m_source_regex_func_names, regexp, internal,
+ m_options.m_hardware, m_options.m_move_to_nearest_code)
+ .get();
+ } break;
+ case eSetTypeException: {
+ Error precond_error;
+ bp = target
+ ->CreateExceptionBreakpoint(
+ m_options.m_exception_language, m_options.m_catch_bp,
+ m_options.m_throw_bp, internal,
+ &m_options.m_exception_extra_args, &precond_error)
+ .get();
+ if (precond_error.Fail()) {
+ result.AppendErrorWithFormat(
+ "Error setting extra exception arguments: %s",
+ precond_error.AsCString());
+ target->RemoveBreakpointByID(bp->GetID());
+ result.SetStatus(eReturnStatusFailed);
+ return false;
+ }
+ } break;
+ default:
+ break;
+ }
- if (target == nullptr)
- {
- result.AppendError ("Invalid target. Must set target before setting breakpoints (see 'target create' command).");
- result.SetStatus (eReturnStatusFailed);
+ // Now set the various options that were passed in:
+ if (bp) {
+ if (m_options.m_thread_id != LLDB_INVALID_THREAD_ID)
+ bp->SetThreadID(m_options.m_thread_id);
+
+ if (m_options.m_thread_index != UINT32_MAX)
+ bp->GetOptions()->GetThreadSpec()->SetIndex(m_options.m_thread_index);
+
+ if (!m_options.m_thread_name.empty())
+ bp->GetOptions()->GetThreadSpec()->SetName(
+ m_options.m_thread_name.c_str());
+
+ if (!m_options.m_queue_name.empty())
+ bp->GetOptions()->GetThreadSpec()->SetQueueName(
+ m_options.m_queue_name.c_str());
+
+ if (m_options.m_ignore_count != 0)
+ bp->GetOptions()->SetIgnoreCount(m_options.m_ignore_count);
+
+ if (!m_options.m_condition.empty())
+ bp->GetOptions()->SetCondition(m_options.m_condition.c_str());
+
+ if (!m_options.m_breakpoint_names.empty()) {
+ Error name_error;
+ for (auto name : m_options.m_breakpoint_names) {
+ bp->AddName(name.c_str(), name_error);
+ if (name_error.Fail()) {
+ result.AppendErrorWithFormat("Invalid breakpoint name: %s",
+ name.c_str());
+ target->RemoveBreakpointByID(bp->GetID());
+ result.SetStatus(eReturnStatusFailed);
return false;
+ }
}
+ }
- // The following are the various types of breakpoints that could be set:
- // 1). -f -l -p [-s -g] (setting breakpoint by source location)
- // 2). -a [-s -g] (setting breakpoint by address)
- // 3). -n [-s -g] (setting breakpoint by function name)
- // 4). -r [-s -g] (setting breakpoint by function name regular expression)
- // 5). -p -f (setting a breakpoint by comparing a reg-exp to source text)
- // 6). -E [-w -h] (setting a breakpoint for exceptions for a given language.)
-
- BreakpointSetType break_type = eSetTypeInvalid;
-
- if (m_options.m_line_num != 0)
- break_type = eSetTypeFileAndLine;
- else if (m_options.m_load_addr != LLDB_INVALID_ADDRESS)
- break_type = eSetTypeAddress;
- else if (!m_options.m_func_names.empty())
- break_type = eSetTypeFunctionName;
- else if (!m_options.m_func_regexp.empty())
- break_type = eSetTypeFunctionRegexp;
- else if (!m_options.m_source_text_regexp.empty())
- break_type = eSetTypeSourceRegexp;
- else if (m_options.m_exception_language != eLanguageTypeUnknown)
- break_type = eSetTypeException;
-
- Breakpoint *bp = nullptr;
- FileSpec module_spec;
- const bool internal = false;
-
- // If the user didn't specify skip-prologue, having an offset should turn that off.
- if (m_options.m_offset_addr != 0 && m_options.m_skip_prologue == eLazyBoolCalculate)
- m_options.m_skip_prologue = eLazyBoolNo;
-
- switch (break_type)
- {
- case eSetTypeFileAndLine: // Breakpoint by source position
- {
- FileSpec file;
- const size_t num_files = m_options.m_filenames.GetSize();
- if (num_files == 0)
- {
- if (!GetDefaultFile (target, file, result))
- {
- result.AppendError("No file supplied and no default file available.");
- result.SetStatus (eReturnStatusFailed);
- return false;
- }
- }
- else if (num_files > 1)
- {
- result.AppendError("Only one file at a time is allowed for file and line breakpoints.");
- result.SetStatus (eReturnStatusFailed);
- return false;
- }
- else
- file = m_options.m_filenames.GetFileSpecAtIndex(0);
-
- // Only check for inline functions if
- LazyBool check_inlines = eLazyBoolCalculate;
-
- bp = target->CreateBreakpoint (&(m_options.m_modules),
- file,
- m_options.m_line_num,
- m_options.m_offset_addr,
- check_inlines,
- m_options.m_skip_prologue,
- internal,
- m_options.m_hardware,
- m_options.m_move_to_nearest_code).get();
- }
- break;
-
- case eSetTypeAddress: // Breakpoint by address
- {
- // If a shared library has been specified, make an lldb_private::Address with the library, and
- // use that. That way the address breakpoint will track the load location of the library.
- size_t num_modules_specified = m_options.m_modules.GetSize();
- if (num_modules_specified == 1)
- {
- const FileSpec *file_spec = m_options.m_modules.GetFileSpecPointerAtIndex(0);
- bp = target->CreateAddressInModuleBreakpoint (m_options.m_load_addr,
- internal,
- file_spec,
- m_options.m_hardware).get();
- }
- else if (num_modules_specified == 0)
- {
- bp = target->CreateBreakpoint (m_options.m_load_addr,
- internal,
- m_options.m_hardware).get();
- }
- else
- {
- result.AppendError("Only one shared library can be specified for address breakpoints.");
- result.SetStatus(eReturnStatusFailed);
- return false;
- }
- break;
- }
- case eSetTypeFunctionName: // Breakpoint by function name
- {
- uint32_t name_type_mask = m_options.m_func_name_type_mask;
-
- if (name_type_mask == 0)
- name_type_mask = eFunctionNameTypeAuto;
-
- bp = target->CreateBreakpoint (&(m_options.m_modules),
- &(m_options.m_filenames),
- m_options.m_func_names,
- name_type_mask,
- m_options.m_language,
- m_options.m_offset_addr,
- m_options.m_skip_prologue,
- internal,
- m_options.m_hardware).get();
- }
- break;
-
- case eSetTypeFunctionRegexp: // Breakpoint by regular expression function name
- {
- RegularExpression regexp(m_options.m_func_regexp.c_str());
- if (!regexp.IsValid())
- {
- char err_str[1024];
- regexp.GetErrorAsCString(err_str, sizeof(err_str));
- result.AppendErrorWithFormat("Function name regular expression could not be compiled: \"%s\"",
- err_str);
- result.SetStatus (eReturnStatusFailed);
- return false;
- }
-
- bp = target->CreateFuncRegexBreakpoint (&(m_options.m_modules),
- &(m_options.m_filenames),
- regexp,
- m_options.m_language,
- m_options.m_skip_prologue,
- internal,
- m_options.m_hardware).get();
- }
- break;
- case eSetTypeSourceRegexp: // Breakpoint by regexp on source text.
- {
- const size_t num_files = m_options.m_filenames.GetSize();
-
- if (num_files == 0 && !m_options.m_all_files)
- {
- FileSpec file;
- if (!GetDefaultFile (target, file, result))
- {
- result.AppendError ("No files provided and could not find default file.");
- result.SetStatus (eReturnStatusFailed);
- return false;
- }
- else
- {
- m_options.m_filenames.Append (file);
- }
- }
-
- RegularExpression regexp(m_options.m_source_text_regexp.c_str());
- if (!regexp.IsValid())
- {
- char err_str[1024];
- regexp.GetErrorAsCString(err_str, sizeof(err_str));
- result.AppendErrorWithFormat("Source text regular expression could not be compiled: \"%s\"",
- err_str);
- result.SetStatus (eReturnStatusFailed);
- return false;
- }
- bp = target->CreateSourceRegexBreakpoint (&(m_options.m_modules),
- &(m_options.m_filenames),
- m_options.m_source_regex_func_names,
- regexp,
- internal,
- m_options.m_hardware,
- m_options.m_move_to_nearest_code).get();
- }
- break;
- case eSetTypeException:
- {
- Error precond_error;
- bp = target->CreateExceptionBreakpoint (m_options.m_exception_language,
- m_options.m_catch_bp,
- m_options.m_throw_bp,
- internal,
- &m_options.m_exception_extra_args,
- &precond_error).get();
- if (precond_error.Fail())
- {
- result.AppendErrorWithFormat("Error setting extra exception arguments: %s",
- precond_error.AsCString());
- target->RemoveBreakpointByID(bp->GetID());
- result.SetStatus(eReturnStatusFailed);
- return false;
- }
- }
- break;
- default:
- break;
- }
-
- // Now set the various options that were passed in:
- if (bp)
- {
- if (m_options.m_thread_id != LLDB_INVALID_THREAD_ID)
- bp->SetThreadID (m_options.m_thread_id);
-
- if (m_options.m_thread_index != UINT32_MAX)
- bp->GetOptions()->GetThreadSpec()->SetIndex(m_options.m_thread_index);
-
- if (!m_options.m_thread_name.empty())
- bp->GetOptions()->GetThreadSpec()->SetName(m_options.m_thread_name.c_str());
-
- if (!m_options.m_queue_name.empty())
- bp->GetOptions()->GetThreadSpec()->SetQueueName(m_options.m_queue_name.c_str());
-
- if (m_options.m_ignore_count != 0)
- bp->GetOptions()->SetIgnoreCount(m_options.m_ignore_count);
-
- if (!m_options.m_condition.empty())
- bp->GetOptions()->SetCondition(m_options.m_condition.c_str());
-
- if (!m_options.m_breakpoint_names.empty())
- {
- Error error; // We don't need to check the error here, since the option parser checked it...
- for (auto name : m_options.m_breakpoint_names)
- bp->AddName(name.c_str(), error);
- }
-
- bp->SetOneShot (m_options.m_one_shot);
- }
-
- if (bp)
- {
- Stream &output_stream = result.GetOutputStream();
- const bool show_locations = false;
- bp->GetDescription(&output_stream, lldb::eDescriptionLevelInitial, show_locations);
- if (target == m_interpreter.GetDebugger().GetDummyTarget())
- output_stream.Printf ("Breakpoint set in dummy target, will get copied into future targets.\n");
- else
- {
- // Don't print out this warning for exception breakpoints. They can get set before the target
- // is set, but we won't know how to actually set the breakpoint till we run.
- if (bp->GetNumLocations() == 0 && break_type != eSetTypeException)
- {
- output_stream.Printf ("WARNING: Unable to resolve breakpoint to any actual locations.\n");
- }
- }
- result.SetStatus (eReturnStatusSuccessFinishResult);
- }
- else if (!bp)
- {
- result.AppendError ("Breakpoint creation failed: No breakpoint created.");
- result.SetStatus (eReturnStatusFailed);
- }
-
- return result.Succeeded();
+ bp->SetOneShot(m_options.m_one_shot);
}
-private:
- bool
- GetDefaultFile (Target *target, FileSpec &file, CommandReturnObject &result)
- {
- uint32_t default_line;
- // First use the Source Manager's default file.
- // Then use the current stack frame's file.
- if (!target->GetSourceManager().GetDefaultFileAndLine(file, default_line))
- {
- StackFrame *cur_frame = m_exe_ctx.GetFramePtr();
- if (cur_frame == nullptr)
- {
- result.AppendError ("No selected frame to use to find the default file.");
- result.SetStatus (eReturnStatusFailed);
- return false;
- }
- else if (!cur_frame->HasDebugInformation())
- {
- result.AppendError ("Cannot use the selected frame to find the default file, it has no debug info.");
- result.SetStatus (eReturnStatusFailed);
- return false;
- }
- else
- {
- const SymbolContext &sc = cur_frame->GetSymbolContext (eSymbolContextLineEntry);
- if (sc.line_entry.file)
- {
- file = sc.line_entry.file;
- }
- else
- {
- result.AppendError ("Can't find the file for the selected frame to use as the default file.");
- result.SetStatus (eReturnStatusFailed);
- return false;
- }
- }
- }
- return true;
+ if (bp) {
+ Stream &output_stream = result.GetOutputStream();
+ const bool show_locations = false;
+ bp->GetDescription(&output_stream, lldb::eDescriptionLevelInitial,
+ show_locations);
+ if (target == m_interpreter.GetDebugger().GetDummyTarget())
+ output_stream.Printf("Breakpoint set in dummy target, will get copied "
+ "into future targets.\n");
+ else {
+ // Don't print out this warning for exception breakpoints. They can get
+ // set before the target
+ // is set, but we won't know how to actually set the breakpoint till we
+ // run.
+ if (bp->GetNumLocations() == 0 && break_type != eSetTypeException) {
+ output_stream.Printf("WARNING: Unable to resolve breakpoint to any "
+ "actual locations.\n");
+ }
+ }
+ result.SetStatus(eReturnStatusSuccessFinishResult);
+ } else if (!bp) {
+ result.AppendError("Breakpoint creation failed: No breakpoint created.");
+ result.SetStatus(eReturnStatusFailed);
}
-
- CommandOptions m_options;
-};
-
-// If an additional option set beyond LLDB_OPTION_SET_10 is added, make sure to
-// update the numbers passed to LLDB_OPT_SET_FROM_TO(...) appropriately.
-#define LLDB_OPT_FILE ( LLDB_OPT_SET_FROM_TO(1, 9) & ~LLDB_OPT_SET_2 )
-#define LLDB_OPT_NOT_10 ( LLDB_OPT_SET_FROM_TO(1, 10) & ~LLDB_OPT_SET_10 )
-#define LLDB_OPT_SKIP_PROLOGUE ( LLDB_OPT_SET_1 | LLDB_OPT_SET_FROM_TO(3,8) )
-#define LLDB_OPT_OFFSET_APPLIES (LLDB_OPT_SET_1 | LLDB_OPT_SET_FROM_TO(3,8) )
-#define LLDB_OPT_MOVE_TO_NEAREST_CODE ( LLDB_OPT_SET_1 | LLDB_OPT_SET_9 )
-#define LLDB_OPT_EXPR_LANGUAGE ( LLDB_OPT_SET_FROM_TO(3, 8) )
-
-OptionDefinition
-CommandObjectBreakpointSet::CommandOptions::g_option_table[] =
-{
- { LLDB_OPT_NOT_10, false, "shlib", 's', OptionParser::eRequiredArgument, nullptr, nullptr, CommandCompletions::eModuleCompletion, eArgTypeShlibName,
- "Set the breakpoint only in this shared library. "
- "Can repeat this option multiple times to specify multiple shared libraries."},
-
- { LLDB_OPT_SET_ALL, false, "ignore-count", 'i', OptionParser::eRequiredArgument, nullptr, nullptr, 0, eArgTypeCount,
- "Set the number of times this breakpoint is skipped before stopping." },
-
- { LLDB_OPT_SET_ALL, false, "one-shot", 'o', OptionParser::eNoArgument, nullptr, nullptr, 0, eArgTypeNone,
- "The breakpoint is deleted the first time it causes a stop." },
-
- { LLDB_OPT_SET_ALL, false, "condition", 'c', OptionParser::eRequiredArgument, nullptr, nullptr, 0, eArgTypeExpression,
- "The breakpoint stops only if this condition expression evaluates to true."},
-
- { LLDB_OPT_SET_ALL, false, "thread-index", 'x', OptionParser::eRequiredArgument, nullptr, nullptr, 0, eArgTypeThreadIndex,
- "The breakpoint stops only for the thread whose indeX matches this argument."},
-
- { LLDB_OPT_SET_ALL, false, "thread-id", 't', OptionParser::eRequiredArgument, nullptr, nullptr, 0, eArgTypeThreadID,
- "The breakpoint stops only for the thread whose TID matches this argument."},
-
- { LLDB_OPT_SET_ALL, false, "thread-name", 'T', OptionParser::eRequiredArgument, nullptr, nullptr, 0, eArgTypeThreadName,
- "The breakpoint stops only for the thread whose thread name matches this argument."},
- { LLDB_OPT_SET_ALL, false, "hardware", 'H', OptionParser::eNoArgument, nullptr, nullptr, 0, eArgTypeNone,
- "Require the breakpoint to use hardware breakpoints."},
+ return result.Succeeded();
+ }
- { LLDB_OPT_SET_ALL, false, "queue-name", 'q', OptionParser::eRequiredArgument, nullptr, nullptr, 0, eArgTypeQueueName,
- "The breakpoint stops only for threads in the queue whose name is given by this argument."},
-
- { LLDB_OPT_FILE, false, "file", 'f', OptionParser::eRequiredArgument, nullptr, nullptr, CommandCompletions::eSourceFileCompletion, eArgTypeFilename,
- "Specifies the source file in which to set this breakpoint. "
- "Note, by default lldb only looks for files that are #included if they use the standard include file extensions. "
- "To set breakpoints on .c/.cpp/.m/.mm files that are #included, set target.inline-breakpoint-strategy"
- " to \"always\"."},
-
- { LLDB_OPT_SET_1, true, "line", 'l', OptionParser::eRequiredArgument, nullptr, nullptr, 0, eArgTypeLineNum,
- "Specifies the line number on which to set this breakpoint."},
-
- // Comment out this option for the moment, as we don't actually use it, but will in the future.
- // This way users won't see it, but the infrastructure is left in place.
- // { 0, false, "column", 'C', OptionParser::eRequiredArgument, nullptr, "<column>",
- // "Set the breakpoint by source location at this particular column."},
-
- { LLDB_OPT_SET_2, true, "address", 'a', OptionParser::eRequiredArgument, nullptr, nullptr, 0, eArgTypeAddressOrExpression,
- "Set the breakpoint at the specified address. "
- "If the address maps uniquely to a particular "
- "binary, then the address will be converted to a \"file\" address, so that the breakpoint will track that binary+offset no matter where "
- "the binary eventually loads. "
- "Alternately, if you also specify the module - with the -s option - then the address will be treated as "
- "a file address in that module, and resolved accordingly. Again, this will allow lldb to track that offset on "
- "subsequent reloads. The module need not have been loaded at the time you specify this breakpoint, and will "
- "get resolved when the module is loaded."},
-
- { LLDB_OPT_SET_3, true, "name", 'n', OptionParser::eRequiredArgument, nullptr, nullptr, CommandCompletions::eSymbolCompletion, eArgTypeFunctionName,
- "Set the breakpoint by function name. Can be repeated multiple times to make one breakpoint for multiple names" },
+private:
+ bool GetDefaultFile(Target *target, FileSpec &file,
+ CommandReturnObject &result) {
+ uint32_t default_line;
+ // First use the Source Manager's default file.
+ // Then use the current stack frame's file.
+ if (!target->GetSourceManager().GetDefaultFileAndLine(file, default_line)) {
+ StackFrame *cur_frame = m_exe_ctx.GetFramePtr();
+ if (cur_frame == nullptr) {
+ result.AppendError(
+ "No selected frame to use to find the default file.");
+ result.SetStatus(eReturnStatusFailed);
+ return false;
+ } else if (!cur_frame->HasDebugInformation()) {
+ result.AppendError("Cannot use the selected frame to find the default "
+ "file, it has no debug info.");
+ result.SetStatus(eReturnStatusFailed);
+ return false;
+ } else {
+ const SymbolContext &sc =
+ cur_frame->GetSymbolContext(eSymbolContextLineEntry);
+ if (sc.line_entry.file) {
+ file = sc.line_entry.file;
+ } else {
+ result.AppendError("Can't find the file for the selected frame to "
+ "use as the default file.");
+ result.SetStatus(eReturnStatusFailed);
+ return false;
+ }
+ }
+ }
+ return true;
+ }
- { LLDB_OPT_SET_9, false, "source-regexp-function", 'X', OptionParser::eRequiredArgument, nullptr, nullptr, CommandCompletions::eSymbolCompletion, eArgTypeFunctionName,
- "When used with '-p' limits the source regex to source contained in the named functions. Can be repeated multiple times." },
+ CommandOptions m_options;
+};
- { LLDB_OPT_SET_4, true, "fullname", 'F', OptionParser::eRequiredArgument, nullptr, nullptr, CommandCompletions::eSymbolCompletion, eArgTypeFullName,
- "Set the breakpoint by fully qualified function names. For C++ this means namespaces and all arguments, and "
- "for Objective C this means a full function prototype with class and selector. "
- "Can be repeated multiple times to make one breakpoint for multiple names." },
+//-------------------------------------------------------------------------
+// CommandObjectBreakpointModify
+//-------------------------------------------------------------------------
- { LLDB_OPT_SET_5, true, "selector", 'S', OptionParser::eRequiredArgument, nullptr, nullptr, 0, eArgTypeSelector,
- "Set the breakpoint by ObjC selector name. Can be repeated multiple times to make one breakpoint for multiple Selectors." },
+#pragma mark Modify::CommandOptions
+static OptionDefinition g_breakpoint_modify_options[] = {
+ // clang-format off
+ { LLDB_OPT_SET_ALL, false, "ignore-count", 'i', OptionParser::eRequiredArgument, nullptr, nullptr, 0, eArgTypeCount, "Set the number of times this breakpoint is skipped before stopping." },
+ { LLDB_OPT_SET_ALL, false, "one-shot", 'o', OptionParser::eRequiredArgument, nullptr, nullptr, 0, eArgTypeBoolean, "The breakpoint is deleted the first time it stop causes a stop." },
+ { LLDB_OPT_SET_ALL, false, "thread-index", 'x', OptionParser::eRequiredArgument, nullptr, nullptr, 0, eArgTypeThreadIndex, "The breakpoint stops only for the thread whose index matches this argument." },
+ { LLDB_OPT_SET_ALL, false, "thread-id", 't', OptionParser::eRequiredArgument, nullptr, nullptr, 0, eArgTypeThreadID, "The breakpoint stops only for the thread whose TID matches this argument." },
+ { LLDB_OPT_SET_ALL, false, "thread-name", 'T', OptionParser::eRequiredArgument, nullptr, nullptr, 0, eArgTypeThreadName, "The breakpoint stops only for the thread whose thread name matches this argument." },
+ { LLDB_OPT_SET_ALL, false, "queue-name", 'q', OptionParser::eRequiredArgument, nullptr, nullptr, 0, eArgTypeQueueName, "The breakpoint stops only for threads in the queue whose name is given by this argument." },
+ { LLDB_OPT_SET_ALL, false, "condition", 'c', OptionParser::eRequiredArgument, nullptr, nullptr, 0, eArgTypeExpression, "The breakpoint stops only if this condition expression evaluates to true." },
+ { LLDB_OPT_SET_1, false, "enable", 'e', OptionParser::eNoArgument, nullptr, nullptr, 0, eArgTypeNone, "Enable the breakpoint." },
+ { LLDB_OPT_SET_2, false, "disable", 'd', OptionParser::eNoArgument, nullptr, nullptr, 0, eArgTypeNone, "Disable the breakpoint." },
+ { LLDB_OPT_SET_ALL, false, "dummy-breakpoints", 'D', OptionParser::eNoArgument, nullptr, nullptr, 0, eArgTypeNone, "Sets Dummy breakpoints - i.e. breakpoints set before a file is provided, which prime new targets." },
+ // clang-format on
+};
- { LLDB_OPT_SET_6, true, "method", 'M', OptionParser::eRequiredArgument, nullptr, nullptr, 0, eArgTypeMethod,
- "Set the breakpoint by C++ method names. Can be repeated multiple times to make one breakpoint for multiple methods." },
+#pragma mark Modify
- { LLDB_OPT_SET_7, true, "func-regex", 'r', OptionParser::eRequiredArgument, nullptr, nullptr, 0, eArgTypeRegularExpression,
- "Set the breakpoint by function name, evaluating a regular-expression to find the function name(s)." },
+class CommandObjectBreakpointModify : public CommandObjectParsed {
+public:
+ CommandObjectBreakpointModify(CommandInterpreter &interpreter)
+ : CommandObjectParsed(interpreter, "breakpoint modify",
+ "Modify the options on a breakpoint or set of "
+ "breakpoints in the executable. "
+ "If no breakpoint is specified, acts on the last "
+ "created breakpoint. "
+ "With the exception of -e, -d and -i, passing an "
+ "empty argument clears the modification.",
+ nullptr),
+ m_options() {
+ CommandArgumentEntry arg;
+ CommandObject::AddIDsArgumentData(arg, eArgTypeBreakpointID,
+ eArgTypeBreakpointIDRange);
+ // Add the entry for the first argument for this command to the object's
+ // arguments vector.
+ m_arguments.push_back(arg);
+ }
+
+ ~CommandObjectBreakpointModify() override = default;
+
+ Options *GetOptions() override { return &m_options; }
+
+ class CommandOptions : public Options {
+ public:
+ CommandOptions()
+ : Options(), m_ignore_count(0), m_thread_id(LLDB_INVALID_THREAD_ID),
+ m_thread_id_passed(false), m_thread_index(UINT32_MAX),
+ m_thread_index_passed(false), m_thread_name(), m_queue_name(),
+ m_condition(), m_one_shot(false), m_enable_passed(false),
+ m_enable_value(false), m_name_passed(false), m_queue_passed(false),
+ m_condition_passed(false), m_one_shot_passed(false),
+ m_use_dummy(false) {}
+
+ ~CommandOptions() override = default;
+
+ Error SetOptionValue(uint32_t option_idx, llvm::StringRef option_arg,
+ ExecutionContext *execution_context) override {
+ Error error;
+ const int short_option = m_getopt_table[option_idx].val;
+
+ switch (short_option) {
+ case 'c':
+ m_condition = option_arg;
+ m_condition_passed = true;
+ break;
+ case 'd':
+ m_enable_passed = true;
+ m_enable_value = false;
+ break;
+ case 'D':
+ m_use_dummy = true;
+ break;
+ case 'e':
+ m_enable_passed = true;
+ m_enable_value = true;
+ break;
+ case 'i':
+ if (option_arg.getAsInteger(0, m_ignore_count))
+ error.SetErrorStringWithFormat("invalid ignore count '%s'",
+ option_arg.str().c_str());
+ break;
+ case 'o': {
+ bool value, success;
+ value = Args::StringToBoolean(option_arg, false, &success);
+ if (success) {
+ m_one_shot_passed = true;
+ m_one_shot = value;
+ } else
+ error.SetErrorStringWithFormat(
+ "invalid boolean value '%s' passed for -o option",
+ option_arg.str().c_str());
+ } break;
+ case 't':
+ if (option_arg[0] == '\0') {
+ m_thread_id = LLDB_INVALID_THREAD_ID;
+ m_thread_id_passed = true;
+ } else {
+ if (option_arg.getAsInteger(0, m_thread_id))
+ error.SetErrorStringWithFormat("invalid thread id string '%s'",
+ option_arg.str().c_str());
+ else
+ m_thread_id_passed = true;
+ }
+ break;
+ case 'T':
+ m_thread_name = option_arg;
+ m_name_passed = true;
+ break;
+ case 'q':
+ m_queue_name = option_arg;
+ m_queue_passed = true;
+ break;
+ case 'x':
+ if (option_arg[0] == '\n') {
+ m_thread_index = UINT32_MAX;
+ m_thread_index_passed = true;
+ } else {
+ if (option_arg.getAsInteger(0, m_thread_index))
+ error.SetErrorStringWithFormat("invalid thread index string '%s'",
+ option_arg.str().c_str());
+ else
+ m_thread_index_passed = true;
+ }
+ break;
+ default:
+ error.SetErrorStringWithFormat("unrecognized option '%c'",
+ short_option);
+ break;
+ }
+
+ return error;
+ }
- { LLDB_OPT_SET_8, true, "basename", 'b', OptionParser::eRequiredArgument, nullptr, nullptr, CommandCompletions::eSymbolCompletion, eArgTypeFunctionName,
- "Set the breakpoint by function basename (C++ namespaces and arguments will be ignored). "
- "Can be repeated multiple times to make one breakpoint for multiple symbols." },
+ void OptionParsingStarting(ExecutionContext *execution_context) override {
+ m_ignore_count = 0;
+ m_thread_id = LLDB_INVALID_THREAD_ID;
+ m_thread_id_passed = false;
+ m_thread_index = UINT32_MAX;
+ m_thread_index_passed = false;
+ m_thread_name.clear();
+ m_queue_name.clear();
+ m_condition.clear();
+ m_one_shot = false;
+ m_enable_passed = false;
+ m_queue_passed = false;
+ m_name_passed = false;
+ m_condition_passed = false;
+ m_one_shot_passed = false;
+ m_use_dummy = false;
+ }
- { LLDB_OPT_SET_9, true, "source-pattern-regexp", 'p', OptionParser::eRequiredArgument, nullptr, nullptr, 0, eArgTypeRegularExpression,
- "Set the breakpoint by specifying a regular expression which is matched against the source text in a source file or files "
- "specified with the -f option. The -f option can be specified more than once. "
- "If no source files are specified, uses the current \"default source file\". "
- "If you want to match against all source files, pass the \"--all-files\" option." },
+ llvm::ArrayRef<OptionDefinition> GetDefinitions() override {
+ return llvm::makeArrayRef(g_breakpoint_modify_options);
+ }
- { LLDB_OPT_SET_9, false, "all-files", 'A', OptionParser::eNoArgument, nullptr, nullptr, 0, eArgTypeNone,
- "All files are searched for source pattern matches." },
+ // Instance variables to hold the values for command options.
+
+ uint32_t m_ignore_count;
+ lldb::tid_t m_thread_id;
+ bool m_thread_id_passed;
+ uint32_t m_thread_index;
+ bool m_thread_index_passed;
+ std::string m_thread_name;
+ std::string m_queue_name;
+ std::string m_condition;
+ bool m_one_shot;
+ bool m_enable_passed;
+ bool m_enable_value;
+ bool m_name_passed;
+ bool m_queue_passed;
+ bool m_condition_passed;
+ bool m_one_shot_passed;
+ bool m_use_dummy;
+ };
- { LLDB_OPT_SET_10, true, "language-exception", 'E', OptionParser::eRequiredArgument, nullptr, nullptr, 0, eArgTypeLanguage,
- "Set the breakpoint on exceptions thrown by the specified language (without options, on throw but not catch.)" },
+protected:
+ bool DoExecute(Args &command, CommandReturnObject &result) override {
+ Target *target = GetSelectedOrDummyTarget(m_options.m_use_dummy);
+ if (target == nullptr) {
+ result.AppendError("Invalid target. No existing target or breakpoints.");
+ result.SetStatus(eReturnStatusFailed);
+ return false;
+ }
- { LLDB_OPT_SET_10, false, "on-throw", 'w', OptionParser::eRequiredArgument, nullptr, nullptr, 0, eArgTypeBoolean,
- "Set the breakpoint on exception throW." },
+ std::unique_lock<std::recursive_mutex> lock;
+ target->GetBreakpointList().GetListMutex(lock);
- { LLDB_OPT_SET_10, false, "on-catch", 'h', OptionParser::eRequiredArgument, nullptr, nullptr, 0, eArgTypeBoolean,
- "Set the breakpoint on exception catcH." },
+ BreakpointIDList valid_bp_ids;
-// Don't add this option till it actually does something useful...
-// { LLDB_OPT_SET_10, false, "exception-typename", 'O', OptionParser::eRequiredArgument, nullptr, nullptr, 0, eArgTypeTypeName,
-// "The breakpoint will only stop if an exception Object of this type is thrown. Can be repeated multiple times to stop for multiple object types" },
+ CommandObjectMultiwordBreakpoint::VerifyBreakpointOrLocationIDs(
+ command, target, result, &valid_bp_ids);
- { LLDB_OPT_EXPR_LANGUAGE, false, "language", 'L', OptionParser::eRequiredArgument, nullptr, nullptr, 0, eArgTypeLanguage,
- "Specifies the Language to use when interpreting the breakpoint's expression (note: currently only implemented for setting breakpoints on identifiers). If not set the target.language setting is used." },
+ if (result.Succeeded()) {
+ const size_t count = valid_bp_ids.GetSize();
+ for (size_t i = 0; i < count; ++i) {
+ BreakpointID cur_bp_id = valid_bp_ids.GetBreakpointIDAtIndex(i);
- { LLDB_OPT_SKIP_PROLOGUE, false, "skip-prologue", 'K', OptionParser::eRequiredArgument, nullptr, nullptr, 0, eArgTypeBoolean,
- "sKip the prologue if the breakpoint is at the beginning of a function. If not set the target.skip-prologue setting is used." },
+ if (cur_bp_id.GetBreakpointID() != LLDB_INVALID_BREAK_ID) {
+ Breakpoint *bp =
+ target->GetBreakpointByID(cur_bp_id.GetBreakpointID()).get();
+ if (cur_bp_id.GetLocationID() != LLDB_INVALID_BREAK_ID) {
+ BreakpointLocation *location =
+ bp->FindLocationByID(cur_bp_id.GetLocationID()).get();
+ if (location) {
+ if (m_options.m_thread_id_passed)
+ location->SetThreadID(m_options.m_thread_id);
- { LLDB_OPT_SET_ALL, false, "dummy-breakpoints", 'D', OptionParser::eNoArgument, nullptr, nullptr, 0, eArgTypeNone,
- "Sets Dummy breakpoints - i.e. breakpoints set before a file is provided, which prime new targets."},
+ if (m_options.m_thread_index_passed)
+ location->SetThreadIndex(m_options.m_thread_index);
- { LLDB_OPT_SET_ALL, false, "breakpoint-name", 'N', OptionParser::eRequiredArgument, nullptr, nullptr, 0, eArgTypeBreakpointName,
- "Adds this to the list of names for this breakpoint."},
+ if (m_options.m_name_passed)
+ location->SetThreadName(m_options.m_thread_name.c_str());
- { LLDB_OPT_OFFSET_APPLIES, false, "address-slide", 'R', OptionParser::eRequiredArgument, nullptr, nullptr, 0, eArgTypeAddress,
- "Add the specified offset to whatever address(es) the breakpoint resolves to. "
- "At present this applies the offset directly as given, and doesn't try to align it to instruction boundaries."},
+ if (m_options.m_queue_passed)
+ location->SetQueueName(m_options.m_queue_name.c_str());
- { LLDB_OPT_MOVE_TO_NEAREST_CODE, false, "move-to-nearest-code", 'm', OptionParser::eRequiredArgument, nullptr, nullptr, 0, eArgTypeBoolean,
- "Move breakpoints to nearest code. If not set the target.move-to-nearest-code setting is used." },
+ if (m_options.m_ignore_count != 0)
+ location->SetIgnoreCount(m_options.m_ignore_count);
- { 0, false, nullptr, 0, 0, nullptr, nullptr, 0, eArgTypeNone, nullptr }
-};
+ if (m_options.m_enable_passed)
+ location->SetEnabled(m_options.m_enable_value);
-//-------------------------------------------------------------------------
-// CommandObjectBreakpointModify
-//-------------------------------------------------------------------------
-#pragma mark Modify
-
-class CommandObjectBreakpointModify : public CommandObjectParsed
-{
-public:
- CommandObjectBreakpointModify (CommandInterpreter &interpreter) :
- CommandObjectParsed(interpreter,
- "breakpoint modify",
- "Modify the options on a breakpoint or set of breakpoints in the executable. "
- "If no breakpoint is specified, acts on the last created breakpoint. "
- "With the exception of -e, -d and -i, passing an empty argument clears the modification.",
- nullptr),
- m_options (interpreter)
- {
- CommandArgumentEntry arg;
- CommandObject::AddIDsArgumentData(arg, eArgTypeBreakpointID, eArgTypeBreakpointIDRange);
- // Add the entry for the first argument for this command to the object's arguments vector.
- m_arguments.push_back (arg);
- }
-
- ~CommandObjectBreakpointModify() override = default;
-
- Options *
- GetOptions () override
- {
- return &m_options;
- }
+ if (m_options.m_condition_passed)
+ location->SetCondition(m_options.m_condition.c_str());
+ }
+ } else {
+ if (m_options.m_thread_id_passed)
+ bp->SetThreadID(m_options.m_thread_id);
- class CommandOptions : public Options
- {
- public:
- CommandOptions (CommandInterpreter &interpreter) :
- Options (interpreter),
- m_ignore_count (0),
- m_thread_id(LLDB_INVALID_THREAD_ID),
- m_thread_id_passed(false),
- m_thread_index (UINT32_MAX),
- m_thread_index_passed(false),
- m_thread_name(),
- m_queue_name(),
- m_condition (),
- m_one_shot (false),
- m_enable_passed (false),
- m_enable_value (false),
- m_name_passed (false),
- m_queue_passed (false),
- m_condition_passed (false),
- m_one_shot_passed (false),
- m_use_dummy (false)
- {
- }
+ if (m_options.m_thread_index_passed)
+ bp->SetThreadIndex(m_options.m_thread_index);
- ~CommandOptions() override = default;
-
- Error
- SetOptionValue (uint32_t option_idx, const char *option_arg) override
- {
- Error error;
- const int short_option = m_getopt_table[option_idx].val;
-
- switch (short_option)
- {
- case 'c':
- if (option_arg != nullptr)
- m_condition.assign (option_arg);
- else
- m_condition.clear();
- m_condition_passed = true;
- break;
- case 'd':
- m_enable_passed = true;
- m_enable_value = false;
- break;
- case 'D':
- m_use_dummy = true;
- break;
- case 'e':
- m_enable_passed = true;
- m_enable_value = true;
- break;
- case 'i':
- m_ignore_count = StringConvert::ToUInt32(option_arg, UINT32_MAX, 0);
- if (m_ignore_count == UINT32_MAX)
- error.SetErrorStringWithFormat ("invalid ignore count '%s'", option_arg);
- break;
- case 'o':
- {
- bool value, success;
- value = Args::StringToBoolean(option_arg, false, &success);
- if (success)
- {
- m_one_shot_passed = true;
- m_one_shot = value;
- }
- else
- error.SetErrorStringWithFormat("invalid boolean value '%s' passed for -o option", option_arg);
- }
- break;
- case 't' :
- if (option_arg[0] == '\0')
- {
- m_thread_id = LLDB_INVALID_THREAD_ID;
- m_thread_id_passed = true;
- }
- else
- {
- m_thread_id = StringConvert::ToUInt64(option_arg, LLDB_INVALID_THREAD_ID, 0);
- if (m_thread_id == LLDB_INVALID_THREAD_ID)
- error.SetErrorStringWithFormat ("invalid thread id string '%s'", option_arg);
- else
- m_thread_id_passed = true;
- }
- break;
- case 'T':
- if (option_arg != nullptr)
- m_thread_name.assign (option_arg);
- else
- m_thread_name.clear();
- m_name_passed = true;
- break;
- case 'q':
- if (option_arg != nullptr)
- m_queue_name.assign (option_arg);
- else
- m_queue_name.clear();
- m_queue_passed = true;
- break;
- case 'x':
- if (option_arg[0] == '\n')
- {
- m_thread_index = UINT32_MAX;
- m_thread_index_passed = true;
- }
- else
- {
- m_thread_index = StringConvert::ToUInt32 (option_arg, UINT32_MAX, 0);
- if (m_thread_id == UINT32_MAX)
- error.SetErrorStringWithFormat ("invalid thread index string '%s'", option_arg);
- else
- m_thread_index_passed = true;
- }
- break;
- default:
- error.SetErrorStringWithFormat ("unrecognized option '%c'", short_option);
- break;
- }
+ if (m_options.m_name_passed)
+ bp->SetThreadName(m_options.m_thread_name.c_str());
- return error;
- }
+ if (m_options.m_queue_passed)
+ bp->SetQueueName(m_options.m_queue_name.c_str());
- void
- OptionParsingStarting () override
- {
- m_ignore_count = 0;
- m_thread_id = LLDB_INVALID_THREAD_ID;
- m_thread_id_passed = false;
- m_thread_index = UINT32_MAX;
- m_thread_index_passed = false;
- m_thread_name.clear();
- m_queue_name.clear();
- m_condition.clear();
- m_one_shot = false;
- m_enable_passed = false;
- m_queue_passed = false;
- m_name_passed = false;
- m_condition_passed = false;
- m_one_shot_passed = false;
- m_use_dummy = false;
- }
-
- const OptionDefinition*
- GetDefinitions () override
- {
- return g_option_table;
- }
-
- // Options table: Required for subclasses of Options.
-
- static OptionDefinition g_option_table[];
-
- // Instance variables to hold the values for command options.
-
- uint32_t m_ignore_count;
- lldb::tid_t m_thread_id;
- bool m_thread_id_passed;
- uint32_t m_thread_index;
- bool m_thread_index_passed;
- std::string m_thread_name;
- std::string m_queue_name;
- std::string m_condition;
- bool m_one_shot;
- bool m_enable_passed;
- bool m_enable_value;
- bool m_name_passed;
- bool m_queue_passed;
- bool m_condition_passed;
- bool m_one_shot_passed;
- bool m_use_dummy;
- };
+ if (m_options.m_ignore_count != 0)
+ bp->SetIgnoreCount(m_options.m_ignore_count);
-protected:
- bool
- DoExecute (Args& command, CommandReturnObject &result) override
- {
- Target *target = GetSelectedOrDummyTarget(m_options.m_use_dummy);
- if (target == nullptr)
- {
- result.AppendError ("Invalid target. No existing target or breakpoints.");
- result.SetStatus (eReturnStatusFailed);
- return false;
- }
+ if (m_options.m_enable_passed)
+ bp->SetEnabled(m_options.m_enable_value);
- std::unique_lock<std::recursive_mutex> lock;
- target->GetBreakpointList().GetListMutex(lock);
-
- BreakpointIDList valid_bp_ids;
-
- CommandObjectMultiwordBreakpoint::VerifyBreakpointOrLocationIDs (command, target, result, &valid_bp_ids);
-
- if (result.Succeeded())
- {
- const size_t count = valid_bp_ids.GetSize();
- for (size_t i = 0; i < count; ++i)
- {
- BreakpointID cur_bp_id = valid_bp_ids.GetBreakpointIDAtIndex (i);
-
- if (cur_bp_id.GetBreakpointID() != LLDB_INVALID_BREAK_ID)
- {
- Breakpoint *bp = target->GetBreakpointByID (cur_bp_id.GetBreakpointID()).get();
- if (cur_bp_id.GetLocationID() != LLDB_INVALID_BREAK_ID)
- {
- BreakpointLocation *location = bp->FindLocationByID (cur_bp_id.GetLocationID()).get();
- if (location)
- {
- if (m_options.m_thread_id_passed)
- location->SetThreadID (m_options.m_thread_id);
-
- if (m_options.m_thread_index_passed)
- location->SetThreadIndex(m_options.m_thread_index);
-
- if (m_options.m_name_passed)
- location->SetThreadName(m_options.m_thread_name.c_str());
-
- if (m_options.m_queue_passed)
- location->SetQueueName(m_options.m_queue_name.c_str());
-
- if (m_options.m_ignore_count != 0)
- location->SetIgnoreCount(m_options.m_ignore_count);
-
- if (m_options.m_enable_passed)
- location->SetEnabled (m_options.m_enable_value);
-
- if (m_options.m_condition_passed)
- location->SetCondition (m_options.m_condition.c_str());
- }
- }
- else
- {
- if (m_options.m_thread_id_passed)
- bp->SetThreadID (m_options.m_thread_id);
-
- if (m_options.m_thread_index_passed)
- bp->SetThreadIndex(m_options.m_thread_index);
-
- if (m_options.m_name_passed)
- bp->SetThreadName(m_options.m_thread_name.c_str());
-
- if (m_options.m_queue_passed)
- bp->SetQueueName(m_options.m_queue_name.c_str());
-
- if (m_options.m_ignore_count != 0)
- bp->SetIgnoreCount(m_options.m_ignore_count);
-
- if (m_options.m_enable_passed)
- bp->SetEnabled (m_options.m_enable_value);
-
- if (m_options.m_condition_passed)
- bp->SetCondition (m_options.m_condition.c_str());
- }
- }
- }
+ if (m_options.m_condition_passed)
+ bp->SetCondition(m_options.m_condition.c_str());
+ }
}
-
- return result.Succeeded();
+ }
}
-private:
- CommandOptions m_options;
-};
+ return result.Succeeded();
+ }
-#pragma mark Modify::CommandOptions
-OptionDefinition
-CommandObjectBreakpointModify::CommandOptions::g_option_table[] =
-{
-{ LLDB_OPT_SET_ALL, false, "ignore-count", 'i', OptionParser::eRequiredArgument, nullptr, nullptr, 0, eArgTypeCount, "Set the number of times this breakpoint is skipped before stopping." },
-{ LLDB_OPT_SET_ALL, false, "one-shot", 'o', OptionParser::eRequiredArgument, nullptr, nullptr, 0, eArgTypeBoolean, "The breakpoint is deleted the first time it stop causes a stop." },
-{ LLDB_OPT_SET_ALL, false, "thread-index", 'x', OptionParser::eRequiredArgument, nullptr, nullptr, 0, eArgTypeThreadIndex, "The breakpoint stops only for the thread whose index matches this argument."},
-{ LLDB_OPT_SET_ALL, false, "thread-id", 't', OptionParser::eRequiredArgument, nullptr, nullptr, 0, eArgTypeThreadID, "The breakpoint stops only for the thread whose TID matches this argument."},
-{ LLDB_OPT_SET_ALL, false, "thread-name", 'T', OptionParser::eRequiredArgument, nullptr, nullptr, 0, eArgTypeThreadName, "The breakpoint stops only for the thread whose thread name matches this argument."},
-{ LLDB_OPT_SET_ALL, false, "queue-name", 'q', OptionParser::eRequiredArgument, nullptr, nullptr, 0, eArgTypeQueueName, "The breakpoint stops only for threads in the queue whose name is given by this argument."},
-{ LLDB_OPT_SET_ALL, false, "condition", 'c', OptionParser::eRequiredArgument, nullptr, nullptr, 0, eArgTypeExpression, "The breakpoint stops only if this condition expression evaluates to true."},
-{ LLDB_OPT_SET_1, false, "enable", 'e', OptionParser::eNoArgument, nullptr, nullptr, 0, eArgTypeNone, "Enable the breakpoint."},
-{ LLDB_OPT_SET_2, false, "disable", 'd', OptionParser::eNoArgument, nullptr, nullptr, 0, eArgTypeNone, "Disable the breakpoint."},
-{ LLDB_OPT_SET_ALL, false, "dummy-breakpoints", 'D', OptionParser::eNoArgument, nullptr, nullptr, 0, eArgTypeNone, "Sets Dummy breakpoints - i.e. breakpoints set before a file is provided, which prime new targets."},
-
-{ 0, false, nullptr, 0 , 0, nullptr, nullptr, 0, eArgTypeNone, nullptr }
+private:
+ CommandOptions m_options;
};
//-------------------------------------------------------------------------
@@ -1193,97 +1052,89 @@ CommandObjectBreakpointModify::CommandOptions::g_option_table[] =
//-------------------------------------------------------------------------
#pragma mark Enable
-class CommandObjectBreakpointEnable : public CommandObjectParsed
-{
+class CommandObjectBreakpointEnable : public CommandObjectParsed {
public:
- CommandObjectBreakpointEnable (CommandInterpreter &interpreter) :
- CommandObjectParsed(interpreter,
- "enable",
- "Enable the specified disabled breakpoint(s). If no breakpoints are specified, enable all of them.",
- nullptr)
- {
- CommandArgumentEntry arg;
- CommandObject::AddIDsArgumentData(arg, eArgTypeBreakpointID, eArgTypeBreakpointIDRange);
- // Add the entry for the first argument for this command to the object's arguments vector.
- m_arguments.push_back (arg);
- }
-
- ~CommandObjectBreakpointEnable() override = default;
+ CommandObjectBreakpointEnable(CommandInterpreter &interpreter)
+ : CommandObjectParsed(interpreter, "enable",
+ "Enable the specified disabled breakpoint(s). If "
+ "no breakpoints are specified, enable all of them.",
+ nullptr) {
+ CommandArgumentEntry arg;
+ CommandObject::AddIDsArgumentData(arg, eArgTypeBreakpointID,
+ eArgTypeBreakpointIDRange);
+ // Add the entry for the first argument for this command to the object's
+ // arguments vector.
+ m_arguments.push_back(arg);
+ }
+
+ ~CommandObjectBreakpointEnable() override = default;
protected:
- bool
- DoExecute (Args& command, CommandReturnObject &result) override
- {
- Target *target = GetSelectedOrDummyTarget();
- if (target == nullptr)
- {
- result.AppendError ("Invalid target. No existing target or breakpoints.");
- result.SetStatus (eReturnStatusFailed);
- return false;
- }
+ bool DoExecute(Args &command, CommandReturnObject &result) override {
+ Target *target = GetSelectedOrDummyTarget();
+ if (target == nullptr) {
+ result.AppendError("Invalid target. No existing target or breakpoints.");
+ result.SetStatus(eReturnStatusFailed);
+ return false;
+ }
- std::unique_lock<std::recursive_mutex> lock;
- target->GetBreakpointList().GetListMutex(lock);
+ std::unique_lock<std::recursive_mutex> lock;
+ target->GetBreakpointList().GetListMutex(lock);
- const BreakpointList &breakpoints = target->GetBreakpointList();
+ const BreakpointList &breakpoints = target->GetBreakpointList();
- size_t num_breakpoints = breakpoints.GetSize();
+ size_t num_breakpoints = breakpoints.GetSize();
- if (num_breakpoints == 0)
- {
- result.AppendError ("No breakpoints exist to be enabled.");
- result.SetStatus (eReturnStatusFailed);
- return false;
- }
+ if (num_breakpoints == 0) {
+ result.AppendError("No breakpoints exist to be enabled.");
+ result.SetStatus(eReturnStatusFailed);
+ return false;
+ }
- if (command.GetArgumentCount() == 0)
- {
- // No breakpoint selected; enable all currently set breakpoints.
- target->EnableAllBreakpoints ();
- result.AppendMessageWithFormat ("All breakpoints enabled. (%" PRIu64 " breakpoints)\n", (uint64_t)num_breakpoints);
- result.SetStatus (eReturnStatusSuccessFinishNoResult);
- }
- else
- {
- // Particular breakpoint selected; enable that breakpoint.
- BreakpointIDList valid_bp_ids;
- CommandObjectMultiwordBreakpoint::VerifyBreakpointOrLocationIDs (command, target, result, &valid_bp_ids);
-
- if (result.Succeeded())
- {
- int enable_count = 0;
- int loc_count = 0;
- const size_t count = valid_bp_ids.GetSize();
- for (size_t i = 0; i < count; ++i)
- {
- BreakpointID cur_bp_id = valid_bp_ids.GetBreakpointIDAtIndex (i);
-
- if (cur_bp_id.GetBreakpointID() != LLDB_INVALID_BREAK_ID)
- {
- Breakpoint *breakpoint = target->GetBreakpointByID (cur_bp_id.GetBreakpointID()).get();
- if (cur_bp_id.GetLocationID() != LLDB_INVALID_BREAK_ID)
- {
- BreakpointLocation *location = breakpoint->FindLocationByID (cur_bp_id.GetLocationID()).get();
- if (location)
- {
- location->SetEnabled (true);
- ++loc_count;
- }
- }
- else
- {
- breakpoint->SetEnabled (true);
- ++enable_count;
- }
- }
- }
- result.AppendMessageWithFormat ("%d breakpoints enabled.\n", enable_count + loc_count);
- result.SetStatus (eReturnStatusSuccessFinishNoResult);
+ if (command.empty()) {
+ // No breakpoint selected; enable all currently set breakpoints.
+ target->EnableAllBreakpoints();
+ result.AppendMessageWithFormat("All breakpoints enabled. (%" PRIu64
+ " breakpoints)\n",
+ (uint64_t)num_breakpoints);
+ result.SetStatus(eReturnStatusSuccessFinishNoResult);
+ } else {
+ // Particular breakpoint selected; enable that breakpoint.
+ BreakpointIDList valid_bp_ids;
+ CommandObjectMultiwordBreakpoint::VerifyBreakpointOrLocationIDs(
+ command, target, result, &valid_bp_ids);
+
+ if (result.Succeeded()) {
+ int enable_count = 0;
+ int loc_count = 0;
+ const size_t count = valid_bp_ids.GetSize();
+ for (size_t i = 0; i < count; ++i) {
+ BreakpointID cur_bp_id = valid_bp_ids.GetBreakpointIDAtIndex(i);
+
+ if (cur_bp_id.GetBreakpointID() != LLDB_INVALID_BREAK_ID) {
+ Breakpoint *breakpoint =
+ target->GetBreakpointByID(cur_bp_id.GetBreakpointID()).get();
+ if (cur_bp_id.GetLocationID() != LLDB_INVALID_BREAK_ID) {
+ BreakpointLocation *location =
+ breakpoint->FindLocationByID(cur_bp_id.GetLocationID()).get();
+ if (location) {
+ location->SetEnabled(true);
+ ++loc_count;
+ }
+ } else {
+ breakpoint->SetEnabled(true);
+ ++enable_count;
}
+ }
}
-
- return result.Succeeded();
+ result.AppendMessageWithFormat("%d breakpoints enabled.\n",
+ enable_count + loc_count);
+ result.SetStatus(eReturnStatusSuccessFinishNoResult);
+ }
}
+
+ return result.Succeeded();
+ }
};
//-------------------------------------------------------------------------
@@ -1291,23 +1142,24 @@ protected:
//-------------------------------------------------------------------------
#pragma mark Disable
-class CommandObjectBreakpointDisable : public CommandObjectParsed
-{
+class CommandObjectBreakpointDisable : public CommandObjectParsed {
public:
- CommandObjectBreakpointDisable(CommandInterpreter &interpreter)
- : CommandObjectParsed(interpreter, "breakpoint disable", "Disable the specified breakpoint(s) without deleting "
- "them. If none are specified, disable all "
- "breakpoints.",
- nullptr)
- {
- SetHelpLong("Disable the specified breakpoint(s) without deleting them. \
+ CommandObjectBreakpointDisable(CommandInterpreter &interpreter)
+ : CommandObjectParsed(
+ interpreter, "breakpoint disable",
+ "Disable the specified breakpoint(s) without deleting "
+ "them. If none are specified, disable all "
+ "breakpoints.",
+ nullptr) {
+ SetHelpLong(
+ "Disable the specified breakpoint(s) without deleting them. \
If none are specified, disable all breakpoints."
- R"(
+ R"(
)"
- "Note: disabling a breakpoint will cause none of its locations to be hit \
+ "Note: disabling a breakpoint will cause none of its locations to be hit \
regardless of whether individual locations are enabled or disabled. After the sequence:"
- R"(
+ R"(
(lldb) break disable 1
(lldb) break enable 1.1
@@ -1318,674 +1170,562 @@ execution will NOT stop at location 1.1. To achieve that, type:
(lldb) break enable 1.1
)"
- "The first command disables all locations for breakpoint 1, \
+ "The first command disables all locations for breakpoint 1, \
the second re-enables the first location.");
- CommandArgumentEntry arg;
- CommandObject::AddIDsArgumentData(arg, eArgTypeBreakpointID, eArgTypeBreakpointIDRange);
- // Add the entry for the first argument for this command to the object's arguments vector.
- m_arguments.push_back (arg);
- }
+ CommandArgumentEntry arg;
+ CommandObject::AddIDsArgumentData(arg, eArgTypeBreakpointID,
+ eArgTypeBreakpointIDRange);
+ // Add the entry for the first argument for this command to the object's
+ // arguments vector.
+ m_arguments.push_back(arg);
+ }
- ~CommandObjectBreakpointDisable() override = default;
+ ~CommandObjectBreakpointDisable() override = default;
protected:
- bool
- DoExecute (Args& command, CommandReturnObject &result) override
- {
- Target *target = GetSelectedOrDummyTarget();
- if (target == nullptr)
- {
- result.AppendError ("Invalid target. No existing target or breakpoints.");
- result.SetStatus (eReturnStatusFailed);
- return false;
- }
+ bool DoExecute(Args &command, CommandReturnObject &result) override {
+ Target *target = GetSelectedOrDummyTarget();
+ if (target == nullptr) {
+ result.AppendError("Invalid target. No existing target or breakpoints.");
+ result.SetStatus(eReturnStatusFailed);
+ return false;
+ }
- std::unique_lock<std::recursive_mutex> lock;
- target->GetBreakpointList().GetListMutex(lock);
+ std::unique_lock<std::recursive_mutex> lock;
+ target->GetBreakpointList().GetListMutex(lock);
- const BreakpointList &breakpoints = target->GetBreakpointList();
- size_t num_breakpoints = breakpoints.GetSize();
+ const BreakpointList &breakpoints = target->GetBreakpointList();
+ size_t num_breakpoints = breakpoints.GetSize();
- if (num_breakpoints == 0)
- {
- result.AppendError ("No breakpoints exist to be disabled.");
- result.SetStatus (eReturnStatusFailed);
- return false;
- }
+ if (num_breakpoints == 0) {
+ result.AppendError("No breakpoints exist to be disabled.");
+ result.SetStatus(eReturnStatusFailed);
+ return false;
+ }
- if (command.GetArgumentCount() == 0)
- {
- // No breakpoint selected; disable all currently set breakpoints.
- target->DisableAllBreakpoints ();
- result.AppendMessageWithFormat ("All breakpoints disabled. (%" PRIu64 " breakpoints)\n", (uint64_t)num_breakpoints);
- result.SetStatus (eReturnStatusSuccessFinishNoResult);
- }
- else
- {
- // Particular breakpoint selected; disable that breakpoint.
- BreakpointIDList valid_bp_ids;
-
- CommandObjectMultiwordBreakpoint::VerifyBreakpointOrLocationIDs (command, target, result, &valid_bp_ids);
-
- if (result.Succeeded())
- {
- int disable_count = 0;
- int loc_count = 0;
- const size_t count = valid_bp_ids.GetSize();
- for (size_t i = 0; i < count; ++i)
- {
- BreakpointID cur_bp_id = valid_bp_ids.GetBreakpointIDAtIndex (i);
-
- if (cur_bp_id.GetBreakpointID() != LLDB_INVALID_BREAK_ID)
- {
- Breakpoint *breakpoint = target->GetBreakpointByID (cur_bp_id.GetBreakpointID()).get();
- if (cur_bp_id.GetLocationID() != LLDB_INVALID_BREAK_ID)
- {
- BreakpointLocation *location = breakpoint->FindLocationByID (cur_bp_id.GetLocationID()).get();
- if (location)
- {
- location->SetEnabled (false);
- ++loc_count;
- }
- }
- else
- {
- breakpoint->SetEnabled (false);
- ++disable_count;
- }
- }
- }
- result.AppendMessageWithFormat ("%d breakpoints disabled.\n", disable_count + loc_count);
- result.SetStatus (eReturnStatusSuccessFinishNoResult);
+ if (command.empty()) {
+ // No breakpoint selected; disable all currently set breakpoints.
+ target->DisableAllBreakpoints();
+ result.AppendMessageWithFormat("All breakpoints disabled. (%" PRIu64
+ " breakpoints)\n",
+ (uint64_t)num_breakpoints);
+ result.SetStatus(eReturnStatusSuccessFinishNoResult);
+ } else {
+ // Particular breakpoint selected; disable that breakpoint.
+ BreakpointIDList valid_bp_ids;
+
+ CommandObjectMultiwordBreakpoint::VerifyBreakpointOrLocationIDs(
+ command, target, result, &valid_bp_ids);
+
+ if (result.Succeeded()) {
+ int disable_count = 0;
+ int loc_count = 0;
+ const size_t count = valid_bp_ids.GetSize();
+ for (size_t i = 0; i < count; ++i) {
+ BreakpointID cur_bp_id = valid_bp_ids.GetBreakpointIDAtIndex(i);
+
+ if (cur_bp_id.GetBreakpointID() != LLDB_INVALID_BREAK_ID) {
+ Breakpoint *breakpoint =
+ target->GetBreakpointByID(cur_bp_id.GetBreakpointID()).get();
+ if (cur_bp_id.GetLocationID() != LLDB_INVALID_BREAK_ID) {
+ BreakpointLocation *location =
+ breakpoint->FindLocationByID(cur_bp_id.GetLocationID()).get();
+ if (location) {
+ location->SetEnabled(false);
+ ++loc_count;
+ }
+ } else {
+ breakpoint->SetEnabled(false);
+ ++disable_count;
}
+ }
}
-
- return result.Succeeded();
+ result.AppendMessageWithFormat("%d breakpoints disabled.\n",
+ disable_count + loc_count);
+ result.SetStatus(eReturnStatusSuccessFinishNoResult);
+ }
}
+
+ return result.Succeeded();
+ }
};
//-------------------------------------------------------------------------
// CommandObjectBreakpointList
//-------------------------------------------------------------------------
-#pragma mark List
-
-class CommandObjectBreakpointList : public CommandObjectParsed
-{
-public:
- CommandObjectBreakpointList (CommandInterpreter &interpreter) :
- CommandObjectParsed(interpreter,
- "breakpoint list",
- "List some or all breakpoints at configurable levels of detail.",
- nullptr),
- m_options (interpreter)
- {
- CommandArgumentEntry arg;
- CommandArgumentData bp_id_arg;
- // Define the first (and only) variant of this arg.
- bp_id_arg.arg_type = eArgTypeBreakpointID;
- bp_id_arg.arg_repetition = eArgRepeatOptional;
+#pragma mark List::CommandOptions
+static OptionDefinition g_breakpoint_list_options[] = {
+ // clang-format off
+ { LLDB_OPT_SET_ALL, false, "internal", 'i', OptionParser::eNoArgument, nullptr, nullptr, 0, eArgTypeNone, "Show debugger internal breakpoints" },
+ { LLDB_OPT_SET_1, false, "brief", 'b', OptionParser::eNoArgument, nullptr, nullptr, 0, eArgTypeNone, "Give a brief description of the breakpoint (no location info)." },
+ // FIXME: We need to add an "internal" command, and then add this sort of thing to it.
+ // But I need to see it for now, and don't want to wait.
+ { LLDB_OPT_SET_2, false, "full", 'f', OptionParser::eNoArgument, nullptr, nullptr, 0, eArgTypeNone, "Give a full description of the breakpoint and its locations." },
+ { LLDB_OPT_SET_3, false, "verbose", 'v', OptionParser::eNoArgument, nullptr, nullptr, 0, eArgTypeNone, "Explain everything we know about the breakpoint (for debugging debugger bugs)." },
+ { LLDB_OPT_SET_ALL, false, "dummy-breakpoints", 'D', OptionParser::eNoArgument, nullptr, nullptr, 0, eArgTypeNone, "List Dummy breakpoints - i.e. breakpoints set before a file is provided, which prime new targets." },
+ // clang-format on
+};
- // There is only one variant this argument could be; put it into the argument entry.
- arg.push_back (bp_id_arg);
+#pragma mark List
- // Push the data for the first argument into the m_arguments vector.
- m_arguments.push_back (arg);
+class CommandObjectBreakpointList : public CommandObjectParsed {
+public:
+ CommandObjectBreakpointList(CommandInterpreter &interpreter)
+ : CommandObjectParsed(
+ interpreter, "breakpoint list",
+ "List some or all breakpoints at configurable levels of detail.",
+ nullptr),
+ m_options() {
+ CommandArgumentEntry arg;
+ CommandArgumentData bp_id_arg;
+
+ // Define the first (and only) variant of this arg.
+ bp_id_arg.arg_type = eArgTypeBreakpointID;
+ bp_id_arg.arg_repetition = eArgRepeatOptional;
+
+ // There is only one variant this argument could be; put it into the
+ // argument entry.
+ arg.push_back(bp_id_arg);
+
+ // Push the data for the first argument into the m_arguments vector.
+ m_arguments.push_back(arg);
+ }
+
+ ~CommandObjectBreakpointList() override = default;
+
+ Options *GetOptions() override { return &m_options; }
+
+ class CommandOptions : public Options {
+ public:
+ CommandOptions()
+ : Options(), m_level(lldb::eDescriptionLevelBrief), m_use_dummy(false) {
}
- ~CommandObjectBreakpointList() override = default;
-
- Options *
- GetOptions () override
- {
- return &m_options;
+ ~CommandOptions() override = default;
+
+ Error SetOptionValue(uint32_t option_idx, llvm::StringRef option_arg,
+ ExecutionContext *execution_context) override {
+ Error error;
+ const int short_option = m_getopt_table[option_idx].val;
+
+ switch (short_option) {
+ case 'b':
+ m_level = lldb::eDescriptionLevelBrief;
+ break;
+ case 'D':
+ m_use_dummy = true;
+ break;
+ case 'f':
+ m_level = lldb::eDescriptionLevelFull;
+ break;
+ case 'v':
+ m_level = lldb::eDescriptionLevelVerbose;
+ break;
+ case 'i':
+ m_internal = true;
+ break;
+ default:
+ error.SetErrorStringWithFormat("unrecognized option '%c'",
+ short_option);
+ break;
+ }
+
+ return error;
}
-
- class CommandOptions : public Options
- {
- public:
- CommandOptions (CommandInterpreter &interpreter) :
- Options (interpreter),
- m_level (lldb::eDescriptionLevelBrief),
- m_use_dummy(false)
- {
- }
-
- ~CommandOptions() override = default;
-
- Error
- SetOptionValue (uint32_t option_idx, const char *option_arg) override
- {
- Error error;
- const int short_option = m_getopt_table[option_idx].val;
-
- switch (short_option)
- {
- case 'b':
- m_level = lldb::eDescriptionLevelBrief;
- break;
- case 'D':
- m_use_dummy = true;
- break;
- case 'f':
- m_level = lldb::eDescriptionLevelFull;
- break;
- case 'v':
- m_level = lldb::eDescriptionLevelVerbose;
- break;
- case 'i':
- m_internal = true;
- break;
- default:
- error.SetErrorStringWithFormat ("unrecognized option '%c'", short_option);
- break;
- }
-
- return error;
- }
- void
- OptionParsingStarting () override
- {
- m_level = lldb::eDescriptionLevelFull;
- m_internal = false;
- m_use_dummy = false;
- }
-
- const OptionDefinition *
- GetDefinitions () override
- {
- return g_option_table;
- }
-
- // Options table: Required for subclasses of Options.
+ void OptionParsingStarting(ExecutionContext *execution_context) override {
+ m_level = lldb::eDescriptionLevelFull;
+ m_internal = false;
+ m_use_dummy = false;
+ }
- static OptionDefinition g_option_table[];
+ llvm::ArrayRef<OptionDefinition> GetDefinitions() override {
+ return llvm::makeArrayRef(g_breakpoint_list_options);
+ }
- // Instance variables to hold the values for command options.
+ // Instance variables to hold the values for command options.
- lldb::DescriptionLevel m_level;
+ lldb::DescriptionLevel m_level;
- bool m_internal;
- bool m_use_dummy;
- };
+ bool m_internal;
+ bool m_use_dummy;
+ };
protected:
- bool
- DoExecute (Args& command, CommandReturnObject &result) override
- {
- Target *target = GetSelectedOrDummyTarget(m_options.m_use_dummy);
-
- if (target == nullptr)
- {
- result.AppendError ("Invalid target. No current target or breakpoints.");
- result.SetStatus (eReturnStatusSuccessFinishNoResult);
- return true;
- }
-
- const BreakpointList &breakpoints = target->GetBreakpointList(m_options.m_internal);
- std::unique_lock<std::recursive_mutex> lock;
- target->GetBreakpointList(m_options.m_internal).GetListMutex(lock);
-
- size_t num_breakpoints = breakpoints.GetSize();
-
- if (num_breakpoints == 0)
- {
- result.AppendMessage ("No breakpoints currently set.");
- result.SetStatus (eReturnStatusSuccessFinishNoResult);
- return true;
- }
-
- Stream &output_stream = result.GetOutputStream();
-
- if (command.GetArgumentCount() == 0)
- {
- // No breakpoint selected; show info about all currently set breakpoints.
- result.AppendMessage ("Current breakpoints:");
- for (size_t i = 0; i < num_breakpoints; ++i)
- {
- Breakpoint *breakpoint = breakpoints.GetBreakpointAtIndex (i).get();
- AddBreakpointDescription (&output_stream, breakpoint, m_options.m_level);
- }
- result.SetStatus (eReturnStatusSuccessFinishNoResult);
- }
- else
- {
- // Particular breakpoints selected; show info about that breakpoint.
- BreakpointIDList valid_bp_ids;
- CommandObjectMultiwordBreakpoint::VerifyBreakpointOrLocationIDs (command, target, result, &valid_bp_ids);
-
- if (result.Succeeded())
- {
- for (size_t i = 0; i < valid_bp_ids.GetSize(); ++i)
- {
- BreakpointID cur_bp_id = valid_bp_ids.GetBreakpointIDAtIndex (i);
- Breakpoint *breakpoint = target->GetBreakpointByID (cur_bp_id.GetBreakpointID()).get();
- AddBreakpointDescription (&output_stream, breakpoint, m_options.m_level);
- }
- result.SetStatus (eReturnStatusSuccessFinishNoResult);
- }
- else
- {
- result.AppendError("Invalid breakpoint ID.");
- result.SetStatus (eReturnStatusFailed);
- }
- }
+ bool DoExecute(Args &command, CommandReturnObject &result) override {
+ Target *target = GetSelectedOrDummyTarget(m_options.m_use_dummy);
- return result.Succeeded();
+ if (target == nullptr) {
+ result.AppendError("Invalid target. No current target or breakpoints.");
+ result.SetStatus(eReturnStatusSuccessFinishNoResult);
+ return true;
}
-private:
- CommandOptions m_options;
-};
+ const BreakpointList &breakpoints =
+ target->GetBreakpointList(m_options.m_internal);
+ std::unique_lock<std::recursive_mutex> lock;
+ target->GetBreakpointList(m_options.m_internal).GetListMutex(lock);
-#pragma mark List::CommandOptions
-OptionDefinition
-CommandObjectBreakpointList::CommandOptions::g_option_table[] =
-{
- { LLDB_OPT_SET_ALL, false, "internal", 'i', OptionParser::eNoArgument, nullptr, nullptr, 0, eArgTypeNone,
- "Show debugger internal breakpoints" },
+ size_t num_breakpoints = breakpoints.GetSize();
- { LLDB_OPT_SET_1, false, "brief", 'b', OptionParser::eNoArgument, nullptr, nullptr, 0, eArgTypeNone,
- "Give a brief description of the breakpoint (no location info)."},
-
- // FIXME: We need to add an "internal" command, and then add this sort of thing to it.
- // But I need to see it for now, and don't want to wait.
- { LLDB_OPT_SET_2, false, "full", 'f', OptionParser::eNoArgument, nullptr, nullptr, 0, eArgTypeNone,
- "Give a full description of the breakpoint and its locations."},
+ if (num_breakpoints == 0) {
+ result.AppendMessage("No breakpoints currently set.");
+ result.SetStatus(eReturnStatusSuccessFinishNoResult);
+ return true;
+ }
- { LLDB_OPT_SET_3, false, "verbose", 'v', OptionParser::eNoArgument, nullptr, nullptr, 0, eArgTypeNone,
- "Explain everything we know about the breakpoint (for debugging debugger bugs)." },
+ Stream &output_stream = result.GetOutputStream();
+
+ if (command.empty()) {
+ // No breakpoint selected; show info about all currently set breakpoints.
+ result.AppendMessage("Current breakpoints:");
+ for (size_t i = 0; i < num_breakpoints; ++i) {
+ Breakpoint *breakpoint = breakpoints.GetBreakpointAtIndex(i).get();
+ AddBreakpointDescription(&output_stream, breakpoint, m_options.m_level);
+ }
+ result.SetStatus(eReturnStatusSuccessFinishNoResult);
+ } else {
+ // Particular breakpoints selected; show info about that breakpoint.
+ BreakpointIDList valid_bp_ids;
+ CommandObjectMultiwordBreakpoint::VerifyBreakpointOrLocationIDs(
+ command, target, result, &valid_bp_ids);
+
+ if (result.Succeeded()) {
+ for (size_t i = 0; i < valid_bp_ids.GetSize(); ++i) {
+ BreakpointID cur_bp_id = valid_bp_ids.GetBreakpointIDAtIndex(i);
+ Breakpoint *breakpoint =
+ target->GetBreakpointByID(cur_bp_id.GetBreakpointID()).get();
+ AddBreakpointDescription(&output_stream, breakpoint,
+ m_options.m_level);
+ }
+ result.SetStatus(eReturnStatusSuccessFinishNoResult);
+ } else {
+ result.AppendError("Invalid breakpoint ID.");
+ result.SetStatus(eReturnStatusFailed);
+ }
+ }
- { LLDB_OPT_SET_ALL, false, "dummy-breakpoints", 'D', OptionParser::eNoArgument, nullptr, nullptr, 0, eArgTypeNone,
- "List Dummy breakpoints - i.e. breakpoints set before a file is provided, which prime new targets."},
+ return result.Succeeded();
+ }
- { 0, false, nullptr, 0, 0, nullptr, nullptr, 0, eArgTypeNone, nullptr }
+private:
+ CommandOptions m_options;
};
//-------------------------------------------------------------------------
// CommandObjectBreakpointClear
//-------------------------------------------------------------------------
-#pragma mark Clear
+#pragma mark Clear::CommandOptions
-class CommandObjectBreakpointClear : public CommandObjectParsed
-{
-public:
- typedef enum BreakpointClearType
- {
- eClearTypeInvalid,
- eClearTypeFileAndLine
- } BreakpointClearType;
-
- CommandObjectBreakpointClear(CommandInterpreter &interpreter)
- : CommandObjectParsed(interpreter, "breakpoint clear",
- "Delete or disable breakpoints matching the specified source file and line.",
- "breakpoint clear <cmd-options>"),
- m_options(interpreter)
- {
- }
+static OptionDefinition g_breakpoint_clear_options[] = {
+ // clang-format off
+ { LLDB_OPT_SET_1, false, "file", 'f', OptionParser::eRequiredArgument, nullptr, nullptr, CommandCompletions::eSourceFileCompletion, eArgTypeFilename, "Specify the breakpoint by source location in this particular file." },
+ { LLDB_OPT_SET_1, true, "line", 'l', OptionParser::eRequiredArgument, nullptr, nullptr, 0, eArgTypeLineNum, "Specify the breakpoint by source location at this particular line." }
+ // clang-format on
+};
- ~CommandObjectBreakpointClear() override = default;
+#pragma mark Clear
- Options *
- GetOptions () override
- {
- return &m_options;
- }
+class CommandObjectBreakpointClear : public CommandObjectParsed {
+public:
+ typedef enum BreakpointClearType {
+ eClearTypeInvalid,
+ eClearTypeFileAndLine
+ } BreakpointClearType;
- class CommandOptions : public Options
- {
- public:
- CommandOptions (CommandInterpreter &interpreter) :
- Options (interpreter),
- m_filename (),
- m_line_num (0)
- {
- }
+ CommandObjectBreakpointClear(CommandInterpreter &interpreter)
+ : CommandObjectParsed(interpreter, "breakpoint clear",
+ "Delete or disable breakpoints matching the "
+ "specified source file and line.",
+ "breakpoint clear <cmd-options>"),
+ m_options() {}
- ~CommandOptions() override = default;
+ ~CommandObjectBreakpointClear() override = default;
- Error
- SetOptionValue (uint32_t option_idx, const char *option_arg) override
- {
- Error error;
- const int short_option = m_getopt_table[option_idx].val;
+ Options *GetOptions() override { return &m_options; }
- switch (short_option)
- {
- case 'f':
- m_filename.assign (option_arg);
- break;
+ class CommandOptions : public Options {
+ public:
+ CommandOptions() : Options(), m_filename(), m_line_num(0) {}
- case 'l':
- m_line_num = StringConvert::ToUInt32 (option_arg, 0);
- break;
+ ~CommandOptions() override = default;
- default:
- error.SetErrorStringWithFormat ("unrecognized option '%c'", short_option);
- break;
- }
+ Error SetOptionValue(uint32_t option_idx, llvm::StringRef option_arg,
+ ExecutionContext *execution_context) override {
+ Error error;
+ const int short_option = m_getopt_table[option_idx].val;
- return error;
- }
+ switch (short_option) {
+ case 'f':
+ m_filename.assign(option_arg);
+ break;
- void
- OptionParsingStarting () override
- {
- m_filename.clear();
- m_line_num = 0;
- }
+ case 'l':
+ option_arg.getAsInteger(0, m_line_num);
+ break;
- const OptionDefinition*
- GetDefinitions () override
- {
- return g_option_table;
- }
+ default:
+ error.SetErrorStringWithFormat("unrecognized option '%c'",
+ short_option);
+ break;
+ }
- // Options table: Required for subclasses of Options.
+ return error;
+ }
- static OptionDefinition g_option_table[];
+ void OptionParsingStarting(ExecutionContext *execution_context) override {
+ m_filename.clear();
+ m_line_num = 0;
+ }
- // Instance variables to hold the values for command options.
+ llvm::ArrayRef<OptionDefinition> GetDefinitions() override {
+ return llvm::makeArrayRef(g_breakpoint_clear_options);
+ }
- std::string m_filename;
- uint32_t m_line_num;
+ // Instance variables to hold the values for command options.
- };
+ std::string m_filename;
+ uint32_t m_line_num;
+ };
protected:
- bool
- DoExecute (Args& command, CommandReturnObject &result) override
- {
- Target *target = GetSelectedOrDummyTarget();
- if (target == nullptr)
- {
- result.AppendError ("Invalid target. No existing target or breakpoints.");
- result.SetStatus (eReturnStatusFailed);
- return false;
- }
+ bool DoExecute(Args &command, CommandReturnObject &result) override {
+ Target *target = GetSelectedOrDummyTarget();
+ if (target == nullptr) {
+ result.AppendError("Invalid target. No existing target or breakpoints.");
+ result.SetStatus(eReturnStatusFailed);
+ return false;
+ }
- // The following are the various types of breakpoints that could be cleared:
- // 1). -f -l (clearing breakpoint by source location)
+ // The following are the various types of breakpoints that could be cleared:
+ // 1). -f -l (clearing breakpoint by source location)
- BreakpointClearType break_type = eClearTypeInvalid;
+ BreakpointClearType break_type = eClearTypeInvalid;
- if (m_options.m_line_num != 0)
- break_type = eClearTypeFileAndLine;
+ if (m_options.m_line_num != 0)
+ break_type = eClearTypeFileAndLine;
- std::unique_lock<std::recursive_mutex> lock;
- target->GetBreakpointList().GetListMutex(lock);
+ std::unique_lock<std::recursive_mutex> lock;
+ target->GetBreakpointList().GetListMutex(lock);
- BreakpointList &breakpoints = target->GetBreakpointList();
- size_t num_breakpoints = breakpoints.GetSize();
+ BreakpointList &breakpoints = target->GetBreakpointList();
+ size_t num_breakpoints = breakpoints.GetSize();
- // Early return if there's no breakpoint at all.
- if (num_breakpoints == 0)
- {
- result.AppendError ("Breakpoint clear: No breakpoint cleared.");
- result.SetStatus (eReturnStatusFailed);
- return result.Succeeded();
- }
+ // Early return if there's no breakpoint at all.
+ if (num_breakpoints == 0) {
+ result.AppendError("Breakpoint clear: No breakpoint cleared.");
+ result.SetStatus(eReturnStatusFailed);
+ return result.Succeeded();
+ }
- // Find matching breakpoints and delete them.
-
- // First create a copy of all the IDs.
- std::vector<break_id_t> BreakIDs;
- for (size_t i = 0; i < num_breakpoints; ++i)
- BreakIDs.push_back(breakpoints.GetBreakpointAtIndex(i)->GetID());
-
- int num_cleared = 0;
- StreamString ss;
- switch (break_type)
- {
- case eClearTypeFileAndLine: // Breakpoint by source position
- {
- const ConstString filename(m_options.m_filename.c_str());
- BreakpointLocationCollection loc_coll;
-
- for (size_t i = 0; i < num_breakpoints; ++i)
- {
- Breakpoint *bp = breakpoints.FindBreakpointByID(BreakIDs[i]).get();
-
- if (bp->GetMatchingFileLine(filename, m_options.m_line_num, loc_coll))
- {
- // If the collection size is 0, it's a full match and we can just remove the breakpoint.
- if (loc_coll.GetSize() == 0)
- {
- bp->GetDescription(&ss, lldb::eDescriptionLevelBrief);
- ss.EOL();
- target->RemoveBreakpointByID (bp->GetID());
- ++num_cleared;
- }
- }
- }
- }
- break;
-
- default:
- break;
- }
+ // Find matching breakpoints and delete them.
- if (num_cleared > 0)
- {
- Stream &output_stream = result.GetOutputStream();
- output_stream.Printf ("%d breakpoints cleared:\n", num_cleared);
- output_stream << ss.GetData();
- output_stream.EOL();
- result.SetStatus (eReturnStatusSuccessFinishNoResult);
- }
- else
- {
- result.AppendError ("Breakpoint clear: No breakpoint cleared.");
- result.SetStatus (eReturnStatusFailed);
- }
+ // First create a copy of all the IDs.
+ std::vector<break_id_t> BreakIDs;
+ for (size_t i = 0; i < num_breakpoints; ++i)
+ BreakIDs.push_back(breakpoints.GetBreakpointAtIndex(i)->GetID());
- return result.Succeeded();
+ int num_cleared = 0;
+ StreamString ss;
+ switch (break_type) {
+ case eClearTypeFileAndLine: // Breakpoint by source position
+ {
+ const ConstString filename(m_options.m_filename.c_str());
+ BreakpointLocationCollection loc_coll;
+
+ for (size_t i = 0; i < num_breakpoints; ++i) {
+ Breakpoint *bp = breakpoints.FindBreakpointByID(BreakIDs[i]).get();
+
+ if (bp->GetMatchingFileLine(filename, m_options.m_line_num, loc_coll)) {
+ // If the collection size is 0, it's a full match and we can just
+ // remove the breakpoint.
+ if (loc_coll.GetSize() == 0) {
+ bp->GetDescription(&ss, lldb::eDescriptionLevelBrief);
+ ss.EOL();
+ target->RemoveBreakpointByID(bp->GetID());
+ ++num_cleared;
+ }
+ }
+ }
+ } break;
+
+ default:
+ break;
}
-private:
- CommandOptions m_options;
-};
-
-#pragma mark Clear::CommandOptions
-
-OptionDefinition
-CommandObjectBreakpointClear::CommandOptions::g_option_table[] =
-{
- { LLDB_OPT_SET_1, false, "file", 'f', OptionParser::eRequiredArgument, nullptr, nullptr, CommandCompletions::eSourceFileCompletion, eArgTypeFilename,
- "Specify the breakpoint by source location in this particular file."},
+ if (num_cleared > 0) {
+ Stream &output_stream = result.GetOutputStream();
+ output_stream.Printf("%d breakpoints cleared:\n", num_cleared);
+ output_stream << ss.GetString();
+ output_stream.EOL();
+ result.SetStatus(eReturnStatusSuccessFinishNoResult);
+ } else {
+ result.AppendError("Breakpoint clear: No breakpoint cleared.");
+ result.SetStatus(eReturnStatusFailed);
+ }
- { LLDB_OPT_SET_1, true, "line", 'l', OptionParser::eRequiredArgument, nullptr, nullptr, 0, eArgTypeLineNum,
- "Specify the breakpoint by source location at this particular line."},
+ return result.Succeeded();
+ }
- { 0, false, nullptr, 0, 0, nullptr, nullptr, 0, eArgTypeNone, nullptr }
+private:
+ CommandOptions m_options;
};
//-------------------------------------------------------------------------
// CommandObjectBreakpointDelete
//-------------------------------------------------------------------------
+static OptionDefinition g_breakpoint_delete_options[] = {
+ // clang-format off
+ { LLDB_OPT_SET_1, false, "force", 'f', OptionParser::eNoArgument, nullptr, nullptr, 0, eArgTypeNone, "Delete all breakpoints without querying for confirmation." },
+ { LLDB_OPT_SET_1, false, "dummy-breakpoints", 'D', OptionParser::eNoArgument, nullptr, nullptr, 0, eArgTypeNone, "Delete Dummy breakpoints - i.e. breakpoints set before a file is provided, which prime new targets." },
+ // clang-format on
+};
+
#pragma mark Delete
-class CommandObjectBreakpointDelete : public CommandObjectParsed
-{
+class CommandObjectBreakpointDelete : public CommandObjectParsed {
public:
- CommandObjectBreakpointDelete (CommandInterpreter &interpreter) :
- CommandObjectParsed(interpreter,
- "breakpoint delete",
- "Delete the specified breakpoint(s). If no breakpoints are specified, delete them all.",
+ CommandObjectBreakpointDelete(CommandInterpreter &interpreter)
+ : CommandObjectParsed(interpreter, "breakpoint delete",
+ "Delete the specified breakpoint(s). If no "
+ "breakpoints are specified, delete them all.",
nullptr),
- m_options (interpreter)
- {
- CommandArgumentEntry arg;
- CommandObject::AddIDsArgumentData(arg, eArgTypeBreakpointID, eArgTypeBreakpointIDRange);
- // Add the entry for the first argument for this command to the object's arguments vector.
- m_arguments.push_back (arg);
+ m_options() {
+ CommandArgumentEntry arg;
+ CommandObject::AddIDsArgumentData(arg, eArgTypeBreakpointID,
+ eArgTypeBreakpointIDRange);
+ // Add the entry for the first argument for this command to the object's
+ // arguments vector.
+ m_arguments.push_back(arg);
+ }
+
+ ~CommandObjectBreakpointDelete() override = default;
+
+ Options *GetOptions() override { return &m_options; }
+
+ class CommandOptions : public Options {
+ public:
+ CommandOptions() : Options(), m_use_dummy(false), m_force(false) {}
+
+ ~CommandOptions() override = default;
+
+ Error SetOptionValue(uint32_t option_idx, llvm::StringRef option_arg,
+ ExecutionContext *execution_context) override {
+ Error error;
+ const int short_option = m_getopt_table[option_idx].val;
+
+ switch (short_option) {
+ case 'f':
+ m_force = true;
+ break;
+
+ case 'D':
+ m_use_dummy = true;
+ break;
+
+ default:
+ error.SetErrorStringWithFormat("unrecognized option '%c'",
+ short_option);
+ break;
+ }
+
+ return error;
}
- ~CommandObjectBreakpointDelete() override = default;
-
- Options *
- GetOptions () override
- {
- return &m_options;
+ void OptionParsingStarting(ExecutionContext *execution_context) override {
+ m_use_dummy = false;
+ m_force = false;
}
- class CommandOptions : public Options
- {
- public:
- CommandOptions (CommandInterpreter &interpreter) :
- Options (interpreter),
- m_use_dummy (false),
- m_force (false)
- {
- }
-
- ~CommandOptions() override = default;
-
- Error
- SetOptionValue (uint32_t option_idx, const char *option_arg) override
- {
- Error error;
- const int short_option = m_getopt_table[option_idx].val;
-
- switch (short_option)
- {
- case 'f':
- m_force = true;
- break;
-
- case 'D':
- m_use_dummy = true;
- break;
-
- default:
- error.SetErrorStringWithFormat ("unrecognized option '%c'", short_option);
- break;
- }
-
- return error;
- }
-
- void
- OptionParsingStarting () override
- {
- m_use_dummy = false;
- m_force = false;
- }
-
- const OptionDefinition*
- GetDefinitions () override
- {
- return g_option_table;
- }
-
- // Options table: Required for subclasses of Options.
-
- static OptionDefinition g_option_table[];
+ llvm::ArrayRef<OptionDefinition> GetDefinitions() override {
+ return llvm::makeArrayRef(g_breakpoint_delete_options);
+ }
- // Instance variables to hold the values for command options.
- bool m_use_dummy;
- bool m_force;
- };
+ // Instance variables to hold the values for command options.
+ bool m_use_dummy;
+ bool m_force;
+ };
protected:
- bool
- DoExecute (Args& command, CommandReturnObject &result) override
- {
- Target *target = GetSelectedOrDummyTarget(m_options.m_use_dummy);
+ bool DoExecute(Args &command, CommandReturnObject &result) override {
+ Target *target = GetSelectedOrDummyTarget(m_options.m_use_dummy);
- if (target == nullptr)
- {
- result.AppendError ("Invalid target. No existing target or breakpoints.");
- result.SetStatus (eReturnStatusFailed);
- return false;
- }
+ if (target == nullptr) {
+ result.AppendError("Invalid target. No existing target or breakpoints.");
+ result.SetStatus(eReturnStatusFailed);
+ return false;
+ }
- std::unique_lock<std::recursive_mutex> lock;
- target->GetBreakpointList().GetListMutex(lock);
+ std::unique_lock<std::recursive_mutex> lock;
+ target->GetBreakpointList().GetListMutex(lock);
- const BreakpointList &breakpoints = target->GetBreakpointList();
+ const BreakpointList &breakpoints = target->GetBreakpointList();
- size_t num_breakpoints = breakpoints.GetSize();
+ size_t num_breakpoints = breakpoints.GetSize();
- if (num_breakpoints == 0)
- {
- result.AppendError ("No breakpoints exist to be deleted.");
- result.SetStatus (eReturnStatusFailed);
- return false;
- }
+ if (num_breakpoints == 0) {
+ result.AppendError("No breakpoints exist to be deleted.");
+ result.SetStatus(eReturnStatusFailed);
+ return false;
+ }
- if (command.GetArgumentCount() == 0)
- {
- if (!m_options.m_force && !m_interpreter.Confirm ("About to delete all breakpoints, do you want to do that?", true))
- {
- result.AppendMessage("Operation cancelled...");
- }
- else
- {
- target->RemoveAllBreakpoints ();
- result.AppendMessageWithFormat ("All breakpoints removed. (%" PRIu64 " breakpoint%s)\n", (uint64_t)num_breakpoints, num_breakpoints > 1 ? "s" : "");
+ if (command.empty()) {
+ if (!m_options.m_force &&
+ !m_interpreter.Confirm(
+ "About to delete all breakpoints, do you want to do that?",
+ true)) {
+ result.AppendMessage("Operation cancelled...");
+ } else {
+ target->RemoveAllBreakpoints();
+ result.AppendMessageWithFormat(
+ "All breakpoints removed. (%" PRIu64 " breakpoint%s)\n",
+ (uint64_t)num_breakpoints, num_breakpoints > 1 ? "s" : "");
+ }
+ result.SetStatus(eReturnStatusSuccessFinishNoResult);
+ } else {
+ // Particular breakpoint selected; disable that breakpoint.
+ BreakpointIDList valid_bp_ids;
+ CommandObjectMultiwordBreakpoint::VerifyBreakpointOrLocationIDs(
+ command, target, result, &valid_bp_ids);
+
+ if (result.Succeeded()) {
+ int delete_count = 0;
+ int disable_count = 0;
+ const size_t count = valid_bp_ids.GetSize();
+ for (size_t i = 0; i < count; ++i) {
+ BreakpointID cur_bp_id = valid_bp_ids.GetBreakpointIDAtIndex(i);
+
+ if (cur_bp_id.GetBreakpointID() != LLDB_INVALID_BREAK_ID) {
+ if (cur_bp_id.GetLocationID() != LLDB_INVALID_BREAK_ID) {
+ Breakpoint *breakpoint =
+ target->GetBreakpointByID(cur_bp_id.GetBreakpointID()).get();
+ BreakpointLocation *location =
+ breakpoint->FindLocationByID(cur_bp_id.GetLocationID()).get();
+ // It makes no sense to try to delete individual locations, so we
+ // disable them instead.
+ if (location) {
+ location->SetEnabled(false);
+ ++disable_count;
+ }
+ } else {
+ target->RemoveBreakpointByID(cur_bp_id.GetBreakpointID());
+ ++delete_count;
}
- result.SetStatus (eReturnStatusSuccessFinishNoResult);
+ }
}
- else
- {
- // Particular breakpoint selected; disable that breakpoint.
- BreakpointIDList valid_bp_ids;
- CommandObjectMultiwordBreakpoint::VerifyBreakpointOrLocationIDs (command, target, result, &valid_bp_ids);
-
- if (result.Succeeded())
- {
- int delete_count = 0;
- int disable_count = 0;
- const size_t count = valid_bp_ids.GetSize();
- for (size_t i = 0; i < count; ++i)
- {
- BreakpointID cur_bp_id = valid_bp_ids.GetBreakpointIDAtIndex (i);
-
- if (cur_bp_id.GetBreakpointID() != LLDB_INVALID_BREAK_ID)
- {
- if (cur_bp_id.GetLocationID() != LLDB_INVALID_BREAK_ID)
- {
- Breakpoint *breakpoint = target->GetBreakpointByID (cur_bp_id.GetBreakpointID()).get();
- BreakpointLocation *location = breakpoint->FindLocationByID (cur_bp_id.GetLocationID()).get();
- // It makes no sense to try to delete individual locations, so we disable them instead.
- if (location)
- {
- location->SetEnabled (false);
- ++disable_count;
- }
- }
- else
- {
- target->RemoveBreakpointByID (cur_bp_id.GetBreakpointID());
- ++delete_count;
- }
- }
- }
- result.AppendMessageWithFormat ("%d breakpoints deleted; %d breakpoint locations disabled.\n",
- delete_count, disable_count);
- result.SetStatus (eReturnStatusSuccessFinishNoResult);
- }
- }
- return result.Succeeded();
+ result.AppendMessageWithFormat(
+ "%d breakpoints deleted; %d breakpoint locations disabled.\n",
+ delete_count, disable_count);
+ result.SetStatus(eReturnStatusSuccessFinishNoResult);
+ }
}
+ return result.Succeeded();
+ }
private:
- CommandOptions m_options;
-};
-
-OptionDefinition
-CommandObjectBreakpointDelete::CommandOptions::g_option_table[] =
-{
- { LLDB_OPT_SET_1, false, "force", 'f', OptionParser::eNoArgument, nullptr, nullptr, 0, eArgTypeNone,
- "Delete all breakpoints without querying for confirmation."},
-
- { LLDB_OPT_SET_1, false, "dummy-breakpoints", 'D', OptionParser::eNoArgument, nullptr, nullptr, 0, eArgTypeNone,
- "Delete Dummy breakpoints - i.e. breakpoints set before a file is provided, which prime new targets."},
-
- { 0, false, nullptr, 0, 0, nullptr, nullptr, 0, eArgTypeNone, nullptr }
+ CommandOptions m_options;
};
//-------------------------------------------------------------------------
@@ -1993,375 +1733,566 @@ CommandObjectBreakpointDelete::CommandOptions::g_option_table[] =
//-------------------------------------------------------------------------
static OptionDefinition g_breakpoint_name_options[] = {
- {LLDB_OPT_SET_1, false, "name", 'N', OptionParser::eRequiredArgument, nullptr, nullptr, 0, eArgTypeBreakpointName,
- "Specifies a breakpoint name to use."},
- {LLDB_OPT_SET_2, false, "breakpoint-id", 'B', OptionParser::eRequiredArgument, nullptr, nullptr, 0,
- eArgTypeBreakpointID, "Specify a breakpoint ID to use."},
- {LLDB_OPT_SET_ALL, false, "dummy-breakpoints", 'D', OptionParser::eNoArgument, nullptr, nullptr, 0, eArgTypeNone,
- "Operate on Dummy breakpoints - i.e. breakpoints set before a file is provided, which prime new targets."},
+ // clang-format off
+ {LLDB_OPT_SET_1, false, "name", 'N', OptionParser::eRequiredArgument, nullptr, nullptr, 0, eArgTypeBreakpointName, "Specifies a breakpoint name to use."},
+ {LLDB_OPT_SET_2, false, "breakpoint-id", 'B', OptionParser::eRequiredArgument, nullptr, nullptr, 0, eArgTypeBreakpointID, "Specify a breakpoint ID to use."},
+ {LLDB_OPT_SET_ALL, false, "dummy-breakpoints", 'D', OptionParser::eNoArgument, nullptr, nullptr, 0, eArgTypeNone, "Operate on Dummy breakpoints - i.e. breakpoints set before a file is provided, which prime new targets."},
+ // clang-format on
};
-class BreakpointNameOptionGroup : public OptionGroup
-{
+class BreakpointNameOptionGroup : public OptionGroup {
public:
- BreakpointNameOptionGroup() :
- OptionGroup(),
- m_breakpoint(LLDB_INVALID_BREAK_ID),
- m_use_dummy (false)
- {
+ BreakpointNameOptionGroup()
+ : OptionGroup(), m_breakpoint(LLDB_INVALID_BREAK_ID), m_use_dummy(false) {
+ }
+
+ ~BreakpointNameOptionGroup() override = default;
+
+ llvm::ArrayRef<OptionDefinition> GetDefinitions() override {
+ return llvm::makeArrayRef(g_breakpoint_name_options);
+ }
+
+ Error SetOptionValue(uint32_t option_idx, llvm::StringRef option_arg,
+ ExecutionContext *execution_context) override {
+ Error error;
+ const int short_option = g_breakpoint_name_options[option_idx].short_option;
+
+ switch (short_option) {
+ case 'N':
+ if (BreakpointID::StringIsBreakpointName(option_arg, error) &&
+ error.Success())
+ m_name.SetValueFromString(option_arg);
+ break;
+
+ case 'B':
+ if (m_breakpoint.SetValueFromString(option_arg).Fail())
+ error.SetErrorStringWithFormat(
+ "unrecognized value \"%s\" for breakpoint",
+ option_arg.str().c_str());
+ break;
+ case 'D':
+ if (m_use_dummy.SetValueFromString(option_arg).Fail())
+ error.SetErrorStringWithFormat(
+ "unrecognized value \"%s\" for use-dummy",
+ option_arg.str().c_str());
+ break;
+
+ default:
+ error.SetErrorStringWithFormat("unrecognized short option '%c'",
+ short_option);
+ break;
}
+ return error;
+ }
+
+ void OptionParsingStarting(ExecutionContext *execution_context) override {
+ m_name.Clear();
+ m_breakpoint.Clear();
+ m_use_dummy.Clear();
+ m_use_dummy.SetDefaultValue(false);
+ }
+
+ OptionValueString m_name;
+ OptionValueUInt64 m_breakpoint;
+ OptionValueBoolean m_use_dummy;
+};
- ~BreakpointNameOptionGroup() override = default;
+class CommandObjectBreakpointNameAdd : public CommandObjectParsed {
+public:
+ CommandObjectBreakpointNameAdd(CommandInterpreter &interpreter)
+ : CommandObjectParsed(
+ interpreter, "add", "Add a name to the breakpoints provided.",
+ "breakpoint name add <command-options> <breakpoint-id-list>"),
+ m_name_options(), m_option_group() {
+ // Create the first variant for the first (and only) argument for this
+ // command.
+ CommandArgumentEntry arg1;
+ CommandArgumentData id_arg;
+ id_arg.arg_type = eArgTypeBreakpointID;
+ id_arg.arg_repetition = eArgRepeatOptional;
+ arg1.push_back(id_arg);
+ m_arguments.push_back(arg1);
+
+ m_option_group.Append(&m_name_options, LLDB_OPT_SET_1, LLDB_OPT_SET_ALL);
+ m_option_group.Finalize();
+ }
+
+ ~CommandObjectBreakpointNameAdd() override = default;
+
+ Options *GetOptions() override { return &m_option_group; }
- uint32_t
- GetNumDefinitions () override
- {
- return sizeof (g_breakpoint_name_options) / sizeof (OptionDefinition);
+protected:
+ bool DoExecute(Args &command, CommandReturnObject &result) override {
+ if (!m_name_options.m_name.OptionWasSet()) {
+ result.SetError("No name option provided.");
+ return false;
}
- const OptionDefinition*
- GetDefinitions () override
- {
- return g_breakpoint_name_options;
+ Target *target =
+ GetSelectedOrDummyTarget(m_name_options.m_use_dummy.GetCurrentValue());
+
+ if (target == nullptr) {
+ result.AppendError("Invalid target. No existing target or breakpoints.");
+ result.SetStatus(eReturnStatusFailed);
+ return false;
}
- Error
- SetOptionValue (CommandInterpreter &interpreter,
- uint32_t option_idx,
- const char *option_value) override
- {
- Error error;
- const int short_option = g_breakpoint_name_options[option_idx].short_option;
-
- switch (short_option)
- {
- case 'N':
- if (BreakpointID::StringIsBreakpointName(option_value, error) && error.Success())
- m_name.SetValueFromString(option_value);
- break;
-
- case 'B':
- if (m_breakpoint.SetValueFromString(option_value).Fail())
- error.SetErrorStringWithFormat ("unrecognized value \"%s\" for breakpoint", option_value);
- break;
- case 'D':
- if (m_use_dummy.SetValueFromString(option_value).Fail())
- error.SetErrorStringWithFormat ("unrecognized value \"%s\" for use-dummy", option_value);
- break;
+ std::unique_lock<std::recursive_mutex> lock;
+ target->GetBreakpointList().GetListMutex(lock);
- default:
- error.SetErrorStringWithFormat("unrecognized short option '%c'", short_option);
- break;
- }
- return error;
+ const BreakpointList &breakpoints = target->GetBreakpointList();
+
+ size_t num_breakpoints = breakpoints.GetSize();
+ if (num_breakpoints == 0) {
+ result.SetError("No breakpoints, cannot add names.");
+ result.SetStatus(eReturnStatusFailed);
+ return false;
}
- void
- OptionParsingStarting (CommandInterpreter &interpreter) override
- {
- m_name.Clear();
- m_breakpoint.Clear();
- m_use_dummy.Clear();
- m_use_dummy.SetDefaultValue(false);
+ // Particular breakpoint selected; disable that breakpoint.
+ BreakpointIDList valid_bp_ids;
+ CommandObjectMultiwordBreakpoint::VerifyBreakpointIDs(
+ command, target, result, &valid_bp_ids);
+
+ if (result.Succeeded()) {
+ if (valid_bp_ids.GetSize() == 0) {
+ result.SetError("No breakpoints specified, cannot add names.");
+ result.SetStatus(eReturnStatusFailed);
+ return false;
+ }
+ size_t num_valid_ids = valid_bp_ids.GetSize();
+ for (size_t index = 0; index < num_valid_ids; index++) {
+ lldb::break_id_t bp_id =
+ valid_bp_ids.GetBreakpointIDAtIndex(index).GetBreakpointID();
+ BreakpointSP bp_sp = breakpoints.FindBreakpointByID(bp_id);
+ Error error; // We don't need to check the error here, since the option
+ // parser checked it...
+ bp_sp->AddName(m_name_options.m_name.GetCurrentValue(), error);
+ }
}
- OptionValueString m_name;
- OptionValueUInt64 m_breakpoint;
- OptionValueBoolean m_use_dummy;
+ return true;
+ }
+
+private:
+ BreakpointNameOptionGroup m_name_options;
+ OptionGroupOptions m_option_group;
};
-class CommandObjectBreakpointNameAdd : public CommandObjectParsed
-{
+class CommandObjectBreakpointNameDelete : public CommandObjectParsed {
public:
- CommandObjectBreakpointNameAdd (CommandInterpreter &interpreter) :
- CommandObjectParsed (interpreter,
- "add",
- "Add a name to the breakpoints provided.",
- "breakpoint name add <command-options> <breakpoint-id-list>"),
- m_name_options(),
- m_option_group(interpreter)
- {
- // Create the first variant for the first (and only) argument for this command.
- CommandArgumentEntry arg1;
- CommandArgumentData id_arg;
- id_arg.arg_type = eArgTypeBreakpointID;
- id_arg.arg_repetition = eArgRepeatOptional;
- arg1.push_back(id_arg);
- m_arguments.push_back (arg1);
-
- m_option_group.Append (&m_name_options, LLDB_OPT_SET_1, LLDB_OPT_SET_ALL);
- m_option_group.Finalize();
- }
+ CommandObjectBreakpointNameDelete(CommandInterpreter &interpreter)
+ : CommandObjectParsed(
+ interpreter, "delete",
+ "Delete a name from the breakpoints provided.",
+ "breakpoint name delete <command-options> <breakpoint-id-list>"),
+ m_name_options(), m_option_group() {
+ // Create the first variant for the first (and only) argument for this
+ // command.
+ CommandArgumentEntry arg1;
+ CommandArgumentData id_arg;
+ id_arg.arg_type = eArgTypeBreakpointID;
+ id_arg.arg_repetition = eArgRepeatOptional;
+ arg1.push_back(id_arg);
+ m_arguments.push_back(arg1);
+
+ m_option_group.Append(&m_name_options, LLDB_OPT_SET_1, LLDB_OPT_SET_ALL);
+ m_option_group.Finalize();
+ }
+
+ ~CommandObjectBreakpointNameDelete() override = default;
+
+ Options *GetOptions() override { return &m_option_group; }
+
+protected:
+ bool DoExecute(Args &command, CommandReturnObject &result) override {
+ if (!m_name_options.m_name.OptionWasSet()) {
+ result.SetError("No name option provided.");
+ return false;
+ }
- ~CommandObjectBreakpointNameAdd() override = default;
+ Target *target =
+ GetSelectedOrDummyTarget(m_name_options.m_use_dummy.GetCurrentValue());
- Options *
- GetOptions() override
- {
- return &m_option_group;
+ if (target == nullptr) {
+ result.AppendError("Invalid target. No existing target or breakpoints.");
+ result.SetStatus(eReturnStatusFailed);
+ return false;
}
-protected:
- bool
- DoExecute (Args& command, CommandReturnObject &result) override
- {
- if (!m_name_options.m_name.OptionWasSet())
- {
- result.SetError("No name option provided.");
- return false;
- }
+ std::unique_lock<std::recursive_mutex> lock;
+ target->GetBreakpointList().GetListMutex(lock);
- Target *target = GetSelectedOrDummyTarget(m_name_options.m_use_dummy.GetCurrentValue());
+ const BreakpointList &breakpoints = target->GetBreakpointList();
- if (target == nullptr)
- {
- result.AppendError ("Invalid target. No existing target or breakpoints.");
- result.SetStatus (eReturnStatusFailed);
- return false;
- }
+ size_t num_breakpoints = breakpoints.GetSize();
+ if (num_breakpoints == 0) {
+ result.SetError("No breakpoints, cannot delete names.");
+ result.SetStatus(eReturnStatusFailed);
+ return false;
+ }
- std::unique_lock<std::recursive_mutex> lock;
- target->GetBreakpointList().GetListMutex(lock);
+ // Particular breakpoint selected; disable that breakpoint.
+ BreakpointIDList valid_bp_ids;
+ CommandObjectMultiwordBreakpoint::VerifyBreakpointIDs(
+ command, target, result, &valid_bp_ids);
+
+ if (result.Succeeded()) {
+ if (valid_bp_ids.GetSize() == 0) {
+ result.SetError("No breakpoints specified, cannot delete names.");
+ result.SetStatus(eReturnStatusFailed);
+ return false;
+ }
+ size_t num_valid_ids = valid_bp_ids.GetSize();
+ for (size_t index = 0; index < num_valid_ids; index++) {
+ lldb::break_id_t bp_id =
+ valid_bp_ids.GetBreakpointIDAtIndex(index).GetBreakpointID();
+ BreakpointSP bp_sp = breakpoints.FindBreakpointByID(bp_id);
+ bp_sp->RemoveName(m_name_options.m_name.GetCurrentValue());
+ }
+ }
- const BreakpointList &breakpoints = target->GetBreakpointList();
+ return true;
+ }
- size_t num_breakpoints = breakpoints.GetSize();
- if (num_breakpoints == 0)
- {
- result.SetError("No breakpoints, cannot add names.");
- result.SetStatus (eReturnStatusFailed);
- return false;
- }
+private:
+ BreakpointNameOptionGroup m_name_options;
+ OptionGroupOptions m_option_group;
+};
- // Particular breakpoint selected; disable that breakpoint.
- BreakpointIDList valid_bp_ids;
- CommandObjectMultiwordBreakpoint::VerifyBreakpointIDs (command, target, result, &valid_bp_ids);
-
- if (result.Succeeded())
- {
- if (valid_bp_ids.GetSize() == 0)
- {
- result.SetError("No breakpoints specified, cannot add names.");
- result.SetStatus (eReturnStatusFailed);
- return false;
- }
- size_t num_valid_ids = valid_bp_ids.GetSize();
- for (size_t index = 0; index < num_valid_ids; index++)
- {
- lldb::break_id_t bp_id = valid_bp_ids.GetBreakpointIDAtIndex(index).GetBreakpointID();
- BreakpointSP bp_sp = breakpoints.FindBreakpointByID(bp_id);
- Error error; // We don't need to check the error here, since the option parser checked it...
- bp_sp->AddName(m_name_options.m_name.GetCurrentValue(), error);
- }
- }
+class CommandObjectBreakpointNameList : public CommandObjectParsed {
+public:
+ CommandObjectBreakpointNameList(CommandInterpreter &interpreter)
+ : CommandObjectParsed(interpreter, "list",
+ "List either the names for a breakpoint or the "
+ "breakpoints for a given name.",
+ "breakpoint name list <command-options>"),
+ m_name_options(), m_option_group() {
+ m_option_group.Append(&m_name_options);
+ m_option_group.Finalize();
+ }
- return true;
+ ~CommandObjectBreakpointNameList() override = default;
+
+ Options *GetOptions() override { return &m_option_group; }
+
+protected:
+ bool DoExecute(Args &command, CommandReturnObject &result) override {
+ Target *target =
+ GetSelectedOrDummyTarget(m_name_options.m_use_dummy.GetCurrentValue());
+
+ if (target == nullptr) {
+ result.AppendError("Invalid target. No existing target or breakpoints.");
+ result.SetStatus(eReturnStatusFailed);
+ return false;
}
+ if (m_name_options.m_name.OptionWasSet()) {
+ const char *name = m_name_options.m_name.GetCurrentValue();
+ std::unique_lock<std::recursive_mutex> lock;
+ target->GetBreakpointList().GetListMutex(lock);
+
+ BreakpointList &breakpoints = target->GetBreakpointList();
+ for (BreakpointSP bp_sp : breakpoints.Breakpoints()) {
+ if (bp_sp->MatchesName(name)) {
+ StreamString s;
+ bp_sp->GetDescription(&s, eDescriptionLevelBrief);
+ s.EOL();
+ result.AppendMessage(s.GetString());
+ }
+ }
+
+ } else if (m_name_options.m_breakpoint.OptionWasSet()) {
+ BreakpointSP bp_sp = target->GetBreakpointList().FindBreakpointByID(
+ m_name_options.m_breakpoint.GetCurrentValue());
+ if (bp_sp) {
+ std::vector<std::string> names;
+ bp_sp->GetNames(names);
+ result.AppendMessage("Names:");
+ for (auto name : names)
+ result.AppendMessageWithFormat(" %s\n", name.c_str());
+ } else {
+ result.AppendErrorWithFormat(
+ "Could not find breakpoint %" PRId64 ".\n",
+ m_name_options.m_breakpoint.GetCurrentValue());
+ result.SetStatus(eReturnStatusFailed);
+ return false;
+ }
+ } else {
+ result.SetError("Must specify -N or -B option to list.");
+ result.SetStatus(eReturnStatusFailed);
+ return false;
+ }
+ return true;
+ }
+
private:
- BreakpointNameOptionGroup m_name_options;
- OptionGroupOptions m_option_group;
+ BreakpointNameOptionGroup m_name_options;
+ OptionGroupOptions m_option_group;
};
-class CommandObjectBreakpointNameDelete : public CommandObjectParsed
-{
+//-------------------------------------------------------------------------
+// CommandObjectBreakpointName
+//-------------------------------------------------------------------------
+class CommandObjectBreakpointName : public CommandObjectMultiword {
public:
- CommandObjectBreakpointNameDelete (CommandInterpreter &interpreter) :
- CommandObjectParsed (interpreter,
- "delete",
- "Delete a name from the breakpoints provided.",
- "breakpoint name delete <command-options> <breakpoint-id-list>"),
- m_name_options(),
- m_option_group(interpreter)
- {
- // Create the first variant for the first (and only) argument for this command.
- CommandArgumentEntry arg1;
- CommandArgumentData id_arg;
- id_arg.arg_type = eArgTypeBreakpointID;
- id_arg.arg_repetition = eArgRepeatOptional;
- arg1.push_back(id_arg);
- m_arguments.push_back (arg1);
+ CommandObjectBreakpointName(CommandInterpreter &interpreter)
+ : CommandObjectMultiword(
+ interpreter, "name", "Commands to manage name tags for breakpoints",
+ "breakpoint name <subcommand> [<command-options>]") {
+ CommandObjectSP add_command_object(
+ new CommandObjectBreakpointNameAdd(interpreter));
+ CommandObjectSP delete_command_object(
+ new CommandObjectBreakpointNameDelete(interpreter));
+ CommandObjectSP list_command_object(
+ new CommandObjectBreakpointNameList(interpreter));
+
+ LoadSubCommand("add", add_command_object);
+ LoadSubCommand("delete", delete_command_object);
+ LoadSubCommand("list", list_command_object);
+ }
+
+ ~CommandObjectBreakpointName() override = default;
+};
- m_option_group.Append (&m_name_options, LLDB_OPT_SET_1, LLDB_OPT_SET_ALL);
- m_option_group.Finalize();
- }
+//-------------------------------------------------------------------------
+// CommandObjectBreakpointRead
+//-------------------------------------------------------------------------
+#pragma mark Read::CommandOptions
+static OptionDefinition g_breakpoint_read_options[] = {
+ // clang-format off
+ { LLDB_OPT_SET_ALL, true, "file", 'f', OptionParser::eRequiredArgument, nullptr, nullptr, CommandCompletions::eDiskFileCompletion, eArgTypeFilename, "The file from which to read the breakpoints." },
+ {LLDB_OPT_SET_ALL, false, "breakpoint-name", 'N', OptionParser::eRequiredArgument, nullptr, nullptr, 0, eArgTypeBreakpointName, "Only read in breakpoints with this name."},
+ // clang-format on
+};
- ~CommandObjectBreakpointNameDelete() override = default;
+#pragma mark Read
- Options *
- GetOptions() override
- {
- return &m_option_group;
+class CommandObjectBreakpointRead : public CommandObjectParsed {
+public:
+ CommandObjectBreakpointRead(CommandInterpreter &interpreter)
+ : CommandObjectParsed(interpreter, "breakpoint read",
+ "Read and set the breakpoints previously saved to "
+ "a file with \"breakpoint write\". ",
+ nullptr),
+ m_options() {
+ CommandArgumentEntry arg;
+ CommandObject::AddIDsArgumentData(arg, eArgTypeBreakpointID,
+ eArgTypeBreakpointIDRange);
+ // Add the entry for the first argument for this command to the object's
+ // arguments vector.
+ m_arguments.push_back(arg);
+ }
+
+ ~CommandObjectBreakpointRead() override = default;
+
+ Options *GetOptions() override { return &m_options; }
+
+ class CommandOptions : public Options {
+ public:
+ CommandOptions() : Options() {}
+
+ ~CommandOptions() override = default;
+
+ Error SetOptionValue(uint32_t option_idx, llvm::StringRef option_arg,
+ ExecutionContext *execution_context) override {
+ Error error;
+ const int short_option = m_getopt_table[option_idx].val;
+
+ switch (short_option) {
+ case 'f':
+ m_filename.assign(option_arg);
+ break;
+ case 'N': {
+ Error name_error;
+ if (!BreakpointID::StringIsBreakpointName(llvm::StringRef(option_arg),
+ name_error)) {
+ error.SetErrorStringWithFormat("Invalid breakpoint name: %s",
+ name_error.AsCString());
+ }
+ m_names.push_back(option_arg);
+ break;
+ }
+ default:
+ error.SetErrorStringWithFormat("unrecognized option '%c'",
+ short_option);
+ break;
+ }
+
+ return error;
}
-protected:
- bool
- DoExecute (Args& command, CommandReturnObject &result) override
- {
- if (!m_name_options.m_name.OptionWasSet())
- {
- result.SetError("No name option provided.");
- return false;
- }
+ void OptionParsingStarting(ExecutionContext *execution_context) override {
+ m_filename.clear();
+ m_names.clear();
+ }
- Target *target = GetSelectedOrDummyTarget(m_name_options.m_use_dummy.GetCurrentValue());
+ llvm::ArrayRef<OptionDefinition> GetDefinitions() override {
+ return llvm::makeArrayRef(g_breakpoint_read_options);
+ }
- if (target == nullptr)
- {
- result.AppendError ("Invalid target. No existing target or breakpoints.");
- result.SetStatus (eReturnStatusFailed);
- return false;
- }
+ // Instance variables to hold the values for command options.
- std::unique_lock<std::recursive_mutex> lock;
- target->GetBreakpointList().GetListMutex(lock);
+ std::string m_filename;
+ std::vector<std::string> m_names;
+ };
- const BreakpointList &breakpoints = target->GetBreakpointList();
+protected:
+ bool DoExecute(Args &command, CommandReturnObject &result) override {
+ Target *target = GetSelectedOrDummyTarget();
+ if (target == nullptr) {
+ result.AppendError("Invalid target. No existing target or breakpoints.");
+ result.SetStatus(eReturnStatusFailed);
+ return false;
+ }
- size_t num_breakpoints = breakpoints.GetSize();
- if (num_breakpoints == 0)
- {
- result.SetError("No breakpoints, cannot delete names.");
- result.SetStatus (eReturnStatusFailed);
- return false;
- }
+ std::unique_lock<std::recursive_mutex> lock;
+ target->GetBreakpointList().GetListMutex(lock);
- // Particular breakpoint selected; disable that breakpoint.
- BreakpointIDList valid_bp_ids;
- CommandObjectMultiwordBreakpoint::VerifyBreakpointIDs (command, target, result, &valid_bp_ids);
-
- if (result.Succeeded())
- {
- if (valid_bp_ids.GetSize() == 0)
- {
- result.SetError("No breakpoints specified, cannot delete names.");
- result.SetStatus (eReturnStatusFailed);
- return false;
- }
- size_t num_valid_ids = valid_bp_ids.GetSize();
- for (size_t index = 0; index < num_valid_ids; index++)
- {
- lldb::break_id_t bp_id = valid_bp_ids.GetBreakpointIDAtIndex(index).GetBreakpointID();
- BreakpointSP bp_sp = breakpoints.FindBreakpointByID(bp_id);
- bp_sp->RemoveName(m_name_options.m_name.GetCurrentValue());
- }
- }
+ FileSpec input_spec(m_options.m_filename, true);
+ BreakpointIDList new_bps;
+ Error error = target->CreateBreakpointsFromFile(input_spec,
+ m_options.m_names, new_bps);
+
+ if (!error.Success()) {
+ result.AppendError(error.AsCString());
+ result.SetStatus(eReturnStatusFailed);
+ return false;
+ }
- return true;
+ Stream &output_stream = result.GetOutputStream();
+
+ size_t num_breakpoints = new_bps.GetSize();
+ if (num_breakpoints == 0) {
+ result.AppendMessage("No breakpoints added.");
+ } else {
+ // No breakpoint selected; show info about all currently set breakpoints.
+ result.AppendMessage("New breakpoints:");
+ for (size_t i = 0; i < num_breakpoints; ++i) {
+ BreakpointID bp_id = new_bps.GetBreakpointIDAtIndex(i);
+ Breakpoint *bp = target->GetBreakpointList()
+ .FindBreakpointByID(bp_id.GetBreakpointID())
+ .get();
+ if (bp)
+ bp->GetDescription(&output_stream, lldb::eDescriptionLevelInitial,
+ false);
+ }
}
+ return result.Succeeded();
+ }
private:
- BreakpointNameOptionGroup m_name_options;
- OptionGroupOptions m_option_group;
+ CommandOptions m_options;
+};
+
+//-------------------------------------------------------------------------
+// CommandObjectBreakpointWrite
+//-------------------------------------------------------------------------
+#pragma mark Write::CommandOptions
+static OptionDefinition g_breakpoint_write_options[] = {
+ // clang-format off
+ { LLDB_OPT_SET_ALL, true, "file", 'f', OptionParser::eRequiredArgument, nullptr, nullptr, CommandCompletions::eDiskFileCompletion, eArgTypeFilename, "The file into which to write the breakpoints." },
+ { LLDB_OPT_SET_ALL, false, "append",'a', OptionParser::eNoArgument, nullptr, nullptr, 0, eArgTypeNone, "Append to saved breakpoints file if it exists."},
+ // clang-format on
};
-class CommandObjectBreakpointNameList : public CommandObjectParsed
-{
+#pragma mark Write
+class CommandObjectBreakpointWrite : public CommandObjectParsed {
public:
- CommandObjectBreakpointNameList (CommandInterpreter &interpreter) :
- CommandObjectParsed (interpreter,
- "list",
- "List either the names for a breakpoint or the breakpoints for a given name.",
- "breakpoint name list <command-options>"),
- m_name_options(),
- m_option_group(interpreter)
- {
- m_option_group.Append (&m_name_options);
- m_option_group.Finalize();
+ CommandObjectBreakpointWrite(CommandInterpreter &interpreter)
+ : CommandObjectParsed(interpreter, "breakpoint write",
+ "Write the breakpoints listed to a file that can "
+ "be read in with \"breakpoint read\". "
+ "If given no arguments, writes all breakpoints.",
+ nullptr),
+ m_options() {
+ CommandArgumentEntry arg;
+ CommandObject::AddIDsArgumentData(arg, eArgTypeBreakpointID,
+ eArgTypeBreakpointIDRange);
+ // Add the entry for the first argument for this command to the object's
+ // arguments vector.
+ m_arguments.push_back(arg);
+ }
+
+ ~CommandObjectBreakpointWrite() override = default;
+
+ Options *GetOptions() override { return &m_options; }
+
+ class CommandOptions : public Options {
+ public:
+ CommandOptions() : Options() {}
+
+ ~CommandOptions() override = default;
+
+ Error SetOptionValue(uint32_t option_idx, llvm::StringRef option_arg,
+ ExecutionContext *execution_context) override {
+ Error error;
+ const int short_option = m_getopt_table[option_idx].val;
+
+ switch (short_option) {
+ case 'f':
+ m_filename.assign(option_arg);
+ break;
+ case 'a':
+ m_append = true;
+ break;
+ default:
+ error.SetErrorStringWithFormat("unrecognized option '%c'",
+ short_option);
+ break;
+ }
+
+ return error;
}
- ~CommandObjectBreakpointNameList() override = default;
-
- Options *
- GetOptions() override
- {
- return &m_option_group;
+ void OptionParsingStarting(ExecutionContext *execution_context) override {
+ m_filename.clear();
+ m_append = false;
}
-protected:
- bool
- DoExecute (Args& command, CommandReturnObject &result) override
- {
- Target *target = GetSelectedOrDummyTarget(m_name_options.m_use_dummy.GetCurrentValue());
+ llvm::ArrayRef<OptionDefinition> GetDefinitions() override {
+ return llvm::makeArrayRef(g_breakpoint_write_options);
+ }
- if (target == nullptr)
- {
- result.AppendError ("Invalid target. No existing target or breakpoints.");
- result.SetStatus (eReturnStatusFailed);
- return false;
- }
+ // Instance variables to hold the values for command options.
- if (m_name_options.m_name.OptionWasSet())
- {
- const char *name = m_name_options.m_name.GetCurrentValue();
- std::unique_lock<std::recursive_mutex> lock;
- target->GetBreakpointList().GetListMutex(lock);
-
- BreakpointList &breakpoints = target->GetBreakpointList();
- for (BreakpointSP bp_sp : breakpoints.Breakpoints())
- {
- if (bp_sp->MatchesName(name))
- {
- StreamString s;
- bp_sp->GetDescription(&s, eDescriptionLevelBrief);
- s.EOL();
- result.AppendMessage(s.GetData());
- }
- }
+ std::string m_filename;
+ bool m_append = false;
+ };
- }
- else if (m_name_options.m_breakpoint.OptionWasSet())
- {
- BreakpointSP bp_sp = target->GetBreakpointList().FindBreakpointByID(m_name_options.m_breakpoint.GetCurrentValue());
- if (bp_sp)
- {
- std::vector<std::string> names;
- bp_sp->GetNames (names);
- result.AppendMessage ("Names:");
- for (auto name : names)
- result.AppendMessageWithFormat (" %s\n", name.c_str());
- }
- else
- {
- result.AppendErrorWithFormat ("Could not find breakpoint %" PRId64 ".\n",
- m_name_options.m_breakpoint.GetCurrentValue());
- result.SetStatus (eReturnStatusFailed);
- return false;
- }
- }
- else
- {
- result.SetError ("Must specify -N or -B option to list.");
- result.SetStatus (eReturnStatusFailed);
- return false;
- }
- return true;
+protected:
+ bool DoExecute(Args &command, CommandReturnObject &result) override {
+ Target *target = GetSelectedOrDummyTarget();
+ if (target == nullptr) {
+ result.AppendError("Invalid target. No existing target or breakpoints.");
+ result.SetStatus(eReturnStatusFailed);
+ return false;
}
-private:
- BreakpointNameOptionGroup m_name_options;
- OptionGroupOptions m_option_group;
-};
+ std::unique_lock<std::recursive_mutex> lock;
+ target->GetBreakpointList().GetListMutex(lock);
-//-------------------------------------------------------------------------
-// CommandObjectMultiwordBreakpoint
-//-------------------------------------------------------------------------
-class CommandObjectBreakpointName : public CommandObjectMultiword
-{
-public:
- CommandObjectBreakpointName(CommandInterpreter &interpreter)
- : CommandObjectMultiword(interpreter, "name", "Commands to manage name tags for breakpoints",
- "breakpoint name <subcommand> [<command-options>]")
- {
- CommandObjectSP add_command_object (new CommandObjectBreakpointNameAdd (interpreter));
- CommandObjectSP delete_command_object (new CommandObjectBreakpointNameDelete (interpreter));
- CommandObjectSP list_command_object (new CommandObjectBreakpointNameList (interpreter));
+ BreakpointIDList valid_bp_ids;
+ if (!command.empty()) {
+ CommandObjectMultiwordBreakpoint::VerifyBreakpointIDs(
+ command, target, result, &valid_bp_ids);
- LoadSubCommand ("add", add_command_object);
- LoadSubCommand ("delete", delete_command_object);
- LoadSubCommand ("list", list_command_object);
+ if (!result.Succeeded()) {
+ result.SetStatus(eReturnStatusFailed);
+ return false;
+ }
+ }
+ Error error = target->SerializeBreakpointsToFile(
+ FileSpec(m_options.m_filename, true), valid_bp_ids, m_options.m_append);
+ if (!error.Success()) {
+ result.AppendErrorWithFormat("error serializing breakpoints: %s.",
+ error.AsCString());
+ result.SetStatus(eReturnStatusFailed);
}
+ return result.Succeeded();
+ }
- ~CommandObjectBreakpointName() override = default;
+private:
+ CommandOptions m_options;
};
//-------------------------------------------------------------------------
@@ -2369,120 +2300,142 @@ public:
//-------------------------------------------------------------------------
#pragma mark MultiwordBreakpoint
-CommandObjectMultiwordBreakpoint::CommandObjectMultiwordBreakpoint(CommandInterpreter &interpreter)
- : CommandObjectMultiword(interpreter, "breakpoint",
- "Commands for operating on breakpoints (see 'help b' for shorthand.)",
- "breakpoint <subcommand> [<command-options>]")
-{
- CommandObjectSP list_command_object (new CommandObjectBreakpointList (interpreter));
- CommandObjectSP enable_command_object (new CommandObjectBreakpointEnable (interpreter));
- CommandObjectSP disable_command_object (new CommandObjectBreakpointDisable (interpreter));
- CommandObjectSP clear_command_object (new CommandObjectBreakpointClear (interpreter));
- CommandObjectSP delete_command_object (new CommandObjectBreakpointDelete (interpreter));
- CommandObjectSP set_command_object (new CommandObjectBreakpointSet (interpreter));
- CommandObjectSP command_command_object (new CommandObjectBreakpointCommand (interpreter));
- CommandObjectSP modify_command_object (new CommandObjectBreakpointModify(interpreter));
- CommandObjectSP name_command_object (new CommandObjectBreakpointName(interpreter));
-
- list_command_object->SetCommandName ("breakpoint list");
- enable_command_object->SetCommandName("breakpoint enable");
- disable_command_object->SetCommandName("breakpoint disable");
- clear_command_object->SetCommandName("breakpoint clear");
- delete_command_object->SetCommandName("breakpoint delete");
- set_command_object->SetCommandName("breakpoint set");
- command_command_object->SetCommandName ("breakpoint command");
- modify_command_object->SetCommandName ("breakpoint modify");
- name_command_object->SetCommandName ("breakpoint name");
-
- LoadSubCommand ("list", list_command_object);
- LoadSubCommand ("enable", enable_command_object);
- LoadSubCommand ("disable", disable_command_object);
- LoadSubCommand ("clear", clear_command_object);
- LoadSubCommand ("delete", delete_command_object);
- LoadSubCommand ("set", set_command_object);
- LoadSubCommand ("command", command_command_object);
- LoadSubCommand ("modify", modify_command_object);
- LoadSubCommand ("name", name_command_object);
+CommandObjectMultiwordBreakpoint::CommandObjectMultiwordBreakpoint(
+ CommandInterpreter &interpreter)
+ : CommandObjectMultiword(
+ interpreter, "breakpoint",
+ "Commands for operating on breakpoints (see 'help b' for shorthand.)",
+ "breakpoint <subcommand> [<command-options>]") {
+ CommandObjectSP list_command_object(
+ new CommandObjectBreakpointList(interpreter));
+ CommandObjectSP enable_command_object(
+ new CommandObjectBreakpointEnable(interpreter));
+ CommandObjectSP disable_command_object(
+ new CommandObjectBreakpointDisable(interpreter));
+ CommandObjectSP clear_command_object(
+ new CommandObjectBreakpointClear(interpreter));
+ CommandObjectSP delete_command_object(
+ new CommandObjectBreakpointDelete(interpreter));
+ CommandObjectSP set_command_object(
+ new CommandObjectBreakpointSet(interpreter));
+ CommandObjectSP command_command_object(
+ new CommandObjectBreakpointCommand(interpreter));
+ CommandObjectSP modify_command_object(
+ new CommandObjectBreakpointModify(interpreter));
+ CommandObjectSP name_command_object(
+ new CommandObjectBreakpointName(interpreter));
+ CommandObjectSP write_command_object(
+ new CommandObjectBreakpointWrite(interpreter));
+ CommandObjectSP read_command_object(
+ new CommandObjectBreakpointRead(interpreter));
+
+ list_command_object->SetCommandName("breakpoint list");
+ enable_command_object->SetCommandName("breakpoint enable");
+ disable_command_object->SetCommandName("breakpoint disable");
+ clear_command_object->SetCommandName("breakpoint clear");
+ delete_command_object->SetCommandName("breakpoint delete");
+ set_command_object->SetCommandName("breakpoint set");
+ command_command_object->SetCommandName("breakpoint command");
+ modify_command_object->SetCommandName("breakpoint modify");
+ name_command_object->SetCommandName("breakpoint name");
+ write_command_object->SetCommandName("breakpoint write");
+ read_command_object->SetCommandName("breakpoint read");
+
+ LoadSubCommand("list", list_command_object);
+ LoadSubCommand("enable", enable_command_object);
+ LoadSubCommand("disable", disable_command_object);
+ LoadSubCommand("clear", clear_command_object);
+ LoadSubCommand("delete", delete_command_object);
+ LoadSubCommand("set", set_command_object);
+ LoadSubCommand("command", command_command_object);
+ LoadSubCommand("modify", modify_command_object);
+ LoadSubCommand("name", name_command_object);
+ LoadSubCommand("write", write_command_object);
+ LoadSubCommand("read", read_command_object);
}
CommandObjectMultiwordBreakpoint::~CommandObjectMultiwordBreakpoint() = default;
-void
-CommandObjectMultiwordBreakpoint::VerifyIDs (Args &args,
- Target *target,
- bool allow_locations,
- CommandReturnObject &result,
- BreakpointIDList *valid_ids)
-{
- // args can be strings representing 1). integers (for breakpoint ids)
- // 2). the full breakpoint & location canonical representation
- // 3). the word "to" or a hyphen, representing a range (in which case there
- // had *better* be an entry both before & after of one of the first two types.
- // 4). A breakpoint name
- // If args is empty, we will use the last created breakpoint (if there is one.)
-
- Args temp_args;
-
- if (args.GetArgumentCount() == 0)
- {
- if (target->GetLastCreatedBreakpoint())
- {
- valid_ids->AddBreakpointID (BreakpointID(target->GetLastCreatedBreakpoint()->GetID(), LLDB_INVALID_BREAK_ID));
- result.SetStatus (eReturnStatusSuccessFinishNoResult);
- }
- else
- {
- result.AppendError("No breakpoint specified and no last created breakpoint.");
- result.SetStatus (eReturnStatusFailed);
- }
- return;
+void CommandObjectMultiwordBreakpoint::VerifyIDs(Args &args, Target *target,
+ bool allow_locations,
+ CommandReturnObject &result,
+ BreakpointIDList *valid_ids) {
+ // args can be strings representing 1). integers (for breakpoint ids)
+ // 2). the full breakpoint & location
+ // canonical representation
+ // 3). the word "to" or a hyphen,
+ // representing a range (in which case there
+ // had *better* be an entry both before &
+ // after of one of the first two types.
+ // 4). A breakpoint name
+ // If args is empty, we will use the last created breakpoint (if there is
+ // one.)
+
+ Args temp_args;
+
+ if (args.empty()) {
+ if (target->GetLastCreatedBreakpoint()) {
+ valid_ids->AddBreakpointID(BreakpointID(
+ target->GetLastCreatedBreakpoint()->GetID(), LLDB_INVALID_BREAK_ID));
+ result.SetStatus(eReturnStatusSuccessFinishNoResult);
+ } else {
+ result.AppendError(
+ "No breakpoint specified and no last created breakpoint.");
+ result.SetStatus(eReturnStatusFailed);
}
-
- // Create a new Args variable to use; copy any non-breakpoint-id-ranges stuff directly from the old ARGS to
- // the new TEMP_ARGS. Do not copy breakpoint id range strings over; instead generate a list of strings for
- // all the breakpoint ids in the range, and shove all of those breakpoint id strings into TEMP_ARGS.
-
- BreakpointIDList::FindAndReplaceIDRanges (args, target, allow_locations, result, temp_args);
-
- // NOW, convert the list of breakpoint id strings in TEMP_ARGS into an actual BreakpointIDList:
-
- valid_ids->InsertStringArray (temp_args.GetConstArgumentVector(), temp_args.GetArgumentCount(), result);
-
- // At this point, all of the breakpoint ids that the user passed in have been converted to breakpoint IDs
- // and put into valid_ids.
-
- if (result.Succeeded())
- {
- // Now that we've converted everything from args into a list of breakpoint ids, go through our tentative list
- // of breakpoint id's and verify that they correspond to valid/currently set breakpoints.
-
- const size_t count = valid_ids->GetSize();
- for (size_t i = 0; i < count; ++i)
- {
- BreakpointID cur_bp_id = valid_ids->GetBreakpointIDAtIndex (i);
- Breakpoint *breakpoint = target->GetBreakpointByID (cur_bp_id.GetBreakpointID()).get();
- if (breakpoint != nullptr)
- {
- const size_t num_locations = breakpoint->GetNumLocations();
- if (static_cast<size_t>(cur_bp_id.GetLocationID()) > num_locations)
- {
- StreamString id_str;
- BreakpointID::GetCanonicalReference (&id_str,
- cur_bp_id.GetBreakpointID(),
- cur_bp_id.GetLocationID());
- i = valid_ids->GetSize() + 1;
- result.AppendErrorWithFormat ("'%s' is not a currently valid breakpoint/location id.\n",
- id_str.GetData());
- result.SetStatus (eReturnStatusFailed);
- }
- }
- else
- {
- i = valid_ids->GetSize() + 1;
- result.AppendErrorWithFormat("'%d' is not a currently valid breakpoint ID.\n",
- cur_bp_id.GetBreakpointID());
- result.SetStatus (eReturnStatusFailed);
- }
- }
+ return;
+ }
+
+ // Create a new Args variable to use; copy any non-breakpoint-id-ranges stuff
+ // directly from the old ARGS to
+ // the new TEMP_ARGS. Do not copy breakpoint id range strings over; instead
+ // generate a list of strings for
+ // all the breakpoint ids in the range, and shove all of those breakpoint id
+ // strings into TEMP_ARGS.
+
+ BreakpointIDList::FindAndReplaceIDRanges(args, target, allow_locations,
+ result, temp_args);
+
+ // NOW, convert the list of breakpoint id strings in TEMP_ARGS into an actual
+ // BreakpointIDList:
+
+ valid_ids->InsertStringArray(temp_args.GetConstArgumentVector(),
+ temp_args.GetArgumentCount(), result);
+
+ // At this point, all of the breakpoint ids that the user passed in have been
+ // converted to breakpoint IDs
+ // and put into valid_ids.
+
+ if (result.Succeeded()) {
+ // Now that we've converted everything from args into a list of breakpoint
+ // ids, go through our tentative list
+ // of breakpoint id's and verify that they correspond to valid/currently set
+ // breakpoints.
+
+ const size_t count = valid_ids->GetSize();
+ for (size_t i = 0; i < count; ++i) {
+ BreakpointID cur_bp_id = valid_ids->GetBreakpointIDAtIndex(i);
+ Breakpoint *breakpoint =
+ target->GetBreakpointByID(cur_bp_id.GetBreakpointID()).get();
+ if (breakpoint != nullptr) {
+ const size_t num_locations = breakpoint->GetNumLocations();
+ if (static_cast<size_t>(cur_bp_id.GetLocationID()) > num_locations) {
+ StreamString id_str;
+ BreakpointID::GetCanonicalReference(
+ &id_str, cur_bp_id.GetBreakpointID(), cur_bp_id.GetLocationID());
+ i = valid_ids->GetSize() + 1;
+ result.AppendErrorWithFormat(
+ "'%s' is not a currently valid breakpoint/location id.\n",
+ id_str.GetData());
+ result.SetStatus(eReturnStatusFailed);
+ }
+ } else {
+ i = valid_ids->GetSize() + 1;
+ result.AppendErrorWithFormat(
+ "'%d' is not a currently valid breakpoint ID.\n",
+ cur_bp_id.GetBreakpointID());
+ result.SetStatus(eReturnStatusFailed);
+ }
}
+ }
}
OpenPOWER on IntegriCloud