mmap 和 valgrind,mmap 不会增加堆大小
Mmap and valgrind, mmap doesnt increase heap size
我正在大学上操作系统课程,我们的任务之一是使用 mmap 实现简单的 malloc。现在我开始工作了,我尝试使用 valgrind 来检测遗留的任何错误。不管是否释放内存,valgrind 都看不到任何内存泄漏。例如考虑以下 C 代码:
int main()
{
int psize = getpagesize(),i;
int *ptr = mmap(NULL, psize, PROT_WRITE | PROT_READ, MAP_ANONYMOUS | MAP_PRIVATE, -1, 0);
for(i = 0; i < psize/4; i++) ptr[i] = i;
for(i = 0; i < psize/4; i++) printf("%d\n", ptr[i]);
return 0;
}
让我们用 gcc 编译它,并使用 valgrind。这是 valgrind returns:
==17841== Memcheck, a memory error detector
==17841== Copyright (C) 2002-2012, and GNU GPL'd, by Julian Seward et al.
==17841== Using Valgrind-3.8.1 and LibVEX; rerun with -h for copyright info
==17841== Command: ./test
==17841==
------------ printing numbers from 0 to 1023
==17841==
==17841== HEAP SUMMARY:
==17841== in use at exit: 0 bytes in 0 blocks
==17841== total heap usage: 0 allocs, 0 frees, 0 bytes allocated
==17841==
==17841== All heap blocks were freed -- no leaks are possible
==17841==
==17841== For counts of detected and suppressed errors, rerun with: -v
==17841== ERROR SUMMARY: 0 errors from 0 contexts (suppressed: 2 from 2)
这是意想不到的事情,我们通常希望在退出程序之前取消映射页面才能看到这样的消息。
起初我认为页面可能被延迟映射,这就是为什么我强制在该页面上执行一些操作,例如更改值和打印它们,但正如我们所见,这不是问题。
这可能是 valgrind 有问题,或者我对 mmap 和 valgrind 工作原理的理解有问题。
mmap doesn't increase heap size
堆与从 mmap
获得的内存是分开的。 Unix 进程获取内存有两种基本方式:
- 通过
brk(2)
/sbrk(2)
增加 "break" - 这是堆
- 通过使用
mmap
在内存中映射 - 这些独立于堆
Anatomy of a Program in Memory有好图:
This is probably something wrong with valgrind or my understanding of
how mmap and valgrind works.
阅读 memcheck manual 可能会有帮助,尤其是关于自定义分配器的部分。它的要点是,出于泄漏检查的目的,mmap
-分配的块对 valgrind 是不可见的。它只拦截malloc
、calloc
、free
、new
等
令人困惑的是,一些 mmap
分配的区域 被 valgrind
跟踪!例如,当 malloc
选择 mmap
内存而不是使用堆时,就会发生这种情况。
我正在大学上操作系统课程,我们的任务之一是使用 mmap 实现简单的 malloc。现在我开始工作了,我尝试使用 valgrind 来检测遗留的任何错误。不管是否释放内存,valgrind 都看不到任何内存泄漏。例如考虑以下 C 代码:
int main()
{
int psize = getpagesize(),i;
int *ptr = mmap(NULL, psize, PROT_WRITE | PROT_READ, MAP_ANONYMOUS | MAP_PRIVATE, -1, 0);
for(i = 0; i < psize/4; i++) ptr[i] = i;
for(i = 0; i < psize/4; i++) printf("%d\n", ptr[i]);
return 0;
}
让我们用 gcc 编译它,并使用 valgrind。这是 valgrind returns:
==17841== Memcheck, a memory error detector
==17841== Copyright (C) 2002-2012, and GNU GPL'd, by Julian Seward et al.
==17841== Using Valgrind-3.8.1 and LibVEX; rerun with -h for copyright info
==17841== Command: ./test
==17841==
------------ printing numbers from 0 to 1023
==17841==
==17841== HEAP SUMMARY:
==17841== in use at exit: 0 bytes in 0 blocks
==17841== total heap usage: 0 allocs, 0 frees, 0 bytes allocated
==17841==
==17841== All heap blocks were freed -- no leaks are possible
==17841==
==17841== For counts of detected and suppressed errors, rerun with: -v
==17841== ERROR SUMMARY: 0 errors from 0 contexts (suppressed: 2 from 2)
这是意想不到的事情,我们通常希望在退出程序之前取消映射页面才能看到这样的消息。
起初我认为页面可能被延迟映射,这就是为什么我强制在该页面上执行一些操作,例如更改值和打印它们,但正如我们所见,这不是问题。
这可能是 valgrind 有问题,或者我对 mmap 和 valgrind 工作原理的理解有问题。
mmap doesn't increase heap size
堆与从 mmap
获得的内存是分开的。 Unix 进程获取内存有两种基本方式:
- 通过
brk(2)
/sbrk(2)
增加 "break" - 这是堆 - 通过使用
mmap
在内存中映射 - 这些独立于堆
Anatomy of a Program in Memory有好图:
This is probably something wrong with valgrind or my understanding of how mmap and valgrind works.
阅读 memcheck manual 可能会有帮助,尤其是关于自定义分配器的部分。它的要点是,出于泄漏检查的目的,mmap
-分配的块对 valgrind 是不可见的。它只拦截malloc
、calloc
、free
、new
等
令人困惑的是,一些 mmap
分配的区域 被 valgrind
跟踪!例如,当 malloc
选择 mmap
内存而不是使用堆时,就会发生这种情况。