You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
{{ message }}
Repository navigation
[Microsoft.Gen.Logging] [LogProperties(Transitive = true)] crashes the compiler with a stack overflow on a cycle through an inherited property (e.g. a System.Type property) #7858
With [LogProperties(Transitive = true)], the [LoggerMessage] generator reports a cycle in the logged type (LOGGEN021) when the cycle goes through a property the type declares. When the cycle goes through a property declared on a base class, whose type is the derived class, the cycle is not detected. The generator recurses until the compiler process dies with Stack overflow. A property of type System.Type is enough to hit it, through the inherited properties of the reflection types.
With the shared compiler server, the server process dies as well (Error reading response: Reached end of stream before end of read.). MSBuild then falls back to csc, which dies the same way.
publicclassNode{publicLeaf?Next{get;init;}// declared on the base class, of the derived type}publicsealedclassLeaf:Node;publicsealedclassHolder{publicLeaf?Leaf{get;init;}}internalstaticpartialclassLog{[LoggerMessage(Level=LogLevel.Information,Message="Received")]publicstaticpartialvoidReceived(ILoggerlogger,[LogProperties(Transitive=true)]Holderholder);}
LOGGEN021, as when Next is declared on Leaf itself:
Library.cs(17,99): error LOGGEN021: Parameter "holder" annotated for properties logging within logging method "Received" has type with a cycle in its hierarchy: Leaf? ⇆ Leaf? (https://aka.ms/dotnet-extensions-warnings/LOGGEN021)
Actual behavior
Stack overflow.
at Microsoft.Gen.Logging.Parsing.Parser.<ProcessLogPropertiesForParameter>g__GetTypePropertiesToLog|17_1(...) <- 1376 times
at Microsoft.Gen.Logging.Parsing.Parser.ProcessLogPropertiesForParameter(...)
at Microsoft.Gen.Logging.Parsing.Parser.GetLogTypes(...)
at Microsoft.Gen.Logging.LoggingGenerator.HandleAnnotatedTypes(...)
The build reports this as hundreds of error : lines from Microsoft.CSharp.Core.targets, one per stack frame. The same trace appears for the System.Type property.
Regression?
Not known.
Known Workarounds
Do not use Transitive on a type that reaches such a cycle, or mark the property [LogPropertyIgnore]. Note that under Transitive the ignored property is then logged whole, as reported in #7856.
Configuration
Windows 11 (10.0.26200), x64, .NET SDK 10.0.402 (Roslyn 5.9), net10.0.
On main (42a0f35), GetTypePropertiesToLog walks the type and then its base types (namedType = namedType.BaseType). Before recursing into a property's type, it adds namedType, the type currently walked, to typesChain (Parser.LogProperties.cs#L278), rather than type, the type being expanded. For a property declared on a base class, the chain therefore holds Node and never Leaf, so the check typesChain.Contains(extractedType) (L261) never matches. Adding type as well, or instead, would probably close it. A depth limit would also stop a large acyclic graph (System.Type's) from growing without bound.
#4231 fixed a similar crash in the metering generator.
Investigation and write-up assisted by Claude (Anthropic); the linked repro was run on Windows 11 (10.0.26200), .NET SDK 10.0.402, Microsoft.Extensions.Telemetry.Abstractions 10.11.0, and I reviewed this report.
Activity