microsoft / DirectXShaderCompiler

This repo hosts the source for the DirectX Shader Compiler which is based on LLVM/Clang.
Other
3.11k stars 698 forks source link

[SPIR-V] crash compiling shader using printf #3768

Open baldurk opened 3 years ago

baldurk commented 3 years ago

I get a crash when compiling shaders to SPIR-V with printf. It seems to be a bit inconsistent and from what I can tell there are unit tests of this that seem to pass, so I think it might be some memory corruption of some kind.

Note all the builds below have -fcgl -Vd to disable legalization, since there's a current spirv-tools issue that would crash and confuse issues: KhronosGroup/SPIRV-Tools#4219

Running dxc from the latest appveyor or latest vulkan SDK distribution and building the intrinsics.printf.hlsl test shader hits an ICE fairly consistently for me:

$ tmp/bin/dxc.exe -help | head -n 3
OVERVIEW: HLSL Compiler for Windows

Version: dxcompiler.dll: 1.7 - 1.6.0.3148 (742657ade); dxil.dll: 1.5(10.0.19041.685)
$ tmp/bin/dxc.exe -fcgl -Vd -T ps_6_0 -E main -spirv intrinsics.printf.hlsl
Internal compiler error: access violation. Attempted to read from address 0x00000154C3669308
Segmentation fault
$ /c/VulkanSDK/1.2.176.1/Bin/dxc.exe -help | head -n 3
OVERVIEW: HLSL Compiler for Windows

Version: dxcompiler.dll: 1.7 - 1.6.0.3117 (3be3d15fc); dxil.dll: 1.5(10.0.19041.685)
$ /c/VulkanSDK/1.2.176.1/Bin/dxc.exe -fcgl -Vd -T ps_6_0 -E main -spirv intrinsics.printf.hlsl
Internal compiler error: access violation. Attempted to read from address 0x00000730F44E0EB8
Segmentation fault

Weirdly if I build locally from source in debug it works. In release it works from visual studio but fails on the command line - perhaps due to differences in debug heap. Attaching to the release build gives a callstack of:

    ntdll.dll!RtlFreeHeap()    Unknown
    ole32.dll!CRetailMalloc_Free(IMalloc * pThis, void * pv) Line 687   C++
