valgrind使用

本文最后更新于:2025年11月19日 下午

valgrind使用

编译

如下是编译armv7的版本

1
2
3
4
./configure --prefix=`pwd`/llm CC=/projects/hnd/tools/bcm/crosstools-arm-gcc-5.5-linux-4.1-glibc-2.26-binutils-2.28.1/usr/bin/arm-buildroot-linux-gnueabi-gcc --host=armv7-linux
mkdir llm
make -j6
make install

打包使用

编译出来的install目录有100多M,全部拷到设备里面内存没那么大。所以只拷贝关键的
bin/valgrind 文件
Libexec下所有文件,然后删掉里面最大的一些可执行文件(删掉不需要用的,检查内存泄漏的话,只保留memcheck-arm-linux这个可执行文件即可,其他的库文件,xml都要保留)

使用

注意需要设置环境变量

1
2
3
4
5
6
7
8
9
10
11
12
cd /tmp
mkdir 123
cd 123
tftp -gr valgrind 192.168.10.123
tftp -gr test_arm 192.168.10.123
tftp -gr libexec.tar 192.168.10.123
tar -xf libexec.tar
rm libexec.tar
# 下面这个目录根据实际情况修改
export VALGRIND_LIB=/tmp/123/libexec/valgrind
chmod +x -R ./
./valgrind --leak-check=full ./test_arm

例子

源码:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
fun1()
{
char *p=malloc(100);
memset(p,0x2,100);
}

fun2()
{
char *p=malloc(100);
memset(p,0x2,100);

fun1();
}

main()
{
fun2();
}

打印如下:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
==1199== Memcheck, a memory error detector
==1199== Copyright (C) 2002-2017, and GNU GPL'd, by Julian Seward et al.
==1199== Using Valgrind-3.17.0 and LibVEX; rerun with -h for copyright info
==1199== Command: ./test_arm
==1199==
==1199==
==1199== HEAP SUMMARY:
==1199== in use at exit: 200 bytes in 2 blocks
==1199== total heap usage: 2 allocs, 0 frees, 200 bytes allocated
==1199==
==1199== 100 bytes in 1 blocks are definitely lost in loss record 1 of 2
==1199== at 0x484876C: malloc (vg_replace_malloc.c:380)
==1199== by 0x1048B: fun2 (test.c:9)
==1199== by 0x104C3: main (test.c:17)
==1199==
==1199== 100 bytes in 1 blocks are definitely lost in loss record 2 of 2
==1199== at 0x484876C: malloc (vg_replace_malloc.c:380)
==1199== by 0x1044F: fun1 (test.c:3)
==1199== by 0x104A7: fun2 (test.c:12)
==1199== by 0x104C3: main (test.c:17)
==1199==
==1199== LEAK SUMMARY:
==1199== definitely lost: 200 bytes in 2 blocks
==1199== indirectly lost: 0 bytes in 0 blocks
==1199== possibly lost: 0 bytes in 0 blocks
==1199== still reachable: 0 bytes in 0 blocks
==1199== suppressed: 0 bytes in 0 blocks
==1199==
==1199== For lists of detected and suppressed errors, rerun with: -s
==1199== ERROR SUMMARY: 2 errors from 2 contexts (suppressed: 0 from 0)

遇到的问题

运行报错,错误如下:
valgrind setrlimit(RLIMIT_NOFILE) error: Operation not permitted
根据查资料来看貌似是valgrind的限制,如下https://stackoverflow.com/questions/52070477/setrlimit-fails-with-operation-not-permitted-when-run-under-valgrind
不支持进程调用这个,需要在代码里面去掉这个setrlimit,我调试的进程是cm_init调用的。去掉相关代码即可。

因strip运行报错

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
valgrind:  Fatal error at startup: a function redirection
valgrind: which is mandatory for this platform-tool combination
valgrind: cannot be set up. Details of the redirection are:
valgrind:
valgrind: A must-be-redirected function
valgrind: whose name matches the pattern: index
valgrind: in an object with soname matching: ld-linux.so.3
valgrind: was not found whilst processing
valgrind: symbols from the object with soname: ld-linux.so.3
valgrind:
valgrind: Possible fixes: (1, short term): install glibc's debuginfo
valgrind: package on this machine. (2, longer term): ask the packagers
valgrind: for your Linux distribution to please in future ship a non-
valgrind: stripped ld.so (or whatever the dynamic linker .so is called)
valgrind: that exports the above-named function using the standard
valgrind: calling conventions for this platform. The package you need
valgrind: to install for fix (1) is called
valgrind:
valgrind: On Debian, Ubuntu: libc6-dbg
valgrind: On SuSE, openSuSE, Fedora, RHEL: glibc-debuginfo
valgrind:
valgrind: Note that if you are debugging a 32 bit process on a
valgrind: 64 bit system, you will need a corresponding 32 bit debuginfo
valgrind: package (e.g. libc6-dbg:i386).

这是由于ld-linux.so.3这个库被strip了,编译一个不strip的软件。
博通的改法是:
targets/buildFS文件, 最后几行代码前添加如下:

1
2
3
# leon add, vagraind使用
echo "##leon cp $INSTALL_DIR/lib/ld-linux.so.3 $TARGETS_DIR/$ROOTFS/lib/"
cp $INSTALL_DIR/lib/ld-linux.so.3 $TARGETS_DIR/$ROOTFS/lib/

共享内存运行报错

cms框架使用mdm的会共享内存,shmat报错如下

1
2
3
4
5
6
7
8
9
[0216 19:19:32] ==15363== Either way, Valgrind will now raise a SIGILL signal which will
[0216 19:19:32] ==15363== probably kill your program.
[0216 19:19:33] ==15363== Warning: client syscall shmat tried to modify addresses 0x58800000-0x5890ffff
[0216 19:19:33] hgcmif::730.543:error:oalShm_init:209:Could not attach to shmId=0 at 0x58800000, error=Invalid argument
[0216 19:19:33] Error at:InitCms,77 cmsMdm_init ret[9002]
[0216 19:19:33] Start hgcmif ipc thread
[0216 19:19:35] ==15363== Invalid read of size 4
[0216 19:19:35] ==15363== at 0x4D5832C: mdm_getObjectNodeFlags (in /lib/libmdm_db.so)
[0216 19:19:35] ==15363== Address 0x0 is not stack'd, malloc'd or (recently) free'd

共享内存的地址是写死的,据说和valgrind的重叠了,所以不行。修改这个地址才行(改成0x58d00000就行)

1
#define MDM_SHM_ATTACH_ADDR  0x58d00000  //0x58800000

如果不是用的MDM_SHM_ATTACH_ADDR这个地址,同理也应当修改其他宏即可。

其他

只显示确认的泄漏 --show-leak-kinds=definite参数

1
./valgrind --leak-check=full --show-leak-kinds=definite ./test

valgrind使用
https://leon0625.github.io/2020/08/21/25d4a948ddf5/
作者
leon.liu
发布于
2020年8月21日
许可协议