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

[tests] Find a workaround for #xamarin/maccore@2668. #18159

Merged
merged 1 commit into from
Apr 27, 2023

Commits on Apr 27, 2023

  1. [tests] Find a workaround for #xamarin/maccore@2668.

    1. Mono changed dyld lookup to start looking in directories in
       NATIVE_DLL_SEARCH_DIRECTORIES before the actual given path, even when the
       given path is absolute [1].
    2. This turned out to break Mac Catalyst, because when a DllImport says a
       P/Invoke is in "/System/Library/Frameworks/SceneKit.framework/SceneKit",
       Mono would try loading by prefixing the directories in
       NATIVE_DLL_SEARCH_DIRECTORIES. We add the Contents/MonoBundle directory to
       NATIVE_DLL_SEARCH_DIRECTORIES, so Mono would try to load
       "/path/to/my.app/Contents/MonoBundle//System/Library/Frameworks/SceneKit.framework/SceneKit",
       and things would go wrong.
    3. We found a workaround: add "/" to NATIVE_DLL_SEARCH_DIRECTORIES. This works
       on Ventura, but apparently not on older macOS version, because the actual
       path we pass to dlopen ends up being "///System/Library/Frameworks/SceneKit.framework/SceneKit"
       (note the three initial slashes instead of a single slash).
    4. Add a second workaround, where we add a dll import resolver to load exactly
       the path we want to load.
    
    [1]: dotnet/runtime@5a1baeb
    [2]: dotnet/runtime#85255
    
    Technical sidenote:
    
    Why trying to load "/path/to/my.app/Contents/MonoBundle//System/Library/Frameworks/SceneKit.framework/SceneKit"
    turned out so bad on Mac Catalyst is not obvious. What happens is this:
    
    * The app calls 'dlopen ("/path/to/my.app/Contents/MonoBundle//System/Library/Frameworks/SceneKit.framework/SceneKit")'
    * dlopen checks if this is a Mac Catalyst override of a macOS system
      framework, by prefixing "/System/iOSSupport" and trying to load that. So
      dlopen would try to load "/System/iOSSupport/path/to/my.app/Contents/MonoBundle//System/Library/Frameworks/SceneKit.framework/SceneKit",
      which would obviously fail.
    * Then dlopen would try a few more fallbacks, eventually trying
      "/System/Library/Frameworks/SceneKit.framework/SceneKit", and successfully
      loading that library.
    * Unfortunately "/System/Library/Frameworks/SceneKit.framework/SceneKit" is
      the wrong library to load for Mac Catalyst ("/System/iOSSupport/System/Library/Frameworks/SceneKit.framework/SceneKit"
      is the correct version). These two libraries are incompatible, and calling
      one when you mean to call the other will do nasty things like corrupting the
      stack.
    rolfbjarne committed Apr 27, 2023
    Configuration menu
    Copy the full SHA
    470b2ad View commit details
    Browse the repository at this point in the history