diff --git a/lldb/include/lldb/Target/Process.h b/lldb/include/lldb/Target/Process.h --- a/lldb/include/lldb/Target/Process.h +++ b/lldb/include/lldb/Target/Process.h @@ -3007,6 +3007,7 @@ m_unix_signals_sp; /// This is the current signal set for this process. lldb::ABISP m_abi_sp; lldb::IOHandlerSP m_process_input_reader; + mutable std::mutex m_process_input_reader_mutex; ThreadedCommunication m_stdio_communication; std::recursive_mutex m_stdio_communication_mutex; bool m_stdin_forward; /// Remember if stdin must be forwarded to remote debug @@ -3132,6 +3133,7 @@ bool ProcessIOHandlerIsActive(); bool ProcessIOHandlerExists() const { + std::lock_guard<std::mutex> guard(m_process_input_reader_mutex); return static_cast<bool>(m_process_input_reader); } diff --git a/lldb/source/Target/Process.cpp b/lldb/source/Target/Process.cpp --- a/lldb/source/Target/Process.cpp +++ b/lldb/source/Target/Process.cpp @@ -629,6 +629,7 @@ const Timeout<std::micro> &timeout) { // don't sync (potentially context switch) in case where there is no process // IO + std::lock_guard<std::mutex> guard(m_process_input_reader_mutex); if (!m_process_input_reader) return; @@ -2504,7 +2505,11 @@ m_jit_loaders_up.reset(); m_system_runtime_up.reset(); m_os_up.reset(); - m_process_input_reader.reset(); + + { + std::lock_guard<std::mutex> guard(m_process_input_reader_mutex); + m_process_input_reader.reset(); + } Module *exe_module = GetTarget().GetExecutableModulePointer(); @@ -2802,7 +2807,10 @@ Status Process::Attach(ProcessAttachInfo &attach_info) { m_abi_sp.reset(); - m_process_input_reader.reset(); + { + std::lock_guard<std::mutex> guard(m_process_input_reader_mutex); + m_process_input_reader.reset(); + } m_dyld_up.reset(); m_jit_loaders_up.reset(); m_system_runtime_up.reset(); @@ -3053,7 +3061,10 @@ Status Process::ConnectRemote(llvm::StringRef remote_url) { m_abi_sp.reset(); - m_process_input_reader.reset(); + { + std::lock_guard<std::mutex> guard(m_process_input_reader_mutex); + m_process_input_reader.reset(); + } // Find the process and its architecture. Make sure it matches the // architecture of the current Target, and if not adjust it. @@ -3341,10 +3352,13 @@ m_stdio_communication.Disconnect(); m_stdin_forward = false; - if (m_process_input_reader) { - m_process_input_reader->SetIsDone(true); - m_process_input_reader->Cancel(); - m_process_input_reader.reset(); + { + std::lock_guard<std::mutex> guard(m_process_input_reader_mutex); + if (m_process_input_reader) { + m_process_input_reader->SetIsDone(true); + m_process_input_reader->Cancel(); + m_process_input_reader.reset(); + } } // If we exited when we were waiting for a process to stop, then forward @@ -4522,20 +4536,25 @@ m_stdio_communication.StartReadThread(); // Now read thread is set up, set up input reader. - - if (!m_process_input_reader) - m_process_input_reader = - std::make_shared<IOHandlerProcessSTDIO>(this, fd); + { + std::lock_guard<std::mutex> guard(m_process_input_reader_mutex); + if (!m_process_input_reader) + m_process_input_reader = + std::make_shared<IOHandlerProcessSTDIO>(this, fd); + } } } bool Process::ProcessIOHandlerIsActive() { + std::lock_guard<std::mutex> guard(m_process_input_reader_mutex); IOHandlerSP io_handler_sp(m_process_input_reader); if (io_handler_sp) return GetTarget().GetDebugger().IsTopIOHandler(io_handler_sp); return false; } + bool Process::PushProcessIOHandler() { + std::lock_guard<std::mutex> guard(m_process_input_reader_mutex); IOHandlerSP io_handler_sp(m_process_input_reader); if (io_handler_sp) { Log *log = GetLog(LLDBLog::Process); @@ -4555,6 +4574,7 @@ } bool Process::PopProcessIOHandler() { + std::lock_guard<std::mutex> guard(m_process_input_reader_mutex); IOHandlerSP io_handler_sp(m_process_input_reader); if (io_handler_sp) return GetTarget().GetDebugger().RemoveIOHandler(io_handler_sp);