【问题标题】:Accessing memory after shm_unlink在 shm_unlink 之后访问内存
【发布时间】:2016-01-18 16:35:04
【问题描述】:

shm_unlink 的操作我不清楚。我创建了一个共享内存对象并映射到一个进程。后来,我对内存对象做了shm_unlink。在shm_unlink 之后,我能够访问相同的内存进行读写。这怎么可能?由于内存对象被shm_unlink 破坏,我预计在这种情况下会出现分段错误。但是,它没有发生吗?是什么原因? shm_unlink 到底在这里做什么?

下面是代码sn-p。

main(int argc, char * argv[])
{
    int   fd;
    char  *addr;
    int i = 0;

    /*
    * In case the unlink code isn't executed at the end
    */
    if (argc != 1) {
        shm_unlink("/bolts");
        return EXIT_SUCCESS;
    }

    /* Create a new memory object */
    fd = shm_open("/bolts", O_RDWR | O_CREAT, 0666);
    if (fd == -1) {
        fprintf(stderr, "Open failed : %s\n",
            strerror(errno));
        return EXIT_FAILURE;
    }

    /* Set the memory object's size */
    if (ftruncate(fd, 1024) == -1) {
        fprintf(stderr, "ftruncate : %s\n", strerror(errno));
        return EXIT_FAILURE;
    }

    addr = mmap(0, 1024, PROT_READ | PROT_WRITE,
        MAP_SHARED, fd, 0);

    if (addr == MAP_FAILED) {
        fprintf(stderr, "mmap failed:%s\n", strerror(errno));
        return EXIT_FAILURE;
    }

    sleep(10);

    printf("Map addr is %x\n",(unsigned int) addr);

    if (fork())
    {
        sleep(10);
        strcpy (addr, "Sreehari in parent\n");
    }
    else
    {
        strcpy(addr,  "I am in child\n");

    }

    sleep(6);
    i = shm_unlink("/bolts");

    printf("addr is %s, i is %d \n", addr, i);
    return EXIT_SUCCESS;
}

【问题讨论】:

    标签: c linux embedded-linux


    【解决方案1】:

    shm_open/shm_unlink 不直接影响内存映射,这必须通过相应的 mmap/munmap-calls 来完成。

    shm_unlink 从 shm 文件系统中删除一个 Posix 共享内存段,如果最后一个映射被删除,则实际内存被破坏。

    【讨论】:

      【解决方案2】:

      shm_open 创建一个命名的共享内存对象。任何进程都可以使用传递给shm_open 的名称映射该共享内存对象。 shm_unlink 删除该名称,因此无法再映射共享内存区域,但实际内存在未映射之前是可用的。请注意,这类似于unlink:您可以在unlink()ing 之后使用open()ed 文件,并且在最后一个文件描述符为close()d 之后,实际文件内容将被释放。

      根据手册页:

      shm_unlink() 的操作类似于 unlink(2):它删除一个 共享内存对象名称,并且,一旦所有进程都取消映射 对象,取消分配和销毁关联的内容 内存区域。成功 shm_unlink() 后,尝试 shm_open() 同名对象将失败(除非 O_CREAT 指定,在这种情况下会创建一个新的、不同的对象)。

      【讨论】:

        【解决方案3】:

        如 shm_unlink man 页面所述:

        " 名称应在 shm_unlink() 返回之前删除,但内存对象内容的删除应推迟到 所有对共享内存对象的打开和映射引用都已 删除。”

        这意味着取消链接后内存可能还在。

        【讨论】:

          猜你喜欢
          • 2019-06-05
          • 2017-07-24
          • 1970-01-01
          • 2014-07-10
          • 2011-12-08
          • 2017-03-16
          • 2015-05-11
          • 1970-01-01
          • 1970-01-01
          相关资源
          最近更新 更多