【问题标题】:Coredump at sem_waitsem_wait 的核心转储
【发布时间】:2013-12-10 06:12:45
【问题描述】:

我在这里有一个相当奇怪的问题,或者我不知道它的工作方式,但是我有下面的程序可以正确创建信号量并第一次运行到最后。但是如果信号量已经存在,SEGFaults at sem_wait。 我在 64 位 Fedora 17 上运行它。这与错误有什么关系吗?

#include <stdio.h>          /* printf()                 */
#include <stdlib.h>         /* exit(), malloc(), free() */
#include <sys/types.h>      /* key_t, sem_t, pid_t      */
#include <sys/shm.h>        /* shmat(), IPC_RMID        */
#include <errno.h>          /* errno, ECHILD            */
#include <semaphore.h>      /* sem_open(), sem_destroy(), sem_wait().. */
#include <fcntl.h>          /* O_CREAT, O_EXEC          */

int
main() {


        sem_t *mysem;
        int oflag = O_CREAT | O_EXCL;
        mode_t mode = 0777;
        const char semname[] = "mysem";
        unsigned int value = 1;
        int sts;


        mysem = sem_open(semname, oflag, mode, value);
        //sem_unlink(semname);

        if(mysem == (void *)-1) {
                printf("sem_open() failed");
                exit(1);
        }

        printf("opened a semaphore successful\n");

        if(!sem_wait(mysem)) {
                /*locked */
                printf("worked\n");
        } else {
                printf("error\n");
        }
         return 0;
}

/dev/shm 的内容 sem.mysem

Program received signal SIGSEGV, Segmentation fault.
0x000000332980d5f0 in sem_wait () from /lib64/libpthread.so.0
Missing separate debuginfos, use: debuginfo-install glibc-2.15-58.fc17.x86_64
(gdb) where
#0  0x000000332980d5f0 in sem_wait () from /lib64/libpthread.so.0
#1  0x000000000040074a in main () at str2.c:31

奇怪的问题是,当我删除 /dev/shm 中的信号量或取消注释 sem_unlink 时,它每次都有效。我在这里做错了什么还是需要在某个地方运行 sem_post?

谢谢。

【问题讨论】:

    标签: c linux synchronization ipc fedora


    【解决方案1】:

    如果sem_open 失败,它会返回SEM_FAILED,在我的系统(可能还有其他所有人)上它相当于NULL。检查它而不是-1

    此外,如果失败,则打印实际错误(使用例如 perror()strerror())。

    【讨论】:

      【解决方案2】:

      当尝试访问 CPU 无法物理寻址的特定内存时,通常会发生分段错误。硬件通知操作系统内存违规,内核(OS)作为响应发送一个纠正措施,通常会终止它或导致转储核心。最常见的分段原因是取消引用 NULL 指针。尝试一下可能会有所帮助。

      【讨论】:

      • 就我而言,我可能误解了一件事。这些 64 位指针值是否相同? 0x7f0d0b8c0000 和 0xb8c1000。我在这里遇到了核心转储
      • 我认为代码作为 32 位或 64 位指针值编写、编译和执行都一样。当/如果您执行诸如假设操作系统类型之间的相似性之类的事情(例如,DWORD 将保存一个指针——在 32 位代码中为真,但在 64 位代码中不是)时,大多数问题就会出现。
      【解决方案3】:

      检查人 open_sem:

      "如果 O_CREAT 和 O_EXCL 都在 oflag 中指定,则如果具有给定名称的信号量已经存在,则返回错误。"

      您的信号量似乎已经存在。这就是为什么您的代码在从 /dev/shm 删除后再次工作的原因 - 因此它可以再次创建它而不会出错。

      当人说 SEM_FAILED 时,我不确定为什么每个人都检查 -1 返回值是否存在错误。可能曾经表现得像开放。 SEM_FAILED 可以定义为任何值,您不应假定它的值并使用 MACRO。

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 1970-01-01
        • 2015-05-12
        • 2017-01-29
        • 2011-01-16
        • 2021-12-06
        • 1970-01-01
        • 2017-08-13
        • 2021-02-16
        相关资源
        最近更新 更多