-
Notifications
You must be signed in to change notification settings - Fork 5.3k
Closed
Description
Repro:
[Fact]
public async Task ManagedAVE_MinimalFailingTest()
{
async Task GetStreamIdWithoutStartWorks()
{
using QuicListener listener = CreateQuicListener();
using QuicConnection clientConnection = CreateQuicConnection(listener.ListenEndPoint);
ValueTask clientTask = clientConnection.ConnectAsync();
using QuicConnection serverConnection = await listener.AcceptConnectionAsync();
await clientTask;
using QuicStream clientStream = clientConnection.OpenBidirectionalStream();
Assert.Equal(0, clientStream.StreamId);
// TODO: stream that is opened by client but left unaccepted by server may cause AccessViolationException in its Finalizer
}
await GetStreamIdWithoutStartWorks();
GC.Collect();
}For me it now fails on every run, with a stacktrace
Fatal error. System.AccessViolationException: Attempted to read or write protected memory. This is often an indication that other memory is corrupt.
at System.Net.Quic.Implementations.MsQuic.Internal.SafeMsQuicStreamHandle.ReleaseHandle()
at System.Runtime.InteropServices.SafeHandle.InternalRelease(Boolean)
at System.Runtime.InteropServices.SafeHandle.Dispose(Boolean)
at System.Runtime.InteropServices.SafeHandle.Dispose()
at System.Net.Quic.Implementations.MsQuic.MsQuicStream.Dispose(Boolean)
at System.Net.Quic.Implementations.MsQuic.MsQuicStream.Finalize()
As mentioned before in TODO comment, the stream that is being finalized is the one left inside connection's Channel<MsQuicStream> AcceptQueue - it was created and put there on PEER_STREAM_STARTED event, but was never claimed by calling AcceptStreamAsync. I didn't find an easy way to dispose what's inside AcceptQueue on connection's Dispose. But maybe that's not the only problem - users might easily leave QuicStreams undisposed, but it shouldn't lead to AVE.