summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--ChangeLog10
-rw-r--r--generic/tclBasic.c29
-rw-r--r--tests/trace.test20
3 files changed, 46 insertions, 13 deletions
diff --git a/ChangeLog b/ChangeLog
index 7c3bc20..c2203c2 100644
--- a/ChangeLog
+++ b/ChangeLog
@@ -1,3 +1,13 @@
+2006-11-03 Miguel Sofer <msofer@users.sf.net>
+
+ * 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.
+
2006-11-01 Daniel Steffen <das@users.sourceforge.net>
* generic/tclEnv.c (Darwin): mark _environ symbol as unexported.
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;
diff --git a/tests/trace.test b/tests/trace.test
index a85bda2..32e1b4e 100644
--- a/tests/trace.test
+++ b/tests/trace.test
@@ -11,7 +11,7 @@
# See the file "license.terms" for information on usage and redistribution
# of this file, and for a DISCLAIMER OF ALL WARRANTIES.
#
-# RCS: @(#) $Id: trace.test,v 1.26.2.16 2006/04/11 14:37:05 dgp Exp $
+# RCS: @(#) $Id: trace.test,v 1.26.2.17 2006/11/04 01:37:56 msofer Exp $
if {[lsearch [namespace children] ::tcltest] == -1} {
package require tcltest
@@ -1624,6 +1624,24 @@ test trace-21.10 {trace execution: TCL_EVAL_GLOBAL} testevalobjv {
set ::info
} {SUCCESS 1 SUCCESS 1}
+test trace-21.11 {trace execution and alias} -setup {
+ set res {}
+ proc ::x {} {return ::}
+ namespace eval a {}
+ proc ::a::x {} {return ::a}
+ interp alias {} y {} x
+} -body {
+ lappend res [namespace eval ::a y]
+ trace add execution ::x enter {
+ rename ::x {}
+ proc ::x {} {return ::}
+ #}
+ lappend res [namespace eval ::a y]
+} -cleanup {
+ namespace delete a
+ rename ::x {}
+} -result {:: ::}
+
proc factorial {n} {
if {$n != 1} { return [expr {$n * [factorial [expr {$n -1 }]]}] }
return 1