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

FlexASIO 1.4 Causes Polyphone to crash on startup #47

Closed
arvindhal opened this issue Jun 10, 2019 · 9 comments
Closed

FlexASIO 1.4 Causes Polyphone to crash on startup #47

arvindhal opened this issue Jun 10, 2019 · 9 comments
Assignees
Labels
asiohost Relates to a specific ASIO Host Application. bug

Comments

@arvindhal
Copy link

Hello,
First off I have to thank the developer for this wonderful driver! It works really well for me with all of the software I have used with it thus far. Also it allows me to actually be able to use Ardour on Windows without horrible feedback from monitoring.
I've only been a user for a day or so but I had an issue with FlexASIO 1.4 being installed and Polyphone crashing on startup. I didn't know it was related to FlexASIO until I launched the MS Debugger on the Polyphone crash and traced the DLL tree finding the FlexASIO dll being loaded. I uninstalled FlexASIO and Polyphone started working again.

My OS is: Win7/64Bit
Crash Interaction occurs with: 64bit and 32bit versions of Polyphone 2.0 and 1.9
MS crash debug information point to

Fault Module Name: ucrtbase.DLL

I tried repairing all versions of MS Visual C Runtimes both 32bit and 64bit on my machine as that dll is related to the MS Visual C Runtimes but it still didn't fix the problem. I also did several reboots and application uninstalls/re installs of Polyphone.

I hope this post helps the developer sort it out. Thanks again for a wonderful contribution.

@dechamps
Copy link
Owner

Sorry to hear that, that's definitely not supposed to happen. Can you see if you can get a log out of FlexASIO when the crash occurs? Not sure it will be able to write one depending on how early it crashes, but if it does it would really help troubleshooting the problem.

@arvindhal
Copy link
Author

arvindhal commented Jun 10, 2019 via email

@dechamps
Copy link
Owner

dechamps commented Jun 10, 2019

Okay, I was able to reproduce this using Polyphone 2.0 32-bit, with the same log. For some reason, in 64-bit Polyphone does not crash but it doesn't show FlexASIO in the list of devices either - it only lists ASIO4ALL and ASIO2WASAPI on my system.

I obtained a stack trace from WinDbg:

00 ucrtbase!abort
01 FlexASIO!flexasio::PortAudioDebugRedirector::PortAudioDebugRedirector
02 FlexASIO!flexasio::FlexASIO::FlexASIO
03 FlexASIO!std::_Construct_in_place
04 FlexASIO!std::_Optional_construct_base<flexasio::FlexASIO>::_Construct
05 FlexASIO!std::optional<flexasio::FlexASIO>::emplace
06 FlexASIO!flexasio::`anonymous-namespace'::CFlexASIO::init::__l2::<lambda_190da7a6d4b30cf06dfe46ae084c2b0f>::operator()
07 FlexASIO!flexasio::`anonymous namespace'::CFlexASIO::Enter<<lambda_190da7a6d4b30cf06dfe46ae084c2b0f> >
08 FlexASIO!flexasio::`anonymous namespace'::CFlexASIO::init
WARNING: Stack unwind information not available. Following frames may be wrong.
09 portaudio_x86!PaAsio_ShowControlPanel
0a portaudio_x86!Pa_WriteStream
0b portaudio_x86!Pa_WriteStream
0c portaudio_x86!PaAsio_GetOutputChannelName
0d portaudio_x86!PaUtil_SetDebugPrintFunction
0e portaudio_x86!Pa_Initialize
0f FlexASIO!flexasio::FlexASIO::FlexASIO
10 FlexASIO!std::_Construct_in_place
11 FlexASIO!std::_Optional_construct_base<flexasio::FlexASIO>::_Construct
12 FlexASIO!std::optional<flexasio::FlexASIO>::emplace
13 FlexASIO!flexasio::`anonymous-namespace'::CFlexASIO::init::__l2::<lambda_190da7a6d4b30cf06dfe46ae084c2b0f>::operator()
14 FlexASIO!flexasio::`anonymous namespace'::CFlexASIO::Enter<<lambda_190da7a6d4b30cf06dfe46ae084c2b0f> >
15 FlexASIO!flexasio::`anonymous namespace'::CFlexASIO::init
16 portaudio_x86!PaAsio_ShowControlPanel
17 portaudio_x86!Pa_WriteStream
18 portaudio_x86!Pa_WriteStream
19 portaudio_x86!PaAsio_GetOutputChannelName
1a portaudio_x86!PaUtil_SetDebugPrintFunction
1b portaudio_x86!Pa_Initialize
1c polyphone
1d polyphone
1e polyphone
1f polyphone
20 polyphone
21 polyphone
22 KERNEL32!BaseThreadInitThunk
23 ntdll!__RtlUserThreadStart
24 ntdll!_RtlUserThreadStart

