Skip to content
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

.Net 5.0 Application using NAudio libraries crashes without any error message #54132

Closed
TheRealLenon opened this issue Jun 14, 2021 · 47 comments · Fixed by #54235 or #54244
Closed

.Net 5.0 Application using NAudio libraries crashes without any error message #54132

TheRealLenon opened this issue Jun 14, 2021 · 47 comments · Fixed by #54235 or #54244

Comments

@TheRealLenon
Copy link

TheRealLenon commented Jun 14, 2021

Description

Hey Guys,

It seems something on .NET 5 made NAudio (master-branch) crashing without any error message.

There is also an open Issue open on the NAudio´s GitHub.

After discussions i found out, that the runtime tries to access memory it does not own so Windows kills the process with Access Violation.

Configuration

It happens on Windows 20H2 with ANY .NET 5.X.X version.

Related information

Based on the issue from NAudio, it was referred, that .NET Core 3.1 is working. I only could verify it for .NET 5.

@dotnet-issue-labeler
Copy link

I couldn't figure out the best area label to add to this issue. If you have write-permissions please help me learn by adding exactly one area label.

@dotnet-issue-labeler dotnet-issue-labeler bot added the untriaged New issue has not been triaged by the area owner label Jun 14, 2021
@jackpoz
Copy link

jackpoz commented Jun 14, 2021

Last week I installed Windows Updates and upgraded to Windows 10 21H1 after. I started a .NET 5 application that uses NAudio that worked fine the day before and after the upgrade it closed with Access Violation unhandled exception. Changing the runtime to .Net Core 3.1 fixed the issue.

@TheRealLenon
Copy link
Author

Sadly I´m not being able to downgrade to .NET Core 3.1.

But referring to this comment, it is indicating, that there is a bug in the "hotfix" of the current .NET 5.x runtime, which lets the windows kernel kill the application with "Access Violation".

@Zintom
Copy link

Zintom commented Jun 14, 2021

It would be beneficial if anyone on Windows 20H2 could test this in .NET 5+, that way it would determine if a windows update was involved in the regression.

@TheRealLenon
Copy link
Author

TheRealLenon commented Jun 14, 2021

It would be beneficial if anyone on Windows 20H2 could test this in .NET 5+, that way it would determine if a windows update was involved in the regression.

I´m currently running 20H2 and couldn´t run it with all .NET 5.x versions. I´ve edited the original message to state this :)

@jackpoz
Copy link

jackpoz commented Jun 14, 2021

I tried on another computer with .NET 5.0.6 and Windows 10 20H2 and it works.
I downloaded .NET 5.0.7 runtime from https://dotnet.microsoft.com/download/dotnet/thank-you/runtime-desktop-5.0.7-windows-x64-installer , started the application and at first I heard random noises and then the application crashed

dotnet --list-runtimes before and working:
image

dotnet --list-runtimes after and crashing:
image

So to me this is clearly a 5.0.7 issue not present in 5.0.6

@jkotas
Copy link
Member

jkotas commented Jun 14, 2021

@jkoritzinsky Can this be regression introduced by #50882 ?

@wzchua
Copy link
Contributor

wzchua commented Jun 14, 2021

It works if you published self-contained

@jackpoz
Copy link

jackpoz commented Jun 14, 2021

I created a repro project at https://github.com/jackpoz/NetCore507Crash

image

Callstack using VS and native debugging enabled:
image

@jkotas
Copy link
Member

jkotas commented Jun 14, 2021

https://github.com/jackpoz/NetCore507Crash fails for me with:

C:\NetCore507Crash>C:\NetCore507Crash\bin\Debug\net5.0\NetCore507Crash.exe
Playing some music...
Unhandled exception. System.InvalidOperationException: Buffer full
   at NAudio.Wave.BufferedWaveProvider.AddSamples(Byte[] buffer, Int32 offset, Int32 count)
   at NetCore507Crash.MusicPlayer.Play(String filePath) in C:\NetCore507Crash\Program.cs:line 51
   at NetCore507Crash.Program.Main() in C:\NetCore507Crash\Program.cs:line 20

