From 66aa6453d641cfce82108825f9e9e29654851cb8 Mon Sep 17 00:00:00 2001 From: Chris Jerdonek Date: Sat, 2 May 2020 21:12:48 -0700 Subject: [PATCH 1/2] Remove the exc_value NULL check and add a failing test. --- Lib/test/test_generators.py | 19 +++++++++++++++++++ Objects/genobject.c | 6 ++---- 2 files changed, 21 insertions(+), 4 deletions(-) diff --git a/Lib/test/test_generators.py b/Lib/test/test_generators.py index 4d96f44b150622..ccd13ff42b59b9 100644 --- a/Lib/test/test_generators.py +++ b/Lib/test/test_generators.py @@ -332,6 +332,25 @@ def f(): context = cm.exception.__context__ self.assertEqual((type(context), context.args), (KeyError, ('a',))) + def test_throw_after_none_exc_type(self): + def g(): + try: + raise KeyError + except KeyError: + pass + + try: + yield + except Exception: + # This line causes a crash ("Segmentation fault (core dumped)") + # on e.g. Fedora 32. + raise RuntimeError + + gen = g() + gen.send(None) + with self.assertRaises(RuntimeError) as cm: + gen.throw(ValueError) + class YieldFromTests(unittest.TestCase): def test_generator_gi_yieldfrom(self): diff --git a/Objects/genobject.c b/Objects/genobject.c index 41a63ae2e666aa..65ad9d4d3d07b0 100644 --- a/Objects/genobject.c +++ b/Objects/genobject.c @@ -512,11 +512,9 @@ _gen_throw(PyGenObject *gen, int close_on_genexit, } PyErr_Restore(typ, val, tb); - /* XXX Should we also handle the case where exc_type is true and - exc_value is false? */ - if (gen->gi_exc_state.exc_type && gen->gi_exc_state.exc_value) { + if (gen->gi_exc_state.exc_type) { Py_INCREF(gen->gi_exc_state.exc_type); - Py_INCREF(gen->gi_exc_state.exc_value); + Py_XINCREF(gen->gi_exc_state.exc_value); Py_XINCREF(gen->gi_exc_state.exc_traceback); _PyErr_ChainExceptions(gen->gi_exc_state.exc_type, gen->gi_exc_state.exc_value, gen->gi_exc_state.exc_traceback); From 66ae854acbeacc30553e20812b50d9f731bec3a7 Mon Sep 17 00:00:00 2001 From: Chris Jerdonek Date: Sat, 2 May 2020 21:20:18 -0700 Subject: [PATCH 2/2] Check that exc_type doesn't equal Py_None. --- Lib/test/test_generators.py | 5 +++-- Objects/genobject.c | 5 ++++- 2 files changed, 7 insertions(+), 3 deletions(-) diff --git a/Lib/test/test_generators.py b/Lib/test/test_generators.py index ccd13ff42b59b9..5824ecd7c37e88 100644 --- a/Lib/test/test_generators.py +++ b/Lib/test/test_generators.py @@ -342,8 +342,9 @@ def g(): try: yield except Exception: - # This line causes a crash ("Segmentation fault (core dumped)") - # on e.g. Fedora 32. + # Without the `gi_exc_state.exc_type != Py_None` in + # _gen_throw(), this line was causing a crash ("Segmentation + # fault (core dumped)") on e.g. Fedora 32. raise RuntimeError gen = g() diff --git a/Objects/genobject.c b/Objects/genobject.c index 65ad9d4d3d07b0..b27fa929a26258 100644 --- a/Objects/genobject.c +++ b/Objects/genobject.c @@ -512,7 +512,10 @@ _gen_throw(PyGenObject *gen, int close_on_genexit, } PyErr_Restore(typ, val, tb); - if (gen->gi_exc_state.exc_type) { + /* XXX It seems like we shouldn't have to check not equal to Py_None + here because exc_type should only ever be a class. But not including + this check was causing crashes on certain tests e.g. on Fedora. */ + if (gen->gi_exc_state.exc_type && gen->gi_exc_state.exc_type != Py_None) { Py_INCREF(gen->gi_exc_state.exc_type); Py_XINCREF(gen->gi_exc_state.exc_value); Py_XINCREF(gen->gi_exc_state.exc_traceback); pFad - Phonifier reborn

Pfad - The Proxy pFad of © 2024 Garber Painting. All rights reserved.

Note: This service is not intended for secure transactions such as banking, social media, email, or purchasing. Use at your own risk. We assume no liability whatsoever for broken pages.


Alternative Proxies:

Alternative Proxy

pFad Proxy

pFad v3 Proxy

pFad v4 Proxy