summaryrefslogtreecommitdiffstats
path: root/generic/tclBasic.c
diff options
context:
space:
mode:
authordgp <dgp@users.sourceforge.net>2002-09-06 00:20:29 (GMT)
committerdgp <dgp@users.sourceforge.net>2002-09-06 00:20:29 (GMT)
commitff4a267f0be445ca56e06e36c671c793b307814d (patch)
treed99a89309a9578a6b6ac63ba1a17570abe96486f /generic/tclBasic.c
parent97f74cddc8704cd7c70a4f0e34dfaed1f1ddbfed (diff)
downloadtcl-ff4a267f0be445ca56e06e36c671c793b307814d.zip
tcl-ff4a267f0be445ca56e06e36c671c793b307814d.tar.gz
tcl-ff4a267f0be445ca56e06e36c671c793b307814d.tar.bz2
* generic/tclBasic.c (TclRenameCommand,CallCommandTraces):
* tests/trace.test (trace-27.1): Corrected memory leak when a rename trace deleted the command being traced. Test added. Thanks to Hemang Lavana for the fix. [Bug 604609]
Diffstat (limited to 'generic/tclBasic.c')
-rw-r--r--generic/tclBasic.c27
1 files changed, 21 insertions, 6 deletions
diff --git a/generic/tclBasic.c b/generic/tclBasic.c
index 379d290..6fe4db2 100644
--- a/generic/tclBasic.c
+++ b/generic/tclBasic.c
@@ -13,7 +13,7 @@
* See the file "license.terms" for information on usage and redistribution
* of this file, and for a DISCLAIMER OF ALL WARRANTIES.
*
- * RCS: @(#) $Id: tclBasic.c,v 1.69 2002/08/22 15:57:53 msofer Exp $
+ * RCS: @(#) $Id: tclBasic.c,v 1.70 2002/09/06 00:20:29 dgp Exp $
*/
#include "tclInt.h"
@@ -2001,6 +2001,13 @@ TclRenameCommand(interp, oldName, newName)
return result;
}
+ /*
+ * Script for rename traces can delete the command "oldName".
+ * Therefore increment the reference count for cmdPtr so that
+ * it's Command structure is freed only towards the end of this
+ * function by calling TclCleanupCommand.
+ */
+ cmdPtr->refCount++;
CallCommandTraces(iPtr,cmdPtr,oldName,newName,TCL_TRACE_RENAME);
/*
@@ -2023,6 +2030,12 @@ TclRenameCommand(interp, oldName, newName)
iPtr->compileEpoch++;
}
+ /*
+ * Now free the Command structure, if the "oldName" command has
+ * been deleted by invocation of rename traces.
+ */
+ TclCleanupCommand(cmdPtr);
+
return TCL_OK;
}
@@ -2523,15 +2536,17 @@ CallCommandTraces(iPtr, cmdPtr, oldName, newName, flags)
if (cmdPtr->flags & CMD_TRACE_ACTIVE) {
/*
* While a rename trace is active, we will not process any more
- * rename traces; while a delete trace is active we will not
- * process any more delete traces
+ * rename traces; while a delete trace is active we will never
+ * reach here -- because Tcl_DeleteCommandFromToken checks for the
+ * condition (cmdPtr->flags & CMD_IS_DELETED) and returns immediately
+ * when a command deletion is in progress. For all other traces,
+ * delete traces will not be invoked but a call to TraceCommandProc
+ * will ensure that tracePtr->clientData is freed whenever the
+ * command "oldName" is deleted.
*/
if (cmdPtr->flags & TCL_TRACE_RENAME) {
flags &= ~TCL_TRACE_RENAME;
}
- if (cmdPtr->flags & TCL_TRACE_DELETE) {
- flags &= ~TCL_TRACE_DELETE;
- }
if (flags == 0) {
return NULL;
}