From: Krzysztof Wicher Date: Fri, 19 Apr 2019 13:15:52 +0000 (-0700) Subject: Nullable: System.Diagnostics.Tracing (#24070) X-Git-Tag: accepted/tizen/unified/20190813.215958~42^2~357^2~5 X-Git-Url: http://review.tizen.org/git/?a=commitdiff_plain;h=898d95a811428b0adc0c8de0b74797ea445a93fd;p=platform%2Fupstream%2Fcoreclr.git Nullable: System.Diagnostics.Tracing (#24070) * Nullable: System.Diagnostics.Tracing * apply feedback * fix one more comment --- diff --git a/src/System.Private.CoreLib/shared/System/Diagnostics/Tracing/ActivityTracker.cs b/src/System.Private.CoreLib/shared/System/Diagnostics/Tracing/ActivityTracker.cs index d0cd84a..c3d5242 100644 --- a/src/System.Private.CoreLib/shared/System/Diagnostics/Tracing/ActivityTracker.cs +++ b/src/System.Private.CoreLib/shared/System/Diagnostics/Tracing/ActivityTracker.cs @@ -2,6 +2,7 @@ // The .NET Foundation licenses this file to you under the MIT license. // See the LICENSE file in the project root for more information. +#nullable enable using System; using System.Diagnostics; using System.Threading; @@ -99,7 +100,7 @@ namespace System.Diagnostics.Tracing // Check for recursion, and force-stop any activities if the activity already started. if ((options & EventActivityOptions.Recursive) == 0) { - ActivityInfo existingActivity = FindActiveActivity(fullActivityName, currentActivity); + ActivityInfo? existingActivity = FindActiveActivity(fullActivityName, currentActivity); if (existingActivity != null) { OnStop(providerName, activityName, task, ref activityId); @@ -154,13 +155,13 @@ namespace System.Diagnostics.Tracing for (; ; ) // This is a retry loop. { - ActivityInfo currentActivity = m_current.Value; - ActivityInfo newCurrentActivity = null; // if we have seen any live activities (orphans), at he first one we have seen. + ActivityInfo? currentActivity = m_current.Value; + ActivityInfo? newCurrentActivity = null; // if we have seen any live activities (orphans), at he first one we have seen. // Search to find the activity to stop in one pass. This insures that we don't let one mistake // (stopping something that was not started) cause all active starts to be stopped // By first finding the target start to stop we are more robust. - ActivityInfo activityToStop = FindActiveActivity(fullActivityName, currentActivity); + ActivityInfo? activityToStop = FindActiveActivity(fullActivityName, currentActivity); // ignore stops where we can't find a start because we may have popped them previously. if (activityToStop == null) @@ -175,7 +176,7 @@ namespace System.Diagnostics.Tracing activityId = activityToStop.ActivityId; // See if there are any orphans that need to be stopped. - ActivityInfo orphan = currentActivity; + ActivityInfo? orphan = currentActivity; while (orphan != activityToStop && orphan != null) { if (orphan.m_stopped != 0) // Skip dead activities. @@ -229,7 +230,7 @@ namespace System.Diagnostics.Tracing // Catch the not Implemented try { - m_current = new AsyncLocal(ActivityChanging); + m_current = new AsyncLocal(ActivityChanging); } catch (NotImplementedException) { #if (!ES_BUILD_PCL && ! ES_BUILD_PN) @@ -251,9 +252,9 @@ namespace System.Diagnostics.Tracing /// /// Searched for a active (nonstopped) activity with the given name. Returns null if not found. /// - private ActivityInfo FindActiveActivity(string name, ActivityInfo startLocation) + private ActivityInfo? FindActiveActivity(string name, ActivityInfo? startLocation) { - var activity = startLocation; + ActivityInfo? activity = startLocation; while (activity != null) { if (name == activity.m_name && activity.m_stopped == 0) @@ -293,7 +294,7 @@ namespace System.Diagnostics.Tracing /// private class ActivityInfo { - public ActivityInfo(string name, long uniqueId, ActivityInfo creator, Guid activityIDToRestore, EventActivityOptions options) + public ActivityInfo(string name, long uniqueId, ActivityInfo? creator, Guid activityIDToRestore, EventActivityOptions options) { m_name = name; m_eventOptions = options; @@ -314,10 +315,10 @@ namespace System.Diagnostics.Tracing } } - public static string Path(ActivityInfo activityInfo) + public static string Path(ActivityInfo? activityInfo) { if (activityInfo == null) - return (""); + return ""; return Path(activityInfo.m_creator) + "/" + activityInfo.m_uniqueId.ToString(); } @@ -326,7 +327,7 @@ namespace System.Diagnostics.Tracing return m_name + "(" + Path(this) + (m_stopped != 0 ? ",DEAD)" : ")"); } - public static string LiveActivities(ActivityInfo list) + public static string LiveActivities(ActivityInfo? list) { if (list == null) return ""; @@ -400,7 +401,7 @@ namespace System.Diagnostics.Tracing private unsafe void CreateOverflowGuid(Guid* outPtr) { // Search backwards for an ancestor that has sufficient space to put the ID. - for (ActivityInfo ancestor = m_creator; ancestor != null; ancestor = ancestor.m_creator) + for (ActivityInfo? ancestor = m_creator; ancestor != null; ancestor = ancestor.m_creator) { if (ancestor.m_activityPathGuidOffset <= 10) // we need at least 2 bytes. { @@ -540,7 +541,7 @@ namespace System.Diagnostics.Tracing readonly internal EventActivityOptions m_eventOptions; // Options passed to start. internal long m_lastChildID; // used to create a unique ID for my children activities internal int m_stopped; // This work item has stopped - readonly internal ActivityInfo m_creator; // My parent (creator). Forms the Path() for the activity. + readonly internal ActivityInfo? m_creator; // My parent (creator). Forms the Path() for the activity. readonly internal Guid m_activityIdToRestore; // The Guid to restore after a stop. #endregion } @@ -548,10 +549,10 @@ namespace System.Diagnostics.Tracing // This callback is used to initialize the m_current AsyncLocal Variable. // Its job is to keep the ETW Activity ID (part of thread local storage) in sync // with m_current.ActivityID - void ActivityChanging(AsyncLocalValueChangedArgs args) + void ActivityChanging(AsyncLocalValueChangedArgs args) { - ActivityInfo cur = args.CurrentValue; - ActivityInfo prev = args.PreviousValue; + ActivityInfo? cur = args.CurrentValue; + ActivityInfo? prev = args.PreviousValue; // Are we popping off a value? (we have a prev, and it creator is cur) // Then check if we should use the GUID at the time of the start event @@ -592,7 +593,7 @@ namespace System.Diagnostics.Tracing /// /// This variable points to a linked list that represents all Activities that have started but have not stopped. /// - AsyncLocal m_current; + AsyncLocal? m_current; bool m_checkedForEnable; // Singleton diff --git a/src/System.Private.CoreLib/shared/System/Diagnostics/Tracing/CounterGroup.cs b/src/System.Private.CoreLib/shared/System/Diagnostics/Tracing/CounterGroup.cs index 0382556..a9fa903 100644 --- a/src/System.Private.CoreLib/shared/System/Diagnostics/Tracing/CounterGroup.cs +++ b/src/System.Private.CoreLib/shared/System/Diagnostics/Tracing/CounterGroup.cs @@ -2,6 +2,7 @@ // The .NET Foundation licenses this file to you under the MIT license. // See the LICENSE file in the project root for more information. +#nullable enable using System; using System.Diagnostics; using System.Collections; @@ -48,12 +49,14 @@ namespace System.Diagnostics.Tracing _eventSource.EventCommandExecuted += OnEventSourceCommand; } - private void OnEventSourceCommand(object sender, EventCommandEventArgs e) + private void OnEventSourceCommand(object? sender, EventCommandEventArgs e) { if (e.Command == EventCommand.Enable || e.Command == EventCommand.Update) { string valueStr; float value; + Debug.Assert(e.Arguments != null); + if (e.Arguments.TryGetValue("EventCounterIntervalSec", out valueStr) && float.TryParse(valueStr, out value)) { // Recursion through EventSource callbacks possible. When we enable the timer @@ -76,7 +79,7 @@ namespace System.Diagnostics.Tracing // We need eventCounters to 'attach' themselves to a particular EventSource. // this table provides the mapping from EventSource -> CounterGroup // which represents this 'attached' information. - private static WeakReference[] s_counterGroups; + private static WeakReference[]? s_counterGroups; private static readonly object s_counterGroupsLock = new object(); private static void EnsureEventSourceIndexAvailable(int eventSourceIndex) @@ -100,8 +103,9 @@ namespace System.Diagnostics.Tracing { int eventSourceIndex = EventListener.EventSourceIndex(eventSource); EnsureEventSourceIndexAvailable(eventSourceIndex); + Debug.Assert(s_counterGroups != null); WeakReference weakRef = CounterGroup.s_counterGroups[eventSourceIndex]; - CounterGroup ret = null; + CounterGroup? ret = null; if (weakRef == null || !weakRef.TryGetTarget(out ret)) { ret = new CounterGroup(eventSource); @@ -117,7 +121,7 @@ namespace System.Diagnostics.Tracing private DateTime _timeStampSinceCollectionStarted; private int _pollingIntervalInMilliseconds; - private Timer _pollingTimer; + private Timer? _pollingTimer; private void DisposeTimer() { @@ -153,7 +157,7 @@ namespace System.Diagnostics.Tracing restoreFlow = true; } - _pollingTimer = new Timer(s => ((CounterGroup)s).OnTimer(null), this, _pollingIntervalInMilliseconds, _pollingIntervalInMilliseconds); + _pollingTimer = new Timer(s => ((CounterGroup)s!).OnTimer(null), this, _pollingIntervalInMilliseconds, _pollingIntervalInMilliseconds); } finally { @@ -166,7 +170,7 @@ namespace System.Diagnostics.Tracing OnTimer(null); } - private void OnTimer(object state) + private void OnTimer(object? state) { Debug.WriteLine("Timer fired at " + DateTime.UtcNow.ToString("mm.ss.ffffff")); lock (this) // Lock the CounterGroup @@ -227,4 +231,4 @@ namespace System.Diagnostics.Tracing #endregion // Timer Processing } -} \ No newline at end of file +} diff --git a/src/System.Private.CoreLib/shared/System/Diagnostics/Tracing/CounterPayload.cs b/src/System.Private.CoreLib/shared/System/Diagnostics/Tracing/CounterPayload.cs index 1be7d54..bca7d3b 100644 --- a/src/System.Private.CoreLib/shared/System/Diagnostics/Tracing/CounterPayload.cs +++ b/src/System.Private.CoreLib/shared/System/Diagnostics/Tracing/CounterPayload.cs @@ -2,6 +2,7 @@ // The .NET Foundation licenses this file to you under the MIT license. // See the LICENSE file in the project root for more information. +#nullable enable using System; using System.Diagnostics; using System.Collections; @@ -18,11 +19,11 @@ namespace System.Diagnostics.Tracing #endif { [EventData] - internal class CounterPayload : IEnumerable> + internal class CounterPayload : IEnumerable> { - public string Name { get; set; } + public string? Name { get; set; } - public string DisplayName { get; set; } + public string? DisplayName { get; set; } public double Mean { get; set; } @@ -36,11 +37,11 @@ namespace System.Diagnostics.Tracing public float IntervalSec { get; internal set; } - public string Metadata { get; set; } + public string? Metadata { get; set; } #region Implementation of the IEnumerable interface - public IEnumerator> GetEnumerator() + public IEnumerator> GetEnumerator() { return ForEnumeration.GetEnumerator(); } @@ -50,21 +51,21 @@ namespace System.Diagnostics.Tracing return ForEnumeration.GetEnumerator(); } - private IEnumerable> ForEnumeration + private IEnumerable> ForEnumeration { get { - yield return new KeyValuePair("Name", Name); - yield return new KeyValuePair("DisplayName", DisplayName); - yield return new KeyValuePair("Mean", Mean); - yield return new KeyValuePair("StandardDeviation", StandardDeviation); - yield return new KeyValuePair("Count", Count); - yield return new KeyValuePair("Min", Min); - yield return new KeyValuePair("Max", Max); - yield return new KeyValuePair("IntervalSec", IntervalSec); - yield return new KeyValuePair("Series", $"Interval={IntervalSec}"); - yield return new KeyValuePair("CounterType", "Mean"); - yield return new KeyValuePair("Metadata", Metadata); + yield return new KeyValuePair("Name", Name); + yield return new KeyValuePair("DisplayName", DisplayName); + yield return new KeyValuePair("Mean", Mean); + yield return new KeyValuePair("StandardDeviation", StandardDeviation); + yield return new KeyValuePair("Count", Count); + yield return new KeyValuePair("Min", Min); + yield return new KeyValuePair("Max", Max); + yield return new KeyValuePair("IntervalSec", IntervalSec); + yield return new KeyValuePair("Series", $"Interval={IntervalSec}"); + yield return new KeyValuePair("CounterType", "Mean"); + yield return new KeyValuePair("Metadata", Metadata); } } @@ -72,23 +73,23 @@ namespace System.Diagnostics.Tracing } [EventData] - internal class IncrementingCounterPayload : IEnumerable> + internal class IncrementingCounterPayload : IEnumerable> { - public string Name { get; set; } + public string? Name { get; set; } - public string DisplayName { get; set; } + public string? DisplayName { get; set; } - public string DisplayRateTimeScale { get; set; } + public string? DisplayRateTimeScale { get; set; } public double Increment { get; set; } public float IntervalSec { get; internal set; } - public string Metadata { get; set; } + public string? Metadata { get; set; } #region Implementation of the IEnumerable interface - public IEnumerator> GetEnumerator() + public IEnumerator> GetEnumerator() { return ForEnumeration.GetEnumerator(); } @@ -98,18 +99,18 @@ namespace System.Diagnostics.Tracing return ForEnumeration.GetEnumerator(); } - private IEnumerable> ForEnumeration + private IEnumerable> ForEnumeration { get { - yield return new KeyValuePair("Name", Name); - yield return new KeyValuePair("DisplayName", DisplayName); - yield return new KeyValuePair("DisplayRateTimeScale", DisplayRateTimeScale); - yield return new KeyValuePair("Increment", Increment); - yield return new KeyValuePair("IntervalSec", IntervalSec); - yield return new KeyValuePair("Series", $"Interval={IntervalSec}"); - yield return new KeyValuePair("CounterType", "Sum"); - yield return new KeyValuePair("Metadata", Metadata); + yield return new KeyValuePair("Name", Name); + yield return new KeyValuePair("DisplayName", DisplayName); + yield return new KeyValuePair("DisplayRateTimeScale", DisplayRateTimeScale); + yield return new KeyValuePair("Increment", Increment); + yield return new KeyValuePair("IntervalSec", IntervalSec); + yield return new KeyValuePair("Series", $"Interval={IntervalSec}"); + yield return new KeyValuePair("CounterType", "Sum"); + yield return new KeyValuePair("Metadata", Metadata); } } diff --git a/src/System.Private.CoreLib/shared/System/Diagnostics/Tracing/DiagnosticCounter.cs b/src/System.Private.CoreLib/shared/System/Diagnostics/Tracing/DiagnosticCounter.cs index ea4cb92..1d0bc54 100644 --- a/src/System.Private.CoreLib/shared/System/Diagnostics/Tracing/DiagnosticCounter.cs +++ b/src/System.Private.CoreLib/shared/System/Diagnostics/Tracing/DiagnosticCounter.cs @@ -2,6 +2,7 @@ // The .NET Foundation licenses this file to you under the MIT license. // See the LICENSE file in the project root for more information. +#nullable enable using System; using System.Diagnostics; using System.Collections; @@ -59,7 +60,7 @@ namespace System.Diagnostics.Tracing if (_group != null) { _group.Remove(this); - _group = null; + _group = null!; // TODO-NULLABLE: should not be nulled out } } @@ -75,7 +76,7 @@ namespace System.Diagnostics.Tracing } } - public string DisplayName { get; set; } + public string? DisplayName { get; set; } public string Name { get; } @@ -84,7 +85,7 @@ namespace System.Diagnostics.Tracing #region private implementation private CounterGroup _group; - private Dictionary _metadata; + private Dictionary? _metadata; internal abstract void WritePayload(float intervalSec); diff --git a/src/System.Private.CoreLib/shared/System/Diagnostics/Tracing/EventCounter.cs b/src/System.Private.CoreLib/shared/System/Diagnostics/Tracing/EventCounter.cs index a9fc089..7c230a2 100644 --- a/src/System.Private.CoreLib/shared/System/Diagnostics/Tracing/EventCounter.cs +++ b/src/System.Private.CoreLib/shared/System/Diagnostics/Tracing/EventCounter.cs @@ -2,6 +2,7 @@ // The .NET Foundation licenses this file to you under the MIT license. // See the LICENSE file in the project root for more information. +#nullable enable using System; using System.Diagnostics; using System.Collections; @@ -111,6 +112,7 @@ namespace System.Diagnostics.Tracing EventSource.Write("EventCounters", new EventSourceOptions() { Level = EventLevel.LogAlways }, new CounterPayloadType(payload)); } } + private void ResetStatistics() { Debug.Assert(Monitor.IsEntered(MyLock)); @@ -127,7 +129,7 @@ namespace System.Diagnostics.Tracing private const int BufferedSize = 10; private const double UnusedBufferSlotValue = double.NegativeInfinity; private const int UnsetIndex = -1; - private volatile double[] _bufferedValues; + private volatile double[] _bufferedValues = null!; private volatile int _bufferedValuesIndex; private void InitializeBuffer() diff --git a/src/System.Private.CoreLib/shared/System/Diagnostics/Tracing/EventDescriptor.cs b/src/System.Private.CoreLib/shared/System/Diagnostics/Tracing/EventDescriptor.cs index 53017b7..cf269bc 100644 --- a/src/System.Private.CoreLib/shared/System/Diagnostics/Tracing/EventDescriptor.cs +++ b/src/System.Private.CoreLib/shared/System/Diagnostics/Tracing/EventDescriptor.cs @@ -2,6 +2,7 @@ // The .NET Foundation licenses this file to you under the MIT license. // See the LICENSE file in the project root for more information. +#nullable enable using System; using System.Runtime.InteropServices; @@ -176,7 +177,7 @@ namespace System.Diagnostics.Tracing } } - public override bool Equals(object obj) + public override bool Equals(object? obj) { if (!(obj is EventDescriptor)) return false; diff --git a/src/System.Private.CoreLib/shared/System/Diagnostics/Tracing/EventProvider.cs b/src/System.Private.CoreLib/shared/System/Diagnostics/Tracing/EventProvider.cs index a8622a8..2d4d68a 100644 --- a/src/System.Private.CoreLib/shared/System/Diagnostics/Tracing/EventProvider.cs +++ b/src/System.Private.CoreLib/shared/System/Diagnostics/Tracing/EventProvider.cs @@ -1,6 +1,8 @@ // Licensed to the .NET Foundation under one or more agreements. // The .NET Foundation licenses this file to you under the MIT license. // See the LICENSE file in the project root for more information. + +#nullable enable using Microsoft.Win32; using System.Collections.Generic; using System.Diagnostics; @@ -93,14 +95,14 @@ namespace System.Diagnostics.Tracing } internal IEventProvider m_eventProvider; // The interface that implements the specific logging mechanism functions. - Interop.Advapi32.EtwEnableCallback m_etwCallback; // Trace Callback function + Interop.Advapi32.EtwEnableCallback? m_etwCallback; // Trace Callback function private long m_regHandle; // Trace Registration Handle private byte m_level; // Tracing Level private long m_anyKeywordMask; // Trace Enable Flags private long m_allKeywordMask; // Match all keyword - private List m_liveSessions; // current live sessions (Tuple) + private List? m_liveSessions; // current live sessions (Tuple) private bool m_enabled; // Enabled flag from Trace callback - private string m_providerName; // Control name + private string? m_providerName; // Control name private Guid m_providerId; // Control Guid internal bool m_disposed; // when true provider has unregistered @@ -277,7 +279,7 @@ namespace System.Diagnostics.Tracing try { ControllerCommand command = ControllerCommand.Update; - IDictionary args = null; + IDictionary? args = null; bool skipFinalOnControllerCommand = false; if (controlCode == Interop.Advapi32.EVENT_CONTROL_CODE_ENABLE_PROVIDER) { @@ -315,12 +317,13 @@ namespace System.Diagnostics.Tracing filterData = null; // read filter data only when a session is being *added* - byte[] data; + byte[]? data; int keyIndex; if (bEnabling && GetDataFromController(etwSessionId, filterData, out command, out data, out keyIndex)) { args = new Dictionary(4); + Debug.Assert(data != null); // TODO-NULLABLE: https://github.com/dotnet/roslyn/issues/26761 while (keyIndex < data.Length) { int keyEnd = FindNull(data, keyIndex); @@ -366,7 +369,7 @@ namespace System.Diagnostics.Tracing } // New in CLR4.0 - protected virtual void OnControllerCommand(ControllerCommand command, IDictionary arguments, int sessionId, int etwSessionId) { } + protected virtual void OnControllerCommand(ControllerCommand command, IDictionary? arguments, int sessionId, int etwSessionId) { } protected EventLevel Level { get { return (EventLevel)m_level; } set { m_level = (byte)value; } } protected EventKeywords MatchAnyKeyword { get { return (EventKeywords)m_anyKeywordMask; } set { m_anyKeywordMask = unchecked((long)value); } } protected EventKeywords MatchAllKeyword { get { return (EventKeywords)m_allKeywordMask; } set { m_allKeywordMask = unchecked((long)value); } } @@ -390,10 +393,10 @@ namespace System.Diagnostics.Tracing /// private List> GetSessions() { - List liveSessionList = null; + List? liveSessionList = null; GetSessionInfo( - (int etwSessionId, long matchAllKeywords, ref List sessionList) => + (int etwSessionId, long matchAllKeywords, ref List? sessionList) => GetSessionInfoCallback(etwSessionId, matchAllKeywords, ref sessionList), ref liveSessionList); @@ -407,7 +410,7 @@ namespace System.Diagnostics.Tracing { int idx; if ((idx = IndexOfSessionInList(liveSessionList, s.etwSessionId)) < 0 || - (liveSessionList[idx].sessionIdBit != s.sessionIdBit)) + (liveSessionList![idx].sessionIdBit != s.sessionIdBit)) changedSessionList.Add(Tuple.Create(s, false)); } @@ -420,7 +423,7 @@ namespace System.Diagnostics.Tracing { int idx; if ((idx = IndexOfSessionInList(m_liveSessions, s.etwSessionId)) < 0 || - (m_liveSessions[idx].sessionIdBit != s.sessionIdBit)) + (m_liveSessions![idx].sessionIdBit != s.sessionIdBit)) changedSessionList.Add(Tuple.Create(s, true)); } } @@ -435,7 +438,7 @@ namespace System.Diagnostics.Tracing /// GetSessionInfo() passes in. /// private static void GetSessionInfoCallback(int etwSessionId, long matchAllKeywords, - ref List sessionList) + ref List? sessionList) { uint sessionIdBitMask = (uint)SessionMask.FromEventKeywords(unchecked((ulong)matchAllKeywords)); // an ETW controller that specifies more than the mandated bit for our EventSource @@ -461,14 +464,14 @@ namespace System.Diagnostics.Tracing sessionList.Add(new SessionInfo(val + 1, etwSessionId)); } - private delegate void SessionInfoCallback(int etwSessionId, long matchAllKeywords, ref List sessionList); + private delegate void SessionInfoCallback(int etwSessionId, long matchAllKeywords, ref List? sessionList); /// /// This method enumerates over all active ETW sessions that have enabled 'this.m_Guid' /// for the current process ID, calling 'action' for each session, and passing it the /// ETW session and the 'AllKeywords' the session enabled for the current provider. /// - private unsafe void GetSessionInfo(SessionInfoCallback action, ref List sessionList) + private unsafe void GetSessionInfo(SessionInfoCallback action, ref List? sessionList) { // We wish the EventSource package to be legal for Windows Store applications. // Currently EnumerateTraceGuidsEx is not an allowed API, so we avoid its use here @@ -578,7 +581,7 @@ namespace System.Diagnostics.Tracing /// Returns the index of the SesisonInfo from 'sessions' that has the specified 'etwSessionId' /// or -1 if the value is not present. /// - private static int IndexOfSessionInList(List sessions, int etwSessionId) + private static int IndexOfSessionInList(List? sessions, int etwSessionId) { if (sessions == null) return -1; @@ -600,7 +603,7 @@ namespace System.Diagnostics.Tracing /// starts, and the command being issued associated with that data. /// private unsafe bool GetDataFromController(int etwSessionId, - Interop.Advapi32.EVENT_FILTER_DESCRIPTOR* filterData, out ControllerCommand command, out byte[] data, out int dataStart) + Interop.Advapi32.EVENT_FILTER_DESCRIPTOR* filterData, out ControllerCommand command, out byte[]? data, out int dataStart) { data = null; dataStart = 0; @@ -727,7 +730,7 @@ namespace System.Diagnostics.Tracing // // // - private static unsafe object EncodeObject(ref object data, ref EventData* dataDescriptor, ref byte* dataBuffer, ref uint totalEventSize) + private static unsafe object? EncodeObject(ref object data, ref EventData* dataDescriptor, ref byte* dataBuffer, ref uint totalEventSize) /*++ Routine Description: @@ -753,8 +756,8 @@ namespace System.Diagnostics.Tracing Again: dataDescriptor->Reserved = 0; - string sRet = data as string; - byte[] blobRet = null; + string? sRet = data as string; + byte[]? blobRet = null; if (sRet != null) { @@ -921,7 +924,7 @@ namespace System.Diagnostics.Tracing if (data == null) sRet = ""; else - sRet = data.ToString(); + sRet = data.ToString()!; dataDescriptor->Size = ((uint)sRet.Length + 1) * 2; } @@ -931,7 +934,7 @@ namespace System.Diagnostics.Tracing dataDescriptor++; dataBuffer += s_basicTypeAllocationBufferSize; - return (object)sRet ?? (object)blobRet; + return (object?)sRet ?? (object?)blobRet; } /// @@ -989,7 +992,7 @@ namespace System.Diagnostics.Tracing int index; int refObjIndex = 0; List refObjPosition = new List(s_etwAPIMaxRefObjCount); - List dataRefObj = new List(s_etwAPIMaxRefObjCount); + List dataRefObj = new List(s_etwAPIMaxRefObjCount); EventData* userData = stackalloc EventData[2 * argCount]; for (int i = 0; i < 2 * argCount; i++) userData[i] = default; @@ -1008,8 +1011,7 @@ namespace System.Diagnostics.Tracing { if (eventPayload[index] != null) { - object supportedRefObj; - supportedRefObj = EncodeObject(ref eventPayload[index], ref userDataPtr, ref currentBuffer, ref totalEventSize); + object? supportedRefObj = EncodeObject(ref eventPayload[index], ref userDataPtr, ref currentBuffer, ref totalEventSize); if (supportedRefObj != null) { @@ -1061,8 +1063,8 @@ namespace System.Diagnostics.Tracing // // now fix any string arguments and set the pointer on the data descriptor // - fixed (char* v0 = (string)dataRefObj[0], v1 = (string)dataRefObj[1], v2 = (string)dataRefObj[2], v3 = (string)dataRefObj[3], - v4 = (string)dataRefObj[4], v5 = (string)dataRefObj[5], v6 = (string)dataRefObj[6], v7 = (string)dataRefObj[7]) + fixed (char* v0 = (string?)dataRefObj[0], v1 = (string?)dataRefObj[1], v2 = (string?)dataRefObj[2], v3 = (string?)dataRefObj[3], + v4 = (string?)dataRefObj[4], v5 = (string?)dataRefObj[5], v6 = (string?)dataRefObj[6], v7 = (string?)dataRefObj[7]) { userDataPtr = (EventData*)userData; if (dataRefObj[0] != null) @@ -1114,12 +1116,12 @@ namespace System.Diagnostics.Tracing rgGCHandle[i] = GCHandle.Alloc(dataRefObj[i], GCHandleType.Pinned); if (dataRefObj[i] is string) { - fixed (char* p = (string)dataRefObj[i]) + fixed (char* p = (string?)dataRefObj[i]) userDataPtr[refObjPosition[i]].Ptr = (ulong)p; } else { - fixed (byte* p = (byte[])dataRefObj[i]) + fixed (byte* p = (byte[]?)dataRefObj[i]) userDataPtr[refObjPosition[i]].Ptr = (ulong)p; } } diff --git a/src/System.Private.CoreLib/shared/System/Diagnostics/Tracing/EventSource.cs b/src/System.Private.CoreLib/shared/System/Diagnostics/Tracing/EventSource.cs index 50343b4..5a66257 100644 --- a/src/System.Private.CoreLib/shared/System/Diagnostics/Tracing/EventSource.cs +++ b/src/System.Private.CoreLib/shared/System/Diagnostics/Tracing/EventSource.cs @@ -2,6 +2,7 @@ // The .NET Foundation licenses this file to you under the MIT license. // See the LICENSE file in the project root for more information. +#nullable enable // This program uses code hyperlinks available as part of the HyperAddin Visual Studio plug-in. // It is available from http://www.codeplex.com/hyperAddin #if ES_BUILD_STANDALONE @@ -320,7 +321,7 @@ namespace System.Diagnostics.Tracing if (eventSourceType == null) throw new ArgumentNullException(nameof(eventSourceType)); - EventSourceAttribute attrib = (EventSourceAttribute)GetCustomAttributeHelper(eventSourceType, typeof(EventSourceAttribute)); + EventSourceAttribute? attrib = (EventSourceAttribute?)GetCustomAttributeHelper(eventSourceType, typeof(EventSourceAttribute)); string name = eventSourceType.Name; if (attrib != null) { @@ -366,7 +367,7 @@ namespace System.Diagnostics.Tracing /// The manifest XML fragment contains the string name of the DLL name in /// which it is embedded. This parameter specifies what name will be used /// The XML data string - public static string GenerateManifest(Type eventSourceType, string assemblyPathToIncludeInManifest) + public static string? GenerateManifest(Type eventSourceType, string? assemblyPathToIncludeInManifest) { return GenerateManifest(eventSourceType, assemblyPathToIncludeInManifest, EventManifestOptions.None); } @@ -382,12 +383,12 @@ namespace System.Diagnostics.Tracing /// The flags to customize manifest generation. If flags has bit OnlyIfNeededForRegistration specified /// this returns null when the eventSourceType does not require explicit registration /// The XML data string or null - public static string GenerateManifest(Type eventSourceType, string assemblyPathToIncludeInManifest, EventManifestOptions flags) + public static string? GenerateManifest(Type eventSourceType, string? assemblyPathToIncludeInManifest, EventManifestOptions flags) { if (eventSourceType == null) throw new ArgumentNullException(nameof(eventSourceType)); - byte[] manifestBytes = EventSource.CreateManifestAndDescriptors(eventSourceType, assemblyPathToIncludeInManifest, null, flags); + byte[]? manifestBytes = EventSource.CreateManifestAndDescriptors(eventSourceType, assemblyPathToIncludeInManifest, null, flags); return (manifestBytes == null) ? null : Encoding.UTF8.GetString(manifestBytes, 0, manifestBytes.Length); } @@ -401,6 +402,8 @@ namespace System.Diagnostics.Tracing var ret = new List(); lock (EventListener.EventListenersLock) { + Debug.Assert(EventListener.s_EventSources != null); + foreach (WeakReference eventSourceRef in EventListener.s_EventSources) { if (eventSourceRef.Target is EventSource eventSource && !eventSource.IsDisposed) @@ -419,7 +422,7 @@ namespace System.Diagnostics.Tracing /// The instance of EventSource to send the command to /// A positive user-defined EventCommand, or EventCommand.SendManifest /// A set of (name-argument, value-argument) pairs associated with the command - public static void SendCommand(EventSource eventSource, EventCommand command, IDictionary commandArguments) + public static void SendCommand(EventSource eventSource, EventCommand command, IDictionary? commandArguments) { if (eventSource == null) throw new ArgumentNullException(nameof(eventSource)); @@ -443,7 +446,7 @@ namespace System.Diagnostics.Tracing /// The event source constructor does not throw exceptions. Instead we remember any exception that /// was generated (it is also logged to Trace.WriteLine). /// - public Exception ConstructionException { get { return m_constructionException; } } + public Exception? ConstructionException { get { return m_constructionException; } } /// /// EventSources can have arbitrary string key-value pairs associated with them called Traits. @@ -453,7 +456,7 @@ namespace System.Diagnostics.Tracing /// /// The key to look up in the set of key-value pairs passed to the EventSource constructor /// The value string associated with key. Will return null if there is no such key. - public string GetTrait(string key) + public string? GetTrait(string key) { if (m_traits != null) { @@ -463,6 +466,7 @@ namespace System.Diagnostics.Tracing return m_traits[i + 1]; } } + return null; } @@ -485,7 +489,7 @@ namespace System.Diagnostics.Tracing // If we have an EventHandler attached to the EventSource before the first command arrives // It should get a chance to handle the deferred commands. - EventCommandEventArgs deferredCommands = m_deferredCommands; + EventCommandEventArgs? deferredCommands = m_deferredCommands; while (deferredCommands != null) { value(this, deferredCommands); @@ -658,15 +662,15 @@ namespace System.Diagnostics.Tracing /// /// See EventSourceSettings for more. /// A collection of key-value strings (must be an even number). - protected EventSource(EventSourceSettings settings, params string[] traits) + protected EventSource(EventSourceSettings settings, params string[]? traits) { m_config = ValidateSettings(settings); Guid eventSourceGuid; - string eventSourceName; + string? eventSourceName; - EventMetadata[] eventDescriptors; - byte[] manifest; + EventMetadata[]? eventDescriptors; + byte[]? manifest; GetMetadata(out eventSourceGuid, out eventSourceName, out eventDescriptors, out manifest); if (eventSourceGuid.Equals(Guid.Empty) || eventSourceName == null) @@ -726,7 +730,7 @@ namespace System.Diagnostics.Tracing } #endif - internal virtual void GetMetadata(out Guid eventSourceGuid, out string eventSourceName, out EventMetadata[] eventData, out byte[] manifestBytes) + internal virtual void GetMetadata(out Guid eventSourceGuid, out string? eventSourceName, out EventMetadata[]? eventData, out byte[]? manifestBytes) { // // In ProjectN subclasses need to override this method, and return the data from their EventSourceAttribute and EventAttribute annotations. @@ -858,7 +862,7 @@ namespace System.Diagnostics.Tracing // optimized for common signatures (strings) [SuppressMessage("Microsoft.Concurrency", "CA8001", Justification = "This does not need to be correct when racing with other threads")] - protected unsafe void WriteEvent(int eventId, string arg1) + protected unsafe void WriteEvent(int eventId, string? arg1) { if (m_eventSourceEnabled) { @@ -875,7 +879,7 @@ namespace System.Diagnostics.Tracing } [SuppressMessage("Microsoft.Concurrency", "CA8001", Justification = "This does not need to be correct when racing with other threads")] - protected unsafe void WriteEvent(int eventId, string arg1, string arg2) + protected unsafe void WriteEvent(int eventId, string? arg1, string? arg2) { if (m_eventSourceEnabled) { @@ -897,7 +901,7 @@ namespace System.Diagnostics.Tracing } [SuppressMessage("Microsoft.Concurrency", "CA8001", Justification = "This does not need to be correct when racing with other threads")] - protected unsafe void WriteEvent(int eventId, string arg1, string arg2, string arg3) + protected unsafe void WriteEvent(int eventId, string? arg1, string? arg2, string? arg3) { if (m_eventSourceEnabled) { @@ -925,7 +929,7 @@ namespace System.Diagnostics.Tracing // optimized for common signatures (string and ints) [SuppressMessage("Microsoft.Concurrency", "CA8001", Justification = "This does not need to be correct when racing with other threads")] - protected unsafe void WriteEvent(int eventId, string arg1, int arg2) + protected unsafe void WriteEvent(int eventId, string? arg1, int arg2) { if (m_eventSourceEnabled) { @@ -945,7 +949,7 @@ namespace System.Diagnostics.Tracing } [SuppressMessage("Microsoft.Concurrency", "CA8001", Justification = "This does not need to be correct when racing with other threads")] - protected unsafe void WriteEvent(int eventId, string arg1, int arg2, int arg3) + protected unsafe void WriteEvent(int eventId, string? arg1, int arg2, int arg3) { if (m_eventSourceEnabled) { @@ -969,7 +973,7 @@ namespace System.Diagnostics.Tracing // optimized for common signatures (string and longs) [SuppressMessage("Microsoft.Concurrency", "CA8001", Justification = "This does not need to be correct when racing with other threads")] - protected unsafe void WriteEvent(int eventId, string arg1, long arg2) + protected unsafe void WriteEvent(int eventId, string? arg1, long arg2) { if (m_eventSourceEnabled) { @@ -990,7 +994,7 @@ namespace System.Diagnostics.Tracing // optimized for common signatures (long and string) [SuppressMessage("Microsoft.Concurrency", "CA8001", Justification = "This does not need to be correct when racing with other threads")] - protected unsafe void WriteEvent(int eventId, long arg1, string arg2) + protected unsafe void WriteEvent(int eventId, long arg1, string? arg2) { if (m_eventSourceEnabled) { @@ -1011,7 +1015,7 @@ namespace System.Diagnostics.Tracing // optimized for common signatures (int and string) [SuppressMessage("Microsoft.Concurrency", "CA8001", Justification = "This does not need to be correct when racing with other threads")] - protected unsafe void WriteEvent(int eventId, int arg1, string arg2) + protected unsafe void WriteEvent(int eventId, int arg1, string? arg2) { if (m_eventSourceEnabled) { @@ -1031,7 +1035,7 @@ namespace System.Diagnostics.Tracing } [SuppressMessage("Microsoft.Concurrency", "CA8001", Justification = "This does not need to be correct when racing with other threads")] - protected unsafe void WriteEvent(int eventId, byte[] arg1) + protected unsafe void WriteEvent(int eventId, byte[]? arg1) { if (m_eventSourceEnabled) { @@ -1065,7 +1069,7 @@ namespace System.Diagnostics.Tracing } [SuppressMessage("Microsoft.Concurrency", "CA8001", Justification = "This does not need to be correct when racing with other threads")] - protected unsafe void WriteEvent(int eventId, long arg1, byte[] arg2) + protected unsafe void WriteEvent(int eventId, long arg1, byte[]? arg2) { if (m_eventSourceEnabled) { @@ -1212,9 +1216,9 @@ namespace System.Diagnostics.Tracing { if (m_eventSourceEnabled) { + Debug.Assert(m_eventData != null); // You must have initialized this if you enabled the source. try { - Debug.Assert(m_eventData != null); // You must have initialized this if you enabled the source. if (relatedActivityId != null) ValidateEventOpcodeForTransfer(ref m_eventData[eventId], m_eventData[eventId].Name); @@ -1260,7 +1264,7 @@ namespace System.Diagnostics.Tracing } else { - TraceLoggingEventTypes tlet = m_eventData[eventId].TraceLoggingEventTypes; + TraceLoggingEventTypes? tlet = m_eventData[eventId].TraceLoggingEventTypes; if (tlet == null) { tlet = new TraceLoggingEventTypes(m_eventData[eventId].Name, @@ -1362,14 +1366,14 @@ namespace System.Diagnostics.Tracing if (m_etwProvider != null) { m_etwProvider.Dispose(); - m_etwProvider = null; + m_etwProvider = null!; // TODO-NULLABLE: should not be nulled out on Dispose } #endif #if FEATURE_PERFTRACING if (m_eventPipeProvider != null) { m_eventPipeProvider.Dispose(); - m_eventPipeProvider = null; + m_eventPipeProvider = null!; // TODO-NULLABLE: should not be nulled out on Dispose } #endif } @@ -1388,7 +1392,7 @@ namespace System.Diagnostics.Tracing #region private private unsafe void WriteEventRaw( - string eventName, + string? eventName, ref EventDescriptor eventDescriptor, IntPtr eventHandle, Guid* activityID, @@ -1427,7 +1431,7 @@ namespace System.Diagnostics.Tracing { } // Used by the internal FrameworkEventSource constructor and the TraceLogging-style event source constructor - internal EventSource(Guid eventSourceGuid, string eventSourceName, EventSourceSettings settings, string[] traits = null) + internal EventSource(Guid eventSourceGuid, string eventSourceName, EventSourceSettings settings, string[]? traits = null) { m_config = ValidateSettings(settings); Initialize(eventSourceGuid, eventSourceName, traits); @@ -1440,7 +1444,7 @@ namespace System.Diagnostics.Tracing /// member, and any future access to the "Log" would throw the cached exception). /// [System.Diagnostics.CodeAnalysis.SuppressMessage("Microsoft.Naming", "CA1720:IdentifiersShouldNotContainTypeNames", MessageId = "guid")] - private unsafe void Initialize(Guid eventSourceGuid, string eventSourceName, string[] traits) + private unsafe void Initialize(Guid eventSourceGuid, string eventSourceName, string[]? traits) { try { @@ -1536,7 +1540,7 @@ namespace System.Diagnostics.Tracing // This is the most likely place for exceptions to happen. // Note that we are NOT resetting m_deferredCommands to NULL here, // We are giving for EventHandler that will be attached later - EventCommandEventArgs deferredCommands = m_deferredCommands; + EventCommandEventArgs? deferredCommands = m_deferredCommands; while (deferredCommands != null) { DoCommand(deferredCommands); // This can never throw, it catches them and reports the errors. @@ -1550,7 +1554,7 @@ namespace System.Diagnostics.Tracing if (eventSourceType == null) throw new ArgumentNullException(nameof(eventSourceType)); - EventSourceAttribute attrib = (EventSourceAttribute)GetCustomAttributeHelper(eventSourceType, typeof(EventSourceAttribute), flags); + EventSourceAttribute? attrib = (EventSourceAttribute?)GetCustomAttributeHelper(eventSourceType, typeof(EventSourceAttribute), flags); if (attrib != null && attrib.Name != null) return attrib.Name; @@ -1732,14 +1736,14 @@ namespace System.Diagnostics.Tracing hash.Start(); hash.Append(namespaceBytes); hash.Append(bytes); - Array.Resize(ref bytes, 16); + Array.Resize(ref bytes!, 16); // TODO-NULLABLE: https://github.com/dotnet/roslyn/issues/26761 hash.Finish(bytes); bytes[7] = unchecked((byte)((bytes[7] & 0x0F) | 0x50)); // Set high 4 bits of octet 7 to 5, as per RFC 4122 return new Guid(bytes); } - private unsafe object DecodeObject(int eventId, int parameterId, ref EventSource.EventData* data) + private unsafe object? DecodeObject(int eventId, int parameterId, ref EventSource.EventData* data) { // TODO FIX : We use reflection which in turn uses EventSource, right now we carefully avoid // the recursion, but can we do this in a robust way? @@ -1748,6 +1752,7 @@ namespace System.Diagnostics.Tracing // advance to next EventData in array ++data; + Debug.Assert(m_eventData != null); Type dataType = GetDataType(m_eventData[eventId], parameterId); Again: @@ -1884,9 +1889,9 @@ namespace System.Diagnostics.Tracing // Finds the Dispatcher (which holds the filtering state), for a given dispatcher for the current // eventSource). - private EventDispatcher GetDispatcher(EventListener listener) + private EventDispatcher? GetDispatcher(EventListener? listener) { - EventDispatcher dispatcher = m_Dispatchers; + EventDispatcher? dispatcher = m_Dispatchers; while (dispatcher != null) { if (dispatcher.m_Listener == listener) @@ -1900,9 +1905,9 @@ namespace System.Diagnostics.Tracing { if (m_eventSourceEnabled) { + Debug.Assert(m_eventData != null); // You must have initialized this if you enabled the source. try { - Debug.Assert(m_eventData != null); // You must have initialized this if you enabled the source. if (childActivityID != null) { ValidateEventOpcodeForTransfer(ref m_eventData[eventId], m_eventData[eventId].Name); @@ -1965,7 +1970,7 @@ namespace System.Diagnostics.Tracing } else { - TraceLoggingEventTypes tlet = m_eventData[eventId].TraceLoggingEventTypes; + TraceLoggingEventTypes? tlet = m_eventData[eventId].TraceLoggingEventTypes; if (tlet == null) { tlet = new TraceLoggingEventTypes(m_eventData[eventId].Name, @@ -2003,7 +2008,7 @@ namespace System.Diagnostics.Tracing else #endif // !ES_BUILD_STANDALONE { - object[] serializedArgs = SerializeEventArgs(eventId, args); + object?[] serializedArgs = SerializeEventArgs(eventId, args); WriteToAllListeners( eventId: eventId, osThreadId: null, @@ -2024,9 +2029,10 @@ namespace System.Diagnostics.Tracing } } - private unsafe object[] SerializeEventArgs(int eventId, object[] args) + private unsafe object?[] SerializeEventArgs(int eventId, object?[] args) { - TraceLoggingEventTypes eventTypes = m_eventData[eventId].TraceLoggingEventTypes; + Debug.Assert(m_eventData != null); + TraceLoggingEventTypes? eventTypes = m_eventData[eventId].TraceLoggingEventTypes; if (eventTypes == null) { eventTypes = new TraceLoggingEventTypes(m_eventData[eventId].Name, @@ -2034,7 +2040,7 @@ namespace System.Diagnostics.Tracing m_eventData[eventId].Parameters); Interlocked.CompareExchange(ref m_eventData[eventId].TraceLoggingEventTypes, eventTypes, null); } - var eventData = new object[eventTypes.typeInfos.Length]; + var eventData = new object?[eventTypes.typeInfos.Length]; for (int i = 0; i < eventTypes.typeInfos.Length; i++) { eventData[i] = eventTypes.typeInfos[i].GetData(args[i]); @@ -2083,6 +2089,7 @@ namespace System.Diagnostics.Tracing private unsafe void WriteToAllListeners(int eventId, Guid* activityID, Guid* childActivityID, int eventDataCount, EventSource.EventData* data) { + Debug.Assert(m_eventData != null); // We represent a byte[] as a integer denoting the length and then a blob of bytes in the data pointer. This causes a spurious // warning because eventDataCount is off by one for the byte[] case since a byte[] has 2 items associated it. So we want to check // that the number of parameters is correct against the byte[] case, but also we the args array would be one too long if @@ -2107,7 +2114,7 @@ namespace System.Diagnostics.Tracing paramCount = Math.Min(paramCount, eventDataCount); } - object[] args = new object[paramCount]; + object?[] args = new object[paramCount]; EventSource.EventData* dataPtr = data; for (int i = 0; i < paramCount; i++) @@ -2122,7 +2129,7 @@ namespace System.Diagnostics.Tracing } // helper for writing to all EventListeners attached the current eventSource. - internal unsafe void WriteToAllListeners(int eventId, uint* osThreadId, DateTime* timeStamp, Guid* activityID, Guid* childActivityID, params object[] args) + internal unsafe void WriteToAllListeners(int eventId, uint* osThreadId, DateTime* timeStamp, Guid* activityID, Guid* childActivityID, params object?[] args) { EventWrittenEventArgs eventCallbackArgs = new EventWrittenEventArgs(this); eventCallbackArgs.EventId = eventId; @@ -2134,17 +2141,19 @@ namespace System.Diagnostics.Tracing eventCallbackArgs.ActivityId = *activityID; if (childActivityID != null) eventCallbackArgs.RelatedActivityId = *childActivityID; + + Debug.Assert(m_eventData != null); eventCallbackArgs.EventName = m_eventData[eventId].Name; eventCallbackArgs.Message = m_eventData[eventId].Message; - eventCallbackArgs.Payload = new ReadOnlyCollection(args); + eventCallbackArgs.Payload = new ReadOnlyCollection(args); DispatchToAllListeners(eventId, childActivityID, eventCallbackArgs); } private unsafe void DispatchToAllListeners(int eventId, Guid* childActivityID, EventWrittenEventArgs eventCallbackArgs) { - Exception lastThrownException = null; - for (EventDispatcher dispatcher = m_Dispatchers; dispatcher != null; dispatcher = dispatcher.m_Next) + Exception? lastThrownException = null; + for (EventDispatcher? dispatcher = m_Dispatchers; dispatcher != null; dispatcher = dispatcher.m_Next) { Debug.Assert(dispatcher.m_EventEnabled != null); if (eventId == -1 || dispatcher.m_EventEnabled[eventId]) @@ -2225,11 +2234,11 @@ namespace System.Diagnostics.Tracing EventWrittenEventArgs eventCallbackArgs = new EventWrittenEventArgs(this); eventCallbackArgs.EventId = 0; eventCallbackArgs.Message = msg; - eventCallbackArgs.Payload = new ReadOnlyCollection(new List() { msg }); + eventCallbackArgs.Payload = new ReadOnlyCollection(new List() { msg }); eventCallbackArgs.PayloadNames = new ReadOnlyCollection(new List { "message" }); eventCallbackArgs.EventName = eventName; - for (EventDispatcher dispatcher = m_Dispatchers; dispatcher != null; dispatcher = dispatcher.m_Next) + for (EventDispatcher? dispatcher = m_Dispatchers; dispatcher != null; dispatcher = dispatcher.m_Next) { bool dispatcherEnabled = false; if (dispatcher.m_EventEnabled == null) @@ -2272,6 +2281,7 @@ namespace System.Diagnostics.Tracing if (!enable) return false; + Debug.Assert(m_eventData != null); EventLevel eventLevel = (EventLevel)m_eventData[eventNum].Descriptor.Level; EventKeywords eventKeywords = unchecked((EventKeywords)((ulong)m_eventData[eventNum].Descriptor.Keywords & (~(SessionMask.All.ToEventKeywords())))); @@ -2316,7 +2326,7 @@ namespace System.Diagnostics.Tracing } [System.Runtime.CompilerServices.MethodImpl(System.Runtime.CompilerServices.MethodImplOptions.NoInlining)] - private void ThrowEventSourceException(string eventName, Exception innerEx = null) + private void ThrowEventSourceException(string? eventName, Exception? innerEx = null) { // If we fail during out of band logging we may end up trying // to throw another EventSourceException, thus hitting a StackOverflowException. @@ -2370,7 +2380,7 @@ namespace System.Diagnostics.Tracing } } - private void ValidateEventOpcodeForTransfer(ref EventMetadata eventData, string eventName) + private void ValidateEventOpcodeForTransfer(ref EventMetadata eventData, string? eventName) { if ((EventOpcode)eventData.Descriptor.Opcode != EventOpcode.Send && (EventOpcode)eventData.Descriptor.Opcode != EventOpcode.Receive && @@ -2380,7 +2390,7 @@ namespace System.Diagnostics.Tracing } } - internal static EventOpcode GetOpcodeWithDefault(EventOpcode opcode, string eventName) + internal static EventOpcode GetOpcodeWithDefault(EventOpcode opcode, string? eventName) { if (opcode == EventOpcode.Info && eventName != null) { @@ -2409,11 +2419,11 @@ namespace System.Diagnostics.Tracing this.m_eventSource = eventSource; this.m_eventProviderType = providerType; } - protected override void OnControllerCommand(ControllerCommand command, IDictionary arguments, + protected override void OnControllerCommand(ControllerCommand command, IDictionary? arguments, int perEventSourceSessionId, int etwSessionId) { // We use null to represent the ETW EventListener. - EventListener listener = null; + EventListener? listener = null; m_eventSource.SendCommand(listener, m_eventProviderType, perEventSourceSessionId, etwSessionId, (EventCommand)command, IsEnabled(), Level, MatchAnyKeyword, arguments); } @@ -2485,10 +2495,10 @@ namespace System.Diagnostics.Tracing public byte TriggersActivityTracking; // count of listeners that marked this event as trigger for start of activity logging. #pragma warning restore 0649 public string Name; // the name of the event - public string Message; // If the event has a message associated with it, this is it. + public string? Message; // If the event has a message associated with it, this is it. public ParameterInfo[] Parameters; // TODO can we remove? - public TraceLoggingEventTypes TraceLoggingEventTypes; + public TraceLoggingEventTypes? TraceLoggingEventTypes; public EventActivityOptions ActivityOptions; #if ES_BUILD_PN @@ -2630,10 +2640,10 @@ namespace System.Diagnostics.Tracing // * The 'enabled' 'level', matchAnyKeyword' arguments are ignored (must be true, 0, 0). // // dispatcher == null has special meaning. It is the 'ETW' dispatcher. - internal void SendCommand(EventListener listener, EventProviderType eventProviderType, int perEventSourceSessionId, int etwSessionId, + internal void SendCommand(EventListener? listener, EventProviderType eventProviderType, int perEventSourceSessionId, int etwSessionId, EventCommand command, bool enable, EventLevel level, EventKeywords matchAnyKeyword, - IDictionary commandArguments) + IDictionary? commandArguments) { var commandArgs = new EventCommandEventArgs(command, commandArguments, this, listener, eventProviderType, perEventSourceSessionId, etwSessionId, enable, level, matchAnyKeyword); lock (EventListener.EventListenersLock) @@ -2784,8 +2794,10 @@ namespace System.Diagnostics.Tracing for (int i = 0; i < m_eventData.Length; i++) { bool isEnabledForAnyListener = false; - for (EventDispatcher dispatcher = m_Dispatchers; dispatcher != null; dispatcher = dispatcher.m_Next) + for (EventDispatcher? dispatcher = m_Dispatchers; dispatcher != null; dispatcher = dispatcher.m_Next) { + Debug.Assert(dispatcher.m_EventEnabled != null); + if (dispatcher.m_EventEnabled[i]) { isEnabledForAnyListener = true; @@ -2840,8 +2852,10 @@ namespace System.Diagnostics.Tracing /// of 'eventId. If value is 'false' disable the event for that dispatcher. If 'eventId' is out of /// range return false, otherwise true. /// - internal bool EnableEventForDispatcher(EventDispatcher dispatcher, EventProviderType eventProviderType, int eventId, bool value) + internal bool EnableEventForDispatcher(EventDispatcher? dispatcher, EventProviderType eventProviderType, int eventId, bool value) { + Debug.Assert(m_eventData != null); + if (dispatcher == null) { if (eventId >= m_eventData.Length) @@ -2857,6 +2871,7 @@ namespace System.Diagnostics.Tracing } else { + Debug.Assert(dispatcher.m_EventEnabled != null); if (eventId >= dispatcher.m_EventEnabled.Length) return false; dispatcher.m_EventEnabled[eventId] = value; @@ -2871,6 +2886,8 @@ namespace System.Diagnostics.Tracing /// private bool AnyEventEnabled() { + Debug.Assert(m_eventData != null); + for (int i = 0; i < m_eventData.Length; i++) if (m_eventData[i].EnabledForETW || m_eventData[i].EnabledForAnyListener #if FEATURE_PERFTRACING @@ -2894,9 +2911,9 @@ namespace System.Diagnostics.Tracing if (m_eventData == null) { Guid eventSourceGuid = Guid.Empty; - string eventSourceName = null; - EventMetadata[] eventData = null; - byte[] manifest = null; + string? eventSourceName = null; + EventMetadata[]? eventData = null; + byte[]? manifest = null; // Try the GetMetadata provided by the ILTransform in ProjectN. The default sets all to null, and in that case we fall back // to the reflection approach. @@ -2909,7 +2926,6 @@ namespace System.Diagnostics.Tracing m_rawManifest = CreateManifestAndDescriptors(this.GetType(), Name, this); Debug.Assert(m_eventData != null); - } else { @@ -2920,6 +2936,7 @@ namespace System.Diagnostics.Tracing m_rawManifest = manifest; } // TODO Enforce singleton pattern + Debug.Assert(EventListener.s_EventSources != null, "should be called within lock on EventListener.EventListenersLock which ensures s_EventSources to be initialized"); foreach (WeakReference eventSourceRef in EventListener.s_EventSources) { if (eventSourceRef.Target is EventSource eventSource && eventSource.Guid == m_guid && !eventSource.IsDisposed) @@ -2932,7 +2949,7 @@ namespace System.Diagnostics.Tracing } // Make certain all dispatchers also have their arrays initialized - EventDispatcher dispatcher = m_Dispatchers; + EventDispatcher? dispatcher = m_Dispatchers; while (dispatcher != null) { if (dispatcher.m_EventEnabled == null) @@ -2956,7 +2973,7 @@ namespace System.Diagnostics.Tracing // Send out the ETW manifest XML out to ETW // Today, we only send the manifest to ETW, custom listeners don't get it. - private unsafe bool SendManifest(byte[] rawManifest) + private unsafe bool SendManifest(byte[]? rawManifest) { bool success = true; @@ -3041,7 +3058,7 @@ namespace System.Diagnostics.Tracing // Helper to deal with the fact that the type we are reflecting over might be loaded in the ReflectionOnly context. // When that is the case, we have the build the custom assemblies on a member by hand. - internal static Attribute GetCustomAttributeHelper(MemberInfo member, Type attributeType, EventManifestOptions flags = EventManifestOptions.None) + internal static Attribute? GetCustomAttributeHelper(MemberInfo member, Type attributeType, EventManifestOptions flags = EventManifestOptions.None) { #if !ES_BUILD_PN // On ProjectN, ReflectionOnly() always equals false. AllowEventSourceOverride is an option that allows either Microsoft.Diagnostics.Tracing or @@ -3050,7 +3067,7 @@ namespace System.Diagnostics.Tracing #endif // !ES_BUILD_PN { // Let the runtime to the work for us, since we can execute code in this context. - Attribute firstAttribute = null; + Attribute? firstAttribute = null; foreach (var attribute in member.GetCustomAttributes(attributeType, false)) { firstAttribute = (Attribute)attribute; @@ -3071,17 +3088,17 @@ namespace System.Diagnostics.Tracing { if (AttributeTypeNamesMatch(attributeType, data.Constructor.ReflectedType)) { - Attribute attr = null; + Attribute? attr = null; Debug.Assert(data.ConstructorArguments.Count <= 1); if (data.ConstructorArguments.Count == 1) { - attr = (Attribute)Activator.CreateInstance(attributeType, new object[] { data.ConstructorArguments[0].Value }); + attr = (Attribute?)Activator.CreateInstance(attributeType, new object[] { data.ConstructorArguments[0].Value }); } else if (data.ConstructorArguments.Count == 0) { - attr = (Attribute)Activator.CreateInstance(attributeType); + attr = (Attribute?)Activator.CreateInstance(attributeType); } if (attr != null) @@ -3095,7 +3112,8 @@ namespace System.Diagnostics.Tracing if (p.PropertyType.IsEnum) { - value = Enum.Parse(p.PropertyType, value.ToString()); + string val = value.ToString()!; + value = Enum.Parse(p.PropertyType, val); } p.SetValue(attr, value, null); @@ -3140,47 +3158,49 @@ namespace System.Diagnostics.Tracing ); } - private static Type GetEventSourceBaseType(Type eventSourceType, bool allowEventSourceOverride, bool reflectionOnly) + private static Type? GetEventSourceBaseType(Type eventSourceType, bool allowEventSourceOverride, bool reflectionOnly) { + Type? ret = eventSourceType; + // return false for "object" and interfaces - if (eventSourceType.BaseType() == null) + if (ret.BaseType() == null) return null; // now go up the inheritance chain until hitting a concrete type ("object" at worse) do { - eventSourceType = eventSourceType.BaseType(); + ret = ret.BaseType(); } - while (eventSourceType != null && eventSourceType.IsAbstract()); + while (ret != null && ret.IsAbstract()); - if (eventSourceType != null) + if (ret != null) { if (!allowEventSourceOverride) { - if (reflectionOnly && eventSourceType.FullName != typeof(EventSource).FullName || - !reflectionOnly && eventSourceType != typeof(EventSource)) + if (reflectionOnly && ret.FullName != typeof(EventSource).FullName || + !reflectionOnly && ret != typeof(EventSource)) return null; } else { - if (eventSourceType.Name != "EventSource") + if (ret.Name != "EventSource") return null; } } - return eventSourceType; + return ret; } // Use reflection to look at the attributes of a class, and generate a manifest for it (as UTF8) and // return the UTF8 bytes. It also sets up the code:EventData structures needed to dispatch events // at run time. 'source' is the event source to place the descriptors. If it is null, // then the descriptors are not creaed, and just the manifest is generated. - private static byte[] CreateManifestAndDescriptors(Type eventSourceType, string eventSourceDllName, EventSource source, + private static byte[]? CreateManifestAndDescriptors(Type eventSourceType, string? eventSourceDllName, EventSource? source, EventManifestOptions flags = EventManifestOptions.None) { - ManifestBuilder manifest = null; + ManifestBuilder? manifest = null; bool bNeedsManifest = source != null ? !source.SelfDescribingEvents : true; - Exception exception = null; // exception that might get raised during validation b/c we couldn't/didn't recover from a previous error - byte[] res = null; + Exception? exception = null; // exception that might get raised during validation b/c we couldn't/didn't recover from a previous error + byte[]? res = null; if (eventSourceType.IsAbstract() && (flags & EventManifestOptions.Strict) == 0) return null; @@ -3197,8 +3217,8 @@ namespace System.Diagnostics.Tracing MethodInfo[] methods = eventSourceType.GetMethods(BindingFlags.DeclaredOnly | BindingFlags.NonPublic | BindingFlags.Public | BindingFlags.Instance); EventAttribute defaultEventAttribute; int eventId = 1; // The number given to an event that does not have a explicitly given ID. - EventMetadata[] eventData = null; - Dictionary eventsByName = null; + EventMetadata[]? eventData = null; + Dictionary? eventsByName = null; if (source != null || (flags & EventManifestOptions.Strict) != 0) { eventData = new EventMetadata[methods.Length + 1]; @@ -3206,8 +3226,8 @@ namespace System.Diagnostics.Tracing } // See if we have localization information. - ResourceManager resources = null; - EventSourceAttribute eventSourceAttrib = (EventSourceAttribute)GetCustomAttributeHelper(eventSourceType, typeof(EventSourceAttribute), flags); + ResourceManager? resources = null; + EventSourceAttribute? eventSourceAttrib = (EventSourceAttribute?)GetCustomAttributeHelper(eventSourceType, typeof(EventSourceAttribute), flags); if (eventSourceAttrib != null && eventSourceAttrib.LocalizationResources != null) resources = new ResourceManager(eventSourceAttrib.LocalizationResources, eventSourceType.Assembly()); @@ -3273,7 +3293,7 @@ namespace System.Diagnostics.Tracing ParameterInfo[] args = method.GetParameters(); // Get the EventDescriptor (from the Custom attributes) - EventAttribute eventAttribute = (EventAttribute)GetCustomAttributeHelper(method, typeof(EventAttribute), flags); + EventAttribute? eventAttribute = (EventAttribute?)GetCustomAttributeHelper(method, typeof(EventAttribute), flags); // Compat: until v4.5.1 we ignored any non-void returning methods as well as virtual methods for // the only reason of limiting the number of methods considered to be events. This broke a common @@ -3388,6 +3408,7 @@ namespace System.Diagnostics.Tracing bool hasRelatedActivityID = RemoveFirstArgIfRelatedActivityId(ref args); if (!(source != null && source.SelfDescribingEvents)) { + Debug.Assert(eventData != null); manifest.StartEvent(eventName, eventAttribute); for (int fieldIdx = 0; fieldIdx < args.Length; fieldIdx++) { @@ -3398,6 +3419,7 @@ namespace System.Diagnostics.Tracing if (source != null || (flags & EventManifestOptions.Strict) != 0) { + Debug.Assert(eventData != null); // Do checking for user errors (optional, but not a big deal so we do it). DebugCheckEvent(ref eventsByName, eventData, method, eventAttribute, manifest, flags); @@ -3413,11 +3435,11 @@ namespace System.Diagnostics.Tracing } #endif string eventKey = "event_" + eventName; - string msg = manifest.GetLocalizedMessage(eventKey, CultureInfo.CurrentUICulture, etwFormat: false); + string? msg = manifest.GetLocalizedMessage(eventKey, CultureInfo.CurrentUICulture, etwFormat: false); // overwrite inline message with the localized message if (msg != null) eventAttribute.Message = msg; - AddEventDescriptor(ref eventData, eventName, eventAttribute, args, hasRelatedActivityID); + AddEventDescriptor(ref eventData!, eventName, eventAttribute, args, hasRelatedActivityID); // TODO-NULLABLE: https://github.com/dotnet/roslyn/issues/34874 } } } @@ -3427,7 +3449,8 @@ namespace System.Diagnostics.Tracing if (source != null) { - TrimEventDescriptors(ref eventData); + Debug.Assert(eventData != null); + TrimEventDescriptors(ref eventData!); // TODO-NULLABLE: https://github.com/dotnet/roslyn/issues/34874 source.m_eventData = eventData; // officially initialize it. We do this at most once (it is racy otherwise). #if FEATURE_MANAGED_ETW_CHANNELS source.m_channelData = manifest.GetChannelData(); @@ -3459,9 +3482,11 @@ namespace System.Diagnostics.Tracing exception = e; } + Debug.Assert((flags & EventManifestOptions.Strict) != 0 && manifest != null); // TODO-NULLABLE: possible bug: if error is thrown before manifest is assigned in non-strict mode, this will NRE if ((flags & EventManifestOptions.Strict) != 0 && (manifest.Errors.Count > 0 || exception != null)) { string msg = string.Empty; + if (manifest.Errors.Count > 0) { bool firstError = true; @@ -3474,7 +3499,7 @@ namespace System.Diagnostics.Tracing } } else - msg = "Unexpected error: " + exception.Message; + msg = "Unexpected error: " + exception!.Message; throw new ArgumentException(msg, exception); } @@ -3544,6 +3569,7 @@ namespace System.Diagnostics.Tracing { if (eventData == null || eventData.Length <= eventAttribute.EventId) { + Debug.Assert(eventData != null); // TODO-NULLABLE: possible bug in the code: NRE when eventData == null EventMetadata[] newValues = new EventMetadata[Math.Max(eventData.Length + 16, eventAttribute.EventId + 1)]; Array.Copy(eventData, 0, newValues, 0, eventData.Length); eventData = newValues; @@ -3596,7 +3622,7 @@ namespace System.Diagnostics.Tracing { lock (EventListener.EventListenersLock) { - bool[] enabledArray = null; + bool[]? enabledArray = null; if (m_eventData != null) enabledArray = new bool[m_eventData.Length]; m_Dispatchers = new EventDispatcher(m_Dispatchers, enabledArray, listener); @@ -3606,7 +3632,7 @@ namespace System.Diagnostics.Tracing // Helper used by code:CreateManifestAndDescriptors to find user mistakes like reusing an event // index for two distinct events etc. Throws exceptions when it finds something wrong. - private static void DebugCheckEvent(ref Dictionary eventsByName, + private static void DebugCheckEvent(ref Dictionary? eventsByName, EventMetadata[] eventData, MethodInfo method, EventAttribute eventAttribute, ManifestBuilder manifest, EventManifestOptions options) { @@ -3912,13 +3938,13 @@ namespace System.Diagnostics.Tracing } // private instance state - private string m_name; // My friendly name (privided in ctor) + private string m_name = null!; // My friendly name (privided in ctor) internal int m_id; // A small integer that is unique to this instance. private Guid m_guid; // GUID representing the ETW eventSource to the OS. - internal volatile EventMetadata[] m_eventData; // None per-event data - private volatile byte[] m_rawManifest; // Bytes to send out representing the event schema + internal volatile EventMetadata[]? m_eventData; // None per-event data + private volatile byte[]? m_rawManifest; // Bytes to send out representing the event schema - private EventHandler m_eventCommandExecuted; + private EventHandler? m_eventCommandExecuted; private EventSourceSettings m_config; // configuration information @@ -3930,19 +3956,19 @@ namespace System.Diagnostics.Tracing internal EventKeywords m_matchAnyKeyword; // the logical OR of all levels enabled by any output dispatcher (zero is a special case) meaning 'all keywords' // Dispatching state - internal volatile EventDispatcher m_Dispatchers; // Linked list of code:EventDispatchers we write the data to (we also do ETW specially) + internal volatile EventDispatcher? m_Dispatchers; // Linked list of code:EventDispatchers we write the data to (we also do ETW specially) #if FEATURE_MANAGED_ETW - private volatile OverideEventProvider m_etwProvider; // This hooks up ETW commands to our 'OnEventCommand' callback + private volatile OverideEventProvider m_etwProvider = null!; // This hooks up ETW commands to our 'OnEventCommand' callback #endif #if FEATURE_PERFTRACING - private volatile OverideEventProvider m_eventPipeProvider; + private volatile OverideEventProvider m_eventPipeProvider = null!; #endif private bool m_completelyInited; // The EventSource constructor has returned without exception. - private Exception m_constructionException; // If there was an exception construction, this is it + private Exception? m_constructionException; // If there was an exception construction, this is it private byte m_outOfBandMessageCount; // The number of out of band messages sent (we throttle them - private EventCommandEventArgs m_deferredCommands;// If we get commands before we are fully we store them here and run the when we are fully inited. + private EventCommandEventArgs? m_deferredCommands;// If we get commands before we are fully we store them here and run the when we are fully inited. - private string[] m_traits; // Used to implement GetTraits + private string[]? m_traits; // Used to implement GetTraits internal static uint s_currentPid; // current process id, used in synthesizing quasi-GUIDs [ThreadStatic] @@ -3952,12 +3978,12 @@ namespace System.Diagnostics.Tracing private static bool m_EventSourceInDecodeObject = false; #if FEATURE_MANAGED_ETW_CHANNELS - internal volatile ulong[] m_channelData; + internal volatile ulong[]? m_channelData; #endif // We use a single instance of ActivityTracker for all EventSources instances to allow correlation between multiple event providers. // We have m_activityTracker field simply because instance field is more efficient than static field fetch. - ActivityTracker m_activityTracker; + ActivityTracker m_activityTracker = null!; internal const string s_ActivityStartSuffix = "Start"; internal const string s_ActivityStopSuffix = "Stop"; @@ -4041,7 +4067,7 @@ namespace System.Diagnostics.Tracing /// public class EventListener : IDisposable { - private event EventHandler _EventSourceCreated; + private event EventHandler? _EventSourceCreated; /// /// This event is raised whenever a new eventSource is 'attached' to the dispatcher. @@ -4061,11 +4087,11 @@ namespace System.Diagnostics.Tracing { CallBackForExistingEventSources(false, value); - this._EventSourceCreated = (EventHandler)Delegate.Combine(_EventSourceCreated, value); + this._EventSourceCreated = (EventHandler?)Delegate.Combine(_EventSourceCreated, value); } remove { - this._EventSourceCreated = (EventHandler)Delegate.Remove(_EventSourceCreated, value); + this._EventSourceCreated = (EventHandler?)Delegate.Remove(_EventSourceCreated, value); } } @@ -4092,7 +4118,10 @@ namespace System.Diagnostics.Tracing public EventListener() { // This will cause the OnEventSourceCreated callback to fire. - CallBackForExistingEventSources(true, (obj, args) => args.EventSource.AddListener((EventListener)obj)); + CallBackForExistingEventSources(true, (obj, args) => + { + args.EventSource!.AddListener((EventListener)obj!); + }); } /// @@ -4122,7 +4151,7 @@ namespace System.Diagnostics.Tracing EventListener prev = s_Listeners; for (;;) { - EventListener cur = prev.m_Next; + EventListener? cur = prev.m_Next; if (cur == null) break; if (cur == this) @@ -4183,7 +4212,7 @@ namespace System.Diagnostics.Tracing /// /// This call never has an effect on other EventListeners. /// - public void EnableEvents(EventSource eventSource, EventLevel level, EventKeywords matchAnyKeyword, IDictionary arguments) + public void EnableEvents(EventSource eventSource, EventLevel level, EventKeywords matchAnyKeyword, IDictionary? arguments) { if (eventSource == null) { @@ -4245,7 +4274,7 @@ namespace System.Diagnostics.Tracing /// internal protected virtual void OnEventSourceCreated(EventSource eventSource) { - EventHandler callBack = this._EventSourceCreated; + EventHandler? callBack = this._EventSourceCreated; if (callBack != null) { EventSourceCreatedEventArgs args = new EventSourceCreatedEventArgs(); @@ -4335,7 +4364,7 @@ namespace System.Diagnostics.Tracing { #endif // Add every existing dispatcher to the new EventSource - for (EventListener listener = s_Listeners; listener != null; listener = listener.m_Next) + for (EventListener? listener = s_Listeners; listener != null; listener = listener.m_Next) newEventSource.AddListener(listener); #if DEBUG } @@ -4356,10 +4385,11 @@ namespace System.Diagnostics.Tracing // such callbacks on process shutdown or appdomain so that unmanaged code will never // do this. This is what this callback is for. // See bug 724140 for more - private static void DisposeOnShutdown(object sender, EventArgs e) + private static void DisposeOnShutdown(object? sender, EventArgs e) { lock (EventListenersLock) { + Debug.Assert(s_EventSources != null); foreach (var esRef in s_EventSources) { if (esRef.Target is EventSource es) @@ -4380,20 +4410,22 @@ namespace System.Diagnostics.Tracing Debug.Assert(Monitor.IsEntered(EventListener.EventListenersLock)); #endif // Foreach existing EventSource in the appdomain + Debug.Assert(s_EventSources != null); foreach (WeakReference eventSourceRef in s_EventSources) { if (eventSourceRef.Target is EventSource eventSource) { + Debug.Assert(eventSource.m_Dispatchers != null); // Is the first output dispatcher the dispatcher we are removing? if (eventSource.m_Dispatchers.m_Listener == listenerToRemove) eventSource.m_Dispatchers = eventSource.m_Dispatchers.m_Next; else { // Remove 'listenerToRemove' from the eventSource.m_Dispatchers linked list. - EventDispatcher prev = eventSource.m_Dispatchers; + EventDispatcher? prev = eventSource.m_Dispatchers; for (;;) { - EventDispatcher cur = prev.m_Next; + EventDispatcher? cur = prev.m_Next; if (cur == null) { Debug.Fail("EventSource did not have a registered EventListener!"); @@ -4432,9 +4464,10 @@ namespace System.Diagnostics.Tracing lock (EventListenersLock) { + Debug.Assert(s_EventSources != null); // Get all listeners Dictionary allListeners = new Dictionary(); - EventListener cur = s_Listeners; + EventListener? cur = s_Listeners; while (cur != null) { allListeners.Add(cur, true); @@ -4451,7 +4484,7 @@ namespace System.Diagnostics.Tracing Debug.Assert(eventSource.m_id == id, "Unexpected event source ID."); // None listeners on eventSources exist in the dispatcher list. - EventDispatcher dispatcher = eventSource.m_Dispatchers; + EventDispatcher? dispatcher = eventSource.m_Dispatchers; while (dispatcher != null) { Debug.Assert(allListeners.ContainsKey(dispatcher.m_Listener), "EventSource has a listener not on the global list."); @@ -4485,7 +4518,7 @@ namespace System.Diagnostics.Tracing { if (s_EventSources == null) Interlocked.CompareExchange(ref s_EventSources, new List(2), null); - return s_EventSources; + return s_EventSources!; // TODO-NULLABLE: https://github.com/dotnet/roslyn/issues/34901 } } @@ -4493,6 +4526,8 @@ namespace System.Diagnostics.Tracing { lock (EventListenersLock) { + Debug.Assert(s_EventSources != null); + // Disallow creating EventListener reentrancy. if (s_CreatingListener) { @@ -4552,7 +4587,7 @@ namespace System.Diagnostics.Tracing } // Instance fields - internal volatile EventListener m_Next; // These form a linked list in s_Listeners + internal volatile EventListener? m_Next; // These form a linked list in s_Listeners // static fields @@ -4560,14 +4595,14 @@ namespace System.Diagnostics.Tracing /// The list of all listeners in the appdomain. Listeners must be explicitly disposed to remove themselves /// from this list. Note that EventSources point to their listener but NOT the reverse. /// - internal static EventListener s_Listeners; + internal static EventListener? s_Listeners; /// /// The list of all active eventSources in the appdomain. Note that eventSources do NOT /// remove themselves from this list this is a weak list and the GC that removes them may /// not have happened yet. Thus it can contain event sources that are dead (thus you have /// to filter those out. /// - internal static List s_EventSources; + internal static List? s_EventSources; /// /// Used to disallow reentrancy. @@ -4604,7 +4639,7 @@ namespace System.Diagnostics.Tracing /// /// Gets the arguments for the callback. /// - public IDictionary Arguments { get; internal set; } + public IDictionary? Arguments { get; internal set; } /// /// Enables the event that has the specified identifier. @@ -4632,8 +4667,8 @@ namespace System.Diagnostics.Tracing #region private - internal EventCommandEventArgs(EventCommand command, IDictionary arguments, EventSource eventSource, - EventListener listener, EventProviderType eventProviderType, int perEventSourceSessionId, int etwSessionId, bool enable, EventLevel level, EventKeywords matchAnyKeyword) + internal EventCommandEventArgs(EventCommand command, IDictionary? arguments, EventSource eventSource, + EventListener? listener, EventProviderType eventProviderType, int perEventSourceSessionId, int etwSessionId, bool enable, EventLevel level, EventKeywords matchAnyKeyword) { this.Command = command; this.Arguments = arguments; @@ -4648,17 +4683,17 @@ namespace System.Diagnostics.Tracing } internal EventSource eventSource; - internal EventDispatcher dispatcher; + internal EventDispatcher? dispatcher; internal EventProviderType eventProviderType; // These are the arguments of sendCommand and are only used for deferring commands until after we are fully initialized. - internal EventListener listener; + internal EventListener? listener; internal int perEventSourceSessionId; internal int etwSessionId; internal bool enable; internal EventLevel level; internal EventKeywords matchAnyKeyword; - internal EventCommandEventArgs nextCommand; // We form a linked list of these deferred commands. + internal EventCommandEventArgs? nextCommand; // We form a linked list of these deferred commands. #endregion } @@ -4671,7 +4706,7 @@ namespace System.Diagnostics.Tracing /// /// The EventSource that is attaching to the listener. /// - public EventSource EventSource + public EventSource? EventSource { get; internal set; @@ -4687,7 +4722,7 @@ namespace System.Diagnostics.Tracing /// /// The name of the event. /// - public string EventName + public string? EventName { get { @@ -4696,7 +4731,10 @@ namespace System.Diagnostics.Tracing return m_eventName; } else + { + Debug.Assert(m_eventSource.m_eventData != null); return m_eventSource.m_eventData[EventId].Name; + } } internal set { @@ -4742,12 +4780,12 @@ namespace System.Diagnostics.Tracing /// /// Gets the payload for the event. /// - public ReadOnlyCollection Payload { get; internal set; } + public ReadOnlyCollection? Payload { get; internal set; } /// /// Gets the payload argument names. /// - public ReadOnlyCollection PayloadNames + public ReadOnlyCollection? PayloadNames { get { @@ -4758,10 +4796,12 @@ namespace System.Diagnostics.Tracing { var names = new List(); + Debug.Assert(m_eventSource.m_eventData != null); foreach (var parameter in m_eventSource.m_eventData[EventId].Parameters) { names.Add(parameter.Name); } + m_payloadNames = new ReadOnlyCollection(names); } @@ -4789,6 +4829,7 @@ namespace System.Diagnostics.Tracing if (EventId < 0) // TraceLogging convention EventID == -1 return m_keywords; + Debug.Assert(m_eventSource.m_eventData != null); return (EventKeywords)m_eventSource.m_eventData[EventId].Descriptor.Keywords; } } @@ -4802,6 +4843,8 @@ namespace System.Diagnostics.Tracing { if (EventId <= 0) // TraceLogging convention EventID == -1 return m_opcode; + + Debug.Assert(m_eventSource.m_eventData != null); return (EventOpcode)m_eventSource.m_eventData[EventId].Descriptor.Opcode; } } @@ -4816,6 +4859,7 @@ namespace System.Diagnostics.Tracing if (EventId <= 0) // TraceLogging convention EventID == -1 return EventTask.None; + Debug.Assert(m_eventSource.m_eventData != null); return (EventTask)m_eventSource.m_eventData[EventId].Descriptor.Task; } } @@ -4829,6 +4873,8 @@ namespace System.Diagnostics.Tracing { if (EventId <= 0) // TraceLogging convention EventID == -1 return m_tags; + + Debug.Assert(m_eventSource.m_eventData != null); return m_eventSource.m_eventData[EventId].Tags; } } @@ -4836,14 +4882,19 @@ namespace System.Diagnostics.Tracing /// /// Gets the message for the event. If the message has {N} parameters they are NOT substituted. /// - public string Message + public string? Message { get { if (EventId <= 0) // TraceLogging convention EventID == -1 + { return m_message; + } else + { + Debug.Assert(m_eventSource.m_eventData != null); return m_eventSource.m_eventData[EventId].Message; + } } internal set { @@ -4862,6 +4913,8 @@ namespace System.Diagnostics.Tracing { if (EventId <= 0) // TraceLogging convention EventID == -1 return EventChannel.None; + + Debug.Assert(m_eventSource.m_eventData != null); return (EventChannel)m_eventSource.m_eventData[EventId].Descriptor.Channel; } } @@ -4876,6 +4929,8 @@ namespace System.Diagnostics.Tracing { if (EventId <= 0) // TraceLogging convention EventID == -1 return 0; + + Debug.Assert(m_eventSource.m_eventData != null); return m_eventSource.m_eventData[EventId].Descriptor.Version; } } @@ -4889,6 +4944,8 @@ namespace System.Diagnostics.Tracing { if (EventId <= 0) // TraceLogging convention EventID == -1 return m_level; + + Debug.Assert(m_eventSource.m_eventData != null); return (EventLevel)m_eventSource.m_eventData[EventId].Descriptor.Level; } } @@ -4932,10 +4989,10 @@ namespace System.Diagnostics.Tracing m_eventSource = eventSource; TimeStamp = DateTime.UtcNow; } - private string m_message; - private string m_eventName; + private string? m_message; + private string? m_eventName; private EventSource m_eventSource; - private ReadOnlyCollection m_payloadNames; + private ReadOnlyCollection? m_payloadNames; private Guid m_activityId; private long? m_osThreadId; internal EventTags m_tags; @@ -4954,13 +5011,13 @@ namespace System.Diagnostics.Tracing /// /// Overrides the ETW name of the event source (which defaults to the class name) /// - public string Name { get; set; } + public string? Name { get; set; } /// /// Overrides the default (calculated) Guid of an EventSource type. Explicitly defining a GUID is discouraged, /// except when upgrading existing ETW providers to using event sources. /// - public string Guid { get; set; } + public string? Guid { get; set; } /// /// @@ -4983,7 +5040,7 @@ namespace System.Diagnostics.Tracing /// which represent the payload values. /// /// - public string LocalizationResources { get; set; } + public string? LocalizationResources { get; set; } } /// @@ -5041,7 +5098,7 @@ namespace System.Diagnostics.Tracing /// use standard .NET substitution operators (eg {1}) in the string and they will be replaced /// with the 'ToString()' of the corresponding part of the event payload. /// - public string Message { get; set; } + public string? Message { get; set; } /// /// User defined options associated with the event. These do not have meaning to the EventSource but @@ -5116,12 +5173,12 @@ namespace System.Diagnostics.Tracing /// Specifies an SDDL access descriptor that controls access to the log file that backs the channel. /// See MSDN (https://docs.microsoft.com/en-us/windows/desktop/WES/eventmanifestschema-channeltype-complextype) for details. /// - public string Access { get; set; } + public string? Access { get; set; } /// /// Allows importing channels defined in external manifests /// - public string ImportChannel { get; set; } + public string? ImportChannel { get; set; } #endif // TODO: there is a convention that the name is the Provider/Type Should we provide an override? @@ -5302,7 +5359,7 @@ namespace System.Diagnostics.Tracing /// internal class EventDispatcher { - internal EventDispatcher(EventDispatcher next, bool[] eventEnabled, EventListener listener) + internal EventDispatcher(EventDispatcher? next, bool[]? eventEnabled, EventListener listener) { m_Next = next; m_EventEnabled = eventEnabled; @@ -5311,10 +5368,10 @@ namespace System.Diagnostics.Tracing // Instance fields readonly internal EventListener m_Listener; // The dispatcher this entry is for - internal bool[] m_EventEnabled; // For every event in a the eventSource, is it enabled? + internal bool[]? m_EventEnabled; // For every event in a the eventSource, is it enabled? // Only guaranteed to exist after a InsureInit() - internal EventDispatcher m_Next; // These form a linked list in code:EventSource.m_Dispatchers + internal EventDispatcher? m_Next; // These form a linked list in code:EventSource.m_Dispatchers // Of all listeners for that eventSource. } @@ -5360,7 +5417,7 @@ namespace System.Diagnostics.Tracing /// Build a manifest for 'providerName' with the given GUID, which will be packaged into 'dllName'. /// 'resources, is a resource manager. If specified all messages are localized using that manager. /// - public ManifestBuilder(string providerName, Guid providerGuid, string dllName, ResourceManager resources, + public ManifestBuilder(string providerName, Guid providerGuid, string? dllName, ResourceManager? resources, EventManifestOptions flags) { #if FEATURE_MANAGED_ETW_CHANNELS @@ -5451,7 +5508,7 @@ namespace System.Diagnostics.Tracing /// /// Add a channel. channelAttribute can be null /// - public void AddChannel(string name, int value, EventChannelAttribute channelAttribute) + public void AddChannel(string? name, int value, EventChannelAttribute? channelAttribute) { EventChannel chValue = (EventChannel)value; if (value < (int)EventChannel.Admin || value > 255) @@ -5590,6 +5647,8 @@ namespace System.Diagnostics.Tracing } public void EndEvent() { + Debug.Assert(eventName != null); + if (numParams > 0) { templates.Append(" ").AppendLine(); @@ -5605,7 +5664,7 @@ namespace System.Diagnostics.Tracing string msg; if (stringTab.TryGetValue("event_" + eventName, out msg)) { - msg = TranslateToManifestConvention(msg, eventName); + msg = TranslateToManifestConvention(msg!, eventName); // https://github.com/dotnet/roslyn/issues/26761 stringTab["event_" + eventName] = msg; } @@ -5695,13 +5754,13 @@ namespace System.Diagnostics.Tracing int channel = kvpair.Key; ChannelInfo channelInfo = kvpair.Value; - string channelType = null; + string? channelType = null; string elementName = "channel"; bool enabled = false; - string fullName = null; + string? fullName = null; #if FEATURE_ADVANCED_MANAGED_ETW_CHANNELS - string isolation = null; - string access = null; + string? isolation = null; + string? access = null; #endif if (channelInfo.Attribs != null) { @@ -5728,6 +5787,7 @@ namespace System.Diagnostics.Tracing sb.Append(" name=\"").Append(fullName).Append("\""); if (elementName == "channel") // not applicable to importChannels. { + Debug.Assert(channelInfo.Name != null); WriteMessageAttrib(sb, "channel", channelInfo.Name, null); sb.Append(" value=\"").Append(channel).Append("\""); if (channelType != null) @@ -5862,7 +5922,7 @@ namespace System.Diagnostics.Tracing // Output the localization information. sb.Append("").AppendLine(); - List cultures = null; + List? cultures = null; if (resources != null && (flags & EventManifestOptions.AllCultures) != 0) { cultures = GetSupportedCultures(resources); @@ -5884,7 +5944,7 @@ namespace System.Diagnostics.Tracing foreach (var stringKey in sortedStrings) { - string val = GetLocalizedMessage(stringKey, ci, etwFormat: true); + string? val = GetLocalizedMessage(stringKey, ci, etwFormat: true); sb.Append(" ").AppendLine(); } sb.Append(" ").AppendLine(); @@ -5901,14 +5961,14 @@ namespace System.Diagnostics.Tracing stringBuilder.Append(" name=\"").Append(name).Append("\""); WriteMessageAttrib(sb, elementName, name, name); } - private void WriteMessageAttrib(StringBuilder stringBuilder, string elementName, string name, string value) + private void WriteMessageAttrib(StringBuilder stringBuilder, string elementName, string name, string? value) { string key = elementName + "_" + name; // See if the user wants things localized. if (resources != null) { // resource fallback: strings in the neutral culture will take precedence over inline strings - string localizedString = resources.GetString(key, CultureInfo.InvariantCulture); + string? localizedString = resources.GetString(key, CultureInfo.InvariantCulture); if (localizedString != null) value = localizedString; } @@ -5925,12 +5985,12 @@ namespace System.Diagnostics.Tracing stringTab[key] = value; } - internal string GetLocalizedMessage(string key, CultureInfo ci, bool etwFormat) + internal string? GetLocalizedMessage(string key, CultureInfo ci, bool etwFormat) { - string value = null; + string? value = null; if (resources != null) { - string localizedString = resources.GetString(key, ci); + string? localizedString = resources.GetString(key, ci); if (localizedString != null) { value = localizedString; @@ -5969,9 +6029,9 @@ namespace System.Diagnostics.Tracing } #if FEATURE_MANAGED_ETW_CHANNELS - private string GetChannelName(EventChannel channel, string eventName, string eventMessage) + private string? GetChannelName(EventChannel channel, string eventName, string? eventMessage) { - ChannelInfo info = null; + ChannelInfo? info = null; if (channelTab == null || !channelTab.TryGetValue((int)channel, out info)) { if (channel < EventChannel.Admin) // || channel > EventChannel.Debug) @@ -5993,6 +6053,8 @@ namespace System.Diagnostics.Tracing // events that specify admin channels *must* have non-null "Message" attributes if (resources != null && eventMessage == null) eventMessage = resources.GetString("event_" + eventName, CultureInfo.InvariantCulture); + + Debug.Assert(info.Attribs != null); // TODO-NULLABLE: Bug - Attribs is documented that it can be null in which case this code will NRE if (info.Attribs.EventChannelType == EventChannelType.Admin && eventMessage == null) ManifestError(SR.Format(SR.EventSource_EventWithAdminChannelMustHaveMessage, eventName, info.Name)); return info.Name; @@ -6011,7 +6073,7 @@ namespace System.Diagnostics.Tracing return ret; } - private string GetOpcodeName(EventOpcode opcode, string eventName) + private string? GetOpcodeName(EventOpcode opcode, string eventName) { switch (opcode) { @@ -6039,12 +6101,13 @@ namespace System.Diagnostics.Tracing return "win:Receive"; } - string ret; + string? ret; if (opcodeTab == null || !opcodeTab.TryGetValue((int)opcode, out ret)) { ManifestError(SR.Format(SR.EventSource_UndefinedOpcode, opcode, eventName), true); ret = null; } + return ret; } @@ -6061,7 +6124,7 @@ namespace System.Diagnostics.Tracing { if ((keywords & bit) != 0) { - string keyword = null; + string? keyword = null; if ((keywordTab == null || !keywordTab.TryGetValue(bit, out keyword)) && (bit >= (ulong)0x1000000000000)) { @@ -6133,7 +6196,7 @@ namespace System.Diagnostics.Tracing } } - private static void UpdateStringBuilder(ref StringBuilder stringBuilder, string eventMessage, int startIndex, int count) + private static void UpdateStringBuilder(ref StringBuilder? stringBuilder, string eventMessage, int startIndex, int count) // TODO-NULLABLE: https://github.com/dotnet/roslyn/issues/26761 nullable in, non-nullable out { if (stringBuilder == null) stringBuilder = new StringBuilder(); @@ -6145,7 +6208,7 @@ namespace System.Diagnostics.Tracing // .NET conventions. We can't use RegEx for this (we are in mscorlib), so we do it 'by hand' private string TranslateToManifestConvention(string eventMessage, string evtName) { - StringBuilder stringBuilder = null; // We lazily create this + StringBuilder? stringBuilder = null; // We lazily create this int writtenSoFar = 0; int chIdx = -1; for (int i = 0; ;) @@ -6155,14 +6218,14 @@ namespace System.Diagnostics.Tracing if (stringBuilder == null) return eventMessage; UpdateStringBuilder(ref stringBuilder, eventMessage, writtenSoFar, i - writtenSoFar); - return stringBuilder.ToString(); + return stringBuilder!.ToString(); // TODO-NULLABLE: https://github.com/dotnet/roslyn/issues/26761 } if (eventMessage[i] == '%') { // handle format message escaping character '%' by escaping it UpdateStringBuilder(ref stringBuilder, eventMessage, writtenSoFar, i - writtenSoFar); - stringBuilder.Append("%%"); + stringBuilder!.Append("%%"); // TODO-NULLABLE: https://github.com/dotnet/roslyn/issues/26761 i++; writtenSoFar = i; } @@ -6171,7 +6234,7 @@ namespace System.Diagnostics.Tracing { // handle C# escaped '{" and '}' UpdateStringBuilder(ref stringBuilder, eventMessage, writtenSoFar, i - writtenSoFar); - stringBuilder.Append(eventMessage[i]); + stringBuilder!.Append(eventMessage[i]); // TODO-NULLABLE: https://github.com/dotnet/roslyn/issues/26761 i++; i++; writtenSoFar = i; } @@ -6190,7 +6253,7 @@ namespace System.Diagnostics.Tracing i++; UpdateStringBuilder(ref stringBuilder, eventMessage, writtenSoFar, leftBracket - writtenSoFar); int manIndex = TranslateIndexToManifestConvention(argNum, evtName); - stringBuilder.Append('%').Append(manIndex); + stringBuilder!.Append('%').Append(manIndex); // TODO-NULLABLE: https://github.com/dotnet/roslyn/issues/26761 // An '!' after the insert specifier {n} will be interpreted as a literal. // We'll escape it so that mc.exe does not attempt to consider it the // beginning of a format string. @@ -6210,7 +6273,7 @@ namespace System.Diagnostics.Tracing { UpdateStringBuilder(ref stringBuilder, eventMessage, writtenSoFar, i - writtenSoFar); i++; - stringBuilder.Append(s_escapes[chIdx]); + stringBuilder!.Append(s_escapes[chIdx]); // TODO-NULLABLE: https://github.com/dotnet/roslyn/issues/26761 writtenSoFar = i; } else @@ -6237,19 +6300,19 @@ namespace System.Diagnostics.Tracing #if FEATURE_MANAGED_ETW_CHANNELS class ChannelInfo { - public string Name; + public string? Name; public ulong Keywords; - public EventChannelAttribute Attribs; + public EventChannelAttribute? Attribs; } #endif Dictionary opcodeTab; - Dictionary taskTab; + Dictionary? taskTab; #if FEATURE_MANAGED_ETW_CHANNELS - Dictionary channelTab; + Dictionary? channelTab; #endif - Dictionary keywordTab; - Dictionary mapsTab; + Dictionary? keywordTab; + Dictionary? mapsTab; Dictionary stringTab; // Maps unlocalized strings to localized ones @@ -6271,15 +6334,15 @@ namespace System.Diagnostics.Tracing #if FEATURE_MANAGED_ETW_CHANNELS string providerName; #endif - ResourceManager resources; // Look up localized strings here. + ResourceManager? resources; // Look up localized strings here. EventManifestOptions flags; IList errors; // list of currently encountered errors Dictionary> perEventByteArrayArgIndices; // "event_name" -> List_of_Indices_of_Byte[]_Arg // State we track between StartEvent and EndEvent. - string eventName; // Name of the event currently being processed. + string? eventName; // Name of the event currently being processed. int numParams; // keeps track of the number of args the event has. - List byteArrArgIndices; // keeps track of the index of each byte[] argument + List? byteArrArgIndices; // keeps track of the index of each byte[] argument #endregion } diff --git a/src/System.Private.CoreLib/shared/System/Diagnostics/Tracing/FrameworkEventSource.cs b/src/System.Private.CoreLib/shared/System/Diagnostics/Tracing/FrameworkEventSource.cs index bbeaa24..7cd3c09 100644 --- a/src/System.Private.CoreLib/shared/System/Diagnostics/Tracing/FrameworkEventSource.cs +++ b/src/System.Private.CoreLib/shared/System/Diagnostics/Tracing/FrameworkEventSource.cs @@ -2,6 +2,7 @@ // The .NET Foundation licenses this file to you under the MIT license. // See the LICENSE file in the project root for more information. +#nullable enable using Internal.Runtime.CompilerServices; namespace System.Diagnostics.Tracing @@ -33,7 +34,7 @@ namespace System.Diagnostics.Tracing // optimized for common signatures (used by the ThreadTransferSend/Receive events) [NonEvent] - private unsafe void WriteEvent(int eventId, long arg1, int arg2, string arg3, bool arg4, int arg5, int arg6) + private unsafe void WriteEvent(int eventId, long arg1, int arg2, string? arg3, bool arg4, int arg5, int arg6) { if (IsEnabled()) { @@ -66,7 +67,7 @@ namespace System.Diagnostics.Tracing // optimized for common signatures (used by the ThreadTransferSend/Receive events) [NonEvent] - private unsafe void WriteEvent(int eventId, long arg1, int arg2, string arg3) + private unsafe void WriteEvent(int eventId, long arg1, int arg2, string? arg3) { if (IsEnabled()) { @@ -145,7 +146,7 @@ namespace System.Diagnostics.Tracing // 3 - WinRT dispatch operations // info - any additional information user code might consider interesting [Event(151, Level = EventLevel.Informational, Keywords = Keywords.ThreadTransfer, Task = Tasks.ThreadTransfer, Opcode = EventOpcode.Receive)] - public void ThreadTransferReceive(long id, int kind, string info) + public void ThreadTransferReceive(long id, int kind, string? info) { WriteEvent(151, id, kind, info); } @@ -153,7 +154,7 @@ namespace System.Diagnostics.Tracing // keep track of GC movements in order to correlate the value passed to XyzSend with the // (possibly changed) value passed to XyzReceive [NonEvent] - public unsafe void ThreadTransferReceiveObj(object id, int kind, string info) + public unsafe void ThreadTransferReceiveObj(object id, int kind, string? info) { ThreadTransferReceive((long)*((void**)Unsafe.AsPointer(ref id)), kind, info); } diff --git a/src/System.Private.CoreLib/shared/System/Diagnostics/Tracing/IEventProvider.cs b/src/System.Private.CoreLib/shared/System/Diagnostics/Tracing/IEventProvider.cs index bc7ab9a..010d9ea 100644 --- a/src/System.Private.CoreLib/shared/System/Diagnostics/Tracing/IEventProvider.cs +++ b/src/System.Private.CoreLib/shared/System/Diagnostics/Tracing/IEventProvider.cs @@ -2,6 +2,7 @@ // The .NET Foundation licenses this file to you under the MIT license. // See the LICENSE file in the project root for more information. +#nullable enable using System; using Microsoft.Win32; diff --git a/src/System.Private.CoreLib/shared/System/Diagnostics/Tracing/IncrementingEventCounter.cs b/src/System.Private.CoreLib/shared/System/Diagnostics/Tracing/IncrementingEventCounter.cs index 4058105..24a9ea2 100644 --- a/src/System.Private.CoreLib/shared/System/Diagnostics/Tracing/IncrementingEventCounter.cs +++ b/src/System.Private.CoreLib/shared/System/Diagnostics/Tracing/IncrementingEventCounter.cs @@ -2,6 +2,7 @@ // The .NET Foundation licenses this file to you under the MIT license. // See the LICENSE file in the project root for more information. +#nullable enable using System; using System.Diagnostics; using System.Collections; @@ -43,7 +44,7 @@ namespace System.Diagnostics.Tracing /// The value to increment by. public void Increment(double increment = 1) { - lock(MyLock) + lock (MyLock) { _increment += increment; } diff --git a/src/System.Private.CoreLib/shared/System/Diagnostics/Tracing/IncrementingPollingCounter.cs b/src/System.Private.CoreLib/shared/System/Diagnostics/Tracing/IncrementingPollingCounter.cs index 1b8ee75..44fd757 100644 --- a/src/System.Private.CoreLib/shared/System/Diagnostics/Tracing/IncrementingPollingCounter.cs +++ b/src/System.Private.CoreLib/shared/System/Diagnostics/Tracing/IncrementingPollingCounter.cs @@ -2,6 +2,7 @@ // The .NET Foundation licenses this file to you under the MIT license. // See the LICENSE file in the project root for more information. +#nullable enable using System; using System.Diagnostics; using System.Collections; @@ -36,6 +37,9 @@ namespace System.Diagnostics.Tracing /// The event source. public IncrementingPollingCounter(string name, EventSource eventSource, Func totalValueProvider) : base(name, eventSource) { + if (totalValueProvider == null) + throw new ArgumentNullException(nameof(totalValueProvider)); + _totalValueProvider = totalValueProvider; } @@ -53,7 +57,7 @@ namespace System.Diagnostics.Tracing { try { - lock(MyLock) + lock (MyLock) { _increment = _totalValueProvider(); } diff --git a/src/System.Private.CoreLib/shared/System/Diagnostics/Tracing/PollingCounter.cs b/src/System.Private.CoreLib/shared/System/Diagnostics/Tracing/PollingCounter.cs index e057718..ab69a1e 100644 --- a/src/System.Private.CoreLib/shared/System/Diagnostics/Tracing/PollingCounter.cs +++ b/src/System.Private.CoreLib/shared/System/Diagnostics/Tracing/PollingCounter.cs @@ -2,6 +2,7 @@ // The .NET Foundation licenses this file to you under the MIT license. // See the LICENSE file in the project root for more information. +#nullable enable using System; using System.Diagnostics; using System.Collections; @@ -34,6 +35,9 @@ namespace System.Diagnostics.Tracing /// The event source. public PollingCounter(string name, EventSource eventSource, Func metricProvider) : base(name, eventSource) { + if (metricProvider == null) + throw new ArgumentNullException(nameof(metricProvider)); + _metricProvider = metricProvider; } diff --git a/src/System.Private.CoreLib/shared/System/Diagnostics/Tracing/StubEnvironment.cs b/src/System.Private.CoreLib/shared/System/Diagnostics/Tracing/StubEnvironment.cs index d376389..7487c0f 100644 --- a/src/System.Private.CoreLib/shared/System/Diagnostics/Tracing/StubEnvironment.cs +++ b/src/System.Private.CoreLib/shared/System/Diagnostics/Tracing/StubEnvironment.cs @@ -2,6 +2,7 @@ // The .NET Foundation licenses this file to you under the MIT license. // See the LICENSE file in the project root for more information. +#nullable enable using System; using System.Collections.Generic; @@ -28,24 +29,18 @@ namespace System.Diagnostics.Tracing.Internal public static int TickCount { get { return System.Environment.TickCount; } } - public static string GetResourceString(string key, params object[] args) + public static string GetResourceString(string key, params object?[] args) { - string fmt = rm.GetString(key); + string? fmt = rm.GetString(key); if (fmt != null) return string.Format(fmt, args); - string sargs = string.Empty; - foreach(var arg in args) - { - if (sargs != string.Empty) - sargs += ", "; - sargs += arg.ToString(); - } + string sargs = string.Join(", ", args); return key + " (" + sargs + ")"; } - public static string GetRuntimeResourceString(string key, params object[] args) + public static string GetRuntimeResourceString(string key, params object?[] args) { return GetResourceString(key, args); } @@ -313,9 +308,9 @@ namespace Microsoft.Reflection } return fieldInfos.ToArray(); } - public static Type GetNestedType(this Type type, string nestedTypeName) + public static Type? GetNestedType(this Type type, string nestedTypeName) { - TypeInfo ti = null; + TypeInfo? ti = null; foreach(var nt in type.GetTypeInfo().DeclaredNestedTypes) { if (nt.Name == nestedTypeName) diff --git a/src/System.Private.CoreLib/shared/System/Diagnostics/Tracing/TraceLogging/ArrayTypeInfo.cs b/src/System.Private.CoreLib/shared/System/Diagnostics/Tracing/TraceLogging/ArrayTypeInfo.cs index 5771354..83d37c4 100644 --- a/src/System.Private.CoreLib/shared/System/Diagnostics/Tracing/TraceLogging/ArrayTypeInfo.cs +++ b/src/System.Private.CoreLib/shared/System/Diagnostics/Tracing/TraceLogging/ArrayTypeInfo.cs @@ -2,6 +2,7 @@ // The .NET Foundation licenses this file to you under the MIT license. // See the LICENSE file in the project root for more information. +#nullable enable using System; using System.Collections.Generic; @@ -23,7 +24,7 @@ namespace System.Diagnostics.Tracing public override void WriteMetadata( TraceLoggingMetadataCollector collector, - string name, + string? name, EventFieldFormat format) { collector.BeginBufferedArray(); @@ -36,7 +37,7 @@ namespace System.Diagnostics.Tracing var bookmark = collector.BeginBufferedArray(); var count = 0; - Array array = (Array)value.ReferenceValue; + Array? array = (Array?)value.ReferenceValue; if (array != null) { count = array.Length; @@ -49,10 +50,11 @@ namespace System.Diagnostics.Tracing collector.EndBufferedArray(bookmark, count); } - public override object GetData(object value) + public override object? GetData(object? value) { + Debug.Assert(value != null, "null accepted only for some overrides"); var array = (Array)value; - var serializedArray = new object[array.Length]; + var serializedArray = new object?[array.Length]; for (int i = 0; i < array.Length; i++) { serializedArray[i] = this.elementInfo.GetData(array.GetValue(i)); diff --git a/src/System.Private.CoreLib/shared/System/Diagnostics/Tracing/TraceLogging/ConcurrentSet.cs b/src/System.Private.CoreLib/shared/System/Diagnostics/Tracing/TraceLogging/ConcurrentSet.cs index 76c01c6..32f4799 100644 --- a/src/System.Private.CoreLib/shared/System/Diagnostics/Tracing/TraceLogging/ConcurrentSet.cs +++ b/src/System.Private.CoreLib/shared/System/Diagnostics/Tracing/TraceLogging/ConcurrentSet.cs @@ -2,6 +2,7 @@ // The .NET Foundation licenses this file to you under the MIT license. // See the LICENSE file in the project root for more information. +#nullable enable using System; using Interlocked = System.Threading.Interlocked; @@ -26,11 +27,11 @@ namespace System.Diagnostics.Tracing internal struct ConcurrentSet where ItemType : ConcurrentSetItem { - private ItemType[] items; + private ItemType[]? items; - public ItemType TryGet(KeyType key) + public ItemType? TryGet(KeyType key) { - ItemType item; + ItemType? item; var oldItems = this.items; if (oldItems != null) @@ -110,7 +111,7 @@ namespace System.Diagnostics.Tracing Array.Copy(oldItems, lo, newItems, lo + 1, oldLength - lo); } - newItems = Interlocked.CompareExchange(ref this.items, newItems, oldItems); + newItems = Interlocked.CompareExchange(ref this.items, newItems, oldItems)!; // TODO-NULLABLE: https://github.com/dotnet/roslyn/issues/34901 if (oldItems != newItems) { oldItems = newItems; diff --git a/src/System.Private.CoreLib/shared/System/Diagnostics/Tracing/TraceLogging/ConcurrentSetItem.cs b/src/System.Private.CoreLib/shared/System/Diagnostics/Tracing/TraceLogging/ConcurrentSetItem.cs index 558dbf6..4dbd45e 100644 --- a/src/System.Private.CoreLib/shared/System/Diagnostics/Tracing/TraceLogging/ConcurrentSetItem.cs +++ b/src/System.Private.CoreLib/shared/System/Diagnostics/Tracing/TraceLogging/ConcurrentSetItem.cs @@ -2,6 +2,7 @@ // The .NET Foundation licenses this file to you under the MIT license. // See the LICENSE file in the project root for more information. +#nullable enable using System; #if ES_BUILD_STANDALONE diff --git a/src/System.Private.CoreLib/shared/System/Diagnostics/Tracing/TraceLogging/DataCollector.cs b/src/System.Private.CoreLib/shared/System/Diagnostics/Tracing/TraceLogging/DataCollector.cs index 11c18a2..6afd187 100644 --- a/src/System.Private.CoreLib/shared/System/Diagnostics/Tracing/TraceLogging/DataCollector.cs +++ b/src/System.Private.CoreLib/shared/System/Diagnostics/Tracing/TraceLogging/DataCollector.cs @@ -2,6 +2,7 @@ // The .NET Foundation licenses this file to you under the MIT license. // See the LICENSE file in the project root for more information. +#nullable enable using System; using System.Resources; using System.Runtime.InteropServices; @@ -35,7 +36,7 @@ namespace System.Diagnostics.Tracing private byte* scratch; private EventSource.EventData* datas; private GCHandle* pins; - private byte[] buffer; + private byte[]? buffer; private int bufferPos; private int bufferNesting; // We may merge many fields int a single blob. If we are doing this we increment this. private bool writingScalars; @@ -102,6 +103,8 @@ namespace System.Diagnostics.Tracing var oldPos = this.bufferPos; this.bufferPos = checked(this.bufferPos + size); this.EnsureBuffer(); + Debug.Assert(buffer != null); + for (int i = 0; i != size; i++, oldPos++) { this.buffer[oldPos] = pb[i]; @@ -109,7 +112,7 @@ namespace System.Diagnostics.Tracing } } - internal void AddBinary(string value, int size) + internal void AddBinary(string? value, int size) { if (size > ushort.MaxValue) { @@ -135,6 +138,8 @@ namespace System.Diagnostics.Tracing var oldPos = this.bufferPos; this.bufferPos = checked(this.bufferPos + size); this.EnsureBuffer(); + Debug.Assert(buffer != null); + fixed (void* p = value) { Marshal.Copy((IntPtr)p, buffer, oldPos, size); @@ -143,7 +148,7 @@ namespace System.Diagnostics.Tracing } } - internal unsafe void AddNullTerminatedString(string value) + internal unsafe void AddNullTerminatedString(string? value) { // Treat null strings as empty strings. if (value == null) @@ -175,6 +180,8 @@ namespace System.Diagnostics.Tracing var oldPos = this.bufferPos; this.bufferPos = checked(this.bufferPos + size); this.EnsureBuffer(); + Debug.Assert(buffer != null); + fixed (void* p = value) { Marshal.Copy((IntPtr)p, buffer, oldPos, size); @@ -187,7 +194,7 @@ namespace System.Diagnostics.Tracing this.AddArray(value, size, 1); } - internal void AddArray(Array value, int length, int itemSize) + internal void AddArray(Array? value, int length, int itemSize) { if (length > ushort.MaxValue) { @@ -214,6 +221,7 @@ namespace System.Diagnostics.Tracing var oldPos = this.bufferPos; this.bufferPos = checked(this.bufferPos + size); this.EnsureBuffer(); + Debug.Assert(value != null && buffer != null); Buffer.BlockCopy(value, 0, this.buffer, oldPos, size); } } @@ -238,6 +246,7 @@ namespace System.Diagnostics.Tracing internal void EndBufferedArray(int bookmark, int count) { this.EnsureBuffer(); + Debug.Assert(buffer != null); this.buffer[bookmark - 2] = unchecked((byte)count); this.buffer[bookmark - 1] = unchecked((byte)(count >> 8)); this.EndBuffered(); @@ -270,6 +279,7 @@ namespace System.Diagnostics.Tracing */ this.EnsureBuffer(); + Debug.Assert(buffer != null); this.PinArray(this.buffer, this.bufferPos); this.buffer = null; this.bufferPos = 0; @@ -307,7 +317,7 @@ namespace System.Diagnostics.Tracing Array.Resize(ref this.buffer, newSize); } - private void PinArray(object value, int size) + private void PinArray(object? value, int size) { var pinsTemp = this.pins; if (this.pinsEnd <= pinsTemp) diff --git a/src/System.Private.CoreLib/shared/System/Diagnostics/Tracing/TraceLogging/EmptyStruct.cs b/src/System.Private.CoreLib/shared/System/Diagnostics/Tracing/TraceLogging/EmptyStruct.cs index bc7fb8c..38dd167 100644 --- a/src/System.Private.CoreLib/shared/System/Diagnostics/Tracing/TraceLogging/EmptyStruct.cs +++ b/src/System.Private.CoreLib/shared/System/Diagnostics/Tracing/TraceLogging/EmptyStruct.cs @@ -2,6 +2,7 @@ // The .NET Foundation licenses this file to you under the MIT license. // See the LICENSE file in the project root for more information. +#nullable enable #if ES_BUILD_STANDALONE namespace Microsoft.Diagnostics.Tracing #else diff --git a/src/System.Private.CoreLib/shared/System/Diagnostics/Tracing/TraceLogging/EnumHelper.cs b/src/System.Private.CoreLib/shared/System/Diagnostics/Tracing/TraceLogging/EnumHelper.cs index 7a23378..10cac02 100644 --- a/src/System.Private.CoreLib/shared/System/Diagnostics/Tracing/TraceLogging/EnumHelper.cs +++ b/src/System.Private.CoreLib/shared/System/Diagnostics/Tracing/TraceLogging/EnumHelper.cs @@ -1,6 +1,8 @@ // Licensed to the .NET Foundation under one or more agreements. // The .NET Foundation licenses this file to you under the MIT license. // See the LICENSE file in the project root for more information. + +#nullable enable #if EVENTSOURCE_GENERICS ?using System; using System.Reflection; diff --git a/src/System.Private.CoreLib/shared/System/Diagnostics/Tracing/TraceLogging/EnumerableTypeInfo.cs b/src/System.Private.CoreLib/shared/System/Diagnostics/Tracing/TraceLogging/EnumerableTypeInfo.cs index 74a3fa2..9a98458 100644 --- a/src/System.Private.CoreLib/shared/System/Diagnostics/Tracing/TraceLogging/EnumerableTypeInfo.cs +++ b/src/System.Private.CoreLib/shared/System/Diagnostics/Tracing/TraceLogging/EnumerableTypeInfo.cs @@ -2,6 +2,7 @@ // The .NET Foundation licenses this file to you under the MIT license. // See the LICENSE file in the project root for more information. +#nullable enable using System; using System.Collections; using System.Collections.Generic; @@ -24,7 +25,7 @@ namespace System.Diagnostics.Tracing public override void WriteMetadata( TraceLoggingMetadataCollector collector, - string name, + string? name, EventFieldFormat format) { collector.BeginBufferedArray(); @@ -37,7 +38,7 @@ namespace System.Diagnostics.Tracing var bookmark = collector.BeginBufferedArray(); var count = 0; - IEnumerable enumerable = (IEnumerable)value.ReferenceValue; + IEnumerable? enumerable = (IEnumerable?)value.ReferenceValue; if (enumerable != null) { foreach (var element in enumerable) @@ -50,10 +51,11 @@ namespace System.Diagnostics.Tracing collector.EndBufferedArray(bookmark, count); } - public override object GetData(object value) + public override object? GetData(object? value) { + Debug.Assert(value != null, "null accepted only for some overrides"); var iterType = (IEnumerable)value; - List serializedEnumerable = new List(); + List serializedEnumerable = new List(); foreach (var element in iterType) { serializedEnumerable.Add(elementInfo.GetData(element)); diff --git a/src/System.Private.CoreLib/shared/System/Diagnostics/Tracing/TraceLogging/EventDataAttribute.cs b/src/System.Private.CoreLib/shared/System/Diagnostics/Tracing/TraceLogging/EventDataAttribute.cs index cdedf13..509f885 100644 --- a/src/System.Private.CoreLib/shared/System/Diagnostics/Tracing/TraceLogging/EventDataAttribute.cs +++ b/src/System.Private.CoreLib/shared/System/Diagnostics/Tracing/TraceLogging/EventDataAttribute.cs @@ -2,6 +2,7 @@ // The .NET Foundation licenses this file to you under the MIT license. // See the LICENSE file in the project root for more information. +#nullable enable using System; #if ES_BUILD_STANDALONE @@ -53,7 +54,7 @@ namespace System.Diagnostics.Tracing /// else /// fieldName = typeof(T).Name; /// - public string Name + public string? Name { get; set; diff --git a/src/System.Private.CoreLib/shared/System/Diagnostics/Tracing/TraceLogging/EventFieldAttribute.cs b/src/System.Private.CoreLib/shared/System/Diagnostics/Tracing/TraceLogging/EventFieldAttribute.cs index 1a298c2..3d9da9d 100644 --- a/src/System.Private.CoreLib/shared/System/Diagnostics/Tracing/TraceLogging/EventFieldAttribute.cs +++ b/src/System.Private.CoreLib/shared/System/Diagnostics/Tracing/TraceLogging/EventFieldAttribute.cs @@ -2,6 +2,7 @@ // The .NET Foundation licenses this file to you under the MIT license. // See the LICENSE file in the project root for more information. +#nullable enable using System; #if ES_BUILD_STANDALONE @@ -58,7 +59,7 @@ namespace System.Diagnostics.Tracing /// as the event field's name. /// TODO REMOVE /// - internal string Name + internal string? Name { get; set; diff --git a/src/System.Private.CoreLib/shared/System/Diagnostics/Tracing/TraceLogging/EventIgnoreAttribute.cs b/src/System.Private.CoreLib/shared/System/Diagnostics/Tracing/TraceLogging/EventIgnoreAttribute.cs index 769345f..51c457d 100644 --- a/src/System.Private.CoreLib/shared/System/Diagnostics/Tracing/TraceLogging/EventIgnoreAttribute.cs +++ b/src/System.Private.CoreLib/shared/System/Diagnostics/Tracing/TraceLogging/EventIgnoreAttribute.cs @@ -2,6 +2,7 @@ // The .NET Foundation licenses this file to you under the MIT license. // See the LICENSE file in the project root for more information. +#nullable enable using System; #if ES_BUILD_STANDALONE diff --git a/src/System.Private.CoreLib/shared/System/Diagnostics/Tracing/TraceLogging/EventPayload.cs b/src/System.Private.CoreLib/shared/System/Diagnostics/Tracing/TraceLogging/EventPayload.cs index 22abdbe..45a66a3 100644 --- a/src/System.Private.CoreLib/shared/System/Diagnostics/Tracing/TraceLogging/EventPayload.cs +++ b/src/System.Private.CoreLib/shared/System/Diagnostics/Tracing/TraceLogging/EventPayload.cs @@ -2,6 +2,7 @@ // The .NET Foundation licenses this file to you under the MIT license. // See the LICENSE file in the project root for more information. +#nullable enable using System; using System.Collections.Generic; using System.Collections; @@ -24,9 +25,9 @@ namespace System.Diagnostics.Tracing /// EventSource APIs. /// Preserving the order of the elements as they were found inside user defined types is the most important characteristic of this class. /// - internal class EventPayload : IDictionary + internal class EventPayload : IDictionary { - internal EventPayload(List payloadNames, List payloadValues) + internal EventPayload(List payloadNames, List payloadValues) { Debug.Assert(payloadNames.Count == payloadValues.Count); @@ -35,9 +36,9 @@ namespace System.Diagnostics.Tracing } public ICollection Keys { get { return m_names; } } - public ICollection Values { get { return m_values; } } + public ICollection Values { get { return m_values; } } - public object this[string key] + public object? this[string key] { get { @@ -62,12 +63,12 @@ namespace System.Diagnostics.Tracing } } - public void Add(string key, object value) + public void Add(string key, object? value) { throw new System.NotSupportedException(); } - public void Add(KeyValuePair payloadEntry) + public void Add(KeyValuePair payloadEntry) { throw new System.NotSupportedException(); } @@ -77,7 +78,7 @@ namespace System.Diagnostics.Tracing throw new System.NotSupportedException(); } - public bool Contains(KeyValuePair entry) + public bool Contains(KeyValuePair entry) { return ContainsKey(entry.Key); } @@ -99,21 +100,21 @@ namespace System.Diagnostics.Tracing public bool IsReadOnly { get { return true; } } - public IEnumerator> GetEnumerator() + public IEnumerator> GetEnumerator() { for (int i = 0; i < Keys.Count; i++) { - yield return new KeyValuePair(this.m_names[i], this.m_values[i]); + yield return new KeyValuePair(this.m_names[i], this.m_values[i]); } } IEnumerator IEnumerable.GetEnumerator() { - var instance = this as IEnumerable>; + var instance = this as IEnumerable>; return instance.GetEnumerator(); } - public void CopyTo(KeyValuePair[] payloadEntries, int count) + public void CopyTo(KeyValuePair[] payloadEntries, int count) { throw new System.NotSupportedException(); } @@ -123,12 +124,12 @@ namespace System.Diagnostics.Tracing throw new System.NotSupportedException(); } - public bool Remove(KeyValuePair entry) + public bool Remove(KeyValuePair entry) { throw new System.NotSupportedException(); } - public bool TryGetValue(string key, out object value) + public bool TryGetValue(string key, out object? value) { if (key == null) throw new System.ArgumentNullException(nameof(key)); @@ -150,7 +151,7 @@ namespace System.Diagnostics.Tracing #region private private List m_names; - private List m_values; + private List m_values; #endregion } } diff --git a/src/System.Private.CoreLib/shared/System/Diagnostics/Tracing/TraceLogging/EventSourceActivity.cs b/src/System.Private.CoreLib/shared/System/Diagnostics/Tracing/TraceLogging/EventSourceActivity.cs index 2d71550..ab5f6d0 100644 --- a/src/System.Private.CoreLib/shared/System/Diagnostics/Tracing/TraceLogging/EventSourceActivity.cs +++ b/src/System.Private.CoreLib/shared/System/Diagnostics/Tracing/TraceLogging/EventSourceActivity.cs @@ -2,6 +2,7 @@ // The .NET Foundation licenses this file to you under the MIT license. // See the LICENSE file in the project root for more information. +#nullable enable using System; #if !ES_BUILD_AGAINST_DOTNET_V35 @@ -92,7 +93,7 @@ namespace System.Diagnostics.Tracing /// Allow options (keywords, level) to be set for the write associated with this start /// These will also be used for the stop event. /// The data to include in the event. - public EventSourceActivity Start(string eventName, EventSourceOptions options, T data) + public EventSourceActivity Start(string? eventName, EventSourceOptions options, T data) { return this.Start(eventName, ref options, ref data); } @@ -100,7 +101,7 @@ namespace System.Diagnostics.Tracing /// Shortcut version see Start(string eventName, EventSourceOptions options, T data) Options is empty (no keywords /// and level==Info) Data payload is empty. /// - public EventSourceActivity Start(string eventName) + public EventSourceActivity Start(string? eventName) { var options = new EventSourceOptions(); var data = new EmptyStruct(); @@ -109,7 +110,7 @@ namespace System.Diagnostics.Tracing /// /// Shortcut version see Start(string eventName, EventSourceOptions options, T data). Data payload is empty. /// - public EventSourceActivity Start(string eventName, EventSourceOptions options) + public EventSourceActivity Start(string? eventName, EventSourceOptions options) { var data = new EmptyStruct(); return this.Start(eventName, ref options, ref data); @@ -118,7 +119,7 @@ namespace System.Diagnostics.Tracing /// Shortcut version see Start(string eventName, EventSourceOptions options, T data) Options is empty (no keywords /// and level==Info) /// - public EventSourceActivity Start(string eventName, T data) + public EventSourceActivity Start(string? eventName, T data) { var options = new EventSourceOptions(); return this.Start(eventName, ref options, ref data); @@ -141,7 +142,7 @@ namespace System.Diagnostics.Tracing /// This can be useful to indicate unusual ways of stopping (but it is still STRONGLY recommended that /// you start with the same prefix used for the start event and you end with the 'Stop' suffix. /// - public void Stop(string eventName) + public void Stop(string? eventName) { var data = new EmptyStruct(); this.Stop(eventName, ref data); @@ -151,7 +152,7 @@ namespace System.Diagnostics.Tracing /// This can be useful to indicate unusual ways of stopping (but it is still STRONGLY recommended that /// you start with the same prefix used for the start event and you end with the 'Stop' suffix. /// - public void Stop(string eventName, T data) + public void Stop(string? eventName, T data) { this.Stop(eventName, ref data); } @@ -168,7 +169,7 @@ namespace System.Diagnostics.Tracing /// The options to use for the event. /// /// The data to include in the event. - public void Write(string eventName, EventSourceOptions options, T data) + public void Write(string? eventName, EventSourceOptions options, T data) { this.Write(this.eventSource, eventName, ref options, ref data); } @@ -181,7 +182,7 @@ namespace System.Diagnostics.Tracing /// data's type. /// /// The data to include in the event. - public void Write(string eventName, T data) + public void Write(string? eventName, T data) { var options = new EventSourceOptions(); this.Write(this.eventSource, eventName, ref options, ref data); @@ -196,7 +197,7 @@ namespace System.Diagnostics.Tracing /// /// The options to use for the event. /// - public void Write(string eventName, EventSourceOptions options) + public void Write(string? eventName, EventSourceOptions options) { var data = new EmptyStruct(); this.Write(this.eventSource, eventName, ref options, ref data); @@ -208,7 +209,7 @@ namespace System.Diagnostics.Tracing /// /// The name to use for the event. Must not be null. /// - public void Write(string eventName) + public void Write(string? eventName) { var options = new EventSourceOptions(); var data = new EmptyStruct(); @@ -217,7 +218,7 @@ namespace System.Diagnostics.Tracing /// /// Writes an event to a arbitrary eventSource stamped with the activity ID of this activity. /// - public void Write(EventSource source, string eventName, EventSourceOptions options, T data) + public void Write(EventSource source, string? eventName, EventSourceOptions options, T data) { this.Write(source, eventName, ref options, ref data); } @@ -236,7 +237,7 @@ namespace System.Diagnostics.Tracing } #region private - private EventSourceActivity Start(string eventName, ref EventSourceOptions options, ref T data) + private EventSourceActivity Start(string? eventName, ref EventSourceOptions options, ref T data) { if (this.state != State.Started) throw new InvalidOperationException(); @@ -265,7 +266,7 @@ namespace System.Diagnostics.Tracing return newActivity; } - private void Write(EventSource eventSource, string eventName, ref EventSourceOptions options, ref T data) + private void Write(EventSource eventSource, string? eventName, ref EventSourceOptions options, ref T data) { if (this.state != State.Started) throw new InvalidOperationException(); // Write after stop. @@ -275,7 +276,7 @@ namespace System.Diagnostics.Tracing eventSource.Write(eventName, ref options, ref this.activityId, ref s_empty, ref data); } - private void Stop(string eventName, ref T data) + private void Stop(string? eventName, ref T data) { if (this.state != State.Started) throw new InvalidOperationException(); @@ -284,6 +285,8 @@ namespace System.Diagnostics.Tracing if (!StartEventWasFired) return; + Debug.Assert(this.eventName != null); + this.state = State.Stopped; if (eventName == null) { @@ -312,7 +315,7 @@ namespace System.Diagnostics.Tracing internal Guid activityId; // internal Guid relatedActivityId; private State state; - private string eventName; + private string? eventName; internal static Guid s_empty; #endregion diff --git a/src/System.Private.CoreLib/shared/System/Diagnostics/Tracing/TraceLogging/EventSourceOptions.cs b/src/System.Private.CoreLib/shared/System/Diagnostics/Tracing/TraceLogging/EventSourceOptions.cs index 26305a5..054fbb2 100644 --- a/src/System.Private.CoreLib/shared/System/Diagnostics/Tracing/TraceLogging/EventSourceOptions.cs +++ b/src/System.Private.CoreLib/shared/System/Diagnostics/Tracing/TraceLogging/EventSourceOptions.cs @@ -2,6 +2,7 @@ // The .NET Foundation licenses this file to you under the MIT license. // See the LICENSE file in the project root for more information. +#nullable enable using System; #if ES_BUILD_STANDALONE diff --git a/src/System.Private.CoreLib/shared/System/Diagnostics/Tracing/TraceLogging/FieldMetadata.cs b/src/System.Private.CoreLib/shared/System/Diagnostics/Tracing/TraceLogging/FieldMetadata.cs index f153734..c3f4b67 100644 --- a/src/System.Private.CoreLib/shared/System/Diagnostics/Tracing/TraceLogging/FieldMetadata.cs +++ b/src/System.Private.CoreLib/shared/System/Diagnostics/Tracing/TraceLogging/FieldMetadata.cs @@ -2,6 +2,7 @@ // The .NET Foundation licenses this file to you under the MIT license. // See the LICENSE file in the project root for more information. +#nullable enable using System; using System.Resources; using Encoding = System.Text.Encoding; @@ -29,7 +30,7 @@ namespace System.Diagnostics.Tracing /// private readonly int nameSize; private readonly EventFieldTags tags; - private readonly byte[] custom; + private readonly byte[]? custom; /// /// ETW supports fixed sized arrays. If inType has the InTypeFixedCountFlag then this is the @@ -57,7 +58,6 @@ namespace System.Diagnostics.Tracing 0, null) { - return; } /// @@ -86,7 +86,7 @@ namespace System.Diagnostics.Tracing string name, TraceLoggingDataType type, EventFieldTags tags, - byte[] custom) + byte[]? custom) : this( name, type, @@ -104,7 +104,7 @@ namespace System.Diagnostics.Tracing EventFieldTags tags, byte countFlags, ushort fixedCount = 0, - byte[] custom = null) + byte[]? custom = null) { if (name == null) { @@ -172,7 +172,7 @@ namespace System.Diagnostics.Tracing /// for a 'two pass' approach where you figure out how big to make the array, and then you /// fill it in. /// - public void Encode(ref int pos, byte[] metadata) + public void Encode(ref int pos, byte[]? metadata) { // Write out the null terminated UTF8 encoded name if (metadata != null) @@ -220,7 +220,8 @@ namespace System.Diagnostics.Tracing { if (metadata != null) { - Buffer.BlockCopy(this.custom, 0, metadata, pos, this.fixedCount); + Debug.Assert(custom != null); + Buffer.BlockCopy(custom, 0, metadata, pos, this.fixedCount); } pos += this.fixedCount; } diff --git a/src/System.Private.CoreLib/shared/System/Diagnostics/Tracing/TraceLogging/InvokeTypeInfo.cs b/src/System.Private.CoreLib/shared/System/Diagnostics/Tracing/TraceLogging/InvokeTypeInfo.cs index 23339f1..6b926ee 100644 --- a/src/System.Private.CoreLib/shared/System/Diagnostics/Tracing/TraceLogging/InvokeTypeInfo.cs +++ b/src/System.Private.CoreLib/shared/System/Diagnostics/Tracing/TraceLogging/InvokeTypeInfo.cs @@ -2,6 +2,7 @@ // The .NET Foundation licenses this file to you under the MIT license. // See the LICENSE file in the project root for more information. +#nullable enable using System; using System.Collections.Generic; @@ -18,14 +19,14 @@ namespace System.Diagnostics.Tracing /// internal sealed class InvokeTypeInfo : TraceLoggingTypeInfo { - internal readonly PropertyAnalysis[] properties; + internal readonly PropertyAnalysis[]? properties; public InvokeTypeInfo( Type type, TypeAnalysis typeAnalysis) : base( type, - typeAnalysis.name, + typeAnalysis.name!, typeAnalysis.level, typeAnalysis.opcode, typeAnalysis.keywords, @@ -37,7 +38,7 @@ namespace System.Diagnostics.Tracing public override void WriteMetadata( TraceLoggingMetadataCollector collector, - string name, + string? name, EventFieldFormat format) { var groupCollector = collector.AddGroup(name); @@ -72,12 +73,12 @@ namespace System.Diagnostics.Tracing } } - public override object GetData(object value) + public override object? GetData(object? value) { if (this.properties != null) { var membersNames = new List(); - var memebersValues = new List(); + var memebersValues = new List(); for (int i = 0; i < this.properties.Length; i++) { var propertyValue = properties[i].propertyInfo.GetValue(value); diff --git a/src/System.Private.CoreLib/shared/System/Diagnostics/Tracing/TraceLogging/NameInfo.cs b/src/System.Private.CoreLib/shared/System/Diagnostics/Tracing/TraceLogging/NameInfo.cs index a7daf5e..48fe8cf 100644 --- a/src/System.Private.CoreLib/shared/System/Diagnostics/Tracing/TraceLogging/NameInfo.cs +++ b/src/System.Private.CoreLib/shared/System/Diagnostics/Tracing/TraceLogging/NameInfo.cs @@ -2,6 +2,7 @@ // The .NET Foundation licenses this file to you under the MIT license. // See the LICENSE file in the project root for more information. +#nullable enable using System; using System.Collections.Generic; using System.Collections.Concurrent; diff --git a/src/System.Private.CoreLib/shared/System/Diagnostics/Tracing/TraceLogging/PropertyAnalysis.cs b/src/System.Private.CoreLib/shared/System/Diagnostics/Tracing/TraceLogging/PropertyAnalysis.cs index 1f07539..05eac6d 100644 --- a/src/System.Private.CoreLib/shared/System/Diagnostics/Tracing/TraceLogging/PropertyAnalysis.cs +++ b/src/System.Private.CoreLib/shared/System/Diagnostics/Tracing/TraceLogging/PropertyAnalysis.cs @@ -2,6 +2,7 @@ // The .NET Foundation licenses this file to you under the MIT license. // See the LICENSE file in the project root for more information. +#nullable enable using System; using System.Reflection; @@ -21,13 +22,13 @@ namespace System.Diagnostics.Tracing internal readonly PropertyInfo propertyInfo; internal readonly Func getter; internal readonly TraceLoggingTypeInfo typeInfo; - internal readonly EventFieldAttribute fieldAttribute; + internal readonly EventFieldAttribute? fieldAttribute; public PropertyAnalysis( string name, PropertyInfo propertyInfo, TraceLoggingTypeInfo typeInfo, - EventFieldAttribute fieldAttribute) + EventFieldAttribute? fieldAttribute) { this.name = name; this.propertyInfo = propertyInfo; diff --git a/src/System.Private.CoreLib/shared/System/Diagnostics/Tracing/TraceLogging/PropertyValue.cs b/src/System.Private.CoreLib/shared/System/Diagnostics/Tracing/TraceLogging/PropertyValue.cs index 0f87ea5..35fe760 100644 --- a/src/System.Private.CoreLib/shared/System/Diagnostics/Tracing/TraceLogging/PropertyValue.cs +++ b/src/System.Private.CoreLib/shared/System/Diagnostics/Tracing/TraceLogging/PropertyValue.cs @@ -2,6 +2,7 @@ // The .NET Foundation licenses this file to you under the MIT license. // See the LICENSE file in the project root for more information. +#nullable enable using System; using System.Reflection; using System.Runtime.InteropServices; @@ -80,11 +81,11 @@ namespace System.Diagnostics.Tracing } // Anything not covered by the Scalar union gets stored in this reference. - readonly object _reference; + readonly object? _reference; readonly Scalar _scalar; readonly int _scalarLength; - private PropertyValue(object value) + private PropertyValue(object? value) { _reference = value; _scalar = default; @@ -118,33 +119,32 @@ namespace System.Diagnostics.Tracing private PropertyValue(TimeSpan value) : this(new Scalar() { AsTimeSpan = value }, sizeof(TimeSpan)) { } private PropertyValue(decimal value) : this(new Scalar() { AsDecimal = value }, sizeof(decimal)) { } - public static Func GetFactory(Type type) + public static Func GetFactory(Type type) { - if (type == typeof(bool)) return value => new PropertyValue((bool)value); - if (type == typeof(byte)) return value => new PropertyValue((byte)value); - if (type == typeof(sbyte)) return value => new PropertyValue((sbyte)value); - if (type == typeof(char)) return value => new PropertyValue((char)value); - if (type == typeof(short)) return value => new PropertyValue((short)value); - if (type == typeof(ushort)) return value => new PropertyValue((ushort)value); - if (type == typeof(int)) return value => new PropertyValue((int)value); - if (type == typeof(uint)) return value => new PropertyValue((uint)value); - if (type == typeof(long)) return value => new PropertyValue((long)value); - if (type == typeof(ulong)) return value => new PropertyValue((ulong)value); - if (type == typeof(IntPtr)) return value => new PropertyValue((IntPtr)value); - if (type == typeof(UIntPtr)) return value => new PropertyValue((UIntPtr)value); - if (type == typeof(float)) return value => new PropertyValue((float)value); - if (type == typeof(double)) return value => new PropertyValue((double)value); - if (type == typeof(Guid)) return value => new PropertyValue((Guid)value); - if (type == typeof(DateTime)) return value => new PropertyValue((DateTime)value); - if (type == typeof(DateTimeOffset)) return value => new PropertyValue((DateTimeOffset)value); - if (type == typeof(TimeSpan)) return value => new PropertyValue((TimeSpan)value); - if (type == typeof(decimal)) return value => new PropertyValue((decimal)value); + if (type == typeof(bool)) return value => new PropertyValue((bool)value!); + if (type == typeof(byte)) return value => new PropertyValue((byte)value!); + if (type == typeof(sbyte)) return value => new PropertyValue((sbyte)value!); + if (type == typeof(char)) return value => new PropertyValue((char)value!); + if (type == typeof(short)) return value => new PropertyValue((short)value!); + if (type == typeof(ushort)) return value => new PropertyValue((ushort)value!); + if (type == typeof(int)) return value => new PropertyValue((int)value!); + if (type == typeof(uint)) return value => new PropertyValue((uint)value!); + if (type == typeof(long)) return value => new PropertyValue((long)value!); + if (type == typeof(ulong)) return value => new PropertyValue((ulong)value!); + if (type == typeof(IntPtr)) return value => new PropertyValue((IntPtr)value!); + if (type == typeof(UIntPtr)) return value => new PropertyValue((UIntPtr)value!); + if (type == typeof(float)) return value => new PropertyValue((float)value!); + if (type == typeof(double)) return value => new PropertyValue((double)value!); + if (type == typeof(Guid)) return value => new PropertyValue((Guid)value!); + if (type == typeof(DateTime)) return value => new PropertyValue((DateTime)value!); + if (type == typeof(DateTimeOffset)) return value => new PropertyValue((DateTimeOffset)value!); + if (type == typeof(TimeSpan)) return value => new PropertyValue((TimeSpan)value!); + if (type == typeof(decimal)) return value => new PropertyValue((decimal)value!); return value => new PropertyValue(value); } - - public object ReferenceValue + public object? ReferenceValue { get { @@ -209,7 +209,7 @@ namespace System.Diagnostics.Tracing /// private static Func GetReferenceTypePropertyGetter(PropertyInfo property) { - var helper = (TypeHelper)Activator.CreateInstance(typeof(ReferenceTypeHelper<>).MakeGenericType(property.DeclaringType)); + var helper = (TypeHelper)Activator.CreateInstance(typeof(ReferenceTypeHelper<>).MakeGenericType(property.DeclaringType))!; return helper.GetPropertyGetter(property); } @@ -233,7 +233,7 @@ namespace System.Diagnostics.Tracing #else private #endif - sealed class ReferenceTypeHelper : TypeHelper where TContainer : class + sealed class ReferenceTypeHelper : TypeHelper where TContainer : class? { public override Func GetPropertyGetter(PropertyInfo property) { @@ -241,33 +241,33 @@ namespace System.Diagnostics.Tracing if (!Statics.IsValueType(type)) { - var getter = (Func)GetGetMethod(property, type); - return container => new PropertyValue(getter((TContainer)container.ReferenceValue)); + var getter = (Func)GetGetMethod(property, type); + return container => new PropertyValue(getter((TContainer)container.ReferenceValue!)); // TODO-NULLABLE-GENERIC: Re-review } else { if (type.GetTypeInfo().IsEnum) type = Enum.GetUnderlyingType(type); - if (type == typeof(bool)) { var f = (Func)GetGetMethod(property, type); return container => new PropertyValue(f((TContainer)container.ReferenceValue)); } - if (type == typeof(byte)) { var f = (Func)GetGetMethod(property, type); return container => new PropertyValue(f((TContainer)container.ReferenceValue)); } - if (type == typeof(sbyte)) { var f = (Func)GetGetMethod(property, type); return container => new PropertyValue(f((TContainer)container.ReferenceValue)); } - if (type == typeof(char)) { var f = (Func)GetGetMethod(property, type); return container => new PropertyValue(f((TContainer)container.ReferenceValue)); } - if (type == typeof(short)) { var f = (Func)GetGetMethod(property, type); return container => new PropertyValue(f((TContainer)container.ReferenceValue)); } - if (type == typeof(ushort)) { var f = (Func)GetGetMethod(property, type); return container => new PropertyValue(f((TContainer)container.ReferenceValue)); } - if (type == typeof(int)) { var f = (Func)GetGetMethod(property, type); return container => new PropertyValue(f((TContainer)container.ReferenceValue)); } - if (type == typeof(uint)) { var f = (Func)GetGetMethod(property, type); return container => new PropertyValue(f((TContainer)container.ReferenceValue)); } - if (type == typeof(long)) { var f = (Func)GetGetMethod(property, type); return container => new PropertyValue(f((TContainer)container.ReferenceValue)); } - if (type == typeof(ulong)) { var f = (Func)GetGetMethod(property, type); return container => new PropertyValue(f((TContainer)container.ReferenceValue)); } - if (type == typeof(IntPtr)) { var f = (Func)GetGetMethod(property, type); return container => new PropertyValue(f((TContainer)container.ReferenceValue)); } - if (type == typeof(UIntPtr)) { var f = (Func)GetGetMethod(property, type); return container => new PropertyValue(f((TContainer)container.ReferenceValue)); } - if (type == typeof(float)) { var f = (Func)GetGetMethod(property, type); return container => new PropertyValue(f((TContainer)container.ReferenceValue)); } - if (type == typeof(double)) { var f = (Func)GetGetMethod(property, type); return container => new PropertyValue(f((TContainer)container.ReferenceValue)); } - if (type == typeof(Guid)) { var f = (Func)GetGetMethod(property, type); return container => new PropertyValue(f((TContainer)container.ReferenceValue)); } - if (type == typeof(DateTime)) { var f = (Func)GetGetMethod(property, type); return container => new PropertyValue(f((TContainer)container.ReferenceValue)); } - if (type == typeof(DateTimeOffset)) { var f = (Func)GetGetMethod(property, type); return container => new PropertyValue(f((TContainer)container.ReferenceValue)); } - if (type == typeof(TimeSpan)) { var f = (Func)GetGetMethod(property, type); return container => new PropertyValue(f((TContainer)container.ReferenceValue)); } - if (type == typeof(decimal)) { var f = (Func)GetGetMethod(property, type); return container => new PropertyValue(f((TContainer)container.ReferenceValue)); } + if (type == typeof(bool)) { var f = (Func)GetGetMethod(property, type); return container => new PropertyValue(f((TContainer)container.ReferenceValue!)); } // TODO-NULLABLE-GENERIC: Re-review + if (type == typeof(byte)) { var f = (Func)GetGetMethod(property, type); return container => new PropertyValue(f((TContainer)container.ReferenceValue!)); } // TODO-NULLABLE-GENERIC: Re-review + if (type == typeof(sbyte)) { var f = (Func)GetGetMethod(property, type); return container => new PropertyValue(f((TContainer)container.ReferenceValue!)); } // TODO-NULLABLE-GENERIC: Re-review + if (type == typeof(char)) { var f = (Func)GetGetMethod(property, type); return container => new PropertyValue(f((TContainer)container.ReferenceValue!)); } // TODO-NULLABLE-GENERIC: Re-review + if (type == typeof(short)) { var f = (Func)GetGetMethod(property, type); return container => new PropertyValue(f((TContainer)container.ReferenceValue!)); } // TODO-NULLABLE-GENERIC: Re-review + if (type == typeof(ushort)) { var f = (Func)GetGetMethod(property, type); return container => new PropertyValue(f((TContainer)container.ReferenceValue!)); } // TODO-NULLABLE-GENERIC: Re-review + if (type == typeof(int)) { var f = (Func)GetGetMethod(property, type); return container => new PropertyValue(f((TContainer)container.ReferenceValue!)); } // TODO-NULLABLE-GENERIC: Re-review + if (type == typeof(uint)) { var f = (Func)GetGetMethod(property, type); return container => new PropertyValue(f((TContainer)container.ReferenceValue!)); } // TODO-NULLABLE-GENERIC: Re-review + if (type == typeof(long)) { var f = (Func)GetGetMethod(property, type); return container => new PropertyValue(f((TContainer)container.ReferenceValue!)); } // TODO-NULLABLE-GENERIC: Re-review + if (type == typeof(ulong)) { var f = (Func)GetGetMethod(property, type); return container => new PropertyValue(f((TContainer)container.ReferenceValue!)); } // TODO-NULLABLE-GENERIC: Re-review + if (type == typeof(IntPtr)) { var f = (Func)GetGetMethod(property, type); return container => new PropertyValue(f((TContainer)container.ReferenceValue!)); } // TODO-NULLABLE-GENERIC: Re-review + if (type == typeof(UIntPtr)) { var f = (Func)GetGetMethod(property, type); return container => new PropertyValue(f((TContainer)container.ReferenceValue!)); } // TODO-NULLABLE-GENERIC: Re-review + if (type == typeof(float)) { var f = (Func)GetGetMethod(property, type); return container => new PropertyValue(f((TContainer)container.ReferenceValue!)); } // TODO-NULLABLE-GENERIC: Re-review + if (type == typeof(double)) { var f = (Func)GetGetMethod(property, type); return container => new PropertyValue(f((TContainer)container.ReferenceValue!)); } // TODO-NULLABLE-GENERIC: Re-review + if (type == typeof(Guid)) { var f = (Func)GetGetMethod(property, type); return container => new PropertyValue(f((TContainer)container.ReferenceValue!)); } // TODO-NULLABLE-GENERIC: Re-review + if (type == typeof(DateTime)) { var f = (Func)GetGetMethod(property, type); return container => new PropertyValue(f((TContainer)container.ReferenceValue!)); } // TODO-NULLABLE-GENERIC: Re-review + if (type == typeof(DateTimeOffset)) { var f = (Func)GetGetMethod(property, type); return container => new PropertyValue(f((TContainer)container.ReferenceValue!)); } // TODO-NULLABLE-GENERIC: Re-review + if (type == typeof(TimeSpan)) { var f = (Func)GetGetMethod(property, type); return container => new PropertyValue(f((TContainer)container.ReferenceValue!)); } // TODO-NULLABLE-GENERIC: Re-review + if (type == typeof(decimal)) { var f = (Func)GetGetMethod(property, type); return container => new PropertyValue(f((TContainer)container.ReferenceValue!)); } // TODO-NULLABLE-GENERIC: Re-review return container => new PropertyValue(property.GetValue(container.ReferenceValue)); } diff --git a/src/System.Private.CoreLib/shared/System/Diagnostics/Tracing/TraceLogging/SimpleEventTypes.cs b/src/System.Private.CoreLib/shared/System/Diagnostics/Tracing/TraceLogging/SimpleEventTypes.cs index cdced96..280c03c 100644 --- a/src/System.Private.CoreLib/shared/System/Diagnostics/Tracing/TraceLogging/SimpleEventTypes.cs +++ b/src/System.Private.CoreLib/shared/System/Diagnostics/Tracing/TraceLogging/SimpleEventTypes.cs @@ -2,6 +2,7 @@ // The .NET Foundation licenses this file to you under the MIT license. // See the LICENSE file in the project root for more information. +#nullable enable using System; using Interlocked = System.Threading.Interlocked; @@ -21,7 +22,7 @@ namespace System.Diagnostics.Tracing /// internal static class SimpleEventTypes { - private static TraceLoggingEventTypes instance; + private static TraceLoggingEventTypes? instance; public static TraceLoggingEventTypes Instance { @@ -33,6 +34,7 @@ namespace System.Diagnostics.Tracing var info = TraceLoggingTypeInfo.GetInstance(typeof(T), null); var newInstance = new TraceLoggingEventTypes(info.Name, info.Tags, new TraceLoggingTypeInfo[] { info }); Interlocked.CompareExchange(ref instance, newInstance, null); + Debug.Assert(instance != null); return instance; } } diff --git a/src/System.Private.CoreLib/shared/System/Diagnostics/Tracing/TraceLogging/SimpleTypeInfos.cs b/src/System.Private.CoreLib/shared/System/Diagnostics/Tracing/TraceLogging/SimpleTypeInfos.cs index dc714d8..dc8be3e 100644 --- a/src/System.Private.CoreLib/shared/System/Diagnostics/Tracing/TraceLogging/SimpleTypeInfos.cs +++ b/src/System.Private.CoreLib/shared/System/Diagnostics/Tracing/TraceLogging/SimpleTypeInfos.cs @@ -2,6 +2,7 @@ // The .NET Foundation licenses this file to you under the MIT license. // See the LICENSE file in the project root for more information. +#nullable enable using System; using System.Collections.Generic; using System.Reflection; @@ -28,7 +29,7 @@ namespace System.Diagnostics.Tracing public override void WriteMetadata( TraceLoggingMetadataCollector collector, - string name, + string? name, EventFieldFormat format) { collector.AddGroup(name); @@ -39,7 +40,7 @@ namespace System.Diagnostics.Tracing return; } - public override object GetData(object value) + public override object? GetData(object? value) { return null; } @@ -63,9 +64,9 @@ namespace System.Diagnostics.Tracing this.nativeFormat = nativeFormat; } - public override void WriteMetadata(TraceLoggingMetadataCollector collector, string name, EventFieldFormat format) + public override void WriteMetadata(TraceLoggingMetadataCollector collector, string? name, EventFieldFormat format) { - collector.AddScalar(name, formatFunc(format, nativeFormat)); + collector.AddScalar(name!, formatFunc(format, nativeFormat)); } public override void WriteData(TraceLoggingDataCollector collector, PropertyValue value) @@ -112,9 +113,9 @@ namespace System.Diagnostics.Tracing this.elementSize = elementSize; } - public override void WriteMetadata(TraceLoggingMetadataCollector collector, string name, EventFieldFormat format) + public override void WriteMetadata(TraceLoggingMetadataCollector collector, string? name, EventFieldFormat format) { - collector.AddArray(name, formatFunc(format, nativeFormat)); + collector.AddArray(name!, formatFunc(format, nativeFormat)); } public override void WriteData(TraceLoggingDataCollector collector, PropertyValue value) @@ -148,20 +149,20 @@ namespace System.Diagnostics.Tracing public override void WriteMetadata( TraceLoggingMetadataCollector collector, - string name, + string? name, EventFieldFormat format) { - collector.AddNullTerminatedString(name, Statics.MakeDataType(TraceLoggingDataType.Utf16String, format)); + collector.AddNullTerminatedString(name!, Statics.MakeDataType(TraceLoggingDataType.Utf16String, format)); } public override void WriteData(TraceLoggingDataCollector collector, PropertyValue value) { - collector.AddNullTerminatedString((string)value.ReferenceValue); + collector.AddNullTerminatedString((string?)value.ReferenceValue); } - public override object GetData(object value) + public override object GetData(object? value) { - if(value == null) + if (value == null) { return ""; } @@ -179,10 +180,10 @@ namespace System.Diagnostics.Tracing public override void WriteMetadata( TraceLoggingMetadataCollector collector, - string name, + string? name, EventFieldFormat format) { - collector.AddScalar(name, Statics.MakeDataType(TraceLoggingDataType.FileTime, format)); + collector.AddScalar(name!, Statics.MakeDataType(TraceLoggingDataType.FileTime, format)); } public override void WriteData(TraceLoggingDataCollector collector, PropertyValue value) @@ -205,7 +206,7 @@ namespace System.Diagnostics.Tracing { public DateTimeOffsetTypeInfo() : base(typeof(DateTimeOffset)) { } - public override void WriteMetadata(TraceLoggingMetadataCollector collector, string name, EventFieldFormat format) + public override void WriteMetadata(TraceLoggingMetadataCollector collector, string? name, EventFieldFormat format) { var group = collector.AddGroup(name); group.AddScalar("Ticks", Statics.MakeDataType(TraceLoggingDataType.FileTime, format)); @@ -230,10 +231,10 @@ namespace System.Diagnostics.Tracing public override void WriteMetadata( TraceLoggingMetadataCollector collector, - string name, + string? name, EventFieldFormat format) { - collector.AddScalar(name, Statics.MakeDataType(TraceLoggingDataType.Int64, format)); + collector.AddScalar(name!, Statics.MakeDataType(TraceLoggingDataType.Int64, format)); } public override void WriteData(TraceLoggingDataCollector collector, PropertyValue value) @@ -251,10 +252,10 @@ namespace System.Diagnostics.Tracing public override void WriteMetadata( TraceLoggingMetadataCollector collector, - string name, + string? name, EventFieldFormat format) { - collector.AddScalar(name, Statics.MakeDataType(TraceLoggingDataType.Double, format)); + collector.AddScalar(name!, Statics.MakeDataType(TraceLoggingDataType.Double, format)); } public override void WriteData(TraceLoggingDataCollector collector, PropertyValue value) @@ -282,7 +283,7 @@ namespace System.Diagnostics.Tracing public override void WriteMetadata( TraceLoggingMetadataCollector collector, - string name, + string? name, EventFieldFormat format) { var group = collector.AddGroup(name); diff --git a/src/System.Private.CoreLib/shared/System/Diagnostics/Tracing/TraceLogging/Statics.cs b/src/System.Private.CoreLib/shared/System/Diagnostics/Tracing/TraceLogging/Statics.cs index 0c21672..56d53c1 100644 --- a/src/System.Private.CoreLib/shared/System/Diagnostics/Tracing/TraceLogging/Statics.cs +++ b/src/System.Private.CoreLib/shared/System/Diagnostics/Tracing/TraceLogging/Statics.cs @@ -2,6 +2,7 @@ // The .NET Foundation licenses this file to you under the MIT license. // See the LICENSE file in the project root for more information. +#nullable enable using System; using System.Collections.Generic; using System.Reflection; @@ -112,7 +113,7 @@ namespace System.Diagnostics.Tracing /// This is useful for a two pass approach where you figure out how big to /// make the array, and then you fill it in. /// - public static void EncodeTags(int tags, ref int pos, byte[] metadata) + public static void EncodeTags(int tags, ref int pos, byte[]? metadata) { // We transmit the low 28 bits of tags, high bits first, 7 bits at a time. var tagsLeft = tags & 0xfffffff; @@ -172,7 +173,7 @@ namespace System.Diagnostics.Tracing } } - public static void CheckName(string name) + public static void CheckName(string? name) { if (name != null && 0 <= name.IndexOf('\0')) { @@ -363,7 +364,7 @@ namespace System.Diagnostics.Tracing kinds of reflection operations are being done. */ - public static object CreateInstance(Type type, params object[] parameters) + public static object? CreateInstance(Type type, params object?[]? parameters) { return Activator.CreateInstance(type, parameters); } @@ -422,9 +423,9 @@ namespace System.Diagnostics.Tracing } public static AttributeType GetCustomAttribute(PropertyInfo propInfo) - where AttributeType : Attribute + where AttributeType : Attribute? { - AttributeType result = null; + AttributeType result = null!; // TODO-NULLABLE-GENERIC: re-review #if (ES_BUILD_PCL || ES_BUILD_PN) foreach (var attrib in propInfo.GetCustomAttributes(false)) { @@ -442,9 +443,9 @@ namespace System.Diagnostics.Tracing } public static AttributeType GetCustomAttribute(Type type) - where AttributeType : Attribute + where AttributeType : Attribute? { - AttributeType result = null; + AttributeType result = null!; // TODO-NULLABLE-GENERIC: re-review #if (ES_BUILD_PCL || ES_BUILD_PN) foreach (var attrib in type.GetTypeInfo().GetCustomAttributes(false)) { @@ -466,9 +467,9 @@ namespace System.Diagnostics.Tracing return type.GetGenericArguments(); } - public static Type FindEnumerableElementType(Type type) + public static Type? FindEnumerableElementType(Type type) { - Type elementType = null; + Type? elementType = null; if (IsGenericMatch(type, typeof(IEnumerable<>))) { @@ -537,9 +538,9 @@ namespace System.Diagnostics.Tracing recursionCheck.Add(dataType); - var eventAttrib = Statics.GetCustomAttribute(dataType); + var eventAttrib = Statics.GetCustomAttribute(dataType); if (eventAttrib != null || - Statics.GetCustomAttribute(dataType) != null || + Statics.GetCustomAttribute(dataType) != null || IsGenericMatch(dataType, typeof(KeyValuePair<,>))) { var analysis = new TypeAnalysis(dataType, eventAttrib, recursionCheck); diff --git a/src/System.Private.CoreLib/shared/System/Diagnostics/Tracing/TraceLogging/TraceLoggingDataCollector.cs b/src/System.Private.CoreLib/shared/System/Diagnostics/Tracing/TraceLogging/TraceLoggingDataCollector.cs index c6f89c8..afa0e71 100644 --- a/src/System.Private.CoreLib/shared/System/Diagnostics/Tracing/TraceLogging/TraceLoggingDataCollector.cs +++ b/src/System.Private.CoreLib/shared/System/Diagnostics/Tracing/TraceLogging/TraceLoggingDataCollector.cs @@ -2,6 +2,7 @@ // The .NET Foundation licenses this file to you under the MIT license. // See the LICENSE file in the project root for more information. +#nullable enable using System; using System.Security; @@ -99,7 +100,7 @@ namespace System.Diagnostics.Tracing /// /// Value to be added. A null value is treated as a zero-length string. /// - public void AddNullTerminatedString(string value) + public void AddNullTerminatedString(string? value) { DataCollector.ThreadInstance.AddNullTerminatedString(value); } @@ -110,14 +111,14 @@ namespace System.Diagnostics.Tracing /// /// Value to be added. A null value is treated as a zero-length string. /// - public void AddBinary(string value) + public void AddBinary(string? value) { DataCollector.ThreadInstance.AddBinary(value, value == null ? 0 : value.Length * 2); } public void AddArray(PropertyValue value, int elementSize) { - Array array = (Array)value.ReferenceValue; + Array? array = (Array?)value.ReferenceValue; DataCollector.ThreadInstance.AddArray(array, array == null ? 0 : array.Length, elementSize); } } diff --git a/src/System.Private.CoreLib/shared/System/Diagnostics/Tracing/TraceLogging/TraceLoggingEventSource.cs b/src/System.Private.CoreLib/shared/System/Diagnostics/Tracing/TraceLogging/TraceLoggingEventSource.cs index 0553f98..178334f 100644 --- a/src/System.Private.CoreLib/shared/System/Diagnostics/Tracing/TraceLogging/TraceLoggingEventSource.cs +++ b/src/System.Private.CoreLib/shared/System/Diagnostics/Tracing/TraceLogging/TraceLoggingEventSource.cs @@ -2,6 +2,7 @@ // The .NET Foundation licenses this file to you under the MIT license. // See the LICENSE file in the project root for more information. +#nullable enable // This program uses code hyperlinks available as part of the HyperAddin Visual Studio plug-in. // It is available from http://www.codeplex.com/hyperAddin @@ -44,7 +45,7 @@ namespace System.Diagnostics.Tracing public partial class EventSource { #if FEATURE_MANAGED_ETW - private byte[] providerMetadata; + private byte[] providerMetadata = null!; #endif #if FEATURE_PERFTRACING @@ -93,10 +94,10 @@ namespace System.Diagnostics.Tracing public EventSource( string eventSourceName, EventSourceSettings config, - params string[] traits) + params string[]? traits) : this( eventSourceName == null ? new Guid() : GenerateGuidFromName(eventSourceName.ToUpperInvariant()), - eventSourceName, + eventSourceName!, config, traits) { if (eventSourceName == null) @@ -170,7 +171,7 @@ namespace System.Diagnostics.Tracing /// create the fields of the event. /// public unsafe void Write( - string eventName, + string? eventName, T data) { if (!this.IsEnabled()) @@ -206,7 +207,7 @@ namespace System.Diagnostics.Tracing /// create the fields of the event. /// public unsafe void Write( - string eventName, + string? eventName, EventSourceOptions options, T data) { @@ -244,7 +245,7 @@ namespace System.Diagnostics.Tracing /// create the fields of the event. /// public unsafe void Write( - string eventName, + string? eventName, ref EventSourceOptions options, ref T data) { @@ -289,7 +290,7 @@ namespace System.Diagnostics.Tracing /// create the fields of the event. /// public unsafe void Write( - string eventName, + string? eventName, ref EventSourceOptions options, ref Guid activityId, ref Guid relatedActivityId, @@ -345,7 +346,7 @@ namespace System.Diagnostics.Tracing /// eventTypes parameter. /// private unsafe void WriteMultiMerge( - string eventName, + string? eventName, ref EventSourceOptions options, TraceLoggingEventTypes eventTypes, Guid* activityID, @@ -405,7 +406,7 @@ namespace System.Diagnostics.Tracing /// eventTypes parameter. /// private unsafe void WriteMultiMergeInner( - string eventName, + string? eventName, ref EventSourceOptions options, TraceLoggingEventTypes eventTypes, Guid* activityID, @@ -528,7 +529,7 @@ namespace System.Diagnostics.Tracing /// fields described by the eventTypes parameter. /// internal unsafe void WriteMultiMerge( - string eventName, + string? eventName, ref EventSourceOptions options, TraceLoggingEventTypes eventTypes, Guid* activityID, @@ -600,9 +601,9 @@ namespace System.Diagnostics.Tracing } private unsafe void WriteImpl( - string eventName, + string? eventName, ref EventSourceOptions options, - object data, + object? data, Guid* pActivityId, Guid* pRelatedActivityId, TraceLoggingEventTypes eventTypes) @@ -630,7 +631,7 @@ namespace System.Diagnostics.Tracing var pinCount = eventTypes.pinCount; var scratch = stackalloc byte[eventTypes.scratchSize]; var descriptors = stackalloc EventData[eventTypes.dataCount + 3]; - for(int i=0; i((IList)payload.Values); + eventCallbackArgs.Payload = new ReadOnlyCollection((IList)payload.Values); eventCallbackArgs.PayloadNames = new ReadOnlyCollection((IList)payload.Keys); } @@ -875,13 +878,13 @@ namespace System.Diagnostics.Tracing throw new ArgumentException(SR.Format(SR.EventSource_BadHexDigit, c), "traits"); } - private NameInfo UpdateDescriptor( - string name, + private NameInfo? UpdateDescriptor( + string? name, TraceLoggingEventTypes eventInfo, ref EventSourceOptions options, out EventDescriptor descriptor) { - NameInfo nameInfo = null; + NameInfo? nameInfo = null; int identity = 0; byte level = (options.valuesSet & EventSourceOptions.levelSet) != 0 ? options.level diff --git a/src/System.Private.CoreLib/shared/System/Diagnostics/Tracing/TraceLogging/TraceLoggingEventTypes.cs b/src/System.Private.CoreLib/shared/System/Diagnostics/Tracing/TraceLogging/TraceLoggingEventTypes.cs index 8887714..d894acb 100644 --- a/src/System.Private.CoreLib/shared/System/Diagnostics/Tracing/TraceLogging/TraceLoggingEventTypes.cs +++ b/src/System.Private.CoreLib/shared/System/Diagnostics/Tracing/TraceLogging/TraceLoggingEventTypes.cs @@ -2,6 +2,7 @@ // The .NET Foundation licenses this file to you under the MIT license. // See the LICENSE file in the project root for more information. +#nullable enable using System; using System.Collections.Generic; using Interlocked = System.Threading.Interlocked; @@ -26,7 +27,7 @@ namespace System.Diagnostics.Tracing { internal readonly TraceLoggingTypeInfo[] typeInfos; #if FEATURE_PERFTRACING - internal readonly string[] paramNames; + internal readonly string[]? paramNames; #endif internal readonly string name; internal readonly EventTags tags; @@ -60,7 +61,6 @@ namespace System.Diagnostics.Tracing params Type[] types) : this(tags, name, MakeArray(types)) { - return; } /// @@ -87,7 +87,6 @@ namespace System.Diagnostics.Tracing params TraceLoggingTypeInfo[] typeInfos) : this(tags, name, MakeArray(typeInfos)) { - return; } internal TraceLoggingEventTypes( diff --git a/src/System.Private.CoreLib/shared/System/Diagnostics/Tracing/TraceLogging/TraceLoggingMetadataCollector.cs b/src/System.Private.CoreLib/shared/System/Diagnostics/Tracing/TraceLogging/TraceLoggingMetadataCollector.cs index b5b199d..7e39c96 100644 --- a/src/System.Private.CoreLib/shared/System/Diagnostics/Tracing/TraceLogging/TraceLoggingMetadataCollector.cs +++ b/src/System.Private.CoreLib/shared/System/Diagnostics/Tracing/TraceLogging/TraceLoggingMetadataCollector.cs @@ -2,6 +2,7 @@ // The .NET Foundation licenses this file to you under the MIT license. // See the LICENSE file in the project root for more information. +#nullable enable using System; using System.Collections.Generic; @@ -19,7 +20,7 @@ namespace System.Diagnostics.Tracing internal class TraceLoggingMetadataCollector { private readonly Impl impl; - private readonly FieldMetadata currentGroup; + private readonly FieldMetadata? currentGroup; private int bufferedArrayFieldCount = int.MinValue; /// @@ -93,7 +94,7 @@ namespace System.Diagnostics.Tracing /// /// A new metadata collector that can be used to add fields to the group. /// - public TraceLoggingMetadataCollector AddGroup(string name) + public TraceLoggingMetadataCollector AddGroup(string? name) { TraceLoggingMetadataCollector result = this; @@ -101,7 +102,7 @@ namespace System.Diagnostics.Tracing this.BeginningBufferedArray) // Error, FieldMetadata's constructor will throw the appropriate exception. { var newGroup = new FieldMetadata( - name, + name!, TraceLoggingDataType.Struct, this.Tags, this.BeginningBufferedArray); @@ -375,7 +376,7 @@ namespace System.Diagnostics.Tracing this.bufferNesting--; } - public int Encode(byte[] metadata) + public int Encode(byte[]? metadata) { int size = 0; diff --git a/src/System.Private.CoreLib/shared/System/Diagnostics/Tracing/TraceLogging/TraceLoggingTypeInfo.cs b/src/System.Private.CoreLib/shared/System/Diagnostics/Tracing/TraceLogging/TraceLoggingTypeInfo.cs index 511a4fe..62dc932 100644 --- a/src/System.Private.CoreLib/shared/System/Diagnostics/Tracing/TraceLogging/TraceLoggingTypeInfo.cs +++ b/src/System.Private.CoreLib/shared/System/Diagnostics/Tracing/TraceLogging/TraceLoggingTypeInfo.cs @@ -2,6 +2,7 @@ // The .NET Foundation licenses this file to you under the MIT license. // See the LICENSE file in the project root for more information. +#nullable enable using System; using System.Collections.Generic; @@ -30,7 +31,7 @@ namespace System.Diagnostics.Tracing private readonly EventOpcode opcode = (EventOpcode)(-1); private readonly EventTags tags; private readonly Type dataType; - private readonly Func propertyValueFactory; + private readonly Func propertyValueFactory; internal TraceLoggingTypeInfo(Type dataType) { @@ -124,7 +125,7 @@ namespace System.Diagnostics.Tracing get { return this.dataType; } } - internal Func PropertyValueFactory + internal Func PropertyValueFactory { get { return this.propertyValueFactory; } } @@ -153,7 +154,7 @@ namespace System.Diagnostics.Tracing /// public abstract void WriteMetadata( TraceLoggingMetadataCollector collector, - string name, + string? name, EventFieldFormat format); /// @@ -177,15 +178,15 @@ namespace System.Diagnostics.Tracing /// /// /// - public virtual object GetData(object value) + public virtual object? GetData(object? value) { return value; } [ThreadStatic] // per-thread cache to avoid synchronization - private static Dictionary threadCache; + private static Dictionary? threadCache; - public static TraceLoggingTypeInfo GetInstance(Type type, List recursionCheck) + public static TraceLoggingTypeInfo GetInstance(Type type, List? recursionCheck) { var cache = threadCache ?? (threadCache = new Dictionary()); diff --git a/src/System.Private.CoreLib/shared/System/Diagnostics/Tracing/TraceLogging/TypeAnalysis.cs b/src/System.Private.CoreLib/shared/System/Diagnostics/Tracing/TraceLogging/TypeAnalysis.cs index 42cdde5..83f76af 100644 --- a/src/System.Private.CoreLib/shared/System/Diagnostics/Tracing/TraceLogging/TypeAnalysis.cs +++ b/src/System.Private.CoreLib/shared/System/Diagnostics/Tracing/TraceLogging/TypeAnalysis.cs @@ -2,6 +2,7 @@ // The .NET Foundation licenses this file to you under the MIT license. // See the LICENSE file in the project root for more information. +#nullable enable using System; using System.Collections.Generic; using System.Reflection; @@ -19,7 +20,7 @@ namespace System.Diagnostics.Tracing internal sealed class TypeAnalysis { internal readonly PropertyAnalysis[] properties; - internal readonly string name; + internal readonly string? name; internal readonly EventKeywords keywords; internal readonly EventLevel level = (EventLevel)(-1); internal readonly EventOpcode opcode = (EventOpcode)(-1); @@ -27,7 +28,7 @@ namespace System.Diagnostics.Tracing public TypeAnalysis( Type dataType, - EventDataAttribute eventAttrib, + EventDataAttribute? eventAttrib, List recursionCheck) { var propertyInfos = Statics.GetProperties(dataType); @@ -46,7 +47,7 @@ namespace System.Diagnostics.Tracing continue; } - MethodInfo getterInfo = Statics.GetGetMethod(propertyInfo); + MethodInfo? getterInfo = Statics.GetGetMethod(propertyInfo); if (getterInfo == null) { continue; @@ -59,7 +60,7 @@ namespace System.Diagnostics.Tracing var propertyType = propertyInfo.PropertyType; var propertyTypeInfo = TraceLoggingTypeInfo.GetInstance(propertyType, recursionCheck); - var fieldAttribute = Statics.GetCustomAttribute(propertyInfo); + var fieldAttribute = Statics.GetCustomAttribute(propertyInfo); string propertyName = fieldAttribute != null && fieldAttribute.Name != null diff --git a/src/System.Private.CoreLib/shared/System/Diagnostics/Tracing/Winmeta.cs b/src/System.Private.CoreLib/shared/System/Diagnostics/Tracing/Winmeta.cs index c60ca5b..2175005 100644 --- a/src/System.Private.CoreLib/shared/System/Diagnostics/Tracing/Winmeta.cs +++ b/src/System.Private.CoreLib/shared/System/Diagnostics/Tracing/Winmeta.cs @@ -2,6 +2,7 @@ // The .NET Foundation licenses this file to you under the MIT license. // See the LICENSE file in the project root for more information. +#nullable enable /*============================================================ ** **