C/C++ recvmsg() causes error 'unaligned tcache chunk detected' but recv() is successful

I observe the below error when receiving UDP packets via Epoll:

'unaligned tcache chunk detected' 

I've managed to locate which part of the code but it doesn't make much sense.

This is the original code:

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 is a class member declared as: char _buffer[65'536];

By trial and error I narrowed the problem to this line:

const int64_t n = recvmsg(sock, &msg, 0); 

So I replaced ::recvmsg() with a call to ::recv() and it runs successfully:

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 } } 

Now the problem doesn't occur. What is causing this?

I'd like to understand why the first code doesn't work. The only memory is _buffer and that's not manually allocated.

(Unfortunately I cannot use a sanitize build due to the environment/build system).

13

1 Answer

In your code you forgot to set member msg_name of the struct msg:

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 

The reason you had memory corruption is because you had undefined behavior: recvmsg() tried to write to pointer msg.msg_name, but the latter contained an uninitialized memory address, so recvmsg() was actually writing to an invalid location.

recvmsg() writes information about the host that sent the message inside msg.msg_name.

1

Your Answer

Sign up or log in

Sign up using Google Sign up using Facebook Sign up using Email and Password

Post as a guest

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge that you have read and understand our privacy policy and code of conduct.

You Might Also Like