diff --git a/src/Build.UnitTests/BinaryLogger_Tests.cs b/src/Build.UnitTests/BinaryLogger_Tests.cs index 57e2bc3fa82..5d0753df46e 100644 --- a/src/Build.UnitTests/BinaryLogger_Tests.cs +++ b/src/Build.UnitTests/BinaryLogger_Tests.cs @@ -188,8 +188,13 @@ public void UnusedEnvironmentVariablesDoNotAppearInBinaryLog() } } - [Fact] - public void AssemblyLoadsDuringTaskRunLogged() + [WindowsFullFrameworkOnlyFact(additionalMessage: "Tests if the AppDomain used to load the task is included in the log text for the event, which is true only on Framework.")] + public void AssemblyLoadsDuringTaskRunLoggedWithAppDomain() => AssemblyLoadsDuringTaskRun("AppDomain: [Default]"); + + [DotNetOnlyFact(additionalMessage: "Tests if the AssemblyLoadContext used to load the task is included in the log text for the event, which is true only on Core.")] + public void AssemblyLoadsDuringTaskRunLoggedWithAssemblyLoadContext() => AssemblyLoadsDuringTaskRun("AssemblyLoadContext: Default"); + + private void AssemblyLoadsDuringTaskRun(string additionalEventText) { using (TestEnvironment env = TestEnvironment.Create()) { @@ -201,7 +206,7 @@ public void AssemblyLoadsDuringTaskRunLogged() TaskFactory="RoslynCodeTaskFactory" AssemblyFile="$(MSBuildToolsPath)\Microsoft.Build.Tasks.Core.dll" > - + @@ -235,17 +240,20 @@ public void AssemblyLoadsDuringTaskRunLogged() "Assembly loaded during TaskRun (InlineCode.HelloWorld): System.Diagnostics.Debug"; string text = File.ReadAllText(Path.Combine(logFolder.Path, "logFile.log")); text.ShouldContain(assemblyLoadedEventText); + text.ShouldContain(additionalEventText); // events should not be in logger with verbosity normal string text2 = File.ReadAllText(Path.Combine(logFolder.Path, "logFile2.log")); text2.ShouldNotContain(assemblyLoadedEventText); - + text2.ShouldNotContain(additionalEventText); RunnerUtilities.ExecMSBuild($"{logger.Parameters} -flp1:logfile={Path.Combine(logFolder.Path, "logFile3.log")};verbosity=diagnostic -flp2:logfile={Path.Combine(logFolder.Path, "logFile4.log")};verbosity=normal", out success); success.ShouldBeTrue(); text = File.ReadAllText(Path.Combine(logFolder.Path, "logFile3.log")); text.ShouldContain(assemblyLoadedEventText); + text.ShouldContain(additionalEventText); // events should not be in logger with verbosity normal text2 = File.ReadAllText(Path.Combine(logFolder.Path, "logFile4.log")); text2.ShouldNotContain(assemblyLoadedEventText); + text2.ShouldNotContain(additionalEventText); } } diff --git a/src/Build/BackEnd/Components/RequestBuilder/AssemblyLoadsTracker.cs b/src/Build/BackEnd/Components/RequestBuilder/AssemblyLoadsTracker.cs index 7e03b6cfd3e..14150696614 100644 --- a/src/Build/BackEnd/Components/RequestBuilder/AssemblyLoadsTracker.cs +++ b/src/Build/BackEnd/Components/RequestBuilder/AssemblyLoadsTracker.cs @@ -7,6 +7,9 @@ using System.Linq; #endif using System.Reflection; +#if FEATURE_ASSEMBLYLOADCONTEXT +using System.Runtime.Loader; +#endif using Microsoft.Build.BackEnd.Logging; using Microsoft.Build.Framework; @@ -152,10 +155,15 @@ private void CurrentDomainOnAssemblyLoad(object? sender, AssemblyLoadEventArgs a string? assemblyName = args.LoadedAssembly.FullName; string assemblyPath = args.LoadedAssembly.IsDynamic ? string.Empty : args.LoadedAssembly.Location; Guid mvid = args.LoadedAssembly.ManifestModule.ModuleVersionId; +#if FEATURE_ASSEMBLYLOADCONTEXT + // AssemblyLoadContext.GetLoadContext returns null when the assembly isn't a RuntimeAssembly, which should not be the case here. + // Name would only be null if the AssemblyLoadContext didn't supply a name, but MSBuildLoadContext does. + string appDomainDescriptor = AssemblyLoadContext.GetLoadContext(args.LoadedAssembly)?.Name ?? "Unknown"; +#else string? appDomainDescriptor = _appDomain.IsDefaultAppDomain() ? null : $"{_appDomain.Id}|{_appDomain.FriendlyName}"; - +#endif AssemblyLoadBuildEventArgs buildArgs = new(_context, _initiator, assemblyName, assemblyPath, mvid, appDomainDescriptor); diff --git a/src/Build/Resources/Strings.resx b/src/Build/Resources/Strings.resx index 0707bc3bbb4..3e949a272e4 100644 --- a/src/Build/Resources/Strings.resx +++ b/src/Build/Resources/Strings.resx @@ -1987,6 +1987,9 @@ Utilization: {0} Average Utilization: {1:###.0} Assembly loaded during {0}{1}: {2} (location: {3}, MVID: {4}, AppDomain: {5}) + + Assembly loaded during {0}{1}: {2} (location: {3}, MVID: {4}, AssemblyLoadContext: {5}) + Reusing node {0} (PID: {1}). diff --git a/src/Build/Resources/xlf/Strings.cs.xlf b/src/Build/Resources/xlf/Strings.cs.xlf index e47a6be2f0e..0e0182a129c 100644 --- a/src/Build/Resources/xlf/Strings.cs.xlf +++ b/src/Build/Resources/xlf/Strings.cs.xlf @@ -451,6 +451,11 @@ Sestavení načtené během {0}{1}: {2} (umístění: {3}, MVID: {4}, AppDomain: {5}) + + Assembly loaded during {0}{1}: {2} (location: {3}, MVID: {4}, AssemblyLoadContext: {5}) + Assembly loaded during {0}{1}: {2} (location: {3}, MVID: {4}, AssemblyLoadContext: {5}) + + Task "{0}" released {1} cores and now holds {2} cores total. Úloha {0} uvolnila tento počet jader: {1}. Teď používá celkem tento počet jader: {2} diff --git a/src/Build/Resources/xlf/Strings.de.xlf b/src/Build/Resources/xlf/Strings.de.xlf index afc7548add2..6d1b74b7103 100644 --- a/src/Build/Resources/xlf/Strings.de.xlf +++ b/src/Build/Resources/xlf/Strings.de.xlf @@ -451,6 +451,11 @@ Assembly während {0}{1} geladen: {2} (Speicherort: {3}, MVID: {4}, AppDomain: {5}) + + Assembly loaded during {0}{1}: {2} (location: {3}, MVID: {4}, AssemblyLoadContext: {5}) + Assembly loaded during {0}{1}: {2} (location: {3}, MVID: {4}, AssemblyLoadContext: {5}) + + Task "{0}" released {1} cores and now holds {2} cores total. Die Aufgabe "{0}" hat {1} Kerne freigegeben und belegt jetzt insgesamt {2} Kerne. diff --git a/src/Build/Resources/xlf/Strings.es.xlf b/src/Build/Resources/xlf/Strings.es.xlf index b239a2147f8..671bdf72929 100644 --- a/src/Build/Resources/xlf/Strings.es.xlf +++ b/src/Build/Resources/xlf/Strings.es.xlf @@ -451,6 +451,11 @@ Ensamblado cargado durante {0}{1}: {2} (ubicación: {3}, MVID: {4}, AppDomain: {5}) + + Assembly loaded during {0}{1}: {2} (location: {3}, MVID: {4}, AssemblyLoadContext: {5}) + Assembly loaded during {0}{1}: {2} (location: {3}, MVID: {4}, AssemblyLoadContext: {5}) + + Task "{0}" released {1} cores and now holds {2} cores total. La tarea "{0}" liberó {1} núcleos y ahora retiene un total de {2} núcleos. diff --git a/src/Build/Resources/xlf/Strings.fr.xlf b/src/Build/Resources/xlf/Strings.fr.xlf index 1a7b7f44d73..dadd8a30c3a 100644 --- a/src/Build/Resources/xlf/Strings.fr.xlf +++ b/src/Build/Resources/xlf/Strings.fr.xlf @@ -451,6 +451,11 @@ Assembly chargé pendant {0}{1}: {2} (emplacement : {3}, MVID : {4}, AppDomain : {5}) + + Assembly loaded during {0}{1}: {2} (location: {3}, MVID: {4}, AssemblyLoadContext: {5}) + Assembly loaded during {0}{1}: {2} (location: {3}, MVID: {4}, AssemblyLoadContext: {5}) + + Task "{0}" released {1} cores and now holds {2} cores total. La tâche "{0}" a libéré {1} cœur. Elle détient désormais {2} cœurs au total. diff --git a/src/Build/Resources/xlf/Strings.it.xlf b/src/Build/Resources/xlf/Strings.it.xlf index 2b84a74df2e..2055daa2c3d 100644 --- a/src/Build/Resources/xlf/Strings.it.xlf +++ b/src/Build/Resources/xlf/Strings.it.xlf @@ -451,6 +451,11 @@ Assembly caricato durante {0}{1}: {2} (percorso: {3}, MVID: {4}, AppDomain: {5}) + + Assembly loaded during {0}{1}: {2} (location: {3}, MVID: {4}, AssemblyLoadContext: {5}) + Assembly loaded during {0}{1}: {2} (location: {3}, MVID: {4}, AssemblyLoadContext: {5}) + + Task "{0}" released {1} cores and now holds {2} cores total. L'attività "{0}" ha rilasciato {1} core e ora contiene {2} core in totale. diff --git a/src/Build/Resources/xlf/Strings.ja.xlf b/src/Build/Resources/xlf/Strings.ja.xlf index b542f06c26c..be831821dd6 100644 --- a/src/Build/Resources/xlf/Strings.ja.xlf +++ b/src/Build/Resources/xlf/Strings.ja.xlf @@ -451,6 +451,11 @@ {0}{1} 中にアセンブリが読み込まれました: {2} (場所: {3}、MVID: {4}、AppDomain: {5}) + + Assembly loaded during {0}{1}: {2} (location: {3}, MVID: {4}, AssemblyLoadContext: {5}) + Assembly loaded during {0}{1}: {2} (location: {3}, MVID: {4}, AssemblyLoadContext: {5}) + + Task "{0}" released {1} cores and now holds {2} cores total. タスク "{0}" では、{1} 個のコアを解放したため、現在合計 {2} 個のコアを保持しています。 diff --git a/src/Build/Resources/xlf/Strings.ko.xlf b/src/Build/Resources/xlf/Strings.ko.xlf index cc93c3d1c32..3cd4e210794 100644 --- a/src/Build/Resources/xlf/Strings.ko.xlf +++ b/src/Build/Resources/xlf/Strings.ko.xlf @@ -451,6 +451,11 @@ {0}{1} 동안 로드된 어셈블리: {2}(위치: {3}%1, MVID: {4}%2, AppDomain: {5}%2). + + Assembly loaded during {0}{1}: {2} (location: {3}, MVID: {4}, AssemblyLoadContext: {5}) + Assembly loaded during {0}{1}: {2} (location: {3}, MVID: {4}, AssemblyLoadContext: {5}) + + Task "{0}" released {1} cores and now holds {2} cores total. "{0}" 작업에서 코어 {1}개를 해제했고 지금 총 {2}개의 코어를 보유하고 있습니다. diff --git a/src/Build/Resources/xlf/Strings.pl.xlf b/src/Build/Resources/xlf/Strings.pl.xlf index c41c1a12d2b..a22f0dfc28c 100644 --- a/src/Build/Resources/xlf/Strings.pl.xlf +++ b/src/Build/Resources/xlf/Strings.pl.xlf @@ -451,6 +451,11 @@ Załadowano zestaw podczas {0}{1}: {2} (lokalizacja: {3}, MVID: {4}, domena aplikacji: {5}) + + Assembly loaded during {0}{1}: {2} (location: {3}, MVID: {4}, AssemblyLoadContext: {5}) + Assembly loaded during {0}{1}: {2} (location: {3}, MVID: {4}, AssemblyLoadContext: {5}) + + Task "{0}" released {1} cores and now holds {2} cores total. Zadanie „{0}” zwolniło rdzenie ({1}) i teraz jego łączna liczba rdzeni to {2}. diff --git a/src/Build/Resources/xlf/Strings.pt-BR.xlf b/src/Build/Resources/xlf/Strings.pt-BR.xlf index 56b0d6b36f5..cdc4b13c11f 100644 --- a/src/Build/Resources/xlf/Strings.pt-BR.xlf +++ b/src/Build/Resources/xlf/Strings.pt-BR.xlf @@ -451,6 +451,11 @@ Montagem carregada durante {0}{1}: {2} (localização: {3}, MVID: {4}, AppDomain: {5}) + + Assembly loaded during {0}{1}: {2} (location: {3}, MVID: {4}, AssemblyLoadContext: {5}) + Assembly loaded during {0}{1}: {2} (location: {3}, MVID: {4}, AssemblyLoadContext: {5}) + + Task "{0}" released {1} cores and now holds {2} cores total. A tarefa "{0}" liberou {1} núcleos e agora contém {2} núcleos no total. diff --git a/src/Build/Resources/xlf/Strings.ru.xlf b/src/Build/Resources/xlf/Strings.ru.xlf index 07817ef4752..3e7014a5cf7 100644 --- a/src/Build/Resources/xlf/Strings.ru.xlf +++ b/src/Build/Resources/xlf/Strings.ru.xlf @@ -451,6 +451,11 @@ Сборка загружена во время {0}{1}: {2} (расположение: {3}, MVID: {4}, домен приложения: {5}) + + Assembly loaded during {0}{1}: {2} (location: {3}, MVID: {4}, AssemblyLoadContext: {5}) + Assembly loaded during {0}{1}: {2} (location: {3}, MVID: {4}, AssemblyLoadContext: {5}) + + Task "{0}" released {1} cores and now holds {2} cores total. Задача "{0}" освободила указанное число ядер ({1}). Теперь общее число ядер, которыми располагает задача, равно {2}. diff --git a/src/Build/Resources/xlf/Strings.tr.xlf b/src/Build/Resources/xlf/Strings.tr.xlf index 19239812ab3..303b551c45e 100644 --- a/src/Build/Resources/xlf/Strings.tr.xlf +++ b/src/Build/Resources/xlf/Strings.tr.xlf @@ -451,6 +451,11 @@ Derleme {0}{1} sırasında yüklendi: {2} (konum: {3}, MVID: {4}, AppDomain: {5}) + + Assembly loaded during {0}{1}: {2} (location: {3}, MVID: {4}, AssemblyLoadContext: {5}) + Assembly loaded during {0}{1}: {2} (location: {3}, MVID: {4}, AssemblyLoadContext: {5}) + + Task "{0}" released {1} cores and now holds {2} cores total. "{0}" görevi {1} çekirdeği serbest bıraktı. Şu anda toplam {2} çekirdek tutuyor. diff --git a/src/Build/Resources/xlf/Strings.zh-Hans.xlf b/src/Build/Resources/xlf/Strings.zh-Hans.xlf index 757c28ce80f..6ce5022b17c 100644 --- a/src/Build/Resources/xlf/Strings.zh-Hans.xlf +++ b/src/Build/Resources/xlf/Strings.zh-Hans.xlf @@ -451,6 +451,11 @@ 程序集加载期间 {0}{1}: {2} (位置: {3}, MVID: {4}, AppDomain: {5}) + + Assembly loaded during {0}{1}: {2} (location: {3}, MVID: {4}, AssemblyLoadContext: {5}) + Assembly loaded during {0}{1}: {2} (location: {3}, MVID: {4}, AssemblyLoadContext: {5}) + + Task "{0}" released {1} cores and now holds {2} cores total. 任务“{0}”发布了 {1} 个核心,现总共包含 {2} 个核心。 diff --git a/src/Build/Resources/xlf/Strings.zh-Hant.xlf b/src/Build/Resources/xlf/Strings.zh-Hant.xlf index b2bdd01d43e..5111576884b 100644 --- a/src/Build/Resources/xlf/Strings.zh-Hant.xlf +++ b/src/Build/Resources/xlf/Strings.zh-Hant.xlf @@ -451,6 +451,11 @@ 組件在 {0}{1} 期間載入: {2} (位置: {3},MVID: {4},AppDomain: {5}) + + Assembly loaded during {0}{1}: {2} (location: {3}, MVID: {4}, AssemblyLoadContext: {5}) + Assembly loaded during {0}{1}: {2} (location: {3}, MVID: {4}, AssemblyLoadContext: {5}) + + Task "{0}" released {1} cores and now holds {2} cores total. 工作 "{0}" 已發行 {1} 個核心,現在共保留 {2} 個核心。 diff --git a/src/Framework/AssemblyLoadBuildEventArgs.cs b/src/Framework/AssemblyLoadBuildEventArgs.cs index 49f827b19c9..767772f5fc8 100644 --- a/src/Framework/AssemblyLoadBuildEventArgs.cs +++ b/src/Framework/AssemblyLoadBuildEventArgs.cs @@ -39,7 +39,8 @@ public AssemblyLoadBuildEventArgs( public string? AssemblyName { get; private set; } public string? AssemblyPath { get; private set; } public Guid MVID { get; private set; } - // Null string indicates that load occurred on Default AppDomain (for both Core and Framework). + // Null string indicates that load occurred on Default AppDomain (for Framework). + // For Core, string won't be null. public string? AppDomainDescriptor { get; private set; } internal override void WriteToStream(BinaryWriter writer) @@ -77,7 +78,12 @@ public override string Message if (RawMessage == null) { string? loadingInitiator = LoadingInitiator == null ? null : $" ({LoadingInitiator})"; - RawMessage = FormatResourceStringIgnoreCodeAndKeyword("TaskAssemblyLoaded", LoadingContext.ToString(), loadingInitiator, AssemblyName, AssemblyPath, MVID.ToString(), AppDomainDescriptor ?? DefaultAppDomainDescriptor); +#if FEATURE_ASSEMBLYLOADCONTEXT + string resourceName = "TaskAssemblyLoadedWithAssemblyLoadContext"; +#else + string resourceName = "TaskAssemblyLoaded"; +#endif + RawMessage = FormatResourceStringIgnoreCodeAndKeyword(resourceName, LoadingContext.ToString(), loadingInitiator, AssemblyName, AssemblyPath, MVID.ToString(), AppDomainDescriptor ?? DefaultAppDomainDescriptor); } return RawMessage; diff --git a/src/Shared/UnitTests/TypeLoader_Dependencies_Tests.cs b/src/Shared/UnitTests/TypeLoader_Dependencies_Tests.cs index d1387eeb0b4..191642f2806 100644 --- a/src/Shared/UnitTests/TypeLoader_Dependencies_Tests.cs +++ b/src/Shared/UnitTests/TypeLoader_Dependencies_Tests.cs @@ -33,6 +33,7 @@ public void LoadAssemblyAndDependency_InsideProjectFolder() string dllPath = Path.Combine(dir.Path, TaskDllFileName); CheckIfCorrectAssemblyLoaded(output, dllPath); + CheckIfCorrectAssemblyLoadedMessageLogged(output); } } @@ -51,6 +52,7 @@ public void LoadAssemblyAndDependency_OutsideProjectFolder() successfulExit.ShouldBeTrue(output); CheckIfCorrectAssemblyLoaded(output, newTaskDllPath); + CheckIfCorrectAssemblyLoadedMessageLogged(output); } } @@ -107,5 +109,19 @@ private void CheckIfCorrectAssemblyLoaded(string scriptOutput, string expectedAs scriptOutput.ShouldNotContain(successfulMessage, Case.Insensitive); } } + + private void CheckIfCorrectAssemblyLoadedMessageLogged(string scriptOutput) + { + var assemblyLoadedTaskRun = "Assembly loaded during TaskRun"; + +#if FEATURE_ASSEMBLYLOADCONTEXT + var message = "AssemblyLoadContext: MSBuild plugin"; +#else + var message = "AppDomain: [Default]"; +#endif + + scriptOutput.ShouldContain(assemblyLoadedTaskRun); + scriptOutput.ShouldContain(message); + } } }