【问题标题】:Why does this POSIX shared memory code give a segmentation fault?为什么这个 POSIX 共享内存代码会出现分段错误?
【发布时间】:2019-04-13 21:09:45
【问题描述】:
#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;
}

我基本上是想在子进程中创建一些共享内存并从父进程中访问它。

在子进程中,mmap 工作正常。当我使用mmap 返回的指针进行打印时,它实际上打印了Hello, World!,但同样的打印会从父级给出一个段错误。

【问题讨论】:

    标签: c fork posix shared-memory mmap


    【解决方案1】:

    在父级 (pid != 0) 中,您打开了 O_RDONLY 对象,但使用 PROT_WRITE、MAP_SHARED 对其进行了映射。删除 | PROT_WRITE,你很好。 您可能想在奇数时间检查错误的返回值。

    【讨论】:

      【解决方案2】:

      崩溃是由于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.
      

      您尝试过:

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

      另外一点:您的name 应该遵循man 的可移植性建议:

      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.
      

      最后,您有一些不必要的 (char *) 强制转换,并且总是错误检查您的返回值。

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 2010-10-19
        • 2013-03-28
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        相关资源
        最近更新 更多