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

Correct how instances may be reachable from a finalizer/dispose #26710

Closed
shadow-cs opened this issue Oct 28, 2021 · 3 comments · Fixed by #27073
Closed

Correct how instances may be reachable from a finalizer/dispose #26710

shadow-cs opened this issue Oct 28, 2021 · 3 comments · Fixed by #27073
Labels
dotnet-fundamentals/svc Pri1 High priority, do before Pri2 and Pri3 ⌚ Not Triaged Not triaged

Comments

@shadow-cs
Copy link
Contributor

The way I understand it there actually are two pieces of information that I find misleading.

Instances (eg. fields) are reachable from a finalizer

If the method call comes from a finalizer, only the code that frees unmanaged resources should execute. The implementer is responsible for ensuring that the false path doesn't interact with managed objects that may have been reclaimed. This is important because the order in which the garbage collector destroys managed objects during finalization is non-deterministic.

GC indeed is non-deterministic as well as the finalizer but fields containing managed instances do not get set to null before the finalizer is finished (at which point the object graph starting with the finalized instance may get reclaimed).

@Maoni0 stated in a blog post:

The CF/F segs are considered as a source of roots so they will be scanned to indicate which objects should be live.

So not only the instances being finalized but also all references there should be live, no?

Null-checking in a Dispose call

In the sample of Cascade dispose calls a null checking is used but it may not be clear to the reader why.

In this sample null may never end-up in the _bar because in case Bar ctor throws an exception, nothing is returned and the caller has no way to call Dispose thus making the check a no-op.

However, there are two ways a null-checking is actually the desired pattern in a Dispose method:

  1. The ctor itself calls Dispose (in a finally block perhaps) to clean after itself when things go wrong (ie. exception is thrown from the ctor) - not the best pattern to use, but this can cause problem if the programmer doesn't realize that soon enough.
  2. The ctor throws an exception and the class has a finalizer that uses some fields which may not be fully initialized (because the finalizer is executed even in case of ctor throwing an exception).

There were even more samples with null-checking which was added (#24259) and later removed (#26192).

I'll be happy to update the docs if desirable, please provide feedback on how much information should be put in the docs.


Document Details

Do not edit this section. It is required for docs.microsoft.com ➟ GitHub issue linking.

@dotnet-bot dotnet-bot added the ⌚ Not Triaged Not triaged label Oct 28, 2021
@PRMerger6 PRMerger6 added dotnet-fundamentals/svc Pri1 High priority, do before Pri2 and Pri3 labels Oct 28, 2021
@gewarren
Copy link
Contributor

@IEvangelist Do we want @shadow-cs to add the null-checking info to the "Cascade dispose calls" section?

For the first concern, it's not clear to me what the suggested change would be.

@IEvangelist
Copy link
Member

@gewarren - I would be fine with @shadow-cs adding the null-checking info for our review, and I'd ask that @bartonjs help validate the concerns raised here.

@shadow-cs
Copy link
Contributor Author

@IEvangelist @gewarren I'll prepare the adjustments so we can discuss them in a PR. I'll be a bit over excessive at first so the intention is clear, and we can refine it later and provide a concise result, in the end, hope it's OK 😉

@dotnet-bot dotnet-bot removed the ⌚ Not Triaged Not triaged label Dec 9, 2021
IEvangelist added a commit that referenced this issue Dec 9, 2021
…27073)

* Clarify information about reference validity in a finalizer (#26710)

* Update docs/standard/garbage-collection/implementing-dispose.md

Co-authored-by: David Pine <[email protected]>
@dotnet-bot dotnet-bot added the ⌚ Not Triaged Not triaged label Dec 9, 2021
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
dotnet-fundamentals/svc Pri1 High priority, do before Pri2 and Pri3 ⌚ Not Triaged Not triaged
Projects
None yet
Development

Successfully merging a pull request may close this issue.

5 participants