Skip to content

Fully initialize the epoll_data structure. #321

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Closed
wants to merge 1 commit into from

Conversation

Lukasa
Copy link
Contributor

@Lukasa Lukasa commented Nov 17, 2017

While running a simple libdispatch-using application on Linux under Valgrind, I noticed that Valgrind complained that the struct epoll_event initialized in this function was not fully initialized:

==3103== Syscall param epoll_ctl(event) points to uninitialised byte(s)
==3103==    at 0x5DBE63A: epoll_ctl (syscall-template.S:81)
==3103==    by 0x4075493: _dispatch_timeout_program (in /usr/lib/swift/linux/libdispatch.so)
==3103==    by 0x407534F: _dispatch_event_loop_timer_arm (in /usr/lib/swift/linux/libdispatch.so)
==3103==    by 0x4072391: _dispatch_timers_program (in /usr/lib/swift/linux/libdispatch.so)
==3103==    by 0x40712D9: _dispatch_mgr_invoke (in /usr/lib/swift/linux/libdispatch.so)
==3103==    by 0x407118D: _dispatch_mgr_thread (in /usr/lib/swift/linux/libdispatch.so)

While this is unlikely to cause any bugs today (none of those fields are accessed anywhere else), we can save ourselves the risk of future pain by initialising those portions of the structure appropriately before we pass it to the kernel.

Copy link
Contributor

@MadCoder MadCoder left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This just can't be the cause for the bug, as C initializer will 0-initialize non explicitly initialized fields already.

@MadCoder MadCoder closed this Dec 4, 2017
@Lukasa
Copy link
Contributor Author

Lukasa commented Dec 4, 2017

You're right that the fix is wrong, but the why was a bit of a surprise to me. I went back and checked the man page for epoll and noticed that epoll_data is a union, not a struct (my mistake), and that union type contains 64-bit members. The compiler output for _dispatch_timeout_program initialises .data like this:

   4f3d7:       4c 8d 3d f2 58 04 00    lea    0x458f2(%rip),%r15        # 94cd0 <_dispatch_epoll_timeout>
   4f3de:       43 0f b7 44 e7 04       movzwl 0x4(%r15,%r12,8),%eax
   4f3e4:       89 44 24 04             mov    %eax,0x4(%rsp)

Note that the initialisation is done with movzwl, which initialises only first 4 bytes of the 8 byte union. Nowhere else zero-initialises the epoll_event structure, so the trailing 4 bytes of the structure are in fact uninitialized.

As noted before, this is probably not an issue, but it may be better to split the initialisation up. If we changed the code to look like this:

struct epoll_event ev = {
    .events = EPOLLONESHOT | EPOLLIN
};
ev.data.u32 = timer->det_ident;

This should correctly initialise all bytes of the union, and silence this warning. I'll double-check this by recompiling Swift and confirming that this fixes up the assembly, and that this no longer annoys valgrind, and then open a new PR.

@MadCoder MadCoder reopened this Dec 4, 2017
@MadCoder
Copy link
Contributor

MadCoder commented Dec 4, 2017

Ok, this makes more sense, I like the code the way you just wrote it. I reopened the pull request, please make this patch instead.

@MadCoder
Copy link
Contributor

MadCoder commented Dec 4, 2017

actually there's even simpler, which is to use u64 instead in the dispatch codebase, given that it's the larger member of the union, it'll DTRT.

@Lukasa
Copy link
Contributor Author

Lukasa commented Dec 4, 2017

Yup, that fix works. I'll open a new PR.

@MadCoder
Copy link
Contributor

MadCoder commented Dec 4, 2017

you can reuse this one and force push it should work. (I think).

@Lukasa Lukasa mentioned this pull request Dec 4, 2017
@MadCoder MadCoder closed this Dec 4, 2017
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Development

Successfully merging this pull request may close these issues.

2 participants