-
-
Notifications
You must be signed in to change notification settings - Fork 1.6k
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
Fix error handling for LibC.clock_gettime(CLOCK_MONOTONIC)
calls
#15309
Fix error handling for LibC.clock_gettime(CLOCK_MONOTONIC)
calls
#15309
Conversation
src/crystal/system/unix/time.cr
Outdated
@@ -51,7 +50,8 @@ module Crystal::System::Time | |||
info = mach_timebase_info | |||
LibC.mach_absolute_time &* info.numer // info.denom | |||
{% else %} | |||
LibC.clock_gettime(LibC::CLOCK_MONOTONIC, out tp) | |||
ret = LibC.clock_gettime(LibC::CLOCK_MONOTONIC, out tp) | |||
raise RuntimeError.from_errno("clock_gettime(CLOCK_MONOTONIC)") unless ret == 0 |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This specific method mustn't raise. It could make sure to initialize tp
to zero. That's fine.
I'm not sure we really need to check for errno. Reading the manage, it looks impossible to reach a failure (we do control all the values). |
That's good to know, thank you @ysbaddaden ! I've added a second commit to reduce the scope. This PR now only fixes the one explicitly incorrect return value check in I have not yet been able to consistently reproduce my
and we have these errors randomly every few weeks on our CI builds. (I've never been able to reproduce it on demand, locally or in CI, despite trying.) This made me take a closer look at the |
LibC.clock_gettime(CLOCK_MONOTONIC)
calls
@compumike It's an issue in timecop. |
POSIX
clock_gettime
returns 0 on success and -1 on error. See https://man7.org/linux/man-pages/man3/clock_gettime.3.html#RETURN_VALUEThe code for
Crystal::System::Time.compute_utc_seconds_and_nanoseconds
correctly does araise RuntimeError.from_errno(...) unless ret == 0
. However, the code forCrystal::System::Time.monotonic
incorrectly does araise ... if ret == 1
(checking for positive one return value, not a negative one!). So any errors will not be detected, and the uninitialized timespec struct will be used by the caller.This PR fixes this to make the
monotonic
return value checking logic be the same.(My context is that in 1.14.0 I am still occasionally seeing an unreproducible segfault in CI related to
Time.monotonic
https://forum.crystal-lang.org/t/how-to-diagnose-occasional-segfault-in-time-monotonic-within-timecop-travel/6099 and came across this as I was looking more closely at the code.)