Skip to content

Shutdown crash in SPIRV-tools due to allocator mismatch #8086

@dpelksnitis

Description

@dpelksnitis

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.

Metadata

Metadata

Assignees

No one assigned

    Labels

    bugBug, regression, crashneeds-triageAwaiting triage

    Type

    No type

    Projects

    Status

    No status

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions