(правильный код в «Обновлении 5»)
Я попытался отобразить диапазон памяти от 0x100000000 до 0x200000000 в этом примере. Код C:
#include <stdio.h>
#include <stdlib.h>
#include <stdint.h>
#include <sys/mman.h>
int main(void)
{
uint64_t* rr_addr = 0;
uint64_t i = 17179869184;
printf("\nsizeof(size_t): %llu\n", sizeof(size_t));
printf("(uint64_t)0x100000000: %llx\n", (uint64_t)0x100000000);
printf("1L << 33: %llx\n", 1L << 33);
rr_addr = mmap((void*)i, (1UL << 33), PROT_READ|PROT_WRITE, MAP_ANON|MAP_PRIVATE, -1, 0);
printf("rr_addr: %p, %llu \n", rr_addr, rr_addr);
if (rr_addr == MAP_FAILED) {
perror("mmap error");
}
return 0;
}
В разных системах(Linux, gcc), я получаю разные результаты:
Результат 1:
sizeof(size_t): 8
(uint64_t)0x100000000: 100000000
1L << 33: 200000000
rr_addr: 0xffffffffffffffff, 18446744073709551615
mmap error: Cannot allocate memory
Информация о системе (Fedora 14):
Linux localhost.localdomain 2.6.35.10-74.fc14.x86_64 #1 SMP Thu Dec 23 16:04:50 UTC 2010 x86_64 x86_64 x86_64 GNU/Linux
gcc (GCC) 4.5.1 20100924 (Red Hat 4.5.1-4)
glibc: 2.12.90-21
Результат 2:
sizeof(size_t): 8
(uint64_t)0x100000000: 100000000
1L << 33: 200000000
rr_addr: 0x400000000, 17179869184
Информация о системе (Fedora 12):
Linux wiles 2.6.32.13 #2 SMP Fri Sep 10 01:29:43 HKT 2010 x86_64 x86_64 x86_64 GNU/Linux
gcc (GCC) 4.4.4 20100630 (Red Hat 4.4.4-10)
glibc verison: 2.11.2-1
Я ожидаю «Результат 2».Возможно, что-то не так с моим кодом.
Пожалуйста, помогите мне.
Обновление 1 : errno выводится на печать в случае сбоя mmap.
Обновление 3 : после изменения вызова mmap на эти строки:
char *cmd[20];
sprintf(cmd, "pmap -x %i", getpid());
printf("%s\n", cmd);
system(cmd);
rr_addr = mmap((void*)i, (1UL << 33), PROT_READ|PROT_WRITE, MAP_ANON|MAP_PRIVATE, -1, 0);
printf("%s\n", cmd);
system(cmd);
Результат:
sizeof(size_t): 8
(uint64_t)0x100000000: 100000000
1L << 33: 200000000
pmap -x 5618
5618: ./test
Address Kbytes RSS Dirty Mode Mapping
0000000000400000 4 4 0 r-x-- test
0000000000600000 4 4 4 rw--- test
00007f1cc941e000 1640 280 0 r-x-- libc-2.12.90.so
00007f1cc95b8000 2044 0 0 ----- libc-2.12.90.so
00007f1cc97b7000 16 16 16 r---- libc-2.12.90.so
00007f1cc97bb000 4 4 4 rw--- libc-2.12.90.so
00007f1cc97bc000 24 16 16 rw--- [ anon ]
00007f1cc97c2000 132 108 0 r-x-- ld-2.12.90.so
00007f1cc99c6000 12 12 12 rw--- [ anon ]
00007f1cc99e0000 8 8 8 rw--- [ anon ]
00007f1cc99e2000 4 4 4 r---- ld-2.12.90.so
00007f1cc99e3000 4 4 4 rw--- ld-2.12.90.so
00007f1cc99e4000 4 4 4 rw--- [ anon ]
00007fffa0da8000 132 8 8 rw--- [ stack ]
00007fffa0dff000 4 4 0 r-x-- [ anon ]
ffffffffff600000 4 0 0 r-x-- [ anon ]
---------------- ------ ------ ------
total kB 4040 476 80
pmap -x 5618
5618: ./test
Address Kbytes RSS Dirty Mode Mapping
0000000000400000 4 4 0 r-x-- test
0000000000600000 4 4 4 rw--- test
00007f1cc941e000 1640 280 0 r-x-- libc-2.12.90.so
00007f1cc95b8000 2044 0 0 ----- libc-2.12.90.so
00007f1cc97b7000 16 16 16 r---- libc-2.12.90.so
00007f1cc97bb000 4 4 4 rw--- libc-2.12.90.so
00007f1cc97bc000 24 16 16 rw--- [ anon ]
00007f1cc97c2000 132 108 0 r-x-- ld-2.12.90.so
00007f1cc99c6000 12 12 12 rw--- [ anon ]
00007f1cc99e0000 8 8 8 rw--- [ anon ]
00007f1cc99e2000 4 4 4 r---- ld-2.12.90.so
00007f1cc99e3000 4 4 4 rw--- ld-2.12.90.so
00007f1cc99e4000 4 4 4 rw--- [ anon ]
00007fffa0da8000 132 8 8 rw--- [ stack ]
00007fffa0dff000 4 4 0 r-x-- [ anon ]
ffffffffff600000 4 0 0 r-x-- [ anon ]
---------------- ------ ------ ------
total kB 4040 476 80
rr_addr: 0xffffffffffffffff, 18446744073709551615
mmap error: Cannot allocate memory
Обновление 4 : добавить "систему ("ulimit -m -v"); "непосредственно перед вызовом mmap: вывод ulimit:
max memory size (kbytes, -m) unlimited
virtual memory (kbytes, -v) unlimited
Другой вывод такой же, как «Обновление 3» (все еще не работает), за исключением pid.
Обновление 5: обновленный код, который работает в обеих системах:
#include <stdio.h>
#include <stdlib.h>
#include <stdint.h>
#include <sys/mman.h>
int main(void)
{
uint64_t* rr_addr = 0;
uint64_t i = 17179869184;
uint64_t len = 0;
char cmd[20];
printf("\nsizeof(size_t): %llu\n", sizeof(size_t));
len = (1UL << 32);
printf("len: %llx\n", len);
snprintf(cmd, sizeof cmd, "pmap -x %i", getpid());
printf("%s\n", cmd);
system(cmd);
system("ulimit -m -v");
rr_addr = mmap((void*)i, len, PROT_READ|PROT_WRITE, MAP_ANON|MAP_PRIVATE|MAP_NORESERVE, -1, 0);
printf("%s\n", cmd);
system(cmd);
printf("rr_addr: %p, %llu \n", rr_addr, rr_addr);
if (rr_addr == MAP_FAILED) {
perror("mmap error");
}
return 0;
}
Правильный ответ дает @caf: добавление флага MAP_NORESERVE в mmap решает эту проблему.Подробности причины в ответе кафе.Большое спасибо, кафе, и все они оказывают добрую помощь!