diff options
| author | Dimitry Andric <dim@FreeBSD.org> | 2021-02-16 20:13:02 +0000 |
|---|---|---|
| committer | Dimitry Andric <dim@FreeBSD.org> | 2021-02-16 20:13:02 +0000 |
| commit | b60736ec1405bb0a8dd40989f67ef4c93da068ab (patch) | |
| tree | 5c43fbb7c9fc45f0f87e0e6795a86267dbd12f9d /lldb/bindings/python/python-wrapper.swig | |
| parent | cfca06d7963fa0909f90483b42a6d7d194d01e08 (diff) | |
Diffstat (limited to 'lldb/bindings/python/python-wrapper.swig')
| -rw-r--r-- | lldb/bindings/python/python-wrapper.swig | 132 |
1 files changed, 126 insertions, 6 deletions
diff --git a/lldb/bindings/python/python-wrapper.swig b/lldb/bindings/python/python-wrapper.swig index f9e89373fe25..443ddfb8dd20 100644 --- a/lldb/bindings/python/python-wrapper.swig +++ b/lldb/bindings/python/python-wrapper.swig @@ -271,9 +271,6 @@ LLDBSwigPythonCreateScriptedThreadPlan if (python_class_name == NULL || python_class_name[0] == '\0' || !session_dictionary_name) Py_RETURN_NONE; - // I do not want the SBThreadPlan to be deallocated when going out of scope because python - // has ownership of it and will manage memory for this object by itself - lldb::SBThreadPlan *tp_value = new lldb::SBThreadPlan(thread_plan_sp); PyErr_Cleaner py_err_cleaner(true); @@ -286,7 +283,10 @@ LLDBSwigPythonCreateScriptedThreadPlan return nullptr; } - PythonObject tp_arg(PyRefType::Owned, SBTypeToSWIGWrapper(tp_value)); + // I do not want the SBThreadPlan to be deallocated when going out of scope + // because python has ownership of it and will manage memory for this + // object by itself + PythonObject tp_arg(PyRefType::Owned, SBTypeToSWIGWrapper(new lldb::SBThreadPlan(thread_plan_sp))); if (!tp_arg.IsAllocated()) Py_RETURN_NONE; @@ -312,8 +312,7 @@ LLDBSwigPythonCreateScriptedThreadPlan } result = pfunc(tp_arg, dict); } else if (arg_info.get().max_positional_args >= 3) { - lldb::SBStructuredData *args_value = new lldb::SBStructuredData(args_impl); - PythonObject args_arg(PyRefType::Owned, SBTypeToSWIGWrapper(args_value)); + PythonObject args_arg(PyRefType::Owned, SBTypeToSWIGWrapper(new lldb::SBStructuredData(args_impl))); result = pfunc(tp_arg, args_arg, dict); } else { error_string.assign("wrong number of arguments in __init__, should be 2 or 3 (not including self)"); @@ -469,6 +468,127 @@ LLDBSwigPythonCallBreakpointResolver return ret_val; } +SWIGEXPORT void * +LLDBSwigPythonCreateScriptedStopHook +( + lldb::TargetSP target_sp, + const char *python_class_name, + const char *session_dictionary_name, + lldb_private::StructuredDataImpl *args_impl, + Status &error +) +{ + if (python_class_name == NULL || python_class_name[0] == '\0') { + error.SetErrorString("Empty class name."); + Py_RETURN_NONE; + } + if (!session_dictionary_name) { + error.SetErrorString("No session dictionary"); + 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()) { + error.SetErrorStringWithFormat("Could not find class: %s.", + python_class_name); + return nullptr; + } + + lldb::SBTarget *target_val + = new lldb::SBTarget(target_sp); + + PythonObject target_arg(PyRefType::Owned, SBTypeToSWIGWrapper(target_val)); + + lldb::SBStructuredData *args_value = new lldb::SBStructuredData(args_impl); + PythonObject args_arg(PyRefType::Owned, SBTypeToSWIGWrapper(args_value)); + + PythonObject result = pfunc(target_arg, args_arg, dict); + + if (result.IsAllocated()) + { + // Check that the handle_stop callback is defined: + auto callback_func = result.ResolveName<PythonCallable>("handle_stop"); + if (callback_func.IsAllocated()) { + if (auto args_info = callback_func.GetArgInfo()) { + size_t num_args = (*args_info).max_positional_args; + if (num_args != 2) { + error.SetErrorStringWithFormat("Wrong number of args for " + "handle_stop callback, should be 2 (excluding self), got: %zu", + num_args); + Py_RETURN_NONE; + } else + return result.release(); + } else { + error.SetErrorString("Couldn't get num arguments for handle_stop " + "callback."); + Py_RETURN_NONE; + } + return result.release(); + } + else { + error.SetErrorStringWithFormat("Class \"%s\" is missing the required " + "handle_stop callback.", + python_class_name); + result.release(); + } + } + Py_RETURN_NONE; +} + +SWIGEXPORT bool +LLDBSwigPythonStopHookCallHandleStop +( + void *implementor, + lldb::ExecutionContextRefSP exc_ctx_sp, + lldb::StreamSP stream +) +{ + // handle_stop will return a bool with the meaning "should_stop"... + // If you return nothing we'll assume we are going to stop. + // Also any errors should return true, since we should stop on error. + + PyErr_Cleaner py_err_cleaner(false); + PythonObject self(PyRefType::Borrowed, static_cast<PyObject*>(implementor)); + auto pfunc = self.ResolveName<PythonCallable>("handle_stop"); + + if (!pfunc.IsAllocated()) + return true; + + PythonObject result; + lldb::SBExecutionContext sb_exc_ctx(exc_ctx_sp); + PythonObject exc_ctx_arg(PyRefType::Owned, SBTypeToSWIGWrapper(sb_exc_ctx)); + lldb::SBStream sb_stream; + PythonObject sb_stream_arg(PyRefType::Owned, + SBTypeToSWIGWrapper(sb_stream)); + result = pfunc(exc_ctx_arg, sb_stream_arg); + + if (PyErr_Occurred()) + { + stream->PutCString("Python error occurred handling stop-hook."); + PyErr_Print(); + PyErr_Clear(); + return true; + } + + // Now add the result to the output stream. SBStream only + // makes an internally help StreamString which I can't interpose, so I + // have to copy it over here. + stream->PutCString(sb_stream.GetData()); + + if (result.get() == Py_False) + return false; + else + return true; +} + // wrapper that calls an optional instance member of an object taking no arguments static PyObject* LLDBSwigPython_CallOptionalMember |
