Skip to content

Loading jnidispatch on Android 15 with 16 KB page size leads to crash #1618

Closed

Description

@lisa-bella97
  1. Version of JNA and related jars
    5.14.0@aar
  2. Version and vendor of the java virtual machine
    ART, Android 15
    System.getProperty("java.vm.version") = "2.1.0"
  3. Operating system
    Android 15 with 16 KB page size
  4. System architecture (CPU type, bitness of the JVM)
    arm64-v8a
  5. Complete description of the problem
    Loading jnidispatch using System.loadLibrary("jnidispatch") is OK on Android 15 or less with 4 KB page size, but is not OK (leads to SIGSEGV crash) on Android 15 with 16 KB page size (support of this page size in Android 15 is described in docs).
    System.loadLibrary("jnidispatch") is called on Android platform in loadNativeDispatchLibrary function that is called in static block of JNA class Native, so you cannot properly use, for example, Native.load function on Android 15 with 16 KB page size.
    To test this behaviour, corresponding Android Studio emulators were used. Info about emulator:
    Emulator version: 35.1.13-11943732 (HVF 14.5.0)
    Host machine: macOS 14.5
    Api level: 35
    Type: Google APIs PlayStore Page Size 16 KB
  6. Steps to reproduce
    You can find minimal sample here. Launching this app on Android 15, 16-KB-based emulator will lead to SIGSEGV crash, full log with dump.

Activity

  1. pgarba commented on Oct 10, 2024

    @pgarba

    Yes, this one is critical. Would be great if you could fix it in the upcoming release

  2. dbwiddis commented on Oct 10, 2024

    @dbwiddis
    Contributor

    Looks like there are page size assumptions in the native code that are used when compiling:

    #ifndef malloc_getpagesize
    # ifdef _SC_PAGESIZE /* some SVR4 systems omit an underscore */
    # ifndef _SC_PAGE_SIZE
    # define _SC_PAGE_SIZE _SC_PAGESIZE
    # endif
    # endif
    # ifdef _SC_PAGE_SIZE
    # define malloc_getpagesize sysconf(_SC_PAGE_SIZE)
    # else
    # if defined(BSD) || defined(DGUX) || defined(HAVE_GETPAGESIZE)
    extern size_t getpagesize();
    # define malloc_getpagesize getpagesize()
    # else
    # ifdef WIN32 /* use supplied emulation of getpagesize */
    # define malloc_getpagesize getpagesize()
    # else
    # ifndef LACKS_SYS_PARAM_H
    # include <sys/param.h>
    # endif
    # ifdef EXEC_PAGESIZE
    # define malloc_getpagesize EXEC_PAGESIZE
    # else
    # ifdef NBPG
    # ifndef CLSIZE
    # define malloc_getpagesize NBPG
    # else
    # define malloc_getpagesize (NBPG * CLSIZE)
    # endif
    # else
    # ifdef NBPC
    # define malloc_getpagesize NBPC
    # else
    # ifdef PAGESIZE
    # define malloc_getpagesize PAGESIZE
    # else /* just guess */
    # define malloc_getpagesize ((size_t)4096U)
    # endif
    # endif
    # endif
    # endif
    # endif
    # endif
    # endif
    #endif

    I assume the native library version with the distribution was likely compiled on a smaller page size. Can you compile the native library on the system with the higher page size and does it resolve the problem?

  3. pgarba commented on Oct 10, 2024

    @pgarba

    Based on Googles recommendations the code should be updated;

    Check for code instances that reference specific page sizes

    Even if your app is 16 KB-aligned, your app can encounter errors if places in your code assume that a device is using a specific page size. To avoid this, complete the following steps:
    
        Remove any hard-coded dependencies that reference the [PAGE_SIZE](https://cs.android.com/android/platform/superproject/main/+/main:bionic/libc/include/bits/page_size.h;l=34-39) constant or instances in your code logic that assume that a device's page size is 4 KB (4096).
    
        Use [getpagesize()](https://cs.android.com/android/platform/superproject/main/+/main:bionic/libc/bionic/getpagesize.cpp;l=32) or [sysconf(_SC_PAGESIZE)](https://cs.android.com/android/platform/superproject/main/+/main:bionic/libc/bionic/sysconf.cpp;l=151) instead.
    
  4. matthiasblaesing commented on Oct 14, 2024

    @matthiasblaesing
    Member

    @pgarba could you please test if this helps:

    matthias@enterprise:~/src/jnalib$ git diff                                                                                                                                                                                                                 
    diff --git a/native/Makefile b/native/Makefile
    index 9bafc4c032..3dafe4bdb1 100644
    --- a/native/Makefile
    +++ b/native/Makefile
    @@ -175,7 +175,7 @@ CPP=$(PREFIX)cpp
     LD=$(CC)
     RANLIB=$(PREFIX)ranlib
     STRIP=$(PREFIX)strip -x
    -CDEFINES=-DFFI_STATIC_BUILD -DNO_JAWT -DNO_WEAK_GLOBALS -DFFI_MMAP_EXEC_WRIT=1 -DFFI_MMAP_EXEC_SELINUX=0
    +CDEFINES=-DFFI_STATIC_BUILD -DNO_JAWT -DNO_WEAK_GLOBALS -DFFI_MMAP_EXEC_WRIT=1 -DFFI_MMAP_EXEC_SELINUX=0 -Dmalloc_getpagesize='getpagesize()'
     COPT+=-fpic -ffunction-sections -funwind-tables -fno-short-enums
     JAVA_INCLUDES=
     CINCLUDES+=-I"$(NDK_PLATFORM)/arch-$(AARCH)/usr/include" # -I/usr/include
    matthias@enterprise:~/src/jnalib$

    The idea follows @dbwiddis observation where the hardcoded pagesize is used.

  5. mugz3m commented on Oct 25, 2024

    @mugz3m

    Hi,

    I'm facing the same problem and tried to fix JNA by making the changes suggested by @matthiasblaesing, but unfortunately, it didn’t help. After making the changes, I built jna.aar, added it to @lisa-bella97's app, and encountered the same crash again: https://gist.github.com/mugz3m/634707842dfa4a2f4b3a245714140dbe.

    Could it be that I built the library incorrectly? I followed the Build Environment wiki and created artifacts by simply invoking ant native dist.

  6. Thomyrock commented on Nov 12, 2024

    @Thomyrock

    Hello,
    It seems that the cause of the issue is actually the 16KB ELF alignment. I built JNA with the following patch and tried it on @lisa-bella97's app, which now appears to be working fine:

    diff --git a/native/Makefile b/native/Makefile
    index 49240421e..bb89169a2 100644
    --- a/native/Makefile
    +++ b/native/Makefile
    @@ -181,7 +181,7 @@ COPT+=-fpic -ffunction-sections -funwind-tables -fno-short-enums
     JAVA_INCLUDES=
     CINCLUDES+=-I"$(NDK_PLATFORM)/arch-$(AARCH)/usr/include" # -I/usr/include
     LIBS=-nostdlib -L"$(NDK_PLATFORM)/arch-$(AARCH)$(ALIBDIR)/" -lgcc -lc -ldl -lm
    -LDFLAGS+=-Wl,-shared,-Bsymbolic -Wl,--build-id=sha1
    +LDFLAGS+=-Wl,-shared,-Bsymbolic -Wl,--build-id=sha1 -Wl,-z,max-page-size=16384
     FFI_ENV=CPP="$(CPP)" CC="$(CC)" CFLAGS="$(COPT) $(CDEBUG) $(CINCLUDES)" CPPFLAGS="$(CDEFINES) $(CINCLUDES)" LIBS="$(LIBS)" RANLIB="$(RANLIB)"
     FFI_CONFIG=--enable-static --disable-shared --with-pic=yes --host=$(HOST)
     endif
  7. rvandermeulen commented on Dec 5, 2024

    @rvandermeulen

    Are there plans to ship a 5.16.0 release with this change so apps depending on JNA can complete their own 16KB page size migrations?

  8. matthiasblaesing commented on Dec 8, 2024

    @matthiasblaesing
    Member

    @Thomyrock this indeed makes sense. Do you want to create a PR with this change (and an entry to the CHANGES.md or shall I go ahead?

  9. Thomyrock commented on Dec 17, 2024

    @Thomyrock

    Should be fixed by #1642

  10. rvandermeulen commented on Dec 17, 2024

    @rvandermeulen

    Thanks! Is there an ETA on when the next release will ship with that fix?

  11. matthiasblaesing commented on Dec 21, 2024

    @matthiasblaesing
    Member

    Fair question. I'll see if I manage to get a release out tomorrow.

  12. matthiasblaesing commented on Dec 22, 2024

    @matthiasblaesing
    Member
  13. rvandermeulen commented on Dec 22, 2024

    @rvandermeulen
  14. matthiasblaesing commented on Dec 30, 2024

    @matthiasblaesing
    Member

    For anyone not aware yet, in #1647 there is a claim, that the change introduced by #1640 were not enough. On x86-64 16kB pages seem to work in emulator, but it is claimed, that the build fails on aarch64 with 16kB pages.

    Anyone interested is invited to have a look at the problem.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type

    Projects

    No projects

      Milestone

      No milestone

      Relationships

      None yet

      Development

      No branches or pull requests

      Issue actions