This is the mail archive of the cygwin@sources.redhat.com mailing list for the Cygwin project.


Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]

Re: Call for Testers: mmap autoconf logic


With cygwin 1.1.7 on a W98 box:

cc: not found
No mmap from /dev/zero.
cc: not found
No mmap with MAP_ANON(YMOUS).
ls: *.l: No such file or directory

When that didn't work, I changed the script to use "gcc" instead of
"cc", and got:

No mmap from /dev/zero.
No mmap with MAP_ANON(YMOUS).
-rw-r--r--   1 wpd      wpd             0 Jan  9 12:53 test1a.l
-rw-r--r--   1 wpd      wpd             0 Jan  9 12:52 test1z.l

Zack Weinberg wrote:
> 
> I would appreciate it if y'all would run the appended shell script and
> send me its output + any nonempty .l files it generates.  (They'll be
> in a subdirectory named "mmt12345" for some value of 12345.)
> 
> I do not need to know about common, modern systems (*BSD, Linux,
> Solaris, IRIX >=6.2, etc.)  nor about systems known to have no mmap(2)
> at all.  I am specifically interested in the behavior under cygwin;
> the "works/is buggy" check is supposed to catch several bugs known to
> exist in that mmap implementation.
> 
> Thanks.
> 
> zw
> 
> -- cut here --
> #! /bin/sh
> 
> mkdir mmt$$ || exit 1
> cd mmt$$ || exit 1
> 
> cat >testcore.h <<EOF
> /* Test by Richard Henderson and Alexandre Oliva.
>    Check whether mmap MAP_ANONYMOUS or mmap from /dev/zero works. */
> #include <sys/types.h>
> #include <sys/param.h>
> #include <sys/mman.h>
> #include <unistd.h>
> #include <stdlib.h>
> #include <fcntl.h>
> 
> #ifndef MAP_ANON
> # ifdef MAP_ANONYMOUS
> #  define MAP_ANON MAP_ANONYMOUS
> # else
> #  define MAP_ANON 0
> # endif
> #endif
> 
> #ifndef MAP_FAILED
> # define MAP_FAILED -1
> #endif
> 
> static char *
> anonmap (size)
>      size_t size;
> {
> #ifdef USE_MAP_ANON
>   return (char *) mmap (0, size, PROT_READ|PROT_WRITE,
>                         MAP_PRIVATE|MAP_ANON, -1, 0);
> #else
>   static int devzero = -1;
>   if (devzero == -1)
>     {
>       devzero = open ("/dev/zero", O_RDWR);
>       if (devzero < 0)
>         exit (1);
>     }
>   return (char *) mmap (0, size, PROT_READ|PROT_WRITE,
>                         MAP_PRIVATE, devzero, 0);
> #endif
> }
> EOF
> 
> cat >test1.c <<EOF
> #include "testcore.h"
> 
> int
> main()
> {
>   int pg = getpagesize ();
>   char *x = anonmap (pg);
> 
>   if (x == (char *) MAP_FAILED)
>     exit(2);
> 
>   *(int *)x += 1;
> 
>   if (munmap(x, pg) < 0)
>     exit(3);
> 
>   exit(0);
> }
> EOF
> 
> if ${CC-cc} test1.c -o test1z.x >test1z.l 2>&1 && ./test1z.x >>test1z.l 2>&1
> then echo "Have mmap from /dev/zero."
>      have_dev_zero=y
> else echo "No mmap from /dev/zero."
> fi
> 
> if ${CC-cc} test1.c -DUSE_MAP_ANON -o test1a.x >test1a.l 2>&1 \
>     && ./test1a.x >>test1a.l 2>&1
> then echo "Have mmap with MAP_ANON(YMOUS)."
>      have_map_anon=y
> else echo "No mmap with MAP_ANON(YMOUS)."
> fi
> 
> cat >test2.c <<EOF
> #include "testcore.h"
> #include <signal.h>
> #include <setjmp.h>
> 
> /* Some versions of cygwin mmap require that munmap is called with the
>    same parameters as mmap.  GCC expects that this is not the case.
>    Test for various forms of this problem.  Warning - icky signal games.  */
> static jmp_buf r;
> static size_t pg;
> 
> static void
> sigsegv (unused)
>      int unused;
> {
>   longjmp (r, 1);
> }
> 
> /* 1. If we map a 2-page region and unmap its second page, the first page
>    must remain.  */
> void
> test_1 ()
> {
>   char *x = anonmap (pg * 2);
>   if (x == (char *)MAP_FAILED)
>     exit (1);
> 
>   signal (SIGSEGV, sigsegv);
>   if (setjmp (r))
>     exit (2);
> 
>   x[0] = 1;
>   x[pg] = 1;
> 
>   munmap (x + pg, pg);
>   x[0] = 2;
> 
>   if (setjmp (r))
>     {
>       munmap (x, pg);
>       return;
>     }
>   x[pg] = 1;
>   exit (3);
> }
> 
> /* 2. If we map a 2-page region and unmap its first page, the second
>    page must remain.  */
> void
> test_2 ()
> {
>   char *x = anonmap (pg * 2);
>   if (x == (char *)MAP_FAILED)
>     exit (4);
> 
>   signal (SIGSEGV, sigsegv);
>   if (setjmp (r))
>     exit (5);
> 
>   x[0] = 1;
>   x[pg] = 1;
> 
>   munmap (x, pg);
>   x[pg] = 2;
> 
>   if (setjmp (r))
>     {
>       munmap (x + pg, pg);
>       return;
>     }
>   x[0] = 1;
>   exit (6);
> }
> 
> /* 3. If we map two consecutive 1-page regions and unmap them both with
>    one munmap, both must go away.  */
> 
> void
> test_3 ()
> {
>   char *x = anonmap (pg);
>   char *y = anonmap (pg);
>   if (x == (char *)MAP_FAILED || y == (char *)MAP_FAILED || x + pg != y)
>     exit (7);
> 
>   signal (SIGSEGV, sigsegv);
>   if (setjmp (r))
>     exit (8);
> 
>   x[0] = 1;
>   x[pg] = 1;
> 
>   munmap (x, pg * 2);
> 
>   if (setjmp (r) == 0)
>     {
>       x[0] = 1;
>       exit (9);
>     }
> 
>   signal (SIGSEGV, sigsegv);
>   if (setjmp (r) == 0)
>     {
>       x[pg] = 1;
>       exit (10);
>     }
> }
> 
> int
> main ()
> {
>   pg = getpagesize ();
> 
>   test_1();
>   test_2();
>   test_3();
> 
>   exit(0);
> }
> EOF
> 
> if test -n "$have_dev_zero"; then
>   if ${CC-cc} test2.c  -o test2z.x >test2z.l 2>&1 \
>      && ./test2z.x >>test2z.l 2>&1
>   then echo "mmap of /dev/zero works."
>   else echo "mmap of /dev/zero is buggy. ($?)"
>   fi
> fi
> 
> if test -n "$have_map_anon"; then
>   if ${CC-cc} test2.c -DUSE_MAP_ANON -o test2a.x >test2a.l 2>&1 \
>      && ./test2a.x >>test2a.l 2>&1
>   then echo "mmap with MAP_ANON(YMOUS) works."
>   else echo "mmap with MAP_ANON(YMOUS) is buggy. ($?)"
>   fi
> fi
> 
> ls -l *.l
> 
> --
> Want to unsubscribe from this list?
> Check out: http://cygwin.com/ml/#unsubscribe-simple

--
Want to unsubscribe from this list?
Check out: http://cygwin.com/ml/#unsubscribe-simple


Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]