diff --git a/CHANGES.md b/CHANGES.md index c21d491ccf..60f65abcc9 100644 --- a/CHANGES.md +++ b/CHANGES.md @@ -12,6 +12,7 @@ Bug Fixes --------- * [#925](https://github.com/java-native-access/jna/issues/925): Optimize `Structure#validate` and prevent `ArrayIndexOutOfBoundsException` in `SAFEARRAY#read` for zero dimensions - [@matthiasblaesing](https://github.com/matthiasblaesing). * [#958](https://github.com/java-native-access/jna/issues/958): Update for PR 863: Old toolchains produce binaries without hard-/softfloat markers. Rasbian is missinng the markers and the oracle JDK is also affected. For hardfloat detection now also the Arm EABI section is also considered - [@matthiasblaesing](https://github.com/matthiasblaesing). +* [#974](https://github.com/java-native-access/jna/issues/974): If the callback code failed to attach to the JVM, this lead to a segfault. The success of attaching to the JVM was checked to late and an invalid `JNIEnv` pointer was used to access the JVM - [@matthiasblaesing](https://github.com/matthiasblaesing). Release 4.5.1 ============= diff --git a/build.xml b/build.xml index d6b612e9a2..f763f02ec1 100644 --- a/build.xml +++ b/build.xml @@ -69,7 +69,7 @@ - + diff --git a/lib/native/aix-ppc.jar b/lib/native/aix-ppc.jar index f6be141f54..d59e910edc 100644 Binary files a/lib/native/aix-ppc.jar and b/lib/native/aix-ppc.jar differ diff --git a/lib/native/aix-ppc64.jar b/lib/native/aix-ppc64.jar index 01a378bdb1..4995ce9cba 100644 Binary files a/lib/native/aix-ppc64.jar and b/lib/native/aix-ppc64.jar differ diff --git a/lib/native/android-aarch64.jar b/lib/native/android-aarch64.jar index 83438eaa14..96c2d9f570 100644 Binary files a/lib/native/android-aarch64.jar and b/lib/native/android-aarch64.jar differ diff --git a/lib/native/android-arm.jar b/lib/native/android-arm.jar index d78f1611e2..20d21ae5a9 100755 Binary files a/lib/native/android-arm.jar and b/lib/native/android-arm.jar differ diff --git a/lib/native/android-armv7.jar b/lib/native/android-armv7.jar index ad98394186..8f537179ac 100644 Binary files a/lib/native/android-armv7.jar and b/lib/native/android-armv7.jar differ diff --git a/lib/native/android-mips.jar b/lib/native/android-mips.jar index 7fd7ee799f..5b20b67f20 100644 Binary files a/lib/native/android-mips.jar and b/lib/native/android-mips.jar differ diff --git a/lib/native/android-mips64.jar b/lib/native/android-mips64.jar index 6b2b561cea..2cafc732aa 100644 Binary files a/lib/native/android-mips64.jar and b/lib/native/android-mips64.jar differ diff --git a/lib/native/android-x86-64.jar b/lib/native/android-x86-64.jar index dbc1c7f09c..0e715a4947 100644 Binary files a/lib/native/android-x86-64.jar and b/lib/native/android-x86-64.jar differ diff --git a/lib/native/android-x86.jar b/lib/native/android-x86.jar index 5ebf1f0a7c..c3d802fc4b 100755 Binary files a/lib/native/android-x86.jar and b/lib/native/android-x86.jar differ diff --git a/lib/native/darwin.jar b/lib/native/darwin.jar index d8c06c21b2..77a2d35cb2 100644 Binary files a/lib/native/darwin.jar and b/lib/native/darwin.jar differ diff --git a/lib/native/freebsd-x86-64.jar b/lib/native/freebsd-x86-64.jar index c58184476c..9f2a2cca09 100755 Binary files a/lib/native/freebsd-x86-64.jar and b/lib/native/freebsd-x86-64.jar differ diff --git a/lib/native/freebsd-x86.jar b/lib/native/freebsd-x86.jar index b04bbb0b97..eb5f0daa02 100755 Binary files a/lib/native/freebsd-x86.jar and b/lib/native/freebsd-x86.jar differ diff --git a/lib/native/linux-aarch64.jar b/lib/native/linux-aarch64.jar index 3cf08eb1eb..cb84490565 100644 Binary files a/lib/native/linux-aarch64.jar and b/lib/native/linux-aarch64.jar differ diff --git a/lib/native/linux-arm.jar b/lib/native/linux-arm.jar index 6dd1afbb47..5afdd38512 100755 Binary files a/lib/native/linux-arm.jar and b/lib/native/linux-arm.jar differ diff --git a/lib/native/linux-armel.jar b/lib/native/linux-armel.jar index 70d9b1ab35..174bf98f77 100644 Binary files a/lib/native/linux-armel.jar and b/lib/native/linux-armel.jar differ diff --git a/lib/native/linux-mips64el.jar b/lib/native/linux-mips64el.jar index 9202631078..deb0b92ffd 100644 Binary files a/lib/native/linux-mips64el.jar and b/lib/native/linux-mips64el.jar differ diff --git a/lib/native/linux-ppc.jar b/lib/native/linux-ppc.jar index c6890dc78c..5667f59c91 100755 Binary files a/lib/native/linux-ppc.jar and b/lib/native/linux-ppc.jar differ diff --git a/lib/native/linux-ppc64le.jar b/lib/native/linux-ppc64le.jar index 2201978865..ae4d3f5561 100644 Binary files a/lib/native/linux-ppc64le.jar and b/lib/native/linux-ppc64le.jar differ diff --git a/lib/native/linux-s390x.jar b/lib/native/linux-s390x.jar index 1b4d6fa78f..102fc5044d 100644 Binary files a/lib/native/linux-s390x.jar and b/lib/native/linux-s390x.jar differ diff --git a/lib/native/linux-x86-64.jar b/lib/native/linux-x86-64.jar index a4ec3c1660..b99f49fc6e 100644 Binary files a/lib/native/linux-x86-64.jar and b/lib/native/linux-x86-64.jar differ diff --git a/lib/native/linux-x86.jar b/lib/native/linux-x86.jar index 58296a8a88..4dc786fca5 100755 Binary files a/lib/native/linux-x86.jar and b/lib/native/linux-x86.jar differ diff --git a/lib/native/openbsd-x86-64.jar b/lib/native/openbsd-x86-64.jar index 414bcbbd9b..ddd6d316fc 100755 Binary files a/lib/native/openbsd-x86-64.jar and b/lib/native/openbsd-x86-64.jar differ diff --git a/lib/native/openbsd-x86.jar b/lib/native/openbsd-x86.jar index 0e6226e5ea..e9d7a289b8 100755 Binary files a/lib/native/openbsd-x86.jar and b/lib/native/openbsd-x86.jar differ diff --git a/lib/native/sunos-sparc.jar b/lib/native/sunos-sparc.jar index 71c510e17e..5798c7f213 100644 Binary files a/lib/native/sunos-sparc.jar and b/lib/native/sunos-sparc.jar differ diff --git a/lib/native/sunos-sparcv9.jar b/lib/native/sunos-sparcv9.jar index 4b6303ca8b..e508bf8e7e 100755 Binary files a/lib/native/sunos-sparcv9.jar and b/lib/native/sunos-sparcv9.jar differ diff --git a/lib/native/sunos-x86-64.jar b/lib/native/sunos-x86-64.jar index e995162bb7..ac43ba891b 100755 Binary files a/lib/native/sunos-x86-64.jar and b/lib/native/sunos-x86-64.jar differ diff --git a/lib/native/sunos-x86.jar b/lib/native/sunos-x86.jar index 761f7fa3e1..80e811f3e5 100755 Binary files a/lib/native/sunos-x86.jar and b/lib/native/sunos-x86.jar differ diff --git a/lib/native/win32-x86-64.jar b/lib/native/win32-x86-64.jar index 04acb3ada5..626cd95e9c 100755 Binary files a/lib/native/win32-x86-64.jar and b/lib/native/win32-x86-64.jar differ diff --git a/lib/native/win32-x86.jar b/lib/native/win32-x86.jar index c9b508f6bd..c00f625eb4 100644 Binary files a/lib/native/win32-x86.jar and b/lib/native/win32-x86.jar differ diff --git a/native/callback.c b/native/callback.c index 52c6165213..2bbedf00d2 100644 --- a/native/callback.c +++ b/native/callback.c @@ -686,6 +686,14 @@ dispatch_callback(ffi_cif* cif, void* resp, void** cbargs, void* user_data) { else { attach_status = (*jvm)->AttachCurrentThread(jvm, (void *)&env, &args); } + if (attach_status != JNI_OK) { + free((void *)args.name); + if (args.group) { + (*env)->DeleteWeakGlobalRef(env, args.group); + } + fprintf(stderr, "JNA: Can't attach native thread to VM for callback: %d (check stacksize for callbacks)\n", attach_status); + return; + } tls = get_thread_storage(env); if (tls) { snprintf(tls->name, sizeof(tls->name), "%s", args.name ? args.name : ""); @@ -694,15 +702,11 @@ dispatch_callback(ffi_cif* cif, void* resp, void** cbargs, void* user_data) { } // Dispose of allocated memory free((void *)args.name); - if (attach_status != JNI_OK) { - fprintf(stderr, "JNA: Can't attach native thread to VM for callback: %d\n", attach_status); - return; - } if (args.group) { (*env)->DeleteWeakGlobalRef(env, args.group); } } - + if (!tls) { fprintf(stderr, "JNA: couldn't obtain thread-local storage\n"); return; diff --git a/native/testlib.c b/native/testlib.c index 4c8387f3c1..575cf010ae 100644 --- a/native/testlib.c +++ b/native/testlib.c @@ -54,7 +54,7 @@ typedef __int64 int64_t; #define EXPORT __declspec(dllexport) #define SLEEP(MS) Sleep(MS) #define THREAD_T DWORD -#define THREAD_CREATE(TP, FN, DATA) CreateThread(NULL, 0, FN, DATA, 0, TP) +#define THREAD_CREATE(TP, FN, DATA, STACKSIZE) CreateThread(NULL, STACKSIZE, FN, DATA, 0, TP) #define THREAD_EXIT() ExitThread(0) #define THREAD_FUNC(FN,ARG) DWORD WINAPI FN(LPVOID ARG) #define THREAD_CURRENT() GetCurrentThreadId() @@ -69,7 +69,15 @@ typedef __int64 int64_t; #include #define SLEEP(MS) usleep(MS*1000) #define THREAD_T pthread_t -#define THREAD_CREATE(TP, FN, DATA) pthread_create(TP, NULL, FN, DATA) +#define THREAD_CREATE(TP, FN, DATA, STACKSIZE) {\ + pthread_attr_t attr;\ + pthread_attr_init(&attr);\ + if (STACKSIZE > 0) {\ + pthread_attr_setstacksize(&attr, STACKSIZE);\ + }\ + pthread_create(TP, &attr, FN, DATA);\ + pthread_attr_destroy(&attr);\ +} #define THREAD_EXIT() pthread_exit(NULL) #define THREAD_FUNC(FN,ARG) void* FN(void *ARG) #define THREAD_RETURN return NULL @@ -676,7 +684,7 @@ static THREAD_FUNC(thread_function, arg) { } EXPORT void -callVoidCallbackThreaded(void (*func)(void), int n, int ms, const char* name) { +callVoidCallbackThreaded(void (*func)(void), int n, int ms, const char* name, int stacksize) { THREAD_T thread; thread_data* data = (thread_data*)malloc(sizeof(thread_data)); @@ -684,7 +692,7 @@ callVoidCallbackThreaded(void (*func)(void), int n, int ms, const char* name) { data->sleep_time = ms; data->func = func; snprintf(data->name, sizeof(data->name), "%s", name); - THREAD_CREATE(&thread, &thread_function, data); + THREAD_CREATE(&thread, &thread_function, data, stacksize); } EXPORT int diff --git a/test/com/sun/jna/CallbacksTest.java b/test/com/sun/jna/CallbacksTest.java index 230f81dfb1..39d7497477 100644 --- a/test/com/sun/jna/CallbacksTest.java +++ b/test/com/sun/jna/CallbacksTest.java @@ -127,7 +127,7 @@ interface VoidCallback extends Callback { void callback(); } void callVoidCallback(VoidCallback c); - void callVoidCallbackThreaded(VoidCallback c, int count, int ms, String name); + void callVoidCallbackThreaded(VoidCallback c, int count, int ms, String name, int stacksize); interface VoidCallbackCustom extends Callback { void customMethodName(); } @@ -1215,7 +1215,7 @@ protected void callThreadedCallback(TestLibrary.VoidCallback cb, if (cti != null) { Native.setCallbackThreadInitializer(cb, cti); } - lib.callVoidCallbackThreaded(cb, repeat, sleepms, getName()); + lib.callVoidCallbackThreaded(cb, repeat, sleepms, getName(), 0); long start = System.currentTimeMillis(); while (called[0] < returnAfter) { @@ -1304,6 +1304,25 @@ public void callback() { waitFor(t[0]); } + public void testSmallStackCallback() throws Exception { + // This test runs the callback in a thread, that is allocated a very + // small size. It was observed on linux amd64, that a library allocated + // a stack size of 64kB, this prevented the JVM to attach to that + // thread. The JNIEnv pointer was not checked and this lead to a + // hard crash of the JVM. + TestLibrary.VoidCallback cb = new TestLibrary.VoidCallback() { + @Override + public void callback() { + System.out.println("Callback called"); + } + }; + + lib.callVoidCallbackThreaded(cb, 1, 0, "Test Callback", 32 * 1024); + + // Give the JVM enough time to run the call back + Thread.sleep(1 * 1000); + } + // Detach preference is indicated by the initializer. Thread is attached // as daemon to avoid VM having to wait for it. public void testCallbackThreadPersistence() throws Exception { diff --git a/test/com/sun/jna/DirectCallbacksTest.java b/test/com/sun/jna/DirectCallbacksTest.java index d15e338e15..ec2d277690 100644 --- a/test/com/sun/jna/DirectCallbacksTest.java +++ b/test/com/sun/jna/DirectCallbacksTest.java @@ -73,7 +73,7 @@ public static class DirectTestLibrary implements TestLibrary { @Override public native void callVoidCallback(VoidCallback c); @Override - public native void callVoidCallbackThreaded(VoidCallback c, int count, int ms, String name); + public native void callVoidCallbackThreaded(VoidCallback c, int count, int ms, String name, int stacksize); @Override public native int callInt32Callback(CustomCallback cb, int arg1, int arg2);