Index: generic/tclBasic.c
===================================================================
RCS file: /cvsroot/tcl/tcl/generic/tclBasic.c,v
retrieving revision 1.75.2.6
diff -u -r1.75.2.6 tclBasic.c
--- generic/tclBasic.c	29 Sep 2003 22:03:44 -0000	1.75.2.6
+++ generic/tclBasic.c	2 Oct 2003 17:48:18 -0000
@@ -2550,11 +2550,9 @@
                                  * must get the name from cmdPtr */
     CONST char *newName;        /* Command's new name, or NULL if
                                  * the command is not being renamed */
-    int flags;			/* Flags passed to trace procedures:
-				 * indicates what's happening to command,
-				 * plus other stuff like TCL_GLOBAL_ONLY,
-				 * TCL_NAMESPACE_ONLY, and
-				 * TCL_INTERP_DESTROYED. */
+    int flags;			/* Flags indicating the type of traces
+				 * to trigger, either TCL_TRACE_DELETE
+				 * or TCL_TRACE_RENAME. */
 {
     register CommandTrace *tracePtr;
     ActiveCommandTrace active;
Index: generic/tclCmdMZ.c
===================================================================
RCS file: /cvsroot/tcl/tcl/generic/tclCmdMZ.c,v
retrieving revision 1.82.2.7
diff -u -r1.82.2.7 tclCmdMZ.c
--- generic/tclCmdMZ.c	24 Sep 2003 02:17:10 -0000	1.82.2.7
+++ generic/tclCmdMZ.c	2 Oct 2003 17:48:22 -0000
@@ -3257,8 +3257,10 @@
 		tcmdPtr->length = length;
 		tcmdPtr->refCount = 1;
 		flags |= TCL_TRACE_DELETE;
-		if (flags & (TRACE_EXEC_ENTER_STEP | TRACE_EXEC_LEAVE_STEP)) {
-		    flags |= (TCL_TRACE_ENTER_EXEC | TCL_TRACE_LEAVE_EXEC);
+		if (flags & (TCL_TRACE_ENTER_DURING_EXEC |
+			     TCL_TRACE_LEAVE_DURING_EXEC)) {
+		    flags |= (TCL_TRACE_ENTER_EXEC | 
+			      TCL_TRACE_LEAVE_EXEC);
 		}
 		strcpy(tcmdPtr->command, command);
 		name = Tcl_GetString(objv[3]);
@@ -3299,8 +3301,8 @@
 			    && (strncmp(command, tcmdPtr->command,
 				    (size_t) length) == 0)) {
 			flags |= TCL_TRACE_DELETE;
-			if (flags & (TRACE_EXEC_ENTER_STEP | 
-				     TRACE_EXEC_LEAVE_STEP)) {
+			if (flags & (TCL_TRACE_ENTER_DURING_EXEC |
+				     TCL_TRACE_LEAVE_DURING_EXEC)) {
 			    flags |= (TCL_TRACE_ENTER_EXEC | 
 				      TCL_TRACE_LEAVE_EXEC);
 			}
@@ -4096,6 +4098,8 @@
      * because command deletes are unconditional, so the trace must go away.
      */
     if (flags & (TCL_TRACE_DESTROYED | TCL_TRACE_DELETE)) {
+	int untraceFlags = tcmdPtr->flags;
+
 	if (tcmdPtr->stepTrace != NULL) {
 	    Tcl_DeleteTrace(interp, tcmdPtr->stepTrace);
 	    tcmdPtr->stepTrace = NULL;
@@ -4107,10 +4111,31 @@
 	    /* Postpone deletion, until exec trace returns */
 	    tcmdPtr->flags = 0;
 	}
+
+	/*
+	 * We need to construct the same flags for Tcl_UntraceCommand
+	 * as were passed to Tcl_TraceCommand.  Reproduce the processing
+	 * of [trace add execution/command].  Be careful to keep this
+	 * code in sync with that.
+	 */
+
+	if (untraceFlags & TCL_TRACE_ANY_EXEC) {
+	    untraceFlags |= TCL_TRACE_DELETE;
+	    if (untraceFlags & (TCL_TRACE_ENTER_DURING_EXEC 
+		    | TCL_TRACE_LEAVE_DURING_EXEC)) {
+		untraceFlags |= (TCL_TRACE_ENTER_EXEC | TCL_TRACE_LEAVE_EXEC);
+	    }
+	} else if (untraceFlags & TCL_TRACE_RENAME) {
+	    untraceFlags |= TCL_TRACE_DELETE;
+	}
+
 	/* 
-	 * Decrement the refCount since the command which held our
-	 * reference (ever since we were created) has just gone away
+	 * Remove the trace since TCL_TRACE_DESTROYED tells us to, or the
+	 * command we're tracing has just gone away.  Then decrement the
+	 * clientData refCount that was set up by trace creation.
 	 */
+	Tcl_UntraceCommand(interp, oldName, untraceFlags,
+		TraceCommandProc, clientData);
 	tcmdPtr->refCount--;
     }
     if ((--tcmdPtr->refCount) <= 0) {