@KyodaiKen
Copy link

To me it really looks like a memory pointer issue. It also is NOT the latest cumulative update. It's one of the .NET security updates. I've uninstalled the 2 latest cumulative updates and it didn't fix it. :/

@jackpoz
Copy link

jackpoz commented Jun 14, 2021

@jkotas I added now a check in case the buffer gets full, I never reached that point in my tests with 5.0.7 as it crashes right away. Please pull latest version.

@jkoritzinsky
Copy link
Member

I don't think this is caused by #50882 since that aligned all of the behavior to match .NET Core 3.1, but I guess it's possible that NAudio hits some corner case in it's interop. Without knowing if it even uses LayoutClass marshalling though, I don't know.

@jkotas
Copy link
Member

jkotas commented Jun 15, 2021

It does use LayoutClass marshaling and it depends on blittable classes to be marshalled using pinning strategy. The problem is that 5.0.7 switched to use copying strategy for blittable classes that broke this library.

The affected code is here: https://github.com/naudio/NAudio/blob/fb35ce8367f30b8bc5ea84e7d2529e172cf4c381/NAudio.WinMM/WaveOutBuffer.cs#L140 . This code depends on WaveHeader to be marshaled using pinning strategy.

Here is small test to demonstrate the problem:

On 5.0.6 (and .NET Framework), the program below prints pointers that are really far apart (GCHeap and stack):
On 5.0.7, the program below prints pointers that are really close togetger (two stack pointers):

using System;
using System.Runtime.InteropServices;
using System.IO;

[StructLayout(LayoutKind.Sequential)]
class WaveHeader
{
    /// <summary>pointer to locked data buffer (lpData)</summary>
    public IntPtr dataBuffer;
    /// <summary>length of data buffer (dwBufferLength)</summary>
    public int bufferLength;
    /// <summary>used for input only (dwBytesRecorded)</summary>
    public int bytesRecorded;
    /// <summary>for client's use (dwUser)</summary>
    public IntPtr userData;
    /// <summary>assorted flags (dwFlags)</summary>
    // public WaveHeaderFlags flags;
    /// <summary>loop control counter (dwLoops)</summary>
    public int loops;
    /// <summary>PWaveHdr, reserved for driver (lpNext)</summary>
    public IntPtr next;
    /// <summary>reserved for driver</summary>
    public IntPtr reserved;
}

unsafe class Program
{
    [DllImport("msvcrt.dll")]
    extern static void printf(string s, WaveHeader p);

    [DllImport("msvcrt.dll")]
    extern static void printf(string s, void* p);

    static unsafe void Main(string[] args)
    {
        int x;
        printf("%p\n", &x);
        printf("%p\n", new WaveHeader());
    }
}

@jkoritzinsky Could you please take it from here?

@jackpoz Thank you for providing good repro!

@jkoritzinsky
Copy link
Member

I'm trying to figure out how this depends on the pinning optimization. I specifically added a compat feature as part of the change in 5.0.7 to automatically marshal both to and from native whenever a layoutclass with blittable contents is passed to ensure compat as well as tests to validate the behavior, so any dependency would have to be on the address itself and not the implicit side effects.

@jkotas
Copy link
Member

jkotas commented Jun 15, 2021

I'm trying to figure out how this depends on the pinning optimization.

The WaveHeader address has to be valid even after waveOutWrite returns. The code achieves that by creating Pinned GCHandle for WaveHeader. This only works when the marshalled WaveHeader pointer points into the pinned object (.NET 5.0.6 behavior). It does not work when the marshalled WaveHeader pointer points to a stack local (.NET 5.0.7 behavior).

@jkoritzinsky
Copy link
Member

So it does actually depend on the address. 😢

I'll put together a fix for this and once it's in we can decide if we want to backport it.

@michaelgsharp
Copy link
Member

Whats interesting though is that it works on .NET 6 preview 3. So either the pinning optimization has been changed in preview 3 or something else is going on.

