(Copied from jna-users forum post on 2015-12-23, https://groups.google.com/forum/#!topic/jna-users/dCPnztnQnRw.)
I compiled JNA myself, and when I ran the test suite, the testLongStringGeneration(com.sun.jna.NativeTest) test sometimes failed with a "Invalid memory access" error indicating a JVM segfault. Here's what it looks like running JUnit from the command-line:
C:\rprichard\work\jna>c:\java\jdk1.8.0_60\bin\java -cp "build/jna.jar;build/jna-test.jar;lib/junit.jar;lib/hamcrest-core-1.3.jar" org.junit.runner.JUnitCore com.sun.jna.NativeTest
JUnit version 4.11
............E..E........JNA Warning: Encoding 'unsupported' is unsupported
JNA Warning: Encoding with fallback Cp1252
.......E
Time: 0.374
There were 3 failures:
1) testSynchronizedAccess(com.sun.jna.NativeTest)
java.lang.UnsatisfiedLinkError: Unable to load library 'testlib': Native library (win32-x86/testlib.dll) not found in re
source path ([file:/C:/rprichard/work/jna/build/jna.jar, file:/C:/rprichard/work/jna/build/jna-test.jar, file:/C:/rprich
ard/work/jna/lib/junit.jar, file:/C:/rprichard/work/jna/lib/hamcrest-core-1.3.jar])
... elided ... (test setup issue)
2) testOptionsInferenceFromInstanceField(com.sun.jna.NativeTest)
java.lang.UnsatisfiedLinkError: Unable to load library 'testlib': Native library (win32-x86/testlib.dll) not found in re
source path ([file:/C:/rprichard/work/jna/build/jna.jar, file:/C:/rprichard/work/jna/build/jna-test.jar, file:/C:/rprich
ard/work/jna/lib/junit.jar, file:/C:/rprichard/work/jna/lib/hamcrest-core-1.3.jar])
... elided ... (test setup issue)
3) testLongStringGeneration(com.sun.jna.NativeTest)
java.lang.Error: Invalid memory access
at com.sun.jna.Native.getWideString(Native Method)
at com.sun.jna.Pointer.getWideString(Pointer.java:696)
at com.sun.jna.Memory.getWideString(Memory.java:561)
at com.sun.jna.NativeTest.testLongStringGeneration(NativeTest.java:77)
at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:62)
at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
at java.lang.reflect.Method.invoke(Method.java:497)
at junit.framework.TestCase.runTest(TestCase.java:176)
at junit.framework.TestCase.runBare(TestCase.java:141)
at junit.framework.TestResult$1.protect(TestResult.java:122)
at junit.framework.TestResult.runProtected(TestResult.java:142)
at junit.framework.TestResult.run(TestResult.java:125)
at junit.framework.TestCase.run(TestCase.java:129)
at junit.framework.TestSuite.runTest(TestSuite.java:255)
at junit.framework.TestSuite.run(TestSuite.java:250)
at org.junit.internal.runners.JUnit38ClassRunner.run(JUnit38ClassRunner.java:84)
at org.junit.runners.Suite.runChild(Suite.java:127)
at org.junit.runners.Suite.runChild(Suite.java:26)
at org.junit.runners.ParentRunner$3.run(ParentRunner.java:238)
at org.junit.runners.ParentRunner$1.schedule(ParentRunner.java:63)
at org.junit.runners.ParentRunner.runChildren(ParentRunner.java:236)
at org.junit.runners.ParentRunner.access$000(ParentRunner.java:53)
at org.junit.runners.ParentRunner$2.evaluate(ParentRunner.java:229)
at org.junit.runners.ParentRunner.run(ParentRunner.java:309)
at org.junit.runner.JUnitCore.run(JUnitCore.java:160)
at org.junit.runner.JUnitCore.run(JUnitCore.java:138)
at org.junit.runner.JUnitCore.run(JUnitCore.java:117)
at org.junit.runner.JUnitCore.runMain(JUnitCore.java:96)
at org.junit.runner.JUnitCore.runMainAndExit(JUnitCore.java:47)
at org.junit.runner.JUnitCore.main(JUnitCore.java:40)
FAILURES!!!
Tests run: 29, Failures: 3
I'm using 32-bit Windows 7 SP1, with jdk1.8.0_60.
I worked on the test a bit, and came up with this standalone test program that segfaults using the official JNA 4.2.1 JAR.
package com.example;
import com.sun.jna.Memory;
import com.sun.jna.Native;
public class JnaTest {
public static void main(String[] args) {
// This code below is reduced from a different test. (I forget which.)
new Memory(4);
// The code below comes from NativeTest.testLongStringGeneration.
StringBuilder buf = new StringBuilder();
final int MAX = 2000000;
for (int i=0;i < MAX;i++) {
buf.append('a');
}
String s1 = buf.toString();
Memory m = new Memory((MAX + 1)*Native.WCHAR_SIZE);
m.setWideString(0, s1);
m.getWideString(0);
}
}
C:\rprichard\proj\JnaTest>c:\Java\jdk1.8.0_60\bin\java.exe -cp build\classes\main;lib\jna-4.2.1.jar com.example.JnaTest
Exception in thread "main" java.lang.Error: Invalid memory access
at com.sun.jna.Native.getWideString(Native Method)
at com.sun.jna.Pointer.getWideString(Pointer.java:696)
at com.sun.jna.Memory.getWideString(Memory.java:561)
at com.example.JnaTest.main(JnaTest.java:19)
With lots of printf debugging, I think I identified the cause. The final m.getWideString call ultimately calls Java_com_sun_jna_Native_getWideString. Once the JVM reaches this native function, there are no live references remaining to the Memory object. newJavaString calls back into the JVM, ((*env)->NewString), to create the 2MB String object, at which point the JVM finalizes the Memory object, which frees the buffer. The JVM then attempts to read from the freed buffer and segfaults.
(Copied from jna-users forum post on 2015-12-23, https://groups.google.com/forum/#!topic/jna-users/dCPnztnQnRw.)
I compiled JNA myself, and when I ran the test suite, the
testLongStringGeneration(com.sun.jna.NativeTest)test sometimes failed with a "Invalid memory access" error indicating a JVM segfault. Here's what it looks like running JUnit from the command-line:I'm using 32-bit Windows 7 SP1, with jdk1.8.0_60.
I worked on the test a bit, and came up with this standalone test program that segfaults using the official JNA 4.2.1 JAR.
With lots of printf debugging, I think I identified the cause. The final
m.getWideStringcall ultimately callsJava_com_sun_jna_Native_getWideString. Once the JVM reaches this native function, there are no live references remaining to theMemoryobject.newJavaStringcalls back into the JVM,((*env)->NewString), to create the 2MB String object, at which point the JVM finalizes the Memory object, which frees the buffer. The JVM then attempts to read from the freed buffer and segfaults.