Bug 24286 - Android - jobject must not be intptr.zero
Summary: Android - jobject must not be intptr.zero
Alias: None
Product: Forms
Classification: Xamarin
Component: Forms ()
Version: 1.2.3
Hardware: Macintosh Mac OS
: Normal normal
Target Milestone: ---
Assignee: Mark Probst
Depends on:
Reported: 2014-11-05 10:40 UTC by Brad
Modified: 2017-01-04 17:01 UTC (History)
23 users (show)

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

Sample project (21.20 KB, application/zip)
2014-11-05 11:03 UTC, Brad
Test Case (36.52 KB, application/zip)
2014-12-17 16:53 UTC, John Miller [MSFT]

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:

Description Brad 2014-11-05 10:40:32 UTC
Sorry if this seems like a duplicate of Bug ID #22324, but there are differences in how we arrive at the problem.

I've tested this on an HTC One M8 with Android 4.4.4 and GenyMotion emulator running Android 4.2.2

I've attached a zip with a simple project that can reproduce the problem and following are the steps to reproduce it.

1. Tap the first button on the main page
2. Tap random items in list 1 to change the switch's value
3. Go back to main screen
4. Tap the second button on the main screen
5. Tap random items in list 2 to change the switch's value
6. Go back to main screen
7. Repeat 1-6 until you get the exception

It will fail inside one of the two models (depending on which list has the error) within the RaisePropertyChanged method on the call to PropertyChanged.

Here's the full exception: 
System.ArgumentException: 'jobject' must not be IntPtr.Zero.
Parameter name: jobject
at Android.Runtime.JNIEnv.CallVoidMethod (intptr,intptr,Android.Runtime.JValue[]) [0x00010] in /Users/builder/data/lanes/monodroid-mlion-monodroid-4.18-series/3b7ef0a7/source/monodroid/src/Mono.Android/src/Runtime/JNIEnv.g.cs:500
at Android.Widget.CompoundButton.set_Checked (bool) [0x00043] in /Users/builder/data/lanes/monodroid-mlion-monodroid-4.18-series/3b7ef0a7/source/monodroid/src/Mono.Android/platforms/android-19/src/generated/Android.Widget.CompoundButton.cs:274
at Xamarin.Forms.Platform.Android.SwitchRenderer.HandleToggled (object,System.EventArgs) <IL 0x00011, 0x000b7>
at Xamarin.Forms.Switch.<.cctor>b__0 (Xamarin.Forms.BindableObject,object,object) <IL 0x0001c, 0x00123>
at Xamarin.Forms.BindableObject.SetValueActual (Xamarin.Forms.BindableProperty,object,bool,bool,bool) <IL 0x000b9, 0x0058f>
at Xamarin.Forms.BindableObject.SetValueCore (Xamarin.Forms.BindableProperty,object,bool,bool,bool) <IL 0x00213, 0x00aeb>
at Xamarin.Forms.BindingExpression.ApplyCore (object,Xamarin.Forms.BindableObject,Xamarin.Forms.BindableProperty,bool) <IL 0x00206, 0x01287>
at Xamarin.Forms.BindingExpression.Apply (bool) <IL 0x00041, 0x0018b>
at Xamarin.Forms.BindingExpression/BindingExpressionPart.<PropertyChanged>b__12 () <IL 0x00007, 0x00053>
at Java.Lang.Thread/RunnableImplementor.Run () [0x0000b] in /Users/builder/data/lanes/monodroid-mlion-monodroid-4.18-series/3b7ef0a7/source/monodroid/src/Mono.Android/src/Java.Lang/Thread.cs:36
at Java.Lang.IRunnableInvoker.n_Run (intptr,intptr) [0x00009] in /Users/builder/data/lanes/monodroid-mlion-monodroid-4.18-series/3b7ef0a7/source/monodroid/src/Mono.Android/platforms/android-19/src/generated/Java.Lang.IRunnable.cs:71
at (wrapper dynamic-method) object.6522ff35-60f0-4960-914c-627b776c78b2 (intptr,intptr) <IL 0x00011, 0x0003b>
Comment 1 Brad 2014-11-05 11:03:57 UTC
Created attachment 8632 [details]
Sample project
Comment 2 Ram Chandra 2014-11-05 12:18:31 UTC
I have checked this issue and with the help of steps mentioned in bug description I am able to reproduce this issue.

