]> git.ipfire.org Git - thirdparty/valgrind.git/commitdiff
Fix 372504 Hanging on exit_group
authorPhilippe Waroquiers <philippe.waroquiers@skynet.be>
Sat, 19 Nov 2016 14:54:44 +0000 (14:54 +0000)
committerPhilippe Waroquiers <philippe.waroquiers@skynet.be>
Sat, 19 Nov 2016 14:54:44 +0000 (14:54 +0000)
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

NEWS
coregrind/m_syswrap/syswrap-linux.c
coregrind/pub_core_threadstate.h
none/tests/Makefile.am
none/tests/sigsusp.c [new file with mode: 0644]
none/tests/sigsusp.stderr.exp [new file with mode: 0644]
none/tests/sigsusp.vgtest [new file with mode: 0644]

diff --git a/NEWS b/NEWS
index d22fd403d7d738e2cde7510c235632b7a6f7eb93..188721203ba3f1540730c38713cbc5a12ee0d217 100644 (file)
--- 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)
 ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
 
index 1dcb95dce053095eccd6d894f322bb0b3cf3084b..fda8dd1e49cd1463a0846734cc26ca258eb4dddc 100644 (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).  */
    }
 }
 
index 861f233820cc2ffbb3071bfc90e5ae1486e1e3d2..f3d956cff2e1007456535499d6ea970dee4e03b7 100644 (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
index 987218a7d699280c0b0d152590dd85692226b753..ad52d452979c61e66c4a7f3c3295a13d10b14762 100644 (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)
diff --git a/none/tests/sigsusp.c b/none/tests/sigsusp.c
new file mode 100644 (file)
index 0000000..0977e26
--- /dev/null
@@ -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);
+}
diff --git a/none/tests/sigsusp.stderr.exp b/none/tests/sigsusp.stderr.exp
new file mode 100644 (file)
index 0000000..e69de29
diff --git a/none/tests/sigsusp.vgtest b/none/tests/sigsusp.vgtest
new file mode 100644 (file)
index 0000000..4b3931d
--- /dev/null
@@ -0,0 +1,2 @@
+prog: sigsusp
+vgopts: -q