Skip to content

Commit

Permalink
Avoid potential signal loss before sigsuspend in suspend_handler if TSan
Browse files Browse the repository at this point in the history
Issue #236 (bdwgc).

As comment between sem_post() and sigsuspend() says GC_sig_thr_restart
signal should be masked at that point otherwise there could be a race.
Thus, this commit removes pthread_sigmask(SIG_UNBLOCK) call before
sem_post() one in GC_suspend_handler_inner.

* pthread_stop_world.c [!GC_OPENBSD_UTHREADS && !NACL
&& THREAD_SANITIZER] (GC_suspend_handler_inner): Remove "set" local
variable; do not call sigemptyset(), pthread_sigmask(SIG_UNBLOCK),
sigaddset().
  • Loading branch information
ivmai committed Apr 4, 2022
1 parent 851cf18 commit 9bf0bb0
Showing 1 changed file with 0 additions and 14 deletions.
14 changes: 0 additions & 14 deletions pthread_stop_world.c
Original file line number Diff line number Diff line change
Expand Up @@ -392,20 +392,6 @@ STATIC void GC_suspend_handler_inner(ptr_t dummy GC_ATTR_UNUSED,
me -> backing_store_ptr = bs_lo + stack_size;
# endif

# ifdef THREAD_SANITIZER
/* TSan disables signals around signal handlers. Without */
/* a pthread_sigmask call, sigsuspend may block forever. */
{
sigset_t set;
sigemptyset(&set);
GC_ASSERT(GC_sig_suspend != SIGNAL_UNSET);
GC_ASSERT(GC_sig_thr_restart != SIGNAL_UNSET);
sigaddset(&set, GC_sig_suspend);
sigaddset(&set, GC_sig_thr_restart);
if (pthread_sigmask(SIG_UNBLOCK, &set, NULL) != 0)
ABORT("pthread_sigmask failed in suspend handler");
}
# endif
/* Tell the thread that wants to stop the world that this */
/* thread has been stopped. Note that sem_post() is */
/* the only async-signal-safe primitive in LinuxThreads. */
Expand Down

0 comments on commit 9bf0bb0

Please sign in to comment.