NVIDIA drivers 470.xx crash when calling exit on a separate thread after creating two or more OpenGL contexts via EGL

The latest NVIDIA drivers (470.xx, tested versions: 470.42.01, 470.57.02, 470.63.01) crash (segfault, see stack trace below) when we create two or more OpenGL contexts via EGL and we quit the application by calling exit on a separate thread. The crash is reproducible on both Ubuntu (tested versions: 20.04, 21.04) and CentOS (tested version: 8.4). It does not happen with earlier drivers (465.xx and earlier, latest tested working version 465.19.01) and it does not happen if we only create a single context or call exit from the main thread. A minimal reproducer is available here: nvidia_crash_repro.cpp (954 Bytes)

The issue surfaced in a Java application that uses the JOGL Java OpenGL bindings library, where the exit system call is invoked on a JVM internal system thread different from the system main thread, even when calling System.exit on the Java main thread.

Is there an issue with how the contexts are created in the reproducer or is this a bug in the driver?

Stack trace:

#0  0x00007ffff5203410 in ?? () from /lib64/libnvidia-glsi.so.470.57.02
#1  0x00007ffff520913e in _nv004glsi () from /lib64/libnvidia-glsi.so.470.57.02
#2  0x00007ffff3826ff9 in ?? () from /lib64/libnvidia-eglcore.so.470.57.02
#3  0x00007ffff3819b46 in ?? () from /lib64/libnvidia-eglcore.so.470.57.02
#4  0x00007ffff383996b in ?? () from /lib64/libnvidia-eglcore.so.470.57.02
#5  0x00007ffff56a25df in ?? () from /lib64/libEGL_nvidia.so.0
#6  0x00007ffff56a26a7 in ?? () from /lib64/libEGL_nvidia.so.0
#7  0x00007ffff570e595 in ?? () from /lib64/libEGL_nvidia.so.0
#8  0x00007ffff570e60d in ?? () from /lib64/libEGL_nvidia.so.0
#9  0x00007ffff56a19e9 in ?? () from /lib64/libEGL_nvidia.so.0
#10 0x00007ffff570e845 in ?? () from /lib64/libEGL_nvidia.so.0
#11 0x00007ffff6a5bb0c in __run_exit_handlers () from /lib64/libc.so.6
#12 0x00007ffff6a5bc40 in exit () from /lib64/libc.so.6
#13 0x0000000000401018 in main::$_0::operator()() const ()
#14 0x0000000000401006 in void std::__invoke_impl<void, main::$_0>(std::__invoke_other, main::$_0&&) ()
#15 0x0000000000400ff6 in std::__invoke_result<main::$_0>::type std::__invoke<main::$_0>(main::$_0&&) ()
#16 0x0000000000400fe6 in std::thread::_Invoker<std::tuple<main::$_0> >::_M_invoke<0ul> ()
#17 0x0000000000400fd6 in std::thread::_Invoker<std::tuple<main::$_0> >::operator()() ()
#18 0x0000000000400fc6 in std::thread::_State_impl<std::thread::_Invoker<std::tuple<main::$_0> > >::_M_run() ()
#19 0x00007ffff7443ba3 in execute_native_thread_routine () from /lib64/libstdc++.so.6
#20 0x00007ffff771e14a in start_thread () from /lib64/libpthread.so.0
#21 0x00007ffff6b1edc3 in clone () from /lib64/libc.so.6