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

Conversation

rolfbjarne
Copy link
Member

  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.

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.

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.
@vs-mobiletools-engineering-service2
Copy link
Collaborator

💻 [CI Build] Windows Integration Tests passed 💻

All Windows Integration Tests passed.

Pipeline on Agent
Hash: 470b2adb4589f440154a0a2eaffd332fddf0aa6e [PR build]

@vs-mobiletools-engineering-service2
Copy link
Collaborator

📚 [PR Build] Artifacts 📚

Packages generated

View packages

Pipeline on Agent XAMMINI-011.Ventura
Hash: 470b2adb4589f440154a0a2eaffd332fddf0aa6e [PR build]

@vs-mobiletools-engineering-service2
Copy link
Collaborator

✅ API diff for current PR / commit

Legacy Xamarin (No breaking changes)
  • iOS (no change detected)
  • tvOS (no change detected)
  • watchOS (no change detected)
  • macOS (no change detected)
NET (empty diffs)
  • iOS: (empty diff detected)
  • tvOS: (empty diff detected)
  • MacCatalyst: (empty diff detected)
  • macOS: (empty diff detected)

✅ API diff vs stable

Legacy Xamarin (No breaking changes)
.NET (No breaking changes)
Legacy Xamarin (stable) vs .NET

✅ Generator diff

Generator diff is empty

Pipeline on Agent
Hash: 470b2adb4589f440154a0a2eaffd332fddf0aa6e [PR build]

@vs-mobiletools-engineering-service2
Copy link
Collaborator

💻 [PR Build] Tests on macOS M1 - Mac Big Sur (11.5) passed 💻

All tests on macOS M1 - Mac Big Sur (11.5) passed.

Pipeline on Agent
Hash: [PR build]

@vs-mobiletools-engineering-service2
Copy link
Collaborator

❌ [PR Build] Tests on macOS M1 - Mac Ventura (13.0) failed ❌

Failed tests are:

  • monotouch-test

Pipeline on Agent
Hash: [PR build]

@vs-mobiletools-engineering-service2
Copy link
Collaborator

🚀 [CI Build] Test results 🚀

Test results

✅ All tests passed on VSTS: simulator tests.

🎉 All 225 tests passed 🎉

Tests counts

✅ bcl: All 69 tests passed. Html Report (VSDrops) Download
✅ cecil: All 1 tests passed. Html Report (VSDrops) Download
✅ dotnettests: All 1 tests passed. Html Report (VSDrops) Download
✅ fsharp: All 7 tests passed. Html Report (VSDrops) Download
✅ framework: All 8 tests passed. Html Report (VSDrops) Download
✅ generator: All 2 tests passed. Html Report (VSDrops) Download
✅ interdependent_binding_projects: All 7 tests passed. Html Report (VSDrops) Download
✅ install_source: All 1 tests passed. Html Report (VSDrops) Download
✅ introspection: All 8 tests passed. Html Report (VSDrops) Download
✅ linker: All 65 tests passed. Html Report (VSDrops) Download
✅ mac_binding_project: All 1 tests passed. Html Report (VSDrops) Download
✅ mmp: All 2 tests passed. Html Report (VSDrops) Download
✅ mononative: All 12 tests passed. Html Report (VSDrops) Download
✅ monotouch: All 25 tests passed. Html Report (VSDrops) Download
✅ msbuild: All 2 tests passed. Html Report (VSDrops) Download
✅ mtouch: All 1 tests passed. Html Report (VSDrops) Download
✅ xammac: All 3 tests passed. Html Report (VSDrops) Download
✅ xcframework: All 8 tests passed. Html Report (VSDrops) Download
✅ xtro: All 2 tests passed. Html Report (VSDrops) Download

Pipeline on Agent
Hash: 470b2adb4589f440154a0a2eaffd332fddf0aa6e [PR build]

@rolfbjarne
Copy link
Member Author

