alsa-project / alsa-lib

The Advanced Linux Sound Architecture (ALSA) - library
GNU Lesser General Public License v2.1
366 stars 177 forks source link

Wrong binds configuration for dmix plugin causes segmentation fault in alsa #117

Closed elara-leitstellentechnik closed 3 years ago

elara-leitstellentechnik commented 3 years ago

On Debian buster I can get alsa to run into a segmentation fault with the following procedure: Configure dmix with two channels (binds) for a Mono device. (I am not sure that this is reproducible with any mono device, I tested with a Jabra LINK 230):

~$ cat .asoundrc  
pcm."Jabra LINK 230" {  
       type dmix  
       ipc_key 1024  
       slave.pcm "hw:2,0"  
       bindings {  
              0 0  
             # The next line is the problematic line that triggers the segfault
              1 1  
       }  
}  

Then when playing any sound file with e.g. mplayer and making it use the dmix device the following happens:

$ mplayer -ao alsa:device="Jabra LINK 230" /usr/share/sounds/alsa/Front_Left.wav
MPlayer 1.3.0 (Debian), built with gcc-8 (C) 2000-2016 MPlayer Team
do_connect: could not connect to socket
connect: No such file or directory
Failed to open LIRC support. You will not be able to use your remote control.

Playing /usr/share/sounds/alsa/Front_Left.wav.
libavformat version 58.20.100 (external)
Mismatching header version 58.12.100
Audio only file format detected.
Load subtitles in /usr/share/sounds/alsa/
==========================================================================
Opening audio decoder: [pcm] Uncompressed PCM audio decoder
AUDIO: 48000 Hz, 1 ch, s16le, 768.0 kbit/100.00% (ratio: 96000->96000)
Selected audio codec: [pcm] afm: pcm (Uncompressed PCM)
==========================================================================
[AO_ALSA] alsa-lib: pcm_hw.c:1711:(snd_pcm_hw_open) open '/dev/snd/pcmC2D0p' failed (-77): File descriptor in bad state
AO: [alsa] 48000Hz 2ch s16le (2 bytes per sample)
Video: no video
Starting playback...

MPlayer interrupted by signal 11 in module: play_audio
- MPlayer crashed by bad usage of CPU/FPU/RAM.
  Recompile MPlayer with --enable-debug and make a 'gdb' backtrace and
  disassembly. Details in DOCS/HTML/en/bugreports_what.html#bugreports_crash.
 [ This binary of MPlayer in Debian is currently compiled with
   '--enable-debug'; the debugging symbols are in the package
   'mplayer-dbgsym'.]

I appreciate that configuring two bindings for a single-channel audio device is an error, but I am not sure that this justifies a segfault. Here is some more information I have been able to extract using gdb:

~$ gdb --args mplayer -ao alsa:device="Jabra LINK 230" /usr/share/sounds/alsa/Front_Left.wav
GNU gdb (Debian 8.2.1-2+b3) 8.2.1
Copyright (C) 2018 Free Software Foundation, Inc.
License GPLv3+: GNU GPL version 3 or later <http://gnu.org/licenses/gpl.html>
This is free software: you are free to change and redistribute it.
There is NO WARRANTY, to the extent permitted by law.
Type "show copying" and "show warranty" for details.
This GDB was configured as "x86_64-linux-gnu".
Type "show configuration" for configuration details.
For bug reporting instructions, please see:
<http://www.gnu.org/software/gdb/bugs/>.
Find the GDB manual and other documentation resources online at:
    <http://www.gnu.org/software/gdb/documentation/>.

For help, type "help".
Type "apropos word" to search for commands related to "word"...
Reading symbols from mplayer...Reading symbols from /usr/lib/debug/.build-id/3a/9816e9d363979a4f76e6cb809a33dffda67d05.debug...done.
done.
(gdb) run
Starting program: /usr/bin/mplayer -ao alsa:device=Jabra\ LINK\ 230 /usr/share/sounds/alsa/Front_Left.wav
[Thread debugging using libthread_db enabled]
Using host libthread_db library "/lib/x86_64-linux-gnu/libthread_db.so.1".
MPlayer 1.3.0 (Debian), built with gcc-8 (C) 2000-2016 MPlayer Team
do_connect: could not connect to socket
connect: No such file or directory
Failed to open LIRC support. You will not be able to use your remote control.

Playing /usr/share/sounds/alsa/Front_Left.wav.
libavformat version 58.20.100 (external)
Mismatching header version 58.12.100
Audio only file format detected.
Load subtitles in /usr/share/sounds/alsa/
==========================================================================
Opening audio decoder: [pcm] Uncompressed PCM audio decoder
AUDIO: 48000 Hz, 1 ch, s16le, 768.0 kbit/100.00% (ratio: 96000->96000)
Selected audio codec: [pcm] afm: pcm (Uncompressed PCM)
==========================================================================
[AO_ALSA] alsa-lib: pcm_hw.c:1711:(snd_pcm_hw_open) open '/dev/snd/pcmC2D0p' failed (-77): File descriptor in bad state
AO: [alsa] 48000Hz 2ch s16le (2 bytes per sample)
Video: no video
Starting playback...

Program received signal SIGSEGV, Segmentation fault.
0x00007ffff7a09b76 in mix_areas_16_smp (size=4160473088, size@entry=17424, dst=0x555555aa9510, src=0xde020109, sum=0x21fe0f3c, dst_step=2, src_step=4, sum_step=8) at pcm_dmix_x86_64.h:48
48  pcm_dmix_x86_64.h: No such file or directory.
(gdb) where
#0  0x00007ffff7a09b76 in mix_areas_16_smp (size=4160473088, size@entry=17424, dst=0x555555aa9510, src=0xde020109, sum=0x21fe0f3c, dst_step=2, src_step=4, sum_step=8) at pcm_dmix_x86_64.h:48
#1  0x00007ffff7a0ba1c in mix_areas (size=17424, dst_ofs=576, src_ofs=0, dst_areas=0x555555a927f0, src_areas=0x7fffe88b3000, dmix=0x555555a929e0) at pcm_dmix.c:215
#2  snd_pcm_dmix_sync_area (pcm=pcm@entry=0x555555a94850) at pcm_dmix.c:382
#3  0x00007ffff7a0bdfa in snd_pcm_dmix_start (pcm=0x555555a94850) at pcm_dmix.c:619
#4  0x00007ffff79d8b4a in __snd_pcm_start (pcm=0x555555a94850, pcm=0x555555a94850) at pcm_local.h:434
#5  snd1_pcm_write_areas (pcm=pcm@entry=0x555555a94850, areas=areas@entry=0x7fffffffcfd0, offset=offset@entry=0, size=<optimized out>, size@entry=18000, func=func@entry=0x7ffff79e46c0 <snd_pcm_mmap_write_areas>) at pcm.c:7421
#6  0x00007ffff79e4b01 in snd_pcm_mmap_writei (pcm=0x555555a94850, buffer=<optimized out>, size=18000) at pcm_mmap.c:153
#7  0x00005555556242f8 in play (data=0x555555ac4f70, len=<optimized out>, flags=<optimized out>) at libao2/ao_alsa.c:812
#8  0x000055555560bbab in fill_audio_out_buffers () at mplayer.c:2212
#9  main (argc=<optimized out>, argv=<optimized out>) at mplayer.c:3794
(gdb) 

To me this looks like the segfault is triggered in pcm_dmix_x86_64.h:48 so I believe it is an alsa problem rather than a problem with mplayer. I hope this makes sense. If I can support with further information please let me know.

perexg commented 3 years ago

Could you test this change? (LD_PRELOAD may help to test the self-compiled alsa-lib)

diff --git a/src/pcm/pcm_direct.c b/src/pcm/pcm_direct.c
index 19c5a811..79017bcb 100644
--- a/src/pcm/pcm_direct.c
+++ b/src/pcm/pcm_direct.c
@@ -1635,6 +1635,7 @@ int snd_pcm_direct_check_interleave(snd_pcm_direct_t *dmix, snd_pcm_t *pcm)
        if ((bits % 8) != 0)
                interleaved = 0;
        channels = dmix->channels;
