stop using mmap for zip I/O
Dmitry Samersoff
dmitry.samersoff at oracle.com
Tue Mar 3 11:41:54 UTC 2015
Christos,
JVM install it's own signal handler and use it to numerous tasks, so add
signal handler to zip_util.c is problematic.
The simplest way to address the problem is use mlock/munlock to test
page presence before touching it.
i.e. add code like
if ((i % 4096) == 0) {
if ( mlock(v+i, 4096) < 0) {
printf("No page. Bail out\n");
return;
}
}
to *compute()* in your example below.
-Dmitry
On 2015-02-27 01:17, christos at zoulas.com wrote:
> Hi,
>
> There are numerous bug reports about the jvm crashing in libzip...
> Just google for "libzip java crash". The bottom line is that using
> mmap is problematic (I can get into more per OS details if necessary)
> because it will potentially signal when the file size is altered.
> Can we please turn USE_MMAP off, and/or remove the code (zip_util.c)?
> I don't think it is acceptable for the jvm to crash if it tries to
> read a file while it is being modified. The following simple program
> demonstrates the issue... just:
>
> $ cc mmap.c
> $ cp a.out b.out
> $ ./a.out b.out
>
> Best,
>
> christos
>
> $ cat << _EOF > mmap.c
> #include <stdio.h>
> #include <stdlib.h>
> #include <unistd.h>
> #include <fcntl.h>
> #include <err.h>
> #include <signal.h>
>
> #include <sys/mman.h>
> #include <sys/stat.h>
>
> volatile size_t i;
> size_t size = 0;
>
> void
> sig(int s)
> {
> printf("boom %d %zu\n", s, i);
> exit(1);
> }
>
> void
> compute(unsigned char *v)
> {
> int j = 0;
> for (i = 0; i < size; i++)
> j += v[i];
> printf("%d\n", j);
> }
>
> int
> main(int argc, char *argv[])
> {
> struct stat st;
> unsigned char *v;
> int fd;
>
> signal(SIGSEGV, sig);
> signal(SIGBUS, sig);
> fd = open(argv[1], O_RDONLY);
> if (fd == -1)
> err(1, "open %s", argv[1]);
>
> if (fstat(fd, &st) == -1)
> err(1, "fstat %s", argv[1]);
> size = st.st_size;
> if (size == 0)
> errx(1, "0 sized file");
>
> v = mmap(0, size, PROT_READ, MAP_FILE | MAP_PRIVATE, fd, 0);
> if (v == MAP_FAILED)
> err(1, "mmap");
>
> printf("go1\n");
> compute(v);
> truncate(argv[1], 0);
> printf("go2\n");
> compute(v);
> return 0;
> }
> _EOF
>
--
Dmitry Samersoff
Oracle Java development team, Saint Petersburg, Russia
* I would love to change the world, but they won't give me the sources.
More information about the core-libs-dev
mailing list