Two more refinements of the cleanup process.

(1) Explicitly clear __builtin__._ and sys.{last,exc}_* before
clearing anything else.  These are common places where user values
hide and people complain when their destructors fail.  Since the
modules containing them are deleted *last* of all, they would come too
late in the normal destruction order.  Sigh.

(2) Add some debugging aid to cleanup (after a suggestion by Marc
Lemburg) -- print the names of the modules being cleaned, and (when
-vv is used) print the names of the variables being cleared.
diff --git a/Python/import.c b/Python/import.c
index 224a3bc..9dbbd25 100644
--- a/Python/import.c
+++ b/Python/import.c
@@ -148,8 +148,11 @@
 	while (PyDict_Next(d, &pos, &key, &value)) {
 		if (value != Py_None && PyString_Check(key)) {
 			char *s = PyString_AsString(key);
-			if (s[0] == '_' && s[1] != '_')
+			if (s[0] == '_' && s[1] != '_') {
+				if (Py_VerboseFlag > 1)
+				    fprintf(stderr, "#   clear[1] %s\n", s);
 				PyDict_SetItem(d, key, Py_None);
+			}
 		}
 	}
 
@@ -158,8 +161,11 @@
 	while (PyDict_Next(d, &pos, &key, &value)) {
 		if (value != Py_None && PyString_Check(key)) {
 			char *s = PyString_AsString(key);
-			if (s[0] != '_' || s[1] != '_')
+			if (s[0] != '_' || s[1] != '_') {
+				if (Py_VerboseFlag > 1)
+				    fprintf(stderr, "#   clear[2] %s\n", s);
 				PyDict_SetItem(d, key, Py_None);
+			}
 		}
 	}
 
@@ -169,6 +175,14 @@
 }
 
 
+/* List of names to clear in sys */
+static char* sys_deletes[] = {
+	"exc_type", "exc_value", "exc_traceback",
+	"last_type", "last_value", "last_traceback",
+	NULL
+};
+
+
 /* Un-initialize things, as good as we can */
 
 void
@@ -183,6 +197,30 @@
 	if (modules == NULL)
 		return; /* Already done */
 
+	/* Delete some special variables first.  These are common
+	   places where user values hide and people complain when their
+	   destructors fail.  Since the modules containing them are
+	   deleted *last* of all, they would come too late in the normal
+	   destruction order.  Sigh. */
+
+	value = PyDict_GetItemString(modules, "__builtin__");
+	if (value != NULL && PyModule_Check(value)) {
+		dict = PyModule_GetDict(value);
+		if (Py_VerboseFlag)
+			fprintf(stderr, "# clear __builtin__._\n");
+		PyDict_SetItemString(dict, "_", Py_None);
+	}
+	value = PyDict_GetItemString(modules, "sys");
+	if (value != NULL && PyModule_Check(value)) {
+		char **p;
+		dict = PyModule_GetDict(value);
+		for (p = sys_deletes; *p != NULL; p++) {
+			if (Py_VerboseFlag)
+				fprintf(stderr, "# clear sys.%s\n", *p);
+			PyDict_SetItemString(dict, *p, Py_None);
+		}
+	}
+
 	/* The special treatment of __builtin__ here is because even
 	   when it's not referenced as a module, its dictionary is
 	   referenced by almost every module's __builtins__.  Since
@@ -212,6 +250,9 @@
 					continue;
 				if (strcmp(name, "sys") == 0)
 					continue;
+				if (Py_VerboseFlag)
+					fprintf(stderr,
+						"# cleanup[1] %s\n", name);
 				clear_carefully(dict);
 				PyDict_SetItem(modules, key, Py_None);
 				ndone++;
@@ -223,6 +264,8 @@
 	value = PyDict_GetItemString(modules, "__main__");
 	if (value != NULL && PyModule_Check(value)) {
 		dict = PyModule_GetDict(value);
+		if (Py_VerboseFlag)
+			fprintf(stderr, "# cleanup __main__\n");
 		clear_carefully(dict);
 		PyDict_SetItemString(modules, "__main__", Py_None);
 	}
@@ -237,6 +280,8 @@
 				continue;
 			if (strcmp(name, "sys") == 0)
 				continue;
+			if (Py_VerboseFlag)
+				fprintf(stderr, "# cleanup[2] %s\n", name);
 			clear_carefully(dict);
 			PyDict_SetItem(modules, key, Py_None);
 		}
@@ -246,13 +291,17 @@
 	value = PyDict_GetItemString(modules, "sys");
 	if (value != NULL && PyModule_Check(value)) {
 		dict = PyModule_GetDict(value);
+		if (Py_VerboseFlag)
+			fprintf(stderr, "# cleanup sys\n");
 		clear_carefully(dict);
 		PyDict_SetItemString(modules, "sys", Py_None);
 	}
 	value = PyDict_GetItemString(modules, "__builtin__");
 	if (value != NULL && PyModule_Check(value)) {
 		dict = PyModule_GetDict(value);
-		clear_carefully(dict);
+		if (Py_VerboseFlag)
+			fprintf(stderr, "# cleanup __builtin__\n");
+		clear_carefully(dict); /* XXX Is this necessary? */
 		PyDict_SetItemString(modules, "__builtin__", Py_None);
 	}