Hi there,
I've got the following problem whenever I close my window:
Quote#
# A fatal error has been detected by the Java Runtime Environment:
#
# EXCEPTION_ACCESS_VIOLATION (0xc0000005) at pc=0x00007ffaf48377d0, pid=8052, tid=13844
#
# JRE version: Java(TM) SE Runtime Environment (11.0.1+13) (build 11.0.1+13-LTS)
# Java VM: Java HotSpot(TM) 64-Bit Server VM (11.0.1+13-LTS, mixed mode, tiered, compressed oops, g1 gc, windows-amd64)
# Problematic frame:
# C [lwjgl.dll+0x177d0]
#
# No core dump will be written. Minidumps are not enabled by default on client versions of Windows
#
# An error report file with more information is saved as:
# D:\XXXX\Game\hs_err_pid8052.log
#
# If you would like to submit a bug report, please visit:
# http://bugreport.java.com/bugreport/crash.jsp
# The crash happened outside the Java Virtual Machine in native code.
# See problematic frame for where to report the bug.
#
--------------- S U M M A R Y ------------
Command Line: -Dfile.encoding=UTF-8 test.game.HelloWorld
[...]
--------------- T H R E A D ---------------
Current thread (0x0000019dee63d800): JavaThread "main" [_thread_in_native, id=13844, stack(0x0000003edfc00000,0x0000003edfd00000)]
Stack: [0x0000003edfc00000,0x0000003edfd00000], sp=0x0000003edfcff498, free space=1021k
Native frames: (J=compiled Java code, j=interpreted, Vv=VM code, C=native code)
C [lwjgl.dll+0x177d0]
Java frames: (J=compiled Java code, j=interpreted, Vv=VM code)
j org.lwjgl.system.dyncall.DynCallback.ndcbGetUserData(J)J+0
j org.lwjgl.system.dyncall.DynCallback.dcbGetUserData(J)J+12
j org.lwjgl.system.Callback.free(J)V+1
j org.lwjgl.glfw.Callbacks.glfwFreeCallbacks(J)V+165
j test.game.HelloWorld.run()V+59
j test.game.HelloWorld.main([Ljava/lang/String;)V+7
v ~StubRoutines::call_stub
siginfo: EXCEPTION_ACCESS_VIOLATION (0xc0000005), reading address 0x0000019da5df0020
Minimal code example:
public class HelloWorld {
// The window handle
private long window;
private InputHandler input;
public void run() {
System.out.println("Hello LWJGL " + Version.getVersion() + "!");
init();
this.input = new InputHandler();
loop();
this.input.dispose();
// Free the window callbacks and destroy the window
glfwFreeCallbacks(window);
glfwDestroyWindow(window);
// Terminate GLFW and free the error callback
glfwTerminate();
glfwSetErrorCallback(null).free();
}
private void init() {
// Setup an error callback. The default implementation
// will print the error message in System.err.
GLFWErrorCallback.createPrint(System.err).set();
// Initialize GLFW. Most GLFW functions will not work before doing this.
if ( !glfwInit() )
throw new IllegalStateException("Unable to initialize GLFW");
// Configure GLFW
glfwDefaultWindowHints(); // optional, the current window hints are already the default
glfwWindowHint(GLFW_VISIBLE, GLFW_FALSE); // the window will stay hidden after creation
glfwWindowHint(GLFW_RESIZABLE, GLFW_TRUE); // the window will be resizable
// Create the window
window = glfwCreateWindow(300, 300, "Hello World!", NULL, NULL);
if ( window == NULL )
throw new RuntimeException("Failed to create the GLFW window");
// Setup a key callback. It will be called every time a key is pressed, repeated or released.
glfwSetKeyCallback(window, (window, key, scancode, action, mods) -> {
if ( key == GLFW_KEY_ESCAPE && action == GLFW_RELEASE )
glfwSetWindowShouldClose(window, true); // We will detect this in the rendering loop
});
// Get the thread stack and push a new frame
try ( MemoryStack stack = stackPush() ) {
IntBuffer pWidth = stack.mallocInt(1); // int*
IntBuffer pHeight = stack.mallocInt(1); // int*
// Get the window size passed to glfwCreateWindow
glfwGetWindowSize(window, pWidth, pHeight);
// Get the resolution of the primary monitor
GLFWVidMode vidmode = glfwGetVideoMode(glfwGetPrimaryMonitor());
// Center the window
glfwSetWindowPos(
window,
(vidmode.width() - pWidth.get(0)) / 2,
(vidmode.height() - pHeight.get(0)) / 2
);
} // the stack frame is popped automatically
// Make the OpenGL context current
glfwMakeContextCurrent(window);
// Enable v-sync
glfwSwapInterval(1);
// Make the window visible
glfwShowWindow(window);
}
private void loop() {
// This line is critical for LWJGL's interoperation with GLFW's
// OpenGL context, or any context that is managed externally.
// LWJGL detects the context that is current in the current thread,
// creates the GLCapabilities instance and makes the OpenGL
// bindings available for use.
GL.createCapabilities();
// Set the clear color
glClearColor(1.0f, 0.0f, 0.0f, 0.0f);
// Run the rendering loop until the user has attempted to close
// the window or has pressed the ESCAPE key.
while ( !glfwWindowShouldClose(window) ) {
glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT); // clear the framebuffer
glfwSwapBuffers(window); // swap the color buffers
// Poll for window events. The key callback above will only be
// invoked during this call.
this.input.update();
}
}
public static void main(String[] args) {
new HelloWorld().run();
}
}
And the
Input Handler itself:
public class InputHandler {
private long window;
private GLFWKeyCallback keyCallback;
public InputHandler() {
this.window = GLFW.glfwGetCurrentContext();
this.initInputs();
}
private void initInputs() {
glfwSetKeyCallback(this.window, this.keyCallback = GLFWKeyCallback.create((window, key, scancode, action, mods) -> {
this.keyInput(key, action, mods);
}));
}
public void update() {
glfwPollEvents();
}
public void dispose() {
this.keyCallback.free();
this.keyCallback = null;
}
public void keyInput(int key, int action, int mods) {
// TODO: ...
}
}
Any ideas why I'm getting this crash? I'm also wondering how someone should read this
hs_err_pid8052 file.. To me such a file looks like a lot of unreadable hex values (probaby memory addresses and their data???) printed out into a txt file. ^^
Thx in advance.
ShadowDragon
You dispose of the keycallback twice. Once in InputHandler.dispose() and then afterwards let LWJGL dispose of it again in HelloWorld.run() -> glfwFreeCallbacks, because LWJGL (or rather GLFW) does not know of your first disposal, since you did not clear/unregister the callback back in InputHandler.dispose().
Quote from: KaiHH on November 29, 2018, 19:10:04
You dispose of the keycallback twice. Once in InputHandler.dispose() and then afterwards let LWJGL dispose of it again in HelloWorld.run() -> glfwFreeCallbacks, because LWJGL (or rather GLFW) does not know of your first disposal, since you did not clear/unregister the callback back in InputHandler.dispose().
How would I let GLFW know that this callback has already been disposed?
For example by calling `glfwSetKeyCallback(window, null);` at the beginning of your InputHandler.dispose() - or just not doing anything in that method.
Thx. :)