我需要调查我C项目中的内存泄漏问题。但在此之前,我只是编写了一个示例程序,并交叉编译到ARM-v8-a 64位OpenWRT Linux平台上。通过这个程序,我试图理解Valgrind泄漏报告。
不幸的是,在这次valgrind运行中,没有发现任何泄漏,并且期望memcheck工具报告一个50字节的泄漏摘要。
Valgrind工具优化:是的,使用-Os(OpenWRT)和-O2(Valgrind Makefile) 二进制优化:否 使用的libc标准:MUSL OpenWRT ARM 64位
为什么Valgrind无法拦截malloc调用,即使二进制执行了malloc调用?
示例代码:
Valgrind 输出:
以下是我的二进制文件和valgrind文件类型信息:
编译器版本详细信息:
.text部分的拆解:
Valgrind是使用以下优化和加固选项构建的。
期望得到一些帮助/指引以继续前进。
Valgrind工具优化:是的,使用-Os(OpenWRT)和-O2(Valgrind Makefile) 二进制优化:否 使用的libc标准:MUSL OpenWRT ARM 64位
为什么Valgrind无法拦截malloc调用,即使二进制执行了malloc调用?
示例代码:
char *ptr = NULL;
printf("Doing memory alloc\n");
ptr = malloc(50);
if (!ptr) {
printf("Malloc failure\n");
return -1;
}
printf("Malloc returned : %p\n", (void *)ptr);
memset(ptr, 0, 50);
strcpy(ptr, "Valgrind leak Analysis!!!\n");
printf("%s\n", ptr);
return 0;
Valgrind 输出:
==481==
--481-- Valgrind options:
--481-- --tool=memcheck
--481-- --leak-check=full
--481-- --show-leak-kinds=all
--481-- --track-origins=yes
--481-- --verbose
--481-- --default-suppressions=no
--481-- Contents of /proc/version:
--481-- Linux version 5.4.164 (renv@bbd-svr-ubt20-004) (gcc version 7.5.0 (OpenWrt GCC 7.5.0 r11-afafb2b1c)) #0 SMP PREEMPT Mon Jun 5 15:00:29 2023
--481--
--481-- Arch and hwcaps: ARM64, LittleEndian, baseline
--481-- Page sizes: currently 4096, max supported 65536
--481-- Valgrind library directory: /usr/lib/valgrind
--481-- Reading syms from /home/superadmin/leaks
--481-- Scheduler: using generic scheduler lock implementation.
Doing memory alloc
Malloc returned : 0x40945e0
Valgrind leak Analysis!!!
==481==
==481== HEAP SUMMARY:
==481== in use at exit: 0 bytes in 0 blocks
==481== total heap usage: 0 allocs, 0 frees, 0 bytes allocated
==481==
==481== All heap blocks were freed -- no leaks are possible
==481==
==481== ERROR SUMMARY: 0 errors from 0 contexts (suppressed: 0 from 0)
以下是我的二进制文件和valgrind文件类型信息:
root@Bean10:/home/superadmin# file leaks
leaks: ELF 64-bit LSB executable, ARM aarch64, version 1 (SYSV), dynamically linked, interpreter /lib/ld-musl-aarch64.so.1, with debug_info, not stripped
root@Bean10:/home/superadmin#
root@Bean10:/home/superadmin# file /usr/bin/valgrind
/usr/bin/valgrind: ELF 64-bit LSB pie executable, ARM aarch64, version 1 (SYSV), dynamically linked, interpreter /lib/ld-musl-aarch64.so.1, no section header
root@Bean10:/home/superadmin#
root@Bean10:/home/superadmin# ls /usr/lib/valgrind/
64bit-core-valgrind-s1.xml 64bit-linux-valgrind-s2.xml memcheck-arm64-linux
64bit-core-valgrind-s2.xml 64bit-linux.xml none-arm64-linux
64bit-core.xml default.supp vgpreload_core-arm64-linux.so
64bit-linux-valgrind-s1.xml leaks vgpreload_memcheck-arm64-linux.so
root@Bean10:/home/superadmin#
使用的编译命令:
请注意,这是我项目中使用的交叉工具链编译器。如何检查它是否隐式地使用了优化标志。
aarch64-openwrt-linux-musl-gcc -g leaks.c
编译器版本详细信息:
aarch64-openwrt-linux-musl-gcc (OpenWrt GCC 7.5.0 r11-afafb2b1c) 7.5.0
Copyright (C) 2017 Free Software Foundation, Inc.
This is free software; see the source for copying conditions. There is NO
warranty; not even for MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
来自目标文件的符号信息:
nm显示malloc和其他几个函数为未定义符号。
$ aarch64-openwrt-linux-musl-nm leaks.o
0000000000000000 T main
U malloc
U memset
U printf
U puts
$ aarch64-openwrt-linux-musl-strings -a leaks.o
Doing memory alloc
Malloc failure
Malloc returned : %p
Valgrind leak Analysis!!!
GCC: (OpenWrt GCC 7.5.0 r11-afafb2b1c) 7.5.0
leaks.c
main
puts
malloc
printf
memset
.symtab
.strtab
.shstrtab
.rela.text
.data
.bss
.rodata
.comment
.note.GNU-stack
$
objdump 输出包含文本和 PLT 段:
$ aarch64-openwrt-linux-musl-objdump -D leaks
分解 .plt 部分:
.....
0000000000400530 <malloc@plt>:
400530: b0000090 adrp x16, 411000 <printf>
400534: f9400a11 ldr x17, [x16, #16]
400538: 91004210 add x16, x16, #0x10
40053c: d61f0220 br x17
0000000000400540 <memset@plt>:
400540: b0000090 adrp x16, 411000 <printf>
400544: f9400e11 ldr x17, [x16, #24]
400548: 91006210 add x16, x16, #0x18
40054c: d61f0220 br x17
.text部分的拆解:
......
000000000040060c <main>:
40060c: a9be7bfd stp x29, x30, [sp, #-32]!
400610: 910003fd mov x29, sp
400614: f9000fbf str xzr, [x29, #24]
400618: 90000000 adrp x0, 400000 <_init-0x4d8>
40061c: 911b0000 add x0, x0, #0x6c0
400620: 97ffffc0 bl 400520 <puts@plt>
400624: d2800640 mov x0, #0x32 // #50
400628: 97ffffc2 bl 400530 <malloc@plt>
40062c: f9000fa0 str x0, [x29, #24]
400630: f9400fa0 ldr x0, [x29, #24]
400634: f100001f cmp x0, #0x0
400638: 540000c1 b.ne 400650 <main+0x44> // b.any
40063c: 90000000 adrp x0, 400000 <_init-0x4d8>
400640: 911b6000 add x0, x0, #0x6d8
400644: 97ffffb7 bl 400520 <puts@plt>
400648: 12800000 mov w0, #0xffffffff // #-1
40064c: 14000016 b 4006a4 <main+0x98>
400650: 90000000 adrp x0, 400000 <_init-0x4d8>
400654: 911ba000 add x0, x0, #0x6e8
400658: f9400fa1 ldr x1, [x29, #24]
40065c: 97ffffad bl 400510 <printf@plt>
400660: d2800642 mov x2, #0x32 // #50
400664: 52800001 mov w1, #0x0 // #0
400668: f9400fa0 ldr x0, [x29, #24]
40066c: 97ffffb5 bl 400540 <memset@plt>
400670: f9400fa2 ldr x2, [x29, #24]
400674: 90000000 adrp x0, 400000 <_init-0x4d8>
400678: 911c0001 add x1, x0, #0x700
40067c: aa0203e0 mov x0, x2
400680: a9400c22 ldp x2, x3, [x1]
400684: a9000c02 stp x2, x3, [x0]
400688: f9400822 ldr x2, [x1, #16]
40068c: f9000802 str x2, [x0, #16]
400690: b8417021 ldur w1, [x1, #23]
400694: b8017001 stur w1, [x0, #23]
400698: f9400fa0 ldr x0, [x29, #24]
40069c: 97ffffa1 bl 400520 <puts@plt>
4006a0: 52800000 mov w0, #0x0 // #0
4006a4: a8c27bfd ldp x29, x30, [sp], #32
4006a8: d65f03c0 ret
Valgrind是使用以下优化和加固选项构建的。
-O2 -g -Wall -Wmissing-prototypes -Wshadow -Wpointer-arith -Wstrict-prototypes -Wmissing-declarations -Wcast-align -Wcast-qual -Wwrite-strings -Wempty-body -Wformat -Wformat-signedness -Wformat-security -Wignored-qualifiers -Wmissing-parameter-type -Wlogical-op -Wimplicit-fallthrough=2 -Wold-style-declaration -finline-functions -fno-stack-protector -fno-strict-aliasing -fno-builtin -O2 -Os -pipe -march=armv8-a -mcpu=cortex-a73+crypto -fno-caller-saves -fno-plt -Wa,--noexecstack -fhonour-copts -Wno-error=unused-but-set-variable -Wno-error=unused-result -iremap/home/renv/BBD_R2302OpenWrtB/working/QSDK12/qsdk/build_dir/target-aarch64/valgrind-3.15.0:valgrind-3.15.0 -Wformat -Werror=format-security -fPIC -D_FORTIFY_SOURCE=2 -Wl,-z,now -Wl,-z,relro
期望得到一些帮助/指引以继续前进。
malloc
和memset
。如果需要更多细节,请留言。 - renga_in_stackmalloc
在内部只是在单个页面内移动brk
一样。 - Peter Cordes