2016-01-24 65 views
-1

我遇到了两个不同进程之间交换消息的问题。 我只能使用动态数组。 我也试过使用共享内存,但我还没有解决我的问题。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; 
} 
+0

我们都坐在座位边缘试图找出你的问题! –

+0

您是否尝试过使用'-g'选项编译此代码,然后运行'valgrind。/ /程序名称? Valgrind会告诉你更多关于正在发生的事情的信息。如果你使用'yum',你可以在Ubuntu上用'sudo apt-get install valgrind'安装Valgrind,并且可能'yum install valgrind'。 – conradkdotcom

回答

2

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

定义消息例如像这样:

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

2.)总是对由malloc(3)返回的指针进行错误检查!

+0

感谢您的答案,这种方式,但我不能定义任何非动态数组即使在msg结构。 有什么建议吗?谢谢 –

+0

在'msgsnd()'中指定消息的长度。因此你可以使用malloc()任意大小。定义这样的消息 'typedef struct msg { long int type; char str []; 'msg * mymsg = malloc(sizeof(msg)+ length_of_string);'。 – Bernhard

0

所以你写的Linux下的软件,其失败段错误。如何找到它?

第一步是使你的编译器调试信息(-g在GCC)。

然后安装的valgrind。

现在让我们假设你的程序被称为homework(因此可以将其作为./homework),这样运行:

valgrind homework 

和Valgrind的会告诉你哪里出了问题。

0

读者部分,你可能会得到一个堆溢出,因为mymsgrcv.str1mymsgrcv.str2可以为空字符串(不带有结束字符\0)。

可以选择使用的valgrind或洗手液GCC地址(这个编译行:gcc -g -Wall -fsanitize=address -fno-omit-frame-pointer reader.c -o reader)。

下面是GCC地址消毒剂报道:每当你想通过IPC发送字符串,

==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) 
+0

对不起,但这个答案是巫毒魔法。在玩像valgrind这样的工具之前,你应该看看代码。 – Bernhard

0

喜欢使用数组大小​​固定,这将使得即使你有非常少的数据,以更大尺寸的IPC消息发送

为了除去这样的问题就可以使使用可变大小阵列和数据的大小后跟消息报头数据的拖尾。