镜像站点 · 本页由第三方 GitHub 只读镜像提供,非 GitHub 官方站点,不接受任何登录或凭据输入。前往 github.com
Skip to content

Random NullReference and InvalidCast crashes in mono class libraries #1188

Closed

Description

@Belorus

Steps to Reproduce

We have a big game that communicates with server via HTTP.

<AndroidLinkMode>SdkOnly</AndroidLinkMode>
<AotAssemblies>True</AotAssemblies>
<EnableLLVM>True</EnableLLVM>
<AndroidEnableSGenConcurrent>false</AndroidEnableSGenConcurrent>

GCBridge - default, it is tarjan in this XA version.

Actual Behavior

Most of the crashes come from SSL/TLS stack, but List.Add, Dictionary.Add also crash for some users, but 50 times less often.

Crashes on Androids:

Xamarin caused by: android.runtime.JavaProxyThrowable: System.NullReferenceException: Object reference not set to an instance of an object
  at (wrapper remoting-invoke-with-check) Mono.Security.Protocol.Tls.SslStreamBase:set_CheckCertRevocationStatus (bool)
Xamarin caused by: android.runtime.JavaProxyThrowable: System.NullReferenceException: Object reference not set to an instance of an object
  at Mono.Security.Protocol.Tls.SslClientStream.add_ServerCertValidation2 (Mono.Security.Protocol.Tls.CertificateValidationCallback2 value) <0x9d0ee038 + 0x0005c> in <cdde401f4fc64c87a9a513ce5f60d5ad>:0 
  at (wrapper remoting-invoke-with-check) Mono.Security.Protocol.Tls.SslClientStream:add_ServerCertValidation2 (Mono.Security.Protocol.Tls.CertificateValidationCallback2)
Xamarin caused by: android.runtime.JavaProxyThrowable: System.ObjectDisposedException: Cannot access a disposed object.
Object name: 'SslStream'.
System.Net.Security.SslStream.get_Impl()
System.Net.Security.SslStream.get_Impl()(wrapper remoting-invoke-with-check)
Xamarin caused by: android.runtime.JavaProxyThrowable: System.NullReferenceException: Object reference not set to an instance of an object
System.Net.HttpWebRequest.get_ClientCertificates()
System.Net.HttpWebRequest.get_ClientCertificates()(wrapper remoting-invoke-with-check)
Xamarin caused by: android.runtime.JavaProxyThrowable: System.NullReferenceException: Object reference not set to an instance of an object
System.Net.HttpWebRequest.get_ServerCertValidationCallback()
System.Net.HttpWebRequest.get_ServerCertValidationCallback()(wrapper remoting-invoke-with-check)
Xamarin caused by: android.runtime.JavaProxyThrowable: System.NullReferenceException: Object reference not set to an instance of an object
Mono.Security.Protocol.Tls.TlsStream.ToArray()
Mono.Security.Protocol.Tls.TlsStream.ToArray()(wrapper remoting-invoke-with-check)
Xamarin caused by: android.runtime.JavaProxyThrowable: System.NullReferenceException: Object reference not set to an instance of an object
System.Collections.Generic.List<T>.Add(T item)
Xamarin caused by: android.runtime.JavaProxyThrowable: System.NullReferenceException: Object reference not set to an instance of an object
  at System.Runtime.CompilerServices.TaskAwaiter`1[TResult].UnsafeOnCompleted (System.Action continuation) <0x9c1fa264 + 0x00014> in <162b154355a14010abd9ab37698d0a10>:0 
  at System.Runtime.CompilerServices.AsyncTaskMethodBuilder`1[TResult].AwaitUnsafeOnCompleted[TAwaiter,TStateMachine] (TAwaiter& awaiter, TStateMachine& stateMachine) [0x0004c] in <162b154355a14010abd9ab37698d0a10>:0 
