Uh oh!
There was an error while loading. Please reload this page.
Standardize EventSource behavior in ETW for null values - #77172
Standardize EventSource behavior in ETW for null values#77172JJamesWWang wants to merge 9 commits into
Conversation
ghost
commented
Oct 18, 2022
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(Objecttarget,Void**arguments,Signaturesig,BooleanisConstructor)C:\Users\JJame\Documents\OSSE\runtime\src\libraries\System.Private.CoreLib\src\System\Reflection\MethodInvoker.cs(64,0):atSystem.Reflection.MethodInvoker.Invoke(Objectobj,IntPtr*args,BindingFlagsinvokeAttr) |
JJamesWWang
commented
Oct 18, 2022
@AaronRobinsonMSFT re: #12662 |
AaronRobinsonMSFT
commented
Oct 18, 2022
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 |
AaronRobinsonMSFT
commented
Oct 18, 2022
A good rule of thumb is to put quotes around the string. Like so:
|
davmason
commented
Oct 18, 2022
It looks like we special case null strings and make them empty strings here: 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 |
davmason
commented
Oct 18, 2022
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: 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 usingSystem.Diagnostics.Tracing;usingSystem.Diagnostics;usingSystem;usingSystem.Threading.Tasks;usingSystem.Collections.Generic;usingMicrosoft.Diagnostics.NETCore.Client;usingMicrosoft.Diagnostics.Tracing;[EventSource(Name="Test.MyEventSource")]classEventSourceTest:EventSource{[Event(1)]publicvoidTestEvent(stringstr,inti,floatf,longl){WriteEvent(1,str,i,f,l,nullStr);}}classProgram{staticvoidMain(string[]args){List<EventPipeProvider>providers=newList<EventPipeProvider>{newEventPipeProvider("Test.MyEventSource",EventLevel.Verbose)};intprocessId=Process.GetCurrentProcess().Id;DiagnosticsClientclient=newDiagnosticsClient(processId);using(EventPipeSessionsession=client.StartEventPipeSession(providers,/* requestRunDown */false)){using(varsource=newEventSourceTest()){source.TestEvent(null,1,1,1);;varevents=newEventPipeEventSource(session.EventStream);TaskprocessTask=Task.Run(()=>{events.Dynamic.All+=(TraceEventtraceEvent)=>{Console.WriteLine($"Got event {traceEvent.EventName} with #args {traceEvent.PayloadNames.Length}");foreach(stringnameintraceEvent.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)]publicunsafevoidEventWithFallbackArgs(stringstr,inti,floatf,longl){this.WriteEvent(56,str,i,f,l);} |
The two objects that can be |
davmason
commented
Nov 5, 2022
@JJamesWWang thanks for sticking with this! Answers to your questions below.
We have a test harness that automates it. See here for example:
You give it a list of providers and then the expected event count, if it runs in to an exception it will fail the test. 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: You can determine what type it is by checking |
I've added a test ( Expected behavior: Actual behavior: |
davmason
commented
Jan 4, 2023
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