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, chris...@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.

Reply via email to