diff --git a/greenlet.c b/greenlet.c index c60199a9..b5e3e173 100644 --- a/greenlet.c +++ b/greenlet.c @@ -479,13 +479,13 @@ g_switch(PyGreenlet* target, PyObject* args, PyObject* kwargs) /* check ts_current */ if (!STATE_OK) { - Py_DECREF(args); + Py_XDECREF(args); Py_XDECREF(kwargs); return NULL; } run_info = green_statedict(target); if (run_info == NULL || run_info != ts_current->run_info) { - Py_DECREF(args); + Py_XDECREF(args); Py_XDECREF(kwargs); PyErr_SetString(PyExc_GreenletError, run_info ? "cannot switch to a different thread" diff --git a/tests/test_greenlet.py b/tests/test_greenlet.py index 8fb60191..d151d00b 100644 --- a/tests/test_greenlet.py +++ b/tests/test_greenlet.py @@ -331,3 +331,16 @@ def __getattribute__(self, name): return greenlet.__getattribute__(self, name) g = mygreenlet(lambda: None) self.assertRaises(SomeError, g.throw, SomeError()) + + def test_throw_doesnt_crash(self): + result = [] + def worker(): + greenlet.getcurrent().parent.switch() + def creator(): + g = greenlet(worker) + g.switch() + result.append(g) + t = threading.Thread(target=creator) + t.start() + t.join() + self.assertRaises(greenlet.error, result[0].throw, SomeError())