nicklockwood/Euclid

Crash on apps built with Xcode 15 on iOS 16 in release mode

enchantingmoon opened this issue · 18 comments

When running on iOS 16 in release mode, an app (built with Xcode 15) crashes with the following message:
Symbol not found: _$s10Foundation13__DataStorageC12replaceBytes2in4with6lengthySnySiG_SVSgSitF
The same app works fine when:

  • Run on iOS 16 in debug mode
  • Run on iOS 17
  • Built with Xcode 14

Steps to reproduce:

  1. Create a new project in Xcode 15
  2. Add Euclid as a dependency via SPM
  3. Change scheme to release mode
  4. Build and run on a device running iOS 16 (tested specifically on iOS 16.6.1)

Yeah, I noticed this myself recently. I thought it was related to Catalyst though - I didn't realize it was affecting iOS as well.

Do you have any ideas for what may be causing this? I have been experimenting with the source today and tried removing the two uses of deprecated APIs (NSKeyedArchiver calls), but it unfortunately didn't help.

To eliminate any issues with SPM, I also created a blank project and copied all the Swift source files directly into the target, which also creates the same behavior.

Thanks!

I think it might be a bug in Xcode 15.

Have you tried changing the supported platforms/SDK of Euclid to iOS-only instead of multiplatform? It might also help to make it a static library instead of dynamic?

Thanks for the link! I also feel like it's an Xcode bug.

I tried the linker flags to use the classic linker, but unfortunately it didn't help. To avoid working with frameworks altogether, I copied all the source files of Euclid into an iOS target, as shown below.
Screenshot 2023-09-21 at 4 55 05 PM

This seems to be an SDK issue (I've filed FB13195864):

The missing symbol is a variant of the internal __DataStorage.replaceBytes method that takes a Range<Int>, which, despite being added in iOS 17, is incorrectly marked as being available back to iOS 8. The method is usable from inline, and a reference to it gets inlined into the app (via a couple layers of inlined framework code). And so the app crashes when running pre-iOS 17 since method does not actually exist.

@shadowfacts thanks! Is there any sort of workaround? Do you know which code specifically is calling it?

SCNGeometry(polygons:materialLookup:) is where the reference to the new method is being inlined. Specifically, one or both of the Data.append calls on indexData here.

The best workaround I can come up with is using @_optimize(none) to prevent append from being inlined, like adding an extension method and calling that instead:

extension Data {
    @_optimize(none)
    mutating func unoptimizedAppend(_ x: UInt32) { append(x) }
}

Thank you so much! This seems to fix it. Here is the full list of extension methods I created based on your response that resolves the issue.

extension Data {
    @_optimize(none)
    mutating func unoptimizedAppend(_ x: UInt32) {
        append(x)
    }
    
    @_optimize(none)
    mutating func unoptimizedAppend(_ x: UInt16) {
        append(x)
    }
    
    @_optimize(none)
    mutating func unoptimizedAppend(_ x: Float) {
        append(x)
    }
    
    @_optimize(none)
    mutating func unoptimizedAppend<SourceType>(_ buffer: UnsafeBufferPointer<SourceType>) {
        append(buffer)
    }
}

@shadowfacts thanks so much! That's a huge help.

@enchantingmoon fixed in 0.6.18

That's great to hear! Thank you again @nicklockwood and @shadowfacts.

@nicklockwood I am also facing this issue Could you pl. guide me where exactly I need to use / add the unoptimised lines of Data Extension

@PrashantKT for Euclid? You don't need to do anything - these are internal methods, not part of the public API.

@nicklockwood Thanks Okay Actually my app also crashes , when I run in release mode from Xcode 15 ,

dyld[26653]: Symbol not found: _$s10Foundation13__DataStorageC12replaceBytes2in4with6lengthySnySiG_SVSgSitF
Referenced from: /Users/prashanttukadiya/Library/Developer/Xcode/DerivedData/Smilefy-eytvisqqcorbenadufuvkqpohiiy/Build/Products/Release-maccatalyst/Smilefy_TNG.app/Contents/MacOS/Smilefy_TNG
Expected in: /System/Library/Frameworks/Foundation.framework/Versions/C/Foundation

Do you have any idea what should I do to fix ?
I am not able to find solution

@nicklockwood any update on this or any recommendations what should I do to fix this crash ?

Thanks

@PrashantKT this crash seems to be in an unrelated library (or possibly your own app's code?). If it's using Data.append() internally then you can try the same fix that @enchantingmoon found for Euclid, but I'm not able to offer help with that.

Okay Thanks @nicklockwood , App is big is there any way to find out that this method is called or not , app has some dependencies also , any tips or suggestion will help