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

[macOS] NativeAOT unable to produce executables when using the Xcode 15 toolchain #92491

Closed
lambdageek opened this issue Sep 22, 2023 · 10 comments

Comments

@lambdageek
Copy link
Member

lambdageek commented Sep 22, 2023

When the new linker from Xcode 15 is used on object files produced by NativeAOT, the Xcode linker produces artifacts that crash during the first stack walk.

As a workaround it is possible to install Xcode 14.3.1 in parallel and set it as the default toolchain using xcode-select.

This affects arm64 and x64 Macs when using the -p:PublishAot=true option with .NET 8

It also affects the experimental ios NativeAOT support.

There is already a PR to fix the the underlying issue here:

I'm opening this issue mostly for tracking purposes

@ghost ghost added the untriaged New issue has not been triaged by the area owner label Sep 22, 2023
@ghost
Copy link

ghost commented Sep 22, 2023

Tagging subscribers to this area: @agocke, @MichalStrehovsky, @jkotas
See info in area-owners.md if you want to be subscribed.

Issue Details

When the new linker from Xcode 15 is used on object files produced by NativeAOT, the Xcode linker crashes.

As a workaround it is possible to install Xcode 14.3.1 in parallel and set it as the default toolchain using xcode-select.

This affects arm64 and x64 Macs when using the -p:PublishAot=true option with .NET 8

It also affects the experimental ios NativeAOT support.

There is already a PR to fix the the underlying issue here: dotnet/llvm-project#471
So I'm opening this PR mostly for tracking purposes

Author: lambdageek
Assignees: -
Labels:

area-NativeAOT-coreclr

Milestone: -

@lambdageek lambdageek added this to the 8.0.0 milestone Sep 22, 2023
@ghost ghost removed the untriaged New issue has not been triaged by the area owner label Sep 22, 2023
@lambdageek lambdageek added blocking-release untriaged New issue has not been triaged by the area owner labels Sep 22, 2023
@lambdageek
Copy link
Member Author

@lambdageek
Copy link
Member Author

Do we need to fix net7, too?

@filipnavara
Copy link
Member

filipnavara commented Sep 22, 2023 via email

@filipnavara
Copy link
Member

Another Xcode 15 breakage was reported in #92297. Preliminary analysis suggests that we hit the same bug with non-MH_SUBSECTIONS_VIA_SYMBOLS object files getting the unwind tables corrupted. In this case, however, it's for the assembly code in both CoreCLR and NativeAOT runtime. For NativeAOT we are much less likely to observe this as a problem but it's easily observable on CoreCLR.

A possible fix is to update the assembly code to use MH_SUBSECTIONS_VIA_SYMBOLS and thus avoid hitting the linker bug. I have done an experiment with that (filipnavara@aba0b02) and now I am waiting for a feedback.

Crucially, I didn't audit Mono code or other components that may run into the same issue.

@lambdageek
Copy link
Member Author

Crucially, I didn't audit Mono code or other components that may run into the same issue.

What would we need to audit:

  • handwritten asm files comprising libmonosgen or other platform libraries;
  • the aot object files that are linked using the platform toolchain linker when targeting apple platforms
    anything else?

And I suppose @dalexsoto the macios team should likewise look at their code?

@steveisok do we have any xcode15 testing lanes?

@filipnavara
Copy link
Member

handwritten asm files comprising libmonosgen or other platform libraries;

If you emit DWARF or compact unwinding there, yes. I am not sure if, and to what extent, MonoVM does that.

anything else?

The assembly files and AOT output are the only two things that come to mind. C/C++/ObjC always produces object files with the subsections-via-symbols flag.

And I suppose @dalexsoto the macios team should likewise look at their code?

They should...but in their case it's slightly less urgent. On the Xcode 15 branch they currently detect the Xcode version and force the old linker to be used by -ld_classic linker flag. There's an open issue to evaluate whether it is still needed (it is), and to remove it.

Forcing the old linker is an option, but it's logistically challenging since you need to also detect Xcode tools version. Apple already stated that they will eventually remove the old linker, so this strategy only buys some time.

@steveisok
Copy link
Member

@steveisok do we have any xcode15 testing lanes?

We have a scouting queue with an older beta on it. We could probably update it quickly ourselves if need be.

@lambdageek
Copy link
Member Author

lambdageek commented Sep 25, 2023

handwritten asm files comprising libmonosgen or other platform libraries;

If you emit DWARF or compact unwinding there, yes. I am not sure if, and to what extent, MonoVM does that.

anything else?

The assembly files and AOT output are the only two things that come to mind. C/C++/ObjC always produces object files with the subsections-via-symbols flag.

And I suppose @dalexsoto the macios team should likewise look at their code?

They should...but in their case it's slightly less urgent. On the Xcode 15 branch they currently detect the Xcode version and force the old linker to be used by -ld_classic linker flag. There's an open issue to evaluate whether it is still needed (it is), and to remove it.

Forcing the old linker is an option, but it's logistically challenging since you need to also detect Xcode tools version. Apple already stated that they will eventually remove the old linker, so this strategy only buys some time.

Seems like Mono is ok:

  1. We've been using .subsections_via_symbols since mono/mono@c60098a
  2. I tried net8.0 RC1 with Xcode 15 and the following:
    $ mkdir -p /tmp/hw && cd /tmp/hw
    $ dotnet new console
    # add SelfContained and UseMonoRuntime options to the .csproj
    $ cd bin/Release/net8.0/osx-arm64/publish
    $ MONO_PATH=`pwd` MONO_ENV_OPTIONS='--aot=full,dwarfdebug,soft-debug' ./hw *.dll
    ...
    $ MONO_PATH=`pwd` MONO_ENV_OPTIONS='--full-aot' ./hw *.dll
    ...
    and the app ran without crashing

The app:

using System;
using System.Diagnostics;
using System.Runtime.CompilerServices;

public class C {
        public static void Main()
        {
                Helper(20, 10);
        }

        [MethodImpl(MethodImplOptions.NoInlining)]
        public static void Helper (int throwOnFrame, int catchOnFrame)
        {
                if (throwOnFrame == 0)
                        throw new Exception("Throwing");
                if (catchOnFrame == 0)
                {
                        try {
                                Helper (throwOnFrame - 1, -1);
                        } catch (Exception e) {
                                Console.WriteLine ($"Caught {e}");
                                var st = new StackTrace (e);
                                var frames = st.GetFrames();
                                int frameNum = 0;
                                foreach (var frame in frames) {
                                        Console.WriteLine ($"frame {frameNum++}: {frame}");
                                }
                        }
                        return;
                }
                Helper (throwOnFrame - 1, catchOnFrame - 1);
        }
}

Update: tried our in-tree MacCatalyst sample with the same throw/catch code with mono's asmwriter and with LLVM and both seem to work correctly with Xcode 15.

@lambdageek lambdageek removed the untriaged New issue has not been triaged by the area owner label Sep 25, 2023
@MichalStrehovsky
Copy link
Member

I assume this is all resolved and we won't ship something that wouldn't work with xcode 15.

@ghost ghost locked as resolved and limited conversation to collaborators Nov 22, 2023
Sign up for free to subscribe to this conversation on GitHub. Already have an account? Sign in.
Projects
None yet
Development

No branches or pull requests

4 participants