Bug 36032 - Omitting 'UIKit.UIApplication.Main (args, null, "AppDelegate");' in the entry point causes mtouch to crash (see later comments)
Summary: Omitting 'UIKit.UIApplication.Main (args, null, "AppDelegate");' in the entry...
Status: IN_PROGRESS
Alias: None
Product: Android
Classification: Xamarin
Component: MSBuild ()
Version: unspecified
Hardware: Macintosh Mac OS
: --- normal
Target Milestone: ---
Assignee: Radek Doulik
URL:
Depends on:
Blocks:
 
Reported: 2015-11-19 02:08 UTC by June Rhodes
Modified: 2015-11-24 15:18 UTC (History)
5 users (show)

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

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 for Bug 36032 on Developer Community or GitHub if you have new information to add and do not yet see a matching new report.

If the latest results still closely match this report, you can use the original description:

  • Export the original title and description: Developer Community HTML or GitHub Markdown
  • Copy the title and description into the new report. Adjust them to be up-to-date if needed.
  • Add your new information.

In special cases on GitHub you might also want the comments: GitHub Markdown with public comments

Related Links:
Status:
IN_PROGRESS

Description June Rhodes 2015-11-19 02:08:20 UTC
I have a post-build step which does some post-processing on assemblies that are built.  The reason for this is that I want to automatically implement some interfaces, and mobile platforms (at least iOS) don't support JIT, so I need to generate the IL before AOT occurs.

Interestingly, this issue ONLY occurs when building under Mac (for both iOS and Android).  When building for Android on Windows, everything works fine.

To reproduce:
  - Clone https://github.com/hach-que/Protoinject
  - Run "mono Protobuild.exe --generate iOS" or "mono Protobuild.exe --generate Android"
  - Run "xbuild Protoinject.iOS.sln" or "xbuild Protoinject.Android.sln"

You will observe output similar to the following when compiling Protoinject.Example:

2638	      	Target _ValidateAndroidPackageProperties:
2639	      		  PackageName: Protoinject.Example
2640	      	
2641	      	Target _ResolveLibraryProjectImports:
2642	      :  monodroiderror XA0000: Unexpected error - Please file a bug report at http://bugzilla.xamarin.com. Reason: System.IO.FileNotFoundException: Could not load assembly 'Protoinject.Test.exe, Version=, Culture=neutral, PublicKeyToken='. Perhaps it doesn't exist in the Mono for Android profile?
2643	      	Task "ResolveLibraryProjectImports" execution -- FAILED
2644	      	Done building target "_ResolveLibraryProjectImports" in project "/Users/june/Leases/26442/Protoinject.Example/Protoinject.Example.Android.csproj".-- FAILED

You will also see Protoinject.Test being post-processed:

2524	      	Target PostBuildHooks:
2525	      		Running "Protoinject.FactoryGenerator" post-build hook...
2526	      		Executing: chmod u+x "/Users/june/Leases/26442/Protoinject.FactoryGenerator/bin/MacOS/AnyCPU/Debug/Protoinject.FactoryGenerator.exe"
2527	      		Executing: mono "/Users/june/Leases/26442/Protoinject.FactoryGenerator/bin/MacOS/AnyCPU/Debug/Protoinject.FactoryGenerator.exe" "obj/Android/AnyCPU/Debug/Protoinject.Test.exe" "/Library/Frameworks/Mono.framework/External/xbuild-frameworks/MonoAndroid/v1.0/System.dll;/Library/Frameworks/Mono.framework/External/xbuild-frameworks/MonoAndroid/v1.0/System.Core.dll;/Users/june/Leases/26442/Prototest/Prototest.Library/bin/Android/AnyCPU/Debug//Prototest.Library.dll;/Users/june/Leases/26442/Protoinject/bin/Android/AnyCPU/Debug//Protoinject.dll;/Library/Frameworks/Mono.framework/External/xbuild-frameworks/MonoAndroid/v1.0/mscorlib.dll"
2528	      		Loading referenced assembly from /Library/Frameworks/Mono.framework/External/xbuild-frameworks/MonoAndroid/v1.0/System.dll...
2529	      		Loading referenced assembly from /Library/Frameworks/Mono.framework/External/xbuild-frameworks/MonoAndroid/v1.0/System.Core.dll...
2530	      		Loading referenced assembly from /Users/june/Leases/26442/Prototest/Prototest.Library/bin/Android/AnyCPU/Debug//Prototest.Library.dll...
2531	      		Loading referenced assembly from /Users/june/Leases/26442/Protoinject/bin/Android/AnyCPU/Debug//Protoinject.dll...
2532	      		Loading referenced assembly from /Library/Frameworks/Mono.framework/External/xbuild-frameworks/MonoAndroid/v1.0/mscorlib.dll...
2533	      		Generating factories for Protoinject.Test, Version=0.0.0.0, Culture=neutral, PublicKeyToken=null...
2534	      		Resolved type 'Protoinject.IGenerateFactory' as Protoinject.IGenerateFactory (in Protoinject, Version=0.0.0.0, Culture=neutral, PublicKeyToken=null)
2535	      		Resolved type 'Protoinject.INode' as Protoinject.INode (in Protoinject, Version=0.0.0.0, Culture=neutral, PublicKeyToken=null)
2536	      		Resolved type 'Protoinject.IKernel' as Protoinject.IKernel (in Protoinject, Version=0.0.0.0, Culture=neutral, PublicKeyToken=null)
2537	      		Resolved type 'Protoinject.ICurrentNode' as Protoinject.ICurrentNode (in Protoinject, Version=0.0.0.0, Culture=neutral, PublicKeyToken=null)
2538	      		Resolved type 'System.Type' as System.Type (in mscorlib, Version=2.0.5.0, Culture=neutral, PublicKeyToken=7cec85d7bea7798e)
2539	      		Resolved type 'Protoinject.IConstructorArgument' as Protoinject.IConstructorArgument (in Protoinject, Version=0.0.0.0, Culture=neutral, PublicKeyToken=null)
2540	      		Resolved type 'Protoinject.NamedConstructorArgument' as Protoinject.NamedConstructorArgument (in Protoinject, Version=0.0.0.0, Culture=neutral, PublicKeyToken=null)
2541	      		Resolved type 'Protoinject.GeneratedFactoryAttribute' as Protoinject.GeneratedFactoryAttribute (in Protoinject, Version=0.0.0.0, Culture=neutral, PublicKeyToken=null)
2542	      		Generating factory: Protoinject.Example.IEntityFactory
2543	      		Generating factory: Protoinject.Test.IGenericFactory`2

Protoinject.Test is post-processed by the tool Protoinject.FactoryGenerator.  There isn't anything obvious in the post-processor that would be causing the issue (it only references types that the assembly already knows about, so it doesn't import them from wrong or incorrect profiles).

Unfortunately I only have a Mac as a build server, which makes diagnosing this issue rather tedious and difficult as my workstation is Windows (where everything works fine).  Since this error only occurs on Mac, I'm reasonably confident that there is a Xamarin bug in here somewhere (at the very least, the Mac version should be resolving the assembly the same as Windows).
Comment 1 June Rhodes 2015-11-19 04:58:46 UTC
I think it might actually be because Protobuild is not emitting the following element:

<MtouchLink>None</MtouchLink>

However, this is omitted for device configurations by default, which makes me think it's required in that scenario.
Comment 2 June Rhodes 2015-11-19 05:36:03 UTC
It doesn't look like this issue is related to the post-build hooks or the generation.  I've narrowed down a project file that produces the issue, and this is the difference between a working project (Test) and the project that reproduces (Protoinject.Test):

Mac-Mini:Protoinject june$ diff -u Test/Test.csproj Protoinject.Test/Protoinject.Test.iOS.csproj                                                         
--- Test/Test.csproj    2015-11-19 21:13:04.000000000 +1100
+++ Protoinject.Test/Protoinject.Test.iOS.csproj        2015-11-19 21:33:30.000000000 +1100
@@ -1,4 +1,4 @@
-<?xml version="1.0" encoding="utf-8"?>
+<?xml version="1.0" encoding="utf-8"?>
 <Project DefaultTargets="Build" ToolsVersion="4.0" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
   <PropertyGroup>
     <Configuration Condition=" '$(Configuration)' == '' ">Debug</Configuration>
@@ -6,11 +6,11 @@
     <ProjectTypeGuids>{FEACFBD2-3405-455C-9665-78FE426C6842};{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}</ProjectTypeGuids>
     <ProductVersion>8.0.30703</ProductVersion>
     <SchemaVersion>2.0</SchemaVersion>
-    <ProjectGuid>{1323AEB4-B7E6-4628-A2BA-15DB0F772DEA}</ProjectGuid>
+    <ProjectGuid>{C7BEDB7E-696F-6A6E-6563-742E54657374}</ProjectGuid>
     <OutputType>Exe</OutputType>
-    <RootNamespace>Test</RootNamespace>
+    <RootNamespace>Protoinject.Test</RootNamespace>
     <IPhoneResourcePrefix>Resources</IPhoneResourcePrefix>
-    <AssemblyName>Test</AssemblyName>
+    <AssemblyName>Protoinject.Test</AssemblyName>
   </PropertyGroup>
   <PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Release|iPhoneSimulator' ">
     <Optimize>true</Optimize>
@@ -25,30 +25,62 @@
     <MtouchUseArmv7>false</MtouchUseArmv7>
   </PropertyGroup>
   <ItemGroup>
+    <Reference Include="Xamarin.iOS" />
     <Reference Include="System" />
-    <Reference Include="System.Xml" />
     <Reference Include="System.Core" />
-    <Reference Include="Xamarin.iOS" />
-  </ItemGroup>
-  <ItemGroup>
-    <ImageAsset Include="Resources\Images.xcassets\AppIcons.appiconset\Contents.json" />
   </ItemGroup>
   <ItemGroup>
-    <InterfaceDefinition Include="Resources\LaunchScreen.xib" />
-    <InterfaceDefinition Include="Main.storyboard" />
+    <Compile Include="EntityFactoryTests.cs" />
+    <Compile Include="Fictional\DefaultGeneric.cs" />
+    <Compile Include="Fictional\DefaultInput.cs" />
+    <Compile Include="Fictional\DefaultInventory.cs" />
+    <Compile Include="Fictional\DefaultMovement.cs" />
+    <Compile Include="Fictional\DefaultProfiler.cs" />
+    <Compile Include="Fictional\DefaultProfilerUtil.cs" />
+    <Compile Include="Fictional\DefaultWorld.cs" />
+    <Compile Include="Fictional\Entity.cs" />
+    <Compile Include="Fictional\IEntity.cs" />
+    <Compile Include="Fictional\IEntityFactory.cs" />
+    <Compile Include="Fictional\IGeneric.cs" />
+    <Compile Include="Fictional\IGenericFactory.cs" />
+    <Compile Include="Fictional\IInput.cs" />
+    <Compile Include="Fictional\IInventory.cs" />
+    <Compile Include="Fictional\IMovement.cs" />
+    <Compile Include="Fictional\INetworkingPlayer.cs" />
+    <Compile Include="Fictional\INetworkingSession.cs" />
+    <Compile Include="Fictional\IPlayer.cs" />
+    <Compile Include="Fictional\IProfiler.cs" />
+    <Compile Include="Fictional\IProfilerUtil.cs" />
+    <Compile Include="Fictional\IWorld.cs" />
+    <Compile Include="Fictional\NetworkingPlayer.cs" />
+    <Compile Include="Fictional\NetworkingSession.cs" />
+    <Compile Include="Fictional\Player.cs" />
+    <Compile Include="GenericFactoryTests.cs" />
+    <Compile Include="..\Prototest\Prototest.Include\Program.cs">
+      <Link>Included Code\Prototest\Prototest.Include\Program.cs</Link>
+      <FromIncludeProject>True</FromIncludeProject>
+    </Compile>
   </ItemGroup>
+  <ItemGroup />
+  <ItemGroup />
+  <ItemGroup />
+  <ItemGroup />
+  <ItemGroup />
+  <ItemGroup />
+  <ItemGroup />
+  <ItemGroup />
+  <ItemGroup />
+  <ItemGroup />
+  <ItemGroup />
+  <ItemGroup />
+  <ItemGroup />
+  <ItemGroup />
+  <ItemGroup />
+  <ItemGroup />
   <ItemGroup>
     <None Include="Info.plist" />
     <None Include="Entitlements.plist" />
   </ItemGroup>
-  <ItemGroup>
-    <Compile Include="Main.cs" />
-    <Compile Include="AppDelegate.cs" />
-    <Compile Include="ViewController.cs" />
-    <Compile Include="ViewController.designer.cs">
-      <DependentUpon>ViewController.cs</DependentUpon>
-    </Compile>
-  </ItemGroup>
   <Import Project="$(MSBuildExtensionsPath)\Xamarin\iOS\Xamarin.iOS.CSharp.targets" />
   <ItemGroup>
     <ProjectReference Include="..\Prototest\Prototest.Library\Prototest.Library.iOS.csproj">

There's nothing left here except the difference in files compiled.  But surely that wouldn't cause a null reference inside mtouch?
Comment 3 June Rhodes 2015-11-19 05:36:42 UTC
Actually I just realised the error I'm getting now is different to the original.

I'm now getting (and have been for some time):

MTOUCH: error MT0000: Unexpected error - Please file a bug report at http://bugzilla.xamarin.com
                System.NullReferenceException: Object reference not set to an instance of an object
                  at MTouch.GatherFrameworks (MonoTouch.Target target, System.Collections.Generic.HashSet`1 frameworks, System.Collections.Generic.HashSet`1 weak_frameworks) <0x1074ed000 + 0x001e8> in <filename unknown>:0 
                  at MonoTouch.Target.ProcessAssemblies () <0x1051b2090 + 0x0054c> in <filename unknown>:0 
                  at MonoTouch.Application.BuildApp () <0x1051b1760 + 0x000af> in <filename unknown>:0 
                  at MonoTouch.Application.Build () <0x105107c00 + 0x000ee> in <filename unknown>:0 
                  at MTouch.Main2 (System.String[] args) <0x102fdf000 + 0x074bf> in <filename unknown>:0 
                  at MTouch.Main (System.String[] args) <0x102f24e60 + 0x00024> in <filename unknown>:0
Comment 4 June Rhodes 2015-11-19 05:42:00 UTC
Whoa.

Copying the section (and related files):

  <ItemGroup>
    <Compile Include="Main.cs" />
    <Compile Include="AppDelegate.cs" />
    <Compile Include="ViewController.cs" />
    <Compile Include="ViewController.designer.cs">
      <DependentUpon>ViewController.cs</DependentUpon>
    </Compile>
  </ItemGroup>

from the default template over to the broken project, and removing the old Program entry point, actually resolved the issue.  Which means "mtouch not crashing" is actually dependent on the code you're including.

I'm going to comment out each of these files individually to see if I can isolate what makes mtouch work.
Comment 5 June Rhodes 2015-11-19 05:45:46 UTC
This issue is isolated to a difference between Main.cs and Program.cs, i.e. the differences in the way the entry points are specified causes this crash.
Comment 6 June Rhodes 2015-11-19 05:52:12 UTC
This is, unbelievably, caused by not calling UIApplication.Main within the entry point.

This is an application that builds successfully:

namespace Prototest.Include
{
    public static class Program
    {
        public static void Main(string[] args)
        {
            UIKit.UIApplication.Main (args, null, "AppDelegate");
        }
    }
}

and this is one that crashes the compiler:

namespace Prototest.Include
{
    public static class Program
    {
        public static void Main(string[] args)
        {
            //UIKit.UIApplication.Main (args, null, "AppDelegate");
        }
    }
}