@michaelgsharp
Copy link
Member

I am wondering it its a combination windows updates and .NET 5. Unless I am switching runtimes incorrectly (which is very possible) it doesn't work on any version of .NET 5 on my computer.

@KyodaiKen
Copy link

I am wondering it its a combination windows updates and .NET 5. Unless I am switching runtimes incorrectly (which is very possible) it doesn't work on any version of .NET 5 on my computer.

Same here. 5.0 completely broken

@TheRealLenon
Copy link
Author

I am wondering it its a combination windows updates and .NET 5. Unless I am switching runtimes incorrectly (which is very possible) it doesn't work on any version of .NET 5 on my computer.

This is the same for me. Confusing, that this is not happening to all, as a few on here and on the NAudio Issue were able to run it with another .NET version.

@michaelgsharp
Copy link
Member

So I tested on another machine that only had 5.0.1 installed. It ran just fine. Tried same thing/version on the original machine same problem with crashing. Then, I uninstalled the June 2008 security update for 5.0.7 and now it works on my original machine. So it is the issue with 5.0.7 as mentioned above, what is still weird to me is why having 5.0.7 installed breaks all versions of .NET 5 even if you run with an older version.

@jkotas
Copy link
Member

jkotas commented Jun 15, 2021

what is still weird to me is why having 5.0.7 installed breaks all versions of .NET 5 even if you run with an older version.

Applications targeting 5.0.x will automatically roll forward to the latest 5.0.x installed by default.

jkoritzinsky added a commit to jkoritzinsky/runtime that referenced this issue Jun 15, 2021
@michaelgsharp
Copy link
Member

I created a global.json file and set "rollForward": "disable". Does that not prevent that behavior? I also tried specifically setting the SDK version in that file. And when using dotnet run I also tried manually setting the framework with --fx-version.

@jkoritzinsky
Copy link
Member

The same fix that went into .NET 5 that broke this also went into .NET 6 in the Preview 4 time frame, so a fix is needed for .NET 6 as well.

@Fabi
Copy link

Fabi commented Jun 15, 2021

The same fix that went into .NET 5 that broke this also went into .NET 6 in the Preview 4 time frame, so a fix is needed for .NET 6 as well.

fun fact: it works fine on 5.0.8 and 6 preview 4 and later for me

@AraHaan
Copy link
Member

AraHaan commented Jun 15, 2021

Perhaps some other code in .NET 6 Preview 4 that made it work was forgotten in the backport and it just works in .NET 6 Preview 4 because of coincidence.

@jkotas
Copy link
Member

jkotas commented Jun 15, 2021

The crash is caused by use-after-free bug. The crash will only happen if something else actually modified the freed memory in a specific window of time. It is certainly possible that the crash will come and go due to unrelated changes - that's the nature of use-after-free bugs.

@jkoritzinsky
Copy link
Member

Would anyone here be willing/able to test that their NAudio scenario is fixed if I share a .NET runtime build with the proposed fix?

@cits
Copy link

cits commented Jun 15, 2021

Would anyone here be willing/able to test that their NAudio scenario is fixed if I share a .NET runtime build with the proposed fix?

I am willing test my NAudio WPF app.

@jcddcjjcd
Copy link

I am also ready to try with my WPF app.

@TheRealLenon
Copy link
Author

Would anyone here be willing/able to test that their NAudio scenario is fixed if I share a .NET runtime build with the proposed fix?

I would test it with input and instant output on console applications.

@warappa
Copy link

warappa commented Jun 16, 2021

Maybe worth noting, that I'm running NAudio 2.0.0 on 5.0.6 as I have not 5.0.7 installed and having a very similar, but slightly different problem: Microsoft's AudioDG.exe crashes in background while my WPF app keeps on running.

Maybe Helpful Details

In WPF I use NAudio to only change volume on default audio device and play a test-sound with System.Media.SystemSounds.Beep.Play() (read: not played by NAudio). After hearing the beep-sound in full length, AudioDG.exe crashes. The sound device gets disconnected by Windows(?) and 1 second later added again (I can even see it vanish and reappear in Sound settings of classic control panel).

