Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Purchases framework causes crash on older iOS devices #278

Closed
5 tasks done
kbunarjo opened this issue Apr 28, 2023 · 14 comments · Fixed by RevenueCat/purchases-ios#2565
Closed
5 tasks done

Purchases framework causes crash on older iOS devices #278

kbunarjo opened this issue Apr 28, 2023 · 14 comments · Fixed by RevenueCat/purchases-ios#2565
Labels
bug Something isn't working triaged

Comments

@kbunarjo
Copy link

kbunarjo commented Apr 28, 2023

Describe the bug
We had recently updated this framework from 2.0.1 to version 4.14.1. However, we've started getting crashes on older iOS devices. The crash happens right after our splash screen is finished displaying -- right when our first scene is loaded in. The stack trace for this issue is here:

Date/Time:           2023-04-26 21:45:28.2987 -0500
Launch Time:         2023-04-26 21:45:15.3798 -0500
OS Version:          iPhone OS 12.5.7 (16H81)
Baseband Version:    10.80.02
Report Version:      104

Exception Type:  EXC_CRASH (SIGABRT)
Exception Codes: 0x0000000000000000, 0x0000000000000000
Exception Note:  EXC_CORPSE_NOTIFY
Triggered by Thread:  0

Thread 0 name:
Thread 0 Crashed:
0   dyld                          	0x00000001001ae418 __abort_with_payload + 8
1   dyld                          	0x00000001001ada58 abort_with_payload_wrapper_internal + 100 (terminate_with_reason.c:72)
2   dyld                          	0x00000001001ada88 abort_with_payload + 12 (terminate_with_reason.c:94)
3   dyld                          	0x00000001001708f8 dyld::halt(char const*) + 304 (dyld.cpp:4024)
4   dyld                          	0x0000000100170a14 dyld::fastBindLazySymbol(ImageLoader**, unsigned long) + 284 (dyld.cpp:4112)
5   libdyld.dylib                 	0x00000001d7353848 dyld_stub_binder + 60
6   UnityFramework                	0x0000000102346a38 type metadata completion function for SK2StoreProduct + 24 (<compiler-generated>:0)
7   libswiftCore.dylib            	0x0000000205128820 swift_getSingletonMetadata + 636 (MetadataCache.h:920)
8   UnityFramework                	0x0000000102346a18 type metadata accessor for SK2StoreProduct + 48 (<compiler-generated>:0)
9   libswiftCore.dylib            	0x000000020513f098 swift_conformsToSwiftProtocolImpl(swift::TargetMetadata<swift::InProcess> const*, swift::TargetProtocolDescriptor<swift::InProcess> const*, llvm::StringRef) + 312 (ProtocolConformance.cpp:478)
10  libswiftCore.dylib            	0x000000020513ee38 swift_conformsToProtocol + 188 (CompatibilityOverride.def:137)
11  libswiftCore.dylib            	0x0000000205118a58 swift::_conformsToProtocol(swift::OpaqueValue const*, swift::TargetMetadata<swift::InProcess> const*, swift::TargetProtocolDescriptorRef<swift::InProcess>, swift::TargetWitnessTable<swift::InProces... + 44 (Casting.cpp:320)
12  libswiftCore.dylib            	0x000000020513e6fc swift::_checkGenericRequirements(llvm::ArrayRef<swift::TargetGenericRequirementDescriptor<swift::InProcess> >, std::__1::vector<void const*, std::__1::allocator<void const*> >&, std::__1::function<... + 1160 (ProtocolConformance.cpp:648)
13  libswiftCore.dylib            	0x000000020513b740 (anonymous namespace)::DecodedMetadataBuilder::createBoundGenericType(swift::TargetContextDescriptor<swift::InProcess> const*, llvm::ArrayRef<swift::TargetMetadata<swift::InProcess> const*>, swift:... + 584 (MetadataLookup.cpp:1083)
14  libswiftCore.dylib            	0x000000020513adec swift::Demangle::TypeDecoder<(anonymous namespace)::DecodedMetadataBuilder>::decodeMangledType(swift::Demangle::Node* const&) + 2832 (TypeDecoder.h:201)
15  libswiftCore.dylib            	0x000000020513a428 swift::Demangle::TypeDecoder<(anonymous namespace)::DecodedMetadataBuilder>::decodeMangledType(swift::Demangle::Node* const&) + 332 (Demangle.h:0)
16  libswiftCore.dylib            	0x0000000205139d10 swift_getTypeByMangledNodeImpl(swift::MetadataRequest, swift::Demangle::Demangler&, swift::Demangle::Node*, std::__1::function<swift::TargetMetadata<swift::InProcess> const* (unsigned int, unsigned... + 460 (TypeDecoder.h:700)
17  libswiftCore.dylib            	0x0000000205139ad0 swift::swift_getTypeByMangledNode(swift::MetadataRequest, swift::Demangle::Demangler&, swift::Demangle::Node*, std::__1::function<swift::TargetMetadata<swift::InProcess> const* (unsigned int, unsig... + 520 (CompatibilityOverride.def:148)
18  libswiftCore.dylib            	0x000000020513a044 swift_getTypeByMangledNameImpl(swift::MetadataRequest, llvm::StringRef, std::__1::function<swift::TargetMetadata<swift::InProcess> const* (unsigned int, unsigned int)>, std::__1::function<swift::Ta... + 652 (MetadataLookup.cpp:1300)
19  libswiftCore.dylib            	0x0000000205138450 swift::swift_getTypeByMangledName(swift::MetadataRequest, llvm::StringRef, std::__1::function<swift::TargetMetadata<swift::InProcess> const* (unsigned int, unsigned int)>, std::__1::function<swift:... + 520 (CompatibilityOverride.def:155)
20  libswiftCore.dylib            	0x000000020513859c swift_getTypeByMangledNameInContext + 216 (MetadataLookup.cpp:1326)
21  UnityFramework                	0x0000000102112694 __swift_instantiateConcreteTypeFromMangledName + 52 (<compiler-generated>:0)
22  UnityFramework                	0x00000001022d14d0 specialized _NativeDictionary.resize(capacity:) + 12 (<compiler-generated>:0)
23  UnityFramework                	0x00000001022d14d0 specialized _NativeDictionary.ensureUnique(isUnique:capacity:) + 24 (<compiler-generated>:0)
24  UnityFramework                	0x00000001022d14d0 specialized _NativeDictionary.mutatingFind(_:isUnique:) + 64 (<compiler-generated>:0)
25  UnityFramework                	0x00000001022d14d0 specialized _NativeDictionary.merge<A>(_:isUnique:uniquingKeysWith:) + 196
26  UnityFramework                	0x00000001022d1368 specialized protocol witness for Sequence.underestimatedCount.getter in conformance LazyMapSequence<A, B> + 32 (<compiler-generated>:0)
27  UnityFramework                	0x00000001022d1368 specialized Dictionary.init<A>(uniqueKeysWithValues:) + 32 (Logger.swift:267)
28  UnityFramework                	0x00000001022d1368 one-time initialization function for order + 108
29  libdispatch.dylib             	0x00000001d73407d4 _dispatch_client_callout + 16 (object.m:511)
30  libdispatch.dylib             	0x00000001d72e3eb8 _dispatch_once_callout + 28 (once.c:52)
31  libswiftCore.dylib            	0x000000020513de40 swift_once + 40 (once.h:111)
32  UnityFramework                	0x00000001022da794 specialized static Logger.log(level:intent:message:fileName:functionName:line:) + 700
33  UnityFramework                	0x00000001022d9888 specialized static Logger.log(level:intent:message:fileName:functionName:line:) + 64
34  UnityFramework                	0x000000010231b630 specialized static Logger.log(level:intent:message:fileName:functionName:line:) + 60 (Logger.swift:127)
35  UnityFramework                	0x000000010231b630 static Logger.debug(_:fileName:functionName:line:) + 60 (Purchases.swift:0)
36  UnityFramework                	0x000000010231b630 specialized Purchases.__allocating_init(apiKey:appUserID:userDefaults:observerMode:platformInfo:responseVerificationLevel:storeKit2Setting:storeKitTimeout:networkTimeout:dangerousSettings:) + 172
37  UnityFramework                	0x000000010231dd0c Purchases.__allocating_init(apiKey:appUserID:userDefaults:observerMode:platformInfo:responseVerificationLevel:storeKit2Setting:storeKitTimeout:networkTimeout:dangerousSettings:) + 52 (<compiler-generated>:1038)
38  UnityFramework                	0x000000010231dd0c implicit closure #1 in static Purchases.configure(withAPIKey:appUserID:observerMode:userDefaults:platformInfo:responseVerificationLevel:storeKit2Setting:storeKitTimeout:networkTimeout:dangerousSett... + 104 (<compiler-generated>:0)
39  UnityFramework                	0x000000010231dd0c partial apply for implicit closure #1 in static Purchases.configure(withAPIKey:appUserID:observerMode:userDefaults:platformInfo:responseVerificationLevel:storeKit2Setting:storeKitTimeout:networkTim... + 172
40  UnityFramework                	0x00000001023191d4 closure #1 in static Purchases.setDefaultInstance(_:) + 4 (Purchases.swift:517)
41  UnityFramework                	0x00000001023191d4 specialized closure #1 in Atomic.modify<A>(_:) + 4 (Atomic.swift:64)
42  UnityFramework                	0x00000001023191d4 specialized closure #1 in Atomic.modify<A>(_:) + 4 (<compiler-generated>:0)
43  UnityFramework                	0x00000001023191d4 specialized Lock.perform<A>(_:) + 4 (Lock.swift:49)
44  UnityFramework                	0x00000001023191d4 specialized Atomic.modify<A>(_:) + 4 (Atomic.swift:63)
45  UnityFramework                	0x00000001023191d4 specialized static Purchases.setDefaultInstance(_:) + 192 (Purchases.swift:504)
46  UnityFramework                	0x000000010231d340 static Purchases.setDefaultInstance(_:) + 16 (<compiler-generated>:0)
47  UnityFramework                	0x000000010231d340 static Purchases.configure(withAPIKey:appUserID:observerMode:userDefaults:platformInfo:responseVerificationLevel:storeKit2Setting:storeKitTimeout:networkTimeout:dangerousSettings:) + 48 (Purchases.swift:909)
48  UnityFramework                	0x000000010231d340 specialized static Purchases.configure(with:) + 224
49  UnityFramework                	0x0000000102248750 static Purchases.configure(apiKey:appUserID:observerMode:userDefaultsSuiteName:platformFlavor:platformFlavorVersion:usesStoreKit2IfAvailable:dangerousSettings:) + 880 (Purchases+HybridAdditions.swift:49)
50  UnityFramework                	0x0000000102248914 @objc static Purchases.configure(apiKey:appUserID:observerMode:userDefaultsSuiteName:platformFlavor:platformFlavorVersion:usesStoreKit2IfAvailable:dangerousSettings:) + 304 (<compiler-generated>:0)
51  UnityFramework                	0x00000001020fae2c -[RCUnityHelperDelegate setupPurchases:appUserID:gameObject:observerMode:usesStoreKit2IfAvailable:userDefaultsSuiteName:dangerousSettingsJson:] + 448 (PurchasesUnityHelper.m:83)
52  UnityFramework                	0x00000001020fc22c _RCSetupPurchases + 208 (PurchasesUnityHelper.m:454)
53  UnityFramework                	0x0000000104bb2c00 PurchasesWrapperiOS__RCSetupPurchases_mD3D94F7356E6ACB5DC9D4144B05271890B674AC9 + 136 (revenuecat.purchases-unity.cpp:12676)
54  UnityFramework                	0x0000000104ba6b14 InterfaceActionInvoker8<String_t*, String_t*, String_t*, bool, bool, String_t*, bool, String_t*>::Invoke(unsigned short, Il2CppClass*, Il2CppObject*, String_t*, String_t*, String_t*, bool, bool, St... + 32 (revenuecat.purchases-unity.cpp:186)
55  UnityFramework                	0x0000000104ba6b14 Purchases_Configure_mB6B15274DFB7B7FFCB1D96E626D7C6DE2A9A3FF0 + 304 (revenuecat.purchases-unity.cpp:4534)
56  UnityFramework                	0x0000000104ba63d8 Purchases_Start_m879CBCF4317AB1B0233FBD048C48D5B99E5C382B + 316 (revenuecat.purchases-unity.cpp:4297)
57  UnityFramework                	0x00000001030975f8 il2cpp::vm::Runtime::InvokeWithThrow(MethodInfo const*, void*, void**) + 100 (Runtime.cpp:567)
58  UnityFramework                	0x0000000103097458 il2cpp::vm::Runtime::Invoke(MethodInfo const*, void*, void**, Il2CppException**) + 84 (Runtime.cpp:553)
59  UnityFramework                	0x00000001025e2094 scripting_method_invoke(ScriptingMethodPtr, ScriptingObjectPtr, ScriptingArguments&, ScriptingExceptionPtr*, bool) + 112 (ScriptingApi_Il2Cpp.cpp:292)
60  UnityFramework                	0x00000001025ede3c ScriptingInvocation::Invoke(ScriptingExceptionPtr*, bool) + 120 (ScriptingInvocation.cpp:298)
61  UnityFramework                	0x00000001025fdf14 MonoBehaviour::InvokeMethodOrCoroutineChecked(ScriptingMethodPtr, ScriptingObjectPtr, ScriptingExceptionPtr*) + 2012 (MonoBehaviour.cpp:0)
62  UnityFramework                	0x00000001025fe098 MonoBehaviour::InvokeMethodOrCoroutineChecked(ScriptingMethodPtr, ScriptingObjectPtr) + 84 (MonoBehaviour.cpp:860)
63  UnityFramework                	0x00000001025fe880 Start + 40 (MonoBehaviour.cpp:465)
64  UnityFramework                	0x00000001025fe880 MonoBehaviour::DelayedStartCall(Object*, void*) + 56 (MonoBehaviour.cpp:1239)
65  UnityFramework                	0x0000000102448f54 DelayedCallManager::Update(int) + 536 (CallDelayed.cpp:185)
66  UnityFramework                	0x000000010250b34c ExecutePlayerLoop(NativePlayerLoopSystem*) + 100 (PlayerLoop.cpp:383)
67  UnityFramework                	0x000000010250b38c ExecutePlayerLoop(NativePlayerLoopSystem*) + 164 (PlayerLoop.cpp:404)
68  UnityFramework                	0x000000010250b5e8 PlayerLoop() + 272 (PlayerLoop.cpp:508)
69  UnityFramework                	0x0000000102af5fc4 UnityPlayerLoopImpl(bool) + 112 (LibEntryPoint.mm:327)
70  UnityFramework                	0x0000000101ebfdb4 UnityRepaint + 12 (UnityAppController+Rendering.mm:236)
71  UnityFramework                	0x0000000101ebfdb4 -[UnityAppController(Rendering) repaint] + 84 (UnityAppController+Rendering.mm:90)
72  UnityFramework                	0x0000000101ebfd44 -[UnityAppController(Rendering) repaintDisplayLink] + 76 (UnityAppController+Rendering.mm:71)
73  QuartzCore                    	0x00000001dbd13ff0 CA::Display::DisplayLink::dispatch_items(unsigned long long, unsigned long long, unsigned long long) + 636 (CADisplay.mm:2349)
74  IOKit                         	0x00000001d7b5f4b0 IODispatchCalloutFromCFMessage + 488 (IOKitLib.c:1216)
75  CoreFoundation                	0x00000001d786d990 __CFMachPortPerform + 188 (CFMachPort.c:522)
76  CoreFoundation                	0x00000001d7894594 __CFRUNLOOP_IS_CALLING_OUT_TO_A_SOURCE1_PERFORM_FUNCTION__ + 56 (CFRunLoop.c:1996)
77  CoreFoundation                	0x00000001d7893ce0 __CFRunLoopDoSource1 + 440 (CFRunLoop.c:2133)
78  CoreFoundation                	0x00000001d788eb04 __CFRunLoopRun + 2096 (CFRunLoop.c:3152)
79  CoreFoundation                	0x00000001d788dfb4 CFRunLoopRunSpecific + 436 (CFRunLoop.c:3247)
80  GraphicsServices              	0x00000001d9a9079c GSEventRunModal + 104 (GSEvent.c:2245)
81  UIKitCore                     	0x0000000203d56c38 UIApplicationMain + 212 (UIApplication.m:4353)
82  UnityFramework                	0x0000000101ebf8ec -[UnityFramework runUIApplicationMainWithArgc:argv:] + 92 (main.mm:96)
83  JoonPetGame                   	0x00000001000bb978 main + 744 (main.mm:34)
84  libdyld.dylib                 	0x00000001d73518e0 start + 4

Here's a Sentry error of what's happening:
Screenshot 2023-04-28 at 11 59 55 AM

Do not remove any of the steps from the template below. If a step is not applicable to your issue, please leave that step empty.

  1. Environment
    1. Platform: Unity iOS
    2. SDK version: v4.14.1
    3. OS + version: iOS v12.5.7
    4. Xcode/Android Studio version: Xcode 13 and Xcode 14 (tried both)
    5. Unity version: 2021.3.16f1
    6. How widespread is the issue. Percentage of devices affected. Just affecting users with old iOS devices. About 5
  2. Debug logs that reproduce the issue
  3. Steps to reproduce, with a description of expected vs. actual behavior
  4. Other information (e.g. stacktraces, related issues, suggestions how to fix, links for us to have context, eg. stackoverflow, etc.)

Additional context
Here is our UpdatedCustomerInfoListener class:

using System.Collections.Generic;
using UnityEngine;

// TODO: Since the parent class is not utilized in anyway. I figured it would be safe to just make this a standard
// TODO: Singleton. If there are any issues, I can happily revert it.
public class SubscriptionManager : Purchases.UpdatedCustomerInfoListener
{
    public static SubscriptionManager Instance;
    
    public delegate void SubscriptionStatusCallback(bool isSubscribed, bool isInTrialMode);

    private Purchases Purchases => transform.parent.GetComponentInChildren<Purchases>();

    public void UserLoggedIn(Parent parent)
    {
        // TODO: Created and error are never used. Should we make a use case for them or remove them?
        Purchases.LogIn(appUserId: $"{parent.FamilyId}", callback: (info, _, _) =>
        {
            Purchases.SetEmail(email: parent.Email);
            Purchases.SetAttributes(attributes: new Dictionary<string, string>
            {
                { JoonConsts.PARENT_ID, $"{parent.Id}" },
                { JoonConsts.NAME, parent.Name },
                { JoonConsts.EMAIL, parent.Email }
            });
        });
    }

    public void UserLoggedOut()
    {
        Purchases.LogOut(callback: null);
    }

    public void SubscriptionStatus(SubscriptionStatusCallback callback)
    {
        // Purchases will only return a callback if it actually is on Android or iOS. This check allows us to
        // callback the caller of this function when running on Unity.
        if (Application.platform is RuntimePlatform.Android or RuntimePlatform.IPhonePlayer)
        {
            Purchases.GetCustomerInfo(callback: (info, error) =>
            {
                if (error != null)
                {
                    callback(isSubscribed: false, isInTrialMode: false);
                    return;
                }

                bool isUserSubscribed = info.Entitlements.Active.Count > 0;
                Parent parent = AuthenticationManager.GetParent();
                bool isInTrialMode = parent.NumQuestsVerified < parent.MaxFreeVerified;
                callback(isUserSubscribed, isInTrialMode);
            });
        }
        else
        {
            // Default callback if it isn't iOS or Android.
            callback(true, true);
        }
    }

    // Old Singleton set up for now since this uses an inherited class.
    private void Awake()
    {
        if (Instance != null && Instance != this)
        {
            Destroy(transform.root.gameObject);
        }
        else
        {
            Instance = this;
            DontDestroyOnLoad(transform.root.gameObject);
        }
    }

    // No-op
    public override void CustomerInfoReceived(Purchases.CustomerInfo customerInfo) { }
}
@kbunarjo kbunarjo added the bug Something isn't working label Apr 28, 2023
@RCGitBot
Copy link
Contributor

RCGitBot commented Apr 28, 2023

👀 SDKONCALL-267 We've just linked this issue to our internal tracker and notified the team. Thank you for reporting, we're checking this out!

@kbunarjo
Copy link
Author

fwiw, we do not include any products in our unity app. we have another ios app that handles purchases. our unity game just uses RevenueCat to check the subscription status of the users

@NachoSoto
Copy link
Contributor

Thanks for the report!
Just to clarify, when you say version 4.14.1, do you mean 4.13.1.

That's really weird, it's crashing here:

private static let orderedLevels: [LogLevel] = [
    .verbose,
    .debug,
    .info,
    .warn,
    .error
]
static let order: [LogLevel: Int] = Dictionary(uniqueKeysWithValues:
                                                Self.orderedLevels
    .enumerated()
    .lazy
    .map { ($1, $0) }
)

Creating that order property, which for some weird reason is making Swift load the metadata for SK2StoreProduct .

Which version of Xcode 14 are you using? Can you reproduce this with 14.3?
Are you able to reproduce this locally with an iOS 12 simulator?

Thanks!

@kbunarjo
Copy link
Author

kbunarjo commented Apr 28, 2023

Ahh sorry I guess it is 4.14.1 of PurchasesHybridCommon (the generated line in our podfile is pod 'PurchasesHybridCommon', '4.14.1'). how can i check the purchases version?

We've actually been unable to reproduce the crash with our test devices since we don't have an old iOS device (seems to be happening on SE, 6 and similar devices for users. However, we've been seeing this crash happen for users when we built with Xcode 14.3 and Xcode 13.4 (I recently updated my Xcode yesterday and uploaded a new build). And yes, it looks like a similar crash happens when you run the generated xcode workspace with a simulator. But for the simulator, it doesn't matter what ios version the simulator is using (happens on ios 12 and 14 simulators).

@kbunarjo
Copy link
Author

kbunarjo commented May 1, 2023

i can confirm moving back to v2.0.1 fixes the issue @NachoSoto

@kbunarjo
Copy link
Author

kbunarjo commented May 8, 2023

@NachoSoto any updates here?

@NachoSoto
Copy link
Contributor

And yes, it looks like a similar crash happens when you run the generated xcode workspace with a simulator. But for the simulator, it doesn't matter what ios version the simulator is using (happens on ios 12 and 14 simulators).

Do you have a screenshot of Xcode when that crash happens?

@kbunarjo
Copy link
Author

@NachoSoto currently having trouble building our app for the simulator (i think related to another package we have), but here's the crash logs. is this helpful?
BcibpleE9C-tRgiuIMgpLN.xccrashpoint.zip

@NachoSoto
Copy link
Contributor

This is the crash:

Termination Description: DYLD, Symbol not found: _$s8StoreKit7ProductVMa | Referenced from: /var/containers/Bundle/Application/BE952961-667F-41B4-A3C0-36F264A7D054/JoonPetGame.app/Frameworks/UnityFramework.framework/UnityFramework | Expected in: dyld shared cache

For some reason your project isn't embedding RevenueCat.framework in the bundle, or perhaps LD_RUNPATH_SEARCH_PATHS is wrong. Could you send a screenshot for that value in your target?

Screenshot 2023-05-26 at 10 47 29

Something about this is likely making it only fail on iOS 12 (which unfortunately I can't even test anymore from a Mac M1...)

@kbunarjo
Copy link
Author

Here's a screenshot of what ours looks like. The value that's set is @executable_path/Frameworks as well
Screenshot 2023-05-26 at 2 02 14 PM

@NachoSoto
Copy link
Contributor

Could you double-click to show us the whole value? 🙏🏻

@vegaro
Copy link
Contributor

vegaro commented May 26, 2023

We use EDM4U, which generates that Podfile in your project, and we have seen this issue reported in their repository googlesamples/unity-jar-resolver#575 (comment). They suggest changing the Enable Swift Framework Support Workaround. setting in that issue. Do you think you can give that a try? Also, what version of the EDM4U you have currently installed?

Thanks!

NachoSoto added a commit to RevenueCat/purchases-ios that referenced this issue May 30, 2023
Even though https://bugs.swift.org/browse/SR-15825 is supposedly fix on Xcode 14.x, and we validated that on CI, that's still crashing for some reason on iOS 12 devices.
Fixes RevenueCat/purchases-unity#278, [SDKONCALL-267], SDK-3154.
@NachoSoto
Copy link
Contributor

We've identified the issue. We'll have a release with the fix out soon. Thanks again for reporting this!

@NachoSoto
Copy link
Contributor

The fix is now released! Thank you for your patience.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
bug Something isn't working triaged
Projects
None yet
Development

Successfully merging a pull request may close this issue.

4 participants