首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >是否返回EDEADLK?

是否返回EDEADLK?
EN

Stack Overflow用户
提问于 2015-03-19 13:12:48
回答 1查看 1.5K关注 0票数 3

我有套接字家族PF_PACKET类型的SOCK_RAW。通过recvmsg和poll()读取消息。我定期地返回EDEADLK。我试着用下一段代码调试这个问题。我试着调查谁以及如何阻止我的套接字描述符。可能是某个人知道其他方法如何调试这样的情况?正如我所理解的

避免了EDEADLK资源死锁。试图锁定可能导致死锁情况的系统资源。在我的例子中,这是套接字文件描述符锁定问题。分配系统资源套接字文件描述符会导致死锁情况。该系统并不保证它会注意到所有这些情况。这个错误意味着你很幸运,系统也注意到了。

代码语言:javascript
复制
error = recvmsg(fd, &msghdr, flags);
msghdr_flags = msg_hdr.msg_flags;

void recvmsg_errno(int fd, unsigned int msghdr_flags, int flags, int error)
{
    struct flock fl;
    memset(&fl, 0x0, sizeof(fl));

    printf("recvmsg return: %d errno: %d description: %s\n", error, errno,
                    strerror(errno));

    printf("recvmsg flags: %x %d\n", flags, flags);
    if (flags & MSG_ERRQUEUE) printf("MSG_ERRQUEUE\n");
    if (flags & MSG_OOB) printf("MSG_OOB\n");
    if (flags & MSG_PEEK) printf("MSG_PEEK\n");
    if (flags & MSG_TRUNC) printf("MSG_TRUNC\n");
    if (flags & MSG_WAITALL) printf("MSG_WAITALL\n");

    printf("msghdr flags: %x %d\n", msghdr_flags, msghdr_flags);
    if (msghdr_flags & MSG_EOR) printf("MSG_EOR\n");           //indicates end-of-record; SOCK_SEQPACKET
    if (msghdr_flags & MSG_TRUNC) printf("MSG_TRUNC\n");       //discarded datagram was larger than the buffer supplied
    if (msghdr_flags & MSG_CTRUNC) printf("MSG_CTRUNC\n");     //control data were discarded due to lack of space in the buffer
    if (msghdr_flags & MSG_OOB) printf("MSG_OOB\n");           //out-of-band data were received
    if (msghdr_flags & MSG_ERRQUEUE) printf("MSG_ERRQUEUE\n"); //no data received; extended error from the socket error queue

    flags = 0;
    flags = fcntl(fd, F_GETLK, &fl); {
            printf("F_GETLK: 0x%x\n", flags);
            printf("l_start: %x l_len: %x l_pid: %d l_type: %x l_whence: %x\n",
                            fl.l_start,   //Starting offset for lock
                            fl.l_len,     //Number of bytes to lock
                            fl.l_pid,     //PID of process blocking our lock (F_GETLK only)
                            fl.l_type,    //Type of lock: F_RDLCK, F_WRLCK, F_UNLCK
                            fl.l_whence); // How to interpret l_start: SEEK_SET, SEEK_CUR, SEEK_END
    }//Get the first lock which blocks the lock description

    flags = 0;
    flags = fcntl(fd, F_GETFD); {
            printf("F_GETFD: 0x%x\n", flags);
    }//Get the file descriptor flags

    flags = 0;
    flags = fcntl(fd, F_GETFL); {
            printf("F_GETFL: 0x%x\n", flags);
            if (flags & O_NONBLOCK) printf("O_NONBLOCK\n");
            if (!(flags & O_NONBLOCK)) printf("BLOCK\n");
            if (flags & O_APPEND) printf("O_APPEND\n");
    }//Get the file status flags and file access modes

    flags = 0;
    flags = fcntl(fd, F_GETOWN); {
            printf("F_GETOWN: %d\n", flags);
    }//Socket, set the process or process group ID specified to receive SIGURG signals when out-of-band data is available.
}
EN

回答 1

Stack Overflow用户

回答已采纳

发布于 2015-03-19 22:30:05

如果recvmsg()返回0,并不意味着发生了错误。这意味着另一端关闭了连接。

在对这个问题的后续评论中,OP提到他们使用了if ((error = recvmsg()) <= 0) {return -errno;}。这是错误的。当另一端关闭连接时,recvmsg()返回零,而不设置errno。即使使用名为error的变量也是错误的,因为函数返回接收到的字节数。

换句话说,OP正在从其他早期失败的锁定函数中看到一个陈旧的、陈旧的errno == EDEADLK,并处理另一端将连接错误地关闭为错误的情况。

(只有在发生错误时才会设置errno;任何库函数都不会将其清除为零,因为在某些情况下可能会导致错误被隐藏。)

票数 8
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/29145546

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档