After an evaluation, GNOME has moved from Bugzilla to GitLab. Learn more about GitLab.
No new issues can be reported in GNOME Bugzilla anymore.
To report an issue in a GNOME project, go to GNOME GitLab.
Do not go to GNOME Gitlab for: Bluefish, Doxygen, GnuCash, GStreamer, java-gnome, LDTP, NetworkManager, Tomboy.
Bug 731780 - rtpjitterbuffer: free item if it is a duplicated one
rtpjitterbuffer: free item if it is a duplicated one
Status: RESOLVED OBSOLETE
Product: GStreamer
Classification: Platform
Component: gst-plugins-good
git master
Other Linux
: Normal normal
: git master
Assigned To: GStreamer Maintainers
GStreamer Maintainers
Depends on:
Blocks:
 
 
Reported: 2014-06-17 13:16 UTC by Miguel París Díaz
Modified: 2018-11-03 14:52 UTC
See Also:
GNOME target: ---
GNOME version: ---


Attachments
A patch to solve the issue (2.04 KB, patch)
2014-06-17 13:17 UTC, Miguel París Díaz
needs-work Details | Review
log of failure (30.82 KB, application/x-bzip2)
2016-12-02 10:40 UTC, Edward Hervey
  Details
log of failure without valgrind (30.82 KB, application/x-bzip2)
2016-12-02 10:42 UTC, Edward Hervey
  Details

Description Miguel París Díaz 2014-06-17 13:16:55 UTC
A duplicate item is not inserted into the buffer, so it must be freed.
Comment 1 Miguel París Díaz 2014-06-17 13:17:36 UTC
Created attachment 278598 [details] [review]
A patch to solve the issue
Comment 2 Wim Taymans 2014-06-17 13:32:54 UTC
while technically correct, the items that are inserted either have no seqnum or we make sure we only insert the item once so the added code will not ever execute. 

