This is an archive of the discontinued LLVM Phabricator instance.

tsan: fix deadlock in pthread_atfork callbacks
ClosedPublic

Authored by dvyukov on Apr 23 2021, 4:12 AM.

Details

Summary

We take report/thread_registry locks around fork.
This means we cannot report any bugs in atfork handlers.
We resolved this by enabling per-thread ignores around fork.
This resolved some of the cases, but not all.
The added test triggers a race report from a signal handler
called from atfork callback, we reset per-thread ignores
around signal handlers, so we tried to report it and deadlocked.
But there are more cases: a signal handler can be called
synchronously if it's sent to itself. Or any other report
types would cause deadlocks as well: mutex misuse,
signal handler spoiling errno, etc.
Disable all reports for the duration of fork with
thr->suppress_reports and don't re-enable them around
signal handlers.

Diff Detail

Event Timeline

dvyukov created this revision.Apr 23 2021, 4:12 AM
dvyukov requested review of this revision.Apr 23 2021, 4:12 AM
Herald added a project: Restricted Project. · View Herald TranscriptApr 23 2021, 4:12 AM
Herald added a subscriber: Restricted Project. · View Herald Transcript
dvyukov updated this revision to Diff 339980.Apr 23 2021, 4:24 AM

Update a comment.

dvyukov edited the summary of this revision. (Show Details)Apr 23 2021, 4:25 AM
dvyukov added a reviewer: vitalybuka.
bruno added a subscriber: bruno.Apr 26 2021, 3:54 PM
vitalybuka accepted this revision.Apr 26 2021, 4:58 PM
vitalybuka added inline comments.
compiler-rt/lib/tsan/rtl/tsan_rtl_report.cpp
150–151

I don't understand what is guarder by this lock here.
this is essentially

if (SANITIZER_DEBUG) {
  ThreadRegistryLock l(ctx->thread_registry);
}

Is this intentional?

This revision is now accepted and ready to land.Apr 26 2021, 4:58 PM
dvyukov updated this revision to Diff 340790.Apr 27 2021, 4:19 AM

addressed the comment

compiler-rt/lib/tsan/rtl/tsan_rtl_report.cpp
150–151

It's a check that we didn't lock thread_registry yet. I've extended the comment.

This revision was landed with ongoing or failed builds.Apr 27 2021, 4:25 AM
This revision was automatically updated to reflect the committed changes.

The test is failing on https://lab.llvm.org/buildbot/#/builders/70/builds/6736/steps/7/logs/stdio

1: FATAL: ThreadSanitizer CHECK failed: /b/sanitizer-x86_64-linux-autoconf/build/llvm-project/compiler-rt/lib/tsan/rtl/tsan_mutex.cpp:169 "((locked_[i])) == ((0))" (0x2, 0x0)

check:48'0 X~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ error: no match found
check:48'1 ? possible intended match

2:  #0 __tsan::TsanCheckFailed(char const*, int, char const*, unsigned long long, unsigned long long) /b/sanitizer-x86_64-linux-autoconf/build/llvm-project/compiler-rt/lib/tsan/rtl/tsan_rtl_report.cpp:47:25 (pthread_atfork_deadlock2.c.tmp+0x516705)

check:48'0 ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~

3:  #1 __sanitizer::CheckFailed(char const*, int, char const*, unsigned long long, unsigned long long) /b/sanitizer-x86_64-linux-autoconf/build/llvm-project/compiler-rt/lib/sanitizer_common/sanitizer_termination.cpp:78:5 (pthread_atfork_deadlock2.c.tmp+0x43c19f)

check:48'0 ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~

4:  #2 __tsan::InternalDeadlockDetector::CheckNoLocks() /b/sanitizer-x86_64-linux-autoconf/build/llvm-project/compiler-rt/lib/tsan/rtl/tsan_mutex.cpp:169:5 (pthread_atfork_deadlock2.c.tmp+0x4e7770)

check:48'0 ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~

5:  #3 __tsan::CheckNoLocks(__tsan::ThreadState*) /b/sanitizer-x86_64-linux-autoconf/build/llvm-project/compiler-rt/lib/tsan/rtl/tsan_mutex.cpp:176:35 (pthread_atfork_deadlock2.c.tmp+0x4e77ab)

check:48'0 ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~

6:  #4 __tsan::ReportRace(__tsan::ThreadState*) /b/sanitizer-x86_64-linux-autoconf/build/llvm-project/compiler-rt/lib/tsan/rtl/tsan_rtl_report.cpp:610:3 (pthread_atfork_deadlock2.c.tmp+0x518697)

check:48'0 ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~

.

Just noticed D101385.
I'll revert this anyway to keep the bots green overnight.