Bug 55135

Summary: module-match asserts on channels=0
Product: PulseAudio Reporter: Jussi Kukkonen [inactive] <jussi.kukkonen>
Component: modulesAssignee: pulseaudio-bugs
Status: RESOLVED FIXED QA Contact: pulseaudio-bugs
Severity: normal    
Priority: medium CC: lennart
Version: unspecified   
Hardware: Other   
OS: All   
Whiteboard:
i915 platform: i915 features:
Attachments: Fix candidate

Description Jussi Kukkonen [inactive] 2012-09-20 10:07:35 UTC
I'm trying to test module-match but so far the only result is making the daemon assert.

#0  0x00007fa2ff30f475 in raise () from /lib/x86_64-linux-gnu/libc.so.6
#1  0x00007fa2ff3126f0 in abort () from /lib/x86_64-linux-gnu/libc.so.6
#2  0x00007fa3005960fe in pa_cvolume_set (a=a@entry=0x7fff7544ce50, channels=<optimized out>, v=<optimized out>)
    at pulse/volume.c:77
#3  0x00007fa2ee574727 in sink_input_new_hook_callback (c=<optimized out>, si=0x7fff7544d5f0, u=<optimized out>)
    at modules/module-match.c:236
#4  0x00007fa300a38d5c in pa_hook_fire (hook=hook@entry=0xf764b8, data=data@entry=0x7fff7544d5f0)
    at pulsecore/hook-list.c:106
#5  0x00007fa300a51783 in pa_sink_input_new (_i=_i@entry=0x7fff7544d478, core=0xf76130, 
    data=data@entry=0x7fff7544d5f0) at pulsecore/sink-input.c:273
#6  0x00007fa2f68d27d8 in playback_stream_new (ret=<synthetic pointer>, missing=<synthetic pointer>, syncid=2, 
    relative_volume=false, early_requests=false, adjust_latency=true, p=0xf972a0, flags=PA_SINK_INPUT_START_CORKED, 
    muted_set=false, muted=false, volume=0x0, a=0x7fff7544d490, formats=0x0, map=0x7fff7544d4d0, ss=0x7fff7544d480, 
    sink=0x0, c=0x10ab610) at pulsecore/protocol-native.c:1147
#7  command_create_playback_stream (pd=<optimized out>, command=<optimized out>, tag=<optimized out>, 
    t=<optimized out>, userdata=0x10ab610) at pulsecore/protocol-native.c:2134
#8  0x00007fa3007dd8fd in pa_pdispatch_run (pd=0xf8e1d0, packet=<optimized out>, creds=0xf9bf40, 
    userdata=userdata@entry=0x10ab610) at pulsecore/pdispatch.c:336
#9  0x00007fa2f68d31e0 in pstream_packet_callback (p=0xf9bdf0, packet=<optimized out>, creds=<optimized out>, 
    userdata=0x10ab610) at pulsecore/protocol-native.c:4747
#10 0x00007fa3007e192b in do_read (p=0xf9bdf0) at pulsecore/pstream.c:812
#11 do_something (p=0xf9bdf0) at pulsecore/pstream.c:180
#12 0x00007fa300585654 in dispatch_pollfds (m=0xf75d50) at pulse/mainloop.c:677
#13 pa_mainloop_dispatch (m=m@entry=0xf75d50) at pulse/mainloop.c:927
#14 0x00007fa300585a05 in pa_mainloop_iterate (m=m@entry=0xf75d50, block=block@entry=1, 
    retval=retval@entry=0x7fff7544db14) at pulse/mainloop.c:958
#15 0x00007fa300585ab0 in pa_mainloop_run (m=m@entry=0xf75d50, retval=retval@entry=0x7fff7544db14)
    at pulse/mainloop.c:973
#16 0x000000000040732f in main (argc=<optimized out>, argv=<optimized out>) at daemon/main.c:1135


From a quick look in gdb, it seems that module-match.c:sink_input_new_hook_callback() calls pa_cvolume_set() with channels=0.

