Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
[Xamarin.Android.Build.Tasks] Delete inconsistent debug symbols (#701)
Fixes: https://bugzilla.xamarin.com/show_bug.cgi?id=58221 The build scenario: 1. Use Windows. (This doesn't happen on macOS.) 2. Clone: https://github.com/xamarin/xamarin-forms-samples/tree/master/Templates/DataTemplateSelector 3. Edit `Selector\Selector.csproj` and change `$(DebugType)` to Portable. 4. Open `Selector.sln` within VS and restore all packages. 5. Build the `Droid\Selector.Droid.csproj` project: msbuild /p:Configuration=Release /t:SignAndroidPackage Droid\Selector.Droid.csproj 6. Touch (update the timestamp of) `Selector\Selector.csproj`. 7. Build the project `Droid\Selector.Droid.csproj` project again. msbuild /p:Configuration=Release /t:SignAndroidPackage Droid\Selector.Droid.csproj Expected results: No errors. Actual results: Linking fails: error MSB4018: The "LinkAssemblies" task failed unexpectedly.\r [C:\Users\jonpr\Dev\xamarin-forms-samples\Templates\DataTemplateSelector\Droid\Selector.Droid.csproj] error MSB4018: Mono.Linker.MarkException: Error processing method: 'Xamarin.Forms.View Xamarin.Forms.Platform.Android.VisualElementRenderer`1::get_View()' in assembly: 'Xamarin.Forms.Platform.Android.dll' ---> System.ArgumentNullException: Value cannot be null.\r [C:\Users\jonpr\Dev\xamarin-forms-samples\Templates\DataTemplateSelector\Droid\Selector.Droid.csproj] error MSB4018: Parameter name: instruction\r [C:\Users\jonpr\Dev\xamarin-forms-samples\Templates\DataTemplateSelector\Droid\Selector.Droid.csproj] error MSB4018: at Mono.Cecil.Cil.InstructionOffset..ctor(Instruction instruction)\r [C:\Users\jonpr\Dev\xamarin-forms-samples\Templates\DataTemplateSelector\Droid\Selector.Droid.csproj] error MSB4018: at Mono.Cecil.Cil.CodeReader.ReadScope(ScopeDebugInformation scope)\r [C:\Users\jonpr\Dev\xamarin-forms-samples\Templates\DataTemplateSelector\Droid\Selector.Droid.csproj] error MSB4018: at Mono.Cecil.Cil.CodeReader.ReadScopes(Collection`1 scopes)\r [C:\Users\jonpr\Dev\xamarin-forms-samples\Templates\DataTemplateSelector\Droid\Selector.Droid.csproj] error MSB4018: at Mono.Cecil.Cil.CodeReader.ReadScope(ScopeDebugInformation scope)\r [C:\Users\jonpr\Dev\xamarin-forms-samples\Templates\DataTemplateSelector\Droid\Selector.Droid.csproj] error MSB4018: at Mono.Cecil.Cil.CodeReader.ReadScopes(Collection`1 scopes)\r [C:\Users\jonpr\Dev\xamarin-forms-samples\Templates\DataTemplateSelector\Droid\Selector.Droid.csproj] error MSB4018: at Mono.Cecil.Cil.CodeReader.ReadScope(ScopeDebugInformation scope)\r [C:\Users\jonpr\Dev\xamarin-forms-samples\Templates\DataTemplateSelector\Droid\Selector.Droid.csproj] error MSB4018: at Mono.Cecil.Cil.CodeReader.ReadDebugInfo()\r [C:\Users\jonpr\Dev\xamarin-forms-samples\Templates\DataTemplateSelector\Droid\Selector.Droid.csproj] error MSB4018: at Mono.Cecil.Cil.CodeReader.ReadMethodBody()\r [C:\Users\jonpr\Dev\xamarin-forms-samples\Templates\DataTemplateSelector\Droid\Selector.Droid.csproj] error MSB4018: at Mono.Cecil.Cil.CodeReader.ReadMethodBody(MethodDefinition method)\r [C:\Users\jonpr\Dev\xamarin-forms-samples\Templates\DataTemplateSelector\Droid\Selector.Droid.csproj] error MSB4018: at Mono.Cecil.MetadataReader.ReadMethodBody(MethodDefinition method)\r [C:\Users\jonpr\Dev\xamarin-forms-samples\Templates\DataTemplateSelector\Droid\Selector.Droid.csproj] error MSB4018: at Mono.Cecil.MethodDefinition.<>c.<get_Body>b__41_0(MethodDefinition method, MetadataReader reader)\r [C:\Users\jonpr\Dev\xamarin-forms-samples\Templates\DataTemplateSelector\Droid\Selector.Droid.csproj] error MSB4018: at Mono.Cecil.ModuleDefinition.Read[TItem,TRet](TRet& variable, TItem item, Func`3 read)\r [C:\Users\jonpr\Dev\xamarin-forms-samples\Templates\DataTemplateSelector\Droid\Selector.Droid.csproj] error MSB4018: at Mono.Cecil.MethodDefinition.get_Body()\r [C:\Users\jonpr\Dev\xamarin-forms-samples\Templates\DataTemplateSelector\Droid\Selector.Droid.csproj] error MSB4018: at Mono.Linker.Steps.MarkStep.ProcessMethod(MethodDefinition method)\r [C:\Users\jonpr\Dev\xamarin-forms-samples\Templates\DataTemplateSelector\Droid\Selector.Droid.csproj] error MSB4018: at Mono.Linker.Steps.MarkStep.ProcessQueue()\r [C:\Users\jonpr\Dev\xamarin-forms-samples\Templates\DataTemplateSelector\Droid\Selector.Droid.csproj] error MSB4018: --- End of inner exception stack trace ---\r [C:\Users\jonpr\Dev\xamarin-forms-samples\Templates\DataTemplateSelector\Droid\Selector.Droid.csproj] error MSB4018: at Mono.Linker.Steps.MarkStep.ProcessQueue()\r [C:\Users\jonpr\Dev\xamarin-forms-samples\Templates\DataTemplateSelector\Droid\Selector.Droid.csproj] error MSB4018: at Mono.Linker.Steps.MarkStep.Process()\r [C:\Users\jonpr\Dev\xamarin-forms-samples\Templates\DataTemplateSelector\Droid\Selector.Droid.csproj] error MSB4018: at Mono.Linker.Steps.MarkStep.Process(LinkContext context)\r [C:\Users\jonpr\Dev\xamarin-forms-samples\Templates\DataTemplateSelector\Droid\Selector.Droid.csproj] error MSB4018: at Mono.Linker.Pipeline.Process(LinkContext context)\r [C:\Users\jonpr\Dev\xamarin-forms-samples\Templates\DataTemplateSelector\Droid\Selector.Droid.csproj] error MSB4018: at MonoDroid.Tuner.Linker.Run(Pipeline pipeline, LinkContext context)\r [C:\Users\jonpr\Dev\xamarin-forms-samples\Templates\DataTemplateSelector\Droid\Selector.Droid.csproj] error MSB4018: at MonoDroid.Tuner.Linker.Process(LinkerOptions options, LinkContext& context)\r [C:\Users\jonpr\Dev\xamarin-forms-samples\Templates\DataTemplateSelector\Droid\Selector.Droid.csproj] error MSB4018: at Xamarin.Android.Tasks.LinkAssemblies.Execute(DirectoryAssemblyResolver res)\r [C:\Users\jonpr\Dev\xamarin-forms-samples\Templates\DataTemplateSelector\Droid\Selector.Droid.csproj] error MSB4018: at Xamarin.Android.Tasks.LinkAssemblies.Execute()\r [C:\Users\jonpr\Dev\xamarin-forms-samples\Templates\DataTemplateSelector\Droid\Selector.Droid.csproj] error MSB4018: at Microsoft.Build.BackEnd.TaskExecutionHost.Microsoft.Build.BackEnd.ITaskExecutionHost.Execute()\r [C:\Users\jonpr\Dev\xamarin-forms-samples\Templates\DataTemplateSelector\Droid\Selector.Droid.csproj] error MSB4018: at Microsoft.Build.BackEnd.TaskBuilder.<ExecuteInstantiatedTask>d__26.MoveNext() [C:\Users\jonpr\Dev\xamarin-forms-samples\Templates\DataTemplateSelector\Droid\Selector.Droid.csproj] The cause of the error is in the interaction between the `_CopyIntermediateAssemblies`, `_CopyMdbFiles`, and `_StripEmbeddedLibraries` targets. During the initial build in Step (5), `obj\Release\linksrc` is populated with copies of the original assemblies and debug symbols for those assemblies. The contents of `obj\Release\linksrc` are then updated *in place* by various tasks such as the `<StripEmbeddedLibraries/>` and `<LinkAssemblies/>` tasks. After stripping and linking, the timestamps in `obj\Release\linksrc` are updated and the assemblies and associated debug symbols may be smaller than the original copies. During the rebuild in Step (7), `_CopyIntermediateAssemblies` replaces `obj\Release\linksrc\Xamarin.Forms.Platform.Android.dll` with a copy of the original file in `packages\Xamarin.Forms...\lib\MonoAndroid10`. The `_CopyMdbFiles` task -- which is responsible for copying `.dll.mdb` files into `obj\Release\linksrc` -- does *not* update the `Xamarin.Forms.Platform.Android.dll.mdb` file. The result of this inaction is that when the `<StripEmbeddedLibraries/>` task executes, the assembly and corresponding debug symbols are out-of-sync: `Xamarin.Forms.Platform.Android.dll` is the original+unstripped assembly, while `Xamarin.Forms.Platform.Android.dll.mdb` has been *modified* as part of (both?) the `<StripEmbeddedLibraries/>` and/or `<LinkAssemblies/>` task. When `<StripEmbeddedLibraries/>` executes again as part of the rebuild, it takes these out-of-sync files and then proceeds to *corrupt* the `Xamarin.Forms.Platform.Android.dll.mdb` file. After the `<StripEmbeddedLibraries/>` task completes, we eventually hit the `<LinkAssemblies/>` task, during which Cecil attempts to load the now-corrupt `Xamarin.Forms.Platform.Android.dll.mdb` file, which results in the above `ArgumentNullException`. The fix is in the `_CopyIntermediateAssemblies` target: when we copy assemblies into the `obj\Release\linksrc` directory, ensure that any corresponding `.dll.mdb` files for those asssemblies are *deleted*. This will allow `_CopyMdbFiles` to re-copy the debug symbols, ensuring that everything stays in sync. *Additionally*, update the `_CopyIntermediateAssemblies` target to `<Touch/>` the copied files so that timestamps compare properly. Otherwise, on the 2nd+ build, the target re-executes because the project assembly is newer than e.g. a BCL assembly: Target _CopyIntermediateAssemblies needs to be built as input file '…/xamarin-android/bin/TestDebug/temp/BuildBasicApplicationCheckPdb/bin/Debug/UnnamedProject.dll' is newer than output file 'obj/Debug/linksrc/NetStandard16.dll' Without the `<Touch/>`, the above will *always* be true.
- Loading branch information