diff options
Diffstat (limited to 'source/Commands/CommandObjectBreakpoint.cpp')
| -rw-r--r-- | source/Commands/CommandObjectBreakpoint.cpp | 228 | 
1 files changed, 139 insertions, 89 deletions
diff --git a/source/Commands/CommandObjectBreakpoint.cpp b/source/Commands/CommandObjectBreakpoint.cpp index fb0553e482db9..8eb6a5fa5a026 100644 --- a/source/Commands/CommandObjectBreakpoint.cpp +++ b/source/Commands/CommandObjectBreakpoint.cpp @@ -7,12 +7,8 @@  //  //===----------------------------------------------------------------------===// -// C Includes -// C++ Includes  #include <vector> -// Other libraries and framework includes -// Project includes  #include "CommandObjectBreakpoint.h"  #include "CommandObjectBreakpointCommand.h"  #include "lldb/Breakpoint/Breakpoint.h" @@ -50,19 +46,19 @@ static void AddBreakpointDescription(Stream *s, Breakpoint *bp,  // Modifiable Breakpoint Options  //-------------------------------------------------------------------------  #pragma mark Modify::CommandOptions -static OptionDefinition g_breakpoint_modify_options[] = { +static constexpr OptionDefinition g_breakpoint_modify_options[] = {      // clang-format off -  { LLDB_OPT_SET_1, false, "ignore-count", 'i', OptionParser::eRequiredArgument, nullptr, nullptr, 0, eArgTypeCount,       "Set the number of times this breakpoint is skipped before stopping." }, -  { LLDB_OPT_SET_1, 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_1, 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_1, 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_1, 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_1, 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_1, 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, "auto-continue",'G', OptionParser::eRequiredArgument, nullptr, nullptr, 0, eArgTypeBoolean,     "The breakpoint will auto-continue after running its commands." }, -  { LLDB_OPT_SET_2, false, "enable",       'e', OptionParser::eNoArgument,       nullptr, nullptr, 0, eArgTypeNone,        "Enable the breakpoint." }, -  { LLDB_OPT_SET_3, false, "disable",      'd', OptionParser::eNoArgument,       nullptr, nullptr, 0, eArgTypeNone,        "Disable the breakpoint." }, -  { LLDB_OPT_SET_4, false, "command",      'C', OptionParser::eRequiredArgument, nullptr, nullptr, 0, eArgTypeCommand,     "A command to run when the breakpoint is hit, can be provided more than once, the commands will get run in order left to right." }, +  { LLDB_OPT_SET_1, false, "ignore-count", 'i', OptionParser::eRequiredArgument, nullptr, {}, 0, eArgTypeCount,       "Set the number of times this breakpoint is skipped before stopping." }, +  { LLDB_OPT_SET_1, false, "one-shot",     'o', OptionParser::eRequiredArgument, nullptr, {}, 0, eArgTypeBoolean,     "The breakpoint is deleted the first time it stop causes a stop." }, +  { LLDB_OPT_SET_1, false, "thread-index", 'x', OptionParser::eRequiredArgument, nullptr, {}, 0, eArgTypeThreadIndex, "The breakpoint stops only for the thread whose index matches this argument." }, +  { LLDB_OPT_SET_1, false, "thread-id",    't', OptionParser::eRequiredArgument, nullptr, {}, 0, eArgTypeThreadID,    "The breakpoint stops only for the thread whose TID matches this argument." }, +  { LLDB_OPT_SET_1, false, "thread-name",  'T', OptionParser::eRequiredArgument, nullptr, {}, 0, eArgTypeThreadName,  "The breakpoint stops only for the thread whose thread name matches this argument." }, +  { LLDB_OPT_SET_1, false, "queue-name",   'q', OptionParser::eRequiredArgument, nullptr, {}, 0, eArgTypeQueueName,   "The breakpoint stops only for threads in the queue whose name is given by this argument." }, +  { LLDB_OPT_SET_1, false, "condition",    'c', OptionParser::eRequiredArgument, nullptr, {}, 0, eArgTypeExpression,  "The breakpoint stops only if this condition expression evaluates to true." }, +  { LLDB_OPT_SET_1, false, "auto-continue",'G', OptionParser::eRequiredArgument, nullptr, {}, 0, eArgTypeBoolean,     "The breakpoint will auto-continue after running its commands." }, +  { LLDB_OPT_SET_2, false, "enable",       'e', OptionParser::eNoArgument,       nullptr, {}, 0, eArgTypeNone,        "Enable the breakpoint." }, +  { LLDB_OPT_SET_3, false, "disable",      'd', OptionParser::eNoArgument,       nullptr, {}, 0, eArgTypeNone,        "Disable the breakpoint." }, +  { LLDB_OPT_SET_4, false, "command",      'C', OptionParser::eRequiredArgument, nullptr, {}, 0, eArgTypeCommand,     "A command to run when the breakpoint is hit, can be provided more than once, the commands will get run in order left to right." },      // clang-format on  };  class lldb_private::BreakpointOptionGroup : public OptionGroup @@ -198,9 +194,9 @@ public:    BreakpointOptions m_bp_opts;  }; -static OptionDefinition g_breakpoint_dummy_options[] = { +static constexpr OptionDefinition g_breakpoint_dummy_options[] = {      // clang-format off -  { LLDB_OPT_SET_1, false, "dummy-breakpoints", 'D', OptionParser::eNoArgument, nullptr, nullptr, 0, eArgTypeNone, "Act on Dummy breakpoints - i.e. breakpoints set before a file is provided, " +  { LLDB_OPT_SET_1, false, "dummy-breakpoints", 'D', OptionParser::eNoArgument, nullptr, {}, 0, eArgTypeNone, "Act on Dummy breakpoints - i.e. breakpoints set before a file is provided, "    "which prime new targets." },      // clang-format on  }; @@ -245,23 +241,23 @@ public:  // 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_NOT_10 (LLDB_OPT_SET_FROM_TO(1, 11) & ~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_FILE (LLDB_OPT_SET_FROM_TO(1, 11) & ~LLDB_OPT_SET_2 & ~LLDB_OPT_SET_10) +#define LLDB_OPT_OFFSET_APPLIES (LLDB_OPT_SET_FROM_TO(1, 8) & ~LLDB_OPT_SET_2)  #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[] = { +static constexpr 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 " +  { LLDB_OPT_NOT_10,               false, "shlib",                  's', OptionParser::eRequiredArgument, 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, "hardware",               'H', OptionParser::eNoArgument,       nullptr, nullptr, 0,                                         eArgTypeNone,                "Require the breakpoint to use hardware breakpoints." }, -  { 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_OPT_SET_ALL,              false, "hardware",               'H', OptionParser::eNoArgument,       nullptr, {}, 0,                                         eArgTypeNone,                "Require the breakpoint to use hardware breakpoints." }, +  { LLDB_OPT_FILE,                 false, "file",                   'f', OptionParser::eRequiredArgument, 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." }, +  { LLDB_OPT_SET_1,                true,  "line",                   'l', OptionParser::eRequiredArgument, 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 @@ -269,7 +265,7 @@ static OptionDefinition g_breakpoint_set_options[] = {    //    { 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 " +  { LLDB_OPT_SET_2,                true,  "address",                'a', OptionParser::eRequiredArgument, 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 - " @@ -278,47 +274,50 @@ static OptionDefinition g_breakpoint_set_options[] = {    "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 " +  { LLDB_OPT_SET_3,                true,  "name",                   'n', OptionParser::eRequiredArgument, 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 " +  { LLDB_OPT_SET_9,                false, "source-regexp-function", 'X', OptionParser::eRequiredArgument, 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 " +  { LLDB_OPT_SET_4,                true,  "fullname",               'F', OptionParser::eRequiredArgument, 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 " +  { LLDB_OPT_SET_5,                true,  "selector",               'S', OptionParser::eRequiredArgument, 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 " +  { LLDB_OPT_SET_6,                true,  "method",                 'M', OptionParser::eRequiredArgument, 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 " +  { LLDB_OPT_SET_7,                true,  "func-regex",             'r', OptionParser::eRequiredArgument, 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 " +  { LLDB_OPT_SET_8,                true,  "basename",               'b', OptionParser::eRequiredArgument, 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 " +  { LLDB_OPT_SET_9,                true,  "source-pattern-regexp",  'p', OptionParser::eRequiredArgument, 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 " +  { LLDB_OPT_SET_9,                false, "all-files",              'A', OptionParser::eNoArgument,       nullptr, {}, 0,                                         eArgTypeNone,                "All files are searched for source pattern matches." }, +  { LLDB_OPT_SET_11,               true, "python-class",            'P', OptionParser::eRequiredArgument, nullptr, {}, 0,                                         eArgTypePythonClass,       "The name of the class that implement a scripted breakpoint." }, +  { LLDB_OPT_SET_11,               false, "python-class-key",       'k', OptionParser::eRequiredArgument, nullptr, {}, 0,                                         eArgTypeNone,                "The key for a key/value pair passed to the class that implements a scripted breakpoint.  Can be specified more than once." }, +  { LLDB_OPT_SET_11,               false, "python-class-value",     'v', OptionParser::eRequiredArgument, nullptr, {}, 0,                                         eArgTypeNone,                "The value for the previous key in the pair passed to the class that implements a scripted breakpoint.    Can be specified more than once." }, +  { LLDB_OPT_SET_10,               true,  "language-exception",     'E', OptionParser::eRequiredArgument, 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." }, +  { LLDB_OPT_SET_10,               false, "on-throw",               'w', OptionParser::eRequiredArgument, nullptr, {}, 0,                                         eArgTypeBoolean,             "Set the breakpoint on exception throW." }, +  { LLDB_OPT_SET_10,               false, "on-catch",               'h', OptionParser::eRequiredArgument, 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 " +  { LLDB_OPT_EXPR_LANGUAGE,        false, "language",               'L', OptionParser::eRequiredArgument, 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.  " +  { LLDB_OPT_SKIP_PROLOGUE,        false, "skip-prologue",          'K', OptionParser::eRequiredArgument, 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, "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.  " +  { LLDB_OPT_SET_ALL,              false, "breakpoint-name",        'N', OptionParser::eRequiredArgument, nullptr, {}, 0,                                         eArgTypeBreakpointName,      "Adds this to the list of names for this breakpoint." }, +  { LLDB_OPT_OFFSET_APPLIES,       false, "address-slide",          'R', OptionParser::eRequiredArgument, 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 " +  { LLDB_OPT_MOVE_TO_NEAREST_CODE, false, "move-to-nearest-code", 'm', OptionParser::eRequiredArgument,   nullptr, {}, 0,                                         eArgTypeBoolean,             "Move breakpoints to nearest code. If not set the target.move-to-nearest-code "    "setting is used." },      // clang-format on  }; @@ -336,7 +335,8 @@ public:      eSetTypeFunctionName,      eSetTypeFunctionRegexp,      eSetTypeSourceRegexp, -    eSetTypeException +    eSetTypeException, +    eSetTypeScripted,    } BreakpointSetType;    CommandObjectBreakpointSet(CommandInterpreter &interpreter) @@ -434,7 +434,7 @@ public:        } break;        case 'f': -        m_filenames.AppendIfUnique(FileSpec(option_arg, false)); +        m_filenames.AppendIfUnique(FileSpec(option_arg));          break;        case 'F': @@ -454,7 +454,15 @@ public:        case 'H':          m_hardware = true;          break; - +         +      case 'k': { +          if (m_current_key.empty()) +            m_current_key.assign(option_arg); +          else +            error.SetErrorStringWithFormat("Key: %s missing value.", +                                            m_current_key.c_str()); +         +      } break;        case 'K': {          bool success;          bool value; @@ -535,13 +543,17 @@ public:        case 'p':          m_source_text_regexp.assign(option_arg);          break; +         +      case 'P': +        m_python_class.assign(option_arg); +        break;        case 'r':          m_func_regexp.assign(option_arg);          break;        case 's': -        m_modules.AppendIfUnique(FileSpec(option_arg, false)); +        m_modules.AppendIfUnique(FileSpec(option_arg));          break;        case 'S': @@ -549,6 +561,16 @@ public:          m_func_name_type_mask |= eFunctionNameTypeSelector;          break; +      case 'v': { +          if (!m_current_key.empty()) { +              m_extra_args_sp->AddStringItem(m_current_key, option_arg); +              m_current_key.clear(); +          } +          else +            error.SetErrorStringWithFormat("Value \"%s\" missing matching key.", +                                           option_arg.str().c_str()); +      } break; +                case 'w': {          bool success;          m_throw_bp = OptionArgParser::ToBoolean(option_arg, true, &success); @@ -593,6 +615,9 @@ public:        m_exception_extra_args.Clear();        m_move_to_nearest_code = eLazyBoolCalculate;        m_source_regex_func_names.clear(); +      m_python_class.clear(); +      m_extra_args_sp.reset(new StructuredData::Dictionary()); +      m_current_key.clear();      }      llvm::ArrayRef<OptionDefinition> GetDefinitions() override { @@ -607,7 +632,7 @@ public:      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; +    lldb::FunctionNameType m_func_name_type_mask;      std::string m_func_regexp;      std::string m_source_text_regexp;      FileSpecList m_modules; @@ -623,6 +648,9 @@ public:      Args m_exception_extra_args;      LazyBool m_move_to_nearest_code;      std::unordered_set<std::string> m_source_regex_func_names; +    std::string m_python_class; +    StructuredData::DictionarySP m_extra_args_sp; +    std::string m_current_key;    };  protected: @@ -649,7 +677,9 @@ protected:      BreakpointSetType break_type = eSetTypeInvalid; -    if (m_options.m_line_num != 0) +    if (!m_options.m_python_class.empty()) +      break_type = eSetTypeScripted; +    else if (m_options.m_line_num != 0)        break_type = eSetTypeFileAndLine;      else if (m_options.m_load_addr != LLDB_INVALID_ADDRESS)        break_type = eSetTypeAddress; @@ -696,7 +726,8 @@ protected:        bp_sp = target->CreateBreakpoint(&(m_options.m_modules),                                          file, -                                       m_options.m_line_num,  +                                       m_options.m_line_num, +                                       m_options.m_column,                                         m_options.m_offset_addr,                                         check_inlines,                                          m_options.m_skip_prologue, @@ -730,7 +761,7 @@ protected:      }      case eSetTypeFunctionName: // Breakpoint by function name      { -      uint32_t name_type_mask = m_options.m_func_name_type_mask; +      FunctionNameType name_type_mask = m_options.m_func_name_type_mask;        if (name_type_mask == 0)          name_type_mask = eFunctionNameTypeAuto; @@ -823,6 +854,25 @@ protected:          return false;        }      } break; +    case eSetTypeScripted: { + +      Status error; +      bp_sp = target->CreateScriptedBreakpoint(m_options.m_python_class, +                                               &(m_options.m_modules),  +                                               &(m_options.m_filenames), +                                               false, +                                               m_options.m_hardware, +                                               m_options.m_extra_args_sp, +                                               &error); +      if (error.Fail()) { +        result.AppendErrorWithFormat( +            "Error setting extra exception arguments: %s", +            error.AsCString()); +        target->RemoveBreakpointByID(bp_sp->GetID()); +        result.SetStatus(eReturnStatusFailed); +        return false; +      } +    } break;      default:        break;      } @@ -1207,15 +1257,15 @@ protected:  //-------------------------------------------------------------------------  #pragma mark List::CommandOptions -static OptionDefinition g_breakpoint_list_options[] = { +static constexpr 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)." }, +  { LLDB_OPT_SET_ALL, false, "internal",          'i', OptionParser::eNoArgument, nullptr, {}, 0, eArgTypeNone, "Show debugger internal breakpoints" }, +  { LLDB_OPT_SET_1,   false, "brief",             'b', OptionParser::eNoArgument, 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." }, +  { LLDB_OPT_SET_2,   false, "full",              'f', OptionParser::eNoArgument, nullptr, {}, 0, eArgTypeNone, "Give a full description of the breakpoint and its locations." }, +  { LLDB_OPT_SET_3,   false, "verbose",           'v', OptionParser::eNoArgument, 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, {}, 0, eArgTypeNone, "List Dummy breakpoints - i.e. breakpoints set before a file is provided, which prime new targets." },      // clang-format on  }; @@ -1373,10 +1423,10 @@ private:  //-------------------------------------------------------------------------  #pragma mark Clear::CommandOptions -static OptionDefinition g_breakpoint_clear_options[] = { +static constexpr 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." } +  { LLDB_OPT_SET_1, false, "file", 'f', OptionParser::eRequiredArgument, nullptr, {}, CommandCompletions::eSourceFileCompletion, eArgTypeFilename, "Specify the breakpoint by source location in this particular file." }, +  { LLDB_OPT_SET_1, true,  "line", 'l', OptionParser::eRequiredArgument, nullptr, {}, 0,                                         eArgTypeLineNum,  "Specify the breakpoint by source location at this particular line." }      // clang-format on  }; @@ -1531,10 +1581,10 @@ private:  //-------------------------------------------------------------------------  // CommandObjectBreakpointDelete  //------------------------------------------------------------------------- -static OptionDefinition g_breakpoint_delete_options[] = { +static constexpr 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." }, +  { LLDB_OPT_SET_1, false, "force",             'f', OptionParser::eNoArgument, nullptr, {}, 0, eArgTypeNone, "Delete all breakpoints without querying for confirmation." }, +  { LLDB_OPT_SET_1, false, "dummy-breakpoints", 'D', OptionParser::eNoArgument, nullptr, {}, 0, eArgTypeNone, "Delete Dummy breakpoints - i.e. breakpoints set before a file is provided, which prime new targets." },      // clang-format on  }; @@ -1688,12 +1738,12 @@ private:  // CommandObjectBreakpointName  //------------------------------------------------------------------------- -static OptionDefinition g_breakpoint_name_options[] = { +static constexpr OptionDefinition g_breakpoint_name_options[] = {      // 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_3, 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."}, -  {LLDB_OPT_SET_4, false, "help-string",  'H', OptionParser::eRequiredArgument, nullptr, nullptr, 0, eArgTypeNone, "A help string describing the purpose of this name."}, +  {LLDB_OPT_SET_1, false, "name",              'N', OptionParser::eRequiredArgument, nullptr, {}, 0, eArgTypeBreakpointName, "Specifies a breakpoint name to use."}, +  {LLDB_OPT_SET_2, false, "breakpoint-id",     'B', OptionParser::eRequiredArgument, nullptr, {}, 0, eArgTypeBreakpointID,   "Specify a breakpoint ID to use."}, +  {LLDB_OPT_SET_3, false, "dummy-breakpoints", 'D', OptionParser::eNoArgument,       nullptr, {}, 0, eArgTypeNone,           "Operate on Dummy breakpoints - i.e. breakpoints set before a file is provided, which prime new targets."}, +  {LLDB_OPT_SET_4, false, "help-string",       'H', OptionParser::eRequiredArgument, nullptr, {}, 0, eArgTypeNone,           "A help string describing the purpose of this name."},      // clang-format on  };  class BreakpointNameOptionGroup : public OptionGroup { @@ -1757,23 +1807,20 @@ public:    OptionValueString m_help_string;  }; -static OptionDefinition g_breakpoint_access_options[] = { +static constexpr OptionDefinition g_breakpoint_access_options[] = {      // clang-format off -  {LLDB_OPT_SET_1,   false, "allow-list",    'L', OptionParser::eRequiredArgument, nullptr, nullptr, 0, eArgTypeBoolean, "Determines whether the breakpoint will show up in break list if not referred to explicitly."}, -  {LLDB_OPT_SET_2,   false, "allow-disable", 'A', OptionParser::eRequiredArgument, nullptr, nullptr, 0, eArgTypeBoolean, "Determines whether the breakpoint can be disabled by name or when all breakpoints are disabled."}, -  {LLDB_OPT_SET_3,   false, "allow-delete",  'D', OptionParser::eRequiredArgument, nullptr, nullptr, 0, eArgTypeBoolean, "Determines whether the breakpoint can be deleted by name or when all breakpoints are deleted."}, +  {LLDB_OPT_SET_1,   false, "allow-list",    'L', OptionParser::eRequiredArgument, nullptr, {}, 0, eArgTypeBoolean, "Determines whether the breakpoint will show up in break list if not referred to explicitly."}, +  {LLDB_OPT_SET_2,   false, "allow-disable", 'A', OptionParser::eRequiredArgument, nullptr, {}, 0, eArgTypeBoolean, "Determines whether the breakpoint can be disabled by name or when all breakpoints are disabled."}, +  {LLDB_OPT_SET_3,   false, "allow-delete",  'D', OptionParser::eRequiredArgument, nullptr, {}, 0, eArgTypeBoolean, "Determines whether the breakpoint can be deleted by name or when all breakpoints are deleted."},      // clang-format on  }; -class BreakpointAccessOptionGroup : public OptionGroup -{ +class BreakpointAccessOptionGroup : public OptionGroup {  public: -  BreakpointAccessOptionGroup() : -          OptionGroup() -   {} -   +  BreakpointAccessOptionGroup() : OptionGroup() {} +    ~BreakpointAccessOptionGroup() override = default; -   +    llvm::ArrayRef<OptionDefinition> GetDefinitions() override {      return llvm::makeArrayRef(g_breakpoint_access_options);    } @@ -2229,10 +2276,10 @@ public:  // CommandObjectBreakpointRead  //-------------------------------------------------------------------------  #pragma mark Read::CommandOptions -static OptionDefinition g_breakpoint_read_options[] = { +static constexpr 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."}, +  {LLDB_OPT_SET_ALL, true,  "file",                   'f', OptionParser::eRequiredArgument, nullptr, {}, CommandCompletions::eDiskFileCompletion, eArgTypeFilename,       "The file from which to read the breakpoints." }, +  {LLDB_OPT_SET_ALL, false, "breakpoint-name",        'N', OptionParser::eRequiredArgument, nullptr, {}, 0,                                       eArgTypeBreakpointName, "Only read in breakpoints with this name."},      // clang-format on  }; @@ -2319,7 +2366,8 @@ protected:      std::unique_lock<std::recursive_mutex> lock;      target->GetBreakpointList().GetListMutex(lock); -    FileSpec input_spec(m_options.m_filename, true); +    FileSpec input_spec(m_options.m_filename); +    FileSystem::Instance().Resolve(input_spec);      BreakpointIDList new_bps;      Status error = target->CreateBreakpointsFromFile(          input_spec, m_options.m_names, new_bps); @@ -2359,10 +2407,10 @@ private:  // CommandObjectBreakpointWrite  //-------------------------------------------------------------------------  #pragma mark Write::CommandOptions -static OptionDefinition g_breakpoint_write_options[] = { +static constexpr 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."}, +  { LLDB_OPT_SET_ALL, true,  "file",  'f', OptionParser::eRequiredArgument, nullptr, {}, CommandCompletions::eDiskFileCompletion, eArgTypeFilename,    "The file into which to write the breakpoints." }, +  { LLDB_OPT_SET_ALL, false, "append",'a', OptionParser::eNoArgument,       nullptr, {}, 0,                                       eArgTypeNone,        "Append to saved breakpoints file if it exists."},      // clang-format on  }; @@ -2453,8 +2501,10 @@ protected:          return false;        }      } -    Status error = target->SerializeBreakpointsToFile( -        FileSpec(m_options.m_filename, true), valid_bp_ids, m_options.m_append); +    FileSpec file_spec(m_options.m_filename); +    FileSystem::Instance().Resolve(file_spec); +    Status error = target->SerializeBreakpointsToFile(file_spec, valid_bp_ids, +                                                      m_options.m_append);      if (!error.Success()) {        result.AppendErrorWithFormat("error serializing breakpoints: %s.",                                     error.AsCString());  | 
