summaryrefslogtreecommitdiffstats
path: root/generic/tclProc.c
diff options
context:
space:
mode:
authorandreas_kupries <akupries@shaw.ca>2008-08-11 19:01:54 (GMT)
committerandreas_kupries <akupries@shaw.ca>2008-08-11 19:01:54 (GMT)
commit49f30082dd3c2a494c7a7bca131dbd509953c961 (patch)
tree83c9f82292818dd1c83e3e39efb972d185a0e914 /generic/tclProc.c
parent7f38194f5e9dc40e7cff32fa65af88021011cfab (diff)
downloadtcl-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/tclProc.c')
-rw-r--r--generic/tclProc.c28
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) {