Skip to content

Commit 827ef12

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 043ab3a commit 827ef12

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
@@ -4321,7 +4321,8 @@ _PyExc_InitTypes(PyInterpreterState *interp)
43214321
return -1;
43224322
}
43234323
if (exc->tp_new == BaseException_new
4324-
&& exc->tp_init == BaseException_init)
4324+
&& exc->tp_init == BaseException_init
4325+
&& _Py_IsMainInterpreter(interp))
43254326
{
43264327
exc->tp_vectorcall = BaseException_vectorcall;
43274328
}

Objects/typeobject.c

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

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

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

0 commit comments

Comments
 (0)