bugsnag / bugsnag-cocoa

BugSnag error monitoring & exception reporter for iOS, macOS, tvOS and watchOS
https://docs.bugsnag.com/platforms/ios
MIT License
237 stars 129 forks source link

Mac Catalyst symbol not found os_proc_available_memory crash #1676

Closed braess closed 3 months ago

braess commented 4 months ago

Describe the bug

Mac Catalyst apps running on older macOS versions (10.15) are terminated on launch with a symbol not found exception: Symbol not found: _os_proc_available_memory

Function os_proc_available_memory is available on iOS 13.0+ and Mac Catalyst 13.1+: Apple Documentation

It looks like BSGRunContext.m UpdateTaskMemory might be incorrectly checking api availability: BSGRunContext.m

This issue could be related or a regression of a similar problem: Fix os_proc_available_memory runtime link error on Mac Catalyst

This crash was reported by users, unfortunately I can't reproduce it myself as I don't have macOS 10.15 anymore for testing. Below the limited information I received.

I'm not quite sure that this really is the problem, but BugSnag appears to be the only sdk using os_proc_available_memory. It would mean that Mac Catalyst apps supporting older macOS versions can't use bugsnag-cocoa at the moment.

Thanks for looking into this issue.

Steps to reproduce

  1. Integrate BugSnag as Swift package
  2. Launch macCatalyst app on macOS 10.15.7
  3. App is terminated on launch with exception

Environment

Crash report

- Exception
Exception Type: EXC_CRASH (SIGABRT)
Termination Reason: DYLD, [0x4] Symbol missing
Symbol not found: _os_proc_available_memory
Expected in: /usr/lib/libSystem.B.dylib

- Stacktrace
Thread 0 Crashed:: Dispatch queue: com.apple.main-thread
0   dyld                            0x00000001177ce05e __abort_with_payload + 10
1   dyld                            0x00000001177f76ed abort_with_payload_wrapper_internal + 80
2   dyld                            0x00000001177f771f abort_with_payload + 9
3   dyld                            0x00000001177f4d74 dyld::halt(char const*) + 463
4   dyld                            0x000000011777cbc3 dyld::fastBindLazySymbol(ImageLoader**, unsigned long) + 140
5   libdyld.dylib                   0x00007fff7395d692 dyld_stub_binder + 282
...
15  com.apple.UIKitCore             0x00007fff7a3cfcad -[UIApplication _handleDelegateCallbacksWithOptions:isSuspended:restoreState:] + 312
16  com.apple.UIKitCore             0x00007fff7a3cf527 -[UIApplication _callInitializationDelegatesWithActions:forCanvas:payload:fromOriginatingProcess:] + 5775
17  com.apple.UIKitCore             0x00007fff7a3cc91f -[UIApplication _runWithMainScene:transitionContext:completion:] + 1319
18  com.apple.UIKitCore             0x00007fff7a3cc328 -[_UISceneLifecycleMultiplexer completeApplicationLaunchWithFBSScene:transitionContext:] + 179
19  com.apple.UIKitCore             0x00007fff7af3a4d7 -[UIApplication _compellApplicationLaunchToCompleteUnconditionally] + 59
20  com.apple.UIKitCore             0x00007fff7a3a5a8b -[UIApplication _run] + 747
21  com.apple.UIKitCore             0x00007fff7a39a1ef UIApplicationMain + 2114
...
23  libdyld.dylib                   0x00007fff7395ecc9 start + 1
mclack commented 4 months ago

Hi @braess

Thanks for raising this with us. We've added a task to our backlog to investigate this further, as this is something we should be able to test for.

While I don't currently have an ETA I can share on exactly when this will be addressed, we'll make sure to post any updates here.

braess commented 4 months ago

Hi Milo, thanks for your quick reply. Let me know if you need any further information.

hannah-smartbear commented 3 months ago

Hi @braess

A fix for this has now been released in v6.30.1 of bugsnag-cocoa. Mac Catalyst targets now only attempt to call os_proc_available_memory() for version 13.1 or above of Mac Catalyst. Please let us know if you have any questions about this!

braess commented 3 months ago

Thanks for the update! This should solve the problem.

braess commented 3 months ago

Hi @hannah-smartbear,

release v6.30.1 does not seem to resolve this issue. Mac Catalyst apps running on macOS 10.15 are still terminated on launch with the same symbol not found exception.

Only extending @available as in the current fix is probably not enough. To check for api availability in this case, the TARGET_OS_MACCATALYST macro would need to be used as well.

hannah-smartbear commented 3 months ago

Hi @braess

Thanks for letting us know. We’ve added another task to look into this further and consider the approach of using TARGET_OS_MACCATALYST to check for API availability. We will be sure to let you know of any updates on this.

hannah-smartbear commented 1 week ago

Hi @braess,

We just wanted to let you know that v6.30.2 of bugsnag-cocoa has been released, which also checks TARGET_OS_MACCATALYST to fix the os_proc_available_memory crash. Please let us know if you have any further questions!

braess commented 3 days ago

Hi @hannah-smartbear, thanks for the update. I have since stopped supporting older macOS versions for my apps and can't confirm the fix.

But it looks like os_proc_available_memory() has now been completely removed for all Mac Catalyst versions. Is this an intentional change?

To check availability for iOS 13.0+ and Mac Catalyst 13.1+, something like the following could be used:

#if !TARGET_OS_OSX
    #if !TARGET_OS_MACCATALYST
    if (@available(iOS 13.0, tvOS 13.0, watchOS 6.0, *)) {
        setMemoryUsage(footprint, os_proc_available_memory());
    }
    #else
    if (@available(macCatalyst 13.1, *)) {
        setMemoryUsage(footprint, os_proc_available_memory());
    }
    #endif
#endif

For me this issue is resolved, I will leave this up to you.

clr182 commented 1 day ago

Hi @braess

But it looks like os_proc_available_memory() has now been completely removed for all Mac Catalyst versions. Is this an intentional change? Thank you for bringing this up. Our engineering team looked into the issue and confirmed that the function os_proc_available_memory() is indeed unavailable in Mac Catalyst versions, which is likely causing the crash on launch.

To explain a bit further, @available is a runtime check for API availability, while TARGET_OS_MACCATALYST is a compile-time check. It seems that the Catalyst app may be passing the compile-time check but still crashes at runtime because os_proc_available_memory() isn’t available in the Catalyst environment. This discrepancy between compile-time and runtime is what leads to the crash, as the app is attempting to link to a function that doesn't exist in Catalyst.

What we have done to address this is to wrapping the code with #if TARGET_OS_MACCATALYST, which would prevent the app from trying to compile or link to os_proc_available_memory() at all when targeting Mac Catalyst. However, it’s worth noting that this workaround has removed os_proc_available_memory() for all Catalyst versions, including potential future versions that might introduce support for the function.

braess commented 1 day ago

Hi @clr182, ah you are right: it's a linker error of a system library. In this case, removing it completely for Catalyst builds is probably the only solution. Thanks for the additional details and the fix!