Skip to content

Commit b12af0a

Browse files
gh-131401: fix data races in exception handling (#131447)
1 parent f141e8e commit b12af0a

File tree

2 files changed

+18
-13
lines changed

2 files changed

+18
-13
lines changed

Python/ceval.c

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -3120,7 +3120,7 @@ _PyEval_FormatKwargsError(PyThreadState *tstate, PyObject *func, PyObject *kwarg
31203120
}
31213121
else if (_PyErr_ExceptionMatches(tstate, PyExc_KeyError)) {
31223122
PyObject *exc = _PyErr_GetRaisedException(tstate);
3123-
PyObject *args = ((PyBaseExceptionObject *)exc)->args;
3123+
PyObject *args = PyException_GetArgs(exc);
31243124
if (exc && PyTuple_Check(args) && PyTuple_GET_SIZE(args) == 1) {
31253125
_PyErr_Clear(tstate);
31263126
PyObject *funcstr = _PyObject_FunctionStr(func);
@@ -3137,6 +3137,7 @@ _PyEval_FormatKwargsError(PyThreadState *tstate, PyObject *func, PyObject *kwarg
31373137
else {
31383138
_PyErr_SetRaisedException(tstate, exc);
31393139
}
3140+
Py_DECREF(args);
31403141
}
31413142
}
31423143

Python/errors.c

Lines changed: 16 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -517,7 +517,7 @@ _PyErr_Fetch(PyThreadState *tstate, PyObject **p_type, PyObject **p_value,
517517
}
518518
else {
519519
*p_type = Py_NewRef(Py_TYPE(exc));
520-
*p_traceback = Py_XNewRef(((PyBaseExceptionObject *)exc)->traceback);
520+
*p_traceback = PyException_GetTraceback(exc);
521521
}
522522
}
523523

@@ -545,7 +545,7 @@ PyErr_Clear(void)
545545
}
546546

547547
static PyObject*
548-
get_exc_type(PyObject *exc_value) /* returns a borrowed ref */
548+
get_exc_type(PyObject *exc_value) /* returns a strong ref */
549549
{
550550
if (exc_value == NULL || exc_value == Py_None) {
551551
return Py_None;
@@ -554,20 +554,19 @@ get_exc_type(PyObject *exc_value) /* returns a borrowed ref */
554554
assert(PyExceptionInstance_Check(exc_value));
555555
PyObject *type = PyExceptionInstance_Class(exc_value);
556556
assert(type != NULL);
557-
return type;
557+
return Py_NewRef(type);
558558
}
559559
}
560560

561561
static PyObject*
562-
get_exc_traceback(PyObject *exc_value) /* returns a borrowed ref */
562+
get_exc_traceback(PyObject *exc_value) /* returns a strong ref */
563563
{
564564
if (exc_value == NULL || exc_value == Py_None) {
565565
return Py_None;
566566
}
567567
else {
568568
assert(PyExceptionInstance_Check(exc_value));
569569
PyObject *tb = PyException_GetTraceback(exc_value);
570-
Py_XDECREF(tb);
571570
return tb ? tb : Py_None;
572571
}
573572
}
@@ -578,9 +577,9 @@ _PyErr_GetExcInfo(PyThreadState *tstate,
578577
{
579578
_PyErr_StackItem *exc_info = _PyErr_GetTopmostException(tstate);
580579

581-
*p_type = Py_XNewRef(get_exc_type(exc_info->exc_value));
580+
*p_type = get_exc_type(exc_info->exc_value);
582581
*p_value = Py_XNewRef(exc_info->exc_value);
583-
*p_traceback = Py_XNewRef(get_exc_traceback(exc_info->exc_value));
582+
*p_traceback = get_exc_traceback(exc_info->exc_value);
584583
}
585584

586585
PyObject*
@@ -641,14 +640,19 @@ _PyErr_StackItemToExcInfoTuple(_PyErr_StackItem *err_info)
641640
exc_value == Py_None ||
642641
PyExceptionInstance_Check(exc_value));
643642

643+
PyObject *ret = PyTuple_New(3);
644+
if (ret == NULL) {
645+
return NULL;
646+
}
647+
644648
PyObject *exc_type = get_exc_type(exc_value);
645649
PyObject *exc_traceback = get_exc_traceback(exc_value);
646650

647-
return PyTuple_Pack(
648-
3,
649-
exc_type ? exc_type : Py_None,
650-
exc_value ? exc_value : Py_None,
651-
exc_traceback ? exc_traceback : Py_None);
651+
PyTuple_SET_ITEM(ret, 0, exc_type ? exc_type : Py_None);
652+
PyTuple_SET_ITEM(ret, 1, exc_value ? Py_NewRef(exc_value) : Py_None);
653+
PyTuple_SET_ITEM(ret, 2, exc_traceback ? exc_traceback : Py_None);
654+
655+
return ret;
652656
}
653657

654658

0 commit comments

Comments
 (0)