Bug 10379 - NullReferenceException in AppDomain.UnhandledException handler
Summary: NullReferenceException in AppDomain.UnhandledException handler
Status: NEEDINFO
Alias: None
Product: Android
Classification: Xamarin
Component: General (show other bugs)
Version: 4.4.x
Hardware: PC Windows
: High normal
Target Milestone: ---
Assignee: Bugzilla
URL:
Depends on:
Blocks:
 
Reported: 2013-02-18 11:49 UTC by Sebastian Krysmanski
Modified: 2014-01-10 21:55 UTC (History)
3 users (show)

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

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 for Bug 10379 on Developer Community or GitHub if you have new information to add and do not yet see a matching new report.

If the latest results still closely match this report, you can use the original description:

  • Export the original title and description: Developer Community HTML or GitHub Markdown
  • Copy the title and description into the new report. Adjust them to be up-to-date if needed.
  • Add your new information.

In special cases on GitHub you might also want the comments: GitHub Markdown with public comments

Related Links:
Status:
NEEDINFO

Description Sebastian Krysmanski 2013-02-18 11:49:35 UTC
Create a new project (default Mono for Android target), and provide the following for Activity1.cs:

  using System;
  using Android.App;
  using Android.OS;
  using Android.Util;
  using Android.Widget;

  namespace ExceptionMessageBug {
    [Activity(Label = "ExceptionMessageBug", MainLauncher = true, Icon = "@drawable/icon")]
    public class Activity1 : Activity {
      protected override void OnCreate(Bundle bundle) {
        base.OnCreate(bundle);
        SetContentView(Resource.Layout.Main);

        AppDomain.CurrentDomain.UnhandledException += OnUnhandledException;

        Button button = FindViewById<Button>(Resource.Id.MyButton);
        button.Click += OnButtonClick;
      }

      private void OnButtonClick(object sender, EventArgs eventArgs) {
        throw new Java.Lang.RuntimeException("This is a Java exception.");
      }

      private void OnUnhandledException(object sender, UnhandledExceptionEventArgs e) {
        var javaException = e.ExceptionObject as Java.Lang.RuntimeException;
        if (javaException != null) {
          try {
            // this will trigger a "System.NullReferenceException" exception.
            string msg = javaException.Message;
          }
          catch (NullReferenceException e2) {
            string err = e2.ToString();
          }

          try {
            // This will trigger a NullReferenceException as well
            Log.Error("IamBuggy", "Some text");
          }
          catch (NullReferenceException e2) {
            string err = e2.ToString();
          }
        }
      }
    }
  }

When you hit the button, a Java exception will be thrown. It'll then be handled by "OnUnhandledException()".

However, the Android binding seem to be "shut down" at this moment. "System.NullReferenceExceptions" will be thrown in lines 29 and 37:

"string msg = javaException.Message;"
  System.NullReferenceException: Object reference not set to an instance of an object
    at Android.Runtime.JNIEnv.CallObjectMethod (IntPtr jobject, IntPtr jmethod) [0x00000] in /Users/builder/data/lanes/monodroid-mac-monodroid-4.4-series/6418373f/source/monodroid/src/Mono.Android/src/Runtime/JNIEnv.g.cs:129 
    at Java.Lang.Throwable.get_Message () [0x0003e] in /Users/builder/data/lanes/monodroid-mac-monodroid-4.4-series/6418373f/source/monodroid/src/Mono.Android/platforms/android-8/src/generated/Java.Lang.Throwable.cs:175 
    at ExceptionMessageBug.Activity1.OnUnhandledException (System.Object sender, System.UnhandledExceptionEventArgs e) [0x00019] in d:\Bugs\MonoDroid\ExceptionMessageBug\ExceptionMessageBug\Activity1.cs:29

"Log.Error(...)"
  System.NullReferenceException: Object reference not set to an instance of an object
    at (wrapper delegate-invoke) <Module>:invoke_intptr__this___intptr_intptr_string_string (intptr,intptr,string,string)
    at Android.Runtime.JNIEnv.GetStaticMethodID (IntPtr jclass, System.String name, System.String sig) [0x00000] in /Users/builder/data/lanes/monodroid-mac-monodroid-4.4-series/6418373f/source/monodroid/src/Mono.Android/src/Runtime/JNIEnv.g.cs:740 
    at Android.Util.Log.Error (System.String tag, System.String msg) [0x00014] in /Users/builder/data/lanes/monodroid-mac-monodroid-4.4-series/6418373f/source/monodroid/src/Mono.Android/platforms/android-8/src/generated/Android.Util.Log.cs:60 
    at ExceptionMessageBug.Activity1.OnUnhandledException (System.Object sender, System.UnhandledExceptionEventArgs e) [0x00031] in d:\Bugs\MonoDroid\ExceptionMessageBug\ExceptionMessageBug\Activity1.cs:37
Comment 1 Miguel de Icaza [MSFT] 2013-05-22 14:09:42 UTC
In this case, we should decide on a policy about what to do about this.

