Skip to content

Native AOT on .NET 11 RC2: every value set ToString traps (SIGTRAP) in the default IFormattable.ToString of IValueSetFactory<TSet, T> #291

Closed

Description

@CaffeinatedCoder

Problem

A Native AOT consumer published with the .NET 11 RC2 SDK (11.0.100-rc.2.26504.105, ILCompiler 11.0.0-rc.2, osx-arm64) dies with SIGTRAP (exit 133, nothing on stderr) on the first ToString() of any value set — Int32Set<Code>, Float64Set, Float64Set<Ratio>.Parse(…) printed, a set read from JSON and printed. The macOS crash report puts the trap in the instantiating stub ILCompiler emits for the interface's default implementation:

Internal_CompilerGenerated__Module___<__InstantiatingStub_4__>CodoMetis_ValueRanges_CodoMetis_ValueRanges_Core_IValueSetFactory_2<System___Canon__aot2_Code>__System_IFormattable_ToString +52
aot2_Program___Main__ +544

IValueSetFactory<TSet, T> implements IFormattable.ToString once, as a default interface method calling SetFormat.Format<TSet, T>((IValueSet<T>)this, …), and every set type's ToString() goes through it. TSet is always a class, so the instantiation is shared (__Canon) and the stub has to fetch the generic dictionary; on RC2 the stub is a brk. The ranges' IRangeFactory<TRange, T> has the same shape and does not trap.

Measured: the same program on .NET 10 with the 10.0.0 package runs; a net11.0 program against the unchanged 10.0.0 package traps the same way, so this is the toolchain, not the retarget's build; the managed (JIT) build of the same program runs. A library-free copy of the shape (generic interface, DIM IFormattable.ToString, generic static formatter, IntSet<T> over a struct) does not trap, so the trigger is narrower than the pattern; the next-closer copy is being tried for the upstream report.

The consumer smoke test's NativeAOT leg (test/consumer-smoke-test.sh) stops at aot-float64set-wrapper-read with no output after it, which is how this was found.

Change

Every set type (the twelve core families, their wrapper arities, and the five NodaTime families) implements IFormattable.ToString itself and its ToString() calls SetFormat.Format directly, so the default on the interface is never the implementation a compiled consumer runs. Public surface unchanged (explicit interface implementations). The interface keeps its default for documentation and for any implementer that has none. Upstream report to follow once a library-free repro traps.

Found by the #103 retarget's smoke test run.

Activity

  1. added this to the 11.0.0 milestone on Oct 19, 2026
  2. added
    bugSomething isn't working
    area/value-setsValue set families and wrapper arities
    package/nodatimeAffects CodoMetis.ValueRanges.NodaTime
    area/aotNative AOT and trimming
    package/coreAffects CodoMetis.ValueRanges
    severity/criticalData loss, corruption, or silently wrong results in common use
    on Oct 19, 2026
  3. CaffeinatedCoder commented on Oct 19, 2026

    @CaffeinatedCoder
    OwnerAuthor

    Library-free repro traps the same way (the next-closer copy: static abstract factory, ISpanParsable, a generic static formatter over IValueSet<T>); reported upstream as dotnet/runtime#136073. The workaround in the retarget PR implements IFormattable.ToString on every set type; the smoke test's NativeAOT leg passes with it on RC2.

  4. CaffeinatedCoder commented on Oct 19, 2026

    @CaffeinatedCoder
    OwnerAuthor

    The 10.x line meets this too: the measurement above ("a net11.0 program against the unchanged 10.0.0 package traps the same way") means every consumer who publishes Native AOT with the .NET 11 SDK against the released 10.x packages hits it. Filed as #299 under the 10.0.1 epic (#296): the same workaround, hand-ported from PR #292 to release/10.x.

  5. added
    severity/highWrong results, crash or failed writes in a realistic scenario
    and removed
    severity/criticalData loss, corruption, or silently wrong results in common use
    on Oct 19, 2026
  6. CaffeinatedCoder commented on Oct 19, 2026

    @CaffeinatedCoder
    OwnerAuthor

    Relabelled severity/critical → severity/high on 2026-10-19: the label legend puts a crash at high (critical is data loss, corruption or silently wrong results); the 10.x counterpart #299 carries high for the same trap.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Metadata

Metadata

Assignees

No one assigned

    Labels

    area/aotNative AOT and trimmingarea/value-setsValue set families and wrapper aritiesbugSomething isn't workingpackage/coreAffects CodoMetis.ValueRangespackage/nodatimeAffects CodoMetis.ValueRanges.NodaTimeseverity/highWrong results, crash or failed writes in a realistic scenario

    Projects

    No projects

      Relationships

      None yet

      Development

      No branches or pull requests

      Issue actions