Test failure is unrelated (#18157).

#if __MACCATALYST__
// This is a workaround for a temporary issue in the .NET runtime
// See https://github.com/xamarin/maccore/issues/2668
// The issue is present in .NET 7.0.5, and will likely be fixed in .NET 7.0.6.
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

If this is likely to be fixed in 7.0.6, do we have an issue open on it to check in the future to remove this?

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Filed: #18164

@rolfbjarne rolfbjarne merged commit bc272a9 into xamarin:main Apr 27, 2023
@rolfbjarne rolfbjarne deleted the maccore-issue-2668-take-two branch April 27, 2023 16:17
rolfbjarne added a commit to rolfbjarne/xamarin-macios that referenced this pull request Apr 27, 2023
…ccore@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.

Backport of xamarin#18159.
@rolfbjarne
Copy link
Member Author

/sudo backport release/7.0.2xx-xcode14.2

@rolfbjarne
Copy link
Member Author

/sudo backport release/7.0.2xx-xcode14.3

@rolfbjarne
Copy link
Member Author

/sudo backport release/7.0.3xx

@vs-mobiletools-engineering-service2
Copy link
Collaborator

Backport Job to branch release/7.0.2xx-xcode14.2 Created! The magic is happening here

@vs-mobiletools-engineering-service2
Copy link
Collaborator

Backport Job to branch release/7.0.2xx-xcode14.3 Created! The magic is happening here

@vs-mobiletools-engineering-service2
Copy link
Collaborator

Backport Job to branch release/7.0.3xx Created! The magic is happening here

@vs-mobiletools-engineering-service2
Copy link
Collaborator

Hooray! Backport succeeded! Please see https://devdiv.visualstudio.com/DevDiv/_build/results?buildId=7694185 for more details.

@vs-mobiletools-engineering-service2
Copy link
Collaborator

Hooray! Backport succeeded! Please see https://devdiv.visualstudio.com/DevDiv/_build/results?buildId=7694184 for more details.

rolfbjarne added a commit to rolfbjarne/xamarin-macios that referenced this pull request Apr 27, 2023
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.

This is a backport of #xamarin#18159.
rolfbjarne added a commit to rolfbjarne/xamarin-macios that referenced this pull request Apr 27, 2023
…ccore@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.

This is a backport of xamarin#18159.
@rolfbjarne
Copy link
Member Author

/sudo backport release/7.0.2xx

@vs-mobiletools-engineering-service2
Copy link
Collaborator

Backport Job to branch backport release/7.0.2xx Created! The magic is happening here

@rolfbjarne
Copy link
Member Author

/sudo backport release/7.0.2xx

@vs-mobiletools-engineering-service2
Copy link
Collaborator

Backport Job to branch release/7.0.2xx Created! The magic is happening here

@vs-mobiletools-engineering-service2
Copy link
Collaborator

Oh no! Backport failed! Please see https://devdiv.visualstudio.com/DevDiv/_build/results?buildId=7694309 for more details.

@rolfbjarne
Copy link
Member Author

/sudo backport release/7.0.2xx

@vs-mobiletools-engineering-service2
Copy link
Collaborator

Backport Job to branch release/7.0.2xx Created! The magic is happening here

@vs-mobiletools-engineering-service2
Copy link
Collaborator

Oh no! Backport failed! Please see https://devdiv.visualstudio.com/DevDiv/_build/results?buildId=7698418 for more details.

rolfbjarne pushed a commit that referenced this pull request Apr 28, 2023
…ccore@2668. (#18167)

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.


Backport of #18159
rolfbjarne added a commit that referenced this pull request Apr 28, 2023
…ccore@2668. (#18172)

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.


Backport of #18159
rolfbjarne added a commit that referenced this pull request Apr 28, 2023
…ccore@2668. (#18171)

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.

This is a backport of #18159.
rolfbjarne pushed a commit that referenced this pull request Apr 28, 2023
#18166)

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.

This is a backport of #18159.
rolfbjarne added a commit to rolfbjarne/xamarin-macios that referenced this pull request Apr 28, 2023
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.

This is a backport of xamarin#18159.
@rolfbjarne
Copy link
Member Author

/sudo backport release/8.0.1xx-preview4

@vs-mobiletools-engineering-service2
Copy link
Collaborator

Backport Job to branch release/8.0.1xx-preview4 Created! The magic is happening here

@vs-mobiletools-engineering-service2
Copy link
Collaborator

Hooray! Backport succeeded! Please see https://devdiv.visualstudio.com/DevDiv/_build/results?buildId=7698556 for more details.

rolfbjarne pushed a commit that referenced this pull request May 3, 2023
…core@2668. (#18181)

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.


Backport of #18159
rolfbjarne added a commit that referenced this pull request May 3, 2023
#18178)

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.

This is a backport of #18159.
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

4 participants