简体   繁体   English

为什么此POSIX共享内存代码出现分段错误?

[英]Why does this POSIX shared memory code give a segmentation fault?

#include <stdio.h>
#include <stdlib.h>
#include <sys/wait.h>
#include <string.h>
#include <fcntl.h>
#include <sys/shm.h>
#include <sys/stat.h>
#include <sys/time.h>
#include <unistd.h>
#include <sys/mman.h>

int main()
{
    const int SIZE = 500;
    const char *name = "name";
    int fd;
    char *ptr = NULL;
    pid_t pid;
    pid = fork();

    if (pid < 0) {
        fprintf(stderr, "Fork Failed");
        return 1;
    }
    else if (pid == 0) {
        fd = shm_open(name,O_CREAT | O_RDWR,0666);
        ftruncate(fd, SIZE);
        ptr = (char *)mmap(0, SIZE, PROT_READ | PROT_WRITE, MAP_SHARED, fd, 0);
        sprintf(ptr, "%s", "Hello, World!\n");
        return 0;
    }
    else {
        wait(NULL);
        fd = shm_open(name, O_RDONLY, 0666);
        ptr = (char *)mmap(0, SIZE, PROT_READ | PROT_WRITE, MAP_SHARED, fd, 0);
        printf("%s\n", (char *)ptr);
    }
    return 0;
}

I am basically looking to create some shared memory in the child process and access it from the parent. 我基本上希望在子进程中创建一些共享内存,并从父进程访问它。

In the child process, the mmap works fine. 在子进程中, mmap可以正常工作。 When I print using the pointer returned by mmap it does in fact print Hello, World! 当我使用mmap返回的指针进行打印时Hello, World!实际上会打印Hello, World! , but the same print gives a seg fault from the parent. ,但相同的打印内容会导致父级出现段错误。

In the parent (pid != 0) you opened the object O_RDONLY, but mmapped it with PROT_WRITE, MAP_SHARED. 在父级(pid!= 0)中,您打开了对象O_RDONLY,但使用PROT_WRITE,MAP_SHARED映射了该对象。 Remove the | 删除| PROT_WRITE and you are fine. PROT_WRITE,您还好。 You might want to check the return values for errors the odd time. 您可能希望在奇数时间检查返回值是否有错误。

The crash is due to this excerpt from man : 崩溃是由于man的摘录:

O_RDONLY   Open the object for read access.  A shared memory object
           opened in this way can be mmap(2)ed only for read
           (PROT_READ) access.

You've attempted to: 您试图:

fd = shm_open(name, O_RDONLY, 0666);
//                  ^^^^^^^^
ptr = (char *)mmap(0, SIZE, PROT_READ | PROT_WRITE, MAP_SHARED, fd, 0);
//                                    ^^^^^^^^^^^^ incorrect!

Another remark: your name should follow the man recommendation for portability: 另一句话:您的name应遵循男性的建议,以便携带:

For portable use, a shared memory object should be identified by a name
of the form /somename; that is, a null-terminated string of up to
NAME_MAX (i.e., 255) characters consisting of an initial slash,
followed by one or more characters, none of which are slashes.

Lastly, you have some unnecessary (char *) casts and always error check your return values. 最后,您进行了一些不必要的(char *)强制转换,并始终对返回值进行错误检查。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM