diff -ur tcl8.5.6.orig/generic/tclTrace.c tcl8.5.6.patched/generic/tclTrace.c
--- tcl8.5.6.orig/generic/tclTrace.c	2009-02-22 19:44:28.000000000 -0600
+++ tcl8.5.6.patched/generic/tclTrace.c	2009-02-22 22:03:31.000000000 -0600
@@ -2894,6 +2894,7 @@
     } else {
 	prevPtr->nextPtr = nextPtr;
     }
+    tracePtr->nextPtr = NULL;
     Tcl_EventuallyFree((ClientData) tracePtr, TCL_DYNAMIC);
 
     for (tracePtr = nextPtr; tracePtr != NULL;
diff -ur tcl8.5.6.orig/generic/tclVar.c tcl8.5.6.patched/generic/tclVar.c
--- tcl8.5.6.orig/generic/tclVar.c	2009-02-22 19:44:28.000000000 -0600
+++ tcl8.5.6.patched/generic/tclVar.c	2009-02-22 22:11:27.000000000 -0600
@@ -2357,6 +2357,16 @@
 		    (flags & (TCL_GLOBAL_ONLY|TCL_NAMESPACE_ONLY))
 			    | TCL_TRACE_UNSETS,
 		    /* leaveErrMsg */ 0, -1);
+        /*
+         * the traces that we just called may have triggered a change in the 
+         * set of traces
+         */
+        tracePtr = NULL;
+        if (TclIsVarTraced(&dummyVar)) {
+            tPtr = Tcl_FindHashEntry(&iPtr->varTraces, (char *) &dummyVar);
+            tracePtr = Tcl_GetHashValue(tPtr);
+        }
+
 	    if (tPtr) {
 		Tcl_DeleteHashEntry(tPtr);
 	    }
@@ -2369,6 +2379,7 @@
 		VarTrace *prevPtr = tracePtr;
 
 		tracePtr = tracePtr->nextPtr;
+        prevPtr->nextPtr = NULL;
 		Tcl_EventuallyFree((ClientData) prevPtr, TCL_DYNAMIC);
 	    }
 	    for (activePtr = iPtr->activeVarTracePtr;  activePtr != NULL;
@@ -4385,6 +4396,7 @@
 	 */
 
 	if (TclIsVarTraced(varPtr)) {
+	    ActiveVarTrace *activePtr;
 	    Tcl_HashEntry *tPtr = Tcl_FindHashEntry(&iPtr->varTraces,
 		    (char *) varPtr);
 	    VarTrace *tracePtr = (VarTrace *) Tcl_GetHashValue(tPtr);
@@ -4393,10 +4405,17 @@
 		VarTrace *prevPtr = tracePtr;
 
 		tracePtr = tracePtr->nextPtr;
+        prevPtr->nextPtr = NULL;
 		Tcl_EventuallyFree((ClientData) prevPtr, TCL_DYNAMIC);
 	    }
 	    Tcl_DeleteHashEntry(tPtr);
 	    varPtr->flags &= ~VAR_ALL_TRACES;
+	    for (activePtr = iPtr->activeVarTracePtr; activePtr != NULL;
+		    activePtr = activePtr->nextPtr) {
+		if (activePtr->varPtr == varPtr) {
+		    activePtr->nextTracePtr = NULL;
+		}
+	    }
 	}
 	VarHashRefCount(varPtr)--;
 	VarHashDeleteEntry(varPtr);
@@ -4499,6 +4518,7 @@
 	UnsetVarStruct(varPtr, NULL, iPtr, *namePtrPtr, NULL,
 		TCL_TRACE_UNSETS);
     }
+    framePtr->numCompiledLocals=0;
 }
 
 /*
@@ -4575,6 +4595,7 @@
 		VarTrace *prevPtr = tracePtr;
 
 		tracePtr = tracePtr->nextPtr;
+        prevPtr->nextPtr = NULL;
 		Tcl_EventuallyFree((ClientData) prevPtr, TCL_DYNAMIC);
 	    }
 	    Tcl_DeleteHashEntry(tPtr);