+       interleaved = dmix->channels == dmix->shmptr->s.channels;
        dst_areas = snd_pcm_mmap_areas(dmix->spcm);
        src_areas = snd_pcm_mmap_areas(pcm);
        for (chn = 1; chn < channels; chn++) {
elara-leitstellentechnik commented 3 years ago

Still crashing, but with a different stack trace:

$ gdb --args mplayer -ao alsa:device="Jabra LINK 230" /usr/share/sounds/alsa/Front_Left.wav
GNU gdb (Debian 8.2.1-2+b3) 8.2.1
Copyright (C) 2018 Free Software Foundation, Inc.
License GPLv3+: GNU GPL version 3 or later <http://gnu.org/licenses/gpl.html>
This is free software: you are free to change and redistribute it.
There is NO WARRANTY, to the extent permitted by law.
Type "show copying" and "show warranty" for details.
This GDB was configured as "x86_64-linux-gnu".
Type "show configuration" for configuration details.
For bug reporting instructions, please see:
<http://www.gnu.org/software/gdb/bugs/>.
Find the GDB manual and other documentation resources online at:
    <http://www.gnu.org/software/gdb/documentation/>.

For help, type "help".
Type "apropos word" to search for commands related to "word"...
Reading symbols from mplayer...Reading symbols from /usr/lib/debug/.build-id/3a/9816e9d363979a4f76e6cb809a33dffda67d05.debug...done.
done.
(gdb) run
Starting program: /usr/bin/mplayer -ao alsa:device=Jabra\ LINK\ 230 /usr/share/sounds/alsa/Front_Left.wav
[Thread debugging using libthread_db enabled]
Using host libthread_db library "/lib/x86_64-linux-gnu/libthread_db.so.1".
MPlayer 1.3.0 (Debian), built with gcc-8 (C) 2000-2016 MPlayer Team
do_connect: could not connect to socket
connect: No such file or directory
Failed to open LIRC support. You will not be able to use your remote control.

Playing /usr/share/sounds/alsa/Front_Left.wav.
libavformat version 58.20.100 (external)
Mismatching header version 58.12.100
Audio only file format detected.
Load subtitles in /usr/share/sounds/alsa/
==========================================================================
Opening audio decoder: [pcm] Uncompressed PCM audio decoder
AUDIO: 48000 Hz, 1 ch, s16le, 768.0 kbit/100.00% (ratio: 96000->96000)
Selected audio codec: [pcm] afm: pcm (Uncompressed PCM)
==========================================================================
[AO_ALSA] alsa-lib: pcm_hw.c:1711:(snd_pcm_hw_open) open '/dev/snd/pcmC2D0p' failed (-77): File descriptor in bad state
AO: [alsa] 48000Hz 2ch s16le (2 bytes per sample)
Video: no video
Starting playback...

Program received signal SIGSEGV, Segmentation fault.
0x00007ffff7a09b86 in ?? () from /lib/x86_64-linux-gnu/libasound.so.2
(gdb) where
#0  0x00007ffff7a09b86 in ?? () from /lib/x86_64-linux-gnu/libasound.so.2
#1  0x00007ffff7a0ba2c in ?? () from /lib/x86_64-linux-gnu/libasound.so.2
#2  0x00007ffff7a0be0a in ?? () from /lib/x86_64-linux-gnu/libasound.so.2
#3  0x00007ffff79d8b3a in ?? () from /lib/x86_64-linux-gnu/libasound.so.2
#4  0x00007ffff79e4b11 in snd_pcm_mmap_writei () from /lib/x86_64-linux-gnu/libasound.so.2
#5  0x00005555556242f8 in play (data=0x555555aba920, len=<optimized out>, flags=<optimized out>) at libao2/ao_alsa.c:812
#6  0x000055555560bbab in fill_audio_out_buffers () at mplayer.c:2212
#7  main (argc=<optimized out>, argv=<optimized out>) at mplayer.c:3794
(gdb) 

I applied the proposed patch using the debian src packaging toolchain. Here is the patch file I used:

$ cat debian/patches/alsa-dmix-crash.patch 
Index: alsa-lib-1.1.8/src/pcm/pcm_direct.c
===================================================================
--- alsa-lib-1.1.8.orig/src/pcm/pcm_direct.c
+++ alsa-lib-1.1.8/src/pcm/pcm_direct.c
@@ -1613,6 +1613,7 @@ int snd_pcm_direct_check_interleave(snd_
    if ((bits % 8) != 0)
        interleaved = 0;
    channels = dmix->channels;
+    interleaved = dmix->channels == dmix->shmptr->s.channels;
    dst_areas = snd_pcm_mmap_areas(dmix->spcm);
    src_areas = snd_pcm_mmap_areas(pcm);
    for (chn = 1; chn < channels; chn++) {

May I ask if you have been able to reproduce the problem?

elara-leitstellentechnik commented 3 years ago

Oh I think the debug symbols might have got lost in the process of installing the patched package...

elara-leitstellentechnik commented 3 years ago

Ok. After reinstalling the dbg package the stack trace looks more similar. Sorry for the confusion

GNU gdb (Debian 8.2.1-2+b3) 8.2.1
Copyright (C) 2018 Free Software Foundation, Inc.
License GPLv3+: GNU GPL version 3 or later <http://gnu.org/licenses/gpl.html>
This is free software: you are free to change and redistribute it.
There is NO WARRANTY, to the extent permitted by law.
Type "show copying" and "show warranty" for details.
This GDB was configured as "x86_64-linux-gnu".
Type "show configuration" for configuration details.
For bug reporting instructions, please see:
<http://www.gnu.org/software/gdb/bugs/>.
Find the GDB manual and other documentation resources online at:
    <http://www.gnu.org/software/gdb/documentation/>.

For help, type "help".
Type "apropos word" to search for commands related to "word"...
Reading symbols from mplayer...Reading symbols from /usr/lib/debug/.build-id/3a/9816e9d363979a4f76e6cb809a33dffda67d05.debug...done.
done.
(gdb) run
Starting program: /usr/bin/mplayer -ao alsa:device=Jabra\ LINK\ 230 /usr/share/sounds/alsa/Front_Left.wav
[Thread debugging using libthread_db enabled]
Using host libthread_db library "/lib/x86_64-linux-gnu/libthread_db.so.1".
MPlayer 1.3.0 (Debian), built with gcc-8 (C) 2000-2016 MPlayer Team
do_connect: could not connect to socket
connect: No such file or directory
Failed to open LIRC support. You will not be able to use your remote control.

Playing /usr/share/sounds/alsa/Front_Left.wav.
libavformat version 58.20.100 (external)
Mismatching header version 58.12.100
Audio only file format detected.
Load subtitles in /usr/share/sounds/alsa/
==========================================================================
Opening audio decoder: [pcm] Uncompressed PCM audio decoder
AUDIO: 48000 Hz, 1 ch, s16le, 768.0 kbit/100.00% (ratio: 96000->96000)
Selected audio codec: [pcm] afm: pcm (Uncompressed PCM)
==========================================================================
[AO_ALSA] alsa-lib: pcm_hw.c:1711:(snd_pcm_hw_open) open '/dev/snd/pcmC2D0p' failed (-77): File descriptor in bad state
AO: [alsa] 48000Hz 2ch s16le (2 bytes per sample)
Video: no video
Starting playback...

Program received signal SIGSEGV, Segmentation fault.
0x00007ffff7a09b86 in mix_areas_16_smp (size=4160473088, size@entry=17424, dst=0x555555a9eec0, src=0xde020109, sum=0x21fe0f3c, dst_step=2, src_step=4, sum_step=8) at pcm_dmix_x86_64.h:48
48  pcm_dmix_x86_64.h: No such file or directory.
(gdb) where
#0  0x00007ffff7a09b86 in mix_areas_16_smp (size=4160473088, size@entry=17424, dst=0x555555a9eec0, src=0xde020109, sum=0x21fe0f3c, dst_step=2, src_step=4, sum_step=8) at pcm_dmix_x86_64.h:48
#1  0x00007ffff7a0ba2c in mix_areas (size=17424, dst_ofs=576, src_ofs=0, dst_areas=0x555555a92f20, src_areas=0x7fffe88b3000, dmix=0x555555a94ac0) at pcm_dmix.c:215
#2  snd_pcm_dmix_sync_area (pcm=pcm@entry=0x555555a94c30) at pcm_dmix.c:382
#3  0x00007ffff7a0be0a in snd_pcm_dmix_start (pcm=0x555555a94c30) at pcm_dmix.c:619
#4  0x00007ffff79d8b3a in __snd_pcm_start (pcm=0x555555a94c30, pcm=0x555555a94c30) at pcm_local.h:434
#5  snd1_pcm_write_areas (pcm=pcm@entry=0x555555a94c30, areas=areas@entry=0x7fffffffcfe0, offset=offset@entry=0, size=<optimized out>, size@entry=18000, func=func@entry=0x7ffff79e46d0 <snd_pcm_mmap_write_areas>) at pcm.c:7421
#6  0x00007ffff79e4b11 in snd_pcm_mmap_writei (pcm=0x555555a94c30, buffer=<optimized out>, size=18000) at pcm_mmap.c:153
#7  0x00005555556242f8 in play (data=0x555555aba920, len=<optimized out>, flags=<optimized out>) at libao2/ao_alsa.c:812
#8  0x000055555560bbab in fill_audio_out_buffers () at mplayer.c:2212
#9  main (argc=<optimized out>, argv=<optimized out>) at mplayer.c:3794
(gdb) 
perexg commented 3 years ago

Fixed in https://github.com/alsa-project/alsa-lib/commit/e0e084659083c2ab75d5c894f24227ea2f67010f . Thank you for your report.