Steffen Daode Nurpmeso <sdao...@googlemail.com> added the comment:

I was able to spend more time on that this afternoon.
'Got an unkillable diff(1) along the way which required me to
force a cold reboot.  Well.

I attach a C version (11277.mmap.c) which i've used for testing.
The file 11277.zsum32.c is a quick-and-dirty C program to
calculate CRC-32 and Adler-32 checksums (i had none for the
latter and maybe you want to test some more, so); it requires zlib.
I also attach 11277.1.diff which updates test/test_zlib.py, though
this is rather useless, because that still results in a bus error.

This is the real interesting thing however, because the C version
actually works quite well for the chosen value, and the resulting
files are identical, as zsum32 shows:

    Adler-32 <14b9018b> CRC-32 <c6e340bf> -- test_python_413/@test_413_tmp
    Adler-32 <14b9018b> CRC-32 <c6e340bf> -- c-mmap-testfile

I thought
             os.fsync(f.fileno())
does the trick because it does it in C (hi, Charles-Francois),
but no.
So what do i come up with?
Nothing.  A quick look into 11277.mmap.c will show you this:

    /* *Final* sizes (string written after lseek(2): "abcd") */
...
        /* Tested good */
        //0x100000000 - PAGESIZE - 5,
        //0x100000000 - 4,
        //0x100000000 - 3,
        //0x100000000 - 1,
        0x100000000 + PAGESIZE + 4,
        //0x100000000 + PAGESIZE + 5,
        /* Tested bad */
        //0x100000000,
        //0x100000000 + PAGESIZE,
        //0x100000000 + PAGESIZE + 1,
        //0x100000000 + PAGESIZE + 3,

Hm!
Now i have to go but maybe i can do some more testing tomorrow to
answer the question why test_zlib.py fails even though there is
the fsync() and even though the values work in C.
Any comments?

----------
Added file: http://bugs.python.org/file21671/11277.1.diff
Added file: http://bugs.python.org/file21672/11277.mmap.c
Added file: http://bugs.python.org/file21673/11277.zsum32.c

_______________________________________
Python tracker <rep...@bugs.python.org>
<http://bugs.python.org/issue11277>
_______________________________________
diff --git a/Lib/test/test_zlib.py b/Lib/test/test_zlib.py
--- a/Lib/test/test_zlib.py
+++ b/Lib/test/test_zlib.py
@@ -3,6 +3,7 @@
 import binascii
 import random
 import sys
+import os
 from test.support import precisionbigmemtest, _1G, _4G
 
 zlib = support.import_module('zlib')
@@ -68,9 +69,10 @@
 
     def setUp(self):
         with open(support.TESTFN, "wb+") as f:
-            f.seek(_4G)
-            f.write(b"asdf")
-        with open(support.TESTFN, "rb") as f:
+            f.seek(_4G + mmap.PAGESIZE)
+            f.write(b"abcd")
+            f.flush()
+            os.fsync(f.fileno())
             self.mapping = mmap.mmap(f.fileno(), 0, access=mmap.ACCESS_READ)
 
     def tearDown(self):
@@ -82,9 +84,8 @@
     @unittest.skipUnless(support.is_resource_enabled("largefile"),
                          "May use lots of disk space.")
     def test_big_buffer(self):
-        self.assertEqual(zlib.crc32(self.mapping), 3058686908)
-        self.assertEqual(zlib.adler32(self.mapping), 82837919)
-
+        self.assertEqual(zlib.crc32(self.mapping), 0xc6e340bf)
+        self.assertEqual(zlib.adler32(self.mapping), 0x14b9018b)
 
 class ExceptionTestCase(unittest.TestCase):
     # make sure we generate some expected errors
#include <errno.h>
#include <signal.h>
#include <stdio.h>
#include <string.h>

#include <fcntl.h>
#include <unistd.h>

#include <sys/mman.h>
#include <sys/stat.h>
#include <sys/types.h>
#include <sys/uio.h>

#define PATH        "c-mmap-testfile"
#define PAGESIZE    4096

static void sighdl(int);

static void
sighdl(int signo)
{
    const char errmsg[] = "\nSignal occurred, cleaning up\n";
    (void)signo;
    (void)signal(SIGSEGV, SIG_DFL);
    (void)signal(SIGBUS, SIG_DFL);
    write(2, errmsg, sizeof(errmsg)-1);
    (void)unlink(PATH);
    return;
}

