nptl: Fix testcases for new pthread cancellation mechanism
authorAdhemerval Zanella <adhemerval.zanella@linaro.com>
Mon, 21 Sep 2015 22:55:58 +0000 (15:55 -0700)
committerAdhemerval Zanella <adhemerval.zanella@linaro.org>
Thu, 3 Jan 2019 20:38:09 +0000 (18:38 -0200)
With upcoming fix for BZ#12683, pthread cancellation does not act for:

  1. If syscall is blocked but with some side effects already having
     taken place (e.g. a partial read or write).
  2. After the syscall has returned.

The main change is due the fact programs need to act in syscalls with
side-effects (for instance, to avoid leak of allocated resources or
handle partial read/write).

This patch changes the NPTL testcase that assumes the old behavior and
also changes the tst-backtrace{5,6} to ignore the cancellable wrappers.

Checked on i686-linux-gnu, x86_64-linux-gnu, x86_64-linux-gnux32,
aarch64-linux-gnu, arm-linux-gnueabihf, powerpc64le-linux-gnu,
powerpc-linux-gnu, sparcv9-linux-gnu, and sparc64-linux-gnu.

* debug/tst-backtrace5.c (handle_signal): Avoid cancellable wrappers
in backtrace analysis.
* nptl/tst-cancel4.c (tf_write): Handle cancelled syscall with
side-effects.
(tf_send): Likewise.

ChangeLog
debug/tst-backtrace5.c
nptl/tst-cancel4.c

index b190eb8..b695780 100644 (file)
--- a/ChangeLog
+++ b/ChangeLog
@@ -1,5 +1,11 @@
 2019-01-03  Adhemerval Zanella  <adhemerval.zanella@linaro.org>
 
+       * debug/tst-backtrace5.c (handle_signal): Avoid cancellable wrappers
+       in backtrace analysis.
+       * nptl/tst-cancel4.c (tf_write): Handle cancelled syscall with
+       side-effects.
+       (tf_send): Likewise.
+
        * io/creat.c (LIBC_CANCEL_HANDLED): Remove macro.
        * io/ppoll.c (LIBC_CANCEL_HANDLED): Likewise.
        * misc/pselect.c (LIBC_CANCEL_HANDLED): Likewise.
index dfbe4c1..5a5ce8b 100644 (file)
@@ -69,17 +69,18 @@ handle_signal (int signum)
       FAIL ();
       return;
     }
-  /* Do not check name for signal trampoline.  */
-  i = 2;
-  if (!match (symbols[i++], "read"))
+
+  /* Do not check name for signal trampoline or cancellable syscall
+     wrappers (__syscall_cancel*).  */
+  for (; i < n - 1; i++)
+    if (match (symbols[i], "read"))
+      break;
+  if (i == n - 1)
     {
-      /* Perhaps symbols[2] is __kernel_vsyscall?  */
-      if (!match (symbols[i++], "read"))
-       {
-         FAIL ();
-         return;
-       }
+      FAIL ();
+      return;
     }
+
   for (; i < n - 1; i++)
     if (!match (symbols[i], "fn"))
       {
index a0fc30f..60a965d 100644 (file)
@@ -166,6 +166,10 @@ tf_write  (void *arg)
   char buf[WRITE_BUFFER_SIZE];
   memset (buf, '\0', sizeof (buf));
   s = write (fd, buf, sizeof (buf));
+  /* The write can return a value higher than 0 (meaning partial write)
+     due to the SIGCANCEL, but the thread may still be pending
+     cancellation.  */
+  pthread_testcancel ();
 
   pthread_cleanup_pop (0);
 
@@ -743,6 +747,10 @@ tf_send (void *arg)
   char mem[WRITE_BUFFER_SIZE];
 
   send (tempfd2, mem, arg == NULL ? sizeof (mem) : 1, 0);
+  /* The send can return a value higher than 0 (meaning partial send)
+     due to the SIGCANCEL, but the thread may still be pending
+     cancellation.  */
+  pthread_testcancel ();
 
   pthread_cleanup_pop (0);