[Bug 797251] webrtcbin: might leak resources when changing to NULL

GStreamer (GNOME Bugzilla) bugzilla at gnome.org
Fri Oct 5 16:05:05 UTC 2018


https://bugzilla.gnome.org/show_bug.cgi?id=797251

--- Comment #8 from Aleix Conchillo Flaqué <aconchillo at gmail.com> ---
Btw, I forgot to thank you for this webrtc implementation. I think it's
fantastic and very well done and clean. So, thanks for that!

(In reply to Matthew Waters (ystreet00) from comment #7)
> If this is a hang, a backtrace is most useful. A debug log would also be
> useful.
> 
> (In reply to Aleix Conchillo Flaqué from comment #6)
> > (In reply to Aleix Conchillo Flaqué from comment #4)
> > 
> > > That is, nothing prevents the idle sources to keep executing when the
> > > element changes state to NULL. In my app I have a ref to the pipeline and a
> > > ref to the webrtcbin element. I set the pipeline to NULL and I unref it
> > > next. At this point I would expect GST_OBJECT_REFCOUNT_VALUE for the
> > > webrtcbin element to always be 1 (my copy should be the last one), but it's
> > > not.
> 
> Nothing guarantees that your reference is the last one so you can't use that
> as a metric.
> 

I thought that setting a pipeline to NULL guarantees that since all elements
should free their resources. Why would we want the tasks to keep executing
after the pipeline is NULL?

> > Also, my app has it's own main loop where I run the gstreamer pipelines.
> > After setting the pipelines to NULL I stop my main loop. At this point I
> > have no idea what happens with the webrtcbin idle sources. Since webrtcbin
> > has its own main loop they should still be executing.
> 
> Correct, they would execute normally.
> 

Same as above. Why would we want this?

> > With own of my prints I have seen an idle source blocking here:
> > 
> > _create_transport_channel (...)
> > {
> >   ...
> >   gst_element_sync_state_with_parent (GST_ELEMENT (ret->send_bin));
> >   gst_element_sync_state_with_parent (GST_ELEMENT (ret->receive_bin));
> > 
> > My guess is that once the pipeline is set to NULL (and the idle source still
> > running), this will just be blocked somewhere. But since it's an idle source
> > and it's running on its own main context it will not affect the main
> > application.
> 
> It should not be blocked though and a backtrace of all the threads and a
> debug log is definitely needed to figure out what else might be going on.

Very good point! I wrote that before going to sleep and I didn't realize I
could verify my guess. So, with my patch and after 10,000 iterations there are
almost no more leaks, except for one case where my ref counter is 2 after
setting the pipeline to NULL (I have an explanation below).

So, I went to gdb and below is the thread that is hanging. The main loop
doesn't quit. In this case, I think the issue is that the idle source doesn't
hold a reference to webrtcbin (op only stores a pointer) so if in my app I
unref webrtcbin, then g_signal_emit will unref the last reference which means
the idle source will be waiting for the main loop to finish, but it can't
finish because the idle source is still running. Does that make any sense?

Also, considering my patch, in my app the webrtc refcount is 2 because
_on_ice_candidate_task calls PC_UNBLOCK but then emits the signal. This means
that the state will go to NULL while the signal is being emitted.

Thread 8 (Thread 0x7f474b5af700 (LWP 30664)):
#0  syscall () at ../sysdeps/unix/sysv/linux/x86_64/syscall.S:38
#1  0x00007f4766edbeaf in g_cond_wait (cond=0x7f475447eb38,
mutex=0x7f475447eb30) at gthread-posix.c:1402
#2  0x00007f475819e93d in _stop_thread (webrtc=0x7f475447eb90) at
gstwebrtcbin.c:618
#3  gst_webrtc_bin_dispose (object=0x7f475447eb90) at gstwebrtcbin.c:3967
#4  0x00007f4767178855 in g_object_unref (_object=0x7f475447eb90) at
gobject.c:3309
#5  0x00007f476719f0a0 in g_value_unset (value=value at entry=0x7f474b5ae870) at
gvalue.c:275
#6  0x00007f476719111b in g_signal_emit_valist (instance=<optimized out>,
signal_id=<optimized out>, detail=<optimized out>,
var_args=var_args at entry=0x7f474b5aea50) at gsignal.c:3421
#7  0x00007f47671914af in g_signal_emit
(instance=instance at entry=0x7f475447eb90, signal_id=<optimized out>,
detail=detail at entry=0) at gsignal.c:3447
#8  0x00007f475819c981 in _on_ice_candidate_task (webrtc=0x7f475447eb90,
item=0x7f4755afcb40) at gstwebrtcbin.c:3166
#9  0x00007f475819ca5a in _execute_op (op=0x7f4755afedf0) at gstwebrtcbin.c:638
#10 0x00007f4766e858ba in g_main_dispatch (context=0x7f4755ae32d0) at
gmain.c:3182
#11 g_main_context_dispatch (context=context at entry=0x7f4755ae32d0) at
gmain.c:3847
#12 0x00007f4766e85d18 in g_main_context_iterate (context=0x7f4755ae32d0,
block=block at entry=1, dispatch=dispatch at entry=1, self=<optimized out>) at
gmain.c:3920
#13 0x00007f4766e86252 in g_main_loop_run (loop=0x7f4755ab0de0) at gmain.c:4116
#14 0x00007f475819cbaa in _gst_pc_thread (webrtc=0x7f475447eb90) at
gstwebrtcbin.c:585
---Type <return> to continue, or q <return> to quit---
#15 0x00007f4766eb8ac5 in g_thread_proxy (data=0x7f4729440f70) at gthread.c:784
#16 0x00007f4767e0e6ba in start_thread (arg=0x7f474b5af700) at
pthread_create.c:333
#17 0x00007f4764aa441d in clone () at
../sysdeps/unix/sysv/linux/x86_64/clone.S:109

-- 
You are receiving this mail because:
You are the QA Contact for the bug.
You are the assignee for the bug.


More information about the gstreamer-bugs mailing list