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

Mono linker failed with function pointer delegates #41866

Closed
hez2010 opened this issue Sep 4, 2020 · 18 comments
Closed

Mono linker failed with function pointer delegates #41866

hez2010 opened this issue Sep 4, 2020 · 18 comments

Comments

@hez2010
Copy link
Contributor

hez2010 commented Sep 4, 2020

Description

Mono linker failed with function pointer delegates.
Code:

#define UNICODE
#define WIN32
#include <cstring>

extern "C" __declspec(dllexport) char* __cdecl InvokeFun(char* (*foo)(int)) {
    return foo(5);
}
using System;
using System.Diagnostics;
using System.Linq;
using System.Runtime.CompilerServices;
using System.Runtime.InteropServices;

namespace Test
{
    unsafe class Program
    {
        [DllImport("./Test.dll")]
        static extern string InvokeFun(delegate* cdecl<int, IntPtr> fun);

        [UnmanagedCallersOnly(CallConvs = new[] { typeof(CallConvCdecl) })]
        public static IntPtr Foo(int x)
        {
            var str = Enumerable.Repeat("x", x).Aggregate((a, b) => $"{a}{b}");
            return Marshal.StringToHGlobalAnsi(str);
        }
        static void Main(string[] args)
        {
            var callback = (delegate* cdecl<int, nint>)(delegate*<int, nint>)&Foo;
            Console.WriteLine(InvokeFun(callback));
        }
    }
}

Now run dotnet publish with PublishTrimmed:

dotnet publish -c Release -r win-x64 /p:PublishTrimmed=true

Got exception from mono lnker:

  Mono.Linker.LinkerFatalErrorException: ILLink: error IL1005: Test.Program.InvokeFun(method): Error processing method 'Test.Program.InvokeFun(method)' in assembly 'Test.dll'
   ---> System.NullReferenceException: Object reference not set to an instance of an object.
     at Mono.Linker.Steps.MarkStep.ProcessInteropMethod(MethodDefinition method)
     at Mono.Linker.Steps.MarkStep.ProcessMethod(MethodDefinition method, DependencyInfo& reason)
     at Mono.Linker.Steps.MarkStep.ProcessQueue()
     --- End of inner exception stack trace ---
     at Mono.Linker.Steps.MarkStep.ProcessQueue()
     at Mono.Linker.Steps.MarkStep.ProcessPrimaryQueue()
     at Mono.Linker.Steps.MarkStep.Process()
     at Mono.Linker.Steps.MarkStep.Process(LinkContext context)
     at Mono.Linker.Pipeline.ProcessStep(LinkContext context, IStep step)
     at Mono.Linker.Pipeline.Process(LinkContext context)
     at Mono.Linker.Driver.Run(ILogger customLogger)

Configuration

.NET 5 preview 8

@Dotnet-GitSync-Bot
Copy link
Collaborator

I couldn't figure out the best area label to add to this issue. If you have write-permissions please help me learn by adding exactly one area label.

@Dotnet-GitSync-Bot Dotnet-GitSync-Bot added the untriaged New issue has not been triaged by the area owner label Sep 4, 2020
@danmoseley
Copy link
Member

@vitek-karas should this transfer to linker repo?

@EgorBo
Copy link
Member

EgorBo commented Sep 4, 2020

both Android and iOS samples from src/mono/netcore/sample directory fail to build because of this error.

@vitek-karas
Copy link
Member

vitek-karas commented Sep 4, 2020

This has been already fixed - see the original linker bug dotnet/linker#1345.

I just tried the repro from this issue with latest 5.0.100-rc.1.20453.7 and I don't see any errors.
(Note that the syntax for function pointers has changed, now it looks like delegate* unmanaged[Cdecl]<int, IntPtr> fun)

Can you please try with the latest RC build?

@akoeplinger
Copy link
Member

akoeplinger commented Sep 4, 2020

For the Android/iOS samples we build with the SDK specified in global.json which is still using a preview8 SDK:

"version": "5.0.100-preview.8.20362.3",
.

@EgorBo
Copy link
Member

EgorBo commented Sep 4, 2020

@akoeplinger @vitek-karas updating global.json to 5.0.100-rc.1.20453.7 fixed the issue! thanks, I'll update it as part of my pr

@akoeplinger
Copy link
Member

akoeplinger commented Sep 4, 2020

