Skip to content
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

Finalizer called without ctor in optimized compilation case #1149

Closed
peppy opened this issue Dec 25, 2019 · 3 comments
Closed

Finalizer called without ctor in optimized compilation case #1149

peppy opened this issue Dec 25, 2019 · 3 comments
Labels
area-CodeGen-coreclr CLR JIT compiler in src/coreclr/src/jit and related components such as SuperPMI bug untriaged New issue has not been triaged by the area owner

Comments

@peppy
Copy link

peppy commented Dec 25, 2019

We recently encountered a bug where an object expected to be in an initialized state at point of finalizing was not. Minimal reproduction case:

using System;
using System.Diagnostics;

namespace ReproduceFinalizerFailure
{
    class Program
    {
        public static bool CtorReached;
        public static bool FinalizerReached;

        static void Main()
        {
            try
            {
                GetObject();
            }
            catch
            {
            }

            GC.Collect();
            GC.WaitForPendingFinalizers();

            Trace.Assert(!CtorReached, "Constructor should not be reached");
            Trace.Assert(!FinalizerReached, "Finalizer should not be reached");
        }

        private static void GetObject()
        {
            var obj = throwException();
            new FinalizingObject(obj);
        }

        private static object throwException()
        {
            throw new Exception();
        }
    }

    class FinalizingObject
    {
        public FinalizingObject(object obj) => Program.CtorReached = true;

        ~FinalizingObject() => Program.FinalizerReached = true;
    }
}
➜  ReproduceFinalizerFailure  dotnet --version
3.1.100
➜  ReproduceFinalizerFailure  dotnet run -c Release
Process terminated. Assertion Failed
Finalizer should not be reached
   at ReproduceFinalizerFailure.Program.Main() in /Users/dean/Projects/ReproduceFinalizerFailure/ReproduceFinalizerFailure/Program.cs:line 27

This only happens with build configuration Release and debugger detached.

Potentially related to #764.

@mikedn
Copy link
Contributor

mikedn commented Dec 25, 2019

This looks like https://github.com/dotnet/coreclr/issues/2478

The problem is that the object is allocated before the constructor arguments are evaluated, this results in the object not being constructed but still queued for finalization.

And I think that this particular example has a twist that makes it even less likely to be fixed. In fact I'd argue that the exhibited behavior is expected:

  • Finalizers are NOT destructors. They're basically GC callbacks that are called when the GC determines that the object is dead. That has nothing to do with the object being constructed or not.
  • Object allocation and construction are separate affairs. They have to be.
  • The twist: the object allocated in this example is not used anywhere, not even in its own constructor. So it's eligible for garbage collection and finalization as soon as it is allocated. Even if the JIT would fix the allocation/arg evaluation order this problem may still randomly occur.

Anyway, if finalization is used as intended this is unlikely to be a real issue.

@peppy
Copy link
Author

peppy commented Dec 25, 2019

Thanks for the insight. This is something that wasn't apparently to any of the devs on our team. I guess we have a bit of reading to do.

If this is deemed non-actionable then closing is fine.

@jkotas
Copy link
Member

jkotas commented Dec 25, 2019

Closing as duplicate dotnet/coreclr#2478

cc @AndyAyersMS

@jkotas jkotas closed this as completed Dec 25, 2019
@jkotas jkotas added area-CodeGen-coreclr CLR JIT compiler in src/coreclr/src/jit and related components such as SuperPMI bug labels Dec 25, 2019
@ghost ghost locked as resolved and limited conversation to collaborators Dec 11, 2020
Sign up for free to subscribe to this conversation on GitHub. Already have an account? Sign in.
Labels
area-CodeGen-coreclr CLR JIT compiler in src/coreclr/src/jit and related components such as SuperPMI bug untriaged New issue has not been triaged by the area owner
Projects
None yet
Development

No branches or pull requests

4 participants