summaryrefslogtreecommitdiff
path: root/src/file.c
diff options
context:
space:
mode:
authorPaul Smith <psmith@gnu.org>2023-03-26 15:35:00 -0400
committerPaul Smith <psmith@gnu.org>2023-04-01 11:13:12 -0400
commit9db74434cd34b2b875b3f9bfbab4f1e0b682e27c (patch)
treeb488a9766c9e1a932518fd6e4e1db25ae6b788b5 /src/file.c
parent23f70b0cb86208d3b9b47b0efa9707a1dac5360b (diff)
downloadmake-git-9db74434cd34b2b875b3f9bfbab4f1e0b682e27c.tar.gz
Clean up memory leak warnings from ASAN and Valgrind
* src/main.c (main): Add "sanitize" to .FEATURES if ASAN is enabled. * src/expand.c (expand_variable_output): Remember "recursive" setting in case it's changed by the expansion of the variable. * src/file.c (rehash_file): If we drop a file from the global 'files' hash, remember it in rehashed_files. We can't free it because it's still being referenced (callers will invoke check_renamed()) but it will be a leak since it's no longer referenced by 'files'. * src/remake.c (update_file_1): If we drop a dependency, remember it in dropped_list. We can't free it because it's still being referenced by callers but it will be a leak since it's no longer referenced as a prerequisite. * tests/scripts/functions/guile: Don't run Guile tests when ASAN is enabled. * tests/scripts/functions/wildcard: Enabling ASAN causes glob(3) to break! Don't run this test. * tests/scripts/features/exec: Valgrind's exec() doesn't support scripts with no shbang. * tests/scripts/jobserver: Valgrind fails if TMPDIR is set to an invalid directory: skip those tests. * tests/scripts/features/output-sync: Ditto. * tests/scripts/features/temp_stdin: Ditto.
Diffstat (limited to 'src/file.c')
-rw-r--r--src/file.c17
1 files changed, 15 insertions, 2 deletions
diff --git a/src/file.c b/src/file.c
index 9828d283..f8e4fb91 100644
--- a/src/file.c
+++ b/src/file.c
@@ -60,6 +60,14 @@ file_hash_cmp (const void *x, const void *y)
static struct hash_table files;
+/* We can't free files we take out of the hash table, because they are still
+ likely pointed to in various places. The check_renamed() will be used if
+ we come across these, to find the new correct file. This is mainly to
+ prevent leak checkers from complaining. */
+static struct file **rehashed_files = NULL;
+static size_t rehashed_files_len = 0;
+#define REHASHED_FILES_INCR 5
+
/* Whether or not .SECONDARY with no prerequisites was given. */
static int all_secondary = 0;
@@ -217,8 +225,7 @@ rehash_file (struct file *from_file, const char *to_hname)
/* Find the end of the renamed list for the "from" file. */
file_key.hname = from_file->hname;
- while (from_file->renamed != 0)
- from_file = from_file->renamed;
+ check_renamed (from_file);
if (file_hash_cmp (from_file, &file_key))
/* hname changed unexpectedly!! */
abort ();
@@ -331,6 +338,12 @@ rehash_file (struct file *from_file, const char *to_hname)
to_file->builtin = 0;
from_file->renamed = to_file;
+
+ if (rehashed_files_len % REHASHED_FILES_INCR == 0)
+ rehashed_files = xrealloc (rehashed_files,
+ sizeof (struct file *) * (rehashed_files_len + REHASHED_FILES_INCR));
+
+ rehashed_files[rehashed_files_len++] = from_file;
}
/* Rename FILE to NAME. This is not as simple as resetting