This is the mail archive of the cygwin 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]
Other format: [Raw text]

mmap() on 64K aligned address fails


Hi,

I was trying to figure out the often reported failure of mmap seen by running
configure on some packages and, after looking at the answers on the list, I
tried a test on a 64k aligned (malloced) address, mmap(... MAP_FIXED ...) fails.

Attached is the small test file that was compiled with the command at the end of
the same file.

Any ideas what's wrong?

Thanks.
-- 
René Berber
/* confdefs.h.  */

#define PACKAGE_NAME "package-unused"
#define PACKAGE_TARNAME "libstdc++"
#define PACKAGE_VERSION "version-unused"
#define PACKAGE_STRING "package-unused version-unused"
#define PACKAGE_BUGREPORT ""
#ifdef __cplusplus
extern "C" void exit (int);
#endif
#define _GLIBCXX_HOSTED 1
#define _GLIBCXX_SJLJ_EXCEPTIONS 1
#define STDC_HEADERS 1
#define HAVE_SYS_TYPES_H 1
#define HAVE_SYS_STAT_H 1
#define HAVE_STDLIB_H 1
#define HAVE_STRING_H 1
#define HAVE_MEMORY_H 1
#define HAVE_STRINGS_H 1
#define HAVE_INTTYPES_H 1
#define HAVE_STDINT_H 1
#define HAVE_UNISTD_H 1
#define _GLIBCXX_USE_C99_MATH 1
#define _GLIBCXX_USE_LONG_LONG 1
#define HAVE_GTHR_DEFAULT 1
#define HAVE_IEEEFP_H 1
#define HAVE_ENDIAN_H 1
#define HAVE_MACHINE_ENDIAN_H 1
#define HAVE_MACHINE_PARAM_H 1
#define HAVE_LOCALE_H 1
#define HAVE_FLOAT_H 1
#define HAVE_INTTYPES_H 1
#define HAVE_SYS_TYPES_H 1
#define HAVE_SYS_IPC_H 1
#define HAVE_SYS_SEM_H 1
#define HAVE_ISINF 1
#define HAVE_ISNAN 1
#define HAVE_FINITE 1
#define HAVE_COPYSIGN 1
#define HAVE_SINCOS 1
#define HAVE_HYPOT 1
#define HAVE_ACOSF 1
#define HAVE_ASINF 1
#define HAVE_ATANF 1
#define HAVE_COSF 1
#define HAVE_SINF 1
#define HAVE_TANF 1
#define HAVE_COSHF 1
#define HAVE_SINHF 1
#define HAVE_TANHF 1
#define HAVE_CEILF 1
#define HAVE_FLOORF 1
#define HAVE_EXPF 1
#define HAVE_ATAN2F 1
#define HAVE_FABSF 1
#define HAVE_FMODF 1
#define HAVE_FREXPF 1
#define HAVE_HYPOTF 1
#define HAVE_LDEXPF 1
#define HAVE_LOGF 1
#define HAVE_LOG10F 1
#define HAVE_MODFF 1
#define HAVE_POWF 1
#define HAVE_SQRTF 1
#define HAVE_SINCOSF 1
#define HAVE___BUILTIN_ABS 1
#define HAVE___BUILTIN_FABSF 1
#define HAVE___BUILTIN_FABS 1
#define HAVE___BUILTIN_FABSL 1
#define HAVE___BUILTIN_LABS 1
#define HAVE___BUILTIN_SQRTF 1
#define HAVE___BUILTIN_SQRT 1
#define HAVE___BUILTIN_SQRTL 1
#define HAVE___BUILTIN_SINF 1
#define HAVE___BUILTIN_SIN 1
#define HAVE___BUILTIN_SINL 1
#define HAVE___BUILTIN_COSF 1
#define HAVE___BUILTIN_COS 1
#define HAVE___BUILTIN_COSL 1
#define HAVE_LIBM 1
#define HAVE_COPYSIGNF 1
#define HAVE___SIGNBITF 1
#define HAVE_MBSTATE_T 1
#define HAVE_WCHAR_H 1
#define HAVE_WCTYPE_H 1
#define HAVE_WCSLEN 1
#define HAVE_WMEMCHR 1
#define HAVE_WMEMCMP 1
#define HAVE_WMEMCPY 1
#define HAVE_WMEMMOVE 1
#define HAVE_WMEMSET 1
#define HAVE_BTOWC 1
#define HAVE_WCTOB 1
#define HAVE_WPRINTF 1
#define HAVE_MBSINIT 1
#define HAVE_MBRLEN 1
#define HAVE_MBRTOWC 1
#define HAVE_MBSRTOWCS 1
#define HAVE_WCSRTOMBS 1
#define HAVE_WCRTOMB 1
#define HAVE_WCSCPY 1
#define HAVE_WCSNCPY 1
#define HAVE_WCSCAT 1
#define HAVE_WCSNCAT 1
#define HAVE_WCSCMP 1
#define HAVE_WCSCOLL 1
#define HAVE_WCSNCMP 1
#define HAVE_WCSCSPN 1
#define HAVE_WCSSPN 1
#define HAVE_WCSCHR 1
#define HAVE_WCSPBRK 1
#define HAVE_WCSRCHR 1
#define HAVE_WCSSTR 1
#define HAVE_ISWBLANK 1
#define HAVE_NL_LANGINFO 1
#define HAVE_STRTOF 1
#define HAVE_SYS_IOCTL_H 1
#define HAVE_POLL 1
#define HAVE_S_ISREG 1
#define HAVE_SYS_UIO_H 1
#define HAVE_WRITEV 1
#define HAVE_INT64_T 1
#define HAVE_LC_MESSAGES 1
#define HAVE_SIGSETJMP 1
#define HAVE_STDLIB_H 1
#define HAVE_UNISTD_H 1
#define HAVE_GETPAGESIZE 1
/* end confdefs.h.  */
#include <stdio.h>
#if HAVE_SYS_TYPES_H
# include <sys/types.h>
#endif
#if HAVE_SYS_STAT_H
# include <sys/stat.h>
#endif
#if STDC_HEADERS
# include <stdlib.h>
# include <stddef.h>
#else
# if HAVE_STDLIB_H
#  include <stdlib.h>
# endif
#endif
#if HAVE_STRING_H
# if !STDC_HEADERS && HAVE_MEMORY_H
#  include <memory.h>
# endif
# include <string.h>
#endif
#if HAVE_STRINGS_H
# include <strings.h>
#endif
#if HAVE_INTTYPES_H
# include <inttypes.h>
#else
# if HAVE_STDINT_H
#  include <stdint.h>
# endif
#endif
#if HAVE_UNISTD_H
# include <unistd.h>
#endif
/* malloc might have been renamed as rpl_malloc. */
#undef malloc

