diff --git a/lldb/source/Plugins/Process/scripted/ScriptedProcess.h b/lldb/source/Plugins/Process/scripted/ScriptedProcess.h --- a/lldb/source/Plugins/Process/scripted/ScriptedProcess.h +++ b/lldb/source/Plugins/Process/scripted/ScriptedProcess.h @@ -75,7 +75,7 @@ Status DoDestroy() override; - void RefreshStateAfterStop() override{}; + void RefreshStateAfterStop() override; bool IsAlive() override; 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 @@ -20,7 +20,6 @@ #include "lldb/Interpreter/ScriptInterpreter.h" #include "lldb/Target/MemoryRegionInfo.h" #include "lldb/Target/RegisterContext.h" - #include "lldb/Utility/State.h" #include @@ -291,6 +290,7 @@ // actually new threads will get added to new_thread_list. CheckInterpreterAndScriptObject(); + m_thread_plans.ClearThreadCache(); Status error; ScriptLanguage language = m_interpreter->GetLanguage(); @@ -316,6 +316,12 @@ return new_thread_list.GetSize(false) > 0; } +void ScriptedProcess::RefreshStateAfterStop() { + // Let all threads recover from stopping and do any clean up based on the + // previous thread state (if any). + m_thread_list.RefreshStateAfterStop(); +} + bool ScriptedProcess::GetProcessInfo(ProcessInstanceInfo &info) { info.Clear(); info.SetProcessID(GetID()); 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 @@ -64,32 +64,6 @@ m_script_object_sp = object_sp; SetID(scripted_thread_interface->GetThreadID()); - - llvm::Optional reg_data = - scripted_thread_interface->GetRegisterContext(); - if (!reg_data) { - error.SetErrorString("Failed to get scripted thread registers data."); - return; - } - - DataBufferSP data_sp( - std::make_shared(reg_data->c_str(), reg_data->size())); - - if (!data_sp->GetByteSize()) { - error.SetErrorString("Failed to copy raw registers data."); - return; - } - - std::shared_ptr reg_ctx_memory = - std::make_shared( - *this, 0, *GetDynamicRegisterInfo(), LLDB_INVALID_ADDRESS); - if (!reg_ctx_memory) { - error.SetErrorString("Failed to create a register context."); - return; - } - - reg_ctx_memory->SetAllRegisterData(data_sp); - m_reg_context_sp = reg_ctx_memory; } ScriptedThread::~ScriptedThread() { DestroyThread(); } @@ -115,21 +89,48 @@ void ScriptedThread::ClearStackFrames() { Thread::ClearStackFrames(); } RegisterContextSP ScriptedThread::GetRegisterContext() { - if (!m_reg_context_sp) { - m_reg_context_sp = std::make_shared( - *this, LLDB_INVALID_ADDRESS); - GetInterface()->GetRegisterContext(); - } + if (!m_reg_context_sp) + m_reg_context_sp = CreateRegisterContextForFrame(nullptr); return m_reg_context_sp; } RegisterContextSP ScriptedThread::CreateRegisterContextForFrame(StackFrame *frame) { - uint32_t concrete_frame_idx = frame ? frame->GetConcreteFrameIndex() : 0; + const uint32_t concrete_frame_idx = + frame ? frame->GetConcreteFrameIndex() : 0; + + if (concrete_frame_idx) + return GetUnwinder().CreateRegisterContextForFrame(frame); + + lldb::RegisterContextSP reg_ctx_sp; + Status error; + + llvm::Optional reg_data = GetInterface()->GetRegisterContext(); + if (!reg_data) + return GetInterface()->ErrorWithMessage( + LLVM_PRETTY_FUNCTION, "Failed to get scripted thread registers data.", + error, LIBLLDB_LOG_THREAD); + + DataBufferSP data_sp( + std::make_shared(reg_data->c_str(), reg_data->size())); + + if (!data_sp->GetByteSize()) + return GetInterface()->ErrorWithMessage( + LLVM_PRETTY_FUNCTION, "Failed to copy raw registers data.", error, + LIBLLDB_LOG_THREAD); - if (concrete_frame_idx == 0) - return GetRegisterContext(); - return GetUnwinder().CreateRegisterContextForFrame(frame); + std::shared_ptr reg_ctx_memory = + std::make_shared( + *this, 0, *GetDynamicRegisterInfo(), LLDB_INVALID_ADDRESS); + if (!reg_ctx_memory) + return GetInterface()->ErrorWithMessage( + LLVM_PRETTY_FUNCTION, "Failed to create a register context.", error, + LIBLLDB_LOG_THREAD); + + reg_ctx_memory->SetAllRegisterData(data_sp); + m_reg_context_sp = reg_ctx_memory; + + return m_reg_context_sp; } bool ScriptedThread::CalculateStopInfo() { @@ -142,13 +143,15 @@ if (!dict_sp->GetValueForKeyAsInteger("type", stop_reason_type)) return GetInterface()->ErrorWithMessage( LLVM_PRETTY_FUNCTION, - "Couldn't find value for key 'type' in stop reason dictionary.", error); + "Couldn't find value for key 'type' in stop reason dictionary.", error, + LIBLLDB_LOG_THREAD); StructuredData::Dictionary *data_dict; if (!dict_sp->GetValueForKeyAsDictionary("data", data_dict)) return GetInterface()->ErrorWithMessage( LLVM_PRETTY_FUNCTION, - "Couldn't find value for key 'type' in stop reason dictionary.", error); + "Couldn't find value for key 'type' in stop reason dictionary.", error, + LIBLLDB_LOG_THREAD); switch (stop_reason_type) { case lldb::eStopReasonNone: @@ -175,7 +178,7 @@ llvm::Twine("Unsupported stop reason type (" + llvm::Twine(stop_reason_type) + llvm::Twine(").")) .str(), - error); + error, LIBLLDB_LOG_THREAD); } SetStopInfo(stop_info_sp); @@ -183,9 +186,7 @@ } void ScriptedThread::RefreshStateAfterStop() { - // TODO: Implement - if (m_reg_context_sp) - m_reg_context_sp->InvalidateAllRegisters(); + GetRegisterContext()->InvalidateIfNeeded(/*force=*/false); } lldb::ScriptedThreadInterfaceSP ScriptedThread::GetInterface() const {