[Lldb-commits] [lldb] r342185 - Add a "scripted" breakpoint type to lldb.

Davide Italiano via lldb-commits lldb-commits at lists.llvm.org
Thu Sep 13 14:50:24 PDT 2018


This last commit broke the build:


[56/997] : && /Users/buildslave/jenkins/workspace/lldb-cmake/host-compiler/bin/clang++
 -fPIC -fvisibility-inlines-hidden -Werror=date-time
-Werror=unguarded-availability-new -std=c++11 -fmodules
-fmodules-cache-path=/Users/buildslave/jenkins/workspace/lldb-cmake/lldb-build/module.cache
-fcxx-modules -Wall -Wextra -Wno-unused-parameter -Wwrite-strings
-Wcast-qual -Wmissing-field-initializers -pedantic -Wno-long-long
-Wcovered-switch-default -Wno-noexcept-type -Wnon-virtual-dtor
-Wdelete-non-virtual-dtor -Wstring-conversion -fdiagnostics-color
-fno-common -Woverloaded-virtual -Wno-nested-anon-types -O3
-Wl,-search_paths_first -Wl,-headerpad_max_install_names
-Wl,-dead_strip
tools/clang/tools/clang-format/CMakeFiles/clang-format.dir/ClangFormat.cpp.o
 -o bin/clang-format  -Wl,-rpath, at loader_path/../lib
lib/libLLVMSupport.a lib/libclangBasic.a lib/libclangFormat.a
lib/libclangRewrite.a lib/libclangToolingCore.a
lib/libclangToolingInclusions.a lib/libclangToolingCore.a
lib/libclangRewrite.a lib/libclangAST.a lib/libclangLex.a
lib/libclangBasic.a lib/libLLVMCore.a lib/libLLVMMC.a
lib/libLLVMBinaryFormat.a lib/libLLVMDebugInfoCodeView.a
lib/libLLVMDebugInfoMSF.a lib/libLLVMSupport.a -lz -lcurses -lm
lib/libLLVMDemangle.a && :

[57/997] /Users/buildslave/jenkins/workspace/lldb-cmake/host-compiler/bin/clang++
 -DGTEST_HAS_RTTI=0 -DHAVE_ROUND -DLIBXML2_DEFINED
-DLLDB_CONFIGURATION_RELEASE -DLLDB_USE_OS_LOG -D_DEBUG
-D__STDC_CONSTANT_MACROS -D__STDC_FORMAT_MACROS -D__STDC_LIMIT_MACROS
-Itools/lldb/source/Breakpoint
-I/Users/buildslave/jenkins/workspace/lldb-cmake/llvm/tools/lldb/source/Breakpoint
-Itools/lldb/include
-I/Users/buildslave/jenkins/workspace/lldb-cmake/llvm/tools/lldb/include
-I/usr/include/libxml2 -Iinclude
-I/Users/buildslave/jenkins/workspace/lldb-cmake/llvm/include
-I/usr/include/python2.7
-I/Users/buildslave/jenkins/workspace/lldb-cmake/llvm/tools/clang/include
-Itools/lldb/../clang/include
-I/Users/buildslave/jenkins/workspace/lldb-cmake/llvm/tools/lldb/source/.
-fPIC -fvisibility-inlines-hidden -Werror=date-time
-Werror=unguarded-availability-new -std=c++11 -fmodules
-fmodules-cache-path=/Users/buildslave/jenkins/workspace/lldb-cmake/lldb-build/module.cache
-fcxx-modules -Wall -Wextra -Wno-unused-parameter -Wwrite-strings
-Wcast-qual -Wmissing-field-initializers -pedantic -Wno-long-long
-Wcovered-switch-default -Wno-noexcept-type -Wnon-virtual-dtor
-Wdelete-non-virtual-dtor -Wstring-conversion -fdiagnostics-color
-Wno-deprecated-declarations -Wno-unknown-pragmas -Wno-strict-aliasing
-Wno-deprecated-register -Wno-vla-extension -O3    -UNDEBUG
-fno-exceptions -fno-rtti -MD -MT
tools/lldb/source/Breakpoint/CMakeFiles/lldbBreakpoint.dir/BreakpointResolver.cpp.o
-MF tools/lldb/source/Breakpoint/CMakeFiles/lldbBreakpoint.dir/BreakpointResolver.cpp.o.d
-o tools/lldb/source/Breakpoint/CMakeFiles/lldbBreakpoint.dir/BreakpointResolver.cpp.o
-c /Users/buildslave/jenkins/workspace/lldb-cmake/llvm/tools/lldb/source/Breakpoint/BreakpointResolver.cpp

FAILED: tools/lldb/source/Breakpoint/CMakeFiles/lldbBreakpoint.dir/BreakpointResolver.cpp.o

/Users/buildslave/jenkins/workspace/lldb-cmake/host-compiler/bin/clang++
 -DGTEST_HAS_RTTI=0 -DHAVE_ROUND -DLIBXML2_DEFINED
-DLLDB_CONFIGURATION_RELEASE -DLLDB_USE_OS_LOG -D_DEBUG
-D__STDC_CONSTANT_MACROS -D__STDC_FORMAT_MACROS -D__STDC_LIMIT_MACROS
-Itools/lldb/source/Breakpoint
-I/Users/buildslave/jenkins/workspace/lldb-cmake/llvm/tools/lldb/source/Breakpoint
-Itools/lldb/include
-I/Users/buildslave/jenkins/workspace/lldb-cmake/llvm/tools/lldb/include
-I/usr/include/libxml2 -Iinclude
-I/Users/buildslave/jenkins/workspace/lldb-cmake/llvm/include
-I/usr/include/python2.7
-I/Users/buildslave/jenkins/workspace/lldb-cmake/llvm/tools/clang/include
-Itools/lldb/../clang/include
-I/Users/buildslave/jenkins/workspace/lldb-cmake/llvm/tools/lldb/source/.
-fPIC -fvisibility-inlines-hidden -Werror=date-time
-Werror=unguarded-availability-new -std=c++11 -fmodules
-fmodules-cache-path=/Users/buildslave/jenkins/workspace/lldb-cmake/lldb-build/module.cache
-fcxx-modules -Wall -Wextra -Wno-unused-parameter -Wwrite-strings
-Wcast-qual -Wmissing-field-initializers -pedantic -Wno-long-long
-Wcovered-switch-default -Wno-noexcept-type -Wnon-virtual-dtor
-Wdelete-non-virtual-dtor -Wstring-conversion -fdiagnostics-color
-Wno-deprecated-declarations -Wno-unknown-pragmas -Wno-strict-aliasing
-Wno-deprecated-register -Wno-vla-extension -O3    -UNDEBUG
-fno-exceptions -fno-rtti -MD -MT
tools/lldb/source/Breakpoint/CMakeFiles/lldbBreakpoint.dir/BreakpointResolver.cpp.o
-MF tools/lldb/source/Breakpoint/CMakeFiles/lldbBreakpoint.dir/BreakpointResolver.cpp.o.d
-o tools/lldb/source/Breakpoint/CMakeFiles/lldbBreakpoint.dir/BreakpointResolver.cpp.o
-c /Users/buildslave/jenkins/workspace/lldb-cmake/llvm/tools/lldb/source/Breakpoint/BreakpointResolver.cpp

