LWJGL Forum

Programming => Lightweight Java Gaming Library => Topic started by: Simon Felix on September 08, 2009, 10:00:17

Title: JVM crash in setGammaRamp
Post by: Simon Felix on September 08, 2009, 10:00:17
Hi everyone,

we just released Cultris II beta1 and now receive lot's of crashlogs (all from people with an Intel GMA 945 cards on notebooks):

#
# A fatal error has been detected by the Java Runtime Environment:
#
#  EXCEPTION_ACCESS_VIOLATION (0xc0000005) at pc=0x6d8f4c25, pid=6060, tid=2944
#
# JRE version: 6.0_14-b08
# Java VM: Java HotSpot(TM) Client VM (14.0-b16 mixed mode, sharing windows-x86 )
# Problematic frame:
# V  [jvm.dll+0xf4c25]
#
# If you would like to submit a bug report, please visit:
#   http://java.sun.com/webapps/bugreport/crash.jsp
#

---------------  T H R E A D  ---------------

Current thread (0x003c6c00):  JavaThread "main" [_thread_in_vm, id=2944, stack(0x00030000,0x00130000)]

siginfo: ExceptionCode=0xc0000005, reading address 0x00000000

Registers:
EAX=0x00000000, EBX=0x003c6c00, ECX=0x003c6c00, EDX=0x6da27078
ESP=0x0012d6e4, EBP=0x0012d700, ESI=0x003c6d10, EDI=0x003c6d10
EIP=0x6d8f4c25, EFLAGS=0x00010246

Top of Stack: (sp=0x0012d6e4)
0x0012d6e4:   003c6d10 003c6d10 02d78000 003c6c00
0x0012d6f4:   003c74f0 00000076 6da27078 0012d770
0x0012d704:   1000126f 003c6d10 00000000 100328d0
0x0012d714:   41010dd4 10002c4a 003c6d10 100328d0
0x0012d724:   003c6c00 26a27bb0 26a27bb8 100066bf
0x0012d734:   003c6d10 0012d780 00aa9e37 003c6d10
0x0012d744:   0012d778 0012d780 fffffffe 0012d750
0x0012d754:   26a27bb0 0012d780 26a2f250 00000000

Instructions: (pc=0x6d8f4c25)
0x6d8f4c15:   00 00 00 74 08 8d 4d f0 e8 4e 97 08 00 8b 45 0c
0x6d8f4c25:   8b 00 50 e8 d3 90 ff ff 8b f0 8b 7e 44 83 c6 08


Stack: [0x00030000,0x00130000],  sp=0x0012d6e4,  free space=1013k
Native frames: (J=compiled Java code, j=interpreted, Vv=VM code, C=native code)
V  [jvm.dll+0xf4c25]
C  [lwjgl.dll+0x126f]
j  org.lwjgl.opengl.WindowsDisplay.int(Ljava/nio/ByteBuffer;)V+1
j  org.lwjgl.opengl.WindowsDisplay.native()V+5
j  org.lwjgl.opengl.WindowsDisplay.for(Z)V+29
j  org.lwjgl.opengl.WindowsDisplay.do(JIJJJ)I+214
j  org.lwjgl.opengl.WindowsDisplay.handleMessage(JIJJJ)I+16
v  ~StubRoutines::call_stub
V  [jvm.dll+0xecabc]
V  [jvm.dll+0x173d61]
V  [jvm.dll+0xecb3d]
V  [jvm.dll+0xf5705]
V  [jvm.dll+0xfc38d]

