-
Notifications
You must be signed in to change notification settings - Fork 4.8k
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Test failure: HandleRefTest.Validate_NoGC() #97334
Comments
Tagging subscribers to this area: @dotnet/gc Issue DetailsThis test is failing on osx-arm64 with GCStress=3 with a timeout/hang.
|
I'm moving this to GC since the original issue that was mitigated involved frozen objects - PR #97109 |
@markples told me perhaps we shouldn't be running this test under GCStress since |
Is that really true? Why? There are hundreds of tests that call WaitForPendingFinalizers; I don't think they are all marked as incompatible with GCStress. |
There was some discussion earlier: #68529 (comment) It could be that WaitForPendingFinalizers is fine but not if the test (where test can mean an entire process - or merged group) has a ReRegisterForFinalize, but I don't think anyone knows. gcstress does seem to create a rather artificial environment - an infinite loop could very well be the correct behavior for the finalization mechanisms given the code+gcstress. |
My mental model is that if a test can fail under GCStress then it can fail without GCStress if the set of GCs that happens is "unlucky". So if WaitForPendingFinalizers + (possibly) ReRegisterForFinalize can cause failures under GCStress but not without it, then we're assuming/hoping that GC doesn't happen in some subset of that scenario, which seems risky. |
WaitForPendingFinalizers + allocation is enough to be in this situation, and we can force the (otherwise unlikely/unlucky) failure with an explicit using System;
using System.Runtime.CompilerServices;
FFF.Alloc();
GC.Collect();
GC.WaitForPendingFinalizers();
class FFF
{
[MethodImpl(MethodImplOptions.NoInlining)]
public static void Alloc()
{
FFF f = new FFF();
}
~FFF()
{
Console.Write('~');
Alloc();
GC.Collect();
}
} It doesn't quite work just calling using System;
using System.Runtime.CompilerServices;
FFF.Alloc();
FFF.Alloc();
GC.Collect();
GC.WaitForPendingFinalizers();
class FFF
{
[MethodImpl(MethodImplOptions.NoInlining)]
public static void Alloc()
{
FFF f = new FFF();
}
~FFF()
{
Console.Write('~');
GC.ReRegisterForFinalize(this);
GC.Collect();
}
} So yes, the test pattern is risky - waiting for a queue to empty where the objects put themselves back into it. A "delayed reregister" would fix it, assuming that it didn't ruin the intent of the test(s). The finalization feature isn't used that way in practice, so it seems like this would be artificial. using System;
using System.Runtime.CompilerServices;
FFF.Alloc();
FFF.Alloc();
GC.Collect();
GC.WaitForPendingFinalizers();
while (FFF.WaitToRegister.TryPop(out var f)) GC.ReRegisterForFinalize(f);
GC.Collect();
GC.WaitForPendingFinalizers();
class FFF
{
public static Stack<FFF> WaitToRegister = new Stack<FFF>();
[MethodImpl(MethodImplOptions.NoInlining)]
public static void Alloc()
{
FFF f = new FFF();
}
~FFF()
{
Console.Write('~');
WaitToRegister.Push(this);
GC.Collect();
}
} |
This test is failing on osx-arm64 with GCStress=3 with a timeout/hang.
https://dev.azure.com/dnceng-public/public/_build/results?buildId=535333&view=ms.vss-test-web.build-test-results-tab&runId=12652286&resultId=116250&paneView=dotnet-dnceng.dnceng-build-release-tasks.helix-test-information-tab
@AaronRobinsonMSFT @cshung
The text was updated successfully, but these errors were encountered: