https://gcc.gnu.org/bugzilla/show_bug.cgi?id=61675
Bug ID: 61675 Summary: Wrong code generation for 32-bit x86 with i686-w64-mingw32 Product: gcc Version: 4.6.3 Status: UNCONFIRMED Severity: normal Priority: P3 Component: c Assignee: unassigned at gcc dot gnu.org Reporter: oliverst at online dot de Created attachment 33051 --> https://gcc.gnu.org/bugzilla/attachment.cgi?id=33051&action=edit The preprocessed file using GCC 4.6.2 I have a JNI DLL, that crashes when using GetFieldID() on a class object, that was passed into a function. The library is working fine on Linux with 32-bit and 64-bit JVMs and only crashes when using 32-bit under Windows - 64-bit is fine. The original DLL was cross-compiled on ubuntu 13.10 x86_64 using MinGW-w64 GCC 4.6.3, but I also compiled it natively under Windows using MinGW-w64 GCC 4.6.3 and I still got the same crash. Using ubuntu 14.04 with MinGW-w64 4.8.2 still produces the same error. Using Visual Studio 2010 produces a working DLL, so I reckon this is a MinGW compiler bug. Compiling the code as C++ by using the J NI C++ interface didn't help either. It appears there is some memory corruption going on since when I use an unoptimized DLL the crash doesn't happen an the first call on GetFieldID(), but on a later one (the original DLL has way more code than the stripped down example below) or even after the function finished somewhere in the JVM garbage collection. The JVM I am using is Java 7u60, but I also tried it with 8u5 and got the same results. I tested it with the 32-bit JVM on a 64-bit and 32-bit systems as I came across an article, that said, that a 32-bit JVM might not be reliable on 64-bit Windows operating systems (sounded a bit bogus to me, but just to be sure). Also there are other JNI DLLs, that don't utilize GetFieldID() at all and they are working just fine with 32-bit. The crash data from the hs_err_pid.log Current thread (0x00d5e000): JavaThread "main" [_thread_in_native, id=1104, stack(0x00dd0000,0x00e20000)] siginfo: ExceptionCode=0xc0000005, ExceptionInformation=0x00000008 0x3462c9e8 Registers: EAX=0x00000000, EBX=0x00e1f1fc, ECX=0x97254d7c, EDX=0x00d5eac4 ESP=0x00e1f1dc, EBP=0x00e1f1ec, ESI=0x3462c6e8, EDI=0x00d5e000 EIP=0x3462c9e8, EFLAGS=0x00010246 Top of Stack: (sp=0x00e1f1dc) 0x00e1f1dc: 00000000 3462c6e8 00000000 00e1f1fc 0x00e1f1ec: 00e1f224 025f334f 246970c0 025f88c9 0x00e1f1fc: 24695668 2460b700 00e1f204 34628d1b 0x00e1f20c: 00e1f22c 34628ee8 00000000 34628d40 0x00e1f21c: 00e1f1fc 00e1f22c 00e1f25c 025f3207 0x00e1f22c: 24693760 24693760 00000001 24693758 0x00e1f23c: 00e1f234 34628c56 00e1f264 34628ee8 0x00e1f24c: 00000000 34628c88 00e1f22c 00e1f268 Instructions: (pc=0x3462c9e8) 0x3462c9c8: 78 bc 62 34 50 bb 62 34 c0 bd 62 34 30 bd 62 34 0x3462c9d8: 00 00 00 00 00 00 00 00 0c 00 00 00 02 00 00 00 0x3462c9e8: 01 00 00 00 60 f9 5f 39 02 00 00 00 a0 b9 62 34 0x3462c9f8: 0a 00 b8 00 10 d6 00 39 00 00 00 00 01 00 40 80 Register to memory mapping: EAX=0x00000000 is an unknown value EBX=0x00e1f1fc is pointing into the stack for thread: 0x00d5e000 ECX=0x97254d7c is an unknown value EDX=0x00d5eac4 is an unknown value ESP=0x00e1f1dc is pointing into the stack for thread: 0x00d5e000 EBP=0x00e1f1ec is pointing into the stack for thread: 0x00d5e000 ESI=0x3462c6e8 is an oop {method} - klass: {other class} EDI=0x00d5e000 is a thread Stack: [0x00dd0000,0x00e20000], sp=0x00e1f1dc, free space=316k Native frames: (J=compiled Java code, j=interpreted, Vv=VM code, C=native code) C 0x3462c9e8 j jnitest.JNIClass.<init>()V+27 j jnitest.JNIClass.getInstance()Ljnitest/JNIClass;+22 j jnitest.Program.main([Ljava/lang/String;)V+0 v ~StubRoutines::call_stub V [jvm.dll+0x140e6a] V [jvm.dll+0x20529e] V [jvm.dll+0x140eed] V [jvm.dll+0x14d2ee] V [jvm.dll+0x14d515] V [jvm.dll+0xf1f99] C [java.dll+0x7d82] j sun.reflect.NativeMethodAccessorImpl.invoke(Ljava/lang/Object;[Ljava/lang/Object;)Ljava/lang/Object;+87 j sun.reflect.DelegatingMethodAccessorImpl.invoke(Ljava/lang/Object;[Ljava/lang/Object;)Ljava/lang/Object;+6 j java.lang.reflect.Method.invoke(Ljava/lang/Object;[Ljava/lang/Object;)Ljava/lang/Object;+57 j com.intellij.rt.execution.application.AppMain.main([Ljava/lang/String;)V+163 v ~StubRoutines::call_stub V [jvm.dll+0x140e6a] V [jvm.dll+0x20529e] V [jvm.dll+0x140eed] V [jvm.dll+0xca5c5] V [jvm.dll+0xd5267] C [java.exe+0x2063] C [java.exe+0xa5d1] C [java.exe+0xa65b] C [kernel32.dll+0x1338a] C [ntdll.dll+0x39f72] C [ntdll.dll+0x39f45] Java frames: (J=compiled Java code, j=interpreted, Vv=VM code) j jnitest.JNIWrapper.createUuid(Ljnitest/JNIWrapper$sender_id_t;)I+25 j jnitest.JNIClass.<init>()V+27 j jnitest.JNIClass.getInstance()Ljnitest/JNIClass;+22 j jnitest.Program.main([Ljava/lang/String;)V+0 v ~StubRoutines::call_stub j sun.reflect.NativeMethodAccessorImpl.invoke0(Ljava/lang/reflect/Method;Ljava/lang/Object;[Ljava/lang/Object;)Ljava/lang/Object;+0 j sun.reflect.NativeMethodAccessorImpl.invoke(Ljava/lang/Object;[Ljava/lang/Object;)Ljava/lang/Object;+87 j sun.reflect.DelegatingMethodAccessorImpl.invoke(Ljava/lang/Object;[Ljava/lang/Object;)Ljava/lang/Object;+6 j java.lang.reflect.Method.invoke(Ljava/lang/Object;[Ljava/lang/Object;)Ljava/lang/Object;+57 j com.intellij.rt.execution.application.AppMain.main([Ljava/lang/String;)V+163 v ~StubRoutines::call_stub The Java class: package jnitest; public class JNIClass { static final Object _mutex = new Object(); static JNIClass _instance = null; public static JNIClass getInstance() { if (_instance == null) { synchronized (_mutex) { if (_instance == null) _instance = new JNIClass(); } } return _instance; } JNIWrapper.sender_id_t sid = null; JNIClass() { //create uuid sid = new JNIWrapper.sender_id_t(); System.out.print(JNIWrapper.createUuid(sid)); } } The JNI wrapper class: package jnitest; public final class JNIWrapper { static { System.loadLibrary("JNIWrapper"); } public static class sender_id_t { public long phy_idx; } public static native int createUuid(JNIWrapper.sender_id_t id); } The application: package jnitest; public class Program { public static void main(String[] args) { JNIClass.getInstance(); System.exit(0); } } The auto-generated JNI DLL header: /* DO NOT EDIT THIS FILE - it is machine generated */ #include <jni.h> /* Header for class jnitest_JNIWrapper */ #ifndef _Included_jnitest_JNIWrapper #define _Included_jnitest_JNIWrapper #ifdef __cplusplus extern "C" { #endif /* * Class: jnitest_JNIWrapper * Method: createUuid * Signature: (Ljnitest/JNIWrapper/sender_id_t;)I */ JNIEXPORT jint JNICALL Java_jnitest_JNIWrapper_createUuid (JNIEnv *, jclass, jobject); #ifdef __cplusplus } #endif #endif The JNI DLL implementation (**updated to be able to use either C or C++ interface**): #include "jnitest_JNIWrapper.h" #ifdef __cplusplus extern "C" { #endif #ifdef __cplusplus #define JNIFUNC(e,f) e->f() #define JNIFUNCV(e,f,...) e->f(__VA_ARGS__) #else #define JNIFUNC(e,f) (*e)->f(e) #define JNIFUNCV(e,f,...) (*e)->f(e,__VA_ARGS__) #endif JNIEXPORT jint JNICALL Java_jnitest_JNIWrapper_createUuid(JNIEnv *env, jclass clazz, jobject sid) { (void)clazz; jclass cls = JNIFUNCV(env,GetObjectClass, sid); jfieldID phyID = JNIFUNCV(env,GetFieldID, cls, "phy_idx", "J"); (void)phyID; if (JNIFUNC(env,ExceptionCheck)) return 100; return 0; } #ifdef __cplusplus } #endif **Update:** The compilation command: i686-w64-mingw32-gcc -std=c99 -O3 -s -Wall -Wextra -Werror -o ../bin/JNIWrapper.dll -shared -Wl,--subsystem,windows dllmain.c JNIWrapper.c -I /usr/lib/jvm/java-7-openjdk-amd64/include The MinGW of ubuntu 13.10: Using built-in specs. COLLECT_GCC=i686-w64-mingw32-gcc COLLECT_LTO_WRAPPER=/usr/lib/gcc/i686-w64-mingw32/4.6/lto-wrapper Target: i686-w64-mingw32 Configured with: ../../src/configure --build=x86_64-linux-gnu --prefix=/usr --includedir='/usr/include' --mandir='/usr/share/man' --infodir='/usr/share/info' --sysconfdir=/etc --localstatedir=/var --libexecdir='/usr/lib/gcc-mingw-w64' --disable-maintainer-mode --disable-dependency-tracking --prefix=/usr --enable-shared --enable-static --disable-multilib --enable-linker-build-id --with-system-zlib --libexecdir=/usr/lib --without-included-gettext --libdir=/usr/lib --enable-libstdcxx-time=yes --with-tune=generic --enable-version-specific-runtime-libs --enable-threads=win32 --enable-fully-dynamic-string --enable-sjlj-exceptions --enable-languages=c,c++,fortran,objc,obj-c++,ada --enable-lto --with-plugin-ld --target=i686-w64-mingw32 --with-gxx-include-dir=/usr/include/c++/4.6 --with-as=/usr/bin/i686-w64-mingw32-as --with-ld=/usr/bin/i686-w64-mingw32-ld Thread model: win32 gcc version 4.6.3 (GCC) The MinGW of ubuntu 14.04: The native MinGW I used: Using built-in specs. COLLECT_GCC=gcc COLLECT_LTO_WRAPPER=c:/mingw/mingw64-w32/bin/../libexec/gcc/i686-w64-mingw32/4.6.3/lto-wrapper.exe Target: i686-w64-mingw32 Configured with: /home/ruben/mingw-w64/src/gcc/configure --host=i686-w64-mingw32 --build=x86_64-linux-gnu --target=i686-w64-mingw32 --with-sysroot=/home/ruben/mingw-w64/mingw32mingw32/mingw32 --prefix=/home/ruben/mingw-w64/mingw32mingw32/mingw32 --with-gmp=/home/ruben/mingw-w64/prereq/i686-w64-mingw32/install --with-mpfr=/home/ruben/mingw-w64/prereq/i686-w64-mingw32/install --with-mpc=/home/ruben/mingw-w64/prereq/i686-w64-mingw32/install --with-ppl=/home/ruben/mingw-w64/prereq/i686-w64-mingw32/install --with-cloog=/home/ruben/mingw-w64/prereq/i686-w64-mingw32/install --enable-cloog-backend=isl --with-host-libstdcxx='-static -lstdc++ -lm' --enable-shared --enable-static --enable-threads=win32 --enable-plugins --disable-multilib --enable-languages=c,lto,c++,objc,obj-c++,fortran,java --enable-libgomp --disable-dw2-exceptions --enable-sjlj-exceptions --enable-fully-dynamic-string --enable-libstdcxx-time --disable-nls --disable-werror --enable-checking=release --with-gnu-as --with-gnu-ld --disable-win32-registry --disable-rpath --disable-werror --with-libiconv-prefix=/home/ruben/mingw-w64/prereq/i686-w64-mingw32/install CFLAGS='-O2 -march=nocona -mtune=core2 -fomit-frame-pointer -momit-leaf-frame-pointer -fgraphite-identity -floop-interchange -floop-block -floop-parallelize-all' LDFLAGS= : (reconfigured) /home/ruben/mingw-w64/src/gcc/configure --host=i686-w64-mingw32 --build=x86_64-linux-gnu --target=i686-w64-mingw32 --with-sysroot=/home/ruben/mingw-w64/mingw32mingw32/mingw32 --prefix=/home/ruben/mingw-w64/mingw32mingw32/mingw32 --with-gmp=/home/ruben/mingw-w64/prereq/i686-w64-mingw32/install --with-mpfr=/home/ruben/mingw-w64/prereq/i686-w64-mingw32/install --with-mpc=/home/ruben/mingw-w64/prereq/i686-w64-mingw32/install --with-ppl=/home/ruben/mingw-w64/prereq/i686-w64-mingw32/install --with-cloog=/home/ruben/mingw-w64/prereq/i686-w64-mingw32/install --enable-cloog-backend=isl --with-host-libstdcxx='-static -lstdc++ -lm' --enable-shared --enable-static --enable-threads=win32 --enable-plugins --disable-multilib --enable-libgomp --disable-dw2-exceptions --enable-sjlj-exceptions --enable-fully-dynamic-string --enable-libstdcxx-time --disable-nls --enable-checking=release --with-gnu-as --with-gnu-ld --disable-win32-registry --disable-rpath --disable-werror --with-libiconv-prefix=/home/ruben/mingw-w64/prereq/i686-w64-mingw32/install CFLAGS='-O2 -march=nocona -mtune=core2 -fomit-frame-pointer -momit-leaf-frame-pointer -fgraphite-identity -floop-interchange -floop-block -floop-parallelize-all' LDFLAGS= build_alias=x86_64-linux-gnu host_alias=i686-w64-mingw32 target_alias=i686-w64-mingw32 --enable-languages=c,c++,fortran,java,lto,objc,obj-c++ --no-create --no-recursion Thread model: win32 gcc version 4.6.3 (GCC) I posted this on Stack Overflow first: http://stackoverflow.com/questions/24485588/jni-dll-crashes-jvm-32-bit-only