GAL graphics/3D Viewer crashes under WSL2/Xvfb (existance of GLX_EXT_swap_control extension not being checked)
Description
I get a crash when running in accelerated mode, or in the 3D viewer on WSL2 (Ubuntu 20.04.4) using Xvfb.
Backtrace:
PCBNew:
#0 0x0000000000000000 in ()
#1 0x00007fffdceb21f3 in __glXGetDrawableAttribute (value=0x7fffffffc538, attribute=8433, drawable=<optimized out>, dpy=0x5555557f99b0) at ../src/glx/glx_pbuffer.c:311
#2 __glXGetDrawableAttribute (dpy=0x5555557f99b0, drawable=<optimized out>, attribute=8433, value=0x7fffffffc538) at ../src/glx/glx_pbuffer.c:241
#3 0x00007ffff213a2b9 in GL_UTILS::SetSwapInterval(int) (aVal=<optimized out>) at ./kicad/include/gl_utils.h:81
#4 KIGFX::OPENGL_GAL::init() (this=0x555558970400) at ./kicad/common/gal/opengl/opengl_gal.cpp:2310
#5 0x00007ffff213cc08 in KIGFX::OPENGL_GAL::CheckFeatures(KIGFX::GAL_DISPLAY_OPTIONS&) (aOptions=...) at ./kicad/common/gal/opengl/opengl_gal.cpp:352
#6 0x00007ffff211a4da in EDA_DRAW_PANEL_GAL::SwitchBackend(EDA_DRAW_PANEL_GAL::GAL_TYPE) (this=this@entry=0x555558154c00, aGalType=EDA_DRAW_PANEL_GAL::GAL_TYPE_OPENGL) at ./kicad/common/draw_panel_gal.cpp:441
#7 0x00007ffff1c9e453 in PCB_DRAW_PANEL_GAL::SwitchBackend(EDA_DRAW_PANEL_GAL::GAL_TYPE) (this=0x555558154c00, aGalType=<optimized out>) at ./kicad/pcbnew/pcb_draw_panel_gal.cpp:535
#8 0x00007ffff1692931 in PCB_EDIT_FRAME::PCB_EDIT_FRAME(KIWAY*, wxWindow*) (this=<optimized out>, aKiway=<optimized out>, aParent=<optimized out>) at ./kicad/pcbnew/pcb_edit_frame.cpp:323
#9 0x00007ffff1271a9b in PCB::IFACE::CreateWindow(wxWindow*, int, KIWAY*, int) (this=<optimized out>, aParent=0x0, aClassId=5, aKiway=0x55555576c680 <Kiway>, aCtlBits=<optimized out>) at ./kicad/pcbnew/pcbnew.cpp:84
#10 0x00005555555dc4d1 in KIWAY::Player(FRAME_T, bool, wxTopLevelWindow*) (this=0x55555576c680 <Kiway>, aFrameType=FRAME_PCB_EDITOR, doCreate=<optimized out>, aParent=0x0) at ./kicad/common/kiway.cpp:419
#11 0x00005555555d17f8 in PGM_SINGLE_TOP::OnPgmInit() (this=0x55555576c740 <program>) at ./kicad/common/single_top.cpp:368
#12 0x00005555555d4009 in APP_SINGLE_TOP::OnInit() (this=<optimized out>) at ./kicad/common/single_top.cpp:154
#13 0x00007ffff746779a in wxEntry(int&, wchar_t**) () at /lib/x86_64-linux-gnu/libwx_baseu-3.0.so.0
#14 0x000055555559e68c in main(int, char**) (argc=<optimized out>, argv=<optimized out>) at ./kicad/common/single_top.cpp:269
3d Viewer:
#0 0x0000000000000000 in ()
#1 0x00007fffec93f1f3 in __glXGetDrawableAttribute (value=0x55555d59d770, attribute=8433, drawable=<optimized out>, dpy=0x5555557f99b0) at ../src/glx/glx_pbuffer.c:311
#2 __glXGetDrawableAttribute (dpy=0x5555557f99b0, drawable=<optimized out>, attribute=8433, value=0x55555d59d770) at ../src/glx/glx_pbuffer.c:241
#3 0x00007ffff1abc316 in GL_UTILS::SetSwapInterval(int) (aVal=<optimized out>) at ./kicad/include/gl_utils.h:81
#4 EDA_3D_CANVAS::initializeOpenGL() (this=0x55555e118b60) at ./kicad/3d-viewer/3d_canvas/eda_3d_canvas.cpp:284
#5 0x00007ffff1abdcf0 in EDA_3D_CANVAS::DoRePaint() (this=0x55555e118b60) at ./kicad/3d-viewer/3d_canvas/eda_3d_canvas.cpp:401
#6 0x00007ffff755f641 in wxEvtHandler::ProcessEventIfMatchesId(wxEventTableEntryBase const&, wxEvtHandler*, wxEvent&) () at /lib/x86_64-linux-gnu/libwx_baseu-3.0.so.0
#7 0x00007ffff755f743 in wxEventHashTable::HandleEvent(wxEvent&, wxEvtHandler*) () at /lib/x86_64-linux-gnu/libwx_baseu-3.0.so.0
#8 0x00007ffff755faa0 in wxEvtHandler::TryHereOnly(wxEvent&) () at /lib/x86_64-linux-gnu/libwx_baseu-3.0.so.0
#9 0x00007ffff755fb2b in wxEvtHandler::ProcessEventLocally(wxEvent&) () at /lib/x86_64-linux-gnu/libwx_baseu-3.0.so.0
#10 0x00007ffff755fbd1 in wxEvtHandler::ProcessEvent(wxEvent&) () at /lib/x86_64-linux-gnu/libwx_baseu-3.0.so.0
#11 0x00007ffff75605b2 in wxEvtHandler::ProcessPendingEvents() () at /lib/x86_64-linux-gnu/libwx_baseu-3.0.so.0
#12 0x00007ffff73d98ff in wxAppConsoleBase::ProcessPendingEvents() () at /lib/x86_64-linux-gnu/libwx_baseu-3.0.so.0
#13 0x00007ffff78f86ea in wxGUIEventLoop::YieldFor(long) () at /lib/x86_64-linux-gnu/libwx_gtk3u_core-3.0.so.0
#14 0x00007ffff1b97a41 in PCB_BASE_FRAME::CreateAndShow3D_Frame() (this=0x55555802d060) at ./kicad/pcbnew/pcb_base_frame.cpp:626
#15 0x00007ffff1ce45d8 in PCB_VIEWER_TOOLS::Show3DViewer(TOOL_EVENT const&) (this=0x5555585a82e0, aEvent=...) at ./kicad/include/tool/tool_base.h:187
#16 0x00007ffff2003b50 in std::function<int (TOOL_EVENT const&)>::operator()(TOOL_EVENT const&) const (__args#0=..., this=0x5555587c4b70) at /usr/include/c++/9/bits/std_function.h:683
#17 COROUTINE<int, TOOL_EVENT const&>::callerStub(long) (aData=<optimized out>) at ./kicad/include/tool/coroutine.h:428
#18 0x00007ffff20aee01 in make_fcontext () at /usr/bin/_pcbnew.kiface
#19 0x34c83434c8231000 in ()
#20 0x002310003434c834 in ()
#21 0x2310002310002310 in ()
#22 0x0000000000000041 in ()
#23 0x00007fff00000001 in ()
#24 0x000055555e0d7030 in ()
#25 0x0000000000000000 in ()
gl_utils.h:81 points at glXQueryDrawable
unsigned clampedInterval;
glXSwapIntervalEXT( dpy, drawable, aVal );
glXQueryDrawable( dpy, drawable, GLX_SWAP_INTERVAL_EXT, &clampedInterval ); <=====
It's using GLX_EXT_swap_control
extension, but doesn't really check if it exists in glXQueryExtensionsString
.
glxinfo:
GLX version: 1.4
GLX extensions: // uses glXQueryExtensionsString, GLX_EXT_swap_control not supported nere
GLX_ARB_context_flush_control, GLX_ARB_create_context,
GLX_ARB_create_context_no_error, GLX_ARB_create_context_profile,
GLX_ARB_fbconfig_float, GLX_ARB_framebuffer_sRGB,
GLX_ARB_get_proc_address, GLX_ARB_multisample,
GLX_EXT_create_context_es2_profile, GLX_EXT_create_context_es_profile,
GLX_EXT_fbconfig_packed_float, GLX_EXT_framebuffer_sRGB,
GLX_EXT_import_context, GLX_EXT_no_config_context,
GLX_EXT_texture_from_pixmap, GLX_EXT_visual_info, GLX_EXT_visual_rating,
GLX_MESA_copy_sub_buffer, GLX_MESA_query_renderer, GLX_OML_swap_method,
GLX_SGIS_multisample, GLX_SGIX_fbconfig, GLX_SGIX_pbuffer,
GLX_SGIX_visual_select_group, GLX_SGI_make_current_read
Extended renderer info (GLX_MESA_query_renderer):
Vendor: Microsoft Corporation (0xffffffff)
Device: D3D12 (NVIDIA GeForce GTX 950M) (0xffffffff)
Version: 21.2.6
Accelerated: yes
Video memory: 10160MB
Unified memory: no
Preferred profile: core (0x1)
Max core profile version: 3.3
Max compat profile version: 3.1
Max GLES1 profile version: 1.1
Max GLES[23] profile version: 3.0
OpenGL vendor string: Microsoft Corporation
OpenGL renderer string: D3D12 (NVIDIA GeForce GTX 950M)
OpenGL core profile version string: 3.3 (Core Profile) Mesa 21.2.6
OpenGL core profile shading language version string: 3.30
OpenGL core profile context flags: (none)
OpenGL core profile profile mask: core profile
If this is fixed, the Mesa vendor check could be removed I think.
References in glmark2:
- https://github.com/glmark2/glmark2/blob/cf4496a1939d8aa0392406c8ee0aa9d02c3e4e39/src/gl-state-glx.cpp#L210
- https://github.com/glmark2/glmark2/blob/e5aa936583a7195b9e000b917c690e1b127895ca/src/glad/src/glx.c#L132
- https://github.com/glmark2/glmark2/blob/e5aa936583a7195b9e000b917c690e1b127895ca/src/glad/src/glx.c#L185
- https://github.com/glmark2/glmark2/blob/e5aa936583a7195b9e000b917c690e1b127895ca/src/glad/src/glx.c#L157
Steps to reproduce
On WSL2:
- Execute
export DISPLAY=:2
Xvfb $DISPLAY -screen 0 1400x1000x24 &
fluxbox &
x11vnc -display $DISPLAY -bg -forever -nopw -quiet -listen localhost -xkb
-
- Launch pcbnew and experience the crash.
- Or In pcbnew.json, set canvas_type to 2 then launch pcbnew and open 3D Viewer.
If OpenGL GL vendor string contains Mesa:
Сreate ~/.drirc with content to override vendor string:
<driconf>
<device screen="0" driver="swrast">
<application name="Default">
<option name="force_gl_vendor" value="Microsoft Corporation" />
</application>
</device>
</driconf>
Workaround
This bug can be worked around by creating ~/.drirc with this content:
<driconf>
<device screen="0" driver="swrast">
<application name="Default">
<option name="force_gl_vendor" value="Mesa" />
</application>
</device>
</driconf>
KiCad Version
Application: KiCad PCB Editor
Version: 6.0.5-a6ca702e91~116~ubuntu20.04.1, release build
Libraries:
wxWidgets 3.0.4
libcurl/7.68.0 OpenSSL/1.1.1f zlib/1.2.11 brotli/1.0.7 libidn2/2.2.0 libpsl/0.21.0 (+libidn2/2.2.0) libssh/0.9.3/openssl/zlib nghttp2/1.40.0 librtmp/2.3
Platform: Linux 4.19.128-microsoft-standard x86_64, 64 bit, Little endian, wxGTK, ,
Build Info:
Date: May 4 2022 07:55:51
wxWidgets: 3.0.4 (wchar_t,wx containers,compatible with 2.8) GTK+ 3.24
Boost: 1.71.0
OCC: 7.5.2
Curl: 7.83.0
ngspice: 36
Compiler: GCC 9.4.0 with C++ ABI 1013
Build settings:
KICAD_USE_OCC=ON
KICAD_SPICE=ON
Edited by dsa-t