Module Name: src
Committed By: rillig
Date: Sat May 25 00:00:25 UTC 2024
Modified Files:
src/usr.bin/make: cond.c dir.c for.c make.c make.h parse.c targ.c
test-variants.mk var.c
Log Message:
make: fix a few more memory leaks
To generate a diff of this commit:
cvs rdiff -u -r1.363 -r1.364 src/usr.bin/make/cond.c
cvs rdiff -u -r1.291 -r1.292 src/usr.bin/make/dir.c
cvs rdiff -u -r1.179 -r1.180 src/usr.bin/make/for.c
cvs rdiff -u -r1.262 -r1.263 src/usr.bin/make/make.c
cvs rdiff -u -r1.333 -r1.334 src/usr.bin/make/make.h
cvs rdiff -u -r1.723 -r1.724 src/usr.bin/make/parse.c
cvs rdiff -u -r1.181 -r1.182 src/usr.bin/make/targ.c
cvs rdiff -u -r1.7 -r1.8 src/usr.bin/make/test-variants.mk
cvs rdiff -u -r1.1110 -r1.1111 src/usr.bin/make/var.c
Please note that diffs are not public domain; they are subject to the
copyright notices on the relevant files.
Modified files:
Index: src/usr.bin/make/cond.c
diff -u src/usr.bin/make/cond.c:1.363 src/usr.bin/make/cond.c:1.364
--- src/usr.bin/make/cond.c:1.363 Tue Apr 23 22:51:28 2024
+++ src/usr.bin/make/cond.c Sat May 25 00:00:25 2024
@@ -1,4 +1,4 @@
-/* $NetBSD: cond.c,v 1.363 2024/04/23 22:51:28 rillig Exp $ */
+/* $NetBSD: cond.c,v 1.364 2024/05/25 00:00:25 rillig Exp $ */
/*
* Copyright (c) 1988, 1989, 1990 The Regents of the University of California.
@@ -91,7 +91,7 @@
#include "dir.h"
/* "@(#)cond.c 8.2 (Berkeley) 1/2/94" */
-MAKE_RCSID("$NetBSD: cond.c,v 1.363 2024/04/23 22:51:28 rillig Exp $");
+MAKE_RCSID("$NetBSD: cond.c,v 1.364 2024/05/25 00:00:25 rillig Exp $");
/*
* Conditional expressions conform to this grammar:
@@ -736,8 +736,10 @@ CondParser_ComparisonOrLeaf(CondParser *
arg = ParseWord(&p, doEval);
assert(arg[0] != '\0');
- if (*p == '=' || *p == '!' || *p == '<' || *p == '>')
+ if (*p == '=' || *p == '!' || *p == '<' || *p == '>') {
+ free(arg);
return CondParser_Comparison(par, doEval);
+ }
par->p = p;
/*
Index: src/usr.bin/make/dir.c
diff -u src/usr.bin/make/dir.c:1.291 src/usr.bin/make/dir.c:1.292
--- src/usr.bin/make/dir.c:1.291 Fri May 24 22:52:24 2024
+++ src/usr.bin/make/dir.c Sat May 25 00:00:25 2024
@@ -1,4 +1,4 @@
-/* $NetBSD: dir.c,v 1.291 2024/05/24 22:52:24 rillig Exp $ */
+/* $NetBSD: dir.c,v 1.292 2024/05/25 00:00:25 rillig Exp $ */
/*
* Copyright (c) 1988, 1989, 1990 The Regents of the University of California.
@@ -132,7 +132,7 @@
#include "job.h"
/* "@(#)dir.c 8.2 (Berkeley) 1/2/94" */
-MAKE_RCSID("$NetBSD: dir.c,v 1.291 2024/05/24 22:52:24 rillig Exp $");
+MAKE_RCSID("$NetBSD: dir.c,v 1.292 2024/05/25 00:00:25 rillig Exp $");
/*
* A search path is a list of CachedDir structures. A CachedDir has in it the
@@ -501,6 +501,18 @@ Dir_InitDot(void)
Dir_SetPATH(); /* initialize */
}
+#ifdef CLEANUP
+static void
+FreeCachedTable(HashTable *tbl)
+{
+ HashIter hi;
+ HashIter_Init(&hi, tbl);
+ while (HashIter_Next(&hi) != NULL)
+ free(hi.entry->value);
+ HashTable_Done(tbl);
+}
+#endif
+
/* Clean up the directories module. */
void
Dir_End(void)
@@ -511,8 +523,8 @@ Dir_End(void)
CachedDir_Assign(&dotLast, NULL);
SearchPath_Clear(&dirSearchPath);
OpenDirs_Done(&openDirs);
- HashTable_Done(&mtimes);
- HashTable_Done(&lmtimes);
+ FreeCachedTable(&mtimes);
+ FreeCachedTable(&lmtimes);
#endif
}
Index: src/usr.bin/make/for.c
diff -u src/usr.bin/make/for.c:1.179 src/usr.bin/make/for.c:1.180
--- src/usr.bin/make/for.c:1.179 Mon Apr 1 12:33:27 2024
+++ src/usr.bin/make/for.c Sat May 25 00:00:25 2024
@@ -1,4 +1,4 @@
-/* $NetBSD: for.c,v 1.179 2024/04/01 12:33:27 rillig Exp $ */
+/* $NetBSD: for.c,v 1.180 2024/05/25 00:00:25 rillig Exp $ */
/*
* Copyright (c) 1992, The Regents of the University of California.
@@ -58,7 +58,7 @@
#include "make.h"
/* "@(#)for.c 8.1 (Berkeley) 6/6/93" */
-MAKE_RCSID("$NetBSD: for.c,v 1.179 2024/04/01 12:33:27 rillig Exp $");
+MAKE_RCSID("$NetBSD: for.c,v 1.180 2024/05/25 00:00:25 rillig Exp $");
typedef struct ForLoop {
@@ -156,7 +156,8 @@ ForLoop_ParseVarnames(ForLoop *f, const
cpp_skip_whitespace(&p);
if (*p == '\0') {
Parse_Error(PARSE_FATAL, "missing `in' in for");
- f->vars.len = 0;
+ while (f->vars.len > 0)
+ free(*(char **)Vector_Pop(&f->vars));
return;
}
@@ -166,7 +167,8 @@ ForLoop_ParseVarnames(ForLoop *f, const
"invalid character '%c' "
"in .for loop variable name",
p[len]);
- f->vars.len = 0;
+ while (f->vars.len > 0)
+ free(*(char **)Vector_Pop(&f->vars));
return;
}
}
Index: src/usr.bin/make/make.c
diff -u src/usr.bin/make/make.c:1.262 src/usr.bin/make/make.c:1.263
--- src/usr.bin/make/make.c:1.262 Fri Jan 5 23:22:06 2024
+++ src/usr.bin/make/make.c Sat May 25 00:00:25 2024
@@ -1,4 +1,4 @@
-/* $NetBSD: make.c,v 1.262 2024/01/05 23:22:06 rillig Exp $ */
+/* $NetBSD: make.c,v 1.263 2024/05/25 00:00:25 rillig Exp $ */
/*
* Copyright (c) 1988, 1989, 1990, 1993
@@ -104,7 +104,7 @@
#include "job.h"
/* "@(#)make.c 8.1 (Berkeley) 6/6/93" */
-MAKE_RCSID("$NetBSD: make.c,v 1.262 2024/01/05 23:22:06 rillig Exp $");
+MAKE_RCSID("$NetBSD: make.c,v 1.263 2024/05/25 00:00:25 rillig Exp $");
/* Sequence # to detect recursion. */
static unsigned int checked_seqno = 1;
@@ -127,8 +127,8 @@ debug_printf(const char *fmt, ...)
va_end(ap);
}
-static const char *
-GNodeType_ToString(GNodeType type, void **freeIt)
+static char *
+GNodeType_ToString(GNodeType type)
{
Buffer buf;
@@ -166,11 +166,13 @@ GNodeType_ToString(GNodeType type, void
ADD(OP_DEPS_FOUND);
ADD(OP_MARK);
#undef ADD
- return buf.len == 0 ? "none" : (*freeIt = Buf_DoneData(&buf));
+ if (buf.len == 0)
+ Buf_AddStr(&buf, "none");
+ return Buf_DoneData(&buf);
}
-static const char *
-GNodeFlags_ToString(GNodeFlags flags, void **freeIt)
+static char *
+GNodeFlags_ToString(GNodeFlags flags)
{
Buffer buf;
@@ -184,24 +186,22 @@ GNodeFlags_ToString(GNodeFlags flags, vo
Buf_AddFlag(&buf, flags.doneAllsrc, "DONE_ALLSRC");
Buf_AddFlag(&buf, flags.cycle, "CYCLE");
Buf_AddFlag(&buf, flags.doneCycle, "DONECYCLE");
- return buf.len == 0 ? "none" : (*freeIt = Buf_DoneData(&buf));
+ if (buf.len == 0)
+ Buf_AddStr(&buf, "none");
+ return Buf_DoneData(&buf);
}
void
GNode_FprintDetails(FILE *f, const char *prefix, const GNode *gn,
const char *suffix)
{
- void *type_freeIt = NULL;
- void *flags_freeIt = NULL;
+ char *type = GNodeType_ToString(gn->type);
+ char *flags = GNodeFlags_ToString(gn->flags);
fprintf(f, "%s%s, type %s, flags %s%s",
- prefix,
- GNodeMade_Name(gn->made),
- GNodeType_ToString(gn->type, &type_freeIt),
- GNodeFlags_ToString(gn->flags, &flags_freeIt),
- suffix);
- free(type_freeIt);
- free(flags_freeIt);
+ prefix, GNodeMade_Name(gn->made), type, flags, suffix);
+ free(type);
+ free(flags);
}
bool
Index: src/usr.bin/make/make.h
diff -u src/usr.bin/make/make.h:1.333 src/usr.bin/make/make.h:1.334
--- src/usr.bin/make/make.h:1.333 Tue May 7 18:26:22 2024
+++ src/usr.bin/make/make.h Sat May 25 00:00:25 2024
@@ -1,4 +1,4 @@
-/* $NetBSD: make.h,v 1.333 2024/05/07 18:26:22 sjg Exp $ */
+/* $NetBSD: make.h,v 1.334 2024/05/25 00:00:25 rillig Exp $ */
/*
* Copyright (c) 1988, 1989, 1990, 1993
@@ -1004,6 +1004,9 @@ typedef enum VarExportMode {
} VarExportMode;
void Var_Delete(GNode *, const char *);
+#ifdef CLEANUP
+void Var_DeleteAll(GNode *scope);
+#endif
void Var_Undef(const char *);
void Var_Set(GNode *, const char *, const char *);
void Var_SetExpand(GNode *, const char *, const char *);
Index: src/usr.bin/make/parse.c
diff -u src/usr.bin/make/parse.c:1.723 src/usr.bin/make/parse.c:1.724
--- src/usr.bin/make/parse.c:1.723 Sun May 19 20:09:40 2024
+++ src/usr.bin/make/parse.c Sat May 25 00:00:25 2024
@@ -1,4 +1,4 @@
-/* $NetBSD: parse.c,v 1.723 2024/05/19 20:09:40 sjg Exp $ */
+/* $NetBSD: parse.c,v 1.724 2024/05/25 00:00:25 rillig Exp $ */
/*
* Copyright (c) 1988, 1989, 1990, 1993
@@ -105,7 +105,7 @@
#include "pathnames.h"
/* "@(#)parse.c 8.3 (Berkeley) 3/19/94" */
-MAKE_RCSID("$NetBSD: parse.c,v 1.723 2024/05/19 20:09:40 sjg Exp $");
+MAKE_RCSID("$NetBSD: parse.c,v 1.724 2024/05/25 00:00:25 rillig Exp $");
/* Detects a multiple-inclusion guard in a makefile. */
typedef enum {
@@ -1263,13 +1263,12 @@ IncludeFile(const char *file, bool isSys
}
if (SkipGuarded(fullname))
- return;
+ goto done;
if ((fd = open(fullname, O_RDONLY)) == -1) {
if (!silent)
Parse_Error(PARSE_FATAL, "Cannot open %s", fullname);
- free(fullname);
- return;
+ goto done;
}
buf = LoadFile(fullname, fd);
@@ -1278,6 +1277,7 @@ IncludeFile(const char *file, bool isSys
Parse_PushInput(fullname, 1, 0, buf, NULL);
if (depinc)
doing_depend = depinc; /* only turn it on */
+done:
free(fullname);
}
Index: src/usr.bin/make/targ.c
diff -u src/usr.bin/make/targ.c:1.181 src/usr.bin/make/targ.c:1.182
--- src/usr.bin/make/targ.c:1.181 Sat Apr 27 17:33:47 2024
+++ src/usr.bin/make/targ.c Sat May 25 00:00:25 2024
@@ -1,4 +1,4 @@
-/* $NetBSD: targ.c,v 1.181 2024/04/27 17:33:47 rillig Exp $ */
+/* $NetBSD: targ.c,v 1.182 2024/05/25 00:00:25 rillig Exp $ */
/*
* Copyright (c) 1988, 1989, 1990, 1993
@@ -107,7 +107,7 @@
#include "dir.h"
/* "@(#)targ.c 8.2 (Berkeley) 3/19/94" */
-MAKE_RCSID("$NetBSD: targ.c,v 1.181 2024/04/27 17:33:47 rillig Exp $");
+MAKE_RCSID("$NetBSD: targ.c,v 1.182 2024/05/25 00:00:25 rillig Exp $");
/*
* All target nodes that appeared on the left-hand side of one of the
@@ -219,6 +219,10 @@ GNode_New(const char *name)
static void
GNode_Free(GNode *gn)
{
+#ifdef CLEANUP
+ Var_DeleteAll(gn);
+#endif
+
free(gn->name);
free(gn->uname);
free(gn->path);
@@ -236,20 +240,6 @@ GNode_Free(GNode *gn)
Lst_Done(&gn->order_succ);
Lst_Done(&gn->cohorts);
- /*
- * Do not free the variables themselves, even though they are owned
- * by this node.
- *
- * XXX: For the nodes that represent targets or sources (and not
- * SCOPE_GLOBAL), it should be safe to free the variables as well,
- * since each node manages the memory for all its variables itself.
- *
- * XXX: The GNodes that are only used as variable scopes (SCOPE_CMD,
- * SCOPE_GLOBAL, SCOPE_INTERNAL) are not freed at all (see Var_End,
- * where they are not mentioned). These may be freed if their
- * variable values are indeed not used anywhere else (see Trace_Init
- * for the only suspicious use).
- */
HashTable_Done(&gn->vars);
/*
Index: src/usr.bin/make/test-variants.mk
diff -u src/usr.bin/make/test-variants.mk:1.7 src/usr.bin/make/test-variants.mk:1.8
--- src/usr.bin/make/test-variants.mk:1.7 Fri May 24 23:02:46 2024
+++ src/usr.bin/make/test-variants.mk Sat May 25 00:00:25 2024
@@ -1,4 +1,4 @@
-# $NetBSD: test-variants.mk,v 1.7 2024/05/24 23:02:46 rillig Exp $
+# $NetBSD: test-variants.mk,v 1.8 2024/05/25 00:00:25 rillig Exp $
#
# Build several variants of make and run the tests on them.
#
@@ -60,6 +60,7 @@ ENV.no-meta= USE_META="no"
SKIP_TESTS.no-meta= depsrc-meta meta-cmd-cmp
TESTS+= cleanup
+ENV.cleanup= MKLINT=yes
CPPFLAGS.cleanup= -DCLEANUP
TESTS+= debug-refcnt
Index: src/usr.bin/make/var.c
diff -u src/usr.bin/make/var.c:1.1110 src/usr.bin/make/var.c:1.1111
--- src/usr.bin/make/var.c:1.1110 Fri May 24 23:02:46 2024
+++ src/usr.bin/make/var.c Sat May 25 00:00:25 2024
@@ -1,4 +1,4 @@
-/* $NetBSD: var.c,v 1.1110 2024/05/24 23:02:46 rillig Exp $ */
+/* $NetBSD: var.c,v 1.1111 2024/05/25 00:00:25 rillig Exp $ */
/*
* Copyright (c) 1988, 1989, 1990, 1993
@@ -132,7 +132,7 @@
#include "metachar.h"
/* "@(#)var.c 8.3 (Berkeley) 3/19/94" */
-MAKE_RCSID("$NetBSD: var.c,v 1.1110 2024/05/24 23:02:46 rillig Exp $");
+MAKE_RCSID("$NetBSD: var.c,v 1.1111 2024/05/25 00:00:25 rillig Exp $");
/*
* Variables are defined using one of the VAR=value assignments. Their
@@ -582,6 +582,21 @@ Var_Delete(GNode *scope, const char *var
free(v);
}
+#ifdef CLEANUP
+void
+Var_DeleteAll(GNode *scope)
+{
+ for (;;) {
+ HashIter hi;
+ HashIter_Init(&hi, &scope->vars);
+ if (HashIter_Next(&hi) == NULL)
+ return;
+ ((Var *)hi.entry->value)->readOnly = false;
+ Var_Delete(scope, hi.entry->key);
+ }
+}
+#endif
+
/*
* Undefine one or more variables from the global scope.
* The argument is expanded exactly once and then split into words.
@@ -2466,6 +2481,7 @@ ApplyModifier_Defined(const char **pp, M
Expr_Define(expr);
if (shouldEval)
Expr_SetValue(expr, Substring_Str(LazyBuf_Get(&buf)));
+ LazyBuf_Done(&buf);
return AMR_OK;
}
@@ -4753,32 +4769,11 @@ Var_Init(void)
SCOPE_CMDLINE = GNode_New("Command");
}
-#ifdef CLEANUP
-static void
-Var_DeleteAll(GNode *scope)
-{
- for (;;) {
- HashIter hi;
- HashIter_Init(&hi, &scope->vars);
- if (!HashIter_Next(&hi))
- return;
- ((Var *)hi.entry->value)->readOnly = false;
- Var_Delete(scope, hi.entry->key);
- }
-}
-
-#endif
-
/* Clean up the variables module. */
void
Var_End(void)
{
Var_Stats();
-#ifdef CLEANUP
- Var_DeleteAll(SCOPE_CMDLINE);
- Var_DeleteAll(SCOPE_GLOBAL);
- Var_DeleteAll(SCOPE_INTERNAL);
-#endif
}
void