Skip to content

Trimming removes the module initializers of [ModuleInitializer] #273

Open

Description

A method marked [PostSharp.Aspects.ModuleInitializer] does not run in an application published with PublishTrimmed.

Measured. The aspect test SmallTests/Aspects/ModuleInitializer/ModuleInitializer_Basic passes under the JIT, ReadyToRun and NativeAOT, and fails when published self-contained, trimmed and ReadyToRun: none of the initializers runs. The woven assembly has a <Module>..cctor that calls them, and the trimmed assembly has no <Module>..cctor. The woven <Module> type is marked BeforeFieldInit; the <Module> type that the C# compiler emits for [System.Runtime.CompilerServices.ModuleInitializer] is not, and survives trimming (measured with a C# application published the same way).

Inferred. ILLink removes the static constructor of a BeforeFieldInit type whose static fields are never read, and it does so for <Module> too. The weaver marks <Module> BeforeFieldInit because the client of the module initializers says it supports it (ModuleInitializerTask), which a module initializer cannot: it must run when the module loads.

Fix. Never mark <Module> BeforeFieldInit (StaticConstructorAdvice in TypeInitializationManager). Measured: with that change, ModuleInitializer_Basic passes trimmed. The change is prepared on a branch of its own.

Found by running every aspect test of the PostSharp repository published with NativeAOT and trimmed ReadyToRun (PostSharpTestPublishMode of the aspect test framework, postsharp/PostSharp#246), on Windows x64 with the .NET 11.0 SDK (11.0.100-rc.1).

-- Claude for Gael

Metadata

Metadata

Labels

Type

Projects

Milestone

No milestone

Relationships

None yet

Development

No branches or pull requests

Issue actions