diff --git a/lldb/bindings/python/python-swigsafecast.swig b/lldb/bindings/python/python-swigsafecast.swig --- a/lldb/bindings/python/python-swigsafecast.swig +++ b/lldb/bindings/python/python-swigsafecast.swig @@ -5,18 +5,6 @@ return SWIG_NewPointerObj(&event_sb, SWIGTYPE_p_lldb__SBEvent, 0); } -PyObject *SBTypeToSWIGWrapper(lldb::SBThread &thread_sb) { - return SWIG_NewPointerObj(&thread_sb, SWIGTYPE_p_lldb__SBThread, 0); -} - -PyObject *SBTypeToSWIGWrapper(lldb::SBFrame &frame_sb) { - return SWIG_NewPointerObj(&frame_sb, SWIGTYPE_p_lldb__SBFrame, 0); -} - -PyObject *SBTypeToSWIGWrapper(lldb::SBDebugger &debugger_sb) { - return SWIG_NewPointerObj(&debugger_sb, SWIGTYPE_p_lldb__SBDebugger, 0); -} - PyObject *SBTypeToSWIGWrapper(lldb::SBWatchpoint &watchpoint_sb) { return SWIG_NewPointerObj(&watchpoint_sb, SWIGTYPE_p_lldb__SBWatchpoint, 0); } @@ -89,5 +77,20 @@ return ToSWIGWrapper(std::make_unique(data_impl)); } +PythonObject ToSWIGWrapper(lldb::ThreadSP thread_sp) { + return ToSWIGHelper(new lldb::SBThread(std::move(thread_sp)), + SWIGTYPE_p_lldb__SBThread); +} + +PythonObject ToSWIGWrapper(lldb::StackFrameSP frame_sp) { + return ToSWIGHelper(new lldb::SBFrame(std::move(frame_sp)), + SWIGTYPE_p_lldb__SBFrame); +} + +PythonObject ToSWIGWrapper(lldb::DebuggerSP debugger_sp) { + return ToSWIGHelper(new lldb::SBDebugger(std::move(debugger_sp)), + SWIGTYPE_p_lldb__SBDebugger); +} + } // namespace python } // namespace lldb_private diff --git a/lldb/bindings/python/python-wrapper.swig b/lldb/bindings/python/python-wrapper.swig --- a/lldb/bindings/python/python-wrapper.swig +++ b/lldb/bindings/python/python-wrapper.swig @@ -23,7 +23,6 @@ const lldb_private::StructuredDataImpl &args_impl) { using namespace llvm; - lldb::SBFrame sb_frame(frame_sp); lldb::SBBreakpointLocation sb_bp_loc(bp_loc_sp); PyErr_Cleaner py_err_cleaner(true); @@ -38,7 +37,7 @@ else return arg_info.takeError(); - PythonObject frame_arg(PyRefType::Owned, SBTypeToSWIGWrapper(sb_frame)); + PythonObject frame_arg = ToSWIGWrapper(frame_sp); PythonObject bp_loc_arg(PyRefType::Owned, SBTypeToSWIGWrapper(sb_bp_loc)); auto result = [&]() -> Expected { @@ -71,7 +70,6 @@ bool lldb_private::LLDBSwigPythonWatchpointCallbackFunction( const char *python_function_name, const char *session_dictionary_name, const lldb::StackFrameSP &frame_sp, const lldb::WatchpointSP &wp_sp) { - lldb::SBFrame sb_frame(frame_sp); lldb::SBWatchpoint sb_wp(wp_sp); bool stop_at_watchpoint = true; @@ -86,7 +84,7 @@ if (!pfunc.IsAllocated()) return stop_at_watchpoint; - PythonObject frame_arg(PyRefType::Owned, SBTypeToSWIGWrapper(sb_frame)); + PythonObject frame_arg = ToSWIGWrapper(frame_sp); PythonObject wp_arg(PyRefType::Owned, SBTypeToSWIGWrapper(sb_wp)); PythonObject result = pfunc(frame_arg, wp_arg, dict); @@ -194,7 +192,7 @@ void *lldb_private::LLDBSwigPythonCreateCommandObject( const char *python_class_name, const char *session_dictionary_name, - const lldb::DebuggerSP debugger_sp) { + lldb::DebuggerSP debugger_sp) { if (python_class_name == NULL || python_class_name[0] == '\0' || !session_dictionary_name) Py_RETURN_NONE; @@ -208,9 +206,7 @@ if (!pfunc.IsAllocated()) return nullptr; - lldb::SBDebugger debugger_sb(debugger_sp); - PythonObject debugger_arg(PyRefType::Owned, SBTypeToSWIGWrapper(debugger_sb)); - PythonObject result = pfunc(debugger_arg, dict); + PythonObject result = pfunc(ToSWIGWrapper(std::move(debugger_sp)), dict); if (result.IsAllocated()) return result.release(); @@ -809,11 +805,10 @@ bool lldb_private::LLDBSwigPythonCallCommand( const char *python_function_name, const char *session_dictionary_name, - lldb::DebuggerSP &debugger, const char *args, + lldb::DebuggerSP debugger, const char *args, lldb_private::CommandReturnObject &cmd_retobj, lldb::ExecutionContextRefSP exe_ctx_ref_sp) { lldb::SBCommandReturnObject cmd_retobj_sb(cmd_retobj); - lldb::SBDebugger debugger_sb(debugger); lldb::SBExecutionContext exe_ctx_sb(exe_ctx_ref_sp); PyErr_Cleaner py_err_cleaner(true); @@ -830,7 +825,7 @@ llvm::consumeError(argc.takeError()); return false; } - PythonObject debugger_arg(PyRefType::Owned, SBTypeToSWIGWrapper(debugger_sb)); + PythonObject debugger_arg = ToSWIGWrapper(std::move(debugger)); PythonObject exe_ctx_arg(PyRefType::Owned, SBTypeToSWIGWrapper(exe_ctx_sb)); PythonObject cmd_retobj_arg(PyRefType::Owned, SBTypeToSWIGWrapper(cmd_retobj_sb)); @@ -844,11 +839,10 @@ } bool lldb_private::LLDBSwigPythonCallCommandObject( - PyObject * implementor, lldb::DebuggerSP & debugger, const char *args, + PyObject *implementor, lldb::DebuggerSP debugger, const char *args, lldb_private::CommandReturnObject &cmd_retobj, lldb::ExecutionContextRefSP exe_ctx_ref_sp) { lldb::SBCommandReturnObject cmd_retobj_sb(cmd_retobj); - lldb::SBDebugger debugger_sb(debugger); lldb::SBExecutionContext exe_ctx_sb(exe_ctx_ref_sp); PyErr_Cleaner py_err_cleaner(true); @@ -859,12 +853,12 @@ if (!pfunc.IsAllocated()) return false; - PythonObject debugger_arg(PyRefType::Owned, SBTypeToSWIGWrapper(debugger_sb)); PythonObject exe_ctx_arg(PyRefType::Owned, SBTypeToSWIGWrapper(exe_ctx_sb)); PythonObject cmd_retobj_arg(PyRefType::Owned, SBTypeToSWIGWrapper(cmd_retobj_sb)); - pfunc(debugger_arg, PythonString(args), exe_ctx_arg, cmd_retobj_arg); + pfunc(ToSWIGWrapper(std::move(debugger)), PythonString(args), exe_ctx_arg, + cmd_retobj_arg); return true; } @@ -922,8 +916,7 @@ PyObject * implementor, const lldb::StackFrameSP &frame_sp) { static char callee_name[] = "get_recognized_arguments"; - lldb::SBFrame frame_sb(frame_sp); - PyObject *arg = SBTypeToSWIGWrapper(frame_sb); + PythonObject arg = ToSWIGWrapper(frame_sp); PythonString str(callee_name); PyObject *result = @@ -973,14 +966,12 @@ return true; } -bool lldb_private::LLDBSWIGPythonRunScriptKeywordThread( +llvm::Optional lldb_private::LLDBSWIGPythonRunScriptKeywordThread( const char *python_function_name, const char *session_dictionary_name, - lldb::ThreadSP &thread, std::string &output) - -{ + lldb::ThreadSP thread) { if (python_function_name == NULL || python_function_name[0] == '\0' || !session_dictionary_name) - return false; + return llvm::None; PyErr_Cleaner py_err_cleaner(true); @@ -990,15 +981,11 @@ python_function_name, dict); if (!pfunc.IsAllocated()) - return false; + return llvm::None; - lldb::SBThread thread_sb(thread); - PythonObject thread_arg(PyRefType::Owned, SBTypeToSWIGWrapper(thread_sb)); - auto result = pfunc(thread_arg, dict); + auto result = pfunc(ToSWIGWrapper(std::move(thread)), dict); - output = result.Str().GetString().str(); - - return true; + return result.Str().GetString().str(); } bool lldb_private::LLDBSWIGPythonRunScriptKeywordTarget( @@ -1026,14 +1013,12 @@ return true; } -bool lldb_private::LLDBSWIGPythonRunScriptKeywordFrame( +llvm::Optional lldb_private::LLDBSWIGPythonRunScriptKeywordFrame( const char *python_function_name, const char *session_dictionary_name, - lldb::StackFrameSP &frame, std::string &output) - -{ + lldb::StackFrameSP frame) { if (python_function_name == NULL || python_function_name[0] == '\0' || !session_dictionary_name) - return false; + return llvm::None; PyErr_Cleaner py_err_cleaner(true); @@ -1043,15 +1028,11 @@ python_function_name, dict); if (!pfunc.IsAllocated()) - return false; + return llvm::None; - lldb::SBFrame frame_sb(frame); - PythonObject frame_arg(PyRefType::Owned, SBTypeToSWIGWrapper(frame_sb)); - auto result = pfunc(frame_arg, dict); + auto result = pfunc(ToSWIGWrapper(std::move(frame)), dict); - output = result.Str().GetString().str(); - - return true; + return result.Str().GetString().str(); } bool lldb_private::LLDBSWIGPythonRunScriptKeywordValue( @@ -1081,7 +1062,7 @@ bool lldb_private::LLDBSwigPythonCallModuleInit( const char *python_module_name, const char *session_dictionary_name, - lldb::DebuggerSP &debugger) { + lldb::DebuggerSP debugger) { std::string python_function_name_string = python_module_name; python_function_name_string += ".__lldb_init_module"; const char *python_function_name = python_function_name_string.c_str(); @@ -1098,9 +1079,7 @@ if (!pfunc.IsAllocated()) return true; - lldb::SBDebugger debugger_sb(debugger); - PythonObject debugger_arg(PyRefType::Owned, SBTypeToSWIGWrapper(debugger_sb)); - pfunc(debugger_arg, dict); + pfunc(ToSWIGWrapper(std::move(debugger)), dict); return true; } diff --git a/lldb/source/Plugins/ScriptInterpreter/Python/SWIGPythonBridge.h b/lldb/source/Plugins/ScriptInterpreter/Python/SWIGPythonBridge.h --- a/lldb/source/Plugins/ScriptInterpreter/Python/SWIGPythonBridge.h +++ b/lldb/source/Plugins/ScriptInterpreter/Python/SWIGPythonBridge.h @@ -90,7 +90,7 @@ void *LLDBSwigPythonCreateCommandObject(const char *python_class_name, const char *session_dictionary_name, - const lldb::DebuggerSP debugger_sp); + lldb::DebuggerSP debugger_sp); void *LLDBSwigPythonCreateScriptedThreadPlan( const char *python_class_name, const char *session_dictionary_name, @@ -137,18 +137,18 @@ bool LLDBSwigPythonCallCommand(const char *python_function_name, const char *session_dictionary_name, - lldb::DebuggerSP &debugger, const char *args, + lldb::DebuggerSP debugger, const char *args, lldb_private::CommandReturnObject &cmd_retobj, lldb::ExecutionContextRefSP exe_ctx_ref_sp); bool LLDBSwigPythonCallCommandObject( - PyObject *implementor, lldb::DebuggerSP &debugger, const char *args, + PyObject *implementor, lldb::DebuggerSP debugger, const char *args, lldb_private::CommandReturnObject &cmd_retobj, lldb::ExecutionContextRefSP exe_ctx_ref_sp); bool LLDBSwigPythonCallModuleInit(const char *python_module_name, const char *session_dictionary_name, - lldb::DebuggerSP &debugger); + lldb::DebuggerSP debugger); void *LLDBSWIGPythonCreateOSPlugin(const char *python_class_name, const char *session_dictionary_name, @@ -166,20 +166,20 @@ const lldb::ProcessSP &process, std::string &output); -bool LLDBSWIGPythonRunScriptKeywordThread(const char *python_function_name, - const char *session_dictionary_name, - lldb::ThreadSP &thread, - std::string &output); +llvm::Optional +LLDBSWIGPythonRunScriptKeywordThread(const char *python_function_name, + const char *session_dictionary_name, + lldb::ThreadSP thread); bool LLDBSWIGPythonRunScriptKeywordTarget(const char *python_function_name, const char *session_dictionary_name, const lldb::TargetSP &target, std::string &output); -bool LLDBSWIGPythonRunScriptKeywordFrame(const char *python_function_name, - const char *session_dictionary_name, - lldb::StackFrameSP &frame, - std::string &output); +llvm::Optional +LLDBSWIGPythonRunScriptKeywordFrame(const char *python_function_name, + const char *session_dictionary_name, + lldb::StackFrameSP frame); bool LLDBSWIGPythonRunScriptKeywordValue(const char *python_function_name, const char *session_dictionary_name, diff --git a/lldb/source/Plugins/ScriptInterpreter/Python/ScriptInterpreterPython.cpp b/lldb/source/Plugins/ScriptInterpreter/Python/ScriptInterpreterPython.cpp --- a/lldb/source/Plugins/ScriptInterpreter/Python/ScriptInterpreterPython.cpp +++ b/lldb/source/Plugins/ScriptInterpreter/Python/ScriptInterpreterPython.cpp @@ -2521,7 +2521,6 @@ bool ScriptInterpreterPythonImpl::RunScriptFormatKeyword( const char *impl_function, Thread *thread, std::string &output, Status &error) { - bool ret_val; if (!thread) { error.SetErrorString("no thread"); return false; @@ -2531,16 +2530,16 @@ return false; } - { - ThreadSP thread_sp(thread->shared_from_this()); - Locker py_lock(this, - Locker::AcquireLock | Locker::InitSession | Locker::NoSTDIN); - ret_val = LLDBSWIGPythonRunScriptKeywordThread( - impl_function, m_dictionary_name.c_str(), thread_sp, output); - if (!ret_val) - error.SetErrorString("python script evaluation failed"); + Locker py_lock(this, + Locker::AcquireLock | Locker::InitSession | Locker::NoSTDIN); + if (llvm::Optional result = LLDBSWIGPythonRunScriptKeywordThread( + impl_function, m_dictionary_name.c_str(), + thread->shared_from_this())) { + output = std::move(*result); + return true; } - return ret_val; + error.SetErrorString("python script evaluation failed"); + return false; } bool ScriptInterpreterPythonImpl::RunScriptFormatKeyword( @@ -2571,7 +2570,6 @@ bool ScriptInterpreterPythonImpl::RunScriptFormatKeyword( const char *impl_function, StackFrame *frame, std::string &output, Status &error) { - bool ret_val; if (!frame) { error.SetErrorString("no frame"); return false; @@ -2581,16 +2579,16 @@ return false; } - { - StackFrameSP frame_sp(frame->shared_from_this()); - Locker py_lock(this, - Locker::AcquireLock | Locker::InitSession | Locker::NoSTDIN); - ret_val = LLDBSWIGPythonRunScriptKeywordFrame( - impl_function, m_dictionary_name.c_str(), frame_sp, output); - if (!ret_val) - error.SetErrorString("python script evaluation failed"); + Locker py_lock(this, + Locker::AcquireLock | Locker::InitSession | Locker::NoSTDIN); + if (llvm::Optional result = LLDBSWIGPythonRunScriptKeywordFrame( + impl_function, m_dictionary_name.c_str(), + frame->shared_from_this())) { + output = std::move(*result); + return true; } - return ret_val; + error.SetErrorString("python script evaluation failed"); + return false; } bool ScriptInterpreterPythonImpl::RunScriptFormatKeyword( @@ -2655,7 +2653,6 @@ } ScriptInterpreterIORedirect &io_redirect = **io_redirect_or_error; - lldb::DebuggerSP debugger_sp = m_debugger.shared_from_this(); // Before executing Python code, lock the GIL. Locker py_lock(this, @@ -2792,7 +2789,8 @@ // if we are here, everything worked // call __lldb_init_module(debugger,dict) if (!LLDBSwigPythonCallModuleInit(module_name.c_str(), - m_dictionary_name.c_str(), debugger_sp)) { + m_dictionary_name.c_str(), + m_debugger.shared_from_this())) { error.SetErrorString("calling __lldb_init_module failed"); return false; } diff --git a/lldb/test/API/commands/command/script/TestCommandScript.py b/lldb/test/API/commands/command/script/TestCommandScript.py --- a/lldb/test/API/commands/command/script/TestCommandScript.py +++ b/lldb/test/API/commands/command/script/TestCommandScript.py @@ -165,3 +165,9 @@ self.runCmd('command script add -f bug11569 bug11569') # This should not crash. self.runCmd('bug11569', check=False) + + def test_persistence(self): + self.runCmd("command script import persistence.py") + self.runCmd("command script add -f persistence.save_debugger save_debugger") + self.expect("save_debugger", substrs=[str(self.dbg)]) + self.expect("script str(persistence.debugger_copy)", substrs=[str(self.dbg)]) diff --git a/lldb/test/API/commands/command/script/persistence.py b/lldb/test/API/commands/command/script/persistence.py new file mode 100644 --- /dev/null +++ b/lldb/test/API/commands/command/script/persistence.py @@ -0,0 +1,9 @@ +import lldb + +debugger_copy = None + +def save_debugger(debugger, command, context, result, internal_dict): + global debugger_copy + debugger_copy = debugger + result.AppendMessage(str(debugger)) + result.SetStatus(lldb.eReturnStatusSuccessFinishResult) diff --git a/lldb/unittests/ScriptInterpreter/Python/PythonTestSuite.cpp b/lldb/unittests/ScriptInterpreter/Python/PythonTestSuite.cpp --- a/lldb/unittests/ScriptInterpreter/Python/PythonTestSuite.cpp +++ b/lldb/unittests/ScriptInterpreter/Python/PythonTestSuite.cpp @@ -88,7 +88,7 @@ void *lldb_private::LLDBSwigPythonCreateCommandObject( const char *python_class_name, const char *session_dictionary_name, - const lldb::DebuggerSP debugger_sp) { + lldb::DebuggerSP debugger_sp) { return nullptr; } @@ -172,14 +172,14 @@ bool lldb_private::LLDBSwigPythonCallCommand( const char *python_function_name, const char *session_dictionary_name, - lldb::DebuggerSP &debugger, const char *args, + lldb::DebuggerSP debugger, const char *args, lldb_private::CommandReturnObject &cmd_retobj, lldb::ExecutionContextRefSP exe_ctx_ref_sp) { return false; } bool lldb_private::LLDBSwigPythonCallCommandObject( - PyObject *implementor, lldb::DebuggerSP &debugger, const char *args, + PyObject *implementor, lldb::DebuggerSP debugger, const char *args, lldb_private::CommandReturnObject &cmd_retobj, lldb::ExecutionContextRefSP exe_ctx_ref_sp) { return false; @@ -187,7 +187,7 @@ bool lldb_private::LLDBSwigPythonCallModuleInit( const char *python_module_name, const char *session_dictionary_name, - lldb::DebuggerSP &debugger) { + lldb::DebuggerSP debugger) { return false; } @@ -228,10 +228,10 @@ return false; } -bool lldb_private::LLDBSWIGPythonRunScriptKeywordThread( +llvm::Optional lldb_private::LLDBSWIGPythonRunScriptKeywordThread( const char *python_function_name, const char *session_dictionary_name, - lldb::ThreadSP &thread, std::string &output) { - return false; + lldb::ThreadSP thread) { + return llvm::None; } bool lldb_private::LLDBSWIGPythonRunScriptKeywordTarget( @@ -240,10 +240,10 @@ return false; } -bool lldb_private::LLDBSWIGPythonRunScriptKeywordFrame( +llvm::Optional lldb_private::LLDBSWIGPythonRunScriptKeywordFrame( const char *python_function_name, const char *session_dictionary_name, - lldb::StackFrameSP &frame, std::string &output) { - return false; + lldb::StackFrameSP frame) { + return llvm::None; } bool lldb_private::LLDBSWIGPythonRunScriptKeywordValue(