@EgorBo we can't do that, it needs to happen as part of the monthly infrastructure rollout (#41684)

@marek-safar
Copy link
Contributor

@akoeplinger isn't the rollout scheduled for Monday?

@ghost
Copy link

ghost commented Sep 4, 2020

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

@akoeplinger
Copy link
Member

akoeplinger commented Sep 4, 2020

yeah but it looks like it's not as simple as bumping the version, see #41684. So I'd let Viktor handle it.

/cc @ViktorHofer

@ViktorHofer
Copy link
Member

Thanks for looping me in. Yes, the plan is that I update the SDK as part of September's monthly rollout. Will send out a mail later today about the rollout. Thanks

@ViktorHofer
Copy link
Member

@akoeplinger the plan was to update the P8 final. What's the minimum required version that you need?

akoeplinger pushed a commit that referenced this issue Sep 4, 2020
Fixes broken samples for Android and iOS.
`InvariantGlobalization` fixes the issue described in #41866 because otherwise ILLink fails on Interop.Globalization.EnumCalendarInfo (with a function pointer).
@akoeplinger
Copy link
Member

akoeplinger commented Sep 4, 2020

@ViktorHofer it looks like the error still happens with 5.0.100-preview.8.20359.7 SDK but is fixed in 5.0.100-rc.1.20453.7 based on the comments in dotnet/linker#1345, so I think a Preview8 SDK is probably not enough.

@akoeplinger
Copy link
Member

@EgorBo can you try whether it happens with 5.0.100-preview.8.20417.9 which is the released preview 8 SDK?

@ViktorHofer
Copy link
Member

Let's baseline on P8 final (min version) but use an RC1 build as the target version.

@akoeplinger
Copy link
Member

I did a quick check with the code from #41866 (comment) and it indeed still fails with 5.0.100-preview.8.20417.9.

@CoffeeFlux CoffeeFlux added area-Infrastructure and removed area-AssemblyLoader-coreclr untriaged New issue has not been triaged by the area owner labels Sep 14, 2020
@ghost
Copy link

ghost commented Sep 14, 2020

Tagging subscribers to this area: @ViktorHofer
See info in area-owners.md if you want to be subscribed.

@ericstj
Copy link
Member

ericstj commented Sep 16, 2020

I tested this on latest and it's working.

I needed to update the syntax per: https://github.com/dotnet/csharplang/blob/master/proposals/csharp-9.0/function-pointers.md

Now it is

using System;
using System.Diagnostics;
using System.Linq;
using System.Runtime.CompilerServices;
using System.Runtime.InteropServices;

namespace Test
{
    unsafe class Program
    {
        [DllImport("./Test.dll")]
        static extern string InvokeFun(delegate* unmanaged[Cdecl]<int, IntPtr> fun);

        [UnmanagedCallersOnly(CallConvs = new[] { typeof(CallConvCdecl) })]
        public static IntPtr Foo(int x)
        {
            var str = Enumerable.Repeat("x", x).Aggregate((a, b) => $"{a}{b}");
            return Marshal.StringToHGlobalAnsi(str);
        }
        static void Main(string[] args)
        {
            var callback = (delegate* unmanaged[Cdecl]<int, nint>)(delegate* managed<int, nint>)&Foo;
            Console.WriteLine(InvokeFun(callback));
        }
    }
}

Running on

dotnet --version
5.0.100-rc.2.20465.15
C:\scratch\linkerTest>dotnet.exe publish -c Release -r win-x64 /p:PublishTrimmed=true
Microsoft (R) Build Engine version 16.8.0-preview-20464-02+0220c5eae for .NET
Copyright (C) Microsoft Corporation. All rights reserved.

  Determining projects to restore...
  All projects are up-to-date for restore.
  You are using a preview version of .NET. See: https://aka.ms/dotnet-core-preview
  linkerTest -> C:\scratch\linkerTest\bin\Release\net5.0\win-x64\linkerTest.dll
  Optimizing assemblies for size, which may change the behavior of the app. Be sure to test after publishing. See: https://aka.ms/dotnet-illink
  linkerTest -> C:\scratch\linkerTest\bin\Release\net5.0\win-x64\publish\

@ericstj ericstj closed this as completed Sep 16, 2020
@ghost ghost locked as resolved and limited conversation to collaborators Dec 7, 2020
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