I've included a fix for 2 memory leaks in CVS version 1.10.8 in rcs.c.
On a 600 megabyte CVS repository with lots of tags, this patch makes a tag
operation take ~ 2.5 megabytes of RSS versus 11 megabytes without.
Briefly, the memory leak is because the char **key and value arguments to
getdelta() are sometimes pointers to malloc()'ed areas and sometime
pointers from rcsbuf_getkey that we cant (and dont) free from callers. If
you have any questions or comments, please email me directly, as I am not
on any CVS list. The two leaks were alloced from:
rcs.c, line 7817
rcs.c, line 7874
//Jesse Off
[EMAIL PROTECTED]
And now, the patch:
diff -uNr cvs-1.10.8.orig/ChangeLog cvs-1.10.8/ChangeLog
--- cvs-1.10.8.orig/ChangeLog Mon Dec 13 13:08:19 1999
+++ cvs-1.10.8/ChangeLog Tue Aug 1 23:47:58 2000
@@ -1,3 +1,7 @@
+2000-07-31 Jesse Off <[EMAIL PROTECTED]>
+
+ * rcs.c: Fixed a memory leak in getdelta().
+
1999-12-09 Larry Jones <[EMAIL PROTECTED]>
* configure.in: Correctly handle systems that need both libsocket
diff -uNr cvs-1.10.8.orig/src/rcs.c cvs-1.10.8/src/rcs.c
--- cvs-1.10.8.orig/src/rcs.c Tue Aug 1 23:15:24 2000
+++ cvs-1.10.8/src/rcs.c Wed Aug 2 00:00:57 2000
@@ -560,6 +560,8 @@
revision delta in KEY (the revision) and VALUE (the date key
and its value). This is what getdelta expects to receive. */
+ key = xstrdup (key);
+ value = rcsbuf_valcopy (&rcsbuf, value, 0, (size_t *) NULL);
while ((vnode = getdelta (&rcsbuf, rcsfile, &key, &value)) != NULL)
{
/* get the node */
@@ -605,6 +607,10 @@
*pfp = fp;
*rcsbufp = rcsbuf;
}
+ if (key)
+ free (key);
+ if (value)
+ free (value);
rdata->flags &= ~PARTIAL;
}
@@ -7740,6 +7746,8 @@
{
if (! rcsbuf_getkey (rcsbuf, &key, &value))
error (1, 0, "%s: unexpected EOF", rcsfile);
+ key = xstrdup (key);
+ value = rcsbuf_valcopy (rcsbuf, value, 0, (size_t *)NULL);
}
/* Make sure that it is a revision number and not a cabbage
@@ -7770,7 +7778,12 @@
cp++;
vnode->date = xstrdup (cp);
-
+
+ if (key)
+ free (key);
+ if (value)
+ free (value);
+ key = value = NULL;
/* Get author field. */
if (! rcsbuf_getkey (rcsbuf, &key, &value))
{
@@ -7806,8 +7819,8 @@
}
if (STREQ (key, RCSDESC))
{
- *keyp = key;
- *valp = value;
+ *keyp = xstrdup (key);
+ *valp = rcsbuf_valcopy (rcsbuf, value, 0, (size_t *)NULL);;
/* Probably could/should be a fatal error. */
error (0, 0, "warning: 'branches' keyword missing from %s", rcsfile);
return vnode;
@@ -7827,8 +7840,8 @@
}
if (STREQ (key, RCSDESC))
{
- *keyp = key;
- *valp = value;
+ *keyp = xstrdup (key);
+ *valp = rcsbuf_valcopy (rcsbuf, value, 0, (size_t *)NULL);
/* Probably could/should be a fatal error. */
error (0, 0, "warning: 'next' keyword missing from %s", rcsfile);
return vnode;