public inbox for glibc-cvs@sourceware.org help / color / mirror / Atom feed
From: Adhemerval Zanella <azanella@sourceware.org> To: glibc-cvs@sourceware.org Subject: [glibc/azanella/pthread-multiple-fixes] nptl: Fix tst-cancel7 and tst-cancelx7 race condition (BZ #14232) Date: Tue, 8 Jun 2021 20:48:35 +0000 (GMT) [thread overview] Message-ID: <20210608204835.26F9A3983C39@sourceware.org> (raw) https://sourceware.org/git/gitweb.cgi?p=glibc.git;h=761b155218de515de6997b2ad865ae0406b48b87 commit 761b155218de515de6997b2ad865ae0406b48b87 Author: Adhemerval Zanella <adhemerval.zanella@linaro.org> Date: Fri Jun 4 09:49:30 2021 -0300 nptl: Fix tst-cancel7 and tst-cancelx7 race condition (BZ #14232) A named semaphore is used to synchronize the pid information on the created file, the semaphore is updated once the file contents is flushed. Checked on x86_64-linux-gnu. Diff: --- nptl/Makefile | 2 ++ nptl/tst-cancel7.c | 92 ++++++++++++++++++++++++++++-------------------------- 2 files changed, 50 insertions(+), 44 deletions(-) diff --git a/nptl/Makefile b/nptl/Makefile index 3b260277dc..0dd139a53d 100644 --- a/nptl/Makefile +++ b/nptl/Makefile @@ -540,6 +540,8 @@ else librt = $(common-objpfx)rt/librt.a endif +$(objpfx)tst-cancel7: $(librt) +$(objpfx)tst-cancelx7: $(librt) $(objpfx)tst-cancel17: $(librt) $(objpfx)tst-cancelx17: $(librt) diff --git a/nptl/tst-cancel7.c b/nptl/tst-cancel7.c index 7a1870ac74..597f91f65e 100644 --- a/nptl/tst-cancel7.c +++ b/nptl/tst-cancel7.c @@ -18,44 +18,57 @@ #include <errno.h> #include <fcntl.h> -#include <pthread.h> +#include <getopt.h> #include <signal.h> -#include <stdio.h> #include <stdlib.h> -#include <string.h> -#include <unistd.h> -#include <getopt.h> +#include <semaphore.h> +#include <support/check.h> +#include <support/support.h> +#include <support/temp_file.h> +#include <support/xstdio.h> +#include <support/xunistd.h> #include <support/xthread.h> -const char *command; -const char *pidfile; -char pidfilename[] = "/tmp/tst-cancel7-XXXXXX"; +static const char *command; +static const char *pidfile; +static char *pidfilename; + +static const char sem_name[] = "/tst-cancel7-sem"; +static sem_t *sem; static void * tf (void *arg) { +#if 0 const char *args = " --direct --pidfile "; char *cmd = alloca (strlen (command) + strlen (args) + strlen (pidfilename) + 1); strcpy (stpcpy (stpcpy (cmd, command), args), pidfilename); +#endif + char *cmd = xasprintf ("%s --direct --pidfile %s", command, pidfilename); system (cmd); /* This call should never return. */ return NULL; } - static void sl (void) { +#if 0 FILE *f = fopen (pidfile, "w"); if (f == NULL) exit (1); +#endif + FILE *f = xfopen (pidfile, "w"); fprintf (f, "%lld\n", (long long) getpid ()); fflush (f); + if (sem_post (sem) != 0) + FAIL_EXIT1 ("sem_post: %m"); + struct flock fl = { .l_type = F_WRLCK, @@ -64,7 +77,7 @@ sl (void) .l_len = 1 }; if (fcntl (fileno (f), F_SETLK, &fl) != 0) - exit (1); + FAIL_EXIT1 ("fcntl (F_SETFL): %m"); sigset_t ss; sigfillset (&ss); @@ -76,57 +89,53 @@ sl (void) static void do_prepare (int argc, char *argv[]) { + sem = sem_open (sem_name, O_RDWR | O_CREAT | O_EXCL | O_TRUNC, 0666, 0); + if (sem == SEM_FAILED) + { + if (errno != EEXIST) + FAIL_EXIT1 ("sem_open failed: %m"); + sem = sem_open (sem_name, O_RDWR); + if (sem == SEM_FAILED) + FAIL_EXIT1 ("sem_open failed: %m"); + } + if (command == NULL) command = argv[0]; if (pidfile) sl (); - int fd = mkstemp (pidfilename); + int fd = create_temp_file ("tst-cancel7-pid-", &pidfilename); if (fd == -1) - { - puts ("mkstemp failed"); - exit (1); - } + FAIL_EXIT1 ("create_temp_file failed: %m"); - write (fd, " ", 1); - close (fd); + xwrite (fd, " ", 1); + xclose (fd); } static int do_test (void) { - pthread_t th; - if (pthread_create (&th, NULL, tf, NULL) != 0) - { - puts ("pthread_create failed"); - return 1; - } + pthread_t th = xpthread_create (NULL, tf, NULL); do - sleep (1); + nanosleep (&(struct timespec) { .tv_sec = 0, .tv_nsec = 100000000 }, NULL); while (access (pidfilename, R_OK) != 0); + if (sem_wait (sem) != 0) + FAIL_EXIT1 ("sem_wait: %m"); + xpthread_cancel (th); void *r = xpthread_join (th); sleep (1); - FILE *f = fopen (pidfilename, "r+"); - if (f == NULL) - { - puts ("no pidfile"); - return 1; - } + FILE *f = xfopen (pidfilename, "r+"); long long ll; if (fscanf (f, "%lld\n", &ll) != 1) - { - puts ("could not read pid"); - unlink (pidfilename); - return 1; - } + FAIL_EXIT1 ("fscanf: %m"); struct flock fl = { @@ -136,11 +145,7 @@ do_test (void) .l_len = 1 }; if (fcntl (fileno (f), F_GETLK, &fl) != 0) - { - puts ("F_GETLK failed"); - unlink (pidfilename); - return 1; - } + FAIL_EXIT1 ("fcntl: %m"); if (fl.l_type != F_UNLCK) { @@ -148,13 +153,12 @@ do_test (void) if (fl.l_pid == ll) kill (fl.l_pid, SIGKILL); - unlink (pidfilename); return 1; } - fclose (f); + xfclose (f); - unlink (pidfilename); + sem_unlink (sem_name); return r != PTHREAD_CANCELED; } @@ -181,7 +185,7 @@ do_cleanup (void) fclose (f); } - unlink (pidfilename); + sem_unlink (sem_name); } #define OPT_COMMAND 10000
next reply other threads:[~2021-06-08 20:48 UTC|newest] Thread overview: 2+ messages / expand[flat|nested] mbox.gz Atom feed top 2021-06-08 20:48 Adhemerval Zanella [this message] 2021-08-20 17:55 Adhemerval Zanella
Reply instructions: You may reply publicly to this message via plain-text email using any one of the following methods: * Save the following mbox file, import it into your mail client, and reply-to-all from there: mbox Avoid top-posting and favor interleaved quoting: https://en.wikipedia.org/wiki/Posting_style#Interleaved_style * Reply using the --to, --cc, and --in-reply-to switches of git-send-email(1): git send-email \ --in-reply-to=20210608204835.26F9A3983C39@sourceware.org \ --to=azanella@sourceware.org \ --cc=glibc-cvs@sourceware.org \ /path/to/YOUR_REPLY https://kernel.org/pub/software/scm/git/docs/git-send-email.html * If your mail client supports setting the In-Reply-To header via mailto: links, try the mailto: linkBe sure your reply has a Subject: header at the top and a blank line before the message body.
This is a public inbox, see mirroring instructions for how to clone and mirror all data and code used for this inbox; as well as URLs for read-only IMAP folder(s) and NNTP newsgroup(s).