Подтвердить что ты не робот

Недопустимый аргумент для чтения-записи mmap?

Я почему-то получаю -EINVAL, и мне непонятно почему. Здесь, где я открываю и пытаюсь выполнить mmap файл:

if ((fd = open(argv[1], O_RDWR)) < 0)
{
    fprintf(stderr, "Failed to open %s: %s\n", argv[1], strerror(errno));
    return 1;
}

struct stat statbuf;
if (fstat(fd, &statbuf))
{
    fprintf(stderr, "stat filed: %s\n", strerror(errno));
    return 1;
}

char* fbase = mmap(NULL, statbuf.st_size, PROT_READ | PROT_WRITE, MAP_SHARED, fd, 0);
if (fbase == MAP_FAILED)
{
    fprintf(stderr, "mmap failed: %s\n", strerror(errno));
    return 1;
}

EDIT: я должен добавить, ошибка возникает в mmap.

4b9b3361

Ответ 1

Выключает изменение MAP_SHARED на MAP_PRIVATE, чтобы это удалось.

Эта причина была неудачной: мой код работает внутри виртуальной виртуальной машины, а файл, который я пытался выполнить mmap, находился в общем каталоге на моей главной машине. Виртуальная файловая система VirtualBox, по-видимому, не реализует mmap с опцией MAP_SHARED по границе гипервизора.

Если вы прочитаете jxh полезные комментарии как по моему вопросу, так и по его ответу, выясняется, что этот код работал на него, потому что он, вероятно, пытался mmap файл файловой системы хоста в память хоста.

Мое наблюдение, что переход от MAP_SHARED к MAP_PRIVATE также согласуется с этим: поскольку конфиденциальная память невидима для других процессов, драйвер виртуальной файловой системы, вероятно, не будет возражать против сопоставления памяти.

Решение состояло в том, чтобы переместить файл, который я хотел отобразить, на гостевой жесткий диск и выполнить манипуляции оттуда.

Ответ 2

Ваш statbuf.st_size - 0. mmap() завершится с ошибкой, если параметр длины 0.

Для EINVAL ошибки mmap() есть 3 перечисленные причины:

void *mmap(void *addr, size_t length, int prot, int flags,
           int fd, off_t offset);

...

  • Нам не нравятся addr, length или offset (например, они слишком большие или не выровнены на границе страницы).
  • (начиная с Linux 2.6.12) length было 0.
  • flags не содержал ни MAP_PRIVATE, ни MAP_SHARED, либо содержал оба этих значения.