google-ar / arcore-unity-extensions

Google ARCore Extensions and Geospatial Creator for Unity's AR Foundation
Other
353 stars 96 forks source link

App crashes after ARSession.Reset() #90

Open TakafumiYuasa opened 2 years ago

TakafumiYuasa commented 2 years ago

This problem does not occur without Cloud Anchor Mode Enabled.

Adding Session.Reset() to PersistentCloudAnchorsController.cs in ARCore Extensions Samples.

public void SwitchToHomePage()
{
    ResetAllViews();
    Mode = ApplicationMode.Ready;
    ResolvingSet.Clear();
    HomePage.SetActive(true);

    // Added session reset
    SessionCore.Reset();
}

Log when problem occurs.

2022/09/14 11:05:27.702 native I0000 00:00:1663121127.702415   16368 session.cc:1730] Session::PauseWithAnalytics returning OK.
2022/09/14 11:05:27.706 native I0000 00:00:1663121127.706211   16368 session_manager.cc:322] ArPresto::Moving from ArPrestoStatus 100 to 102
2022/09/14 11:05:27.706 native I0000 00:00:1663121127.706344   16324 session_manager.cc:85] ArPresto::Session destroyed.
2022/09/14 11:05:27.706 native I0000 00:00:1663121127.706400   16324 session_lite_c_api.cc:37] Deleting ArSession...
2022/09/14 11:05:27.747 CRASH *** *** *** *** *** *** *** *** *** *** *** *** *** *** *** ***
2022/09/14 11:05:27.747 CRASH Version '2021.1.22f1 (a137e5fb0427)', Build type 'Release', Scripting Backend 'il2cpp', CPU 'arm64-v8a'
2022/09/14 11:05:27.747 CRASH Build fingerprint: 'google/oriole/oriole:12/SQ3A.220705.004.A1/8847371:user/release-keys'
2022/09/14 11:05:27.747 CRASH Revision: 'MP1.0'
2022/09/14 11:05:27.747 CRASH ABI: 'arm64'
2022/09/14 11:05:27.747 CRASH Timestamp: 2022-09-14 11:05:27+0900
2022/09/14 11:05:27.747 CRASH pid: 16306, tid: 16522, name: Thread-28  >>> com.DefaultCompany.ARCoreSamples.Test3 <<<
2022/09/14 11:05:27.747 CRASH uid: 10266
2022/09/14 11:05:27.747 CRASH signal 11 (SIGSEGV), code 1 (SEGV_MAPERR), fault addr 0x6f00000018
2022/09/14 11:05:27.747 CRASH     x0  b40000722983aee0  x1  b4000073a9c9e4a0  x2  0000000000000000  x3  0000006fb7de68d0
2022/09/14 11:05:27.748 CRASH     x4  0000000000000000  x5  b4000071f98c6bfd  x6  6f7073746f68390a  x7  6363366163652f74
2022/09/14 11:05:27.748 CRASH     x8  0000006f00000000  x9  0000006fde2ea470  x10 0000000000000040  x11 00000000e9912f10
2022/09/14 11:05:27.748 CRASH     x12 0000ffff00000eff  x13 00000000930443af  x14 bf5c731e824f3c34  x15 0000008000000000
2022/09/14 11:05:27.748 CRASH     x16 0000006fde565420  x17 0000007441f68c58  x18 0000006fb1e10000  x19 b400007289880aa8
2022/09/14 11:05:27.748 CRASH     x20 b4000072898809e0  x21 b40000722983aee0  x22 b40000721984e180  x23 b4000073a9c9e4a0
2022/09/14 11:05:27.748 CRASH     x24 00000000000093be  x25 b40000721984e198  x26 0000006fb7de7000  x27 b4000071e9900910
2022/09/14 11:05:27.748 CRASH     x28 b4000071e9900928  x29 b4000071b9826570
2022/09/14 11:05:27.748 CRASH     sp  0000006fb7de6750  lr  0000006fde2eaa00  pc  0000006fde2eaa38
2022/09/14 11:05:27.748 CRASH backtrace:
2022/09/14 11:05:27.748 CRASH       #00 pc 0000000001eb6a38  /data/app/~~uDRgmCD5EpTbNFAzl59idA==/com.google.ar.core-uxIBKe87ca83Vd3iYCMpsg==/base.apk (BuildId: 2461ce044d3a3d0250884c0b839ce522)
2022/09/14 11:05:27.748 CRASH       #01 pc 0000000001ebc108  /data/app/~~uDRgmCD5EpTbNFAzl59idA==/com.google.ar.core-uxIBKe87ca83Vd3iYCMpsg==/base.apk (BuildId: 2461ce044d3a3d0250884c0b839ce522)
2022/09/14 11:05:27.748 CRASH       #02 pc 0000000001ebd280  /data/app/~~uDRgmCD5EpTbNFAzl59idA==/com.google.ar.core-uxIBKe87ca83Vd3iYCMpsg==/base.apk (BuildId: 2461ce044d3a3d0250884c0b839ce522)
2022/09/14 11:05:27.748 CRASH       #03 pc 000000000128f9e4  /data/app/~~uDRgmCD5EpTbNFAzl59idA==/com.google.ar.core-uxIBKe87ca83Vd3iYCMpsg==/base.apk (BuildId: 2461ce044d3a3d0250884c0b839ce522)
2022/09/14 11:05:27.748 CRASH       #04 pc 000000000128e29c  /data/app/~~uDRgmCD5EpTbNFAzl59idA==/com.google.ar.core-uxIBKe87ca83Vd3iYCMpsg==/base.apk (BuildId: 2461ce044d3a3d0250884c0b839ce522)
2022/09/14 11:05:27.748 CRASH       #05 pc 000000000128a304  /data/app/~~uDRgmCD5EpTbNFAzl59idA==/com.google.ar.core-uxIBKe87ca83Vd3iYCMpsg==/base.apk (BuildId: 2461ce044d3a3d0250884c0b839ce522)
2022/09/14 11:05:27.748 CRASH       #06 pc 00000000000b1590  /apex/com.android.runtime/lib64/bionic/libc.so (__pthread_start(void*)+204) (BuildId: 53a228529316d67f22e241dd17ea9b9e)
2022/09/14 11:05:27.748 CRASH       #07 pc 0000000000050fac  /apex/com.android.runtime/lib64/bionic/libc.so (__start_thread+64) (BuildId: 53a228529316d67f22e241dd17ea9b9e)

