Skip to content

About

Minimal Windows reproduction for flutter/flutter#190809 - FragmentProgram load crashes in d3dcompiler_47.dll under Impeller/ANGLE

Resources

Stars

0 stars

Watchers

0 watching

Forks

Repository files navigation

Minimal reproduction — flutter/flutter#190809

Loading a FragmentProgram on Windows kills the process with 0xC0000005 inside d3dcompiler_47.dll, while Impeller's ANGLE backend compiles the runtime stage.

Reproduce it

flutter pub get
flutter run -d windows

The app dies within a few seconds and flutter run prints Lost connection to device. No environment variables, no scripts, nothing else required.

To see the faulting stack instead of a silent exit, set one variable first:

$env:FLUTTER_REPRO_CRASH_TRACE = '1'
flutter run -d windows

That enables a small vectored exception handler in the runner (windows/runner/native_crash_reporter.cpp) which prints module+offset frames to stderr. It is off by default and is not part of the bug.

Expected: the app paints two shaders for 30 seconds, prints clean timeout reached; exiting normally, exits 0. Actual: access violation in d3dcompiler_47.dll, exit 0xC0000005.

Environment reproduced on

Item Value
Flutter 3.47.0-0.1.pre (beta)
Framework revision bd1e75d918605c91b411e8789fb911e6c9a84534
Engine revision bbd15867c003dc66e678cb3c218649fa8bf914f2
flutter_windows.dll SHA-256 7902667F7BE09E606AEC1A8679AD53EC02B1E25CA580F525C114FEE8AD697635
OS Windows 11 Pro build 26200 x64
GPU NVIDIA RTX 3080, driver 595.95 (32.0.15.9595)
Toolchain VS 2022 17.14.36, Windows SDK 10.0.26100.0
Backend Using the Impeller rendering backend (OpenGLESSDF)

Module offsets are only comparable within a single engine revision. Also reproduces on 3.47.0-0.3.pre (engine effb186f31…) and on the current beta 3.47.0-0.4.pre (engine f88005a259…).

What it contains

A default Flutter app, one main.dart, and two .frag files. Dependencies are flutter, flutter_test, flutter_lints only. There are no image or media assets — the shaders are the only declared assets, and sampler inputs are synthetic in-memory 64×64 solid colours. The two shaders are production sources with comments and whitespace stripped; their compiled blobs are 9,632 bytes (parallax) and 23,096 bytes (lighting).

--dart-define=SHADER_MODE= selects what runs: both (default), lighting, parallax, or load_only. That switch exists because it isolates the two findings below.

Two findings that narrow it down

1. Neither program has to be used for painting. With --dart-define=SHADER_MODE=load_only the app never calls FragmentProgram.fragmentShader() and never issues a canvas draw with either program — and still dies with the same signature. Loading is sufficient. Ordinary Flutter UI still renders, so this rules out use of the runtime effect, not rendering in general. The Dart future from FragmentProgram.fromAsset completes normally first; the fault lands afterwards.

2. It is specific to one of the two shaders. SHADER_MODE=lighting loads only the larger program and crashes. SHADER_MODE=parallax loads only the smaller one, configures it, paints with it, and exits cleanly. Since lighting skips the parallax load entirely, this is not a load-ordering effect.

The responsible shader property is not isolated. The two differ at once in uniform count (~161 vs 9 float components), sampler count (4 vs 2), array declarations, control flow, generated HLSL and blob size. No delta-reduction was run to find a threshold.

Stack

Symbolized under cdb; d3dcompiler_47 symbols come from the Microsoft public symbol server.

d3dcompiler_47!CShaderProgram::AssignCBSlots_Misc+0x2bc   <-- faults here
d3dcompiler_47!CShaderProgram::AssignCBSlots+0x112
d3dcompiler_47!CD3D10Program::GenerateCode+0x2f9
d3dcompiler_47!CCompiler::EmitAndGenerateCode+0x161
d3dcompiler_47!CCompiler::CompileInternal+0x511
d3dcompiler_47!D3DCompileShader+0x177
d3dcompiler_47!D3DCompileImpl+0x1b2
d3dcompiler_47!D3DCompileSaveReplay+0xed
d3dcompiler_47!D3DCompile2+0xc9
d3dcompiler_47!D3DCompile+0x6c
flutter_windows+0xefa13d   (ANGLE, called D3DCompile)
flutter_windows+0xeb70d0
flutter_windows+0xf084a2
flutter_windows+0xefeac8

Fault address d3dcompiler_47.dll+0x77ebc, READ at 0xffffffffffffffff. This address and the whole d3dcompiler_47 chain are identical on all three engines tested, because that DLL is a Windows system library rather than a Flutter artifact; only the ANGLE frames move.

The top public symbol is AssignCBSlots_Misc — HLSL constant-buffer slot assignment. That is suggestive given the uniform-count difference, but it is a candidate explanation, not an isolated cause.

Caveats: .ecxr returns Unable to get exception context, HRESULT 0x8000FFFF, so frames come from the break-in context at the first-chance AV. There are no public PDBs for flutter_windows.dll, so the debugger resolves its frames to the nearest exported symbol plus a huge offset; those names are meaningless and only module+offset is quoted. To capture a dump yourself, use .dump /mrR — /mp includes the process environment block.

Optional: the full control matrix

Everything above needs only flutter run. run_repro.ps1 exists to run the controls reproducibly and record evidence; it is tooling, not part of the bug.

.\run_repro.ps1 -Mode both -DurationSeconds 30 -Clean
-Mode Impeller Result Exit code
both (clean build) ×2 on crash, signature matched 0xC0000005
lighting on crash, signature matched 0xC0000005
load_only on crash, signature matched 0xC0000005
parallax on control passed 0
both off control passed 0

Each run used a 30-second configured timeout; crashing runs end earlier. Logs are retained under logs\. Add -AllowAnyEngine to test a different SDK, which classifies on fault module and fault type rather than exact offsets.

One trap worth knowing if you write your own controls: flutter run does not propagate FLUTTER_ENGINE_SWITCHES to the application process. An "Impeller disabled" run launched through flutter run still starts Impeller and still crashes, which reads as "not Impeller-specific." My first Impeller-off control was invalid for exactly that reason. run_repro.ps1 builds and launches the .exe directly to avoid it, and fails if -ImpellerOff is requested but Impeller starts anyway. flutter run also reported exit code 0 after the app had died of an access violation, so classify from the log, not the CLI.

About

Minimal Windows reproduction for flutter/flutter#190809 - FragmentProgram load crashes in d3dcompiler_47.dll under Impeller/ANGLE

Resources

Stars

0 stars

Watchers

0 watching

Forks

Releases

Packages

Contributors

Languages