В приведенном ниже коде начинаются mmap (initlen = 10), позже - переназначение (nsize = 400000) и доступ к адресу памяти с переназначением. Доступ от 0x7ffff7f8c000 до 0x7ffff7f8cfff - это нормально, но в 0x7ffff7f8d000 возникает ошибка доступа
#define _GNU_SOURCE
#include <stdio.h>
#include <limits.h>
#include <stdint.h>
#include <stdlib.h>
#include <errno.h>
#include <sys/types.h>
#include <sys/stat.h>
#include <sys/mman.h>
#include <fcntl.h>
int main()
{
int i;
char *p;
void *base;
const int initlen = 10;
const int nsize = 400000;
const char *fname = "/tmp/task.0";
int fd = open(fname, O_CREAT|O_RDWR, 0600);
if (fd == -1) {
return 1;
}
if (ftruncate(fd, initlen) < 0) {
return 1;
}
base = mmap(NULL, initlen, PROT_READ|PROT_WRITE, MAP_SHARED, fd, 0);
if (base == MAP_FAILED) {
return 1;
}
// now remap big page.
base = mremap(base, initlen, nsize, MREMAP_MAYMOVE);
if (base == MAP_FAILED) {
printf("mremap fail, %s\n", strerror(errno));
return 1;
}
p = base;
for (i = 0; i < nsize; i++) {
printf("%p\n", p);
*p = i % CHAR_MAX;
++p;
}
return 0;
}
mremapпосле того, как gdb показывает, что регион /tmp/task.0 равен 0x7ffff7f8c000-0x7ffff7fee000, ошибка доступа в 0x7ffff7f8d000, почему ???
37 base = mremap(base, initlen, nsize, MREMAP_MAYMOVE);
(gdb)
38 if (base == MAP_FAILED) {
(gdb)
43 p = base;
(gdb)
44 for (i = 0; i < nsize; i++) {
(gdb) p base
$1 = (void *) 0x7ffff7f8c000
(gdb) i proc mappings
process 3333
Mapped address spaces:
Start Addr End Addr Size Offset objfile
0x400000 0x401000 0x1000 0x0 /tmp/a.out
0x600000 0x601000 0x1000 0x0 /tmp/a.out
0x601000 0x602000 0x1000 0x1000 /tmp/a.out
0x7ffff7a0e000 0x7ffff7bd1000 0x1c3000 0x0 /usr/lib64/libc-2.17.so
0x7ffff7bd1000 0x7ffff7dd0000 0x1ff000 0x1c3000 /usr/lib64/libc-2.17.so
0x7ffff7dd0000 0x7ffff7dd4000 0x4000 0x1c2000 /usr/lib64/libc-2.17.so
0x7ffff7dd4000 0x7ffff7dd6000 0x2000 0x1c6000 /usr/lib64/libc-2.17.so
0x7ffff7dd6000 0x7ffff7ddb000 0x5000 0x0
0x7ffff7ddb000 0x7ffff7dfd000 0x22000 0x0 /usr/lib64/ld-2.17.so
0x7ffff7f8c000 0x7ffff7fee000 0x62000 0x0 /tmp/task.0
0x7ffff7fee000 0x7ffff7ff1000 0x3000 0x0
0x7ffff7ff9000 0x7ffff7ffa000 0x1000 0x0
0x7ffff7ffa000 0x7ffff7ffc000 0x2000 0x0 [vdso]
0x7ffff7ffc000 0x7ffff7ffd000 0x1000 0x21000 /usr/lib64/ld-2.17.so
0x7ffff7ffd000 0x7ffff7ffe000 0x1000 0x22000 /usr/lib64/ld-2.17.so
0x7ffff7ffe000 0x7ffff7fff000 0x1000 0x0
0x7ffffffde000 0x7ffffffff000 0x21000 0x0 [stack]
0xffffffffff600000 0xffffffffff601000 0x1000 0x0 [vsyscall]
Program received signal SIGBUS, Bus error.
0x0000000000400831 in main () at ./test.c:46
46 *p = i % CHAR_MAX;
(gdb) p p
$2 = 0x7ffff7f8d000 <Address 0x7ffff7f8d000 out of bounds>