autoconf-patches
[Top][All Lists]
Advanced

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

Re: Broken autoconf mmap test


From: Ralf Wildenhues
Subject: Re: Broken autoconf mmap test
Date: Tue, 24 Nov 2009 16:09:25 +0100
User-agent: Mutt/1.5.20 (2009-08-09)

Hi Eric,

* Eric Blake wrote on Tue, Nov 10, 2009 at 06:00:58AM CET:
> According to Corinna Vinschen on 11/9/2009 7:05 AM:
> > This part of the testcase
> > 
> >   data2 = (char *) malloc (2 * pagesize);
> >   if (!data2)
> >     return 1;
> >   data2 += (pagesize - ((long int) data2 & (pagesize - 1))) & (pagesize - 
> > 1);
> >   if (data2 != mmap (data2, pagesize, PROT_READ | PROT_WRITE,
> >                        MAP_PRIVATE | MAP_FIXED, fd, 0L))
> >     return 1;
> > 
> > is bad.  The chance that the address of data2 is not usable for mmap on
> > Windows/Cygwin is 100%.  The problem here is that the generic HAVE_MMAP
> > test tests one certain feature, which is not usable on Windows, and which
> > is non-portable.
> 
> MAP_FIXED appears to be more portable when the fixed address was obtained
> from a previous mmap call.  Therefore, this patch fixes the macro as well
> as making diagnosing configure failures more accurately pinpoint why they
> are declaring failure.  I don't have access to HP-UX 11, which is another
> platform where AC_FUNC_MMAP was failing; I would appreciate if someone
> else could see if this makes a difference there.  But I have verified that
> this now sets HAVE_MMAP for cygwin 1.5.x and cygwin 1.7 where the old
> version failed, and that it does not change behavior on Linux or OpenBSD.

With this patch, the test exits with status 10 on HP/UX 11.  Without the
patch, the failure is 1 and also happens at the
    if (data2 != mmap (data2, pagesize, PROT_READ | PROT_WRITE,
                       MAP_PRIVATE | MAP_FIXED, fd, 0L))

line.  Not sure what to try next.

mmap(2) has several parts.  The general part documents:

      When MAP_FIXED is set in the flags argument, the implementation is
      informed that the value of pa must be addr, exactly. If MAP_FIXED is
      set, mmap() may return MAP_FAILED and set errno to EINVAL.  If a
      MAP_FIXED request is successful, the mapping established by mmap()
      replaces any previous mappings for the process' pages in the range
      [pa, pa+len].
[...]
      Use of MAP_FIXED may result in unspecified behavior in further use of
      brk(), sbrk(), malloc(), and shmat().  The use of MAP_FIXED is
      discouraged, as it may prevent an implementation from making the most
      effective use of resources.

The HP-UX extensions part documents:

      If MAP_FIXED is set in flags:

           +    addr must be a multiple of the page size returned by
                sysconf(_SC_PAGE_SIZE).
[...]
           +    The use of MAP_FIXED is strongly discouraged because it is
                not portable.  Using MAP_FIXED is generally unsuccessful on
                this implementation, and when it is successful, it may
                prevent the system from optimally allocating virtual address
                space.

      MAP_FIXED is discouraged, but there are some applications which by
      design must fix pointer offsets into file data.  The application must
      map the file at a specific address in order for the file offsets
      embedded in the file to make sense.


Cheers,
Ralf

> >From fb1f28a2ff2c688e63dc97ece7fde86e16864491 Mon Sep 17 00:00:00 2001
> From: Eric Blake <address@hidden>
> Date: Mon, 9 Nov 2009 21:45:00 -0700
> Subject: [PATCH] Fix AC_FUNC_MMAP for cygwin.
> 
> * lib/autoconf/functions.m4 (AC_FUNC_MMAP): Make the test more
> portable: Actually check for <sys/param.h>, and only use MAP_FIXED
> on an address previously returned from mmap.
> * THANKS: Update.
> Reported by Corinna Vinschen.


>    /* Next, try to mmap the file at a fixed address which already has
>       something else allocated at it.  If we can, also make sure that
>       we see the same garbage.  */
>    fd = open ("conftest.mmap", O_RDWR);
>    if (fd < 0)
> -    return 1;
> -  data2 = (char *) malloc (2 * pagesize);
> -  if (!data2)
> -    return 1;
> -  data2 += (pagesize - ((long int) data2 & (pagesize - 1))) & (pagesize - 1);
> +    return 9;
>    if (data2 != mmap (data2, pagesize, PROT_READ | PROT_WRITE,
>                    MAP_PRIVATE | MAP_FIXED, fd, 0L))
> -    return 1;
> +    return 10;





reply via email to

[Prev in Thread] Current Thread [Next in Thread]