microsoft / microsoft/DirectXShaderCompiler
Shutdown crash in SPIRV-tools due to allocator mismatch
Nobody has claimed this yet.
- Dominant language
- C++
- Stars
- 3.7k
- Forks
- 900
- Avg merge
- 2d 11h
- Merged PRs (30d)
- 44
Description
Hi,
I'm looking into a shutdown crash we are encountering with SPIRV-tools when compiling shaders for Vulkan in UE when using a custom IMalloc instance. The callstack is the following:
dxcompiler.dll!DxcDelete(void * ptr) Line 137 C++ [Inline Frame] dxcompiler.dll!std::_Deallocate(void * _Ptr, unsigned __int64 _Bytes) Line 289 C++ [Inline Frame] dxcompiler.dll!std::_Default_allocator_traits<std::allocator<std::_List_node<spv::Op,void *>>>::deallocate(std::allocator<std::_List_node<spv::Op,void *>> & _Al, std::_List_node<spv::Op,void *> * const _Ptr, const unsigned __int64 _Count) Line 723 C++ [Inline Frame] dxcompiler.dll!std::_List_node<spv::Op,void *>::_Freenode0(std::allocator<std::_List_node<spv::Op,void *>> & _Al, std::_List_node<spv::Op,void *> * _Ptr) Line 312 C++ [Inline Frame] dxcompiler.dll!std::_List_node<spv::Op,void *>::_Freenode(std::allocator<std::_List_node<spv::Op,void *>> & _Al, std::_List_node<spv::Op,void *> * _Ptr) Line 318 C++ [Inline Frame] dxcompiler.dll!std::_List_node<spv::Op,void *>::_Free_non_head(std::allocator<std::_List_node<spv::Op,void *>> & _Al, std::_List_node<spv::Op,void *> * _Head) Line 329 C++ dxcompiler.dll!std::list<spv::Op,std::allocator<spv::Op>>::_Tidy() Line 1518 C++ ucrtbase.dll!00007ffc696abc75() Unknown ucrtbase.dll!00007ffc696ab897() Unknown ucrtbase.dll!00007ffc696ab84d() Unknown dxcompiler.dll!dllmain_crt_process_detach(const bool is_terminating) Line 182 C++ dxcompiler.dll!dllmain_dispatch(HINSTANCE__ * const instance, const unsigned long reason, void * const reserved) Line 293 C++
I've tracked this down to some function-local static standard library containers in SPIRV-tools validate_id.cpp, within the InstructionCanHaveTypeOperand and InstructionRequiresTypeOperand functions; these are allocated on first use after we've registered our custom allocator, but this override is cleared on shutdown and the DLL main detach procedure tries to free them using the default malloc instance instead. I've been able to work around these by replacing the heap-allocated std::unordered_maps with simple static arrays and using std::find.
I will note we've hit a similar issue in the past; not sure if it's possible to consider some sort of more systemic fix with how the allocator overrides work to prevent such issues in the future?
I'm also happy to submit a PR with my workaround if there's no better fix that can be suggested.
Contributor guide
First steps
- Read the whole issue, then the project's contributing guide.
- Comment on the issue to say you are picking it up — it saves two people doing the same work.
- Fork the repository and make your change on a branch.
- Open a pull request that references the issue number.
Research direction
Start in validate_id.cpp at InstructionCanHaveTypeOperand and InstructionRequiresTypeOperand, then review the shutdown path shown in the call stack around dllmain_crt_process_detach. Reproduce compilation with a custom IMalloc and verify whether the function-local containers are freed after the allocator override is cleared. Done means the shutdown crash is resolved without regressing SPIRV-tools validation.
Written by the indexing model from the issue text.
Assessment
- Tech stack
- cpp
- Domain
- compilers
- Issue type
- Bug
- Difficulty
- 4/5
- Estimated time
- 3-5 days
- Activity status
- Stale
- Clarity
- Mostly clear
- Newbie friendliness
- 35/100