Benedicht / BestHTTP-Issues

Issue tracking repo for the Best HTTP and all related Unity plugins.
https://assetstore.unity.com/publishers/4137
12 stars 1 forks source link

An unexpected IL2CPP exception on iOS devices when entering the Background. #177

Closed firatgs closed 6 months ago

firatgs commented 1 year ago

Hello, the following exception occurs when user goes to background. Most of the users has either no connection to the internet or a bad connection. But I saw couple of users has connection.

Role:               Background
OS Version:         iOS 16.6.1

Il2CppExceptionWrapper: 

0  UnityFramework +0x1a10548       il2cpp::vm::Exception::Raise(Il2CppException*, MethodInfo*) (Exception.cpp:115:9)
1  UnityFramework +0x19c5d50       il2cpp_codegen_raise_exception(Exception_t*, MethodInfo*) (il2cpp-codegen-il2cpp.cpp:374:5)
2  UnityFramework +0x2053950       TcpClient_CheckDisposed_mF1DD34F6D1FA4C83EF0BF8C2B7EDDDAED9D12BBA (BestHTTP41.cpp:15315:3)
3  UnityFramework +0x3dad8         TcpClient_Connect_m08EC5E88B9F463DE7EAF40807C19DA33EE698D90::$_5::operator()() const (BestHTTP41.cpp:14346:5)
4  UnityFramework +0x2052f54       TcpClient_Connect_m08EC5E88B9F463DE7EAF40807C19DA33EE698D90 (BestHTTP41.cpp:14472:2)
5  UnityFramework +0x2053468       TcpClient_Connect_m6E785827795EDEED859238835787810E3D00E4FB (BestHTTP41.cpp:14904:4)
6  UnityFramework +0x209b50c       TCPConnector_Connect_mFF2188E178DCCAA9AFE787AAE66D7396A25E6C8B (BestHTTP44.cpp:21654:5)
7  UnityFramework +0x2099f38       HTTPConnection_ThreadFunc_mE79EAE3CE7AEE073E71DCC2506B7BF6F34996340 (BestHTTP44.cpp:20242:3)
8  UnityFramework +0x36cc624       ContextCallback_Invoke_m872CCCD40428B88C2612772491BE5157895B5F61_inline(ContextCallback_tE8AFBDBFCC040FDA8DA8C1EEFE9BD66B16BDA007*, Il2CppObject*, MethodInfo const*) (mscorlib8.cpp:34314:2)
9  UnityFramework +0x1a2d174       il2cpp::vm::Runtime::InvokeWithThrow(MethodInfo const*, void*, void**) (Runtime.cpp:578:13)
10 UnityFramework +0x1a2cfd4       il2cpp::vm::Runtime::Invoke(MethodInfo const*, void*, void**, Il2CppException**) (Runtime.cpp:564:20)
11 UnityFramework +0x19da128       il2cpp::icalls::mscorlib::System::Threading::ThreadStart(void*) (Thread.cpp:64:17)
12 UnityFramework +0x19ebbcc       il2cpp::os::Thread::RunWrapper(void*) (Thread.cpp:201:9)
13 UnityFramework +0x19eebb4       il2cpp::os::ThreadImpl::ThreadStartWrapper(void*) (ThreadImpl.cpp:125:9)
14 libsystem_pthread.dylib +0x16b4 __pthread_start
15 libsystem_pthread.dylib +0xb84  _thread_start

The error is caused by:

        private void CheckDisposed()
        {
            if (disposed)
                throw new ObjectDisposedException(GetType().FullName);
        }

