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 577318 - rtspsrc appears to be leaking memory
rtspsrc appears to be leaking memory
Status: RESOLVED FIXED
Product: GStreamer
Classification: Platform
Component: gst-plugins-good
git master
Other Linux
: Normal normal
: 0.10.16
Assigned To: GStreamer Maintainers
GStreamer Maintainers
Depends on:
Blocks:
 
 
Reported: 2009-03-30 15:30 UTC by Patrick Radizi
Modified: 2009-05-25 08:59 UTC
See Also:
GNOME target: ---
GNOME version: ---


Attachments
Test program to reproduce problem. (1.58 KB, text/plain)
2009-03-30 15:38 UTC, Patrick Radizi
  Details
Fixes memory leak mentioned in comment #7 (1.52 KB, patch)
2009-04-22 12:32 UTC, Patrick Radizi
committed Details | Review
Valgrind trace showing three sections that increase over time (2.92 KB, text/plain)
2009-04-24 15:37 UTC, Patrick Radizi
  Details
Adds call to gst_rtsp_message_unset() in gst_rtspsrc_try_send() (618 bytes, patch)
2009-04-28 11:51 UTC, Patrick Radizi
none Details | Review
gst-plugins-good patch, see comment #17 (1.76 KB, patch)
2009-05-13 09:35 UTC, Patrick Radizi
committed Details | Review

Description Patrick Radizi 2009-03-30 15:30:44 UTC
I have a very simple testprogram where an rtpssrc->fakesink pipeline is being created, set to playing and then destroyed repeatedly in a loop. This testprogram is leaking memory very rapidly. Valgrind can't find the problem.

Versions 
The rtspsrc element and rtsplib is from HEAD, 
gstreamer 0.10.22
gst-plugins-base (except rtsplib) 0.10.22
gst-plugins-good (except rtspspsrc) 0.10.13
gst-plugins-bad 0.10.10
Comment 1 Jan Schmidt 2009-03-30 15:36:29 UTC
When you 'destroy' the pipeline, are you setting it back to NULL, or are you just casting a running pipeline off into the void?
Comment 2 Patrick Radizi 2009-03-30 15:38:05 UTC
Created attachment 131709 [details]
Test program to reproduce problem.
Comment 3 Patrick Radizi 2009-03-30 15:47:10 UTC
I first set the state to NULL, then I unref the pipeline, i.e.:
gst_object_unref (GST_OBJECT (pipeline));

I forgot to mention, that when I run the same testprogram on an 'older' gstreamer installation (gst-plugins-good 0.10.8, from the debian testing release) the program does not leak memory.
Comment 4 Wim Taymans 2009-04-02 19:07:22 UTC
This is the only one I could found. Top seems to report a memory increase but this could be due to the thread stacks or something..

commit 40f6ed8875959a4ca02a4c63ad7156f4cd411dc7
Author: Wim Taymans <wim.taymans@collabora.co.uk>
Date:   Thu Apr 2 21:08:48 2009 +0200

    rtspsrc: don't leak the udpsrc pad
    
    Fix memory leak in rtspsrc because we didn't unref the udpsrc pad.
    See #577318
