diff --git a/lldb/include/lldb/Target/Thread.h b/lldb/include/lldb/Target/Thread.h --- a/lldb/include/lldb/Target/Thread.h +++ b/lldb/include/lldb/Target/Thread.h @@ -1244,7 +1244,7 @@ // the stop info was checked against // the stop info override const uint32_t m_index_id; ///< A unique 1 based index assigned to each thread - ///for easy UI/command line access. + /// for easy UI/command line access. lldb::RegisterContextSP m_reg_context_sp; ///< The register context for this ///thread's current register state. lldb::StateType m_state; ///< The state of our process. diff --git a/lldb/source/Plugins/Process/scripted/ScriptedProcess.cpp b/lldb/source/Plugins/Process/scripted/ScriptedProcess.cpp --- a/lldb/source/Plugins/Process/scripted/ScriptedProcess.cpp +++ b/lldb/source/Plugins/Process/scripted/ScriptedProcess.cpp @@ -328,12 +328,14 @@ return true; } - lldb::ThreadSP thread_sp = - std::make_shared(*this, error, val->GetAsGeneric()); + auto thread_or_error = ScriptedThread::Create(*this, val->GetAsGeneric()); - if (!thread_sp || error.Fail()) - return GetInterface().ErrorWithMessage(LLVM_PRETTY_FUNCTION, - error.AsCString(), error); + if (!thread_or_error) + return GetInterface().ErrorWithMessage( + LLVM_PRETTY_FUNCTION, toString(thread_or_error.takeError()), error); + + ThreadSP thread_sp = thread_or_error.get(); + lldbassert(thread_sp && "Couldn't initialize scripted thread."); RegisterContextSP reg_ctx_sp = thread_sp->GetRegisterContext(); if (!reg_ctx_sp) diff --git a/lldb/source/Plugins/Process/scripted/ScriptedThread.h b/lldb/source/Plugins/Process/scripted/ScriptedThread.h --- a/lldb/source/Plugins/Process/scripted/ScriptedThread.h +++ b/lldb/source/Plugins/Process/scripted/ScriptedThread.h @@ -25,12 +25,18 @@ namespace lldb_private { class ScriptedThread : public lldb_private::Thread { + public: - ScriptedThread(ScriptedProcess &process, Status &error, - StructuredData::Generic *script_object = nullptr); + ScriptedThread(ScriptedProcess &process, + lldb::ScriptedThreadInterfaceSP interface_sp, lldb::tid_t tid, + StructuredData::GenericSP script_object_sp = nullptr); ~ScriptedThread() override; + static llvm::Expected> + Create(ScriptedProcess &process, + StructuredData::Generic *script_object = nullptr); + lldb::RegisterContextSP GetRegisterContext() override; lldb::RegisterContextSP @@ -61,8 +67,8 @@ const ScriptedProcess &m_scripted_process; lldb::ScriptedThreadInterfaceSP m_scripted_thread_interface_sp = nullptr; + lldb_private::StructuredData::GenericSP m_script_object_sp = nullptr; std::shared_ptr m_register_info_sp = nullptr; - lldb_private::StructuredData::ObjectSP m_script_object_sp = nullptr; }; } // namespace lldb_private diff --git a/lldb/source/Plugins/Process/scripted/ScriptedThread.cpp b/lldb/source/Plugins/Process/scripted/ScriptedThread.cpp --- a/lldb/source/Plugins/Process/scripted/ScriptedThread.cpp +++ b/lldb/source/Plugins/Process/scripted/ScriptedThread.cpp @@ -28,52 +28,60 @@ lldbassert(GetInterface() && "Invalid Scripted Thread Interface."); } -ScriptedThread::ScriptedThread(ScriptedProcess &process, Status &error, - StructuredData::Generic *script_object) - : Thread(process, LLDB_INVALID_THREAD_ID), m_scripted_process(process), - m_scripted_thread_interface_sp( - m_scripted_process.GetInterface().CreateScriptedThreadInterface()) { - if (!process.IsValid()) { - error.SetErrorString("Invalid scripted process"); - return; - } +llvm::Expected> +ScriptedThread::Create(ScriptedProcess &process, + StructuredData::Generic *script_object) { + if (!process.IsValid()) + return llvm::createStringError(llvm::inconvertibleErrorCode(), + "Invalid scripted process."); process.CheckInterpreterAndScriptObject(); - auto scripted_thread_interface = GetInterface(); - if (!scripted_thread_interface) { - error.SetErrorString("Failed to get scripted thread interface."); - return; - } - - llvm::Optional class_name = - process.GetInterface().GetScriptedThreadPluginName(); - if (!class_name || class_name->empty()) { - error.SetErrorString("Failed to get scripted thread class name."); - return; + auto scripted_thread_interface = + process.GetInterface().CreateScriptedThreadInterface(); + if (!scripted_thread_interface) + return llvm::createStringError( + llvm::inconvertibleErrorCode(), + "Failed to create scripted thread interface."); + + llvm::StringRef thread_class_name; + if (!script_object) { + llvm::Optional class_name = + process.GetInterface().GetScriptedThreadPluginName(); + if (!class_name || class_name->empty()) + return llvm::createStringError( + llvm::inconvertibleErrorCode(), + "Failed to get scripted thread class name."); + thread_class_name = *class_name; } ExecutionContext exe_ctx(process); - - m_script_object_sp = scripted_thread_interface->CreatePluginObject( - class_name->c_str(), exe_ctx, process.m_scripted_process_info.GetArgsSP(), - script_object); - - if (!m_script_object_sp) { - error.SetErrorString("Failed to create script object"); - return; - } - - if (!m_script_object_sp->IsValid()) { - m_script_object_sp = nullptr; - error.SetErrorString("Created script object is invalid"); - return; - } + StructuredData::GenericSP owned_script_object_sp = + scripted_thread_interface->CreatePluginObject( + thread_class_name, exe_ctx, + process.m_scripted_process_info.GetArgsSP(), script_object); + + if (!owned_script_object_sp) + return llvm::createStringError(llvm::inconvertibleErrorCode(), + "Failed to create script object."); + if (!owned_script_object_sp->IsValid()) + return llvm::createStringError(llvm::inconvertibleErrorCode(), + "Created script object is invalid."); lldb::tid_t tid = scripted_thread_interface->GetThreadID(); - SetID(tid); + + return std::make_shared(process, scripted_thread_interface, + tid, owned_script_object_sp); } +ScriptedThread::ScriptedThread(ScriptedProcess &process, + ScriptedThreadInterfaceSP interface_sp, + lldb::tid_t tid, + StructuredData::GenericSP script_object_sp) + : Thread(process, tid), m_scripted_process(process), + m_scripted_thread_interface_sp(interface_sp), + m_script_object_sp(script_object_sp) {} + ScriptedThread::~ScriptedThread() { DestroyThread(); } const char *ScriptedThread::GetName() { diff --git a/lldb/source/Plugins/ScriptInterpreter/Python/ScriptedThreadPythonInterface.cpp b/lldb/source/Plugins/ScriptInterpreter/Python/ScriptedThreadPythonInterface.cpp --- a/lldb/source/Plugins/ScriptInterpreter/Python/ScriptedThreadPythonInterface.cpp +++ b/lldb/source/Plugins/ScriptInterpreter/Python/ScriptedThreadPythonInterface.cpp @@ -32,7 +32,7 @@ StructuredData::GenericSP ScriptedThreadPythonInterface::CreatePluginObject( const llvm::StringRef class_name, ExecutionContext &exe_ctx, StructuredData::DictionarySP args_sp, StructuredData::Generic *script_obj) { - if (class_name.empty()) + if (class_name.empty() && !script_obj) return {}; ProcessSP process_sp = exe_ctx.GetProcessSP();