简体   繁体   中英

Segmentation fault on recv() of socket.h

I got a strange segmentation fault when executing recv() function of . Here's the function used recv() in my code.

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

The most weird part of this problem is that the segmentation fault doesn't happen every time. Usually after 100 or 200 times of receiving ( or less times occasionally ). And when it happens, the program would only output my "start recv()" sentence without "end recv()".

So I think the problem happens right in the recv() function, but I failed to figure out why and how to fix this.

From your discription it looks like recv() is blocking and the app crashes due to an error at a different location, will say in a different thread.

Nevertheless buf is declared one byte too small.

If having read BUFLEN bytes numbytes will be BUFLEN and the following call will write to memory not being allocated to be buf :

buf[numbytes] = '\0';

To fix this change

char buf[BUFLEN];

to be

char buf[BUFLEN + 1];

The SIGSEGV could happen elsewhere, eg in translate_and_update .

Why don't you enable core dumps (with eg ulimit -c bash builtin ) and debug the post-mortem core with gdb yourprog core ?

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM