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@dc37a.nci.nih.gov> Subject: FW: mail to tz list bounced To: tz@lecserver.nci.nih.gov Cc: Andreas Radke <a.radke@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@arcor.de> An: tz@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