diff options
Diffstat (limited to 'lldb/source/Plugins/ScriptInterpreter/Python/ScriptInterpreterPython.cpp')
| -rw-r--r-- | lldb/source/Plugins/ScriptInterpreter/Python/ScriptInterpreterPython.cpp | 253 |
1 files changed, 252 insertions, 1 deletions
diff --git a/lldb/source/Plugins/ScriptInterpreter/Python/ScriptInterpreterPython.cpp b/lldb/source/Plugins/ScriptInterpreter/Python/ScriptInterpreterPython.cpp index ef7a2c128a22..dadcde612614 100644 --- a/lldb/source/Plugins/ScriptInterpreter/Python/ScriptInterpreterPython.cpp +++ b/lldb/source/Plugins/ScriptInterpreter/Python/ScriptInterpreterPython.cpp @@ -24,6 +24,7 @@ #include "ScriptInterpreterPythonImpl.h" #include "lldb/API/SBError.h" +#include "lldb/API/SBExecutionContext.h" #include "lldb/API/SBFrame.h" #include "lldb/API/SBValue.h" #include "lldb/Breakpoint/StoppointCallbackContext.h" @@ -531,7 +532,6 @@ void ScriptInterpreterPythonImpl::IOHandlerInputComplete(IOHandler &io_handler, break; data_up->user_source.SplitIntoLines(data); - StructuredData::ObjectSP empty_args_sp; if (GenerateBreakpointCommandCallbackData(data_up->user_source, data_up->script_source, /*has_extra_args=*/false, @@ -2766,6 +2766,58 @@ bool ScriptInterpreterPythonImpl::RunScriptBasedCommand( return ret_val; } +bool ScriptInterpreterPythonImpl::RunScriptBasedParsedCommand( + StructuredData::GenericSP impl_obj_sp, Args &args, + ScriptedCommandSynchronicity synchronicity, + lldb_private::CommandReturnObject &cmd_retobj, Status &error, + const lldb_private::ExecutionContext &exe_ctx) { + if (!impl_obj_sp || !impl_obj_sp->IsValid()) { + error.SetErrorString("no function to execute"); + return false; + } + + lldb::DebuggerSP debugger_sp = m_debugger.shared_from_this(); + lldb::ExecutionContextRefSP exe_ctx_ref_sp(new ExecutionContextRef(exe_ctx)); + + if (!debugger_sp.get()) { + error.SetErrorString("invalid Debugger pointer"); + return false; + } + + bool ret_val = false; + + std::string err_msg; + + { + Locker py_lock(this, + Locker::AcquireLock | Locker::InitSession | + (cmd_retobj.GetInteractive() ? 0 : Locker::NoSTDIN), + Locker::FreeLock | Locker::TearDownSession); + + SynchronicityHandler synch_handler(debugger_sp, synchronicity); + + StructuredData::ArraySP args_arr_sp(new StructuredData::Array()); + + for (const Args::ArgEntry &entry : args) { + args_arr_sp->AddStringItem(entry.ref()); + } + StructuredDataImpl args_impl(args_arr_sp); + + ret_val = SWIGBridge::LLDBSwigPythonCallParsedCommandObject( + static_cast<PyObject *>(impl_obj_sp->GetValue()), debugger_sp, + args_impl, cmd_retobj, exe_ctx_ref_sp); + } + + if (!ret_val) + error.SetErrorString("unable to execute script function"); + else if (cmd_retobj.GetStatus() == eReturnStatusFailed) + return false; + + error.Clear(); + return ret_val; +} + + /// In Python, a special attribute __doc__ contains the docstring for an object /// (function, method, class, ...) if any is defined Otherwise, the attribute's /// value is None. @@ -2884,6 +2936,205 @@ uint32_t ScriptInterpreterPythonImpl::GetFlagsForCommandObject( return result; } +StructuredData::ObjectSP +ScriptInterpreterPythonImpl::GetOptionsForCommandObject( + StructuredData::GenericSP cmd_obj_sp) { + StructuredData::ObjectSP result = {}; + + Locker py_lock(this, Locker::AcquireLock | Locker::NoSTDIN, Locker::FreeLock); + + static char callee_name[] = "get_options_definition"; + + if (!cmd_obj_sp) + return result; + + PythonObject implementor(PyRefType::Borrowed, + (PyObject *)cmd_obj_sp->GetValue()); + + if (!implementor.IsAllocated()) + return result; + + PythonObject pmeth(PyRefType::Owned, + PyObject_GetAttrString(implementor.get(), callee_name)); + + if (PyErr_Occurred()) + PyErr_Clear(); + + if (!pmeth.IsAllocated()) + return result; + + if (PyCallable_Check(pmeth.get()) == 0) { + if (PyErr_Occurred()) + PyErr_Clear(); + return result; + } + + if (PyErr_Occurred()) + PyErr_Clear(); + + PythonDictionary py_return = unwrapOrSetPythonException( + As<PythonDictionary>(implementor.CallMethod(callee_name))); + + // if it fails, print the error but otherwise go on + if (PyErr_Occurred()) { + PyErr_Print(); + PyErr_Clear(); + return {}; + } + return py_return.CreateStructuredObject(); +} + +StructuredData::ObjectSP +ScriptInterpreterPythonImpl::GetArgumentsForCommandObject( + StructuredData::GenericSP cmd_obj_sp) { + StructuredData::ObjectSP result = {}; + + Locker py_lock(this, Locker::AcquireLock | Locker::NoSTDIN, Locker::FreeLock); + + static char callee_name[] = "get_args_definition"; + + if (!cmd_obj_sp) + return result; + + PythonObject implementor(PyRefType::Borrowed, + (PyObject *)cmd_obj_sp->GetValue()); + + if (!implementor.IsAllocated()) + return result; + + PythonObject pmeth(PyRefType::Owned, + PyObject_GetAttrString(implementor.get(), callee_name)); + + if (PyErr_Occurred()) + PyErr_Clear(); + + if (!pmeth.IsAllocated()) + return result; + + if (PyCallable_Check(pmeth.get()) == 0) { + if (PyErr_Occurred()) + PyErr_Clear(); + return result; + } + + if (PyErr_Occurred()) + PyErr_Clear(); + + PythonList py_return = unwrapOrSetPythonException( + As<PythonList>(implementor.CallMethod(callee_name))); + + // if it fails, print the error but otherwise go on + if (PyErr_Occurred()) { + PyErr_Print(); + PyErr_Clear(); + return {}; + } + return py_return.CreateStructuredObject(); +} + +void +ScriptInterpreterPythonImpl::OptionParsingStartedForCommandObject( + StructuredData::GenericSP cmd_obj_sp) { + + Locker py_lock(this, Locker::AcquireLock | Locker::NoSTDIN, Locker::FreeLock); + + static char callee_name[] = "option_parsing_started"; + + if (!cmd_obj_sp) + return ; + + PythonObject implementor(PyRefType::Borrowed, + (PyObject *)cmd_obj_sp->GetValue()); + + if (!implementor.IsAllocated()) + return; + + PythonObject pmeth(PyRefType::Owned, + PyObject_GetAttrString(implementor.get(), callee_name)); + + if (PyErr_Occurred()) + PyErr_Clear(); + + if (!pmeth.IsAllocated()) + return; + + if (PyCallable_Check(pmeth.get()) == 0) { + if (PyErr_Occurred()) + PyErr_Clear(); + return; + } + + if (PyErr_Occurred()) + PyErr_Clear(); + + // option_parsing_starting doesn't return anything, ignore anything but + // python errors. + unwrapOrSetPythonException( + As<bool>(implementor.CallMethod(callee_name))); + + // if it fails, print the error but otherwise go on + if (PyErr_Occurred()) { + PyErr_Print(); + PyErr_Clear(); + return; + } +} + +bool +ScriptInterpreterPythonImpl::SetOptionValueForCommandObject( + StructuredData::GenericSP cmd_obj_sp, ExecutionContext *exe_ctx, + llvm::StringRef long_option, llvm::StringRef value) { + StructuredData::ObjectSP result = {}; + + Locker py_lock(this, Locker::AcquireLock | Locker::NoSTDIN, Locker::FreeLock); + + static char callee_name[] = "set_option_value"; + + if (!cmd_obj_sp) + return false; + + PythonObject implementor(PyRefType::Borrowed, + (PyObject *)cmd_obj_sp->GetValue()); + + if (!implementor.IsAllocated()) + return false; + + PythonObject pmeth(PyRefType::Owned, + PyObject_GetAttrString(implementor.get(), callee_name)); + + if (PyErr_Occurred()) + PyErr_Clear(); + + if (!pmeth.IsAllocated()) + return false; + + if (PyCallable_Check(pmeth.get()) == 0) { + if (PyErr_Occurred()) + PyErr_Clear(); + return false; + } + + if (PyErr_Occurred()) + PyErr_Clear(); + + lldb::ExecutionContextRefSP exe_ctx_ref_sp; + if (exe_ctx) + exe_ctx_ref_sp.reset(new ExecutionContextRef(exe_ctx)); + PythonObject ctx_ref_obj = SWIGBridge::ToSWIGWrapper(exe_ctx_ref_sp); + + bool py_return = unwrapOrSetPythonException( + As<bool>(implementor.CallMethod(callee_name, ctx_ref_obj, long_option.str().c_str(), + value.str().c_str()))); + + // if it fails, print the error but otherwise go on + if (PyErr_Occurred()) { + PyErr_Print(); + PyErr_Clear(); + return false; + } + return py_return; +} + bool ScriptInterpreterPythonImpl::GetLongHelpForCommandObject( StructuredData::GenericSP cmd_obj_sp, std::string &dest) { dest.clear(); |
