C UNIX消息队列分段错误
两个不同进程之间的消息交换有问题。 我必须只使用动态数组。 我也尝试过使用共享内存,但我没有解决我的问题 这是发件人的代码:C UNIX消息队列分段错误,c,linux,unix,C,Linux,Unix,两个不同进程之间的消息交换有问题。 我必须只使用动态数组。 我也尝试过使用共享内存,但我没有解决我的问题 这是发件人的代码: #include <stdio.h> #include <string.h> #include <unistd.h> #include <stdlib.h> #include <sys/ipc.h> #include <sys/msg.h> #
#include <stdio.h>
#include <string.h>
#include <unistd.h>
#include <stdlib.h>
#include <sys/ipc.h>
#include <sys/msg.h>
#include <errno.h>
#define KEYMSG 12345678
typedef struct msg
{
long int type;
char* str1;
char* str2;
}msg;
int main()
{
msg mymsg;
mymsg.str1=(char*)malloc(30*sizeof(char));
mymsg.str2=(char*)malloc(30*sizeof(char));
strcpy(mymsg.str1,"this is a test ");
strcpy(mymsg.str2,"test ok ");
mymsg.type=1;
if((msgget(KEYMSG,IPC_CREAT|0666))==-1)
{
fprintf(stderr,"ERROR CREATION\n");
fflush(stderr);
}
else
{
fprintf(stdout,"CREATION OK\n-----------\n");
fflush(stdout);
}
if((msgsnd(msgget(KEYMSG,0666),&mymsg,sizeof(msg),IPC_NOWAIT))<0)
{
fprintf(stderr,"msg not sent\n");
fflush(stderr);
}
else
{
fprintf(stdout, "\nmsg sent:\n");
fprintf(stdout, "%s\t%s\n\n",mymsg.str1,mymsg.str2);
fflush(stdout);
}
这是读者的代码:
#include <stdio.h>
#include <string.h>
#include <unistd.h>
#include <stdlib.h>
#include <sys/ipc.h>
#include <sys/msg.h>
#include <errno.h>
#include <sys/shm.h>
#define KEYMSG 12345678
typedef struct msg
{
long int type;
char* str1;
char* str2;
}msg;
int main()
{
msg mymsgrcv;
mymsgrcv.str1=(char*)malloc(30*sizeof(char));
mymsgrcv.str2=(char*)malloc(30*sizeof(char));
if((msgrcv(msgget(KEYMSG,0666),&mymsgrcv,sizeof(msg),1,IPC_NOWAIT))==-1)
{
fprintf(stderr,"READ ERROR\n");
fflush(stderr);
}
else
{
fprintf(stdout, "\nmsg read:\n");
fprintf(stdout, "%s\t%s\n\n",mymsgrcv.str1,mymsgrcv.str2);
fflush(stdout);
}
return 0;
}
一,。在消息中,您有指向字符串的指针,但它们的地址只是一个进程的本地地址。这些地址对另一个进程没有意义。 您必须传递字符串,而不仅仅是指向它的指针 定义消息,例如如下所示:
typedef struct msg
{
long int type;
char str1[32];
char str2[32];
}msg;
二,。始终对malloc3返回的指针执行错误检查 因此,您在Linux下编写了一个软件,该软件出现故障。如何找到它 第一步是在gcc中的编译器-g中启用调试信息 然后安装valgrind 现在让我们假设您的程序名为“家庭作业”,因此您可以将其作为./homography运行,因此运行: valgrind会告诉您问题出在哪里。在读卡器部分,您可能会遇到堆溢出,因为mymsgrcv.str1和mymsgrcv.str2可能是空字符串,它们不带结束字符\0 您可以将valgrind或gcc地址消毒剂与以下编译行一起使用:gcc-g-Wall-fsanize=address-fno省略帧指针读取器.c-o读取器 以下是gcc地址消毒剂报告的内容:
==22502==ERROR: AddressSanitizer: heap-buffer-overflow on address 0x60300000effe at pc 0x7fca63d99111 bp 0x7fff4ff40520 sp 0x7fff4ff3fcd0
READ of size 31 at 0x60300000effe thread T0
#0 0x7fca63d99110 (/usr/lib/x86_64-linux-gnu/libasan.so.2+0x5e110)
#1 0x7fca63d99a64 in __interceptor_vfprintf (/usr/lib/x86_64-linux-gnu/libasan.so.2+0x5ea64)
#2 0x7fca63d99b69 in __interceptor_fprintf (/usr/lib/x86_64-linux-gnu/libasan.so.2+0x5eb69)
#3 0x400c15 in main /home/jvet/TMP/reader.c:32
#4 0x7fca639b3b44 in __libc_start_main (/lib/x86_64-linux-gnu/libc.so.6+0x21b44)
#5 0x400988 (/home/jvet/TMP/reader+0x400988)
0x60300000effe is located 0 bytes to the right of 30-byte region [0x60300000efe0,0x60300000effe)
allocated by thread T0 here:
#0 0x7fca63dcf37a in malloc (/usr/lib/x86_64-linux-gnu/libasan.so.2+0x9437a)
#1 0x400ad7 in main /home/jvet/TMP/p2.c:21
#2 0x7fca639b3b44 in __libc_start_main (/lib/x86_64-linux-gnu/libc.so.6+0x21b44)
每当您想通过IPC发送字符串时,最好使用固定大小的数组,这将使IPC消息的大小更大,即使您要发送的数据非常少
要消除此类问题,您可以使用可变大小数组和数据大小(后跟消息头)对数据进行跟踪。我们都坐在座位边缘,试图找出您的问题!您是否尝试过使用-g选项编译此代码,然后运行valgrind./name of program?Valgrind将向您展示更多关于正在发生的事情的信息。您可以使用sudo apt get install Valgrind在Ubuntu上安装Valgrind,如果您使用yum,可能还可以使用yum install Valgrind。感谢您以这种方式给出的答案,它可以正常工作,但即使在msg struct中,我也无法定义任何非动态数组。有什么建议吗?感谢您在msgsnd中指定消息的长度。因此,您可以随意选择大小。像这样定义消息typedef struct msg{long int type;char str[];}msg;而malloc则是:msg*mymsg=mallocsizeofmsg+length\u of_string;。对不起,这个答案是巫术。在使用valgrind之类的工具之前,您应该先看看代码。
==22502==ERROR: AddressSanitizer: heap-buffer-overflow on address 0x60300000effe at pc 0x7fca63d99111 bp 0x7fff4ff40520 sp 0x7fff4ff3fcd0
READ of size 31 at 0x60300000effe thread T0
#0 0x7fca63d99110 (/usr/lib/x86_64-linux-gnu/libasan.so.2+0x5e110)
#1 0x7fca63d99a64 in __interceptor_vfprintf (/usr/lib/x86_64-linux-gnu/libasan.so.2+0x5ea64)
#2 0x7fca63d99b69 in __interceptor_fprintf (/usr/lib/x86_64-linux-gnu/libasan.so.2+0x5eb69)
#3 0x400c15 in main /home/jvet/TMP/reader.c:32
#4 0x7fca639b3b44 in __libc_start_main (/lib/x86_64-linux-gnu/libc.so.6+0x21b44)
#5 0x400988 (/home/jvet/TMP/reader+0x400988)
0x60300000effe is located 0 bytes to the right of 30-byte region [0x60300000efe0,0x60300000effe)
allocated by thread T0 here:
#0 0x7fca63dcf37a in malloc (/usr/lib/x86_64-linux-gnu/libasan.so.2+0x9437a)
#1 0x400ad7 in main /home/jvet/TMP/p2.c:21
#2 0x7fca639b3b44 in __libc_start_main (/lib/x86_64-linux-gnu/libc.so.6+0x21b44)