-
Notifications
You must be signed in to change notification settings - Fork 5.2k
Description
Description
I noticed a change in behavior between .NET 8 and .NET 9 with System.Environment.FailFast
when running in a container on ARM64 hosts.
When called in .NET 8, the process is terminated and the container is stopped. But when called in .NET 9 (and 10), the process lingers and the container is never stopped. It is even able to keep on doing work, as demonstrated in the small project in the reproduction steps.
This has been especially problematic when running Microsoft.Orleans, which uses the call to stop the silo if the health is degraded. Due to this behavior change, the silo doesn't really exit.
Reproduction Steps
Program.cs:
using Microsoft.Extensions.DependencyInjection;
using Microsoft.Extensions.Hosting;
var host = new HostBuilder().ConfigureServices((ctx, services) =>
{
services.AddHostedService<Ticker>();
}).UseConsoleLifetime().Build();
await host.StartAsync();
await Task.Delay(2000);
Environment.FailFast("Goodbye, World!", null);
public class Ticker : BackgroundService
{
protected override async Task ExecuteAsync(CancellationToken stoppingToken)
{
var timer = new PeriodicTimer(TimeSpan.FromSeconds(1));
while (await timer.WaitForNextTickAsync(stoppingToken))
{
Console.WriteLine("tick");
}
}
}
Dockerfile:
FROM mcr.microsoft.com/dotnet/runtime:9.0 AS base
USER app
WORKDIR /app
FROM mcr.microsoft.com/dotnet/sdk:9.0 AS build
ARG BUILD_CONFIGURATION=Release
WORKDIR /src
COPY ["ConsoleApp1.csproj", "./"]
RUN dotnet restore "ConsoleApp1.csproj"
COPY . .
WORKDIR "/src/"
RUN dotnet build "./ConsoleApp1.csproj" -c $BUILD_CONFIGURATION -o /app/build
FROM build AS publish
ARG BUILD_CONFIGURATION=Release
RUN dotnet publish "./ConsoleApp1.csproj" -c $BUILD_CONFIGURATION -o /app/publish /p:UseAppHost=false
FROM base AS final
WORKDIR /app
COPY --from=publish /app/publish .
ENTRYPOINT ["dotnet", "ConsoleApp1.dll"]
podman build -t failfast:latest . && podman run --rm -it failfast:latest
https://github.com/eddietibber/failfast
Expected behavior
Should terminate the container with Process terminated. Goodbye, World!
as the last message
Actual behavior
Message Process terminated. Goodbye, World!
is written to stdout/stderr, but process is not terminated and tick
continues to be written every second until process is forcefully terminated (kill -9 pid)
Regression?
Yes, on .NET 8 I observe the expected behavior.
Known Workarounds
No response
Configuration
Tested on ARM64, locally on a macbook and in AWS EKS using graviton instances
On x64 linux the expected behavior was observed.
Other information
No response