Question

Would this still be explicable with the found bug, or is this then maybe another issue?

Event viewer (multiple entries like this)

Name der fehlerhaften Anwendung: AUDIODG.EXE, Version: 10.0.19041.1023, Zeitstempel: 0x4507cb5a
Name des fehlerhaften Moduls: ntdll.dll, Version: 10.0.19041.1023, Zeitstempel: 0x7977b9de
Ausnahmecode: 0xc0000005
Fehleroffset: 0x0000000000063416
ID des fehlerhaften Prozesses: 0x904
Startzeit der fehlerhaften Anwendung: 0x01d762b2305f2407
Pfad der fehlerhaften Anwendung: C:\Windows\system32\AUDIODG.EXE
Pfad des fehlerhaften Moduls: C:\Windows\SYSTEM32\ntdll.dll
Berichtskennung: 70721d07-491f-4dcb-a91d-b69e9da2cdd8
Vollständiger Name des fehlerhaften Pakets: 
Anwendungs-ID, die relativ zum fehlerhaften Paket ist: 

dotnet --info in WPF app folder

.NET SDK (gemäß "global.json"):
 Version:   5.0.300
 Commit:    2e0c8c940e

Laufzeitumgebung:
 OS Name:     Windows
 OS Version:  10.0.19043
 OS Platform: Windows
 RID:         win10-x64
 Base Path:   C:\Program Files\dotnet\sdk\5.0.300\

Host (useful for support):
  Version: 5.0.6
  Commit:  478b2f8c0e

.NET SDKs installed:
  2.1.807 [C:\Program Files\dotnet\sdk]
  2.2.207 [C:\Program Files\dotnet\sdk]
  5.0.202 [C:\Program Files\dotnet\sdk]
  5.0.300-preview.21258.4 [C:\Program Files\dotnet\sdk]
  5.0.300 [C:\Program Files\dotnet\sdk]

.NET runtimes installed:
  Microsoft.AspNetCore.All 2.1.19 [C:\Program Files\dotnet\shared\Microsoft.AspNetCore.All]
  Microsoft.AspNetCore.All 2.1.28 [C:\Program Files\dotnet\shared\Microsoft.AspNetCore.All]
  Microsoft.AspNetCore.All 2.2.8 [C:\Program Files\dotnet\shared\Microsoft.AspNetCore.All]
  Microsoft.AspNetCore.App 2.1.19 [C:\Program Files\dotnet\shared\Microsoft.AspNetCore.App]
  Microsoft.AspNetCore.App 2.1.28 [C:\Program Files\dotnet\shared\Microsoft.AspNetCore.App]
  Microsoft.AspNetCore.App 2.2.8 [C:\Program Files\dotnet\shared\Microsoft.AspNetCore.App]
  Microsoft.AspNetCore.App 3.1.15 [C:\Program Files\dotnet\shared\Microsoft.AspNetCore.App]
  Microsoft.AspNetCore.App 5.0.5 [C:\Program Files\dotnet\shared\Microsoft.AspNetCore.App]
  Microsoft.AspNetCore.App 5.0.6 [C:\Program Files\dotnet\shared\Microsoft.AspNetCore.App]
  Microsoft.NETCore.App 2.1.19 [C:\Program Files\dotnet\shared\Microsoft.NETCore.App]
  Microsoft.NETCore.App 2.1.28 [C:\Program Files\dotnet\shared\Microsoft.NETCore.App]
  Microsoft.NETCore.App 2.2.8 [C:\Program Files\dotnet\shared\Microsoft.NETCore.App]
  Microsoft.NETCore.App 3.1.15 [C:\Program Files\dotnet\shared\Microsoft.NETCore.App]
  Microsoft.NETCore.App 5.0.5 [C:\Program Files\dotnet\shared\Microsoft.NETCore.App]
  Microsoft.NETCore.App 5.0.6 [C:\Program Files\dotnet\shared\Microsoft.NETCore.App]
  Microsoft.WindowsDesktop.App 3.1.15 [C:\Program Files\dotnet\shared\Microsoft.WindowsDesktop.App]
  Microsoft.WindowsDesktop.App 5.0.5 [C:\Program Files\dotnet\shared\Microsoft.WindowsDesktop.App]
  Microsoft.WindowsDesktop.App 5.0.6 [C:\Program Files\dotnet\shared\Microsoft.WindowsDesktop.App]

