annidy / notes

0 stars 0 forks source link

cgo内存泄漏检测 #285

Open annidy opened 4 months ago

annidy commented 4 months ago

cgo中的内存泄漏,不能通过pprof检测出来。只能使用valgrind等工具

valgrind只支持linux。macOS上的移植版测试发现不准

基本命令使用

valgrind --leak-check=full ./demo

检测过程中,会输出可能发生泄漏的堆栈。

对于C语言中的泄漏,堆栈会比较清晰

==203235== 134,217,728 bytes in 1 blocks are possibly lost in loss record 6 of 6
==203235==    at 0x4C29F73: malloc (vg_replace_malloc.c:309)
==203235==    by 0x45A50D: f1 (demo.go:11)
==203235==    by 0x45A50D: _cgo_f71f7fb1e19b_Cfunc_f1 (cgo-gcc-prolog:49)
==203235==    by 0x456047: runtime.asmcgocall.abi0 (asm_amd64.s:872)

对于go代码中的内存泄漏,比如C.GoString、C.malloc没有释放,堆栈的位置不太好辨认

==203235== 17 bytes in 1 blocks are definitely lost in loss record 1 of 6
==203235==    at 0x4C29F73: malloc (vg_replace_malloc.c:309)
==203235==    by 0x45A4D3: _cgo_f71f7fb1e19b_Cfunc__Cmalloc (_cgo_export.c:30)
==203235==    by 0x456047: runtime.asmcgocall.abi0 (asm_amd64.s:872)

测试benchmark的泄漏

valgrind启动参数是要检测的程序,一般做benchmark测试是这样

go test -bench=.

显然,这个是不能给到valgrind的。

go test会在当前目录生成一个xxx.test可执行文件,这个是经过go testing框架包装过的,可以用这个来运行

valgrind --leak-check=full ./xxx.test -test.bench=.
# 记得要加-test.bench参数,否则默认是不执行benchmark用例