I am using urn on 32-bit Linux and have noticed some randomly occurring problems with the timer suddenly jumping to a very large negative value.
I believe the culprit is in urn_time_now() in urn.c:
long long urn_time_now(void) {
struct timespec timespec;
clock_gettime(CLOCK_MONOTONIC, ×pec);
return timespec.tv_sec * 1000000L + timespec.tv_nsec / 1000;
}
The issue is that generally on a 32-bit platform sizeof(long) == 32, so the use of 1000000L can cause an overflow. This can be fixed by always using 1000000LL when returning a long long. This overflow doesn't occur on 64-bit systems because generally sizeof(long) == sizeof(long long) on 64-bit.
How to reproduce
Below is a concrete example of an overflow. On Linux the time returned from clock_gettime(CLOCK_MONOTONIC,...) is based on system uptime. The following code hardcodes specific time values that cause an overflow. It calls urn_time_now() twice, 1 second apart, then subtracts the times.
The first is used in a comparison against a long long, the second is the issue already mentioned, and the last one is in urn_time_value() where the return value is long long. So I think all three should be 1000000LL to avoid bugs on 32-bit systems.
Thanks for the great timer, hope you found this helpful :).
Issue
Hi,
I am using urn on 32-bit Linux and have noticed some randomly occurring problems with the timer suddenly jumping to a very large negative value.
I believe the culprit is in urn_time_now() in urn.c:
The issue is that generally on a 32-bit platform
sizeof(long) == 32
, so the use of1000000L
can cause an overflow. This can be fixed by always using1000000LL
when returning a long long. This overflow doesn't occur on 64-bit systems because generallysizeof(long) == sizeof(long long)
on 64-bit.How to reproduce
Below is a concrete example of an overflow. On Linux the time returned from
clock_gettime(CLOCK_MONOTONIC,...)
is based on system uptime. The following code hardcodes specific time values that cause an overflow. It callsurn_time_now()
twice, 1 second apart, then subtracts the times.When run on a 32 bit system:
Other potential issues
There are other uses of
1000000L
that might have potential overflow issues:The first is used in a comparison against a
long long
, the second is the issue already mentioned, and the last one is inurn_time_value()
where the return value islong long
. So I think all three should be1000000LL
to avoid bugs on 32-bit systems.Thanks for the great timer, hope you found this helpful :).