diff options
author | dgp <dgp@users.sourceforge.net> | 2002-09-06 00:20:29 (GMT) |
---|---|---|
committer | dgp <dgp@users.sourceforge.net> | 2002-09-06 00:20:29 (GMT) |
commit | ff4a267f0be445ca56e06e36c671c793b307814d (patch) | |
tree | d99a89309a9578a6b6ac63ba1a17570abe96486f /generic | |
parent | 97f74cddc8704cd7c70a4f0e34dfaed1f1ddbfed (diff) | |
download | tcl-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')
-rw-r--r-- | generic/tclBasic.c | 27 |
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; } |