We develop a Java software that uses SWT and JOGL to render into an OpenGL context.
Recently we found out that there is a bug that enough resizing will crash the program (resp. the Graphics Drivers) when swapping buffers. This happens only on a few hardware configurations (my primary config is at the bottom).
E.g. my secondary PC with a Ryzen 5950X and an Nvidia RTX 3070 never crashes on resize.
The actual crash is this:
Unhandled exception at 0x00007FFCC5C14340 (atio6axx.dll) in hs_err_pid16940.mdmp: 0xC0000005: Access violation reading location 0x0000000087872270.
With the following stacktrace:
The swap buffer call comes through the Java function org.eclipse.swt.internal.opengl.win32.WGL.SwapBuffers().
I ran many GL traces and also other logging to see if anything is different in the resize event when the crash happens compared to all previous resize events. So far I couldn't find anything that differs (Hardware handles, Stack traces, etc.).
Even the openGL trace looks exactly the same (except for the glViewport arguments obviously). Also the container we render into has the same size as is set with glViewport.
To reproduce the bug please follow these steps:
Any help debugging this issue is highly appreciated. I can also provide a minidump file if that helps.
Thanks a lot!
My Primary System:
CPU: Core i9-9900
RAM: 32GB
GPUs: Intel UHD Graphics 630 / AMD Radeon RX 5700 XT (used for program)
OS: Win 10.0.19042
AMD Driver version: 22.3.1 (released 3/9/2022)
Solved! Go to Solution.
A colleague of mine figured it out:
It turns out the Dell Nahimic service and Asus Sonic Suite use some weird injection code.
For us the problem solved itself after disabling these services.
Hi @sgoetschi_esri ,
Thank you for reporting it. I'm moving the post to the AMD OpenGL forum.
Also, I have whitelisted you.
Thanks.
I invested a bit more time into this issue and reduced it down down to a rather short program that also crashes.
import java.util.Timer;
import java.util.TimerTask;
import org.eclipse.swt.SWT;
import org.eclipse.swt.layout.FillLayout;
import org.eclipse.swt.opengl.GLCanvas;
import org.eclipse.swt.opengl.GLData;
import org.eclipse.swt.widgets.Composite;
import org.eclipse.swt.widgets.Display;
import org.eclipse.swt.widgets.Shell;
public class Program {
private static final boolean renderAsync = true;
private static SAGLCanvas canvas;
private static final Timer animTimer = new Timer();
public static void main(String[] args) {
Display display = Display.getDefault();
Shell shell = new Shell(display, SWT.RESIZE | SWT.CLOSE);
shell.setLayout(new FillLayout());
canvas = new SAGLCanvas(shell, SWT.NULL, null);
shell.open();
if (renderAsync)
animTimer.schedule(new RenderTask(), 500, 200);
try {
while (!shell.isDisposed()) {
if (!display.readAndDispatch()) {
if (!renderAsync)
canvas.render();
display.sleep();
}
}
} finally {
if (renderAsync)
animTimer.cancel();
}
}
private static class RenderTask extends TimerTask {
@Override
public void run() {
Display.getDefault().asyncExec(() -> canvas.render());
}
}
public static class SAGLCanvas extends GLCanvas {
public SAGLCanvas(Composite parent, int style, GLData data) {
super(parent, style, new GLData());
}
public void render() {
if (isDisposed() || !isVisible())
return;
swapBuffers();
}
}
}
This is the only code necessary. You need to add the org.eclipse.swt.win32.win32.x86_64_3.114.100.jar library though (Downloadable from here).
The flag renderAsync can be used to redraw every 200-500ms (true) or to only redraw when the resize is actually finished (false).
The program crashes either way for me - it's just much more work to get it to crash when not redrawing while resizing.
The crash happens inside swapBuffers() which calls WGL.SwapBuffers (hDC) which is a native call that I don't see inside. From there it goes into the openGL drivers as seen in the stacktrace above.
Any help is highly appreciated.
A colleague of mine figured it out:
It turns out the Dell Nahimic service and Asus Sonic Suite use some weird injection code.
For us the problem solved itself after disabling these services.