From: Joel Rosdahl Date: Sat, 5 Dec 2009 13:09:21 +0000 (+0100) Subject: Correctly handle direct mode hit, missing object file and differing cpp hash X-Git-Tag: v3.0pre0~150 X-Git-Url: http://git.ipfire.org/gitweb.cgi?a=commitdiff_plain;h=9e167408cb535005466e8e13a656f53ba8990cd7;p=thirdparty%2Fccache.git Correctly handle direct mode hit, missing object file and differing cpp hash --- diff --git a/ccache.c b/ccache.c index 98926853b..ce78850b6 100644 --- a/ccache.c +++ b/ccache.c @@ -1402,6 +1402,7 @@ static void ccache(int argc, char *argv[]) time_t t; struct tm *tm; int put_object_in_manifest = 0; + struct file_hash *object_hash_from_manifest = NULL; t = time(NULL); tm = localtime(&t); @@ -1469,6 +1470,9 @@ static void ccache(int argc, char *argv[]) * so don't readd it later. */ put_object_in_manifest = 0; + + object_hash_from_manifest = object_hash; + object_hash = NULL; } else { /* Add object to manifest later. */ put_object_in_manifest = 1; @@ -1481,6 +1485,31 @@ static void ccache(int argc, char *argv[]) */ find_hash(stripped_args, FINDHASH_CPP_MODE); + if (object_hash_from_manifest + && !file_hashes_equal(object_hash_from_manifest, object_hash)) { + /* + * The hash from manifest differs from the hash of the + * preprocessor output. This could be because: + * + * - The preprocessor produces different output for the same + * input (not likely). + * - There's a bug in ccache (maybe incorrect handling of + * compiler arguments). + * - The user has used a different CCACHE_BASEDIR (most + * likely). + * + * The best thing here would probably be to remove the hash + * entry from the manifest. For now, we use a simpler method: + * just remove the manifest file. + */ + cc_log("Hash from manifest doesn't match preprocessor output\n"); + cc_log("Likely reason: different CCACHE_BASEDIRs used\n"); + cc_log("Removing manifest as a safety measure\n"); + unlink(manifest_path); + + put_object_in_manifest = 1; + } + /* if we can return from cache at this point then do */ from_cache(FROMCACHE_CPP_MODE, put_object_in_manifest); diff --git a/hashutil.c b/hashutil.c index 5989f769b..3e4921647 100644 --- a/hashutil.c +++ b/hashutil.c @@ -12,3 +12,9 @@ int strings_equal(void *str1, void *str2) { return strcmp((const char *)str1, (const char *)str2) == 0; } + +int file_hashes_equal(struct file_hash *fh1, struct file_hash *fh2) +{ + return memcmp(fh1->hash, fh2->hash, 16) == 0 + && fh1->size == fh2->size; +} diff --git a/hashutil.h b/hashutil.h index 2fdd63e2f..e562519ed 100644 --- a/hashutil.h +++ b/hashutil.h @@ -1,7 +1,16 @@ #ifndef HASHUTIL_H #define HASHUTIL_H +#include + +struct file_hash +{ + uint8_t hash[16]; + uint32_t size; +}; + unsigned int hash_from_string(void *str); int strings_equal(void *str1, void *str2); +int file_hashes_equal(struct file_hash *fh1, struct file_hash *fh2); #endif diff --git a/manifest.h b/manifest.h index b80014e8e..f6e9a4a63 100644 --- a/manifest.h +++ b/manifest.h @@ -1,15 +1,9 @@ #ifndef MANIFEST_H #define MANIFEST_H -#include +#include "hashutil.h" #include "hashtable.h" -struct file_hash -{ - uint8_t hash[16]; - uint32_t size; -}; - struct file_hash *manifest_get(const char *manifest_path); int manifest_put(const char *manifest_path, struct file_hash *object_hash, struct hashtable *included_files);