In some unusual, timing-dependent cases on some platforms, 'make -p' can generate output that incorrectly makes it look like the system clock ran backwards, when it didn't.

Also, there's a torture-test case (system clock in the far past or future) where 'make -p' can dump core.

Proposed patch attached.
From 2e6355c4f3813c346ded2a90997a4308114d2893 Mon Sep 17 00:00:00 2001
From: Paul Eggert <egg...@cs.ucla.edu>
Date: Sun, 19 Mar 2023 14:40:39 -0700
Subject: [PATCH] Fix clock skew / crash issue with 'make -p'

* NEWS: Mention this.
* src/main.c (print_data_base): Use file_timestamp_sprintf
instead of time+ctime, to avoid inconsistent clocks.  See:
https://www.gnu.org/software/gnulib/manual/html_node/time.html
https://sourceware.org/bugzilla/show_bug.cgi?id=30200
This avoids output that incorrectly implies that the clock ran backwards.
Avoiding ctime also means 'make' won't have undefined behavior
if ctime crashes or returns a null pointer, which can happen if
the system clock is set far in the past or future.
---
 NEWS       |  5 +++++
 src/main.c | 10 ++++++----
 2 files changed, 11 insertions(+), 4 deletions(-)

diff --git a/NEWS b/NEWS
index 4ab15136..dcce8d93 100644
--- a/NEWS
+++ b/NEWS
@@ -9,6 +9,11 @@ which is contained in this distribution as the file doc/make.texi.
 See the README file and the GNU Make manual for instructions for
 reporting bugs.
 
+* 'make --print-data-base' (or 'make -p') now outputs more-consistent
+  timestamps, e.g., "2023-03-19 14:23:42.570558743".  Previously it
+  sometimes also used the form "Sun Mar 19 14:23:42 2023", and
+  sometimes used a clock that ticked slightly inconsistently.
+
 
 Version 4.4.1 (26 Feb 2023)
 
diff --git a/src/main.c b/src/main.c
index a9d3a644..2a02e399 100644
--- a/src/main.c
+++ b/src/main.c
@@ -3744,11 +3744,13 @@ print_version (void)
 static void
 print_data_base (void)
 {
-  time_t when = time ((time_t *) 0);
+  int resolution;
+  char buf[FILE_TIMESTAMP_PRINT_LEN_BOUND + 1];
+  file_timestamp_sprintf (buf, file_timestamp_now (&resolution));
 
   print_version ();
 
-  printf (_("\n# Make data base, printed on %s"), ctime (&when));
+  printf (_("\n# Make data base, printed on %s"), buf);
 
   print_variable_data_base ();
   print_dir_data_base ();
@@ -3757,8 +3759,8 @@ print_data_base (void)
   print_vpath_data_base ();
   strcache_print_stats ("#");
 
-  when = time ((time_t *) 0);
-  printf (_("\n# Finished Make data base on %s\n"), ctime (&when));
+  file_timestamp_sprintf (buf, file_timestamp_now (&resolution));
+  printf (_("\n# Finished Make data base on %s\n"), buf);
 }
 
 static void
-- 
2.37.2

Reply via email to