mirror of
https://github.com/capstone-engine/llvm-capstone.git
synced 2024-11-27 15:41:46 +00:00
[lldb] Fix data race in ThreadedCommunication
TSan reports the following race: Write of size 8 at 0x000107707ee8 by main thread: #0 lldb_private::ThreadedCommunication::StartReadThread(...) ThreadedCommunication.cpp:175 #1 lldb_private::Process::SetSTDIOFileDescriptor(...) Process.cpp:4533 #2 lldb_private::Platform::DebugProcess(...) Platform.cpp:1121 #3 lldb_private::PlatformDarwin::DebugProcess(...) PlatformDarwin.cpp:711 #4 lldb_private::Target::Launch(...) Target.cpp:3235 #5 CommandObjectProcessLaunch::DoExecute(...) CommandObjectProcess.cpp:256 #6 lldb_private::CommandObjectParsed::Execute(...) CommandObject.cpp:751 #7 lldb_private::CommandInterpreter::HandleCommand(...) CommandInterpreter.cpp:2054 Previous read of size 8 at 0x000107707ee8 by thread T5: #0 lldb_private::HostThread::IsJoinable(...) const HostThread.cpp:30 #1 lldb_private::ThreadedCommunication::StopReadThread(...) ThreadedCommunication.cpp:192 #2 lldb_private::Process::ShouldBroadcastEvent(...) Process.cpp:3420 #3 lldb_private::Process::HandlePrivateEvent(...) Process.cpp:3728 #4 lldb_private::Process::RunPrivateStateThread(...) Process.cpp:3914 #5 std::__1::__function::__func<lldb_private::Process::StartPrivateStateThread(...) function.h:356 #6 lldb_private::HostNativeThreadBase::ThreadCreateTrampoline(...) HostNativeThreadBase.cpp:62 #7 lldb_private::HostThreadMacOSX::ThreadCreateTrampoline(...) HostThreadMacOSX.mm:18 The problem is the lack of synchronization between starting and stopping the read thread. This patch fixes that by protecting those operations with a mutex. Differential revision: https://reviews.llvm.org/D157361
This commit is contained in:
parent
bdd17b853f
commit
1a8d9a7657
@ -223,10 +223,22 @@ public:
|
||||
}
|
||||
|
||||
protected:
|
||||
HostThread m_read_thread; ///< The read thread handle in case we need to
|
||||
/// cancel the thread.
|
||||
/// The read thread handle in case we need to cancel the thread.
|
||||
/// @{
|
||||
HostThread m_read_thread;
|
||||
std::mutex m_read_thread_mutex;
|
||||
/// @}
|
||||
|
||||
/// Whether the read thread is enabled. This cannot be guarded by the read
|
||||
/// thread mutex becuase it is used as the control variable to exit the read
|
||||
/// thread.
|
||||
std::atomic<bool> m_read_thread_enabled;
|
||||
|
||||
/// Whether the read thread is enabled. Technically this could be guarded by
|
||||
/// the read thread mutex but that needlessly complicates things to
|
||||
/// check this variables momentary value.
|
||||
std::atomic<bool> m_read_thread_did_exit;
|
||||
|
||||
std::string
|
||||
m_bytes; ///< A buffer to cache bytes read in the ReadThread function.
|
||||
std::recursive_mutex m_bytes_mutex; ///< A mutex to protect multi-threaded
|
||||
|
@ -23,6 +23,7 @@
|
||||
#include <chrono>
|
||||
#include <cstring>
|
||||
#include <memory>
|
||||
#include <shared_mutex>
|
||||
|
||||
#include <cerrno>
|
||||
#include <cinttypes>
|
||||
@ -155,6 +156,8 @@ size_t ThreadedCommunication::Read(void *dst, size_t dst_len,
|
||||
}
|
||||
|
||||
bool ThreadedCommunication::StartReadThread(Status *error_ptr) {
|
||||
std::lock_guard<std::mutex> lock(m_read_thread_mutex);
|
||||
|
||||
if (error_ptr)
|
||||
error_ptr->Clear();
|
||||
|
||||
@ -189,6 +192,8 @@ bool ThreadedCommunication::StartReadThread(Status *error_ptr) {
|
||||
}
|
||||
|
||||
bool ThreadedCommunication::StopReadThread(Status *error_ptr) {
|
||||
std::lock_guard<std::mutex> lock(m_read_thread_mutex);
|
||||
|
||||
if (!m_read_thread.IsJoinable())
|
||||
return true;
|
||||
|
||||
@ -199,13 +204,13 @@ bool ThreadedCommunication::StopReadThread(Status *error_ptr) {
|
||||
|
||||
BroadcastEvent(eBroadcastBitReadThreadShouldExit, nullptr);
|
||||
|
||||
// error = m_read_thread.Cancel();
|
||||
|
||||
Status error = m_read_thread.Join(nullptr);
|
||||
return error.Success();
|
||||
}
|
||||
|
||||
bool ThreadedCommunication::JoinReadThread(Status *error_ptr) {
|
||||
std::lock_guard<std::mutex> lock(m_read_thread_mutex);
|
||||
|
||||
if (!m_read_thread.IsJoinable())
|
||||
return true;
|
||||
|
||||
|
Loading…
Reference in New Issue
Block a user