From 2f8a646d4e68d3f515d0b5275d179562a219a9ed Mon Sep 17 00:00:00 2001 From: Peter Stephenson Date: Thu, 18 Mar 2004 12:23:31 +0000 Subject: 19655, 19656, 19657: Memory leaks spotted by valgrind. Also bug with multiple math function autoloads. --- ChangeLog | 14 ++++++++++++++ Src/exec.c | 4 ++++ Src/module.c | 35 +++++++++++++++++++++++++---------- Src/params.c | 1 + 4 files changed, 44 insertions(+), 10 deletions(-) diff --git a/ChangeLog b/ChangeLog index 8831f679b..b07f9f34a 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,3 +1,17 @@ +2004-03-18 Peter Stephenson + + * 19657: Src/modules.c: Leak when an autoloadable math function + was read in. Also, it was impossible to autoload multiple math + functions from the same library. + + * 19656: Src/exec.c Leak saving and restoring parameters around + builtins and functions when set temporarily for that command if + the parameter was previously exported. + + * 19655: Src/params.c: the reverse pointer from a tied array + to a tied scalar wasn't delete if the array was unset by unsetting + the scalar (or probably vice versa). + 2004-03-17 Peter Stephenson * unposted: Etc/MACHINES: dlcompat apparently not needed diff --git a/Src/exec.c b/Src/exec.c index bb4194d52..4bd6503bf 100644 --- a/Src/exec.c +++ b/Src/exec.c @@ -2519,6 +2519,10 @@ save_params(Estate state, Wordcode pc, LinkList *restore_p, LinkList *remove_p) while (wc_code(ac = *pc) == WC_ASSIGN) { s = ecrawstr(state->prog, pc + 1, NULL); if ((pm = (Param) paramtab->getnode(paramtab, s))) { + if (pm->env) { + delenv(pm->env); + pm->env = NULL; + } if (!(pm->flags & PM_SPECIAL)) { paramtab->removenode(paramtab, s); } else if (!(pm->flags & PM_READONLY) && diff --git a/Src/module.c b/Src/module.c index 3a89294e5..4a4807a31 100644 --- a/Src/module.c +++ b/Src/module.c @@ -2038,6 +2038,19 @@ add_autoparam(char *nam, char *module) /**/ MathFunc mathfuncs; +/**/ +static void removemathfunc(MathFunc previous, MathFunc current) +{ + if (previous) + previous->next = current->next; + else + mathfuncs = current->next; + + zsfree(current->name); + zsfree(current->module); + zfree(current, sizeof(*current)); +} + /**/ MathFunc getmathfunc(char *name, int autol) @@ -2049,13 +2062,7 @@ getmathfunc(char *name, int autol) if (autol && p->module) { char *n = dupstring(p->module); - if (q) - q->next = p->next; - else - mathfuncs = p->next; - - zsfree(p->module); - zfree(p, sizeof(*p)); + removemathfunc(q, p); load_module(n); @@ -2071,14 +2078,22 @@ getmathfunc(char *name, int autol) mod_export int addmathfunc(MathFunc f) { - MathFunc p; + MathFunc p, q = NULL; if (f->flags & MFF_ADDED) return 1; - for (p = mathfuncs; p; p = p->next) - if (!strcmp(f->name, p->name)) + for (p = mathfuncs; p; q = p, p = p->next) + if (!strcmp(f->name, p->name)) { + if (p->module) { + /* + * Autoloadable, replace. + */ + removemathfunc(q, p); + break; + } return 1; + } f->flags |= MFF_ADDED; f->next = mathfuncs; diff --git a/Src/params.c b/Src/params.c index 0760146fe..d742a389e 100644 --- a/Src/params.c +++ b/Src/params.c @@ -2673,6 +2673,7 @@ tiedarrunsetfn(Param pm, int exp) zfree(pm->u.data, sizeof(struct tieddata)); /* paranoia -- shouldn't need these, but in case we reuse the struct... */ pm->u.data = NULL; + zsfree(pm->ename); pm->flags &= ~PM_TIED; } -- cgit 1.4.1