ref: f009bd339788ee01539a74b68a9daf59969163bf
parent: 240201426090f9eca923980e388cab5e66ecc0ef
author: Miguel Pineiro Jr <mpj@pineiro.cc>
date: Mon May 23 13:14:42 EDT 2022
Fix memory leak in string assignment to built-ins
The new string value is always freeable (strdup'd by tostring), so
never mark it as DONTFREE.
$ paste <(./leak.sh master.out) <(./leak.sh fixed.out)
2564 2464
7260 2476
11948 2476
16636 2476
21324 2476
26012 2476
30700 2476
35388 2476
40076 2476
44760 2476
49448 2476
$ cat leak.sh
#/bin/sh
awk=${1:-nawk}
# Print the initial resident set size
# Assign each record to FS
# Print rsz every 100,000 records
# Exit after a million
yes abcdefghijklmnopqrstuvwxyz | $awk -v mem='ps -p $PPID -o rsz=' '
BEGIN { system(mem) }
{ FS = $0 }
NR % 100000 == 0 { system(mem) }
NR == 1000000 { exit }
'
--- a/FIXES
+++ b/FIXES
@@ -25,6 +25,10 @@
This file lists all bug fixes, changes, etc., made since the AWK book
was sent to the printers in August, 1987.
+May 23, 2022:
+ Memory leak when assigning a string to some of the built-in
+ variables. Thanks to Miguel Pineiro Jr. <mpj@pineiro.cc>.
+
Mar 3, 2022:
Fixed file management memory leak that appears to have been
there since the files array was first initialized with stdin,
--- a/main.c
+++ b/main.c
@@ -22,7 +22,7 @@
THIS SOFTWARE.
****************************************************************/
-const char *version = "version 20220303";
+const char *version = "version 20220523";
#define DEBUG
#include <stdio.h>
--- a/tran.c
+++ b/tran.c
@@ -70,18 +70,6 @@
extern Cell **fldtab;
-static void
-setfree(Cell *vp)
-{- if (&vp->sval == FS || &vp->sval == RS ||
- &vp->sval == OFS || &vp->sval == ORS ||
- &vp->sval == OFMT || &vp->sval == CONVFMT ||
- &vp->sval == FILENAME || &vp->sval == SUBSEP)
- vp->tval |= DONTFREE;
- else
- vp->tval &= ~DONTFREE;
-}
-
void syminit(void) /* initialize symbol table with builtin vars */
{ literal0 = setsymtab("0", "0", 0.0, NUM|STR|CON|DONTFREE, symtab);@@ -377,10 +365,9 @@
t = s ? tostring(s) : tostring(""); /* in case it's self-assign */if (freeable(vp))
xfree(vp->sval);
- vp->tval &= ~(NUM|CONVC|CONVO);
+ vp->tval &= ~(NUM|DONTFREE|CONVC|CONVO);
vp->tval |= STR;
vp->fmt = NULL;
- setfree(vp);
DPRINTF("setsval %p: %s = \"%s (%p) \", t=%o r,f=%d,%d\n",(void*)vp, NN(vp->nval), t, (void*)t, vp->tval, donerec, donefld);
vp->sval = t;
--
⑨