Index: generic/tclEncoding.c
===================================================================
RCS file: /cvsroot/tcl/tcl/generic/tclEncoding.c,v
retrieving revision 1.59.2.1
diff -u -p -u -p -r1.59.2.1 tclEncoding.c
--- generic/tclEncoding.c	4 Jul 2008 19:22:21 -0000	1.59.2.1
+++ generic/tclEncoding.c	16 Nov 2009 10:57:59 -0000
@@ -845,6 +845,9 @@ FreeEncoding(
     if (encodingPtr == NULL) {
 	return;
     }
+    if (encodingPtr->refCount<=0) {
+	Tcl_Panic("FreeEncoding: refcount problem !!!");
+    }
     encodingPtr->refCount--;
     if (encodingPtr->refCount == 0) {
 	if (encodingPtr->freeProc != NULL) {
@@ -3393,11 +3396,24 @@ EscapeFreeProc(
     if (dataPtr == NULL) {
 	return;
     }
-    subTablePtr = dataPtr->subTables;
-    for (i = 0; i < dataPtr->numSubTables; i++) {
-	FreeEncoding((Tcl_Encoding) subTablePtr->encodingPtr);
-	subTablePtr++;
-    }
+    /*
+     *  The subTables should be freed recursively in normal operation but not
+     *  during TclFinalizeEncodingSubsystem because they are also present as a
+     *  weak reference in the toplevel encodingTable (ie they don't have a +1
+     *  refcount for this), and unpredictable nuking order could remove them
+     *  from under the following loop's feet [Bug 2891556].
+     *  
+     *  The encodingsInitialized flag, being reset on entry to TFES, can serve
+     *  as a "not in finalization" test.
+     */
+    if (encodingsInitialized)
+	{
+	    subTablePtr = dataPtr->subTables;
+	    for (i = 0; i < dataPtr->numSubTables; i++) {
+		FreeEncoding((Tcl_Encoding) subTablePtr->encodingPtr);
+		subTablePtr++;
+	    }
+	}
     ckfree((char *) dataPtr);
 }
 
Index: tests/encoding.test
===================================================================
RCS file: /cvsroot/tcl/tcl/tests/encoding.test,v
retrieving revision 1.27.4.1
diff -u -p -u -p -r1.27.4.1 encoding.test
--- tests/encoding.test	22 Jul 2008 03:34:30 -0000	1.27.4.1
+++ tests/encoding.test	16 Nov 2009 10:58:00 -0000
@@ -414,6 +414,7 @@ test encoding-24.2 {EscapeFreeProc on op
 } -setup {
     # Bug #524674 output
     set file [makeFile {
+	encoding system cp1252;	# Bug #2891556 crash revelator
 	fconfigure stdout -encoding iso2022-jp
 	puts ab\u4e4e\u68d9g
 	exit
