-
Notifications
You must be signed in to change notification settings - Fork 4.8k
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Standardize EventSource behavior in ETW for null values #77172
Standardize EventSource behavior in ETW for null values #77172
Conversation
Tagging subscribers to this area: @tarekgh, @tommcdon, @pjanotti Issue Detailsnull
|
This is the test failure based on the test case added. BasicEventSourceTests.TestsWriteEventToListener.Test_WriteEvent_ArgsBasicTypes [FAIL]
Assert.Null() Failure
Expected: (null)
Actual:
Stack Trace:
C:\Users\JJame\Documents\OSSE\runtime\src\libraries\System.Diagnostics.Tracing\tests\BasicEventSourceTest\TestsWriteEventToListener.cs(208,0): at BasicEventSourceTests.TestsWriteEventToListener.Test_Wr
iteEvent_ArgsBasicTypes()
at System.RuntimeMethodHandle.InvokeMethod(Object target, Void** arguments, Signature sig, Boolean isConstructor)
C:\Users\JJame\Documents\OSSE\runtime\src\libraries\System.Private.CoreLib\src\System\Reflection\MethodInvoker.cs(64,0): at System.Reflection.MethodInvoker.Invoke(Object obj, IntPtr* args, BindingFlags
invokeAttr) |
@AaronRobinsonMSFT re: #12662 |
This is saying that the value at index |
I added this in: Console.WriteLine("------------------------------------------");
Console.WriteLine((string)LoudListener.t_lastEvent.Payload[0]);
Console.WriteLine("------------------------------------------"); and the output is: ------------------------------------------
------------------------------------------ which leads me to believe it is the empty string. Adding the following assert statement before the Assert.Null seems to prove it: Assert.Equals("", (string)LoudListener.t_lastEvent.Payload[0]); as it still fails on the It seems that this is what is being called, and it looks consistent for the rest of the Is it intentional that |
A good rule of thumb is to put quotes around the string. Like so:
|
It looks like we special case null strings and make them empty strings here: runtime/src/libraries/System.Private.CoreLib/src/System/Diagnostics/Tracing/EventSource.cs Lines 908 to 927 in 570b373
I'm taking a deeper look now to see if this means #12662 was fixed but never closed or if it is talking about a different scenario |
Ok, so this issue stills repros, but it's way more subtle than any of the previous discussion suggests. The error happens specifically when an ETW or EventPipe session is enabled, and the We have some specific overloads in EventSource for performance, but we fall back to this If we are writing to an ETW/EventPipe session, however, we call in to EventProvider.WriteEvent and the code here sees that an argument is null and translates it to an error: runtime/src/libraries/System.Private.CoreLib/src/System/Diagnostics/Tracing/EventProvider.cs Lines 981 to 985 in fdcbc7b
To fix this the right way we should audit all the overloads of |
Repro for the failing case, you can make a console app and add the Microsoft.Diagnostics.NETCore.Client nuget package using System.Diagnostics.Tracing;
using System.Diagnostics;
using System;
using System.Threading.Tasks;
using System.Collections.Generic;
using Microsoft.Diagnostics.NETCore.Client;
using Microsoft.Diagnostics.Tracing;
[EventSource(Name = "Test.MyEventSource")]
class EventSourceTest : EventSource
{
[Event(1)]
public void TestEvent(string str, int i, float f, long l)
{
WriteEvent(1, str, i, f, l, nullStr);
}
}
class Program
{
static void Main(string[] args)
{
List<EventPipeProvider> providers = new List<EventPipeProvider>
{
new EventPipeProvider("Test.MyEventSource", EventLevel.Verbose)
};
int processId = Process.GetCurrentProcess().Id;
DiagnosticsClient client = new DiagnosticsClient(processId);
using (EventPipeSession session = client.StartEventPipeSession(providers, /* requestRunDown */ false))
{
using (var source = new EventSourceTest())
{
source.TestEvent(null, 1, 1, 1); ;
var events = new EventPipeEventSource(session.EventStream);
Task processTask = Task.Run(() =>
{
events.Dynamic.All += (TraceEvent traceEvent) =>
{
Console.WriteLine($"Got event {traceEvent.EventName} with #args {traceEvent.PayloadNames.Length}");
foreach (string name in traceEvent.PayloadNames)
{
Console.WriteLine($" {name}: \"{traceEvent.PayloadByName(name)}\"");
}
};
events.Process();
});
session.Stop();
processTask.Wait();
}
}
}
} |
How do I simulate the EventPipe session in a test case? I believe the following set of assertions will fail if executed while an ETW or EventPipe session is enabled (as per the failing case repro), but I'm not quite sure how to create a test under the same circumstances. log.EventWithFallbackArgs(null, 10, 11, 12);
Assert.Equal(56, LoudListener.t_lastEvent.EventId);
Assert.Equal(4, LoudListener.t_lastEvent.Payload.Count);
Assert.Equal("", (string)LoudListener.t_lastEvent.Payload[0]);
Assert.Equal(10, (int)LoudListener.t_lastEvent.Payload[1]);
Assert.Equal(11, (float)LoudListener.t_lastEvent.Payload[2]);
Assert.Equal(12, (long)LoudListener.t_lastEvent.Payload[3]); [Event(56)]
public unsafe void EventWithFallbackArgs(string str, int i, float f, long l)
{
this.WriteEvent(56, str, i, f, l);
} |
The two objects that can be |
@JJamesWWang thanks for sticking with this! Answers to your questions below.
We have a test harness that automates it. See here for example: runtime/src/tests/tracing/eventpipe/eventsvalidation/ExceptionThrown_V1.cs Lines 14 to 23 in d3ab95d
If you want to add a test, the easiest way is to copy and paste the .cs and .csproj and change all the names as appropriate, and then add your event.
We keep information about the parameters in the event metadata. The metadata we already have available here has a .Parameters field: runtime/src/libraries/System.Private.CoreLib/src/System/Diagnostics/Tracing/EventSource.cs Line 1861 in d3ab95d
You can determine what type it is by checking |
I've added a test ( Expected behavior: Actual behavior: |
Hi @JJamesWWang, My suspicion is that the test hanging is related to the failure, but I can't take a look since you deleted the repo you had created the pull request from. I suspect that the test is failing, but that failure causes a hang. |
fixes #12662