From e3e213074e40df670ed59cd5952ada20e44a6adf Mon Sep 17 00:00:00 2001 From: Rolf Bjarne Kvinge Date: Mon, 18 Nov 2024 17:19:04 +0100 Subject: [PATCH] Don't log from property accessors in the ILLink task. When executing a remote iOS build from Windows on macOS, the ILLink task is instantiated on the remote macOS machine using a json deserializer. This means that the properties will be read and written to before the task has been fully initialized, and this happens: ``` Newtonsoft.Json.JsonSerializationException: Error getting value from 'ILLinkPath' on 'Xamarin.MacDev.Tasks.ILLink'. ---> System.InvalidOperationException: Task attempted to log before it was initialized. Message was: ILLink.Tasks path: /Users/rolf/Library/Caches/Xamarin/XMA/Agents/Build/net/illink.dll at Microsoft.Build.Shared.ErrorUtilities.ThrowInvalidOperation(String resourceName, Object[] args) at Microsoft.Build.Utilities.TaskLoggingHelper.LogMessage(MessageImportance importance, String message, Object[] messageArgs) at ILLink.Tasks.ILLink.get_ILLinkPath() at Newtonsoft.Json.Serialization.ExpressionValueProvider.GetValue(Object target) --- End of inner exception stack trace --- at Newtonsoft.Json.Serialization.ExpressionValueProvider.GetValue(Object target) at Newtonsoft.Json.Serialization.JsonSerializerInternalReader.SetPropertyValue(JsonProperty property, JsonConverter propertyConverter, JsonContainerContract containerContract, JsonProperty containerProperty, JsonReader reader, Object target) at Newtonsoft.Json.Serialization.JsonSerializerInternalReader.PopulateObject(Object newObject, JsonReader reader, JsonObjectContract contract, JsonProperty member, String id) at Newtonsoft.Json.Serialization.JsonSerializerInternalReader.CreateObject(JsonReader reader, Type objectType, JsonContract contract, JsonProperty member, JsonContainerContract containerContract, JsonProperty containerMember, Object existingValue) at Newtonsoft.Json.Serialization.JsonSerializerInternalReader.CreateValueInternal(JsonReader reader, Type objectType, JsonContract contract, JsonProperty member, JsonContainerContract containerContract, JsonProperty containerMember, Object existingValue) at Newtonsoft.Json.Serialization.JsonSerializerInternalReader.Deserialize(JsonReader reader, Type objectType, Boolean checkAdditionalContent) at Newtonsoft.Json.JsonSerializer.DeserializeInternal(JsonReader reader, Type objectType) at Newtonsoft.Json.JsonSerializer.Deserialize(JsonReader reader, Type objectType) at Xamarin.Messaging.Build.Serialization.TaskSerializer.Deserialize(String content, Type taskType) in D:\a\_work\1\s\src\MSBuild\Xamarin.Messaging.Build.Common\Serialization\TaskSerializer.cs:line 25 at Xamarin.Messaging.Build.TaskRunner.Execute(String taskName, String inputs) in /Users/rolf/work/maccore/net10.0/xamarin-macios/msbuild/Messaging/Xamarin.Messaging.Build/TaskRunner.cs:line 42 at Xamarin.Messaging.Build.ExecuteTaskMessageHandler.<>c__DisplayClass5_0.b__0() in /Users/rolf/work/maccore/net10.0/xamarin-macios/msbuild/Messaging/Xamarin.Messaging.Build/Handlers/ExecuteTaskMessageHandler.cs:line 40 at System.Threading.Tasks.Task`1.InnerInvoke() at System.Threading.ExecutionContext.RunFromThreadPoolDispatchLoop(Thread threadPoolThread, ExecutionContext executionContext, ContextCallback callback, Object state) --- End of stack trace from previous location --- at System.Threading.ExecutionContext.RunFromThreadPoolDispatchLoop(Thread threadPoolThread, ExecutionContext executionContext, ContextCallback callback, Object state) at System.Threading.Tasks.Task.ExecuteWithThreadLocal(Task& currentTaskSlot, Thread threadPoolThread) --- End of stack trace from previous location --- at Xamarin.Messaging.Build.ExecuteTaskMessageHandler.ExecuteAsync(ExecuteTaskMessage message) in /Users/rolf/work/maccore/net10.0/xamarin-macios/msbuild/Messaging/Xamarin.Messaging.Build/Handlers/ExecuteTaskMessageHandler.cs:line 28 at Xamarin.Messaging.Client.RequestHandler`2.HandleAsync(TMessage message) in D:\a\_work\1\s\src\Xamarin.Messaging.Client\Handlers\RequestHandler.cs:line 68 at Xamarin.Messaging.Client.MessageHandlerManager.<>c__DisplayClass12_1`2.<b__2>d.MoveNext() in D:\a\_work\1\s\src\Xamarin.Messaging.Client\MessageHandlerManager.cs:line 96 --- End of stack trace from previous location --- at Xamarin.Messaging.Client.MessagingClient.ReplyAsync[TRequest,TResponse](IRequest`1 request, MessagePriority priority, Func`1 replyFunctionAsync) in D:\a\_work\1\s\src\Xamarin.Messaging.Client\MessagingClient.cs:line 351: 11/18/2024 10:23:11Z ``` So move the logging statement to when it the property in question is used. --- src/tools/illink/src/ILLink.Tasks/LinkTask.cs | 11 +++++------ 1 file changed, 5 insertions(+), 6 deletions(-) diff --git a/src/tools/illink/src/ILLink.Tasks/LinkTask.cs b/src/tools/illink/src/ILLink.Tasks/LinkTask.cs index 979d5599fdab8f..a14f775ebe4517 100644 --- a/src/tools/illink/src/ILLink.Tasks/LinkTask.cs +++ b/src/tools/illink/src/ILLink.Tasks/LinkTask.cs @@ -270,11 +270,7 @@ public string ILLinkPath { #pragma warning restore IL3000 // Avoid accessing Assembly file path when publishing as a single file // IL Linker always runs on .NET Core, even when using desktop MSBuild to host ILLink.Tasks. - string path = Path.Combine (Path.GetDirectoryName (taskDirectory), "net", "illink.dll"); - - Log.LogMessage(MessageImportance.Normal, $"ILLink.Tasks path: {path}"); - - _illinkPath = path; + _illinkPath = Path.Combine (Path.GetDirectoryName (taskDirectory), "net", "illink.dll"); return _illinkPath; } @@ -289,7 +285,10 @@ private static string Quote (string path) protected override string GenerateCommandLineCommands () { var args = new StringBuilder (); - args.Append (Quote (ILLinkPath)); + var path = ILLinkPath; + args.Append (Quote (path)); + Log.LogMessage(MessageImportance.Normal, $"ILLink.Tasks path: {path}"); + return args.ToString (); }