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]

msync failure due to rounding up length (with test case and suggested fix)


See winsup/cygwin/mmap.cc line 1355 in current CVS (msync function):

len = roundup2 (len, pagesize);

I verified my suspicion that roundup2() is causing Python's test suite
to fail.  When
I stepped in the debugger and reset the len to its original value
after calling roundup2() the test passed.  Can we get that line
removed?  It doesn't really make sense to me.  Why wouldn't msync only
sync the size we asked for, why would it do more?  Maybe it needs to
be rounded up to min(len + pagesize, max_size_of_region)?

It was part of a massive checkin to winsup/cygwin/mmap.cc:

revision 1.120
date: 2005/12/07 11:16:47;  author: corinna;  state: Exp;  lines: +443 -191
...
       (msync): Rework argument checks. Align len to pagesize.
...

No hint as to why roundup is needed though.

Below is a test program that works on Linux (and presumably every
other platform that passes the Python test suite including: OpenBSD,
MacOS X, Solaris and various Linux versions).

The result should be 0 (no failure), but is -1, EINVAL.

n
--

#include <stdio.h>
#include <string.h>
#include <errno.h>
#include <sys/mman.h>

#define TEST_FILE "test.txt"

int main(int argc, char**argv) {
 const char buffer[] = "this is ~10";
 char buffer2[1024];
 size_t len = strlen(buffer);

 // Create the file with about 10 bytes for later use
 FILE *fp = fopen(TEST_FILE, "w+");
 fwrite(buffer, len, 1, fp);
 fclose(fp);

/* Original Python test from Lib/test/test_mmap.py

       f = open(TESTFN, "r+b")
       m = mmap.mmap(f.fileno(), mapsize, access=mmap.ACCESS_COPY)
       print "  Modifying copy-on-write memory map."
       m[:] = 'd'*mapsize
       verify(m[:] == 'd' * mapsize,
              "Copy-on-write memory map data not written correctly.")
       m.flush()
*/

 // open file for use with mmap
 fp = fopen(TEST_FILE, "r+");
 void *mm = mmap(NULL, len, PROT_READ | PROT_WRITE, MAP_SHARED,
fileno(fp), 0);  memset(buffer2, 'c', len);
 int result = msync(mm, len, MS_SYNC);
 printf("result=%d should be 0, errno=%d\n", result, errno);

 munmap(mm, len);
 fclose(fp);
 return result;
}

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