问题描述
考虑采用这种方法来实现包装缓冲区:
#define _GNU_SOURCE
#include <stdio.h>
#include <string.h>
#include <unistd.h>
#include <sys/mman.h>
static int wrapping_buffer(void)
{
char *b1,*b2;
long size;
size = sysconf(_SC_PAGE_SIZE);
if (size == -1) {
perror("_SC_PAGE_SIZE");
return 1;
}
b1 = mmap(NULL,2 * size,PROT_READ|PROT_WRITE,MAP_SHARED|MAP_ANONYMOUS,-1,0);
if (!b1) {
perror("mmap");
return 1;
}
memset(b1,2 * size);
/* This remaps the upper half of the buffer to the lower half,The same memory is now accessed by 2 different virtual adresses */
b2 = mremap(b1,size,MREMAP_MAYMOVE|MREMAP_FIXED,b1 + size);
if (b2 != b1 + size) {
perror("mremap");
return 1;
}
sprintf(b1 + size - 16,"this sentence is too long to fit in buffer");
printf("end:\t\"%s\"\n",b1 + size - 16);
printf("start:\t\"%s\"\n",b1);
if (munmap(b2,size) != 0)
perror("munmap(2)");
if (munmap(b1,2 * size) != 0)
perror("munmap(1)");
return 0;
}
int main(void)
{
return wrapping_buffer();
}
该程序编译并产生如下输出
end: "this sentence is too long to fit in buffer"
start: " too long to fit in buffer"
IOW,写入缓冲区的字符串扩展了一页的大小,这些字符串被包装到缓冲区的开头。这基于 mremap(2)记录的行为:
如果old_size的值为零,并且old_address引用了可共享的映射(请参阅mmap(2)MAP_SHARED),则mremap()将创建相同页面的新映射。
不幸的是,如果我尝试在valgrind下运行该程序,它将在mremap()
调用中失败:
==7217== Memcheck,a memory error detector
==7217== Copyright (C) 2002-2017,and GNU GPL'd,by Julian Seward et al.
==7217== Using Valgrind-3.16.1 and LibVEX; rerun with -h for copyright info
==7217== Command: /tmp/wrapping_buffer
==7217==
mremap: Invalid argument
这意味着我不能在应该用valgrind调试的任何程序中使用此技术(不是在谈论此特定代码,而是程序的其他部分可能包含内存泄漏)。不幸的是,因为我真的很喜欢重新映射技术的优雅和效率。
有人知道如何在valgrind下进行这项工作吗?还是我必须为此而破解valgrind?
解决方法
暂无找到可以解决该程序问题的有效方法,小编努力寻找整理中!
如果你已经找到好的解决方法,欢迎将解决方案带上本链接一起发送给小编。
小编邮箱:dio#foxmail.com (将#修改为@)