如何摆脱第三方框架(gstreamer)中的内存泄漏

时间:2019-05-20 10:21:24

标签: c++ memory-leaks valgrind gstreamer gobject

我正在尝试使用Valgrind检查程序的内存泄漏。

注意:我的程序包含一个每200毫秒轮询一次的FSM。(提及此是因为我认为这可能与泄漏有关)

我已执行以下命令并创建了日志文件。

valgrind --leak-check=full --track-origins=yes --verbose --log-file=valgrind_test.log ./foo

我发现程序中存在很多泄漏,其中90%遵循以下相同的路径/路径

==9890== 96 bytes in 1 blocks are possibly lost in loss record 2,341 of 2,707
==9890==    at 0x4C30035: calloc (in /usr/lib64/valgrind/vgpreload_memcheck-amd64-linux.so)
==9890==    by 0x66D96B0: g_malloc0 (in /usr/lib64/libglib-2.0.so.0.5400.3)
==9890==    by 0x69CB421: ??? (in /usr/lib64/libgobject-2.0.so.0.5400.3)
==9890==    by 0x69CB5CA: ??? (in /usr/lib64/libgobject-2.0.so.0.5400.3)
==9890==    by 0x69D1062: g_type_register_fundamental (in /usr/lib64/libgobject-2.0.so.0.5400.3)
==9890==    by 0x6CBADD1: gst_fraction_get_type (gstvalue.c:7428)
==9890==    by 0x6CBB0B5: _priv_gst_value_initialize (gstvalue.c:7527)
==9890==    by 0x6C23B50: init_post (gst.c:777)
==9890==    by 0x66E011F: g_option_context_parse (in /usr/lib64/libglib-2.0.so.0.5400.3)
==9890==    by 0x6C2462E: gst_init_check (gst.c:427)
==9890==    by 0x6C24676: gst_init (gst.c:471)
==9890==    by 0x5546CC: main (foo.cpp:97)

现在,由于这组特定的行在日志中重复出现,因此我认为轮询与此有关,尽管我不确定。

我在Valgrind日志中找不到路径,在该路径中,我已阻止/分配/获取的内存没有被释放/取消分配。这是所有第三方(GStreamer)路径。如何分析和消除这些泄漏?

问题:

==9890==    by 0x69CB421: ??? (in /usr/lib64/libgobject-2.0.so.0.5400.3)

这是什么意思

-------------------------------------------- - - -编辑 - - - - - - - - - - - - - - - - - - - - - - -----------

更新脚本以抑制glib内存泄漏的误报情况

export G_DEBUG=gc-friendly
export G_SLICE=always-malloc
export GLIBCPP_FORCE_NEW=1
export GLIBCXX_FORCE_NEW=1

OPTS="-v --time-stamp=yes --tool=memcheck --leak-check=yes --leak-resolution=high --log-file=valgrind_test.log --suppressions=/path/to/glibc-2.supp --suppressions=/path/to/gst.supp"

valgrind $OPTS ./foo

以下是生成的完整日志文件:
Complete log

==00:00:00:25.155 3241== LEAK SUMMARY:
==00:00:00:25.155 3241==    definitely lost: 0 bytes in 0 blocks
==00:00:00:25.155 3241==    indirectly lost: 0 bytes in 0 blocks
==00:00:00:25.155 3241==      possibly lost: 96 bytes in 1 blocks
==00:00:00:25.155 3241==    still reachable: 133,919 bytes in 1,457 blocks
==00:00:00:25.155 3241==                       of which reachable via heuristic:
==00:00:00:25.155 3241==                         length64           : 504 bytes in 12 blocks
==00:00:00:25.155 3241==                         newarray           : 1,616 bytes in 21 blocks
==00:00:00:25.155 3241==         suppressed: 831,853 bytes in 10,770 blocks
==00:00:00:25.155 3241== Reachable blocks (those to which a pointer was found) are not shown.
==00:00:00:25.155 3241== To see them, rerun with: --leak-check=full --show-leak-kinds=all

那么,如何防止这些损失?

1 个答案:

答案 0 :(得分:0)

根据日志中的内容,这些是GStreamer使用的GObject中动态类型信息的一次性分配。他们没什么好担心的。如果将valgrind--suppressions=/usr/share/glib-2.0/valgrind/glib.supp一起运行,则应该发现它们消失了。如果不是这样,并且如果您确定代码中没有该错误,请针对GStreamer提交错误,并与GStreamer开发人员一起修复该错误。


  

问题:

==9890==    by 0x69CB421: ??? (in /usr/lib64/libgobject-2.0.so.0.5400.3)
     

这是什么意思

这意味着调用帧位于libgobject-2.0.so.*中的未知函数中。这通常是由于没有可用于库的调试符号引起的。您应该发现,如果安装调试符号,则相应的函数名称将出现在valgrind的回溯中。