-
-
Notifications
You must be signed in to change notification settings - Fork 16
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
IO::Event::Interrupt#signal
mangles errno
#127
Comments
Thanks for pointing this out. As an aside, I strongly dislike having a write lock in the IO object. My general feeling is operations that require
Or even better, we follow the pattern using negative error codes:
Because of the reasons you mention, most of the new IO code uses the latter pattern, e.g.: https://github.com/ruby/ruby/blob/5f3d1eeb55ec69591e76633346d8a4812d3cc36b/io_buffer.c#L2782 I think as you said, saving and restoring the I think the best solution is to ensure I need to review the code in more detail to see the impact. |
For some reason, your fix does not resolve the issue for me: VALUE
rb_fiber_scheduler_unblock(VALUE scheduler, VALUE blocker, VALUE fiber)
{
RUBY_ASSERT(rb_obj_is_fiber(fiber));
int saved_errno = errno;
VALUE result = rb_funcall(scheduler, id_unblock, 2, blocker, fiber);
fprintf(stderr, "Restoring errno: %d -> %d\n", errno, saved_errno);
errno = saved_errno;
return result;
} And the output:
Am I missing something? |
Cross referencing socketry/async#368 |
@ioquatix sorry for any confusion. There are two issues:
As far as I can tell these two issues are unrelated, except that the same repro test case happens to trigger both (one more reliably than the other.) Does this make sense? |
Yes, that clarifies the situation, thanks! |
IO::Event::Interrupt#signal
overwriteserrno
which can cause havoc, including VM-level errors such as this one.The patch below (against Ruby master) fixes that particular error, however I'm not sure it's the correct general fix - it seems too narrow. Ideally similar code would be used in the
signal
implementation directly, and in any other functions where errno could be corrupted unexpectedly.To reproduce, use this repo and run the following command a few times:
Sooner or later you should hit the case where
io_binwrite
usesrb_mutex_synchronize
here with a scheduler set, while returning -1 because the socket isECONNREFUSED
.In this case
rb_mutex_synchronize
usesrb_fiber_scheduler_unblock
, which due to the mangling bysignal
will reset errno to zero, which Ruby doesn't like whenio_binwrite
returns -1:rb_sys_fail_on_write
ends up invokingrb_bug
in that situation.The text was updated successfully, but these errors were encountered: