[Python-checkins] [2.7] bpo-33622: Fix issues with handling errors in the GC. (GH-7078) (#7096)

Serhiy Storchaka webhook-mailer at python.org
Thu May 24 16:27:12 EDT 2018


https://github.com/python/cpython/commit/9044cd675902b438bc500908e410382ff48299d8
commit: 9044cd675902b438bc500908e410382ff48299d8
branch: 2.7
author: Serhiy Storchaka <storchaka at gmail.com>
committer: GitHub <noreply at github.com>
date: 2018年05月24日T23:27:08+03:00
summary:
[2.7] bpo-33622: Fix issues with handling errors in the GC. (GH-7078) (#7096)
* Fixed a leak when the GC fails to add an object with __del__ into
 the gc.garbage list.
* PyGC_Collect() can now be called when an exception is set and
 preserves it.
(cherry picked from commit 301e3cc8a5bc68c5347ab6ac6f83428000d31ab2)
files:
A Misc/NEWS.d/next/Core and Builtins/2018-05-23-20-46-14.bpo-33622.xPucO9.rst
M Modules/gcmodule.c
diff --git a/Misc/NEWS.d/next/Core and Builtins/2018-05-23-20-46-14.bpo-33622.xPucO9.rst b/Misc/NEWS.d/next/Core and Builtins/2018-05-23-20-46-14.bpo-33622.xPucO9.rst
new file mode 100644
index 000000000000..e589b4503229
--- /dev/null
+++ b/Misc/NEWS.d/next/Core and Builtins/2018-05-23-20-46-14.bpo-33622.xPucO9.rst	
@@ -0,0 +1,4 @@
+Fixed a leak when the garbage collector fails to add an object with the
+``__del__`` method or referenced by it into the :data:`gc.garbage` list.
+:c:func:`PyGC_Collect` can now be called when an exception is set and
+preserves it.
diff --git a/Modules/gcmodule.c b/Modules/gcmodule.c
index 19011c47b5c4..700c1a32b079 100644
--- a/Modules/gcmodule.c
+++ b/Modules/gcmodule.c
@@ -771,10 +771,8 @@ debug_cycle(char *msg, PyObject *op)
 * garbage list (a Python list), else only the objects in finalizers with
 * __del__ methods are appended to garbage. All objects in finalizers are
 * merged into the old list regardless.
- * Returns 0 if all OK, <0 on error (out of memory to grow the garbage list).
- * The finalizers list is made empty on a successful return.
 */
-static int
+static void
 handle_finalizers(PyGC_Head *finalizers, PyGC_Head *old)
 {
 PyGC_Head *gc = finalizers->gc.gc_next;
@@ -789,12 +787,11 @@ handle_finalizers(PyGC_Head *finalizers, PyGC_Head *old)
 
 if ((debug & DEBUG_SAVEALL) || has_finalizer(op)) {
 if (PyList_Append(garbage, op) < 0)
- return -1;
+ break;
 }
 }
 
 gc_list_merge(finalizers, old);
- return 0;
 }
 
 /* Break reference cycles by clearing the containers involved. This is
@@ -1012,7 +1009,7 @@ collect(int generation)
 * reachable list of garbage. The programmer has to deal with
 * this if they insist on creating this type of structure.
 */
- (void)handle_finalizers(&finalizers, old);
+ handle_finalizers(&finalizers, old);
 
 /* Clear free list only during the collection of the highest
 * generation */
@@ -1436,8 +1433,11 @@ PyGC_Collect(void)
 if (collecting)
 n = 0; /* already collecting, don't do anything */
 else {
+ PyObject *exc, *value, *tb;
 collecting = 1;
+ PyErr_Fetch(&exc, &value, &tb);
 n = collect(NUM_GENERATIONS - 1);
+ PyErr_Restore(exc, value, tb);
 collecting = 0;
 }
 


More information about the Python-checkins mailing list

AltStyle によって変換されたページ (->オリジナル) /