c-通过消息队列接收单个消息时的堆栈粉碎



我有以下发件人:

#include <stdio.h>
#include <stdlib.h>
#include <sys/ipc.h>
#include <sys/msg.h>
#include <sys/types.h>
#include <errno.h>
typedef struct message {
long int mtype;
int mtext[200];
} message;
int main(int argc, char *argv[]) {
// msg queue
int msgid;
message msg;
key_t key;

// create msg queue key
if ((key = ftok("master.c", 'b')) == -1) {
perror("ftok");
}
// create msg queue
if ((msgid = msgget(key, 0666 | IPC_CREAT)) == -1) {
perror("msgget");
}
msg.mtype=10;
msg.mtext[0] = 1;
if ((msgsnd(msgid, &msg, sizeof(message), 0)) == -1) {
perror("msgsnd");
}
sleep(5);
// TODO: uncomment section
if (msgctl(msgid, IPC_RMID, NULL) == -1) {
perror("msgctl");
}

return 0;
}

和接收器:

#include <stdio.h>
#include <stdlib.h>
#include <sys/ipc.h>
#include <sys/msg.h>
#include <sys/types.h>
#include <errno.h>
typedef struct message {
long int mtype;
int mtext[200];
} message;
int main(int argc, char *argv[]) {
// msg queue
message msg;
int msgid;
key_t key;

// create msg queue key
if ((key = ftok("master.c", 'b')) == -1) {
perror("ftok");
}
// create msg queue
if ((msgid = msgget(key, 0666)) == -1) {
perror("msgget");
}
if ((msgrcv(msgid, &msg, sizeof(message), 10, 0)) == -1) {
perror("msgrcv");
}
printf("%dn", msg.mtext[0]);
return 0;
}

问题是,当我运行这两个程序时,我会得到

*** stack smashing detected ***: terminated
Aborted (core dumped)

上面的短语是在整个代码按预期执行之后显示的,但它仍然意味着有些地方不正确。但是,如果我将msgrcv放置在一个无限循环中,则一切都按预期运行,并且不会引发任何警告。由于我正在写入和读取相同大小的数据,错误可能来自哪里?

根据文档,msgrcvmsgsz参数应指示消息结构的.mtext成员的大小(以字节为单位(,而不是整个结构的大小。

该结构通常比可用缓冲区大4或8个字节(取决于long int的定义(,因此您可能会在可用/分配的内存之外进行写入,从而导致未定义的行为。

UB的一个可能影响是分配给main函数的堆栈损坏;如果该函数从未返回(如添加无限循环时(,则堆栈损坏可能不会自行显现。

最新更新