通过 linux msg 队列传递的 C 结构间歇性失败

Posted

技术标签:

【中文标题】通过 linux msg 队列传递的 C 结构间歇性失败【英文标题】:C struct being passed thru a linux msg queue failing intermittently 【发布时间】:2021-04-14 13:25:38 【问题描述】:

我有一个客户端进程,它构建一个 IPC 消息结构 queue_msg,它通过 linux IPC 消息队列发送到服务器。大小为 68 字节。 struct 定义为:

struct FOO_TYPE 
   long mtype;
   struct 
      int sev;
      char msg[32];
      char bt[32];
    foomsg;
;

客户端在函数中本地声明一个指向 FOO_TYPE 结构的指针,并为其分配 malloc 空间。然后代码会加载 sev、msg 和 bt 字段。

static struct FOO_TYPE *FooEntry = NULL;

...代码被剪辑

   if (FooEntry == NULL)
      FooEntry = malloc(sizeof(struct FOO_TYPE));

   memset(FooEntry, 0, sizeof(struct FOO_TYPE));

...代码被剪辑

   MsgSize = sizeof(FooEntry) - sizeof(long);

   FooEntry->mtype = CHANGESTATUS;

   FooEntry->foomsg.sev = serr->serr_data->sev;

   strcpy(FooEntry->syserrmsg.emsg, elog);
   strcpy(FooEntry->syserrmsg.bt, btlog);

...代码被剪辑

   result = msg_snd(FooExchange, FooEntry, MsgSize, IPC_WAIT);

接收 IPC msg 的服务器正在获取 68 个字节(即:sizeof FOO_TYPE),但间歇性地,里面的字段要么丢失,要么是垃圾。

我是否也必须为结构内结构中的字段分配空间??

【问题讨论】:

如果你为指针分配了malloc空间,你就有问题了……但是贴出代码来代替对代码的描述 代码没有贴出来,我们无法判断问题出在哪里。 另请注意... struct padding 在两个系统上可能不同。当使用 IPC 结构时,您应该使用打包结构 除非您在史前机器上,否则您的结构大于 68 字节。 chars + an int + long 为 64 个字节。而且,正如所指出的,可能涉及填充。 按要求添加到帖子中的代码段。机器正在运行 RHEL 7.9 - 64 位。 【参考方案1】:

这至少是一个错误:

MsgSize = sizeof(FooEntry) - sizeof(long);

FooEntry是这里定义的指针:

static struct FOO_TYPE *FooEntry = NULL;

所以sizeof(FooEntry) 为您提供指针的大小 - 而不是结构的大小。

你可能想要

MsgSize = sizeof(*FooEntry) - sizeof(long);

或者只是

MsgSize = sizeof(FooEntry->foomsg);

【讨论】:

以上是关于通过 linux msg 队列传递的 C 结构间歇性失败的主要内容,如果未能解决你的问题,请参考以下文章

Linux进程间通信 --- 消息队列

IPC消息队列中msg的结构

Linux编程之自定义消息队列

Linux下获取消息队列的信息

C指针原理(20)-C指针基础

LInux进程间通信之消息队列编程实例