1

のrecv()関数を実行すると、奇妙なセグメンテーション違反が発生しました。これが私のコードで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回行った後(場合によってはそれ以下)。そして、それが起こったとき、プログラムは「endrecv()」なしで私の「startrecv()」文だけを出力します。

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

4

2 に答える 2

3

あなたの説明から、それはブロックされているように見えrecv()、別の場所でのエラーのためにアプリがクラッシュします、別のスレッドで言います。

それにもかかわらずbuf、1バイトが小さすぎると宣言されています。

BUFLENバイトnumbytesを読み取った場合、次の呼び出しは、割り当てられていないBUFLENメモリに書き込みます。buf

buf[numbytes] = '\0';

この変更を修正するには

char buf[BUFLEN];

することが

char buf[BUFLEN + 1];
于 2011-11-12T09:30:13.567 に答える
2

SIGSEGVは、他の場所、たとえばで発生する可能性がありtranslate_and_updateます。

コアダンプ(ulimit -cbashビルトインなど)を有効にして、事後コアをデバッグしてみませんgdb yourprog coreか?

于 2011-11-12T09:29:37.197 に答える