Bug 13822 - Dispose local variable
Summary: Dispose local variable
Status: RESOLVED FIXED
Alias: None
Product: Android
Classification: Xamarin
Component: General ()
Version: 4.8.x
Hardware: PC Mac OS
: High normal
Target Milestone: ---
Assignee: Rodrigo Kumpera
URL:
Depends on: 14011 14013 14017 14019 14042 14043 14045 14050
Blocks:
  Show dependency tree
 
Reported: 2013-08-07 11:15 UTC by Randy
Modified: 2016-04-14 06:44 UTC (History)
3 users (show)

Tags:
Is this bug a regression?: ---
Last known good build:


Attachments
debugger screenshot before crash (467.00 KB, image/png)
2013-08-07 12:33 UTC, Randy
Details


Notice (2018-05-24): bugzilla.xamarin.com is now in read-only mode.

Please join us on Visual Studio Developer Community and in the Xamarin and Mono organizations on GitHub to continue tracking issues. Bugzilla will remain available for reference in read-only mode. We will continue to work on open Bugzilla bugs, copy them to the new locations as needed for follow-up, and add the new items under Related Links.

Our sincere thanks to everyone who has contributed on this bug tracker over the years. Thanks also for your understanding as we make these adjustments and improvements for the future.


Please create a new report on Developer Community or GitHub with your current version information, steps to reproduce, and relevant error messages or log files if you are hitting an issue that looks similar to this resolved bug and you do not yet see a matching new report.

Related Links:
Status:
RESOLVED FIXED

Description Randy 2013-08-07 11:15:53 UTC
I have code that was working in 4.7 that would create a local object, set some members of that object and then create a 1 element array for that object as a member of my class. With 4.8 it appears the local object is getting disposed by the garbage collector even though the array should still have a reference to the object.

Orignal code:


NfcAdapter Nfc = null;
PendingIntent NfcPending = null;
IntentFilter[] NfcFilterList = null;

protected override void OnCreate (Bundle savedInstanceState)
{
  // ... skipping unrelated code
  Nfc = NfcAdapter.GetDefaultAdapter (this);
  if (Nfc != null)
  {
    NfcPending = PendingIntent.GetActivity (this, 0, new Intent (this, Class).AddFlags (ActivityFlags.SingleTop), 0);
    var NfcFilter = new IntentFilter (NfcAdapter.ActionNdefDiscovered);
    NfcFilter.AddDataType ("*/*");
    NfcFilterList = new IntentFilter[]{NfcFilter};
  }
  // ... skipping unrelated code
}

I later use NfcFilterList in my OnResume function and it used to work correctly. I now get an exception sometimes (probably caused by when GC runs). Trying to stop in the debugger in OnResume and examine the array will cause the debugger to crash.

If I make NfcFilter a member variable of my object instead of a local 'var' object in OnCreate, the problem goes away. However I don't think this is correct and don't know what other issues the change in object management will cause.
Comment 1 Rodrigo Kumpera 2013-08-07 11:32:35 UTC
Please provide a test case that shows the issue you're having.
Comment 2 Randy 2013-08-07 12:30:35 UTC
I tried to make a simple test case but can't get one to reproduce the problem. The code from my main app above will create the problem every time.

The only place the NfcFilterList is used is this function


protected override void OnResume ()
{
	base.OnResume ();
	
	// Enable NFC capture
	if (Nfc != null)
		Nfc.EnableForegroundDispatch (this, NfcPending, NfcFilterList, NfcTechLists);
}

If I set a breakpoint on the EnableForegroundDispatch call and try to examine the contents of NfcFilterList in the debugger, the debugger crashes with this text:


