[FIXED] Load 64bit natives first when the JVM is a 64bit

Started by Matthias, November 26, 2010, 16:50:35

Previous topic - Next topic

Matthias

The attached patch checks os.arch and tries to load the 64bit natives first if it is "amd64"

kappa

just out of curiosity "amd64" just looks a bit odd.

Isn't that specific for AMD 64bit processors? what about Intel 64 bit processors?

would "x86_64" not also work but in a vendor neutral way?

Matthias

amd64 is the string returned by System.getProperty("os.arch")

Matthias

amd64 does not refer to the used CPU - in fact I have an Intel i5-750 CPU. It refers to the instruction set.

jediTofu

It appears that the implementation uses getPointerSize...so this seems unnecessary.

But the code does seem odd to me:

private static void loadLibrary(final String lib_name) {
		try {
			doLoadLibrary(lib_name);
		} catch (UnsatisfiedLinkError e) {
			if (implementation.has64Bit()) {
				try {
					doLoadLibrary(lib_name + POSTFIX64BIT);
					return;
				} catch (UnsatisfiedLinkError e2) {
					LWJGLUtil.log("Failed to load 64 bit library: " + e2.getMessage());
				}
			}
			// Throw original error
			throw e;
		}
	}

	static {
		implementation = createImplementation();
		loadLibrary(JNI_LIBRARY_NAME);
		is64Bit = implementation.getPointerSize() == 8;

		//more code....
	}


"implementation.has64Bit()":  In the Windows implementation class, has64Bit is always true...
"is64Bit = implementation.getPointerSize() == 8;":  Shouldn't this be before loadLibrary...but has64Bit is used instead, so I guess it's unnecessary, but that means the 64-bit libs are always trying to be loaded and crashes on 32-bit...but it doesn't crash on 32-bit or else someone would have posted...so I must be confused in the code

I have Windows 7 amd 64-bit, and I know that it fails if I don't have the 64-bit native libs, so to me, it appears everything is working fine and completely unnecessary to do the code you provided.  I don't even need the 32-bit native libs even there actually (which makes sense of course) and are completely useless; if 64-bit loading fails, LWJGL doesn't even try to load the 32-bit libs and crashes...

Also, in your code, maybe you could use indexOf "64" instead of equals so that all 64-bit CPU's work...
cool story, bro

Matthias

I updated the patch to check for "amd64" (reported by OpenJDK and Sun JRE on Windows and Ubuntu) and "x86_64" which is mentioned on many websites

Matthias

We can't use getPointerSize() - it is a native function.

The idea for the RFE is that someone using LWJGL has reports from users where the app fails to start (on Ubuntu 64) when the 32bit natives are loaded first.

jediTofu

Quote from: Matthias on November 26, 2010, 19:25:28
...(on Ubuntu 64) when the 32bit natives are loaded first.

Then what about ppc64?

This would be better to use:

boolean is64bit = osArch.indexOf("64") != -1;
cool story, bro

broumbroum

Quote from: Matthias on November 26, 2010, 19:25:28
We can't use getPointerSize() - it is a native function.

The idea for the RFE is that someone using LWJGL has reports from users where the app fails to start (on Ubuntu 64) when the 32bit natives are loaded first.

could you find that post ? I'm running 64bits w7 for a while and my jdk always load 64 bits. 32 bits natives don't run on 64 bits arch.

Matthias

Quote from: jediTofu on November 26, 2010, 20:27:36
boolean is64bit = osArch.indexOf("64") != -1;
I think this is dangerous as we can't be sure that everything with a 64 in it means a 64 bit OS. This system property has no clear spec. I think testing should be limited to known values.
Also this has no impact on PPC as Mac uses a universal binary. Even if this test should fail to identify a 64bit platform it will just execute the loading order as it was before. To prevent regression this should only change the load order for known 64bit system.

Matthias

Quote from: broumbroum on November 26, 2010, 21:40:06
Quote from: Matthias on November 26, 2010, 19:25:28
The idea for the RFE is that someone using LWJGL has reports from users where the app fails to start (on Ubuntu 64) when the 32bit natives are loaded first.

could you find that post ? I'm running 64bits w7 for a while and my jdk always load 64 bits. 32 bits natives don't run on 64 bits arch.
The problem with this "someone" is that he refuses to write a bug report. I just created the patch so that he stops to annoy everyone in #lwjgl :)

According to him and his tests loading liblwjgl.so on Ubuntu 64bit (no idea which Ubuntu version) can cause future load attempts of liblwjgl64.so to fail:
Exception in thread "main" java.lang.UnsatisfiedLinkError: /home/bitcoin/DiabloMiner/target/libs/natives/linux/liblwjgl.so: /usr/lib/jvm/java-6-sun-1.6.0.22/jre/lib/amd64/libjawt.so: symbol awt_FreeDrawingSurface, version SUNWprivate_1.1 not defined in file libmawt.so with link time reference
Exception in thread "main" java.lang.UnsatisfiedLinkError: /home/bitcoin/DiabloMiner/target/libs/natives/linux/liblwjgl.so: /home/bitcoin/DiabloMiner/target/libs/natives/linux/liblwjgl.so: wrong ELF class: ELFCLASS32 (Possible cause: architecture word width mismatch)


broumbroum


Matthias

LWJGL already has 64bit natives for Windows and Linux (MacOSX probably too - I don't have access to a Mac).

Diablo-D3

The patch Matt made does not solve the problem. It only happens when DISPLAY is unset, which actually is theoretically okay in the use case of headless OpenCL (which my app uses through lwjgl, and three of my users have this problem).

Now that I understand whats going on, I can reproduce it. Do:

unset DISPLAY
./foo


It should output something like:
Exception in thread "main" java.lang.UnsatisfiedLinkError: /foo/natives/linux/liblwjgl.so: /foo/natives/linux/liblwjgl.so: wrong ELF class: ELFCLASS32 (Possible cause: architecture word width mismatch)
	at java.lang.ClassLoader$NativeLibrary.load(Native Method)
	at java.lang.ClassLoader.loadLibrary0(ClassLoader.java:1803)
	at java.lang.ClassLoader.loadLibrary(ClassLoader.java:1728)
	at java.lang.Runtime.loadLibrary0(Runtime.java:823)
	at java.lang.System.loadLibrary(System.java:1028)
	at org.lwjgl.Sys$1.run(Sys.java:73)
	at java.security.AccessController.doPrivileged(Native Method)
	at org.lwjgl.Sys.doLoadLibrary(Sys.java:66)
	at org.lwjgl.Sys.loadLibrary(Sys.java:82)
	at org.lwjgl.Sys.<clinit>(Sys.java:99)
	at org.lwjgl.opencl.CL.<clinit>(CL.java:51)
	at com.foo.main(foo.java:87)

Matthias

Quote from: Diablo-D3 on November 27, 2010, 17:02:25
The patch Matt made does not solve the problem. ...
And that without even applying the patch - that's a great way to test ...