Skip to content

Commit 18e0bcb

Browse files
vstinnerngoldbaum
andauthored
[3.15] gh-157415: Fix data race in pthread wrapper (#157430) (#159277)
gh-157415: Fix data race in pthread wrapper (#157430) Use free() instead of PyMem_RawFree() in pythread_wrapper() to avoid a data race if another thread calls PyMem_SetAllocator() in parallel. Reenable @nomemtest tests on TSAN. (cherry picked from commit d1878cc) Co-authored-by: Nathan Goldbaum <nathan.goldbaum@gmail.com>
1 parent 689c420 commit 18e0bcb

2 files changed

Lines changed: 6 additions & 9 deletions

File tree

‎Lib/test/support/__init__.py‎

Lines changed: 1 addition & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -1314,12 +1314,7 @@ def internal(*args, **kwargs):
13141314
import_module('_testcapi')
13151315
return f(*args, **kwargs)
13161316

1317-
return unittest.skipIf(
1318-
# Python built with Py_TRACE_REFS fail with a fatal error in
1319-
# _PyRefchain_Trace() on memory allocation error.
1320-
Py_TRACE_REFS,
1321-
'cannot test Py_TRACE_REFS build',
1322-
)(cpython_only(internal))
1317+
return cpython_only(internal)
13231318

13241319
def bigaddrspacetest(f):
13251320
"""Decorator for tests that fill the address space."""

‎Python/thread_pthread.h‎

Lines changed: 5 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -229,7 +229,7 @@ pythread_wrapper(void *arg)
229229
pythread_callback *callback = arg;
230230
void (*func)(void *) = callback->func;
231231
void *func_arg = callback->arg;
232-
PyMem_RawFree(arg);
232+
free(callback);
233233

234234
func(func_arg);
235235
return NULL;
@@ -269,7 +269,9 @@ do_start_joinable_thread(void (*func)(void *), void *arg, pthread_t* out_id)
269269
pthread_attr_setscope(&attrs, PTHREAD_SCOPE_SYSTEM);
270270
#endif
271271

272-
pythread_callback *callback = PyMem_RawMalloc(sizeof(pythread_callback));
272+
// Use free() instead of PyMem_RawFree() in pythread_wrapper() to avoid a
273+
// data race if another thread calls PyMem_SetAllocator() in parallel.
274+
pythread_callback *callback = malloc(sizeof(pythread_callback));
273275

274276
if (callback == NULL) {
275277
return -1;
@@ -291,7 +293,7 @@ do_start_joinable_thread(void (*func)(void *), void *arg, pthread_t* out_id)
291293
#endif
292294

293295
if (status != 0) {
294-
PyMem_RawFree(callback);
296+
free(callback);
295297
return -1;
296298
}
297299
*out_id = th;

0 commit comments

Comments
 (0)