unofficial mirror of bug-guix@gnu.org 
 help / color / mirror / code / Atom feed
From: Mark H Weaver <mhw@netris.org>
To: "Ludovic Courtès" <ludo@gnu.org>, 38958@debbugs.gnu.org
Subject: bug#38958: Timestamp out of range; substituting 2514-05-30 01:53:03.999999999
Date: Thu, 03 Sep 2020 15:42:02 -0400	[thread overview]
Message-ID: <87y2lq3avu.fsf@netris.org> (raw)
In-Reply-To: <87lfhr1bra.fsf@gnu.org>

Hi,

Ludovic Courtès <ludo@gnu.org> writes:

> The GNU make warnings come from this impenetrable function:
>
> --8<---------------cut here---------------start------------->8---
> FILE_TIMESTAMP
> file_timestamp_cons (const char *fname, time_t stamp, long int ns)
> {
>   int offset = ORDINARY_MTIME_MIN + (FILE_TIMESTAMP_HI_RES ? ns : 0);
>   FILE_TIMESTAMP s = stamp;
>   FILE_TIMESTAMP product = (FILE_TIMESTAMP) s << FILE_TIMESTAMP_LO_BITS;
>   FILE_TIMESTAMP ts = product + offset;
>
>   if (! (s <= FILE_TIMESTAMP_S (ORDINARY_MTIME_MAX)
>          && product <= ts && ts <= ORDINARY_MTIME_MAX))
>     {
>       char buf[FILE_TIMESTAMP_PRINT_LEN_BOUND + 1];
>       const char *f = fname ? fname : _("Current time");
>       ts = s <= OLD_MTIME ? ORDINARY_MTIME_MIN : ORDINARY_MTIME_MAX;
>       file_timestamp_sprintf (buf, ts);
>       OSS (error, NILF,
>            _("%s: Timestamp out of range; substituting %s"), f, buf);
>     }
>
>   return ts;
> }
> --8<---------------cut here---------------end--------------->8---
>
> What’s OLD_MTIME?
>
> --8<---------------cut here---------------start------------->8---
> /* The file does not exist, and we assume that it is older than any
>    actual file.  */
> #define OLD_MTIME 2
>
> /* The smallest and largest ordinary timestamps.  */
> #define ORDINARY_MTIME_MIN (OLD_MTIME + 1)
> --8<---------------cut here---------------end--------------->8---
>
> That would mean that any file with mtime < 3 is considered bogus, but
> then, why wouldn’t things fail on other machines as well?

I spent a bit of time looking at the relevant code in GNU Make.  The
special MTIME values of 0, 1, and 2 seem to apply only to GNU Make's
*internal* representation of the timestamp.  'file_timestamp_cons',
which converts a standard POSIX time to the internal representation,
seems to properly handle times near the POSIX epoch by adding
ORDINARY_MTIME_MIN (via 'offset') to the POSIX time, after multiplying
it by 2^30 (if FILE_TIMESTAMP_HI_RES is enabled).

> I’m looking for ideas!  :-)

Note that the date printed in the warning (ORDINARY_MTIME_MAX),
represented as a POSIX time (seconds past the epoch), is precisely 2^34
seconds minus one nanosecond.

The problem doesn't seem to be that 'stamp' is too small, because if it
were, then the following line in 'file_timestamp_cons',

    ts = s <= OLD_MTIME ? ORDINARY_MTIME_MIN : ORDINARY_MTIME_MAX;

would substitute ORDINARY_MTIME_MIN, which is close to the POSIX epoch,
and the warning message would print a time near 1970, instead of one
near 2514 (ORDINARY_MTIME_MAX).

Rather, it appears that the 'stamp' passed into 'file_timestamp_cons'
was close to or larger than 2^34, which is approximately the largest
timestamp that GNU make supports when FILE_TIMESTAMP is 64 bits and
FILE_TIMESTAMP_HI_RES is enabled.

My guess is that maybe our near-zero timestamps are somewhere being
adjusted downwards by a timezone conversion, using an unsigned integer
type, causing them to wrap around to near the maximum value of that
type.

Note that although 'stamp' usually comes from a file 'mtime' as returned
by stat(2), it can also come from an 'ar' archive member.  In
make-4.3/src/remake.c, 'f_mtime' includes the following code:

--8<---------------cut here---------------start------------->8---
      member_date = ar_member_date (file->hname);
      mtime = (member_date == (time_t) -1
               ? NONEXISTENT_MTIME
               : file_timestamp_cons (file->hname, member_date, 0));
--8<---------------cut here---------------end--------------->8---

      Mark




      reply	other threads:[~2020-09-03 19:44 UTC|newest]

Thread overview: 6+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2020-01-05 20:45 bug#38958: Timestamp out of range; substituting 2514-05-30 01:53:03.999999999 Roel Janssen
2020-01-08 21:58 ` Ludovic Courtès
2020-03-27  9:26   ` Roel Janssen
2020-03-27 11:54     ` Ludovic Courtès
2020-09-03  8:54 ` Ludovic Courtès
2020-09-03 19:42   ` Mark H Weaver [this message]

Reply instructions:

You may reply publicly to this message via plain-text email
using any one of the following methods:

* Save the following mbox file, import it into your mail client,
  and reply-to-all from there: mbox

  Avoid top-posting and favor interleaved quoting:
  https://en.wikipedia.org/wiki/Posting_style#Interleaved_style

  List information: https://guix.gnu.org/

* Reply using the --to, --cc, and --in-reply-to
  switches of git-send-email(1):

  git send-email \
    --in-reply-to=87y2lq3avu.fsf@netris.org \
    --to=mhw@netris.org \
    --cc=38958@debbugs.gnu.org \
    --cc=ludo@gnu.org \
    /path/to/YOUR_REPLY

  https://kernel.org/pub/software/scm/git/docs/git-send-email.html

* If your mail client supports setting the In-Reply-To header
  via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line before the message body.
Code repositories for project(s) associated with this public inbox

	https://git.savannah.gnu.org/cgit/guix.git

This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for read-only IMAP folder(s) and NNTP newsgroup(s).