]> git.ipfire.org Git - thirdparty/ccache.git/commitdiff
feat: Include timestamp in per-object debug filenames
authorJoel Rosdahl <joel@rosdahl.net>
Sat, 11 Jun 2022 12:13:02 +0000 (14:13 +0200)
committerJoel Rosdahl <joel@rosdahl.net>
Sat, 11 Jun 2022 13:45:33 +0000 (15:45 +0200)
Including a timestamp in the filenames makes it easier to compare two
builds without having to save previous debug files before the second
build. It also makes sure debug files won't be overwritten if an object
file is compiled several times during one build.

doc/MANUAL.adoc
src/Context.cpp
src/Context.hpp
src/ccache.cpp
test/suites/base.bash
test/suites/fileclone.bash
test/suites/inode_cache.bash
test/suites/multi_arch.bash
test/suites/secondary_http.bash
test/suites/secondary_redis.bash

index 248d654599500d0198d90e0082586ba2d9afeeeb..9df93220497cde833c1418d33e7422e735da5a63 100644 (file)
@@ -1557,23 +1557,26 @@ next to the object file:
 |==============================================================================
 | *Filename* | *Description*
 
-| `<objectfile>.ccache-input-c` |
+| `<objectfile>.<timestamp>.ccache-input-c` |
 Binary input hashed by both the direct mode and the preprocessor mode.
 
-| `<objectfile>.ccache-input-d` |
+| `<objectfile>.<timestamp>.ccache-input-d` |
 Binary input only hashed by the direct mode.
 
-| `<objectfile>.ccache-input-p` |
+| `<objectfile>.<timestamp>.ccache-input-p` |
 Binary input only hashed by the preprocessor mode.
 
-| `<objectfile>.ccache-input-text` |
+| `<objectfile>.<timestamp>.ccache-input-text` |
 Human-readable combined diffable text version of the three files above.
 
-| `<objectfile>.ccache-log` |
+| `<objectfile>.<timestamp>.ccache-log` |
 Log for this object file.
 
 |==============================================================================
 
+ The timestamp format is
+`<year><month><day>_<hour><minute><second>_<microsecond>`.
+
 If <<config_debug_dir,*debug_dir*>> (environment variable `CCACHE_DEBUGDIR`) is
 set, the files above will be written to that directory with full absolute paths
 instead of next to the object file.
@@ -1591,12 +1594,12 @@ data comes next.
 To debug why you don't get an expected cache hit for an object file, you can do
 something like this:
 
-1. Build with debug mode enabled.
-2. Save the `<objectfile>.ccache-++*++` files.
-3. Build again with debug mode enabled.
-4. Compare `<objectfile>.ccache-input-text` for the two builds. This together
-   with the `<objectfile>.ccache-log` files should give you some clues about
-   what is happening.
+1. Enable `debug` (`CCACHE_DEBUG`).
+2. Build.
+3. Clean and build again.
+4. Compare the `<objectfile>.<timestamp>.ccache-input-text` files for the two
+   builds. This together with the `<objectfile>.<timestamp>.ccache-log` files
+   should give you some clues about what is happening.
 
 
 == Compiling in different directories
index 3b0628c287b29c797cd8a4d6071222a9716b65c7..27a2a2c98d0e4d45c37b9ac9f5221523d220f05a 100644 (file)
 #include "Util.hpp"
 #include "hashutil.hpp"
 
+#include <Win32Util.hpp>
 #include <core/wincompat.hpp>
 #include <util/path.hpp>
 
+#ifdef HAVE_SYS_TIME_H
+#  include <sys/time.h>
+#endif
 #ifdef HAVE_UNISTD_H
 #  include <unistd.h>
 #endif
@@ -43,6 +47,7 @@ Context::Context()
     inode_cache(config)
 #endif
 {
+  gettimeofday(&time_of_invocation, nullptr);
 }
 
 void
index c2861f76b09cf5d302cdc62fd0a0828d8f6f0d10..af1be6503f21e7dc859c688e29d4504d33348c1c 100644 (file)
 #include <unordered_map>
 #include <vector>
 
+#ifdef HAVE_SYS_TIME_H
+#  include <sys/time.h>
+#endif
+
 class SignalHandler;
 
 class Context : NonCopyable
@@ -63,6 +67,9 @@ public:
   // The original argument list.
   Args orig_args;
 