This will require some research on our end, but raising the visibiltiy level.
Comment 2 Jonathan Pryor 2014-01-10 21:55:40 UTC
I am not able to repro your NullReferenceException with Xamarin.Android 4.11 alpha. Running the app, I now get:

> I/MonoDroid( 6778): UNHANDLED EXCEPTION: Java.Lang.RuntimeException: Exception of type 'Java.Lang.RuntimeException' was thrown.
> I/MonoDroid( 6778): at Scratch.Bxc10379.Activity1.OnButtonClick (object,System.EventArgs) <0x00044>
> I/MonoDroid( 6778): at Android.Views.View/IOnClickListenerImplementor.OnClick (Android.Views.View) <0x00047>
> I/MonoDroid( 6778): at Android.Views.View/IOnClickListenerInvoker.n_OnClick_Landroid_view_View_ (intptr,intptr,intptr) <0x0005f>
> I/MonoDroid( 6778): at (wrapper dynamic-method) object.724bd5bf-8daf-4f91-a6a2-8bead8354e0b (intptr,intptr,intptr) <0x00043>
> I/MonoDroid( 6778): 
> I/MonoDroid( 6778):   --- End of managed exception stack trace ---
> I/MonoDroid( 6778): java.lang.RuntimeException: This is a Java exception.
> I/MonoDroid( 6778):     at mono.android.view.View_OnClickListenerImplementor.n_onClick(Native Method)
> I/MonoDroid( 6778):     at mono.android.view.View_OnClickListenerImplementor.onClick(View_OnClickListenerImplementor.java:29)
> I/MonoDroid( 6778):     at android.view.View.performClick(View.java:4438)
> I/MonoDroid( 6778):     at android.view.View$PerformClick.run(View.java:18422)
> I/MonoDroid( 6778):     at android.os.Handler.handleCallback(Handler.java:733)
> I/MonoDroid( 6778):     at android.os.Handler.dispatchMessage(Handler.java:95)
> I/MonoDroid( 6778):     at android.os.Looper.loop(Looper.java:136)
> I/MonoDroid( 6778):     at android.app.ActivityThread.main(ActivityThread.java:5017)
> I/MonoDroid( 6778):     at java.lang.reflect.Method.invokeNative(Native Method)
> I/MonoDroid( 6778):     at java.lang.reflect.Method.invoke(Method.java:515)
> I/MonoDroid( 6778):     at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:779)
> I/MonoDroid( 6778):     at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:595)
> I/MonoDroid( 6778):     at dalvik.system.NativeStart.main(Native Method)
> W/dalvikvm( 6778): JNI WARNING: JNI function GetMethodID called with exception pending
> W/dalvikvm( 6778):              in Lmono/android/view/View_OnClickListenerImplementor;.n_onClick:(Landroid/view/View;)V (GetMethodID)
> W/dalvikvm( 6778): Pending exception is:
> I/dalvikvm( 6778): java.lang.RuntimeException: This is a Java exception.
... 
> E/dalvikvm( 6778): VM aborting
> E/mono-rt ( 6778): Stacktrace:
> E/mono-rt ( 6778): 
> E/mono-rt ( 6778):   at <unknown> <0xffffffff>
> E/mono-rt ( 6778):   at (wrapper managed-to-native) object.wrapper_native_0x41540c59 (intptr,intptr,string,string) <0xffffffff>
> E/mono-rt ( 6778):   at (wrapper delegate-invoke) <Module>.invoke_intptr__this___intptr_intptr_string_string (intptr,intptr,string,string) <0xffffffff>
> E/mono-rt ( 6778):   at Android.Runtime.JNIEnv.GetMethodID (intptr,string,string) <0x00093>
> E/mono-rt ( 6778):   at Java.Lang.Throwable.get_Message () <0x00047>
> E/mono-rt ( 6778):   at Scratch.Bxc10379.Activity1.OnUnhandledException (object,System.UnhandledExceptionEventArgs) <0x0008b>
> E/mono-rt ( 6778):   at (wrapper runtime-invoke) <Module>.runtime_invoke_void__this___object_object (object,intptr,intptr,intptr) <0xffffffff>

This isn't entirely desirable, but!

The purpose of AppDomain.UnhandledException is to allow you to find out information about the exception before the app dies. The app WILL die; you're just getting a chance to do something BEFORE it dies.

The problem with the above stack trace is that instead of Mono aborting the process, Dalvik did.

Dalvik aborted the process because you had a pending Java-side exception, then called Log.Error(), and Dalvik (JNI?) doesn't like calling JNI methods when a Java exception is pending, so it nuked the process from orbit.

The one thing I'm not sure about is why there was a pending Java-side exception. I don't think that `throw new Java.Lang.RuntimeException("This is a Java exception.");` will do that...

Regardless, we do know of issues with exception propagation (Bug #7634), but this is not quite the same.