diff options
Diffstat (limited to 'lldb/scripts')
-rw-r--r-- | lldb/scripts/Python/python-swigsafecast.swig | 14 | ||||
-rw-r--r-- | lldb/scripts/Python/python-wrapper.swig | 95 | ||||
-rw-r--r-- | lldb/scripts/interface/SBBreakpoint.i | 4 | ||||
-rw-r--r-- | lldb/scripts/interface/SBStructuredData.i | 2 | ||||
-rw-r--r-- | lldb/scripts/interface/SBTarget.i | 68 |
5 files changed, 183 insertions, 0 deletions
diff --git a/lldb/scripts/Python/python-swigsafecast.swig b/lldb/scripts/Python/python-swigsafecast.swig index ffd7546323a..57ae00c067d 100644 --- a/lldb/scripts/Python/python-swigsafecast.swig +++ b/lldb/scripts/Python/python-swigsafecast.swig @@ -147,3 +147,17 @@ SBTypeToSWIGWrapper (lldb::SBTypeSummaryOptions* summary_options_sb) { 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); +} diff --git a/lldb/scripts/Python/python-wrapper.swig b/lldb/scripts/Python/python-wrapper.swig index 96b8dda80f8..1679d895e4a 100644 --- a/lldb/scripts/Python/python-wrapper.swig +++ b/lldb/scripts/Python/python-wrapper.swig @@ -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 diff --git a/lldb/scripts/interface/SBBreakpoint.i b/lldb/scripts/interface/SBBreakpoint.i index 525797ad91f..b810682d10f 100644 --- a/lldb/scripts/interface/SBBreakpoint.i +++ b/lldb/scripts/interface/SBBreakpoint.i @@ -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); diff --git a/lldb/scripts/interface/SBStructuredData.i b/lldb/scripts/interface/SBStructuredData.i index 4e54cdd7b40..d30179c4d48 100644 --- a/lldb/scripts/interface/SBStructuredData.i +++ b/lldb/scripts/interface/SBStructuredData.i @@ -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; diff --git a/lldb/scripts/interface/SBTarget.i b/lldb/scripts/interface/SBTarget.i index 993c374080c..1743b4d0858 100644 --- a/lldb/scripts/interface/SBTarget.i +++ b/lldb/scripts/interface/SBTarget.i @@ -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; |