summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--ChangeLog12
-rw-r--r--generic/tclEvent.c18
-rw-r--r--generic/tclIO.c3
-rw-r--r--generic/tclInt.h3
-rw-r--r--unix/tclUnixPipe.c23
-rw-r--r--win/tclWinPipe.c11
6 files changed, 58 insertions, 12 deletions
diff --git a/ChangeLog b/ChangeLog
index 62b3e62..dfe4bb4 100644
--- a/ChangeLog
+++ b/ChangeLog
@@ -1,3 +1,15 @@
+2005-06-22 Kevin Kenny <kennykb@acm.org>
+
+ * generic/tclInt.h: Changed the finalization
+ * generic/tclEvent.c (Tcl_Finalize): logic to defer the
+ * generic/tclIO.c (TclFinalizeIOSubsystem): shutdown of the pipe
+ * unix/tclUnixPipe.c (TclFinalizePipes): management until after
+ * win/tclWinPipe.c (TclFinalizePipes): all channels have been
+ closed, in order to avoid a situation where the Windows
+ PipeCloseProc2 would re-establish the exit handler after
+ exit handlers had already run, corrupting the heap.
+ [Bug #1225727]
+
2005-06-21 Andreas Kupries <andreask@activestate.com>
* generic/tclInt.h: Followup to change made on 2005-06-18 by
diff --git a/generic/tclEvent.c b/generic/tclEvent.c
index 6e2a4df..3ecf3f1 100644
--- a/generic/tclEvent.c
+++ b/generic/tclEvent.c
@@ -12,7 +12,7 @@
* See the file "license.terms" for information on usage and redistribution
* of this file, and for a DISCLAIMER OF ALL WARRANTIES.
*
- * RCS: @(#) $Id: tclEvent.c,v 1.57 2005/05/10 18:34:35 kennykb Exp $
+ * RCS: @(#) $Id: tclEvent.c,v 1.58 2005/06/22 19:47:42 kennykb Exp $
*/
#include "tclInt.h"
@@ -946,10 +946,24 @@ Tcl_Finalize()
TclFinalizeDoubleConversion();
/*
+ * 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)
- TclFinalizeThreadAlloc();
+ TclFinalizeThreadAlloc();
#endif
TclFinalizeMemorySubsystem();
inFinalize = 0;
diff --git a/generic/tclIO.c b/generic/tclIO.c
index 0aeb6b8..0766e19 100644
--- a/generic/tclIO.c
+++ b/generic/tclIO.c
@@ -10,7 +10,7 @@
* See the file "license.terms" for information on usage and redistribution
* of this file, and for a DISCLAIMER OF ALL WARRANTIES.
*
- * RCS: @(#) $Id: tclIO.c,v 1.89 2005/06/07 20:37:40 dkf Exp $
+ * RCS: @(#) $Id: tclIO.c,v 1.90 2005/06/22 19:47:43 kennykb Exp $
*/
#include "tclInt.h"
@@ -270,6 +270,7 @@ TclFinalizeIOSubsystem()
statePtr->flags |= CHANNEL_DEAD;
}
}
+ TclpFinalizePipes();
}
/*
diff --git a/generic/tclInt.h b/generic/tclInt.h
index f431d35..4d13329 100644
--- a/generic/tclInt.h
+++ b/generic/tclInt.h
@@ -12,7 +12,7 @@
* See the file "license.terms" for information on usage and redistribution
* of this file, and for a DISCLAIMER OF ALL WARRANTIES.
*
- * RCS: @(#) $Id: tclInt.h,v 1.238 2005/06/21 19:49:25 andreas_kupries Exp $
+ * RCS: @(#) $Id: tclInt.h,v 1.239 2005/06/22 19:48:08 kennykb Exp $
*/
#ifndef _TCLINT
@@ -2031,6 +2031,7 @@ MODULE_SCOPE int TclpDeleteFile _ANSI_ARGS_((CONST char *path));
MODULE_SCOPE void TclpFinalizeCondition _ANSI_ARGS_((
Tcl_Condition *condPtr));
MODULE_SCOPE void TclpFinalizeMutex _ANSI_ARGS_((Tcl_Mutex *mutexPtr));
+MODULE_SCOPE void TclpFinalizePipes _ANSI_ARGS_((void));
MODULE_SCOPE void TclpFinalizeThreadData _ANSI_ARGS_((
Tcl_ThreadDataKey *keyPtr));
MODULE_SCOPE int TclpThreadCreate _ANSI_ARGS_((
diff --git a/unix/tclUnixPipe.c b/unix/tclUnixPipe.c
index f1353c3..c0dcb46 100644
--- a/unix/tclUnixPipe.c
+++ b/unix/tclUnixPipe.c
@@ -10,7 +10,7 @@
* See the file "license.terms" for information on usage and redistribution
* of this file, and for a DISCLAIMER OF ALL WARRANTIES.
*
- * RCS: @(#) $Id: tclUnixPipe.c,v 1.28 2005/05/10 18:35:28 kennykb Exp $
+ * RCS: @(#) $Id: tclUnixPipe.c,v 1.29 2005/06/22 19:48:10 kennykb Exp $
*/
#include "tclInt.h"
@@ -1247,3 +1247,24 @@ Tcl_PidObjCmd(dummy, interp, objc, objv)
}
return TCL_OK;
}
+
+/*
+ *----------------------------------------------------------------------
+ *
+ * TclpFinalizePipes --
+ *
+ * Cleans up the pipe subsystem from Tcl_FinalizeThread
+ *
+ * Results:
+ * None.
+ *
+ * This procedure carries out no operation on Unix.
+ *
+ *----------------------------------------------------------------------
+ */
+
+void
+TclpFinalizePipes()
+{
+}
+
diff --git a/win/tclWinPipe.c b/win/tclWinPipe.c
index 34ed29f..8782f5e 100644
--- a/win/tclWinPipe.c
+++ b/win/tclWinPipe.c
@@ -9,7 +9,7 @@
* See the file "license.terms" for information on usage and redistribution
* of this file, and for a DISCLAIMER OF ALL WARRANTIES.
*
- * RCS: @(#) $Id: tclWinPipe.c,v 1.55 2005/05/10 18:35:40 kennykb Exp $
+ * RCS: @(#) $Id: tclWinPipe.c,v 1.56 2005/06/22 19:48:11 kennykb Exp $
*/
#include "tclWinInt.h"
@@ -201,7 +201,6 @@ static DWORD WINAPI PipeReaderThread(LPVOID arg);
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 @@ PipeInit()
if (!initialized) {
initialized = 1;
procList = NULL;
- Tcl_CreateExitHandler(ProcExitHandler, NULL);
}
Tcl_MutexUnlock(&pipeMutex);
}
@@ -304,7 +302,7 @@ PipeExitHandler(
/*
*----------------------------------------------------------------------
*
- * ProcExitHandler --
+ * TclpFinalizePipes --
*
* This function is called to cleanup the process list before
* Tcl is unloaded.
@@ -318,9 +316,8 @@ PipeExitHandler(
*----------------------------------------------------------------------
*/
-static void
-ProcExitHandler(
- ClientData clientData) /* Old window proc */
+void
+TclpFinalizePipes()
{
Tcl_MutexLock(&pipeMutex);
initialized = 0;