From: Philippe Waroquiers Date: Sat, 19 Nov 2016 14:54:44 +0000 (+0000) Subject: Fix 372504 Hanging on exit_group X-Git-Tag: svn/VALGRIND_3_13_0~280 X-Git-Url: http://git.ipfire.org/cgi-bin/gitweb.cgi?a=commitdiff_plain;h=d208bc934bb5453976e811bd61b6bb0c72ec6a30;p=thirdparty%2Fvalgrind.git 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 --- diff --git a/NEWS b/NEWS index d22fd403d7..188721203b 100644 --- a/NEWS +++ b/NEWS @@ -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) ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ diff --git a/coregrind/m_syswrap/syswrap-linux.c b/coregrind/m_syswrap/syswrap-linux.c index 1dcb95dce0..fda8dd1e49 100644 --- a/coregrind/m_syswrap/syswrap-linux.c +++ b/coregrind/m_syswrap/syswrap-linux.c @@ -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). */ } } diff --git a/coregrind/pub_core_threadstate.h b/coregrind/pub_core_threadstate.h index 861f233820..f3d956cff2 100644 --- a/coregrind/pub_core_threadstate.h +++ b/coregrind/pub_core_threadstate.h @@ -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 diff --git a/none/tests/Makefile.am b/none/tests/Makefile.am index 987218a7d6..ad52d45297 100644 --- a/none/tests/Makefile.am +++ b/none/tests/Makefile.am @@ -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) diff --git a/none/tests/sigsusp.c b/none/tests/sigsusp.c new file mode 100644 index 0000000000..0977e26242 --- /dev/null +++ b/none/tests/sigsusp.c @@ -0,0 +1,24 @@ +#include +#include +#include +#include +#include +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); +} diff --git a/none/tests/sigsusp.stderr.exp b/none/tests/sigsusp.stderr.exp new file mode 100644 index 0000000000..e69de29bb2 diff --git a/none/tests/sigsusp.vgtest b/none/tests/sigsusp.vgtest new file mode 100644 index 0000000000..4b3931dec1 --- /dev/null +++ b/none/tests/sigsusp.vgtest @@ -0,0 +1,2 @@ +prog: sigsusp +vgopts: -q