Native compilation with GCJ!

Started by blue_tomato, June 18, 2005, 04:04:59

Previous topic - Next topic

Matzon

Test 3
I get to select mode, window pops up, and boom - exit
Perhaps print some stuff to console to check where it crashes ?
QuoteAvailable display modes:
1280 x 800 x 32 @60Hz
1360 x 768 x 32 @75Hz

LOTS

1600 x 1024 x 32 @72Hz
1088 x 612 x 32 @70Hz
1600 x 1024 x 16 @70Hz
Exception in thread "main" java.lang.ExceptionInInitializerError
*** Got java.lang.NullPointerException while trying to print stack trace.

blue_tomato

Quote from: "Matzon"Test 3
I get to select mode, window pops up, and boom - exit
Perhaps print some stuff to console to check where it crashes ?
QuoteAvailable display modes:
1280 x 800 x 32 @60Hz
1360 x 768 x 32 @75Hz

LOTS

1600 x 1024 x 32 @72Hz
1088 x 612 x 32 @70Hz
1600 x 1024 x 16 @70Hz
Exception in thread "main" java.lang.ExceptionInInitializerError
*** Got java.lang.NullPointerException while trying to print stack trace.

Hm, I do print quite a lot of info when an exception is caught. But from the error it seems like the exception itself is causing a new exception to be thrown?

I have put the source code here:

www.ninjasoftware.com/download/src.rar

blue_tomato

I have compiled a new test which will output more debug information, so it should be possible to pinpoint where the problem occurs on some systems

www.ninjasoftware.com/download/deploy_test4.rar

Matzon

Quote[init]
[createWindow]
Exception in thread "main" java.lang.ExceptionInInitializerError
  at 0x0044d56e (Unknown Source)
  at 0x0044cf02 (Unknown Source)
  at 0x0050f9e4 (Unknown Source)
  at 0x0044cb94 (Unknown Source)
  at 0x0051d1dc (Unknown Source)
  at 0x0045500f (Unknown Source)
  at 0x00591bbe (Unknown Source)
  at 0x00595633 (Unknown Source)
  at 0x00454e04 (Unknown Source)
  at 0x004fde69 (Unknown Source)
  at 0x004fe010 (Unknown Source)
  at 0x004fe05f (Unknown Source)
  at 0x004495dd (Unknown Source)
  at 0x0041a108 (Unknown Source)
  at 0x00411b91 (Unknown Source)
  at 0x004145a4 (Unknown Source)
  at 0x004148f0 (Unknown Source)
  at 0x0041a6f0 (Unknown Source)
  at 0x0040499f (Unknown Source)
  at 0x00417af9 (Unknown Source)
  at 0x004170a4 (Unknown Source)
  at 0x00417ce4 (Unknown Source)
  at 0x00417b8f (Unknown Source)
  at 0x00417b5d (Unknown Source)
  at 0x00402323 (Unknown Source)
  at 0x00402649 (Unknown Source)
  at 0x00401e6c (Unknown Source)
  at 0x00401762 (Unknown Source)
  at 0x004761b3 (Unknown Source)
  at 0x0045bea0 (Unknown Source)
  at 0x00420606 (Unknown Source)
  at 0x00420787 (Unknown Source)
  at 0x004012ca (Unknown Source)
  at 0x004011e3 (Unknown Source)
  at 0x00401234 (Unknown Source)
  at 0x7c816d4b (Unknown Source)
Caused by: java.util.MissingResourceException: Bundle gnu/regexp/MessagesBundle not found
  at 0x0044d56e (Unknown Source)
  at 0x0044cf02 (Unknown Source)
  at 0x00448bb4 (Unknown Source)
  at 0x0044cdf4 (Unknown Source)
  at 0x0060d465 (Unknown Source)
  at 0x005c820d (Unknown Source)
  at 0x005c829a (Unknown Source)
  at 0x00595282 (Unknown Source)
  at 0x00454e04 (Unknown Source)
  ...30 more

Is it possible to make stacktrace lines work in gcj ?
Could you post the source + scripts to generate the exe, then I could debug easily myself

blue_tomato

