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