Weird thing is the exception should have been caught by following try-catch block. But it seems it is not.

           if (this.connector == null)
            {
                this.connector = new Connections.TCPConnector();

                try
                {
                    this.connector.Connect(this.CurrentRequest);
                }
                catch(Exception ex)
                {
                    if (HTTPManager.Logger.Level == Logger.Loglevels.All)
                        HTTPManager.Logger.Exception("HTTPConnection", "Connector.Connect", ex, this.Context, this.CurrentRequest.Context);

                    if (ex is TimeoutException)
                        this.CurrentRequest.State = HTTPRequestStates.ConnectionTimedOut;
                    else if (!this.CurrentRequest.IsTimedOut) // Do nothing here if Abort() got called on the request, its State is already set.
                    {
                        this.CurrentRequest.Exception = ex;
                        this.CurrentRequest.State = HTTPRequestStates.Error;
                    }

                    ConnectionEventHelper.EnqueueConnectionEvent(new ConnectionEventInfo(this, HTTPConnectionStates.Closed));

                    return;
                }

When I looked the generated IL2CPP code:

    try
    {// begin try (depth: 1)
        // this.connector.Connect(this.CurrentRequest);
        TCPConnector_tB8625031CFDB9AFFE426BE6B6110DDD799EAD701* L_14 = __this->___connector_10;
        HTTPRequest_t32091DC566685F9827D7D7EA51A5D6601CB6485B* L_15;
        L_15 = ConnectionBase_get_CurrentRequest_m6387678B3FA63D65ADD02299A6423B566444996A_inline(__this, NULL);
        NullCheck(L_14);
        TCPConnector_Connect_mFF2188E178DCCAA9AFE787AAE66D7396A25E6C8B(L_14, L_15, NULL);
        // }
        goto IL_0118;
    }// end try (depth: 1)
    catch(Il2CppExceptionWrapper& e)
    {
        if(il2cpp_codegen_class_is_assignable_from (((RuntimeClass*)il2cpp_codegen_initialize_runtime_metadata_inline((uintptr_t*)&Exception_t_il2cpp_TypeInfo_var)), il2cpp_codegen_object_class(e.ex)))
        {
            IL2CPP_PUSH_ACTIVE_EXCEPTION(e.ex);
            goto CATCH_0098;
        }
        throw e;
    }

CATCH_0098:
    {// begin catch(System.Exception)
        {
            // catch(Exception ex)
            V_0 = ((Exception_t*)IL2CPP_GET_ACTIVE_EXCEPTION(Exception_t*));
            // if (HTTPManager.Logger.Level == Logger.Loglevels.All)
            il2cpp_codegen_runtime_class_init_inline(((RuntimeClass*)il2cpp_codegen_initialize_runtime_metadata_inline((uintptr_t*)&HTTPManager_t86D8215611565E4EA17A7F33953CD53FFE3D2E01_il2cpp_TypeInfo_var)));
            RuntimeObject* L_16;
            L_16 = HTTPManager_get_Logger_mEDD203F65ED42CBEEA69F90048726069CCF81C9C(NULL);
            NullCheck(L_16);
            int32_t L_17;
            L_17 = InterfaceFuncInvoker0< int32_t >::Invoke(0 /* BestHTTP.Logger.Loglevels BestHTTP.Logger.ILogger::get_Level() */, ((RuntimeClass*)il2cpp_codegen_initialize_runtime_metadata_inline((uintptr_t*)&ILogger_t8F36E3934D3F149219F504463CAE778D10667451_il2cpp_TypeInfo_var)), L_16);
            if (L_17)
            {
                goto IL_00cc;
            }
        }

It seems this condition state fails and directly throws the exception as unhandled state.

        if(il2cpp_codegen_class_is_assignable_from (((RuntimeClass*)il2cpp_codegen_initialize_runtime_metadata_inline((uintptr_t*)&Exception_t_il2cpp_TypeInfo_var)), il2cpp_codegen_object_class(e.ex)))
        {
            IL2CPP_PUSH_ACTIVE_EXCEPTION(e.ex);
            goto CATCH_0098;
        }
        throw e;
besthttp
Benedicht commented 1 year ago

Is this happening with Unity 2021.3 (from your other issue)?

I don't have any clue why it doesn't catch that exception. I wouldn't think the plugin does anything wrong here, so i'm thinking about posting to the Unity forums, maybe someone knows in what case it wouldn't catch it.

firatgs commented 1 year ago

yes, Sorry I forgot to mention that.

Environment = Unity 2021.3.20f1, Xcode 15.0.

I agree with your point. Just wanted to point out that there could be a better handling by not use the object if it has been disposed or about to dispose instead of checking it in inner scope and throwing an exception as an alternative if there are no immediate solution out there.

Benedicht commented 6 months ago

Closing this issue for now, Unity fixed quite a lot of issues on their end too.