diff options
author | andreas_kupries <akupries@shaw.ca> | 2008-08-11 19:01:54 (GMT) |
---|---|---|
committer | andreas_kupries <akupries@shaw.ca> | 2008-08-11 19:01:54 (GMT) |
commit | 49f30082dd3c2a494c7a7bca131dbd509953c961 (patch) | |
tree | 83c9f82292818dd1c83e3e39efb972d185a0e914 /generic | |
parent | 7f38194f5e9dc40e7cff32fa65af88021011cfab (diff) | |
download | tcl-49f30082dd3c2a494c7a7bca131dbd509953c961.zip tcl-49f30082dd3c2a494c7a7bca131dbd509953c961.tar.gz tcl-49f30082dd3c2a494c7a7bca131dbd509953c961.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')
-rw-r--r-- | generic/tclProc.c | 28 |
1 files changed, 24 insertions, 4 deletions
diff --git a/generic/tclProc.c b/generic/tclProc.c index 2b7c5f7..bf67600 100644 --- a/generic/tclProc.c +++ b/generic/tclProc.c @@ -12,7 +12,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.139.2.2 2008/07/25 20:30:47 andreas_kupries Exp $ + * RCS: @(#) $Id: tclProc.c,v 1.139.2.3 2008/08/11 19:01:59 andreas_kupries Exp $ */ #include "tclInt.h" @@ -245,6 +245,7 @@ Tcl_ProcObjCmd( if (contextPtr->line && (contextPtr->nline >= 4) && (contextPtr->line[3] >= 0)) { int isNew; + Tcl_HashEntry* hePtr; CmdFrame *cfPtr = (CmdFrame *) ckalloc(sizeof(CmdFrame)); cfPtr->level = -1; @@ -261,8 +262,26 @@ Tcl_ProcObjCmd( cfPtr->cmd.str.cmd = NULL; cfPtr->cmd.str.len = 0; - Tcl_SetHashValue(Tcl_CreateHashEntry(iPtr->linePBodyPtr, - (char *) procPtr, &isNew), 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); } /* @@ -2162,7 +2181,8 @@ TclProcCleanupProc( /* * TIP #280: Release the location data associated with this Proc * structure, if any. The interpreter may not exist (For example for - * procbody structures created by tbcload. + * procbody structures created by tbcload. See also Tcl_ProcObjCmd(), when + * the same ProcPtr is overwritten with a new CmdFrame. */ if (!iPtr) { |