threads/79887: [patch] freopen() isn't thread-safe

Vasil Dimov vd at FreeBSD.org
Tue Dec 7 07:50:11 UTC 2010


The following reply was made to PR threads/79887; it has been noted by GNATS.

From: Vasil Dimov <vd at FreeBSD.org>
To: bug-followup at FreeBSD.org, tejblum at yandex-team.ru
Cc:  
Subject: Re: threads/79887: [patch] freopen() isn't thread-safe
Date: Tue, 7 Dec 2010 09:42:02 +0200

 --jRHKVT23PllUwdXP
 Content-Type: text/plain; charset=us-ascii
 Content-Disposition: inline
 
 Hi,
 
 This bug is biting MySQL badly (data corruption due to writing to the
 wrong file).
 
 See http://bugs.mysql.com/51023
 Bug#51023 Mysql server crashes on SIGHUP and destroys InnoDB files
 
 Attaching a simple prog to reproduce this (tested on 8.1-STABLE/amd64).
 
 -- 
 Vasil Dimov
 gro.DSBeerF at dv
 %
 The difference between life and the movies is that a script has to
 make sense, and life doesn't.
                 -- Joseph L. Mankiewicz
 
 --jRHKVT23PllUwdXP
 Content-Type: text/x-csrc; charset=us-ascii
 Content-Disposition: attachment; filename="pr79887.c"
 
 #include <sys/types.h>
 #include <sys/uio.h>
 
 #include <errno.h>
 #include <fcntl.h>
 #include <pthread.h>    
 #include <stdio.h>
 #include <stdlib.h>
 #include <string.h>
 #include <unistd.h>     
 
 FILE*	l;
 
 void*
 openmany(void* p)
 {
 	int			fds[1500];
 	unsigned long long	i, j;
 	char			filename[100];
 
 	for (i = 0; ; i++) {
 		for (j = 0; j < 1500; j++) {
 
 			snprintf(filename, sizeof(filename),
 				 "/tmp/ib%04llu", j);
 			fds[j] = open(filename, O_RDWR | O_CREAT, 0644);
 			fprintf(l, "open(): %s: %d\n", filename, fds[j]);
 			if (fds[j] == -1) {
 				fprintf(l, "open(): %s: %s\n", filename,
 					strerror(errno));
 				exit(1);
 			}
 			write(fds[j], "ABCABCABC", 9);
 		}
 
 		for (j = 0; j < 1500; j++) {
 			int	ret;
 
 			ret = close(fds[j]);
 
 			fprintf(l, "close(): %d: %d\n", fds[j], ret);
 
 			if (ret == -1) {
 				fprintf(l, "error: close(%d): %s\n", fds[j],
 				       strerror(errno));
 				exit(1);
 			}
 		}
 	}
 }
 
 void*
 reopenstd(void* p)
 {
 	unsigned long long i;
 
 	for (i = 0; ; i++) {
 		freopen("/tmp/std_redirected", "a+", stdout);
 		freopen("/tmp/std_redirected", "a+", stderr);
 		printf("XXXXXXXXXXX %llu\n", i);
 	}
 
 	return(NULL);
 }
 
 int
 main(int argc, char **argv, char **envp)
 {
 	pthread_t	t1;
 	pthread_t	t2;
 	void*		ret;
 
 	l = fopen("/tmp/log", "w");
 	if (l == NULL) {
 		fprintf(stderr, "error: fopen(): /tmp/log: %s\n",
 			strerror(errno));
 		exit(1);
 	}
 
 	pthread_create(&t1, NULL, reopenstd, NULL);
 	pthread_create(&t2, NULL, openmany, NULL);
 
 	pthread_join(t1, &ret);
 	pthread_join(t2, &ret);
 
 	fclose(l);
 
 	return(0);
 }
 
 --jRHKVT23PllUwdXP--


More information about the freebsd-threads mailing list