Did you actually see a case where the item was leaked?
Comment 3 Miguel París Díaz 2014-06-17 13:45:52 UTC
It takes place when there is some timeouts about the the same packet.
Comment 4 Wim Taymans 2014-06-18 14:44:32 UTC
(In reply to comment #3)
> It takes place when there is some timeouts about the the same packet.

Could you be more specific when it happens? what series of events lead to the leaked event. In no case should it ever attempt to insert the ITEM_TYPE_LOST event twice (and the others don't have a seqnum so will never return FALSE).
Comment 5 Miguel París Díaz 2014-06-18 16:30:31 UTC
The item leaked is created here http://cgit.freedesktop.org/gstreamer/gst-plugins-good/tree/gst/rtpmanager/gstrtpjitterbuffer.c?id=1.3.2#n2800, which provokes the leak of the item and the event. See the valgrind trace:

==5004== 6,480 (480 direct, 6,000 indirect) bytes in 15 blocks are definitely lost in loss record 8,550 of 8,597
==5004==    at 0x4C2AB80: malloc (in /usr/lib/valgrind/vgpreload_memcheck-amd64-linux.so)
==5004==    by 0x53E4610: g_malloc (in /lib/x86_64-linux-gnu/libglib-2.0.so.0.4000.0)
==5004==    by 0x53FA22D: g_slice_alloc (in /lib/x86_64-linux-gnu/libglib-2.0.so.0.4000.0)
==5004==    by 0x4EBE9B6: gst_structure_new_id_empty_with_size (in /usr/lib/x86_64-linux-gnu/libgstreamer-1.0.so.0.302.0)
==5004==    by 0x4EC0E4E: gst_structure_new_valist (in /usr/lib/x86_64-linux-gnu/libgstreamer-1.0.so.0.302.0)
==5004==    by 0x4EC0EF6: gst_structure_new (in /usr/lib/x86_64-linux-gnu/libgstreamer-1.0.so.0.302.0)
==5004==    by 0xC1EB62E: wait_next_timeout (gstrtpjitterbuffer.c:2792)
==5004==    by 0x5403F14: ??? (in /lib/x86_64-linux-gnu/libglib-2.0.so.0.4000.0)
==5004==    by 0x659E181: start_thread (pthread_create.c:312)
==5004==    by 0x5BBD30C: clone (clone.S:111)
==5004== 
==5004== 8,400 (1,920 direct, 6,480 indirect) bytes in 30 blocks are definitely lost in loss record 8,560 of 8,597
==5004==    at 0x4C2AB80: malloc (in /usr/lib/valgrind/vgpreload_memcheck-amd64-linux.so)
==5004==    by 0x53E4610: g_malloc (in /lib/x86_64-linux-gnu/libglib-2.0.so.0.4000.0)
==5004==    by 0x53FA22D: g_slice_alloc (in /lib/x86_64-linux-gnu/libglib-2.0.so.0.4000.0)
==5004==    by 0xC1EB648: wait_next_timeout (gstrtpjitterbuffer.c:776)
==5004==    by 0x5403F14: ??? (in /lib/x86_64-linux-gnu/libglib-2.0.so.0.4000.0)
==5004==    by 0x659E181: start_thread (pthread_create.c:312)
==5004==    by 0x5BBD30C: clone (clone.S:111)

The entry point of this call i wait_next_timeout (http://cgit.freedesktop.org/gstreamer/gst-plugins-good/tree/gst/rtpmanager/gstrtpjitterbuffer.c?id=1.3.2#n2877)
Comment 6 Tim-Philipp Müller 2014-12-13 01:08:20 UTC
Easy way to reproduce this:

tpm@xps:~/gst/glib-master/gst-plugins-good/tests/check$ make elements/rtpaux.valgrind
Running suite(s): rtpaux
==9521== 64 bytes in 1 blocks are definitely lost in loss record 2,563 of 3,764
==9521==    at 0x4C28C20: malloc (vg_replace_malloc.c:296)
==9521==    by 0x5B1E539: g_malloc (gmem.c:97)
==9521==    by 0x5B34C5F: g_slice_alloc (gslice.c:1007)
==9521==    by 0x825BEFF: alloc_item (gstrtpjitterbuffer.c:815)
==9521==    by 0x825BEFF: do_lost_timeout (gstrtpjitterbuffer.c:2884)
==9521==    by 0x825BEFF: do_timeout (gstrtpjitterbuffer.c:2941)
==9521==    by 0x825BEFF: wait_next_timeout (gstrtpjitterbuffer.c:3020)
==9521==    by 0x5B3ED14: g_thread_proxy (gthread.c:764)
==9521==    by 0x5E0F0A3: start_thread (pthread_create.c:309)
==9521== 
==9521== 432 (32 direct, 400 indirect) bytes in 1 blocks are definitely lost in loss record 3,690 of 3,764
==9521==    at 0x4C28C20: malloc (vg_replace_malloc.c:296)
==9521==    by 0x5B1E539: g_malloc (gmem.c:97)
==9521==    by 0x5B34C5F: g_slice_alloc (gslice.c:1007)
==9521==    by 0x55EE6F2: gst_structure_new_id_empty_with_size (gststructure.c:145)
==9521==    by 0x55F0ABE: gst_structure_new_valist (gststructure.c:281)
==9521==    by 0x55F0B66: gst_structure_new (gststructure.c:253)
==9521==    by 0x825BEE1: do_lost_timeout (gstrtpjitterbuffer.c:2876)
==9521==    by 0x825BEE1: do_timeout (gstrtpjitterbuffer.c:2941)
==9521==    by 0x825BEE1: wait_next_timeout (gstrtpjitterbuffer.c:3020)
==9521==    by 0x5B3ED14: g_thread_proxy (gthread.c:764)
==9521==    by 0x5E0F0A3: start_thread (pthread_create.c:309)
==9521==
Comment 7 Sebastian Dröge (slomo) 2015-03-20 17:06:57 UTC
Review of attachment 278598 [details] [review]:

::: gst/rtpmanager/gstrtpjitterbuffer.c
@@ +1393,3 @@
+  if (G_UNLIKELY (!rtp_jitter_buffer_insert (priv->jbuf, item, &head, NULL))) {
+    free_item (item);
+  }

This one should go away, events have no seqnum and as such will never be duplicates

@@ +2803,3 @@
   item = alloc_item (event, ITEM_TYPE_LOST, -1, -1, seqnum, lost_packets, -1);
+  if (G_UNLIKELY (!rtp_jitter_buffer_insert (priv->jbuf, item, &head, NULL))) {
+    free_item (item);

I can't reproduce the leak with the unit test here (even after disabling the sticky event misordering warnings). From looking at the code, if this happens it is a bug in a higher layer already. There shouldn't be an item with the same seqnum in the queue at this point.

The only way how I can see this happen is either
a) we received the packet with the seqnum now... in which case we shouldn't be in this code at all (nothing is lost!)
b) we queued a lost event already in the jitterbuffer but did not push it out yet (this should not happen unless the jitterbuffer is blocked downstream for too long)

Miguel, can you provide a testcase for this problem?


But from looking at the code, we don't seem to check in the chain function if the currently received packet currently has a lost item in the queue. If there is a lost item for it, we would discard the packet unless I'm missing something... just to request retransmission of that packet later.
Wim, is that correct?

@@ +3252,3 @@
           item = alloc_item (query, ITEM_TYPE_QUERY, -1, -1, -1, 0, -1);
+          if (G_UNLIKELY (!rtp_jitter_buffer_insert (priv->jbuf, item, &head,
+                      NULL))) {

Should go away, some as for events
Comment 8 Edward Hervey 2016-12-02 10:39:53 UTC
While I *did* push a commit to fix this leak, there might indeed be another issue here ,but it's hard to say whether it's because of valgrind slowing everything down way too much or not.

I will attach a log of the test running under valgrind with an assert where that insertion fails.
Comment 9 Edward Hervey 2016-12-02 10:40:35 UTC
Created attachment 341226 [details]
log of failure
Comment 10 Edward Hervey 2016-12-02 10:42:54 UTC
Created attachment 341227 [details]
log of failure without valgrind

I can actually reproduce the issue outside of valgrind.
Comment 11 Edward Hervey 2016-12-02 10:52:20 UTC
The change to apply to make it assert

@@ -3757,9 +3760,11 @@ do_lost_timeout (GstRtpJitterBuffer * jitterbuffer, TimerData * timer,
             "retry", G_TYPE_UINT, num_rtx_retry, NULL));
   }
   item = alloc_item (event, ITEM_TYPE_LOST, -1, -1, seqnum, lost_packets, -1);
-  if (!rtp_jitter_buffer_insert (priv->jbuf, item, &head, NULL))
+  if (!rtp_jitter_buffer_insert (priv->jbuf, item, &head, NULL)) {
     /* Duplicate */
+    g_assert(FALSE);
     free_item (item);
+  }
 
   if (GST_CLOCK_TIME_IS_VALID (timer->rtx_last)) {
     /* Store info to update stats if the packet arrives too late */
Comment 12 GStreamer system administrator 2018-11-03 14:52:45 UTC
-- GitLab Migration Automatic Message --

This bug has been migrated to freedesktop.org's GitLab instance and has been closed from further activity.

You can subscribe and participate further through the new bug through this link to our GitLab instance: https://gitlab.freedesktop.org/gstreamer/gst-plugins-good/issues/118.