Warning: file_get_contents(/data/phpspider/zhask/data//catemap/4/c/61.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
C UNIX消息队列分段错误_C_Linux_Unix - Fatal编程技术网

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)