Skip to content

gh-117657: Fix some races in tracebacks #121748

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Open
wants to merge 6 commits into
base: main
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
61 changes: 61 additions & 0 deletions Objects/clinic/exceptions.c.h

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

38 changes: 30 additions & 8 deletions Objects/exceptions.c
Original file line number Diff line number Diff line change
Expand Up @@ -16,6 +16,12 @@

#include "osdefs.h" // SEP

#include "clinic/exceptions.c.h"

/*[clinic input]
class BaseException "PyBaseExceptionObject *" "&PyExc_BaseException"
[clinic start generated code]*/
/*[clinic end generated code: output=da39a3ee5e6b4b0d input=90558eb0fbf8a3d0]*/

/* Compatibility aliases */
PyObject *PyExc_EnvironmentError = NULL; // borrowed ref
Expand Down Expand Up @@ -307,26 +313,41 @@ BaseException_set_args(PyBaseExceptionObject *self, PyObject *val, void *Py_UNUS
return 0;
}

/*[clinic input]
@critical_section
@getter
BaseException.__traceback__
[clinic start generated code]*/

static PyObject *
BaseException_get_tb(PyBaseExceptionObject *self, void *Py_UNUSED(ignored))
BaseException___traceback___get_impl(PyBaseExceptionObject *self)
/*[clinic end generated code: output=17cf874a52339398 input=a2277f0de62170cf]*/
{
if (self->traceback == NULL) {
Py_RETURN_NONE;
}
return Py_NewRef(self->traceback);
}

/*[clinic input]
@critical_section
@setter
BaseException.__traceback__
[clinic start generated code]*/

static int
BaseException_set_tb(PyBaseExceptionObject *self, PyObject *tb, void *Py_UNUSED(ignored))
BaseException___traceback___set_impl(PyBaseExceptionObject *self,
PyObject *value)
/*[clinic end generated code: output=a82c86d9f29f48f0 input=12676035676badad]*/
{
if (tb == NULL) {
if (value == NULL) {
PyErr_SetString(PyExc_TypeError, "__traceback__ may not be deleted");
return -1;
}
if (PyTraceBack_Check(tb)) {
Py_XSETREF(self->traceback, Py_NewRef(tb));
if (PyTraceBack_Check(value)) {
Py_XSETREF(self->traceback, Py_NewRef(value));
}
else if (tb == Py_None) {
else if (value == Py_None) {
Py_CLEAR(self->traceback);
}
else {
Expand All @@ -337,6 +358,7 @@ BaseException_set_tb(PyBaseExceptionObject *self, PyObject *tb, void *Py_UNUSED(
return 0;
}


static PyObject *
BaseException_get_context(PyObject *self, void *Py_UNUSED(ignored))
{
Expand Down Expand Up @@ -399,7 +421,7 @@ BaseException_set_cause(PyObject *self, PyObject *arg, void *Py_UNUSED(ignored))
static PyGetSetDef BaseException_getset[] = {
{"__dict__", PyObject_GenericGetDict, PyObject_GenericSetDict},
{"args", (getter)BaseException_get_args, (setter)BaseException_set_args},
{"__traceback__", (getter)BaseException_get_tb, (setter)BaseException_set_tb},
BASEEXCEPTION___TRACEBACK___GETSETDEF
{"__context__", BaseException_get_context,
BaseException_set_context, PyDoc_STR("exception context")},
{"__cause__", BaseException_get_cause,
Expand All @@ -419,7 +441,7 @@ PyException_GetTraceback(PyObject *self)
int
PyException_SetTraceback(PyObject *self, PyObject *tb)
{
return BaseException_set_tb(_PyBaseExceptionObject_cast(self), tb, NULL);
return BaseException___traceback___set_impl(_PyBaseExceptionObject_cast(self), tb);
}

PyObject *
Expand Down
Loading