UNIX消息队列分段错误

时间:2016-01-24 14:30:29

标签: c linux unix

我在两个不同进程之间交换消息时遇到了问题。 我必须只使用动态数组。 我也试过使用共享内存,但我还没有解决我的问题。

这是发件人的代码:

  #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;   
}

4 个答案:

答案 0 :(得分:2)

1。)在您的消息中,您有指向字符串的指针,但它们的地址只是一个进程的本地地址。地址对其他进程没有意义。 你必须传递字符串,而不仅仅是指向它的指针。

定义消息,例如像这样:

   typedef struct msg
   {
     long int type;
     char str1[32];
     char str2[32];
   }msg;

2。)始终对malloc(3)返回的指针进行错误检查!

答案 1 :(得分:0)

所以你在Linux下编写了一个软件崩溃的软件。如何找到它?

第一步是在编译器中启用调试信息(gcc中的-g)。

然后安装valgrind。

现在假设您的程序名为homework(因此您将其作为./homework运行),因此请运行:

valgrind homework

和valgrind会告诉你问题所在。

答案 2 :(得分:0)

reader 部分中,由于mymsgrcv.str1mymsgrcv.str2可能是空字符串(它们不带结束字符\0),因此可能会出现堆溢出

您可以使用valgrind或gcc地址清理程序(使用此编译行:gcc -g -Wall -fsanitize=address -fno-omit-frame-pointer reader.c -o reader)。

以下是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)

答案 3 :(得分:0)

每当你想通过IPC发送字符串时,更喜欢使用数组固定大小,即使你发送的数据非常少,这也会使IPC消息变得更大

要删除此类问题,您可以使用可变大小的数组和消息头后面的数据大小来拖尾数据。