[REGRESSION] Crash in `loader_dri3_wait_gl()` due to `dri3_front_buffer(draw) == NULL`
System information
System:
Host: constantine-N61Ja Kernel: 6.2.8-zen1-1-zen arch: x86_64 bits: 64
compiler: gcc v: 12.2.1 Desktop: KDE Plasma v: 5.27.3 tk: Qt v: 5.15.8
wm: i3 dm: SDDM Distro: Arch Linux
CPU:
Info: dual core model: Intel Core i5-7200U bits: 64 type: MT MCP
arch: Amber/Kaby Lake note: check rev: 9 cache: L1: 128 KiB L2: 512 KiB
L3: 3 MiB
Speed (MHz): avg: 1595 high: 2700 min/max: 400/3100 cores: 1: 2700 2: 483
3: 2700 4: 500 bogomips: 21599
Flags: avx avx2 ht lm nx pae sse sse2 sse3 sse4_1 sse4_2 ssse3 vmx
Graphics:
Device-1: Intel HD Graphics 620 vendor: Dell driver: i915 v: kernel
arch: Gen-9.5 ports: active: eDP-1 empty: HDMI-A-1 bus-ID: 00:02.0
chip-ID: 8086:5916
Device-2: AMD Topaz XT [Radeon R7 M260/M265 / M340/M360 M440/M445 530/535
620/625 Mobile] vendor: Dell driver: amdgpu v: kernel arch: GCN-3 pcie:
speed: 2.5 GT/s lanes: 4 bus-ID: 01:00.0 chip-ID: 1002:6900 temp: 35.0 C
Device-3: Sunplus Innovation Integrated_Webcam_HD type: USB
driver: uvcvideo bus-ID: 1-5:4 chip-ID: 1bcf:28c1
Display: x11 server: X.Org v: 21.1.7 with: Xwayland v: 23.1.0
compositor: Picom v: git-b700a driver: X: loaded: modesetting
alternate: fbdev,intel,vesa dri: iris gpu: i915 display-ID: :0 screens: 1
Screen-1: 0 s-res: 1920x1080 s-dpi: 96
Monitor-1: eDP-1 model: BOE Display 0x0695 res: 1920x1080 dpi: 128
diag: 434mm (17.1")
API: OpenGL v: 4.6 Mesa 23.0.3 renderer: Mesa Intel HD Graphics 620 (KBL
GT2) direct-render: Yes
Describe the issue
I am researching a problem where WINE game Heroes Ⅲ: In The Wake Of God
stops updating a screen after opening WOG options; unless run with LIBGL_ALWAYS_SOFTWARE=true
or MESA_LOADER_DRIVER_OVERRIDE=zink
.
When run with WINEDEBUG=+opengl
, the problem triggers a print warn:opengl:glFlush glFlush returned 0xc0000005
. Turns out, it's a Segmentation Fault which wine intercepts and shows as a 0xc0000005
.
The reason of the crash is that in this line the front
is NULL
, which then a few lines below gets dereferenced as front->pixmap
.
The stack trace at commit dabc5289:
#0 0x7d7f5299 in loader_dri3_wait_gl (draw=0x7afa5e2c) at ../mesa/src/loader/loader_dri3_helper.c:969
#1 0x7d7ed736 in dri3_flush_front_buffer (driDrawable=0x7af8d8d0, loaderPrivate=0x7afa5e2c) at ../mesa/src/glx/dri3_glx.c:484
#2 0x78030c07 in dri2_flush_frontbuffer (ctx=0x7af007f0, drawable=0x7af8d8d0, statt=ST_ATTACHMENT_FRONT_LEFT) at ../mesa/src/gallium/frontends/dri/dri2.c:808
#3 0x78034d0b in dri_st_framebuffer_flush_front (st=0x7af8a030, pdrawable=0x7af8d8d0, statt=ST_ATTACHMENT_FRONT_LEFT) at ../mesa/src/gallium/frontends/dri/dri_drawable.c:129
#4 0x78134004 in st_manager_flush_frontbuffer (st=0x7af8a030) at ../mesa/src/mesa/state_tracker/st_manager.c:1219
#5 0x78116d0c in st_glFlush (ctx=0x7af44330, gallium_flush_flags=0) at ../mesa/src/mesa/state_tracker/st_cb_flush.c:101
#6 0x78351b21 in _mesa_make_current (newCtx=0x0, drawBuffer=0x0, readBuffer=0x0) at ../mesa/src/mesa/main/context.c:1487
#7 0x78133f27 in st_api_make_current (st=0x0, stdrawi=0x0, streadi=0x0) at ../mesa/src/mesa/state_tracker/st_manager.c:1179
#8 0x78034391 in dri_unbind_context (ctx=0x7af007f0) at ../mesa/src/gallium/frontends/dri/dri_context.c:295
#9 0x7803960c in driUnbindContext (pcp=0x7af007f0) at ../mesa/src/gallium/frontends/dri/dri_util.c:735
#10 0x7d7ecf76 in dri3_unbind_context (context=0x7afa9620) at ../mesa/src/glx/dri3_glx.c:197
#11 0x7d7d8904 in MakeContextCurrent (dpy=0x7ddd7b30, draw=127926460, read=127926460, gc_user=0x7afa9620, opcode=26) at ../mesa/src/glx/glxcurrent.c:127
#12 0x7d7d8a63 in glXMakeContextCurrent (dpy=0x7ddd7b30, d=127926460, r=127926460, ctx=0x7afa9620) at ../mesa/src/glx/glxcurrent.c:186
#13 0x7d84211a in ?? () from /usr/lib32/libGLX.so.0.0.0
#14 0x7d848eaf in ?? () from /usr/lib32/libGLX.so.0.0.0
#15 0x7e19e6f6 in sync_context (context=0x7afa54c0) at ../dlls/winex11.drv/opengl.c:1223
#16 wglFlush () at ../dlls/winex11.drv/opengl.c:2010
#17 0x7e213125 in gl_glFlush (args=0x8d8fa9c) at ../dlls/opengl32/unix_thunks.c:810
The fix is really simple:
diff --git a/src/loader/loader_dri3_helper.c b/src/loader/loader_dri3_helper.c
index 63be04ed2a4..d109bdc4a79 100644
--- a/src/loader/loader_dri3_helper.c
+++ b/src/loader/loader_dri3_helper.c
@@ -955,6 +955,8 @@ loader_dri3_wait_gl(struct loader_dri3_drawable *draw)
return;
front = dri3_front_buffer(draw);
+ if (!front)
+ return;
/* In the psc->is_different_gpu case, we update the linear_buffer
* before updating the real front.
with such change the game runs fine for me as far as I've tested.
However, I don't know these internals: is front
pointer even supposed to be NULL
? Is my fix correct?
I don't know, so before going forward and sending the patch I decided to create this issue in case someone might shed some light on that.
Steps to reproduce
- Install
In The Wake Of Gods
addon (tested with an older3.58f
available at this link). - Run
WINEDEBUG=+opengl wine h3wog.exe
, wait for game window to appear - Click
New Game
- Click
Scenario
- Click
WOG Options
in the upper-right corner.
Expected
A menu shows up
Actual
The game hangs (only music continues playing), and the wine log shows a warn:opengl:glFlush glFlush returned 0xc0000005
.
Additional information
The problem is reproduced on at least two different systems: Archlinux and Fedora 38