From 50f5536cfdc33a70c463542ef2276e48e0fa0ff8 Mon Sep 17 00:00:00 2001 From: Brian Robbins Date: Sat, 3 Mar 2018 21:00:42 -0800 Subject: [PATCH] Update TraceLogging to use NULL-terminated strings instead of counted strings (#16672) --- .../System/Diagnostics/Tracing/EventSource.cs | 0 .../Tracing/TraceLogging/DataCollector.cs | 39 ++++++++++++++++++++++ .../Tracing/TraceLogging/FieldMetadata.cs | 2 -- .../Tracing/TraceLogging/SimpleTypeInfos.cs | 4 +-- .../TraceLogging/TraceLoggingDataCollector.cs | 11 ++++++ .../TraceLogging/TraceLoggingEventSource.cs | 28 ++++------------ .../TraceLogging/TraceLoggingMetadataCollector.cs | 31 ++++++++++++++--- 7 files changed, 84 insertions(+), 31 deletions(-) mode change 100644 => 100755 src/mscorlib/shared/System/Diagnostics/Tracing/EventSource.cs mode change 100644 => 100755 src/mscorlib/shared/System/Diagnostics/Tracing/TraceLogging/DataCollector.cs mode change 100644 => 100755 src/mscorlib/shared/System/Diagnostics/Tracing/TraceLogging/SimpleTypeInfos.cs mode change 100644 => 100755 src/mscorlib/shared/System/Diagnostics/Tracing/TraceLogging/TraceLoggingDataCollector.cs mode change 100644 => 100755 src/mscorlib/shared/System/Diagnostics/Tracing/TraceLogging/TraceLoggingMetadataCollector.cs diff --git a/src/mscorlib/shared/System/Diagnostics/Tracing/EventSource.cs b/src/mscorlib/shared/System/Diagnostics/Tracing/EventSource.cs old mode 100644 new mode 100755 diff --git a/src/mscorlib/shared/System/Diagnostics/Tracing/TraceLogging/DataCollector.cs b/src/mscorlib/shared/System/Diagnostics/Tracing/TraceLogging/DataCollector.cs old mode 100644 new mode 100755 index 1444c26..11c18a2 --- a/src/mscorlib/shared/System/Diagnostics/Tracing/TraceLogging/DataCollector.cs +++ b/src/mscorlib/shared/System/Diagnostics/Tracing/TraceLogging/DataCollector.cs @@ -143,6 +143,45 @@ namespace System.Diagnostics.Tracing } } + internal unsafe void AddNullTerminatedString(string value) + { + // Treat null strings as empty strings. + if (value == null) + { + value = string.Empty; + } + + // Calculate the size of the string including the trailing NULL char. + // Don't use value.Length here because string allows for embedded NULL characters. + int nullCharIndex = value.IndexOf((char)0); + if (nullCharIndex < 0) + { + nullCharIndex = value.Length; + } + int size = (nullCharIndex + 1) * 2; + + if (this.bufferNesting != 0) + { + this.EnsureBuffer(size); + } + + if (this.bufferNesting == 0) + { + this.ScalarsEnd(); + this.PinArray(value, size); + } + else + { + var oldPos = this.bufferPos; + this.bufferPos = checked(this.bufferPos + size); + this.EnsureBuffer(); + fixed (void* p = value) + { + Marshal.Copy((IntPtr)p, buffer, oldPos, size); + } + } + } + internal void AddBinary(Array value, int size) { this.AddArray(value, size, 1); diff --git a/src/mscorlib/shared/System/Diagnostics/Tracing/TraceLogging/FieldMetadata.cs b/src/mscorlib/shared/System/Diagnostics/Tracing/TraceLogging/FieldMetadata.cs index 9c7c636..f153734 100644 --- a/src/mscorlib/shared/System/Diagnostics/Tracing/TraceLogging/FieldMetadata.cs +++ b/src/mscorlib/shared/System/Diagnostics/Tracing/TraceLogging/FieldMetadata.cs @@ -135,13 +135,11 @@ namespace System.Diagnostics.Tracing { throw new NotSupportedException(SR.EventSource_NotSupportedArrayOfBinary); } -#if !BROKEN_UNTIL_M3 if (coreType == (int)TraceLoggingDataType.Utf16String || coreType == (int)TraceLoggingDataType.MbcsString) { throw new NotSupportedException(SR.EventSource_NotSupportedArrayOfNullTerminatedString); } -#endif } if (((int)this.tags & 0xfffffff) != 0) diff --git a/src/mscorlib/shared/System/Diagnostics/Tracing/TraceLogging/SimpleTypeInfos.cs b/src/mscorlib/shared/System/Diagnostics/Tracing/TraceLogging/SimpleTypeInfos.cs old mode 100644 new mode 100755 index 9b58d82..2f460d2 --- a/src/mscorlib/shared/System/Diagnostics/Tracing/TraceLogging/SimpleTypeInfos.cs +++ b/src/mscorlib/shared/System/Diagnostics/Tracing/TraceLogging/SimpleTypeInfos.cs @@ -151,12 +151,12 @@ namespace System.Diagnostics.Tracing string name, EventFieldFormat format) { - collector.AddBinary(name, Statics.MakeDataType(TraceLoggingDataType.CountedUtf16String, format)); + collector.AddNullTerminatedString(name, Statics.MakeDataType(TraceLoggingDataType.Utf16String, format)); } public override void WriteData(TraceLoggingDataCollector collector, PropertyValue value) { - collector.AddBinary((string)value.ReferenceValue); + collector.AddNullTerminatedString((string)value.ReferenceValue); } public override object GetData(object value) diff --git a/src/mscorlib/shared/System/Diagnostics/Tracing/TraceLogging/TraceLoggingDataCollector.cs b/src/mscorlib/shared/System/Diagnostics/Tracing/TraceLogging/TraceLoggingDataCollector.cs old mode 100644 new mode 100755 index 04a047f..f6d0a59 --- a/src/mscorlib/shared/System/Diagnostics/Tracing/TraceLogging/TraceLoggingDataCollector.cs +++ b/src/mscorlib/shared/System/Diagnostics/Tracing/TraceLogging/TraceLoggingDataCollector.cs @@ -85,6 +85,17 @@ namespace System.Diagnostics.Tracing } /// + /// Adds a null-terminated String value to the event payload. + /// + /// + /// Value to be added. A null value is treated as a zero-length string. + /// + public void AddNullTerminatedString(string value) + { + DataCollector.ThreadInstance.AddNullTerminatedString(value); + } + + /// /// Adds a counted String value to the event payload. /// /// diff --git a/src/mscorlib/shared/System/Diagnostics/Tracing/TraceLogging/TraceLoggingEventSource.cs b/src/mscorlib/shared/System/Diagnostics/Tracing/TraceLogging/TraceLoggingEventSource.cs index 4348df7..10b378c 100644 --- a/src/mscorlib/shared/System/Diagnostics/Tracing/TraceLogging/TraceLoggingEventSource.cs +++ b/src/mscorlib/shared/System/Diagnostics/Tracing/TraceLogging/TraceLoggingEventSource.cs @@ -557,30 +557,14 @@ namespace System.Diagnostics.Tracing for (int i = 0; i < eventTypes.typeInfos.Length; i++) { - // Until M3, we need to morph strings to a counted representation - // When TDH supports null terminated strings, we can remove this. - if (eventTypes.typeInfos[i].DataType == typeof(string)) - { - // Write out the size of the string - descriptors[numDescrs].DataPointer = (IntPtr) (&descriptors[numDescrs + 1].m_Size); - descriptors[numDescrs].m_Size = 2; - numDescrs++; - - descriptors[numDescrs].m_Ptr = data[i].m_Ptr; - descriptors[numDescrs].m_Size = data[i].m_Size - 2; // Remove the null terminator - numDescrs++; - } - else - { - descriptors[numDescrs].m_Ptr = data[i].m_Ptr; - descriptors[numDescrs].m_Size = data[i].m_Size; + descriptors[numDescrs].m_Ptr = data[i].m_Ptr; + descriptors[numDescrs].m_Size = data[i].m_Size; - // old conventions for bool is 4 bytes, but meta-data assumes 1. - if (data[i].m_Size == 4 && eventTypes.typeInfos[i].DataType == typeof(bool)) - descriptors[numDescrs].m_Size = 1; + // old conventions for bool is 4 bytes, but meta-data assumes 1. + if (data[i].m_Size == 4 && eventTypes.typeInfos[i].DataType == typeof(bool)) + descriptors[numDescrs].m_Size = 1; - numDescrs++; - } + numDescrs++; } this.WriteEventRaw( diff --git a/src/mscorlib/shared/System/Diagnostics/Tracing/TraceLogging/TraceLoggingMetadataCollector.cs b/src/mscorlib/shared/System/Diagnostics/Tracing/TraceLogging/TraceLoggingMetadataCollector.cs old mode 100644 new mode 100755 index 1db1a28..b5b199d --- a/src/mscorlib/shared/System/Diagnostics/Tracing/TraceLogging/TraceLoggingMetadataCollector.cs +++ b/src/mscorlib/shared/System/Diagnostics/Tracing/TraceLogging/TraceLoggingMetadataCollector.cs @@ -192,22 +192,43 @@ namespace System.Diagnostics.Tracing } /// + /// Adds a null-terminated string field to an event. + /// Compatible with core types: Utf16String, MbcsString. + /// Compatible with dataCollector method: AddNullTerminatedString(string). + /// + /// + /// The name to use for the added field. This value must not be null. + /// + /// + /// The type code for the added field. This must be a null-terminated string type. + /// + public void AddNullTerminatedString(string name, TraceLoggingDataType type) + { + switch ((TraceLoggingDataType)((int)type & Statics.InTypeMask)) + { + case TraceLoggingDataType.Utf16String: + break; + default: + throw new ArgumentOutOfRangeException(nameof(type)); + } + + this.impl.AddNonscalar(); + this.AddField(new FieldMetadata(name, type, this.Tags, this.BeginningBufferedArray)); + } + + /// /// Adds an array field to an event. /// /// /// The name to use for the added field. This value must not be null. /// /// - /// The type code for the added field. This must be a fixed-size type - /// or a string type. In the case of a string type, this adds an array - /// of characters, not an array of strings. + /// The type code for the added field. This must be a fixed-size type. /// public void AddArray(string name, TraceLoggingDataType type) { switch ((TraceLoggingDataType)((int)type & Statics.InTypeMask)) { - case TraceLoggingDataType.Utf16String: - case TraceLoggingDataType.MbcsString: case TraceLoggingDataType.Int8: case TraceLoggingDataType.UInt8: case TraceLoggingDataType.Int16: -- 2.7.4