dotnet / runtime

.NET is a cross-platform runtime for cloud, mobile, desktop, and IoT apps.
https://docs.microsoft.com/dotnet/core/
MIT License
14.64k stars 4.57k forks source link

Disposing EventListener doesn't send disable command #56378

Open noahfalk opened 2 years ago

noahfalk commented 2 years ago

Normally when ETW or EventPipe sessions end a disable command is sent to any EventSources that were being monitored to indicate that monitoring has stopped. EventListener also stops listening when it is disposed, but it doesn't provide any notification that it is doing so.

Repro:

using System.Diagnostics;
using System.Diagnostics.Tracing;

class Program
{
    static void Main(string[] args)
    {

        MyEventSource source = new MyEventSource();
        using (MyEventListener listener = new MyEventListener())
        {
            listener.EnableEvents(source, EventLevel.Informational);
            Debug.Assert(source.Enabled);
            // uncommenting this line will make the assert below pass, but it shouldn't be necessary
            //listener.DisableEvents(source);
        }
        Debug.Assert(!source.Enabled); // once the listener is disposed we expect OnEventCommand to be called with a disable command
    }
}

[EventSource(Name ="MyEventSource")]
public class MyEventSource : EventSource
{
    public bool Enabled;

    protected override void OnEventCommand(EventCommandEventArgs command)
    {
        if(command.Command == EventCommand.Enable)
        {
            Enabled = true;
        }
        else
        {
            Enabled = false;
        }
    }
}

public class MyEventListener : EventListener
{
}
ghost commented 2 years ago

Tagging subscribers to this area: @tarekgh, @tommcdon, @pjanotti See info in area-owners.md if you want to be subscribed.

Issue Details
Normally when ETW or EventPipe sessions end a disable command is sent to any EventSources that were being monitored to indicate that monitoring has stopped. EventListener also stops listening when it is disposed, but it doesn't provide any notification that it is doing so. Repro: ```C# using System.Diagnostics; using System.Diagnostics.Tracing; class Program { static void Main(string[] args) { MyEventSource source = new MyEventSource(); using (MyEventListener listener = new MyEventListener()) { listener.EnableEvents(source, EventLevel.Informational); Debug.Assert(source.Enabled); // uncommenting this line will make the assert below pass, but it shouldn't be necessary //listener.DisableEvents(source); } Debug.Assert(!source.Enabled); // once the listener is disposed we expect OnEventCommand to be called with a disable command } } [EventSource(Name ="MyEventSource")] public class MyEventSource : EventSource { public bool Enabled; protected override void OnEventCommand(EventCommandEventArgs command) { if(command.Command == EventCommand.Enable) { Enabled = true; } else { Enabled = false; } } } public class MyEventListener : EventListener { } ```
Author: noahfalk
Assignees: -
Labels: `area-System.Diagnostics.Tracing`
Milestone: 7.0.0