MuseScore incompatible with ALSA libraries 1.2.4 and up

• Dec 29, 2020 - 14:00
Reported version
3.2
Type
Functional
Frequency
Once
Severity
S1 - Blocker
Reproducibility
Always
Status
closed
Regression
No
Workaround
No
Project

Original bugreport: https://bugs.debian.org/cgi-bin/bugreport.cgi?bug=976895
Bugreport against ALSA: https://github.com/alsa-project/alsa-lib/issues/107


Upgrading libasound2 from 1.2.3.2 to 1.2.4 introduces a severe regression affecting MuseScore (both 2 and 3):

Starting musescore3 and loading a score, e.g. like this…

$ musescore3 /usr/share/mscore3-3.2/demos/Reunion.mscz

… quickly brings the whole system down because it spits tons of lines…

Alsa_driver: recover: pcm_status(): Broken pipe

… to the xterm in which it was invoked.


The ALSA developers, very unhelpfully, closed the bugreport at their site, stating it’s the application (i.e. MuseScore) which needs “fixing”. This matches the error message shown:

      if ((err = snd_pcm_status (_play_handle, stat)) < 0) {
            qDebug("Alsa_driver: recover: pcm_status(): %s",  snd_strerror (err));
            return false;
            }

I’m guessing MuseScore needs to do something extra here, not just return an error and go on.

I have no idea what precisely needs “fixing” in MuseScore, but the upstream commit that causes the breakage is https://github.com/alsa-project/alsa-lib/commit/4f90392f07e8822d1984ed9… which, contrary to the initial report suggesting the fix the commit message describes, introduces a new error return path (if snd_pcm_plugin_avail_update(pcm) returns an error (negative value), the entire snd_pcm_plugin_status helper method, and thus everything calling it, will now also return an error).

From grepping around, snd_pcm_status seems to be the (only?) affected function. mscore/alsa.cpp calls this function.


Comments

I don't know which version of that library I build against or which version the AppImage links with, but I've definitely seen that error printed to the console over the past year or so (my Linux builds are on Debian, first stretch then buster). Not so many times the system can't keep up, but maybe a dozen or so times at once. I won't swear it was on my Linux builds (as opposed to Windows) where I've seen them. But shouldn't those qDebug lines only be printed in debug builds? Anyhow, I never noticed any connection to any erroneous behavior, they seemed like innocuous status messages like any of dozens of others we print.

But if the change to ALSA means these are now coming constantly, that sounds like a problem.

I have no insight into this issue, just trying to provide some data that might be helpful. Still, it's not clear to me - in a release build or other context (like running from other than a terminal) where there is no debug output, is there an actual user-visible issue?

I have this very unhelpful message from the ALSA people I have no idea what they are even trying to tell me:

>Refer the documentation: https://www.alsa-project.org/alsa-doc/alsa-lib/pcm.html . -EPIPE means that the
>application is not able to feed the PCM samples in time. The PCM handle should be recovered in this case. But
>the error code may be just a consequence of a wrong buffering. Again, report this to the application
>developers.
>
>--
>You are receiving this because you authored the thread.
>Reply to this email directly or view it on GitHub:
>https://github.com/alsa-project/alsa-lib/issues/107#issuecomment-752246…

As I wrote already: the program freezes (upon loading a score).

From what I see, recover() function in which that message gets printed is actually intended to handle recovering from such type of error, but it just refuses to do so if it fails to get status from snd_pcm_status(). That status is only needed to print another error message about the detected underrun: this is likely what you should see on your system after reverting the commit you have found to cause the issue.

That return false got introduced in this commit, and I guess that reverting that part of the commit (by restoring else if and removing return false) should fix this issue. That is, that part of code should become something like:

if ((err = snd_pcm_status (_play_handle, stat)) < 0) {
      qDebug("Alsa_driver: recover: pcm_status(): %s",  snd_strerror (err));
      }
else if (snd_pcm_status_get_state (stat) == SND_PCM_STATE_XRUN) {
// ...

However, as far as I understand, this issue may freeze the entire application (or even system?) only in environments having only one CPU thread available, as this code is executed in a separate thread. For other systems the symptoms would probably be missing sound and high CPU load. This is, of course, also not good.

Status active closed

We can close this… the ALSA developers looked at the problem again and decided that, indeed, I was right and their commit was wrong.

I expect this to be fixed in 1.2.4.1/1.2.5 or whatever their next release will be, and will take care of fixing this in Debian.

Sorry for the noise caused by this issue. No MuseScore change necessary after all.