Skip to content

Segfault with glGenBuffers/glDeleteBuffers on Nvidia when the thread/program exits #1027

@micheal65536

Description

@micheal65536

Version

3.3.4

Platform

Linux x64

JDK

OpenJDK 8

Module

EGL, GLES

Bug description

On Nvidia GTX 1070 I am experiencing the following segfaults:

  • if glGenBuffers is called at any point with an array size that is not an exact multiple of 128, the program later segfaults when the relevant thread exits
  • if glDeleteBuffers is called at any point, the program segfaults when the relevant thread exits (not immediately after the call to glDeleteBuffers)

No issue on integrated Intel HD graphics.

public static void crash(int count, boolean delete)
{
	long offscreenDisplay = EGL15.eglGetDisplay(EGL15.EGL_DEFAULT_DISPLAY);
	EGL15.eglInitialize(offscreenDisplay, new int[]{0}, new int[]{0});

	PointerBuffer config = PointerBuffer.allocateDirect(1);
	EGL15.eglChooseConfig(offscreenDisplay, new int[]{
			EGL15.EGL_RENDERABLE_TYPE, EGL15.EGL_OPENGL_ES3_BIT,
			EGL15.EGL_SURFACE_TYPE, EGL15.EGL_PBUFFER_BIT,
			EGL15.EGL_RED_SIZE, 8,
			EGL15.EGL_GREEN_SIZE, 8,
			EGL15.EGL_BLUE_SIZE, 8,
			EGL15.EGL_ALPHA_SIZE, 8,
			EGL15.EGL_DEPTH_SIZE, 0,
			EGL15.EGL_STENCIL_SIZE, 0,
			EGL15.EGL_NONE
	}, config, new int[]{0});

	long offscreenSurface = EGL15.eglCreatePbufferSurface(offscreenDisplay, config.get(0), new int[]{
			EGL15.EGL_WIDTH, 8, EGL15.EGL_HEIGHT, 8,
			EGL15.EGL_NONE
	});

	long offscreenContext = EGL15.eglCreateContext(offscreenDisplay, config.get(0), EGL15.EGL_NO_CONTEXT, new int[]{
			EGL15.EGL_CONTEXT_CLIENT_VERSION, 3,
			EGL15.EGL_NONE
	});

	EGL15.eglMakeCurrent(offscreenDisplay, offscreenSurface, offscreenSurface, offscreenContext);
	GLES.createCapabilities();

	int[] ids = new int[count];
	GLES30.glGenBuffers(ids);

	if (delete)
	{
		GLES30.glDeleteBuffers(ids);
	}

	EGL15.eglMakeCurrent(offscreenDisplay, EGL15.EGL_NO_SURFACE, EGL15.EGL_NO_SURFACE, EGL15.EGL_NO_CONTEXT);
	EGL15.eglDestroyContext(offscreenDisplay, offscreenContext);
	EGL15.eglDestroySurface(offscreenDisplay, offscreenSurface);
	EGL15.eglTerminate(offscreenDisplay);
}

The following will trigger the segfault after ~5 seconds, after the "exiting thread" message is displayed:

new Thread(() ->
{
	crash(3, false);

	System.out.println("still alive");
	try
	{
		Thread.sleep(5000);
	}
	catch (InterruptedException exception)
	{
		//
	}
	System.out.println("exiting thread");
}).start();

Examples of parameters which crash:

crash(3, false);
crash(129, false);
crash(128, true);
crash(256, true);

Does not crash:

crash(128, false);
crash(256, false);

I suspect use after free in the Nvidia library implementation but I can't construct a native example with the same/similar behavior. The 128 "alignment" aspect may be specific to my particular system/JVM version and it's possible that other alignments may behave differently on different systems.

Stacktrace or crash log output

No response

Metadata

Metadata

Assignees

No one assigned

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions