Skip to content

AbandonedMutexException in SharedBufferReconciler aborts a passing test host on 18.11.0 #245

Description

@glennawatson

In 18.11.0 a test host that has passed every test aborts while the session is finishing.

SharedBufferReconciler.Reconcile waits on a cross-process mutex. When a concurrently running host exits while still owning that mutex, the next waiter is handed an AbandonedMutexException, which is not handled. The process dies with SIGABRT (OS exit 134) and the platform reports exit code 7.

Unhandled exception. System.Threading.AbandonedMutexException: The wait completed due to an abandoned mutex.
   at System.Threading.WaitHandle.WaitOneNoCheck(Int32 millisecondsTimeout, Boolean useTrivialWaits, Object associatedObject, WaitHandleWaitSourceMap waitSource)
   at Microsoft.CodeCoverage.Core.Threading.Mutex.WaitOne(TimeSpan timeout)
   at Microsoft.CodeCoverage.Instrumentation.SharedBufferReconciler.Reconcile(IAppDomainDataReader appDomainDataReader, IMutexFactory mutexFactory, Int32 mutexTimeoutMs)
   at Microsoft.CodeCoverage.Instrumentation.SharedBufferReconciler.Reconcile(IAppDomainDataReader appDomainDataReader, IMutexFactory mutexFactory)
   at Microsoft.Testing.Extensions.CodeCoverage.TestingPlatformCoverageDynamicTestSessionLifetimeHandler.OnTestSessionFinishingAsync(ITestSessionContext testSessionContext)
   at Microsoft.Testing.Platform.Hosts.CommonHost.NotifyTestSessionEndAsync(ITestSessionContext testSessionContext, BaseMessageBus baseMessageBus, ServiceProvider serviceProvider, IPlatformOpenTelemetryService otelService)

Repro

Several test assemblies must run concurrently; a single test project does not reproduce it (25 consecutive runs of one project were clean).

dotnet test --solution <solution> -c Release --coverage --coverage-output-format cobertura

The run reports failed: 0 for every test, then one arbitrary assembly is marked failed and the run exits 7. Which assembly loses the race varies between runs, so it may take a few attempts.

Versions

result
18.11.0 (latest published) reproduces
18.10.0 does not reproduce

Microsoft.Testing.Platform.MSBuild 2.4.0, TUnit, net8.0/net9.0/net10.0/net11.0 hosts. Reproduced on both Linux x64 and macOS arm64.

Secondary impact: coverage is silently under-reported

The aborting host never reconciles its buffers, so its data is dropped rather than merged. Union line coverage across the same commit, only the collector version differing:

collector exit union line coverage
18.10.0 0 12820/13537 = 94.70%
18.11.0 7 12097/13537 = 89.36%

A consumer who ignores the exit code still gets a number that is quietly ~5 points low.

Links

Activity

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

    No labels
    No labels

    Type

    No type

    Projects

    No projects

      Milestone

      No milestone

      Relationships

      None yet

      Development

      No branches or pull requests

      Issue actions