Suspicious, I looked at the loaded module list, and the relevant modules are:

C:\Program Files\FlexASIO\x86\FlexASIO.dll
C:\Program Files (x86)\Polyphone\portaudio_x86.dll

Oooh. Okay, I see. Jeez, that's messed up.

Basically, the problem is that Polyphone itself already uses PortAudio directly (just like FlexASIO), and the PortAudio DLL that Polyphone is bundled with has the exact same name as the PortAudio DLL that FlexASIO is bundled with. It looks like Windows will not load a DLL with the same basename twice, and will reuse the one that's already loaded (even if the dependent modules are in completely different locations). Which means that when FlexASIO get loaded, instead of using:

C:\Program Files\FlexASIO\x86\portaudio_x86.dll

It ends up using the DLL that Polyphone already loaded, which is:

C:\Program Files (x86)\Polyphone\portaudio_x86.dll

Now at this point we're already in deep trouble, because the Polyphone PortAudio DLL might not be compatible with FlexASIO, and might not have the same features enabled. It doesn't end there, though. The PortAudio DLL that Polyphone is bundled with has ASIO support enabled; in fact that's precisely how Polyphone accesses ASIO drivers. So, Polyphone initializes PortAudio, which initializes FlexASIO. FlexASIO accidentally reuses Polyphone's PortAudio DLL, attempts to initialize that instance of PortAudio again. Which results in PortAudio initializing ASIO drivers again, thus initializing FlexASIO again. At this point we get a reentrant call into FlexASIO's initialization logic, which is an insane situation and, unsurprisingly, everything quickly explodes from there.

This hypothesis is completely consistent with the FlexASIO log, which very clearly shows a reentrant init() call (same thread ID and everything).

Okay, so, I can see two action items here. One is for me, the other is for you:

  • FlexASIO should protect against the situation where a DLL bearing the same base name as its PortAudio DLL is already loaded. Honestly, I already suspected something like this could happen but I expected the Windows DLL loader to do the right thing and load both DLLs side-by-side - evidently that's not how it works. I need to investigate the behaviour of the Windows DLL loader some more and come up with a way to force it to load FlexASIO's PortAudio DLL. (An obvious solution could be to change FlexASIO's PortAudio DLL to have a more unique name, but that seems a bit hacky.)
  • That being said… since Polyphone is already using PortAudio, I'm not sure I understand why you want to use FlexASIO with Polyphone in the first place. It probably won't give you much, since FlexASIO is a thin wrapper on top of PortAudio - so basically, in the end you will always be using PortAudio, directly or indirectly. Maybe you want to use PortAudio features that Polyphone does not enable (such as WASAPI support)? In that case, it might be easier to go to the Polyphone devs and ask them to enable these features. It should be fairly easy for them to do so.

@dechamps dechamps added asiohost Relates to a specific ASIO Host Application. bug labels Jun 10, 2019
@dechamps dechamps self-assigned this Jun 10, 2019
@dechamps
Copy link
Owner

It looks like the cleanest way to make FlexASIO immune from this problem is to use a Windows feature known as Side-by-Side Assemblies:

https://social.msdn.microsoft.com/Forums/vstudio/en-US/b3eaa07f-7f92-4693-8aa1-b8fee0b92d2f/cannot-load-2-dlls-with-same-name-but-different-versions

https://en.wikipedia.org/wiki/Side-by-side_assembly

https://docs.microsoft.com/en-gb/windows/desktop/SbsCs/isolated-applications-and-side-by-side-assemblies-portal

Looks promising. I'll look into that more deeply when I have some time.

@arvindhal
Copy link
Author

arvindhal commented Jun 10, 2019 via email

@arvindhal
Copy link
Author

arvindhal commented Jun 10, 2019 via email

@dechamps
Copy link
Owner

This should be fixed in FlexASIO 1.5.

@dechamps
Copy link
Owner

dechamps commented Feb 2, 2023

FYI, unfortunately this issue is back starting from FlexASIO 1.8 due to a PortAudio change that went unnoticed and broke the fix. This is being tracked in #182. (Although to be clear the new issue might not affect Polyphone if it's still using the old PortAudio DLL name.)

@dechamps
Copy link
Owner

…and it is fixed again via #182 in FlexASIO 1.10.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
asiohost Relates to a specific ASIO Host Application. bug
Projects
None yet
Development

No branches or pull requests

2 participants