summaryrefslogtreecommitdiffstats
path: root/generic
diff options
context:
space:
mode:
authorMiguel Sofer <miguel.sofer@gmail.com>2006-11-04 01:37:55 (GMT)
committerMiguel Sofer <miguel.sofer@gmail.com>2006-11-04 01:37:55 (GMT)
commit3e6a8effaded504ae2e5c836620c08eb5b4f0e68 (patch)
tree864d59cd45281c257b7b9b8fbb0ca46b2ec776c2 /generic
parent05dc17a9876e3f7fedbf33d15d7302fa7a5a278d (diff)
downloadtcl-3e6a8effaded504ae2e5c836620c08eb5b4f0e68.zip
tcl-3e6a8effaded504ae2e5c836620c08eb5b4f0e68.tar.gz
tcl-3e6a8effaded504ae2e5c836620c08eb5b4f0e68.tar.bz2
* generic/tclBasic.c (TEOVI): fix por possible leak of a Command
in the presence of execution traces that delete it. * generic/tclBasic.c (TEOVI): * tests/trace.test (trace-21.11): fix for [Bug 1590232], execution traces may cause a second command resolution in the wrong namespace.
Diffstat (limited to 'generic')
-rw-r--r--generic/tclBasic.c29
1 files changed, 17 insertions, 12 deletions
diff --git a/generic/tclBasic.c b/generic/tclBasic.c
index 9807a19..f55c531 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.75.2.24 2006/09/25 17:27:31 andreas_kupries Exp $
+ * RCS: @(#) $Id: tclBasic.c,v 1.75.2.25 2006/11/04 01:37:55 msofer Exp $
*/
#include "tclInt.h"
@@ -3008,21 +3008,23 @@ TclEvalObjvInternal(interp, objc, objv, command, length, flags)
return TCL_OK;
}
- /* Configure evaluation context to match the requested flags */
- savedVarFramePtr = iPtr->varFramePtr;
- if (flags & TCL_EVAL_GLOBAL) {
- iPtr->varFramePtr = NULL;
- } else if ((flags & TCL_EVAL_INVOKE) && iPtr->varFramePtr) {
- savedNsPtr = iPtr->varFramePtr->nsPtr;
- iPtr->varFramePtr->nsPtr = iPtr->globalNsPtr;
- }
/*
* If any execution traces rename or delete the current command,
* we may need (at most) two passes here.
*/
+
+ savedVarFramePtr = iPtr->varFramePtr;
while (1) {
+ /* Configure evaluation context to match the requested flags */
+ if (flags & TCL_EVAL_GLOBAL) {
+ iPtr->varFramePtr = NULL;
+ } else if ((flags & TCL_EVAL_INVOKE) && iPtr->varFramePtr) {
+ savedNsPtr = iPtr->varFramePtr->nsPtr;
+ iPtr->varFramePtr->nsPtr = iPtr->globalNsPtr;
+ }
+
/*
* Find the procedure to execute this command. If there isn't one,
* then see if there is a command "unknown". If so, create a new
@@ -3067,7 +3069,9 @@ TclEvalObjvInternal(interp, objc, objv, command, length, flags)
*/
if ((checkTraces) && (command != NULL)) {
int cmdEpoch = cmdPtr->cmdEpoch;
- cmdPtr->refCount++;
+ int newEpoch;
+
+ cmdPtr->refCount++;
/*
* If the first set of traces modifies/deletes the command or
* any existing traces, then the set checkTraces to 0 and
@@ -3082,8 +3086,9 @@ TclEvalObjvInternal(interp, objc, objv, command, length, flags)
traceCode = TclCheckExecutionTraces(interp, command, length,
cmdPtr, code, TCL_TRACE_ENTER_EXEC, objc, objv);
}
- cmdPtr->refCount--;
- if (cmdEpoch != cmdPtr->cmdEpoch) {
+ newEpoch = cmdPtr->cmdEpoch;
+ TclCleanupCommand(cmdPtr);
+ if (cmdEpoch != newEpoch) {
/* The command has been modified in some way */
checkTraces = 0;
continue;