Comment 5 Patrick Radizi 2009-04-17 13:16:03 UTC
I think I have found the leak that I originally meant (not the one Wim fixed in Comment #4). Every time the test program runs one lap in the loop, 8192KB of data is lost. Looking in /proc/'pid'/smaps these blocks 8192KB can be seen adding up over time. Not on the stack or heap but close to the libgstrtpmanager.so library address space. I think it must be thread stack data created by the rtpmanager, and more precise belonging to the threads being created in gstrtpsession.c. To test I changed the size of the thread stack, with g_thread_full, when creating these thread to 1024KB, and the leak then became 1024KB instead.

The threads are created with the joinable property set to TRUE, but out of the two threads being created each iteration, only one is actually joined. This explains why one 8192KB block is lost every time. I think the thread stack can't be freed until the join has been done.

I created a simple test program simulating this, creating two 'joinable' threads at a time and then only joining with one, and the memory behaviour is identical, 8192KB is lost each iteration. Add the second join, and the leak goes away.

Since I don't know how the rtpmanager works I haven't added the 'second join' since I don't know when it is supposed to be done. But I hope that someone else can do it given this info.
Comment 6 Wim Taymans 2009-04-17 14:19:01 UTC
commit 71076cad544d34cc7fa1998313af0fdb179969ee
Author: Wim Taymans <wim.taymans@collabora.co.uk>
Date:   Fri Apr 17 16:16:29 2009 +0200

    rtpsession: join the RTCP thread
    
    Avoid a case where a joinable thread would be left unjoined, which leaked the
    thread structure.
    Fixes #577318.
Comment 7 Patrick Radizi 2009-04-21 11:04:04 UTC
Looks like there are more leaks. With the thread join fixed it still leaks about 1.5 - 2kB per loop in the test program. This time the leak is on the heap.

When using valgrind with the --show-reachable=yes option it can be seen that the reachable data is increasing as you increase the number of loops. I haven't been able to determine where the leak is coming from. It still seems to be rtsp related though, because when replacing rtspsrc with souphttpsrc the leak goes away.
Comment 8 Patrick Radizi 2009-04-21 15:11:56 UTC
I think I have found the leak from comment #7. In gstrtspsrc.c there are some pads being created with gst_element_get_request_pad() but they are never freed. 

If I unref them the memory leak seems to disappear. I have done 1000 loops now without seeing any increase in memory. 
Comment 9 Wim Taymans 2009-04-21 20:47:20 UTC
cool.. patch?
Comment 10 Patrick Radizi 2009-04-22 12:32:34 UTC
Created attachment 133107 [details] [review]
Fixes memory leak mentioned in comment #7
Comment 11 Patrick Radizi 2009-04-22 12:48:01 UTC
One small leak seems to remain, about 4-5 bytes are still lost each loop.

The leak does not seem to be on the heap. /proc/pid/smaps shows a stable heap and when using valgrind the reachable data parts does not increase in size. But using ps the RSS part can be seen slowly increasing.
Comment 12 Wim Taymans 2009-04-22 13:30:52 UTC
commit 5b86c66e8a1b9b62e0f6be2d97b3984bdc8ec48e
Author: Patrick Radizi <patrick.radizi at axis.com>
Date:   Wed Apr 22 15:24:55 2009 +0200

    rtspsrc: fix some more pad leaks
    
    Fix some pad leaks.
    See #577318.
Comment 13 Patrick Radizi 2009-04-24 15:35:36 UTC
It leaks memory also if you just run against the same rtps server the whole time. I modified the test program so that it just connects to the rtsp server and then streams forever (to fakesink). This seems to leaks about 2 bytes/sec.

I used valgrind on this test, it does not directly give the error but the reachable data can be seen increasing if you run the test a longer time period. I did one test for 180 sec and one test for 3600 sec. I then compared the valgrind output of these two. There where three sections that showed that more memory had been allocated for the section in the 3600s vs the 180s version. I haven't been able to figure out if this can be used to find the leak because it looks a bit strange. They all originate from gst_init() in the call sequence and that is strange since this is only called once. I have attached a file with these three valgrind sections to this case.

The memory increase of these three sections after 1 hour was :
section 1: 1845 bytes
section 2: 306 bytes
section 3: 2464 bytes
Comment 14 Patrick Radizi 2009-04-24 15:37:21 UTC
Created attachment 133259 [details]
Valgrind trace showing three sections that increase over time
Comment 15 Patrick Radizi 2009-04-28 11:50:21 UTC
In gst_rtspsrc_try_send(), shouldn't the response message be freed in the GST_RTSP_MESSAGE_REQUEST and GST_RTSP_MESSAGE_DATA case ? See patch.

It still leaks though even if I add the missing(?) call to gst_rtsp_message_unset()
Comment 16 Patrick Radizi 2009-04-28 11:51:42 UTC
Created attachment 133483 [details] [review]
Adds call to gst_rtsp_message_unset() in gst_rtspsrc_try_send()
Comment 17 Patrick Radizi 2009-05-13 09:33:32 UTC
I have found the leak that appears when streaming against the same server all the time. It's the server messages that are not being freed when using UDP. 

The Message was declared and initialized in the same inner loop as the call to gst_rtspsrc_connection_receive() which is supposed to free the previous received message. Moving the declaration solves the leak.

I also added some additional message unset for some of the error cases.

I have made a 24h test and so far, with this fix, it appers to not leak any more.

Note, my patch in Comment #15-16 can be dismissed. That was no leak.
Comment 18 Patrick Radizi 2009-05-13 09:35:46 UTC
Created attachment 134554 [details] [review]
gst-plugins-good patch, see comment #17
Comment 19 Wim Taymans 2009-05-25 08:59:00 UTC
commit 301fc8a712273e16eabd3647ccf6a43a871e3ada
Author: Patrick Radizi <patrick.radizi at axis.com>
Date:   Wed May 13 11:50:22 2009 +0200

    rtspsrc: fix memory leak of messages
    
    Free messages correctly.
    Fixes #577318