From 8e0867cd54ace49da5249312e9f14c956acc696f Mon Sep 17 00:00:00 2001 From: Eric Erhardt Date: Thu, 22 Sep 2022 19:00:08 -0500 Subject: [PATCH 01/10] Fix DiagnosticSource to work with NativeAOT There were 2 problems: 1. The use of MakeGenericType doesn't work when a property is a ValueType. An app will crash when a listener is enabled and DiagnosticSourceEventSource tries writing values. 2. The properties on KeyValuePair were not being preserved correctly, so the Arguments of the DiagnosticSourceEventSource methods were not being serialized correctly. Add test (and infrastructure) to ensure DiagnosticSource works in a NativeAOT app Fix #75945 --- .../linker/SupportFiles/Directory.Build.props | 1 - eng/testing/linker/project.csproj.template | 7 + eng/testing/linker/trimmingTests.targets | 5 + src/libraries/Directory.Build.props | 10 +- src/libraries/Directory.Build.targets | 2 +- .../src/HostBuilder.cs | 2 - .../System.Diagnostics.DiagnosticSource.cs | 2 - ...em.Diagnostics.DiagnosticSourceActivity.cs | 2 - ...System.Diagnostics.DiagnosticSource.csproj | 2 + .../System/Diagnostics/DiagnosticListener.cs | 3 - .../System/Diagnostics/DiagnosticSource.cs | 2 - .../Diagnostics/DiagnosticSourceActivity.cs | 2 - .../DiagnosticSourceEventSource.cs | 167 ++++++++++++++---- .../HttpHandlerDiagnosticListener.cs | 5 - .../DiagnosticSourceEventSourceTests.cs | 109 ++++++++++++ ...stics.DiagnosticSource.NativeAotTests.proj | 9 + 16 files changed, 270 insertions(+), 60 deletions(-) create mode 100644 src/libraries/System.Diagnostics.DiagnosticSource/tests/NativeAotTests/DiagnosticSourceEventSourceTests.cs create mode 100644 src/libraries/System.Diagnostics.DiagnosticSource/tests/NativeAotTests/System.Diagnostics.DiagnosticSource.NativeAotTests.proj diff --git a/eng/testing/linker/SupportFiles/Directory.Build.props b/eng/testing/linker/SupportFiles/Directory.Build.props index da3533e49c939f..1e08117fd3171c 100644 --- a/eng/testing/linker/SupportFiles/Directory.Build.props +++ b/eng/testing/linker/SupportFiles/Directory.Build.props @@ -2,7 +2,6 @@ true true - true full false true diff --git a/eng/testing/linker/project.csproj.template b/eng/testing/linker/project.csproj.template index 80180798fd30e8..b628bbf261e7aa 100644 --- a/eng/testing/linker/project.csproj.template +++ b/eng/testing/linker/project.csproj.template @@ -6,6 +6,7 @@ {NetCoreAppMaximumVersion} {UseMonoRuntime} {RuntimeIdentifier} + {PublishAot} {MonoAOTCompilerDir} @@ -25,6 +26,12 @@ {RepositoryEngineeringDir} <_ExtraTrimmerArgs>{ExtraTrimmerArgs} $(_ExtraTrimmerArgs) + + + {IlcToolsPath} + {IlcBuildTasksPath} + {IlcSdkPath} + {IlcFrameworkPath} diff --git a/eng/testing/linker/trimmingTests.targets b/eng/testing/linker/trimmingTests.targets index ac688f61b6b2d7..da548605023e9a 100644 --- a/eng/testing/linker/trimmingTests.targets +++ b/eng/testing/linker/trimmingTests.targets @@ -85,8 +85,13 @@ .Replace('{NetCoreAppMaximumVersion}', '$(NetCoreAppMaximumVersion)') .Replace('{UseMonoRuntime}','$(UseMonoRuntime)') .Replace('{RuntimeIdentifier}','%(TestConsoleApps.TestRuntimeIdentifier)') + .Replace('{PublishAot}','$(IsNativeAotTestProject)') .Replace('{MicrosoftNETILLinkTasksVersion}', '$(MicrosoftNETILLinkTasksVersion)') .Replace('{ExtraTrimmerArgs}', '%(TestConsoleApps.ExtraTrimmerArgs)') + .Replace('{IlcToolsPath}', '$(CoreCLRILCompilerDir)') + .Replace('{IlcBuildTasksPath}', '$(CoreCLRILCompilerDir)netstandard/ILCompiler.Build.Tasks.dll') + .Replace('{IlcSdkPath}', '$(CoreCLRAotSdkDir)') + .Replace('{IlcFrameworkPath}', '$(MicrosoftNetCoreAppRuntimePackRidLibTfmDir)') .Replace('{RuntimeHostConfigurationOptions}', '$(_runtimeHostConfigurationOptionsString)') .Replace('{AdditionalProjectReferences}', '$(_additionalProjectReferencesString)') .Replace('{RepositoryEngineeringDir}', '$(RepositoryEngineeringDir)') diff --git a/src/libraries/Directory.Build.props b/src/libraries/Directory.Build.props index 2b1c22a5cf4ba0..2a5efe383b46c4 100644 --- a/src/libraries/Directory.Build.props +++ b/src/libraries/Directory.Build.props @@ -22,10 +22,12 @@ true true - true + true + true + true - false + false @@ -36,14 +38,14 @@ '$(IsReferenceAssemblyProject)' != 'true' and '$(IsGeneratorProject)' != 'true' and '$(IsTestProject)' != 'true' and - '$(IsTrimmingTestProject)' != 'true' and + '$(IsPublishedAppTestProject)' != 'true' and '$(IsTestSupportProject)' != 'true' and '$(UsingMicrosoftNoTargetsSdk)' != 'true' and '$(UsingMicrosoftTraversalSdk)' != 'true'">true - + $(NoWarn);SYSLIB0011 diff --git a/src/libraries/Directory.Build.targets b/src/libraries/Directory.Build.targets index 8f9b52adb2805d..46cc84f810c209 100644 --- a/src/libraries/Directory.Build.targets +++ b/src/libraries/Directory.Build.targets @@ -127,7 +127,7 @@ - + diff --git a/src/libraries/Microsoft.Extensions.Hosting/src/HostBuilder.cs b/src/libraries/Microsoft.Extensions.Hosting/src/HostBuilder.cs index a285d3e487ef7f..9c864e489ab139 100644 --- a/src/libraries/Microsoft.Extensions.Hosting/src/HostBuilder.cs +++ b/src/libraries/Microsoft.Extensions.Hosting/src/HostBuilder.cs @@ -188,8 +188,6 @@ internal static DiagnosticListener LogHostBuilding(HostApplicationBuilder hostAp return diagnosticListener; } - [UnconditionalSuppressMessage("AOT", "IL3050:RequiresDynamicCode", - Justification = "DiagnosticSource is used here to pass objects in-memory to code using HostFactoryResolver. This won't require creating new generic types.")] [UnconditionalSuppressMessage("ReflectionAnalysis", "IL2026:UnrecognizedReflectionPattern", Justification = "The values being passed into Write are being consumed by the application already.")] private static void Write( diff --git a/src/libraries/System.Diagnostics.DiagnosticSource/ref/System.Diagnostics.DiagnosticSource.cs b/src/libraries/System.Diagnostics.DiagnosticSource/ref/System.Diagnostics.DiagnosticSource.cs index 75b85af1913d47..1b08291cccd2ab 100644 --- a/src/libraries/System.Diagnostics.DiagnosticSource/ref/System.Diagnostics.DiagnosticSource.cs +++ b/src/libraries/System.Diagnostics.DiagnosticSource/ref/System.Diagnostics.DiagnosticSource.cs @@ -20,7 +20,6 @@ public virtual void Dispose() { } public virtual System.IDisposable Subscribe(System.IObserver> observer, System.Predicate? isEnabled) { throw null; } public override string ToString() { throw null; } [System.Diagnostics.CodeAnalysis.RequiresUnreferencedCode("The type of object being written to DiagnosticSource cannot be discovered statically.")] - [System.Diagnostics.CodeAnalysis.RequiresDynamicCode("DiagnosticSource may require creating new generic types or methods, which requires creating code at runtime. This may not work when AOT compiling.")] public override void Write(string name, object? value) { } } public abstract partial class DiagnosticSource @@ -29,7 +28,6 @@ protected DiagnosticSource() { } public abstract bool IsEnabled(string name); public virtual bool IsEnabled(string name, object? arg1, object? arg2 = null) { throw null; } [System.Diagnostics.CodeAnalysis.RequiresUnreferencedCode("The type of object being written to DiagnosticSource cannot be discovered statically.")] - [System.Diagnostics.CodeAnalysis.RequiresDynamicCode("DiagnosticSource may require creating new generic types or methods, which requires creating code at runtime. This may not work when AOT compiling.")] public abstract void Write(string name, object? value); } } diff --git a/src/libraries/System.Diagnostics.DiagnosticSource/ref/System.Diagnostics.DiagnosticSourceActivity.cs b/src/libraries/System.Diagnostics.DiagnosticSource/ref/System.Diagnostics.DiagnosticSourceActivity.cs index 5177cb52339eca..488e6c39224fe0 100644 --- a/src/libraries/System.Diagnostics.DiagnosticSource/ref/System.Diagnostics.DiagnosticSourceActivity.cs +++ b/src/libraries/System.Diagnostics.DiagnosticSource/ref/System.Diagnostics.DiagnosticSourceActivity.cs @@ -197,10 +197,8 @@ public abstract partial class DiagnosticSource public virtual void OnActivityExport(System.Diagnostics.Activity activity, object? payload) { } public virtual void OnActivityImport(System.Diagnostics.Activity activity, object? payload) { } [System.Diagnostics.CodeAnalysis.RequiresUnreferencedCode("The type of object being written to DiagnosticSource cannot be discovered statically.")] - [System.Diagnostics.CodeAnalysis.RequiresDynamicCode("DiagnosticSource may require creating new generic types or methods, which requires creating code at runtime. This may not work when AOT compiling.")] public System.Diagnostics.Activity StartActivity(System.Diagnostics.Activity activity, object? args) { throw null; } [System.Diagnostics.CodeAnalysis.RequiresUnreferencedCode("The type of object being written to DiagnosticSource cannot be discovered statically.")] - [System.Diagnostics.CodeAnalysis.RequiresDynamicCode("DiagnosticSource may require creating new generic types or methods, which requires creating code at runtime. This may not work when AOT compiling.")] public void StopActivity(System.Diagnostics.Activity activity, object? args) { } } public enum ActivitySamplingResult diff --git a/src/libraries/System.Diagnostics.DiagnosticSource/src/System.Diagnostics.DiagnosticSource.csproj b/src/libraries/System.Diagnostics.DiagnosticSource/src/System.Diagnostics.DiagnosticSource.csproj index 6d40be2f856b75..4c20a73469985b 100644 --- a/src/libraries/System.Diagnostics.DiagnosticSource/src/System.Diagnostics.DiagnosticSource.csproj +++ b/src/libraries/System.Diagnostics.DiagnosticSource/src/System.Diagnostics.DiagnosticSource.csproj @@ -85,6 +85,8 @@ System.Diagnostics.DiagnosticSource + diff --git a/src/libraries/System.Diagnostics.DiagnosticSource/src/System/Diagnostics/DiagnosticListener.cs b/src/libraries/System.Diagnostics.DiagnosticSource/src/System/Diagnostics/DiagnosticListener.cs index 75a7116c58fc16..c1677307acb5e0 100644 --- a/src/libraries/System.Diagnostics.DiagnosticSource/src/System/Diagnostics/DiagnosticListener.cs +++ b/src/libraries/System.Diagnostics.DiagnosticSource/src/System/Diagnostics/DiagnosticListener.cs @@ -34,8 +34,6 @@ public partial class DiagnosticListener : DiagnosticSource, IObservable public static IObservable AllListeners { - [UnconditionalSuppressMessage("AotAnalysis", "IL3050:RequiresDynamicCode", - Justification = "ENABLE_HTTP_HANDLER is not enabled in the .NET current version")] get { #if ENABLE_HTTP_HANDLER @@ -255,7 +253,6 @@ public override bool IsEnabled(string name, object? arg1, object? arg2 = null) /// Override abstract method /// [RequiresUnreferencedCode(WriteRequiresUnreferencedCode)] - [RequiresDynamicCode(WriteRequiresDynamicCode)] public override void Write(string name, object? value) { for (DiagnosticSubscription? curSubscription = _subscriptions; curSubscription != null; curSubscription = curSubscription.Next) diff --git a/src/libraries/System.Diagnostics.DiagnosticSource/src/System/Diagnostics/DiagnosticSource.cs b/src/libraries/System.Diagnostics.DiagnosticSource/src/System/Diagnostics/DiagnosticSource.cs index 47fad270bab4b4..89e62d4102c988 100644 --- a/src/libraries/System.Diagnostics.DiagnosticSource/src/System/Diagnostics/DiagnosticSource.cs +++ b/src/libraries/System.Diagnostics.DiagnosticSource/src/System/Diagnostics/DiagnosticSource.cs @@ -17,7 +17,6 @@ namespace System.Diagnostics public abstract partial class DiagnosticSource { internal const string WriteRequiresUnreferencedCode = "The type of object being written to DiagnosticSource cannot be discovered statically."; - internal const string WriteRequiresDynamicCode = "DiagnosticSource may require creating new generic types or methods, which requires creating code at runtime. This may not work when AOT compiling."; /// /// Write is a generic way of logging complex payloads. Each notification @@ -36,7 +35,6 @@ public abstract partial class DiagnosticSource /// An object that represent the value being passed as a payload for the event. /// This is often an anonymous type which contains several sub-values. [RequiresUnreferencedCode(WriteRequiresUnreferencedCode)] - [RequiresDynamicCode(WriteRequiresDynamicCode)] public abstract void Write(string name, object? value); /// diff --git a/src/libraries/System.Diagnostics.DiagnosticSource/src/System/Diagnostics/DiagnosticSourceActivity.cs b/src/libraries/System.Diagnostics.DiagnosticSource/src/System/Diagnostics/DiagnosticSourceActivity.cs index 1156ed5fe3ee62..5bf9fa66916692 100644 --- a/src/libraries/System.Diagnostics.DiagnosticSource/src/System/Diagnostics/DiagnosticSourceActivity.cs +++ b/src/libraries/System.Diagnostics.DiagnosticSource/src/System/Diagnostics/DiagnosticSourceActivity.cs @@ -26,7 +26,6 @@ public abstract partial class DiagnosticSource /// Started Activity for convenient chaining /// [RequiresUnreferencedCode(WriteRequiresUnreferencedCode)] - [RequiresDynamicCode(WriteRequiresDynamicCode)] public Activity StartActivity(Activity activity, object? args) { activity.Start(); @@ -45,7 +44,6 @@ public Activity StartActivity(Activity activity, object? args) /// An object that represent the value being passed as a payload for the event. /// [RequiresUnreferencedCode(WriteRequiresUnreferencedCode)] - [RequiresDynamicCode(WriteRequiresDynamicCode)] public void StopActivity(Activity activity, object? args) { // Stop sets the end time if it was unset, but we want it set before we issue the write diff --git a/src/libraries/System.Diagnostics.DiagnosticSource/src/System/Diagnostics/DiagnosticSourceEventSource.cs b/src/libraries/System.Diagnostics.DiagnosticSource/src/System/Diagnostics/DiagnosticSourceEventSource.cs index decd70bd442513..159050c2e966e8 100644 --- a/src/libraries/System.Diagnostics.DiagnosticSource/src/System/Diagnostics/DiagnosticSourceEventSource.cs +++ b/src/libraries/System.Diagnostics.DiagnosticSource/src/System/Diagnostics/DiagnosticSourceEventSource.cs @@ -1,5 +1,6 @@ // Licensed to the .NET Foundation under one or more agreements. // The .NET Foundation licenses this file to you under the MIT license. +using System.Collections; using System.Collections.Concurrent; using System.Collections.Generic; using System.Diagnostics.CodeAnalysis; @@ -234,7 +235,8 @@ public void Message(string? Message) /// Events from DiagnosticSource can be forwarded to EventSource using this event. /// [UnconditionalSuppressMessage("ReflectionAnalysis", "IL2026:RequiresUnreferencedCode", - Justification = "Arguments parameter is trimmer safe")] + Justification = "Arguments parameter is preserved by DynamicDependency")] + [DynamicDependency(DynamicallyAccessedMemberTypes.PublicProperties, typeof(KeyValuePair<,>))] [Event(2, Keywords = Keywords.Events)] private void Event(string SourceName, string EventName, IEnumerable>? Arguments) { @@ -255,7 +257,8 @@ private void EventJson(string SourceName, string EventName, string ArgmentsJson) /// Used to mark the beginning of an activity /// [UnconditionalSuppressMessage("ReflectionAnalysis", "IL2026:RequiresUnreferencedCode", - Justification = "Arguments parameter is trimmer safe")] + Justification = "Arguments parameter is preserved by DynamicDependency")] + [DynamicDependency(DynamicallyAccessedMemberTypes.PublicProperties, typeof(KeyValuePair<,>))] [Event(4, Keywords = Keywords.Events)] private void Activity1Start(string SourceName, string EventName, IEnumerable> Arguments) { @@ -266,7 +269,8 @@ private void Activity1Start(string SourceName, string EventName, IEnumerable [UnconditionalSuppressMessage("ReflectionAnalysis", "IL2026:RequiresUnreferencedCode", - Justification = "Arguments parameter is trimmer safe")] + Justification = "Arguments parameter is preserved by DynamicDependency")] + [DynamicDependency(DynamicallyAccessedMemberTypes.PublicProperties, typeof(KeyValuePair<,>))] [Event(5, Keywords = Keywords.Events)] private void Activity1Stop(string SourceName, string EventName, IEnumerable> Arguments) { @@ -277,7 +281,8 @@ private void Activity1Stop(string SourceName, string EventName, IEnumerable [UnconditionalSuppressMessage("ReflectionAnalysis", "IL2026:RequiresUnreferencedCode", - Justification = "Arguments parameter is trimmer safe")] + Justification = "Arguments parameter is preserved by DynamicDependency")] + [DynamicDependency(DynamicallyAccessedMemberTypes.PublicProperties, typeof(KeyValuePair<,>))] [Event(6, Keywords = Keywords.Events)] private void Activity2Start(string SourceName, string EventName, IEnumerable> Arguments) { @@ -288,7 +293,8 @@ private void Activity2Start(string SourceName, string EventName, IEnumerable [UnconditionalSuppressMessage("ReflectionAnalysis", "IL2026:RequiresUnreferencedCode", - Justification = "Arguments parameter is trimmer safe")] + Justification = "Arguments parameter is preserved by DynamicDependency")] + [DynamicDependency(DynamicallyAccessedMemberTypes.PublicProperties, typeof(KeyValuePair<,>))] [Event(7, Keywords = Keywords.Events)] private void Activity2Stop(string SourceName, string EventName, IEnumerable> Arguments) { @@ -299,7 +305,8 @@ private void Activity2Stop(string SourceName, string EventName, IEnumerable [UnconditionalSuppressMessage("ReflectionAnalysis", "IL2026:RequiresUnreferencedCode", - Justification = "Arguments parameter is trimmer safe")] + Justification = "Arguments parameter is preserved by DynamicDependency")] + [DynamicDependency(DynamicallyAccessedMemberTypes.PublicProperties, typeof(KeyValuePair<,>))] [Event(8, Keywords = Keywords.Events, ActivityOptions = EventActivityOptions.Recursive)] private void RecursiveActivity1Start(string SourceName, string EventName, IEnumerable> Arguments) { @@ -310,7 +317,8 @@ private void RecursiveActivity1Start(string SourceName, string EventName, IEnume /// Used to mark the end of an activity that can be recursive. /// [UnconditionalSuppressMessage("ReflectionAnalysis", "IL2026:RequiresUnreferencedCode", - Justification = "Arguments parameter is trimmer safe")] + Justification = "Arguments parameter is preserved by DynamicDependency")] + [DynamicDependency(DynamicallyAccessedMemberTypes.PublicProperties, typeof(KeyValuePair<,>))] [Event(9, Keywords = Keywords.Events, ActivityOptions = EventActivityOptions.Recursive)] private void RecursiveActivity1Stop(string SourceName, string EventName, IEnumerable> Arguments) { @@ -334,7 +342,8 @@ private void NewDiagnosticListener(string SourceName) /// The Activity name /// Name and value pairs of the Activity properties [UnconditionalSuppressMessage("ReflectionAnalysis", "IL2026:RequiresUnreferencedCode", - Justification = "Arguments parameter is trimmer safe")] + Justification = "Arguments parameter is preserved by DynamicDependency")] + [DynamicDependency(DynamicallyAccessedMemberTypes.PublicProperties, typeof(KeyValuePair<,>))] [Event(11, Keywords = Keywords.Events, ActivityOptions = EventActivityOptions.Recursive)] private void ActivityStart(string SourceName, string ActivityName, IEnumerable> Arguments) => WriteEvent(11, SourceName, ActivityName, Arguments); @@ -346,7 +355,8 @@ private void ActivityStart(string SourceName, string ActivityName, IEnumerableThe Activity name /// Name and value pairs of the Activity properties [UnconditionalSuppressMessage("ReflectionAnalysis", "IL2026:RequiresUnreferencedCode", - Justification = "Arguments parameter is trimmer safe")] + Justification = "Arguments parameter is preserved by DynamicDependency")] + [DynamicDependency(DynamicallyAccessedMemberTypes.PublicProperties, typeof(KeyValuePair<,>))] [Event(12, Keywords = Keywords.Events, ActivityOptions = EventActivityOptions.Recursive)] private void ActivityStop(string SourceName, string ActivityName, IEnumerable> Arguments) => WriteEvent(12, SourceName, ActivityName, Arguments); @@ -641,8 +651,6 @@ public FilterAndTransform(string filterAndPayloadSpec, int startIdx, int endIdx, [UnconditionalSuppressMessage("ReflectionAnalysis", "IL2119", Justification = "DAM on EventSource references this compiler-generated local function which calls a " + "method that requires unreferenced code. EventSource will not access this local function.")] - [UnconditionalSuppressMessage("AotAnalysis", "IL3050:RequiresDynamicCode", - Justification = "DiagnosticSource.Write is marked with RequiresDynamicCode.")] void OnEventWritten(KeyValuePair evnt) { // The filter given to the DiagnosticSource may not work if users don't is 'IsEnabled' as expected. @@ -890,8 +898,6 @@ internal static void CreateActivityListener(DiagnosticSourceEventSource eventSou [DynamicDependency(nameof(TimeSpan.Ticks), typeof(TimeSpan))] [UnconditionalSuppressMessage("ReflectionAnalysis", "IL2026:RequiresUnreferencedCode", Justification = "Activity's properties are being preserved with the DynamicDependencies on OnActivityStarted.")] - [UnconditionalSuppressMessage("AotAnalysis", "IL3050:RequiresDynamicCode", - Justification = "Activity is a reference type and is safe in aot.")] private static void OnActivityStarted(DiagnosticSourceEventSource eventSource, Activity activity) { FilterAndTransform? list = eventSource._activitySourceSpecs; @@ -911,8 +917,6 @@ private static void OnActivityStarted(DiagnosticSourceEventSource eventSource, A [UnconditionalSuppressMessage("ReflectionAnalysis", "IL2026:RequiresUnreferencedCode", Justification = "Activity's properties are being preserved with the DynamicDependencies on OnActivityStarted.")] - [UnconditionalSuppressMessage("AotAnalysis", "IL3050:RequiresDynamicCode", - Justification = "Activity is a reference type and is safe with aot.")] private static void OnActivityStopped(DiagnosticSourceEventSource eventSource, Activity activity) { FilterAndTransform? list = eventSource._activitySourceSpecs; @@ -1015,7 +1019,6 @@ private void Dispose() Justification = "In EventSource, EnsureDescriptorsInitialized's use of GetType preserves this method which " + "requires unreferenced code, but EnsureDescriptorsInitialized does not access this member and is safe to call.")] [RequiresUnreferencedCode(DiagnosticSource.WriteRequiresUnreferencedCode)] - [RequiresDynamicCode(DiagnosticSource.WriteRequiresDynamicCode)] public List> Morph(object? args) { // Transform the args into a bag of key-value strings. @@ -1197,7 +1200,6 @@ public TransformSpec(string transformSpec, int startIdx, int endIdx, TransformSp Justification = "In EventSource, EnsureDescriptorsInitialized's use of GetType preserves this method which " + "requires unreferenced code, but EnsureDescriptorsInitialized does not access this member and is safe to call.")] [RequiresUnreferencedCode(DiagnosticSource.WriteRequiresUnreferencedCode)] - [RequiresDynamicCode(DiagnosticSource.WriteRequiresDynamicCode)] public KeyValuePair Morph(object? obj) { for (PropertySpec? cur = _fetches; cur != null; cur = cur.Next) @@ -1252,7 +1254,6 @@ public PropertySpec(string propertyName, PropertySpec? next) Justification = "In EventSource, EnsureDescriptorsInitialized's use of GetType preserves this method which " + "requires unreferenced code, but EnsureDescriptorsInitialized does not access this member and is safe to call.")] [RequiresUnreferencedCode(DiagnosticSource.WriteRequiresUnreferencedCode)] - [RequiresDynamicCode(DiagnosticSource.WriteRequiresDynamicCode)] public object? Fetch(object? obj) { PropertyFetch? fetch = _fetchForExpectedType; @@ -1299,7 +1300,6 @@ public PropertyFetch(Type? type) Justification = "In EventSource, EnsureDescriptorsInitialized's use of GetType preserves this method which " + "requires unreferenced code, but EnsureDescriptorsInitialized does not access this member and is safe to call.")] [RequiresUnreferencedCode(DiagnosticSource.WriteRequiresUnreferencedCode)] - [RequiresDynamicCode(DiagnosticSource.WriteRequiresDynamicCode)] public static PropertyFetch FetcherForProperty(Type? type, string propertyName) { if (propertyName == null) @@ -1323,10 +1323,7 @@ public static PropertyFetch FetcherForProperty(Type? type, string propertyName) continue; } - Type elemType = iFaceTypeInfo.GetGenericArguments()[0]; - Type instantiatedTypedPropertyFetcher = typeof(EnumeratePropertyFetch<>) - .GetTypeInfo().MakeGenericType(elemType); - return (PropertyFetch)Activator.CreateInstance(instantiatedTypedPropertyFetcher, type)!; + return CreateEnumeratePropertyFetch(type, iFaceTypeInfo); } // no implementation of IEnumerable found, return a null fetcher @@ -1359,20 +1356,50 @@ public static PropertyFetch FetcherForProperty(Type? type, string propertyName) Log.Message($"Property {propertyName} is static."); return new PropertyFetch(type); } - Type typedPropertyFetcher = typeInfo.IsValueType ? - typeof(ValueTypedFetchProperty<,>) : typeof(RefTypedFetchProperty<,>); - Type instantiatedTypedPropertyFetcher = typedPropertyFetcher.GetTypeInfo().MakeGenericType( - propertyInfo.DeclaringType!, propertyInfo.PropertyType); - return (PropertyFetch)Activator.CreateInstance(instantiatedTypedPropertyFetcher, type, propertyInfo)!; + + return CreatePropertyFetch(typeInfo, propertyInfo); } } + [UnconditionalSuppressMessage("AOT", "IL3050:RequiresDynamicCode", + Justification = "MakeGenericType is only called when IsDynamicCodeSupported is true or only with ref types.")] + private static PropertyFetch CreateEnumeratePropertyFetch(Type type, Type enumerableOfTType) + { + Type elemType = enumerableOfTType.GetGenericArguments()[0]; +#if NETCOREAPP + if (!RuntimeFeature.IsDynamicCodeSupported && elemType.IsValueType) + { + return new EnumeratePropertyFetch(type); + } +#endif + Type instantiatedTypedPropertyFetcher = typeof(EnumeratePropertyFetch<>) + .GetTypeInfo().MakeGenericType(elemType); + return (PropertyFetch)Activator.CreateInstance(instantiatedTypedPropertyFetcher, type)!; + } + + [UnconditionalSuppressMessage("AOT", "IL3050:RequiresDynamicCode", + Justification = "MakeGenericType is only called when IsDynamicCodeSupported is true or only with ref types.")] + private static PropertyFetch CreatePropertyFetch(Type type, PropertyInfo propertyInfo) + { +#if NETCOREAPP + if (!RuntimeFeature.IsDynamicCodeSupported && (propertyInfo.DeclaringType!.IsValueType || propertyInfo.PropertyType.IsValueType)) + { + return new ReflectionPropertyFetch(type, propertyInfo); + } +#endif + Type typedPropertyFetcher = type.IsValueType ? + typeof(ValueTypedFetchProperty<,>) : typeof(RefTypedFetchProperty<,>); + Type instantiatedTypedPropertyFetcher = typedPropertyFetcher.GetTypeInfo().MakeGenericType( + propertyInfo.DeclaringType!, propertyInfo.PropertyType); + return (PropertyFetch)Activator.CreateInstance(instantiatedTypedPropertyFetcher, type, propertyInfo)!; + } + /// /// Given an object, fetch the property that this propertyFech represents. /// public virtual object? Fetch(object? obj) { return null; } - #region private +#region private private sealed class RefTypedFetchProperty : PropertyFetch { @@ -1411,6 +1438,74 @@ public ValueTypedFetchProperty(Type type, PropertyInfo property) : base(type) private readonly StructFunc _propertyFetch; } +#if NETCOREAPP + /// + /// A fetcher that can be used when MakeGenericType isn't available. + /// + private sealed class ReflectionPropertyFetch : PropertyFetch + { + private readonly PropertyInfo _property; + public ReflectionPropertyFetch(Type type, PropertyInfo property) : base(type) + { + _property = property; + } + + public override object? Fetch(object? obj) => _property.GetValue(obj); + } + + /// + /// A fetcher that enumerates and formats an IEnumerable when MakeGenericType isn't available. + /// + private sealed class EnumeratePropertyFetch : PropertyFetch + { + public EnumeratePropertyFetch(Type type) : base(type) { } + + public override object? Fetch(object? obj) + { + IEnumerable? enumerable = obj as IEnumerable; + Debug.Assert(enumerable is not null); + + // string.Join for a non-generic IEnumerable + IEnumerator en = enumerable.GetEnumerator(); + using (IDisposable? disposable = en as IDisposable) + { + if (!en.MoveNext()) + { + return string.Empty; + } + + object? currentValue = en.Current; + string? firstString = currentValue?.ToString(); + + // If there's only 1 item, simply return the ToString of that + if (!en.MoveNext()) + { + // Only one value available + return firstString ?? string.Empty; + } + + var result = new ValueStringBuilder(stackalloc char[256]); + + result.Append(firstString); + + do + { + currentValue = en.Current; + + result.Append(","); + if (currentValue != null) + { + result.Append(currentValue.ToString()); + } + } + while (en.MoveNext()); + + return result.ToString(); + } + } + } +#endif + /// /// A fetcher that returns the result of Activity.Current /// @@ -1435,17 +1530,17 @@ public EnumeratePropertyFetch(Type type) : base(type) { } return string.Join(",", (IEnumerable)obj); } } - #endregion +#endregion } private readonly string _propertyName; private volatile PropertyFetch? _fetchForExpectedType; - #endregion +#endregion } private readonly string _outputName = null!; private readonly PropertySpec? _fetches; - #endregion +#endregion } /// @@ -1458,13 +1553,13 @@ internal sealed class CallbackObserver : IObserver { public CallbackObserver(Action callback) { _callback = callback; } - #region private +#region private public void OnCompleted() { } public void OnError(Exception error) { } public void OnNext(T value) { _callback(value); } private readonly Action _callback; - #endregion +#endregion } // A linked list of IObservable subscriptions (which are IDisposable). @@ -1481,11 +1576,11 @@ public Subscriptions(IDisposable subscription, Subscriptions? next) public Subscriptions? Next; } - #endregion +#endregion private FilterAndTransform? _specs; // Transformation specifications that indicate which sources/events are forwarded. private FilterAndTransform? _activitySourceSpecs; // ActivitySource Transformation specifications that indicate which sources/events are forwarded. private ActivityListener? _activityListener; - #endregion +#endregion } } diff --git a/src/libraries/System.Diagnostics.DiagnosticSource/src/System/Diagnostics/HttpHandlerDiagnosticListener.cs b/src/libraries/System.Diagnostics.DiagnosticSource/src/System/Diagnostics/HttpHandlerDiagnosticListener.cs index a35ea9ce5807d4..94d4192721ca54 100644 --- a/src/libraries/System.Diagnostics.DiagnosticSource/src/System/Diagnostics/HttpHandlerDiagnosticListener.cs +++ b/src/libraries/System.Diagnostics.DiagnosticSource/src/System/Diagnostics/HttpHandlerDiagnosticListener.cs @@ -25,7 +25,6 @@ namespace System.Diagnostics /// when it sees the System.Net.Http.Desktop source, subscribe to it. This will trigger the /// initialization of this DiagnosticListener. /// - [RequiresDynamicCode(WriteRequiresDynamicCode)] internal sealed class HttpHandlerDiagnosticListener : DiagnosticListener { /// @@ -204,7 +203,6 @@ public override void Remove(object key) /// intercept each new ServicePoint object being added to ServicePointManager.s_ServicePointTable /// and replace its ConnectionGroupList hashtable field. /// - [RequiresDynamicCode(WriteRequiresDynamicCode)] private sealed class ServicePointHashtable : HashtableWrapper { public ServicePointHashtable(Hashtable table) : base(table) @@ -245,7 +243,6 @@ public override object this[object key] /// intercept each new ConnectionGroup object being added to ServicePoint.m_ConnectionGroupList /// and replace its m_ConnectionList arraylist field. /// - [RequiresDynamicCode(WriteRequiresDynamicCode)] private sealed class ConnectionGroupHashtable : HashtableWrapper { public ConnectionGroupHashtable(Hashtable table) : base(table) @@ -485,7 +482,6 @@ public override void TrimToSize() /// intercept each new Connection object being added to ConnectionGroup.m_ConnectionList /// and replace its m_WriteList arraylist field. /// - [RequiresDynamicCode(WriteRequiresDynamicCode)] private sealed class ConnectionArrayList : ArrayListWrapper { public ConnectionArrayList(ArrayList list) : base(list) @@ -516,7 +512,6 @@ public override int Add(object value) /// It also intercepts all HttpWebRequest objects that are about to get removed from /// Connection.m_WriteList as they have completed the request. /// - [RequiresDynamicCode(WriteRequiresDynamicCode)] private sealed class HttpWebRequestArrayList : ArrayListWrapper { public HttpWebRequestArrayList(ArrayList list) : base(list) diff --git a/src/libraries/System.Diagnostics.DiagnosticSource/tests/NativeAotTests/DiagnosticSourceEventSourceTests.cs b/src/libraries/System.Diagnostics.DiagnosticSource/tests/NativeAotTests/DiagnosticSourceEventSourceTests.cs new file mode 100644 index 00000000000000..408813b4c55c75 --- /dev/null +++ b/src/libraries/System.Diagnostics.DiagnosticSource/tests/NativeAotTests/DiagnosticSourceEventSourceTests.cs @@ -0,0 +1,109 @@ +// Licensed to the .NET Foundation under one or more agreements. +// The .NET Foundation licenses this file to you under the MIT license. + +using System; +using System.Collections.Generic; +using System.Collections.ObjectModel; +using System.Diagnostics; +using System.Diagnostics.CodeAnalysis; +using System.Diagnostics.Tracing; + +/// +/// Tests that using writing to a DiagnosticSource writes the correct payloads +/// to the DiagnosticSourceEventSource. +/// +internal class Program +{ + private class TestEventListener : EventListener + { + public ReadOnlyCollection LogDataPayload { get; set; } + + protected override void OnEventSourceCreated(EventSource eventSource) + { + if (eventSource.Name == "Microsoft-Diagnostics-DiagnosticSource") + { + EnableEvents(eventSource, EventLevel.Verbose, EventKeywords.All, new Dictionary + { + { "FilterAndPayloadSpecs", "TestDiagnosticListener/Test.Start@Activity2Start:-Id;Ints.*Enumerate"} + }); + } + + base.OnEventSourceCreated(eventSource); + } + + protected override void OnEventWritten(EventWrittenEventArgs eventData) + { + if (eventData.EventName == "Activity2Start") + { + LogDataPayload = eventData.Payload; + } + + base.OnEventWritten(eventData); + } + } + + public static int Main() + { + DiagnosticSource diagnosticSource = new DiagnosticListener("TestDiagnosticListener"); + using (var listener = new TestEventListener()) + { + var data = new EventData() + { + Id = Guid.NewGuid(), + }; + + Write(diagnosticSource, "Test.Start", data); + + if (!(listener.LogDataPayload?.Count == 3 && + (string)listener.LogDataPayload[0] == "TestDiagnosticListener" && + (string)listener.LogDataPayload[1] == "Test.Start")) + { + return -1; + } + + object[] args = (object[])listener.LogDataPayload[2]; + if (args.Length != 2) + { + return -2; + } + + IDictionary arg = (IDictionary)args[0]; + if (!((string)arg["Key"] == "Id" && (string)arg["Value"] == data.Id.ToString())) + { + return -3; + } + + arg = (IDictionary)args[1]; + if (!((string)arg["Key"] == "*Enumerate" && (string)arg["Value"] == "1,2,3")) + { + return -4; + } + + return 100; + } + } + + // can be removed once https://github.com/dotnet/runtime/issues/50454 is implemented + private static void Write<[DynamicallyAccessedMembers(DynamicallyAccessedMemberTypes.PublicProperties)] T>( + DiagnosticSource diagnosticSource, + string name, + T value) + { + diagnosticSource.Write(name, value); + } + + public class EventData + { + public Guid Id { get; set; } + + public IEnumerable Ints + { + get + { + yield return 1; + yield return 2; + yield return 3; + } + } + } +} diff --git a/src/libraries/System.Diagnostics.DiagnosticSource/tests/NativeAotTests/System.Diagnostics.DiagnosticSource.NativeAotTests.proj b/src/libraries/System.Diagnostics.DiagnosticSource/tests/NativeAotTests/System.Diagnostics.DiagnosticSource.NativeAotTests.proj new file mode 100644 index 00000000000000..ad135f8c095be1 --- /dev/null +++ b/src/libraries/System.Diagnostics.DiagnosticSource/tests/NativeAotTests/System.Diagnostics.DiagnosticSource.NativeAotTests.proj @@ -0,0 +1,9 @@ + + + + + + + + + From ae71cddce2d991089e5a1a117030c1447ac8f870 Mon Sep 17 00:00:00 2001 From: Eric Erhardt Date: Mon, 26 Sep 2022 17:33:10 -0500 Subject: [PATCH 02/10] Enable new NativeAotTests in CI --- .../coreclr/nativeaot-post-build-steps.yml | 3 +++ .../linker/SupportFiles/Directory.Build.props | 3 +++ .../SupportFiles/Directory.Build.targets | 4 ++++ eng/testing/linker/project.csproj.template | 1 + eng/testing/linker/trimmingTests.targets | 1 + src/libraries/tests.proj | 20 ++++++++++++------- 6 files changed, 25 insertions(+), 7 deletions(-) diff --git a/eng/pipelines/coreclr/nativeaot-post-build-steps.yml b/eng/pipelines/coreclr/nativeaot-post-build-steps.yml index a44c7223039580..d8f342209ecbe4 100644 --- a/eng/pipelines/coreclr/nativeaot-post-build-steps.yml +++ b/eng/pipelines/coreclr/nativeaot-post-build-steps.yml @@ -29,3 +29,6 @@ steps: - ${{ if ne(parameters.osGroup, 'windows') }}: - script: $(Build.SourcesDirectory)/src/tests/run.sh --runnativeaottests $(buildConfigUpper) ${{ parameters.archType }} displayName: Run tests in single file mode + + - script: $(Build.SourcesDirectory)$(dir)build$(scriptExt) -ci -arch ${{ parameters.archType }} $(_osParameter) -s libs.tests -c $(_BuildConfig) /p:TestAssemblies=false /p:TestNativeAot=true $(_officialBuildParameter) $(_crossBuildPropertyArg) /bl:$(Build.SourcesDirectory)/artifacts/log/$(buildConfigUpper)/NativeAotTests.binlog ${{ parameters.extraTestArgs }} + displayName: Run NativeAot Library Tests diff --git a/eng/testing/linker/SupportFiles/Directory.Build.props b/eng/testing/linker/SupportFiles/Directory.Build.props index 1e08117fd3171c..4bc7c099d3f812 100644 --- a/eng/testing/linker/SupportFiles/Directory.Build.props +++ b/eng/testing/linker/SupportFiles/Directory.Build.props @@ -12,5 +12,8 @@ false true $(NoWarn);IL2121 + + + true diff --git a/eng/testing/linker/SupportFiles/Directory.Build.targets b/eng/testing/linker/SupportFiles/Directory.Build.targets index 491c45e4a43fa9..e735d71fa0f723 100644 --- a/eng/testing/linker/SupportFiles/Directory.Build.targets +++ b/eng/testing/linker/SupportFiles/Directory.Build.targets @@ -12,6 +12,10 @@ DependsOnTargets="BundleTestWasmApp" Condition="'$(TargetArchitecture)' == 'wasm' And '$(TargetOS)' == 'browser'" /> + + $(CoreCLRBuildIntegrationDir)Microsoft.DotNet.ILCompiler.SingleEntry.targets + + diff --git a/eng/testing/linker/project.csproj.template b/eng/testing/linker/project.csproj.template index b628bbf261e7aa..3596f4220b3b5a 100644 --- a/eng/testing/linker/project.csproj.template +++ b/eng/testing/linker/project.csproj.template @@ -32,6 +32,7 @@ {IlcBuildTasksPath} {IlcSdkPath} {IlcFrameworkPath} + {CoreCLRBuildIntegrationDir} diff --git a/eng/testing/linker/trimmingTests.targets b/eng/testing/linker/trimmingTests.targets index da548605023e9a..3e955b7ee666f9 100644 --- a/eng/testing/linker/trimmingTests.targets +++ b/eng/testing/linker/trimmingTests.targets @@ -92,6 +92,7 @@ .Replace('{IlcBuildTasksPath}', '$(CoreCLRILCompilerDir)netstandard/ILCompiler.Build.Tasks.dll') .Replace('{IlcSdkPath}', '$(CoreCLRAotSdkDir)') .Replace('{IlcFrameworkPath}', '$(MicrosoftNetCoreAppRuntimePackRidLibTfmDir)') + .Replace('{CoreCLRBuildIntegrationDir}', '$(CoreCLRBuildIntegrationDir)') .Replace('{RuntimeHostConfigurationOptions}', '$(_runtimeHostConfigurationOptionsString)') .Replace('{AdditionalProjectReferences}', '$(_additionalProjectReferencesString)') .Replace('{RepositoryEngineeringDir}', '$(RepositoryEngineeringDir)') diff --git a/src/libraries/tests.proj b/src/libraries/tests.proj index 07349a0d3d4497..bdc7034ab6f3c4 100644 --- a/src/libraries/tests.proj +++ b/src/libraries/tests.proj @@ -4,7 +4,7 @@ $([MSBuild]::ValueOrDefault('$(BuildTargetFramework)', '$(NetCoreAppCurrent)'))-$(TargetOS) - true + true @@ -18,6 +18,7 @@ true false false + false true false @@ -584,6 +585,11 @@ Condition="'$(TestTrimming)' == 'true'" AdditionalProperties="%(AdditionalProperties);SkipTrimmingProjectsRestore=true" /> + + - - - + - + - From cbe570b9f1aac690a3ed1ce86ed2a87c71a9968b Mon Sep 17 00:00:00 2001 From: Eric Erhardt Date: Mon, 26 Sep 2022 19:17:25 -0500 Subject: [PATCH 03/10] Fix NativeAOT tests - Only run them in Release configuration - Suppress IL2026 warning --- eng/pipelines/coreclr/nativeaot-post-build-steps.yml | 6 ++++-- .../NativeAotTests/DiagnosticSourceEventSourceTests.cs | 3 ++- 2 files changed, 6 insertions(+), 3 deletions(-) diff --git a/eng/pipelines/coreclr/nativeaot-post-build-steps.yml b/eng/pipelines/coreclr/nativeaot-post-build-steps.yml index d8f342209ecbe4..d4c35de5bed71e 100644 --- a/eng/pipelines/coreclr/nativeaot-post-build-steps.yml +++ b/eng/pipelines/coreclr/nativeaot-post-build-steps.yml @@ -30,5 +30,7 @@ steps: - script: $(Build.SourcesDirectory)/src/tests/run.sh --runnativeaottests $(buildConfigUpper) ${{ parameters.archType }} displayName: Run tests in single file mode - - script: $(Build.SourcesDirectory)$(dir)build$(scriptExt) -ci -arch ${{ parameters.archType }} $(_osParameter) -s libs.tests -c $(_BuildConfig) /p:TestAssemblies=false /p:TestNativeAot=true $(_officialBuildParameter) $(_crossBuildPropertyArg) /bl:$(Build.SourcesDirectory)/artifacts/log/$(buildConfigUpper)/NativeAotTests.binlog ${{ parameters.extraTestArgs }} - displayName: Run NativeAot Library Tests + # Publishing tooling doesn't support different configs between runtime and libs, so only run tests in Release config + - ${{ if eq(parameters.jobParameters.buildConfig, 'release') }}: + - script: $(Build.SourcesDirectory)$(dir)build$(scriptExt) -ci -arch ${{ parameters.archType }} $(_osParameter) -s libs.tests -c $(_BuildConfig) /p:TestAssemblies=false /p:TestNativeAot=true $(_officialBuildParameter) $(_crossBuildPropertyArg) /bl:$(Build.SourcesDirectory)/artifacts/log/$(buildConfigUpper)/NativeAotTests.binlog ${{ parameters.extraTestArgs }} + displayName: Run NativeAot Library Tests diff --git a/src/libraries/System.Diagnostics.DiagnosticSource/tests/NativeAotTests/DiagnosticSourceEventSourceTests.cs b/src/libraries/System.Diagnostics.DiagnosticSource/tests/NativeAotTests/DiagnosticSourceEventSourceTests.cs index 408813b4c55c75..fab21b5a7b716c 100644 --- a/src/libraries/System.Diagnostics.DiagnosticSource/tests/NativeAotTests/DiagnosticSourceEventSourceTests.cs +++ b/src/libraries/System.Diagnostics.DiagnosticSource/tests/NativeAotTests/DiagnosticSourceEventSourceTests.cs @@ -83,7 +83,8 @@ public static int Main() } } - // can be removed once https://github.com/dotnet/runtime/issues/50454 is implemented + [UnconditionalSuppressMessage("ReflectionAnalysis", "IL2026:RequiresUnreferencedCode", + Justification = "The value being passed into Write has the necessary properties being preserved with DynamicallyAccessedMembers.")] private static void Write<[DynamicallyAccessedMembers(DynamicallyAccessedMemberTypes.PublicProperties)] T>( DiagnosticSource diagnosticSource, string name, From 553933db3d6f3fadec466d718f7f4a41bae3c442 Mon Sep 17 00:00:00 2001 From: Eric Erhardt Date: Tue, 27 Sep 2022 11:48:42 -0500 Subject: [PATCH 04/10] Fix test CI leg --- .../coreclr/nativeaot-post-build-steps.yml | 4 ++-- src/libraries/tests.proj | 20 +++++++++---------- 2 files changed, 12 insertions(+), 12 deletions(-) diff --git a/eng/pipelines/coreclr/nativeaot-post-build-steps.yml b/eng/pipelines/coreclr/nativeaot-post-build-steps.yml index d4c35de5bed71e..2e8ee062d25aaa 100644 --- a/eng/pipelines/coreclr/nativeaot-post-build-steps.yml +++ b/eng/pipelines/coreclr/nativeaot-post-build-steps.yml @@ -31,6 +31,6 @@ steps: displayName: Run tests in single file mode # Publishing tooling doesn't support different configs between runtime and libs, so only run tests in Release config - - ${{ if eq(parameters.jobParameters.buildConfig, 'release') }}: - - script: $(Build.SourcesDirectory)$(dir)build$(scriptExt) -ci -arch ${{ parameters.archType }} $(_osParameter) -s libs.tests -c $(_BuildConfig) /p:TestAssemblies=false /p:TestNativeAot=true $(_officialBuildParameter) $(_crossBuildPropertyArg) /bl:$(Build.SourcesDirectory)/artifacts/log/$(buildConfigUpper)/NativeAotTests.binlog ${{ parameters.extraTestArgs }} + - ${{ if eq(parameters.buildConfig, 'release') }}: + - script: $(Build.SourcesDirectory)$(dir)build$(scriptExt) -ci -arch ${{ parameters.archType }} $(_osParameter) -s libs.tests -c $(_BuildConfig) /p:TestAssemblies=false /p:RunNativeAotTestApps=true $(_officialBuildParameter) $(_crossBuildPropertyArg) /bl:$(Build.SourcesDirectory)/artifacts/log/$(buildConfigUpper)/NativeAotTests.binlog ${{ parameters.extraTestArgs }} displayName: Run NativeAot Library Tests diff --git a/src/libraries/tests.proj b/src/libraries/tests.proj index bdc7034ab6f3c4..f9f9f94a8204e4 100644 --- a/src/libraries/tests.proj +++ b/src/libraries/tests.proj @@ -4,7 +4,7 @@ $([MSBuild]::ValueOrDefault('$(BuildTargetFramework)', '$(NetCoreAppCurrent)'))-$(TargetOS) - true + true @@ -18,7 +18,7 @@ true false false - false + false true false @@ -585,11 +585,11 @@ Condition="'$(TestTrimming)' == 'true'" AdditionalProperties="%(AdditionalProperties);SkipTrimmingProjectsRestore=true" /> - - + + - - + From c0c6736d46cdcc90fc5121c2c394c8071382a570 Mon Sep 17 00:00:00 2001 From: Eric Erhardt Date: Tue, 27 Sep 2022 16:57:41 -0500 Subject: [PATCH 05/10] Set IlcFrameworkNativePath correctly --- eng/testing/linker/project.csproj.template | 1 + eng/testing/linker/trimmingTests.targets | 1 + 2 files changed, 2 insertions(+) diff --git a/eng/testing/linker/project.csproj.template b/eng/testing/linker/project.csproj.template index 3596f4220b3b5a..6b8165b6ab2403 100644 --- a/eng/testing/linker/project.csproj.template +++ b/eng/testing/linker/project.csproj.template @@ -32,6 +32,7 @@ {IlcBuildTasksPath} {IlcSdkPath} {IlcFrameworkPath} + {IlcFrameworkNativePath} {CoreCLRBuildIntegrationDir} diff --git a/eng/testing/linker/trimmingTests.targets b/eng/testing/linker/trimmingTests.targets index 3e955b7ee666f9..507f95f556cfab 100644 --- a/eng/testing/linker/trimmingTests.targets +++ b/eng/testing/linker/trimmingTests.targets @@ -92,6 +92,7 @@ .Replace('{IlcBuildTasksPath}', '$(CoreCLRILCompilerDir)netstandard/ILCompiler.Build.Tasks.dll') .Replace('{IlcSdkPath}', '$(CoreCLRAotSdkDir)') .Replace('{IlcFrameworkPath}', '$(MicrosoftNetCoreAppRuntimePackRidLibTfmDir)') + .Replace('{IlcFrameworkNativePath}', '$(MicrosoftNetCoreAppRuntimePackNativeDir)') .Replace('{CoreCLRBuildIntegrationDir}', '$(CoreCLRBuildIntegrationDir)') .Replace('{RuntimeHostConfigurationOptions}', '$(_runtimeHostConfigurationOptionsString)') .Replace('{AdditionalProjectReferences}', '$(_additionalProjectReferencesString)') From 0c391ff426dc09670b287b4eb822c2d013496285 Mon Sep 17 00:00:00 2001 From: Eric Erhardt Date: Tue, 27 Sep 2022 17:02:37 -0500 Subject: [PATCH 06/10] Don't run NativeAot published app tests on OSX since it isn't supported --- eng/pipelines/coreclr/nativeaot-post-build-steps.yml | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/eng/pipelines/coreclr/nativeaot-post-build-steps.yml b/eng/pipelines/coreclr/nativeaot-post-build-steps.yml index 2e8ee062d25aaa..a920993b093cbc 100644 --- a/eng/pipelines/coreclr/nativeaot-post-build-steps.yml +++ b/eng/pipelines/coreclr/nativeaot-post-build-steps.yml @@ -31,6 +31,7 @@ steps: displayName: Run tests in single file mode # Publishing tooling doesn't support different configs between runtime and libs, so only run tests in Release config - - ${{ if eq(parameters.buildConfig, 'release') }}: + # PublishAot on OSX doesn't work yet. Need an SDK with https://github.com/dotnet/installer/pull/14443. + - ${{ if and(eq(parameters.buildConfig, 'release'), ne(parameters.osGroup, 'OSX')) }}: - script: $(Build.SourcesDirectory)$(dir)build$(scriptExt) -ci -arch ${{ parameters.archType }} $(_osParameter) -s libs.tests -c $(_BuildConfig) /p:TestAssemblies=false /p:RunNativeAotTestApps=true $(_officialBuildParameter) $(_crossBuildPropertyArg) /bl:$(Build.SourcesDirectory)/artifacts/log/$(buildConfigUpper)/NativeAotTests.binlog ${{ parameters.extraTestArgs }} displayName: Run NativeAot Library Tests From bb378df5474726796d60b3c3f888621fd7fa8da1 Mon Sep 17 00:00:00 2001 From: Eric Erhardt Date: Wed, 28 Sep 2022 12:01:19 -0500 Subject: [PATCH 07/10] Respond to PR feedback Set EventSourceSupport only on the projects that need it. --- eng/testing/linker/SupportFiles/Directory.Build.props | 3 --- eng/testing/linker/project.csproj.template | 1 + eng/testing/linker/trimmingTests.targets | 5 +++++ .../System.Diagnostics.DiagnosticSource.NativeAotTests.proj | 3 ++- 4 files changed, 8 insertions(+), 4 deletions(-) diff --git a/eng/testing/linker/SupportFiles/Directory.Build.props b/eng/testing/linker/SupportFiles/Directory.Build.props index 4bc7c099d3f812..1e08117fd3171c 100644 --- a/eng/testing/linker/SupportFiles/Directory.Build.props +++ b/eng/testing/linker/SupportFiles/Directory.Build.props @@ -12,8 +12,5 @@ false true $(NoWarn);IL2121 - - - true diff --git a/eng/testing/linker/project.csproj.template b/eng/testing/linker/project.csproj.template index 6b8165b6ab2403..9b1c14e36b814d 100644 --- a/eng/testing/linker/project.csproj.template +++ b/eng/testing/linker/project.csproj.template @@ -26,6 +26,7 @@ {RepositoryEngineeringDir} <_ExtraTrimmerArgs>{ExtraTrimmerArgs} $(_ExtraTrimmerArgs) + {AdditionalProperties} {IlcToolsPath} diff --git a/eng/testing/linker/trimmingTests.targets b/eng/testing/linker/trimmingTests.targets index 507f95f556cfab..9f821e99c2a3a5 100644 --- a/eng/testing/linker/trimmingTests.targets +++ b/eng/testing/linker/trimmingTests.targets @@ -72,10 +72,14 @@ <_switchesAsItems Include="%(TestConsoleApps.DisabledFeatureSwitches)" Value="false" /> <_switchesAsItems Include="%(TestConsoleApps.EnabledFeatureSwitches)" Value="true" /> + + <_propertiesAsItems Include="%(TestConsoleApps.DisabledProperties)" Value="false" /> + <_propertiesAsItems Include="%(TestConsoleApps.EnabledProperties)" Value="true" /> <_runtimeHostConfigurationOptionsString>@(_switchesAsItems->'<RuntimeHostConfigurationOption Include="%(Identity)" Value="%(Value)" Trim="true" />', '%0a ') + <_additionalPropertiesString>@(_propertiesAsItems->'<%(Identity)>%(Value)</%(Identity)>', '%0a ') @@ -88,6 +92,7 @@ .Replace('{PublishAot}','$(IsNativeAotTestProject)') .Replace('{MicrosoftNETILLinkTasksVersion}', '$(MicrosoftNETILLinkTasksVersion)') .Replace('{ExtraTrimmerArgs}', '%(TestConsoleApps.ExtraTrimmerArgs)') + .Replace('{AdditionalProperties}', '$(_additionalPropertiesString)') .Replace('{IlcToolsPath}', '$(CoreCLRILCompilerDir)') .Replace('{IlcBuildTasksPath}', '$(CoreCLRILCompilerDir)netstandard/ILCompiler.Build.Tasks.dll') .Replace('{IlcSdkPath}', '$(CoreCLRAotSdkDir)') diff --git a/src/libraries/System.Diagnostics.DiagnosticSource/tests/NativeAotTests/System.Diagnostics.DiagnosticSource.NativeAotTests.proj b/src/libraries/System.Diagnostics.DiagnosticSource/tests/NativeAotTests/System.Diagnostics.DiagnosticSource.NativeAotTests.proj index ad135f8c095be1..8001203352b581 100644 --- a/src/libraries/System.Diagnostics.DiagnosticSource/tests/NativeAotTests/System.Diagnostics.DiagnosticSource.NativeAotTests.proj +++ b/src/libraries/System.Diagnostics.DiagnosticSource/tests/NativeAotTests/System.Diagnostics.DiagnosticSource.NativeAotTests.proj @@ -2,7 +2,8 @@ - + From dcd0a80dfa58ee65d7ffd9746b2cc2efb607d2d1 Mon Sep 17 00:00:00 2001 From: Viktor Hofer Date: Fri, 18 Nov 2022 20:42:44 +0100 Subject: [PATCH 08/10] Add servicing change for DiagnosticSource --- .../src/System.Diagnostics.DiagnosticSource.csproj | 2 ++ 1 file changed, 2 insertions(+) diff --git a/src/libraries/System.Diagnostics.DiagnosticSource/src/System.Diagnostics.DiagnosticSource.csproj b/src/libraries/System.Diagnostics.DiagnosticSource/src/System.Diagnostics.DiagnosticSource.csproj index 4c20a73469985b..9766433b22758a 100644 --- a/src/libraries/System.Diagnostics.DiagnosticSource/src/System.Diagnostics.DiagnosticSource.csproj +++ b/src/libraries/System.Diagnostics.DiagnosticSource/src/System.Diagnostics.DiagnosticSource.csproj @@ -12,6 +12,8 @@ Commonly Used Types: System.Diagnostics.DiagnosticListener System.Diagnostics.DiagnosticSource + true + 1 From 69a8aea7347149e7dbdb33a14ebb5d0199b21cf1 Mon Sep 17 00:00:00 2001 From: Viktor Hofer Date: Fri, 18 Nov 2022 20:43:48 +0100 Subject: [PATCH 09/10] Update Microsoft.Extensions.Hosting.csproj --- .../src/Microsoft.Extensions.Hosting.csproj | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/src/libraries/Microsoft.Extensions.Hosting/src/Microsoft.Extensions.Hosting.csproj b/src/libraries/Microsoft.Extensions.Hosting/src/Microsoft.Extensions.Hosting.csproj index 945760c9aa144c..81b1279805ffd1 100644 --- a/src/libraries/Microsoft.Extensions.Hosting/src/Microsoft.Extensions.Hosting.csproj +++ b/src/libraries/Microsoft.Extensions.Hosting/src/Microsoft.Extensions.Hosting.csproj @@ -3,9 +3,11 @@ $(NetCoreAppCurrent);$(NetCoreAppMinimum);netstandard2.1;netstandard2.0;$(NetFrameworkMinimum) true - Hosting and startup infrastructures for applications. true true + Hosting and startup infrastructures for applications. + true + 1 From fd1859f54b227c84dc646f89c8dac358c674421a Mon Sep 17 00:00:00 2001 From: Viktor Hofer Date: Fri, 18 Nov 2022 22:11:35 +0100 Subject: [PATCH 10/10] Update Microsoft.Extensions.Hosting.csproj --- .../src/Microsoft.Extensions.Hosting.csproj | 2 -- 1 file changed, 2 deletions(-) diff --git a/src/libraries/Microsoft.Extensions.Hosting/src/Microsoft.Extensions.Hosting.csproj b/src/libraries/Microsoft.Extensions.Hosting/src/Microsoft.Extensions.Hosting.csproj index 81b1279805ffd1..58cfcc97605652 100644 --- a/src/libraries/Microsoft.Extensions.Hosting/src/Microsoft.Extensions.Hosting.csproj +++ b/src/libraries/Microsoft.Extensions.Hosting/src/Microsoft.Extensions.Hosting.csproj @@ -6,8 +6,6 @@ true true Hosting and startup infrastructures for applications. - true - 1