【问题标题】:Bad address with mq_openmq_open 的错误地址
【发布时间】:2015-07-12 18:25:01
【问题描述】:

我正在尝试使用 mq_open 打开一个简单的队列,但我不断收到错误消息:

"Error while opening ... 
Bad address: Bad address"

我也不知道为什么。

int main(int argc, char **argv) {
    struct mq_attr attr;
    //max size of a message
    attr.mq_msgsize = MSG_SIZE; 
    attr.mq_flags = 0;
    //maximum of messages on queue
    attr.mq_maxmsg = 1024 ;
    dRegister = mq_open("/serverQRegister",O_RDONLY | O_CREAT, S_IRUSR | S_IWUSR,0664, &attr);
    if(dRegister == -1)
    {
        perror("mq_open() failed");
        exit(1);
 }
}

我按照建议更新了代码,但仍然出现错误(“无效参数”):

#include <stdio.h>
#include <stdlib.h>
#include <mqueue.h>
#include <signal.h>
#include <string.h>
#include <unistd.h>
#include "serverDefinitions.h"
mqd_t dRegister;
int main(int argc, char **argv) {
    struct mq_attr attr;
    //setting all attributes to 0
    memset(&attr, 0, sizeof attr);
    //max size of a message
    attr.mq_msgsize = MSG_SIZE;  //MSG_SIZE = 4096
    attr.mq_flags = 0;
    //maximum of messages on queue
    attr.mq_maxmsg = 1024;
    dRegister = mq_open("/serverQRegister", O_RDONLY | O_CREAT, 0664, &attr);

    if (dRegister == -1) {
        perror("mq_open() failed");
        exit(1);
    }
    return 0;
}

【问题讨论】:

  • 您可能希望将printf("Error while opening ... \n"); perror(strerror(errno)); 替换为perror("mq_open() failed"); 并重新测试。 perror() 自动为errno 附加“文本描述”。
  • “错误地址”是EFAULT。根据mq_open() 的文档,EFAULT 不是由该函数设置的。
  • @alk 我更新了代码。我仍然收到“mq_open() failed: Bad address”。我正在运行:发行商 ID:elementary OS 描述:elementary OS Freya 版本:0.3
  • 因此,您想查看您的平台/实现的文档以了解 mq_open() 的含义,了解 EFAULT 在此上下文中的含义。
  • @alk 我在 Cloud9 上运行这个程序,仍然得到这个错误信息

标签: c posix ipc


【解决方案1】:

这个电话

... = mq_open("/serverQRegister",O_RDONLY | O_CREAT, S_IRUSR | S_IWUSR,0664, &attr);

指定了太多参数。 mode 似乎被指定了两次。

应该是

... = mq_open("/serverQRegister",O_RDONLY | O_CREAT, S_IRUSR | S_IWUSR, &attr);

... = mq_open("/serverQRegister",O_RDONLY | O_CREAT, 0664, &attr);

关于 EINVAL,man mq_open 声明:

EINVAL

O_CREAT 在 oflag 中指定,且 attr 不为 NULL,但 attr->mq_maxmsgattr->mq_msqsize 无效。这两个字段都必须大于零。在非特权进程(没有 CAP_SYS_RESOURCE 能力)中,attr->mq_maxmsg 必须小于或等于 msg_max 限制,并且 attr->mq_msgsize 必须小于或等于 msgsize_max 限制。此外,即使在特权进程中,attr->mq_maxmsg 也不能超过 HARD_MAX 限制。 (有关这些限制的详细信息,请参阅 mq_overview(7)。)

attr 的初始化达到了mq_maxmsg 或/和mq_msgsize 之一或两者的限制。阅读man 7 mq_overview,了解如何找出限制。

【讨论】:

  • 谢谢,但现在我收到“mq_open() failed: Invalid argument”。我写了 'dRegister = mq_open("/serverQRegister",O_RDONLY | O_CREAT, 0664, &attr);'
  • @MarcinMajewski:这很可能是由于缺少正确初始化attr
【解决方案2】:

mq_open() 是一个可变参数函数,它可以接受 2 或 4 个参数,但你给它 5,这是错误的。

做到这一点

dRegister = mq_open("/serverQRegister",O_RDONLY | O_CREAT, 0664, &attr);

或者使用符号名,S_IRUSR | S_IWUSR 而不是八进制表示。

你还应该初始化attr的所有成员,如果你提供mq_attr,你必须同时设置mq_msgsize和mq_maxmsg,所以做它

struct mq_attr attr;
memset(&attr, 0, sizeof attr);
//max size of a message
attr.mq_msgsize = MSG_SIZE;
attr.mq_maxmsg = 10;

(注意,mq_maxmsg 必须小于命令sysctl fs.mqueue.msg_max 设置的值)

【讨论】:

  • 我仍然收到错误,但现在是:“无效参数”
  • 是的,见编辑,你需要设置mq_maxmsg。或者您可以将 NULL 作为最后一个参数传递给 mq_open() 以使用默认属性。)
猜你喜欢
  • 1970-01-01
  • 2015-08-21
  • 1970-01-01
  • 2013-12-25
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2012-03-16
  • 1970-01-01
相关资源
最近更新 更多