int
main(void) {
    int fd, estat = 0;
    void *addr;
    auto struct stat s;
    /* *Final* sizes (string written after lseek(2): "abcd") */
    const size_t *ct, tests[] = {
        /* Tested good */
        //0x100000000 - PAGESIZE - 5,
        //0x100000000 - 4,
        //0x100000000 - 3,
        //0x100000000 - 1,
        0x100000000 + PAGESIZE + 4,
        //0x100000000 + PAGESIZE + 5,
        /* Tested bad */
        //0x100000000,
        //0x100000000 + PAGESIZE,
        //0x100000000 + PAGESIZE + 1,
        //0x100000000 + PAGESIZE + 3,
        0
    };

    if (signal(SIGSEGV, &sighdl) == SIG_ERR)
        goto jerror;
    if (signal(SIGBUS, &sighdl) == SIG_ERR)
        goto jerror;

    for (ct = tests; *ct != 0; ++ct) {
        fprintf(stderr, "Size %lu/0x%lX: open", *ct, *ct);
        fd = open(PATH, O_RDWR|O_TRUNC|O_CREAT, 0666);
        if (fd < 0)
            goto jerror;
        fprintf(stderr, ". ");

        fprintf(stderr, "lseek");
        if (lseek(fd, *ct-4, SEEK_END) < 0)
            goto jerror;
        fprintf(stderr, ". ");

        fprintf(stderr, "write");
        if (write(fd, "abcd", 4) != 4)
            goto jerror;
        fprintf(stderr, ". ");

        fprintf(stderr, "fsync");
        if (fsync(fd) != 0)
            goto jerror;
        fprintf(stderr, ". ");

        fprintf(stderr, "fstat");
        if (fstat(fd, &s) != 0)
            goto jerror;
        fprintf(stderr, ". ");

        if (*ct != (size_t)s.st_size) {
            fprintf(stderr, "fstat size mismatch: %lu is not %lu\n",
                    (size_t)s.st_size, *ct);
            continue;
        }

        fprintf(stderr, "mmap");
        addr = mmap(NULL, s.st_size, PROT_READ, MAP_PRIVATE, fd, 0);
        if (addr == NULL)
            goto jerror;
        fprintf(stderr, ". ");

        (void)close(fd);

        fprintf(stderr, "[0]");
        if (((char*)addr)[0] != '\0')
            goto jerror;
        fprintf(stderr, ". ");

        fprintf(stderr, "[s.st_size-4]");
        if (((char*)addr)[s.st_size-4] != 'a')
            goto jerror;
        fprintf(stderr, ". ");

        fprintf(stderr, "munmap");
        if (munmap(addr, s.st_size) != 0)
            goto jerror;
        fprintf(stderr, ".");

        fprintf(stderr, "\n");
    }

jleave:
    (void)unlink(PATH);
    return estat;

jerror:
    fprintf(stderr, "\n%s\n", strerror(errno));
    estat = 1;
    goto jleave;
}
/* POSIX crc32/adler32 checksum program; requires zlib (a.k.a. libz)
 * Compile:    cc -o zsum32 zsum32.c -lz
 */

#include <zlib.h>

#include <errno.h>
#include <stdio.h>
#include <string.h>

#define BUFSIZE     (8192*4)

int
main(int argc, char **argv) {
    int estat = 0, erri = 0;
    FILE *f;
    uLong adler, crc;
    const char *errs = NULL;
    auto char buffer[BUFSIZE];

    if (argc != 2) {
        erri = EINVAL;
        errs = "Usage zsum32 FILE";
        goto jerror_noc;
    }
    ++argv;

    f = fopen(*argv, "rb");
    if (f == NULL) {
        erri = errno;
        errs = "fopen()ing the file failed";
        goto jerror_noc;
    }

    adler = adler32(0L, Z_NULL, 0);
    crc = 0;
    for (;;) {
        size_t rb = fread(buffer, 1, BUFSIZE, f);
        if (rb > 0) {
            adler = adler32(adler, (const Bytef*)buffer, (uInt)rb);
            crc = crc32(crc, (const Bytef*)buffer, (uInt)rb);
            continue;
        }
        if (feof(f))
            break;
        erri = errno;
        errs = "fread()ing the file failed";
        goto jerror;
    }
    printf("Adler-32 <%lx> CRC-32 <%lx> -- %s\n",
           (unsigned long)adler, (unsigned long)crc, *argv);

    (void)fclose(f);
jleave:
    return estat;

jerror:
    (void)fclose(f);
jerror_noc:
    fprintf(stderr, "%s: %s\n", errs, strerror(erri));
    estat = 1;
    goto jleave;
}
_______________________________________________
Python-bugs-list mailing list
Unsubscribe: 
http://mail.python.org/mailman/options/python-bugs-list/archive%40mail-archive.com

Reply via email to