Skip to content

Commit 2b72d38

Browse files
committed
pythongh-129824: Fix data races in type_ready with subinterpreters
Also add test_interpreters to the list of TSAN tests. The test_running and test_is_running test cases are skipped for now as they have file descriptor races.
1 parent 4162bc1 commit 2b72d38

File tree

3 files changed

+19
-6
lines changed

3 files changed

+19
-6
lines changed

Lib/test/test_interpreters/test_api.py

+2
Original file line numberDiff line numberDiff line change
@@ -703,6 +703,7 @@ def test_not_shareable(self):
703703
with self.assertRaises(ExecutionFailed):
704704
interp.exec('print(spam)')
705705

706+
@support.skip_if_sanitizer('gh-129824: file descriptor race', thread=True)
706707
def test_running(self):
707708
interp = interpreters.create()
708709
interp.prepare_main({'spam': True})
@@ -1530,6 +1531,7 @@ def test_whence(self):
15301531
whence = eval(text)
15311532
self.assertEqual(whence, _interpreters.WHENCE_LEGACY_CAPI)
15321533

1534+
@support.skip_if_sanitizer('gh-129824: file descriptor race', thread=True)
15331535
def test_is_running(self):
15341536
def check(interpid, expected):
15351537
with self.assertRaisesRegex(InterpreterError, 'unrecognized'):

Objects/exceptions.c

+2-1
Original file line numberDiff line numberDiff line change
@@ -4350,7 +4350,8 @@ _PyExc_InitTypes(PyInterpreterState *interp)
43504350
return -1;
43514351
}
43524352
if (exc->tp_new == BaseException_new
4353-
&& exc->tp_init == BaseException_init)
4353+
&& exc->tp_init == BaseException_init
4354+
&& _Py_IsMainInterpreter(interp))
43544355
{
43554356
exc->tp_vectorcall = BaseException_vectorcall;
43564357
}

Objects/typeobject.c

+15-5
Original file line numberDiff line numberDiff line change
@@ -235,10 +235,10 @@ managed_static_type_state_init(PyInterpreterState *interp, PyTypeObject *self,
235235
? index
236236
: index + _Py_MAX_MANAGED_STATIC_BUILTIN_TYPES;
237237

238-
assert((initial == 1) ==
239-
(_PyRuntime.types.managed_static.types[full_index].interp_count == 0));
240-
(void)_Py_atomic_add_int64(
238+
int64_t prev_interp_count = _Py_atomic_add_int64(
241239
&_PyRuntime.types.managed_static.types[full_index].interp_count, 1);
240+
assert((initial == 1) == (prev_interp_count == 0));
241+
(void)prev_interp_count;
242242

243243
if (initial) {
244244
assert(_PyRuntime.types.managed_static.types[full_index].type == NULL);
@@ -8581,12 +8581,22 @@ type_ready_set_new(PyTypeObject *type, int initial)
85818581
}
85828582
else {
85838583
// tp_new is NULL: inherit tp_new from base
8584-
type->tp_new = base->tp_new;
8584+
if (initial) {
8585+
type->tp_new = base->tp_new;
8586+
}
8587+
else {
8588+
assert(type->tp_new == base->tp_new);
8589+
}
85858590
}
85868591
}
85878592
else {
85888593
// Py_TPFLAGS_DISALLOW_INSTANTIATION sets tp_new to NULL
8589-
type->tp_new = NULL;
8594+
if (initial) {
8595+
type->tp_new = NULL;
8596+
}
8597+
else {
8598+
assert(type->tp_new == NULL);
8599+
}
85908600
}
85918601
return 0;
85928602
}

0 commit comments

Comments
 (0)