Ошибка сегментации в recv () файла socket.h - PullRequest
1 голос
/ 12 ноября 2011

У меня возникла странная ошибка сегментации при выполнении функции 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 (), но мне не удалосьвыяснить, почему и как это исправить.

Ответы [ 2 ]

3 голосов
/ 12 ноября 2011

Из вашего описания похоже, что recv() блокируется и приложение вылетает из-за ошибки в другом месте, скажем, в другой теме.

Тем не менее buf объявлен на один байт слишком маленьким.

Если при чтении BUFLEN байт numbytes будет BUFLEN, и следующий вызов будет записывать в память , а не , который будет выделен как buf:

buf[numbytes] = '\0';

Чтобы исправить это изменение

char buf[BUFLEN];

будет

char buf[BUFLEN + 1];
2 голосов
/ 12 ноября 2011

SIGSEGV может произойти в другом месте, например, в translate_and_update.

Почему бы вам не включить дампы ядра (например, с помощью ulimit -c bash builtin ) и отладить посмертноядро с gdb yourprog core?

...