Quote from: "Matzon"
Quote[init]
[createWindow]
Exception in thread "main" java.lang.ExceptionInInitializerError
  at 0x0044d56e (Unknown Source)
  at 0x0044cf02 (Unknown Source)
  at 0x0050f9e4 (Unknown Source)
  at 0x0044cb94 (Unknown Source)
  at 0x0051d1dc (Unknown Source)
  at 0x0045500f (Unknown Source)
  at 0x00591bbe (Unknown Source)
  at 0x00595633 (Unknown Source)
  at 0x00454e04 (Unknown Source)
  at 0x004fde69 (Unknown Source)
  at 0x004fe010 (Unknown Source)
  at 0x004fe05f (Unknown Source)
  at 0x004495dd (Unknown Source)
  at 0x0041a108 (Unknown Source)
  at 0x00411b91 (Unknown Source)
  at 0x004145a4 (Unknown Source)
  at 0x004148f0 (Unknown Source)
  at 0x0041a6f0 (Unknown Source)
  at 0x0040499f (Unknown Source)
  at 0x00417af9 (Unknown Source)
  at 0x004170a4 (Unknown Source)
  at 0x00417ce4 (Unknown Source)
  at 0x00417b8f (Unknown Source)
  at 0x00417b5d (Unknown Source)
  at 0x00402323 (Unknown Source)
  at 0x00402649 (Unknown Source)
  at 0x00401e6c (Unknown Source)
  at 0x00401762 (Unknown Source)
  at 0x004761b3 (Unknown Source)
  at 0x0045bea0 (Unknown Source)
  at 0x00420606 (Unknown Source)
  at 0x00420787 (Unknown Source)
  at 0x004012ca (Unknown Source)
  at 0x004011e3 (Unknown Source)
  at 0x00401234 (Unknown Source)
  at 0x7c816d4b (Unknown Source)
Caused by: java.util.MissingResourceException: Bundle gnu/regexp/MessagesBundle not found
  at 0x0044d56e (Unknown Source)
  at 0x0044cf02 (Unknown Source)
  at 0x00448bb4 (Unknown Source)
  at 0x0044cdf4 (Unknown Source)
  at 0x0060d465 (Unknown Source)
  at 0x005c820d (Unknown Source)
  at 0x005c829a (Unknown Source)
  at 0x00595282 (Unknown Source)
  at 0x00454e04 (Unknown Source)
  ...30 more

Is it possible to make stacktrace lines work in gcj ?
Could you post the source + scripts to generate the exe, then I could debug easily myself

This means the code fails here:

       if (DEBUG) System.out.println("[createWindow]");
        try {
            Display.setDisplayMode(mode);
        } catch (LWJGLException e) {
            System.out.println("Failed to initialize the display at display mode " + mode.toString());
            System.out.println(e.toString());
            e.printStackTrace();
            return;
        }

        Display.create();
        Display.setFullscreen(fullscreen);

        //sync frame (only works on windows) and linux apparently
        Display.setVSyncEnabled(true);
        Display.setTitle(animator.getName() + " " + animator.getVersion());
        if (DEBUG) System.out.println("[/createWindow]");


My guess is the problem is
       Display.setDisplayMode(mode);


I already posted a link to the source code earlier ( www.ninjasoftware.com/download/src.rar ), and the build script is:

@echo off

set exename=Main.exe
set main=Main
set deploy=_deploy

echo **Compiling Java files...
rmdir classes /s/q
md classes
javac -classpath c:\java\lwjgl\jar\lwjgl.jar;c:\java\swt\swt.jar -d classes src\*.java src\engine\*.java

echo **Creating JAR...
cd classes
jar Mcf ..\output.jar *.class engine\*.class
cd ..

echo **Removing unused methods...
java -classpath C:\java\proguard\lib\proguard.jar proguard.ProGuard @proguard.pro

echo **Repackage jar file as workaround for GCJ out-of-memory bug
rmdir temp /s/q
md temp
copy output_proguard.jar temp
cd temp
jar xf output_proguard.jar
del output_proguard.jar
jar cf output_proguard.jar .
copy output_proguard.jar .. /y
cd ..
rmdir temp /s/q

echo **Compiling to machine code...
gcj -fjni --no-bounds-check -O3 -c output_proguard.jar

echo **Linking...
rem add -mwindows to remove the console window
gcj -fjni --main=%main% -o %exename% *.o 

