public inbox for cygwin@cygwin.com
 help / color / mirror / Atom feed
From: Qian Hong <fracting@gmail.com>
To: cygwin <cygwin@cygwin.com>
Subject: Re: Question about flock - potential memory corruption?
Date: Tue, 08 Sep 2015 05:54:00 -0000	[thread overview]
Message-ID: <CALd+sZSspE2pn-tvX+fCkK93h1GVy+Yaf_8DAU4KAmYnKZmMYw@mail.gmail.com> (raw)
In-Reply-To: <55EE66E1.3000908@dwalin.fsnet.co.uk>

[-- Attachment #1: Type: text/plain, Size: 1291 bytes --]

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

[-- Attachment #2: stc-flock-fork-2.c --]
[-- Type: text/x-csrc, Size: 2505 bytes --]

/***********************************************************************
 * 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;
}

[-- Attachment #3: Type: text/plain, Size: 218 bytes --]

--
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

  reply	other threads:[~2015-09-08  5:54 UTC|newest]

Thread overview: 9+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2015-09-04 20:22 Qian Hong
2015-09-07 18:42 ` Qian Hong
2015-09-07 18:46   ` Qian Hong
2015-09-08  4:41     ` Sam Edge
2015-09-08  5:54       ` Qian Hong [this message]
2015-09-08  8:58 ` Corinna Vinschen
2015-09-08 10:36   ` Qian Hong
2015-09-08 15:31     ` Corinna Vinschen
2015-09-08 15:54       ` Qian Hong

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=CALd+sZSspE2pn-tvX+fCkK93h1GVy+Yaf_8DAU4KAmYnKZmMYw@mail.gmail.com \
    --to=fracting@gmail.com \
    --cc=cygwin@cygwin.com \
    /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: link
Be 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).