refactor __del__ exception handler into PyErr_WriteUnraisable
add sanity check to gc: if an exception occurs during GC, call
PyErr_WriteUnraisable and then call Py_FatalEror.
diff --git a/Modules/gcmodule.c b/Modules/gcmodule.c
index 57ee7b9..889ae25 100644
--- a/Modules/gcmodule.c
+++ b/Modules/gcmodule.c
@@ -57,11 +57,13 @@
DEBUG_UNCOLLECTABLE | \
DEBUG_INSTANCES | \
DEBUG_OBJECTS
-static int debug = 0;
+static int debug;
/* list of uncollectable objects */
static PyObject *garbage;
+/* Python string to use if unhandled exception occurs */
+static PyObject *gc_str;
/*** list functions ***/
@@ -435,6 +437,10 @@
* this if they insist on creating this type of structure. */
handle_finalizers(&finalizers, old);
+ if (PyErr_Occurred()) {
+ PyErr_WriteUnraisable(gc_str);
+ Py_FatalError("unexpected exception during garbage collection");
+ }
allocated = 0;
return n+m;
}
@@ -699,6 +705,9 @@
if (garbage == NULL) {
garbage = PyList_New(0);
}
+ if (gc_str == NULL) {
+ gc_str = PyString_FromString("garbage collection");
+ }
PyDict_SetItemString(d, "garbage", garbage);
PyDict_SetItemString(d, "DEBUG_STATS",
PyInt_FromLong(DEBUG_STATS));