diff options
author | andreas_kupries <akupries@shaw.ca> | 2008-08-11 20:13:39 (GMT) |
---|---|---|
committer | andreas_kupries <akupries@shaw.ca> | 2008-08-11 20:13:39 (GMT) |
commit | 8db6e6c1d648002473ed901f9d80f64a4c9c0d43 (patch) | |
tree | fee0c8028045472b91b463fd042c94c3f0f82611 /generic/tclProc.c | |
parent | 79af4b0e2884f647f54c5b8f425b4382ed4a3566 (diff) | |
download | tcl-8db6e6c1d648002473ed901f9d80f64a4c9c0d43.zip tcl-8db6e6c1d648002473ed901f9d80f64a4c9c0d43.tar.gz tcl-8db6e6c1d648002473ed901f9d80f64a4c9c0d43.tar.bz2 |
* generic/tclProc.c (Tcl_ProcObjCmd): Fixed memory leak triggered
* tests/proc.test: by procbody::test::proc. See [Bug 2043636].
Added a test case demonstrating the leak before the fix. Fixed a
few spelling errors in test descriptions as well.
Diffstat (limited to 'generic/tclProc.c')
-rw-r--r-- | generic/tclProc.c | 29 |
1 files changed, 24 insertions, 5 deletions
diff --git a/generic/tclProc.c b/generic/tclProc.c index b2c2b8d..950d448 100644 --- a/generic/tclProc.c +++ b/generic/tclProc.c @@ -11,7 +11,7 @@ * See the file "license.terms" for information on usage and redistribution * of this file, and for a DISCLAIMER OF ALL WARRANTIES. * - * RCS: @(#) $Id: tclProc.c,v 1.44.2.8 2008/07/21 19:37:45 andreas_kupries Exp $ + * RCS: @(#) $Id: tclProc.c,v 1.44.2.9 2008/08/11 20:13:43 andreas_kupries Exp $ */ #include "tclInt.h" @@ -182,7 +182,8 @@ Tcl_ProcObjCmd(dummy, interp, objc, objv) context.line && (context.nline >= 4) && (context.line [3] >= 0)) { - int new; + int isNew; + Tcl_HashEntry* hePtr; CmdFrame* cfPtr = (CmdFrame*) ckalloc (sizeof (CmdFrame)); cfPtr->level = -1; @@ -206,9 +207,27 @@ Tcl_ProcObjCmd(dummy, interp, objc, objv) cfPtr->cmd.str.cmd = NULL; cfPtr->cmd.str.len = 0; - Tcl_SetHashValue (Tcl_CreateHashEntry (iPtr->linePBodyPtr, - (char*) procPtr, &new), - cfPtr); + hePtr = Tcl_CreateHashEntry (iPtr->linePBodyPtr, (char*) procPtr, + &isNew); + if (!isNew) { + /* + * Get the old command frame and release it. See also + * TclProcCleanupProc in this file. Currently it seems as if + * only the procbodytest::proc command of the testsuite is + * able to trigger this situation. + */ + + CmdFrame* cfOldPtr = (CmdFrame *) Tcl_GetHashValue(hePtr); + + if (cfOldPtr->type == TCL_LOCATION_SOURCE) { + Tcl_DecrRefCount(cfOldPtr->data.eval.path); + cfOldPtr->data.eval.path = NULL; + } + ckfree((char *) cfOldPtr->line); + cfOldPtr->line = NULL; + ckfree((char *) cfOldPtr); + } + Tcl_SetHashValue (hePtr, cfPtr); } } #endif |