? NSK1KENNYKB03
Index: generic/tclEvent.c
===================================================================
RCS file: /cvsroot/tcl/tcl/generic/tclEvent.c,v
retrieving revision 1.28.2.9
diff -u -r1.28.2.9 tclEvent.c
--- generic/tclEvent.c	30 Jul 2004 15:15:57 -0000	1.28.2.9
+++ generic/tclEvent.c	22 Jun 2005 18:27:50 -0000
@@ -895,11 +895,26 @@
 	TclResetFilesystem();
 	
 	/*
+	 * There have been several bugs in the past that cause
+	 * exit handlers to be established during Tcl_Finalize
+	 * processing.  Such exit handlers leave malloc'ed memory,
+	 * and Tcl_FinalizeThreadAlloc or Tcl_FinalizeMemorySubsystem
+	 * will result in a corrupted heap.  The result can be a
+	 * mysterious crash on process exit.  Check here that
+	 * nobody's done this.
+	 */
+
+	if ( firstExitPtr != NULL ) {
+	    Tcl_Panic( "exit handlers were created during Tcl_Finalize" );
+	}
+
+	/*
 	 * There shouldn't be any malloc'ed memory after this.
 	 */
 #if defined(TCL_THREADS) && defined(USE_THREAD_ALLOC) && !defined(TCL_MEM_DEBUG) && !defined(PURIFY)
 	TclFinalizeThreadAlloc();
 #endif
+
 	TclFinalizeMemorySubsystem();
 	inFinalize = 0;
     }
Index: generic/tclIO.c
===================================================================
RCS file: /cvsroot/tcl/tcl/generic/tclIO.c,v
retrieving revision 1.61.2.10
diff -u -r1.61.2.10 tclIO.c
--- generic/tclIO.c	14 Apr 2005 07:10:06 -0000	1.61.2.10
+++ generic/tclIO.c	22 Jun 2005 18:27:51 -0000
@@ -274,6 +274,7 @@
             statePtr->flags |= CHANNEL_DEAD;
         }
     }
+    TclpFinalizePipes();
 }
 
 
Index: generic/tclInt.h
===================================================================
RCS file: /cvsroot/tcl/tcl/generic/tclInt.h,v
retrieving revision 1.118.2.13
diff -u -r1.118.2.13 tclInt.h
--- generic/tclInt.h	22 Jun 2005 16:49:28 -0000	1.118.2.13
+++ generic/tclInt.h	22 Jun 2005 18:27:51 -0000
@@ -1721,6 +1721,7 @@
 EXTERN void		TclpFinalizeCondition _ANSI_ARGS_((
 			    Tcl_Condition *condPtr));
 EXTERN void		TclpFinalizeMutex _ANSI_ARGS_((Tcl_Mutex *mutexPtr));
+EXTERN void		TclpFinalizePipes _ANSI_ARGS_((void));
 EXTERN void		TclpFinalizeThreadData _ANSI_ARGS_((
 			    Tcl_ThreadDataKey *keyPtr));
 EXTERN void		TclpFinalizeThreadDataKey _ANSI_ARGS_((
Index: unix/tclUnixPipe.c
===================================================================
RCS file: /cvsroot/tcl/tcl/unix/tclUnixPipe.c,v
retrieving revision 1.23.2.3
diff -u -r1.23.2.3 tclUnixPipe.c
--- unix/tclUnixPipe.c	27 Jan 2005 22:53:36 -0000	1.23.2.3
+++ unix/tclUnixPipe.c	22 Jun 2005 18:27:51 -0000
@@ -1247,3 +1247,24 @@
     }
     return TCL_OK;
 }
+
+/*
+ *----------------------------------------------------------------------
+ *
+ * TclpFinalizePipes --
+ *
+ *	Cleans up the pipe subsystem from Tcl_FinalizeThread
+ *
+ * Results:
+ *	None.
+ *
+ * This procedure carries out no operation on Unix.
+ *
+ *----------------------------------------------------------------------
+ */
+
+void
+TclpFinalizePipes()
+{
+}
+
Index: win/tclWinPipe.c
===================================================================
RCS file: /cvsroot/tcl/tcl/win/tclWinPipe.c,v
retrieving revision 1.33.2.11
diff -u -r1.33.2.11 tclWinPipe.c
--- win/tclWinPipe.c	21 Jun 2005 19:07:58 -0000	1.33.2.11
+++ win/tclWinPipe.c	22 Jun 2005 18:27:51 -0000
@@ -201,7 +201,6 @@
 static void		PipeSetupProc(ClientData clientData, int flags);
 static void		PipeWatchProc(ClientData instanceData, int mask);
 static DWORD WINAPI	PipeWriterThread(LPVOID arg);
-static void		ProcExitHandler(ClientData clientData);
 static int		TempFileName(WCHAR name[MAX_PATH]);
 static int		WaitForRead(PipeInfo *infoPtr, int blocking);
 
@@ -263,7 +262,6 @@
 	if (!initialized) {
 	    initialized = 1;
 	    procList = NULL;
-	    Tcl_CreateExitHandler(ProcExitHandler, NULL);
 	}
 	Tcl_MutexUnlock(&pipeMutex);
     }
@@ -304,7 +302,7 @@
 /*
  *----------------------------------------------------------------------
  *
- * ProcExitHandler --
+ * TclpFinalizePipes --
  *
  *	This function is called to cleanup the process list before
  *	Tcl is unloaded.
@@ -318,9 +316,8 @@
  *----------------------------------------------------------------------
  */
 
-static void
-ProcExitHandler(
-    ClientData clientData)	/* Old window proc */
+void
+TclpFinalizePipes()
 {
     Tcl_MutexLock(&pipeMutex);
     initialized = 0;
