Fix 372504 Hanging on exit_group

Note that it is unclear if the PRE syscall for rt_sigsuspend
is properly setting up a temporary mask in the thread state
tmp_sig_mask:  if an handler is called while a thread is
calling sigsuspend, the mask during the handler run must be
the temporary mask set by sigsuspend.
It is not clear if/where the valgrind sigframe builder/handler
sets the tmp_sig_mask to the value as expected by the user
(i.e. the value of the temporary mask which was given to
the sigsuspend syscall)



git-svn-id: svn://svn.valgrind.org/valgrind/trunk@16141
This commit is contained in:
Philippe Waroquiers 2016-11-19 14:54:44 +00:00
parent 4e139bdead
commit d208bc934b
7 changed files with 39 additions and 3 deletions

2
NEWS
View File

@ -80,9 +80,9 @@ where XXXXXX is the bug number as listed below.
371869 support '%' in symbol Z-encoding
371916 execution tree xtree concept
372120 c++ demangler demangles symbols which are not c++
372504 Hanging on exit_group
372600 process loops forever when fatal signals are arriving quickly
Release 3.12.0 (20 October 2016)
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~

View File

@ -3558,6 +3558,12 @@ PRE(sys_rt_sigsuspend)
PRE_REG_READ2(int, "rt_sigsuspend", vki_sigset_t *, mask, vki_size_t, size)
if (ARG1 != (Addr)NULL) {
PRE_MEM_READ( "rt_sigsuspend(mask)", ARG1, sizeof(vki_sigset_t) );
VG_(sigdelset)((vki_sigset_t*)ARG1, VG_SIGVGKILL);
/* We cannot mask VG_SIGVGKILL, as otherwise this thread would not
be killable by VG_(nuke_all_threads_except).
We thus silently ignore the user request to mask this signal.
Note that this is similar to what is done for e.g.
sigprocmask (see m_signals.c calculate_SKSS_from_SCSS). */
}
}

View File

@ -354,7 +354,9 @@ typedef struct {
different values is during the execution of a sigsuspend, where
tmp_sig_mask is the temporary mask which sigsuspend installs.
It is only consulted to compute the signal mask applied to a
signal handler. */
signal handler.
PW Nov 2016 : it is not clear if and where this tmp_sig_mask
is set when an handler runs "inside" a sigsuspend. */
vki_sigset_t tmp_sig_mask;
/* A little signal queue for signals we can't get the kernel to

View File

@ -189,6 +189,7 @@ EXTRA_DIST = \
shortpush.stderr.exp shortpush.vgtest \
shorts.stderr.exp shorts.vgtest \
sigstackgrowth.stdout.exp sigstackgrowth.stderr.exp sigstackgrowth.vgtest \
sigsusp.stderr.exp sigsusp.vgtest \
stackgrowth.stdout.exp stackgrowth.stderr.exp stackgrowth.vgtest \
syscall-restart1.vgtest syscall-restart1.stdout.exp syscall-restart1.stderr.exp \
syscall-restart2.vgtest syscall-restart2.stdout.exp syscall-restart2.stderr.exp \
@ -233,7 +234,7 @@ check_PROGRAMS = \
require-text-symbol \
res_search resolv \
rlimit_nofile selfrun sem semlimit sha1_test \
shortpush shorts stackgrowth sigstackgrowth \
shortpush shorts stackgrowth sigstackgrowth sigsusp \
syscall-restart1 syscall-restart2 \
syslog \
system \
@ -332,6 +333,7 @@ sha1_test_CFLAGS = $(AM_CFLAGS)
if VGCONF_OS_IS_SOLARIS
sha1_test_CFLAGS += -Du_int32_t=uint32_t
endif
sigsusp_LDADD = -lpthread
thread_exits_LDADD = -lpthread
threaded_fork_LDADD = -lpthread
threadederrno_CFLAGS = $(AM_CFLAGS)

24
none/tests/sigsusp.c Normal file
View File

@ -0,0 +1,24 @@
#include <stdlib.h>
#include <pthread.h>
#include <unistd.h>
#include <stdio.h>
#include <signal.h>
static void* t_fn(void* v)
{
sigset_t mask;
sigfillset(&mask);
sigsuspend(&mask);
return NULL;
}
int main (int argc, char *argv[])
{
pthread_t t1;
pthread_create(&t1, NULL, t_fn, NULL);
sleep(1); // Should be enough to have the thread in sigsuspend
// printf("dying\n");
exit(0);
}

View File

View File

@ -0,0 +1,2 @@
prog: sigsusp
vgopts: -q