我正在测试valgrind并有一个泄漏 4 个字节的小 C 程序:
#include <stdio.h>
#include <stdlib.h>
int main(void)
{
int* x = malloc(sizeof(int));
printf( "Address: %p\n", x);
return 0;
}
Run Code Online (Sandbox Code Playgroud)
我用: 编译它gcc -g -o leak leak.c,然后运行它:
$ leak
Address: 0x55a72e303260
$ leak
Address: 0x55f370273260
Run Code Online (Sandbox Code Playgroud)
因此它显示了两次单独运行的两个不同地址。但是,如果我在 valgrind 下运行它,它总是显示相同的地址0x4a66040::
$ valgrind --leak-check=full --show-leak-kinds=all leak
==8186== Memcheck, a memory error detector
==8186== Copyright (C) 2002-2017, and GNU GPL'd, by Julian Seward et al.
==8186== Using Valgrind-3.14.0 and LibVEX; rerun with -h for copyright info
==8186== Command: leak
==8186==
Address: 0x4a66040
==8186==
==8186== HEAP SUMMARY:
==8186== in use at exit: 4 bytes in 1 blocks
==8186== total heap usage: 2 allocs, 1 frees, 1,028 bytes allocated
==8186==
==8186== 4 bytes in 1 blocks are definitely lost in loss record 1 of 1
==8186== at 0x483874F: malloc (in /usr/lib/x86_64-linux-gnu/valgrind/vgpreload_memcheck-amd64-linux.so)
==8186== by 0x109156: main (leak.c:6)
==8186==
==8186== LEAK SUMMARY:
==8186== definitely lost: 4 bytes in 1 blocks
==8186== indirectly lost: 0 bytes in 0 blocks
==8186== possibly lost: 0 bytes in 0 blocks
==8186== still reachable: 0 bytes in 0 blocks
==8186== suppressed: 0 bytes in 0 blocks
==8186==
==8186== For counts of detected and suppressed errors, rerun with: -v
==8186== ERROR SUMMARY: 1 errors from 1 contexts (suppressed: 0 from 0)
Run Code Online (Sandbox Code Playgroud)
为什么会这样呢?是否可以valgrind显示内存的真实地址?
它是分配的内存的“真实”地址。
Valgrind 将您的malloc()实现替换为它自己的版本,以便它可以执行其功能,请参阅以下行:
==8186== at 0x483874F: malloc (in /usr/lib/x86_64-linux-gnu/valgrind/vgpreload_memcheck-amd64-linux.so)
Run Code Online (Sandbox Code Playgroud)
因此,获取内存的底层调用在“正常”libc 实现malloc()和 valgrind 实现之间有所不同。可能 libc 使用brk()和 valgrind 使用mmap()。
brk()遵循地址空间布局随机化的规则,同时mmap()允许显式选择映射新分配的内存的虚拟内存地址。
编辑:strace两个版本的显示:
库:
brk(NULL) = 0x5611e25ec000
brk(0x5611e260d000) = 0x5611e260d000
fstat(1, {st_dev=makedev(0, 22), st_ino=67, st_mode=S_IFCHR|0620, st_nlink=1, st_uid=1000, st_gid=5, st_blksize=1024, st_blocks=0, st_rdev=makedev(136, 64), st_atime=1566292432 /* 2019-08-20T11:13:52.993864629+0200 */, st_atime_nsec=993864629, st_mtime=1566292432 /* 2019-08-20T11:13:52.993864629+0200 */, st_mtime_nsec=993864629, st_ctime=1564479628 /* 2019-07-30T11:40:28.009864433+0200 */, st_ctime_nsec=9864433}) = 0
write(1, "Address: 0x5611e25ec260\n", 24) = 24
Run Code Online (Sandbox Code Playgroud)
瓦尔格林德:
mmap(0x4c2c000, 2158912, PROT_READ|PROT_EXEC, MAP_PRIVATE|MAP_FIXED|MAP_DENYWRITE, 3, 0) = 0x4c2c000
...
write(1027, "==18842== at 0x4C2FB0F: mallo"..., 91) = 91
Run Code Online (Sandbox Code Playgroud)
所以实际上 Valgrind 明确选择了将其内存池映射到哪里。
| 归档时间: |
|
| 查看次数: |
427 次 |
| 最近记录: |