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