[gstreamer-bugs] [Bug 372071] New: gstbasesrc : race condition upon gst_base_src_deactivate crashes in gst_base_src_get_range

GStreamer (bugzilla.gnome.org) bugzilla-daemon at bugzilla.gnome.org
Tue Nov 7 08:14:04 PST 2006


Do not reply to this via email (we are currently unable to handle email
responses and they get discarded).  You can add comments to this bug at
http://bugzilla.gnome.org/show_bug.cgi?id=372071

  GStreamer | gstreamer (core) | Ver: HEAD CVS

           Summary: gstbasesrc : race condition upon gst_base_src_deactivate
                    crashes in gst_base_src_get_range
           Product: GStreamer
           Version: HEAD CVS
          Platform: Other
        OS/Version: Linux
            Status: UNCONFIRMED
          Severity: normal
          Priority: Normal
         Component: gstreamer (core)
        AssignedTo: gstreamer-bugs at lists.sourceforge.net
        ReportedBy: vanista at gmail.com
         QAContact: gstreamer-bugs at lists.sourceforge.net
     GNOME version: Unspecified
   GNOME milestone: Unspecified


Overview Description:

A crash can occur in gstbasesrc when a pipeline is interupted before normal EOS
by changing its state to NULL.

The unprotected call to gst_pad_stop_task in gst_base_src_deactivate can lead
to unrefs of member objects still used in another thread.


Steps to Reproduce:

This was tested with gstreamer-0.10.6, but the behaviour hasn't changed in HEAD
so the problem should remain...

This is impossible to reproduce using gst-launch-0.10, it occurs in the scope
of a program which dynamically builds a pipeline, runs, and halts it upon
receiving the first buffers from a fakesink's handoff callback. The program
uses gstreamer for media analysis by peeking a few decoded buffers and their
caps.

The main thread of the program has the same behaviour as gst-launch-0.10 for
polling the bus in a loop. When the loop catches and EOS message, it stops and
changes the state of the pipeline bin to NULL.

The callback function, when deciding it has received enough buffers will post
and EOS message on the bus. This way, no change state is triggered within any
thread.

1) As the state is changed to NULL, a pipeline containing a filesrc will call
gst_base_src_deactivate. This will unref the mmap objects of the filesrc,
regardless of what it's currently doing.

2) On some rare occasion, the loop thread of a demuxer will execute
gst_base_src_get_range at the exact same time, pass the checks for pad activity
and end-up with an unreffed buffer moments later. 


Actual Results:

This of course leads to various side effects ranging from gst and glib warnings
to plain seg fault.


Expected Results:

All data flow handling should be protected from element state changes.


Patch/Fix:

Locking the basesrc object before triggering gst_pad_stop_task fixes the
problem...

This simple patch has been created for HEAD :


--- original/gstbasesrc.c       2006-11-07 10:36:53.000000000 -0500
+++ patched/gstbasesrc.c        2006-11-07 10:36:01.000000000 -0500
@@ -1872,7 +1872,9 @@
   result = gst_base_src_unlock (basesrc);

   /* step 2, make sure streaming finishes */
+  GST_OBJECT_LOCK(basesrc);
   result &= gst_pad_stop_task (pad);
+  GST_OBJECT_UNLOCK(basesrc);

   return result;
 }





Debug Traces:

(gdb) bt
#0  0xb679f780 in gst_file_src_create (basesrc=0x0, offset=208576,
length=120000, buffer=0xb3356344) at gstfilesrc.c:602
#1  0xb678038d in gst_base_src_get_range (src=0xb2223080, offset=208576,
length=120000, buf=0xb3356344) at gstbasesrc.c:1269
#2  0xb6780f4e in gst_base_src_pad_get_range (pad=0x0,
offset=12835875214273282048, length=0, buf=0x0) at gstbasesrc.c:1337
#3  0xb7602757 in gst_pad_get_range (pad=0xb2232628, offset=208576,
size=120000, buffer=0xb3356344) at gstpad.c:3492
#4  0xb7602c20 in gst_pad_pull_range (pad=0xb2213bc0,
offset=12835875214273282048, size=0, buffer=0xb3356344) at gstpad.c:3574
#5  0xb676c41a in gst_qtdemux_loop (pad=0xb2213bc0) at qtdemux.c:1296
#6  0xb7616a58 in gst_task_func (task=0xb22348f0, tclass=0x8124a00) at
gsttask.c:193
#7  0xb7412881 in g_thread_pool_thread_proxy (data=0x81238f8) at
gthreadpool.c:114
#8  0xb7410aef in g_thread_create_proxy (data=0xb22339b8) at gthread.c:564
#9  0xb6ebe341 in start_thread () from /lib/tls/i686/cmov/libpthread.so.0
#10 0xb6e534ee in clone () from /lib/tls/i686/cmov/libc.so.6

