Bug 58583 - error MM2001: Could not link assemblies. Reason: Object reference not set to an instance of an object (mixed-mode assembly reference)
Summary: error MM2001: Could not link assemblies. Reason: Object reference not set to ...
Status: RESOLVED FIXED
Alias: None
Product: Xamarin.Mac
Classification: Desktop
Component: mmp ()
Version: 3.4.0 (15.2)
Hardware: Macintosh Mac OS
: --- enhancement
Target Milestone: 15.6
Assignee: Chris Hamons
URL:
Depends on:
Blocks:
 
Reported: 2017-08-04 03:09 UTC by Paul
Modified: 2017-11-16 15:26 UTC (History)
7 users (show)

Tags: VSDCItem
Is this bug a regression?: No
Last known good build:


Attachments
Sample project which will fail to build. (2.04 MB, application/zip)
2017-08-04 03:09 UTC, Paul
Details
Fixed Repro (2.05 MB, application/zip)
2017-08-04 18:47 UTC, Chris Hamons
Details


Notice (2018-05-24): bugzilla.xamarin.com is now in read-only mode.

Please join us on Visual Studio Developer Community and in the Xamarin and Mono organizations on GitHub to continue tracking issues. Bugzilla will remain available for reference in read-only mode. We will continue to work on open Bugzilla bugs, copy them to the new locations as needed for follow-up, and add the new items under Related Links.

Our sincere thanks to everyone who has contributed on this bug tracker over the years. Thanks also for your understanding as we make these adjustments and improvements for the future.


Please create a new report on Developer Community or GitHub with your current version information, steps to reproduce, and relevant error messages or log files if you are hitting an issue that looks similar to this resolved bug and you do not yet see a matching new report.

Related Links:
Status:
RESOLVED FIXED

Description Paul 2017-08-04 03:09:26 UTC
Created attachment 24021 [details]
Sample project which will fail to build.

Overview: 
Building Xamarin.Mac projects that reference managed third-party DLLs which in turn reference other DLLs that I assume are unmanaged (or maybe managed c++) causes the linker to fail and provide no useful message to help isolate or identify the problem. Just referencing the parent DLL causes it to fail, even if no code is using a namespace from that referenced DLL. In this situation I am NOT expecting to be able to use these DLLs; I know that native code is probably present in the child reference.

I ran into this problem when I was trying to migrate a 32-bit MonoMac project to a 64-bit Xamarin.Mac project. My main project was referencing a common portable class library which happened to have some Lua stuff in it for Windows that wasn't being used on the macOS side. The project was rather large and I only managed to isolate the reference to an older third party LuaInterface DLL as I was removing unused DLLs from the project in order to provide a sample that reproduced the problem. I didn't even realize the code was there as I wasn't actually using that part of the shared code. Now that I know it's causing the problem I can just make the reference conditional so it's ignored on macOS, but actually finding that it was the cause was extremely time consuming.

I have provided a sample project that reproduces this problem. The project contains no special code, it's just the default template you get when you create a Xamarin.Mac project. The only thing I did was add a reference to LuaInterface.dll to the project, it's not even used anywhere in the code. You can try to compile this project which will instantly produce the exception.


Steps to Reproduce:
1. Open the attached solution (BreakThings.sln) in the current production version (as of this writing 7.0.1) of Visual Studio for Mac 2017.
2. Build the solution, either by clicking the Play button or selecting Build All from the Build menu.


Actual Results: 
The build fails with the following exception:
    MMP : error MM2001: Could not link assemblies. Reason: Object reference not set to an instance of an object
    --- inner exception
    System.NullReferenceException: Object reference not set to an instance of an object
      at MonoTouch.Tuner.ListExportedSymbols.ProcessMethod (Mono.Cecil.MethodDefinition method) [0x0001d] in <bd8f720887274986b0fb8de7b621eb20>:0 
      at MonoTouch.Tuner.ListExportedSymbols.ProcessType (Mono.Cecil.TypeDefinition type) [0x0006e] in <bd8f720887274986b0fb8de7b621eb20>:0 
      at MonoTouch.Tuner.ListExportedSymbols.ProcessAssembly (Mono.Cecil.AssemblyDefinition assembly) [0x000a6] in <bd8f720887274986b0fb8de7b621eb20>:0 
      at Mono.Linker.Steps.BaseStep.Process (Mono.Linker.LinkContext context) [0x0002b] in <bd8f720887274986b0fb8de7b621eb20>:0 
      at Mono.Linker.Pipeline.Process (Mono.Linker.LinkContext context) [0x00023] in <bd8f720887274986b0fb8de7b621eb20>:0 
      at MonoMac.Tuner.Linker.Process (MonoMac.Tuner.LinkerOptions options, Mono.Linker.LinkContext& context, System.Collections.Generic.List`1[System.String]& assemblies) [0x0009e] in <bd8f720887274986b0fb8de7b621eb20>:0 
    ---
      at MonoMac.Tuner.Linker.Process (MonoMac.Tuner.LinkerOptions options, Mono.Linker.LinkContext& context, System.Collections.Generic.List`1[System.String]& assemblies) [0x00198] in <bd8f720887274986b0fb8de7b621eb20>:0 
      at Xamarin.Bundler.Driver.Link () [0x001cf] in <bd8f720887274986b0fb8de7b621eb20>:0 
      at Xamarin.Bundler.Driver.Pack (System.Collections.Generic.IList`1[T] unprocessed) [0x004ea] in <bd8f720887274986b0fb8de7b621eb20>:0 
      at Xamarin.Bundler.Driver.Main2 (System.String[] args) [0x00f85] in <bd8f720887274986b0fb8de7b621eb20>:0 
      at Xamarin.Bundler.Driver.Main (System.String[] args) [0x0000c] in <bd8f720887274986b0fb8de7b621eb20>:0 
Done building target "_CompileToNative" in project "BreakThings.csproj" -- FAILED.



Expected Results: 
Either provide an error message that is useful and helps identify exactly what reference was causing the linker to fail, or allow the build to succeed (with or without a warning) and just blow up at runtime if someone actually tries to use the bad reference.
I don't really care either way how it's fixed, as long as I get something better than what it does now.



Build Date & Hardware: 
Build 2017-08-03 on macOS 10.12.6
Mac Pro 6,1


Additional Builds and Platforms:
Visual Studio Community 2017 for Mac
Version 7.0.1 (build 24)
Runtime:
	Mono 5.0.1.1 (2017-02/5077205) (64-bit)
	GTK+ 2.24.23 (Raleigh theme)

	Package version: 500010001
NuGet
Version: 4.0.0.2323
.NET Core
Runtime: Not installed
SDK: Not installed
MSBuild SDKs: /Library/Frameworks/Mono.framework/Versions/5.0.1/lib/mono/msbuild/15.0/bin/Sdks
Xamarin.Profiler
Version: 1.5.4
Location: /Applications/Xamarin Profiler.app/Contents/MacOS/Xamarin Profiler
Apple Developer Tools
Xcode 8.3.3 (12175.1)
Build 8E3004b

Xamarin.iOS
Version: 10.10.0.36 (Visual Studio Community)
Hash: d2270eec
Branch: d15-2
Build date: 2017-05-22 16:30:53-0400

Xamarin.Mac
Version: 3.4.0.36 (Visual Studio Community)

Xamarin.Android
Not Installed

Xamarin Inspector
Version: 1.2.2
Hash: b71b035
Branch: d15-1
Build date: Fri, 21 Apr 2017 17:57:12 GMT

Build Information
Release ID: 700010024
Git revision: 7ab1ca2ced6f584e56b7a0d4d321d00775cd95c9
Build date: 2017-05-19 05:44:51-04
Xamarin addins: 08d17158f3365beee5e60f67999e607cce4b3f93
Build lane: monodevelop-lion-d15-2

Operating System
Mac OS X 10.12.6
Darwin 16.7.0 Darwin Kernel Version 16.7.0
    Thu Jun 15 17:36:27 PDT 2017
    root:xnu-3789.70.16~2/RELEASE_X86_64 x86_64

Enabled user installed addins
Eto.Forms Support Addin 2.3.0.6
 

Additional Information: 
None
Comment 2 Chris Hamons 2017-08-04 17:35:39 UTC
So I had some trouble reproducing this with the exact settings the user provided, but I'm able to reproduce with others.

The attached copy is using System Mono, which disables linking. However, if you shove it in a new solution (the configurations were giving me issues) and swap it back to Modern, and enable linking, I reproduce:

    /Library/Frameworks/Xamarin.Mac.framework/Versions/Current/bin/mmp /verbose /output:/Users/donblas/Downloads/BreakThings/bin/SixtyFour/ /name:BreakThings /profile:Xamarin.Mac,Version=v2.0,Profile=Mobile /arch:x86_64 --http-message-handler=HttpClientHandler /minos=10.7 /assembly:/Users/donblas/Downloads/BreakThings/LuaInterface.dll /assembly:/Library/Frameworks/Xamarin.Mac.framework/Versions/Current/lib/mono/Xamarin.Mac/mscorlib.dll /assembly:/Library/Frameworks/Xamarin.Mac.framework/Versions/Current/lib/mono/Xamarin.Mac/System.Core.dll /assembly:/Library/Frameworks/Xamarin.Mac.framework/Versions/Current/lib/mono/Xamarin.Mac/System.dll /assembly:/Library/Frameworks/Xamarin.Mac.framework/Versions/Current/lib/mono/Xamarin.Mac/Xamarin.Mac.dll /Users/donblas/Downloads/BreakThings/bin/SixtyFour/BreakThings.exe -v -v -v -v -v -v /sdkroot /Applications/Xcode9-beta4.app/Contents/Developer --cache /Users/donblas/Downloads/BreakThings/obj/SixtyFour/mmp-cache 
    MMP : error MM2001: Could not link assemblies. Reason: Error processing method: 'System.Int32 modopt(System.Runtime.CompilerServices.CallConvCdecl) <Module>::lua_sethook(lua_State*,method System.Void modopt(System.Runtime.CompilerServices.CallConvCdecl) *(lua_State*,lua_Debug*),System.Int32,System.Int32)' in assembly: 'lua51.dll'
    --- inner exception
    Mono.Linker.MarkException: Error processing method: 'System.Int32 modopt(System.Runtime.CompilerServices.CallConvCdecl) <Module>::lua_sethook(lua_State*,method System.Void modopt(System.Runtime.CompilerServices.CallConvCdecl) *(lua_State*,lua_Debug*),System.Int32,System.Int32)' in assembly: 'lua51.dll' ---> System.NullReferenceException: Object reference not set to an instance of an object

I am uncertain how this could be showing up with system mono.
Comment 3 Paul 2017-08-04 18:11:39 UTC
Yikes, I didn't think about checking if it worked on a clean machine. That exception is much better than the one I was getting.

I will test on a different machine tonight to see how it behaves there. My install has been around for a long time, starting with MonoDevelop then Xamarin Studio and now Visual Studio. At 2 points in time I had built everything from source, although right now it's using updates that Visual Studio installed itself. 

If it turns out to be my machine, then I guess this isn't a problem because your exception actually says what the problem is and that's what I want to see. I'll update this when I've had a chance to play around with it.

In the end I need to be able to get a 64-bit Xamarin.Mac build which can use .NET 4.5 PCL projects. I wasn't noticing a way to disable linking for that.
Comment 4 Chris Hamons 2017-08-04 18:47:31 UTC
Created attachment 24040 [details]
Fixed Repro
Comment 5 Chris Hamons 2017-08-04 19:00:56 UTC
Stack trace looks like:

https://gist.github.com/chamons/54d4c5ff097419f72c75c7e6576cde33

We are here:


		protected TypeDefinition ResolveTypeDefinition (TypeReference type)
		{
			TypeDefinition td = type as TypeDefinition;
			if (td == null)
	---------->	     td = type.Resolve ();

			return td;
		}

Getting a Null Reference Exception.

Thus, somehow type is null?

Rolf - You've fixed a number of linker crashes with non-standard assemblies, any thoughts?
Comment 6 Paul 2017-08-05 00:36:39 UTC
Chris, I'm not sure why you had trouble reproducing with the original sample that I provided. Is it possible you're testing against a different build than the one tagged the report as?

In an attempt to verify whether it was my machine or not, I tried downloading the original attachment onto my laptop and running it there. That has also had older versions of Mono and Xamarin Studio installed, but was much less of a mess because I've never built any Mono framework or MonoDevelop stuff on there. Same problem, but since that's a clean install either I tried it a third time.

I created a new Virtual Machine in VMWare. 
1. Installed macOS Sierra.
2. Installed VMWare Tools into the VM.
3. Updated macOS to current. (10.12.6)
4. Installed current Xcode, 8.3.3. 
5. Installed current production Visual Studio for Mac, via the download link here:
https://www.visualstudio.com/vs/visual-studio-mac/
-- Did not install Android or iOS stuff, unchecked those two. Did install Mac and the Workbooks stuff.
6. Downloaded my unmodified attachment from this bug report.
7. Launched Visual Studio for Mac. Opened "BreakThings.sln" and clicked the "Play" button in the toolbar.

Result:
Got the exact same exception as in my initial post. I didn't need to change any settings at all for it to fail.


The exception you posted above is much nicer than the one I get and tells what DLL is causing the problem. I would be satisfied with that exception if it was happening instead of the useless one I get now. I am not expecting the problematic DLL to work, it probably contains native code and I wasn't trying to use it anyway. Unless it shouldn't be causing the linker to fail in this manner, I think a helpful error message is fine.

I can upload the Virtual Machine that I just created to my OneDrive if it would help your analysis. The VM is 33GB uncompressed.

Thanks in advance for trying to fix this.
Comment 7 Rolf Bjarne Kvinge [MSFT] 2017-08-07 11:28:09 UTC
(In reply to Paul from comment #6)
> 
> The exception you posted above is much nicer than the one I get and tells
> what DLL is causing the problem. I would be satisfied with that exception if
> it was happening instead of the useless one I get now. I am not expecting
> the problematic DLL to work, it probably contains native code and I wasn't
> trying to use it anyway. Unless it shouldn't be causing the linker to fail
> in this manner, I think a helpful error message is fine.

We recently improved the error messages for the linker, so you'll the more helpful version in the future.

That said, we still need to improve this particular scenario (mixed-mode assemblies), we shouldn't be throwing NullReferenceExceptions.

IMHO we should just reject (at the very least warn about) any mixed-mode assemblies [1], both in XI and XM (afaik no non-windows compilers are able to produce mixed-mode assemblies, which means that the native code will always be windows-specific. However, I'm not sure if mono will load/run any methods that are IL-only, so we might have to make it a warning and not an error to avoid breaking people's projects).

In any case this is not a bug, so I'm lowering importance to enhancement.

[1]: How to detect mixed-mode assemblies: https://github.com/jbevain/cecil/blob/d51486c6e98a51df33978aa6abcf6ba373ab3588/Mono.Cecil/AssemblyWriter.cs#L84-L85
Comment 8 Chris Hamons 2017-08-07 17:07:10 UTC
It would be a nice 15.5 change to warn on mixed mode assemblies, moving there as a possible work item.
Comment 9 Chris Hamons 2017-10-19 18:01:08 UTC
https://github.com/xamarin/xamarin-macios/pull/2911