执行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次之后(或偶尔少次)。当它发生时,程序只会在没有“end recv()”的情况下输出我的“start recv()”句子。
所以我认为问题恰好发生在recv()函数中,但我没有弄清楚为什么以及如何解决这个问题。
答案 0 :(得分:3)
从您的描述中看起来recv()
正在阻止,并且应用因不同位置的错误而崩溃,会在另一个帖子中说明。
尽管buf
声明一个字节太小。
如果读取BUFLEN
字节numbytes
将为BUFLEN
,并且以下调用将写入内存而不是被分配为buf
:
buf[numbytes] = '\0';
修复此更改
char buf[BUFLEN];
是
char buf[BUFLEN + 1];
答案 1 :(得分:2)
SIGSEGV可能发生在其他地方,例如:在translate_and_update
。
为什么不启用核心转储(例如ulimit -c
bash builtin)并使用gdb yourprog core
调试验尸核心?