>   [Inline Frame] dxcompiler.dll!llvm::MallocAllocator::Deallocate(const void *) Line 103  C++
    [Inline Frame] dxcompiler.dll!llvm::BumpPtrAllocatorImpl<llvm::MallocAllocator,4096,4096>::DeallocateSlabs(void * * I, void * * E) Line 326 C++
    dxcompiler.dll!llvm::BumpPtrAllocatorImpl<llvm::MallocAllocator,4096,4096>::~BumpPtrAllocatorImpl<llvm::MallocAllocator,4096,4096>() Line 166   C++
    dxcompiler.dll!clang::Sema::BuildOverloadedCallExpr(clang::Scope * S, clang::Expr * Fn, clang::UnresolvedLookupExpr * ULE, clang::SourceLocation LParenLoc, llvm::MutableArrayRef<clang::Expr *> Args, clang::SourceLocation RParenLoc, clang::Expr * ExecConfig, bool AllowTypoCorrection) Line 11082  C++
    dxcompiler.dll!clang::Sema::ActOnCallExpr(clang::Scope * S, clang::Expr * Fn, clang::SourceLocation LParenLoc, llvm::MutableArrayRef<clang::Expr *> ArgExprs, clang::SourceLocation RParenLoc, clang::Expr * ExecConfig, bool IsExecConfig) Line 5001   C++
    dxcompiler.dll!clang::Parser::ParsePostfixExpressionSuffix(clang::ActionResult<clang::Expr *,1> LHS) Line 1655  C++
    dxcompiler.dll!clang::Parser::ParseCastExpression(bool isUnaryExpression, bool isAddressOfOperand, bool & NotCastExpr, clang::Parser::TypeCastState isTypeCast) Line 1460   C++
    dxcompiler.dll!clang::Parser::ParseCastExpression(bool isUnaryExpression, bool isAddressOfOperand, clang::Parser::TypeCastState isTypeCast) Line 484    C++
    dxcompiler.dll!clang::Parser::ParseAssignmentExpression(clang::Parser::TypeCastState isTypeCast) Line 178   C++
    dxcompiler.dll!clang::Parser::ParseExpression(clang::Parser::TypeCastState isTypeCast) Line 122 C++
    dxcompiler.dll!clang::Parser::ParseExprStatement() Line 456 C++
    dxcompiler.dll!clang::Parser::ParseStatementOrDeclarationAfterAttributes(llvm::SmallVector<clang::Stmt *,32> & Stmts, bool OnlyStatement, clang::SourceLocation * TrailingElseLoc, clang::Parser::ParsedAttributesWithRange & Attrs) Line 447   C++
    dxcompiler.dll!clang::Parser::ParseStatementOrDeclaration(llvm::SmallVector<clang::Stmt *,32> & Stmts, bool OnlyStatement, clang::SourceLocation * TrailingElseLoc) Line 113    C++
    dxcompiler.dll!clang::Parser::ParseCompoundStatementBody(bool isStmtExpr) Line 1048 C++
    dxcompiler.dll!clang::Parser::ParseFunctionStatementBody(clang::Decl * Decl, clang::Parser::ParseScope & BodyScope) Line 1985   C++
    dxcompiler.dll!clang::Parser::ParseFunctionDefinition(clang::ParsingDeclarator & D, const clang::Parser::ParsedTemplateInfo & TemplateInfo, clang::Parser::LateParsedAttrList * LateParsedAttrs) Line 1177  C++
    dxcompiler.dll!clang::Parser::ParseDeclGroup(clang::ParsingDeclSpec & DS, unsigned int Context, clang::SourceLocation * DeclEnd, clang::Parser::ForRangeInit * FRI) Line 2399   C++
    dxcompiler.dll!clang::Parser::ParseDeclOrFunctionDefInternal(clang::Parser::ParsedAttributesWithRange & attrs, clang::ParsingDeclSpec & DS, clang::AccessSpecifier AS) Line 966 C++
    dxcompiler.dll!clang::Parser::ParseDeclarationOrFunctionDefinition(clang::Parser::ParsedAttributesWithRange & attrs, clang::ParsingDeclSpec * DS, clang::AccessSpecifier AS) Line 981   C++
    dxcompiler.dll!clang::Parser::ParseExternalDeclaration(clang::Parser::ParsedAttributesWithRange & attrs, clang::ParsingDeclSpec * DS) Line 839  C++
    dxcompiler.dll!clang::Parser::ParseTopLevelDecl(clang::OpaquePtr<clang::DeclGroupRef> & Result) Line 606    C++
    dxcompiler.dll!clang::ParseAST(clang::Sema & S, bool PrintStats, bool SkipFunctionBodies) Line 146  C++
    dxcompiler.dll!clang::ASTFrontendAction::ExecuteAction() Line 554   C++
    dxcompiler.dll!clang::FrontendAction::Execute() Line 469    C++
    dxcompiler.dll!DxcCompiler::Compile(const DxcBuffer * pSource, const wchar_t * * pArguments, unsigned int argCount, IDxcIncludeHandler * pIncludeHandler, const _GUID & riid, void * * ppResult) Line 913   C++
    dxcompiler.dll!hlsl::DxcCompilerAdapter::WrapCompile(int bPreprocess, IDxcBlob * pSource, const wchar_t * pSourceName, const wchar_t * pEntryPoint, const wchar_t * pTargetProfile, const wchar_t * * pArguments, unsigned int argCount, const DxcDefine * pDefines, unsigned int defineCount, IDxcIncludeHandler * pIncludeHandler, IDxcOperationResult * * ppResult, wchar_t * * ppDebugBlobName, IDxcBlob * * ppDebugBlob) Line 1650 C++
    dxcompiler.dll!hlsl::DxcCompilerAdapter::CompileWithDebug(IDxcBlob * pSource, const wchar_t * pSourceName, const wchar_t * pEntryPoint, const wchar_t * pTargetProfile, const wchar_t * * pArguments, unsigned int argCount, const DxcDefine * pDefines, unsigned int defineCount, IDxcIncludeHandler * pIncludeHandler, IDxcOperationResult * * ppResult, wchar_t * * ppDebugBlobName, IDxcBlob * * ppDebugBlob) Line 1556 C++
    dxcompiler.dll!hlsl::DxcCompilerAdapter::Compile(IDxcBlob * pSource, const wchar_t * pSourceName, const wchar_t * pEntryPoint, const wchar_t * pTargetProfile, const wchar_t * * pArguments, unsigned int argCount, const DxcDefine * pDefines, unsigned int defineCount, IDxcIncludeHandler * pIncludeHandler, IDxcOperationResult * * ppResult) Line 72   C++
    dxc.exe!DxcContext::Compile() Line 790  C++
    dxc.exe!dxc::main(int argc, const wchar_t * * argv_) Line 1374  C++

But I suspect that's due to heap corruption from earlier in the program. If I enable heap debugging and appverifier then I get a crash earlier:

    verifier.dll!000007fef007a668() Unknown
    verifier.dll!000007fef00793ea() Unknown
    verifier.dll!000007fef0079736() Unknown
    verifier.dll!000007fef00799cd() Unknown
    verifier.dll!000007fef007873a() Unknown
    ntdll.dll!RtlDebugFreeHeap()   Unknown
    ntdll.dll!string "Enabling heap debug options\n"() Unknown
    verifier.dll!000007fef008f4e1() Unknown
    ole32.dll!CRetailMalloc_Free(IMalloc * pThis, void * pv) Line 687   C++
>   [Inline Frame] dxcompiler.dll!llvm::MallocAllocator::Deallocate(const void *) Line 103  C++
    [Inline Frame] dxcompiler.dll!llvm::BumpPtrAllocatorImpl<llvm::MallocAllocator,4096,4096>::DeallocateSlabs(void * * I, void * * E) Line 326 C++
    dxcompiler.dll!llvm::BumpPtrAllocatorImpl<llvm::MallocAllocator,4096,4096>::~BumpPtrAllocatorImpl<llvm::MallocAllocator,4096,4096>() Line 166   C++
    dxcompiler.dll!clang::ASTContext::~ASTContext() Line 788    C++
    dxcompiler.dll!clang::CompilerInstance::setASTContext(clang::ASTContext * Value) Line 109   C++
    dxcompiler.dll!clang::FrontendAction::EndSourceFile() Line 495  C++
    dxcompiler.dll!DxcCompiler::Compile(const DxcBuffer * pSource, const wchar_t * * pArguments, unsigned int argCount, IDxcIncludeHandler * pIncludeHandler, const _GUID & riid, void * * ppResult) Line 914   C++
    dxcompiler.dll!hlsl::DxcCompilerAdapter::WrapCompile(int bPreprocess, IDxcBlob * pSource, const wchar_t * pSourceName, const wchar_t * pEntryPoint, const wchar_t * pTargetProfile, const wchar_t * * pArguments, unsigned int argCount, const DxcDefine * pDefines, unsigned int defineCount, IDxcIncludeHandler * pIncludeHandler, IDxcOperationResult * * ppResult, wchar_t * * ppDebugBlobName, IDxcBlob * * ppDebugBlob) Line 1650 C++
    dxcompiler.dll!hlsl::DxcCompilerAdapter::CompileWithDebug(IDxcBlob * pSource, const wchar_t * pSourceName, const wchar_t * pEntryPoint, const wchar_t * pTargetProfile, const wchar_t * * pArguments, unsigned int argCount, const DxcDefine * pDefines, unsigned int defineCount, IDxcIncludeHandler * pIncludeHandler, IDxcOperationResult * * ppResult, wchar_t * * ppDebugBlobName, IDxcBlob * * ppDebugBlob) Line 1556 C++
    dxcompiler.dll!hlsl::DxcCompilerAdapter::Compile(IDxcBlob * pSource, const wchar_t * pSourceName, const wchar_t * pEntryPoint, const wchar_t * pTargetProfile, const wchar_t * * pArguments, unsigned int argCount, const DxcDefine * pDefines, unsigned int defineCount, IDxcIncludeHandler * pIncludeHandler, IDxcOperationResult * * ppResult) Line 72   C++
    dxc.exe!DxcContext::Compile() Line 790  C++
    dxc.exe!dxc::main(int argc, const wchar_t * * argv_) Line 1374  C++

===========================================================
VERIFIER STOP 000000000000000F: pid 0xC958: corrupted suffix pattern 

    00000000022C1000 : Heap handle
    00000000033FA290 : Heap block
    0000000000001000 : Block size
    00000000033FB290 : corruption address
===========================================================
This verifier stop is not continuable. Process will be terminated 
when you use the `go' debugger command.
===========================================================
jaebaek commented 3 years ago

@baldurk Thank you for reporting this issue. We will take a look.

s-perron commented 3 months ago

This is not a priority at this time. I don't know when we will get around to it. If someone else wants to investigate it, we would gladly accept a fix. If we see it becomes more prevalent, we can look into it.