From 1227d643d97f6f0c102c0fa0b0c10cd869f81431 Mon Sep 17 00:00:00 2001 From: Eric Erhardt Date: Thu, 22 Sep 2022 19:00:08 -0500 Subject: [PATCH 1/7] 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 d609d71b29f30d..b7abf93f6d9efb 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 9c22bce30dae9b..97163bbceec0a0 100644 --- a/src/libraries/System.Diagnostics.DiagnosticSource/src/System.Diagnostics.DiagnosticSource.csproj +++ b/src/libraries/System.Diagnostics.DiagnosticSource/src/System.Diagnostics.DiagnosticSource.csproj @@ -87,6 +87,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 b1b78fedc80b85..73b3ed529f070a 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. @@ -1193,7 +1196,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) @@ -1248,7 +1250,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; @@ -1295,7 +1296,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) @@ -1319,10 +1319,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 @@ -1355,20 +1352,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 { @@ -1407,6 +1434,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 /// @@ -1431,17 +1526,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 } /// @@ -1454,13 +1549,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). @@ -1477,11 +1572,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 ba624bf2563c2a65475bb78eb44286bb3e4458e9 Mon Sep 17 00:00:00 2001 From: Eric Erhardt Date: Mon, 26 Sep 2022 17:33:10 -0500 Subject: [PATCH 2/7] 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 6ea3f13a2200b7..e78c15752f43ed 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 false @@ -590,6 +591,11 @@ Condition="'$(TestTrimming)' == 'true'" AdditionalProperties="%(AdditionalProperties);SkipTrimmingProjectsRestore=true" /> + + - - - + - + - From b633e7f6ea4ff218a5abd19877dec98b0536ef6c Mon Sep 17 00:00:00 2001 From: Eric Erhardt Date: Mon, 26 Sep 2022 19:17:25 -0500 Subject: [PATCH 3/7] 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 3b4f5bd40c57d30f48d0d49c7d3256479e0340e3 Mon Sep 17 00:00:00 2001 From: Eric Erhardt Date: Tue, 27 Sep 2022 11:48:42 -0500 Subject: [PATCH 4/7] 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 e78c15752f43ed..2220c89cedced0 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 false @@ -591,11 +591,11 @@ Condition="'$(TestTrimming)' == 'true'" AdditionalProperties="%(AdditionalProperties);SkipTrimmingProjectsRestore=true" /> - - + + - - + From ccca5181456dbb14113378226871bd81f3e6edfe Mon Sep 17 00:00:00 2001 From: Eric Erhardt Date: Tue, 27 Sep 2022 16:57:41 -0500 Subject: [PATCH 5/7] 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 9aeca478217d82db6d7636e2839519ae89d99741 Mon Sep 17 00:00:00 2001 From: Eric Erhardt Date: Tue, 27 Sep 2022 17:02:37 -0500 Subject: [PATCH 6/7] 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 15824c8cdc0f386567b43a3b59085099b5b2f68b Mon Sep 17 00:00:00 2001 From: Eric Erhardt Date: Wed, 28 Sep 2022 12:01:19 -0500 Subject: [PATCH 7/7] 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 @@ - +