This issue is occurring in the following environments.

Hardware I'm using for testing:

chankeiro commented 1 year ago

Hi,

I am experiencing the same crash. In my case it only fails if I call ARSession.Reset() or LoaderUtility.Deinitialize() and the cloud anchor is still in CloudAnchorState.TaskInProgress. However, it doesn't crash if I deinitialize after the anchor has reached CloudAnchorState.Success.

While in TaskInprogress state, in the logcat I can see that there is a thread making calls to what I think is the ARCloud Api backend trying to resolve the anchor. This is the logcat:

JniHelper: attached thread (Called from line 217).
JniHelper: about to detach thread (Called from line 217).
JniHelper: detached thread (Called from line 217).
W0000 00:00:1675348850.684429   15494 cloud_anchor_watcher.cc:705] No valid responses were returned from the server: NOT_FOUND: No anchor_t_camera transforms were found.
=== Source Location Trace: ===
third_party/arcore/ar/persistence/cloud_anchor_watcher.cc:666

The pattern I found is that, while the app is doing these calls, trying to deinitialize the AR Subsystems crashes it.

I have tried several strategies to prevent the system from continuing to track the anchor before deinitializing the ar systems, but with no success. There is a detach() method in the ARCore Android SDK that seems to do exactly what I need https://developers.google.com/ar/de...veloper-guide#cancel_or_remove_a_cloud_anchor but I don't see an equivalent in ARFoundation, except by destroying the GameObject that represents the anchor with Destroy(anchor.gameObject), which theoretically also detaches the anchor for the session, https://developers.google.com/ar/re...e/XR/ARCoreExtensions/ARCloudAnchor#ondestroy but it doesn't help to prevent the crash.

I've gone through a lot of ARFoundation documentation and samples, but I haven't found a solution yet.

This is the code that crashes:

// If _arCloudAnchor is in CloudAnchorState.TaskInProgress, the following code generates the SIGSEGV crash

if (_arCloudAnchor.gameObject != null)
{
     Destroy(_arCloudAnchor.gameObject);
}

SceneManager.LoadScene(0);
LoaderUtility.Deinitialize(); // or ARSession.Reset()

The crash looks like this:

 *** *** *** *** *** *** *** *** *** *** *** *** *** *** *** ***
Version '2021.3.11f1 (0a5ca18544bf)', Build type 'Release', Scripting Backend 'il2cpp', CPU 'arm64-v8a'
Build fingerprint: 'POCO/lmi_eea/lmi:12/SKQ1.211006.001/V13.0.5.0.SJKEUXM:user/release-keys'
Revision: '0'
ABI: 'arm64'
Timestamp: 2023-02-02 15:40:51+0100
pid: 14600, tid: 15494, name: Thread-88  >>> com.bercetech.fleepas.debug <<<
uid: 10419
signal 11 (SIGSEGV), code 1 (SEGV_MAPERR), fault addr 0x7900000018
x0  b400007d6bb9e5e0  x1  b4000078ddc72cc0  x2  000000000000ca12  x3  00000078ef0ca9f0
x4  00000078ef0ca678  x5  b400007d984a3ddd  x6  6f7073746f68390a  x7  3137653630622f74
x8  0000007900000000  x9  000000791dc340b8  x10 00000000ffffffff  x11 0000007903b00a1c
x12 0199999999999999  x13 0000000000000080  x14 d028af96de096b4e  x15 0000000080000000
x16 0000007eb4d90d60  x17 0000007eb4d80654  x18 00000078e9584000  x19 b400007d8c511888
x20 00000078ef0ca9f0  x21 b400007d6bb9e5e0  x22 b4000078ddc0fe10  x23 b4000078ddc72cc0
x24 000000000000ca12  x25 b4000078ddc0fe28  x26 00000078ef0cb000  x27 b400007971522500
x28 b400007971522518  x29 b400007df2f03f10
sp  00000078ef0ca870  lr  000000791dc34664  pc  000000791dc346a4
backtrace:
#00 pc 0000000001b996a4  /data/app/~~055EZaO9zA7f6K9NPokqQQ==/com.google.ar.core-JxqCQPsaGDQ_jZdLYTGe0Q==/base.apk (BuildId: a3356455c642199cf0332f847b9875f9)
#01 pc 0000000001b9e9fc  /data/app/~~055EZaO9zA7f6K9NPokqQQ==/com.google.ar.core-JxqCQPsaGDQ_jZdLYTGe0Q==/base.apk (BuildId: a3356455c642199cf0332f847b9875f9)
#02 pc 0000000001b72004  /data/app/~~055EZaO9zA7f6K9NPokqQQ==/com.google.ar.core-JxqCQPsaGDQ_jZdLYTGe0Q==/base.apk (BuildId: a3356455c642199cf0332f847b9875f9)
#03 pc 00000000012a58fc  /data/app/~~055EZaO9zA7f6K9NPokqQQ==/com.google.ar.core-JxqCQPsaGDQ_jZdLYTGe0Q==/base.apk (BuildId: a3356455c642199cf0332f847b9875f9)
#04 pc 00000000012a4028  /data/app/~~055EZaO9zA7f6K9NPokqQQ==/com.google.ar.core-JxqCQPsaGDQ_jZdLYTGe0Q==/base.apk (BuildId: a3356455c642199cf0332f847b9875f9)
#05 pc 000000000129fffc  /data/app/~~055EZaO9zA7f6K9NPokqQQ==/com.google.ar.core-JxqCQPsaGDQ_jZdLYTGe0Q==/base.apk (BuildId: a3356455c642199cf0332f847b9875f9)
#06 pc 00000000000efb14  /apex/com.android.runtime/lib64/bionic/libc.so (__pthread_start(void*)+264) (BuildId: 94065bf91428f6ae9fb310c478171302)
#07 pc 000000000008c35c  /apex/com.android.runtime/lib64/bionic/libc.so (__start_thread+68) (BuildId: 94065bf91428f6ae9fb310c478171302)

ARFoundation vs: 4.2.7 Unity vs: 2021.3.11f1 Smartphone OS: Android 12

chankeiro commented 1 year ago

Thanks for fixing this. Do you know in which release this fix will be included?

chankeiro commented 1 year ago

After updating to vs 1.38 and switching all the CloudAnchor functions to the Promise paradigm as suggested in release 1.37, the problem is solved.

TakafumiYuasaHL commented 5 months ago

I tried it with ARCore Extensions 1.43.0. Since the sample was changed to Promise paradigm, I was hoping that the problem would be fixed. But unfortunately the problem continues to occur.

@devbridie Am I calling SessionCore.Reset() in the wrong place? If you have any information please let me know.

GameWorldsDEV commented 2 months ago

WE HAVE FIXED THIS ISSUE ON A UNITY FORM !

