Skip to content

Commit 8f58d77

Browse files
committed
pythongh-128679: Fix tracemalloc.stop() race condition
Check again 'tracemalloc_config.tracing' once the GIL is held in tracemalloc_raw_alloc() and PyTraceMalloc_Track(), since another thread can call tracemalloc.stop() during PyGILState_Ensure() call.
1 parent 802556a commit 8f58d77

File tree

2 files changed

+24
-4
lines changed

2 files changed

+24
-4
lines changed
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,3 @@
1+
Fix :func:`tracemalloc.stop` race condition. Fix :mod:`tracemalloc` to
2+
support calling :func:`tracemalloc.stop` in one thread, while another thread
3+
is tracing memory allocations. Patch by Victor Stinner.

Python/tracemalloc.c

+21-4
Original file line numberDiff line numberDiff line change
@@ -712,7 +712,18 @@ tracemalloc_raw_alloc(int use_calloc, void *ctx, size_t nelem, size_t elsize)
712712
set_reentrant(1);
713713

714714
gil_state = PyGILState_Ensure();
715-
ptr = tracemalloc_alloc(use_calloc, ctx, nelem, elsize);
715+
if (tracemalloc_config.tracing) {
716+
ptr = tracemalloc_alloc(use_calloc, ctx, nelem, elsize);
717+
}
718+
else {
719+
// gh-128679: tracemalloc.stop() was called by another thread during
720+
// PyGILState_Ensure() call.
721+
PyMemAllocatorEx *alloc = (PyMemAllocatorEx *)ctx;
722+
if (use_calloc)
723+
ptr = alloc->calloc(alloc->ctx, nelem, elsize);
724+
else
725+
ptr = alloc->malloc(alloc->ctx, nelem * elsize);
726+
}
716727
PyGILState_Release(gil_state);
717728

718729
set_reentrant(0);
@@ -1317,9 +1328,15 @@ PyTraceMalloc_Track(unsigned int domain, uintptr_t ptr,
13171328

13181329
gil_state = PyGILState_Ensure();
13191330

1320-
TABLES_LOCK();
1321-
res = tracemalloc_add_trace(domain, ptr, size);
1322-
TABLES_UNLOCK();
1331+
if (tracemalloc_config.tracing) {
1332+
TABLES_LOCK();
1333+
res = tracemalloc_add_trace(domain, ptr, size);
1334+
TABLES_UNLOCK();
1335+
}
1336+
else {
1337+
// gh-128679: tracemalloc.stop() was called by another thread during
1338+
// PyGILState_Ensure() call.
1339+
}
13231340

13241341
PyGILState_Release(gil_state);
13251342
return res;

0 commit comments

Comments
 (0)