Windows build number:
10.0.26100.7628
Your Distribution version:
24.04.4 LTS
Your WSL versions:
WSL version: 2.6.3.0
Kernel version: 6.6.87.2-1
WSLg version: 1.0.71
MSRDC version: 1.2.6353
Direct3D version: 1.611.1-81528511
DXCore version: 10.0.26100.1-240331-1435.ge-release
Windows version: 10.0.26100.7628
WSLInterop is enabled
Steps to reproduce:
Compile any shared library that intercepts D3D12 functions using LD_PRELOAD:
# Example minimal hook (just logs and passes through)
g++ -shared -fPIC -o myhook.so myhook.cpp -ldl
LD_PRELOAD=./myhook.so vulkaninfo
- Observe WSL crash
Our Minimal Test Case
We created a transparent pass-through hook that only logs and forwards all calls unchanged:
// This transparent hook STILL crashes WSL
extern "C" HRESULT D3D12CreateDevice(...) {
// Just log and call real function
return real_D3D12CreateDevice(...);
}
Even with zero modification to the D3D12 calls, WSL crashes.
WSL logs:
No response
WSL dumps:
No response
Expected behavior:
LD_PRELOAD hooks should work (or at minimum, not crash WSL). Standard Linux debugging/profiling tools that use LD_PRELOAD should function.
Actual behavior:
WSL crashes with segfault inside libd3d12.so. The crash is caused by infinite recursion in D3D12GetInterface.
Stack Trace (from ASAN - similar pattern with LD_PRELOAD)
#0 D3D12GetInterface (/usr/lib/wsl/lib/libd3d12.so+0x467de)
#1 ...libd3d12.so (calls D3D12GetInterface again)
#2 ...libd3d12.so (recursive!)
#3 D3D12GetInterface (recursive!)
... repeats infinitely until stack overflow ...
Root Cause Analysis
The dzn driver (Mesa's Direct3D 12 driver for WSL) internally calls D3D12GetInterface which uses dlopen to load additional COM DLLs. When LD_PRELOAD is active:
- The hook intercepts D3D12 functions
- Even a transparent pass-through changes library loading order
- This triggers recursive library loading inside the proprietary Windows driver
- WSL crashes due to stack overflow
Key finding: The crash happens even with zero modification - just the presence of LD_PRELOAD changes symbol resolution, breaking the internal loading mechanism.
This is related to WSL issue #9244 (ASAN causes same crash), but LD_PRELOAD is a more general case that affects:
- Custom debugging hooks
- profiling tools (Valgrind, perf)
- Memory sanitizers
- Game mods/hooks
- Wine/DXVK when using certain configurations
Diagnostic Logs
Please run the following and capture output:
# Enable logging in our fix layer
CIV7_LAYER_LOG=1 VK_INSTANCE_LAYERS=VK_LAYER_CIV7_DUALSOURCE_BLEND_FIX vulkaninfo
# Check dmesg for errors
dmesg | tail -50
Suggested Fix Direction
While Vulkan Layers are the proper way to intercept Vulkan calls (and we have implemented a fix that way), the underlying issue is that LD_PRELOAD should not cause WSL to crash. Potential fixes:
- Fix in libd3d12.so: Prevent recursive dlopen by caching already-loaded interfaces
- Workaround in WSL: Detect LD_PRELOAD and warn/disable dzn gracefully
- Documentation: Clearly document that LD_PRELOAD is incompatible with WSLg graphics stack
Our Workaround
We implemented a Vulkan Layer that intercepts vkCreateGraphicsPipelines and returns VK_ERROR_FEATURE_NOT_PRESENT for unsupported dual-source blend configurations:
- Repository: [Link to your implementation]
- Usage:
VK_INSTANCE_LAYERS=VK_LAYER_CIV7_DUALSOURCE_BLEND_FIX vulkaninfo
This avoids the need for LD_PRELOAD but doesn't fix the underlying issue.
Vulkaninfo
==========
VULKANINFO
Vulkan Instance Version: 1.3.275
Instance Extensions: count = 12
VK_EXT_debug_report : extension revision 10
VK_EXT_debug_utils : extension revision 2
VK_EXT_headless_surface : extension revision 1
VK_EXT_layer_settings : extension revision 2
VK_KHR_device_group_creation : extension revision 1
VK_KHR_get_physical_device_properties2 : extension revision 2
VK_KHR_get_surface_capabilities2 : extension revision 1
VK_KHR_portability_enumeration : extension revision 1
VK_KHR_surface : extension revision 25
VK_KHR_xcb_surface : extension revision 6
VK_KHR_xlib_surface : extension revision 6
VK_LUNARG_direct_driver_loading : extension revision 1
Layers: count = 10
VK_LAYER_INTEL_nullhw (INTEL NULL HW) Vulkan version 1.1.73, layer version 1:
Layer Extensions: count = 0
Devices: count = 1
GPU id = 0 (Microsoft Direct3D12 (NVIDIA GeForce RTX 4080))
Layer-Device Extensions: count = 0
=== Graphics Driver ===
total 179004
drwxr-xr-x 1 root root 60 Mar 28 23:23 .
drwxr-xr-x 4 root root 4096 Mar 15 16:11 ..
-r-xr-xr-x 4 root root 171008 Jun 23 2025 libcuda.so
-r-xr-xr-x 4 root root 171008 Jun 23 2025 libcuda.so.1
-r-xr-xr-x 4 root root 171008 Jun 23 2025 libcuda.so.1.1
-r-xr-xr-x 2 root root 9742088 Jun 23 2025 libcudadebugger.so.1
-r-xr-xr-x 1 root root 801840 Oct 20 2023 libd3d12.so
-r-xr-xr-x 1 root root 6880344 Oct 20 2023 libd3d12core.so
-r-xr-xr-x 1 root root 942048 Apr 1 2024 libdxcore.so
-r-xr-xr-x 3 root root 19020552 Jun 23 2025 libnvcuvid.so
-r-xr-xr-x 3 root root 19020552 Jun 23 2025 libnvcuvid.so.1
-r-xr-xr-x 2 root root 153723328 Jun 23 2025 libnvdxdlkernels.so
-r-xr-xr-x 3 root root 272448 Jun 23 2025 libnvidia-encode.so
-r-xr-xr-x 3 root root 272448 Jun 23 2025 libnvidia-encode.so.1
-r-xr-xr-x 2 root root 260880 Jun 23 2025 libnvidia-ml.so.1
-r-xr-xr-x 2 root root 4578440 Jun 23 2025 libnvidia-ngx.so.1
-r-xr-xr-x 3 root root 67584 Jun 23 2025 libnvidia-opticalflow.so
-r-xr-xr-x 3 root root 67584 Jun 23 2025 libnvidia-opticalflow.so.1
-r-xr-xr-x 2 root root 72616 Jun 23 2025 libnvoptix.so.1
lrwxrwxrwx 1 root root 15 Mar 28 23:23 libnvoptix_loader.so.1 -> libnvoptix.so.1
-r-xr-xr-x 2 root root 99206488 Jun 23 2025 libnvwgf2umx.so
-r-xr-xr-x 2 root root 5047376 Jun 23 2025 nvidia-ngx-updater
-r-xr-xr-x 2 root root 823096 Jun 23 2025 nvidia-smi
Windows build number:
10.0.26100.7628
Your Distribution version:
24.04.4 LTS
Your WSL versions:
WSL version: 2.6.3.0
Kernel version: 6.6.87.2-1
WSLg version: 1.0.71
MSRDC version: 1.2.6353
Direct3D version: 1.611.1-81528511
DXCore version: 10.0.26100.1-240331-1435.ge-release
Windows version: 10.0.26100.7628
WSLInterop is enabled
Steps to reproduce:
Compile any shared library that intercepts D3D12 functions using LD_PRELOAD:
# Example minimal hook (just logs and passes through) g++ -shared -fPIC -o myhook.so myhook.cpp -ldl LD_PRELOAD=./myhook.so vulkaninfoOur Minimal Test Case
We created a transparent pass-through hook that only logs and forwards all calls unchanged:
Even with zero modification to the D3D12 calls, WSL crashes.
WSL logs:
No response
WSL dumps:
No response
Expected behavior:
LD_PRELOAD hooks should work (or at minimum, not crash WSL). Standard Linux debugging/profiling tools that use LD_PRELOAD should function.
Actual behavior:
WSL crashes with segfault inside libd3d12.so. The crash is caused by infinite recursion in D3D12GetInterface.
Stack Trace (from ASAN - similar pattern with LD_PRELOAD)
Root Cause Analysis
The dzn driver (Mesa's Direct3D 12 driver for WSL) internally calls
D3D12GetInterfacewhich usesdlopento load additional COM DLLs. When LD_PRELOAD is active:Key finding: The crash happens even with zero modification - just the presence of LD_PRELOAD changes symbol resolution, breaking the internal loading mechanism.
This is related to WSL issue #9244 (ASAN causes same crash), but LD_PRELOAD is a more general case that affects:
Diagnostic Logs
Please run the following and capture output:
Suggested Fix Direction
While Vulkan Layers are the proper way to intercept Vulkan calls (and we have implemented a fix that way), the underlying issue is that LD_PRELOAD should not cause WSL to crash. Potential fixes:
Our Workaround
We implemented a Vulkan Layer that intercepts vkCreateGraphicsPipelines and returns VK_ERROR_FEATURE_NOT_PRESENT for unsupported dual-source blend configurations:
VK_INSTANCE_LAYERS=VK_LAYER_CIV7_DUALSOURCE_BLEND_FIX vulkaninfoThis avoids the need for LD_PRELOAD but doesn't fix the underlying issue.
Vulkaninfo
==========
VULKANINFO
Vulkan Instance Version: 1.3.275
Instance Extensions: count = 12
Layers: count = 10
VK_LAYER_INTEL_nullhw (INTEL NULL HW) Vulkan version 1.1.73, layer version 1:
Layer Extensions: count = 0
Devices: count = 1
GPU id = 0 (Microsoft Direct3D12 (NVIDIA GeForce RTX 4080))
Layer-Device Extensions: count = 0
=== Graphics Driver ===
total 179004
drwxr-xr-x 1 root root 60 Mar 28 23:23 .
drwxr-xr-x 4 root root 4096 Mar 15 16:11 ..
-r-xr-xr-x 4 root root 171008 Jun 23 2025 libcuda.so
-r-xr-xr-x 4 root root 171008 Jun 23 2025 libcuda.so.1
-r-xr-xr-x 4 root root 171008 Jun 23 2025 libcuda.so.1.1
-r-xr-xr-x 2 root root 9742088 Jun 23 2025 libcudadebugger.so.1
-r-xr-xr-x 1 root root 801840 Oct 20 2023 libd3d12.so
-r-xr-xr-x 1 root root 6880344 Oct 20 2023 libd3d12core.so
-r-xr-xr-x 1 root root 942048 Apr 1 2024 libdxcore.so
-r-xr-xr-x 3 root root 19020552 Jun 23 2025 libnvcuvid.so
-r-xr-xr-x 3 root root 19020552 Jun 23 2025 libnvcuvid.so.1
-r-xr-xr-x 2 root root 153723328 Jun 23 2025 libnvdxdlkernels.so
-r-xr-xr-x 3 root root 272448 Jun 23 2025 libnvidia-encode.so
-r-xr-xr-x 3 root root 272448 Jun 23 2025 libnvidia-encode.so.1
-r-xr-xr-x 2 root root 260880 Jun 23 2025 libnvidia-ml.so.1
-r-xr-xr-x 2 root root 4578440 Jun 23 2025 libnvidia-ngx.so.1
-r-xr-xr-x 3 root root 67584 Jun 23 2025 libnvidia-opticalflow.so
-r-xr-xr-x 3 root root 67584 Jun 23 2025 libnvidia-opticalflow.so.1
-r-xr-xr-x 2 root root 72616 Jun 23 2025 libnvoptix.so.1
lrwxrwxrwx 1 root root 15 Mar 28 23:23 libnvoptix_loader.so.1 -> libnvoptix.so.1
-r-xr-xr-x 2 root root 99206488 Jun 23 2025 libnvwgf2umx.so
-r-xr-xr-x 2 root root 5047376 Jun 23 2025 nvidia-ngx-updater
-r-xr-xr-x 2 root root 823096 Jun 23 2025 nvidia-smi