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 次后(或偶尔更少)。而当它发生时,程序只会输出我的“start recv()”句子而没有“end recv()”。

所以我认为问题发生在 recv() 函数中,但我无法弄清楚为什么以及如何解决这个问题。

4

2 回答 2

3

根据您的描述,它看起来像是recv()阻塞并且应用程序由于不同位置的错误而崩溃,会在不同的线程中说。

尽管如此buf,还是声明了一个字节太小。

如果将读取BUFLEN字节并且以下调用将写入分配为的内存:numbytesBUFLENbuf

buf[numbytes] = '\0';

修复此更改

char buf[BUFLEN];

成为

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

SIGSEGV 可能发生在其他地方,例如translate_and_update.

为什么不启用核心转储(例如ulimit -cbash builtin)并使用 调试事后核心gdb yourprog core

于 2011-11-12T09:29:37.197 回答