2011-11-12 2 views
1

のrecv()関数を実行すると、奇妙なセグメンテーション違反が発生しました。ここで私のコードでrecv()を使った関数があります。socket.hのrecv()でセグメンテーションエラーが発生しました

void* recv_and_update(void* t) { 
int tid = (int) t; 
int sockfd; 
struct sockaddr_in addr; 
int numbytes; 
char buf[BUFLEN]; 
int flag = 1, len = sizeof(int); 

if ((sockfd = socket(AF_INET, SOCK_DGRAM, 0)) < 0) { 
    printf("Failed to create socket on thread %d.\n", tid); 
    exit(-1); 
} 

memset(&addr, 0, sizeof(addr)); 
addr.sin_family = AF_INET; 
addr.sin_port = htons(node.port); 
addr.sin_addr.s_addr = htonl(INADDR_ANY); 

setsockopt(sockfd, SOL_SOCKET, SO_REUSEADDR, &flag, len); 
printf("start binding.\n"); 
if (bind(sockfd, (struct sockaddr*)&addr, sizeof(addr))) { 
    printf("Failed to bind socket on thread %d.\n", tid); 
    exit(-1); 
} 
printf("binding finished.\n"); 

while (1) { 
    printf("start recv()\n"); 
    if ((numbytes = recv(sockfd, buf, BUFLEN, 0)) < 0) { 
     printf("Failed to receive msgs on thread %d.\n", 
       tid); 
     exit(-1); 
    } 
    printf("end recv(), numbytes=%d\n", numbytes); 
    buf[numbytes] = '\0'; 
    pthread_mutex_lock(&mutex); 
    translate_and_update(buf); 
    pthread_mutex_unlock(&mutex); 
} 

close(sockfd); 
pthread_exit(NULL); 
} 

この問題の最も奇妙な部分は、毎回セグメンテーションフォールトが発生しないということです。通常、受信の100回または200回後(または時々より少ない回数)。そして、それが起こると、プログラムは "recv()"を終了しないで "start recv()"文のみを出力します。

私はrecv()関数で問題が発生したと思いますが、これを修正する理由と方法を理解できませんでした。

+2

'recv()'がデータを待っている間に別のスレッドでクラッシュすることもあります。しかし、これは単なる推測です。あなたがデバッガの下でそれを正確に実行することを知りたければ。 –

+0

このエラーが発生するたびに、 'recv()'を出力せずに 'start recv()'を出力します。別のスレッドでエラーが発生した場合、このようにすべきではありません。 (ああ、このスレッドは自分のプログラム内で唯一のスレッドを受け取っていることを忘れていました) – lastland

答えて

3

あなたのディスカッションでは、recv()がブロックされていて、別の場所でエラーが発生してアプリがクラッシュしたように見えます。

でも、bufは1バイトが小さすぎると宣言されます。 BUFLENバイトnumbytesを読んだ場合

BUFLENになり、次の呼び出しではないがbufように割り当てられているメモリに書き込みます:

buf[numbytes] = '\0'; 

する

char buf[BUFLEN]; 

この変更を修正するには

char buf[BUFLEN + 1]; 
+0

私は 'recv(sockfd、buf、BUFLEN-1、0)'を書こうとしました。 。しかし、これはうまくいきませんでした。 – lastland

+0

lastland:*別の*エラーがある必要があります! 'translate_and_update()'が何をするかを表示したいかもしれません – alk

+0

このエラーが起こるたびに、出力は 'start recv()'でなく 'recv()'ですが、エラーはrecv私が何かを見逃したり、誤解したりしなかった場合、 – lastland

2

SIGSEGVは他の場所で発生する可能性があります。 translate_and_updateにあります。

コアダンプを有効にしていない(例:ulimit -c bash builtinなど)、死後のコアをgdb yourprog coreでデバッグするのはなぜですか?

関連する問題