当我将偏移量更改为任何非零值时,在 C 中映射共享内存会出现无效参数错误

问题描述 投票:0回答:1

我正在尝试打开一个共享内存文件,在其中写入,分叉到新进程,然后调用 execl 来运行其他组件,然后在这些组件中我想访问在父级中创建的共享内存。但我不想要整个结构,只想要其中的一部分。所以我使用 offsetof 来查找偏移量并将其传递到 mmap 中。问题是,当我将偏移量更改为零以外的任何值时,它会给出无效参数错误。零时效果很好。

我制作了一个具有相同错误的最小虚拟程序,并且较大程序的代码太大。 `

#include<stdio.h>
#include<unistd.h>
#include<sys/mman.h>
#include<stddef.h>
#include<fcntl.h>

typedef struct test
{
    int moo;
    char hello;
}Lil;


typedef struct bigstruct
{
    int a;
    char cow;
    Lil lil;
}Big;

int main()
{
    int fd = shm_open("/moomor", O_CREAT | O_RDWR, 0666);
    if(fd == -1)
    {
        perror("shmopen");
        return 1;
    }
    ftruncate(fd, sizeof(Big));
    Big * big = (Big *)mmap(NULL, sizeof(Big), PROT_READ | PROT_WRITE, MAP_SHARED, fd, 0);
    if(big == MAP_FAILED)
    {
        perror("mmap");
        return 1;
    }
    big->lil.hello = 'h';
    printf("hello: %c\n", big->lil.hello); //prints correctly
    munmap(big, sizeof(Big)); //tried it with this in and out

    int offset = offsetof(Big, lil); //gives offset of eight
    printf("Offset: %d\n", offset);
    Lil *lily = (Lil *)mmap(NULL, sizeof(Lil), PROT_READ | PROT_WRITE, MAP_SHARED, fd, offset);
    if(lily == MAP_FAILED)
    {
        perror("mmap"); //this causes an error
        goto cleanup;
    }
    printf("HH: %c\n", lily->hello);
    munmap(lily, sizeof(Lil));

    cleanup:
    shm_unlink("/moomor");
    close(fd);
}
c unix posix mmap execl
1个回答
0
投票

假设您使用的是基于 Linux 的平台,该函数的手册页

mmap
说明如下:

偏移量必须是 sysconf(_SC_PAGE_SIZE) 返回的页面大小的倍数。

您发布的代码似乎违反了此规则。

© www.soinside.com 2019 - 2024. All rights reserved.