GNOME Bugzilla – Bug 577318
rtspsrc appears to be leaking memory
Last modified: 2009-05-25 08:59:00 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
When you 'destroy' the pipeline, are you setting it back to NULL, or are you just casting a running pipeline off into the void?
Created attachment 131709 [details] Test program to reproduce problem.
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.
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
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.
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.
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.
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.
cool.. patch?
Created attachment 133107 [details] [review] Fixes memory leak mentioned in comment #7
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.
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.
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
Created attachment 133259 [details] Valgrind trace showing three sections that increase over time
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()
Created attachment 133483 [details] [review] Adds call to gst_rtsp_message_unset() in gst_rtspsrc_try_send()
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.
Created attachment 134554 [details] [review] gst-plugins-good patch, see comment #17
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