epoll_event 不同的初始化会导致不同的 epoll_wait 结果

epoll_event different initialization causes different epoll_wait results

运行 以下带有 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);
  ...

我收到以下错误:

==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)

此处的解决方法是取消注释片段中的第二行。但是,这样做会给我不同的结果,特别是变量 new_event.

如果不把data.ptr初始化为NULL,那么我得到的new_event的值如下:

(gdb) p new_event
 = {events = 1, data = {ptr = 0x3, fd = 3, u32 = 3, u64 = 3}}

符合预期。

但是,通过初始化 data.ptr = NULL,然后 new_event 在 wait 调用后保持初始化:

(gdb) p new_event
 = {events = 1, data = {ptr = 0x0, fd = 0, u32 = 0, u64 = 0}}

1.) 为什么这个初始化会影响epoll_wait的结果?

2.) 如何摆脱 valgrind 错误并获得我期望的结果?

  1. new_event.data 是一个联合。也就是说它的各种元素 共享同一个存储空间。当您将 data.ptr 初始化为 NULL 时,即 覆盖一些(可能 all)其他字段(取决于 你的系统,特别是指针的大小)。
  2. 想到两个选项:
  • (a) 配置 valgrind 以抑制错误,因为它可以说是误报(valgrind 不知道该结构的某些部分未初始化是可以的)
  • (b) 以稍微冗长的方式初始化结构:

struct epoll_event server_socket_conn_ev = {.events = EPOLLIN, .ptr = NULL }; server_socket_conn_ev.fd = server_socket;