Summary
The Windows x86_64 Vulkan native runtime ships a libstdc++-6.dll built for a
different MinGW-w64 configuration than the DLLs that import it. As a result
libllama.dll cannot be loaded at all: LoadLibraryEx fails with
ERROR_PROC_NOT_FOUND (127). No GPU backend is registered and the node falls
back to CPU only.
Affected versions
sha256(lib/libstdc++-6.dll) is
3529d11c422b2aaf0bbad7221bf62ba7b5a39f854e89a015bb58b6b55a677da1 in both
releases.
Environment
- Windows 10 (10.0.19044), x86_64
- Runtime:
meshllm-native-runtime-windows-x86_64-vulkan
Steps to reproduce
- Install the Windows Vulkan native runtime.
- From the runtime
lib directory, call LoadLibraryExW on libllama.dll
with LOAD_WITH_ALTERED_SEARCH_PATH.
- The call fails with error 127.
Expected
libllama.dll loads and the Vulkan backend registers its devices.
Actual
Load fails with error 127. Diffing the PE import tables of the shipped DLLs
against the export table of the shipped libstdc++-6.dll shows 16 imported
symbols that the bundled libstdc++-6.dll does not export.
ggml.dll (5 missing):
_ZNKSt25__codecvt_utf8_utf16_baseIwE10do_unshiftER9_MbstatetPcS3_RS3_
_ZNKSt25__codecvt_utf8_utf16_baseIwE5do_inER9_MbstatetPKcS4_RS4_PwS6_RS6_
_ZNKSt25__codecvt_utf8_utf16_baseIwE6do_outER9_MbstatetPKwS4_RS4_PcS6_RS6_
_ZNKSt25__codecvt_utf8_utf16_baseIwE9do_lengthER9_MbstatetPKcS4_y
_ZNSt7codecvtIwc9_MbstatetEC2Ey
libllama.dll (3 missing):
_ZNSo5seekpESt4fposI9_MbstatetE
__emutls_v._ZSt11__once_call
__emutls_v._ZSt15__once_callable
libllama-common.dll (8 missing): the five above plus
_ZNSt15basic_streambufIcSt11char_traitsIcEE7seekposESt4fposI9_MbstatetESt13_Ios_Openmode
__emutls_v._ZSt11__once_call
__emutls_v._ZSt15__once_callable
Analysis
The missing symbols identify a mismatch on two independent axes.
-
Threading model. The importers reference __emutls_v._ZSt11__once_call and
__emutls_v._ZSt15__once_callable, which a posix-threads libstdc++ emits.
The bundled libstdc++-6.dll instead exports __get_once_callv and
__get_once_callablev, which is the win32-threads form.
-
C runtime. The importers reference symbols mangled with 9_Mbstatet, which
is the UCRT mbstate_t. The bundled libstdc++-6.dll imports msvcrt.dll,
not the api-ms-win-crt-* UCRT stubs that the other runtime DLLs import.
So the ggml and llama DLLs are built with a UCRT posix-threads toolchain while
the bundled support DLL is an MSVCRT win32-threads build.
Confirmed by replacing only libstdc++-6.dll, libgcc_s_seh-1.dll and
libwinpthread-1.dll with the UCRT posix-threads equivalents (WinLibs
winlibs-x86_64-posix-seh-gcc-16.1.0-mingw-w64ucrt-14.0.0-r2). After the swap
the import diff reports zero missing symbols for every DLL in the package, all
11 DLLs load, and the Vulkan backend enumerates the device correctly.
Likely origin
scripts/windows-native-runtime-deps.py:
default_search_dirs() puts $VULKAN_SDK/Bin and $VULKAN_SDK/Bin32 ahead
of every PATH entry.
collect_dependencies() builds a filename keyed index and copies the first
match, with no check that the resolved DLL is ABI compatible with the
importer.
The LunarG SDK ships its own GCC runtime DLLs, so it wins that lookup.
scripts/build-llama.sh already documents this exact hazard around line 166,
including the resulting STATUS_ENTRYPOINT_NOT_FOUND (0xc0000139), and works
around it by putting the selected compiler's runtime directory first on PATH.
That workaround is applied to the build step only. The packaging script never
received the equivalent fix.
verify_dependencies() only reports missing files, so a resolved but ABI
incompatible DLL passes verification and ships.
Suggested fix
- In
windows-native-runtime-deps.py, resolve MinGW runtime DLLs from the
toolchain that built the artifacts (for example the directory of the g++
used by build-llama.sh) and search that before $VULKAN_SDK.
- Extend
verify_dependencies() to check that every imported symbol is
exported by the DLL that was actually bundled. That turns this class of
failure into a build error instead of a broken release.
Summary
The Windows x86_64 Vulkan native runtime ships a
libstdc++-6.dllbuilt for adifferent MinGW-w64 configuration than the DLLs that import it. As a result
libllama.dllcannot be loaded at all:LoadLibraryExfails withERROR_PROC_NOT_FOUND(127). No GPU backend is registered and the node fallsback to CPU only.
Affected versions
sha256(lib/libstdc++-6.dll)is3529d11c422b2aaf0bbad7221bf62ba7b5a39f854e89a015bb58b6b55a677da1in bothreleases.
Environment
meshllm-native-runtime-windows-x86_64-vulkanSteps to reproduce
libdirectory, callLoadLibraryExWonlibllama.dllwith
LOAD_WITH_ALTERED_SEARCH_PATH.Expected
libllama.dllloads and the Vulkan backend registers its devices.Actual
Load fails with error 127. Diffing the PE import tables of the shipped DLLs
against the export table of the shipped
libstdc++-6.dllshows 16 importedsymbols that the bundled
libstdc++-6.dlldoes not export.ggml.dll(5 missing):libllama.dll(3 missing):libllama-common.dll(8 missing): the five above plusAnalysis
The missing symbols identify a mismatch on two independent axes.
Threading model. The importers reference
__emutls_v._ZSt11__once_calland__emutls_v._ZSt15__once_callable, which a posix-threads libstdc++ emits.The bundled
libstdc++-6.dllinstead exports__get_once_callvand__get_once_callablev, which is the win32-threads form.C runtime. The importers reference symbols mangled with
9_Mbstatet, whichis the UCRT
mbstate_t. The bundledlibstdc++-6.dllimportsmsvcrt.dll,not the
api-ms-win-crt-*UCRT stubs that the other runtime DLLs import.So the ggml and llama DLLs are built with a UCRT posix-threads toolchain while
the bundled support DLL is an MSVCRT win32-threads build.
Confirmed by replacing only
libstdc++-6.dll,libgcc_s_seh-1.dllandlibwinpthread-1.dllwith the UCRT posix-threads equivalents (WinLibswinlibs-x86_64-posix-seh-gcc-16.1.0-mingw-w64ucrt-14.0.0-r2). After the swapthe import diff reports zero missing symbols for every DLL in the package, all
11 DLLs load, and the Vulkan backend enumerates the device correctly.
Likely origin
scripts/windows-native-runtime-deps.py:default_search_dirs()puts$VULKAN_SDK/Binand$VULKAN_SDK/Bin32aheadof every
PATHentry.collect_dependencies()builds a filename keyed index and copies the firstmatch, with no check that the resolved DLL is ABI compatible with the
importer.
The LunarG SDK ships its own GCC runtime DLLs, so it wins that lookup.
scripts/build-llama.shalready documents this exact hazard around line 166,including the resulting
STATUS_ENTRYPOINT_NOT_FOUND (0xc0000139), and worksaround it by putting the selected compiler's runtime directory first on
PATH.That workaround is applied to the build step only. The packaging script never
received the equivalent fix.
verify_dependencies()only reports missing files, so a resolved but ABIincompatible DLL passes verification and ships.
Suggested fix
windows-native-runtime-deps.py, resolve MinGW runtime DLLs from thetoolchain that built the artifacts (for example the directory of the
g++used by
build-llama.sh) and search that before$VULKAN_SDK.verify_dependencies()to check that every imported symbol isexported by the DLL that was actually bundled. That turns this class of
failure into a build error instead of a broken release.