@jkotas
Copy link
Member

jkotas commented Jun 16, 2021

Would this still be explicable with the found bug, or is this then maybe another issue?

It is very unlikely to be related to this bug. I would recommend reporting it via Windows Feedback. It looks like a Windows OS bug to me.

@jcddcjjcd
Copy link

This may also not be related but I mention it anyway.

I have stopped using NAudio to play wav files but still use the Volume get and set in NAudio and GetDefaultRenderDevice().AudioMeterInformation.MasterPeakValue.
I have a very rare bug now which I suspect may come from NAudio PeakValues. It does not crash the app but does destroy the RealTek audio driver requiring a reinstall. The crash report mentions ADAudio from Realtek and the NAudio PeakValues code.

This has not happened prior to net v5.07

@jkoritzinsky
Copy link
Member

For everyone who wants to validate this, I've added a link to a zip at the end of this comment with an x64 runtime. If you set the DOTNET_ROOT environment variable to the folder where you unzip this file and set the DOTNET_MULTILEVEL_LOOKUP environment variable to 0 before you run your application from the app host (the .exe that matches your project name), your application will run against the local copy.

https://1drv.ms/u/s!Aj0M_O5AaaC_leEPU6s6nPuz_VGrdA?e=sRRZ7s

@cits
Copy link

cits commented Jun 16, 2021

For everyone who wants to validate this, I've added a link to a zip at the end of this comment with an x64 runtime. If you set the DOTNET_ROOT environment variable to the folder where you unzip this file and set the DOTNET_MULTILEVEL_LOOKUP environment variable to 0 before you run your application from the app host (the .exe that matches your project name), your application will run against the local copy.

https://1drv.ms/u/s!Aj0M_O5AaaC_leEPU6s6nPuz_VGrdA?e=sRRZ7s

Thanks. Worked with my NAudio WPF app.

Any word on how long before this fix will make it into an official public release? Days, weeks or months?

@ghost ghost removed the in-pr There is an active PR which will close this issue when it is merged label Jun 16, 2021
@jkoritzinsky jkoritzinsky reopened this Jun 16, 2021
@jkoritzinsky
Copy link
Member

Reopening to track the servicing fix.

@jkoritzinsky
Copy link
Member

This will likely be more on the scale of months rather than weeks due to the servicing timeline.

@cits
Copy link

cits commented Jun 16, 2021

This will likely be more on the scale of months rather than weeks due to the servicing timeline.

OK. That's disappointing,, I understand.
Time to implement my plan "B", drop using NAudio.

@jcddcjjcd
Copy link

The sad thing here is that NAudio is widely used. It has 2.34 Million downloads on github and there is currently nothing that comes close to it's functionality that is maintained.
There was mention above that if NAudio made it's classes sealled then the problem would go away.
Is that an option that could be considered?

@jkoritzinsky
Copy link
Member

That option would have to be considered by the owners of NAudio, and based off the parallel issue over there, it seems it might be.

@markheath
Copy link

A new version of NAudio is available (2.0.1) that resolves this issue by making WaveHeader sealed.

@elinor-fung elinor-fung removed the untriaged New issue has not been triaged by the area owner label Jun 22, 2021
@elinor-fung elinor-fung added this to the 5.0.x milestone Jun 22, 2021
@jkoritzinsky
Copy link
Member

Fixed by #54244

@ghost ghost locked as resolved and limited conversation to collaborators Aug 14, 2021
Sign up for free to subscribe to this conversation on GitHub. Already have an account? Sign in.