Java frames: (J=compiled Java code, j=interpreted, Vv=VM code)
j  org.lwjgl.opengl.WindowsDisplay.nSetGammaRamp(Ljava/nio/ByteBuffer;)V+0
j  org.lwjgl.opengl.WindowsDisplay.int(Ljava/nio/ByteBuffer;)V+1
j  org.lwjgl.opengl.WindowsDisplay.native()V+5
j  org.lwjgl.opengl.WindowsDisplay.for(Z)V+29
j  org.lwjgl.opengl.WindowsDisplay.do(JIJJJ)I+214
j  org.lwjgl.opengl.WindowsDisplay.handleMessage(JIJJJ)I+16
v  ~StubRoutines::call_stub
j  org.lwjgl.opengl.WindowsDisplay.showWindow(JI)V+0
j  org.lwjgl.opengl.WindowsDisplay.do(Lorg/lwjgl/opengl/DisplayMode;Ljava/awt/Canvas;II)V+207
j  org.lwjgl.opengl.Display.super()V+72
j  org.lwjgl.opengl.Display.do(Lorg/lwjgl/opengl/PixelFormat;Lorg/lwjgl/opengl/f;Lorg/lwjgl/opengl/zd;)V+71
j  org.lwjgl.opengl.Display.do(Lorg/lwjgl/opengl/PixelFormat;)V+9
j  org.lwjgl.opengl.Display.try()V+13
j  dl.for()V+50
j  dl.<init>()V+40
j  ch.cultris.Cultris.main([Ljava/lang/String;)V+22
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;+161
j  jexepackboot.run([Ljava/lang/String;)Ljava/lang/String;+583
j  jexepackboot.boot([Ljava/lang/String;)Ljava/lang/String;+8
v  ~StubRoutines::call_stub


To me this crash looks very weird. The offending code is this:
(http://java-game-lib.svn.sourceforge.net/viewvc/java-game-lib/trunk/LWJGL/src/native/windows/display.c?revision=2985&view=markup)

  190 void setGammaRamp(JNIEnv * env, jobject gammaRampBuffer) {
 191    HDC screenDC;
 192    WORD *gammaRamp = (WORD *)(*env)->GetDirectBufferAddress(env, gammaRampBuffer);
 193
 194    screenDC = GetDC(NULL);
 195    if (SetDeviceGammaRamp(screenDC, gammaRamp) == FALSE) {
 196       throwException(env, "Failed to set device gamma.");
 197    }
 198    ReleaseDC(NULL, screenDC);
 199 }


I can't see the problem. Does anybody have an idea what we can do to fix the problem?

The old Cultris version works (using a very old LWJGL version, pre 1.0) on these computers. They updated the graphics driver to the newest version... Please note that we obfuscated the code. That's why some methods now have weird names like "int" or "do".

dr_evil
Title: Re: JVM crash in setGammaRamp
Post by: Simon Felix on September 08, 2009, 15:55:55
One tester reported that other LWJGL apps (using LWJGL 2.1) are working... Maybe the initialization order we use is "wrong"?

Here's what we do:
Toolkit.getDefaultToolkit();
Sys.initialize();
Display.setIcon(...);
Initialize BASS/NativeBass
Display.setDisplayModeAndFullscreen(...);
Display.setTitle();
Display.create();
Mouse.create();
Keyboard.create();


Is there anything wrong with this order?
Title: Re: JVM crash in setGammaRamp
Post by: princec on September 08, 2009, 16:48:57
It should in theory make no difference to the order of initialisation (if you find a permutation that doesn't work we'd like to make sure it does work). The crash could be caused by passing in a non-direct Buffer to the method.

Cas :)
Title: Re: JVM crash in setGammaRamp
Post by: Simon Felix on September 08, 2009, 17:10:26
I'm not calling the setGammaRamp method. It's called from appActivate(); after the window's created.

If it was in fact a non-direct ByteBuffer the same problem should appear on every computer... But it happens only on some... And only with our application...
Title: Re: JVM crash in setGammaRamp
Post by: Simon Felix on September 08, 2009, 21:20:23
I have another crash log, this time from a computer with a nVidia GeForce 6600GT:

#
# A fatal error has been detected by the Java Runtime Environment:
#
#  EXCEPTION_ACCESS_VIOLATION (0xc0000005) at pc=0x6d8f5115, pid=3616, tid=796
#
# JRE version: 6.0_15-b03
# Java VM: Java HotSpot(TM) Client VM (14.1-b02 mixed mode, sharing windows-x86 )
# Problematic frame:
# V  [jvm.dll+0xf5115]
#
# If you would like to submit a bug report, please visit:
#   http://java.sun.com/webapps/bugreport/crash.jsp
#

---------------  T H R E A D  ---------------

Current thread (0x003c6800):  JavaThread "main" [_thread_in_vm, id=796, stack(0x00030000,0x00130000)]

siginfo: ExceptionCode=0xc0000005, reading address 0x00000000

Registers:
EAX=0x00000000, EBX=0x003c6800, ECX=0x003c6800, EDX=0x6da27078
ESP=0x0012d6e4, EBP=0x0012d700, ESI=0x003c6910, EDI=0x003c6910
EIP=0x6d8f5115, EFLAGS=0x00010246

Top of Stack: (sp=0x0012d6e4)
0x0012d6e4:   003c6910 003c6910 02d92000 003c6800
0x0012d6f4:   003c70c0 00000076 6da27078 0012d770
0x0012d704:   03de126f 003c6910 00000000 03e128d0
0x0012d714:   1a010fe2 03de2c4a 003c6910 03e128d0
0x0012d724:   003c6800 26a2bd10 26a2bd18 03de66bf
0x0012d734:   003c6910 0012d780 00aa9e27 003c6910
0x0012d744:   0012d778 0012d780 fffffffe 0012d750
0x0012d754:   26a2bd10 0012d780 26a2f228 00000000

Instructions: (pc=0x6d8f5115)
0x6d8f5105:   00 00 00 74 08 8d 4d f0 e8 ae 97 08 00 8b 45 0c
0x6d8f5115:   8b 00 50 e8 d3 90 ff ff 8b f0 8b 7e 44 83 c6 08


Stack: [0x00030000,0x00130000],  sp=0x0012d6e4,  free space=1013k
Native frames: (J=compiled Java code, j=interpreted, Vv=VM code, C=native code)
V  [jvm.dll+0xf5115]
C  [lwjgl.dll+0x126f]
j  org.lwjgl.opengl.WindowsDisplay.int(Ljava/nio/ByteBuffer;)V+1
j  org.lwjgl.opengl.WindowsDisplay.native()V+5
j  org.lwjgl.opengl.WindowsDisplay.for(Z)V+29
j  org.lwjgl.opengl.WindowsDisplay.do(JIJJJ)I+214
j  org.lwjgl.opengl.WindowsDisplay.handleMessage(JIJJJ)I+16
v  ~StubRoutines::call_stub
V  [jvm.dll+0xecfac]
V  [jvm.dll+0x1741d1]
V  [jvm.dll+0xed02d]
V  [jvm.dll+0xf5bf5]
V  [jvm.dll+0xfc87d]

Java frames: (J=compiled Java code, j=interpreted, Vv=VM code)
j  org.lwjgl.opengl.WindowsDisplay.nSetGammaRamp(Ljava/nio/ByteBuffer;)V+0
j  org.lwjgl.opengl.WindowsDisplay.int(Ljava/nio/ByteBuffer;)V+1
j  org.lwjgl.opengl.WindowsDisplay.native()V+5
j  org.lwjgl.opengl.WindowsDisplay.for(Z)V+29
j  org.lwjgl.opengl.WindowsDisplay.do(JIJJJ)I+214
j  org.lwjgl.opengl.WindowsDisplay.handleMessage(JIJJJ)I+16
v  ~StubRoutines::call_stub
j  org.lwjgl.opengl.WindowsDisplay.showWindow(JI)V+0
j  org.lwjgl.opengl.WindowsDisplay.do(Lorg/lwjgl/opengl/DisplayMode;Ljava/awt/Canvas;II)V+207
j  org.lwjgl.opengl.Display.throw()V+72
j  org.lwjgl.opengl.Display.do(Lorg/lwjgl/opengl/PixelFormat;Lorg/lwjgl/opengl/f;Lorg/lwjgl/opengl/zd;)V+71
j  org.lwjgl.opengl.Display.do(Lorg/lwjgl/opengl/PixelFormat;)V+9
j  org.lwjgl.opengl.Display.void()V+13
j  el.else()V+50
j  el.<init>()V+40
j  ch.cultris.Cultris.main([Ljava/lang/String;)V+25
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;+161
j  jexepackboot.run([Ljava/lang/String;)Ljava/lang/String;+583
j  jexepackboot.boot([Ljava/lang/String;)Ljava/lang/String;+8
v  ~StubRoutines::call_stub
Title: Re: JVM crash in setGammaRamp
Post by: Matzon on September 09, 2009, 06:45:15
is it possible to get them to execute an unobfuscated test case?
that would narrow it down and make sure that it isn't the obfuscator doing "stuff" ?
Title: Re: JVM crash in setGammaRamp
Post by: Simon Felix on September 09, 2009, 07:00:03
We did that test already. Do you want the stacktrace?


Another reported case, this time with an nVidia GeForce FX5200. I'm beginning to wonder if this really depends on the graphics card as I initially suspected...
Title: Re: JVM crash in setGammaRamp
Post by: Simon Felix on September 09, 2009, 07:33:43
Surprisingly it works on some computers the second time. (This happens on nVidia Quadro NVS 290 as well)

1st start: Crash
2nd start: Works perfectly fine

I'll perhaps create a patch that will call setGammaRamp only when absolutly neccessary.
Title: Re: JVM crash in setGammaRamp
Post by: Matzon on September 09, 2009, 07:41:40
hmm, I must admit that I'd like to add some debug code to void setGammaRamp(JNIEnv * env, jobject gammaRampBuffer) and check the values of all of the fields and then check the OS for errors.

The error isn't happening in the nvidia or ati driver - so maybe gammaRampBuffer is null at times, or WORD *gammaRamp becomes null or screenDC = GetDC(NULL); is null ... its a fairly limited method to debug.

Can you compile the native part yourself ?
Title: Re: JVM crash in setGammaRamp
Post by: Matzon on September 09, 2009, 07:44:10
is the gamme ramp buffer valid ? doh, you're not calling it. its from appactivate
I dont see it getting called by anyone inside - it seems to be called only by DisplayTest or user application...

I do however keep getting
org.lwjgl.LWJGLException: Failed to set device gamma.
        at org.lwjgl.opengl.WindowsDisplay.nSetGammaRamp(Native Method)
        at org.lwjgl.opengl.WindowsDisplay.doSetGammaRamp(WindowsDisplay.java:332)
        at org.lwjgl.opengl.WindowsDisplay.setGammaRamp(WindowsDisplay.java:326)
        at org.lwjgl.opengl.Display.setDisplayConfiguration(Display.java:397)
        at org.lwjgl.test.DisplayTest.changeConfig(DisplayTest.java:219)
        at org.lwjgl.test.DisplayTest.setDisplayConfigurationTest(DisplayTest.java:195)
        at org.lwjgl.test.DisplayTest.executeTest(DisplayTest.java:61)
        at org.lwjgl.test.DisplayTest.main(DisplayTest.java:250)
Title: Re: JVM crash in setGammaRamp
Post by: Matzon on September 09, 2009, 08:19:07
I am unable to get it to crash - however all my calls to SetDeviceGammaRamp are failing:
void setGammaRamp(JNIEnv * env, jobject gammaRampBuffer) {
HDC screenDC;
WORD *gammaRamp = (WORD *)(*env)->GetDirectBufferAddress(env, gammaRampBuffer);
printf("setting gamma using %x\n", gammaRamp);

screenDC = GetDC(NULL);
printf("using screenDC: %x\n", screenDC);

if (SetDeviceGammaRamp(screenDC, gammaRamp) == FALSE) {
  printf("unable to set DeviceGammaRamp\n");
throwException(env, "Failed to set device gamma.");
}

printf("Releasing DC\n");
ReleaseDC(NULL, screenDC);
}


QuoteTesting normal setting
setting gamma using 2b74000
using screenDC: 47011121
unable to set DeviceGammaRamp
Releasing DC
Testing gamma settings
setting gamma using 2ac5000
using screenDC: 570121fe
unable to set DeviceGammaRamp
Releasing DC
Testing brightness settings
setting gamma using 2ac7000
using screenDC: 47011121
unable to set DeviceGammaRamp
Releasing DC
Testing contrast settings
setting gamma using 2aca000
using screenDC: 47011121
unable to set DeviceGammaRamp
Releasing DC
resetting...done
Title: Re: JVM crash in setGammaRamp
Post by: Matzon on September 09, 2009, 08:39:40
and by failing, I mean that it says its failing - but contrast is getting set anyway *ponder*
Title: Re: JVM crash in setGammaRamp
Post by: Simon Felix on September 09, 2009, 12:45:07
SetDeviceGammaRamp is not supported on all graphics cards... So just failing should be ok.

But wait a minute, I just had a report from someone that the un-obfuscated version works. I'll report when I know more.
Title: Re: JVM crash in setGammaRamp
Post by: Simon Felix on September 09, 2009, 19:23:32
It seems to be an obfuscator-related issue... I'm very sorry to have wasted your time.

Very strange issue. Sometimes it crashes on start (fullscreen), sometimes it crashes on exit (windowed) and sometimes it doesn't crash at all (on most computers). I don't get it...