+  // Time of ccache invocation.
+  timeval time_of_invocation;
+
   // Time of compilation. Used to see if include files have changed after
   // compilation.
   time_t time_of_compilation = 0;
index f1f5f060925a98deb372becc159ccf52a1e50aec..ea841da688b47429dc9aab02b9aa5275f7cec45c 100644 (file)
@@ -69,6 +69,9 @@
 #include <optional>
 #include <string_view>
 
+#ifdef HAVE_SYS_TIME_H
+#  include <sys/time.h>
+#endif
 #ifdef HAVE_UNISTD_H
 #  include <unistd.h>
 #endif
@@ -162,6 +165,7 @@ add_prefix(const Context& ctx, Args& args, const std::string& prefix_command)
 
 static std::string
 prepare_debug_path(const std::string& debug_dir,
+                   const timeval& time_of_invocation,
                    const std::string& output_obj,
                    std::string_view suffix)
 {
@@ -172,7 +176,22 @@ prepare_debug_path(const std::string& debug_dir,
     // Ignore since we can't handle an error in another way in this context. The
     // caller takes care of logging when trying to open the path for writing.
   }
-  return FMT("{}.ccache-{}", prefix, suffix);
+
+  char timestamp[100];
+  const auto tm = Util::localtime(time_of_invocation.tv_sec);
+  if (tm) {
+    strftime(timestamp, sizeof(timestamp), "%Y%m%d_%H%M%S", &*tm);
+  } else {
+    snprintf(timestamp,
+             sizeof(timestamp),
+             "%llu",
+             static_cast<long long unsigned int>(time_of_invocation.tv_sec));
+  }
+  return FMT("{}.{}_{:06}.ccache-{}",
+             prefix,
+             timestamp,
+             time_of_invocation.tv_usec,
+             suffix);
 }
 
 static void
@@ -186,8 +205,10 @@ init_hash_debug(Context& ctx,
     return;
   }
 
-  const auto path = prepare_debug_path(
-    ctx.config.debug_dir(), ctx.args_info.output_obj, FMT("input-{}", type));
+  const auto path = prepare_debug_path(ctx.config.debug_dir(),
+                                       ctx.time_of_invocation,
+                                       ctx.args_info.output_obj,
+                                       FMT("input-{}", type));
   File debug_binary_file(path, "wb");
   if (debug_binary_file) {
     hash.enable_debug(section_name, debug_binary_file.get(), debug_text_file);
@@ -2044,8 +2065,10 @@ finalize_at_exit(Context& ctx)
 
   // Dump log buffer last to not lose any logs.
   if (ctx.config.debug() && !ctx.args_info.output_obj.empty()) {
-    Logging::dump_log(prepare_debug_path(
-      ctx.config.debug_dir(), ctx.args_info.output_obj, "log"));
+    Logging::dump_log(prepare_debug_path(ctx.config.debug_dir(),
+                                         ctx.time_of_invocation,
+                                         ctx.args_info.output_obj,
+                                         "log"));
   }
 }
 
@@ -2225,8 +2248,10 @@ do_cache_compilation(Context& ctx, const char* const* argv)
   MTR_META_THREAD_NAME(ctx.args_info.output_obj.c_str());
 
   if (ctx.config.debug()) {
-    const auto path = prepare_debug_path(
-      ctx.config.debug_dir(), ctx.args_info.output_obj, "input-text");
+    const auto path = prepare_debug_path(ctx.config.debug_dir(),
+                                         ctx.time_of_invocation,
+                                         ctx.args_info.output_obj,
+                                         "input-text");
     File debug_text_file(path, "w");
     if (debug_text_file) {
       ctx.hash_debug_files.push_back(std::move(debug_text_file));
index 754649d1c6d570c470c908789a88b07ebb4c93fd..bb0644a62ebc3455b368b92e57900c9e65422974 100644 (file)
@@ -345,14 +345,14 @@ fi
     unset CCACHE_LOGFILE
     unset CCACHE_NODIRECT
     CCACHE_DEBUG=1 $CCACHE_COMPILE -c test1.c
-    if ! grep -q Result: test1.o.ccache-log; then
+    if ! grep -q Result: test1.o.*.ccache-log; then
         test_failed "Unexpected data in <obj>.ccache-log"
     fi
-    if ! grep -q "PREPROCESSOR MODE" test1.o.ccache-input-text; then
-        test_failed "Unexpected data in <obj>.ccache-input-text"
+    if ! grep -q "PREPROCESSOR MODE" test1.o.*.ccache-input-text; then
+        test_failed "Unexpected data in <obj>.<timestamp>.ccache-input-text"
     fi
     for ext in c p d; do
-        if ! [ -f test1.o.ccache-input-$ext ]; then
+        if ! [ -f test1.o.*.ccache-input-$ext ]; then
             test_failed "<obj>.ccache-input-$ext missing"
         fi
     done
@@ -362,13 +362,13 @@ fi
 
     CCACHE_DEBUG=1 $CCACHE_COMPILE -c test1.c -save-temps
     expect_stat unsupported_compiler_option 1
-    expect_exists test1.o.ccache-log
+    expect_exists test1.o.*.ccache-log
 
     # -------------------------------------------------------------------------
     TEST "CCACHE_DEBUGDIR"
 
     CCACHE_DEBUG=1 CCACHE_DEBUGDIR=debugdir $CCACHE_COMPILE -c test1.c
-    expect_contains debugdir"$(pwd -P)"/test1.o.ccache-log "Result: cache_miss"
+    expect_contains debugdir"$(pwd -P)"/test1.o.*.ccache-log "Result: cache_miss"
 
     # -------------------------------------------------------------------------
     TEST "CCACHE_DISABLE"
@@ -849,15 +849,15 @@ EOF
     chmod +x gcc
 
     CCACHE_DEBUG=1 $CCACHE ./gcc -c test1.c
-    compiler_type=$(sed -En 's/.*Compiler type: (.*)/\1/p' test1.o.ccache-log)
+    compiler_type=$(sed -En 's/.*Compiler type: (.*)/\1/p' test1.o.*.ccache-log)
     if [ "$compiler_type" != gcc ]; then
         test_failed "Compiler type $compiler_type != gcc"
     fi
 
-    rm test1.o.ccache-log
+    rm test1.o.*.ccache-log
 
     CCACHE_COMPILERTYPE=clang CCACHE_DEBUG=1 $CCACHE ./gcc -c test1.c
-    compiler_type=$(sed -En 's/.*Compiler type: (.*)/\1/p' test1.o.ccache-log)
+    compiler_type=$(sed -En 's/.*Compiler type: (.*)/\1/p' test1.o.*.ccache-log)
     if [ "$compiler_type" != clang ]; then
         test_failed "Compiler type $compiler_type != clang"
     fi
index 25aec4d7cd62f7a23d19d7fb944e2dd1aa65aadb..833cafffea5113743c3f2a7bba7ebef78550564d 100644 (file)
@@ -25,10 +25,10 @@ SUITE_fileclone() {
     expect_stat cache_miss 1
     expect_stat files_in_cache 2
     expect_equal_object_files reference_test.o test.o
-    if ! grep -q 'Cloning.*to test.o' test.o.ccache-log; then
+    if ! grep -q 'Cloning.*to test.o' test.o.*.ccache-log; then
         test_failed "Did not try to clone file"
     fi
-    if grep -q 'Failed to clone' test.o.ccache-log; then
+    if grep -q 'Failed to clone' test.o.*.ccache-log; then
         test_failed "Failed to clone"
     fi
 
@@ -51,7 +51,7 @@ SUITE_fileclone() {
     expect_stat cache_miss 1
     expect_stat files_in_cache 1
     expect_equal_object_files reference_test.o test.o
-    if grep -q 'Cloning' test.o.ccache-log; then
+    if grep -q 'Cloning' test.o.*.ccache-log; then
         test_failed "Tried to clone"
     fi
 }
index 60563665b7219992dbfac6e91902385c85353cba..f57659aea51e865ff183e0b3cb466fd6f61c1929 100644 (file)
@@ -26,8 +26,7 @@ expect_inode_cache_type() {
     local source_file=$2
     local type=$3
 
-    local log_file=$(echo $source_file | sed 's/\.c$/.o.ccache-log/')
-    local actual=$(grep -c "inode cache $type: $source_file" "$log_file")
+    local actual=$(grep -c "inode cache $type: $source_file" ${source_file/%.c/.o}.*.ccache-log)
     if [ $actual -ne $expected ]; then
         test_failed_internal "Found $actual (expected $expected) $type for $source_file"
     fi
@@ -53,6 +52,8 @@ inode_cache_tests() {
     echo "// recompile" > test1.c
     $CCACHE_COMPILE -c test1.c
     expect_inode_cache 0 1 1 test1.c
+    rm *.ccache-*
+
     $CCACHE_COMPILE -c test1.c
     expect_inode_cache 1 0 0 test1.c
 
@@ -62,6 +63,7 @@ inode_cache_tests() {
     echo "// backdate" > test1.c
     $CCACHE_COMPILE -c test1.c
     expect_inode_cache 0 1 1 test1.c
+    rm *.ccache-*
 
     backdate test1.c
     $CCACHE_COMPILE -c test1.c
@@ -93,6 +95,7 @@ inode_cache_tests() {
     echo "// replace" > test1.c
     $CCACHE_COMPILE -c test1.c
     expect_inode_cache 0 1 1 test1.c
+    rm *.ccache-*
 
     rm test1.c
     echo "// replace" > test1.c
index 9a705cd3ec092d7e6681c898cc37e47c33d09428..f3af74f78df0bdd59f254321f547384fa728497a 100644 (file)
@@ -40,8 +40,8 @@ SUITE_multi_arch() {
     CCACHE_DEBUG=1 $CCACHE_COMPILE -arch x86_64 -Xarch_x86_64 -I. -c test1.c
     expect_stat direct_cache_hit 2
     expect_stat cache_miss 4
-    expect_contains     test1.o.ccache-log "clang -Xarch_x86_64 -I. -arch x86_64 -E test1.c"
-    expect_not_contains test1.o.ccache-log "clang -Xarch_x86_64 -I. -I. -arch x86_64 -E test1.c"
+    expect_contains     test1.o.*.ccache-log "clang -Xarch_x86_64 -I. -arch x86_64 -E test1.c"
+    expect_not_contains test1.o.*.ccache-log "clang -Xarch_x86_64 -I. -I. -arch x86_64 -E test1.c"
 
     $CCACHE_COMPILE -arch x86_64 -Xarch_x86_64 -I. -c test1.c
     expect_stat direct_cache_hit 3
index 25c793909f1acd10750184d04c00eaaf1d1cc904..825b290fabbea671720fa083907af953fde0b858 100644 (file)
@@ -146,7 +146,7 @@ SUITE_secondary_http() {
     expect_stat cache_miss 1
     expect_stat files_in_cache 2
     expect_file_count 2 '*' secondary # result + manifest
-    expect_not_contains test.o.ccache-log secret123
+    expect_not_contains test.o.*.ccache-log secret123
 
     # -------------------------------------------------------------------------
     TEST "Basic auth required"
@@ -160,7 +160,7 @@ SUITE_secondary_http() {
     expect_stat cache_miss 1
     expect_stat files_in_cache 2
     expect_file_count 0 '*' secondary # result + manifest
-    expect_contains test.o.ccache-log "status code: 401"
+    expect_contains test.o.*.ccache-log "status code: 401"
 
     # -------------------------------------------------------------------------
     TEST "Basic auth failed"
@@ -173,8 +173,8 @@ SUITE_secondary_http() {
     expect_stat cache_miss 1
     expect_stat files_in_cache 2
     expect_file_count 0 '*' secondary # result + manifest
-    expect_not_contains test.o.ccache-log secret123
-    expect_contains test.o.ccache-log "status code: 401"
+    expect_not_contains test.o.*.ccache-log secret123
+    expect_contains test.o.*.ccache-log "status code: 401"
 
      # -------------------------------------------------------------------------
     TEST "IPv6 address"
index e8cc1324f726f1ed1fe4d174d27872bb2b069c79..4033b314a96ae7ed8f1630c1d78876e832349da6 100644 (file)
@@ -94,7 +94,7 @@ SUITE_secondary_redis() {
     expect_stat cache_miss 1
     expect_stat files_in_cache 2
     expect_number_of_redis_cache_entries 2 "$redis_url" # result + manifest
-    expect_not_contains test.o.ccache-log "${password}"
+    expect_not_contains test.o.*.ccache-log "${password}"
 
     $CCACHE_COMPILE -c test.c
     expect_stat direct_cache_hit 1