On 12/13/2009 11:10 PM, Kumar Appaiah wrote:
On Sun, Dec 13, 2009 at 10:57:24PM +0100, David Kubicek wrote:
This is the first time I've seen this, though, and I use strptime()
often in my SW, mostly for timestamps which would be discovered by
people rather quickly! :) Are you sure you're not using an alternative
impl. of libc?
Well, in Debian, we use eglibc:
http://packages.qa.debian.org/e/eglibc.html
http://www.eglibc.org/home
Yeah, I've heard about it, that's why I get my libc from Ubuntu since.
:) These are exactly the issues that were talked about.
You see this is not strptime() issue, right? To be portable, we *ought
to* set tm_isdst = -1 after, but here the issue comes from mktime
screwing up. It's about the *sequence* strptime() -> mktime().
Anyway, I've run this binary on 15 servers now and all worked fine
(RHEL4/5, SuSE, Debian). Each and every libc version I've tested it on
sets tm_isdst to -1. That means "DST not yet detected", if mktime() is
called later, it will know it has to detect DST itself. If your libc
*doesn't* do this for you, setting it to *0* pre-call is even worse. It
means "no DST" and mktime will not verify it. Only -1 is acceptable as
input to mktime, unless of course you check DST yourself and set 0/1 as
an informed action.
Well, let me add to your statement that we've been able to reproduce
this error ONLY on amd64 machines. I am also surprised at why this is
the case, and I'll dig into your advice above subsequently. However,
note this, from my mktime man page:
The mktime() function modifies the fields of the tm structure
as follows: tm_wday and tm_yday are set to values determined
from the contents of the other fields; if structure members are
outside their valid interval, they will be normalized (so that,
for example, 40 October is changed into 9 November); tm_isdst
is set (regardless of its initial value) to a positive value or
to 0, respectively, to indicate whether DST is or is not in
effect at the specified time. Calling mktime() also sets the
exter‐ nal variable tzname with information about the current
timezone.
See, this is crap. :) It means the bug is in libc (eglibc). It says it
disregards tm_isdst - whatever the value - but as you've tested
yourself, it didn't disregard it. Depending on the stack junk bytes left
in tm_isdst, it added DST one time, dind't the other.
Not only is eglibc broken with regards to its own documentation, it goes
against the standard too.
Quoting Single Unix Specification v3:
"A positive or 0 value for tm_isdst shall cause mktime() to presume
initially that Daylight Savings Time, respectively, is or is not in
effect for the specified time. A _negative_value_ for tm_isdst shall
cause mktime() to _attempt_to_determine_ whether Daylight Savings Time
is in effect for the specified time."
Eglibc says it attempts to determine DST in any case, but it doesn't. It
returns random junk.
This is what GNU libc has to say:
"The value specified in the tm_isdst field *informs* mktime() whether or
not daylight saving time (DST) is in effect for the time supplied in
the tm structure: a positive value means DST is in effect; zero means
that DST is not in effect; and a negative value means that mktime()
should (use timezone information and system databases to) attempt to
determine whether DST is in effect at the specified time."
See, that's correct according to SUSv3. GNU libc also sets tm_isdst to
-1 on return from strptime(), which works nicely with subsequent calls
to properly implemented mktime().
I do believe eglibc should fix their documentation or their code. I hate
how Debian turned us into guinea pigs with this crap!
--
David Kubicek
--
To UNSUBSCRIBE, email to debian-user-requ...@lists.debian.org
with a subject of "unsubscribe". Trouble? Contact listmas...@lists.debian.org