【问题标题】:C/C++ recvmsg() causes error 'unaligned tcache chunk detected' but recv() is successfulC/C++ recvmsg() 导致错误“检测到未对齐的 tcache 块”但 recv() 成功
【发布时间】:2021-11-17 21:25:16
【问题描述】:

我在通过 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 是一个类成员,声明为: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,不是手动分配的。

(很遗憾,由于环境/构建系统,我无法使用清理构建)。

【问题讨论】:

  • 在您的程序早期的某个地方,您导致了堆损坏。您是否尝试在 Google 上搜索错误消息?
  • @Barmar 是的,但没有什么具体的,只是通用的。他们只是说这意味着堆损坏。
  • 我认为您的代码崩溃是因为您忘记设置成员msg.msg_name
  • 尝试声明变量sockaddr_in addr;,然后用msg.msg_name = &amp;addr;将它添加到你的msg结构中
  • @user997112 您无需在堆栈上初始化即可创建它,因为recvmsg() 将为您初始化它。很高兴它成功了。

标签: c++ linux sockets network-programming


【解决方案1】:

在您的代码中,您忘记设置结构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 中写入有关发送消息的主机的信息。

【讨论】:

  • 谢谢......
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 2020-01-22
  • 1970-01-01
  • 1970-01-01
  • 2012-11-18
  • 1970-01-01
  • 2013-07-17
  • 1970-01-01
相关资源
最近更新 更多