socket.h 的 recv() 上的分段错误
在执行 .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()函数中,但我没能弄清楚为什么以及如何解决这个问题。
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.
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(2)
从您的描述来看,
recv()
正在阻塞,并且应用程序由于不同位置的错误而崩溃,会说在不同的线程中。然而,
buf
被声明为太小了一个字节。如果读取了
BUFLEN
字节,numbytes
将是BUFLEN
并且以下调用将写入未分配的内存buf
:将此更改修复
为
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
bytesnumbytes
will beBUFLEN
and the following call will write to memory not being allocated to bebuf
:To fix this change
to be
SIGSEGV 可能发生在其他地方,例如在
translate_and_update
中。为什么不启用核心转储(例如
ulimit -c
bash 内置)并使用gdb yourprog core
调试事后核心?The SIGSEGV could happen elsewhere, e.g. in
translate_and_update
.Why don't you enable core dumps (with e.g.
ulimit -c
bash builtin) and debug the post-mortem core withgdb yourprog core
?