UnityIAP init freezes the main thread

Sometimes (rate is ~5%) our application hangs on start. No errors or exceptions, it’s definitely a deadlock of some kind. This happens on both Android and iOS. Recently we were able to catch this on our side and get a few logcat traces (they are attached). In all cases last app log is ‘UnityIAP Version: 2.2.7’. This is the last call made on the main thread before the deadlock (see the logs). We double-checked that the very next instruction after ‘ConfigurationBuilder.Instance(StandardPurchasingModule.Instance())’ is not called. We tried adding a 1 second delay before this line and got the same results.

We use Unity 2019.4.21 with latest IAP (UPM package version is 2.2.2, UnityIAP plugin is 2.2.7).

Any suggestions or possible workarounds?

6880244–803633–com.wordfarm.scapes-logcat.txt (171 KB)
6880244–803636–com.wordfarm.scapes-logcat-2.txt (208 KB)
6880244–803639–com.wordfarm.scapes-logcat-3.txt (170 KB)

Please share your initialization code, perhaps compare to IAPManager.cs in the Sample IAP Project Sample IAP Project Place identifiable Debug.Log statements throughout your IAP callbacks to trace the flow which will show in the logcat log.

Hello @JeffDUnity3D , here’s the init code, it’s pretty standard:

try
{
    Debug.Log($"[{ServiceTag}] Initialize");

    // ...

    Debug.Log($"[{ServiceTag}] ConfigurationBuilder.Instance");
    var builder = ConfigurationBuilder.Instance(StandardPurchasingModule.Instance());
    Debug.Log($"[{ServiceTag}] UnityPurchasing.Initialize");

    // ...

    Debug.Log($"[{ServiceTag}] UnityPurchasing.Initialize");
    UnityPurchasing.Initialize(this, builder);
}
catch (Exception e)
{
    Debug.LogError($"[{ServiceTag}] Initialize failed: {e}");
}

You can search for these in the logs attached.

@abogarsuI suspect there is other code involved, please share your full purchase script. And please follow my previous instructions and provide the log. Compare to the Sample IAP Project which does not exhibit this behavior.

@JeffDUnity3D I cannot share the code because of NDA. The logs attached in my initial post contain the Debug.Log() markers (namely ‘ConfigurationBuilder.Instance’ and ‘UnityPurchasing.Initialize’). All logs show that StandardPurchasingModule.Instance() has been called and very next line (with ‘UnityPurchasing.Initialize’ marker) has not.

I’m attaching a symbolized thread traces from iOS freeze. If my understanding is correct, StandardPurchasingModule.Instance() attempts to load an asset and this call somehow interferes with other pending async asset load operations.

6884168–804374–symbolicated_crash.txt (153 KB)

@abogarsukov-braingames A trace would not be helpful unfortunately, we would need steps to reproduce. Perhaps start with the Sample IAP Project

@JeffDUnity3D It appears to be a known issue: Unity Issue Tracker - [Mobile] Calling Resources.Load() while asynchronously loading assetbundle by UnityWebRequest makes main thread stuck. In our case the problem was in Resources.Load call inside StandardPurchasingModule.Instance(). So waiting for the fix.

Got it, so not specific to IAP (not an IAP fix)

@JeffDUnity3D this is not an IAP issue indeed. But, as stated in the above issue resolution notes, there is always a risk of deadlock when using a mix of sync and async. In this particular case Unity IAP unconditionally calls Resources.Load() under the hood. This is problematic for a few reasons:

  • StandardPurchasingModule.Instance() looks like just factory method (thus, users don’t expect any side effects);
  • There is no choice (for IAP users) whether to use synchronous or asynchronous resource loading; in my case this resulted in non-obvious deadlock.

That said, in my opinion, resource loading should be moved out of StandardPurchasingModule.Instance() call into UnityPurchasing.Initialize() and made async (i.e. Resources.LoadAsync()). Another solution I see is adding an async version of StandardPurchasingModule.Instance().

Please consider these changes in upcoming IAP releases.

1 Like

@JeffDUnity3D

As described below thread, I faced to a similar problem when I use Unity 2020.3.22f1 and IAP 4.1.2.

How can I detect if it’s caused by the same problem or not?
Any suggestion to detect the cause and to resolve it?

@k-hida I’d suggest to place logs before and after StandardPurchasingModule.Instance() call. Then you’d have to reproduce the issue and look at the logs to see if next line after StandardPurchasingModule.Instance() gets executed. If not, it’s exactly this issue.