- 
                Notifications
    You must be signed in to change notification settings 
- Fork 561
Labels
Area: App RuntimeIssues in `libmonodroid.so`.Issues in `libmonodroid.so`.
Milestone
Description
Android framework version
net8.0-android
Affected platform version
VS 2022 17.12.4
Description
We spent the last few weeks trying to track down a mysterious bug where two instances of Android.App.Application .NET proxy objects are created. So far we were not able to reproduce the issue locally but it happens quite consistently for thousands of our customers.
Finally we were able to get stack traces from the constructor where the second instance is created.
The usual first instance gets created with this stack trace:
AndroidApp::.ctor
   at System.Environment.get_StackTrace()
   at MailClient.Mobile.Droid.AndroidApp..ctor(IntPtr handle, JniHandleOwnership ownership)
   at System.Reflection.RuntimeConstructorInfo.InternalInvoke(RuntimeConstructorInfo , Object , IntPtr* , Exception& )
   at System.Reflection.MethodBaseInvoker.InterpretedInvoke_Constructor(Object obj, IntPtr* args)
   at System.Reflection.MethodBaseInvoker.InvokeDirectByRefWithFewArgs(Object , Span`1 , BindingFlags )
   at System.Reflection.MethodBaseInvoker.InvokeWithFewArgs(Object , BindingFlags , Binder , Object[] , CultureInfo )
   at System.Reflection.RuntimeConstructorInfo.Invoke(BindingFlags , Binder , Object[] , CultureInfo )
   at System.Reflection.ConstructorInfo.Invoke(Object[] parameters)
   at Java.Interop.TypeManager.CreateProxy(Type , IntPtr , JniHandleOwnership )
   at Java.Interop.TypeManager.CreateInstance(IntPtr , JniHandleOwnership , Type )
   at Java.Lang.Object.GetObject(IntPtr , JniHandleOwnership , Type )
   at Java.Lang.Object._GetObject[Application](IntPtr , JniHandleOwnership )
   at Java.Lang.Object.GetObject[Application](IntPtr handle, JniHandleOwnership transfer)
   at Java.Lang.Object.GetObject[Application](IntPtr jnienv, IntPtr handle, JniHandleOwnership transfer)
   at Android.App.Application.n_OnCreate(IntPtr jnienv, IntPtr native__this)
   at Android.Runtime.JNINativeWrapper.Wrap_JniMarshal_PP_V(_JniMarshal_PP_V callback, IntPtr jnienv, IntPtr klazz)
-- Java --
	at crc647fae2f69c19dcd0d.AndroidApp.n_onCreate(Native Method)
	at crc647fae2f69c19dcd0d.AndroidApp.onCreate(AndroidApp.java:25)
	at android.app.Instrumentation.callApplicationOnCreate(Instrumentation.java:1316)
	at android.app.ActivityThread.handleBindApplication(ActivityThread.java:7848)
	at android.app.ActivityThread.-$$Nest$mhandleBindApplication(Unknown Source:0)
	at android.app.ActivityThread$H.handleMessage(ActivityThread.java:2486)
	at android.os.Handler.dispatchMessage(Handler.java:106)
	at android.os.Looper.loopOnce(Looper.java:230)
	at android.os.Looper.loop(Looper.java:319)
	at android.app.ActivityThread.main(ActivityThread.java:9063)
	at java.lang.reflect.Method.invoke(Native Method)
	at com.android.internal.os.RuntimeInit$MethodAndArgsCaller.run(RuntimeInit.java:588)
	at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:1103)
The second instance comes from a worker (subclass of AndroidX.Work.Worker):
   at System.Environment.get_StackTrace()
   at MailClient.Mobile.Droid.AndroidApp..ctor(IntPtr handle, JniHandleOwnership ownership)
   at System.Reflection.RuntimeConstructorInfo.InternalInvoke(RuntimeConstructorInfo , Object , IntPtr* , Exception& )
   at System.Reflection.MethodBaseInvoker.InterpretedInvoke_Constructor(Object obj, IntPtr* args)
   at System.Reflection.MethodBaseInvoker.InvokeDirectByRefWithFewArgs(Object , Span`1 , BindingFlags )
   at System.Reflection.MethodBaseInvoker.InvokeWithFewArgs(Object , BindingFlags , Binder , Object[] , CultureInfo )
   at System.Reflection.RuntimeConstructorInfo.Invoke(BindingFlags , Binder , Object[] , CultureInfo )
   at System.Reflection.ConstructorInfo.Invoke(Object[] parameters)
   at Java.Interop.TypeManager.CreateProxy(Type , IntPtr , JniHandleOwnership )
   at Java.Interop.TypeManager.CreateInstance(IntPtr , JniHandleOwnership , Type )
   at Java.Lang.Object.GetObject(IntPtr , JniHandleOwnership , Type )
   at Android.Runtime.JNIEnv.<>c.<CreateNativeArrayElementToManaged>b__70_9(Type type, IntPtr source, Int32 index)
   at Android.Runtime.JNIEnv.GetObjectArray(IntPtr , Type[] )
   at Java.Interop.TypeManager.n_Activate(IntPtr jnienv, IntPtr jclass, IntPtr typename_ptr, IntPtr signature_ptr, IntPtr jobject, IntPtr parameters_ptr)
   at Android.Runtime.JNINativeWrapper.Wrap_JniMarshal_PPLLLL_V(_JniMarshal_PPLLLL_V callback, IntPtr jnienv, IntPtr klazz, IntPtr p0, IntPtr p1, IntPtr p2, IntPtr p3)
-- Java --
	at mono.android.TypeManager.n_activate(Native Method)
	at mono.android.TypeManager.Activate(TypeManager.java:7)
	at crc647fae2f69c19dcd0d.SyncWorker.<init>(SyncWorker.java:23)
	at java.lang.reflect.Constructor.newInstance0(Native Method)
	at java.lang.reflect.Constructor.newInstance(Constructor.java:343)
	at androidx.work.WorkerFactory.createWorkerWithDefaultFallback(WorkerFactory.java:95)
	at androidx.work.impl.WorkerWrapper.runWorker(WorkerWrapper.java:243)
	at androidx.work.impl.WorkerWrapper.run(WorkerWrapper.java:144)
	at androidx.work.impl.utils.SerialExecutorImpl$Task.run(SerialExecutorImpl.java:96)
	at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1145)
	at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:644)
	at java.lang.Thread.run(Thread.java:1012)
Notably, the first instance exists and it's not collected on the .NET side (pinned through a static variable). This suggests that there's a race condition that could lead to creation of two proxy objects.
Steps to Reproduce
Did you find any workaround?
No response
Relevant log output
Metadata
Metadata
Assignees
Labels
Area: App RuntimeIssues in `libmonodroid.so`.Issues in `libmonodroid.so`.