[Python-checkins] [3.6] bpo-32591: fix abort in _PyErr_WarnUnawaitedCoroutine during shutdown (GH-5337) (#6536)

T. Wouters webhook-mailer at python.org
Thu May 31 06:20:50 EDT 2018


https://github.com/python/cpython/commit/500a419a7a68c32650717b213f0f5ab0461bb16b
commit: 500a419a7a68c32650717b213f0f5ab0461bb16b
branch: 3.6
author: T. Wouters <thomas at python.org>
committer: GitHub <noreply at github.com>
date: 2018-05-31T12:20:46+02:00
summary:

[3.6] bpo-32591: fix abort in _PyErr_WarnUnawaitedCoroutine during shutdown (GH-5337) (#6536)

When an unawaited coroutine is collected very late in shutdown --
like, during the final GC at the end of PyImport_Cleanup -- then it
was triggering an interpreter abort, because we'd try to look up the
"warnings" module and not only was it missing (we were prepared for
that), but the entire module system was missing (which we were not
prepared for).

I've tried to fix this at the source, by making the utility function
get_warnings_attr robust against this in general. Note that it already
has the convention that it can return NULL without setting an error,
which is how it signals that the attribute it was asked to fetch is
missing, and that all callers already check for NULL returns.

There's a similar check for being late in shutdown at the top of
warn_explicit, which might be unnecessary after this fix, but I'm not
sure so I'm going to leave it..
(cherry picked from commit dba976b8a28d6e5daa66ef31a6a7c694a9193f6a)

Co-authored-by: Nathaniel J. Smith <njs at pobox.com>

files:
M Python/_warnings.c

diff --git a/Python/_warnings.c b/Python/_warnings.c
index 0077b9b1c3d0..e96e154b0d54 100644
--- a/Python/_warnings.c
+++ b/Python/_warnings.c
@@ -63,6 +63,13 @@ get_warnings_attr(const char *attr, int try_import)
         }
     }
     else {
+        /* if we're so late into Python finalization that the module dict is
+           gone, then we can't even use PyImport_GetModule without triggering
+           an interpreter abort.
+        */
+        if (!PyThreadState_GET()->interp->modules) {
+            return NULL;
+        }
         all_modules = PyImport_GetModuleDict();
 
         warnings_module = PyDict_GetItem(all_modules, warnings_str);



More information about the Python-checkins mailing list