页次: 1
今天学习msgsnd()函数后发现,在调用ipcrm -q [id]后,再次调用后会出现msgsnd error: Invalid argument错误。具体过程如下:
#include <string.h>
#include <stdio.h>
#include <stdlib.h>
#include <sys/msg.h>
typedef struct {
long type;
char mtext[512];
} MSG;
int main(int argc, char *argv[])
{
if (argc < 2) {
fprintf(stderr, "usage:%s key\n", argv[0]);
exit(1);
}
// 指定参数1为消息队列的key
key_t key = atoi(argv[1]);
printf("key: %d\n", key);
int msq_id;
if ((msq_id = msgget(key, IPC_CREAT | IPC_EXCL | 0666) < 0)) {
perror("msgget error");
}
printf("msq id: %d\n", msq_id);
MSG m1 = {4, "1" };
MSG m2 = {1, "2" };
MSG m3 = {2, "3"};
MSG m4 = {6, "4" };
MSG m5 = {6, "5"};
if (msgsnd(msq_id, (void*)&m1, sizeof(MSG)-sizeof(long), IPC_NOWAIT) < 0) {
perror("msgsnd error");
}
if (msgsnd(msq_id, &m2, sizeof(MSG)-sizeof(m2.type), IPC_NOWAIT) < 0) {
perror("msgsnd error");
}
if (msgsnd(msq_id, &m3, sizeof(MSG)-sizeof(m2.type), IPC_NOWAIT) < 0) {
perror("msgsnd error");
}
if (msgsnd(msq_id, &m4, sizeof(MSG)-sizeof(m2.type), IPC_NOWAIT) < 0) {
perror("msgsnd error");
}
if (msgsnd(msq_id, &m5, sizeof(MSG)-sizeof(m2.type), IPC_NOWAIT) < 0) {
perror("msgsnd error");
}
// 获得消息队列总数
struct msqid_ds ds;
if (msgctl(msq_id, IPC_STAT, &ds) < 0) {
perror("msgctl error");
}
printf("msg total: %ld\n", ds.msg_qnum);
return 0;
}
编译程序为a.out,执行
./a.out 10
此时一切正常,当调用系统命令
ipcrm --all=msg -v
之后,再次 ./a.out 3后,出现
key: 3
msq id: 0
msgsnd error: Invalid argument
msgsnd error: Invalid argument
msgsnd error: Invalid argument
msgsnd error: Invalid argument
msgsnd error: Invalid argument
msgctl error: Invalid argument
msg total: 17179869188
想问这是怎么回事?在虚拟机kali(Linux kali 5.5.0-kali1-amd64 #1 SMP Debian 5.5.13-2kali1 (2020-04-03) x86_64 GNU/Linux)同样出现相同的问题
本机 manjaro(Linux nsfoxerpc 5.4.40-1-MANJARO #1 SMP PREEMPT Sun May 10 14:17:40 UTC 2020 x86_64 GNU/Linux) 希望大佬解决问题,谢谢
离线
在cnetos上实验时,出现报错
msq id: 1
msgsnd error: Identifier removed
msgsnd error: Identifier removed
msgsnd error: Identifier removed
msgsnd error: Identifier removed
msgsnd error: Identifier removed
msgctl error: Identifier removed
msg total: 0
google已经找到是因为代码第26行括号闭合位置错误,感谢
不同发行版的perror()报错信息还不一样?还是因为centos内核版本低?
离线
呃,我想去给 gcc / clang 报 bug……
if ((msq_id = msgget(key, IPC_CREAT | IPC_EXCL | 0666) < 0)) {
这一行,你仔细匹配一下括号。
另外,sizeof(MSG)-sizeof(long) 这样计算另一个字段的长度是错的,因为会有 padding。你应当用 sizeof(m1.mtext) 或者直接写长度(毕竟你程序里是固定值,用个宏就可以了)。
离线
哦哦,看懂了;因为内存对齐原因,所以会出现padding;
man magsnd 有一段描述:
int msgsnd(int msqid, const void *msgp, size_t msgsz, int msgflg);
......
The msgp argument is a pointer to caller-defined structure of the following general form:struct msgbuf {
long mtype; /* message type, must be > 0 */
char mtext[1]; /* message data */
};
The mtext field is an array (or other structure) whose size is specified by msgsz, a nonnegative integer value.
msgsnd的第三个参数指的是mtext[]大小,而由于内存对齐的原因,sizeof(MSG)-sizeof(long)可能会导致padding也被计算在其中。
感谢大佬
离线
页次: 1