C/C++ recvmsg() 导致错误 'unaligned tcache chunk detected' 但 recv() 成功
C/C++ recvmsg() causes error 'unaligned tcache chunk detected' but recv() is successful
我在通过 Epoll 接收 UDP 数据包时观察到以下错误:
'unaligned tcache chunk detected'
我已经找到了代码的哪一部分,但没有多大意义。
这是原代码:
while (_listen)
{
const int count = epoll_wait(_epollFd, &events[0], MAX_SOCKETS, -1);
assert(count != -1);
for (int j = 0; j < count; ++j)
{
iovec iov;
char control[1024];
msghdr msg;
iov.iov_base = _buffer;
iov.iov_len = sizeof(_buffer);
msg.msg_iov = &iov;
msg.msg_iovlen = 1;
msg.msg_namelen = sizeof(sockaddr_in);
msg.msg_control = &control[0];
msg.msg_controllen = 1024;
const int sock = events[j].data.fd;
const int64_t n = recvmsg(sock, &msg, 0); // This line seems to cause the problem
// More code
}
}
_buffer
是一个 class 成员声明为:char _buffer[65'536];
通过反复试验,我将问题缩小到这一行:
const int64_t n = recvmsg(sock, &msg, 0);
所以我用对 ::recv()
的调用替换了 ::recvmsg()
并且它运行成功:
while (_listen)
{
const int count = epoll_wait(_epollFd, &events[0], MAX_SOCKETS, -1);
assert(count != -1);
for (int j = 0; j < count; ++j)
{
const int sock = events[j].data.fd;
const int64_t n = recv(sock, _buffer, sizeof(_buffer), 0);
// More code
}
}
现在问题没有出现了。这是什么原因造成的?
我想了解为什么第一个代码不起作用。唯一的内存是 _buffer
并且不是手动分配的。
(不幸的是,由于 environment/build 系统,我无法使用清理构建)。
在您的代码中,您忘记设置结构 msg
的成员 msg_name
:
iovec iov;
char control[1024];
msghdr msg;
// add the following line:
sockaddr_in addr;
iov.iov_base = _buffer;
iov.iov_len = sizeof(_buffer);
msg.msg_iov = &iov;
msg.msg_iovlen = 1;
msg.msg_control = &control[0];
msg.msg_controllen = 1024;
// set the following members:
msg.msg_name = &addr;
msg.msg_namelen = sizeof(addr);
const int sock = events[j].data.fd;
const int64_t n = recvmsg(sock, &msg, 0);
// More code
你有内存损坏的原因是因为你有未定义的行为:recvmsg()
试图写入指针 msg.msg_name
,但后者包含一个未初始化的内存地址,所以 recvmsg()
是实际上写入无效位置。
recvmsg()
在msg.msg_name
.
中写入了发送消息的主机信息
我在通过 Epoll 接收 UDP 数据包时观察到以下错误:
'unaligned tcache chunk detected'
我已经找到了代码的哪一部分,但没有多大意义。
这是原代码:
while (_listen)
{
const int count = epoll_wait(_epollFd, &events[0], MAX_SOCKETS, -1);
assert(count != -1);
for (int j = 0; j < count; ++j)
{
iovec iov;
char control[1024];
msghdr msg;
iov.iov_base = _buffer;
iov.iov_len = sizeof(_buffer);
msg.msg_iov = &iov;
msg.msg_iovlen = 1;
msg.msg_namelen = sizeof(sockaddr_in);
msg.msg_control = &control[0];
msg.msg_controllen = 1024;
const int sock = events[j].data.fd;
const int64_t n = recvmsg(sock, &msg, 0); // This line seems to cause the problem
// More code
}
}
_buffer
是一个 class 成员声明为:char _buffer[65'536];
通过反复试验,我将问题缩小到这一行:
const int64_t n = recvmsg(sock, &msg, 0);
所以我用对 ::recv()
的调用替换了 ::recvmsg()
并且它运行成功:
while (_listen)
{
const int count = epoll_wait(_epollFd, &events[0], MAX_SOCKETS, -1);
assert(count != -1);
for (int j = 0; j < count; ++j)
{
const int sock = events[j].data.fd;
const int64_t n = recv(sock, _buffer, sizeof(_buffer), 0);
// More code
}
}
现在问题没有出现了。这是什么原因造成的?
我想了解为什么第一个代码不起作用。唯一的内存是 _buffer
并且不是手动分配的。
(不幸的是,由于 environment/build 系统,我无法使用清理构建)。
在您的代码中,您忘记设置结构 msg
的成员 msg_name
:
iovec iov;
char control[1024];
msghdr msg;
// add the following line:
sockaddr_in addr;
iov.iov_base = _buffer;
iov.iov_len = sizeof(_buffer);
msg.msg_iov = &iov;
msg.msg_iovlen = 1;
msg.msg_control = &control[0];
msg.msg_controllen = 1024;
// set the following members:
msg.msg_name = &addr;
msg.msg_namelen = sizeof(addr);
const int sock = events[j].data.fd;
const int64_t n = recvmsg(sock, &msg, 0);
// More code
你有内存损坏的原因是因为你有未定义的行为:recvmsg()
试图写入指针 msg.msg_name
,但后者包含一个未初始化的内存地址,所以 recvmsg()
是实际上写入无效位置。
recvmsg()
在msg.msg_name
.