--- End of stack trace from previous location where exception was thrown ---
  at System.Runtime.CompilerServices.AsyncMethodBuilderCore+<>c.<ThrowAsync>b__6_1 (System.Object state) <0x9c1f9ba0 + 0x00058> in <162b154355a14010abd9ab37698d0a10>:0 
  at System.Threading.QueueUserWorkItemCallback.WaitCallback_Context (System.Object state) <0x9c151b64 + 0x0004f> in <162b154355a14010abd9ab37698d0a10>:0 
  at System.Threading.ExecutionContext.RunInternal (System.Threading.ExecutionContext executionContext, System.Threading.ContextCallback callback, System.Object state, System.Boolean preserveSyncCtx) <0x9c14ba74 + 0x001bb> in <162b154355a14010abd9ab37698d0a10>:0 
  at System.Threading.QueueUserWorkItemCallback.System.Threading.IThreadPoolWorkItem.ExecuteWorkItem () <0x9c151afc + 0x0003b> in <162b154355a14010abd9ab37698d0a10>:0 
  at System.Threading.ThreadPoolWorkQueue.Dispatch () [0x00074] in <162b154355a14010abd9ab37698d0a10>:0 
  at System.Threading._ThreadPoolWaitCallback.PerformWaitCallback () <0x9c15199c + 0x00007> in <162b154355a14010abd9ab37698d0a10>:0 
Xamarin caused by: android.runtime.JavaProxyThrowable: System.NullReferenceException: Object reference not set to an instance of an object
System.Runtime.CompilerServices.TaskAwaiter.OnCompletedInternal(Task task, Action continuation, bool continueOnCapturedContext, bool flowExecutionContext)
System.Runtime.CompilerServices.TaskAwaiter<TResult>.UnsafeOnCompleted(Action continuation)
System.Runtime.CompilerServices.AsyncTaskMethodBuilder<TResult>.AwaitUnsafeOnCompleted<TAwaiter, TStateMachine>(ref TAwaiter awaiter, ref TStateMachine stateMachine)<162b154355a14010abd9ab37698d0a10>:0
System.Threading.QueueUserWorkItemCallback.WaitCallback_Context(object state)
System.Threading.ExecutionContext.RunInternal(ExecutionContext executionContext, ContextCallback callback, object state, bool preserveSyncCtx)
System.Threading.QueueUserWorkItemCallback.System.Threading.IThreadPoolWorkItem.ExecuteWorkItem()
System.Threading.ThreadPoolWorkQueue.Dispatch()<162b154355a14010abd9ab37698d0a10>:0
System.Threading._ThreadPoolWaitCallback.PerformWaitCallback()

An so on.

Version Information

Microsoft Visual Studio Professional 2017
Version 15.5.2
VisualStudio.15.Release/15.5.2+27130.2010
Microsoft .NET Framework
Version 4.7.02053

Installed Version: Professional

Xamarin 4.8.0.753 (6575bd113)
Visual Studio extension to enable development for Xamarin.iOS and Xamarin.Android.

Xamarin.Android SDK 8.1.0.25 (HEAD/d8c6e504f)
Xamarin.Android Reference Assemblies and MSBuild support.

Other

My naive assumptions is that this is a bug in GC, we'll definitely try SGEN in next release to check that.
Will try new GC bridge as well

