zdump loop problem
Robbin Kawabata
Robbin.Kawabata at sun.com
Mon Nov 24 16:36:15 UTC 2008
This sounds like a problem we encountered too.
zdump.c uses behavior of integer overflow on L.358 to detect when newt
has reached or exceeded the maximum time_t value. When newt exceeds the
maximum time_t value from L.356, it overflows to a negative number, so
the L.358 check for newt less than t succeeds.
However according to the C Standard, the behavior of integer overflow is
undefined (see below). The Sun Studio 11 compiler with -O flag optimizes
L.358 out, because it detects the check is not needed, because for the
valid range of time_t, newt will never be > t, since from L.355 newt is t
plus a positive number. With L.358 optimized out, the for loop at L.352
executes infinitely.
zdump.c:
...
249 time_t t;
250 time_t newt;
...
352 for ( ; ; ) {
353 if (t >= cuthitime)
354 break;
355 newt = t + SECSPERHOUR * 12; <--
356 if (newt >= cuthitime)
357 break;
358 if (newt <= t) <--
359 break;
360 newtmp = localtime(&newt);
...
376 t = newt;
377 tm = newtm;
378 tmp = newtmp;
379 }
A possible fix is to instead check whether t plus delta (delta =
SECSPERHOUR * 12) is greater than the maximum time_t:
(time + delta) > max_time_t
or:
time > max_time_t - delta /* avoids time+delta overflow */
------- zdump.c -------
@@ -314,11 +314,12 @@
for (;;) {
if (t >= cuthitime)
break;
+ /* check if newt will overrun maximum time_t value */
+ if (t > LONG_MAX - (SECSPERHOUR * 12))
+ break;
newt = t + SECSPERHOUR * 12;
if (newt >= cuthitime)
break;
- if (newt <= t)
- break;
newtmp = localtime(&newt);
if (newtmp != NULL)
newtm = *newtmp;
The C Standard says (for signed integer):
ISO/IEC 9899:1999:
6.5 p5:
If an exceptional condition occurs during the evaluation of an
expression (that is, if the result is not mathematically defined or not
in the range of representable values for its type), the behavior is
undefined.
3.4.3 p3:
EXAMPLE: An example of undefined behavior is the behavior on integer
overflow.
> Date: Mon, 24 Nov 2008 09:09:13 -0500
> From: "Olson, Arthur David (NIH/NCI) [E]" <olsona at dc37a.nci.nih.gov>
> Subject: FW: mail to tz list bounced
> To: tz at lecserver.nci.nih.gov
> Cc: Andreas Radke <a.radke at arcor.de>
>
> I'm forwarding this message from Andreas Radke; while Andreas is on the
> time zone mailing list, the message bounced when he tried to send it
> directly.
>
> --ado
>
> Datum: Wed, 19 Nov 2008 21:47:05 +0100
> Von: Andreas Radke <a.radke at arcor.de>
> An: tz at lecserver.nci.nih.gov
> Betreff: optimization -O2 broken?
>
> I'm the ArchLinux package maintainer for tzdata. We are using gcc
> 4.3.2/glibc2.8- We have run into a small problem with compiler
> optimizations.
>
> Using our default CFLAGS="-march=i686 -mtune=generic -O2 -pipe" the
> zdump binary is built in broken way on i686 architecture. I have to
> apply -O1 to make zdump work. See our bugreport:
> http://bugs.archlinux.org/task/11947
>
> I could confirm this when running zdump -v EUROPE/BERLIN it stuck after
> two printing first two lines.
>
> x86_64 architecture doesn't seem to be affected. Any idea why this
> happens and how to fix it?
>
> -Andy
>
More information about the tz
mailing list