There are code paths (mostly error cases) in which it is possible to
initialize an AudioOutput and then kill it without ever calling
audio_output_new().  In such a case, its destructor will attempt to
free a mixer that was never initialized, leading to an attempt to
take out a lock on a mutex that was similarly never initialized,
which hangs forever.

Fix by always initializing the mixer appropriately.
---
 src/output/Init.cxx | 1 +
 1 file changed, 1 insertion(+)

This bug made it hell to get a Shoutcast stream initialized: I forgot
that you need the quality and format even for a flac stream (!) but
rather than giving me an error in the log, I got this (here from a
copy of mpd instrumented with alloc/free logging so you can see the
bug in action, an output init with a garbage mixer, then an attempt
to free that mixer and lock a garbage mutex):

audio output init: mixer is 0x6ca470
freeing mixer: 0x6ca470
mixer_close: mixer lock takeout
Locking 0x6ca488@0x6ca488
# hangs forever
^C
Program received signal SIGINT, Interrupt.
0x00007fffefacf86c in __lll_lock_wait () from /lib/libpthread.so.0
(gdb) bt
#0  0x00007fffefacf86c in __lll_lock_wait () from /lib/libpthread.so.0
#1  0x00007fffefacb517 in _L_lock_574 () from /lib/libpthread.so.0
#2  0x00007fffefacb376 in pthread_mutex_lock () from /lib/libpthread.so.0
#3  0x0000000000414586 in mixer_close(Mixer*) ()
#4  0x0000000000414622 in mixer_free(Mixer*) ()
#5  0x0000000000413ab2 in AudioOutput::~AudioOutput() ()
#6  0x0000000000462f36 in my_shout_init_driver(config_param const&, Error&) ()
#7  0x0000000000413eb2 in audio_output_new(EventLoop&, config_param const&, 
MixerListener&, PlayerControl&, Error&) ()
#8  0x00000000004123ad in LoadOutput(EventLoop&, MixerListener&, 
PlayerControl&, config_param const&) ()
#9  0x000000000041316a in MultipleOutputs::Configure(EventLoop&, 
PlayerControl&) ()
#10 0x0000000000411d84 in mpd_main(int, char**) ()
#11 0x00007fffef739c05 in __libc_start_main () from /lib/libc.so.6
#12 0x0000000000411731 in _start ()

diff --git a/src/output/Init.cxx b/src/output/Init.cxx
index eafcec4..79ef4f9 100644
--- a/src/output/Init.cxx
+++ b/src/output/Init.cxx
@@ -48,6 +48,7 @@
 
 AudioOutput::AudioOutput(const AudioOutputPlugin &_plugin)
        :plugin(_plugin),
+        mixer(nullptr),
         enabled(true), really_enabled(false),
         open(false),
         pause(false),
-- 
2.1.3.185.g60b3e4d
_______________________________________________
mpd-devel mailing list
[email protected]
http://mailman.blarg.de/listinfo/mpd-devel

Reply via email to