@@ -75,6 +75,7 @@ private unsafe byte[] GenerateMetadata(
7575 // level : 4 bytes
7676 // parameterCount : 4 bytes
7777 uint metadataLength = 24 + ( ( uint ) eventName . Length + 1 ) * 2 ;
78+ uint defaultMetadataLength = metadataLength ;
7879
7980 // Check for an empty payload.
8081 // Write<T> calls with no arguments by convention have a parameter of
@@ -87,7 +88,16 @@ private unsafe byte[] GenerateMetadata(
8788 // Increase the metadataLength for parameters.
8889 foreach ( var parameter in parameters )
8990 {
90- metadataLength = metadataLength + parameter . GetMetadataLength ( ) ;
91+ int pMetadataLength = parameter . GetMetadataLength ( ) ;
92+ // The call above may return -1 which means we failed to get the metadata length.
93+ // We then return a default metadata blob (with parameterCount of 0) to prevent it from generating malformed metadata.
94+ if ( pMetadataLength < 0 )
95+ {
96+ parameters = Array . Empty < EventParameterInfo > ( ) ;
97+ metadataLength = defaultMetadataLength ;
98+ break ;
99+ }
100+ metadataLength += ( uint ) pMetadataLength ;
91101 }
92102
93103 metadata = new byte [ metadataLength ] ;
@@ -107,7 +117,11 @@ private unsafe byte[] GenerateMetadata(
107117 WriteToBuffer ( pMetadata , metadataLength , ref offset , ( uint ) parameters . Length ) ;
108118 foreach ( var parameter in parameters )
109119 {
110- parameter . GenerateMetadata ( pMetadata , ref offset , metadataLength ) ;
120+ if ( ! parameter . GenerateMetadata ( pMetadata , ref offset , metadataLength ) )
121+ {
122+ // If we fail to generate metadata for any parameter, we should return the "default" metadata without any parameters
123+ return GenerateMetadata ( eventId , eventName , keywords , level , version , Array . Empty < EventParameterInfo > ( ) ) ;
124+ }
111125 }
112126 Debug . Assert ( metadataLength == offset ) ;
113127 }
@@ -174,7 +188,7 @@ internal void SetInfo(string name, Type type, TraceLoggingTypeInfo typeInfo = nu
174188 TypeInfo = typeInfo ;
175189 }
176190
177- internal unsafe void GenerateMetadata ( byte * pMetadataBlob , ref uint offset , uint blobSize )
191+ internal unsafe bool GenerateMetadata ( byte * pMetadataBlob , ref uint offset , uint blobSize )
178192 {
179193 TypeCode typeCode = GetTypeCodeExtended ( ParameterType ) ;
180194 if ( typeCode == TypeCode . Object )
@@ -189,7 +203,7 @@ internal unsafe void GenerateMetadata(byte* pMetadataBlob, ref uint offset, uint
189203 InvokeTypeInfo invokeTypeInfo = TypeInfo as InvokeTypeInfo ;
190204 if ( invokeTypeInfo == null )
191205 {
192- throw new NotSupportedException ( ) ;
206+ return false ;
193207 }
194208
195209 // Get the set of properties to be serialized.
@@ -201,7 +215,10 @@ internal unsafe void GenerateMetadata(byte* pMetadataBlob, ref uint offset, uint
201215
202216 foreach ( PropertyAnalysis prop in properties )
203217 {
204- GenerateMetadataForProperty ( prop , pMetadataBlob , ref offset , blobSize ) ;
218+ if ( ! GenerateMetadataForProperty ( prop , pMetadataBlob , ref offset , blobSize ) )
219+ {
220+ return false ;
221+ }
205222 }
206223 }
207224 else
@@ -225,9 +242,10 @@ internal unsafe void GenerateMetadata(byte* pMetadataBlob, ref uint offset, uint
225242 EventPipeMetadataGenerator . WriteToBuffer ( pMetadataBlob , blobSize , ref offset , ( byte * ) pParameterName , ( ( uint ) ParameterName . Length + 1 ) * 2 ) ;
226243 }
227244 }
245+ return true ;
228246 }
229247
230- private static unsafe void GenerateMetadataForProperty ( PropertyAnalysis property , byte * pMetadataBlob , ref uint offset , uint blobSize )
248+ private static unsafe bool GenerateMetadataForProperty ( PropertyAnalysis property , byte * pMetadataBlob , ref uint offset , uint blobSize )
231249 {
232250 Debug . Assert ( property != null ) ;
233251 Debug . Assert ( pMetadataBlob != null ) ;
@@ -252,7 +270,10 @@ private static unsafe void GenerateMetadataForProperty(PropertyAnalysis property
252270
253271 foreach ( PropertyAnalysis prop in properties )
254272 {
255- GenerateMetadataForProperty ( prop , pMetadataBlob , ref offset , blobSize ) ;
273+ if ( ! GenerateMetadataForProperty ( prop , pMetadataBlob , ref offset , blobSize ) )
274+ {
275+ return false ;
276+ }
256277 }
257278 }
258279 else
@@ -274,10 +295,10 @@ private static unsafe void GenerateMetadataForProperty(PropertyAnalysis property
274295 // PropertyName : NULL-terminated string
275296 TypeCode typeCode = GetTypeCodeExtended ( property . typeInfo . DataType ) ;
276297
277- // EventPipe does not support this type. Throw , which will cause no metadata to be registered for this event.
298+ // EventPipe does not support this type. Return false , which will cause no metadata to be registered for this event.
278299 if ( typeCode == TypeCode . Object )
279300 {
280- throw new NotSupportedException ( ) ;
301+ return false ;
281302 }
282303
283304 // Write the type code.
@@ -289,20 +310,21 @@ private static unsafe void GenerateMetadataForProperty(PropertyAnalysis property
289310 EventPipeMetadataGenerator . WriteToBuffer ( pMetadataBlob , blobSize , ref offset , ( byte * ) pPropertyName , ( ( uint ) property . name . Length + 1 ) * 2 ) ;
290311 }
291312 }
313+ return true ;
292314 }
293315
294316
295- internal unsafe uint GetMetadataLength ( )
317+ internal unsafe int GetMetadataLength ( )
296318 {
297- uint ret = 0 ;
319+ int ret = 0 ;
298320
299321 TypeCode typeCode = GetTypeCodeExtended ( ParameterType ) ;
300322 if ( typeCode == TypeCode . Object )
301323 {
302324 InvokeTypeInfo typeInfo = TypeInfo as InvokeTypeInfo ;
303325 if ( typeInfo == null )
304326 {
305- throw new NotSupportedException ( ) ;
327+ return - 1 ;
306328 }
307329
308330 // Each nested struct is serialized as:
@@ -319,7 +341,7 @@ internal unsafe uint GetMetadataLength()
319341 {
320342 foreach ( PropertyAnalysis prop in properties )
321343 {
322- ret += GetMetadataLengthForProperty ( prop ) ;
344+ ret += ( int ) GetMetadataLengthForProperty ( prop ) ;
323345 }
324346 }
325347
@@ -330,7 +352,7 @@ internal unsafe uint GetMetadataLength()
330352 }
331353 else
332354 {
333- ret += ( uint ) ( sizeof ( uint ) + ( ( ParameterName . Length + 1 ) * 2 ) ) ;
355+ ret += ( int ) ( sizeof ( uint ) + ( ( ParameterName . Length + 1 ) * 2 ) ) ;
334356 }
335357
336358 return ret ;
0 commit comments