[3/7] nptl: Fix testcases for new pthread cancellation, mechanism
Commit Message
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.
It is because program need to act on such cases (for instance, to avoid
leak of allocated resources our handling partial read/write).
This patches fixes the NPTL testcase that assumes the old behavior and
also remove the tst-cancel-wrappers.sh test (which checks for symbols
that does not exist anymore).
Tested on x86_64, powerpc64, and powerpc32.
--
* nptl/Makefile [test-special]: Remove tst-cancel-wrappers rule.
[generated]: Likewise.
* nptl/tst-cancel-wrappers.sh: Remove file.
* nptl/tst-cancel2.c (tf): Add pthread_cancel checks for partial
read/write due cancel signal.
* nptl/tst-cancel20.c (sh_body): Likewise.
(tf_body): Likewise.
* nptl/tst-cancel21.c (sh_body): Likewise.
(tf_body): Likewise.
* nptl/tst-cancel4.c (tf_write): Likewise.
(tf_send): Likewise.
--
Comments
On Fri, 26 Sep 2014, Adhemerval Zanella wrote:
> This patches fixes the NPTL testcase that assumes the old behavior and
> also remove the tst-cancel-wrappers.sh test (which checks for symbols
> that does not exist anymore).
I don't think there's any clear answer to how it's now tested that all
these functions are cancellable (e.g. a list of tests in the testsuite,
for every function that was covered by that test, that test that
requirement).
For example, where is this tested for pread64?
On 26-09-2014 16:56, Joseph S. Myers wrote:
> On Fri, 26 Sep 2014, Adhemerval Zanella wrote:
>
>> This patches fixes the NPTL testcase that assumes the old behavior and
>> also remove the tst-cancel-wrappers.sh test (which checks for symbols
>> that does not exist anymore).
> I don't think there's any clear answer to how it's now tested that all
> these functions are cancellable (e.g. a list of tests in the testsuite,
> for every function that was covered by that test, that test that
> requirement).
>
> For example, where is this tested for pread64?
>
Indeed, it will require a similar test (although I see tst-cancel-wrapper.sh
does not really exercise the code itself). I think add more test like the
ones in tst-cancel4 would be better to check for pread64 and similar functions.
@@ -377,8 +377,7 @@ tests-reverse += tst-cancel5 tst-cancel23 tst-vfork1x tst-vfork2x
ifeq ($(run-built-tests),yes)
tests-special += $(objpfx)tst-stack3-mem.out $(objpfx)tst-oddstacklimit.out
ifeq ($(build-shared),yes)
-tests-special += $(objpfx)tst-tls6.out $(objpfx)tst-cleanup0-cmp.out \
- $(objpfx)tst-cancel-wrappers.out
+tests-special += $(objpfx)tst-tls6.out $(objpfx)tst-cleanup0-cmp.out
endif
endif
@@ -572,7 +571,7 @@ $(objpfx)$(multidir)/crtn.o: $(objpfx)crtn.o $(objpfx)$(multidir)/
endif
generated += libpthread_nonshared.a \
- multidir.mk tst-atfork2.mtrace tst-cancel-wrappers.out \
+ multidir.mk tst-atfork2.mtrace \
tst-tls6.out
generated += $(objpfx)tst-atfork2.mtrace \
@@ -587,18 +586,6 @@ generated += banner.h
LDFLAGS-pthread.so += -e __nptl_main
endif
-ifeq ($(run-built-tests),yes)
-ifeq (yes,$(build-shared))
-$(objpfx)tst-cancel-wrappers.out: tst-cancel-wrappers.sh
- $(SHELL) $< '$(NM)' \
- $(common-objpfx)libc_pic.a \
- $(common-objpfx)libc.a \
- $(objpfx)libpthread_pic.a \
- $(objpfx)libpthread.a > $@; \
- $(evaluate-test)
-endif
-endif
-
tst-exec4-ARGS = $(host-test-program-cmd)
$(objpfx)tst-execstack: $(libdl)
deleted file mode 100644
@@ -1,92 +0,0 @@
-#! /bin/sh
-# Test whether all cancelable functions are cancelable.
-# Copyright (C) 2002-2014 Free Software Foundation, Inc.
-# This file is part of the GNU C Library.
-# Contributed by Jakub Jelinek <jakub@redhat.com>, 2002.
-
-# The GNU C Library is free software; you can redistribute it and/or
-# modify it under the terms of the GNU Lesser General Public
-# License as published by the Free Software Foundation; either
-# version 2.1 of the License, or (at your option) any later version.
-
-# The GNU C Library is distributed in the hope that it will be useful,
-# but WITHOUT ANY WARRANTY; without even the implied warranty of
-# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
-# Lesser General Public License for more details.
-
-# You should have received a copy of the GNU Lesser General Public
-# License along with the GNU C Library; if not, see
-# <http://www.gnu.org/licenses/>.
-
-NM="$1"; shift
-while [ $# -gt 0 ]; do
- ( $NM -P $1; echo 'end[end]:' ) | gawk ' BEGIN {
-C["accept"]=1
-C["close"]=1
-C["connect"]=1
-C["creat"]=1
-C["fcntl"]=1
-C["fdatasync"]=1
-C["fsync"]=1
-C["msgrcv"]=1
-C["msgsnd"]=1
-C["msync"]=1
-C["nanosleep"]=1
-C["open"]=1
-C["open64"]=1
-C["pause"]=1
-C["poll"]=1
-C["pread"]=1
-C["pread64"]=1
-C["pselect"]=1
-C["pwrite"]=1
-C["pwrite64"]=1
-C["read"]=1
-C["readv"]=1
-C["recv"]=1
-C["recvfrom"]=1
-C["recvmsg"]=1
-C["select"]=1
-C["send"]=1
-C["sendmsg"]=1
-C["sendto"]=1
-C["sigpause"]=1
-C["sigsuspend"]=1
-C["sigwait"]=1
-C["sigwaitinfo"]=1
-C["tcdrain"]=1
-C["wait"]=1
-C["waitid"]=1
-C["waitpid"]=1
-C["write"]=1
-C["writev"]=1
-C["__xpg_sigpause"]=1
-}
-/:$/ {
- if (seen)
- {
- if (!seen_enable || !seen_disable)
- {
- printf "in '$1'(%s) %s'\''s cancellation missing\n", object, seen
- ret = 1
- }
- }
- seen=""
- seen_enable=""
- seen_disable=""
- object=gensub(/^.*\[(.*)\]:$/,"\\1","",$0)
- next
-}
-{
- if (C[$1] && $2 ~ /^[TW]$/)
- seen=$1
- else if ($1 ~ /^([.]|)__(libc|pthread)_enable_asynccancel$/ && $2 == "U")
- seen_enable=1
- else if ($1 ~ /^([.]|)__(libc|pthread)_disable_asynccancel$/ && $2 == "U")
- seen_disable=1
-}
-END {
- exit ret
-}' || exit
- shift
-done
@@ -33,6 +33,9 @@ tf (void *arg)
char buf[100000];
while (write (fd[1], buf, sizeof (buf)) > 0);
+ /* The write can return a value higher than 0 (meaning partial write)
+ due the SIGCANCEL, but the thread may still pending cancellation. */
+ pthread_testcancel ();
return (void *) 42l;
}
@@ -49,6 +49,9 @@ sh_body (void)
puts ("read succeeded");
exit (1);
}
+ /* The read can return a value higher than 0 (meaning partial reads)
+ due the SIGCANCEL, but the thread may still pending cancellation. */
+ pthread_testcancel ();
pthread_cleanup_pop (0);
}
@@ -84,7 +87,8 @@ tf_body (void)
puts ("read succeeded");
exit (1);
}
-
+ /* Check for partial read. */
+ pthread_testcancel ();
read (fd[0], &c, 1);
pthread_cleanup_pop (0);
@@ -50,6 +50,9 @@ sh_body (void)
puts ("read succeeded");
exit (1);
}
+ /* The write can return a value higher than 0 (meaning partial write)
+ due the SIGCANCEL, but the thread may still pending cancellation. */
+ pthread_testcancel ();
pthread_cleanup_pop (0);
}
@@ -85,6 +88,8 @@ tf_body (void)
puts ("read succeeded");
exit (1);
}
+ /* Check partial read. */
+ pthread_testcancel ();
read (fd[0], &c, 1);
@@ -38,8 +38,10 @@
#include <sys/un.h>
#include <sys/wait.h>
-#include "pthreadP.h"
-
+/* The signal used for asynchronous cancelation. */
+#ifndef SIGCANCEL
+# define SIGCANCEL __SIGRTMIN
+#endif
/* Since STREAMS are not supported in the standard Linux kernel and
there we don't advertise STREAMS as supported is no need to test
@@ -247,6 +249,9 @@ 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 the SIGCANCEL, but the thread may still pending cancellation. */
+ pthread_testcancel ();
pthread_cleanup_pop (0);
@@ -1139,6 +1144,8 @@ tf_send (void *arg)
char mem[700000];
send (tempfd2, mem, arg == NULL ? sizeof (mem) : 1, 0);
+ /* Check for partial send. */
+ pthread_testcancel ();
pthread_cleanup_pop (0);