This is the mail archive of the
cygwin
mailing list for the Cygwin project.
Re: Question about flock - potential memory corruption?
- From: Qian Hong <fracting at gmail dot com>
- To: cygwin <cygwin at cygwin dot com>
- Date: Tue, 8 Sep 2015 13:54:02 +0800
- Subject: Re: Question about flock - potential memory corruption?
- Authentication-results: sourceware.org; auth=none
- References: <CALd+sZRo_Nyv=adF5DeeHiShJsxGD+KUPqkDMKb3q47a2Nm=8Q at mail dot gmail dot com> <CALd+sZSUAt6_fdHkgdKqefz1Wv-ijShSo82qJKUcCkZH9v5KzA at mail dot gmail dot com> <CALd+sZQUy=Yn6UJ74N4Bvxd_wi++v+kOU5MehAkW7oaLO+NVbw at mail dot gmail dot com> <55EE66E1 dot 3000908 at dwalin dot fsnet dot co dot uk>
- Reply-to: fracting at gmail dot com
Hi Sam,
Thank you very much for your reply!
On Tue, Sep 8, 2015 at 12:41 PM, Sam Edge <sam.edge@dwalin.fsnet.co.uk> wrote:
> Erm ... slight technical hitch? Your example flock.c doesn't call
> fork(), nor does it use your two macros MAX_ITER & CHILDREN.
Good question. This problem was originally found when running autom4te on Wine.
In autom4te-2.69, we have:
68 my $flock_implemented = 'yes';
982 $icache_file = new Autom4te::XFile $icache, O_RDWR|O_CREAT;
983 $icache_file->lock (LOCK_EX)
984 if ($flock_implemented eq "yes");
This cause problem on Wine on some machine, while it works fine on
some other machine.
After tracking down, I successfully reproduce the problem with Cygwin
using the attached test case stc-flock-fork-2.c, which is changed
based on another test case from an old cygwin mailing list archive
[1].
Later then, I found that even without fork(), we can still reproduce
the same problem, Valgrind + Wine shows same warning either with or
without fork, so I simply the test case a bit further, that's why you
didn't see fork in my test case.
Thank for your comment, it's good to make things clearer to everybody.
Any further comment is welcome!
[1] https://www.cygwin.com/ml/cygwin/2011-08/txt00012.txt
--
Regards,
Qian Hong
-
http://www.winehq.org
/***********************************************************************
* This is a STC that causes the following error on my test machine:
* NtCreateEvent(lock): 0xC0000035
*
* It tries to use flock() for file locking. It creates a temporary
* file, the uses fork to spawn a number of children. Each child opens
* the file, then repeatedly uses flock to lock and unlock it.
*
* This test was extracted from the APR test suite.
*
* Compile: gcc -Wall -o stc-flock-fork stc-flock-fork.c
***********************************************************************/
#include <sys/types.h>
#include <sys/file.h>
#include <sys/wait.h>
#include <stdio.h>
#include <stdlib.h>
#include <fcntl.h>
#include <unistd.h>
#include <errno.h>
#define MAX_ITER 3
#define CHILDREN 2
/* A temporary file used for flock. */
char tmpfilename[] = "/tmp/flocktstXXXXXX";
/* Fork and use flock to lock and unlock the file repeatedly in the child. */
void make_child(int trylock, pid_t *pid)
{
if ((*pid = fork()) < 0) {
perror("fork failed");
exit(1);
}
else if (*pid == 0) {
int fd2 = open(tmpfilename, O_RDONLY);
if (fd2 < 0) {
perror("child open");
exit(1);
}
int rc;
int i;
for (i=0; i<MAX_ITER; ++i) {
do {
rc = flock(fd2, LOCK_EX);
} while (rc < 0 && errno == EINTR);
if (rc < 0) {
perror("lock");
exit(1);
}
do {
rc = flock(fd2, LOCK_UN);
} while (rc < 0 && errno == EINTR);
if (rc < 0) {
perror("unlock");
exit(1);
}
}
exit(0);
}
}
/* Wait for the child to finish. */
void await_child(pid_t pid)
{
pid_t pstatus;
int exit_int;
do {
pstatus = waitpid(pid, &exit_int, WUNTRACED);
} while (pstatus < 0 && errno == EINTR);
}
int main(int argc, const char * const * argv, const char * const *env)
{
pid_t child[CHILDREN];
int n;
int fd;
/* Create the temporary file. */
fd = mkstemp(tmpfilename);
if (fd < 0) {
perror("open failed");
exit(1);
}
close(fd);
/* Create the children. */
for (n = 0; n < CHILDREN; n++)
make_child(0, &child[n]);
/* Wait for them to finish. */
for (n = 0; n < CHILDREN; n++)
await_child(child[n]);
/* Clean up. */
unlink(tmpfilename);
return 0;
}
--
Problem reports: http://cygwin.com/problems.html
FAQ: http://cygwin.com/faq/
Documentation: http://cygwin.com/docs.html
Unsubscribe info: http://cygwin.com/ml/#unsubscribe-simple