(gdb) thread 5
#0  0xffffe410 in __kernel_vsyscall ()
#1  0xb6ec32ae in __lll_mutex_lock_wait () from
/lib/tls/i686/cmov/libpthread.so.0
#2  0xb6ebffbb in _L_mutex_lock_33 () from /lib/tls/i686/cmov/libpthread.so.0
#3  0xbf9ed5d8 in ?? ()
#4  0xb757ce3c in g_thread_equal_posix_impl (thread1=0xfffffffc,
thread2=0xfffffffc) at gthread-posix.c:412
#5  0xb74102cf in IA__g_static_rec_mutex_lock (mutex=0x7ffa) at gthread.c:280
#6  0xb7604148 in gst_pad_stop_task (pad=0xb2232628) at gstpad.c:3989
#7  0xb6782e8e in gst_base_src_deactivate (basesrc=0x1, pad=0xb2232628) at
gstbasesrc.c:1771
#8  0xb75fe6dc in gst_pad_activate_pull (pad=0xb2232628, active=0) at
gstpad.c:720
#9  0xb75fe8d0 in gst_pad_activate_pull (pad=0xb2213bc0, active=0) at
gstpad.c:706
#10 0xb75feb41 in gst_pad_set_active (pad=0xb2213bc0, active=0) at gstpad.c:647
#11 0xb75ec5d2 in activate_pads (pad=0xb2213bc0, ret=0xfffffffc,
active=0xbf9ed7cc) at gstelement.c:2254
#12 0xb75f7599 in gst_iterator_fold (it=0xb2235370, func=0xb75ec5a4
<activate_pads>, ret=0xbf9ed7d0, user_data=0xbf9ed7cc) at gstiterator.c:503
#13 0xb75ec68e in iterator_fold_with_resync (iter=0xb2235370, func=0xb75ec5a4
<activate_pads>, ret=0xbf9ed7d0, user_data=0xbf9ed7cc) at gstelement.c:2272
#14 0xb75ec73d in gst_element_pads_activate (element=0xb2225a68, active=0) at
gstelement.c:2309
#15 0xb75eca64 in gst_element_change_state_func (element=0xb2225a68,
transition=GST_STATE_CHANGE_PAUSED_TO_READY) at gstelement.c:2370
#16 0xb6761290 in gst_qtdemux_change_state (element=0xb2225a68,
transition=GST_STATE_CHANGE_PAUSED_TO_READY) at qtdemux.c:910
#17 0xb75ebc6b in gst_element_change_state (element=0xb2225a68,
transition=3068953524) at gstelement.c:2177
#18 0xb75ec291 in gst_element_set_state_func (element=0xb2225a68,
state=GST_STATE_READY) at gstelement.c:2139
#19 0xb75eaebb in gst_element_set_state (element=0xb2225a68, state=4294967292)
at gstelement.c:2049
#20 0xb75dc3fc in gst_bin_change_state_func (element=0xb222ecc0,
transition=GST_STATE_CHANGE_PAUSED_TO_READY) at gstbin.c:1754
#21 0xb7605451 in gst_pipeline_change_state (element=0xb222ecc0,
transition=GST_STATE_CHANGE_PAUSED_TO_READY) at gstpipeline.c:492
#22 0xb75ebc6b in gst_element_change_state (element=0xb222ecc0,
transition=3068953524) at gstelement.c:2177
#23 0xb75ebd4e in gst_element_change_state (element=0xb222ecc0,
transition=3068953524) at gstelement.c:2217
#24 0xb75ec291 in gst_element_set_state_func (element=0xb222ecc0,
state=GST_STATE_NULL) at gstelement.c:2139
#25 0xb75eaebb in gst_element_set_state (element=0xb222ecc0, state=4294967292)
at gstelement.c:2049
[...]


-- 
Configure bugmail: http://bugzilla.gnome.org/userprefs.cgi?tab=email




More information about the Gstreamer-bugs mailing list