/* Thanks to Mike Haertel and Jim Avera for this test.
   Here is a matrix of mmap possibilities:
	mmap private not fixed
	mmap private fixed at somewhere currently unmapped
	mmap private fixed at somewhere already mapped
	mmap shared not fixed
	mmap shared fixed at somewhere currently unmapped
	mmap shared fixed at somewhere already mapped
   For private mappings, we should verify that changes cannot be read()
   back from the file, nor mmap's back from the file at a different
   address.  (There have been systems where private was not correctly
   implemented like the infamous i386 svr4.0, and systems where the
   VM page cache was not coherent with the file system buffer cache
   like early versions of FreeBSD and possibly contemporary NetBSD.)
   For shared mappings, we should conversely verify that changes get
   propagated back to all the places they're supposed to be.

   Grep wants private fixed already mapped.
   The main things grep needs to know about mmap are:
   * does it exist and is it safe to write into the mmap'd area
   * how to use it (BSD variants)  */

#include <fcntl.h>
#include <sys/mman.h>

#if !STDC_HEADERS && !HAVE_STDLIB_H
char *malloc ();
#endif

/* This mess was copied from the GNU getpagesize.h.  */
#if !HAVE_GETPAGESIZE
/* Assume that all systems that can run configure have sys/param.h.  */
# if !HAVE_SYS_PARAM_H
#  define HAVE_SYS_PARAM_H 1
# endif

# ifdef _SC_PAGESIZE
#  define getpagesize() sysconf(_SC_PAGESIZE)
# else /* no _SC_PAGESIZE */
#  if HAVE_SYS_PARAM_H
#   include <sys/param.h>
#   ifdef EXEC_PAGESIZE
#    define getpagesize() EXEC_PAGESIZE
#   else /* no EXEC_PAGESIZE */
#    ifdef NBPG
#     define getpagesize() NBPG * CLSIZE
#     ifndef CLSIZE
#      define CLSIZE 1
#     endif /* no CLSIZE */
#    else /* no NBPG */
#     ifdef NBPC
#      define getpagesize() NBPC
#     else /* no NBPC */
#      ifdef PAGESIZE
#       define getpagesize() PAGESIZE
#      endif /* PAGESIZE */
#     endif /* no NBPC */
#    endif /* no NBPG */
#   endif /* no EXEC_PAGESIZE */
#  else /* no HAVE_SYS_PARAM_H */
#   define getpagesize() 8192	/* punt totally */
#  endif /* no HAVE_SYS_PARAM_H */
# endif /* no _SC_PAGESIZE */

#endif /* no HAVE_GETPAGESIZE */

int
main ()
{
  char *data, *data2, *data3;
  int i, pagesize;
  int fd;

  pagesize = getpagesize ();

  printf("pagesize is %d\n", pagesize);
  /* First, make a file with some known garbage in it. */
  data = (char *) malloc (pagesize);
  if (!data) {
    printf("malloc failed\n");
    exit (1);
  }
  for (i = 0; i < pagesize; ++i)
    *(data + i) = rand ();
  umask (0);
  fd = creat ("conftest.mmap", 0600);
  if (fd < 0) {
    printf("creat failed\n");
    exit (1);
  }
  if (write (fd, data, pagesize) != pagesize) {
    printf("write failed\n");
    exit (1);
  }
  close (fd);

  /* 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) {
    printf("open failed\n");
    exit (1);
  }
#if !defined(__CYGWIN32__)
  data2 = (char *) malloc (2 * pagesize);
  if (!data2) {
    printf("second malloc failed\n");
    exit (1);
  }
  data2 += (pagesize - ((long) data2 & (pagesize - 1))) & (pagesize - 1);
#else
  data2 = (char *) malloc (16 * pagesize);
  if (!data2) {
    printf("second malloc failed\n");
    exit (1);
  }
  printf("data2 before is %p\n", data2);
  data2 += (16*pagesize - ((long) data2 & (16*pagesize - 1))) & (16*pagesize - 1);
  printf("data2 after  is %p\n", data2);
#endif
  if (data2 != mmap (data2, pagesize, PROT_READ | PROT_WRITE,
		     MAP_PRIVATE | MAP_FIXED, fd, 0L)) {
    printf("mmap failed\n");
    exit (1);
  }
  for (i = 0; i < pagesize; ++i)
    if (*(data + i) != *(data2 + i)) {
      printf("pages are not equal\n");
      exit (1);
    }

  /* Finally, make sure that changes to the mapped area do not
     percolate back to the file as seen by read().  (This is a bug on
     some variants of i386 svr4.0.)  */
  for (i = 0; i < pagesize; ++i)
    *(data2 + i) = *(data2 + i) + 1;
  data3 = (char *) malloc (pagesize);
  if (!data3) {
    printf("third malloc failed\n");
    exit (1);
  }
  if (read (fd, data3, pagesize) != pagesize) {
    printf("read failed\n");
    exit (1);
  }
  for (i = 0; i < pagesize; ++i)
    if (*(data + i) != *(data3 + i)) {
      printf("file changed\n");
      exit (1);
    }
  close (fd);
  printf("OK\n");
  exit (0);
}

/*
 * Local variables:
 * compile: gcc -o mmap_test -O2 mmap_test.c -lm
 * end:
 */

--
Unsubscribe info:      http://cygwin.com/ml/#unsubscribe-simple
Problem reports:       http://cygwin.com/problems.html
Documentation:         http://cygwin.com/docs.html
FAQ:                   http://cygwin.com/faq/

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