Activity

  1. changed the title [-]Random NullRef crashes in SSL/TLS stack[/-] [+]Random NullRef crashes in SSL/TLS (not only) stack[/+] on Jan 12, 2018
  2. marek-safar commented on Jan 15, 2018

    @marek-safar
    Contributor

    /cc @brendanzagaeski could Mono part of the problem be addressed by your latest fix

  3. brendanzagaeski commented on Jan 16, 2018

    @brendanzagaeski
    Contributor

    Hmm. These look a bit different. I quickly checked to see how unobserved exceptions from Tasks look on Xamarin.Android. As it turns out, exception telemetry coming from the UnobservedTaskException event would by default not include the android.runtime.JavaProxyThrowable Java type because the exception would be sent before the transition out of the C# runtime. I think the presence of android.runtime.JavaProxyThrowable in the exceptions in the initial comment means the exceptions have propagated to a Java thread by the time they are sent, and that wouldn't happen by default for the unobserved exceptions targeted by my recent fix.

  4. jonpryor commented on Jan 16, 2018

    @jonpryor
    Contributor

    @brendanzagaeski, @marek-safar: Related: Issue #1144.

    I think the presence of android.runtime.JavaProxyThrowable in the exceptions in the initial comment means the exceptions have propagated to a Java thread by the time they are sent

    Not quite; the presence of JavaProxyThrowable means that the exception was propagated to a Java stack frame.

    For example, consider Android calling an Activity.OnCreate() override:

    [Activity]
    partial class BadExample : Activity {
        protected override void OnCreate(Bundle bundle) {
            throw new InvalidOperationException("Bwa-ha-ha-ha");
        }
    }

    In the above, we'll have a Java stack frame calling BadExample.OnCreate() (through a delegate/JNI), and thus a stack of:

    Java Method > Managed Method (`BadActivity.OnCreate()`)
    

    When BadActivity.OnCreate() throws InvalidOperationException, it is wrapped into a JavaProxyThrowable and then JNIEnv::Throw() is called, making the JavaProxyThrowable a "pending" exception. When control returns to Java Method, the pending JavaProxyThrowable is thrown in the JVM, allowing normal catch and finally blocks to execute.

    Unfortunately (Issue #1144) we neglected to "unwrap" the JavaProxyThrowable before raising the AppDomain.UnhandleException event, which is probably why it's showing up in all of those stack traces...IFF a Java > Managed transition occurred, anyway.

  5. jonpryor commented on Jan 16, 2018

    @jonpryor
    Contributor

    @Belorus wrote:

    we'll definitely try SGEN in next release

    Xamarin.Android doesn't support Boehm. You're already using SGen -- it's the only GC that Xamarin.Android supports.

    Crashes on Androids:

    How are you collecting those stack traces? They seem oddly truncated, in that I would expect more than two calling frames. Maybe even the Java-side stack trace?

  6. Belorus commented on Jan 16, 2018

    @Belorus
    Author
  7. jonpryor commented on Jan 17, 2018

    @jonpryor
    Contributor

    @Belorus: I don't recognize that interface. :-(

    I can only assume it's a web UI to some crash reporter, which means I need to ask what the crash reporter is, how it works, and (most importantly) where is the rest of the stack trace?

    :-/

  8. jonpryor commented on Jan 17, 2018

    @jonpryor
    Contributor

    I can only assume it's a web UI to some crash reporter

    I can only assume I need to spend more time on reading comprehension, as you said it was "HockeyApp SDK 4.1.5".

    Doh!

    Unfortunately that doesn't immediately answer the "how does it work", though a bit of spelunking suggests that AppDomain.UnhandledException is used as well as java.lang.Thread.setDefaultUncaughtExceptionHandler().

    The possible answer to "where is the rest of the stack trace" is probably "< insert gnashing of teeth here >" ^H^H^H I mean "They use Throwable.printStackTrace(), with no calls to Throwable.getMessage()."

    JavaProxyThrowable provides the result of innerException.ToString() as the "message" for the base class, accessible via Throwable.getMessage(). (This is because I didn't know of a way to add stack frames to a java.lang.Throwable, apparently having completely overlooked Throwable.setStackTrace().

    At present, Throwable.getMessage() is the only way to get the inner/managed stack trace held by the JavaProxyThrowable instance, and it appears that (conjecture!) -- while Throwable.getMessage() is seemingly called -- which is presumably why we get the System.NullReferenceException: Object reference not set to an instance of an object message -- it's being truncated to one line.

    Which isn't particularly helpful.

  9. Belorus commented on Jan 17, 2018

    @Belorus
    Author

    Today i saw the winner (https://snag.gy/9R6ewZ.jpg):

    Xamarin caused by: android.runtime.JavaProxyThrowable: System.NullReferenceException: Object reference not set to an instance of an object
    

    We have realtime logs on client devices, there i saw the following (Still truncated, although received not via HockeyApp):

    AppDomain.CurrentDomain.UnhandledException. UtcNow is 2018-01-15T11:40:31. --> System.NullReferenceException: Object reference not set to an instance of an object
    

    In code it looks like (simplified):

    AppDomain.CurrentDomain.UnhandledException += OnCurrentDomainUnhandledException;
    
    // ...
    
    private static void OnCurrentDomainUnhandledException(object sender, UnhandledExceptionEventArgs e)
    {
        if (e.ExceptionObject is Exception exception)
        {
            Log.Fatal($"AppDomain.CurrentDomain.UnhandledException. UtcNow is {DateTime.UtcNow:s}. --> " + exception.ToString());
        }
    }
    

    Looks like exception that we get in event handler is already very lets say... consise.

  10. baulig commented on Jan 17, 2018

    @baulig
    Contributor

    I'm not exactly sure why, but this is using the legacy TLS stack, which is no longer supported and will soon be deleted.

    Looking over your stack traces:

    1. Legacy TLS, unsupported and scheduled for removal
    2. same
    3. We would need a full stack trace here - where's the SslStream used, what may have disposed it.
    4. Client Certificates are not supported - though we should only throw NotImplemented / NotSupported in the setter and not throw at all in the getter.
    5. This property returns an instance field - I don't see how we could null-ref here:
        internal ServerCertValidationCallback ServerCertValidationCallback {
            get { return certValidationCallback; }
        }
    
    1. Legacy TLS, see 1.

    I am very confused about these stack traces and don't really understand what's happening here. If this is related to TLS at all, then we should try to at least use BTLS on Android. Testing with the new web stack (once it gets integrated into Android) would be helpful as well.

    Let me know if there's anything I can help you with - at the moment, I'm not sure what I could possibly do because I just don't understand what's happening.

  11. changed the title [-]Random NullRef crashes in SSL/TLS (not only) stack[/-] [+]Random NullReference and InvalidCast crashes in mono class libraries[/+] on Jan 17, 2018
  12. 1 remaining item

  13. Belorus commented on Jan 19, 2018

    @Belorus
    Author

    image
    This is crash chart of one of our apps after transition from XA7.x (don't remember exactly) to 8.1
    As you see most crashes are not logic related, these are issues of runtime. We didn't have any of these before.

    image

  14. Belorus commented on Jan 19, 2018

    @Belorus
    Author

    Is there any way to downgrade Xamarin Andoid to 7.4 inside VS2017?
    I've downloaded https://xamarin.azureedge.net/XamarinforVisualStudio/Windows/Xamarin.VisualStudio_4.6.3.4.msi but it doesn't change anything after installation.

  15. joj commented on Jan 19, 2018

    @joj
    Member

    @Belorus the msi is only installing for VS2015. There is no easy way to downgrade an installed package in VS2017 AFAIK. I may be wrong, though.

  16. brendanzagaeski commented on Jan 19, 2018

    @brendanzagaeski
    Contributor

    I'm not sure if it will be helpful for this particular scenario (Xamarin.Android 7.1.0.43 might be too old for what you need), but for reference, Visual Studio 2017 version 15.0 is available from the Downloads section of my.VisualStudio.com to align with the Visual Studio servicing guidelines.

    (Related: Installing an earlier release of Visual Studio 2017.)

  17. akravch commented on Apr 10, 2019

    @akravch

    Hi, sorry for necroposting, but are there any updates regarding this? We are still experiencing this issue with the crashes around TLS, even thought we've updated Xamarin and VS since then:

    Android SDK Tools 1.16
    Visual Studio Professional 2017 15.9.28307.222
    Microsoft .NET Native SDK 15.0.24211
    Xamarin.Android 9.1.4.2 (HEAD/8255f42fc)
    SSL/TLS implementation Native TPS 1.2+

    Here is a few of the crashes:

    Xamarin caused by: android.runtime.JavaProxyThrowable: System.NullReferenceException: Object reference not set to an instance of an object
      at (wrapper xdomain-invoke) Mono.Security.Protocol.Tls.TlsStream.Write(byte[])
      at (wrapper remoting-invoke-with-check) Mono.Security.Protocol.Tls.TlsStream.Write(byte[])
    
    Xamarin caused by: android.runtime.JavaProxyThrowable: System.NullReferenceException: Object reference not set to an instance of an object
      at (wrapper xdomain-invoke) Mono.Security.Protocol.Tls.TlsStream.get_EOF()
      at (wrapper remoting-invoke-with-check) Mono.Security.Protocol.Tls.TlsStream.get_EOF()
    
    Xamarin caused by: android.runtime.JavaProxyThrowable: System.NullReferenceException: Object reference not set to an instance of an object
      at (wrapper xdomain-invoke) System.Net.HttpWebRequest.get_TlsSettings()
      at (wrapper remoting-invoke-with-check) System.Net.HttpWebRequest.get_TlsSettings()
    
  18. jonathanpeppers commented on Jun 1, 2022

    @jonathanpeppers
    Member

    Would anyone be able to comment if this issue is solved in .NET 6 Android projects? Thanks!

  19. ghost closed this as completedon Jun 8, 2022
  20. ghost locked as resolved and limited conversation to collaborators on Jul 9, 2022
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Metadata

Metadata

Labels

Area: App RuntimeIssues in `libmonodroid.so`.Area: Mono RuntimeMono-related issues: BCL bugs, AOT issues, etc.need-infoIssues that need more information from the author.

Type

No type

Projects

No projects

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions