Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

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

Open
lisa-bella97 opened this issue Aug 13, 2024 · 5 comments
Open

Comments

@lisa-bella97
Copy link

  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.
@pgarba
Copy link

pgarba commented Oct 10, 2024

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

@dbwiddis
Copy link
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?

@pgarba
Copy link

pgarba commented Oct 10, 2024

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.

@matthiasblaesing
Copy link
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.

@mugz3m
Copy link

mugz3m commented Oct 25, 2024

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.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

5 participants