This happens with e.g. this match.table line:
.* 0
Comment 1 Jussi Kukkonen [inactive] 2012-09-20 10:11:08 UTC
Oh, this is on pulseaudio 2.0 (wouldn't have just filed this but I thought I was running latest release...)
Comment 2 Jussi Kukkonen [inactive] 2012-09-21 09:21:15 UTC
Had some debugging help... It looks like gstreamer does something weird and pulseaudio decides to assert because of that. If I use paplay everything works, but gstreamer using apps will assert PA with module-match.

Here's a pa_sink_input_new_data* in pa_sink_input_new() -- notice how the sample_spec is just empty, e.g. sample_spec.channels = 0:

Breakpoint 1, pa_sink_input_new (_i=_i@entry=0x7fffb2fd4508, core=0x21ea130, data=data@entry=0x7fffb2fd4680)
    at pulsecore/sink-input.c:239
239	pulsecore/sink-input.c: No such file or directory.
(gdb) print *data
$1 = {flags = PA_SINK_INPUT_START_CORKED, proplist = 0x2208780, 
  driver = 0x7f681ee55920 "pulsecore/protocol-native.c", module = 0x2272550, client = 0x2204350, sink = 0x0, 
  origin_sink = 0x0, resample_method = PA_RESAMPLER_INVALID, sync_base = 0x0, sample_spec = {format = PA_SAMPLE_U8, 
    rate = 0, channels = 0 '\000'}, channel_map = {channels = 0 '\000', map = {
      PA_CHANNEL_POSITION_MONO <repeats 32 times>}}, format = 0x0, req_formats = 0x2200e80, nego_formats = 0x0, 
  volume = {channels = 0 '\000', values = {0 <repeats 32 times>}}, volume_factor = {channels = 0 '\000', values = {
      0 <repeats 32 times>}}, volume_factor_sink = {channels = 0 '\000', values = {0 <repeats 32 times>}}, 
  muted = false, sample_spec_is_set = false, channel_map_is_set = false, volume_is_set = false, 
  volume_factor_is_set = false, volume_factor_sink_is_set = false, muted_is_set = false, volume_is_absolute = false, 
  volume_writable = true, save_sink = false, save_volume = false, save_muted = false}


I don't think PA should assert when this happens.
Comment 3 Tanu Kaskinen 2012-09-27 13:35:03 UTC
I couldn't reproduce this, but the information posted so far is enough to find the error. module-match uses the SINK_INPUT_NEW hook, and then relies on the sample spec being properly initialized. This is clearly wrong: if the sink input uses the FIX_CHANNELS flag, the number of channels will be unknown until the sink input has been routed to some sink.

In your case the FIX_CHANNELS flag is not being used. I'm not sure if there's some other bug involved in your case (I wouldn't be surprised), but fixing module-match should make things work for you. If the fix doesn't turn out to be hard to do, I'll post a patch soon.
Comment 4 Tanu Kaskinen 2012-09-27 13:41:12 UTC
Created attachment 67767 [details] [review]
Fix candidate

Does this patch fix the problem for you?
Comment 5 Jussi Kukkonen [inactive] 2012-09-28 08:55:49 UTC
(In reply to comment #4)
> Created attachment 67767 [details] [review] [review]
> Fix candidate
> 
> Does this patch fix the problem for you?

It does. No asserts and seems to work as expected.

Thanks.
Comment 6 Jussi Kukkonen [inactive] 2012-09-28 09:00:42 UTC
Although I did not test at the same time with stream-restore... Is this bound to break the functionality refered in this comment:
     /* hook EARLY - 1, to match before stream-restore */

(I'm not familiar with the internals so maybe that makes no sense)
Comment 7 Tanu Kaskinen 2012-09-28 12:08:18 UTC
This patch actually makes the comment correct :) I think earlier module-stream-restore used the NEW hook too, and the comment was written at that time. Then module-stream-restore was changed to use the FIXATE hook, possibly to fix a bug similar to this, so the comment became outdated. Now the comment is relevant again, because the two modules use the same hook.

Use of freedesktop.org services, including Bugzilla, is subject to our Code of Conduct. How we collect and use information is described in our Privacy Policy.