echo **Building deploy directory
rmdir %deploy% /s/q
md %deploy%
copy %exename% %deploy%
copy C:\java\lwjgl\native\lwjgl.dll %deploy%
copy C:\gcc\i686-pc-mingw32\lib\swt-win32-3116.dll %deploy%

pause

echo **Cleaning up
del output.jar
del output_proguard.jar
del output_proguard.o
del %exename%


The Proguard script is

-injars       output.jar;c:\java\lwjgl\jar\lwjgl.jar
-outjars      output_proguard.jar
-libraryjars  <java.home>/lib/rt.jar;c:\java\swt\swt.jar
-printmapping proguard.map
-overloadaggressively
-defaultpackage ''
-allowaccessmodification
-dontobfuscate
-dontoptimize
-dontskipnonpubliclibraryclasses
-dontskipnonpubliclibraryclassmembers

-keep public class Main {
    public static void main(java.lang.String[]);
}

-keep class org.lwjgl.opengl.Win32Display
-keep class org.lwjgl.opengl.DisplayMode {*;}
-keep class org.lwjgl.Win32SysImplementation
-keep class org.lwjgl.opengl.Win32ContextImplementation

About stacktrace in gcj, sorry, I do not know. But now you have everything I have, and hopefully you can localize the problem more efficiently... :)

Matzon

got it!

I am just going to tell you what the problem was, I cannot tell you why it is so, it just is - I am as confused as I can get...

The crash occurs in: GLContext.java, in the getPlatformSpecificFunctionAddress method.

Specifically, it crashes on the line:
String platform_function_name = function.replaceFirst(function_prefix, os_function_prefixes);

HOWEVER (and this is where it gets funny (did I mention it took a looong time to locate?)) it ONLY occurs when locating methods for : NV_vertex_array_range_initNativeFunctionAddresses, specifically:
glFreeMemoryNV, glAllocateMemoryNV and so forth.

The replaceFirst method is meant to replace gl from  glFreeMemoryNV with wgl, becomming: wglFreeMemoryNV.

If I manually change the function.replace... line to:
String platform_function_name = "w" + function;
then *everything* works fine

:?:

I am totally, completely at a loss as to what is going on - and I have absolutely no idea why it is happening only when running under GCJ, but *somehow* the GCJ code must act weird in some strange corner cases, or something along those lines. (but only on my computer (nVidia))

So, you're code works fine - except for the ghost in the shell.

blue_tomato

Quote from: "Matzon"got it!

I am just going to tell you what the problem was, I cannot tell you why it is so, it just is - I am as confused as I can get...

The crash occurs in: GLContext.java, in the getPlatformSpecificFunctionAddress method.

Specifically, it crashes on the line:
String platform_function_name = function.replaceFirst(function_prefix, os_function_prefixes);

HOWEVER (and this is where it gets funny (did I mention it took a looong time to locate?)) it ONLY occurs when locating methods for : NV_vertex_array_range_initNativeFunctionAddresses, specifically:
glFreeMemoryNV, glAllocateMemoryNV and so forth.

The replaceFirst method is meant to replace gl from  glFreeMemoryNV with wgl, becomming: wglFreeMemoryNV.

If I manually change the function.replace... line to:
String platform_function_name = "w" + function;
then *everything* works fine

:?:

I am totally, completely at a loss as to what is going on - and I have absolutely no idea why it is happening only when running under GCJ, but *somehow* the GCJ code must act weird in some strange corner cases, or something along those lines. (but only on my computer (nVidia))

So, you're code works fine - except for the ghost in the shell.

And I assume your Proguard compiled JAR file will run well, even when you keep the lwjgl.jar away from the classpath?

If not, my first guess would be that Proguard somehow figured out that your platform specific program running path would never occur and thus removed required methods.

This is a quite common problem with Proguard, and any kinds of dynamically loaded code must be included manually.

How about adding

-keep class org.lwjgl.opengl.GLContext {*;}


Or, try compile with different Proguard settings? Like turn off

-overloadaggressively
-allowaccessmodification


Or, maybe compile with less optimization (omit -O3 and removal of bounds checks)?

Just guessing really, sounds very strange....  :roll:

blue_tomato

By the way, do you mind putting the GCJ workaround into the next release of the API?

Thanks :)