網頁

2023年3月29日 星期三

檢查 memory leak

安裝 valgrind
$ sudo apt update
$ sudo apt install snapd
$ sudo snap install valgrind --classic

$ gcc -g -o debug_prog debug_prog.c
$ g++ -g -o debug_prog debug_prog.c

開啟兩個 terminal
$ valgrind --vgdb=yes --vgdb-error=0 --tool=memcheck --leak-check=full ./debug_prog

$ gdb ./debug_prog
(gdb) target remote | vgdb
(gdb) break linenum
(gdb) next
(gdb) step
(gdb) monitor leak_check full reachable any
(gdb) kill
(gdb) quit

若只是單純檢查 memory leak
$ valgrind --tool=memcheck --leak-check=full ./debug_prog

suppression 一些錯誤
$ valgrind --tool=memcheck --leak-check=full --gen-suppressions=all ./debug_prog
...
{
   <insert_a_suppression_name_here>
   Memcheck:Leak
   match-leak-kinds: definite
   fun:malloc
   fun:g_malloc
   obj:/usr/lib/x86_64-linux-gnu/libglib-2.0.so.0.5600.4
   fun:call_init
   fun:_dl_init
   obj:/lib/x86_64-linux-gnu/ld-2.27.so
}
...

利用上個命令的輸出,產生 local.supp 檔
$ valgrind --tool=memcheck --leak-check=full --supressions=./local.supp ./debug_prog
$ valgrind --tool=memcheck --leak-check=full --gen-suppressions=all --log-file=supp.log --supressions=./local.supp ./debug_prog
$ cat ./supp.log | ./suppressions.sh > local.supp
$ valgrind --tool=memcheck --leak-check=full --supressions=./local.supp --supressions=./gtk.supp ./debug_prog

suppressions.sh 若產生下列錯誤
awk: 34: unexpected character '&'
需改變 awk 的版本為 gawk
$ awk -W version
$ sudo apt-get update
$ sudo apt-get install gawk

去除 definitely loss
== 16,384 bytes in 1 blocks are definitely lost in loss record 1,443 of 1,448
==    at 0x4C330C5: malloc (vg_replace_malloc.c:393)
==    by 0x6A0BBD8: g_malloc (gmem.c:99)
==    by 0x6A1674B: g_quark_init (gquark.c:62)
==    by 0x40108D2: call_init (dl-init.c:72)
==    by 0x40108D2: _dl_init (dl-init.c:119)
==    by 0x40010C9: ??? (in /lib/x86_64-linux-gnu/ld-2.27.so)

下載 gst.supp 和 glib.supp gtk.supp
https://gitlab.freedesktop.org/gstreamer/common/-/blob/master/gst.supp
https://github.com/GNOME/glib/blob/main/tools/glib.supp
https://gist.github.com/pendingchaos/81feddb95c06aeb58e2f

Makefile 的
CFLAGS+= -g -O0

安裝 libglib 的 debug symbols 版本
$ echo "deb http://ddebs.ubuntu.com $(lsb_release -cs) main restricted universe multiverse
deb http://ddebs.ubuntu.com $(lsb_release -cs)-updates main restricted universe multiverse
deb http://ddebs.ubuntu.com $(lsb_release -cs)-proposed main restricted universe multiverse" | \
sudo tee -a /etc/apt/sources.list.d/ddebs.list
$ sudo apt install ubuntu-dbgsym-keyring
$ sudo apt update
$ sudo apt install libglib2.0-bin-dbgsym libglib2.0-0-dbgsym libglib2.0-dev-bin-dbgsym


export G_DEBUG=gc-friendly
export G_SLICE=always-malloc

valgrind -v --time-stamp=yes --tool=memcheck --leak-check=full \
  --gen-suppressions=all --log-file=supp.log \
  --suppressions=./glib.supp \
  --suppressions=./gst.supp \
  --suppressions=./gtk.supp \
  ./main

常用觀測記憶體使用狀態命令
$ while true; do echo -n `date +"%Y/%m/%d %H:%M:%S"`" " | tee -a aaa.log ; grep "VmRSS" /proc/26885/status | tee -a aaa.log ; sleep 60 ; done
$ watch "grep 'VmRSS\|VmPeak\|VmData\|VmStk\|VmExe\|VmLib\|Threads' /proc/26885/status" 


沒有留言:

張貼留言