gpt4 book ai didi

c - 系统调用参数 msgsnd(msgp->mtext) 指向未初始化的字节 - 消息队列 - Valgrind

转载 作者:太空宇宙 更新时间:2023-11-04 04:17:48 24 4
gpt4 key购买 nike

我编写了一个 C 程序来测试并行进程上的一些消息队列。消息定义如下:

typedef struct _Message{
long type;
int some_number;
char some_info[SIZE];
}Message;

在我的程序中,msqid是我用msgget得到的消息队列的标识,msg是一个Message的实例,所有的字段都被初始化(所有超出字符串末尾的字符也会得到值 '\0' 以防万一)。所以我调用 msgsnd,指定大小对应于类型没有 long 值的 Message(这就是我应该做的,对吧?),并且 0 代表标志,所以它等待发送消息。

msgsnd(msqid, &msg, sizeof(Message) - sizeof(long), 0);

程序运行良好,数据发送正确,另一个进程接收并正确打印所有内容。然而,Valgrind 大师并不这么看:

    ==3514== Syscall param msgsnd(msgp->mtext) points to uninitialised byte(s)
==3514== at 0x4F368F3: __msgsnd_nocancel (syscall-template.S:81)
==3514== by 0x400E9D: func_a ......
==3514== by 0x4011CB: main ......
==3514== Address 0xfff00002c is on thread 1's stack
==3514== in frame #1, created by func_a (???)
==3514==

msgsnd 的官方文档讨论了一个 struct msgbuf,它包含一个名为 mtext 的字段,但我不太明白它是什么意思,它如何对应于我为 Message 定制的结构以及我应该如何给它一个值。那么,关于如何解决这个问题有什么想法吗?

 struct msgbuf {
long mtype; /* message type, must be > 0 */
char mtext[1]; /* message data */
};

最佳答案

问题可能是您的 _Message 正在与 8 字节边界对齐(我假设是 64 位构建,对于 32 位构建和 4 字节边界也是如此)。

typedef struct _Message{
long type; // 8 bytes
int some_number; // 4 bytes
char some_info[SIZE]; // SIZE bytes
}Message;

如果 SIZE 是 4 的奇数倍,那么 _Message 的总大小将是 8 的倍数,您将看不到任何问题。

如果 SIZE 是任何其他值,则 _Message 将被填充到下一个 8 的倍数。例如,如果 SIZE 是 10,则成员大小的总和为 22 字节(并且也没有对齐孔)。这将四舍五入为 22,表示结构末尾有 2 个填充字节。

Valgrind 提示此填充未初始化。当您 memset 实例为零时,成员数据和填充都会被初始化,Valgrind 不再提示。

在 Valgrind 方面,解决这个问题并不容易。像这样的系统调用接受指向任何东西的指针,而 Valgrind 无法判断未初始化的字节是否是真正的错误,或者它们是否是结构中的空洞/填充。一种可能性是为小于字长的未初始化范围生成较低级别的警告。

关于c - 系统调用参数 msgsnd(msgp->mtext) 指向未初始化的字节 - 消息队列 - Valgrind,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/49965441/

24 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com