/Users/buildslave/jenkins/workspace/lldb-cmake/llvm/tools/lldb/source/Breakpoint/BreakpointResolver.cpp:24:10:
fatal error: 'lldb/Breakpoint/BreakpointResolverScripted.h' file not
found

#include "lldb/Breakpoint/BreakpointResolverScripted.h"

         ^~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~

1 error generated.


It should be just a little oversight, can you pleaase take a look?


Thanks!

--
Davide
On Thu, Sep 13, 2018 at 2:36 PM Jim Ingham via lldb-commits
<lldb-commits at lists.llvm.org> wrote:
>
> Modified: lldb/trunk/packages/Python/lldbsuite/test/lldbutil.py
> URL: http://llvm.org/viewvc/llvm-project/lldb/trunk/packages/Python/lldbsuite/test/lldbutil.py?rev=342185&r1=342184&r2=342185&view=diff
> ==============================================================================
> --- lldb/trunk/packages/Python/lldbsuite/test/lldbutil.py (original)
> +++ lldb/trunk/packages/Python/lldbsuite/test/lldbutil.py Thu Sep 13 14:35:32 2018
> @@ -330,6 +330,20 @@ def sort_stopped_threads(process,
>  # Utility functions for setting breakpoints
>  # ==================================================
>
> +def run_break_set_by_script(
> +        test,
> +        class_name,
> +        extra_options=None,
> +        num_expected_locations=1):
> +    """Set a scripted breakpoint.  Check that it got the right number of locations."""
> +    test.assertTrue(class_name is not None, "Must pass in a class name.")
> +    command = "breakpoint set -P " + class_name
> +    if extra_options is not None:
> +        command += " " + extra_options
> +
> +    break_results = run_break_set_command(test, command)
> +    check_breakpoint_result(test, break_results, num_locations=num_expected_locations)
> +    return get_bpno_from_match(break_results)
>
>  def run_break_set_by_file_and_line(
>          test,
> @@ -737,7 +751,7 @@ def get_crashed_threads(test, process):
>
>  # Helper functions for run_to_{source,name}_breakpoint:
>
> -def run_to_breakpoint_make_target(test, exe_name, in_cwd):
> +def run_to_breakpoint_make_target(test, exe_name = "a.out", in_cwd = True):
>      if in_cwd:
>          exe = test.getBuildArtifact(exe_name)
>
> @@ -746,7 +760,7 @@ def run_to_breakpoint_make_target(test,
>      test.assertTrue(target, "Target: %s is not valid."%(exe_name))
>      return target
>
> -def run_to_breakpoint_do_run(test, target, bkpt, launch_info):
> +def run_to_breakpoint_do_run(test, target, bkpt, launch_info = None):
>
>      # Launch the process, and do not stop at the entry point.
>      if not launch_info:
>
> Modified: lldb/trunk/scripts/Python/python-swigsafecast.swig
> URL: http://llvm.org/viewvc/llvm-project/lldb/trunk/scripts/Python/python-swigsafecast.swig?rev=342185&r1=342184&r2=342185&view=diff
> ==============================================================================
> --- lldb/trunk/scripts/Python/python-swigsafecast.swig (original)
> +++ lldb/trunk/scripts/Python/python-swigsafecast.swig Thu Sep 13 14:35:32 2018
> @@ -147,3 +147,17 @@ SBTypeToSWIGWrapper (lldb::SBTypeSummary
>  {
>      return SWIG_NewPointerObj((void *) summary_options_sb, SWIGTYPE_p_lldb__SBTypeSummaryOptions, 0);
>  }
> +
> +template <>
> +PyObject*
> +SBTypeToSWIGWrapper (lldb::SBStructuredData* structured_data_sb)
> +{
> +    return SWIG_NewPointerObj((void *) structured_data_sb, SWIGTYPE_p_lldb__SBStructuredData, 0);
> +}
> +
> +template <>
> +PyObject*
> +SBTypeToSWIGWrapper (lldb::SBSymbolContext* sym_ctx_sb)
> +{
> +    return SWIG_NewPointerObj((void *) sym_ctx_sb, SWIGTYPE_p_lldb__SBSymbolContext, 0);
> +}
>
> Modified: lldb/trunk/scripts/Python/python-wrapper.swig
> URL: http://llvm.org/viewvc/llvm-project/lldb/trunk/scripts/Python/python-wrapper.swig?rev=342185&r1=342184&r2=342185&view=diff
> ==============================================================================
> --- lldb/trunk/scripts/Python/python-wrapper.swig (original)
> +++ lldb/trunk/scripts/Python/python-wrapper.swig Thu Sep 13 14:35:32 2018
> @@ -333,6 +333,101 @@ LLDBSWIGPythonCallThreadPlan
>      return false;
>  }
>
> +SWIGEXPORT void *
> +LLDBSwigPythonCreateScriptedBreakpointResolver
> +(
> +    const char *python_class_name,
> +    const char *session_dictionary_name,
> +    lldb_private::StructuredDataImpl *args_impl,
> +    lldb::BreakpointSP &breakpoint_sp
> +)
> +{
> +    using namespace lldb_private;
> +
> +    if (python_class_name == NULL || python_class_name[0] == '\0' || !session_dictionary_name)
> +        Py_RETURN_NONE;
> +
> +    PyErr_Cleaner py_err_cleaner(true);
> +
> +    auto dict = PythonModule::MainModule().ResolveName<PythonDictionary>(session_dictionary_name);
> +    auto pfunc = PythonObject::ResolveNameWithDictionary<PythonCallable>(python_class_name, dict);
> +
> +    if (!pfunc.IsAllocated())
> +        return nullptr;
> +
> +    lldb::SBBreakpoint *bkpt_value = new lldb::SBBreakpoint(breakpoint_sp);
> +
> +    PythonObject bkpt_arg(PyRefType::Owned, SBTypeToSWIGWrapper(bkpt_value));
> +
> +    lldb::SBStructuredData *args_value = new lldb::SBStructuredData(args_impl);
> +    PythonObject args_arg(PyRefType::Owned, SBTypeToSWIGWrapper(args_value));
> +
> +    PythonObject result = pfunc(bkpt_arg, args_arg, dict);
> +    // FIXME: At this point we should check that the class we found supports all the methods
> +    // that we need.
> +
> +    if (result.IsAllocated())
> +    {
> +        // Check that __callback__ is defined:
> +        auto callback_func = result.ResolveName<PythonCallable>("__callback__");
> +        if (callback_func.IsAllocated())
> +            return result.release();
> +        else
> +            result.release();
> +    }
> +    Py_RETURN_NONE;
> +}
> +
> +SWIGEXPORT unsigned int
> +LLDBSwigPythonCallBreakpointResolver
> +(
> +    void *implementor,
> +    const char *method_name,
> +    lldb_private::SymbolContext *sym_ctx
> +)
> +{
> +    using namespace lldb_private;
> +
> +    PyErr_Cleaner py_err_cleaner(false);
> +    PythonObject self(PyRefType::Borrowed, static_cast<PyObject*>(implementor));
> +    auto pfunc = self.ResolveName<PythonCallable>(method_name);
> +
> +    if (!pfunc.IsAllocated())
> +        return 0;
> +
> +    PythonObject result;
> +    if (sym_ctx != nullptr) {
> +      lldb::SBSymbolContext sb_sym_ctx(sym_ctx);
> +      PythonObject sym_ctx_arg(PyRefType::Owned, SBTypeToSWIGWrapper(sb_sym_ctx));
> +      result = pfunc(sym_ctx_arg);
> +    } else
> +      result = pfunc();
> +
> +    if (PyErr_Occurred())
> +    {
> +        PyErr_Print();
> +        return 0;
> +    }
> +
> +    // The callback will return a bool, but we're need to also return ints
> +    // so we're squirrelling the bool through as an int...  And if you return
> +    // nothing, we'll continue.
> +    if (strcmp(method_name, "__callback__") == 0) {
> +        if (result.get() == Py_False)
> +          return 0;
> +        else
> +          return 1;
> +    }
> +
> +    PythonInteger int_result = result.AsType<PythonInteger>();
> +    if (!int_result.IsAllocated())
> +        return 0;
> +
> +    unsigned int ret_val = int_result.GetInteger();
> +
> +    return ret_val;
> +}
> +
>  // wrapper that calls an optional instance member of an object taking no arguments
>  static PyObject*
>  LLDBSwigPython_CallOptionalMember
>
> Modified: lldb/trunk/scripts/interface/SBBreakpoint.i
> URL: http://llvm.org/viewvc/llvm-project/lldb/trunk/scripts/interface/SBBreakpoint.i?rev=342185&r1=342184&r2=342185&view=diff
> ==============================================================================
> --- lldb/trunk/scripts/interface/SBBreakpoint.i (original)
> +++ lldb/trunk/scripts/interface/SBBreakpoint.i Thu Sep 13 14:35:32 2018
> @@ -226,6 +226,10 @@ public:
>      bool
>      GetDescription(lldb::SBStream &description, bool include_locations);
>
> +    // Can only be called from a ScriptedBreakpointResolver...
> +    SBError
> +    AddLocation(SBAddress &address);
> +
>      bool
>      operator == (const lldb::SBBreakpoint& rhs);
>
>
> Modified: lldb/trunk/scripts/interface/SBStructuredData.i
> URL: http://llvm.org/viewvc/llvm-project/lldb/trunk/scripts/interface/SBStructuredData.i?rev=342185&r1=342184&r2=342185&view=diff
> ==============================================================================
> --- lldb/trunk/scripts/interface/SBStructuredData.i (original)
> +++ lldb/trunk/scripts/interface/SBStructuredData.i Thu Sep 13 14:35:32 2018
> @@ -38,6 +38,8 @@ namespace lldb {
>
>          size_t GetSize() const;
>
> +        bool GetKeys(lldb::SBStringList &keys) const;
> +
>          lldb::SBStructuredData GetValueForKey(const char *key) const;
>
>          lldb::SBStructuredData GetItemAtIndex(size_t idx) const;
>
> Modified: lldb/trunk/scripts/interface/SBTarget.i
> URL: http://llvm.org/viewvc/llvm-project/lldb/trunk/scripts/interface/SBTarget.i?rev=342185&r1=342184&r2=342185&view=diff
> ==============================================================================
> --- lldb/trunk/scripts/interface/SBTarget.i (original)
> +++ lldb/trunk/scripts/interface/SBTarget.i Thu Sep 13 14:35:32 2018
> @@ -731,6 +731,74 @@ public:
>
>      lldb::SBBreakpoint
>      BreakpointCreateBySBAddress (SBAddress &sb_address);
> +
> +    %feature("docstring", "
> +  //------------------------------------------------------------------
> +  /// Create a breakpoint using a scripted resolver.
> +  ///
> +  /// @param[in] class_name
> +  ///    This is the name of the class that implements a scripted resolver.
> +  ///    The class should have the following signature:
> +  ///    class Resolver:
> +  ///        def __init__(self, bkpt, extra_args):
> +  ///            # bkpt - the breakpoint for which this is the resolver.  When
> +  ///            # the resolver finds an interesting address, call AddLocation
> +  ///            # on this breakpoint to add it.
> +  ///            #
> +  ///            # extra_args - an SBStructuredData that can be used to
> +  ///            # parametrize this instance.  Same as the extra_args passed
> +  ///            # to BreakpointCreateFromScript.
> +  ///
> +  ///        def __get_depth__ (self):
> +  ///            # This is optional, but if defined, you should return the
> +  ///            # depth at which you want the callback to be called.  The
> +  ///            # available options are:
> +  ///            #    lldb.eSearchDepthModule
> +  ///            #    lldb.eSearchDepthCompUnit
> +  ///            # The default if you don't implement this method is
> +  ///            # eSearchDepthModule.
> +  ///
> +  ///        def __callback__(self, sym_ctx):
> +  ///            # sym_ctx - an SBSymbolContext that is the cursor in the
> +  ///            # search through the program to resolve breakpoints.
> +  ///            # The sym_ctx will be filled out to the depth requested in
> +  ///            # __get_depth__.
> +  ///            # Look in this sym_ctx for new breakpoint locations,
> +  ///            # and if found use bkpt.AddLocation to add them.
> +  ///            # Note, you will only get called for modules/compile_units that
> +  ///            # pass the SearchFilter provided by the module_list & file_list
> +  ///            # passed into BreakpointCreateFromScript.
> +  ///
> +  ///        def get_short_help(self):
> +  ///            # Optional, but if implemented return a short string that will
> +  ///            # be printed at the beginning of the break list output for the
> +  ///            # breakpoint.
> +  ///
> +  /// @param[in] extra_args
> +  ///    This is an SBStructuredData object that will get passed to the
> +  ///    constructor of the class in class_name.  You can use this to
> +  ///    reuse the same class, parametrizing it with entries from this
> +  ///    dictionary.
> +  ///
> +  /// @param module_list
> +  ///    If this is non-empty, this will be used as the module filter in the
> +  ///    SearchFilter created for this breakpoint.
> +  ///
> +  /// @param file_list
> +  ///    If this is non-empty, this will be used as the comp unit filter in the
> +  ///    SearchFilter created for this breakpoint.
> +  ///
> +  /// @return
> +  ///     An SBBreakpoint that will set locations based on the logic in the
> +  ///     resolver's search callback.
> +  //------------------------------------------------------------------
> +    ") BreakpointCreateFromScript;
> +    lldb::SBBreakpoint BreakpointCreateFromScript(
> +      const char *class_name,
> +      SBStructuredData &extra_args,
> +      const SBFileSpecList &module_list,
> +      const SBFileSpecList &file_list,
> +      bool request_hardware = false);
>
>      uint32_t
>      GetNumBreakpoints () const;
>
> Modified: lldb/trunk/source/API/SBBreakpoint.cpp
> URL: http://llvm.org/viewvc/llvm-project/lldb/trunk/source/API/SBBreakpoint.cpp?rev=342185&r1=342184&r2=342185&view=diff
> ==============================================================================
> --- lldb/trunk/source/API/SBBreakpoint.cpp (original)
> +++ lldb/trunk/source/API/SBBreakpoint.cpp Thu Sep 13 14:35:32 2018
> @@ -23,6 +23,8 @@
>  #include "lldb/Breakpoint/Breakpoint.h"
>  #include "lldb/Breakpoint/BreakpointIDList.h"
>  #include "lldb/Breakpoint/BreakpointLocation.h"
> +#include "lldb/Breakpoint/BreakpointResolver.h"
> +#include "lldb/Breakpoint/BreakpointResolverScripted.h"
>  #include "lldb/Breakpoint/StoppointCallbackContext.h"
>  #include "lldb/Core/Address.h"
>  #include "lldb/Core/Debugger.h"
> @@ -487,6 +489,40 @@ bool SBBreakpoint::GetDescription(SBStre
>    return false;
>  }
>
> +SBError
> +SBBreakpoint::AddLocation(SBAddress &address) {
> +    BreakpointSP bkpt_sp = GetSP();
> +    SBError error;
> +
> +    if (!address.IsValid()) {
> +      error.SetErrorString("Can't add an invalid address.");
> +      return error;
> +    }
> +
> +    if (!bkpt_sp) {
> +      error.SetErrorString("No breakpoint to add a location to.");
> +      return error;
> +    }
> +
> +    if (!llvm::isa<BreakpointResolverScripted>(bkpt_sp->GetResolver().get())) {
> +      error.SetErrorString("Only a scripted resolver can add locations.");
> +      return error;
> +    }
> +
> +    if (bkpt_sp->GetSearchFilter()->AddressPasses(address.ref()))
> +      bkpt_sp->AddLocation(address.ref());
> +    else
> +    {
> +      StreamString s;
> +      address.get()->Dump(&s, &bkpt_sp->GetTarget(),
> +                          Address::DumpStyleModuleWithFileAddress);
> +      error.SetErrorStringWithFormat("Address: %s didn't pass the filter.",
> +                                     s.GetData());
> +    }
> +    return error;
> +}
> +
> +
>  void SBBreakpoint
>    ::SetCallback(SBBreakpointHitCallback callback,
>    void *baton) {
>
> Modified: lldb/trunk/source/API/SBStructuredData.cpp
> URL: http://llvm.org/viewvc/llvm-project/lldb/trunk/source/API/SBStructuredData.cpp?rev=342185&r1=342184&r2=342185&view=diff
> ==============================================================================
> --- lldb/trunk/source/API/SBStructuredData.cpp (original)
> +++ lldb/trunk/source/API/SBStructuredData.cpp Thu Sep 13 14:35:32 2018
> @@ -10,6 +10,7 @@
>  #include "lldb/API/SBStructuredData.h"
>
>  #include "lldb/API/SBStream.h"
> +#include "lldb/API/SBStringList.h"
>  #include "lldb/Core/Event.h"
>  #include "lldb/Core/StructuredDataImpl.h"
>  #include "lldb/Target/StructuredDataPlugin.h"
> @@ -31,6 +32,9 @@ SBStructuredData::SBStructuredData(const
>  SBStructuredData::SBStructuredData(const lldb::EventSP &event_sp)
>      : m_impl_up(new StructuredDataImpl(event_sp)) {}
>
> +SBStructuredData::SBStructuredData(lldb_private::StructuredDataImpl *impl)
> +    : m_impl_up(impl) {}
> +
>  SBStructuredData::~SBStructuredData() {}
>
>  SBStructuredData &SBStructuredData::
> @@ -76,6 +80,33 @@ size_t SBStructuredData::GetSize() const
>    return (m_impl_up ? m_impl_up->GetSize() : 0);
>  }
>
> +bool SBStructuredData::GetKeys(lldb::SBStringList &keys) const {
> +  if (!m_impl_up)
> +    return false;
> +
> +  if (GetType() != eStructuredDataTypeDictionary)
> +    return false;
> +
> +  StructuredData::ObjectSP obj_sp = m_impl_up->GetObjectSP();
> +  if (!obj_sp)
> +    return false;
> +
> +  StructuredData::Dictionary *dict = obj_sp->GetAsDictionary();
> +  // We claimed we were a dictionary, so this can't be null.
> +  assert(dict);
> +  // The return kind of GetKeys is an Array:
> +  StructuredData::ObjectSP array_sp = dict->GetKeys();
> +  StructuredData::Array *key_arr = array_sp->GetAsArray();
> +  assert(key_arr);
> +
> +  key_arr->ForEach([&keys] (StructuredData::Object *object) -> bool {
> +    llvm::StringRef key = object->GetStringValue("");
> +    keys.AppendString(key.str().c_str());
> +    return true;
> +  });
> +  return true;
> +}
> +
>  lldb::SBStructuredData SBStructuredData::GetValueForKey(const char *key) const {
>    if (!m_impl_up)
>      return SBStructuredData();
>
> Modified: lldb/trunk/source/API/SBTarget.cpp
> URL: http://llvm.org/viewvc/llvm-project/lldb/trunk/source/API/SBTarget.cpp?rev=342185&r1=342184&r2=342185&view=diff
> ==============================================================================
> --- lldb/trunk/source/API/SBTarget.cpp (original)
> +++ lldb/trunk/source/API/SBTarget.cpp Thu Sep 13 14:35:32 2018
> @@ -1044,7 +1044,7 @@ SBTarget::BreakpointCreateForException(l
>    }
>
>    if (log)
> -    log->Printf("SBTarget(%p)::BreakpointCreateByRegex (Language: %s, catch: "
> +    log->Printf("SBTarget(%p)::BreakpointCreateForException (Language: %s, catch: "
>                  "%s throw: %s) => SBBreakpoint(%p)",
>                  static_cast<void *>(target_sp.get()),
>                  Language::GetNameForLanguageType(language),
> @@ -1054,6 +1054,42 @@ SBTarget::BreakpointCreateForException(l
>    return sb_bp;
>  }
>
> +lldb::SBBreakpoint
> +SBTarget::BreakpointCreateFromScript(const char *class_name,
> +                                     SBStructuredData &extra_args,
> +                                     const SBFileSpecList &module_list,
> +                                     const SBFileSpecList &file_list,
> +                                     bool request_hardware)
> +{
> +  Log *log(lldb_private::GetLogIfAllCategoriesSet(LIBLLDB_LOG_API));
> +
> +  SBBreakpoint sb_bp;
> +  TargetSP target_sp(GetSP());
> +  if (target_sp) {
> +    std::lock_guard<std::recursive_mutex> guard(target_sp->GetAPIMutex());
> +    Status error;
> +
> +    StructuredData::ObjectSP obj_sp = extra_args.m_impl_up->GetObjectSP();
> +    sb_bp =
> +        target_sp->CreateScriptedBreakpoint(class_name,
> +                                            module_list.get(),
> +                                            file_list.get(),
> +                                            false, /* internal */
> +                                            request_hardware,
> +                                            obj_sp,
> +                                            &error);
> +  }
> +  if (log)
> +    log->Printf("SBTarget(%p)::BreakpointCreateFromScript (class name: %s) "
> +                " => SBBreakpoint(%p)",
> +                static_cast<void *>(target_sp.get()),
> +                class_name,
> +                static_cast<void *>(sb_bp.GetSP().get()));
> +
> +  return sb_bp;
> +}
> +
> +
>  uint32_t SBTarget::GetNumBreakpoints() const {
>    TargetSP target_sp(GetSP());
>    if (target_sp) {
>
> Modified: lldb/trunk/source/API/SystemInitializerFull.cpp
> URL: http://llvm.org/viewvc/llvm-project/lldb/trunk/source/API/SystemInitializerFull.cpp?rev=342185&r1=342184&r2=342185&view=diff
> ==============================================================================
> --- lldb/trunk/source/API/SystemInitializerFull.cpp (original)
> +++ lldb/trunk/source/API/SystemInitializerFull.cpp Thu Sep 13 14:35:32 2018
> @@ -176,6 +176,18 @@ extern "C" void *LLDBSwigPythonCreateScr
>  extern "C" bool LLDBSWIGPythonCallThreadPlan(void *implementor,
>                                               const char *method_name,
>                                               Event *event_sp, bool &got_error);
> +
> +extern "C" void *LLDBSwigPythonCreateScriptedBreakpointResolver(
> +    const char *python_class_name,
> +    const char *session_dictionary_name,
> +    lldb_private::StructuredDataImpl *args,
> +    lldb::BreakpointSP &bkpt_sp);
> +
> +extern "C" unsigned int LLDBSwigPythonCallBreakpointResolver(
> +    void *implementor,
> +    const char *method_name,
> +    lldb_private::SymbolContext *sym_ctx
> +);
>
>  extern "C" size_t LLDBSwigPython_CalculateNumChildren(void *implementor,
>                                                        uint32_t max);
> @@ -413,7 +425,8 @@ void SystemInitializerFull::InitializeSW
>        LLDBSWIGPythonRunScriptKeywordThread,
>        LLDBSWIGPythonRunScriptKeywordTarget, LLDBSWIGPythonRunScriptKeywordFrame,
>        LLDBSWIGPythonRunScriptKeywordValue, LLDBSWIGPython_GetDynamicSetting,
> -      LLDBSwigPythonCreateScriptedThreadPlan, LLDBSWIGPythonCallThreadPlan);
> +      LLDBSwigPythonCreateScriptedThreadPlan, LLDBSWIGPythonCallThreadPlan,
> +      LLDBSwigPythonCreateScriptedBreakpointResolver, LLDBSwigPythonCallBreakpointResolver);
>  #endif
>  }
>
>
> Modified: lldb/trunk/source/Breakpoint/BreakpointResolver.cpp
> URL: http://llvm.org/viewvc/llvm-project/lldb/trunk/source/Breakpoint/BreakpointResolver.cpp?rev=342185&r1=342184&r2=342185&view=diff
> ==============================================================================
> --- lldb/trunk/source/Breakpoint/BreakpointResolver.cpp (original)
> +++ lldb/trunk/source/Breakpoint/BreakpointResolver.cpp Thu Sep 13 14:35:32 2018
> @@ -21,6 +21,7 @@
>  #include "lldb/Breakpoint/BreakpointResolverFileLine.h"
>  #include "lldb/Breakpoint/BreakpointResolverFileRegex.h"
>  #include "lldb/Breakpoint/BreakpointResolverName.h"
> +#include "lldb/Breakpoint/BreakpointResolverScripted.h"
>  #include "lldb/Core/Address.h"
>  #include "lldb/Core/ModuleList.h"
>  #include "lldb/Core/SearchFilter.h"
> @@ -44,9 +45,10 @@ const char *BreakpointResolver::g_ty_to_
>
>  const char *BreakpointResolver::g_option_names[static_cast<uint32_t>(
>      BreakpointResolver::OptionNames::LastOptionName)] = {
> -    "AddressOffset", "Exact",       "FileName",     "Inlines",    "Language",
> -    "LineNumber",    "Column",      "ModuleName",   "NameMask",   "Offset",
> -    "Regex",         "SectionName", "SkipPrologue", "SymbolNames"};
> +    "AddressOffset", "Exact",     "FileName",     "Inlines",     "Language",
> +    "LineNumber",    "Column",    "ModuleName",   "NameMask",    "Offset",
> +    "PythonClass",   "Regex",     "ScriptArgs",   "SectionName", "SearchDepth",
> +    "SkipPrologue",  "SymbolNames"};
>
>  const char *BreakpointResolver::ResolverTyToName(enum ResolverTy type) {
>    if (type > LastKnownResolverType)
> @@ -132,6 +134,10 @@ BreakpointResolverSP BreakpointResolver:
>      resolver = BreakpointResolverFileRegex::CreateFromStructuredData(
>          nullptr, *subclass_options, error);
>      break;
> +  case PythonResolver:
> +    resolver = BreakpointResolverScripted::CreateFromStructuredData(
> +        nullptr, *subclass_options, error);
> +    break;
>    case ExceptionResolver:
>      error.SetErrorString("Exception resolvers are hard.");
>      break;
> @@ -165,6 +171,7 @@ StructuredData::DictionarySP BreakpointR
>
>  void BreakpointResolver::SetBreakpoint(Breakpoint *bkpt) {
>    m_breakpoint = bkpt;
> +  NotifyBreakpointSet();
>  }
>
>  void BreakpointResolver::ResolveBreakpointInModules(SearchFilter &filter,
>
> Modified: lldb/trunk/source/Commands/CommandObjectBreakpoint.cpp
> URL: http://llvm.org/viewvc/llvm-project/lldb/trunk/source/Commands/CommandObjectBreakpoint.cpp?rev=342185&r1=342184&r2=342185&view=diff
> ==============================================================================
> --- lldb/trunk/source/Commands/CommandObjectBreakpoint.cpp (original)
> +++ lldb/trunk/source/Commands/CommandObjectBreakpoint.cpp Thu Sep 13 14:35:32 2018
> @@ -245,10 +245,10 @@ 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))
>
> @@ -301,6 +301,9 @@ static OptionDefinition g_breakpoint_set
>    "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_11,               true, "python-class",           'P', OptionParser::eRequiredArgument, nullptr, 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, 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, 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, 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." },
> @@ -336,7 +339,8 @@ public:
>      eSetTypeFunctionName,
>      eSetTypeFunctionRegexp,
>      eSetTypeSourceRegexp,
> -    eSetTypeException
> +    eSetTypeException,
> +    eSetTypeScripted,
>    } BreakpointSetType;
>
>    CommandObjectBreakpointSet(CommandInterpreter &interpreter)
> @@ -454,7 +458,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,6 +547,10 @@ 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);
> @@ -549,6 +565,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 +619,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 {
> @@ -623,6 +652,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 +681,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;
> @@ -822,6 +856,25 @@ protected:
>          target->RemoveBreakpointByID(bp_sp->GetID());
>          result.SetStatus(eReturnStatusFailed);
>          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:
>
> Modified: lldb/trunk/source/Core/SearchFilter.cpp
> URL: http://llvm.org/viewvc/llvm-project/lldb/trunk/source/Core/SearchFilter.cpp?rev=342185&r1=342184&r2=342185&view=diff
> ==============================================================================
> --- lldb/trunk/source/Core/SearchFilter.cpp (original)
> +++ lldb/trunk/source/Core/SearchFilter.cpp Thu Sep 13 14:35:32 2018
> @@ -311,7 +311,7 @@ SearchFilter::DoCUIteration(const Module
>              return Searcher::eCallbackReturnContinue;
>            else if (shouldContinue == Searcher::eCallbackReturnStop)
>              return shouldContinue;
> -        } else {
> +        } else if (searcher.GetDepth() == lldb::eSearchDepthFunction) {
>            // FIXME Descend to block.
>          }
>        }
> @@ -748,7 +748,15 @@ SearchFilterByModuleListAndCU::Serialize
>  }
>
>  bool SearchFilterByModuleListAndCU::AddressPasses(Address &address) {
> -  return true;
> +  SymbolContext sym_ctx;
> +  address.CalculateSymbolContext(&sym_ctx, eSymbolContextEverything);
> +  if (!sym_ctx.comp_unit) {
> +    if (m_cu_spec_list.GetSize() != 0)
> +      return false; // Has no comp_unit so can't pass the file check.
> +  }
> +  if (m_cu_spec_list.FindFileIndex(0, sym_ctx.comp_unit, false) == UINT32_MAX)
> +        return false; // Fails the file check
> +  return SearchFilterByModuleList::ModulePasses(sym_ctx.module_sp);
>  }
>
>  bool SearchFilterByModuleListAndCU::CompUnitPasses(FileSpec &fileSpec) {
>
> Modified: lldb/trunk/source/Plugins/ScriptInterpreter/Python/ScriptInterpreterPython.cpp
> URL: http://llvm.org/viewvc/llvm-project/lldb/trunk/source/Plugins/ScriptInterpreter/Python/ScriptInterpreterPython.cpp?rev=342185&r1=342184&r2=342185&view=diff
> ==============================================================================
> --- lldb/trunk/source/Plugins/ScriptInterpreter/Python/ScriptInterpreterPython.cpp (original)
> +++ lldb/trunk/source/Plugins/ScriptInterpreter/Python/ScriptInterpreterPython.cpp Thu Sep 13 14:35:32 2018
> @@ -107,6 +107,10 @@ static ScriptInterpreterPython::SWIGPyth
>      g_swig_thread_plan_script = nullptr;
>  static ScriptInterpreterPython::SWIGPythonCallThreadPlan
>      g_swig_call_thread_plan = nullptr;
> +static ScriptInterpreterPython::SWIGPythonCreateScriptedBreakpointResolver
> +    g_swig_bkpt_resolver_script = nullptr;
> +static ScriptInterpreterPython::SWIGPythonCallBreakpointResolver
> +    g_swig_call_bkpt_resolver = nullptr;
>
>  static bool g_initialized = false;
>
> @@ -1868,6 +1872,84 @@ lldb::StateType ScriptInterpreterPython:
>      return lldb::eStateRunning;
>  }
>
> +StructuredData::GenericSP
> +ScriptInterpreterPython::CreateScriptedBreakpointResolver(
> +    const char *class_name,
> +    StructuredDataImpl *args_data,
> +    lldb::BreakpointSP &bkpt_sp) {
> +
> +  if (class_name == nullptr || class_name[0] == '\0')
> +    return StructuredData::GenericSP();
> +
> +  if (!bkpt_sp.get())
> +    return StructuredData::GenericSP();
> +
> +  Debugger &debugger = bkpt_sp->GetTarget().GetDebugger();
> +  ScriptInterpreter *script_interpreter =
> +      debugger.GetCommandInterpreter().GetScriptInterpreter();
> +  ScriptInterpreterPython *python_interpreter =
> +      static_cast<ScriptInterpreterPython *>(script_interpreter);
> +
> +  if (!script_interpreter)
> +    return StructuredData::GenericSP();
> +
> +  void *ret_val;
> +
> +  {
> +    Locker py_lock(this,
> +                   Locker::AcquireLock | Locker::InitSession | Locker::NoSTDIN);
> +
> +    ret_val = g_swig_bkpt_resolver_script(
> +        class_name, python_interpreter->m_dictionary_name.c_str(),
> +        args_data, bkpt_sp);
> +  }
> +
> +  return StructuredData::GenericSP(new StructuredPythonObject(ret_val));
> +}
> +
> +bool
> +ScriptInterpreterPython::ScriptedBreakpointResolverSearchCallback(
> +    StructuredData::GenericSP implementor_sp,
> +    SymbolContext *sym_ctx) {
> +  bool should_continue = false;
> +
> +  if (implementor_sp) {
> +    Locker py_lock(this,
> +                   Locker::AcquireLock | Locker::InitSession | Locker::NoSTDIN);
> +    should_continue
> +        = g_swig_call_bkpt_resolver(implementor_sp->GetValue(), "__callback__",
> +                                    sym_ctx);
> +    if (PyErr_Occurred()) {
> +      PyErr_Print();
> +      PyErr_Clear();
> +    }
> +  }
> +  return should_continue;
> +}
> +
> +lldb::SearchDepth
> +ScriptInterpreterPython::ScriptedBreakpointResolverSearchDepth(
> +    StructuredData::GenericSP implementor_sp) {
> +  int depth_as_int = lldb::eSearchDepthModule;
> +  if (implementor_sp) {
> +    Locker py_lock(this,
> +                   Locker::AcquireLock | Locker::InitSession | Locker::NoSTDIN);
> +    depth_as_int
> +        = g_swig_call_bkpt_resolver(implementor_sp->GetValue(), "__get_depth__", nullptr);
> +    if (PyErr_Occurred()) {
> +      PyErr_Print();
> +      PyErr_Clear();
> +    }
> +  }
> +  if (depth_as_int == lldb::eSearchDepthInvalid)
> +    return lldb::eSearchDepthModule;
> +
> +  if (depth_as_int <= lldb::kLastSearchDepthKind)
> +    return (lldb::SearchDepth) depth_as_int;
> +  else
> +    return lldb::eSearchDepthModule;
> +}
> +
>  StructuredData::ObjectSP
>  ScriptInterpreterPython::LoadPluginModule(const FileSpec &file_spec,
>                                            lldb_private::Status &error) {
> @@ -3107,7 +3189,9 @@ void ScriptInterpreterPython::Initialize
>      SWIGPythonScriptKeyword_Value swig_run_script_keyword_value,
>      SWIGPython_GetDynamicSetting swig_plugin_get,
>      SWIGPythonCreateScriptedThreadPlan swig_thread_plan_script,
> -    SWIGPythonCallThreadPlan swig_call_thread_plan) {
> +    SWIGPythonCallThreadPlan swig_call_thread_plan,
> +    SWIGPythonCreateScriptedBreakpointResolver swig_bkpt_resolver_script,
> +    SWIGPythonCallBreakpointResolver swig_call_bkpt_resolver) {
>    g_swig_init_callback = swig_init_callback;
>    g_swig_breakpoint_callback = swig_breakpoint_callback;
>    g_swig_watchpoint_callback = swig_watchpoint_callback;
> @@ -3134,6 +3218,8 @@ void ScriptInterpreterPython::Initialize
>    g_swig_plugin_get = swig_plugin_get;
>    g_swig_thread_plan_script = swig_thread_plan_script;
>    g_swig_call_thread_plan = swig_call_thread_plan;
> +  g_swig_bkpt_resolver_script = swig_bkpt_resolver_script;
> +  g_swig_call_bkpt_resolver = swig_call_bkpt_resolver;
>  }
>
>  void ScriptInterpreterPython::InitializePrivate() {
>
> Modified: lldb/trunk/source/Plugins/ScriptInterpreter/Python/ScriptInterpreterPython.h
> URL: http://llvm.org/viewvc/llvm-project/lldb/trunk/source/Plugins/ScriptInterpreter/Python/ScriptInterpreterPython.h?rev=342185&r1=342184&r2=342185&view=diff
> ==============================================================================
> --- lldb/trunk/source/Plugins/ScriptInterpreter/Python/ScriptInterpreterPython.h (original)
> +++ lldb/trunk/source/Plugins/ScriptInterpreter/Python/ScriptInterpreterPython.h Thu Sep 13 14:35:32 2018
> @@ -81,6 +81,15 @@ public:
>                                             const char *method_name,
>                                             Event *event_sp, bool &got_error);
>
> +  typedef void *(*SWIGPythonCreateScriptedBreakpointResolver)(
> +      const char *python_class_name, const char *session_dictionary_name,
> +      lldb_private::StructuredDataImpl *args_impl,
> +      lldb::BreakpointSP &bkpt_sp);
> +
> +  typedef unsigned int (*SWIGPythonCallBreakpointResolver)(void *implementor,
> +                                          const char *method_name,
> +                                          lldb_private::SymbolContext *sym_ctx);
> +
>    typedef void *(*SWIGPythonCreateOSPlugin)(const char *python_class_name,
>                                              const char *session_dictionary_name,
>                                              const lldb::ProcessSP &process_sp);
> @@ -208,6 +217,19 @@ public:
>    lldb::StateType
>    ScriptedThreadPlanGetRunState(StructuredData::ObjectSP implementor_sp,
>                                  bool &script_error) override;
> +
> +  StructuredData::GenericSP
> +  CreateScriptedBreakpointResolver(const char *class_name,
> +                                   StructuredDataImpl *args_data,
> +                                   lldb::BreakpointSP &bkpt_sp) override;
> +  bool
> +  ScriptedBreakpointResolverSearchCallback(StructuredData::GenericSP
> +                                               implementor_sp,
> +                                           SymbolContext *sym_ctx) override;
> +
> +  lldb::SearchDepth
> +  ScriptedBreakpointResolverSearchDepth(StructuredData::GenericSP
> +                                            implementor_sp) override;
>
>    StructuredData::GenericSP
>    OSPlugin_CreatePluginObject(const char *class_name,
> @@ -411,7 +433,9 @@ public:
>        SWIGPythonScriptKeyword_Value swig_run_script_keyword_value,
>        SWIGPython_GetDynamicSetting swig_plugin_get,
>        SWIGPythonCreateScriptedThreadPlan swig_thread_plan_script,
> -      SWIGPythonCallThreadPlan swig_call_thread_plan);
> +      SWIGPythonCallThreadPlan swig_call_thread_plan,
> +      SWIGPythonCreateScriptedBreakpointResolver swig_bkpt_resolver_script,
> +      SWIGPythonCallBreakpointResolver swig_call_breakpoint_resolver);
>
>    const char *GetDictionaryName() { return m_dictionary_name.c_str(); }
>
>
> Modified: lldb/trunk/source/Target/Target.cpp
> URL: http://llvm.org/viewvc/llvm-project/lldb/trunk/source/Target/Target.cpp?rev=342185&r1=342184&r2=342185&view=diff
> ==============================================================================
> --- lldb/trunk/source/Target/Target.cpp (original)
> +++ lldb/trunk/source/Target/Target.cpp Thu Sep 13 14:35:32 2018
> @@ -21,6 +21,7 @@
>  #include "lldb/Breakpoint/BreakpointResolverFileLine.h"
>  #include "lldb/Breakpoint/BreakpointResolverFileRegex.h"
>  #include "lldb/Breakpoint/BreakpointResolverName.h"
> +#include "lldb/Breakpoint/BreakpointResolverScripted.h"
>  #include "lldb/Breakpoint/Watchpoint.h"
>  #include "lldb/Core/Debugger.h"
>  #include "lldb/Core/Event.h"
> @@ -28,8 +29,10 @@
>  #include "lldb/Core/ModuleSpec.h"
>  #include "lldb/Core/PluginManager.h"
>  #include "lldb/Core/Section.h"
> +#include "lldb/Core/SearchFilter.h"
>  #include "lldb/Core/SourceManager.h"
>  #include "lldb/Core/StreamFile.h"
> +#include "lldb/Core/StructuredDataImpl.h"
>  #include "lldb/Core/ValueObject.h"
>  #include "lldb/Expression/REPL.h"
>  #include "lldb/Expression/UserExpression.h"
> @@ -579,6 +582,48 @@ Target::CreateExceptionBreakpoint(enum l
>    return exc_bkpt_sp;
>  }
>
> +lldb::BreakpointSP
> +Target::CreateScriptedBreakpoint(const llvm::StringRef class_name,
> +                                 const FileSpecList *containingModules,
> +                                 const FileSpecList *containingSourceFiles,
> +                                 bool internal,
> +                                 bool request_hardware,
> +                                 StructuredData::ObjectSP extra_args_sp,
> +                                 Status *creation_error)
> +{
> +  SearchFilterSP filter_sp;
> +
> +  lldb::SearchDepth depth = lldb::eSearchDepthTarget;
> +  bool has_files = containingSourceFiles && containingSourceFiles->GetSize() > 0;
> +  bool has_modules = containingModules && containingModules->GetSize() > 0;
> +
> +  if (has_files && has_modules) {
> +    filter_sp = GetSearchFilterForModuleAndCUList(
> +      containingModules, containingSourceFiles);
> +  } else if (has_files) {
> +    filter_sp = GetSearchFilterForModuleAndCUList(
> +      nullptr, containingSourceFiles);
> +  } else if (has_modules) {
> +    filter_sp = GetSearchFilterForModuleList(containingModules);
> +  } else {
> +    filter_sp.reset(new SearchFilterForUnconstrainedSearches(shared_from_this()));
> +  }
> +
> +  StructuredDataImpl *extra_args_impl = new StructuredDataImpl();
> +  if (extra_args_sp)
> +    extra_args_impl->SetObjectSP(extra_args_sp);
> +
> +  BreakpointResolverSP resolver_sp(new
> +                                   BreakpointResolverScripted(nullptr, class_name,
> +                                   depth,
> +                                   extra_args_impl,
> +                                   *GetDebugger().GetCommandInterpreter()
> +                                       .GetScriptInterpreter()));
> +  return CreateBreakpoint(filter_sp, resolver_sp, internal, false, true);
> +
> +}
> +
> +
>  BreakpointSP Target::CreateBreakpoint(SearchFilterSP &filter_sp,
>                                        BreakpointResolverSP &resolver_sp,
>                                        bool internal, bool request_hardware,
>
>
> _______________________________________________
> lldb-commits mailing list
> lldb-commits at lists.llvm.org
> http://lists.llvm.org/cgi-bin/mailman/listinfo/lldb-commits


More information about the lldb-commits mailing list