check it out. (https://discussions.unity.com/t/ar-foundation-stopped-working-all-of-a-sudden-on-android/936111/23)

here's a copy and paste of the comment . im spreading this to see people flourish it took us 2 weeks bashing my head against the wall lol .

So question ?:raising_hand_man:t5: Where you able to find this in the XR Orgin script or AR Session script ?

And from what you’d said it looks like if we take out the ARSession.Reset then do it after it initializes then we should be ok and the app should stop crashing .

So basically I can either do that function separately outside that script or call for that function last after everything is initiated.

I’m currently looking to test this theory and see if that works . Any suggestions will be appreciated!

We have had this issue for some time now and went back to iOS development now that we are done with it we was hoping we gave some time for them to fix it . Now it’s time to take matters in our own hands if possible.

EDIT : SAME DAY

After testing this out and debugging the changes and updates in code and with a little help from chat gpt . I realized in the older version of my app (unity 2019) I am using addressables for my tracked images and we had to call for the ARsession to rest in iOS to make sure users always had the most updated tracked images . IOS Can handle this while the AR session is being created but Android can not .

Apparently if we call this when the android system is building the Ar.Session it will crash . So between me a chat gpt we came up with a solution too either make the reset for IOS only or make a delay for is if it’s android. here is the summary I hope this helps . We have been working on this for a week and a half now !

!!! NOTE !!! if you have made a script you have added the ARSession.Reset then you must edit it with the same constraints as my script making it have a delay or not do it for android at all

Issue Summary

The original issue involved crashes occurring on Android devices when attempting to reset the AR session during initialization. This reset was part of a script designed to dynamically update an XR tracked image library from Unity Cloud, a necessity for iOS devices to ensure they always had the most up-to-date XR library. However, on Android, this reset would cause crashes if called while the AR session was still initializing. On iOS, the reset operation worked without issues, but Android’s initialization process couldn’t handle it, leading to instability.

Original Script

The original script attempted to reset the AR session immediately after starting, which worked well on iOS but caused issues on Android.

csharp

Copy code

using UnityEngine; using UnityEngine.XR.ARFoundation;

public class ARSessionRest : MonoBehaviour { [SerializeField] private ARSession arSession;

void Start()
{
    arSession.Reset();
}

} Issue with Original Script:

iOS: The reset operation was successful, ensuring that the most recent XR library was loaded without any issues. Android: The script caused crashes because it attempted to reset the AR session while it was still initializing. Updated Solution Options

To resolve this issue and maintain functionality across both platforms, two different solutions were implemented:

Platform-Specific Delayed Reset Script: This solution applies a delay before resetting the AR session on Android devices, ensuring the reset only occurs after the AR session is fully initialized. On iOS, the reset happens immediately as before. Platform-Specific Reset Script: This solution makes the reset platform-specific, where the reset only happens on iOS and is completely skipped on Android. This ensures stability on Android while retaining the necessary functionality on iOS.

  1. Platform-Specific Delayed Reset Script

This script ensures the reset operation is delayed on Android until the AR session is fully initialized, while iOS performs the reset immediately.

csharp

Copy code

using System.Collections; using UnityEngine; using UnityEngine.XR.ARFoundation;

public class ARSessionRest : MonoBehaviour { [SerializeField] private ARSession arSession;

void Start()
{

if UNITY_IOS

    // Directly reset for iOS as it handles this well
    arSession.Reset();

elif UNITY_ANDROID

    // Delay the reset until the session is fully initialized on Android
    StartCoroutine(WaitForSessionAndReset());

endif

}

private IEnumerator WaitForSessionAndReset()
{
    // Wait until the AR session is fully initialized
    while (ARSession.state != ARSessionState.SessionTracking)
    {
        yield return null;
    }

    // Once the session is tracking, reset the AR session
    arSession.Reset();
}

} Explanation:

iOS: The reset is performed immediately as iOS handles this operation well without causing crashes. Android: The reset is delayed until the AR session is fully initialized, preventing the crashes that occurred due to the reset being called too early.

  1. Platform-Specific Reset Script

This script performs the reset operation only on iOS and skips it entirely on Android.

csharp

Copy code

using UnityEngine; using UnityEngine.XR.ARFoundation;

public class ARSessionRest : MonoBehaviour { [SerializeField] private ARSession arSession;

void Start()
{

if UNITY_IOS

    // Perform the reset only for iOS
    arSession.Reset();

elif UNITY_ANDROID

    // Skip the reset entirely for Android
    // The AR session will continue without resetting

endif

}

} Explanation:

iOS: The reset is performed as needed to dynamically update the XR library. Android: The reset is skipped to prevent crashes, ensuring stability on this platform while still running the AR session. Outcome

With these two updated scripts, you can choose the approach that best fits your needs:

Platform-Specific Delayed Reset Script: Ensures the reset is handled carefully on Android by delaying it until the session is fully initialized, while maintaining immediate resets on iOS. Platform-Specific Reset Script: Skips the reset on Android entirely, avoiding potential issues while still performing the necessary reset on iOS. Both solutions maintain the functionality required for iOS devices while ensuring that Android devices no longer crash during the AR session initialization. I hoped we helped out !

Check us out at GameWorlds.online for our future projects !

TakafumiYuasaHL commented 2 months ago

@GameWorldsDEV Thanks for the information! However, this issue may not be resolved.

Because...the proposed solution is:

Platform-Specific Delayed Reset Script

The steps to reproduce this issue is to wait 6 minutes or more. There is enough time for ARSession to complete initialization.

Platform-Specific Reset Script

If I don't call Reset, the plane I detected remains. Therefore, it is not possible to disable it on Android.

Thank you for providing such good information. I am bashing my head against the wall, too. lol

chankeiro commented 2 months ago

@TakafumiYuasaHL , If you have not already done so before resetting the session, it may help to cancel any pending cloud anchor promises:

_resolveCloudAnchorPromise = _anchorManager.ResolveCloudAnchorAsync(cloudAnchorId);

// Run this before resetting the AR Session
if (_resolveCloudAnchorPromise != null)
{
    _resolveCloudAnchorPromise.Cancel();
}

I hope it helps.

TakafumiYuasaHL commented 2 months ago

@chankeiro Thank you for information!!

I tried cancel promises. I modified the ARCore extension sample as follows.

Add method to PersistentCloudAnchorsController.cs that calls ARSession.Reset().

public void ARSessionReset()
{
    SessionCore.Reset();
}

This method call in ARViewManager.OnDisable().

public void OnDisable()
{
    if (_qualityIndicator != null)
    {
        Destroy(_qualityIndicator.gameObject);
        _qualityIndicator = null;
    }

    ...

    foreach (var promise in _resolvePromises)
    {
        promise.Cancel();
    }

    _resolvePromises.Clear();
    Controller.ARSessionReset();    // Add call reset

    ...

}

Call reset after canceling promises. But an issue occurred. There may be something missing.

I'll try different things, thanks!!

chankeiro commented 2 months ago

Ok, a workaround while you don't find the cause of the problem might be to disable all your AR managers, destroy trackables, meshes, etc. everything related to your AR session instead of resetting it. Something like that:

void DisableARFoundation()
        {
            if (_arfSession.enabled)
            {
                _arInputManager.enabled = false;
                _trackedPoseDriver.enabled = false;
                _arCoreExtensions.enabled = false;
                _arAnchorManager.enabled = false;
                // Remove all trackables. This includes AR cloud anchors. 
                // Otherwise, if the user reloads a scene with cloud anchors 
                // that were previously resolved in another session, the anchors
                // will automatically resolve, but they won't be properly located.
                foreach (var anchor in _arAnchorManager.trackables)
                    Destroy(anchor);
                _cloudAnchorManager.enabled = false; 
                _arMeshManager.enabled = false;
                _arMeshManager.DestroyAllMeshes(); // Destroy armeshes, if you have created any with the ARMeshManager.
                _arOcclusionManager.enabled = false;
                _arfSession.enabled = false;
                _arfCameraBackground.enabled = false;
                _arfCameraManager.enabled = false;
            }
        }

If you need the AR capabilities, you can turn them back on:

void EnableARFoundation()
        {
            // Enable the managers exactly in this order
            _arfCameraManager.enabled = true;           
            _arfCameraBackground.enabled = true;
            _arfSession.enabled = true;
            // Enable  ARCore Extensions after activating the ARSession. 
            // Also before the anchor manager, otherwise the feature quality
            // estimation for cloud anchors may not work correctly in some cases.
#if !UNITY_EDITOR
            _arCoreExtensions.enabled = true; 
#endif
            _trackedPoseDriver.enabled = true;
            _arInputManager.enabled = true;
#if !UNITY_EDITOR
            _arAnchorManager.enabled = true; 
#endif
        }