Thread started:  #3
[mono-rt] Stacktrace:
[mono-rt] 
[mono-rt]   at <unknown> <0xffffffff>
[mono-rt]   at (wrapper managed-to-native) object.wrapper_native_0x40941439 (intptr,intptr,intptr) <IL 0x00027, 0xffffffff>
[mono-rt]   at Android.Runtime.JNIEnv.CallObjectMethod (intptr,intptr) [0x00005] in /Users/builder/data/lanes/monodroid-mlion-monodroid-4.8.0-branch/3f1c339b/source/monodroid/src/Mono.Android/src/Runtime/JNIEnv.g.cs:129
[mono-rt]   at Java.Lang.Object.ToString () [0x00043] in /Users/builder/data/lanes/monodroid-mlion-monodroid-4.8.0-branch/3f1c339b/source/monodroid/src/Mono.Android/platforms/android-14/src/generated/Java.Lang.Object.cs:198
[mono-rt]   at (wrapper runtime-invoke) <Module>.runtime_invoke_object__this__ (object,intptr,intptr,intptr) <IL 0x00050, 0xffffffff>
[mono-rt]   at <unknown> <0xffffffff>
[mono-rt]   at UI.MrtActivity.OnResume () [0x0002b] in /Users/rbuckland/Documents/Rio/Client/Android/UI.cs:374
[mono-rt]   at Android.App.Activity.n_OnResume (intptr,intptr) [0x00008] in /Users/builder/data/lanes/monodroid-mlion-monodroid-4.8.0-branch/3f1c339b/source/monodroid/src/Mono.Android/platforms/android-14/src/generated/Android.App.Activity.cs:3096
[mono-rt]   at (wrapper dynamic-method) object.61b897b5-3b6f-4fb9-bd29-b16b48559e47 (intptr,intptr) <IL 0x00011, 0x0003b>
[mono-rt]   at (wrapper native-to-managed) object.61b897b5-3b6f-4fb9-bd29-b16b48559e47 (intptr,intptr) <IL 0x00022, 0xffffffff>
[mono-rt] 
[mono-rt] =================================================================
[mono-rt] Got a SIGSEGV while executing native code. This usually indicates
[mono-rt] a fatal error in the mono runtime or one of the native libraries 
[mono-rt] used by your application.
[mono-rt] =================================================================
[mono-rt] 

-------

See screenshot in the debugger. You can see the NfcFilterList array but clicking the arrow to the left will cause the debugger crash.
Comment 3 Randy 2013-08-07 12:33:11 UTC
Created attachment 4566 [details]
debugger screenshot before crash

Clicking the arrow to the left of NfcFilterList to view the array elements will crash the app and exit the debugger. This is not what normally happens when trying to view a disposed object.
Comment 4 Rodrigo Kumpera 2013-08-07 12:43:51 UTC
Are your problem in a debugger session or when running your app?
Comment 5 Randy 2013-08-07 12:52:42 UTC
Both. The app started crashing when built with 4.8. Running it in the debugger found the above issue. I worked around it easily by making NfcFilter a member variable. I'm just worried that similar code my start having issues. There are plenty of places where I do things like 


//some loop
{
  var node = new SomeObject (...)
  list.add (node);
}

If there is a case where the 'var node' might get deleted by the GC, this could cause lots of problems. In the problem code above, it should have reference counted NfcFilter when it was used to create the array NfcFilterList but it appears it didn't.

Is there a memory/GC diagnostic I can enable to get a better log of allocations/frees? 

I can do some testing for you if that will help but will eventually have to return the borrowed testing device that can create the problem. The problem only happens in the code I have to activate NFC support in this app and this is the only NFC capable test device I have.
Comment 6 Randy 2013-08-13 13:53:08 UTC
I'm now seeing a new problem that appears to be part of this issue. I have activities with complex control layouts that are built programatically. When the window closes I have Dispose code that walks the control tree telling each object to Dispose in order. This was written this way since the objects would not delete normally and eventually use up all memory.

With the current 4.8 Android, I am now getting calls from the finalizer thread for some of these objects even though they were already disposed. The first access of a member variable for the object causes an exception that crashes the app since the memory is no longer valid. I clearly see the call to Dispose(true) caused by my code and then one or two window transitions later, the finalizer calls Dispose(false) for the object.

I added a work around to check for disposing==false and do nothing but it never used to be called that way at all under 4.7 and earlier.

This seems like a change in the object cleanup code that is calling the finalizer either for objects still in use or objects that have been disposed. It appears the object reference counting is broken somewhere.
Comment 7 Jamie Hohman 2013-08-26 12:47:14 UTC
Has there been any progress on this issue?  I would be happy to add my experiences if necessary.  Is there a due date for the resolution of this issue?  Thanks.
Comment 8 Jonathan Pryor 2014-01-29 15:53:16 UTC
Is this still an issue? I'm hoping this is a dupe of Bug #13858, fixed in Xamarin.Android 4.10.
Comment 9 Rodrigo Kumpera 2016-04-14 06:44:34 UTC
We now either work or crash with a more useful message.