dotnet / dotnet/macios

warning: Tried to create a managed reference from an object that already has a managed reference

Open
#15,089 6 comments 1 reaction 0 assignees View on GitHub
bug
Dominant language
C#
Stars
2.9k
Forks
576
Avg merge
2d 13h
Merged PRs (30d)
96

Description

### Steps to Reproduce

1. an `NSObject` subclass is finalized
2. this calls `object_queued_for_finalization` and set `NSObjectFlagsInFinalizerQueue` in the instance's flags
3. the call to `Dispose(false)` calls `GC.ReRegisterForFinalize(this);`
4. that has no effect (notification/callback) to change the instance's flags so it's still has `NSObjectFlagsInFinalizerQueue` set
5. something calls the instance itself (e.g. `RemoveFromSuperview`)
6. `GetNSObject` is used to get the instance, `TryGetNSObject` looks for one using `evenInFinalizerQueue: false`
7. since `NSObjectFlagsInFinalizerQueue` is set the method returns `null`
8. however the call `xamarin_set_gchandle_with_flags_safe` will find a `GCHandle` (because a managed peer exists) and return `false`
9. that will make the warning appears in the logs

### Expected Behavior

The warning should not be printed **and** it the condition it checks should not occur.

### Actual Behavior

The logs shows the warning `Tried to create a managed reference from an object that already has a managed reference`. Some `NSObject` instances are resurfaced needlessly since they already exists in managed land.

### Environment

The issue exists in `master`

### Notes

* The warning is recent, added in https://github.com/xamarin/xamarin-macios/pull/11271 but the condition existed before - it just was not visible that a problem existed.

### Build Logs

Not useful.

### Example Project (If Possible)

It's easier to repro using Xamarin.Mac since `NSView.RemoveFromSuperview` calls the `Superview` property. However the warning is also seen on iOS but the conditions might be a little different.

Building [Uno SampleApp for macOS](https://github.com/unoplatform/uno/tree/master/src/SamplesApp/SamplesApp.macOS) and selecting the **Border** sample will print the warning. The generated `Dispose` can be seen in [the generator code](https://github.com/unoplatform/uno/blob/2a156730e15bb2d4b221137db0c3a2bb7e2d37d1/src/SourceGenerators/Uno.UI.SourceGenerators/DependencyObject/DependencyObjectGenerator.cs#L684).

If needed I'll try to create a smaller sample. I had no luck earlier (on iOS) but I had not yet found the root issue.

Contributor guide

No contributing guide indexed for this repository

Assessment

This issue has not been assessed yet.

Get new issues in your inbox

A short digest of beginner-friendly GitHub issues.