Subject: kern/6419: mmap
To: None <gnats-bugs@gnats.netbsd.org>
From: Andreas Wrede <andreas@planix.com>
List: netbsd-bugs
Date: 11/09/1998 19:00:21
>Number: 6419
>Category: kern
>Synopsis: mmap
>Confidential: no
>Severity: serious
>Priority: medium
>Responsible: kern-bug-people (Kernel Bug People)
>State: open
>Class: sw-bug
>Submitter-Id: net
>Arrival-Date: Mon Nov 9 16:05:02 1998
>Last-Modified:
>Originator: Andreas Wrede
>Organization:
Planix, Inc.
>Release: <NetBSD-current source date>-current, Nov 4,98
>Environment:
System: NetBSD woffi 1.3H NetBSD 1.3H (WOFFI) #0: Wed Nov 4 20:44:02 EST 1998 root@woffi:/local1/netbsd/netbsd-current/src/sys/arch/i386/compile/WOFFI i386
>Description:
The configure script for the Cyrus imapd server ver 1.5.14 runs a test program
to "Verify the OS supports the memory mapping semantics needed by
map_private".
The program fails in different ways on both 1.3.2 and -current. On 1.3.2 it
results in "private map does not show change", while on -current it prints
"shared map does not match within page" (see code below).
I don't understand the intricacies of mmap well enough to see what is going
on, but the fact that there is a difference appears to indicate that we
have a problem here.
Both 1.3.2 and -current are i386, -current is 1.3H from Nov 4, using gcc
2.7.2.2, UVM and PMAP_NEW.
>How-To-Repeat:
Compile and run the code below. Jonathan Stone suggests to include the
program below in a regress-test suite.
---[snip]---
/* Verify the OS supports the memory mapping semantics needed by map_private
* from John Myers <jgmyers@netscape.com>
*/
#include <sys/types.h>
#include <sys/mman.h>
#include <fcntl.h>
#ifndef MAP_NORESERVE
#define MAP_NORESERVE 0
#endif
/* not on Linux */
#ifndef MAP_VARIABLE
#define MAP_VARIABLE 0
#endif
#ifndef MAP_FAILED
#define MAP_FAILED ((void *) -1)
#endif
fatal(char *s)
{
write(2, s, strlen(s));
write(2, "\n", 1);
unlink("conftestmmap");
exit(1);
}
main() {
int fd = open("conftestmmap", O_RDWR|O_CREAT|O_TRUNC, 0666);
int fd2;
char *base_shared, *base_private, *base_private2;
if (fd == -1) fatal("cannot create test file");
if (write(fd, "test", 4) != 4) fatal("cannot write test file");
base_shared = mmap((caddr_t)0, 10000, PROT_READ,
MAP_SHARED | MAP_FILE| MAP_VARIABLE,
fd, 0L);
if (base_shared == MAP_FAILED) fatal("cannot create shared map");
base_private = mmap((caddr_t)0, 4, PROT_READ,
MAP_PRIVATE | MAP_NORESERVE | MAP_FILE| MAP_VARIABLE,
fd, 0L);
if (base_private == MAP_FAILED) fatal("cannot create private map");
base_private2 = mmap((caddr_t)0, 4, PROT_READ,
MAP_PRIVATE | MAP_NORESERVE | MAP_FILE| MAP_VARIABLE,
fd, 0L);
if (base_private == MAP_FAILED) fatal("cannot create private2 map");
if (strncmp(base_shared, "test", 4) != 0) fatal("shared map does not match");
if (strncmp(base_private, "test", 4) != 0) fatal("private map does not match");
if (write(fd, "test", 4) != 4) fatal("cannot extend test file within page");
fsync(fd);
msync((caddr_t)base_shared, 10000, MS_INVALIDATE);
if (munmap(base_private, 4)) fatal("cannot unmap private map");
base_private = mmap((caddr_t)0, 8, PROT_READ,
MAP_PRIVATE | MAP_NORESERVE | MAP_FILE| MAP_VARIABLE,
fd, 0L);
if (base_private == MAP_FAILED) fatal("cannot create private map second time");
if (strncmp(base_shared+4, "test", 4) != 0) fatal("shared map does not match within page");
if (strncmp(base_private+4, "test", 4) != 0) fatal("private map does not match within page");
fd2 = open("conftestmmap", O_RDWR, 0666);
if (lseek(fd2, 0, 0) == -1) fatal("cannot seek second fd");
if (write(fd2, "xyzy", 4) != 4) fatal("cannot write second fd");
fsync(fd2);
if (munmap(base_private, 8)) fatal("cannot unmap private map");
base_private = mmap((caddr_t)0, 8, PROT_READ,
MAP_PRIVATE | MAP_NORESERVE | MAP_FILE| MAP_VARIABLE,
fd, 0L);
if (base_private == MAP_FAILED) fatal("cannot create private map third time");
if (strncmp(base_private, "xyzy", 4) != 0) fatal("private map does not show change");
{
int i;
for (i = 0; i < 9000; i++) {
if (write(fd, "test", 4) != 4) fatal("cannot extend test file outside page");
}
}
msync((caddr_t)base_shared, 10000, MS_INVALIDATE);
msync((caddr_t)base_private, 10000, MS_INVALIDATE);
if (strncmp(base_shared+9000, "test", 4) != 0) fatal("shared map does not match beyond page");
#if 0
if (strncmp(base_private+9000, "test", 4) != 0) fatal("private map does notmatch beyond page");
#endif
unlink("conftestmmap");
exit(0);
}
>Fix:
Unknown
>Audit-Trail:
>Unformatted:
mmap test program produces different results in -current and 1.3.2