Screencast: http://www.screencast.com/t/qClUNkmqsg

Application Output: https://gist.github.com/saurabh360/250bbdb0aa1d54703e63
Build Output: https://gist.github.com/saurabh360/45fa3dc02c7bbc85b1dd
IDE logs:  https://gist.github.com/saurabh360/2e82fa17423052f6da39

Environment Info:

=== Xamarin Studio ===

Version 5.5.3 (build 6)
Installation UUID: 6ea47b0d-1852-4aaf-808d-373ff0a5002b
	Mono 3.10.0 ((detached/e204655)
	GTK+ 2.24.23 (Raleigh theme)

	Package version: 310000023

=== Apple Developer Tools ===

Xcode 6.0.1 (6528)
Build 6A317

=== Xamarin.Mac ===

Version: (Trial Edition)

=== Xamarin.Android ===

Version: 4.18.0 (Trial Edition)
Android SDK: /Users/jatin66/Desktop/Backup/android-sdk-macosx
	Supported Android versions:
		1.6   (API level 4)
		2.1   (API level 7)
		2.2   (API level 8)
		2.3   (API level 10)
		3.0   (API level 11)
		3.1   (API level 12)
		3.2   (API level 13)
		4.0   (API level 14)
		4.0.3 (API level 15)
		4.1   (API level 16)
		4.2   (API level 17)
		4.3   (API level 18)
		4.4   (API level 19)
Java SDK: /usr
java version "1.7.0_65"
Java(TM) SE Runtime Environment (build 1.7.0_65-b17)
Java HotSpot(TM) 64-Bit Server VM (build 24.65-b04, mixed mode)

=== Xamarin.iOS ===

Version: (Trial Edition)
Hash: 08968c4
Build date: 2014-10-20 21:48:06-0400

=== Build Information ===

Release ID: 505030006
Git revision: fbe3e9453daf6a3bb9a9709ed22bec35f7c9056b
Build date: 2014-10-23 13:08:38-04
Xamarin addins: e44add2b39de4dd57c0742bb2e620dfad84c64c6

=== Operating System ===

Mac OS X 10.10.0
Darwin Jatin66s-iMac.local 14.0.0 Darwin Kernel Version 14.0.0
    Fri Sep 19 00:26:44 PDT 2014
    root:xnu-2782.1.97~2/RELEASE_X86_64 x86_64
Comment 3 Jonathan Pryor 2014-11-05 12:29:33 UTC
The problem is that a Switch is being collected/disposed of when it shouldn't be, so it's ultimately equivalent to:

    var o = new Java.Lang.Object ();
    o.Dispose ();           // or maybe via GC...?
    var s = o.ToString ();  // BOOM

Knowing that's the problem doesn't help in fixing it, so how do we investigate that? Enter `logcat-parse.exe`, one of the handy new utilities in Xamarin.Android 5.0 (not yet released, but in the 4.99 preview).

    # Enable GREF logging:
    $ adb shell setprop debug.mono.log gref
    # Collect the GREF output...
    $ adb logcat > grefs.txt

    # Run your sample, cause it to crash...
    Ctrl+C # kill `adb logcat`

    # Let's investigate!
    $ logcat-parse.exe grefs.txt

From the stack trace:

> System.Reflection.TargetInvocationException: Exception has been thrown by the target of an invocation. ---> System.ArgumentException: 'jobject' must not be IntPtr.Zero.
> Parameter name: jobject
>   at Android.Runtime.JNIEnv.CallVoidMethod (IntPtr jobject, IntPtr jmethod, Android.Runtime.JValue[] parms) [0x00000] in <filename unknown>:0 
>   at Android.Widget.CompoundButton.set_Checked (Boolean value) [0x00000] in <filename unknown>:0 
>   at Xamarin.Forms.Platform.Android.SwitchRenderer.HandleToggled (System.Object sender, System.EventArgs e) [0x00000] in <filename unknown>:0 
>   at Xamarin.Forms.Switch.<.cctor>b__0 (Xamarin.Forms.BindableObject bindable, System.Object oldValue, System.Object newValue) [0x00000] in <filename unknown>:0 
>   at Xamarin.Forms.BindableObject.SetValueActual (Xamarin.Forms.BindableProperty property, System.Object value, Boolean currentlyApplying, Boolean clearBindings, Boolean raiseOnEqual) [0x00000] in <filename unknown>:0 
>   at Xamarin.Forms.BindableObject.SetValueCore (Xamarin.Forms.BindableProperty property, System.Object value, Boolean clearBindings, Boolean raiseOnEqual, Boolean checkaccess) [0x00000] in <filename unknown>:0 
>   at Xamarin.Forms.BindingExpression.ApplyCore (System.Object sourceObject, Xamarin.Forms.BindableObject target, Xamarin.Forms.BindableProperty property, Boolean fromTarget) [0x00000] in <filename unknown>:0 
>   at Xamarin.Forms.BindingExpression.Apply (Boolean fromTarget) [0x00000] in <filename unknown>:0 
>   at Xamarin.Forms.BindingExpression+BindingExpressionPart.<PropertyChanged>b__12 () [0x00000] in <filename unknown>:0 
>   at Java.Lang.Thread+RunnableImplementor.Run () [0x00000] in <filename unknown>:0 
>   at Java.Lang.IRunnableInvoker.n_Run (IntPtr jnienv, IntPtr native__this) [0x00000] in <filename unknown>:0 
>   at (wrapper dynamic-method) object:05227263-ccb6-49a2-a01f-4b59d8740b59 (intptr,intptr)
>   --- End of inner exception stack trace ---
> at System.Reflection.MonoMethod.Invoke (object,System.Reflection.BindingFlags,System.Reflection.Binder,object[],System.Globalization.CultureInfo) <IL 0x00062, 0x00120>
> at System.Reflection.MethodBase.Invoke (object,object[]) <IL 0x00006, 0x00047>
> at Xamarin.Forms.BindingExpression.ApplyCore (object,Xamarin.Forms.BindableObject,Xamarin.Forms.BindableProperty,bool) <IL 0x002de, 0x0089f>
> at Xamarin.Forms.BindingExpression.Apply (bool) <IL 0x00041, 0x0009b>
> at Xamarin.Forms.Binding.Apply (bool) <IL 0x00027, 0x0007f>
> at Xamarin.Forms.BindableObject.SetValueActual (Xamarin.Forms.BindableProperty,object,bool,bool,bool) <IL 0x00090, 0x00193>
> at Xamarin.Forms.BindableObject.SetValueCore (Xamarin.Forms.BindableProperty,object,bool,bool,bool) <IL 0x00213, 0x0049b>
> at Xamarin.Forms.BindableObject.SetValue (Xamarin.Forms.BindableProperty,object,bool) <IL 0x0005a, 0x00093>
> at Xamarin.Forms.BindableObject.SetValue (Xamarin.Forms.BindableProperty,object) <IL 0x00004, 0x00027>
> at Xamarin.Forms.Switch.set_IsToggled (bool) <IL 0x00007, 0x00043>
> at AppUI.SecondListItemCell.HandleCellTapped (object,System.EventArgs) <IL 0x00012, 0x0004b>
> at Xamarin.Forms.Cell.OnTapped () <IL 0x00014, 0x0003b>
> at Xamarin.Forms.ListView.NotifyRowTapped (int,int) <IL 0x00051, 0x000e7>
> at Xamarin.Forms.ListView.NotifyRowTapped (int) <IL 0x00025, 0x0006b>
> at Xamarin.Forms.Platform.Android.ListViewAdapter.OnRealItemClicked (object,Android.Widget.AdapterView/ItemClickEventArgs) <IL 0x00025, 0x0004b>
> at Android.Widget.AdapterView/IOnItemClickListenerImplementor.OnItemClick (Android.Widget.AdapterView,Android.Views.View,int,long) <IL 0x0001e, 0x0008f>
> at Android.Widget.AdapterView/IOnItemClickListenerInvoker.n_OnItemClick_Landroid_widget_AdapterView_Landroid_view_View_IJ (intptr,intptr,intptr,intptr,int,long) <IL 0x00020, 0x000b7>

we deduce that the problem is in CompoundButton, so let's look for that:

    csharp> grefs.AllocatedPeers.Count(p => p.McwType.Contains("CompoundButton")); 

Nope. :-(

Further investigation shows that it's not a CompoundButton, but actually a Switch, so what about that?

    csharp> grefs.AlivePeers.Where(p => p.McwType.Contains("Switch")).Count(); 
    csharp> grefs.AllocatedPeers.Where(p => p.McwType.Contains("Switch")).Count();

which more or less validates the assumption: we *had* a Switch instance, and it got collected/disposed (which?), and then we're trying to access the invalidated instance.

So what instances have been disposed?

    csharp> grefs.AllocatedPeers.Where(p => p.McwType.Contains("Switch"))
        .Except (grefs.AlivePeers.Where(p => p.McwType.Contains("Switch"))
> {
> PeerInfo(Collected=True Disposed=True Finalized=False JniType='android_ui/ListSwitchRenderer' McwType='Android_UI.ListSwitchRenderer' KeyHandle=0x6559ba08 Handles=4),
> PeerInfo(Collected=True Disposed=False Finalized=False JniType='android_ui/ListSwitchRenderer' McwType='Android_UI.ListSwitchRenderer' KeyHandle=0x65593f70 Handles=3),
> PeerInfo(Collected=True Disposed=False Finalized=False JniType='android/widget/Switch' McwType='Android.Widget.Switch' KeyHandle=0x6553f538 Handles=3),
> PeerInfo(Collected=True Disposed=False Finalized=False JniType='android/widget/Switch' McwType='Android.Widget.Switch' KeyHandle=0x65564678 Handles=3),
> PeerInfo(Collected=True Disposed=False Finalized=False JniType='android_ui/ListSwitchRenderer' McwType='Android_UI.ListSwitchRenderer' KeyHandle=0x65567900 Handles=3),
> PeerInfo(Collected=True Disposed=False Finalized=False JniType='android/widget/Switch' McwType='Android.Widget.Switch' KeyHandle=0x6552d120 Handles=3)
> }

Formatted for readability. (Oh how I wish the actual output were that readable...)

Three of these are actual Switches, as opposed to SwitchRenderer types, and all have been Collected but NOT Disposed or Finalized (!)...which is probably a logcat-parse bug:

    csharp> var s = grefs.AllocatedPeers.First(p => p.KeyHandle=="0x6552d120");
    csharp> s.Handles;
    { "0x6552d120", "0x100732", "0x30072a" }
    csharp> s.GetStackTraceForHandle("0x30072a"); 
    "thread 'finalizer'(30245)"

so this instance was *clearly* finalized, as were the other instances.

Thus, we have a working theory: the GC has collected a Switch instance, invaliding the Switch's Handle, and then the Switch instance is later used, causing the ArgumentException from JNIEnv.Call*Method().

The final question, then, is WHY? Unfortunately, I don't have an answer to that.
Comment 4 Jonathan Pryor 2014-11-05 12:34:01 UTC
@Mark: Is this a GC bug? (How do we diagnose that?)
Comment 5 Jonathan Pryor 2014-11-05 13:07:47 UTC
Please try one of the alternate GC bridges, e.g. 'new' or 'tarjan'.


Does that resolve the issue?
Comment 6 Brad 2014-11-05 13:30:00 UTC
I tried both bridges just now with the same result.

FYI - You can simplify the repro even further by getting rid of the second list entirely and only load one item into the first list then just:
Button tap to list -> Flip switch -> Back to main -> repeat
Comment 8 David Johnson 2014-12-15 15:59:14 UTC
I am encountering this same exception with a similar repro case. I have a page that has a data-bound ListView. Updates to the model behind this ListView are received asynchronously from the server and broadcast via MessagingCenter. The page's viewmodel receives the message and updates its properties, triggering property change notifications.

This usually works fine, but occasionally when this page is not at the top of the navigation stack a "'jobject' must not be IntPtr.Zero" exception is thrown. I've caught this in the debugger, and confirmed that the bound property had a value, so that's not the problem.

This bug is preventing me from submitting to the app store. Is anybody working on a solution?
Comment 9 David Johnson 2014-12-16 11:14:46 UTC
Here is the call stack for my version of this crash. Note that it's happening with a Label and not with a switch. If this is a different bug please let me know and I'll file a separate one:

System.ArgumentException: 'jobject' must not be IntPtr.Zero.
Parameter name: jobject
  at Android.Runtime.JNIEnv.CallVoidMethod (intptr,intptr,Android.Runtime.JValue[]) [0x00010] in /Users/builder/data/lanes/monodroid-mlion-monodroid-4.20-series/ba9bbbdd/source/monodroid/src/Mono.Android/src/Runtime/JNIEnv.g.cs:500
  at Android.Widget.TextView.set_TextFormatted (Java.Lang.ICharSequence) [0x00034] in /Users/builder/data/lanes/monodroid-mlion-monodroid-4.20-series/ba9bbbdd/source/monodroid/src/Mono.Android/platforms/android-19/src/generated/Android.Widget.TextView.cs:2434
  at Android.Widget.TextView.set_Text (string) [0x00013] in /Users/builder/data/lanes/monodroid-mlion-monodroid-4.20-series/ba9bbbdd/source/monodroid/src/Mono.Android/platforms/android-19/src/generated/Android.Widget.TextView.cs:2443
  at at Xamarin.Forms.Platform.Android.LabelRenderer.UpdateText () <IL 0x0008d, 0x003e3>
  at at Xamarin.Forms.Platform.Android.LabelRenderer.OnElementPropertyChanged (object,System.ComponentModel.PropertyChangedEventArgs) <IL 0x000af, 0x00473>
  at at (wrapper delegate-invoke) <Module>.invoke_void_object_PropertyChangedEventArgs (object,System.ComponentModel.PropertyChangedEventArgs) <IL 0x00027, 0x00067>
  at at Xamarin.Forms.BindableObject.OnPropertyChanged (string) <IL 0x00012, 0x000c7>
  at at Xamarin.Forms.BindableObject.SetValueActual (Xamarin.Forms.BindableProperty,object,bool,bool,bool) <IL 0x000a3, 0x004f3>
  at at Xamarin.Forms.BindableObject.SetValueCore (Xamarin.Forms.BindableProperty,object,bool,bool,bool) <IL 0x00213, 0x00aeb>
  at at Xamarin.Forms.BindingExpression.ApplyCore (object,Xamarin.Forms.BindableObject,Xamarin.Forms.BindableProperty,bool) <IL 0x00206, 0x01287>
  at at Xamarin.Forms.BindingExpression.Apply (bool) <IL 0x00041, 0x0018b>
  at at Xamarin.Forms.BindingExpression/BindingExpressionPart.<PropertyChanged>b__12 () <IL 0x00007, 0x00053>
  at Java.Lang.Thread/RunnableImplementor.Run () [0x0000b] in /Users/builder/data/lanes/monodroid-mlion-monodroid-4.20-series/ba9bbbdd/source/monodroid/src/Mono.Android/src/Java.Lang/Thread.cs:36
  at Java.Lang.IRunnableInvoker.n_Run (intptr,intptr) [0x00009] in /Users/builder/data/lanes/monodroid-mlion-monodroid-4.20-series/ba9bbbdd/source/monodroid/src/Mono.Android/platforms/android-19/src/generated/Java.Lang.IRunnable.cs:71
  at at (wrapper dynamic-method) object.fb8fb159-f334-410c-9f31-6fc7788136ab (intptr,intptr) <IL 0x00011, 0x0003b>
Comment 10 David Johnson 2014-12-16 11:23:15 UTC
Another data point related to this crash. This viewmodel is being shared across multiple instances of the page to which it's bound over time. That is, the page is shown once, popped, the viewmodel is changed, and a new instance of the page is shown using the same viewmodel.

The crash above happened BEFORE the new instance of the page was created. That tells me that there was some lingering property binding to the previous instance of the page still referenced. I suspect the property change notification is attempting to update a label that no longer exists.

I tried setting the BindingContext of the page to null when popping it to see if that would clear the binding but that had no effect. Is there any workaround at all for this?

I'm close to the point of concluding that data binding in Xamarin Forms is fundamentally broken and should not be used.
Comment 11 John Miller [MSFT] 2014-12-17 16:53:23 UTC
Created attachment 9110 [details]
Test Case

Added another test case that is very simple. 

To reproduce, just click the buttons quickly to navigate back and forth. After about 4 clicks, it will crash.
Comment 13 David Schwegler 2014-12-17 18:35:20 UTC
I also am having a similar crash when setting the Visibility of an item in a ListView. 

Hope it's fixed soon. :)
Comment 14 David Schwegler 2014-12-18 16:17:00 UTC
In my case, I had a ViewHolder object for each row in my RecyclerView
(ListView). The ViewHolder had a WeakSubscription to a ViewModel which modified
the row's views. If the subscription fired after the row was moved off screen
(no longer referenced by RecyclerView), this exception would be thrown. 

I was attempting to remove the weaksubscriptions in RecyclerView.OnViewRecycled, but that wasn't
beng called due to https://bugzilla.xamarin.com/show_bug.cgi?id=24367. Updating
to RecyclerView v21.0.3.0 got that method called and "fixed" my problem.

Does indeed seem like GC bug though.
Comment 15 Jason Smith [MSFT] 2015-02-05 06:10:56 UTC
This should be resolved in 1.3.3-pre1
Comment 16 Brad 2015-02-16 09:41:13 UTC
Just tried the simplified test instructions from Comment 6 using both and and I still have the problem.
Comment 17 Brad 2015-03-04 12:42:43 UTC
Just checked with XF and still had the problem
Comment 18 Paul Read 2015-03-06 06:52:10 UTC
Likewise come across this same issue. Commonalities with other reporters:

* pages with list views
* One view model - that is bound to a page that is tidied up by GC on navigation to another page 
* Does not happen ever time page is change but eventually does
Comment 19 Falko Schindler 2015-03-16 04:51:01 UTC
Not sure if this is the very same bug. But here is a rather short code example to reproduce it:

    public class App : Application
        public App()
            var optionsPage = new OptionsPage();

            MainPage = new NavigationPage(new ContentPage {
                Content = new Button {
                    Text = "Click",
                    Command = new Command(o => MainPage.Navigation.PushAsync(optionsPage)),

        class OptionsPage: ContentPage
            public OptionsPage()
                var template = new DataTemplate(typeof(TextCell));
                template.SetBinding(TextCell.TextProperty, ".");
                var listView = new ListView {
                    ItemsSource = new []{ "A", "B", "C" },
                    ItemTemplate = template,
                listView.ItemTapped += (sender, e) => Navigation.PopAsync();
                Content = listView;

To reproduce it: Tap "Click" > "A" > "Click" > "B" > Crash!
(In other words: Select two different letters and the app will crash.)

Apparently, it is essential to instantiate optionsPage once in the App constructor (=reusing optionsPage) and not within the button command delegate.

Setting listView.SelectedItem = null within the ItemTapped delegate will cause a crash even when selecting the same letter twice.
Comment 20 Falko Schindler 2015-03-16 05:13:47 UTC
Possible workarounds for the code example above (comment 19):
* instantiate optionsPage in every "Click" button command delegate
* instantiate listView in OnAppearing rather than the OptionsPage constructor.
Comment 21 cloush 2015-04-04 09:24:14 UTC
I can confirm, that creating the controls in OnAppearing will help. Also try to set the Content to null in OnDisappearing.

Details can be found on http://blog.cloush.com/?p=12
Comment 23 Rui Marinho 2017-01-04 17:01:57 UTC
Thank you for taking the time to submit this report. After reviewing the description of this bug, we believe it no longer affects the current version of Xamarin.Forms. If you are still experiencing the issue after updating your packages, please reopen this report with an attached reproduction. 

For your convenience, we have created some reproduction best practices viewable here: https://gist.github.com/jassmith/92405c300e54a01dcc6d

Warm regards, 
Xamarin Forms Team