4日もアドベントカレンダーの更新できませんでした...
なぜかというと、インフルエンザ(´・ω・`)カキタメナカッタノガワルイ
なんとか、25日までには遅れを取り戻したいなあ
今日は Valgrind x GStreamer のハンズオン?的な内容です。
valgrind でリークチェックをするための準備
Debian/Ubuntu 向けの方法を紹介します。
valgrind のインストール
$ sudo apt-get install valgrind
デバッグシンボルのパッケージをインストール
$ sudo apt-get install \
libglib2.0-0-dbg \
libgstreamer1.0-0-dbg \
gstreamer1.0-plugins-base-dbg \
gstreamer1.0-plugins-good-dbg \
gstreamer1.0-plugins-ugly-dbg
※ この他で必要なパッケージがあれば一緒にインストールしておきましょう。
リークしていないのにリークしていると言われる
何も考えずに、リークしていない gstreamer アプリ noleak を valgrind に通すとこうなります。
$ valgrind ./noleak
==15558== memcheck, a memory error detector
==15558== copyright (c) 2002-2015, and gnu gpl'd, by julian seward et al.
==15558== using valgrind-3.12.0 and libvex; rerun with -h for copyright info
==15558== command: ./noleak
==15558==
==15558==
==15558== heap summary:
==15558== in use at exit: 1,859,301 bytes in 23,260 blocks
==15558== total heap usage: 39,354 allocs, 16,094 frees, 5,830,404 bytes allocated
==15558==
==15558== leak summary:
==15558== definitely lost: 16,384 bytes in 1 blocks
==15558== indirectly lost: 0 bytes in 0 blocks
==15558== possibly lost: 4,764 bytes in 63 blocks
==15558== still reachable: 1,746,929 bytes in 22,873 blocks
==15558== of which reachable via heuristic:
==15558== length64 : 240 bytes in 6 blocks
==15558== newarray : 1,568 bytes in 18 blocks
==15558== suppressed: 0 bytes in 0 blocks
==15558== rerun with --leak-check=full to see details of leaked memory
==15558==
==15558== for counts of detected and suppressed errors, rerun with: -v
==15558== error summary: 0 errors from 0 contexts (suppressed: 0 from 0)
definitely lost: 16,384 bytes in 1 blocks
と言われ、まるでリークしているかのように言われてしまいます。
そこで、suppression file の登場です。
Suppression file を使う
GStreamer の suppression file は gstreamer/common から手に入れることができます。
valgrind に suppression file を指定し noleak のリークチェックを再度行ってみます。
$ valgrind --suppressions=gstreamer/common/gst.supp ./noleak
==18190== Memcheck, a memory error detector
==18190== Copyright (C) 2002-2015, and GNU GPL'd, by Julian Seward et al.
==18190== Using Valgrind-3.12.0 and LibVEX; rerun with -h for copyright info
==18190== Command: ./noleak
==18190==
==18190==
==18190== HEAP SUMMARY:
==18190== in use at exit: 1,859,301 bytes in 23,260 blocks
==18190== total heap usage: 39,354 allocs, 16,094 frees, 5,830,404 bytes allocated
==18190==
==18190== LEAK SUMMARY:
==18190== definitely lost: 0 bytes in 0 blocks
==18190== indirectly lost: 0 bytes in 0 blocks
==18190== possibly lost: 0 bytes in 0 blocks
==18190== still reachable: 128,746 bytes in 1,200 blocks
==18190== of which reachable via heuristic:
==18190== length64 : 240 bytes in 6 blocks
==18190== newarray : 1,568 bytes in 18 blocks
==18190== suppressed: 1,639,331 bytes in 21,737 blocks
==18190== Rerun with --leak-check=full to see details of leaked memory
==18190==
==18190== For counts of detected and suppressed errors, rerun with: -v
==18190== ERROR SUMMARY: 0 errors from 0 contexts (suppressed: 0 from 0)
メモリリークが無いことを証明できました
メモリリークさせてみる
noleak の終了処理をおざなりにした leak を作ったので、これを使ってためしてみましょう。ちなみに、ここからは GStreamer に限った話ではなく valgrind の話です。
$ valgrind --suppressions=/home/shotam/src/gst/common/gst.supp ./leak
==18227== Memcheck, a memory error detector
==18227== Copyright (C) 2002-2015, and GNU GPL'd, by Julian Seward et al.
==18227== Using Valgrind-3.12.0 and LibVEX; rerun with -h for copyright info
==18227== Command: ./leak
==18227==
==18227==
==18227== HEAP SUMMARY:
==18227== in use at exit: 1,871,665 bytes in 23,333 blocks
==18227== total heap usage: 39,231 allocs, 15,898 frees, 5,821,138 bytes allocated
==18227==
==18227== LEAK SUMMARY:
==18227== definitely lost: 24 bytes in 1 blocks
==18227== indirectly lost: 64 bytes in 1 blocks
==18227== possibly lost: 0 bytes in 0 blocks
==18227== still reachable: 136,342 bytes in 1,263 blocks
==18227== of which reachable via heuristic:
==18227== length64 : 240 bytes in 6 blocks
==18227== newarray : 1,568 bytes in 18 blocks
==18227== suppressed: 1,639,331 bytes in 21,737 blocks
==18227== Rerun with --leak-check=full to see details of leaked memory
==18227==
==18227== For counts of detected and suppressed errors, rerun with: -v
==18227== ERROR SUMMARY: 0 errors from 0 contexts (suppressed: 0 from 0)
先程同様に、suppression fileを指定しましたがリークしているようです。valgrind は --leak-check=yes
をつけることでリーク箇所を指摘してくれます。
$ valgrind --suppressions=/home/shotam/src/gst/common/gst.supp --leak-check=yes ./leak
==18373== Memcheck, a memory error detector
==18373== Copyright (C) 2002-2015, and GNU GPL'd, by Julian Seward et al.
==18373== Using Valgrind-3.12.0 and LibVEX; rerun with -h for copyright info
==18373== Command: ./leak
==18373==
==18373==
==18373== HEAP SUMMARY:
==18373== in use at exit: 1,871,665 bytes in 23,333 blocks
==18373== total heap usage: 39,231 allocs, 15,898 frees, 5,821,138 bytes allocated
==18373==
==18373== 88 (24 direct, 64 indirect) bytes in 1 blocks are definitely lost in loss record 1,553 of 2,010
==18373== at 0x4C2ABAF: malloc (vg_replace_malloc.c:299)
==18373== by 0x540BE08: g_malloc (gmem.c:94)
==18373== by 0x5424342: g_slice_alloc (gslice.c:1025)
==18373== by 0x5428522: g_string_sized_new (gstring.c:121)
==18373== by 0x5428AD1: g_string_new (gstring.c:154)
==18373== by 0x1089CD: main (leak.c:13)
==18373==
==18373== LEAK SUMMARY:
==18373== definitely lost: 24 bytes in 1 blocks
==18373== indirectly lost: 64 bytes in 1 blocks
==18373== possibly lost: 0 bytes in 0 blocks
==18373== still reachable: 136,342 bytes in 1,263 blocks
==18373== of which reachable via heuristic:
==18373== length64 : 240 bytes in 6 blocks
==18373== newarray : 1,568 bytes in 18 blocks
==18373== suppressed: 1,639,331 bytes in 21,737 blocks
==18373== Reachable blocks (those to which a pointer was found) are not shown.
==18373== To see them, rerun with: --leak-check=full --show-leak-kinds=all
==18373==
==18373== For counts of detected and suppressed errors, rerun with: -v
==18373== ERROR SUMMARY: 1 errors from 1 contexts (suppressed: 64 from 64)
リーク箇所は 13行目のg_string_new
であることがわかりました。noleakの15行目 の g_string_free
を加えてあげることでこれを修正することができます。
まとめ
- GStreamer のメモリリークチェックは valgrind で行える
-
-dbg
のパッケージも忘れずにインストールすべし - リークチェックするときには Suppression file を使うことで余計なリーク報告を除外できる
- GStreamer の Suppression file は gstreamer/common にある。
- Suppression fileは
--suppressions
オプションで使える - メモリリークの箇所を調べるには
--leak-check=yes
をつける