Running the following snippet with valgrind:
struct epoll_event server_socket_conn_ev = {.events = EPOLLIN, .data.fd = server_socket};
//server_socket_conn_ev.data.ptr = NULL;
if (epoll_ctl(epoll_fd, EPOLL_CTL_ADD, server_socket, &server_socket_conn_ev) == -1) {
perror(NULL);
return 1;
}
struct epoll_event new_event;
while(1) {
epoll_wait(epoll_fd, &new_event, 1, -1);
...
I get the following error:
==16219== Syscall param epoll_ctl(event) points to uninitialised byte(s)
==16219== at 0x524AA7A: epoll_ctl (syscall-template.S:84)
==16219== by 0x401464: run_server (server.c:85)
==16219== by 0x401367: main (server.c:57)
==16219== Address 0xfff0002e8 is on thread 1's stack
==16219== in frame #1, created by run_server (server.c:69)
The fix here, is to uncomment the second line from the snippet. However, doing so gives me different results, specifically the variable new_event.
If do not not initialize data.ptr to NULL, then I got the following value for new_event:
(gdb) p new_event
$1 = {events = 1, data = {ptr = 0x3, fd = 3, u32 = 3, u64 = 3}}
as expected.
However, by initializing data.ptr = NULL, then new_event remains initialized after the wait call:
(gdb) p new_event
$1 = {events = 1, data = {ptr = 0x0, fd = 0, u32 = 0, u64 = 0}}
1.) Why does this initialization affect the result of epoll_wait?
2.) How can I get rid of the valgrind error and get the results I expect?
new_event.data
is a union. That is to say, its various elements
share the same storage. When you initialise data.ptr to NULL
, that
overwrites some (potentially all) the other fields (depending on
your system, specifically what size pointers are).struct epoll_event server_socket_conn_ev = {.events = EPOLLIN, .ptr = NULL }; server_socket_conn_ev.fd = server_socket;