Skip to content

Commit 79a8e00

Browse files
committed
[lldb] Fix data race in Process
Thread sanitizer reports a data race in Process.cpp in the usage of m_process_input_reader. Fix this data race by introducing a mutex guarding the access to this variable. Differential Revision: https://reviews.llvm.org/D157648
1 parent bb90063 commit 79a8e00

File tree

2 files changed

+33
-11
lines changed

2 files changed

+33
-11
lines changed

lldb/include/lldb/Target/Process.h

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -3007,6 +3007,7 @@ void PruneThreadPlans();
30073007
m_unix_signals_sp; /// This is the current signal set for this process.
30083008
lldb::ABISP m_abi_sp;
30093009
lldb::IOHandlerSP m_process_input_reader;
3010+
mutable std::mutex m_process_input_reader_mutex;
30103011
ThreadedCommunication m_stdio_communication;
30113012
std::recursive_mutex m_stdio_communication_mutex;
30123013
bool m_stdin_forward; /// Remember if stdin must be forwarded to remote debug
@@ -3132,6 +3133,7 @@ void PruneThreadPlans();
31323133
bool ProcessIOHandlerIsActive();
31333134

31343135
bool ProcessIOHandlerExists() const {
3136+
std::lock_guard<std::mutex> guard(m_process_input_reader_mutex);
31353137
return static_cast<bool>(m_process_input_reader);
31363138
}
31373139

lldb/source/Target/Process.cpp

Lines changed: 31 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -629,6 +629,7 @@ void Process::SyncIOHandler(uint32_t iohandler_id,
629629
const Timeout<std::micro> &timeout) {
630630
// don't sync (potentially context switch) in case where there is no process
631631
// IO
632+
std::lock_guard<std::mutex> guard(m_process_input_reader_mutex);
632633
if (!m_process_input_reader)
633634
return;
634635

@@ -2504,7 +2505,11 @@ Status Process::LaunchPrivate(ProcessLaunchInfo &launch_info, StateType &state,
25042505
m_jit_loaders_up.reset();
25052506
m_system_runtime_up.reset();
25062507
m_os_up.reset();
2507-
m_process_input_reader.reset();
2508+
2509+
{
2510+
std::lock_guard<std::mutex> guard(m_process_input_reader_mutex);
2511+
m_process_input_reader.reset();
2512+
}
25082513

25092514
Module *exe_module = GetTarget().GetExecutableModulePointer();
25102515

@@ -2802,7 +2807,10 @@ Status Process::WillAttachToProcessWithName(const char *process_name,
28022807

28032808
Status Process::Attach(ProcessAttachInfo &attach_info) {
28042809
m_abi_sp.reset();
2805-
m_process_input_reader.reset();
2810+
{
2811+
std::lock_guard<std::mutex> guard(m_process_input_reader_mutex);
2812+
m_process_input_reader.reset();
2813+
}
28062814
m_dyld_up.reset();
28072815
m_jit_loaders_up.reset();
28082816
m_system_runtime_up.reset();
@@ -3053,7 +3061,10 @@ void Process::CompleteAttach() {
30533061

30543062
Status Process::ConnectRemote(llvm::StringRef remote_url) {
30553063
m_abi_sp.reset();
3056-
m_process_input_reader.reset();
3064+
{
3065+
std::lock_guard<std::mutex> guard(m_process_input_reader_mutex);
3066+
m_process_input_reader.reset();
3067+
}
30573068

30583069
// Find the process and its architecture. Make sure it matches the
30593070
// architecture of the current Target, and if not adjust it.
@@ -3341,10 +3352,13 @@ Status Process::DestroyImpl(bool force_kill) {
33413352
m_stdio_communication.Disconnect();
33423353
m_stdin_forward = false;
33433354

3344-
if (m_process_input_reader) {
3345-
m_process_input_reader->SetIsDone(true);
3346-
m_process_input_reader->Cancel();
3347-
m_process_input_reader.reset();
3355+
{
3356+
std::lock_guard<std::mutex> guard(m_process_input_reader_mutex);
3357+
if (m_process_input_reader) {
3358+
m_process_input_reader->SetIsDone(true);
3359+
m_process_input_reader->Cancel();
3360+
m_process_input_reader.reset();
3361+
}
33483362
}
33493363

33503364
// If we exited when we were waiting for a process to stop, then forward
@@ -4522,20 +4536,25 @@ void Process::SetSTDIOFileDescriptor(int fd) {
45224536
m_stdio_communication.StartReadThread();
45234537

45244538
// Now read thread is set up, set up input reader.
4525-
4526-
if (!m_process_input_reader)
4527-
m_process_input_reader =
4528-
std::make_shared<IOHandlerProcessSTDIO>(this, fd);
4539+
{
4540+
std::lock_guard<std::mutex> guard(m_process_input_reader_mutex);
4541+
if (!m_process_input_reader)
4542+
m_process_input_reader =
4543+
std::make_shared<IOHandlerProcessSTDIO>(this, fd);
4544+
}
45294545
}
45304546
}
45314547

45324548
bool Process::ProcessIOHandlerIsActive() {
4549+
std::lock_guard<std::mutex> guard(m_process_input_reader_mutex);
45334550
IOHandlerSP io_handler_sp(m_process_input_reader);
45344551
if (io_handler_sp)
45354552
return GetTarget().GetDebugger().IsTopIOHandler(io_handler_sp);
45364553
return false;
45374554
}
4555+
45384556
bool Process::PushProcessIOHandler() {
4557+
std::lock_guard<std::mutex> guard(m_process_input_reader_mutex);
45394558
IOHandlerSP io_handler_sp(m_process_input_reader);
45404559
if (io_handler_sp) {
45414560
Log *log = GetLog(LLDBLog::Process);
@@ -4555,6 +4574,7 @@ bool Process::PushProcessIOHandler() {
45554574
}
45564575

45574576
bool Process::PopProcessIOHandler() {
4577+
std::lock_guard<std::mutex> guard(m_process_input_reader_mutex);
45584578
IOHandlerSP io_handler_sp(m_process_input_reader);
45594579
if (io_handler_sp)
45604580
return GetTarget().GetDebugger().RemoveIOHandler(io_handler_sp);

0 commit comments

Comments
 (0)